x86_64: remove now unused code
Remove the unused code after the switch to clock events. 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
2f0798a3b1
commit
9f75e9b74a
|
@ -7,7 +7,7 @@ extra-y := head_32.o init_task_32.o vmlinux.lds
|
||||||
obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
|
obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
|
||||||
ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
|
ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
|
||||||
pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\
|
pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\
|
||||||
quirks.o i8237.o topology.o alternative.o i8253_32.o tsc_32.o
|
quirks.o i8237.o topology.o alternative.o i8253.o tsc_32.o
|
||||||
|
|
||||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||||
obj-y += cpu/
|
obj-y += cpu/
|
||||||
|
@ -37,7 +37,7 @@ obj-$(CONFIG_EFI) += efi_32.o efi_stub_32.o
|
||||||
obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o
|
obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o
|
||||||
obj-$(CONFIG_VM86) += vm86_32.o
|
obj-$(CONFIG_VM86) += vm86_32.o
|
||||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||||
obj-$(CONFIG_HPET_TIMER) += hpet_32.o
|
obj-$(CONFIG_HPET_TIMER) += hpet.o
|
||||||
obj-$(CONFIG_K8_NB) += k8.o
|
obj-$(CONFIG_K8_NB) += k8.o
|
||||||
obj-$(CONFIG_MGEODE_LX) += geode_32.o mfgpt_32.o
|
obj-$(CONFIG_MGEODE_LX) += geode_32.o mfgpt_32.o
|
||||||
|
|
||||||
|
|
|
@ -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 \
|
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 \
|
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 \
|
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_32.o tsc_64.o bugs_64.o \
|
pci-dma_64.o pci-nommu_64.o alternative.o hpet.o tsc_64.o bugs_64.o \
|
||||||
perfctr-watchdog.o i8253_32.o
|
perfctr-watchdog.o i8253.o
|
||||||
|
|
||||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||||
obj-$(CONFIG_X86_MCE) += mce_64.o therm_throt.o
|
obj-$(CONFIG_X86_MCE) += mce_64.o therm_throt.o
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
|
|
||||||
int apic_verbosity;
|
int apic_verbosity;
|
||||||
int apic_runs_main_timer;
|
|
||||||
int apic_calibrate_pmtmr __initdata;
|
int apic_calibrate_pmtmr __initdata;
|
||||||
|
|
||||||
int disable_apic_timer __cpuinitdata;
|
int disable_apic_timer __cpuinitdata;
|
||||||
|
@ -129,15 +128,6 @@ static void lapic_timer_broadcast(cpumask_t mask)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* cpu_mask that denotes the CPUs that needs timer interrupt coming in as
|
|
||||||
* IPIs in place of local APIC timers
|
|
||||||
*/
|
|
||||||
static cpumask_t timer_interrupt_broadcast_ipi_mask;
|
|
||||||
|
|
||||||
/* Using APIC to generate smp_local_timer_interrupt? */
|
|
||||||
int using_apic_timer __read_mostly = 0;
|
|
||||||
|
|
||||||
static void apic_pm_activate(void);
|
static void apic_pm_activate(void);
|
||||||
|
|
||||||
void apic_wait_icr_idle(void)
|
void apic_wait_icr_idle(void)
|
||||||
|
@ -973,84 +963,6 @@ void __cpuinit setup_secondary_APIC_clock(void)
|
||||||
setup_APIC_timer();
|
setup_APIC_timer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable_APIC_timer(void)
|
|
||||||
{
|
|
||||||
if (using_apic_timer) {
|
|
||||||
unsigned long v;
|
|
||||||
|
|
||||||
v = apic_read(APIC_LVTT);
|
|
||||||
/*
|
|
||||||
* When an illegal vector value (0-15) is written to an LVT
|
|
||||||
* entry and delivery mode is Fixed, the APIC may signal an
|
|
||||||
* illegal vector error, with out regard to whether the mask
|
|
||||||
* bit is set or whether an interrupt is actually seen on input.
|
|
||||||
*
|
|
||||||
* Boot sequence might call this function when the LVTT has
|
|
||||||
* '0' vector value. So make sure vector field is set to
|
|
||||||
* valid value.
|
|
||||||
*/
|
|
||||||
v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
|
|
||||||
apic_write(APIC_LVTT, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void enable_APIC_timer(void)
|
|
||||||
{
|
|
||||||
int cpu = smp_processor_id();
|
|
||||||
|
|
||||||
if (using_apic_timer &&
|
|
||||||
!cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) {
|
|
||||||
unsigned long v;
|
|
||||||
|
|
||||||
v = apic_read(APIC_LVTT);
|
|
||||||
apic_write(APIC_LVTT, v & ~APIC_LVT_MASKED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void switch_APIC_timer_to_ipi(void *cpumask)
|
|
||||||
{
|
|
||||||
cpumask_t mask = *(cpumask_t *)cpumask;
|
|
||||||
int cpu = smp_processor_id();
|
|
||||||
|
|
||||||
if (cpu_isset(cpu, mask) &&
|
|
||||||
!cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) {
|
|
||||||
disable_APIC_timer();
|
|
||||||
cpu_set(cpu, timer_interrupt_broadcast_ipi_mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(switch_APIC_timer_to_ipi);
|
|
||||||
|
|
||||||
void smp_send_timer_broadcast_ipi(void)
|
|
||||||
{
|
|
||||||
int cpu = smp_processor_id();
|
|
||||||
cpumask_t mask;
|
|
||||||
|
|
||||||
cpus_and(mask, cpu_online_map, timer_interrupt_broadcast_ipi_mask);
|
|
||||||
|
|
||||||
if (cpu_isset(cpu, mask)) {
|
|
||||||
cpu_clear(cpu, mask);
|
|
||||||
add_pda(apic_timer_irqs, 1);
|
|
||||||
smp_local_timer_interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cpus_empty(mask)) {
|
|
||||||
send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void switch_ipi_to_APIC_timer(void *cpumask)
|
|
||||||
{
|
|
||||||
cpumask_t mask = *(cpumask_t *)cpumask;
|
|
||||||
int cpu = smp_processor_id();
|
|
||||||
|
|
||||||
if (cpu_isset(cpu, mask) &&
|
|
||||||
cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) {
|
|
||||||
cpu_clear(cpu, timer_interrupt_broadcast_ipi_mask);
|
|
||||||
enable_APIC_timer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(switch_ipi_to_APIC_timer);
|
|
||||||
|
|
||||||
int setup_profiling_timer(unsigned int multiplier)
|
int setup_profiling_timer(unsigned int multiplier)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1297,21 +1209,7 @@ static __init int setup_noapictimer(char *str)
|
||||||
disable_apic_timer = 1;
|
disable_apic_timer = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
__setup("noapictimer", setup_noapictimer);
|
||||||
static __init int setup_apicmaintimer(char *str)
|
|
||||||
{
|
|
||||||
apic_runs_main_timer = 1;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
__setup("apicmaintimer", setup_apicmaintimer);
|
|
||||||
|
|
||||||
static __init int setup_noapicmaintimer(char *str)
|
|
||||||
{
|
|
||||||
apic_runs_main_timer = -1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
__setup("noapicmaintimer", setup_noapicmaintimer);
|
|
||||||
|
|
||||||
static __init int setup_apicpmtimer(char *s)
|
static __init int setup_apicpmtimer(char *s)
|
||||||
{
|
{
|
||||||
|
@ -1321,5 +1219,3 @@ static __init int setup_apicpmtimer(char *s)
|
||||||
}
|
}
|
||||||
__setup("apicpmtimer", setup_apicpmtimer);
|
__setup("apicpmtimer", setup_apicpmtimer);
|
||||||
|
|
||||||
__setup("noapictimer", setup_noapictimer);
|
|
||||||
|
|
||||||
|
|
|
@ -1,444 +0,0 @@
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/mc146818rtc.h>
|
|
||||||
#include <linux/time.h>
|
|
||||||
#include <linux/clocksource.h>
|
|
||||||
#include <linux/ioport.h>
|
|
||||||
#include <linux/acpi.h>
|
|
||||||
#include <linux/hpet.h>
|
|
||||||
#include <asm/pgtable.h>
|
|
||||||
#include <asm/vsyscall.h>
|
|
||||||
#include <asm/timex.h>
|
|
||||||
#include <asm/hpet.h>
|
|
||||||
|
|
||||||
#define HPET_MASK 0xFFFFFFFF
|
|
||||||
#define HPET_SHIFT 22
|
|
||||||
|
|
||||||
/* FSEC = 10^-15 NSEC = 10^-9 */
|
|
||||||
#define FSEC_PER_NSEC 1000000
|
|
||||||
|
|
||||||
int nohpet __initdata;
|
|
||||||
|
|
||||||
unsigned long hpet_address;
|
|
||||||
unsigned long hpet_period; /* fsecs / HPET clock */
|
|
||||||
unsigned long hpet_tick; /* HPET clocks / interrupt */
|
|
||||||
|
|
||||||
int hpet_use_timer; /* Use counter of hpet for time keeping,
|
|
||||||
* otherwise PIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef CONFIG_HPET
|
|
||||||
static __init int late_hpet_init(void)
|
|
||||||
{
|
|
||||||
struct hpet_data hd;
|
|
||||||
unsigned int ntimer;
|
|
||||||
|
|
||||||
if (!hpet_address)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
memset(&hd, 0, sizeof(hd));
|
|
||||||
|
|
||||||
ntimer = hpet_readl(HPET_ID);
|
|
||||||
ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT;
|
|
||||||
ntimer++;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register with driver.
|
|
||||||
* Timer0 and Timer1 is used by platform.
|
|
||||||
*/
|
|
||||||
hd.hd_phys_address = hpet_address;
|
|
||||||
hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE);
|
|
||||||
hd.hd_nirqs = ntimer;
|
|
||||||
hd.hd_flags = HPET_DATA_PLATFORM;
|
|
||||||
hpet_reserve_timer(&hd, 0);
|
|
||||||
#ifdef CONFIG_HPET_EMULATE_RTC
|
|
||||||
hpet_reserve_timer(&hd, 1);
|
|
||||||
#endif
|
|
||||||
hd.hd_irq[0] = HPET_LEGACY_8254;
|
|
||||||
hd.hd_irq[1] = HPET_LEGACY_RTC;
|
|
||||||
if (ntimer > 2) {
|
|
||||||
struct hpet *hpet;
|
|
||||||
struct hpet_timer *timer;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE);
|
|
||||||
timer = &hpet->hpet_timers[2];
|
|
||||||
for (i = 2; i < ntimer; timer++, i++)
|
|
||||||
hd.hd_irq[i] = (timer->hpet_config &
|
|
||||||
Tn_INT_ROUTE_CNF_MASK) >>
|
|
||||||
Tn_INT_ROUTE_CNF_SHIFT;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
hpet_alloc(&hd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
fs_initcall(late_hpet_init);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int hpet_timer_stop_set_go(unsigned long tick)
|
|
||||||
{
|
|
||||||
unsigned int cfg;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stop the timers and reset the main counter.
|
|
||||||
*/
|
|
||||||
|
|
||||||
cfg = hpet_readl(HPET_CFG);
|
|
||||||
cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY);
|
|
||||||
hpet_writel(cfg, HPET_CFG);
|
|
||||||
hpet_writel(0, HPET_COUNTER);
|
|
||||||
hpet_writel(0, HPET_COUNTER + 4);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up timer 0, as periodic with first interrupt to happen at hpet_tick,
|
|
||||||
* and period also hpet_tick.
|
|
||||||
*/
|
|
||||||
if (hpet_use_timer) {
|
|
||||||
hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
|
|
||||||
HPET_TN_32BIT, HPET_T0_CFG);
|
|
||||||
hpet_writel(hpet_tick, HPET_T0_CMP); /* next interrupt */
|
|
||||||
hpet_writel(hpet_tick, HPET_T0_CMP); /* period */
|
|
||||||
cfg |= HPET_CFG_LEGACY;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Go!
|
|
||||||
*/
|
|
||||||
|
|
||||||
cfg |= HPET_CFG_ENABLE;
|
|
||||||
hpet_writel(cfg, HPET_CFG);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cycle_t read_hpet(void)
|
|
||||||
{
|
|
||||||
return (cycle_t)hpet_readl(HPET_COUNTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cycle_t __vsyscall_fn vread_hpet(void)
|
|
||||||
{
|
|
||||||
return readl((void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct clocksource clocksource_hpet = {
|
|
||||||
.name = "hpet",
|
|
||||||
.rating = 250,
|
|
||||||
.read = read_hpet,
|
|
||||||
.mask = (cycle_t)HPET_MASK,
|
|
||||||
.mult = 0, /* set below */
|
|
||||||
.shift = HPET_SHIFT,
|
|
||||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
|
||||||
.vread = vread_hpet,
|
|
||||||
};
|
|
||||||
|
|
||||||
int __init hpet_arch_init(void)
|
|
||||||
{
|
|
||||||
unsigned int id;
|
|
||||||
u64 tmp;
|
|
||||||
|
|
||||||
if (!hpet_address)
|
|
||||||
return -1;
|
|
||||||
set_fixmap_nocache(FIX_HPET_BASE, hpet_address);
|
|
||||||
__set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read the period, compute tick and quotient.
|
|
||||||
*/
|
|
||||||
|
|
||||||
id = hpet_readl(HPET_ID);
|
|
||||||
|
|
||||||
if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
hpet_period = hpet_readl(HPET_PERIOD);
|
|
||||||
if (hpet_period < 100000 || hpet_period > 100000000)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
hpet_tick = (FSEC_PER_TICK + hpet_period / 2) / hpet_period;
|
|
||||||
|
|
||||||
hpet_use_timer = (id & HPET_ID_LEGSUP);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hpet period is in femto seconds per cycle
|
|
||||||
* so we need to convert this to ns/cyc units
|
|
||||||
* aproximated by mult/2^shift
|
|
||||||
*
|
|
||||||
* fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift
|
|
||||||
* fsec/cyc * 1ns/1000000fsec * 2^shift = mult
|
|
||||||
* fsec/cyc * 2^shift * 1nsec/1000000fsec = mult
|
|
||||||
* (fsec/cyc << shift)/1000000 = mult
|
|
||||||
* (hpet_period << shift)/FSEC_PER_NSEC = mult
|
|
||||||
*/
|
|
||||||
tmp = (u64)hpet_period << HPET_SHIFT;
|
|
||||||
do_div(tmp, FSEC_PER_NSEC);
|
|
||||||
clocksource_hpet.mult = (u32)tmp;
|
|
||||||
clocksource_register(&clocksource_hpet);
|
|
||||||
|
|
||||||
return hpet_timer_stop_set_go(hpet_tick);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpet_reenable(void)
|
|
||||||
{
|
|
||||||
return hpet_timer_stop_set_go(hpet_tick);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_HPET_EMULATE_RTC
|
|
||||||
/* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET
|
|
||||||
* is enabled, we support RTC interrupt functionality in software.
|
|
||||||
* RTC has 3 kinds of interrupts:
|
|
||||||
* 1) Update Interrupt - generate an interrupt, every sec, when RTC clock
|
|
||||||
* is updated
|
|
||||||
* 2) Alarm Interrupt - generate an interrupt at a specific time of day
|
|
||||||
* 3) Periodic Interrupt - generate periodic interrupt, with frequencies
|
|
||||||
* 2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2)
|
|
||||||
* (1) and (2) above are implemented using polling at a frequency of
|
|
||||||
* 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt
|
|
||||||
* overhead. (DEFAULT_RTC_INT_FREQ)
|
|
||||||
* For (3), we use interrupts at 64Hz or user specified periodic
|
|
||||||
* frequency, whichever is higher.
|
|
||||||
*/
|
|
||||||
#include <linux/rtc.h>
|
|
||||||
|
|
||||||
#define DEFAULT_RTC_INT_FREQ 64
|
|
||||||
#define RTC_NUM_INTS 1
|
|
||||||
|
|
||||||
static unsigned long UIE_on;
|
|
||||||
static unsigned long prev_update_sec;
|
|
||||||
|
|
||||||
static unsigned long AIE_on;
|
|
||||||
static struct rtc_time alarm_time;
|
|
||||||
|
|
||||||
static unsigned long PIE_on;
|
|
||||||
static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
|
|
||||||
static unsigned long PIE_count;
|
|
||||||
|
|
||||||
static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
|
|
||||||
static unsigned int hpet_t1_cmp; /* cached comparator register */
|
|
||||||
|
|
||||||
int is_hpet_enabled(void)
|
|
||||||
{
|
|
||||||
return hpet_address != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Timer 1 for RTC, we do not use periodic interrupt feature,
|
|
||||||
* even if HPET supports periodic interrupts on Timer 1.
|
|
||||||
* The reason being, to set up a periodic interrupt in HPET, we need to
|
|
||||||
* stop the main counter. And if we do that everytime someone diables/enables
|
|
||||||
* RTC, we will have adverse effect on main kernel timer running on Timer 0.
|
|
||||||
* So, for the time being, simulate the periodic interrupt in software.
|
|
||||||
*
|
|
||||||
* hpet_rtc_timer_init() is called for the first time and during subsequent
|
|
||||||
* interuppts reinit happens through hpet_rtc_timer_reinit().
|
|
||||||
*/
|
|
||||||
int hpet_rtc_timer_init(void)
|
|
||||||
{
|
|
||||||
unsigned int cfg, cnt;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!is_hpet_enabled())
|
|
||||||
return 0;
|
|
||||||
/*
|
|
||||||
* Set the counter 1 and enable the interrupts.
|
|
||||||
*/
|
|
||||||
if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
|
|
||||||
hpet_rtc_int_freq = PIE_freq;
|
|
||||||
else
|
|
||||||
hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
|
|
||||||
|
|
||||||
local_irq_save(flags);
|
|
||||||
|
|
||||||
cnt = hpet_readl(HPET_COUNTER);
|
|
||||||
cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
|
|
||||||
hpet_writel(cnt, HPET_T1_CMP);
|
|
||||||
hpet_t1_cmp = cnt;
|
|
||||||
|
|
||||||
cfg = hpet_readl(HPET_T1_CFG);
|
|
||||||
cfg &= ~HPET_TN_PERIODIC;
|
|
||||||
cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
|
|
||||||
hpet_writel(cfg, HPET_T1_CFG);
|
|
||||||
|
|
||||||
local_irq_restore(flags);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hpet_rtc_timer_reinit(void)
|
|
||||||
{
|
|
||||||
unsigned int cfg, cnt, ticks_per_int, lost_ints;
|
|
||||||
|
|
||||||
if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
|
|
||||||
cfg = hpet_readl(HPET_T1_CFG);
|
|
||||||
cfg &= ~HPET_TN_ENABLE;
|
|
||||||
hpet_writel(cfg, HPET_T1_CFG);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
|
|
||||||
hpet_rtc_int_freq = PIE_freq;
|
|
||||||
else
|
|
||||||
hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
|
|
||||||
|
|
||||||
/* It is more accurate to use the comparator value than current count.*/
|
|
||||||
ticks_per_int = hpet_tick * HZ / hpet_rtc_int_freq;
|
|
||||||
hpet_t1_cmp += ticks_per_int;
|
|
||||||
hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the interrupt handler was delayed too long, the write above tries
|
|
||||||
* to schedule the next interrupt in the past and the hardware would
|
|
||||||
* not interrupt until the counter had wrapped around.
|
|
||||||
* So we have to check that the comparator wasn't set to a past time.
|
|
||||||
*/
|
|
||||||
cnt = hpet_readl(HPET_COUNTER);
|
|
||||||
if (unlikely((int)(cnt - hpet_t1_cmp) > 0)) {
|
|
||||||
lost_ints = (cnt - hpet_t1_cmp) / ticks_per_int + 1;
|
|
||||||
/* Make sure that, even with the time needed to execute
|
|
||||||
* this code, the next scheduled interrupt has been moved
|
|
||||||
* back to the future: */
|
|
||||||
lost_ints++;
|
|
||||||
|
|
||||||
hpet_t1_cmp += lost_ints * ticks_per_int;
|
|
||||||
hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
|
|
||||||
|
|
||||||
if (PIE_on)
|
|
||||||
PIE_count += lost_ints;
|
|
||||||
|
|
||||||
if (printk_ratelimit())
|
|
||||||
printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n",
|
|
||||||
hpet_rtc_int_freq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The functions below are called from rtc driver.
|
|
||||||
* Return 0 if HPET is not being used.
|
|
||||||
* Otherwise do the necessary changes and return 1.
|
|
||||||
*/
|
|
||||||
int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
|
|
||||||
{
|
|
||||||
if (!is_hpet_enabled())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (bit_mask & RTC_UIE)
|
|
||||||
UIE_on = 0;
|
|
||||||
if (bit_mask & RTC_PIE)
|
|
||||||
PIE_on = 0;
|
|
||||||
if (bit_mask & RTC_AIE)
|
|
||||||
AIE_on = 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpet_set_rtc_irq_bit(unsigned long bit_mask)
|
|
||||||
{
|
|
||||||
int timer_init_reqd = 0;
|
|
||||||
|
|
||||||
if (!is_hpet_enabled())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!(PIE_on | AIE_on | UIE_on))
|
|
||||||
timer_init_reqd = 1;
|
|
||||||
|
|
||||||
if (bit_mask & RTC_UIE) {
|
|
||||||
UIE_on = 1;
|
|
||||||
}
|
|
||||||
if (bit_mask & RTC_PIE) {
|
|
||||||
PIE_on = 1;
|
|
||||||
PIE_count = 0;
|
|
||||||
}
|
|
||||||
if (bit_mask & RTC_AIE) {
|
|
||||||
AIE_on = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timer_init_reqd)
|
|
||||||
hpet_rtc_timer_init();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec)
|
|
||||||
{
|
|
||||||
if (!is_hpet_enabled())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
alarm_time.tm_hour = hrs;
|
|
||||||
alarm_time.tm_min = min;
|
|
||||||
alarm_time.tm_sec = sec;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpet_set_periodic_freq(unsigned long freq)
|
|
||||||
{
|
|
||||||
if (!is_hpet_enabled())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
PIE_freq = freq;
|
|
||||||
PIE_count = 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpet_rtc_dropped_irq(void)
|
|
||||||
{
|
|
||||||
if (!is_hpet_enabled())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
|
|
||||||
{
|
|
||||||
struct rtc_time curr_time;
|
|
||||||
unsigned long rtc_int_flag = 0;
|
|
||||||
int call_rtc_interrupt = 0;
|
|
||||||
|
|
||||||
hpet_rtc_timer_reinit();
|
|
||||||
|
|
||||||
if (UIE_on | AIE_on) {
|
|
||||||
rtc_get_rtc_time(&curr_time);
|
|
||||||
}
|
|
||||||
if (UIE_on) {
|
|
||||||
if (curr_time.tm_sec != prev_update_sec) {
|
|
||||||
/* Set update int info, call real rtc int routine */
|
|
||||||
call_rtc_interrupt = 1;
|
|
||||||
rtc_int_flag = RTC_UF;
|
|
||||||
prev_update_sec = curr_time.tm_sec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (PIE_on) {
|
|
||||||
PIE_count++;
|
|
||||||
if (PIE_count >= hpet_rtc_int_freq/PIE_freq) {
|
|
||||||
/* Set periodic int info, call real rtc int routine */
|
|
||||||
call_rtc_interrupt = 1;
|
|
||||||
rtc_int_flag |= RTC_PF;
|
|
||||||
PIE_count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (AIE_on) {
|
|
||||||
if ((curr_time.tm_sec == alarm_time.tm_sec) &&
|
|
||||||
(curr_time.tm_min == alarm_time.tm_min) &&
|
|
||||||
(curr_time.tm_hour == alarm_time.tm_hour)) {
|
|
||||||
/* Set alarm int info, call real rtc int routine */
|
|
||||||
call_rtc_interrupt = 1;
|
|
||||||
rtc_int_flag |= RTC_AF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (call_rtc_interrupt) {
|
|
||||||
rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8));
|
|
||||||
rtc_interrupt(rtc_int_flag, dev_id);
|
|
||||||
}
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int __init nohpet_setup(char *s)
|
|
||||||
{
|
|
||||||
nohpet = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
__setup("nohpet", nohpet_setup);
|
|
|
@ -150,48 +150,6 @@ int update_persistent_clock(struct timespec now)
|
||||||
return set_rtc_mmss(now.tv_sec);
|
return set_rtc_mmss(now.tv_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main_timer_handler(void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Here we are in the timer irq handler. We have irqs locally disabled (so we
|
|
||||||
* don't need spin_lock_irqsave()) but we don't know if the timer_bh is running
|
|
||||||
* on the other CPU, so we need a lock. We also need to lock the vsyscall
|
|
||||||
* variables, because both do_timer() and us change them -arca+vojtech
|
|
||||||
*/
|
|
||||||
|
|
||||||
write_seqlock(&xtime_lock);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do the timer stuff.
|
|
||||||
*/
|
|
||||||
|
|
||||||
do_timer(1);
|
|
||||||
#ifndef CONFIG_SMP
|
|
||||||
update_process_times(user_mode(get_irq_regs()));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In the SMP case we use the local APIC timer interrupt to do the profiling,
|
|
||||||
* except when we simulate SMP mode on a uniprocessor system, in that case we
|
|
||||||
* have to call the local interrupt handler.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!using_apic_timer)
|
|
||||||
smp_local_timer_interrupt();
|
|
||||||
|
|
||||||
write_sequnlock(&xtime_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t timer_interrupt(int irq, void *dev_id)
|
|
||||||
{
|
|
||||||
if (apic_runs_main_timer > 1)
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
main_timer_handler();
|
|
||||||
if (using_apic_timer)
|
|
||||||
smp_send_timer_broadcast_ipi();
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t timer_event_interrupt(int irq, void *dev_id)
|
static irqreturn_t timer_event_interrupt(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
add_pda(irq0_irqs, 1);
|
add_pda(irq0_irqs, 1);
|
||||||
|
|
|
@ -79,8 +79,6 @@ extern void smp_local_timer_interrupt (void);
|
||||||
extern void setup_boot_APIC_clock (void);
|
extern void setup_boot_APIC_clock (void);
|
||||||
extern void setup_secondary_APIC_clock (void);
|
extern void setup_secondary_APIC_clock (void);
|
||||||
extern int APIC_init_uniprocessor (void);
|
extern int APIC_init_uniprocessor (void);
|
||||||
extern void disable_APIC_timer(void);
|
|
||||||
extern void enable_APIC_timer(void);
|
|
||||||
extern void setup_apic_routing(void);
|
extern void setup_apic_routing(void);
|
||||||
|
|
||||||
extern void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector,
|
extern void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector,
|
||||||
|
@ -95,10 +93,6 @@ extern int apic_is_clustered_box(void);
|
||||||
#define K8_APIC_EXT_INT_MSG_EXT 0x7
|
#define K8_APIC_EXT_INT_MSG_EXT 0x7
|
||||||
#define K8_APIC_EXT_LVT_ENTRY_THRESHOLD 0
|
#define K8_APIC_EXT_LVT_ENTRY_THRESHOLD 0
|
||||||
|
|
||||||
void smp_send_timer_broadcast_ipi(void);
|
|
||||||
void switch_APIC_timer_to_ipi(void *cpumask);
|
|
||||||
void switch_ipi_to_APIC_timer(void *cpumask);
|
|
||||||
|
|
||||||
#define ARCH_APICTIMER_STOPS_ON_C3 1
|
#define ARCH_APICTIMER_STOPS_ON_C3 1
|
||||||
|
|
||||||
extern unsigned boot_cpu_id;
|
extern unsigned boot_cpu_id;
|
||||||
|
|
|
@ -51,9 +51,6 @@ extern void reserve_bootmem_generic(unsigned long phys, unsigned len);
|
||||||
|
|
||||||
extern void load_gs_index(unsigned gs);
|
extern void load_gs_index(unsigned gs);
|
||||||
|
|
||||||
extern void stop_timer_interrupt(void);
|
|
||||||
extern void main_timer_handler(void);
|
|
||||||
|
|
||||||
extern unsigned long end_pfn_map;
|
extern unsigned long end_pfn_map;
|
||||||
|
|
||||||
extern void show_trace(struct task_struct *, struct pt_regs *, unsigned long * rsp);
|
extern void show_trace(struct task_struct *, struct pt_regs *, unsigned long * rsp);
|
||||||
|
@ -90,14 +87,10 @@ extern int timer_over_8254;
|
||||||
|
|
||||||
extern int gsi_irq_sharing(int gsi);
|
extern int gsi_irq_sharing(int gsi);
|
||||||
|
|
||||||
extern void smp_local_timer_interrupt(void);
|
|
||||||
|
|
||||||
extern int force_mwait;
|
extern int force_mwait;
|
||||||
|
|
||||||
long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
|
long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
|
||||||
|
|
||||||
void i8254_timer_resume(void);
|
|
||||||
|
|
||||||
#define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))
|
#define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))
|
||||||
#define round_down(x,y) ((x) & ~((y)-1))
|
#define round_down(x,y) ((x) & ~((y)-1))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue