diff options
| -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; |
