summaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
authorScott Williams <scwilliams@nvidia.com>2010-12-07 11:19:20 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:42:02 -0800
commit816ab05de4f2171e20171db01fa916634ed7bee6 (patch)
tree963ce2c1724c63598deb279d9f6ed54cfc93d1e3 /drivers/gpio
parent7d8324d8f3dfc27407d7514fcbd605649c9bd210 (diff)
[ARM/tegra] Add Tegra3 support
Bug 764354 Original-Change-Id: I8a390eb4dae87dceacb97461f23d13554868b046 Reviewed-on: http://git-master/r/12228 Reviewed-by: Scott Williams <scwilliams@nvidia.com> Tested-by: Scott Williams <scwilliams@nvidia.com> Original-Change-Id: I8e6b8303898796419fb5a759cd16edff9aeac081 Rebase-Id: R2866240384c6c24f46bd7ef54bc3dc9140d9e96b
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-tegra.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 5837b8c1dd79..9a9c8b188c08 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -20,6 +20,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 +37,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 +46,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
@@ -85,6 +99,9 @@ static struct tegra_gpio_bank tegra_gpio_banks[] = {
{.bank = 4, .irq = INT_GPIO5},
{.bank = 5, .irq = INT_GPIO6},
{.bank = 6, .irq = INT_GPIO7},
+#if defined(CONFIG_ARCH_TEGRA_3x_SOC)
+ {.bank = 7, .irq = INT_GPIO8},
+#endif
};
static int tegra_gpio_compose(int bank, int port, int bit)
@@ -153,6 +170,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)