Commit 610bf2f1 authored by Venki Pallipadi's avatar Venki Pallipadi Committed by Thomas Gleixner

x86: HPET restructure hpet code for hpet force enable

Restructure and rename legacy replacement mode HPET timer support.  Just the
code structural changes and should be zero functionality change.
Signed-off-by: default avatarVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Andi Kleen <ak@suse.de>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarArjan van de Ven <arjan@linux.intel.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 4a93232d
...@@ -149,9 +149,9 @@ static void hpet_reserve_platform_timers(unsigned long id) { } ...@@ -149,9 +149,9 @@ static void hpet_reserve_platform_timers(unsigned long id) { }
*/ */
static unsigned long hpet_period; static unsigned long hpet_period;
static void hpet_set_mode(enum clock_event_mode mode, static void hpet_legacy_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt); struct clock_event_device *evt);
static int hpet_next_event(unsigned long delta, static int hpet_legacy_next_event(unsigned long delta,
struct clock_event_device *evt); struct clock_event_device *evt);
/* /*
...@@ -160,8 +160,8 @@ static int hpet_next_event(unsigned long delta, ...@@ -160,8 +160,8 @@ static int hpet_next_event(unsigned long delta,
static struct clock_event_device hpet_clockevent = { static struct clock_event_device hpet_clockevent = {
.name = "hpet", .name = "hpet",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.set_mode = hpet_set_mode, .set_mode = hpet_legacy_set_mode,
.set_next_event = hpet_next_event, .set_next_event = hpet_legacy_next_event,
.shift = 32, .shift = 32,
.irq = 0, .irq = 0,
}; };
...@@ -178,7 +178,7 @@ static void hpet_start_counter(void) ...@@ -178,7 +178,7 @@ static void hpet_start_counter(void)
hpet_writel(cfg, HPET_CFG); hpet_writel(cfg, HPET_CFG);
} }
static void hpet_enable_int(void) static void hpet_enable_legacy_int(void)
{ {
unsigned long cfg = hpet_readl(HPET_CFG); unsigned long cfg = hpet_readl(HPET_CFG);
...@@ -187,7 +187,39 @@ static void hpet_enable_int(void) ...@@ -187,7 +187,39 @@ static void hpet_enable_int(void)
hpet_legacy_int_enabled = 1; hpet_legacy_int_enabled = 1;
} }
static void hpet_set_mode(enum clock_event_mode mode, static void hpet_legacy_clockevent_register(void)
{
uint64_t hpet_freq;
/* Start HPET legacy interrupts */
hpet_enable_legacy_int();
/*
* The period is a femto seconds value. We need to calculate the
* scaled math multiplication factor for nanosecond to hpet tick
* conversion.
*/
hpet_freq = 1000000000000000ULL;
do_div(hpet_freq, hpet_period);
hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
NSEC_PER_SEC, 32);
/* Calculate the min / max delta */
hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
&hpet_clockevent);
hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
&hpet_clockevent);
/*
* Start hpet with the boot cpu mask and make it
* global after the IO_APIC has been initialized.
*/
hpet_clockevent.cpumask = cpumask_of_cpu(smp_processor_id());
clockevents_register_device(&hpet_clockevent);
global_clock_event = &hpet_clockevent;
printk(KERN_DEBUG "hpet clockevent registered\n");
}
static void hpet_legacy_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt) struct clock_event_device *evt)
{ {
unsigned long cfg, cmp, now; unsigned long cfg, cmp, now;
...@@ -228,12 +260,12 @@ static void hpet_set_mode(enum clock_event_mode mode, ...@@ -228,12 +260,12 @@ static void hpet_set_mode(enum clock_event_mode mode,
break; break;
case CLOCK_EVT_MODE_RESUME: case CLOCK_EVT_MODE_RESUME:
hpet_enable_int(); hpet_enable_legacy_int();
break; break;
} }
} }
static int hpet_next_event(unsigned long delta, static int hpet_legacy_next_event(unsigned long delta,
struct clock_event_device *evt) struct clock_event_device *evt)
{ {
unsigned long cnt; unsigned long cnt;
...@@ -273,58 +305,11 @@ static struct clocksource clocksource_hpet = { ...@@ -273,58 +305,11 @@ static struct clocksource clocksource_hpet = {
#endif #endif
}; };
/* static int hpet_clocksource_register(void)
* Try to setup the HPET timer
*/
int __init hpet_enable(void)
{ {
unsigned long id;
uint64_t hpet_freq;
u64 tmp, start, now; u64 tmp, start, now;
cycle_t t1; cycle_t t1;
if (!is_hpet_capable())
return 0;
hpet_set_mapping();
/*
* Read the period and check for a sane value:
*/
hpet_period = hpet_readl(HPET_PERIOD);
if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
goto out_nohpet;
/*
* The period is a femto seconds value. We need to calculate the
* scaled math multiplication factor for nanosecond to hpet tick
* conversion.
*/
hpet_freq = 1000000000000000ULL;
do_div(hpet_freq, hpet_period);
hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
NSEC_PER_SEC, 32);
/* Calculate the min / max delta */
hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
&hpet_clockevent);
hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
&hpet_clockevent);
/*
* Read the HPET ID register to retrieve the IRQ routing
* information and the number of channels
*/
id = hpet_readl(HPET_ID);
#ifdef CONFIG_HPET_EMULATE_RTC
/*
* The legacy routing mode needs at least two channels, tick timer
* and the rtc emulation channel.
*/
if (!(id & HPET_ID_NUMBER))
goto out_nohpet;
#endif
/* Start the counter */ /* Start the counter */
hpet_start_counter(); hpet_start_counter();
...@@ -346,7 +331,7 @@ int __init hpet_enable(void) ...@@ -346,7 +331,7 @@ int __init hpet_enable(void)
if (t1 == read_hpet()) { if (t1 == read_hpet()) {
printk(KERN_WARNING printk(KERN_WARNING
"HPET counter not counting. HPET disabled\n"); "HPET counter not counting. HPET disabled\n");
goto out_nohpet; return -ENODEV;
} }
/* Initialize and register HPET clocksource /* Initialize and register HPET clocksource
...@@ -367,15 +352,48 @@ int __init hpet_enable(void) ...@@ -367,15 +352,48 @@ int __init hpet_enable(void)
clocksource_register(&clocksource_hpet); clocksource_register(&clocksource_hpet);
return 0;
}
/*
* Try to setup the HPET timer
*/
int __init hpet_enable(void)
{
unsigned long id;
if (!is_hpet_capable())
return 0;
hpet_set_mapping();
/*
* Read the period and check for a sane value:
*/
hpet_period = hpet_readl(HPET_PERIOD);
if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
goto out_nohpet;
/*
* Read the HPET ID register to retrieve the IRQ routing
* information and the number of channels
*/
id = hpet_readl(HPET_ID);
#ifdef CONFIG_HPET_EMULATE_RTC
/*
* The legacy routing mode needs at least two channels, tick timer
* and the rtc emulation channel.
*/
if (!(id & HPET_ID_NUMBER))
goto out_nohpet;
#endif
if (hpet_clocksource_register())
goto out_nohpet;
if (id & HPET_ID_LEGSUP) { if (id & HPET_ID_LEGSUP) {
hpet_enable_int(); hpet_legacy_clockevent_register();
/*
* Start hpet with the boot cpu mask and make it
* global after the IO_APIC has been initialized.
*/
hpet_clockevent.cpumask = cpumask_of_cpu(smp_processor_id());
clockevents_register_device(&hpet_clockevent);
global_clock_event = &hpet_clockevent;
return 1; return 1;
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment