aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-tegra.c
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2012-01-04 03:39:37 -0500
committerOlof Johansson <olof@lixom.net>2012-02-06 21:25:00 -0500
commit6f74dc9bc8de41f3de474a7269a70921e773c40f (patch)
tree2804776d56077c3732db396e0cf42719ee9a83a5 /drivers/gpio/gpio-tegra.c
parent2123552d12168e744271aaf206e5826760fbd857 (diff)
gpio: tegra: Dynamically allocate IRQ base, and support DT
Enhance the driver to dynamically allocate the base IRQ number, and create an IRQ domain for itself. The use of an IRQ domain ensures that any device tree node interrupts properties are correctly parsed. Describe interrupt-related properties in the device tree binding docs, and the contents of "child" node interrupts property. Update tegra*.dtsi to specify the required interrupt-related properties. Finally, remove the definition of TEGRA_GPIO_TO_IRQ; this macro no longer gives correct results since the IRQ numbers for GPIOs are dynamically allocated. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/gpio/gpio-tegra.c')
-rw-r--r--drivers/gpio/gpio-tegra.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index bdc293791590..bc923c7acce9 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -25,6 +25,7 @@
25#include <linux/of.h> 25#include <linux/of.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/irqdomain.h>
28 29
29#include <asm/mach/irq.h> 30#include <asm/mach/irq.h>
30 31
@@ -74,7 +75,7 @@ struct tegra_gpio_bank {
74#endif 75#endif
75}; 76};
76 77
77 78static struct irq_domain irq_domain;
78static void __iomem *regs; 79static void __iomem *regs;
79static struct tegra_gpio_bank tegra_gpio_banks[7]; 80static struct tegra_gpio_bank tegra_gpio_banks[7];
80 81
@@ -139,7 +140,7 @@ static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
139 140
140static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset) 141static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
141{ 142{
142 return TEGRA_GPIO_TO_IRQ(offset); 143 return irq_domain_to_irq(&irq_domain, offset);
143} 144}
144 145
145static struct gpio_chip tegra_gpio_chip = { 146static struct gpio_chip tegra_gpio_chip = {
@@ -155,28 +156,28 @@ static struct gpio_chip tegra_gpio_chip = {
155 156
156static void tegra_gpio_irq_ack(struct irq_data *d) 157static void tegra_gpio_irq_ack(struct irq_data *d)
157{ 158{
158 int gpio = d->irq - INT_GPIO_BASE; 159 int gpio = d->hwirq;
159 160
160 tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); 161 tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
161} 162}
162 163
163static void tegra_gpio_irq_mask(struct irq_data *d) 164static void tegra_gpio_irq_mask(struct irq_data *d)
164{ 165{
165 int gpio = d->irq - INT_GPIO_BASE; 166 int gpio = d->hwirq;
166 167
167 tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0); 168 tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0);
168} 169}
169 170
170static void tegra_gpio_irq_unmask(struct irq_data *d) 171static void tegra_gpio_irq_unmask(struct irq_data *d)
171{ 172{
172 int gpio = d->irq - INT_GPIO_BASE; 173 int gpio = d->hwirq;
173 174
174 tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1); 175 tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1);
175} 176}
176 177
177static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) 178static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
178{ 179{
179 int gpio = d->irq - INT_GPIO_BASE; 180 int gpio = d->hwirq;
180 struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); 181 struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
181 int port = GPIO_PORT(gpio); 182 int port = GPIO_PORT(gpio);
182 int lvl_type; 183 int lvl_type;
@@ -343,6 +344,16 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
343 int i; 344 int i;
344 int j; 345 int j;
345 346
347 irq_domain.irq_base = irq_alloc_descs(-1, 0, TEGRA_NR_GPIOS, 0);
348 if (irq_domain.irq_base < 0) {
349 dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n");
350 return -ENODEV;
351 }
352 irq_domain.nr_irq = TEGRA_NR_GPIOS;
353 irq_domain.ops = &irq_domain_simple_ops;
354 irq_domain.of_node = pdev->dev.of_node;
355 irq_domain_add(&irq_domain);
356
346 for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { 357 for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
347 res = platform_get_resource(pdev, IORESOURCE_IRQ, i); 358 res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
348 if (!res) { 359 if (!res) {
@@ -381,7 +392,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
381 gpiochip_add(&tegra_gpio_chip); 392 gpiochip_add(&tegra_gpio_chip);
382 393
383 for (gpio = 0; gpio < TEGRA_NR_GPIOS; gpio++) { 394 for (gpio = 0; gpio < TEGRA_NR_GPIOS; gpio++) {
384 int irq = TEGRA_GPIO_TO_IRQ(gpio); 395 int irq = irq_domain_to_irq(&irq_domain, gpio);
385 /* No validity check; all Tegra GPIOs are valid IRQs */ 396 /* No validity check; all Tegra GPIOs are valid IRQs */
386 397
387 bank = &tegra_gpio_banks[GPIO_BANK(gpio)]; 398 bank = &tegra_gpio_banks[GPIO_BANK(gpio)];