]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/gpio/tegra_gpio.c
tpm: tpm_tis_i2c: Move definitions into the header file
[karo-tx-uboot.git] / drivers / gpio / tegra_gpio.c
index 1cc4abb8a938b16ccc1322a6adcc903bc064b299..4921f0ff42e9706957ae6ca785187a3dcfc8e9ec 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/arch/tegra.h>
 #include <asm/gpio.h>
 #include <dm/device-internal.h>
+#include <dt-bindings/gpio/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -39,7 +40,6 @@ struct tegra_gpio_platdata {
 
 /* Information about each port at run-time */
 struct tegra_port_info {
-       char label[TEGRA_GPIOS_PER_PORT][GPIO_NAME_SIZE];
        struct gpio_ctlr_bank *bank;
        int base_gpio;          /* Port number for this port (0, 1,.., n-1) */
 };
@@ -132,36 +132,6 @@ static void set_level(unsigned gpio, int high)
        writel(u, &bank->gpio_out[GPIO_PORT(gpio)]);
 }
 
-static int check_reserved(struct udevice *dev, unsigned offset,
-                         const char *func)
-{
-       struct tegra_port_info *state = dev_get_priv(dev);
-       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
-
-       if (!*state->label[offset]) {
-               printf("tegra_gpio: %s: error: gpio %s%d not reserved\n",
-                      func, uc_priv->bank_name, offset);
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-/* set GPIO pin 'gpio' as an output, with polarity 'value' */
-int tegra_spl_gpio_direction_output(int gpio, int value)
-{
-       /* Configure as a GPIO */
-       set_config(gpio, 1);
-
-       /* Configure GPIO output value. */
-       set_level(gpio, value);
-
-       /* Configure GPIO direction as output. */
-       set_direction(gpio, 1);
-
-       return 0;
-}
-
 /*
  * Generic_GPIO primitives.
  */
@@ -171,56 +141,16 @@ static int tegra_gpio_request(struct udevice *dev, unsigned offset,
 {
        struct tegra_port_info *state = dev_get_priv(dev);
 
-       if (*state->label[offset])
-               return -EBUSY;
-
-       strncpy(state->label[offset], label, GPIO_NAME_SIZE);
-       state->label[offset][GPIO_NAME_SIZE - 1] = '\0';
-
        /* Configure as a GPIO */
        set_config(state->base_gpio + offset, 1);
 
        return 0;
 }
 
-static int tegra_gpio_free(struct udevice *dev, unsigned offset)
-{
-       struct tegra_port_info *state = dev_get_priv(dev);
-       int ret;
-
-       ret = check_reserved(dev, offset, __func__);
-       if (ret)
-               return ret;
-       state->label[offset][0] = '\0';
-
-       return 0;
-}
-
-/* read GPIO OUT value of pin 'gpio' */
-static int tegra_gpio_get_output_value(unsigned gpio)
-{
-       struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
-       struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
-       int val;
-
-       debug("gpio_get_output_value: pin = %d (port %d:bit %d)\n",
-               gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
-
-       val = readl(&bank->gpio_out[GPIO_PORT(gpio)]);
-
-       return (val >> GPIO_BIT(gpio)) & 1;
-}
-
-
 /* set GPIO pin 'gpio' as an input */
 static int tegra_gpio_direction_input(struct udevice *dev, unsigned offset)
 {
        struct tegra_port_info *state = dev_get_priv(dev);
-       int ret;
-
-       ret = check_reserved(dev, offset, __func__);
-       if (ret)
-               return ret;
 
        /* Configure GPIO direction as input. */
        set_direction(state->base_gpio + offset, 0);
@@ -234,11 +164,6 @@ static int tegra_gpio_direction_output(struct udevice *dev, unsigned offset,
 {
        struct tegra_port_info *state = dev_get_priv(dev);
        int gpio = state->base_gpio + offset;
-       int ret;
-
-       ret = check_reserved(dev, offset, __func__);
-       if (ret)
-               return ret;
 
        /* Configure GPIO output value. */
        set_level(gpio, value);
@@ -254,13 +179,8 @@ static int tegra_gpio_get_value(struct udevice *dev, unsigned offset)
 {
        struct tegra_port_info *state = dev_get_priv(dev);
        int gpio = state->base_gpio + offset;
-       int ret;
        int val;
 
-       ret = check_reserved(dev, offset, __func__);
-       if (ret)
-               return ret;
-
        debug("%s: pin = %d (port %d:bit %d)\n", __func__,
              gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
 
@@ -274,11 +194,6 @@ static int tegra_gpio_set_value(struct udevice *dev, unsigned offset, int value)
 {
        struct tegra_port_info *state = dev_get_priv(dev);
        int gpio = state->base_gpio + offset;
-       int ret;
-
-       ret = check_reserved(dev, offset, __func__);
-       if (ret)
-               return ret;
 
        debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n",
              gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value);
@@ -314,8 +229,6 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset)
        struct tegra_port_info *state = dev_get_priv(dev);
        int gpio = state->base_gpio + offset;
 
-       if (!*state->label[offset])
-               return GPIOF_UNUSED;
        if (!get_config(gpio))
                return GPIOF_FUNC;
        else if (get_direction(gpio))
@@ -324,50 +237,30 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset)
                return GPIOF_INPUT;
 }
 
-static int tegra_gpio_get_state(struct udevice *dev, unsigned int offset,
-                               char *buf, int bufsize)
+static int tegra_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
+                           struct fdtdec_phandle_args *args)
 {
-       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
-       struct tegra_port_info *state = dev_get_priv(dev);
-       int gpio = state->base_gpio + offset;
-       const char *label;
-       int is_output;
-       int is_gpio;
-       int size;
-
-       label = state->label[offset];
-       is_gpio = get_config(gpio); /* GPIO, not SFPIO */
-       size = snprintf(buf, bufsize, "%s%d: ",
-                       uc_priv->bank_name ? uc_priv->bank_name : "", offset);
-       buf += size;
-       bufsize -= size;
-       if (is_gpio) {
-               is_output = get_direction(gpio);
-
-               snprintf(buf, bufsize, "%s: %d [%c]%s%s",
-                        is_output ? "out" : " in",
-                        is_output ?
-                               tegra_gpio_get_output_value(gpio) :
-                               tegra_gpio_get_value(dev, offset),
-                        *label ? 'x' : ' ',
-                        *label ? " " : "",
-                        label);
-       } else {
-               snprintf(buf, bufsize, "sfpio");
-       }
+       int gpio, port, ret;
+
+       gpio = args->args[0];
+       port = gpio / TEGRA_GPIOS_PER_PORT;
+       ret = device_get_child(dev, port, &desc->dev);
+       if (ret)
+               return ret;
+       desc->offset = gpio % TEGRA_GPIOS_PER_PORT;
+       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
 
        return 0;
 }
 
 static const struct dm_gpio_ops gpio_tegra_ops = {
        .request                = tegra_gpio_request,
-       .free                   = tegra_gpio_free,
        .direction_input        = tegra_gpio_direction_input,
        .direction_output       = tegra_gpio_direction_output,
        .get_value              = tegra_gpio_get_value,
        .set_value              = tegra_gpio_set_value,
        .get_function           = tegra_gpio_get_function,
-       .get_state              = tegra_gpio_get_state,
+       .xlate                  = tegra_gpio_xlate,
 };
 
 /**
@@ -402,7 +295,7 @@ static const struct udevice_id tegra_gpio_ids[] = {
 
 static int gpio_tegra_probe(struct udevice *dev)
 {
-       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+       struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
        struct tegra_port_info *priv = dev->priv;
        struct tegra_gpio_platdata *plat = dev->platdata;
 
@@ -430,12 +323,19 @@ static int gpio_tegra_bind(struct udevice *parent)
        int bank_count;
        int bank;
        int ret;
-       int len;
 
        /* If this is a child device, there is nothing to do here */
        if (plat)
                return 0;
 
+       /* TODO(sjg@chromium.org): Remove once SPL supports device tree */
+#ifdef CONFIG_SPL_BUILD
+       ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
+       bank_count = TEGRA_GPIO_BANKS;
+#else
+       {
+       int len;
+
        /*
         * This driver does not make use of interrupts, other than to figure
         * out the number of GPIO banks
@@ -443,8 +343,9 @@ static int gpio_tegra_bind(struct udevice *parent)
        if (!fdt_getprop(gd->fdt_blob, parent->of_offset, "interrupts", &len))
                return -EINVAL;
        bank_count = len / 3 / sizeof(u32);
-       ctlr = (struct gpio_ctlr *)fdtdec_get_addr(gd->fdt_blob,
-                                                  parent->of_offset, "reg");
+       ctlr = (struct gpio_ctlr *)dev_get_addr(parent);
+       }
+#endif
        for (bank = 0; bank < bank_count; bank++) {
                int port;
 
@@ -480,4 +381,5 @@ U_BOOT_DRIVER(gpio_tegra) = {
        .probe = gpio_tegra_probe,
        .priv_auto_alloc_size = sizeof(struct tegra_port_info),
        .ops    = &gpio_tegra_ops,
+       .flags  = DM_FLAG_PRE_RELOC,
 };