diff options
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 56f4d1394d56..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 | } |
@@ -1277,6 +1286,11 @@ static struct clk *gpio_fclks[OMAP34XX_NR_GPIOS]; | |||
1277 | static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS]; | 1286 | static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS]; |
1278 | #endif | 1287 | #endif |
1279 | 1288 | ||
1289 | /* This lock class tells lockdep that GPIO irqs are in a different | ||
1290 | * category than their parents, so it won't report false recursion. | ||
1291 | */ | ||
1292 | static struct lock_class_key gpio_lock_class; | ||
1293 | |||
1280 | static int __init _omap_gpio_init(void) | 1294 | static int __init _omap_gpio_init(void) |
1281 | { | 1295 | { |
1282 | int i; | 1296 | int i; |
@@ -1450,6 +1464,7 @@ static int __init _omap_gpio_init(void) | |||
1450 | #endif | 1464 | #endif |
1451 | for (j = bank->virtual_irq_start; | 1465 | for (j = bank->virtual_irq_start; |
1452 | j < bank->virtual_irq_start + gpio_count; j++) { | 1466 | j < bank->virtual_irq_start + gpio_count; j++) { |
1467 | lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class); | ||
1453 | set_irq_chip_data(j, bank); | 1468 | set_irq_chip_data(j, bank); |
1454 | if (bank_is_mpuio(bank)) | 1469 | if (bank_is_mpuio(bank)) |
1455 | set_irq_chip(j, &mpuio_irq_chip); | 1470 | set_irq_chip(j, &mpuio_irq_chip); |
@@ -1489,6 +1504,7 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) | |||
1489 | void __iomem *wake_status; | 1504 | void __iomem *wake_status; |
1490 | void __iomem *wake_clear; | 1505 | void __iomem *wake_clear; |
1491 | void __iomem *wake_set; | 1506 | void __iomem *wake_set; |
1507 | unsigned long flags; | ||
1492 | 1508 | ||
1493 | switch (bank->method) { | 1509 | switch (bank->method) { |
1494 | #ifdef CONFIG_ARCH_OMAP16XX | 1510 | #ifdef CONFIG_ARCH_OMAP16XX |
@@ -1509,11 +1525,11 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) | |||
1509 | continue; | 1525 | continue; |
1510 | } | 1526 | } |
1511 | 1527 | ||
1512 | spin_lock(&bank->lock); | 1528 | spin_lock_irqsave(&bank->lock, flags); |
1513 | bank->saved_wakeup = __raw_readl(wake_status); | 1529 | bank->saved_wakeup = __raw_readl(wake_status); |
1514 | __raw_writel(0xffffffff, wake_clear); | 1530 | __raw_writel(0xffffffff, wake_clear); |
1515 | __raw_writel(bank->suspend_wakeup, wake_set); | 1531 | __raw_writel(bank->suspend_wakeup, wake_set); |
1516 | spin_unlock(&bank->lock); | 1532 | spin_unlock_irqrestore(&bank->lock, flags); |
1517 | } | 1533 | } |
1518 | 1534 | ||
1519 | return 0; | 1535 | return 0; |
@@ -1530,6 +1546,7 @@ static int omap_gpio_resume(struct sys_device *dev) | |||
1530 | struct gpio_bank *bank = &gpio_bank[i]; | 1546 | struct gpio_bank *bank = &gpio_bank[i]; |
1531 | void __iomem *wake_clear; | 1547 | void __iomem *wake_clear; |
1532 | void __iomem *wake_set; | 1548 | void __iomem *wake_set; |
1549 | unsigned long flags; | ||
1533 | 1550 | ||
1534 | switch (bank->method) { | 1551 | switch (bank->method) { |
1535 | #ifdef CONFIG_ARCH_OMAP16XX | 1552 | #ifdef CONFIG_ARCH_OMAP16XX |
@@ -1548,10 +1565,10 @@ static int omap_gpio_resume(struct sys_device *dev) | |||
1548 | continue; | 1565 | continue; |
1549 | } | 1566 | } |
1550 | 1567 | ||
1551 | spin_lock(&bank->lock); | 1568 | spin_lock_irqsave(&bank->lock, flags); |
1552 | __raw_writel(0xffffffff, wake_clear); | 1569 | __raw_writel(0xffffffff, wake_clear); |
1553 | __raw_writel(bank->saved_wakeup, wake_set); | 1570 | __raw_writel(bank->saved_wakeup, wake_set); |
1554 | spin_unlock(&bank->lock); | 1571 | spin_unlock_irqrestore(&bank->lock, flags); |
1555 | } | 1572 | } |
1556 | 1573 | ||
1557 | return 0; | 1574 | return 0; |