diff options
author | Gary King <gking@nvidia.com> | 2010-05-24 14:59:21 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-05-25 15:13:49 -0700 |
commit | 443d2674352e56b1238eef325107833d19c1ddf8 (patch) | |
tree | 4d3578f22275b0ab29450f56702f0182fe9336e4 /arch/arm/mach-tegra/gpio.c | |
parent | 0622939d52243bb988b14938d5a6df9b2cc172c3 (diff) |
[ARM/tegra] gpio: init RM before I/O rail query; fix disable/enable
the NvOdmPeripheral APIs need the RM to exist since they may perform I2C
operations internally to read board EEPROMs; the RM needs to be opened
before this to ensure that valid values are returned
additionally, tegra_gpio_enable and tegra_gpio_disable are called
by the RM API implementation to reconfigure GPIOs as special function
pins; move the tristate & io_power configuration into request and free,
so that enable and disable are just affecting the GPIO vs SFIO state
Change-Id: Idc950b1f87204fb1fda795f7ae8331bd2b0d8ae2
Diffstat (limited to 'arch/arm/mach-tegra/gpio.c')
-rw-r--r-- | arch/arm/mach-tegra/gpio.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c index 2f06f5849177..8ec4266d2021 100644 --- a/arch/arm/mach-tegra/gpio.c +++ b/arch/arm/mach-tegra/gpio.c @@ -112,6 +112,7 @@ static void tegra_set_gpio_tristate(int gpio_nr, tegra_tristate_t ts) int err; pg = gpio_get_pinmux_group(gpio_nr); + WARN_ON(pg < 0); if (pg >= 0) { err = tegra_pinmux_set_tristate(pg, ts); if (err < 0) @@ -122,27 +123,27 @@ static void tegra_set_gpio_tristate(int gpio_nr, tegra_tristate_t ts) void tegra_gpio_enable(int gpio) { - WARN_ON(tegra_gpio_io_power_config(gpio, 1) != 0); tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); - tegra_set_gpio_tristate(gpio, TEGRA_TRI_NORMAL); } void tegra_gpio_disable(int gpio) { tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); - tegra_set_gpio_tristate(gpio, TEGRA_TRI_TRISTATE); - WARN_ON(tegra_gpio_io_power_config(gpio, 0) != 0); } static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) { + WARN_ON(tegra_gpio_io_power_config(offset, 1) != 0); tegra_gpio_enable(offset); + tegra_set_gpio_tristate(offset, TEGRA_TRI_NORMAL); return 0; } static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) { tegra_gpio_disable(offset); + tegra_set_gpio_tristate(offset, TEGRA_TRI_TRISTATE); + WARN_ON(tegra_gpio_io_power_config(offset, 0) != 0); } static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) @@ -213,7 +214,7 @@ static int tegra_gpio_irq_set_type(unsigned int irq, unsigned int type) int val; unsigned long flags; - switch (type) { + switch (type & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_EDGE_RISING: lvl_type = GPIO_INT_LVL_EDGE_RISING; break; @@ -404,8 +405,13 @@ static void gpio_rail_init(void) { unsigned int i; - if (!s_hRmGlobal) - return; + if (!s_hRmGlobal) { + NvError e = NvRmOpenNew(&s_hRmGlobal); + if (e != NvSuccess) { + WARN_ON(1); + return; + } + } for (i = 0; i < NV_ARRAY_SIZE(gpio_power_rail_table); i++) { struct gpio_power_rail_info *rail = &gpio_power_rail_table[i]; @@ -418,8 +424,8 @@ static void gpio_rail_init(void) rail->address = conn->AddressList[0].Address; - NvRmPmuGetCapabilities(NULL, rail->address, &caps); - rail->mv = (caps.RmProtected) ? 0 : caps.requestMilliVolts; + NvRmPmuGetCapabilities(s_hRmGlobal, rail->address, &caps); + rail->mv = caps.requestMilliVolts; } } |