diff options
Diffstat (limited to 'arch/arm/mach-pxa/generic.c')
| -rw-r--r-- | arch/arm/mach-pxa/generic.c | 184 |
1 files changed, 125 insertions, 59 deletions
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 5510f6fdce55..1c34946ee16e 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c | |||
| @@ -25,10 +25,6 @@ | |||
| 25 | #include <linux/pm.h> | 25 | #include <linux/pm.h> |
| 26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
| 27 | 27 | ||
| 28 | #include <linux/sched.h> | ||
| 29 | #include <asm/cnt32_to_63.h> | ||
| 30 | #include <asm/div64.h> | ||
| 31 | |||
| 32 | #include <asm/hardware.h> | 28 | #include <asm/hardware.h> |
| 33 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
| 34 | #include <asm/system.h> | 30 | #include <asm/system.h> |
| @@ -47,66 +43,39 @@ | |||
| 47 | #include "generic.h" | 43 | #include "generic.h" |
| 48 | 44 | ||
| 49 | /* | 45 | /* |
| 50 | * This is the PXA2xx sched_clock implementation. This has a resolution | 46 | * Get the clock frequency as reflected by CCCR and the turbo flag. |
| 51 | * of at least 308ns and a maximum value that depends on the value of | 47 | * We assume these values have been applied via a fcs. |
| 52 | * CLOCK_TICK_RATE. | 48 | * If info is not 0 we also display the current settings. |
| 53 | * | ||
| 54 | * The return value is guaranteed to be monotonic in that range as | ||
| 55 | * long as there is always less than 582 seconds between successive | ||
| 56 | * calls to this function. | ||
| 57 | */ | 49 | */ |
| 58 | unsigned long long sched_clock(void) | 50 | unsigned int get_clk_frequency_khz(int info) |
| 59 | { | 51 | { |
| 60 | unsigned long long v = cnt32_to_63(OSCR); | 52 | if (cpu_is_pxa21x() || cpu_is_pxa25x()) |
| 61 | /* Note: top bit ov v needs cleared unless multiplier is even. */ | 53 | return pxa25x_get_clk_frequency_khz(info); |
| 62 | 54 | else if (cpu_is_pxa27x()) | |
| 63 | #if CLOCK_TICK_RATE == 3686400 | 55 | return pxa27x_get_clk_frequency_khz(info); |
| 64 | /* 1E9 / 3686400 => 78125 / 288, max value = 32025597s (370 days). */ | 56 | else |
| 65 | /* The <<1 is used to get rid of tick.hi top bit */ | 57 | return pxa3xx_get_clk_frequency_khz(info); |
| 66 | v *= 78125<<1; | 58 | } |
| 67 | do_div(v, 288<<1); | 59 | EXPORT_SYMBOL(get_clk_frequency_khz); |
| 68 | #elif CLOCK_TICK_RATE == 3250000 | ||
| 69 | /* 1E9 / 3250000 => 4000 / 13, max value = 709490156s (8211 days) */ | ||
| 70 | v *= 4000; | ||
| 71 | do_div(v, 13); | ||
| 72 | #elif CLOCK_TICK_RATE == 3249600 | ||
| 73 | /* 1E9 / 3249600 => 625000 / 2031, max value = 4541295s (52 days) */ | ||
| 74 | v *= 625000; | ||
| 75 | do_div(v, 2031); | ||
| 76 | #else | ||
| 77 | #warning "consider fixing sched_clock for your value of CLOCK_TICK_RATE" | ||
| 78 | /* | ||
| 79 | * 96-bit math to perform tick * NSEC_PER_SEC / CLOCK_TICK_RATE for | ||
| 80 | * any value of CLOCK_TICK_RATE. Max value is in the 80 thousand | ||
| 81 | * years range and truncation to unsigned long long limits it to | ||
| 82 | * sched_clock's max range of ~584 years. This is nice but with | ||
| 83 | * higher computation cost. | ||
| 84 | */ | ||
| 85 | { | ||
| 86 | union { | ||
| 87 | unsigned long long val; | ||
| 88 | struct { unsigned long lo, hi; }; | ||
| 89 | } x; | ||
| 90 | unsigned long long y; | ||
| 91 | |||
| 92 | x.val = v; | ||
| 93 | x.hi &= 0x7fffffff; | ||
| 94 | y = (unsigned long long)x.lo * NSEC_PER_SEC; | ||
| 95 | x.lo = y; | ||
| 96 | y = (y >> 32) + (unsigned long long)x.hi * NSEC_PER_SEC; | ||
| 97 | x.hi = do_div(y, CLOCK_TICK_RATE); | ||
| 98 | do_div(x.val, CLOCK_TICK_RATE); | ||
| 99 | x.hi += y; | ||
| 100 | v = x.val; | ||
| 101 | } | ||
| 102 | #endif | ||
| 103 | 60 | ||
| 104 | return v; | 61 | /* |
| 62 | * Return the current memory clock frequency in units of 10kHz | ||
| 63 | */ | ||
| 64 | unsigned int get_memclk_frequency_10khz(void) | ||
| 65 | { | ||
| 66 | if (cpu_is_pxa21x() || cpu_is_pxa25x()) | ||
| 67 | return pxa25x_get_memclk_frequency_10khz(); | ||
| 68 | else if (cpu_is_pxa27x()) | ||
| 69 | return pxa27x_get_memclk_frequency_10khz(); | ||
| 70 | else | ||
| 71 | return pxa3xx_get_memclk_frequency_10khz(); | ||
| 105 | } | 72 | } |
| 73 | EXPORT_SYMBOL(get_memclk_frequency_10khz); | ||
| 106 | 74 | ||
| 107 | /* | 75 | /* |
| 108 | * Handy function to set GPIO alternate functions | 76 | * Handy function to set GPIO alternate functions |
| 109 | */ | 77 | */ |
| 78 | int pxa_last_gpio; | ||
| 110 | 79 | ||
| 111 | int pxa_gpio_mode(int gpio_mode) | 80 | int pxa_gpio_mode(int gpio_mode) |
| 112 | { | 81 | { |
| @@ -115,7 +84,7 @@ int pxa_gpio_mode(int gpio_mode) | |||
| 115 | int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; | 84 | int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; |
| 116 | int gafr; | 85 | int gafr; |
| 117 | 86 | ||
| 118 | if (gpio > PXA_LAST_GPIO) | 87 | if (gpio > pxa_last_gpio) |
| 119 | return -EINVAL; | 88 | return -EINVAL; |
| 120 | 89 | ||
| 121 | local_irq_save(flags); | 90 | local_irq_save(flags); |
| @@ -136,6 +105,44 @@ int pxa_gpio_mode(int gpio_mode) | |||
| 136 | 105 | ||
| 137 | EXPORT_SYMBOL(pxa_gpio_mode); | 106 | EXPORT_SYMBOL(pxa_gpio_mode); |
| 138 | 107 | ||
| 108 | int gpio_direction_input(unsigned gpio) | ||
| 109 | { | ||
| 110 | unsigned long flags; | ||
| 111 | u32 mask; | ||
| 112 | |||
| 113 | if (gpio > pxa_last_gpio) | ||
| 114 | return -EINVAL; | ||
| 115 | |||
| 116 | mask = GPIO_bit(gpio); | ||
| 117 | local_irq_save(flags); | ||
| 118 | GPDR(gpio) &= ~mask; | ||
| 119 | local_irq_restore(flags); | ||
| 120 | |||
| 121 | return 0; | ||
| 122 | } | ||
| 123 | EXPORT_SYMBOL(gpio_direction_input); | ||
| 124 | |||
| 125 | int gpio_direction_output(unsigned gpio, int value) | ||
| 126 | { | ||
| 127 | unsigned long flags; | ||
| 128 | u32 mask; | ||
| 129 | |||
| 130 | if (gpio > pxa_last_gpio) | ||
| 131 | return -EINVAL; | ||
| 132 | |||
| 133 | mask = GPIO_bit(gpio); | ||
| 134 | local_irq_save(flags); | ||
| 135 | if (value) | ||
| 136 | GPSR(gpio) = mask; | ||
| 137 | else | ||
| 138 | GPCR(gpio) = mask; | ||
| 139 | GPDR(gpio) |= mask; | ||
| 140 | local_irq_restore(flags); | ||
| 141 | |||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | EXPORT_SYMBOL(gpio_direction_output); | ||
| 145 | |||
| 139 | /* | 146 | /* |
| 140 | * Return GPIO level | 147 | * Return GPIO level |
| 141 | */ | 148 | */ |
| @@ -159,7 +166,7 @@ EXPORT_SYMBOL(pxa_gpio_set_value); | |||
| 159 | /* | 166 | /* |
| 160 | * Routine to safely enable or disable a clock in the CKEN | 167 | * Routine to safely enable or disable a clock in the CKEN |
| 161 | */ | 168 | */ |
| 162 | void pxa_set_cken(int clock, int enable) | 169 | void __pxa_set_cken(int clock, int enable) |
| 163 | { | 170 | { |
| 164 | unsigned long flags; | 171 | unsigned long flags; |
| 165 | local_irq_save(flags); | 172 | local_irq_save(flags); |
| @@ -172,7 +179,7 @@ void pxa_set_cken(int clock, int enable) | |||
| 172 | local_irq_restore(flags); | 179 | local_irq_restore(flags); |
| 173 | } | 180 | } |
| 174 | 181 | ||
| 175 | EXPORT_SYMBOL(pxa_set_cken); | 182 | EXPORT_SYMBOL(__pxa_set_cken); |
| 176 | 183 | ||
| 177 | /* | 184 | /* |
| 178 | * Intel PXA2xx internal register mapping. | 185 | * Intel PXA2xx internal register mapping. |
| @@ -329,21 +336,80 @@ void __init set_pxa_fb_parent(struct device *parent_dev) | |||
| 329 | pxa_device_fb.dev.parent = parent_dev; | 336 | pxa_device_fb.dev.parent = parent_dev; |
| 330 | } | 337 | } |
| 331 | 338 | ||
| 339 | static struct resource pxa_resource_ffuart[] = { | ||
| 340 | { | ||
| 341 | .start = __PREG(FFUART), | ||
| 342 | .end = __PREG(FFUART) + 35, | ||
| 343 | .flags = IORESOURCE_MEM, | ||
| 344 | }, { | ||
| 345 | .start = IRQ_FFUART, | ||
| 346 | .end = IRQ_FFUART, | ||
| 347 | .flags = IORESOURCE_IRQ, | ||
| 348 | } | ||
| 349 | }; | ||
| 350 | |||
| 332 | struct platform_device pxa_device_ffuart= { | 351 | struct platform_device pxa_device_ffuart= { |
| 333 | .name = "pxa2xx-uart", | 352 | .name = "pxa2xx-uart", |
| 334 | .id = 0, | 353 | .id = 0, |
| 354 | .resource = pxa_resource_ffuart, | ||
| 355 | .num_resources = ARRAY_SIZE(pxa_resource_ffuart), | ||
| 335 | }; | 356 | }; |
| 357 | |||
| 358 | static struct resource pxa_resource_btuart[] = { | ||
| 359 | { | ||
| 360 | .start = __PREG(BTUART), | ||
| 361 | .end = __PREG(BTUART) + 35, | ||
| 362 | .flags = IORESOURCE_MEM, | ||
| 363 | }, { | ||
| 364 | .start = IRQ_BTUART, | ||
| 365 | .end = IRQ_BTUART, | ||
| 366 | .flags = IORESOURCE_IRQ, | ||
| 367 | } | ||
| 368 | }; | ||
| 369 | |||
| 336 | struct platform_device pxa_device_btuart = { | 370 | struct platform_device pxa_device_btuart = { |
| 337 | .name = "pxa2xx-uart", | 371 | .name = "pxa2xx-uart", |
| 338 | .id = 1, | 372 | .id = 1, |
| 373 | .resource = pxa_resource_btuart, | ||
| 374 | .num_resources = ARRAY_SIZE(pxa_resource_btuart), | ||
| 339 | }; | 375 | }; |
| 376 | |||
| 377 | static struct resource pxa_resource_stuart[] = { | ||
| 378 | { | ||
| 379 | .start = __PREG(STUART), | ||
| 380 | .end = __PREG(STUART) + 35, | ||
| 381 | .flags = IORESOURCE_MEM, | ||
| 382 | }, { | ||
| 383 | .start = IRQ_STUART, | ||
| 384 | .end = IRQ_STUART, | ||
| 385 | .flags = IORESOURCE_IRQ, | ||
| 386 | } | ||
| 387 | }; | ||
| 388 | |||
| 340 | struct platform_device pxa_device_stuart = { | 389 | struct platform_device pxa_device_stuart = { |
| 341 | .name = "pxa2xx-uart", | 390 | .name = "pxa2xx-uart", |
| 342 | .id = 2, | 391 | .id = 2, |
| 392 | .resource = pxa_resource_stuart, | ||
| 393 | .num_resources = ARRAY_SIZE(pxa_resource_stuart), | ||
| 343 | }; | 394 | }; |
| 395 | |||
| 396 | static struct resource pxa_resource_hwuart[] = { | ||
| 397 | { | ||
| 398 | .start = __PREG(HWUART), | ||
| 399 | .end = __PREG(HWUART) + 47, | ||
| 400 | .flags = IORESOURCE_MEM, | ||
| 401 | }, { | ||
| 402 | .start = IRQ_HWUART, | ||
| 403 | .end = IRQ_HWUART, | ||
| 404 | .flags = IORESOURCE_IRQ, | ||
| 405 | } | ||
| 406 | }; | ||
| 407 | |||
| 344 | struct platform_device pxa_device_hwuart = { | 408 | struct platform_device pxa_device_hwuart = { |
| 345 | .name = "pxa2xx-uart", | 409 | .name = "pxa2xx-uart", |
| 346 | .id = 3, | 410 | .id = 3, |
| 411 | .resource = pxa_resource_hwuart, | ||
| 412 | .num_resources = ARRAY_SIZE(pxa_resource_hwuart), | ||
| 347 | }; | 413 | }; |
| 348 | 414 | ||
| 349 | static struct resource pxai2c_resources[] = { | 415 | static struct resource pxai2c_resources[] = { |
