summaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2013-10-16 15:25:33 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-10-17 04:51:53 -0400
commitdf231f280f0051e8de05a1f31c13b2ce2a761c3f (patch)
tree55e3a4549b2a3a99ee7725faabe2d6b0cd581e4e /drivers/gpio
parentbd0bf46844ad79c1360eebc73bf6f1e4c31b39fb (diff)
gpio: tegra: use new gpio_lock_as_irq() API
Whenever an IRQ is claimed or freed, call gpio_lock_as_irq() or gpio_unlock_as_irq() on the associated GPIO, to prevent that GPIO from being configured in a manner incompatible with an interrupt. Signed-off-by: Stephen Warren <swarren@nvidia.com> Reviewed-by: Javier Martinez Canillas <javier@dowhile0.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-tegra.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 9a62672f1bed..cfd3b9037bc7 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -75,6 +75,7 @@ struct tegra_gpio_bank {
75#endif 75#endif
76}; 76};
77 77
78static struct device *dev;
78static struct irq_domain *irq_domain; 79static struct irq_domain *irq_domain;
79static void __iomem *regs; 80static void __iomem *regs;
80static u32 tegra_gpio_bank_count; 81static u32 tegra_gpio_bank_count;
@@ -205,6 +206,7 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
205 int lvl_type; 206 int lvl_type;
206 int val; 207 int val;
207 unsigned long flags; 208 unsigned long flags;
209 int ret;
208 210
209 switch (type & IRQ_TYPE_SENSE_MASK) { 211 switch (type & IRQ_TYPE_SENSE_MASK) {
210 case IRQ_TYPE_EDGE_RISING: 212 case IRQ_TYPE_EDGE_RISING:
@@ -231,6 +233,12 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
231 return -EINVAL; 233 return -EINVAL;
232 } 234 }
233 235
236 ret = gpio_lock_as_irq(&tegra_gpio_chip, gpio);
237 if (ret) {
238 dev_err(dev, "unable to lock Tegra GPIO %d as IRQ\n", gpio);
239 return ret;
240 }
241
234 spin_lock_irqsave(&bank->lvl_lock[port], flags); 242 spin_lock_irqsave(&bank->lvl_lock[port], flags);
235 243
236 val = tegra_gpio_readl(GPIO_INT_LVL(gpio)); 244 val = tegra_gpio_readl(GPIO_INT_LVL(gpio));
@@ -251,6 +259,13 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
251 return 0; 259 return 0;
252} 260}
253 261
262static void tegra_gpio_irq_shutdown(struct irq_data *d)
263{
264 int gpio = d->hwirq;
265
266 gpio_unlock_as_irq(&tegra_gpio_chip, gpio);
267}
268
254static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) 269static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
255{ 270{
256 struct tegra_gpio_bank *bank; 271 struct tegra_gpio_bank *bank;
@@ -368,6 +383,7 @@ static struct irq_chip tegra_gpio_irq_chip = {
368 .irq_mask = tegra_gpio_irq_mask, 383 .irq_mask = tegra_gpio_irq_mask,
369 .irq_unmask = tegra_gpio_irq_unmask, 384 .irq_unmask = tegra_gpio_irq_unmask,
370 .irq_set_type = tegra_gpio_irq_set_type, 385 .irq_set_type = tegra_gpio_irq_set_type,
386 .irq_shutdown = tegra_gpio_irq_shutdown,
371#ifdef CONFIG_PM_SLEEP 387#ifdef CONFIG_PM_SLEEP
372 .irq_set_wake = tegra_gpio_irq_set_wake, 388 .irq_set_wake = tegra_gpio_irq_set_wake,
373#endif 389#endif
@@ -413,6 +429,8 @@ static int tegra_gpio_probe(struct platform_device *pdev)
413 int i; 429 int i;
414 int j; 430 int j;
415 431
432 dev = &pdev->dev;
433
416 match = of_match_device(tegra_gpio_of_match, &pdev->dev); 434 match = of_match_device(tegra_gpio_of_match, &pdev->dev);
417 if (!match) { 435 if (!match) {
418 dev_err(&pdev->dev, "Error: No device match found\n"); 436 dev_err(&pdev->dev, "Error: No device match found\n");