1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * linux/arch/arm/mach-pxa/mfp-pxa2xx.c
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * PXA2xx pin mux configuration support
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * The GPIOs on PXA2xx can be configured as one of many alternate
8*4882a593Smuzhiyun * functions, this is by concept samilar to the MFP configuration
9*4882a593Smuzhiyun * on PXA3xx, what's more important, the low power pin state and
10*4882a593Smuzhiyun * wakeup detection are also supported by the same framework.
11*4882a593Smuzhiyun */
12*4882a593Smuzhiyun #include <linux/gpio.h>
13*4882a593Smuzhiyun #include <linux/gpio-pxa.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <linux/kernel.h>
16*4882a593Smuzhiyun #include <linux/init.h>
17*4882a593Smuzhiyun #include <linux/io.h>
18*4882a593Smuzhiyun #include <linux/syscore_ops.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #include <mach/pxa2xx-regs.h>
21*4882a593Smuzhiyun #include "mfp-pxa2xx.h"
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #include "generic.h"
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #define PGSR(x) __REG2(0x40F00020, (x) << 2)
26*4882a593Smuzhiyun #define __GAFR(u, x) __REG2((u) ? 0x40E00058 : 0x40E00054, (x) << 3)
27*4882a593Smuzhiyun #define GAFR_L(x) __GAFR(0, x)
28*4882a593Smuzhiyun #define GAFR_U(x) __GAFR(1, x)
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
31*4882a593Smuzhiyun #define GPLR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5))
32*4882a593Smuzhiyun #define GPDR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c)
33*4882a593Smuzhiyun #define GPSR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x18)
34*4882a593Smuzhiyun #define GPCR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x24)
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #define PWER_WE35 (1 << 24)
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun struct gpio_desc {
39*4882a593Smuzhiyun unsigned valid : 1;
40*4882a593Smuzhiyun unsigned can_wakeup : 1;
41*4882a593Smuzhiyun unsigned keypad_gpio : 1;
42*4882a593Smuzhiyun unsigned dir_inverted : 1;
43*4882a593Smuzhiyun unsigned int mask; /* bit mask in PWER or PKWR */
44*4882a593Smuzhiyun unsigned int mux_mask; /* bit mask of muxed gpio bits, 0 if no mux */
45*4882a593Smuzhiyun unsigned long config;
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1];
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun static unsigned long gpdr_lpm[4];
51*4882a593Smuzhiyun
__mfp_config_gpio(unsigned gpio,unsigned long c)52*4882a593Smuzhiyun static int __mfp_config_gpio(unsigned gpio, unsigned long c)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun unsigned long gafr, mask = GPIO_bit(gpio);
55*4882a593Smuzhiyun int bank = gpio_to_bank(gpio);
56*4882a593Smuzhiyun int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */
57*4882a593Smuzhiyun int shft = (gpio & 0xf) << 1;
58*4882a593Smuzhiyun int fn = MFP_AF(c);
59*4882a593Smuzhiyun int is_out = (c & MFP_DIR_OUT) ? 1 : 0;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun if (fn > 3)
62*4882a593Smuzhiyun return -EINVAL;
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /* alternate function and direction at run-time */
65*4882a593Smuzhiyun gafr = (uorl == 0) ? GAFR_L(bank) : GAFR_U(bank);
66*4882a593Smuzhiyun gafr = (gafr & ~(0x3 << shft)) | (fn << shft);
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun if (uorl == 0)
69*4882a593Smuzhiyun GAFR_L(bank) = gafr;
70*4882a593Smuzhiyun else
71*4882a593Smuzhiyun GAFR_U(bank) = gafr;
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun if (is_out ^ gpio_desc[gpio].dir_inverted)
74*4882a593Smuzhiyun GPDR(gpio) |= mask;
75*4882a593Smuzhiyun else
76*4882a593Smuzhiyun GPDR(gpio) &= ~mask;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun /* alternate function and direction at low power mode */
79*4882a593Smuzhiyun switch (c & MFP_LPM_STATE_MASK) {
80*4882a593Smuzhiyun case MFP_LPM_DRIVE_HIGH:
81*4882a593Smuzhiyun PGSR(bank) |= mask;
82*4882a593Smuzhiyun is_out = 1;
83*4882a593Smuzhiyun break;
84*4882a593Smuzhiyun case MFP_LPM_DRIVE_LOW:
85*4882a593Smuzhiyun PGSR(bank) &= ~mask;
86*4882a593Smuzhiyun is_out = 1;
87*4882a593Smuzhiyun break;
88*4882a593Smuzhiyun case MFP_LPM_INPUT:
89*4882a593Smuzhiyun case MFP_LPM_DEFAULT:
90*4882a593Smuzhiyun break;
91*4882a593Smuzhiyun default:
92*4882a593Smuzhiyun /* warning and fall through, treat as MFP_LPM_DEFAULT */
93*4882a593Smuzhiyun pr_warn("%s: GPIO%d: unsupported low power mode\n",
94*4882a593Smuzhiyun __func__, gpio);
95*4882a593Smuzhiyun break;
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun if (is_out ^ gpio_desc[gpio].dir_inverted)
99*4882a593Smuzhiyun gpdr_lpm[bank] |= mask;
100*4882a593Smuzhiyun else
101*4882a593Smuzhiyun gpdr_lpm[bank] &= ~mask;
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun /* give early warning if MFP_LPM_CAN_WAKEUP is set on the
104*4882a593Smuzhiyun * configurations of those pins not able to wakeup
105*4882a593Smuzhiyun */
106*4882a593Smuzhiyun if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) {
107*4882a593Smuzhiyun pr_warn("%s: GPIO%d unable to wakeup\n", __func__, gpio);
108*4882a593Smuzhiyun return -EINVAL;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun if ((c & MFP_LPM_CAN_WAKEUP) && is_out) {
112*4882a593Smuzhiyun pr_warn("%s: output GPIO%d unable to wakeup\n", __func__, gpio);
113*4882a593Smuzhiyun return -EINVAL;
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun return 0;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
__mfp_validate(int mfp)119*4882a593Smuzhiyun static inline int __mfp_validate(int mfp)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun int gpio = mfp_to_gpio(mfp);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) {
124*4882a593Smuzhiyun pr_warn("%s: GPIO%d is invalid pin\n", __func__, gpio);
125*4882a593Smuzhiyun return -1;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun return gpio;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
pxa2xx_mfp_config(unsigned long * mfp_cfgs,int num)131*4882a593Smuzhiyun void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun unsigned long flags;
134*4882a593Smuzhiyun unsigned long *c;
135*4882a593Smuzhiyun int i, gpio;
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun gpio = __mfp_validate(MFP_PIN(*c));
140*4882a593Smuzhiyun if (gpio < 0)
141*4882a593Smuzhiyun continue;
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun local_irq_save(flags);
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun gpio_desc[gpio].config = *c;
146*4882a593Smuzhiyun __mfp_config_gpio(gpio, *c);
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun local_irq_restore(flags);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun
pxa2xx_mfp_set_lpm(int mfp,unsigned long lpm)152*4882a593Smuzhiyun void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun unsigned long flags, c;
155*4882a593Smuzhiyun int gpio;
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun gpio = __mfp_validate(mfp);
158*4882a593Smuzhiyun if (gpio < 0)
159*4882a593Smuzhiyun return;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun local_irq_save(flags);
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun c = gpio_desc[gpio].config;
164*4882a593Smuzhiyun c = (c & ~MFP_LPM_STATE_MASK) | lpm;
165*4882a593Smuzhiyun __mfp_config_gpio(gpio, c);
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun local_irq_restore(flags);
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun
gpio_set_wake(unsigned int gpio,unsigned int on)170*4882a593Smuzhiyun int gpio_set_wake(unsigned int gpio, unsigned int on)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun struct gpio_desc *d;
173*4882a593Smuzhiyun unsigned long c, mux_taken;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun if (gpio > mfp_to_gpio(MFP_PIN_GPIO127))
176*4882a593Smuzhiyun return -EINVAL;
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun d = &gpio_desc[gpio];
179*4882a593Smuzhiyun c = d->config;
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun if (!d->valid)
182*4882a593Smuzhiyun return -EINVAL;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun /* Allow keypad GPIOs to wakeup system when
185*4882a593Smuzhiyun * configured as generic GPIOs.
186*4882a593Smuzhiyun */
187*4882a593Smuzhiyun if (d->keypad_gpio && (MFP_AF(d->config) == 0) &&
188*4882a593Smuzhiyun (d->config & MFP_LPM_CAN_WAKEUP)) {
189*4882a593Smuzhiyun if (on)
190*4882a593Smuzhiyun PKWR |= d->mask;
191*4882a593Smuzhiyun else
192*4882a593Smuzhiyun PKWR &= ~d->mask;
193*4882a593Smuzhiyun return 0;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun mux_taken = (PWER & d->mux_mask) & (~d->mask);
197*4882a593Smuzhiyun if (on && mux_taken)
198*4882a593Smuzhiyun return -EBUSY;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun if (d->can_wakeup && (c & MFP_LPM_CAN_WAKEUP)) {
201*4882a593Smuzhiyun if (on) {
202*4882a593Smuzhiyun PWER = (PWER & ~d->mux_mask) | d->mask;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun if (c & MFP_LPM_EDGE_RISE)
205*4882a593Smuzhiyun PRER |= d->mask;
206*4882a593Smuzhiyun else
207*4882a593Smuzhiyun PRER &= ~d->mask;
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun if (c & MFP_LPM_EDGE_FALL)
210*4882a593Smuzhiyun PFER |= d->mask;
211*4882a593Smuzhiyun else
212*4882a593Smuzhiyun PFER &= ~d->mask;
213*4882a593Smuzhiyun } else {
214*4882a593Smuzhiyun PWER &= ~d->mask;
215*4882a593Smuzhiyun PRER &= ~d->mask;
216*4882a593Smuzhiyun PFER &= ~d->mask;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun return 0;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun #ifdef CONFIG_PXA25x
pxa25x_mfp_init(void)223*4882a593Smuzhiyun static void __init pxa25x_mfp_init(void)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun int i;
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun /* running before pxa_gpio_probe() */
228*4882a593Smuzhiyun #ifdef CONFIG_CPU_PXA26x
229*4882a593Smuzhiyun pxa_last_gpio = 89;
230*4882a593Smuzhiyun #else
231*4882a593Smuzhiyun pxa_last_gpio = 84;
232*4882a593Smuzhiyun #endif
233*4882a593Smuzhiyun for (i = 0; i <= pxa_last_gpio; i++)
234*4882a593Smuzhiyun gpio_desc[i].valid = 1;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun for (i = 0; i <= 15; i++) {
237*4882a593Smuzhiyun gpio_desc[i].can_wakeup = 1;
238*4882a593Smuzhiyun gpio_desc[i].mask = GPIO_bit(i);
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun /* PXA26x has additional 4 GPIOs (86/87/88/89) which has the
242*4882a593Smuzhiyun * direction bit inverted in GPDR2. See PXA26x DM 4.1.1.
243*4882a593Smuzhiyun */
244*4882a593Smuzhiyun for (i = 86; i <= pxa_last_gpio; i++)
245*4882a593Smuzhiyun gpio_desc[i].dir_inverted = 1;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun #else
pxa25x_mfp_init(void)248*4882a593Smuzhiyun static inline void pxa25x_mfp_init(void) {}
249*4882a593Smuzhiyun #endif /* CONFIG_PXA25x */
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun #ifdef CONFIG_PXA27x
252*4882a593Smuzhiyun static int pxa27x_pkwr_gpio[] = {
253*4882a593Smuzhiyun 13, 16, 17, 34, 36, 37, 38, 39, 90, 91, 93, 94,
254*4882a593Smuzhiyun 95, 96, 97, 98, 99, 100, 101, 102
255*4882a593Smuzhiyun };
256*4882a593Smuzhiyun
keypad_set_wake(unsigned int on)257*4882a593Smuzhiyun int keypad_set_wake(unsigned int on)
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun unsigned int i, gpio, mask = 0;
260*4882a593Smuzhiyun struct gpio_desc *d;
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun gpio = pxa27x_pkwr_gpio[i];
265*4882a593Smuzhiyun d = &gpio_desc[gpio];
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun /* skip if configured as generic GPIO */
268*4882a593Smuzhiyun if (MFP_AF(d->config) == 0)
269*4882a593Smuzhiyun continue;
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun if (d->config & MFP_LPM_CAN_WAKEUP)
272*4882a593Smuzhiyun mask |= gpio_desc[gpio].mask;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun if (on)
276*4882a593Smuzhiyun PKWR |= mask;
277*4882a593Smuzhiyun else
278*4882a593Smuzhiyun PKWR &= ~mask;
279*4882a593Smuzhiyun return 0;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun #define PWER_WEMUX2_GPIO38 (1 << 16)
283*4882a593Smuzhiyun #define PWER_WEMUX2_GPIO53 (2 << 16)
284*4882a593Smuzhiyun #define PWER_WEMUX2_GPIO40 (3 << 16)
285*4882a593Smuzhiyun #define PWER_WEMUX2_GPIO36 (4 << 16)
286*4882a593Smuzhiyun #define PWER_WEMUX2_MASK (7 << 16)
287*4882a593Smuzhiyun #define PWER_WEMUX3_GPIO31 (1 << 19)
288*4882a593Smuzhiyun #define PWER_WEMUX3_GPIO113 (2 << 19)
289*4882a593Smuzhiyun #define PWER_WEMUX3_MASK (3 << 19)
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun #define INIT_GPIO_DESC_MUXED(mux, gpio) \
292*4882a593Smuzhiyun do { \
293*4882a593Smuzhiyun gpio_desc[(gpio)].can_wakeup = 1; \
294*4882a593Smuzhiyun gpio_desc[(gpio)].mask = PWER_ ## mux ## _GPIO ##gpio; \
295*4882a593Smuzhiyun gpio_desc[(gpio)].mux_mask = PWER_ ## mux ## _MASK; \
296*4882a593Smuzhiyun } while (0)
297*4882a593Smuzhiyun
pxa27x_mfp_init(void)298*4882a593Smuzhiyun static void __init pxa27x_mfp_init(void)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun int i, gpio;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun pxa_last_gpio = 120; /* running before pxa_gpio_probe() */
303*4882a593Smuzhiyun for (i = 0; i <= pxa_last_gpio; i++) {
304*4882a593Smuzhiyun /* skip GPIO2, 5, 6, 7, 8, they are not
305*4882a593Smuzhiyun * valid pins allow configuration
306*4882a593Smuzhiyun */
307*4882a593Smuzhiyun if (i == 2 || i == 5 || i == 6 || i == 7 || i == 8)
308*4882a593Smuzhiyun continue;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun gpio_desc[i].valid = 1;
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun /* Keypad GPIOs */
314*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
315*4882a593Smuzhiyun gpio = pxa27x_pkwr_gpio[i];
316*4882a593Smuzhiyun gpio_desc[gpio].can_wakeup = 1;
317*4882a593Smuzhiyun gpio_desc[gpio].keypad_gpio = 1;
318*4882a593Smuzhiyun gpio_desc[gpio].mask = 1 << i;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun /* Overwrite GPIO13 as a PWER wakeup source */
322*4882a593Smuzhiyun for (i = 0; i <= 15; i++) {
323*4882a593Smuzhiyun /* skip GPIO2, 5, 6, 7, 8 */
324*4882a593Smuzhiyun if (GPIO_bit(i) & 0x1e4)
325*4882a593Smuzhiyun continue;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun gpio_desc[i].can_wakeup = 1;
328*4882a593Smuzhiyun gpio_desc[i].mask = GPIO_bit(i);
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun gpio_desc[35].can_wakeup = 1;
332*4882a593Smuzhiyun gpio_desc[35].mask = PWER_WE35;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun INIT_GPIO_DESC_MUXED(WEMUX3, 31);
335*4882a593Smuzhiyun INIT_GPIO_DESC_MUXED(WEMUX3, 113);
336*4882a593Smuzhiyun INIT_GPIO_DESC_MUXED(WEMUX2, 38);
337*4882a593Smuzhiyun INIT_GPIO_DESC_MUXED(WEMUX2, 53);
338*4882a593Smuzhiyun INIT_GPIO_DESC_MUXED(WEMUX2, 40);
339*4882a593Smuzhiyun INIT_GPIO_DESC_MUXED(WEMUX2, 36);
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun #else
pxa27x_mfp_init(void)342*4882a593Smuzhiyun static inline void pxa27x_mfp_init(void) {}
343*4882a593Smuzhiyun #endif /* CONFIG_PXA27x */
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun #ifdef CONFIG_PM
346*4882a593Smuzhiyun static unsigned long saved_gafr[2][4];
347*4882a593Smuzhiyun static unsigned long saved_gpdr[4];
348*4882a593Smuzhiyun static unsigned long saved_gplr[4];
349*4882a593Smuzhiyun static unsigned long saved_pgsr[4];
350*4882a593Smuzhiyun
pxa2xx_mfp_suspend(void)351*4882a593Smuzhiyun static int pxa2xx_mfp_suspend(void)
352*4882a593Smuzhiyun {
353*4882a593Smuzhiyun int i;
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun /* set corresponding PGSR bit of those marked MFP_LPM_KEEP_OUTPUT */
356*4882a593Smuzhiyun for (i = 0; i < pxa_last_gpio; i++) {
357*4882a593Smuzhiyun if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
358*4882a593Smuzhiyun (GPDR(i) & GPIO_bit(i))) {
359*4882a593Smuzhiyun if (GPLR(i) & GPIO_bit(i))
360*4882a593Smuzhiyun PGSR(gpio_to_bank(i)) |= GPIO_bit(i);
361*4882a593Smuzhiyun else
362*4882a593Smuzhiyun PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
367*4882a593Smuzhiyun saved_gafr[0][i] = GAFR_L(i);
368*4882a593Smuzhiyun saved_gafr[1][i] = GAFR_U(i);
369*4882a593Smuzhiyun saved_gpdr[i] = GPDR(i * 32);
370*4882a593Smuzhiyun saved_gplr[i] = GPLR(i * 32);
371*4882a593Smuzhiyun saved_pgsr[i] = PGSR(i);
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun GPSR(i * 32) = PGSR(i);
374*4882a593Smuzhiyun GPCR(i * 32) = ~PGSR(i);
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun /* set GPDR bits taking into account MFP_LPM_KEEP_OUTPUT */
378*4882a593Smuzhiyun for (i = 0; i < pxa_last_gpio; i++) {
379*4882a593Smuzhiyun if ((gpdr_lpm[gpio_to_bank(i)] & GPIO_bit(i)) ||
380*4882a593Smuzhiyun ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
381*4882a593Smuzhiyun (saved_gpdr[gpio_to_bank(i)] & GPIO_bit(i))))
382*4882a593Smuzhiyun GPDR(i) |= GPIO_bit(i);
383*4882a593Smuzhiyun else
384*4882a593Smuzhiyun GPDR(i) &= ~GPIO_bit(i);
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun return 0;
388*4882a593Smuzhiyun }
389*4882a593Smuzhiyun
pxa2xx_mfp_resume(void)390*4882a593Smuzhiyun static void pxa2xx_mfp_resume(void)
391*4882a593Smuzhiyun {
392*4882a593Smuzhiyun int i;
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
395*4882a593Smuzhiyun GAFR_L(i) = saved_gafr[0][i];
396*4882a593Smuzhiyun GAFR_U(i) = saved_gafr[1][i];
397*4882a593Smuzhiyun GPSR(i * 32) = saved_gplr[i];
398*4882a593Smuzhiyun GPCR(i * 32) = ~saved_gplr[i];
399*4882a593Smuzhiyun GPDR(i * 32) = saved_gpdr[i];
400*4882a593Smuzhiyun PGSR(i) = saved_pgsr[i];
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun PSSR = PSSR_RDH | PSSR_PH;
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun #else
405*4882a593Smuzhiyun #define pxa2xx_mfp_suspend NULL
406*4882a593Smuzhiyun #define pxa2xx_mfp_resume NULL
407*4882a593Smuzhiyun #endif
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun struct syscore_ops pxa2xx_mfp_syscore_ops = {
410*4882a593Smuzhiyun .suspend = pxa2xx_mfp_suspend,
411*4882a593Smuzhiyun .resume = pxa2xx_mfp_resume,
412*4882a593Smuzhiyun };
413*4882a593Smuzhiyun
pxa2xx_mfp_init(void)414*4882a593Smuzhiyun static int __init pxa2xx_mfp_init(void)
415*4882a593Smuzhiyun {
416*4882a593Smuzhiyun int i;
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun if (!cpu_is_pxa2xx())
419*4882a593Smuzhiyun return 0;
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun if (cpu_is_pxa25x())
422*4882a593Smuzhiyun pxa25x_mfp_init();
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun if (cpu_is_pxa27x())
425*4882a593Smuzhiyun pxa27x_mfp_init();
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun /* clear RDH bit to enable GPIO receivers after reset/sleep exit */
428*4882a593Smuzhiyun PSSR = PSSR_RDH;
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun /* initialize gafr_run[], pgsr_lpm[] from existing values */
431*4882a593Smuzhiyun for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++)
432*4882a593Smuzhiyun gpdr_lpm[i] = GPDR(i * 32);
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun return 0;
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun postcore_initcall(pxa2xx_mfp_init);
437