forked from Minki/linux
x86_64: convert to clock events
Finally switch to the clockevents code. Share code with i386 for hpet and PIT. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Chris Wright <chrisw@sous-sol.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
This commit is contained in:
parent
ba7eda4c60
commit
b8ce335906
@ -8,8 +8,8 @@ obj-y := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
|
||||
ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \
|
||||
x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \
|
||||
setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \
|
||||
pci-dma_64.o pci-nommu_64.o alternative.o hpet_64.o tsc_64.o bugs_64.o \
|
||||
perfctr-watchdog.o
|
||||
pci-dma_64.o pci-nommu_64.o alternative.o hpet_32.o tsc_64.o bugs_64.o \
|
||||
perfctr-watchdog.o i8253_32.o
|
||||
|
||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||
obj-$(CONFIG_X86_MCE) += mce_64.o therm_throt.o
|
||||
|
@ -857,25 +857,12 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
|
||||
|
||||
static void setup_APIC_timer(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
int irqen;
|
||||
struct clock_event_device *levt = &__get_cpu_var(lapic_events);
|
||||
|
||||
local_irq_save(flags);
|
||||
memcpy(levt, &lapic_clockevent, sizeof(*levt));
|
||||
levt->cpumask = cpumask_of_cpu(smp_processor_id());
|
||||
|
||||
irqen = ! cpu_isset(smp_processor_id(),
|
||||
timer_interrupt_broadcast_ipi_mask);
|
||||
__setup_APIC_LVTT(calibration_result, 0, irqen);
|
||||
/* Turn off PIT interrupt if we use APIC timer as main timer.
|
||||
Only works with the PM timer right now
|
||||
TBD fix it for HPET too. */
|
||||
if ((pmtmr_ioport != 0) &&
|
||||
smp_processor_id() == boot_cpu_id &&
|
||||
apic_runs_main_timer == 1 &&
|
||||
!cpu_isset(boot_cpu_id, timer_interrupt_broadcast_ipi_mask)) {
|
||||
stop_timer_interrupt();
|
||||
apic_runs_main_timer++;
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
clockevents_register_device(levt);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -950,18 +937,34 @@ static void __init calibrate_APIC_clock(void)
|
||||
|
||||
void __init setup_boot_APIC_clock (void)
|
||||
{
|
||||
/*
|
||||
* The local apic timer can be disabled via the kernel commandline.
|
||||
* Register the lapic timer as a dummy clock event source on SMP
|
||||
* systems, so the broadcast mechanism is used. On UP systems simply
|
||||
* ignore it.
|
||||
*/
|
||||
if (disable_apic_timer) {
|
||||
printk(KERN_INFO "Disabling APIC timer\n");
|
||||
/* No broadcast on UP ! */
|
||||
if (num_possible_cpus() > 1)
|
||||
setup_APIC_timer();
|
||||
return;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "Using local APIC timer interrupts.\n");
|
||||
using_apic_timer = 1;
|
||||
|
||||
calibrate_APIC_clock();
|
||||
|
||||
/*
|
||||
* Now set up the timer for real.
|
||||
* If nmi_watchdog is set to IO_APIC, we need the
|
||||
* PIT/HPET going. Otherwise register lapic as a dummy
|
||||
* device.
|
||||
*/
|
||||
if (nmi_watchdog != NMI_IO_APIC)
|
||||
lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
|
||||
else
|
||||
printk(KERN_WARNING "APIC timer registered as dummy,"
|
||||
" due to nmi_watchdog=1!\n");
|
||||
|
||||
setup_APIC_timer();
|
||||
}
|
||||
|
||||
@ -1073,22 +1076,34 @@ void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector,
|
||||
|
||||
void smp_local_timer_interrupt(void)
|
||||
{
|
||||
profile_tick(CPU_PROFILING);
|
||||
#ifdef CONFIG_SMP
|
||||
update_process_times(user_mode(get_irq_regs()));
|
||||
#endif
|
||||
if (apic_runs_main_timer > 1 && smp_processor_id() == boot_cpu_id)
|
||||
main_timer_handler();
|
||||
int cpu = smp_processor_id();
|
||||
struct clock_event_device *evt = &per_cpu(lapic_events, cpu);
|
||||
|
||||
/*
|
||||
* We take the 'long' return path, and there every subsystem
|
||||
* grabs the appropriate locks (kernel lock/ irq lock).
|
||||
* Normally we should not be here till LAPIC has been initialized but
|
||||
* in some cases like kdump, its possible that there is a pending LAPIC
|
||||
* timer interrupt from previous kernel's context and is delivered in
|
||||
* new kernel the moment interrupts are enabled.
|
||||
*
|
||||
* We might want to decouple profiling from the 'long path',
|
||||
* and do the profiling totally in assembly.
|
||||
*
|
||||
* Currently this isn't too much of an issue (performance wise),
|
||||
* we can take more than 100K local irqs per second on a 100 MHz P5.
|
||||
* Interrupts are enabled early and LAPIC is setup much later, hence
|
||||
* its possible that when we get here evt->event_handler is NULL.
|
||||
* Check for event_handler being NULL and discard the interrupt as
|
||||
* spurious.
|
||||
*/
|
||||
if (!evt->event_handler) {
|
||||
printk(KERN_WARNING
|
||||
"Spurious LAPIC timer interrupt on cpu %d\n", cpu);
|
||||
/* Switch it off */
|
||||
lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* the NMI deadlock-detector uses this.
|
||||
*/
|
||||
add_pda(apic_timer_irqs, 1);
|
||||
|
||||
evt->event_handler(evt);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1103,11 +1118,6 @@ void smp_apic_timer_interrupt(struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
|
||||
/*
|
||||
* the NMI deadlock-detector uses this.
|
||||
*/
|
||||
add_pda(apic_timer_irqs, 1);
|
||||
|
||||
/*
|
||||
* NOTE! We'd better ACK the irq immediately,
|
||||
* because timer handling can be slow.
|
||||
@ -1291,7 +1301,7 @@ static __init int setup_noapictimer(char *str)
|
||||
static __init int setup_apicmaintimer(char *str)
|
||||
{
|
||||
apic_runs_main_timer = 1;
|
||||
nohpet = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
__setup("apicmaintimer", setup_apicmaintimer);
|
||||
@ -1307,7 +1317,7 @@ static __init int setup_apicpmtimer(char *s)
|
||||
{
|
||||
apic_calibrate_pmtmr = 1;
|
||||
notsc_setup(NULL);
|
||||
return setup_apicmaintimer(NULL);
|
||||
return 0;
|
||||
}
|
||||
__setup("apicpmtimer", setup_apicpmtimer);
|
||||
|
||||
|
@ -444,46 +444,6 @@ void __init init_ISA_irqs (void)
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_timer_hardware(void)
|
||||
{
|
||||
outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
|
||||
udelay(10);
|
||||
outb_p(LATCH & 0xff , 0x40); /* LSB */
|
||||
udelay(10);
|
||||
outb(LATCH >> 8 , 0x40); /* MSB */
|
||||
}
|
||||
|
||||
static int timer_resume(struct sys_device *dev)
|
||||
{
|
||||
setup_timer_hardware();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i8254_timer_resume(void)
|
||||
{
|
||||
setup_timer_hardware();
|
||||
}
|
||||
|
||||
static struct sysdev_class timer_sysclass = {
|
||||
set_kset_name("timer_pit"),
|
||||
.resume = timer_resume,
|
||||
};
|
||||
|
||||
static struct sys_device device_timer = {
|
||||
.id = 0,
|
||||
.cls = &timer_sysclass,
|
||||
};
|
||||
|
||||
static int __init init_timer_sysfs(void)
|
||||
{
|
||||
int error = sysdev_class_register(&timer_sysclass);
|
||||
if (!error)
|
||||
error = sysdev_register(&device_timer);
|
||||
return error;
|
||||
}
|
||||
|
||||
device_initcall(init_timer_sysfs);
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
int i;
|
||||
@ -533,12 +493,6 @@ void __init init_IRQ(void)
|
||||
set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
|
||||
set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
|
||||
|
||||
/*
|
||||
* Set the clock to HZ Hz, we already have a valid
|
||||
* vector now:
|
||||
*/
|
||||
setup_timer_hardware();
|
||||
|
||||
if (!acpi_ioapic)
|
||||
setup_irq(2, &irq2);
|
||||
}
|
||||
|
@ -223,8 +223,6 @@ void __cpuinit smp_callin(void)
|
||||
local_irq_disable();
|
||||
Dprintk("Stack at about %p\n",&cpuid);
|
||||
|
||||
disable_APIC_timer();
|
||||
|
||||
/*
|
||||
* Save our processor parameters
|
||||
*/
|
||||
@ -348,8 +346,6 @@ void __cpuinit start_secondary(void)
|
||||
enable_8259A_irq(0);
|
||||
}
|
||||
|
||||
enable_APIC_timer();
|
||||
|
||||
/*
|
||||
* The sibling maps must be set before turing the online map on for
|
||||
* this cpu
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clockchips.h>
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
#include <acpi/achware.h> /* for PM timer frequency */
|
||||
#include <acpi/acpi_bus.h>
|
||||
@ -46,12 +48,8 @@
|
||||
#include <asm/nmi.h>
|
||||
#include <asm/vgtod.h>
|
||||
|
||||
static char *timename = NULL;
|
||||
|
||||
DEFINE_SPINLOCK(rtc_lock);
|
||||
EXPORT_SYMBOL(rtc_lock);
|
||||
DEFINE_SPINLOCK(i8253_lock);
|
||||
EXPORT_SYMBOL(i8253_lock);
|
||||
|
||||
volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
|
||||
|
||||
@ -194,6 +192,13 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t timer_event_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
global_clock_event->event_handler(global_clock_event);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
unsigned long read_persistent_clock(void)
|
||||
{
|
||||
unsigned int year, mon, day, hour, min, sec;
|
||||
@ -291,42 +296,8 @@ static unsigned int __init tsc_calibrate_cpu_khz(void)
|
||||
return pmc_now * tsc_khz / (tsc_now - tsc_start);
|
||||
}
|
||||
|
||||
static void __pit_init(int val, u8 mode)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&i8253_lock, flags);
|
||||
outb_p(mode, PIT_MODE);
|
||||
outb_p(val & 0xff, PIT_CH0); /* LSB */
|
||||
outb_p(val >> 8, PIT_CH0); /* MSB */
|
||||
spin_unlock_irqrestore(&i8253_lock, flags);
|
||||
}
|
||||
|
||||
void __init pit_init(void)
|
||||
{
|
||||
__pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
|
||||
}
|
||||
|
||||
void pit_stop_interrupt(void)
|
||||
{
|
||||
__pit_init(0, 0x30); /* mode 0 */
|
||||
}
|
||||
|
||||
void stop_timer_interrupt(void)
|
||||
{
|
||||
char *name;
|
||||
if (hpet_address) {
|
||||
name = "HPET";
|
||||
hpet_timer_stop_set_go(0);
|
||||
} else {
|
||||
name = "PIT";
|
||||
pit_stop_interrupt();
|
||||
}
|
||||
printk(KERN_INFO "timer: %s interrupt stopped.\n", name);
|
||||
}
|
||||
|
||||
static struct irqaction irq0 = {
|
||||
.handler = timer_interrupt,
|
||||
.handler = timer_event_interrupt,
|
||||
.flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING,
|
||||
.mask = CPU_MASK_NONE,
|
||||
.name = "timer"
|
||||
@ -334,20 +305,10 @@ static struct irqaction irq0 = {
|
||||
|
||||
void __init time_init(void)
|
||||
{
|
||||
if (nohpet)
|
||||
hpet_address = 0;
|
||||
if (!hpet_enable())
|
||||
setup_pit_timer();
|
||||
|
||||
if (hpet_arch_init())
|
||||
hpet_address = 0;
|
||||
|
||||
if (hpet_use_timer) {
|
||||
/* set tick_nsec to use the proper rate for HPET */
|
||||
tick_nsec = TICK_NSEC_HPET;
|
||||
timename = "HPET";
|
||||
} else {
|
||||
pit_init();
|
||||
timename = "PIT";
|
||||
}
|
||||
setup_irq(0, &irq0);
|
||||
|
||||
tsc_calibrate();
|
||||
|
||||
@ -369,46 +330,4 @@ void __init time_init(void)
|
||||
printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
|
||||
cpu_khz / 1000, cpu_khz % 1000);
|
||||
init_tsc_clocksource();
|
||||
|
||||
setup_irq(0, &irq0);
|
||||
}
|
||||
|
||||
/*
|
||||
* sysfs support for the timer.
|
||||
*/
|
||||
|
||||
static int timer_suspend(struct sys_device *dev, pm_message_t state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int timer_resume(struct sys_device *dev)
|
||||
{
|
||||
if (hpet_address)
|
||||
hpet_reenable();
|
||||
else
|
||||
i8254_timer_resume();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sysdev_class timer_sysclass = {
|
||||
.resume = timer_resume,
|
||||
.suspend = timer_suspend,
|
||||
set_kset_name("timer"),
|
||||
};
|
||||
|
||||
/* XXX this sysfs stuff should probably go elsewhere later -john */
|
||||
static struct sys_device device_timer = {
|
||||
.id = 0,
|
||||
.cls = &timer_sysclass,
|
||||
};
|
||||
|
||||
static int time_init_device(void)
|
||||
{
|
||||
int error = sysdev_class_register(&timer_sysclass);
|
||||
if (!error)
|
||||
error = sysdev_register(&device_timer);
|
||||
return error;
|
||||
}
|
||||
|
||||
device_initcall(time_init_device);
|
||||
|
@ -40,7 +40,11 @@ config CLOCKSOURCE_WATCHDOG
|
||||
bool
|
||||
default y
|
||||
|
||||
config GENERIC_CLOCKEVENTS_MIGR
|
||||
config GENERIC_CLOCKEVENTS
|
||||
bool
|
||||
default y
|
||||
|
||||
config GENERIC_CLOCKEVENTS_BROADCAST
|
||||
bool
|
||||
default y
|
||||
|
||||
|
@ -1,5 +1,89 @@
|
||||
#ifdef CONFIG_X86_32
|
||||
# include "hpet_32.h"
|
||||
#ifndef ASM_X86_HPET_H
|
||||
#define ASM_X86_HPET_H
|
||||
|
||||
#ifdef CONFIG_HPET_TIMER
|
||||
|
||||
/*
|
||||
* Documentation on HPET can be found at:
|
||||
* http://www.intel.com/ial/home/sp/pcmmspec.htm
|
||||
* ftp://download.intel.com/ial/home/sp/mmts098.pdf
|
||||
*/
|
||||
|
||||
#define HPET_MMAP_SIZE 1024
|
||||
|
||||
#define HPET_ID 0x000
|
||||
#define HPET_PERIOD 0x004
|
||||
#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_ID_REV 0x000000ff
|
||||
#define HPET_ID_NUMBER 0x00001f00
|
||||
#define HPET_ID_64BIT 0x00002000
|
||||
#define HPET_ID_LEGSUP 0x00008000
|
||||
#define HPET_ID_VENDOR 0xffff0000
|
||||
#define HPET_ID_NUMBER_SHIFT 8
|
||||
#define HPET_ID_VENDOR_SHIFT 16
|
||||
|
||||
#define HPET_ID_VENDOR_8086 0x8086
|
||||
|
||||
#define HPET_CFG_ENABLE 0x001
|
||||
#define HPET_CFG_LEGACY 0x002
|
||||
#define HPET_LEGACY_8254 2
|
||||
#define HPET_LEGACY_RTC 8
|
||||
|
||||
#define HPET_TN_LEVEL 0x0002
|
||||
#define HPET_TN_ENABLE 0x0004
|
||||
#define HPET_TN_PERIODIC 0x0008
|
||||
#define HPET_TN_PERIODIC_CAP 0x0010
|
||||
#define HPET_TN_64BIT_CAP 0x0020
|
||||
#define HPET_TN_SETVAL 0x0040
|
||||
#define HPET_TN_32BIT 0x0100
|
||||
#define HPET_TN_ROUTE 0x3e00
|
||||
#define HPET_TN_FSB 0x4000
|
||||
#define HPET_TN_FSB_CAP 0x8000
|
||||
#define HPET_TN_ROUTE_SHIFT 9
|
||||
|
||||
/* Max HPET Period is 10^8 femto sec as in HPET spec */
|
||||
#define HPET_MAX_PERIOD 100000000UL
|
||||
/*
|
||||
* Min HPET period is 10^5 femto sec just for safety. If it is less than this,
|
||||
* then 32 bit HPET counter wrapsaround in less than 0.5 sec.
|
||||
*/
|
||||
#define HPET_MIN_PERIOD 100000UL
|
||||
|
||||
/* hpet memory map physical address */
|
||||
extern unsigned long hpet_address;
|
||||
extern int is_hpet_enabled(void);
|
||||
extern int hpet_enable(void);
|
||||
|
||||
#ifdef CONFIG_HPET_EMULATE_RTC
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
extern int hpet_mask_rtc_irq_bit(unsigned long bit_mask);
|
||||
extern int hpet_set_rtc_irq_bit(unsigned long bit_mask);
|
||||
extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min,
|
||||
unsigned char sec);
|
||||
extern int hpet_set_periodic_freq(unsigned long freq);
|
||||
extern int hpet_rtc_dropped_irq(void);
|
||||
extern int hpet_rtc_timer_init(void);
|
||||
extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
|
||||
|
||||
#endif /* CONFIG_HPET_EMULATE_RTC */
|
||||
|
||||
#else
|
||||
# include "hpet_64.h"
|
||||
#endif
|
||||
|
||||
static inline int hpet_enable(void) { return 0; }
|
||||
|
||||
#endif /* CONFIG_HPET_TIMER */
|
||||
#endif /* ASM_X86_HPET_H */
|
||||
|
@ -1,90 +0,0 @@
|
||||
|
||||
#ifndef _I386_HPET_H
|
||||
#define _I386_HPET_H
|
||||
|
||||
#ifdef CONFIG_HPET_TIMER
|
||||
|
||||
/*
|
||||
* Documentation on HPET can be found at:
|
||||
* http://www.intel.com/ial/home/sp/pcmmspec.htm
|
||||
* ftp://download.intel.com/ial/home/sp/mmts098.pdf
|
||||
*/
|
||||
|
||||
#define HPET_MMAP_SIZE 1024
|
||||
|
||||
#define HPET_ID 0x000
|
||||
#define HPET_PERIOD 0x004
|
||||
#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_ID_REV 0x000000ff
|
||||
#define HPET_ID_NUMBER 0x00001f00
|
||||
#define HPET_ID_64BIT 0x00002000
|
||||
#define HPET_ID_LEGSUP 0x00008000
|
||||
#define HPET_ID_VENDOR 0xffff0000
|
||||
#define HPET_ID_NUMBER_SHIFT 8
|
||||
#define HPET_ID_VENDOR_SHIFT 16
|
||||
|
||||
#define HPET_ID_VENDOR_8086 0x8086
|
||||
|
||||
#define HPET_CFG_ENABLE 0x001
|
||||
#define HPET_CFG_LEGACY 0x002
|
||||
#define HPET_LEGACY_8254 2
|
||||
#define HPET_LEGACY_RTC 8
|
||||
|
||||
#define HPET_TN_LEVEL 0x0002
|
||||
#define HPET_TN_ENABLE 0x0004
|
||||
#define HPET_TN_PERIODIC 0x0008
|
||||
#define HPET_TN_PERIODIC_CAP 0x0010
|
||||
#define HPET_TN_64BIT_CAP 0x0020
|
||||
#define HPET_TN_SETVAL 0x0040
|
||||
#define HPET_TN_32BIT 0x0100
|
||||
#define HPET_TN_ROUTE 0x3e00
|
||||
#define HPET_TN_FSB 0x4000
|
||||
#define HPET_TN_FSB_CAP 0x8000
|
||||
#define HPET_TN_ROUTE_SHIFT 9
|
||||
|
||||
/* Max HPET Period is 10^8 femto sec as in HPET spec */
|
||||
#define HPET_MAX_PERIOD 100000000UL
|
||||
/*
|
||||
* Min HPET period is 10^5 femto sec just for safety. If it is less than this,
|
||||
* then 32 bit HPET counter wrapsaround in less than 0.5 sec.
|
||||
*/
|
||||
#define HPET_MIN_PERIOD 100000UL
|
||||
|
||||
/* hpet memory map physical address */
|
||||
extern unsigned long hpet_address;
|
||||
extern int is_hpet_enabled(void);
|
||||
extern int hpet_enable(void);
|
||||
|
||||
#ifdef CONFIG_HPET_EMULATE_RTC
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
extern int hpet_mask_rtc_irq_bit(unsigned long bit_mask);
|
||||
extern int hpet_set_rtc_irq_bit(unsigned long bit_mask);
|
||||
extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min,
|
||||
unsigned char sec);
|
||||
extern int hpet_set_periodic_freq(unsigned long freq);
|
||||
extern int hpet_rtc_dropped_irq(void);
|
||||
extern int hpet_rtc_timer_init(void);
|
||||
extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
|
||||
|
||||
#endif /* CONFIG_HPET_EMULATE_RTC */
|
||||
|
||||
#else
|
||||
|
||||
static inline int hpet_enable(void) { return 0; }
|
||||
|
||||
#endif /* CONFIG_HPET_TIMER */
|
||||
#endif /* _I386_HPET_H */
|
@ -1,18 +0,0 @@
|
||||
#ifndef _ASM_X8664_HPET_H
|
||||
#define _ASM_X8664_HPET_H 1
|
||||
|
||||
#include <asm/hpet_32.h>
|
||||
|
||||
#define HPET_TICK_RATE (HZ * 100000UL)
|
||||
|
||||
extern int hpet_rtc_timer_init(void);
|
||||
extern int hpet_arch_init(void);
|
||||
extern int hpet_timer_stop_set_go(unsigned long tick);
|
||||
extern int hpet_reenable(void);
|
||||
extern unsigned int hpet_calibrate_tsc(void);
|
||||
|
||||
extern int hpet_use_timer;
|
||||
extern unsigned long hpet_period;
|
||||
extern unsigned long hpet_tick;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user