help
          Select code specific to PXA27x variants
 
+config CPU_PXA26x
+       bool
+       select PXA25x
+       help
+         Select code specific to PXA26x (codename Dalhart)
+
 config PXA3xx
        bool
        help
 
 
 int pxa_last_gpio;
 
+#ifdef CONFIG_CPU_PXA26x
+/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted,
+ * as well as their Alternate Function value being '1' for GPIO in GAFRx.
+ */
+static int __gpio_is_inverted(unsigned gpio)
+{
+       return cpu_is_pxa25x() && gpio > 85;
+}
+#else
+#define __gpio_is_inverted(gpio)       (0)
+#endif
+
 /*
  * Configure pins for GPIO or other functions
  */
        gpdr = pxa->regbase + GPDR_OFFSET;
        local_irq_save(flags);
        value = __raw_readl(gpdr);
-       value &= ~mask;
+       if (__gpio_is_inverted(chip->base + offset))
+               value |= mask;
+       else
+               value &= ~mask;
        __raw_writel(value, gpdr);
        local_irq_restore(flags);
 
        gpdr = pxa->regbase + GPDR_OFFSET;
        local_irq_save(flags);
        tmp = __raw_readl(gpdr);
-       tmp |= mask;
+       if (__gpio_is_inverted(chip->base + offset))
+               tmp &= ~mask;
+       else
+               tmp |= mask;
        __raw_writel(tmp, gpdr);
        local_irq_restore(flags);
 
  */
 static int __gpio_is_occupied(unsigned gpio)
 {
-       if (cpu_is_pxa25x() || cpu_is_pxa27x())
-               return GAFR(gpio) & (0x3 << (((gpio) & 0xf) * 2));
-       else
-               return 0;
+       if (cpu_is_pxa27x() || cpu_is_pxa25x()) {
+               int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3;
+               int dir = GPDR(gpio) & GPIO_bit(gpio);
+
+               if (__gpio_is_inverted(gpio))
+                       return af != 1 || dir == 0;
+               else
+                       return af != 0 || dir != 0;
+       }
+
+       return 0;
 }
 
 static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
                /* Don't mess with enabled GPIOs using preconfigured edges or
                 * GPIOs set to alternate function or to output during probe
                 */
-               if ((GPIO_IRQ_rising_edge[idx] |
-                    GPIO_IRQ_falling_edge[idx] |
-                    GPDR(gpio)) & GPIO_bit(gpio))
+               if ((GPIO_IRQ_rising_edge[idx] & GPIO_bit(gpio)) ||
+                   (GPIO_IRQ_falling_edge[idx] & GPIO_bit(gpio)))
                        return 0;
 
                if (__gpio_is_occupied(gpio))
                type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
        }
 
-       GPDR(gpio) &= ~GPIO_bit(gpio);
+       if (__gpio_is_inverted(gpio))
+               GPDR(gpio) |= GPIO_bit(gpio);
+       else
+               GPDR(gpio) &= ~GPIO_bit(gpio);
 
        if (type & IRQ_TYPE_EDGE_RISING)
                __set_bit(gpio, GPIO_IRQ_rising_edge);
 
 #define GPIO76_LCD_PCLK                MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
 #define GPIO77_LCD_BIAS                MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
 
+#ifdef CONFIG_CPU_PXA26x
+/* GPIO */
+#define GPIO85_GPIO            MFP_CFG_IN(GPIO85, AF0)
+#define GPIO86_GPIO            MFP_CFG_IN(GPIO86, AF1)
+#define GPIO87_GPIO            MFP_CFG_IN(GPIO87, AF1)
+#define GPIO88_GPIO            MFP_CFG_IN(GPIO88, AF1)
+#define GPIO89_GPIO            MFP_CFG_IN(GPIO89, AF1)
+
+/* SDRAM */
+#define GPIO86_nSDCS2          MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH)
+#define GPIO87_nSDCS3          MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH)
+#define GPIO88_RDnWR           MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH)
+#define GPIO89_nACRESET                MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
+
+/* USB */
+#define GPIO9_USB_RCV          MFP_CFG_IN(GPIO9, AF1)
+#define GPIO32_USB_VP          MFP_CFG_IN(GPIO32, AF2)
+#define GPIO34_USB_VM          MFP_CFG_IN(GPIO34, AF2)
+#define GPIO39_USB_VPO         MFP_CFG_OUT(GPIO39, AF3, DRIVE_LOW)
+#define GPIO56_USB_VMO         MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
+#define GPIO57_USB_nOE         MFP_CFG_OUT(GPIO57, AF1, DRIVE_HIGH)
+
+/* ASSP */
+#define GPIO28_ASSP_BITCLK_IN  MFP_CFG_IN(GPIO28, AF3)
+#define GPIO28_ASSP_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF3, DRIVE_LOW)
+#define GPIO29_ASSP_RXD                MFP_CFG_IN(GPIO29, AF3)
+#define GPIO30_ASSP_TXD                MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
+#define GPIO31_ASSP_SFRM_IN    MFP_CFG_IN(GPIO31, AF1)
+#define GPIO31_ASSP_SFRM_OUT   MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
+#endif
+
 #endif /* __ASM_ARCH_MFP_PXA25X_H */
 
        unsigned        valid           : 1;
        unsigned        can_wakeup      : 1;
        unsigned        keypad_gpio     : 1;
+       unsigned        dir_inverted    : 1;
        unsigned int    mask; /* bit mask in PWER or PKWR */
        unsigned int    mux_mask; /* bit mask of muxed gpio bits, 0 if no mux */
        unsigned long   config;
        int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */
        int shft = (gpio & 0xf) << 1;
        int fn = MFP_AF(c);
-       int dir = c & MFP_DIR_OUT;
+       int is_out = (c & MFP_DIR_OUT) ? 1 : 0;
 
        if (fn > 3)
                return -EINVAL;
        else
                GAFR_U(bank) = gafr;
 
-       if (dir == MFP_DIR_OUT)
+       if (is_out ^ gpio_desc[gpio].dir_inverted)
                GPDR(gpio) |= mask;
        else
                GPDR(gpio) &= ~mask;
        switch (c & MFP_LPM_STATE_MASK) {
        case MFP_LPM_DRIVE_HIGH:
                PGSR(bank) |= mask;
-               dir = MFP_DIR_OUT;
+               is_out = 1;
                break;
        case MFP_LPM_DRIVE_LOW:
                PGSR(bank) &= ~mask;
-               dir = MFP_DIR_OUT;
+               is_out = 1;
                break;
        case MFP_LPM_DEFAULT:
                break;
                break;
        }
 
-       if (dir == MFP_DIR_OUT)
+       if (is_out ^ gpio_desc[gpio].dir_inverted)
                gpdr_lpm[bank] |= mask;
        else
                gpdr_lpm[bank] &= ~mask;
                return -EINVAL;
        }
 
-       if ((c & MFP_LPM_CAN_WAKEUP) && (dir == MFP_DIR_OUT)) {
+       if ((c & MFP_LPM_CAN_WAKEUP) && is_out) {
                pr_warning("%s: output GPIO%d unable to wakeup\n",
                                __func__, gpio);
                return -EINVAL;
                gpio_desc[i].can_wakeup = 1;
                gpio_desc[i].mask = GPIO_bit(i);
        }
+
+       /* PXA26x has additional 4 GPIOs (86/87/88/89) which has the
+        * direction bit inverted in GPDR2. See PXA26x DM 4.1.1.
+        */
+       for (i = 86; i <= pxa_last_gpio; i++)
+               gpio_desc[i].dir_inverted = 1;
 }
 #else
 static inline void pxa25x_mfp_init(void) {}
 
        pxa_init_gpio(85, pxa25x_set_wake);
 }
 
+#ifdef CONFIG_CPU_PXA26x
+void __init pxa26x_init_irq(void)
+{
+       pxa_init_irq(32, pxa25x_set_wake);
+       pxa_init_gpio(90, pxa25x_set_wake);
+}
+#endif
+
 static struct platform_device *pxa25x_devices[] __initdata = {
        &pxa25x_device_udc,
        &pxa_device_ffuart,