diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-03-13 00:56:37 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-03-13 00:56:37 (GMT) |
commit | 93d74463d018ddf05c169ad399e62e90e0f82fc0 (patch) | |
tree | 887f61c90a9aab75060a3adbc20bcb8debd98e20 /arch/arm/plat-omap/gpio.c | |
parent | c463be3520065ef8c05e3cbdf946c69604e91ceb (diff) | |
parent | 4c91363dc01310dc34f1621ef00d680b4404f71c (diff) | |
download | linux-93d74463d018ddf05c169ad399e62e90e0f82fc0.tar.xz |
Merge master.kernel.org:/home/rmk/linux-2.6-arm
* master.kernel.org:/home/rmk/linux-2.6-arm: (26 commits)
[ARM] 4856/1: Orion: initialise the sixth PCIe MBUS mapping window as well
[ARM] 4855/1: Orion: use correct ethernet unit address range
[ARM] 4853/1: include uImage target in make help
[ARM] 4851/1: ns9xxx: fix size of gpiores
[ARM] AT91: correct at91sam9263ek LCD power gpio pin
[ARM] replace remaining __FUNCTION__ occurrences
[ARM] 4850/1: include generic pgtable.h for !CONFIG_MMU case
[ARM] 4849/1: move ATAGS asm definitions
[ARM] 4848/1: at91: remove false lockdep warnings
[ARM] 4847/1: kprobes: fix compilation with CONFIG_DEBUG_FS=y
[ARM] include/asm-arm - use angle brackets for includes
[ARM] 4845/1: Orion: Ignore memory tags with invalid data
ARM: OMAP2: Register the L4 io bus to boot OMAP2
ARM: OMAP1: Compile in other 16xx boards to OSK defconfig
ARM: OMAP1: Refresh H2 defconfig
ARM: OMAP1: Refresh OSK defconfig
ARM: OMAP: gpio lockdep updates
ARM: OMAP1: omap1/pm.c build fix
ARM: OMAP1: omap h2 regression fix
ARM: OMAP1: Fix compile for boards depending on old gpio expander
...
Diffstat (limited to 'arch/arm/plat-omap/gpio.c')
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 56f4d13..66a1455 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -333,13 +333,14 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) void omap_set_gpio_direction(int gpio, int is_input) { struct gpio_bank *bank; + unsigned long flags; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); _set_gpio_direction(bank, get_gpio_index(gpio), is_input); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); } static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) @@ -406,13 +407,14 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) void omap_set_gpio_dataout(int gpio, int enable) { struct gpio_bank *bank; + unsigned long flags; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); _set_gpio_dataout(bank, get_gpio_index(gpio), enable); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); } int omap_get_gpio_datain(int gpio) @@ -624,6 +626,7 @@ static int gpio_irq_type(unsigned irq, unsigned type) struct gpio_bank *bank; unsigned gpio; int retval; + unsigned long flags; if (!cpu_class_is_omap2() && irq > IH_MPUIO_BASE) gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); @@ -642,13 +645,13 @@ static int gpio_irq_type(unsigned irq, unsigned type) return -EINVAL; bank = get_irq_chip_data(irq); - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); if (retval == 0) { irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; irq_desc[irq].status |= type; } - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return retval; } @@ -830,11 +833,13 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena */ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) { + unsigned long flags; + switch (bank->method) { #ifdef CONFIG_ARCH_OMAP16XX case METHOD_MPUIO: case METHOD_GPIO_1610: - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); if (enable) { bank->suspend_wakeup |= (1 << gpio); enable_irq_wake(bank->irq); @@ -842,7 +847,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) disable_irq_wake(bank->irq); bank->suspend_wakeup &= ~(1 << gpio); } - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return 0; #endif #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) @@ -853,7 +858,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) (bank - gpio_bank) * 32 + gpio); return -EINVAL; } - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); if (enable) { bank->suspend_wakeup |= (1 << gpio); enable_irq_wake(bank->irq); @@ -861,7 +866,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) disable_irq_wake(bank->irq); bank->suspend_wakeup &= ~(1 << gpio); } - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return 0; #endif default: @@ -897,16 +902,17 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable) int omap_request_gpio(int gpio) { struct gpio_bank *bank; + unsigned long flags; if (check_gpio(gpio) < 0) return -EINVAL; bank = get_gpio_bank(gpio); - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); if (unlikely(bank->reserved_map & (1 << get_gpio_index(gpio)))) { printk(KERN_ERR "omap-gpio: GPIO %d is already reserved!\n", gpio); dump_stack(); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return -1; } bank->reserved_map |= (1 << get_gpio_index(gpio)); @@ -925,7 +931,7 @@ int omap_request_gpio(int gpio) __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); } #endif - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return 0; } @@ -933,15 +939,16 @@ int omap_request_gpio(int gpio) void omap_free_gpio(int gpio) { struct gpio_bank *bank; + unsigned long flags; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); if (unlikely(!(bank->reserved_map & (1 << get_gpio_index(gpio))))) { printk(KERN_ERR "omap-gpio: GPIO %d wasn't reserved!\n", gpio); dump_stack(); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return; } #ifdef CONFIG_ARCH_OMAP16XX @@ -960,7 +967,7 @@ void omap_free_gpio(int gpio) #endif bank->reserved_map &= ~(1 << get_gpio_index(gpio)); _reset_gpio(bank, gpio); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); } /* @@ -1194,11 +1201,12 @@ static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t me { struct gpio_bank *bank = platform_get_drvdata(pdev); void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; + unsigned long flags; - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); bank->saved_wakeup = __raw_readl(mask_reg); __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return 0; } @@ -1207,10 +1215,11 @@ static int omap_mpuio_resume_early(struct platform_device *pdev) { struct gpio_bank *bank = platform_get_drvdata(pdev); void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; + unsigned long flags; - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); __raw_writel(bank->saved_wakeup, mask_reg); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return 0; } @@ -1277,6 +1286,11 @@ static struct clk *gpio_fclks[OMAP34XX_NR_GPIOS]; static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS]; #endif +/* This lock class tells lockdep that GPIO irqs are in a different + * category than their parents, so it won't report false recursion. + */ +static struct lock_class_key gpio_lock_class; + static int __init _omap_gpio_init(void) { int i; @@ -1450,6 +1464,7 @@ static int __init _omap_gpio_init(void) #endif for (j = bank->virtual_irq_start; j < bank->virtual_irq_start + gpio_count; j++) { + lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class); set_irq_chip_data(j, bank); if (bank_is_mpuio(bank)) set_irq_chip(j, &mpuio_irq_chip); @@ -1489,6 +1504,7 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) void __iomem *wake_status; void __iomem *wake_clear; void __iomem *wake_set; + unsigned long flags; switch (bank->method) { #ifdef CONFIG_ARCH_OMAP16XX @@ -1509,11 +1525,11 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) continue; } - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); bank->saved_wakeup = __raw_readl(wake_status); __raw_writel(0xffffffff, wake_clear); __raw_writel(bank->suspend_wakeup, wake_set); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); } return 0; @@ -1530,6 +1546,7 @@ static int omap_gpio_resume(struct sys_device *dev) struct gpio_bank *bank = &gpio_bank[i]; void __iomem *wake_clear; void __iomem *wake_set; + unsigned long flags; switch (bank->method) { #ifdef CONFIG_ARCH_OMAP16XX @@ -1548,10 +1565,10 @@ static int omap_gpio_resume(struct sys_device *dev) continue; } - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); __raw_writel(0xffffffff, wake_clear); __raw_writel(bank->saved_wakeup, wake_set); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); } return 0; |