omap: GPIO: Fix OMAP4 GPIO reg access issues
authorCharulatha V <charu@ti.com>
Fri, 14 May 2010 19:05:27 +0000 (12:05 -0700)
committerTony Lindgren <tony@atomide.com>
Thu, 20 May 2010 18:17:51 +0000 (11:17 -0700)
Access to some of the OMAP4 GPIO registers are not properly handled.
This patch fixes it.

This patch is tested on 3430SDP and 4430SDP boards

Signed-off-by: Charulatha V <charu@ti.com>
Acked-by: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/plat-omap/gpio.c

index 955597fd6d3524081b75d76e947c5c0bcc40caeb..dc2ac42d63195f0dbe6c3b7acd964eef117e9661 100644 (file)
 #define OMAP4_GPIO_IRQSTATUSCLR1       0x0040
 #define OMAP4_GPIO_IRQWAKEN0           0x0044
 #define OMAP4_GPIO_IRQWAKEN1           0x0048
-#define OMAP4_GPIO_SYSSTATUS           0x0104
+#define OMAP4_GPIO_SYSSTATUS           0x0114
+#define OMAP4_GPIO_IRQENABLE1          0x011c
+#define OMAP4_GPIO_WAKE_EN             0x0120
+#define OMAP4_GPIO_IRQSTATUS2          0x0128
+#define OMAP4_GPIO_IRQENABLE2          0x012c
 #define OMAP4_GPIO_CTRL                        0x0130
 #define OMAP4_GPIO_OE                  0x0134
 #define OMAP4_GPIO_DATAIN              0x0138
 #define OMAP4_GPIO_FALLINGDETECT       0x014c
 #define OMAP4_GPIO_DEBOUNCENABLE       0x0150
 #define OMAP4_GPIO_DEBOUNCINGTIME      0x0154
+#define OMAP4_GPIO_CLEARIRQENABLE1     0x0160
+#define OMAP4_GPIO_SETIRQENABLE1       0x0164
+#define OMAP4_GPIO_CLEARWKUENA         0x0180
+#define OMAP4_GPIO_SETWKUENA           0x0184
 #define OMAP4_GPIO_CLEARDATAOUT                0x0190
 #define OMAP4_GPIO_SETDATAOUT          0x0194
 /*
@@ -591,11 +599,15 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
                reg += OMAP7XX_GPIO_DATA_OUTPUT;
                break;
 #endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
        case METHOD_GPIO_24XX:
-       case METHOD_GPIO_44XX:
                reg += OMAP24XX_GPIO_DATAOUT;
                break;
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+       case METHOD_GPIO_44XX:
+               reg += OMAP4_GPIO_DATAOUT;
+               break;
 #endif
        default:
                return -EINVAL;
@@ -1213,11 +1225,17 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
 #endif
        if (!cpu_class_is_omap1()) {
                if (!bank->mod_usage) {
+                       void __iomem *reg = bank->base;
                        u32 ctrl;
-                       ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
-                       ctrl &= 0xFFFFFFFE;
+
+                       if (cpu_is_omap24xx() || cpu_is_omap34xx())
+                               reg += OMAP24XX_GPIO_CTRL;
+                       else if (cpu_is_omap44xx())
+                               reg += OMAP4_GPIO_CTRL;
+                       ctrl = __raw_readl(reg);
                        /* Module is enabled, clocks are not gated */
-                       __raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL);
+                       ctrl &= 0xFFFFFFFE;
+                       __raw_writel(ctrl, reg);
                }
                bank->mod_usage |= 1 << offset;
        }
@@ -1239,22 +1257,34 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
                __raw_writel(1 << offset, reg);
        }
 #endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
-       if ((bank->method == METHOD_GPIO_24XX) ||
-                       (bank->method == METHOD_GPIO_44XX)) {
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+       if (bank->method == METHOD_GPIO_24XX) {
                /* Disable wake-up during idle for dynamic tick */
                void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
                __raw_writel(1 << offset, reg);
        }
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+       if (bank->method == METHOD_GPIO_44XX) {
+               /* Disable wake-up during idle for dynamic tick */
+               void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0;
+               __raw_writel(1 << offset, reg);
+       }
 #endif
        if (!cpu_class_is_omap1()) {
                bank->mod_usage &= ~(1 << offset);
                if (!bank->mod_usage) {
+                       void __iomem *reg = bank->base;
                        u32 ctrl;
-                       ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
+
+                       if (cpu_is_omap24xx() || cpu_is_omap34xx())
+                               reg += OMAP24XX_GPIO_CTRL;
+                       else if (cpu_is_omap44xx())
+                               reg += OMAP4_GPIO_CTRL;
+                       ctrl = __raw_readl(reg);
                        /* Module is disabled, clocks are gated */
                        ctrl |= 1;
-                       __raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL);
+                       __raw_writel(ctrl, reg);
                }
        }
        _reset_gpio(bank, bank->chip.base + offset);
@@ -1583,9 +1613,14 @@ static int gpio_is_input(struct gpio_bank *bank, int mask)
                reg += OMAP7XX_GPIO_DIR_CONTROL;
                break;
        case METHOD_GPIO_24XX:
-       case METHOD_GPIO_44XX:
                reg += OMAP24XX_GPIO_OE;
                break;
+       case METHOD_GPIO_44XX:
+               reg += OMAP4_GPIO_OE;
+               break;
+       default:
+               WARN_ONCE(1, "gpio_is_input: incorrect OMAP GPIO method");
+               return -EINVAL;
        }
        return __raw_readl(reg) & mask;
 }