diff options
author | David Brownell <dbrownell@users.sourceforge.net> | 2008-03-03 07:33:30 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2008-03-05 03:23:21 -0500 |
commit | a6472533e4553985af775982744b0ba088b5ff8c (patch) | |
tree | 5c55fef6dc40829ac07ba07e50de2877fd327dae | |
parent | 02bad5f9bc9f1f42d4bb87bb8bf741d4cefe87d6 (diff) |
ARM: OMAP: gpio lockdep updates
Fix some spinlock issues reported by lockdep: since the gpio bank
locks can be aquired in both irq and non-irq contexts, they need
to be consistent about always using the irq-safe variants.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 9030495509f8..66a1455595f4 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) | |||
333 | void omap_set_gpio_direction(int gpio, int is_input) | 333 | void omap_set_gpio_direction(int gpio, int is_input) |
334 | { | 334 | { |
335 | struct gpio_bank *bank; | 335 | struct gpio_bank *bank; |
336 | unsigned long flags; | ||
336 | 337 | ||
337 | if (check_gpio(gpio) < 0) | 338 | if (check_gpio(gpio) < 0) |
338 | return; | 339 | return; |
339 | bank = get_gpio_bank(gpio); | 340 | bank = get_gpio_bank(gpio); |
340 | spin_lock(&bank->lock); | 341 | spin_lock_irqsave(&bank->lock, flags); |
341 | _set_gpio_direction(bank, get_gpio_index(gpio), is_input); | 342 | _set_gpio_direction(bank, get_gpio_index(gpio), is_input); |
342 | spin_unlock(&bank->lock); | 343 | spin_unlock_irqrestore(&bank->lock, flags); |
343 | } | 344 | } |
344 | 345 | ||
345 | static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) | 346 | 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) | |||
406 | void omap_set_gpio_dataout(int gpio, int enable) | 407 | void omap_set_gpio_dataout(int gpio, int enable) |
407 | { | 408 | { |
408 | struct gpio_bank *bank; | 409 | struct gpio_bank *bank; |
410 | unsigned long flags; | ||
409 | 411 | ||
410 | if (check_gpio(gpio) < 0) | 412 | if (check_gpio(gpio) < 0) |
411 | return; | 413 | return; |
412 | bank = get_gpio_bank(gpio); | 414 | bank = get_gpio_bank(gpio); |
413 | spin_lock(&bank->lock); | 415 | spin_lock_irqsave(&bank->lock, flags); |
414 | _set_gpio_dataout(bank, get_gpio_index(gpio), enable); | 416 | _set_gpio_dataout(bank, get_gpio_index(gpio), enable); |
415 | spin_unlock(&bank->lock); | 417 | spin_unlock_irqrestore(&bank->lock, flags); |
416 | } | 418 | } |
417 | 419 | ||
418 | int omap_get_gpio_datain(int gpio) | 420 | int omap_get_gpio_datain(int gpio) |
@@ -624,6 +626,7 @@ static int gpio_irq_type(unsigned irq, unsigned type) | |||
624 | struct gpio_bank *bank; | 626 | struct gpio_bank *bank; |
625 | unsigned gpio; | 627 | unsigned gpio; |
626 | int retval; | 628 | int retval; |
629 | unsigned long flags; | ||
627 | 630 | ||
628 | if (!cpu_class_is_omap2() && irq > IH_MPUIO_BASE) | 631 | if (!cpu_class_is_omap2() && irq > IH_MPUIO_BASE) |
629 | gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); | 632 | gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); |
@@ -642,13 +645,13 @@ static int gpio_irq_type(unsigned irq, unsigned type) | |||
642 | return -EINVAL; | 645 | return -EINVAL; |
643 | 646 | ||
644 | bank = get_irq_chip_data(irq); | 647 | bank = get_irq_chip_data(irq); |
645 | spin_lock(&bank->lock); | 648 | spin_lock_irqsave(&bank->lock, flags); |
646 | retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); | 649 | retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); |
647 | if (retval == 0) { | 650 | if (retval == 0) { |
648 | irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; | 651 | irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; |
649 | irq_desc[irq].status |= type; | 652 | irq_desc[irq].status |= type; |
650 | } | 653 | } |
651 | spin_unlock(&bank->lock); | 654 | spin_unlock_irqrestore(&bank->lock, flags); |
652 | return retval; | 655 | return retval; |
653 | } | 656 | } |
654 | 657 | ||
@@ -830,11 +833,13 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena | |||
830 | */ | 833 | */ |
831 | static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) | 834 | static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) |
832 | { | 835 | { |
836 | unsigned long flags; | ||
837 | |||
833 | switch (bank->method) { | 838 | switch (bank->method) { |
834 | #ifdef CONFIG_ARCH_OMAP16XX | 839 | #ifdef CONFIG_ARCH_OMAP16XX |
835 | case METHOD_MPUIO: | 840 | case METHOD_MPUIO: |
836 | case METHOD_GPIO_1610: | 841 | case METHOD_GPIO_1610: |
837 | spin_lock(&bank->lock); | 842 | spin_lock_irqsave(&bank->lock, flags); |
838 | if (enable) { | 843 | if (enable) { |
839 | bank->suspend_wakeup |= (1 << gpio); | 844 | bank->suspend_wakeup |= (1 << gpio); |
840 | enable_irq_wake(bank->irq); | 845 | enable_irq_wake(bank->irq); |
@@ -842,7 +847,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) | |||
842 | disable_irq_wake(bank->irq); | 847 | disable_irq_wake(bank->irq); |
843 | bank->suspend_wakeup &= ~(1 << gpio); | 848 | bank->suspend_wakeup &= ~(1 << gpio); |
844 | } | 849 | } |
845 | spin_unlock(&bank->lock); | 850 | spin_unlock_irqrestore(&bank->lock, flags); |
846 | return 0; | 851 | return 0; |
847 | #endif | 852 | #endif |
848 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 853 | #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) | |||
853 | (bank - gpio_bank) * 32 + gpio); | 858 | (bank - gpio_bank) * 32 + gpio); |
854 | return -EINVAL; | 859 | return -EINVAL; |
855 | } | 860 | } |
856 | spin_lock(&bank->lock); | 861 | spin_lock_irqsave(&bank->lock, flags); |
857 | if (enable) { | 862 | if (enable) { |
858 | bank->suspend_wakeup |= (1 << gpio); | 863 | bank->suspend_wakeup |= (1 << gpio); |
859 | enable_irq_wake(bank->irq); | 864 | enable_irq_wake(bank->irq); |
@@ -861,7 +866,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) | |||
861 | disable_irq_wake(bank->irq); | 866 | disable_irq_wake(bank->irq); |
862 | bank->suspend_wakeup &= ~(1 << gpio); | 867 | bank->suspend_wakeup &= ~(1 << gpio); |
863 | } | 868 | } |
864 | spin_unlock(&bank->lock); | 869 | spin_unlock_irqrestore(&bank->lock, flags); |
865 | return 0; | 870 | return 0; |
866 | #endif | 871 | #endif |
867 | default: | 872 | default: |
@@ -897,16 +902,17 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable) | |||
897 | int omap_request_gpio(int gpio) | 902 | int omap_request_gpio(int gpio) |
898 | { | 903 | { |
899 | struct gpio_bank *bank; | 904 | struct gpio_bank *bank; |
905 | unsigned long flags; | ||
900 | 906 | ||
901 | if (check_gpio(gpio) < 0) | 907 | if (check_gpio(gpio) < 0) |
902 | return -EINVAL; | 908 | return -EINVAL; |
903 | 909 | ||
904 | bank = get_gpio_bank(gpio); | 910 | bank = get_gpio_bank(gpio); |
905 | spin_lock(&bank->lock); | 911 | spin_lock_irqsave(&bank->lock, flags); |
906 | if (unlikely(bank->reserved_map & (1 << get_gpio_index(gpio)))) { | 912 | if (unlikely(bank->reserved_map & (1 << get_gpio_index(gpio)))) { |
907 | printk(KERN_ERR "omap-gpio: GPIO %d is already reserved!\n", gpio); | 913 | printk(KERN_ERR "omap-gpio: GPIO %d is already reserved!\n", gpio); |
908 | dump_stack(); | 914 | dump_stack(); |
909 | spin_unlock(&bank->lock); | 915 | spin_unlock_irqrestore(&bank->lock, flags); |
910 | return -1; | 916 | return -1; |
911 | } | 917 | } |
912 | bank->reserved_map |= (1 << get_gpio_index(gpio)); | 918 | bank->reserved_map |= (1 << get_gpio_index(gpio)); |
@@ -925,7 +931,7 @@ int omap_request_gpio(int gpio) | |||
925 | __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); | 931 | __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); |
926 | } | 932 | } |
927 | #endif | 933 | #endif |
928 | spin_unlock(&bank->lock); | 934 | spin_unlock_irqrestore(&bank->lock, flags); |
929 | 935 | ||
930 | return 0; | 936 | return 0; |
931 | } | 937 | } |
@@ -933,15 +939,16 @@ int omap_request_gpio(int gpio) | |||
933 | void omap_free_gpio(int gpio) | 939 | void omap_free_gpio(int gpio) |
934 | { | 940 | { |
935 | struct gpio_bank *bank; | 941 | struct gpio_bank *bank; |
942 | unsigned long flags; | ||
936 | 943 | ||
937 | if (check_gpio(gpio) < 0) | 944 | if (check_gpio(gpio) < 0) |
938 | return; | 945 | return; |
939 | bank = get_gpio_bank(gpio); | 946 | bank = get_gpio_bank(gpio); |
940 | spin_lock(&bank->lock); | 947 | spin_lock_irqsave(&bank->lock, flags); |
941 | if (unlikely(!(bank->reserved_map & (1 << get_gpio_index(gpio))))) { | 948 | if (unlikely(!(bank->reserved_map & (1 << get_gpio_index(gpio))))) { |
942 | printk(KERN_ERR "omap-gpio: GPIO %d wasn't reserved!\n", gpio); | 949 | printk(KERN_ERR "omap-gpio: GPIO %d wasn't reserved!\n", gpio); |
943 | dump_stack(); | 950 | dump_stack(); |
944 | spin_unlock(&bank->lock); | 951 | spin_unlock_irqrestore(&bank->lock, flags); |
945 | return; | 952 | return; |
946 | } | 953 | } |
947 | #ifdef CONFIG_ARCH_OMAP16XX | 954 | #ifdef CONFIG_ARCH_OMAP16XX |
@@ -960,7 +967,7 @@ void omap_free_gpio(int gpio) | |||
960 | #endif | 967 | #endif |
961 | bank->reserved_map &= ~(1 << get_gpio_index(gpio)); | 968 | bank->reserved_map &= ~(1 << get_gpio_index(gpio)); |
962 | _reset_gpio(bank, gpio); | 969 | _reset_gpio(bank, gpio); |
963 | spin_unlock(&bank->lock); | 970 | spin_unlock_irqrestore(&bank->lock, flags); |
964 | } | 971 | } |
965 | 972 | ||
966 | /* | 973 | /* |
@@ -1194,11 +1201,12 @@ static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t me | |||
1194 | { | 1201 | { |
1195 | struct gpio_bank *bank = platform_get_drvdata(pdev); | 1202 | struct gpio_bank *bank = platform_get_drvdata(pdev); |
1196 | void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; | 1203 | void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; |
1204 | unsigned long flags; | ||
1197 | 1205 | ||
1198 | spin_lock(&bank->lock); | 1206 | spin_lock_irqsave(&bank->lock, flags); |
1199 | bank->saved_wakeup = __raw_readl(mask_reg); | 1207 | bank->saved_wakeup = __raw_readl(mask_reg); |
1200 | __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg); | 1208 | __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg); |
1201 | spin_unlock(&bank->lock); | 1209 | spin_unlock_irqrestore(&bank->lock, flags); |
1202 | 1210 | ||
1203 | return 0; | 1211 | return 0; |
1204 | } | 1212 | } |
@@ -1207,10 +1215,11 @@ static int omap_mpuio_resume_early(struct platform_device *pdev) | |||
1207 | { | 1215 | { |
1208 | struct gpio_bank *bank = platform_get_drvdata(pdev); | 1216 | struct gpio_bank *bank = platform_get_drvdata(pdev); |
1209 | void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; | 1217 | void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; |
1218 | unsigned long flags; | ||
1210 | 1219 | ||
1211 | spin_lock(&bank->lock); | 1220 | spin_lock_irqsave(&bank->lock, flags); |
1212 | __raw_writel(bank->saved_wakeup, mask_reg); | 1221 | __raw_writel(bank->saved_wakeup, mask_reg); |
1213 | spin_unlock(&bank->lock); | 1222 | spin_unlock_irqrestore(&bank->lock, flags); |
1214 | 1223 | ||
1215 | return 0; | 1224 | return 0; |
1216 | } | 1225 | } |
@@ -1495,6 +1504,7 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) | |||
1495 | void __iomem *wake_status; | 1504 | void __iomem *wake_status; |
1496 | void __iomem *wake_clear; | 1505 | void __iomem *wake_clear; |
1497 | void __iomem *wake_set; | 1506 | void __iomem *wake_set; |
1507 | unsigned long flags; | ||
1498 | 1508 | ||
1499 | switch (bank->method) { | 1509 | switch (bank->method) { |
1500 | #ifdef CONFIG_ARCH_OMAP16XX | 1510 | #ifdef CONFIG_ARCH_OMAP16XX |
@@ -1515,11 +1525,11 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) | |||
1515 | continue; | 1525 | continue; |
1516 | } | 1526 | } |
1517 | 1527 | ||
1518 | spin_lock(&bank->lock); | 1528 | spin_lock_irqsave(&bank->lock, flags); |
1519 | bank->saved_wakeup = __raw_readl(wake_status); | 1529 | bank->saved_wakeup = __raw_readl(wake_status); |
1520 | __raw_writel(0xffffffff, wake_clear); | 1530 | __raw_writel(0xffffffff, wake_clear); |
1521 | __raw_writel(bank->suspend_wakeup, wake_set); | 1531 | __raw_writel(bank->suspend_wakeup, wake_set); |
1522 | spin_unlock(&bank->lock); | 1532 | spin_unlock_irqrestore(&bank->lock, flags); |
1523 | } | 1533 | } |
1524 | 1534 | ||
1525 | return 0; | 1535 | return 0; |
@@ -1536,6 +1546,7 @@ static int omap_gpio_resume(struct sys_device *dev) | |||
1536 | struct gpio_bank *bank = &gpio_bank[i]; | 1546 | struct gpio_bank *bank = &gpio_bank[i]; |
1537 | void __iomem *wake_clear; | 1547 | void __iomem *wake_clear; |
1538 | void __iomem *wake_set; | 1548 | void __iomem *wake_set; |
1549 | unsigned long flags; | ||
1539 | 1550 | ||
1540 | switch (bank->method) { | 1551 | switch (bank->method) { |
1541 | #ifdef CONFIG_ARCH_OMAP16XX | 1552 | #ifdef CONFIG_ARCH_OMAP16XX |
@@ -1554,10 +1565,10 @@ static int omap_gpio_resume(struct sys_device *dev) | |||
1554 | continue; | 1565 | continue; |
1555 | } | 1566 | } |
1556 | 1567 | ||
1557 | spin_lock(&bank->lock); | 1568 | spin_lock_irqsave(&bank->lock, flags); |
1558 | __raw_writel(0xffffffff, wake_clear); | 1569 | __raw_writel(0xffffffff, wake_clear); |
1559 | __raw_writel(bank->saved_wakeup, wake_set); | 1570 | __raw_writel(bank->saved_wakeup, wake_set); |
1560 | spin_unlock(&bank->lock); | 1571 | spin_unlock_irqrestore(&bank->lock, flags); |
1561 | } | 1572 | } |
1562 | 1573 | ||
1563 | return 0; | 1574 | return 0; |