diff options
author | Roger Quadros <ext-roger.quadros@nokia.com> | 2009-08-05 09:53:24 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2009-08-05 09:53:24 -0400 |
commit | b37c45b8c27c049dc44673e40fd63820fd9a9d91 (patch) | |
tree | fe3a31bc5e61e7c9d13d64c1c3ec0c7eea9bb5d7 /arch/arm/plat-omap | |
parent | ed680c4ad478d0fee9740f7d029087f181346564 (diff) |
OMAP: GPIO: Fix incorrect gpio_get logic for output GPIOs
gpio_get() should return DATAIN register value when the GPIO
is configured as input whereas it should return DATAOUT register
value when the GPIO is configured as output.
Now /sys/kernel/debug/gpio shows proper values for output GPIOs
Signed-off-by: Roger Quadros <ext-roger.quadros@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 121 |
1 files changed, 89 insertions, 32 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 26b387c12423..9c16ca8d293c 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -476,14 +476,12 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) | |||
476 | __raw_writel(l, reg); | 476 | __raw_writel(l, reg); |
477 | } | 477 | } |
478 | 478 | ||
479 | static int __omap_get_gpio_datain(int gpio) | 479 | static int _get_gpio_datain(struct gpio_bank *bank, int gpio) |
480 | { | 480 | { |
481 | struct gpio_bank *bank; | ||
482 | void __iomem *reg; | 481 | void __iomem *reg; |
483 | 482 | ||
484 | if (check_gpio(gpio) < 0) | 483 | if (check_gpio(gpio) < 0) |
485 | return -EINVAL; | 484 | return -EINVAL; |
486 | bank = get_gpio_bank(gpio); | ||
487 | reg = bank->base; | 485 | reg = bank->base; |
488 | switch (bank->method) { | 486 | switch (bank->method) { |
489 | #ifdef CONFIG_ARCH_OMAP1 | 487 | #ifdef CONFIG_ARCH_OMAP1 |
@@ -524,6 +522,53 @@ static int __omap_get_gpio_datain(int gpio) | |||
524 | & (1 << get_gpio_index(gpio))) != 0; | 522 | & (1 << get_gpio_index(gpio))) != 0; |
525 | } | 523 | } |
526 | 524 | ||
525 | static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) | ||
526 | { | ||
527 | void __iomem *reg; | ||
528 | |||
529 | if (check_gpio(gpio) < 0) | ||
530 | return -EINVAL; | ||
531 | reg = bank->base; | ||
532 | |||
533 | switch (bank->method) { | ||
534 | #ifdef CONFIG_ARCH_OMAP1 | ||
535 | case METHOD_MPUIO: | ||
536 | reg += OMAP_MPUIO_OUTPUT; | ||
537 | break; | ||
538 | #endif | ||
539 | #ifdef CONFIG_ARCH_OMAP15XX | ||
540 | case METHOD_GPIO_1510: | ||
541 | reg += OMAP1510_GPIO_DATA_OUTPUT; | ||
542 | break; | ||
543 | #endif | ||
544 | #ifdef CONFIG_ARCH_OMAP16XX | ||
545 | case METHOD_GPIO_1610: | ||
546 | reg += OMAP1610_GPIO_DATAOUT; | ||
547 | break; | ||
548 | #endif | ||
549 | #ifdef CONFIG_ARCH_OMAP730 | ||
550 | case METHOD_GPIO_730: | ||
551 | reg += OMAP730_GPIO_DATA_OUTPUT; | ||
552 | break; | ||
553 | #endif | ||
554 | #ifdef CONFIG_ARCH_OMAP850 | ||
555 | case METHOD_GPIO_850: | ||
556 | reg += OMAP850_GPIO_DATA_OUTPUT; | ||
557 | break; | ||
558 | #endif | ||
559 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | ||
560 | defined(CONFIG_ARCH_OMAP4) | ||
561 | case METHOD_GPIO_24XX: | ||
562 | reg += OMAP24XX_GPIO_DATAOUT; | ||
563 | break; | ||
564 | #endif | ||
565 | default: | ||
566 | return -EINVAL; | ||
567 | } | ||
568 | |||
569 | return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; | ||
570 | } | ||
571 | |||
527 | #define MOD_REG_BIT(reg, bit_mask, set) \ | 572 | #define MOD_REG_BIT(reg, bit_mask, set) \ |
528 | do { \ | 573 | do { \ |
529 | int l = __raw_readl(base + reg); \ | 574 | int l = __raw_readl(base + reg); \ |
@@ -1350,9 +1395,49 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset) | |||
1350 | return 0; | 1395 | return 0; |
1351 | } | 1396 | } |
1352 | 1397 | ||
1398 | static int gpio_is_input(struct gpio_bank *bank, int mask) | ||
1399 | { | ||
1400 | void __iomem *reg = bank->base; | ||
1401 | |||
1402 | switch (bank->method) { | ||
1403 | case METHOD_MPUIO: | ||
1404 | reg += OMAP_MPUIO_IO_CNTL; | ||
1405 | break; | ||
1406 | case METHOD_GPIO_1510: | ||
1407 | reg += OMAP1510_GPIO_DIR_CONTROL; | ||
1408 | break; | ||
1409 | case METHOD_GPIO_1610: | ||
1410 | reg += OMAP1610_GPIO_DIRECTION; | ||
1411 | break; | ||
1412 | case METHOD_GPIO_730: | ||
1413 | reg += OMAP730_GPIO_DIR_CONTROL; | ||
1414 | break; | ||
1415 | case METHOD_GPIO_850: | ||
1416 | reg += OMAP850_GPIO_DIR_CONTROL; | ||
1417 | break; | ||
1418 | case METHOD_GPIO_24XX: | ||
1419 | reg += OMAP24XX_GPIO_OE; | ||
1420 | break; | ||
1421 | } | ||
1422 | return __raw_readl(reg) & mask; | ||
1423 | } | ||
1424 | |||
1353 | static int gpio_get(struct gpio_chip *chip, unsigned offset) | 1425 | static int gpio_get(struct gpio_chip *chip, unsigned offset) |
1354 | { | 1426 | { |
1355 | return __omap_get_gpio_datain(chip->base + offset); | 1427 | struct gpio_bank *bank; |
1428 | void __iomem *reg; | ||
1429 | int gpio; | ||
1430 | u32 mask; | ||
1431 | |||
1432 | gpio = chip->base + offset; | ||
1433 | bank = get_gpio_bank(gpio); | ||
1434 | reg = bank->base; | ||
1435 | mask = 1 << get_gpio_index(gpio); | ||
1436 | |||
1437 | if (gpio_is_input(bank, mask)) | ||
1438 | return _get_gpio_datain(bank, gpio); | ||
1439 | else | ||
1440 | return _get_gpio_dataout(bank, gpio); | ||
1356 | } | 1441 | } |
1357 | 1442 | ||
1358 | static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) | 1443 | static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) |
@@ -1886,34 +1971,6 @@ arch_initcall(omap_gpio_sysinit); | |||
1886 | #include <linux/debugfs.h> | 1971 | #include <linux/debugfs.h> |
1887 | #include <linux/seq_file.h> | 1972 | #include <linux/seq_file.h> |
1888 | 1973 | ||
1889 | static int gpio_is_input(struct gpio_bank *bank, int mask) | ||
1890 | { | ||
1891 | void __iomem *reg = bank->base; | ||
1892 | |||
1893 | switch (bank->method) { | ||
1894 | case METHOD_MPUIO: | ||
1895 | reg += OMAP_MPUIO_IO_CNTL; | ||
1896 | break; | ||
1897 | case METHOD_GPIO_1510: | ||
1898 | reg += OMAP1510_GPIO_DIR_CONTROL; | ||
1899 | break; | ||
1900 | case METHOD_GPIO_1610: | ||
1901 | reg += OMAP1610_GPIO_DIRECTION; | ||
1902 | break; | ||
1903 | case METHOD_GPIO_730: | ||
1904 | reg += OMAP730_GPIO_DIR_CONTROL; | ||
1905 | break; | ||
1906 | case METHOD_GPIO_850: | ||
1907 | reg += OMAP850_GPIO_DIR_CONTROL; | ||
1908 | break; | ||
1909 | case METHOD_GPIO_24XX: | ||
1910 | reg += OMAP24XX_GPIO_OE; | ||
1911 | break; | ||
1912 | } | ||
1913 | return __raw_readl(reg) & mask; | ||
1914 | } | ||
1915 | |||
1916 | |||
1917 | static int dbg_gpio_show(struct seq_file *s, void *unused) | 1974 | static int dbg_gpio_show(struct seq_file *s, void *unused) |
1918 | { | 1975 | { |
1919 | unsigned i, j, gpio; | 1976 | unsigned i, j, gpio; |