X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=drivers%2Fgpio%2Ftegra_gpio.c;h=302efddc2729aa00b3598d35342e1a8adb77994c;hb=83d290c56fab2d38cd1ab4c4cc7099559c1d5046;hp=4921f0ff42e9706957ae6ca785187a3dcfc8e9ec;hpb=4e9838c102e8575fbff3944e1596a53ec579844a;p=platform%2Fkernel%2Fu-boot.git diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c index 4921f0f..302efdd 100644 --- a/drivers/gpio/tegra_gpio.c +++ b/drivers/gpio/tegra_gpio.c @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * NVIDIA Tegra20 GPIO handling. - * (C) Copyright 2010-2012 + * (C) Copyright 2010-2012,2015 * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ */ /* @@ -23,14 +22,10 @@ #include #include -DECLARE_GLOBAL_DATA_PTR; - -enum { - TEGRA_CMD_INFO, - TEGRA_CMD_PORT, - TEGRA_CMD_OUTPUT, - TEGRA_CMD_INPUT, -}; +static const int CONFIG_SFIO = 0; +static const int CONFIG_GPIO = 1; +static const int DIRECTION_INPUT = 0; +static const int DIRECTION_OUTPUT = 1; struct tegra_gpio_platdata { struct gpio_ctlr_bank *bank; @@ -44,7 +39,7 @@ struct tegra_port_info { int base_gpio; /* Port number for this port (0, 1,.., n-1) */ }; -/* Return config of pin 'gpio' as GPIO (1) or SFPIO (0) */ +/* Return config of pin 'gpio' as GPIO (1) or SFIO (0) */ static int get_config(unsigned gpio) { struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; @@ -53,15 +48,15 @@ static int get_config(unsigned gpio) int type; u = readl(&bank->gpio_config[GPIO_PORT(gpio)]); - type = (u >> GPIO_BIT(gpio)) & 1; + type = (u >> GPIO_BIT(gpio)) & 1; debug("get_config: port = %d, bit = %d is %s\n", GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO"); - return type; + return type ? CONFIG_GPIO : CONFIG_SFIO; } -/* Config pin 'gpio' as GPIO or SFPIO, based on 'type' */ +/* Config pin 'gpio' as GPIO or SFIO, based on 'type' */ static void set_config(unsigned gpio, int type) { struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; @@ -72,7 +67,7 @@ static void set_config(unsigned gpio, int type) GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO"); u = readl(&bank->gpio_config[GPIO_PORT(gpio)]); - if (type) /* GPIO */ + if (type != CONFIG_SFIO) u |= 1 << GPIO_BIT(gpio); else u &= ~(1 << GPIO_BIT(gpio)); @@ -93,7 +88,7 @@ static int get_direction(unsigned gpio) debug("get_direction: port = %d, bit = %d, %s\n", GPIO_FULLPORT(gpio), GPIO_BIT(gpio), dir ? "OUT" : "IN"); - return dir; + return dir ? DIRECTION_OUTPUT : DIRECTION_INPUT; } /* Config GPIO pin 'gpio' as input or output (OE) as per 'output' */ @@ -107,7 +102,7 @@ static void set_direction(unsigned gpio, int output) GPIO_FULLPORT(gpio), GPIO_BIT(gpio), output ? "OUT" : "IN"); u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]); - if (output) + if (output != DIRECTION_INPUT) u |= 1 << GPIO_BIT(gpio); else u &= ~(1 << GPIO_BIT(gpio)); @@ -136,24 +131,16 @@ static void set_level(unsigned gpio, int high) * Generic_GPIO primitives. */ -static int tegra_gpio_request(struct udevice *dev, unsigned offset, - const char *label) -{ - struct tegra_port_info *state = dev_get_priv(dev); - - /* Configure as a GPIO */ - set_config(state->base_gpio + offset, 1); - - return 0; -} - /* 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); /* Configure GPIO direction as input. */ - set_direction(state->base_gpio + offset, 0); + set_direction(state->base_gpio + offset, DIRECTION_INPUT); + + /* Enable the pin as a GPIO */ + set_config(state->base_gpio + offset, 1); return 0; } @@ -169,7 +156,10 @@ static int tegra_gpio_direction_output(struct udevice *dev, unsigned offset, set_level(gpio, value); /* Configure GPIO direction as output. */ - set_direction(gpio, 1); + set_direction(gpio, DIRECTION_OUTPUT); + + /* Enable the pin as a GPIO */ + set_config(state->base_gpio + offset, 1); return 0; } @@ -184,7 +174,10 @@ static int tegra_gpio_get_value(struct udevice *dev, unsigned offset) debug("%s: pin = %d (port %d:bit %d)\n", __func__, gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio)); - val = readl(&state->bank->gpio_in[GPIO_PORT(gpio)]); + if (get_direction(gpio) == DIRECTION_INPUT) + val = readl(&state->bank->gpio_in[GPIO_PORT(gpio)]); + else + val = readl(&state->bank->gpio_out[GPIO_PORT(gpio)]); return (val >> GPIO_BIT(gpio)) & 1; } @@ -211,16 +204,18 @@ void gpio_config_table(const struct tegra_gpio_config *config, int len) for (i = 0; i < len; i++) { switch (config[i].init) { case TEGRA_GPIO_INIT_IN: - gpio_direction_input(config[i].gpio); + set_direction(config[i].gpio, DIRECTION_INPUT); break; case TEGRA_GPIO_INIT_OUT0: - gpio_direction_output(config[i].gpio, 0); + set_level(config[i].gpio, 0); + set_direction(config[i].gpio, DIRECTION_OUTPUT); break; case TEGRA_GPIO_INIT_OUT1: - gpio_direction_output(config[i].gpio, 1); + set_level(config[i].gpio, 1); + set_direction(config[i].gpio, DIRECTION_OUTPUT); break; } - set_config(config[i].gpio, 1); + set_config(config[i].gpio, CONFIG_GPIO); } } @@ -238,7 +233,7 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset) } static int tegra_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, - struct fdtdec_phandle_args *args) + struct ofnode_phandle_args *args) { int gpio, port, ret; @@ -254,7 +249,6 @@ static int tegra_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, } static const struct dm_gpio_ops gpio_tegra_ops = { - .request = tegra_gpio_request, .direction_input = tegra_gpio_direction_input, .direction_output = tegra_gpio_direction_output, .get_value = tegra_gpio_get_value, @@ -340,10 +334,13 @@ static int gpio_tegra_bind(struct udevice *parent) * This driver does not make use of interrupts, other than to figure * out the number of GPIO banks */ - if (!fdt_getprop(gd->fdt_blob, parent->of_offset, "interrupts", &len)) - return -EINVAL; + len = dev_read_size(parent, "interrupts"); + if (len < 0) + return len; bank_count = len / 3 / sizeof(u32); - ctlr = (struct gpio_ctlr *)dev_get_addr(parent); + ctlr = (struct gpio_ctlr *)dev_read_addr(parent); + if ((ulong)ctlr == FDT_ADDR_T_NONE) + return -EINVAL; } #endif for (bank = 0; bank < bank_count; bank++) { @@ -366,7 +363,7 @@ static int gpio_tegra_bind(struct udevice *parent) plat->port_name, plat, -1, &dev); if (ret) return ret; - dev->of_offset = parent->of_offset; + dev_set_of_offset(dev, dev_of_offset(parent)); } }