diff options
Diffstat (limited to 'arch/arm/mach-pxa/pxa25x.c')
-rw-r--r-- | arch/arm/mach-pxa/pxa25x.c | 117 |
1 files changed, 62 insertions, 55 deletions
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index de53f2e4aa39..fed363cec9c6 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -21,8 +21,10 @@ | |||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/suspend.h> | 23 | #include <linux/suspend.h> |
24 | #include <linux/sysdev.h> | 24 | #include <linux/syscore_ops.h> |
25 | #include <linux/irq.h> | ||
25 | 26 | ||
27 | #include <asm/mach/map.h> | ||
26 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
27 | #include <mach/irqs.h> | 29 | #include <mach/irqs.h> |
28 | #include <mach/gpio.h> | 30 | #include <mach/gpio.h> |
@@ -30,6 +32,7 @@ | |||
30 | #include <mach/reset.h> | 32 | #include <mach/reset.h> |
31 | #include <mach/pm.h> | 33 | #include <mach/pm.h> |
32 | #include <mach/dma.h> | 34 | #include <mach/dma.h> |
35 | #include <mach/smemc.h> | ||
33 | 36 | ||
34 | #include "generic.h" | 37 | #include "generic.h" |
35 | #include "devices.h" | 38 | #include "devices.h" |
@@ -90,23 +93,21 @@ unsigned int pxa25x_get_clk_frequency_khz(int info) | |||
90 | return (turbo & 1) ? (N/1000) : (M/1000); | 93 | return (turbo & 1) ? (N/1000) : (M/1000); |
91 | } | 94 | } |
92 | 95 | ||
93 | /* | 96 | static unsigned long clk_pxa25x_mem_getrate(struct clk *clk) |
94 | * Return the current memory clock frequency in units of 10kHz | ||
95 | */ | ||
96 | unsigned int pxa25x_get_memclk_frequency_10khz(void) | ||
97 | { | 97 | { |
98 | return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000; | 98 | return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK; |
99 | } | 99 | } |
100 | 100 | ||
101 | static unsigned long clk_pxa25x_lcd_getrate(struct clk *clk) | 101 | static const struct clkops clk_pxa25x_mem_ops = { |
102 | { | 102 | .enable = clk_dummy_enable, |
103 | return pxa25x_get_memclk_frequency_10khz() * 10000; | 103 | .disable = clk_dummy_disable, |
104 | } | 104 | .getrate = clk_pxa25x_mem_getrate, |
105 | }; | ||
105 | 106 | ||
106 | static const struct clkops clk_pxa25x_lcd_ops = { | 107 | static const struct clkops clk_pxa25x_lcd_ops = { |
107 | .enable = clk_cken_enable, | 108 | .enable = clk_pxa2xx_cken_enable, |
108 | .disable = clk_cken_disable, | 109 | .disable = clk_pxa2xx_cken_disable, |
109 | .getrate = clk_pxa25x_lcd_getrate, | 110 | .getrate = clk_pxa25x_mem_getrate, |
110 | }; | 111 | }; |
111 | 112 | ||
112 | static unsigned long gpio12_config_32k[] = { | 113 | static unsigned long gpio12_config_32k[] = { |
@@ -160,31 +161,30 @@ static const struct clkops clk_pxa25x_gpio11_ops = { | |||
160 | * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz | 161 | * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz |
161 | * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) | 162 | * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) |
162 | */ | 163 | */ |
163 | static DEFINE_CKEN(pxa25x_hwuart, HWUART, 14745600, 1); | ||
164 | |||
165 | static struct clk_lookup pxa25x_hwuart_clkreg = | ||
166 | INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL); | ||
167 | 164 | ||
168 | /* | 165 | /* |
169 | * PXA 2xx clock declarations. | 166 | * PXA 2xx clock declarations. |
170 | */ | 167 | */ |
168 | static DEFINE_PXA2_CKEN(pxa25x_hwuart, HWUART, 14745600, 1); | ||
169 | static DEFINE_PXA2_CKEN(pxa25x_ffuart, FFUART, 14745600, 1); | ||
170 | static DEFINE_PXA2_CKEN(pxa25x_btuart, BTUART, 14745600, 1); | ||
171 | static DEFINE_PXA2_CKEN(pxa25x_stuart, STUART, 14745600, 1); | ||
172 | static DEFINE_PXA2_CKEN(pxa25x_usb, USB, 47923000, 5); | ||
173 | static DEFINE_PXA2_CKEN(pxa25x_mmc, MMC, 19169000, 0); | ||
174 | static DEFINE_PXA2_CKEN(pxa25x_i2c, I2C, 31949000, 0); | ||
175 | static DEFINE_PXA2_CKEN(pxa25x_ssp, SSP, 3686400, 0); | ||
176 | static DEFINE_PXA2_CKEN(pxa25x_nssp, NSSP, 3686400, 0); | ||
177 | static DEFINE_PXA2_CKEN(pxa25x_assp, ASSP, 3686400, 0); | ||
178 | static DEFINE_PXA2_CKEN(pxa25x_pwm0, PWM0, 3686400, 0); | ||
179 | static DEFINE_PXA2_CKEN(pxa25x_pwm1, PWM1, 3686400, 0); | ||
180 | static DEFINE_PXA2_CKEN(pxa25x_ac97, AC97, 24576000, 0); | ||
181 | static DEFINE_PXA2_CKEN(pxa25x_i2s, I2S, 14745600, 0); | ||
182 | static DEFINE_PXA2_CKEN(pxa25x_ficp, FICP, 47923000, 0); | ||
183 | |||
171 | static DEFINE_CK(pxa25x_lcd, LCD, &clk_pxa25x_lcd_ops); | 184 | static DEFINE_CK(pxa25x_lcd, LCD, &clk_pxa25x_lcd_ops); |
172 | static DEFINE_CKEN(pxa25x_ffuart, FFUART, 14745600, 1); | ||
173 | static DEFINE_CKEN(pxa25x_btuart, BTUART, 14745600, 1); | ||
174 | static DEFINE_CKEN(pxa25x_stuart, STUART, 14745600, 1); | ||
175 | static DEFINE_CKEN(pxa25x_usb, USB, 47923000, 5); | ||
176 | static DEFINE_CLK(pxa25x_gpio11, &clk_pxa25x_gpio11_ops, 3686400, 0); | 185 | static DEFINE_CLK(pxa25x_gpio11, &clk_pxa25x_gpio11_ops, 3686400, 0); |
177 | static DEFINE_CLK(pxa25x_gpio12, &clk_pxa25x_gpio12_ops, 32768, 0); | 186 | static DEFINE_CLK(pxa25x_gpio12, &clk_pxa25x_gpio12_ops, 32768, 0); |
178 | static DEFINE_CKEN(pxa25x_mmc, MMC, 19169000, 0); | 187 | static DEFINE_CLK(pxa25x_mem, &clk_pxa25x_mem_ops, 0, 0); |
179 | static DEFINE_CKEN(pxa25x_i2c, I2C, 31949000, 0); | ||
180 | static DEFINE_CKEN(pxa25x_ssp, SSP, 3686400, 0); | ||
181 | static DEFINE_CKEN(pxa25x_nssp, NSSP, 3686400, 0); | ||
182 | static DEFINE_CKEN(pxa25x_assp, ASSP, 3686400, 0); | ||
183 | static DEFINE_CKEN(pxa25x_pwm0, PWM0, 3686400, 0); | ||
184 | static DEFINE_CKEN(pxa25x_pwm1, PWM1, 3686400, 0); | ||
185 | static DEFINE_CKEN(pxa25x_ac97, AC97, 24576000, 0); | ||
186 | static DEFINE_CKEN(pxa25x_i2s, I2S, 14745600, 0); | ||
187 | static DEFINE_CKEN(pxa25x_ficp, FICP, 47923000, 0); | ||
188 | 188 | ||
189 | static struct clk_lookup pxa25x_clkregs[] = { | 189 | static struct clk_lookup pxa25x_clkregs[] = { |
190 | INIT_CLKREG(&clk_pxa25x_lcd, "pxa2xx-fb", NULL), | 190 | INIT_CLKREG(&clk_pxa25x_lcd, "pxa2xx-fb", NULL), |
@@ -205,8 +205,12 @@ static struct clk_lookup pxa25x_clkregs[] = { | |||
205 | INIT_CLKREG(&clk_pxa25x_ac97, NULL, "AC97CLK"), | 205 | INIT_CLKREG(&clk_pxa25x_ac97, NULL, "AC97CLK"), |
206 | INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"), | 206 | INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"), |
207 | INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"), | 207 | INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"), |
208 | INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL), | ||
208 | }; | 209 | }; |
209 | 210 | ||
211 | static struct clk_lookup pxa25x_hwuart_clkreg = | ||
212 | INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL); | ||
213 | |||
210 | #ifdef CONFIG_PM | 214 | #ifdef CONFIG_PM |
211 | 215 | ||
212 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | 216 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
@@ -219,20 +223,17 @@ static struct clk_lookup pxa25x_clkregs[] = { | |||
219 | */ | 223 | */ |
220 | enum { | 224 | enum { |
221 | SLEEP_SAVE_PSTR, | 225 | SLEEP_SAVE_PSTR, |
222 | SLEEP_SAVE_CKEN, | ||
223 | SLEEP_SAVE_COUNT | 226 | SLEEP_SAVE_COUNT |
224 | }; | 227 | }; |
225 | 228 | ||
226 | 229 | ||
227 | static void pxa25x_cpu_pm_save(unsigned long *sleep_save) | 230 | static void pxa25x_cpu_pm_save(unsigned long *sleep_save) |
228 | { | 231 | { |
229 | SAVE(CKEN); | ||
230 | SAVE(PSTR); | 232 | SAVE(PSTR); |
231 | } | 233 | } |
232 | 234 | ||
233 | static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) | 235 | static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) |
234 | { | 236 | { |
235 | RESTORE(CKEN); | ||
236 | RESTORE(PSTR); | 237 | RESTORE(PSTR); |
237 | } | 238 | } |
238 | 239 | ||
@@ -243,7 +244,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state) | |||
243 | 244 | ||
244 | switch (state) { | 245 | switch (state) { |
245 | case PM_SUSPEND_MEM: | 246 | case PM_SUSPEND_MEM: |
246 | pxa25x_cpu_suspend(PWRMODE_SLEEP); | 247 | pxa25x_cpu_suspend(PWRMODE_SLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET); |
247 | break; | 248 | break; |
248 | } | 249 | } |
249 | } | 250 | } |
@@ -251,7 +252,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state) | |||
251 | static int pxa25x_cpu_pm_prepare(void) | 252 | static int pxa25x_cpu_pm_prepare(void) |
252 | { | 253 | { |
253 | /* set resume return address */ | 254 | /* set resume return address */ |
254 | PSPR = virt_to_phys(pxa_cpu_resume); | 255 | PSPR = virt_to_phys(cpu_resume); |
255 | return 0; | 256 | return 0; |
256 | } | 257 | } |
257 | 258 | ||
@@ -282,15 +283,15 @@ static inline void pxa25x_init_pm(void) {} | |||
282 | /* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm | 283 | /* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm |
283 | */ | 284 | */ |
284 | 285 | ||
285 | static int pxa25x_set_wake(unsigned int irq, unsigned int on) | 286 | static int pxa25x_set_wake(struct irq_data *d, unsigned int on) |
286 | { | 287 | { |
287 | int gpio = IRQ_TO_GPIO(irq); | 288 | int gpio = irq_to_gpio(d->irq); |
288 | uint32_t mask = 0; | 289 | uint32_t mask = 0; |
289 | 290 | ||
290 | if (gpio >= 0 && gpio < 85) | 291 | if (gpio >= 0 && gpio < 85) |
291 | return gpio_set_wake(gpio, on); | 292 | return gpio_set_wake(gpio, on); |
292 | 293 | ||
293 | if (irq == IRQ_RTCAlrm) { | 294 | if (d->irq == IRQ_RTCAlrm) { |
294 | mask = PWER_RTC; | 295 | mask = PWER_RTC; |
295 | goto set_pwer; | 296 | goto set_pwer; |
296 | } | 297 | } |
@@ -320,6 +321,22 @@ void __init pxa26x_init_irq(void) | |||
320 | } | 321 | } |
321 | #endif | 322 | #endif |
322 | 323 | ||
324 | static struct map_desc pxa25x_io_desc[] __initdata = { | ||
325 | { /* Mem Ctl */ | ||
326 | .virtual = SMEMC_VIRT, | ||
327 | .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE), | ||
328 | .length = 0x00200000, | ||
329 | .type = MT_DEVICE | ||
330 | }, | ||
331 | }; | ||
332 | |||
333 | void __init pxa25x_map_io(void) | ||
334 | { | ||
335 | pxa_map_io(); | ||
336 | iotable_init(ARRAY_AND_SIZE(pxa25x_io_desc)); | ||
337 | pxa25x_get_clk_frequency_khz(1); | ||
338 | } | ||
339 | |||
323 | static struct platform_device *pxa25x_devices[] __initdata = { | 340 | static struct platform_device *pxa25x_devices[] __initdata = { |
324 | &pxa25x_device_udc, | 341 | &pxa25x_device_udc, |
325 | &pxa_device_pmu, | 342 | &pxa_device_pmu, |
@@ -330,21 +347,12 @@ static struct platform_device *pxa25x_devices[] __initdata = { | |||
330 | &pxa25x_device_assp, | 347 | &pxa25x_device_assp, |
331 | &pxa25x_device_pwm0, | 348 | &pxa25x_device_pwm0, |
332 | &pxa25x_device_pwm1, | 349 | &pxa25x_device_pwm1, |
333 | }; | 350 | &pxa_device_asoc_platform, |
334 | |||
335 | static struct sys_device pxa25x_sysdev[] = { | ||
336 | { | ||
337 | .cls = &pxa_irq_sysclass, | ||
338 | }, { | ||
339 | .cls = &pxa2xx_mfp_sysclass, | ||
340 | }, { | ||
341 | .cls = &pxa_gpio_sysclass, | ||
342 | }, | ||
343 | }; | 351 | }; |
344 | 352 | ||
345 | static int __init pxa25x_init(void) | 353 | static int __init pxa25x_init(void) |
346 | { | 354 | { |
347 | int i, ret = 0; | 355 | int ret = 0; |
348 | 356 | ||
349 | if (cpu_is_pxa25x()) { | 357 | if (cpu_is_pxa25x()) { |
350 | 358 | ||
@@ -357,11 +365,10 @@ static int __init pxa25x_init(void) | |||
357 | 365 | ||
358 | pxa25x_init_pm(); | 366 | pxa25x_init_pm(); |
359 | 367 | ||
360 | for (i = 0; i < ARRAY_SIZE(pxa25x_sysdev); i++) { | 368 | register_syscore_ops(&pxa_irq_syscore_ops); |
361 | ret = sysdev_register(&pxa25x_sysdev[i]); | 369 | register_syscore_ops(&pxa2xx_mfp_syscore_ops); |
362 | if (ret) | 370 | register_syscore_ops(&pxa_gpio_syscore_ops); |
363 | pr_err("failed to register sysdev[%d]\n", i); | 371 | register_syscore_ops(&pxa2xx_clock_syscore_ops); |
364 | } | ||
365 | 372 | ||
366 | ret = platform_add_devices(pxa25x_devices, | 373 | ret = platform_add_devices(pxa25x_devices, |
367 | ARRAY_SIZE(pxa25x_devices)); | 374 | ARRAY_SIZE(pxa25x_devices)); |