Skip to content

Commit

Permalink
Merge branch 'syscore' of git://git.kernel.org/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/rafael/suspend-2.6

* 'syscore' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6:
  Introduce ARCH_NO_SYSDEV_OPS config option (v2)
  cpufreq: Use syscore_ops for boot CPU suspend/resume (v2)
  KVM: Use syscore_ops instead of sysdev class and sysdev
  PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev
  timekeeping: Use syscore_ops instead of sysdev class and sysdev
  x86: Use syscore_ops instead of sysdev classes and sysdevs
  • Loading branch information
torvalds committed Mar 26, 2011
2 parents dc50edd + d47d81c commit 16c29da
Show file tree
Hide file tree
Showing 20 changed files with 206 additions and 351 deletions.
1 change: 1 addition & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ config X86
select GENERIC_IRQ_SHOW
select IRQ_FORCED_THREADING
select USE_GENERIC_SMP_HELPERS if SMP
select ARCH_NO_SYSDEV_OPS

config INSTRUCTION_DECODER
def_bool (KPROBES || PERF_EVENTS)
Expand Down
26 changes: 6 additions & 20 deletions arch/x86/kernel/amd_iommu_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <linux/acpi.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/sysdev.h>
#include <linux/syscore_ops.h>
#include <linux/interrupt.h>
#include <linux/msi.h>
#include <asm/pci-direct.h>
Expand Down Expand Up @@ -1260,7 +1260,7 @@ static void disable_iommus(void)
* disable suspend until real resume implemented
*/

static int amd_iommu_resume(struct sys_device *dev)
static void amd_iommu_resume(void)
{
struct amd_iommu *iommu;

Expand All @@ -1276,29 +1276,21 @@ static int amd_iommu_resume(struct sys_device *dev)
*/
amd_iommu_flush_all_devices();
amd_iommu_flush_all_domains();

return 0;
}

static int amd_iommu_suspend(struct sys_device *dev, pm_message_t state)
static int amd_iommu_suspend(void)
{
/* disable IOMMUs to go out of the way for BIOS */
disable_iommus();

return 0;
}

