diff options
Diffstat (limited to 'arch/arm/plat-omap/gpio.c')
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 127 |
1 files changed, 50 insertions, 77 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 424049d83fbe..07b6968a7d16 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -152,6 +152,7 @@ struct gpio_bank { | |||
152 | u32 level_mask; | 152 | u32 level_mask; |
153 | spinlock_t lock; | 153 | spinlock_t lock; |
154 | struct gpio_chip chip; | 154 | struct gpio_chip chip; |
155 | struct clk *dbck; | ||
155 | }; | 156 | }; |
156 | 157 | ||
157 | #define METHOD_MPUIO 0 | 158 | #define METHOD_MPUIO 0 |
@@ -244,6 +245,8 @@ static inline struct gpio_bank *get_gpio_bank(int gpio) | |||
244 | return &gpio_bank[gpio >> 5]; | 245 | return &gpio_bank[gpio >> 5]; |
245 | if (cpu_is_omap34xx()) | 246 | if (cpu_is_omap34xx()) |
246 | return &gpio_bank[gpio >> 5]; | 247 | return &gpio_bank[gpio >> 5]; |
248 | BUG(); | ||
249 | return NULL; | ||
247 | } | 250 | } |
248 | 251 | ||
249 | static inline int get_gpio_index(int gpio) | 252 | static inline int get_gpio_index(int gpio) |
@@ -332,19 +335,6 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) | |||
332 | __raw_writel(l, reg); | 335 | __raw_writel(l, reg); |
333 | } | 336 | } |
334 | 337 | ||
335 | void omap_set_gpio_direction(int gpio, int is_input) | ||
336 | { | ||
337 | struct gpio_bank *bank; | ||
338 | unsigned long flags; | ||
339 | |||
340 | if (check_gpio(gpio) < 0) | ||
341 | return; | ||
342 | bank = get_gpio_bank(gpio); | ||
343 | spin_lock_irqsave(&bank->lock, flags); | ||
344 | _set_gpio_direction(bank, get_gpio_index(gpio), is_input); | ||
345 | spin_unlock_irqrestore(&bank->lock, flags); | ||
346 | } | ||
347 | |||
348 | static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) | 338 | static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) |
349 | { | 339 | { |
350 | void __iomem *reg = bank->base; | 340 | void __iomem *reg = bank->base; |
@@ -406,20 +396,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) | |||
406 | __raw_writel(l, reg); | 396 | __raw_writel(l, reg); |
407 | } | 397 | } |
408 | 398 | ||
409 | void omap_set_gpio_dataout(int gpio, int enable) | 399 | static int __omap_get_gpio_datain(int gpio) |
410 | { | ||
411 | struct gpio_bank *bank; | ||
412 | unsigned long flags; | ||
413 | |||
414 | if (check_gpio(gpio) < 0) | ||
415 | return; | ||
416 | bank = get_gpio_bank(gpio); | ||
417 | spin_lock_irqsave(&bank->lock, flags); | ||
418 | _set_gpio_dataout(bank, get_gpio_index(gpio), enable); | ||
419 | spin_unlock_irqrestore(&bank->lock, flags); | ||
420 | } | ||
421 | |||
422 | int omap_get_gpio_datain(int gpio) | ||
423 | { | 400 | { |
424 | struct gpio_bank *bank; | 401 | struct gpio_bank *bank; |
425 | void __iomem *reg; | 402 | void __iomem *reg; |
@@ -473,6 +450,7 @@ void omap_set_gpio_debounce(int gpio, int enable) | |||
473 | { | 450 | { |
474 | struct gpio_bank *bank; | 451 | struct gpio_bank *bank; |
475 | void __iomem *reg; | 452 | void __iomem *reg; |
453 | unsigned long flags; | ||
476 | u32 val, l = 1 << get_gpio_index(gpio); | 454 | u32 val, l = 1 << get_gpio_index(gpio); |
477 | 455 | ||
478 | if (cpu_class_is_omap1()) | 456 | if (cpu_class_is_omap1()) |
@@ -480,16 +458,28 @@ void omap_set_gpio_debounce(int gpio, int enable) | |||
480 | 458 | ||
481 | bank = get_gpio_bank(gpio); | 459 | bank = get_gpio_bank(gpio); |
482 | reg = bank->base; | 460 | reg = bank->base; |
483 | |||
484 | reg += OMAP24XX_GPIO_DEBOUNCE_EN; | 461 | reg += OMAP24XX_GPIO_DEBOUNCE_EN; |
462 | |||
463 | spin_lock_irqsave(&bank->lock, flags); | ||
485 | val = __raw_readl(reg); | 464 | val = __raw_readl(reg); |
486 | 465 | ||
487 | if (enable) | 466 | if (enable && !(val & l)) |
488 | val |= l; | 467 | val |= l; |
489 | else | 468 | else if (!enable && (val & l)) |
490 | val &= ~l; | 469 | val &= ~l; |
470 | else | ||
471 | goto done; | ||
472 | |||
473 | if (cpu_is_omap34xx()) { | ||
474 | if (enable) | ||
475 | clk_enable(bank->dbck); | ||
476 | else | ||
477 | clk_disable(bank->dbck); | ||
478 | } | ||
491 | 479 | ||
492 | __raw_writel(val, reg); | 480 | __raw_writel(val, reg); |
481 | done: | ||
482 | spin_unlock_irqrestore(&bank->lock, flags); | ||
493 | } | 483 | } |
494 | EXPORT_SYMBOL(omap_set_gpio_debounce); | 484 | EXPORT_SYMBOL(omap_set_gpio_debounce); |
495 | 485 | ||
@@ -906,26 +896,17 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable) | |||
906 | return retval; | 896 | return retval; |
907 | } | 897 | } |
908 | 898 | ||
909 | int omap_request_gpio(int gpio) | 899 | static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) |
910 | { | 900 | { |
911 | struct gpio_bank *bank; | 901 | struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); |
912 | unsigned long flags; | 902 | unsigned long flags; |
913 | int status; | ||
914 | |||
915 | if (check_gpio(gpio) < 0) | ||
916 | return -EINVAL; | ||
917 | 903 | ||
918 | status = gpio_request(gpio, NULL); | ||
919 | if (status < 0) | ||
920 | return status; | ||
921 | |||
922 | bank = get_gpio_bank(gpio); | ||
923 | spin_lock_irqsave(&bank->lock, flags); | 904 | spin_lock_irqsave(&bank->lock, flags); |
924 | 905 | ||
925 | /* Set trigger to none. You need to enable the desired trigger with | 906 | /* Set trigger to none. You need to enable the desired trigger with |
926 | * request_irq() or set_irq_type(). | 907 | * request_irq() or set_irq_type(). |
927 | */ | 908 | */ |
928 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); | 909 | _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); |
929 | 910 | ||
930 | #ifdef CONFIG_ARCH_OMAP15XX | 911 | #ifdef CONFIG_ARCH_OMAP15XX |
931 | if (bank->method == METHOD_GPIO_1510) { | 912 | if (bank->method == METHOD_GPIO_1510) { |
@@ -933,7 +914,7 @@ int omap_request_gpio(int gpio) | |||
933 | 914 | ||
934 | /* Claim the pin for MPU */ | 915 | /* Claim the pin for MPU */ |
935 | reg = bank->base + OMAP1510_GPIO_PIN_CONTROL; | 916 | reg = bank->base + OMAP1510_GPIO_PIN_CONTROL; |
936 | __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); | 917 | __raw_writel(__raw_readl(reg) | (1 << offset), reg); |
937 | } | 918 | } |
938 | #endif | 919 | #endif |
939 | spin_unlock_irqrestore(&bank->lock, flags); | 920 | spin_unlock_irqrestore(&bank->lock, flags); |
@@ -941,39 +922,28 @@ int omap_request_gpio(int gpio) | |||
941 | return 0; | 922 | return 0; |
942 | } | 923 | } |
943 | 924 | ||
944 | void omap_free_gpio(int gpio) | 925 | static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) |
945 | { | 926 | { |
946 | struct gpio_bank *bank; | 927 | struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); |
947 | unsigned long flags; | 928 | unsigned long flags; |
948 | 929 | ||
949 | if (check_gpio(gpio) < 0) | ||
950 | return; | ||
951 | bank = get_gpio_bank(gpio); | ||
952 | spin_lock_irqsave(&bank->lock, flags); | 930 | spin_lock_irqsave(&bank->lock, flags); |
953 | if (unlikely(!gpiochip_is_requested(&bank->chip, | ||
954 | get_gpio_index(gpio)))) { | ||
955 | spin_unlock_irqrestore(&bank->lock, flags); | ||
956 | printk(KERN_ERR "omap-gpio: GPIO %d wasn't reserved!\n", gpio); | ||
957 | dump_stack(); | ||
958 | return; | ||
959 | } | ||
960 | #ifdef CONFIG_ARCH_OMAP16XX | 931 | #ifdef CONFIG_ARCH_OMAP16XX |
961 | if (bank->method == METHOD_GPIO_1610) { | 932 | if (bank->method == METHOD_GPIO_1610) { |
962 | /* Disable wake-up during idle for dynamic tick */ | 933 | /* Disable wake-up during idle for dynamic tick */ |
963 | void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; | 934 | void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; |
964 | __raw_writel(1 << get_gpio_index(gpio), reg); | 935 | __raw_writel(1 << offset, reg); |
965 | } | 936 | } |
966 | #endif | 937 | #endif |
967 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 938 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
968 | if (bank->method == METHOD_GPIO_24XX) { | 939 | if (bank->method == METHOD_GPIO_24XX) { |
969 | /* Disable wake-up during idle for dynamic tick */ | 940 | /* Disable wake-up during idle for dynamic tick */ |
970 | void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; | 941 | void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; |
971 | __raw_writel(1 << get_gpio_index(gpio), reg); | 942 | __raw_writel(1 << offset, reg); |
972 | } | 943 | } |
973 | #endif | 944 | #endif |
974 | _reset_gpio(bank, gpio); | 945 | _reset_gpio(bank, bank->chip.base + offset); |
975 | spin_unlock_irqrestore(&bank->lock, flags); | 946 | spin_unlock_irqrestore(&bank->lock, flags); |
976 | gpio_free(gpio); | ||
977 | } | 947 | } |
978 | 948 | ||
979 | /* | 949 | /* |
@@ -1252,7 +1222,7 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset) | |||
1252 | 1222 | ||
1253 | static int gpio_get(struct gpio_chip *chip, unsigned offset) | 1223 | static int gpio_get(struct gpio_chip *chip, unsigned offset) |
1254 | { | 1224 | { |
1255 | return omap_get_gpio_datain(chip->base + offset); | 1225 | return __omap_get_gpio_datain(chip->base + offset); |
1256 | } | 1226 | } |
1257 | 1227 | ||
1258 | static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) | 1228 | static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) |
@@ -1279,6 +1249,14 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
1279 | spin_unlock_irqrestore(&bank->lock, flags); | 1249 | spin_unlock_irqrestore(&bank->lock, flags); |
1280 | } | 1250 | } |
1281 | 1251 | ||
1252 | static int gpio_2irq(struct gpio_chip *chip, unsigned offset) | ||
1253 | { | ||
1254 | struct gpio_bank *bank; | ||
1255 | |||
1256 | bank = container_of(chip, struct gpio_bank, chip); | ||
1257 | return bank->virtual_irq_start + offset; | ||
1258 | } | ||
1259 | |||
1282 | /*---------------------------------------------------------------------*/ | 1260 | /*---------------------------------------------------------------------*/ |
1283 | 1261 | ||
1284 | static int initialized; | 1262 | static int initialized; |
@@ -1296,7 +1274,6 @@ static struct clk * gpio5_fck; | |||
1296 | #endif | 1274 | #endif |
1297 | 1275 | ||
1298 | #if defined(CONFIG_ARCH_OMAP3) | 1276 | #if defined(CONFIG_ARCH_OMAP3) |
1299 | static struct clk *gpio_fclks[OMAP34XX_NR_GPIOS]; | ||
1300 | static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS]; | 1277 | static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS]; |
1301 | #endif | 1278 | #endif |
1302 | 1279 | ||
@@ -1310,9 +1287,7 @@ static int __init _omap_gpio_init(void) | |||
1310 | int i; | 1287 | int i; |
1311 | int gpio = 0; | 1288 | int gpio = 0; |
1312 | struct gpio_bank *bank; | 1289 | struct gpio_bank *bank; |
1313 | #if defined(CONFIG_ARCH_OMAP3) | ||
1314 | char clk_name[11]; | 1290 | char clk_name[11]; |
1315 | #endif | ||
1316 | 1291 | ||
1317 | initialized = 1; | 1292 | initialized = 1; |
1318 | 1293 | ||
@@ -1367,12 +1342,6 @@ static int __init _omap_gpio_init(void) | |||
1367 | printk(KERN_ERR "Could not get %s\n", clk_name); | 1342 | printk(KERN_ERR "Could not get %s\n", clk_name); |
1368 | else | 1343 | else |
1369 | clk_enable(gpio_iclks[i]); | 1344 | clk_enable(gpio_iclks[i]); |
1370 | sprintf(clk_name, "gpio%d_fck", i + 1); | ||
1371 | gpio_fclks[i] = clk_get(NULL, clk_name); | ||
1372 | if (IS_ERR(gpio_fclks[i])) | ||
1373 | printk(KERN_ERR "Could not get %s\n", clk_name); | ||
1374 | else | ||
1375 | clk_enable(gpio_fclks[i]); | ||
1376 | } | 1345 | } |
1377 | } | 1346 | } |
1378 | #endif | 1347 | #endif |
@@ -1479,10 +1448,13 @@ static int __init _omap_gpio_init(void) | |||
1479 | /* REVISIT eventually switch from OMAP-specific gpio structs | 1448 | /* REVISIT eventually switch from OMAP-specific gpio structs |
1480 | * over to the generic ones | 1449 | * over to the generic ones |
1481 | */ | 1450 | */ |
1451 | bank->chip.request = omap_gpio_request; | ||
1452 | bank->chip.free = omap_gpio_free; | ||
1482 | bank->chip.direction_input = gpio_input; | 1453 | bank->chip.direction_input = gpio_input; |
1483 | bank->chip.get = gpio_get; | 1454 | bank->chip.get = gpio_get; |
1484 | bank->chip.direction_output = gpio_output; | 1455 | bank->chip.direction_output = gpio_output; |
1485 | bank->chip.set = gpio_set; | 1456 | bank->chip.set = gpio_set; |
1457 | bank->chip.to_irq = gpio_2irq; | ||
1486 | if (bank_is_mpuio(bank)) { | 1458 | if (bank_is_mpuio(bank)) { |
1487 | bank->chip.label = "mpuio"; | 1459 | bank->chip.label = "mpuio"; |
1488 | #ifdef CONFIG_ARCH_OMAP16XX | 1460 | #ifdef CONFIG_ARCH_OMAP16XX |
@@ -1511,6 +1483,13 @@ static int __init _omap_gpio_init(void) | |||
1511 | } | 1483 | } |
1512 | set_irq_chained_handler(bank->irq, gpio_irq_handler); | 1484 | set_irq_chained_handler(bank->irq, gpio_irq_handler); |
1513 | set_irq_data(bank->irq, bank); | 1485 | set_irq_data(bank->irq, bank); |
1486 | |||
1487 | if (cpu_is_omap34xx()) { | ||
1488 | sprintf(clk_name, "gpio%d_dbck", i + 1); | ||
1489 | bank->dbck = clk_get(NULL, clk_name); | ||
1490 | if (IS_ERR(bank->dbck)) | ||
1491 | printk(KERN_ERR "Could not get %s\n", clk_name); | ||
1492 | } | ||
1514 | } | 1493 | } |
1515 | 1494 | ||
1516 | /* Enable system clock for GPIO module. | 1495 | /* Enable system clock for GPIO module. |
@@ -1739,12 +1718,6 @@ static int __init omap_gpio_sysinit(void) | |||
1739 | return ret; | 1718 | return ret; |
1740 | } | 1719 | } |
1741 | 1720 | ||
1742 | EXPORT_SYMBOL(omap_request_gpio); | ||
1743 | EXPORT_SYMBOL(omap_free_gpio); | ||
1744 | EXPORT_SYMBOL(omap_set_gpio_direction); | ||
1745 | EXPORT_SYMBOL(omap_set_gpio_dataout); | ||
1746 | EXPORT_SYMBOL(omap_get_gpio_datain); | ||
1747 | |||
1748 | arch_initcall(omap_gpio_sysinit); | 1721 | arch_initcall(omap_gpio_sysinit); |
1749 | 1722 | ||
1750 | 1723 | ||
@@ -1801,14 +1774,14 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) | |||
1801 | continue; | 1774 | continue; |
1802 | 1775 | ||
1803 | irq = bank->virtual_irq_start + j; | 1776 | irq = bank->virtual_irq_start + j; |
1804 | value = omap_get_gpio_datain(gpio); | 1777 | value = gpio_get_value(gpio); |
1805 | is_in = gpio_is_input(bank, mask); | 1778 | is_in = gpio_is_input(bank, mask); |
1806 | 1779 | ||
1807 | if (bank_is_mpuio(bank)) | 1780 | if (bank_is_mpuio(bank)) |
1808 | seq_printf(s, "MPUIO %2d ", j); | 1781 | seq_printf(s, "MPUIO %2d ", j); |
1809 | else | 1782 | else |
1810 | seq_printf(s, "GPIO %3d ", gpio); | 1783 | seq_printf(s, "GPIO %3d ", gpio); |
1811 | seq_printf(s, "(%10s): %s %s", | 1784 | seq_printf(s, "(%-20.20s): %s %s", |
1812 | label, | 1785 | label, |
1813 | is_in ? "in " : "out", | 1786 | is_in ? "in " : "out", |
1814 | value ? "hi" : "lo"); | 1787 | value ? "hi" : "lo"); |