Commit b95ace54a23e2f8ebb032744cebb17c9f43bf651
Committed by
Haojian Zhuang
1 parent
66f75a5d02
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
ARM: pxa: fix gpio wakeup setting
In 3.3, gpio wakeup setting was broken. The call enable_irq_wake() didn't set up the PXA gpio registers (PWER, ...) anymore. Fix it at least for pxa27x. The driver doesn't seem to be used in pxa25x (weird ...), and the fix doesn't extend to pxa3xx and pxa95x (which don't have a gpio_set_wake() available). Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Showing 3 changed files with 28 additions and 3 deletions Inline Diff
arch/arm/mach-pxa/pxa27x.c
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-pxa/pxa27x.c | 2 | * linux/arch/arm/mach-pxa/pxa27x.c |
3 | * | 3 | * |
4 | * Author: Nicolas Pitre | 4 | * Author: Nicolas Pitre |
5 | * Created: Nov 05, 2002 | 5 | * Created: Nov 05, 2002 |
6 | * Copyright: MontaVista Software Inc. | 6 | * Copyright: MontaVista Software Inc. |
7 | * | 7 | * |
8 | * Code specific to PXA27x aka Bulverde. | 8 | * Code specific to PXA27x aka Bulverde. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | #include <linux/gpio.h> | 14 | #include <linux/gpio.h> |
15 | #include <linux/gpio-pxa.h> | 15 | #include <linux/gpio-pxa.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/suspend.h> | 19 | #include <linux/suspend.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/syscore_ops.h> | 21 | #include <linux/syscore_ops.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
24 | #include <linux/i2c/pxa-i2c.h> | 24 | #include <linux/i2c/pxa-i2c.h> |
25 | 25 | ||
26 | #include <asm/mach/map.h> | 26 | #include <asm/mach/map.h> |
27 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
28 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
29 | #include <asm/suspend.h> | 29 | #include <asm/suspend.h> |
30 | #include <mach/irqs.h> | 30 | #include <mach/irqs.h> |
31 | #include <mach/pxa27x.h> | 31 | #include <mach/pxa27x.h> |
32 | #include <mach/reset.h> | 32 | #include <mach/reset.h> |
33 | #include <mach/ohci.h> | 33 | #include <mach/ohci.h> |
34 | #include <mach/pm.h> | 34 | #include <mach/pm.h> |
35 | #include <mach/dma.h> | 35 | #include <mach/dma.h> |
36 | #include <mach/smemc.h> | 36 | #include <mach/smemc.h> |
37 | 37 | ||
38 | #include "generic.h" | 38 | #include "generic.h" |
39 | #include "devices.h" | 39 | #include "devices.h" |
40 | #include "clock.h" | 40 | #include "clock.h" |
41 | 41 | ||
42 | void pxa27x_clear_otgph(void) | 42 | void pxa27x_clear_otgph(void) |
43 | { | 43 | { |
44 | if (cpu_is_pxa27x() && (PSSR & PSSR_OTGPH)) | 44 | if (cpu_is_pxa27x() && (PSSR & PSSR_OTGPH)) |
45 | PSSR |= PSSR_OTGPH; | 45 | PSSR |= PSSR_OTGPH; |
46 | } | 46 | } |
47 | EXPORT_SYMBOL(pxa27x_clear_otgph); | 47 | EXPORT_SYMBOL(pxa27x_clear_otgph); |
48 | 48 | ||
49 | static unsigned long ac97_reset_config[] = { | 49 | static unsigned long ac97_reset_config[] = { |
50 | GPIO113_GPIO, | 50 | GPIO113_GPIO, |
51 | GPIO113_AC97_nRESET, | 51 | GPIO113_AC97_nRESET, |
52 | GPIO95_GPIO, | 52 | GPIO95_GPIO, |
53 | GPIO95_AC97_nRESET, | 53 | GPIO95_AC97_nRESET, |
54 | }; | 54 | }; |
55 | 55 | ||
56 | void pxa27x_assert_ac97reset(int reset_gpio, int on) | 56 | void pxa27x_assert_ac97reset(int reset_gpio, int on) |
57 | { | 57 | { |
58 | if (reset_gpio == 113) | 58 | if (reset_gpio == 113) |
59 | pxa2xx_mfp_config(on ? &ac97_reset_config[0] : | 59 | pxa2xx_mfp_config(on ? &ac97_reset_config[0] : |
60 | &ac97_reset_config[1], 1); | 60 | &ac97_reset_config[1], 1); |
61 | 61 | ||
62 | if (reset_gpio == 95) | 62 | if (reset_gpio == 95) |
63 | pxa2xx_mfp_config(on ? &ac97_reset_config[2] : | 63 | pxa2xx_mfp_config(on ? &ac97_reset_config[2] : |
64 | &ac97_reset_config[3], 1); | 64 | &ac97_reset_config[3], 1); |
65 | } | 65 | } |
66 | EXPORT_SYMBOL_GPL(pxa27x_assert_ac97reset); | 66 | EXPORT_SYMBOL_GPL(pxa27x_assert_ac97reset); |
67 | 67 | ||
68 | /* Crystal clock: 13MHz */ | 68 | /* Crystal clock: 13MHz */ |
69 | #define BASE_CLK 13000000 | 69 | #define BASE_CLK 13000000 |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * Get the clock frequency as reflected by CCSR and the turbo flag. | 72 | * Get the clock frequency as reflected by CCSR and the turbo flag. |
73 | * We assume these values have been applied via a fcs. | 73 | * We assume these values have been applied via a fcs. |
74 | * If info is not 0 we also display the current settings. | 74 | * If info is not 0 we also display the current settings. |
75 | */ | 75 | */ |
76 | unsigned int pxa27x_get_clk_frequency_khz(int info) | 76 | unsigned int pxa27x_get_clk_frequency_khz(int info) |
77 | { | 77 | { |
78 | unsigned long ccsr, clkcfg; | 78 | unsigned long ccsr, clkcfg; |
79 | unsigned int l, L, m, M, n2, N, S; | 79 | unsigned int l, L, m, M, n2, N, S; |
80 | int cccr_a, t, ht, b; | 80 | int cccr_a, t, ht, b; |
81 | 81 | ||
82 | ccsr = CCSR; | 82 | ccsr = CCSR; |
83 | cccr_a = CCCR & (1 << 25); | 83 | cccr_a = CCCR & (1 << 25); |
84 | 84 | ||
85 | /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ | 85 | /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ |
86 | asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); | 86 | asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); |
87 | t = clkcfg & (1 << 0); | 87 | t = clkcfg & (1 << 0); |
88 | ht = clkcfg & (1 << 2); | 88 | ht = clkcfg & (1 << 2); |
89 | b = clkcfg & (1 << 3); | 89 | b = clkcfg & (1 << 3); |
90 | 90 | ||
91 | l = ccsr & 0x1f; | 91 | l = ccsr & 0x1f; |
92 | n2 = (ccsr>>7) & 0xf; | 92 | n2 = (ccsr>>7) & 0xf; |
93 | m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4; | 93 | m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4; |
94 | 94 | ||
95 | L = l * BASE_CLK; | 95 | L = l * BASE_CLK; |
96 | N = (L * n2) / 2; | 96 | N = (L * n2) / 2; |
97 | M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); | 97 | M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); |
98 | S = (b) ? L : (L/2); | 98 | S = (b) ? L : (L/2); |
99 | 99 | ||
100 | if (info) { | 100 | if (info) { |
101 | printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n", | 101 | printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n", |
102 | L / 1000000, (L % 1000000) / 10000, l ); | 102 | L / 1000000, (L % 1000000) / 10000, l ); |
103 | printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n", | 103 | printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n", |
104 | N / 1000000, (N % 1000000)/10000, n2 / 2, (n2 % 2)*5, | 104 | N / 1000000, (N % 1000000)/10000, n2 / 2, (n2 % 2)*5, |
105 | (t) ? "" : "in" ); | 105 | (t) ? "" : "in" ); |
106 | printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n", | 106 | printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n", |
107 | M / 1000000, (M % 1000000) / 10000, m ); | 107 | M / 1000000, (M % 1000000) / 10000, m ); |
108 | printk( KERN_INFO "System bus clock: %d.%02dMHz \n", | 108 | printk( KERN_INFO "System bus clock: %d.%02dMHz \n", |
109 | S / 1000000, (S % 1000000) / 10000 ); | 109 | S / 1000000, (S % 1000000) / 10000 ); |
110 | } | 110 | } |
111 | 111 | ||
112 | return (t) ? (N/1000) : (L/1000); | 112 | return (t) ? (N/1000) : (L/1000); |
113 | } | 113 | } |
114 | 114 | ||
115 | /* | 115 | /* |
116 | * Return the current mem clock frequency as reflected by CCCR[A], B, and L | 116 | * Return the current mem clock frequency as reflected by CCCR[A], B, and L |
117 | */ | 117 | */ |
118 | static unsigned long clk_pxa27x_mem_getrate(struct clk *clk) | 118 | static unsigned long clk_pxa27x_mem_getrate(struct clk *clk) |
119 | { | 119 | { |
120 | unsigned long ccsr, clkcfg; | 120 | unsigned long ccsr, clkcfg; |
121 | unsigned int l, L, m, M; | 121 | unsigned int l, L, m, M; |
122 | int cccr_a, b; | 122 | int cccr_a, b; |
123 | 123 | ||
124 | ccsr = CCSR; | 124 | ccsr = CCSR; |
125 | cccr_a = CCCR & (1 << 25); | 125 | cccr_a = CCCR & (1 << 25); |
126 | 126 | ||
127 | /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ | 127 | /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ |
128 | asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); | 128 | asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); |
129 | b = clkcfg & (1 << 3); | 129 | b = clkcfg & (1 << 3); |
130 | 130 | ||
131 | l = ccsr & 0x1f; | 131 | l = ccsr & 0x1f; |
132 | m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4; | 132 | m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4; |
133 | 133 | ||
134 | L = l * BASE_CLK; | 134 | L = l * BASE_CLK; |
135 | M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); | 135 | M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); |
136 | 136 | ||
137 | return M; | 137 | return M; |
138 | } | 138 | } |
139 | 139 | ||
140 | static const struct clkops clk_pxa27x_mem_ops = { | 140 | static const struct clkops clk_pxa27x_mem_ops = { |
141 | .enable = clk_dummy_enable, | 141 | .enable = clk_dummy_enable, |
142 | .disable = clk_dummy_disable, | 142 | .disable = clk_dummy_disable, |
143 | .getrate = clk_pxa27x_mem_getrate, | 143 | .getrate = clk_pxa27x_mem_getrate, |
144 | }; | 144 | }; |
145 | 145 | ||
146 | /* | 146 | /* |
147 | * Return the current LCD clock frequency in units of 10kHz as | 147 | * Return the current LCD clock frequency in units of 10kHz as |
148 | */ | 148 | */ |
149 | static unsigned int pxa27x_get_lcdclk_frequency_10khz(void) | 149 | static unsigned int pxa27x_get_lcdclk_frequency_10khz(void) |
150 | { | 150 | { |
151 | unsigned long ccsr; | 151 | unsigned long ccsr; |
152 | unsigned int l, L, k, K; | 152 | unsigned int l, L, k, K; |
153 | 153 | ||
154 | ccsr = CCSR; | 154 | ccsr = CCSR; |
155 | 155 | ||
156 | l = ccsr & 0x1f; | 156 | l = ccsr & 0x1f; |
157 | k = (l <= 7) ? 1 : (l <= 16) ? 2 : 4; | 157 | k = (l <= 7) ? 1 : (l <= 16) ? 2 : 4; |
158 | 158 | ||
159 | L = l * BASE_CLK; | 159 | L = l * BASE_CLK; |
160 | K = L / k; | 160 | K = L / k; |
161 | 161 | ||
162 | return (K / 10000); | 162 | return (K / 10000); |
163 | } | 163 | } |
164 | 164 | ||
165 | static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk) | 165 | static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk) |
166 | { | 166 | { |
167 | return pxa27x_get_lcdclk_frequency_10khz() * 10000; | 167 | return pxa27x_get_lcdclk_frequency_10khz() * 10000; |
168 | } | 168 | } |
169 | 169 | ||
170 | static const struct clkops clk_pxa27x_lcd_ops = { | 170 | static const struct clkops clk_pxa27x_lcd_ops = { |
171 | .enable = clk_pxa2xx_cken_enable, | 171 | .enable = clk_pxa2xx_cken_enable, |
172 | .disable = clk_pxa2xx_cken_disable, | 172 | .disable = clk_pxa2xx_cken_disable, |
173 | .getrate = clk_pxa27x_lcd_getrate, | 173 | .getrate = clk_pxa27x_lcd_getrate, |
174 | }; | 174 | }; |
175 | 175 | ||
176 | static DEFINE_PXA2_CKEN(pxa27x_ffuart, FFUART, 14857000, 1); | 176 | static DEFINE_PXA2_CKEN(pxa27x_ffuart, FFUART, 14857000, 1); |
177 | static DEFINE_PXA2_CKEN(pxa27x_btuart, BTUART, 14857000, 1); | 177 | static DEFINE_PXA2_CKEN(pxa27x_btuart, BTUART, 14857000, 1); |
178 | static DEFINE_PXA2_CKEN(pxa27x_stuart, STUART, 14857000, 1); | 178 | static DEFINE_PXA2_CKEN(pxa27x_stuart, STUART, 14857000, 1); |
179 | static DEFINE_PXA2_CKEN(pxa27x_i2s, I2S, 14682000, 0); | 179 | static DEFINE_PXA2_CKEN(pxa27x_i2s, I2S, 14682000, 0); |
180 | static DEFINE_PXA2_CKEN(pxa27x_i2c, I2C, 32842000, 0); | 180 | static DEFINE_PXA2_CKEN(pxa27x_i2c, I2C, 32842000, 0); |
181 | static DEFINE_PXA2_CKEN(pxa27x_usb, USB, 48000000, 5); | 181 | static DEFINE_PXA2_CKEN(pxa27x_usb, USB, 48000000, 5); |
182 | static DEFINE_PXA2_CKEN(pxa27x_mmc, MMC, 19500000, 0); | 182 | static DEFINE_PXA2_CKEN(pxa27x_mmc, MMC, 19500000, 0); |
183 | static DEFINE_PXA2_CKEN(pxa27x_ficp, FICP, 48000000, 0); | 183 | static DEFINE_PXA2_CKEN(pxa27x_ficp, FICP, 48000000, 0); |
184 | static DEFINE_PXA2_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0); | 184 | static DEFINE_PXA2_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0); |
185 | static DEFINE_PXA2_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0); | 185 | static DEFINE_PXA2_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0); |
186 | static DEFINE_PXA2_CKEN(pxa27x_keypad, KEYPAD, 32768, 0); | 186 | static DEFINE_PXA2_CKEN(pxa27x_keypad, KEYPAD, 32768, 0); |
187 | static DEFINE_PXA2_CKEN(pxa27x_ssp1, SSP1, 13000000, 0); | 187 | static DEFINE_PXA2_CKEN(pxa27x_ssp1, SSP1, 13000000, 0); |
188 | static DEFINE_PXA2_CKEN(pxa27x_ssp2, SSP2, 13000000, 0); | 188 | static DEFINE_PXA2_CKEN(pxa27x_ssp2, SSP2, 13000000, 0); |
189 | static DEFINE_PXA2_CKEN(pxa27x_ssp3, SSP3, 13000000, 0); | 189 | static DEFINE_PXA2_CKEN(pxa27x_ssp3, SSP3, 13000000, 0); |
190 | static DEFINE_PXA2_CKEN(pxa27x_pwm0, PWM0, 13000000, 0); | 190 | static DEFINE_PXA2_CKEN(pxa27x_pwm0, PWM0, 13000000, 0); |
191 | static DEFINE_PXA2_CKEN(pxa27x_pwm1, PWM1, 13000000, 0); | 191 | static DEFINE_PXA2_CKEN(pxa27x_pwm1, PWM1, 13000000, 0); |
192 | static DEFINE_PXA2_CKEN(pxa27x_ac97, AC97, 24576000, 0); | 192 | static DEFINE_PXA2_CKEN(pxa27x_ac97, AC97, 24576000, 0); |
193 | static DEFINE_PXA2_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0); | 193 | static DEFINE_PXA2_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0); |
194 | static DEFINE_PXA2_CKEN(pxa27x_msl, MSL, 48000000, 0); | 194 | static DEFINE_PXA2_CKEN(pxa27x_msl, MSL, 48000000, 0); |
195 | static DEFINE_PXA2_CKEN(pxa27x_usim, USIM, 48000000, 0); | 195 | static DEFINE_PXA2_CKEN(pxa27x_usim, USIM, 48000000, 0); |
196 | static DEFINE_PXA2_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0); | 196 | static DEFINE_PXA2_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0); |
197 | static DEFINE_PXA2_CKEN(pxa27x_im, IM, 0, 0); | 197 | static DEFINE_PXA2_CKEN(pxa27x_im, IM, 0, 0); |
198 | static DEFINE_PXA2_CKEN(pxa27x_memc, MEMC, 0, 0); | 198 | static DEFINE_PXA2_CKEN(pxa27x_memc, MEMC, 0, 0); |
199 | 199 | ||
200 | static DEFINE_CK(pxa27x_lcd, LCD, &clk_pxa27x_lcd_ops); | 200 | static DEFINE_CK(pxa27x_lcd, LCD, &clk_pxa27x_lcd_ops); |
201 | static DEFINE_CK(pxa27x_camera, CAMERA, &clk_pxa27x_lcd_ops); | 201 | static DEFINE_CK(pxa27x_camera, CAMERA, &clk_pxa27x_lcd_ops); |
202 | static DEFINE_CLK(pxa27x_mem, &clk_pxa27x_mem_ops, 0, 0); | 202 | static DEFINE_CLK(pxa27x_mem, &clk_pxa27x_mem_ops, 0, 0); |
203 | 203 | ||
204 | static struct clk_lookup pxa27x_clkregs[] = { | 204 | static struct clk_lookup pxa27x_clkregs[] = { |
205 | INIT_CLKREG(&clk_pxa27x_lcd, "pxa2xx-fb", NULL), | 205 | INIT_CLKREG(&clk_pxa27x_lcd, "pxa2xx-fb", NULL), |
206 | INIT_CLKREG(&clk_pxa27x_camera, "pxa27x-camera.0", NULL), | 206 | INIT_CLKREG(&clk_pxa27x_camera, "pxa27x-camera.0", NULL), |
207 | INIT_CLKREG(&clk_pxa27x_ffuart, "pxa2xx-uart.0", NULL), | 207 | INIT_CLKREG(&clk_pxa27x_ffuart, "pxa2xx-uart.0", NULL), |
208 | INIT_CLKREG(&clk_pxa27x_btuart, "pxa2xx-uart.1", NULL), | 208 | INIT_CLKREG(&clk_pxa27x_btuart, "pxa2xx-uart.1", NULL), |
209 | INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-uart.2", NULL), | 209 | INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-uart.2", NULL), |
210 | INIT_CLKREG(&clk_pxa27x_i2s, "pxa2xx-i2s", NULL), | 210 | INIT_CLKREG(&clk_pxa27x_i2s, "pxa2xx-i2s", NULL), |
211 | INIT_CLKREG(&clk_pxa27x_i2c, "pxa2xx-i2c.0", NULL), | 211 | INIT_CLKREG(&clk_pxa27x_i2c, "pxa2xx-i2c.0", NULL), |
212 | INIT_CLKREG(&clk_pxa27x_usb, "pxa27x-udc", NULL), | 212 | INIT_CLKREG(&clk_pxa27x_usb, "pxa27x-udc", NULL), |
213 | INIT_CLKREG(&clk_pxa27x_mmc, "pxa2xx-mci.0", NULL), | 213 | INIT_CLKREG(&clk_pxa27x_mmc, "pxa2xx-mci.0", NULL), |
214 | INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-ir", "UARTCLK"), | 214 | INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-ir", "UARTCLK"), |
215 | INIT_CLKREG(&clk_pxa27x_ficp, "pxa2xx-ir", "FICPCLK"), | 215 | INIT_CLKREG(&clk_pxa27x_ficp, "pxa2xx-ir", "FICPCLK"), |
216 | INIT_CLKREG(&clk_pxa27x_usbhost, "pxa27x-ohci", NULL), | 216 | INIT_CLKREG(&clk_pxa27x_usbhost, "pxa27x-ohci", NULL), |
217 | INIT_CLKREG(&clk_pxa27x_pwri2c, "pxa2xx-i2c.1", NULL), | 217 | INIT_CLKREG(&clk_pxa27x_pwri2c, "pxa2xx-i2c.1", NULL), |
218 | INIT_CLKREG(&clk_pxa27x_keypad, "pxa27x-keypad", NULL), | 218 | INIT_CLKREG(&clk_pxa27x_keypad, "pxa27x-keypad", NULL), |
219 | INIT_CLKREG(&clk_pxa27x_ssp1, "pxa27x-ssp.0", NULL), | 219 | INIT_CLKREG(&clk_pxa27x_ssp1, "pxa27x-ssp.0", NULL), |
220 | INIT_CLKREG(&clk_pxa27x_ssp2, "pxa27x-ssp.1", NULL), | 220 | INIT_CLKREG(&clk_pxa27x_ssp2, "pxa27x-ssp.1", NULL), |
221 | INIT_CLKREG(&clk_pxa27x_ssp3, "pxa27x-ssp.2", NULL), | 221 | INIT_CLKREG(&clk_pxa27x_ssp3, "pxa27x-ssp.2", NULL), |
222 | INIT_CLKREG(&clk_pxa27x_pwm0, "pxa27x-pwm.0", NULL), | 222 | INIT_CLKREG(&clk_pxa27x_pwm0, "pxa27x-pwm.0", NULL), |
223 | INIT_CLKREG(&clk_pxa27x_pwm1, "pxa27x-pwm.1", NULL), | 223 | INIT_CLKREG(&clk_pxa27x_pwm1, "pxa27x-pwm.1", NULL), |
224 | INIT_CLKREG(&clk_pxa27x_ac97, NULL, "AC97CLK"), | 224 | INIT_CLKREG(&clk_pxa27x_ac97, NULL, "AC97CLK"), |
225 | INIT_CLKREG(&clk_pxa27x_ac97conf, NULL, "AC97CONFCLK"), | 225 | INIT_CLKREG(&clk_pxa27x_ac97conf, NULL, "AC97CONFCLK"), |
226 | INIT_CLKREG(&clk_pxa27x_msl, NULL, "MSLCLK"), | 226 | INIT_CLKREG(&clk_pxa27x_msl, NULL, "MSLCLK"), |
227 | INIT_CLKREG(&clk_pxa27x_usim, NULL, "USIMCLK"), | 227 | INIT_CLKREG(&clk_pxa27x_usim, NULL, "USIMCLK"), |
228 | INIT_CLKREG(&clk_pxa27x_memstk, NULL, "MSTKCLK"), | 228 | INIT_CLKREG(&clk_pxa27x_memstk, NULL, "MSTKCLK"), |
229 | INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"), | 229 | INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"), |
230 | INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"), | 230 | INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"), |
231 | INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL), | 231 | INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL), |
232 | INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL), | 232 | INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL), |
233 | }; | 233 | }; |
234 | 234 | ||
235 | #ifdef CONFIG_PM | 235 | #ifdef CONFIG_PM |
236 | 236 | ||
237 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | 237 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
238 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | 238 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] |
239 | 239 | ||
240 | /* | 240 | /* |
241 | * allow platforms to override default PWRMODE setting used for PM_SUSPEND_MEM | 241 | * allow platforms to override default PWRMODE setting used for PM_SUSPEND_MEM |
242 | */ | 242 | */ |
243 | static unsigned int pwrmode = PWRMODE_SLEEP; | 243 | static unsigned int pwrmode = PWRMODE_SLEEP; |
244 | 244 | ||
245 | int __init pxa27x_set_pwrmode(unsigned int mode) | 245 | int __init pxa27x_set_pwrmode(unsigned int mode) |
246 | { | 246 | { |
247 | switch (mode) { | 247 | switch (mode) { |
248 | case PWRMODE_SLEEP: | 248 | case PWRMODE_SLEEP: |
249 | case PWRMODE_DEEPSLEEP: | 249 | case PWRMODE_DEEPSLEEP: |
250 | pwrmode = mode; | 250 | pwrmode = mode; |
251 | return 0; | 251 | return 0; |
252 | } | 252 | } |
253 | 253 | ||
254 | return -EINVAL; | 254 | return -EINVAL; |
255 | } | 255 | } |
256 | 256 | ||
257 | /* | 257 | /* |
258 | * List of global PXA peripheral registers to preserve. | 258 | * List of global PXA peripheral registers to preserve. |
259 | * More ones like CP and general purpose register values are preserved | 259 | * More ones like CP and general purpose register values are preserved |
260 | * with the stack pointer in sleep.S. | 260 | * with the stack pointer in sleep.S. |
261 | */ | 261 | */ |
262 | enum { | 262 | enum { |
263 | SLEEP_SAVE_PSTR, | 263 | SLEEP_SAVE_PSTR, |
264 | SLEEP_SAVE_MDREFR, | 264 | SLEEP_SAVE_MDREFR, |
265 | SLEEP_SAVE_PCFR, | 265 | SLEEP_SAVE_PCFR, |
266 | SLEEP_SAVE_COUNT | 266 | SLEEP_SAVE_COUNT |
267 | }; | 267 | }; |
268 | 268 | ||
269 | void pxa27x_cpu_pm_save(unsigned long *sleep_save) | 269 | void pxa27x_cpu_pm_save(unsigned long *sleep_save) |
270 | { | 270 | { |
271 | sleep_save[SLEEP_SAVE_MDREFR] = __raw_readl(MDREFR); | 271 | sleep_save[SLEEP_SAVE_MDREFR] = __raw_readl(MDREFR); |
272 | SAVE(PCFR); | 272 | SAVE(PCFR); |
273 | 273 | ||
274 | SAVE(PSTR); | 274 | SAVE(PSTR); |
275 | } | 275 | } |
276 | 276 | ||
277 | void pxa27x_cpu_pm_restore(unsigned long *sleep_save) | 277 | void pxa27x_cpu_pm_restore(unsigned long *sleep_save) |
278 | { | 278 | { |
279 | __raw_writel(sleep_save[SLEEP_SAVE_MDREFR], MDREFR); | 279 | __raw_writel(sleep_save[SLEEP_SAVE_MDREFR], MDREFR); |
280 | RESTORE(PCFR); | 280 | RESTORE(PCFR); |
281 | 281 | ||
282 | PSSR = PSSR_RDH | PSSR_PH; | 282 | PSSR = PSSR_RDH | PSSR_PH; |
283 | 283 | ||
284 | RESTORE(PSTR); | 284 | RESTORE(PSTR); |
285 | } | 285 | } |
286 | 286 | ||
287 | void pxa27x_cpu_pm_enter(suspend_state_t state) | 287 | void pxa27x_cpu_pm_enter(suspend_state_t state) |
288 | { | 288 | { |
289 | extern void pxa_cpu_standby(void); | 289 | extern void pxa_cpu_standby(void); |
290 | #ifndef CONFIG_IWMMXT | 290 | #ifndef CONFIG_IWMMXT |
291 | u64 acc0; | 291 | u64 acc0; |
292 | 292 | ||
293 | asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); | 293 | asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); |
294 | #endif | 294 | #endif |
295 | 295 | ||
296 | /* ensure voltage-change sequencer not initiated, which hangs */ | 296 | /* ensure voltage-change sequencer not initiated, which hangs */ |
297 | PCFR &= ~PCFR_FVC; | 297 | PCFR &= ~PCFR_FVC; |
298 | 298 | ||
299 | /* Clear edge-detect status register. */ | 299 | /* Clear edge-detect status register. */ |
300 | PEDR = 0xDF12FE1B; | 300 | PEDR = 0xDF12FE1B; |
301 | 301 | ||
302 | /* Clear reset status */ | 302 | /* Clear reset status */ |
303 | RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; | 303 | RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; |
304 | 304 | ||
305 | switch (state) { | 305 | switch (state) { |
306 | case PM_SUSPEND_STANDBY: | 306 | case PM_SUSPEND_STANDBY: |
307 | pxa_cpu_standby(); | 307 | pxa_cpu_standby(); |
308 | break; | 308 | break; |
309 | case PM_SUSPEND_MEM: | 309 | case PM_SUSPEND_MEM: |
310 | cpu_suspend(pwrmode, pxa27x_finish_suspend); | 310 | cpu_suspend(pwrmode, pxa27x_finish_suspend); |
311 | #ifndef CONFIG_IWMMXT | 311 | #ifndef CONFIG_IWMMXT |
312 | asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); | 312 | asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); |
313 | #endif | 313 | #endif |
314 | break; | 314 | break; |
315 | } | 315 | } |
316 | } | 316 | } |
317 | 317 | ||
318 | static int pxa27x_cpu_pm_valid(suspend_state_t state) | 318 | static int pxa27x_cpu_pm_valid(suspend_state_t state) |
319 | { | 319 | { |
320 | return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; | 320 | return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; |
321 | } | 321 | } |
322 | 322 | ||
323 | static int pxa27x_cpu_pm_prepare(void) | 323 | static int pxa27x_cpu_pm_prepare(void) |
324 | { | 324 | { |
325 | /* set resume return address */ | 325 | /* set resume return address */ |
326 | PSPR = virt_to_phys(cpu_resume); | 326 | PSPR = virt_to_phys(cpu_resume); |
327 | return 0; | 327 | return 0; |
328 | } | 328 | } |
329 | 329 | ||
330 | static void pxa27x_cpu_pm_finish(void) | 330 | static void pxa27x_cpu_pm_finish(void) |
331 | { | 331 | { |
332 | /* ensure not to come back here if it wasn't intended */ | 332 | /* ensure not to come back here if it wasn't intended */ |
333 | PSPR = 0; | 333 | PSPR = 0; |
334 | } | 334 | } |
335 | 335 | ||
336 | static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = { | 336 | static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = { |
337 | .save_count = SLEEP_SAVE_COUNT, | 337 | .save_count = SLEEP_SAVE_COUNT, |
338 | .save = pxa27x_cpu_pm_save, | 338 | .save = pxa27x_cpu_pm_save, |
339 | .restore = pxa27x_cpu_pm_restore, | 339 | .restore = pxa27x_cpu_pm_restore, |
340 | .valid = pxa27x_cpu_pm_valid, | 340 | .valid = pxa27x_cpu_pm_valid, |
341 | .enter = pxa27x_cpu_pm_enter, | 341 | .enter = pxa27x_cpu_pm_enter, |
342 | .prepare = pxa27x_cpu_pm_prepare, | 342 | .prepare = pxa27x_cpu_pm_prepare, |
343 | .finish = pxa27x_cpu_pm_finish, | 343 | .finish = pxa27x_cpu_pm_finish, |
344 | }; | 344 | }; |
345 | 345 | ||
346 | static void __init pxa27x_init_pm(void) | 346 | static void __init pxa27x_init_pm(void) |
347 | { | 347 | { |
348 | pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns; | 348 | pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns; |
349 | } | 349 | } |
350 | #else | 350 | #else |
351 | static inline void pxa27x_init_pm(void) {} | 351 | static inline void pxa27x_init_pm(void) {} |
352 | #endif | 352 | #endif |
353 | 353 | ||
354 | /* PXA27x: Various gpios can issue wakeup events. This logic only | 354 | /* PXA27x: Various gpios can issue wakeup events. This logic only |
355 | * handles the simple cases, not the WEMUX2 and WEMUX3 options | 355 | * handles the simple cases, not the WEMUX2 and WEMUX3 options |
356 | */ | 356 | */ |
357 | static int pxa27x_set_wake(struct irq_data *d, unsigned int on) | 357 | static int pxa27x_set_wake(struct irq_data *d, unsigned int on) |
358 | { | 358 | { |
359 | int gpio = pxa_irq_to_gpio(d->irq); | 359 | int gpio = pxa_irq_to_gpio(d->irq); |
360 | uint32_t mask; | 360 | uint32_t mask; |
361 | 361 | ||
362 | if (gpio >= 0 && gpio < 128) | 362 | if (gpio >= 0 && gpio < 128) |
363 | return gpio_set_wake(gpio, on); | 363 | return gpio_set_wake(gpio, on); |
364 | 364 | ||
365 | if (d->irq == IRQ_KEYPAD) | 365 | if (d->irq == IRQ_KEYPAD) |
366 | return keypad_set_wake(on); | 366 | return keypad_set_wake(on); |
367 | 367 | ||
368 | switch (d->irq) { | 368 | switch (d->irq) { |
369 | case IRQ_RTCAlrm: | 369 | case IRQ_RTCAlrm: |
370 | mask = PWER_RTC; | 370 | mask = PWER_RTC; |
371 | break; | 371 | break; |
372 | case IRQ_USB: | 372 | case IRQ_USB: |
373 | mask = 1u << 26; | 373 | mask = 1u << 26; |
374 | break; | 374 | break; |
375 | default: | 375 | default: |
376 | return -EINVAL; | 376 | return -EINVAL; |
377 | } | 377 | } |
378 | 378 | ||
379 | if (on) | 379 | if (on) |
380 | PWER |= mask; | 380 | PWER |= mask; |
381 | else | 381 | else |
382 | PWER &=~mask; | 382 | PWER &=~mask; |
383 | 383 | ||
384 | return 0; | 384 | return 0; |
385 | } | 385 | } |
386 | 386 | ||
387 | void __init pxa27x_init_irq(void) | 387 | void __init pxa27x_init_irq(void) |
388 | { | 388 | { |
389 | pxa_init_irq(34, pxa27x_set_wake); | 389 | pxa_init_irq(34, pxa27x_set_wake); |
390 | } | 390 | } |
391 | 391 | ||
392 | static struct map_desc pxa27x_io_desc[] __initdata = { | 392 | static struct map_desc pxa27x_io_desc[] __initdata = { |
393 | { /* Mem Ctl */ | 393 | { /* Mem Ctl */ |
394 | .virtual = (unsigned long)SMEMC_VIRT, | 394 | .virtual = (unsigned long)SMEMC_VIRT, |
395 | .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE), | 395 | .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE), |
396 | .length = 0x00200000, | 396 | .length = 0x00200000, |
397 | .type = MT_DEVICE | 397 | .type = MT_DEVICE |
398 | }, { /* IMem ctl */ | 398 | }, { /* IMem ctl */ |
399 | .virtual = 0xfe000000, | 399 | .virtual = 0xfe000000, |
400 | .pfn = __phys_to_pfn(0x58000000), | 400 | .pfn = __phys_to_pfn(0x58000000), |
401 | .length = 0x00100000, | 401 | .length = 0x00100000, |
402 | .type = MT_DEVICE | 402 | .type = MT_DEVICE |
403 | }, | 403 | }, |
404 | }; | 404 | }; |
405 | 405 | ||
406 | void __init pxa27x_map_io(void) | 406 | void __init pxa27x_map_io(void) |
407 | { | 407 | { |
408 | pxa_map_io(); | 408 | pxa_map_io(); |
409 | iotable_init(ARRAY_AND_SIZE(pxa27x_io_desc)); | 409 | iotable_init(ARRAY_AND_SIZE(pxa27x_io_desc)); |
410 | pxa27x_get_clk_frequency_khz(1); | 410 | pxa27x_get_clk_frequency_khz(1); |
411 | } | 411 | } |
412 | 412 | ||
413 | /* | 413 | /* |
414 | * device registration specific to PXA27x. | 414 | * device registration specific to PXA27x. |
415 | */ | 415 | */ |
416 | void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info) | 416 | void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info) |
417 | { | 417 | { |
418 | local_irq_disable(); | 418 | local_irq_disable(); |
419 | PCFR |= PCFR_PI2CEN; | 419 | PCFR |= PCFR_PI2CEN; |
420 | local_irq_enable(); | 420 | local_irq_enable(); |
421 | pxa_register_device(&pxa27x_device_i2c_power, info); | 421 | pxa_register_device(&pxa27x_device_i2c_power, info); |
422 | } | 422 | } |
423 | 423 | ||
424 | static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = { | ||
425 | .gpio_set_wake = gpio_set_wake, | ||
426 | }; | ||
427 | |||
424 | static struct platform_device *devices[] __initdata = { | 428 | static struct platform_device *devices[] __initdata = { |
425 | &pxa_device_gpio, | ||
426 | &pxa27x_device_udc, | 429 | &pxa27x_device_udc, |
427 | &pxa_device_pmu, | 430 | &pxa_device_pmu, |
428 | &pxa_device_i2s, | 431 | &pxa_device_i2s, |
429 | &pxa_device_asoc_ssp1, | 432 | &pxa_device_asoc_ssp1, |
430 | &pxa_device_asoc_ssp2, | 433 | &pxa_device_asoc_ssp2, |
431 | &pxa_device_asoc_ssp3, | 434 | &pxa_device_asoc_ssp3, |
432 | &pxa_device_asoc_platform, | 435 | &pxa_device_asoc_platform, |
433 | &sa1100_device_rtc, | 436 | &sa1100_device_rtc, |
434 | &pxa_device_rtc, | 437 | &pxa_device_rtc, |
435 | &pxa27x_device_ssp1, | 438 | &pxa27x_device_ssp1, |
436 | &pxa27x_device_ssp2, | 439 | &pxa27x_device_ssp2, |
437 | &pxa27x_device_ssp3, | 440 | &pxa27x_device_ssp3, |
438 | &pxa27x_device_pwm0, | 441 | &pxa27x_device_pwm0, |
439 | &pxa27x_device_pwm1, | 442 | &pxa27x_device_pwm1, |
440 | }; | 443 | }; |
441 | 444 | ||
442 | static int __init pxa27x_init(void) | 445 | static int __init pxa27x_init(void) |
443 | { | 446 | { |
444 | int ret = 0; | 447 | int ret = 0; |
445 | 448 | ||
446 | if (cpu_is_pxa27x()) { | 449 | if (cpu_is_pxa27x()) { |
447 | 450 | ||
448 | reset_status = RCSR; | 451 | reset_status = RCSR; |
449 | 452 | ||
450 | clkdev_add_table(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs)); | 453 | clkdev_add_table(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs)); |
451 | 454 | ||
452 | if ((ret = pxa_init_dma(IRQ_DMA, 32))) | 455 | if ((ret = pxa_init_dma(IRQ_DMA, 32))) |
453 | return ret; | 456 | return ret; |
454 | 457 | ||
455 | pxa27x_init_pm(); | 458 | pxa27x_init_pm(); |
456 | 459 | ||
457 | register_syscore_ops(&pxa_irq_syscore_ops); | 460 | register_syscore_ops(&pxa_irq_syscore_ops); |
458 | register_syscore_ops(&pxa2xx_mfp_syscore_ops); | 461 | register_syscore_ops(&pxa2xx_mfp_syscore_ops); |
459 | register_syscore_ops(&pxa2xx_clock_syscore_ops); | 462 | register_syscore_ops(&pxa2xx_clock_syscore_ops); |
460 | 463 | ||
464 | pxa_register_device(&pxa_device_gpio, &pxa27x_gpio_info); | ||
461 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); | 465 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); |
462 | } | 466 | } |
463 | 467 | ||
464 | return ret; | 468 | return ret; |
465 | } | 469 | } |
466 | 470 | ||
467 | postcore_initcall(pxa27x_init); | 471 | postcore_initcall(pxa27x_init); |
drivers/gpio/gpio-pxa.c
1 | /* | 1 | /* |
2 | * linux/arch/arm/plat-pxa/gpio.c | 2 | * linux/arch/arm/plat-pxa/gpio.c |
3 | * | 3 | * |
4 | * Generic PXA GPIO handling | 4 | * Generic PXA GPIO handling |
5 | * | 5 | * |
6 | * Author: Nicolas Pitre | 6 | * Author: Nicolas Pitre |
7 | * Created: Jun 15, 2001 | 7 | * Created: Jun 15, 2001 |
8 | * Copyright: MontaVista Software Inc. | 8 | * Copyright: MontaVista Software Inc. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/gpio-pxa.h> | 17 | #include <linux/gpio-pxa.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/syscore_ops.h> | 22 | #include <linux/syscore_ops.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | 24 | ||
25 | #include <mach/irqs.h> | 25 | #include <mach/irqs.h> |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with | 28 | * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with |
29 | * one set of registers. The register offsets are organized below: | 29 | * one set of registers. The register offsets are organized below: |
30 | * | 30 | * |
31 | * GPLR GPDR GPSR GPCR GRER GFER GEDR | 31 | * GPLR GPDR GPSR GPCR GRER GFER GEDR |
32 | * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048 | 32 | * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048 |
33 | * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C | 33 | * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C |
34 | * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050 | 34 | * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050 |
35 | * | 35 | * |
36 | * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148 | 36 | * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148 |
37 | * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C | 37 | * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C |
38 | * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150 | 38 | * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150 |
39 | * | 39 | * |
40 | * NOTE: | 40 | * NOTE: |
41 | * BANK 3 is only available on PXA27x and later processors. | 41 | * BANK 3 is only available on PXA27x and later processors. |
42 | * BANK 4 and 5 are only available on PXA935 | 42 | * BANK 4 and 5 are only available on PXA935 |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #define GPLR_OFFSET 0x00 | 45 | #define GPLR_OFFSET 0x00 |
46 | #define GPDR_OFFSET 0x0C | 46 | #define GPDR_OFFSET 0x0C |
47 | #define GPSR_OFFSET 0x18 | 47 | #define GPSR_OFFSET 0x18 |
48 | #define GPCR_OFFSET 0x24 | 48 | #define GPCR_OFFSET 0x24 |
49 | #define GRER_OFFSET 0x30 | 49 | #define GRER_OFFSET 0x30 |
50 | #define GFER_OFFSET 0x3C | 50 | #define GFER_OFFSET 0x3C |
51 | #define GEDR_OFFSET 0x48 | 51 | #define GEDR_OFFSET 0x48 |
52 | #define GAFR_OFFSET 0x54 | 52 | #define GAFR_OFFSET 0x54 |
53 | #define ED_MASK_OFFSET 0x9C /* GPIO edge detection for AP side */ | 53 | #define ED_MASK_OFFSET 0x9C /* GPIO edge detection for AP side */ |
54 | 54 | ||
55 | #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) | 55 | #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) |
56 | 56 | ||
57 | int pxa_last_gpio; | 57 | int pxa_last_gpio; |
58 | 58 | ||
59 | struct pxa_gpio_chip { | 59 | struct pxa_gpio_chip { |
60 | struct gpio_chip chip; | 60 | struct gpio_chip chip; |
61 | void __iomem *regbase; | 61 | void __iomem *regbase; |
62 | char label[10]; | 62 | char label[10]; |
63 | 63 | ||
64 | unsigned long irq_mask; | 64 | unsigned long irq_mask; |
65 | unsigned long irq_edge_rise; | 65 | unsigned long irq_edge_rise; |
66 | unsigned long irq_edge_fall; | 66 | unsigned long irq_edge_fall; |
67 | int (*set_wake)(unsigned int gpio, unsigned int on); | ||
67 | 68 | ||
68 | #ifdef CONFIG_PM | 69 | #ifdef CONFIG_PM |
69 | unsigned long saved_gplr; | 70 | unsigned long saved_gplr; |
70 | unsigned long saved_gpdr; | 71 | unsigned long saved_gpdr; |
71 | unsigned long saved_grer; | 72 | unsigned long saved_grer; |
72 | unsigned long saved_gfer; | 73 | unsigned long saved_gfer; |
73 | #endif | 74 | #endif |
74 | }; | 75 | }; |
75 | 76 | ||
76 | enum { | 77 | enum { |
77 | PXA25X_GPIO = 0, | 78 | PXA25X_GPIO = 0, |
78 | PXA26X_GPIO, | 79 | PXA26X_GPIO, |
79 | PXA27X_GPIO, | 80 | PXA27X_GPIO, |
80 | PXA3XX_GPIO, | 81 | PXA3XX_GPIO, |
81 | PXA93X_GPIO, | 82 | PXA93X_GPIO, |
82 | MMP_GPIO = 0x10, | 83 | MMP_GPIO = 0x10, |
83 | MMP2_GPIO, | 84 | MMP2_GPIO, |
84 | }; | 85 | }; |
85 | 86 | ||
86 | static DEFINE_SPINLOCK(gpio_lock); | 87 | static DEFINE_SPINLOCK(gpio_lock); |
87 | static struct pxa_gpio_chip *pxa_gpio_chips; | 88 | static struct pxa_gpio_chip *pxa_gpio_chips; |
88 | static int gpio_type; | 89 | static int gpio_type; |
89 | static void __iomem *gpio_reg_base; | 90 | static void __iomem *gpio_reg_base; |
90 | 91 | ||
91 | #define for_each_gpio_chip(i, c) \ | 92 | #define for_each_gpio_chip(i, c) \ |
92 | for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) | 93 | for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) |
93 | 94 | ||
94 | static inline void __iomem *gpio_chip_base(struct gpio_chip *c) | 95 | static inline void __iomem *gpio_chip_base(struct gpio_chip *c) |
95 | { | 96 | { |
96 | return container_of(c, struct pxa_gpio_chip, chip)->regbase; | 97 | return container_of(c, struct pxa_gpio_chip, chip)->regbase; |
97 | } | 98 | } |
98 | 99 | ||
99 | static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio) | 100 | static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio) |
100 | { | 101 | { |
101 | return &pxa_gpio_chips[gpio_to_bank(gpio)]; | 102 | return &pxa_gpio_chips[gpio_to_bank(gpio)]; |
102 | } | 103 | } |
103 | 104 | ||
104 | static inline int gpio_is_pxa_type(int type) | 105 | static inline int gpio_is_pxa_type(int type) |
105 | { | 106 | { |
106 | return (type & MMP_GPIO) == 0; | 107 | return (type & MMP_GPIO) == 0; |
107 | } | 108 | } |
108 | 109 | ||
109 | static inline int gpio_is_mmp_type(int type) | 110 | static inline int gpio_is_mmp_type(int type) |
110 | { | 111 | { |
111 | return (type & MMP_GPIO) != 0; | 112 | return (type & MMP_GPIO) != 0; |
112 | } | 113 | } |
113 | 114 | ||
114 | /* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted, | 115 | /* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted, |
115 | * as well as their Alternate Function value being '1' for GPIO in GAFRx. | 116 | * as well as their Alternate Function value being '1' for GPIO in GAFRx. |
116 | */ | 117 | */ |
117 | static inline int __gpio_is_inverted(int gpio) | 118 | static inline int __gpio_is_inverted(int gpio) |
118 | { | 119 | { |
119 | if ((gpio_type == PXA26X_GPIO) && (gpio > 85)) | 120 | if ((gpio_type == PXA26X_GPIO) && (gpio > 85)) |
120 | return 1; | 121 | return 1; |
121 | return 0; | 122 | return 0; |
122 | } | 123 | } |
123 | 124 | ||
124 | /* | 125 | /* |
125 | * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate | 126 | * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate |
126 | * function of a GPIO, and GPDRx cannot be altered once configured. It | 127 | * function of a GPIO, and GPDRx cannot be altered once configured. It |
127 | * is attributed as "occupied" here (I know this terminology isn't | 128 | * is attributed as "occupied" here (I know this terminology isn't |
128 | * accurate, you are welcome to propose a better one :-) | 129 | * accurate, you are welcome to propose a better one :-) |
129 | */ | 130 | */ |
130 | static inline int __gpio_is_occupied(unsigned gpio) | 131 | static inline int __gpio_is_occupied(unsigned gpio) |
131 | { | 132 | { |
132 | struct pxa_gpio_chip *pxachip; | 133 | struct pxa_gpio_chip *pxachip; |
133 | void __iomem *base; | 134 | void __iomem *base; |
134 | unsigned long gafr = 0, gpdr = 0; | 135 | unsigned long gafr = 0, gpdr = 0; |
135 | int ret, af = 0, dir = 0; | 136 | int ret, af = 0, dir = 0; |
136 | 137 | ||
137 | pxachip = gpio_to_pxachip(gpio); | 138 | pxachip = gpio_to_pxachip(gpio); |
138 | base = gpio_chip_base(&pxachip->chip); | 139 | base = gpio_chip_base(&pxachip->chip); |
139 | gpdr = readl_relaxed(base + GPDR_OFFSET); | 140 | gpdr = readl_relaxed(base + GPDR_OFFSET); |
140 | 141 | ||
141 | switch (gpio_type) { | 142 | switch (gpio_type) { |
142 | case PXA25X_GPIO: | 143 | case PXA25X_GPIO: |
143 | case PXA26X_GPIO: | 144 | case PXA26X_GPIO: |
144 | case PXA27X_GPIO: | 145 | case PXA27X_GPIO: |
145 | gafr = readl_relaxed(base + GAFR_OFFSET); | 146 | gafr = readl_relaxed(base + GAFR_OFFSET); |
146 | af = (gafr >> ((gpio & 0xf) * 2)) & 0x3; | 147 | af = (gafr >> ((gpio & 0xf) * 2)) & 0x3; |
147 | dir = gpdr & GPIO_bit(gpio); | 148 | dir = gpdr & GPIO_bit(gpio); |
148 | 149 | ||
149 | if (__gpio_is_inverted(gpio)) | 150 | if (__gpio_is_inverted(gpio)) |
150 | ret = (af != 1) || (dir == 0); | 151 | ret = (af != 1) || (dir == 0); |
151 | else | 152 | else |
152 | ret = (af != 0) || (dir != 0); | 153 | ret = (af != 0) || (dir != 0); |
153 | break; | 154 | break; |
154 | default: | 155 | default: |
155 | ret = gpdr & GPIO_bit(gpio); | 156 | ret = gpdr & GPIO_bit(gpio); |
156 | break; | 157 | break; |
157 | } | 158 | } |
158 | return ret; | 159 | return ret; |
159 | } | 160 | } |
160 | 161 | ||
161 | #ifdef CONFIG_ARCH_PXA | 162 | #ifdef CONFIG_ARCH_PXA |
162 | static inline int __pxa_gpio_to_irq(int gpio) | 163 | static inline int __pxa_gpio_to_irq(int gpio) |
163 | { | 164 | { |
164 | if (gpio_is_pxa_type(gpio_type)) | 165 | if (gpio_is_pxa_type(gpio_type)) |
165 | return PXA_GPIO_TO_IRQ(gpio); | 166 | return PXA_GPIO_TO_IRQ(gpio); |
166 | return -1; | 167 | return -1; |
167 | } | 168 | } |
168 | 169 | ||
169 | static inline int __pxa_irq_to_gpio(int irq) | 170 | static inline int __pxa_irq_to_gpio(int irq) |
170 | { | 171 | { |
171 | if (gpio_is_pxa_type(gpio_type)) | 172 | if (gpio_is_pxa_type(gpio_type)) |
172 | return irq - PXA_GPIO_TO_IRQ(0); | 173 | return irq - PXA_GPIO_TO_IRQ(0); |
173 | return -1; | 174 | return -1; |
174 | } | 175 | } |
175 | #else | 176 | #else |
176 | static inline int __pxa_gpio_to_irq(int gpio) { return -1; } | 177 | static inline int __pxa_gpio_to_irq(int gpio) { return -1; } |
177 | static inline int __pxa_irq_to_gpio(int irq) { return -1; } | 178 | static inline int __pxa_irq_to_gpio(int irq) { return -1; } |
178 | #endif | 179 | #endif |
179 | 180 | ||
180 | #ifdef CONFIG_ARCH_MMP | 181 | #ifdef CONFIG_ARCH_MMP |
181 | static inline int __mmp_gpio_to_irq(int gpio) | 182 | static inline int __mmp_gpio_to_irq(int gpio) |
182 | { | 183 | { |
183 | if (gpio_is_mmp_type(gpio_type)) | 184 | if (gpio_is_mmp_type(gpio_type)) |
184 | return MMP_GPIO_TO_IRQ(gpio); | 185 | return MMP_GPIO_TO_IRQ(gpio); |
185 | return -1; | 186 | return -1; |
186 | } | 187 | } |
187 | 188 | ||
188 | static inline int __mmp_irq_to_gpio(int irq) | 189 | static inline int __mmp_irq_to_gpio(int irq) |
189 | { | 190 | { |
190 | if (gpio_is_mmp_type(gpio_type)) | 191 | if (gpio_is_mmp_type(gpio_type)) |
191 | return irq - MMP_GPIO_TO_IRQ(0); | 192 | return irq - MMP_GPIO_TO_IRQ(0); |
192 | return -1; | 193 | return -1; |
193 | } | 194 | } |
194 | #else | 195 | #else |
195 | static inline int __mmp_gpio_to_irq(int gpio) { return -1; } | 196 | static inline int __mmp_gpio_to_irq(int gpio) { return -1; } |
196 | static inline int __mmp_irq_to_gpio(int irq) { return -1; } | 197 | static inline int __mmp_irq_to_gpio(int irq) { return -1; } |
197 | #endif | 198 | #endif |
198 | 199 | ||
199 | static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | 200 | static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
200 | { | 201 | { |
201 | int gpio, ret; | 202 | int gpio, ret; |
202 | 203 | ||
203 | gpio = chip->base + offset; | 204 | gpio = chip->base + offset; |
204 | ret = __pxa_gpio_to_irq(gpio); | 205 | ret = __pxa_gpio_to_irq(gpio); |
205 | if (ret >= 0) | 206 | if (ret >= 0) |
206 | return ret; | 207 | return ret; |
207 | return __mmp_gpio_to_irq(gpio); | 208 | return __mmp_gpio_to_irq(gpio); |
208 | } | 209 | } |
209 | 210 | ||
210 | int pxa_irq_to_gpio(int irq) | 211 | int pxa_irq_to_gpio(int irq) |
211 | { | 212 | { |
212 | int ret; | 213 | int ret; |
213 | 214 | ||
214 | ret = __pxa_irq_to_gpio(irq); | 215 | ret = __pxa_irq_to_gpio(irq); |
215 | if (ret >= 0) | 216 | if (ret >= 0) |
216 | return ret; | 217 | return ret; |
217 | return __mmp_irq_to_gpio(irq); | 218 | return __mmp_irq_to_gpio(irq); |
218 | } | 219 | } |
219 | 220 | ||
220 | static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 221 | static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
221 | { | 222 | { |
222 | void __iomem *base = gpio_chip_base(chip); | 223 | void __iomem *base = gpio_chip_base(chip); |
223 | uint32_t value, mask = 1 << offset; | 224 | uint32_t value, mask = 1 << offset; |
224 | unsigned long flags; | 225 | unsigned long flags; |
225 | 226 | ||
226 | spin_lock_irqsave(&gpio_lock, flags); | 227 | spin_lock_irqsave(&gpio_lock, flags); |
227 | 228 | ||
228 | value = readl_relaxed(base + GPDR_OFFSET); | 229 | value = readl_relaxed(base + GPDR_OFFSET); |
229 | if (__gpio_is_inverted(chip->base + offset)) | 230 | if (__gpio_is_inverted(chip->base + offset)) |
230 | value |= mask; | 231 | value |= mask; |
231 | else | 232 | else |
232 | value &= ~mask; | 233 | value &= ~mask; |
233 | writel_relaxed(value, base + GPDR_OFFSET); | 234 | writel_relaxed(value, base + GPDR_OFFSET); |
234 | 235 | ||
235 | spin_unlock_irqrestore(&gpio_lock, flags); | 236 | spin_unlock_irqrestore(&gpio_lock, flags); |
236 | return 0; | 237 | return 0; |
237 | } | 238 | } |
238 | 239 | ||
239 | static int pxa_gpio_direction_output(struct gpio_chip *chip, | 240 | static int pxa_gpio_direction_output(struct gpio_chip *chip, |
240 | unsigned offset, int value) | 241 | unsigned offset, int value) |
241 | { | 242 | { |
242 | void __iomem *base = gpio_chip_base(chip); | 243 | void __iomem *base = gpio_chip_base(chip); |
243 | uint32_t tmp, mask = 1 << offset; | 244 | uint32_t tmp, mask = 1 << offset; |
244 | unsigned long flags; | 245 | unsigned long flags; |
245 | 246 | ||
246 | writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET)); | 247 | writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET)); |
247 | 248 | ||
248 | spin_lock_irqsave(&gpio_lock, flags); | 249 | spin_lock_irqsave(&gpio_lock, flags); |
249 | 250 | ||
250 | tmp = readl_relaxed(base + GPDR_OFFSET); | 251 | tmp = readl_relaxed(base + GPDR_OFFSET); |
251 | if (__gpio_is_inverted(chip->base + offset)) | 252 | if (__gpio_is_inverted(chip->base + offset)) |
252 | tmp &= ~mask; | 253 | tmp &= ~mask; |
253 | else | 254 | else |
254 | tmp |= mask; | 255 | tmp |= mask; |
255 | writel_relaxed(tmp, base + GPDR_OFFSET); | 256 | writel_relaxed(tmp, base + GPDR_OFFSET); |
256 | 257 | ||
257 | spin_unlock_irqrestore(&gpio_lock, flags); | 258 | spin_unlock_irqrestore(&gpio_lock, flags); |
258 | return 0; | 259 | return 0; |
259 | } | 260 | } |
260 | 261 | ||
261 | static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset) | 262 | static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset) |
262 | { | 263 | { |
263 | return readl_relaxed(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset); | 264 | return readl_relaxed(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset); |
264 | } | 265 | } |
265 | 266 | ||
266 | static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 267 | static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
267 | { | 268 | { |
268 | writel_relaxed(1 << offset, gpio_chip_base(chip) + | 269 | writel_relaxed(1 << offset, gpio_chip_base(chip) + |
269 | (value ? GPSR_OFFSET : GPCR_OFFSET)); | 270 | (value ? GPSR_OFFSET : GPCR_OFFSET)); |
270 | } | 271 | } |
271 | 272 | ||
272 | static int __devinit pxa_init_gpio_chip(int gpio_end) | 273 | static int __devinit pxa_init_gpio_chip(int gpio_end, |
274 | int (*set_wake)(unsigned int, unsigned int)) | ||
273 | { | 275 | { |
274 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; | 276 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; |
275 | struct pxa_gpio_chip *chips; | 277 | struct pxa_gpio_chip *chips; |
276 | 278 | ||
277 | chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL); | 279 | chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL); |
278 | if (chips == NULL) { | 280 | if (chips == NULL) { |
279 | pr_err("%s: failed to allocate GPIO chips\n", __func__); | 281 | pr_err("%s: failed to allocate GPIO chips\n", __func__); |
280 | return -ENOMEM; | 282 | return -ENOMEM; |
281 | } | 283 | } |
282 | 284 | ||
283 | for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) { | 285 | for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) { |
284 | struct gpio_chip *c = &chips[i].chip; | 286 | struct gpio_chip *c = &chips[i].chip; |
285 | 287 | ||
286 | sprintf(chips[i].label, "gpio-%d", i); | 288 | sprintf(chips[i].label, "gpio-%d", i); |
287 | chips[i].regbase = gpio_reg_base + BANK_OFF(i); | 289 | chips[i].regbase = gpio_reg_base + BANK_OFF(i); |
290 | chips[i].set_wake = set_wake; | ||
288 | 291 | ||
289 | c->base = gpio; | 292 | c->base = gpio; |
290 | c->label = chips[i].label; | 293 | c->label = chips[i].label; |
291 | 294 | ||
292 | c->direction_input = pxa_gpio_direction_input; | 295 | c->direction_input = pxa_gpio_direction_input; |
293 | c->direction_output = pxa_gpio_direction_output; | 296 | c->direction_output = pxa_gpio_direction_output; |
294 | c->get = pxa_gpio_get; | 297 | c->get = pxa_gpio_get; |
295 | c->set = pxa_gpio_set; | 298 | c->set = pxa_gpio_set; |
296 | c->to_irq = pxa_gpio_to_irq; | 299 | c->to_irq = pxa_gpio_to_irq; |
297 | 300 | ||
298 | /* number of GPIOs on last bank may be less than 32 */ | 301 | /* number of GPIOs on last bank may be less than 32 */ |
299 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; | 302 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; |
300 | gpiochip_add(c); | 303 | gpiochip_add(c); |
301 | } | 304 | } |
302 | pxa_gpio_chips = chips; | 305 | pxa_gpio_chips = chips; |
303 | return 0; | 306 | return 0; |
304 | } | 307 | } |
305 | 308 | ||
306 | /* Update only those GRERx and GFERx edge detection register bits if those | 309 | /* Update only those GRERx and GFERx edge detection register bits if those |
307 | * bits are set in c->irq_mask | 310 | * bits are set in c->irq_mask |
308 | */ | 311 | */ |
309 | static inline void update_edge_detect(struct pxa_gpio_chip *c) | 312 | static inline void update_edge_detect(struct pxa_gpio_chip *c) |
310 | { | 313 | { |
311 | uint32_t grer, gfer; | 314 | uint32_t grer, gfer; |
312 | 315 | ||
313 | grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~c->irq_mask; | 316 | grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~c->irq_mask; |
314 | gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~c->irq_mask; | 317 | gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~c->irq_mask; |
315 | grer |= c->irq_edge_rise & c->irq_mask; | 318 | grer |= c->irq_edge_rise & c->irq_mask; |
316 | gfer |= c->irq_edge_fall & c->irq_mask; | 319 | gfer |= c->irq_edge_fall & c->irq_mask; |
317 | writel_relaxed(grer, c->regbase + GRER_OFFSET); | 320 | writel_relaxed(grer, c->regbase + GRER_OFFSET); |
318 | writel_relaxed(gfer, c->regbase + GFER_OFFSET); | 321 | writel_relaxed(gfer, c->regbase + GFER_OFFSET); |
319 | } | 322 | } |
320 | 323 | ||
321 | static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) | 324 | static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) |
322 | { | 325 | { |
323 | struct pxa_gpio_chip *c; | 326 | struct pxa_gpio_chip *c; |
324 | int gpio = pxa_irq_to_gpio(d->irq); | 327 | int gpio = pxa_irq_to_gpio(d->irq); |
325 | unsigned long gpdr, mask = GPIO_bit(gpio); | 328 | unsigned long gpdr, mask = GPIO_bit(gpio); |
326 | 329 | ||
327 | c = gpio_to_pxachip(gpio); | 330 | c = gpio_to_pxachip(gpio); |
328 | 331 | ||
329 | if (type == IRQ_TYPE_PROBE) { | 332 | if (type == IRQ_TYPE_PROBE) { |
330 | /* Don't mess with enabled GPIOs using preconfigured edges or | 333 | /* Don't mess with enabled GPIOs using preconfigured edges or |
331 | * GPIOs set to alternate function or to output during probe | 334 | * GPIOs set to alternate function or to output during probe |
332 | */ | 335 | */ |
333 | if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio)) | 336 | if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio)) |
334 | return 0; | 337 | return 0; |
335 | 338 | ||
336 | if (__gpio_is_occupied(gpio)) | 339 | if (__gpio_is_occupied(gpio)) |
337 | return 0; | 340 | return 0; |
338 | 341 | ||
339 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | 342 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; |
340 | } | 343 | } |
341 | 344 | ||
342 | gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); | 345 | gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); |
343 | 346 | ||
344 | if (__gpio_is_inverted(gpio)) | 347 | if (__gpio_is_inverted(gpio)) |
345 | writel_relaxed(gpdr | mask, c->regbase + GPDR_OFFSET); | 348 | writel_relaxed(gpdr | mask, c->regbase + GPDR_OFFSET); |
346 | else | 349 | else |
347 | writel_relaxed(gpdr & ~mask, c->regbase + GPDR_OFFSET); | 350 | writel_relaxed(gpdr & ~mask, c->regbase + GPDR_OFFSET); |
348 | 351 | ||
349 | if (type & IRQ_TYPE_EDGE_RISING) | 352 | if (type & IRQ_TYPE_EDGE_RISING) |
350 | c->irq_edge_rise |= mask; | 353 | c->irq_edge_rise |= mask; |
351 | else | 354 | else |
352 | c->irq_edge_rise &= ~mask; | 355 | c->irq_edge_rise &= ~mask; |
353 | 356 | ||
354 | if (type & IRQ_TYPE_EDGE_FALLING) | 357 | if (type & IRQ_TYPE_EDGE_FALLING) |
355 | c->irq_edge_fall |= mask; | 358 | c->irq_edge_fall |= mask; |
356 | else | 359 | else |
357 | c->irq_edge_fall &= ~mask; | 360 | c->irq_edge_fall &= ~mask; |
358 | 361 | ||
359 | update_edge_detect(c); | 362 | update_edge_detect(c); |
360 | 363 | ||
361 | pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, d->irq, gpio, | 364 | pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, d->irq, gpio, |
362 | ((type & IRQ_TYPE_EDGE_RISING) ? " rising" : ""), | 365 | ((type & IRQ_TYPE_EDGE_RISING) ? " rising" : ""), |
363 | ((type & IRQ_TYPE_EDGE_FALLING) ? " falling" : "")); | 366 | ((type & IRQ_TYPE_EDGE_FALLING) ? " falling" : "")); |
364 | return 0; | 367 | return 0; |
365 | } | 368 | } |
366 | 369 | ||
367 | static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | 370 | static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) |
368 | { | 371 | { |
369 | struct pxa_gpio_chip *c; | 372 | struct pxa_gpio_chip *c; |
370 | int loop, gpio, gpio_base, n; | 373 | int loop, gpio, gpio_base, n; |
371 | unsigned long gedr; | 374 | unsigned long gedr; |
372 | 375 | ||
373 | do { | 376 | do { |
374 | loop = 0; | 377 | loop = 0; |
375 | for_each_gpio_chip(gpio, c) { | 378 | for_each_gpio_chip(gpio, c) { |
376 | gpio_base = c->chip.base; | 379 | gpio_base = c->chip.base; |
377 | 380 | ||
378 | gedr = readl_relaxed(c->regbase + GEDR_OFFSET); | 381 | gedr = readl_relaxed(c->regbase + GEDR_OFFSET); |
379 | gedr = gedr & c->irq_mask; | 382 | gedr = gedr & c->irq_mask; |
380 | writel_relaxed(gedr, c->regbase + GEDR_OFFSET); | 383 | writel_relaxed(gedr, c->regbase + GEDR_OFFSET); |
381 | 384 | ||
382 | n = find_first_bit(&gedr, BITS_PER_LONG); | 385 | n = find_first_bit(&gedr, BITS_PER_LONG); |
383 | while (n < BITS_PER_LONG) { | 386 | while (n < BITS_PER_LONG) { |
384 | loop = 1; | 387 | loop = 1; |
385 | 388 | ||
386 | generic_handle_irq(gpio_to_irq(gpio_base + n)); | 389 | generic_handle_irq(gpio_to_irq(gpio_base + n)); |
387 | n = find_next_bit(&gedr, BITS_PER_LONG, n + 1); | 390 | n = find_next_bit(&gedr, BITS_PER_LONG, n + 1); |
388 | } | 391 | } |
389 | } | 392 | } |
390 | } while (loop); | 393 | } while (loop); |
391 | } | 394 | } |
392 | 395 | ||
393 | static void pxa_ack_muxed_gpio(struct irq_data *d) | 396 | static void pxa_ack_muxed_gpio(struct irq_data *d) |
394 | { | 397 | { |
395 | int gpio = pxa_irq_to_gpio(d->irq); | 398 | int gpio = pxa_irq_to_gpio(d->irq); |
396 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | 399 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
397 | 400 | ||
398 | writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET); | 401 | writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET); |
399 | } | 402 | } |
400 | 403 | ||
401 | static void pxa_mask_muxed_gpio(struct irq_data *d) | 404 | static void pxa_mask_muxed_gpio(struct irq_data *d) |
402 | { | 405 | { |
403 | int gpio = pxa_irq_to_gpio(d->irq); | 406 | int gpio = pxa_irq_to_gpio(d->irq); |
404 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | 407 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
405 | uint32_t grer, gfer; | 408 | uint32_t grer, gfer; |
406 | 409 | ||
407 | c->irq_mask &= ~GPIO_bit(gpio); | 410 | c->irq_mask &= ~GPIO_bit(gpio); |
408 | 411 | ||
409 | grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio); | 412 | grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio); |
410 | gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio); | 413 | gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio); |
411 | writel_relaxed(grer, c->regbase + GRER_OFFSET); | 414 | writel_relaxed(grer, c->regbase + GRER_OFFSET); |
412 | writel_relaxed(gfer, c->regbase + GFER_OFFSET); | 415 | writel_relaxed(gfer, c->regbase + GFER_OFFSET); |
413 | } | 416 | } |
414 | 417 | ||
418 | static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on) | ||
419 | { | ||
420 | int gpio = pxa_irq_to_gpio(d->irq); | ||
421 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | ||
422 | |||
423 | if (c->set_wake) | ||
424 | return c->set_wake(gpio, on); | ||
425 | else | ||
426 | return 0; | ||
427 | } | ||
428 | |||
415 | static void pxa_unmask_muxed_gpio(struct irq_data *d) | 429 | static void pxa_unmask_muxed_gpio(struct irq_data *d) |
416 | { | 430 | { |
417 | int gpio = pxa_irq_to_gpio(d->irq); | 431 | int gpio = pxa_irq_to_gpio(d->irq); |
418 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | 432 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
419 | 433 | ||
420 | c->irq_mask |= GPIO_bit(gpio); | 434 | c->irq_mask |= GPIO_bit(gpio); |
421 | update_edge_detect(c); | 435 | update_edge_detect(c); |
422 | } | 436 | } |
423 | 437 | ||
424 | static struct irq_chip pxa_muxed_gpio_chip = { | 438 | static struct irq_chip pxa_muxed_gpio_chip = { |
425 | .name = "GPIO", | 439 | .name = "GPIO", |
426 | .irq_ack = pxa_ack_muxed_gpio, | 440 | .irq_ack = pxa_ack_muxed_gpio, |
427 | .irq_mask = pxa_mask_muxed_gpio, | 441 | .irq_mask = pxa_mask_muxed_gpio, |
428 | .irq_unmask = pxa_unmask_muxed_gpio, | 442 | .irq_unmask = pxa_unmask_muxed_gpio, |
429 | .irq_set_type = pxa_gpio_irq_type, | 443 | .irq_set_type = pxa_gpio_irq_type, |
444 | .irq_set_wake = pxa_gpio_set_wake, | ||
430 | }; | 445 | }; |
431 | 446 | ||
432 | static int pxa_gpio_nums(void) | 447 | static int pxa_gpio_nums(void) |
433 | { | 448 | { |
434 | int count = 0; | 449 | int count = 0; |
435 | 450 | ||
436 | #ifdef CONFIG_ARCH_PXA | 451 | #ifdef CONFIG_ARCH_PXA |
437 | if (cpu_is_pxa25x()) { | 452 | if (cpu_is_pxa25x()) { |
438 | #ifdef CONFIG_CPU_PXA26x | 453 | #ifdef CONFIG_CPU_PXA26x |
439 | count = 89; | 454 | count = 89; |
440 | gpio_type = PXA26X_GPIO; | 455 | gpio_type = PXA26X_GPIO; |
441 | #elif defined(CONFIG_PXA25x) | 456 | #elif defined(CONFIG_PXA25x) |
442 | count = 84; | 457 | count = 84; |
443 | gpio_type = PXA26X_GPIO; | 458 | gpio_type = PXA26X_GPIO; |
444 | #endif /* CONFIG_CPU_PXA26x */ | 459 | #endif /* CONFIG_CPU_PXA26x */ |
445 | } else if (cpu_is_pxa27x()) { | 460 | } else if (cpu_is_pxa27x()) { |
446 | count = 120; | 461 | count = 120; |
447 | gpio_type = PXA27X_GPIO; | 462 | gpio_type = PXA27X_GPIO; |
448 | } else if (cpu_is_pxa93x() || cpu_is_pxa95x()) { | 463 | } else if (cpu_is_pxa93x() || cpu_is_pxa95x()) { |
449 | count = 191; | 464 | count = 191; |
450 | gpio_type = PXA93X_GPIO; | 465 | gpio_type = PXA93X_GPIO; |
451 | } else if (cpu_is_pxa3xx()) { | 466 | } else if (cpu_is_pxa3xx()) { |
452 | count = 127; | 467 | count = 127; |
453 | gpio_type = PXA3XX_GPIO; | 468 | gpio_type = PXA3XX_GPIO; |
454 | } | 469 | } |
455 | #endif /* CONFIG_ARCH_PXA */ | 470 | #endif /* CONFIG_ARCH_PXA */ |
456 | 471 | ||
457 | #ifdef CONFIG_ARCH_MMP | 472 | #ifdef CONFIG_ARCH_MMP |
458 | if (cpu_is_pxa168() || cpu_is_pxa910()) { | 473 | if (cpu_is_pxa168() || cpu_is_pxa910()) { |
459 | count = 127; | 474 | count = 127; |
460 | gpio_type = MMP_GPIO; | 475 | gpio_type = MMP_GPIO; |
461 | } else if (cpu_is_mmp2()) { | 476 | } else if (cpu_is_mmp2()) { |
462 | count = 191; | 477 | count = 191; |
463 | gpio_type = MMP2_GPIO; | 478 | gpio_type = MMP2_GPIO; |
464 | } | 479 | } |
465 | #endif /* CONFIG_ARCH_MMP */ | 480 | #endif /* CONFIG_ARCH_MMP */ |
466 | return count; | 481 | return count; |
467 | } | 482 | } |
468 | 483 | ||
469 | static int __devinit pxa_gpio_probe(struct platform_device *pdev) | 484 | static int __devinit pxa_gpio_probe(struct platform_device *pdev) |
470 | { | 485 | { |
471 | struct pxa_gpio_chip *c; | 486 | struct pxa_gpio_chip *c; |
472 | struct resource *res; | 487 | struct resource *res; |
473 | struct clk *clk; | 488 | struct clk *clk; |
489 | struct pxa_gpio_platform_data *info; | ||
474 | int gpio, irq, ret; | 490 | int gpio, irq, ret; |
475 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; | 491 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; |
476 | 492 | ||
477 | pxa_last_gpio = pxa_gpio_nums(); | 493 | pxa_last_gpio = pxa_gpio_nums(); |
478 | if (!pxa_last_gpio) | 494 | if (!pxa_last_gpio) |
479 | return -EINVAL; | 495 | return -EINVAL; |
480 | 496 | ||
481 | irq0 = platform_get_irq_byname(pdev, "gpio0"); | 497 | irq0 = platform_get_irq_byname(pdev, "gpio0"); |
482 | irq1 = platform_get_irq_byname(pdev, "gpio1"); | 498 | irq1 = platform_get_irq_byname(pdev, "gpio1"); |
483 | irq_mux = platform_get_irq_byname(pdev, "gpio_mux"); | 499 | irq_mux = platform_get_irq_byname(pdev, "gpio_mux"); |
484 | if ((irq0 > 0 && irq1 <= 0) || (irq0 <= 0 && irq1 > 0) | 500 | if ((irq0 > 0 && irq1 <= 0) || (irq0 <= 0 && irq1 > 0) |
485 | || (irq_mux <= 0)) | 501 | || (irq_mux <= 0)) |
486 | return -EINVAL; | 502 | return -EINVAL; |
487 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 503 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
488 | if (!res) | 504 | if (!res) |
489 | return -EINVAL; | 505 | return -EINVAL; |
490 | gpio_reg_base = ioremap(res->start, resource_size(res)); | 506 | gpio_reg_base = ioremap(res->start, resource_size(res)); |
491 | if (!gpio_reg_base) | 507 | if (!gpio_reg_base) |
492 | return -EINVAL; | 508 | return -EINVAL; |
493 | 509 | ||
494 | if (irq0 > 0) | 510 | if (irq0 > 0) |
495 | gpio_offset = 2; | 511 | gpio_offset = 2; |
496 | 512 | ||
497 | clk = clk_get(&pdev->dev, NULL); | 513 | clk = clk_get(&pdev->dev, NULL); |
498 | if (IS_ERR(clk)) { | 514 | if (IS_ERR(clk)) { |
499 | dev_err(&pdev->dev, "Error %ld to get gpio clock\n", | 515 | dev_err(&pdev->dev, "Error %ld to get gpio clock\n", |
500 | PTR_ERR(clk)); | 516 | PTR_ERR(clk)); |
501 | iounmap(gpio_reg_base); | 517 | iounmap(gpio_reg_base); |
502 | return PTR_ERR(clk); | 518 | return PTR_ERR(clk); |
503 | } | 519 | } |
504 | ret = clk_prepare(clk); | 520 | ret = clk_prepare(clk); |
505 | if (ret) { | 521 | if (ret) { |
506 | clk_put(clk); | 522 | clk_put(clk); |
507 | iounmap(gpio_reg_base); | 523 | iounmap(gpio_reg_base); |
508 | return ret; | 524 | return ret; |
509 | } | 525 | } |
510 | ret = clk_enable(clk); | 526 | ret = clk_enable(clk); |
511 | if (ret) { | 527 | if (ret) { |
512 | clk_unprepare(clk); | 528 | clk_unprepare(clk); |
513 | clk_put(clk); | 529 | clk_put(clk); |
514 | iounmap(gpio_reg_base); | 530 | iounmap(gpio_reg_base); |
515 | return ret; | 531 | return ret; |
516 | } | 532 | } |
517 | 533 | ||
518 | /* Initialize GPIO chips */ | 534 | /* Initialize GPIO chips */ |
519 | pxa_init_gpio_chip(pxa_last_gpio); | 535 | info = dev_get_platdata(&pdev->dev); |
536 | pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL); | ||
520 | 537 | ||
521 | /* clear all GPIO edge detects */ | 538 | /* clear all GPIO edge detects */ |
522 | for_each_gpio_chip(gpio, c) { | 539 | for_each_gpio_chip(gpio, c) { |
523 | writel_relaxed(0, c->regbase + GFER_OFFSET); | 540 | writel_relaxed(0, c->regbase + GFER_OFFSET); |
524 | writel_relaxed(0, c->regbase + GRER_OFFSET); | 541 | writel_relaxed(0, c->regbase + GRER_OFFSET); |
525 | writel_relaxed(~0,c->regbase + GEDR_OFFSET); | 542 | writel_relaxed(~0,c->regbase + GEDR_OFFSET); |
526 | /* unmask GPIO edge detect for AP side */ | 543 | /* unmask GPIO edge detect for AP side */ |
527 | if (gpio_is_mmp_type(gpio_type)) | 544 | if (gpio_is_mmp_type(gpio_type)) |
528 | writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); | 545 | writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); |
529 | } | 546 | } |
530 | 547 | ||
531 | #ifdef CONFIG_ARCH_PXA | 548 | #ifdef CONFIG_ARCH_PXA |
532 | irq = gpio_to_irq(0); | 549 | irq = gpio_to_irq(0); |
533 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | 550 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, |
534 | handle_edge_irq); | 551 | handle_edge_irq); |
535 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 552 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
536 | irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); | 553 | irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); |
537 | 554 | ||
538 | irq = gpio_to_irq(1); | 555 | irq = gpio_to_irq(1); |
539 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | 556 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, |
540 | handle_edge_irq); | 557 | handle_edge_irq); |
541 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 558 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
542 | irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); | 559 | irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); |
543 | #endif | 560 | #endif |
544 | 561 | ||
545 | for (irq = gpio_to_irq(gpio_offset); | 562 | for (irq = gpio_to_irq(gpio_offset); |
546 | irq <= gpio_to_irq(pxa_last_gpio); irq++) { | 563 | irq <= gpio_to_irq(pxa_last_gpio); irq++) { |
547 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | 564 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, |
548 | handle_edge_irq); | 565 | handle_edge_irq); |
549 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 566 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
550 | } | 567 | } |
551 | 568 | ||
552 | irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); | 569 | irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); |
553 | return 0; | 570 | return 0; |
554 | } | 571 | } |
555 | 572 | ||
556 | static struct platform_driver pxa_gpio_driver = { | 573 | static struct platform_driver pxa_gpio_driver = { |
557 | .probe = pxa_gpio_probe, | 574 | .probe = pxa_gpio_probe, |
558 | .driver = { | 575 | .driver = { |
559 | .name = "pxa-gpio", | 576 | .name = "pxa-gpio", |
560 | }, | 577 | }, |
561 | }; | 578 | }; |
562 | 579 | ||
563 | static int __init pxa_gpio_init(void) | 580 | static int __init pxa_gpio_init(void) |
564 | { | 581 | { |
565 | return platform_driver_register(&pxa_gpio_driver); | 582 | return platform_driver_register(&pxa_gpio_driver); |
566 | } | 583 | } |
567 | postcore_initcall(pxa_gpio_init); | 584 | postcore_initcall(pxa_gpio_init); |
568 | 585 | ||
569 | #ifdef CONFIG_PM | 586 | #ifdef CONFIG_PM |
570 | static int pxa_gpio_suspend(void) | 587 | static int pxa_gpio_suspend(void) |
571 | { | 588 | { |
572 | struct pxa_gpio_chip *c; | 589 | struct pxa_gpio_chip *c; |
573 | int gpio; | 590 | int gpio; |
574 | 591 | ||
575 | for_each_gpio_chip(gpio, c) { | 592 | for_each_gpio_chip(gpio, c) { |
576 | c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET); | 593 | c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET); |
577 | c->saved_gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); | 594 | c->saved_gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); |
578 | c->saved_grer = readl_relaxed(c->regbase + GRER_OFFSET); | 595 | c->saved_grer = readl_relaxed(c->regbase + GRER_OFFSET); |
579 | c->saved_gfer = readl_relaxed(c->regbase + GFER_OFFSET); | 596 | c->saved_gfer = readl_relaxed(c->regbase + GFER_OFFSET); |
580 | 597 | ||
581 | /* Clear GPIO transition detect bits */ | 598 | /* Clear GPIO transition detect bits */ |
582 | writel_relaxed(0xffffffff, c->regbase + GEDR_OFFSET); | 599 | writel_relaxed(0xffffffff, c->regbase + GEDR_OFFSET); |
583 | } | 600 | } |
584 | return 0; | 601 | return 0; |
585 | } | 602 | } |
586 | 603 | ||
587 | static void pxa_gpio_resume(void) | 604 | static void pxa_gpio_resume(void) |
588 | { | 605 | { |
589 | struct pxa_gpio_chip *c; | 606 | struct pxa_gpio_chip *c; |
590 | int gpio; | 607 | int gpio; |
591 | 608 | ||
592 | for_each_gpio_chip(gpio, c) { | 609 | for_each_gpio_chip(gpio, c) { |
593 | /* restore level with set/clear */ | 610 | /* restore level with set/clear */ |
594 | writel_relaxed( c->saved_gplr, c->regbase + GPSR_OFFSET); | 611 | writel_relaxed( c->saved_gplr, c->regbase + GPSR_OFFSET); |
595 | writel_relaxed(~c->saved_gplr, c->regbase + GPCR_OFFSET); | 612 | writel_relaxed(~c->saved_gplr, c->regbase + GPCR_OFFSET); |
596 | 613 | ||
597 | writel_relaxed(c->saved_grer, c->regbase + GRER_OFFSET); | 614 | writel_relaxed(c->saved_grer, c->regbase + GRER_OFFSET); |
598 | writel_relaxed(c->saved_gfer, c->regbase + GFER_OFFSET); | 615 | writel_relaxed(c->saved_gfer, c->regbase + GFER_OFFSET); |
599 | writel_relaxed(c->saved_gpdr, c->regbase + GPDR_OFFSET); | 616 | writel_relaxed(c->saved_gpdr, c->regbase + GPDR_OFFSET); |
600 | } | 617 | } |
601 | } | 618 | } |
602 | #else | 619 | #else |
603 | #define pxa_gpio_suspend NULL | 620 | #define pxa_gpio_suspend NULL |
604 | #define pxa_gpio_resume NULL | 621 | #define pxa_gpio_resume NULL |
605 | #endif | 622 | #endif |
606 | 623 | ||
607 | struct syscore_ops pxa_gpio_syscore_ops = { | 624 | struct syscore_ops pxa_gpio_syscore_ops = { |
608 | .suspend = pxa_gpio_suspend, | 625 | .suspend = pxa_gpio_suspend, |
609 | .resume = pxa_gpio_resume, | 626 | .resume = pxa_gpio_resume, |
610 | }; | 627 | }; |
611 | 628 | ||
612 | static int __init pxa_gpio_sysinit(void) | 629 | static int __init pxa_gpio_sysinit(void) |
613 | { | 630 | { |
614 | register_syscore_ops(&pxa_gpio_syscore_ops); | 631 | register_syscore_ops(&pxa_gpio_syscore_ops); |
615 | return 0; | 632 | return 0; |
616 | } | 633 | } |
617 | postcore_initcall(pxa_gpio_sysinit); | 634 | postcore_initcall(pxa_gpio_sysinit); |
618 | 635 |
include/linux/gpio-pxa.h
1 | #ifndef __GPIO_PXA_H | 1 | #ifndef __GPIO_PXA_H |
2 | #define __GPIO_PXA_H | 2 | #define __GPIO_PXA_H |
3 | 3 | ||
4 | #define GPIO_bit(x) (1 << ((x) & 0x1f)) | 4 | #define GPIO_bit(x) (1 << ((x) & 0x1f)) |
5 | 5 | ||
6 | #define gpio_to_bank(gpio) ((gpio) >> 5) | 6 | #define gpio_to_bank(gpio) ((gpio) >> 5) |
7 | 7 | ||
8 | /* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85). | 8 | /* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85). |
9 | * Those cases currently cause holes in the GPIO number space, the | 9 | * Those cases currently cause holes in the GPIO number space, the |
10 | * actual number of the last GPIO is recorded by 'pxa_last_gpio'. | 10 | * actual number of the last GPIO is recorded by 'pxa_last_gpio'. |
11 | */ | 11 | */ |
12 | extern int pxa_last_gpio; | 12 | extern int pxa_last_gpio; |
13 | 13 | ||
14 | extern int pxa_irq_to_gpio(int irq); | 14 | extern int pxa_irq_to_gpio(int irq); |
15 | 15 | ||
16 | struct pxa_gpio_platform_data { | ||
17 | int (*gpio_set_wake)(unsigned int gpio, unsigned int on); | ||
18 | }; | ||
19 | |||
16 | #endif /* __GPIO_PXA_H */ | 20 | #endif /* __GPIO_PXA_H */ |
17 | 21 |