static struct sysdev_class amd_iommu_sysdev_class = {
.name = "amd_iommu",
static struct syscore_ops amd_iommu_syscore_ops = {
.suspend = amd_iommu_suspend,
.resume = amd_iommu_resume,
};

static struct sys_device device_amd_iommu = {
.id = 0,
.cls = &amd_iommu_sysdev_class,
};

/*
* This is the core init function for AMD IOMMU hardware in the system.
* This function is called from the generic x86 DMA layer initialization
Expand Down Expand Up @@ -1415,14 +1407,6 @@ static int __init amd_iommu_init(void)
goto free;
}

ret = sysdev_class_register(&amd_iommu_sysdev_class);
if (ret)
goto free;

ret = sysdev_register(&device_amd_iommu);
if (ret)
goto free;

ret = amd_iommu_init_devices();
if (ret)
goto free;
Expand All @@ -1441,6 +1425,8 @@ static int __init amd_iommu_init(void)

amd_iommu_init_notifier();

register_syscore_ops(&amd_iommu_syscore_ops);

if (iommu_pass_through)
goto out;

Expand Down
33 changes: 9 additions & 24 deletions arch/x86/kernel/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <linux/ftrace.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/sysdev.h>
#include <linux/syscore_ops.h>
#include <linux/delay.h>
#include <linux/timex.h>
#include <linux/dmar.h>
Expand Down Expand Up @@ -2046,7 +2046,7 @@ static struct {
unsigned int apic_thmr;
} apic_pm_state;

static int lapic_suspend(struct sys_device *dev, pm_message_t state)
static int lapic_suspend(void)
{
unsigned long flags;
int maxlvt;
Expand Down Expand Up @@ -2084,23 +2084,21 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
return 0;
}

static int lapic_resume(struct sys_device *dev)
static void lapic_resume(void)
{
unsigned int l, h;
unsigned long flags;
int maxlvt;
int ret = 0;
int maxlvt, ret;
struct IO_APIC_route_entry **ioapic_entries = NULL;

if (!apic_pm_state.active)
return 0;
return;

local_irq_save(flags);
if (intr_remapping_enabled) {
ioapic_entries = alloc_ioapic_entries();
if (!ioapic_entries) {
WARN(1, "Alloc ioapic_entries in lapic resume failed.");
ret = -ENOMEM;
goto restore;
}

Expand Down Expand Up @@ -2162,43 +2160,30 @@ static int lapic_resume(struct sys_device *dev)
}
restore:
local_irq_restore(flags);

return ret;
}

/*
* This device has no shutdown method - fully functioning local APICs
* are needed on every CPU up until machine_halt/restart/poweroff.
*/

static struct sysdev_class lapic_sysclass = {
.name = "lapic",
static struct syscore_ops lapic_syscore_ops = {
.resume = lapic_resume,
.suspend = lapic_suspend,
};

static struct sys_device device_lapic = {
.id = 0,
.cls = &lapic_sysclass,
};

static void __cpuinit apic_pm_activate(void)
{
apic_pm_state.active = 1;
}

static int __init init_lapic_sysfs(void)
{
int error;

if (!cpu_has_apic)
return 0;
/* XXX: remove suspend/resume procs if !apic_pm_state.active? */
if (cpu_has_apic)
register_syscore_ops(&lapic_syscore_ops);

error = sysdev_class_register(&lapic_sysclass);
if (!error)
error = sysdev_register(&device_lapic);
return error;
return 0;
}

/* local apic needs to resume before other devices access its registers. */
Expand Down
97 changes: 46 additions & 51 deletions arch/x86/kernel/apic/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include <linux/compiler.h>
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/sysdev.h>
#include <linux/syscore_ops.h>
#include <linux/msi.h>
#include <linux/htirq.h>
#include <linux/freezer.h>
Expand Down Expand Up @@ -2918,89 +2918,84 @@ static int __init io_apic_bug_finalize(void)

late_initcall(io_apic_bug_finalize);

struct sysfs_ioapic_data {
struct sys_device dev;
struct IO_APIC_route_entry entry[0];
};
static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS];
static struct IO_APIC_route_entry *ioapic_saved_data[MAX_IO_APICS];

static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
static void suspend_ioapic(int ioapic_id)
{
struct IO_APIC_route_entry *entry;
struct sysfs_ioapic_data *data;
struct IO_APIC_route_entry *saved_data = ioapic_saved_data[ioapic_id];
int i;

data = container_of(dev, struct sysfs_ioapic_data, dev);
entry = data->entry;
for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ )
*entry = ioapic_read_entry(dev->id, i);
if (!saved_data)
return;

for (i = 0; i < nr_ioapic_registers[ioapic_id]; i++)
saved_data[i] = ioapic_read_entry(ioapic_id, i);
}

static int ioapic_suspend(void)
{
int ioapic_id;

for (ioapic_id = 0; ioapic_id < nr_ioapics; ioapic_id++)
suspend_ioapic(ioapic_id);

return 0;
}

