Commit e193be86 authored by John Levon's avatar John Levon Committed by Linus Torvalds

[PATCH] Convert APIC to driver model

This is Mikael's version of Pavel's patch, fixed to let CONFIG_PM=n
compile. It works for me on my 2-way using oprofile.
parent 962b2f89
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
* for testing these extensively. * for testing these extensively.
* Maciej W. Rozycki : Various updates and fixes. * Maciej W. Rozycki : Various updates and fixes.
* Mikael Pettersson : Power Management for UP-APIC. * Mikael Pettersson : Power Management for UP-APIC.
* Pavel Machek and
* Mikael Pettersson : PM converted to driver model.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -451,17 +453,14 @@ void __init setup_local_APIC (void) ...@@ -451,17 +453,14 @@ void __init setup_local_APIC (void)
#ifdef CONFIG_PM #ifdef CONFIG_PM
#include <linux/slab.h> #include <linux/device.h>
#include <linux/pm.h> #include <linux/module.h>
static struct { static struct {
/* 'active' is true if the local APIC was enabled by us and /* 'active' is true if the local APIC was enabled by us and
not the BIOS; this signifies that we are also responsible not the BIOS; this signifies that we are also responsible
for disabling it before entering apm/acpi suspend */ for disabling it before entering apm/acpi suspend */
int active; int active;
/* 'perfctr_pmdev' is here because the current (2.4.1) PM
callback system doesn't handle hierarchical dependencies */
struct pm_dev *perfctr_pmdev;
/* r/w apic fields */ /* r/w apic fields */
unsigned int apic_id; unsigned int apic_id;
unsigned int apic_taskpri; unsigned int apic_taskpri;
...@@ -478,13 +477,16 @@ static struct { ...@@ -478,13 +477,16 @@ static struct {
unsigned int apic_thmr; unsigned int apic_thmr;
} apic_pm_state; } apic_pm_state;
static void apic_pm_suspend(void *data) static int lapic_suspend(struct device *dev, u32 state, u32 level)
{ {
unsigned int l, h; unsigned int l, h;
unsigned long flags; unsigned long flags;
if (apic_pm_state.perfctr_pmdev) if (level != SUSPEND_POWER_DOWN)
pm_send(apic_pm_state.perfctr_pmdev, PM_SUSPEND, data); return 0;
if (!apic_pm_state.active)
return 0;
apic_pm_state.apic_id = apic_read(APIC_ID); apic_pm_state.apic_id = apic_read(APIC_ID);
apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
apic_pm_state.apic_ldr = apic_read(APIC_LDR); apic_pm_state.apic_ldr = apic_read(APIC_LDR);
...@@ -505,13 +507,22 @@ static void apic_pm_suspend(void *data) ...@@ -505,13 +507,22 @@ static void apic_pm_suspend(void *data)
l &= ~MSR_IA32_APICBASE_ENABLE; l &= ~MSR_IA32_APICBASE_ENABLE;
wrmsr(MSR_IA32_APICBASE, l, h); wrmsr(MSR_IA32_APICBASE, l, h);
local_irq_restore(flags); local_irq_restore(flags);
return 0;
} }
static void apic_pm_resume(void *data) static int lapic_resume(struct device *dev, u32 level)
{ {
unsigned int l, h; unsigned int l, h;
unsigned long flags; unsigned long flags;
if (level != RESUME_POWER_ON)
return 0;
if (!apic_pm_state.active)
return 0;
/* XXX: Pavel needs this for S3 resume, but can't explain why */
set_fixmap_nocache(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE);
local_irq_save(flags); local_irq_save(flags);
rdmsr(MSR_IA32_APICBASE, l, h); rdmsr(MSR_IA32_APICBASE, l, h);
l &= ~MSR_IA32_APICBASE_BASE; l &= ~MSR_IA32_APICBASE_BASE;
...@@ -536,73 +547,45 @@ static void apic_pm_resume(void *data) ...@@ -536,73 +547,45 @@ static void apic_pm_resume(void *data)
apic_write(APIC_ESR, 0); apic_write(APIC_ESR, 0);
apic_read(APIC_ESR); apic_read(APIC_ESR);
local_irq_restore(flags); local_irq_restore(flags);
if (apic_pm_state.perfctr_pmdev)
pm_send(apic_pm_state.perfctr_pmdev, PM_RESUME, data);
}
static int apic_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
{
switch (rqst) {
case PM_SUSPEND:
apic_pm_suspend(data);
break;
case PM_RESUME:
apic_pm_resume(data);
break;
}
return 0; return 0;
} }
/* perfctr driver should call this instead of pm_register() */ static struct device_driver lapic_driver = {
struct pm_dev *apic_pm_register(pm_dev_t type, .name = "lapic",
unsigned long id, .bus = &system_bus_type,
pm_callback callback) .resume = lapic_resume,
{ .suspend = lapic_suspend,
struct pm_dev *dev; };
if (!apic_pm_state.active) /* not static, needed by child devices */
return pm_register(type, id, callback); struct sys_device device_lapic = {
if (apic_pm_state.perfctr_pmdev) .name = "lapic",
return NULL; /* we're busy */ .id = 0,
dev = kmalloc(sizeof(struct pm_dev), GFP_KERNEL); .dev = {
if (dev) { .name = "lapic",
memset(dev, 0, sizeof(*dev)); .driver = &lapic_driver,
dev->type = type; },
dev->id = id; };
dev->callback = callback; EXPORT_SYMBOL(device_lapic);
apic_pm_state.perfctr_pmdev = dev;
} static void __init apic_pm_activate(void)
return dev;
}
/* perfctr driver should call this instead of pm_unregister() */
void apic_pm_unregister(struct pm_dev *dev)
{ {
if (!apic_pm_state.active) {
pm_unregister(dev);
} else if (dev == apic_pm_state.perfctr_pmdev) {
apic_pm_state.perfctr_pmdev = NULL;
kfree(dev);
}
}
static void __init apic_pm_init1(void)
{
/* can't pm_register() at this early stage in the boot process
(causes an immediate reboot), so just set the flag */
apic_pm_state.active = 1; apic_pm_state.active = 1;
} }
static void __init apic_pm_init2(void) static int __init init_lapic_devicefs(void)
{ {
if (apic_pm_state.active) if (!cpu_has_apic)
pm_register(PM_SYS_DEV, 0, apic_pm_callback); return 0;
/* XXX: remove suspend/resume procs if !apic_pm_state.active? */
driver_register(&lapic_driver);
return sys_device_register(&device_lapic);
} }
device_initcall(init_lapic_devicefs);
#else /* CONFIG_PM */ #else /* CONFIG_PM */
static inline void apic_pm_init1(void) { } static inline void apic_pm_activate(void) { }
static inline void apic_pm_init2(void) { }
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
...@@ -670,7 +653,7 @@ static int __init detect_init_APIC (void) ...@@ -670,7 +653,7 @@ static int __init detect_init_APIC (void)
printk("Found and enabled local APIC!\n"); printk("Found and enabled local APIC!\n");
apic_pm_init1(); apic_pm_activate();
return 0; return 0;
...@@ -1155,8 +1138,6 @@ int __init APIC_init_uniprocessor (void) ...@@ -1155,8 +1138,6 @@ int __init APIC_init_uniprocessor (void)
phys_cpu_present_map = 1 << boot_cpu_physical_apicid; phys_cpu_present_map = 1 << boot_cpu_physical_apicid;
apic_pm_init2();
setup_local_APIC(); setup_local_APIC();
if (nmi_watchdog == NMI_LOCAL_APIC) if (nmi_watchdog == NMI_LOCAL_APIC)
......
...@@ -218,6 +218,7 @@ ...@@ -218,6 +218,7 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/device.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
...@@ -1237,6 +1238,9 @@ static int suspend(int vetoable) ...@@ -1237,6 +1238,9 @@ static int suspend(int vetoable)
} }
printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n"); printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
} }
device_suspend(3, SUSPEND_POWER_DOWN);
/* serialize with the timer interrupt */ /* serialize with the timer interrupt */
write_seqlock_irq(&xtime_lock); write_seqlock_irq(&xtime_lock);
...@@ -1257,6 +1261,7 @@ static int suspend(int vetoable) ...@@ -1257,6 +1261,7 @@ static int suspend(int vetoable)
if (err != APM_SUCCESS) if (err != APM_SUCCESS)
apm_error("suspend", err); apm_error("suspend", err);
err = (err == APM_SUCCESS) ? 0 : -EIO; err = (err == APM_SUCCESS) ? 0 : -EIO;
device_resume(RESUME_POWER_ON);
pm_send_all(PM_RESUME, (void *)0); pm_send_all(PM_RESUME, (void *)0);
queue_event(APM_NORMAL_RESUME, NULL); queue_event(APM_NORMAL_RESUME, NULL);
out: out:
...@@ -1370,6 +1375,7 @@ static void check_events(void) ...@@ -1370,6 +1375,7 @@ static void check_events(void)
write_seqlock_irq(&xtime_lock); write_seqlock_irq(&xtime_lock);
set_time(); set_time();
write_sequnlock_irq(&xtime_lock); write_sequnlock_irq(&xtime_lock);
device_resume(RESUME_POWER_ON);
pm_send_all(PM_RESUME, (void *)0); pm_send_all(PM_RESUME, (void *)0);
queue_event(event, NULL); queue_event(event, NULL);
} }
......
...@@ -163,10 +163,6 @@ EXPORT_SYMBOL(smp_call_function); ...@@ -163,10 +163,6 @@ EXPORT_SYMBOL(smp_call_function);
EXPORT_SYMBOL(flush_tlb_page); EXPORT_SYMBOL(flush_tlb_page);
#endif #endif
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PM)
EXPORT_SYMBOL_GPL(set_nmi_pm_callback);
EXPORT_SYMBOL_GPL(unset_nmi_pm_callback);
#endif
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
#endif #endif
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
* Mikael Pettersson : AMD K7 support for local APIC NMI watchdog. * Mikael Pettersson : AMD K7 support for local APIC NMI watchdog.
* Mikael Pettersson : Power Management for local APIC NMI watchdog. * Mikael Pettersson : Power Management for local APIC NMI watchdog.
* Mikael Pettersson : Pentium 4 support for local APIC NMI watchdog. * Mikael Pettersson : Pentium 4 support for local APIC NMI watchdog.
* Pavel Machek and
* Mikael Pettersson : PM converted to driver model. Disable/enable API.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -20,6 +22,7 @@ ...@@ -20,6 +22,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mc146818rtc.h> #include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/module.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/mtrr.h> #include <asm/mtrr.h>
...@@ -134,14 +137,18 @@ static int __init setup_nmi_watchdog(char *str) ...@@ -134,14 +137,18 @@ static int __init setup_nmi_watchdog(char *str)
__setup("nmi_watchdog=", setup_nmi_watchdog); __setup("nmi_watchdog=", setup_nmi_watchdog);
#ifdef CONFIG_PM /* nmi_active:
* +1: the lapic NMI watchdog is active, but can be disabled
#include <linux/pm.h> * 0: the lapic NMI watchdog has not been set up, and cannot
* be enabled
struct pm_dev *nmi_pmdev; * -1: the lapic NMI watchdog is disabled, but can be enabled
*/
static int nmi_active;
static void disable_apic_nmi_watchdog(void) void disable_lapic_nmi_watchdog(void)
{ {
if (nmi_active <= 0)
return;
switch (boot_cpu_data.x86_vendor) { switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_AMD: case X86_VENDOR_AMD:
wrmsr(MSR_K7_EVNTSEL0, 0, 0); wrmsr(MSR_K7_EVNTSEL0, 0, 0);
...@@ -158,46 +165,65 @@ static void disable_apic_nmi_watchdog(void) ...@@ -158,46 +165,65 @@ static void disable_apic_nmi_watchdog(void)
} }
break; break;
} }
nmi_active = -1;
/* tell do_nmi() and others that we're not active any more */
nmi_watchdog = 0;
} }
static int nmi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) void enable_lapic_nmi_watchdog(void)
{ {
switch (rqst) { if (nmi_active < 0) {
case PM_SUSPEND: nmi_watchdog = NMI_LOCAL_APIC;
disable_apic_nmi_watchdog();
break;
case PM_RESUME:
setup_apic_nmi_watchdog(); setup_apic_nmi_watchdog();
break;
} }
return 0;
} }
struct pm_dev * set_nmi_pm_callback(pm_callback callback) #ifdef CONFIG_PM
#include <linux/device.h>
static int lapic_nmi_suspend(struct device *dev, u32 state, u32 level)
{ {
apic_pm_unregister(nmi_pmdev); if (level != SUSPEND_POWER_DOWN)
return apic_pm_register(PM_SYS_DEV, 0, callback); return 0;
disable_lapic_nmi_watchdog();
return 0;
} }
void unset_nmi_pm_callback(struct pm_dev * dev) static int lapic_nmi_resume(struct device *dev, u32 level)
{ {
apic_pm_unregister(dev); if (level != RESUME_POWER_ON)
nmi_pmdev = apic_pm_register(PM_SYS_DEV, 0, nmi_pm_callback); return 0;
enable_lapic_nmi_watchdog();
return 0;
} }
static void nmi_pm_init(void) static struct device_driver lapic_nmi_driver = {
.name = "lapic_nmi",
.bus = &system_bus_type,
.resume = lapic_nmi_resume,
.suspend = lapic_nmi_suspend,
};
static struct sys_device device_lapic_nmi = {
.name = "lapic_nmi",
.id = 0,
.dev = {
.name = "lapic_nmi",
.driver = &lapic_nmi_driver,
.parent = &device_lapic.dev,
},
};
static int __init init_lapic_nmi_devicefs(void)
{ {
if (!nmi_pmdev) if (nmi_active == 0)
nmi_pmdev = apic_pm_register(PM_SYS_DEV, 0, nmi_pm_callback); return 0;
driver_register(&lapic_nmi_driver);
return sys_device_register(&device_lapic_nmi);
} }
/* must come after the local APIC's device_initcall() */
#define __pminit /*empty*/ late_initcall(init_lapic_nmi_devicefs);
#else /* CONFIG_PM */
static inline void nmi_pm_init(void) { }
#define __pminit __init
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
...@@ -206,7 +232,7 @@ static inline void nmi_pm_init(void) { } ...@@ -206,7 +232,7 @@ static inline void nmi_pm_init(void) { }
* Original code written by Keith Owens. * Original code written by Keith Owens.
*/ */
static void __pminit clear_msr_range(unsigned int base, unsigned int n) static void clear_msr_range(unsigned int base, unsigned int n)
{ {
unsigned int i; unsigned int i;
...@@ -214,7 +240,7 @@ static void __pminit clear_msr_range(unsigned int base, unsigned int n) ...@@ -214,7 +240,7 @@ static void __pminit clear_msr_range(unsigned int base, unsigned int n)
wrmsr(base+i, 0, 0); wrmsr(base+i, 0, 0);
} }
static void __pminit setup_k7_watchdog(void) static void setup_k7_watchdog(void)
{ {
unsigned int evntsel; unsigned int evntsel;
...@@ -236,7 +262,7 @@ static void __pminit setup_k7_watchdog(void) ...@@ -236,7 +262,7 @@ static void __pminit setup_k7_watchdog(void)
wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
} }
static void __pminit setup_p6_watchdog(void) static void setup_p6_watchdog(void)
{ {
unsigned int evntsel; unsigned int evntsel;
...@@ -258,7 +284,7 @@ static void __pminit setup_p6_watchdog(void) ...@@ -258,7 +284,7 @@ static void __pminit setup_p6_watchdog(void)
wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
} }
static int __pminit setup_p4_watchdog(void) static int setup_p4_watchdog(void)
{ {
unsigned int misc_enable, dummy; unsigned int misc_enable, dummy;
...@@ -288,7 +314,7 @@ static int __pminit setup_p4_watchdog(void) ...@@ -288,7 +314,7 @@ static int __pminit setup_p4_watchdog(void)
return 1; return 1;
} }
void __pminit setup_apic_nmi_watchdog (void) void setup_apic_nmi_watchdog (void)
{ {
switch (boot_cpu_data.x86_vendor) { switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_AMD: case X86_VENDOR_AMD:
...@@ -312,7 +338,7 @@ void __pminit setup_apic_nmi_watchdog (void) ...@@ -312,7 +338,7 @@ void __pminit setup_apic_nmi_watchdog (void)
default: default:
return; return;
} }
nmi_pm_init(); nmi_active = 1;
} }
static spinlock_t nmi_print_lock = SPIN_LOCK_UNLOCKED; static spinlock_t nmi_print_lock = SPIN_LOCK_UNLOCKED;
...@@ -400,3 +426,7 @@ void nmi_watchdog_tick (struct pt_regs * regs) ...@@ -400,3 +426,7 @@ void nmi_watchdog_tick (struct pt_regs * regs)
wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1); wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
} }
} }
EXPORT_SYMBOL(nmi_watchdog);
EXPORT_SYMBOL(disable_lapic_nmi_watchdog);
EXPORT_SYMBOL(enable_lapic_nmi_watchdog);
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/oprofile.h> #include <linux/oprofile.h>
#include <linux/device.h>
#include <asm/nmi.h> #include <asm/nmi.h>
#include <asm/msr.h> #include <asm/msr.h>
#include <asm/apic.h> #include <asm/apic.h>
...@@ -25,27 +26,59 @@ static unsigned long saved_lvtpc[NR_CPUS]; ...@@ -25,27 +26,59 @@ static unsigned long saved_lvtpc[NR_CPUS];
static int nmi_start(void); static int nmi_start(void);
static void nmi_stop(void); static void nmi_stop(void);
static struct pm_dev * oprofile_pmdev; /* 0 == registered but off, 1 == registered and on */
static int nmi_enabled = 0;
/* We're at risk of causing big trouble unless we
* make sure to not cause any NMI interrupts when #ifdef CONFIG_PM
* suspended.
*/ static int nmi_suspend(struct device *dev, u32 state, u32 level)
static int oprofile_pm_callback(struct pm_dev * dev,
pm_request_t rqst, void * data)
{ {
switch (rqst) { if (level != SUSPEND_POWER_DOWN)
case PM_SUSPEND: return 0;
nmi_stop(); if (nmi_enabled == 1)
break; nmi_stop();
case PM_RESUME:
nmi_start();
break;
}
return 0; return 0;
} }
static int nmi_resume(struct device *dev, u32 level)
{
if (level != RESUME_POWER_ON)
return 0;
if (nmi_enabled == 1)
nmi_start();
return 0;
}
static struct device_driver nmi_driver = {
.name = "oprofile",
.bus = &system_bus_type,
.resume = nmi_resume,
.suspend = nmi_suspend,
};
static struct device device_nmi = {
.name = "oprofile",
.bus_id = "oprofile",
.driver = &nmi_driver,
.parent = &device_lapic.dev,
};
static int __init init_nmi_driverfs(void)
{
driver_register(&nmi_driver);
return device_register(&device_nmi);
}
late_initcall(init_nmi_driverfs);
#endif /* CONFIG_PM */
static int nmi_callback(struct pt_regs * regs, int cpu) static int nmi_callback(struct pt_regs * regs, int cpu)
{ {
return model->check_ctrs(cpu, &cpu_msrs[cpu], regs); return model->check_ctrs(cpu, &cpu_msrs[cpu], regs);
...@@ -86,7 +119,7 @@ static void nmi_cpu_setup(void * dummy) ...@@ -86,7 +119,7 @@ static void nmi_cpu_setup(void * dummy)
saved_lvtpc[cpu] = apic_read(APIC_LVTPC); saved_lvtpc[cpu] = apic_read(APIC_LVTPC);
apic_write(APIC_LVTPC, APIC_DM_NMI); apic_write(APIC_LVTPC, APIC_DM_NMI);
} }
static int nmi_setup(void) static int nmi_setup(void)
{ {
...@@ -95,9 +128,10 @@ static int nmi_setup(void) ...@@ -95,9 +128,10 @@ static int nmi_setup(void)
* without actually triggering any NMIs as this will * without actually triggering any NMIs as this will
* break the core code horrifically. * break the core code horrifically.
*/ */
disable_lapic_nmi_watchdog();
on_each_cpu(nmi_cpu_setup, NULL, 0, 1); on_each_cpu(nmi_cpu_setup, NULL, 0, 1);
set_nmi_callback(nmi_callback); set_nmi_callback(nmi_callback);
oprofile_pmdev = set_nmi_pm_callback(oprofile_pm_callback); nmi_enabled = 1;
return 0; return 0;
} }
...@@ -145,9 +179,10 @@ static void nmi_cpu_shutdown(void * dummy) ...@@ -145,9 +179,10 @@ static void nmi_cpu_shutdown(void * dummy)
static void nmi_shutdown(void) static void nmi_shutdown(void)
{ {
unset_nmi_pm_callback(oprofile_pmdev); nmi_enabled = 0;
unset_nmi_callback(); unset_nmi_callback();
on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1); on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
enable_lapic_nmi_watchdog();
} }
......
...@@ -79,13 +79,16 @@ extern void smp_local_timer_interrupt (struct pt_regs * regs); ...@@ -79,13 +79,16 @@ extern void smp_local_timer_interrupt (struct pt_regs * regs);
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 void setup_apic_nmi_watchdog (void); extern void setup_apic_nmi_watchdog (void);
extern void disable_lapic_nmi_watchdog(void);
extern void enable_lapic_nmi_watchdog(void);
extern inline void nmi_watchdog_tick (struct pt_regs * regs); extern inline void nmi_watchdog_tick (struct pt_regs * regs);
extern int APIC_init_uniprocessor (void); extern int APIC_init_uniprocessor (void);
extern void disable_APIC_timer(void); extern void disable_APIC_timer(void);
extern void enable_APIC_timer(void); extern void enable_APIC_timer(void);
extern struct pm_dev *apic_pm_register(pm_dev_t, unsigned long, pm_callback); #ifdef CONFIG_PM
extern void apic_pm_unregister(struct pm_dev*); extern struct sys_device device_lapic;
#endif
extern int check_nmi_watchdog (void); extern int check_nmi_watchdog (void);
extern void enable_NMI_through_LVT0 (void * dummy); extern void enable_NMI_through_LVT0 (void * dummy);
......
...@@ -25,25 +25,4 @@ void set_nmi_callback(nmi_callback_t callback); ...@@ -25,25 +25,4 @@ void set_nmi_callback(nmi_callback_t callback);
*/ */
void unset_nmi_callback(void); void unset_nmi_callback(void);
#ifdef CONFIG_PM
/** Replace the PM callback routine for NMI. */
struct pm_dev * set_nmi_pm_callback(pm_callback callback);
/** Unset the PM callback routine back to the default. */
void unset_nmi_pm_callback(struct pm_dev * dev);
#else
static inline struct pm_dev * set_nmi_pm_callback(pm_callback callback)
{
return 0;
}
static inline void unset_nmi_pm_callback(struct pm_dev * dev)
{
}
#endif /* CONFIG_PM */
#endif /* ASM_NMI_H */ #endif /* ASM_NMI_H */
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