All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 0d2ae7a3 authored by Jan Beulich's avatar Jan Beulich

x86/HPET: cleanup

- separate init and resume code paths (so that the [larger] init parts
  can go init .init.* sections)
- drop the separate legacy_hpet_event object, as we can easily re-use
  the first slot of hpet_events[] for that purpose (the whole array is
  otherwise unused when the legacy code is being used)
- use section placement attributes where reasonable
Signed-off-by: default avatarJan Beulich <jbeulich@novell.com>
Acked-by: default avatarWei Gang <gang.wei@intel.com>
parent 8444d910
This diff is collapsed.
......@@ -21,6 +21,7 @@
#include <xen/smp.h>
#include <xen/irq.h>
#include <xen/softirq.h>
#include <xen/symbols.h>
#include <xen/keyhandler.h>
#include <xen/guest_access.h>
#include <asm/io.h>
......@@ -374,10 +375,7 @@ static int __init init_hpet(struct platform_timesource *pts)
static void resume_hpet(struct platform_timesource *pts)
{
u64 hpet_rate = hpet_setup();
BUG_ON(hpet_rate == 0);
pts->frequency = hpet_rate;
hpet_resume();
}
static struct platform_timesource __initdata plt_hpet =
......@@ -1440,10 +1438,12 @@ void __init early_time_init(void)
}
/* keep pit enabled for pit_broadcast working while cpuidle enabled */
static int disable_pit_irq(void)
static int _disable_pit_irq(void(*hpet_broadcast_setup)(void))
{
int ret = 1;
if ( using_pit || !cpu_has_apic )
return 0;
return -1;
/*
* If we do not rely on PIT CH0 then we can use HPET for one-shot timer
......@@ -1453,20 +1453,16 @@ static int disable_pit_irq(void)
*/
if ( xen_cpuidle && !boot_cpu_has(X86_FEATURE_ARAT) )
{
hpet_broadcast_init();
hpet_broadcast_setup();
if ( !hpet_broadcast_is_available() )
{
if ( xen_cpuidle == -1 )
{
xen_cpuidle = 0;
printk("CPUIDLE: disabled due to no HPET. "
"Force enable with 'cpuidle'.\n");
}
else
if ( xen_cpuidle > 0 )
{
printk("HPET broadcast init failed, turn to PIT broadcast.\n");
return 0;
print_symbol("%s() failed, turning to PIT broadcast\n",
(unsigned long)hpet_broadcast_setup);
return -1;
}
ret = 0;
}
}
......@@ -1475,6 +1471,18 @@ static int disable_pit_irq(void)
outb_p(0, PIT_CH0);
outb_p(0, PIT_CH0);
return ret;
}
static int __init disable_pit_irq(void)
{
if ( !_disable_pit_irq(hpet_broadcast_init) )
{
xen_cpuidle = 0;
printk("CPUIDLE: disabled due to no HPET. "
"Force enable with 'cpuidle'.\n");
}
return 0;
}
__initcall(disable_pit_irq);
......@@ -1541,7 +1549,8 @@ int time_resume(void)
resume_platform_timer();
disable_pit_irq();
if ( !_disable_pit_irq(hpet_broadcast_resume) )
BUG();
init_percpu_time();
......
......@@ -14,19 +14,9 @@
#define HPET_CFG 0x010
#define HPET_STATUS 0x020
#define HPET_COUNTER 0x0f0
#define HPET_T0_CFG 0x100
#define HPET_T0_CMP 0x108
#define HPET_T0_ROUTE 0x110
#define HPET_T1_CFG 0x120
#define HPET_T1_CMP 0x128
#define HPET_T1_ROUTE 0x130
#define HPET_T2_CFG 0x140
#define HPET_T2_CMP 0x148
#define HPET_T2_ROUTE 0x150
#define HPET_Tn_CFG(n) (HPET_T0_CFG + n * 0x20)
#define HPET_Tn_CMP(n) (HPET_T0_CMP + n * 0x20)
#define HPET_Tn_ROUTE(n) (HPET_T0_ROUTE + n * 0x20)
#define HPET_Tn_CFG(n) (0x100 + (n) * 0x20)
#define HPET_Tn_CMP(n) (0x108 + (n) * 0x20)
#define HPET_Tn_ROUTE(n) (0x110 + (n) * 0x20)
#define HPET_ID_VENDOR 0xffff0000
#define HPET_ID_LEGSUP 0x00008000
......@@ -65,6 +55,7 @@ extern unsigned long hpet_address;
* Return value is zero if HPET is unavailable.
*/
u64 hpet_setup(void);
void hpet_resume(void);
/*
* Callback from legacy timer (PIT channel 0) IRQ handler.
......@@ -77,6 +68,7 @@ int hpet_legacy_irq_tick(void);
* rather than using the LAPIC timer. Used for Cx state entry.
*/
void hpet_broadcast_init(void);
void hpet_broadcast_resume(void);
void hpet_broadcast_enter(void);
void hpet_broadcast_exit(void);
int hpet_broadcast_is_available(void);
......
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