static int ioapic_resume(struct sys_device *dev)
static void resume_ioapic(int ioapic_id)
{
struct IO_APIC_route_entry *entry;
struct sysfs_ioapic_data *data;
struct IO_APIC_route_entry *saved_data = ioapic_saved_data[ioapic_id];
unsigned long flags;
union IO_APIC_reg_00 reg_00;
int i;

data = container_of(dev, struct sysfs_ioapic_data, dev);
entry = data->entry;
if (!saved_data)
return;

raw_spin_lock_irqsave(&ioapic_lock, flags);
reg_00.raw = io_apic_read(dev->id, 0);
if (reg_00.bits.ID != mp_ioapics[dev->id].apicid) {
reg_00.bits.ID = mp_ioapics[dev->id].apicid;
io_apic_write(dev->id, 0, reg_00.raw);
reg_00.raw = io_apic_read(ioapic_id, 0);
if (reg_00.bits.ID != mp_ioapics[ioapic_id].apicid) {
reg_00.bits.ID = mp_ioapics[ioapic_id].apicid;
io_apic_write(ioapic_id, 0, reg_00.raw);
}
raw_spin_unlock_irqrestore(&ioapic_lock, flags);
for (i = 0; i < nr_ioapic_registers[dev->id]; i++)
ioapic_write_entry(dev->id, i, entry[i]);
for (i = 0; i < nr_ioapic_registers[ioapic_id]; i++)
ioapic_write_entry(ioapic_id, i, saved_data[i]);
}

return 0;
static void ioapic_resume(void)
{
int ioapic_id;

for (ioapic_id = nr_ioapics - 1; ioapic_id >= 0; ioapic_id--)
resume_ioapic(ioapic_id);
}

static struct sysdev_class ioapic_sysdev_class = {
.name = "ioapic",
static struct syscore_ops ioapic_syscore_ops = {
.suspend = ioapic_suspend,
.resume = ioapic_resume,
};

static int __init ioapic_init_sysfs(void)
static int __init ioapic_init_ops(void)
{
struct sys_device * dev;
int i, size, error;
int i;

error = sysdev_class_register(&ioapic_sysdev_class);
if (error)
return error;
for (i = 0; i < nr_ioapics; i++) {
unsigned int size;

for (i = 0; i < nr_ioapics; i++ ) {
size = sizeof(struct sys_device) + nr_ioapic_registers[i]
size = nr_ioapic_registers[i]
* sizeof(struct IO_APIC_route_entry);
mp_ioapic_data[i] = kzalloc(size, GFP_KERNEL);
if (!mp_ioapic_data[i]) {
printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
continue;
}
dev = &mp_ioapic_data[i]->dev;
dev->id = i;
dev->cls = &ioapic_sysdev_class;
error = sysdev_register(dev);
if (error) {
kfree(mp_ioapic_data[i]);
mp_ioapic_data[i] = NULL;
printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
continue;
}
ioapic_saved_data[i] = kzalloc(size, GFP_KERNEL);
if (!ioapic_saved_data[i])
pr_err("IOAPIC %d: suspend/resume impossible!\n", i);
}

register_syscore_ops(&ioapic_syscore_ops);

return 0;
}

device_initcall(ioapic_init_sysfs);
device_initcall(ioapic_init_ops);

/*
* Dynamic irq allocate and deallocation
Expand Down
21 changes: 12 additions & 9 deletions arch/x86/kernel/cpu/mcheck/mce.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/percpu.h>
#include <linux/string.h>
#include <linux/sysdev.h>
#include <linux/syscore_ops.h>
#include <linux/delay.h>
#include <linux/ctype.h>
#include <linux/sched.h>
Expand Down Expand Up @@ -1749,29 +1750,33 @@ static int mce_disable_error_reporting(void)
return 0;
}

static int mce_suspend(struct sys_device *dev, pm_message_t state)
static int mce_suspend(void)
{
return mce_disable_error_reporting();
}

static int mce_shutdown(struct sys_device *dev)
static void mce_shutdown(void)
{
return mce_disable_error_reporting();
mce_disable_error_reporting();
}

/*
* On resume clear all MCE state. Don't want to see leftovers from the BIOS.
* Only one CPU is active at this time, the others get re-added later using
* CPU hotplug:
*/
static int mce_resume(struct sys_device *dev)
static void mce_resume(void)
{
__mcheck_cpu_init_generic();
__mcheck_cpu_init_vendor(__this_cpu_ptr(&cpu_info));

return 0;
}

static struct syscore_ops mce_syscore_ops = {
.suspend = mce_suspend,
.shutdown = mce_shutdown,
.resume = mce_resume,
};

static void mce_cpu_restart(void *data)
{
del_timer_sync(&__get_cpu_var(mce_timer));
Expand Down Expand Up @@ -1808,9 +1813,6 @@ static void mce_enable_ce(void *all)
}

static struct sysdev_class mce_sysclass = {
.suspend = mce_suspend,
.shutdown = mce_shutdown,
.resume = mce_resume,
.name = "machinecheck",
};

Expand Down Expand Up @@ -2139,6 +2141,7 @@ static __init int mcheck_init_device(void)
return err;
}

register_syscore_ops(&mce_syscore_ops);
register_hotcpu_notifier(&mce_cpu_notifier);
misc_register(&mce_log_device);

Expand Down
Loading

0 comments on commit 16c29da

Please sign in to comment.