aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-pxa/Kconfig6
-rw-r--r--arch/arm/mach-pxa/gpio.c47
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa25x.h31
-rw-r--r--arch/arm/mach-pxa/mfp-pxa2xx.c19
-rw-r--r--arch/arm/mach-pxa/pxa25x.c8
5 files changed, 95 insertions, 16 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index a062235e83a8..6c59f989a61a 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -394,6 +394,12 @@ config PXA27x
394 help 394 help
395 Select code specific to PXA27x variants 395 Select code specific to PXA27x variants
396 396
397config CPU_PXA26x
398 bool
399 select PXA25x
400 help
401 Select code specific to PXA26x (codename Dalhart)
402
397config PXA3xx 403config PXA3xx
398 bool 404 bool
399 help 405 help
diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c
index 14930cf8be7b..843144ff1f61 100644
--- a/arch/arm/mach-pxa/gpio.c
+++ b/arch/arm/mach-pxa/gpio.c
@@ -33,6 +33,18 @@ struct pxa_gpio_chip {
33 33
34int pxa_last_gpio; 34int pxa_last_gpio;
35 35
36#ifdef CONFIG_CPU_PXA26x
37/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted,
38 * as well as their Alternate Function value being '1' for GPIO in GAFRx.
39 */
40static int __gpio_is_inverted(unsigned gpio)
41{
42 return cpu_is_pxa25x() && gpio > 85;
43}
44#else
45#define __gpio_is_inverted(gpio) (0)
46#endif
47
36/* 48/*
37 * Configure pins for GPIO or other functions 49 * Configure pins for GPIO or other functions
38 */ 50 */
@@ -75,7 +87,10 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
75 gpdr = pxa->regbase + GPDR_OFFSET; 87 gpdr = pxa->regbase + GPDR_OFFSET;
76 local_irq_save(flags); 88 local_irq_save(flags);
77 value = __raw_readl(gpdr); 89 value = __raw_readl(gpdr);
78 value &= ~mask; 90 if (__gpio_is_inverted(chip->base + offset))
91 value |= mask;
92 else
93 value &= ~mask;
79 __raw_writel(value, gpdr); 94 __raw_writel(value, gpdr);
80 local_irq_restore(flags); 95 local_irq_restore(flags);
81 96
@@ -97,7 +112,10 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip,
97 gpdr = pxa->regbase + GPDR_OFFSET; 112 gpdr = pxa->regbase + GPDR_OFFSET;
98 local_irq_save(flags); 113 local_irq_save(flags);
99 tmp = __raw_readl(gpdr); 114 tmp = __raw_readl(gpdr);
100 tmp |= mask; 115 if (__gpio_is_inverted(chip->base + offset))
116 tmp &= ~mask;
117 else
118 tmp |= mask;
101 __raw_writel(tmp, gpdr); 119 __raw_writel(tmp, gpdr);
102 local_irq_restore(flags); 120 local_irq_restore(flags);
103 121
@@ -173,10 +191,17 @@ static unsigned long GPIO_IRQ_mask[4];
173 */ 191 */
174static int __gpio_is_occupied(unsigned gpio) 192static int __gpio_is_occupied(unsigned gpio)
175{ 193{
176 if (cpu_is_pxa25x() || cpu_is_pxa27x()) 194 if (cpu_is_pxa27x() || cpu_is_pxa25x()) {
177 return GAFR(gpio) & (0x3 << (((gpio) & 0xf) * 2)); 195 int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3;
178 else 196 int dir = GPDR(gpio) & GPIO_bit(gpio);
179 return 0; 197
198 if (__gpio_is_inverted(gpio))
199 return af != 1 || dir == 0;
200 else
201 return af != 0 || dir != 0;
202 }
203
204 return 0;
180} 205}
181 206
182static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) 207static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
@@ -190,9 +215,8 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
190 /* Don't mess with enabled GPIOs using preconfigured edges or 215 /* Don't mess with enabled GPIOs using preconfigured edges or
191 * GPIOs set to alternate function or to output during probe 216 * GPIOs set to alternate function or to output during probe
192 */ 217 */
193 if ((GPIO_IRQ_rising_edge[idx] | 218 if ((GPIO_IRQ_rising_edge[idx] & GPIO_bit(gpio)) ||
194 GPIO_IRQ_falling_edge[idx] | 219 (GPIO_IRQ_falling_edge[idx] & GPIO_bit(gpio)))
195 GPDR(gpio)) & GPIO_bit(gpio))
196 return 0; 220 return 0;
197 221
198 if (__gpio_is_occupied(gpio)) 222 if (__gpio_is_occupied(gpio))
@@ -201,7 +225,10 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
201 type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; 225 type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
202 } 226 }
203 227
204 GPDR(gpio) &= ~GPIO_bit(gpio); 228 if (__gpio_is_inverted(gpio))
229 GPDR(gpio) |= GPIO_bit(gpio);
230 else
231 GPDR(gpio) &= ~GPIO_bit(gpio);
205 232
206 if (type & IRQ_TYPE_EDGE_RISING) 233 if (type & IRQ_TYPE_EDGE_RISING)
207 __set_bit(gpio, GPIO_IRQ_rising_edge); 234 __set_bit(gpio, GPIO_IRQ_rising_edge);
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
index 617cab2cc8d0..a72869b73ee3 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
@@ -158,4 +158,35 @@
158#define GPIO76_LCD_PCLK MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW) 158#define GPIO76_LCD_PCLK MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
159#define GPIO77_LCD_BIAS MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW) 159#define GPIO77_LCD_BIAS MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
160 160
161#ifdef CONFIG_CPU_PXA26x
162/* GPIO */
163#define GPIO85_GPIO MFP_CFG_IN(GPIO85, AF0)
164#define GPIO86_GPIO MFP_CFG_IN(GPIO86, AF1)
165#define GPIO87_GPIO MFP_CFG_IN(GPIO87, AF1)
166#define GPIO88_GPIO MFP_CFG_IN(GPIO88, AF1)
167#define GPIO89_GPIO MFP_CFG_IN(GPIO89, AF1)
168
169/* SDRAM */
170#define GPIO86_nSDCS2 MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH)
171#define GPIO87_nSDCS3 MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH)
172#define GPIO88_RDnWR MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH)
173#define GPIO89_nACRESET MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
174
175/* USB */
176#define GPIO9_USB_RCV MFP_CFG_IN(GPIO9, AF1)
177#define GPIO32_USB_VP MFP_CFG_IN(GPIO32, AF2)
178#define GPIO34_USB_VM MFP_CFG_IN(GPIO34, AF2)
179#define GPIO39_USB_VPO MFP_CFG_OUT(GPIO39, AF3, DRIVE_LOW)
180#define GPIO56_USB_VMO MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
181#define GPIO57_USB_nOE MFP_CFG_OUT(GPIO57, AF1, DRIVE_HIGH)
182
183/* ASSP */
184#define GPIO28_ASSP_BITCLK_IN MFP_CFG_IN(GPIO28, AF3)
185#define GPIO28_ASSP_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF3, DRIVE_LOW)
186#define GPIO29_ASSP_RXD MFP_CFG_IN(GPIO29, AF3)
187#define GPIO30_ASSP_TXD MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
188#define GPIO31_ASSP_SFRM_IN MFP_CFG_IN(GPIO31, AF1)
189#define GPIO31_ASSP_SFRM_OUT MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
190#endif
191
161#endif /* __ASM_ARCH_MFP_PXA25X_H */ 192#endif /* __ASM_ARCH_MFP_PXA25X_H */
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index 1f2298759077..33626de8cbf6 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -38,6 +38,7 @@ struct gpio_desc {
38 unsigned valid : 1; 38 unsigned valid : 1;
39 unsigned can_wakeup : 1; 39 unsigned can_wakeup : 1;
40 unsigned keypad_gpio : 1; 40 unsigned keypad_gpio : 1;
41 unsigned dir_inverted : 1;
41 unsigned int mask; /* bit mask in PWER or PKWR */ 42 unsigned int mask; /* bit mask in PWER or PKWR */
42 unsigned int mux_mask; /* bit mask of muxed gpio bits, 0 if no mux */ 43 unsigned int mux_mask; /* bit mask of muxed gpio bits, 0 if no mux */
43 unsigned long config; 44 unsigned long config;
@@ -54,7 +55,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
54 int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */ 55 int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */
55 int shft = (gpio & 0xf) << 1; 56 int shft = (gpio & 0xf) << 1;
56 int fn = MFP_AF(c); 57 int fn = MFP_AF(c);
57 int dir = c & MFP_DIR_OUT; 58 int is_out = (c & MFP_DIR_OUT) ? 1 : 0;
58 59
59 if (fn > 3) 60 if (fn > 3)
60 return -EINVAL; 61 return -EINVAL;
@@ -68,7 +69,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
68 else 69 else
69 GAFR_U(bank) = gafr; 70 GAFR_U(bank) = gafr;
70 71
71 if (dir == MFP_DIR_OUT) 72 if (is_out ^ gpio_desc[gpio].dir_inverted)
72 GPDR(gpio) |= mask; 73 GPDR(gpio) |= mask;
73 else 74 else
74 GPDR(gpio) &= ~mask; 75 GPDR(gpio) &= ~mask;
@@ -77,11 +78,11 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
77 switch (c & MFP_LPM_STATE_MASK) { 78 switch (c & MFP_LPM_STATE_MASK) {
78 case MFP_LPM_DRIVE_HIGH: 79 case MFP_LPM_DRIVE_HIGH:
79 PGSR(bank) |= mask; 80 PGSR(bank) |= mask;
80 dir = MFP_DIR_OUT; 81 is_out = 1;
81 break; 82 break;
82 case MFP_LPM_DRIVE_LOW: 83 case MFP_LPM_DRIVE_LOW:
83 PGSR(bank) &= ~mask; 84 PGSR(bank) &= ~mask;
84 dir = MFP_DIR_OUT; 85 is_out = 1;
85 break; 86 break;
86 case MFP_LPM_DEFAULT: 87 case MFP_LPM_DEFAULT:
87 break; 88 break;
@@ -92,7 +93,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
92 break; 93 break;
93 } 94 }
94 95
95 if (dir == MFP_DIR_OUT) 96 if (is_out ^ gpio_desc[gpio].dir_inverted)
96 gpdr_lpm[bank] |= mask; 97 gpdr_lpm[bank] |= mask;
97 else 98 else
98 gpdr_lpm[bank] &= ~mask; 99 gpdr_lpm[bank] &= ~mask;
@@ -106,7 +107,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
106 return -EINVAL; 107 return -EINVAL;
107 } 108 }
108 109
109 if ((c & MFP_LPM_CAN_WAKEUP) && (dir == MFP_DIR_OUT)) { 110 if ((c & MFP_LPM_CAN_WAKEUP) && is_out) {
110 pr_warning("%s: output GPIO%d unable to wakeup\n", 111 pr_warning("%s: output GPIO%d unable to wakeup\n",
111 __func__, gpio); 112 __func__, gpio);
112 return -EINVAL; 113 return -EINVAL;
@@ -221,6 +222,12 @@ static void __init pxa25x_mfp_init(void)
221 gpio_desc[i].can_wakeup = 1; 222 gpio_desc[i].can_wakeup = 1;
222 gpio_desc[i].mask = GPIO_bit(i); 223 gpio_desc[i].mask = GPIO_bit(i);
223 } 224 }
225
226 /* PXA26x has additional 4 GPIOs (86/87/88/89) which has the
227 * direction bit inverted in GPDR2. See PXA26x DM 4.1.1.
228 */
229 for (i = 86; i <= pxa_last_gpio; i++)
230 gpio_desc[i].dir_inverted = 1;
224} 231}
225#else 232#else
226static inline void pxa25x_mfp_init(void) {} 233static inline void pxa25x_mfp_init(void) {}
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 6543321a2df4..0f672998b2eb 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -298,6 +298,14 @@ void __init pxa25x_init_irq(void)
298 pxa_init_gpio(85, pxa25x_set_wake); 298 pxa_init_gpio(85, pxa25x_set_wake);
299} 299}
300 300
301#ifdef CONFIG_CPU_PXA26x
302void __init pxa26x_init_irq(void)
303{
304 pxa_init_irq(32, pxa25x_set_wake);
305 pxa_init_gpio(90, pxa25x_set_wake);
306}
307#endif
308
301static struct platform_device *pxa25x_devices[] __initdata = { 309static struct platform_device *pxa25x_devices[] __initdata = {
302 &pxa25x_device_udc, 310 &pxa25x_device_udc,
303 &pxa_device_ffuart, 311 &pxa_device_ffuart,