diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-19 20:44:40 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-19 20:44:40 -0400 |
| commit | 7e6628e4bcb3b3546c625ec63ca724f28ab14f0c (patch) | |
| tree | 111a94cefa9d800ec5c5e59520f4b5d1880965d0 | |
| parent | 0f1bdc1815c4cb29b3cd71a7091b478e426faa0b (diff) | |
| parent | ab0e08f15d23628dd8d50bf6ce1a935a8840c7dc (diff) | |
Merge branch 'timers-clockevents-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-clockevents-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86: hpet: Cleanup the clockevents init and register code
x86: Convert PIT to clockevents_config_and_register()
clockevents: Provide interface to reconfigure an active clock event device
clockevents: Provide combined configure and register function
clockevents: Restructure clock_event_device members
clocksource: Get rid of the hardcoded 5 seconds sleep time limit
clocksource: Restructure clocksource struct members
| -rw-r--r-- | arch/x86/kernel/hpet.c | 72 | ||||
| -rw-r--r-- | arch/x86/kernel/i8253.c | 6 | ||||
| -rw-r--r-- | include/linux/clockchips.h | 56 | ||||
| -rw-r--r-- | include/linux/clocksource.h | 32 | ||||
| -rw-r--r-- | kernel/time/clockevents.c | 64 | ||||
| -rw-r--r-- | kernel/time/clocksource.c | 38 |
6 files changed, 148 insertions, 120 deletions
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index bfe8f729e086..6781765b3a0d 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
| @@ -217,7 +217,7 @@ static void hpet_reserve_platform_timers(unsigned int id) { } | |||
| 217 | /* | 217 | /* |
| 218 | * Common hpet info | 218 | * Common hpet info |
| 219 | */ | 219 | */ |
| 220 | static unsigned long hpet_period; | 220 | static unsigned long hpet_freq; |
| 221 | 221 | ||
| 222 | static void hpet_legacy_set_mode(enum clock_event_mode mode, | 222 | static void hpet_legacy_set_mode(enum clock_event_mode mode, |
| 223 | struct clock_event_device *evt); | 223 | struct clock_event_device *evt); |
| @@ -232,7 +232,6 @@ static struct clock_event_device hpet_clockevent = { | |||
| 232 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 232 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
| 233 | .set_mode = hpet_legacy_set_mode, | 233 | .set_mode = hpet_legacy_set_mode, |
| 234 | .set_next_event = hpet_legacy_next_event, | 234 | .set_next_event = hpet_legacy_next_event, |
| 235 | .shift = 32, | ||
| 236 | .irq = 0, | 235 | .irq = 0, |
| 237 | .rating = 50, | 236 | .rating = 50, |
| 238 | }; | 237 | }; |
| @@ -290,28 +289,12 @@ static void hpet_legacy_clockevent_register(void) | |||
| 290 | hpet_enable_legacy_int(); | 289 | hpet_enable_legacy_int(); |
| 291 | 290 | ||
| 292 | /* | 291 | /* |
| 293 | * The mult factor is defined as (include/linux/clockchips.h) | ||
| 294 | * mult/2^shift = cyc/ns (in contrast to ns/cyc in clocksource.h) | ||
| 295 | * hpet_period is in units of femtoseconds (per cycle), so | ||
| 296 | * mult/2^shift = cyc/ns = 10^6/hpet_period | ||
| 297 | * mult = (10^6 * 2^shift)/hpet_period | ||
| 298 | * mult = (FSEC_PER_NSEC << hpet_clockevent.shift)/hpet_period | ||
| 299 | */ | ||
| 300 | hpet_clockevent.mult = div_sc((unsigned long) FSEC_PER_NSEC, | ||
| 301 | hpet_period, hpet_clockevent.shift); | ||
| 302 | /* Calculate the min / max delta */ | ||
| 303 | hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, | ||
| 304 | &hpet_clockevent); | ||
| 305 | /* Setup minimum reprogramming delta. */ | ||
| 306 | hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, | ||
| 307 | &hpet_clockevent); | ||
| 308 | |||
| 309 | /* | ||
| 310 | * Start hpet with the boot cpu mask and make it | 292 | * Start hpet with the boot cpu mask and make it |
| 311 | * global after the IO_APIC has been initialized. | 293 | * global after the IO_APIC has been initialized. |
| 312 | */ | 294 | */ |
| 313 | hpet_clockevent.cpumask = cpumask_of(smp_processor_id()); | 295 | hpet_clockevent.cpumask = cpumask_of(smp_processor_id()); |
| 314 | clockevents_register_device(&hpet_clockevent); | 296 | clockevents_config_and_register(&hpet_clockevent, hpet_freq, |
| 297 | HPET_MIN_PROG_DELTA, 0x7FFFFFFF); | ||
| 315 | global_clock_event = &hpet_clockevent; | 298 | global_clock_event = &hpet_clockevent; |
| 316 | printk(KERN_DEBUG "hpet clockevent registered\n"); | 299 | printk(KERN_DEBUG "hpet clockevent registered\n"); |
| 317 | } | 300 | } |
| @@ -549,7 +532,6 @@ static int hpet_setup_irq(struct hpet_dev *dev) | |||
| 549 | static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu) | 532 | static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu) |
| 550 | { | 533 | { |
| 551 | struct clock_event_device *evt = &hdev->evt; | 534 | struct clock_event_device *evt = &hdev->evt; |
| 552 | uint64_t hpet_freq; | ||
| 553 | 535 | ||
| 554 | WARN_ON(cpu != smp_processor_id()); | 536 | WARN_ON(cpu != smp_processor_id()); |
| 555 | if (!(hdev->flags & HPET_DEV_VALID)) | 537 | if (!(hdev->flags & HPET_DEV_VALID)) |
| @@ -571,24 +553,10 @@ static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu) | |||
| 571 | 553 | ||
| 572 | evt->set_mode = hpet_msi_set_mode; | 554 | evt->set_mode = hpet_msi_set_mode; |
| 573 | evt->set_next_event = hpet_msi_next_event; | 555 | evt->set_next_event = hpet_msi_next_event; |
| 574 | evt->shift = 32; | ||
| 575 | |||
| 576 | /* | ||
| 577 | * The period is a femto seconds value. We need to calculate the | ||
| 578 | * scaled math multiplication factor for nanosecond to hpet tick | ||
| 579 | * conversion. | ||
| 580 | */ | ||
| 581 | hpet_freq = FSEC_PER_SEC; | ||
| 582 | do_div(hpet_freq, hpet_period); | ||
| 583 | evt->mult = div_sc((unsigned long) hpet_freq, | ||
| 584 | NSEC_PER_SEC, evt->shift); | ||
| 585 | /* Calculate the max delta */ | ||
| 586 | evt->max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, evt); | ||
| 587 | /* 5 usec minimum reprogramming delta. */ | ||
| 588 | evt->min_delta_ns = 5000; | ||
| 589 | |||
| 590 | evt->cpumask = cpumask_of(hdev->cpu); | 556 | evt->cpumask = cpumask_of(hdev->cpu); |
| 591 | clockevents_register_device(evt); | 557 | |
| 558 | clockevents_config_and_register(evt, hpet_freq, HPET_MIN_PROG_DELTA, | ||
| 559 | 0x7FFFFFFF); | ||
| 592 | } | 560 | } |
| 593 | 561 | ||
| 594 | #ifdef CONFIG_HPET | 562 | #ifdef CONFIG_HPET |
| @@ -792,7 +760,6 @@ static struct clocksource clocksource_hpet = { | |||
| 792 | static int hpet_clocksource_register(void) | 760 | static int hpet_clocksource_register(void) |
| 793 | { | 761 | { |
| 794 | u64 start, now; | 762 | u64 start, now; |
| 795 | u64 hpet_freq; | ||
| 796 | cycle_t t1; | 763 | cycle_t t1; |
| 797 | 764 | ||
| 798 | /* Start the counter */ | 765 | /* Start the counter */ |
| @@ -819,24 +786,7 @@ static int hpet_clocksource_register(void) | |||
| 819 | return -ENODEV; | 786 | return -ENODEV; |
| 820 | } | 787 | } |
| 821 | 788 | ||
| 822 | /* | ||
| 823 | * The definition of mult is (include/linux/clocksource.h) | ||
| 824 | * mult/2^shift = ns/cyc and hpet_period is in units of fsec/cyc | ||
| 825 | * so we first need to convert hpet_period to ns/cyc units: | ||
| 826 | * mult/2^shift = ns/cyc = hpet_period/10^6 | ||
| 827 | * mult = (hpet_period * 2^shift)/10^6 | ||
| 828 | * mult = (hpet_period << shift)/FSEC_PER_NSEC | ||
| 829 | */ | ||
| 830 | |||
| 831 | /* Need to convert hpet_period (fsec/cyc) to cyc/sec: | ||
| 832 | * | ||
| 833 | * cyc/sec = FSEC_PER_SEC/hpet_period(fsec/cyc) | ||
| 834 | * cyc/sec = (FSEC_PER_NSEC * NSEC_PER_SEC)/hpet_period | ||
| 835 | */ | ||
| 836 | hpet_freq = FSEC_PER_SEC; | ||
| 837 | do_div(hpet_freq, hpet_period); | ||
| 838 | clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq); | 789 | clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq); |
| 839 | |||
| 840 | return 0; | 790 | return 0; |
| 841 | } | 791 | } |
| 842 | 792 | ||
| @@ -845,7 +795,9 @@ static int hpet_clocksource_register(void) | |||
| 845 | */ | 795 | */ |
| 846 | int __init hpet_enable(void) | 796 | int __init hpet_enable(void) |
| 847 | { | 797 | { |
| 798 | unsigned long hpet_period; | ||
| 848 | unsigned int id; | 799 | unsigned int id; |
| 800 | u64 freq; | ||
| 849 | int i; | 801 | int i; |
| 850 | 802 | ||
| 851 | if (!is_hpet_capable()) | 803 | if (!is_hpet_capable()) |
| @@ -884,6 +836,14 @@ int __init hpet_enable(void) | |||
| 884 | goto out_nohpet; | 836 | goto out_nohpet; |
| 885 | 837 | ||
| 886 | /* | 838 | /* |
| 839 | * The period is a femto seconds value. Convert it to a | ||
| 840 | * frequency. | ||
| 841 | */ | ||
| 842 | freq = FSEC_PER_SEC; | ||
| 843 | do_div(freq, hpet_period); | ||
| 844 | hpet_freq = freq; | ||
| 845 | |||
| 846 | /* | ||
| 887 | * Read the HPET ID register to retrieve the IRQ routing | 847 | * Read the HPET ID register to retrieve the IRQ routing |
| 888 | * information and the number of channels | 848 | * information and the number of channels |
| 889 | */ | 849 | */ |
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c index 577e90cadaeb..fb66dc9e36cb 100644 --- a/arch/x86/kernel/i8253.c +++ b/arch/x86/kernel/i8253.c | |||
| @@ -93,7 +93,6 @@ static struct clock_event_device pit_ce = { | |||
| 93 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 93 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
| 94 | .set_mode = init_pit_timer, | 94 | .set_mode = init_pit_timer, |
| 95 | .set_next_event = pit_next_event, | 95 | .set_next_event = pit_next_event, |
| 96 | .shift = 32, | ||
| 97 | .irq = 0, | 96 | .irq = 0, |
| 98 | }; | 97 | }; |
| 99 | 98 | ||
| @@ -108,11 +107,8 @@ void __init setup_pit_timer(void) | |||
| 108 | * IO_APIC has been initialized. | 107 | * IO_APIC has been initialized. |
| 109 | */ | 108 | */ |
| 110 | pit_ce.cpumask = cpumask_of(smp_processor_id()); | 109 | pit_ce.cpumask = cpumask_of(smp_processor_id()); |
| 111 | pit_ce.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, pit_ce.shift); | ||
