X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fmach-pxa%2Fgeneric.c;fp=arch%2Farm%2Fmach-pxa%2Fgeneric.c;h=9de1278d234f86d655880c6f587e10b785cb843a;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=9b48a90aefce9d4a25910f513d190c1e7ae7d8c5;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 9b48a90ae..9de1278d2 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -25,6 +25,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -40,6 +44,64 @@ #include "generic.h" +/* + * This is the PXA2xx sched_clock implementation. This has a resolution + * of at least 308ns and a maximum value that depends on the value of + * CLOCK_TICK_RATE. + * + * The return value is guaranteed to be monotonic in that range as + * long as there is always less than 582 seconds between successive + * calls to this function. + */ +unsigned long long sched_clock(void) +{ + unsigned long long v = cnt32_to_63(OSCR); + /* Note: top bit ov v needs cleared unless multiplier is even. */ + +#if CLOCK_TICK_RATE == 3686400 + /* 1E9 / 3686400 => 78125 / 288, max value = 32025597s (370 days). */ + /* The <<1 is used to get rid of tick.hi top bit */ + v *= 78125<<1; + do_div(v, 288<<1); +#elif CLOCK_TICK_RATE == 3250000 + /* 1E9 / 3250000 => 4000 / 13, max value = 709490156s (8211 days) */ + v *= 4000; + do_div(v, 13); +#elif CLOCK_TICK_RATE == 3249600 + /* 1E9 / 3249600 => 625000 / 2031, max value = 4541295s (52 days) */ + v *= 625000; + do_div(v, 2031); +#else +#warning "consider fixing sched_clock for your value of CLOCK_TICK_RATE" + /* + * 96-bit math to perform tick * NSEC_PER_SEC / CLOCK_TICK_RATE for + * any value of CLOCK_TICK_RATE. Max value is in the 80 thousand + * years range and truncation to unsigned long long limits it to + * sched_clock's max range of ~584 years. This is nice but with + * higher computation cost. + */ + { + union { + unsigned long long val; + struct { unsigned long lo, hi; }; + } x; + unsigned long long y; + + x.val = v; + x.hi &= 0x7fffffff; + y = (unsigned long long)x.lo * NSEC_PER_SEC; + x.lo = y; + y = (y >> 32) + (unsigned long long)x.hi * NSEC_PER_SEC; + x.hi = do_div(y, CLOCK_TICK_RATE); + do_div(x.val, CLOCK_TICK_RATE); + x.hi += y; + v = x.val; + } +#endif + + return v; +} + /* * Handy function to set GPIO alternate functions */ @@ -204,13 +266,6 @@ static struct platform_device udc_device = { } }; -static struct pxafb_mach_info pxa_fb_info; - -void __init set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info) -{ - memcpy(&pxa_fb_info,hard_pxa_fb_info,sizeof(struct pxafb_mach_info)); -} - static struct resource pxafb_resources[] = { [0] = { .start = 0x44000000, @@ -230,7 +285,6 @@ static struct platform_device pxafb_device = { .name = "pxa2xx-fb", .id = -1, .dev = { - .platform_data = &pxa_fb_info, .dma_mask = &fb_dma_mask, .coherent_dma_mask = 0xffffffff, }, @@ -238,6 +292,11 @@ static struct platform_device pxafb_device = { .resource = pxafb_resources, }; +void __init set_pxa_fb_info(struct pxafb_mach_info *info) +{ + pxafb_device.dev.platform_data = info; +} + void __init set_pxa_fb_parent(struct device *parent_dev) { pxafb_device.dev.parent = parent_dev; @@ -319,6 +378,11 @@ void __init pxa_set_ficp_info(struct pxaficp_platform_data *info) pxaficp_device.dev.platform_data = info; } +static struct platform_device pxartc_device = { + .name = "sa1100-rtc", + .id = -1, +}; + static struct platform_device *devices[] __initdata = { &pxamci_device, &udc_device, @@ -329,6 +393,7 @@ static struct platform_device *devices[] __initdata = { &pxaficp_device, &i2c_device, &i2s_device, + &pxartc_device, }; static int __init pxa_init(void)