diff options
author | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:45:10 -0800 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:45:10 -0800 |
commit | 6a4c4d56e19381689fe0e8f99ad54d1f0c80f3d7 (patch) | |
tree | 2355fca26fc3dd8d074218a60eb117f41586c479 /drivers | |
parent | 0c4a3989e5d5bbccf2090ed78ccf6805e791d101 (diff) | |
parent | 0ff78b252c872587f36afafa85f473fdebe8dc6f (diff) |
Merge branch 'buckets/mach-tegra' into after-buckets
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpio/gpio-tegra.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 5837b8c1dd79..e42ebe0be017 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -6,6 +6,8 @@ * Author: * Erik Gilling <konkers@google.com> * + * Copyright (c) 2011 NVIDIA Corporation. + * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. @@ -20,6 +22,7 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/interrupt.h> +#include <linux/delay.h> #include <linux/io.h> #include <linux/gpio.h> @@ -36,10 +39,6 @@ #define GPIO_PORT(x) (((x) >> 3) & 0x3) #define GPIO_BIT(x) ((x) & 0x7) -#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \ - GPIO_BANK(x) * 0x80 + \ - GPIO_PORT(x) * 4) - #define GPIO_CNF(x) (GPIO_REG(x) + 0x00) #define GPIO_OE(x) (GPIO_REG(x) + 0x10) #define GPIO_OUT(x) (GPIO_REG(x) + 0X20) @@ -49,12 +48,29 @@ #define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60) #define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70) +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) +#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \ + GPIO_BANK(x) * 0x80 + \ + GPIO_PORT(x) * 4) + #define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800) #define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810) #define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820) #define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840) #define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850) #define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860) +#else +#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \ + GPIO_BANK(x) * 0x100 + \ + GPIO_PORT(x) * 4) + +#define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x80) +#define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x90) +#define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0XA0) +#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0xC0) +#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0xD0) +#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0xE0) +#endif #define GPIO_INT_LVL_MASK 0x010101 #define GPIO_INT_LVL_EDGE_RISING 0x000101 @@ -67,7 +83,7 @@ struct tegra_gpio_bank { int bank; int irq; spinlock_t lvl_lock[4]; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP u32 cnf[4]; u32 out[4]; u32 oe[4]; @@ -85,6 +101,9 @@ static struct tegra_gpio_bank tegra_gpio_banks[] = { {.bank = 4, .irq = INT_GPIO5}, {.bank = 5, .irq = INT_GPIO6}, {.bank = 6, .irq = INT_GPIO7}, +#ifndef CONFIG_ARCH_TEGRA_2x_SOC + {.bank = 7, .irq = INT_GPIO8}, +#endif }; static int tegra_gpio_compose(int bank, int port, int bit) @@ -153,6 +172,15 @@ static void tegra_gpio_irq_ack(struct irq_data *d) int gpio = d->irq - INT_GPIO_BASE; __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); + +#ifdef CONFIG_TEGRA_FPGA_PLATFORM + /* FPGA platforms have a serializer between the GPIO + block and interrupt controller. Allow time for + clearing of the GPIO interrupt to propagate to the + interrupt controller before re-enabling the IRQ + to prevent double interrupts. */ + udelay(15); +#endif } static void tegra_gpio_irq_mask(struct irq_data *d) @@ -246,7 +274,7 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static void tegra_gpio_resume(void) { unsigned long flags; @@ -352,7 +380,7 @@ static int __init tegra_gpio_init(void) int i; int j; - for (i = 0; i < 7; i++) { + for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { for (j = 0; j < 4; j++) { int gpio = tegra_gpio_compose(i, j, 0); __raw_writel(0x00, GPIO_INT_ENB(gpio)); @@ -419,7 +447,8 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) int i; int j; - for (i = 0; i < 7; i++) { + seq_printf(s, "Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL\n"); + for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { for (j = 0; j < 4; j++) { int gpio = tegra_gpio_compose(i, j, 0); seq_printf(s, |