summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/gpio.c
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-05-24 14:59:21 -0700
committerGary King <gking@nvidia.com>2010-05-25 15:13:49 -0700
commit443d2674352e56b1238eef325107833d19c1ddf8 (patch)
tree4d3578f22275b0ab29450f56702f0182fe9336e4 /arch/arm/mach-tegra/gpio.c
parent0622939d52243bb988b14938d5a6df9b2cc172c3 (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.c24
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;
}
}