aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-03-23 17:15:54 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2011-03-23 17:15:54 -0400
commitf3c6ea1b06c71b43f751b36bd99345369fe911af (patch)
treea7ed142d4a183cc97fa7fc2af1cc5dec61827aa2
parent4bbba111d94781d34081c37856bbc5eb33f6c72a (diff)
x86: Use syscore_ops instead of sysdev classes and sysdevs
Some subsystems in the x86 tree need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled and they define sysdev classes and sysdevs or sysdev drivers for this purpose. This leads to unnecessarily complicated code and excessive memory usage, so switch them to using struct syscore_ops objects for this purpose instead. Generally, there are three categories of subsystems that use sysdevs for implementing PM operations: (1) subsystems whose suspend/resume callbacks ignore their arguments entirely (the majority), (2) subsystems whose suspend/resume callbacks use their struct sys_device argument, but don't really need to do that, because they can be implemented differently in an arguably simpler way (io_apic.c), and (3) subsystems whose suspend/resume callbacks use their struct sys_device argument, but the value of that argument is always the same and could be ignored (microcode_core.c). In all of these cases the subsystems in question may be readily converted to using struct syscore_ops objects for power management and shutdown. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/kernel/amd_iommu_init.c26
-rw-r--r--arch/x86/kernel/apic/apic.c33
-rw-r--r--arch/x86/kernel/apic/io_apic.c97
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c21
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c10
-rw-r--r--arch/x86/kernel/i8237.c30
-rw-r--r--arch/x86/kernel/i8259.c33
-rw-r--r--arch/x86/kernel/microcode_core.c34
-rw-r--r--arch/x86/kernel/pci-gart_64.c32
-rw-r--r--arch/x86/oprofile/nmi_int.c44
10 files changed, 128 insertions, 232 deletions
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 6e11c8134158..246d727b65b7 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -21,7 +21,7 @@
21#include <linux/acpi.h> 21#include <linux/acpi.h>
22#include <linux/list.h> 22#include <linux/list.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/sysdev.h> 24#include <linux/syscore_ops.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/msi.h> 26#include <linux/msi.h>
27#include <asm/pci-direct.h> 27#include <asm/pci-direct.h>
@@ -1260,7 +1260,7 @@ static void disable_iommus(void)
1260 * disable suspend until real resume implemented 1260 * disable suspend until real resume implemented
1261 */ 1261 */
1262 1262
1263static int amd_iommu_resume(struct sys_device *dev) 1263static void amd_iommu_resume(void)
1264{ 1264{
1265 struct amd_iommu *iommu; 1265 struct amd_iommu *iommu;
1266 1266
@@ -1276,11 +1276,9 @@ static int amd_iommu_resume(struct sys_device *dev)
1276 */ 1276 */
1277 amd_iommu_flush_all_devices(); 1277 amd_iommu_flush_all_devices();
1278 amd_iommu_flush_all_domains(); 1278 amd_iommu_flush_all_domains();
1279
1280 return 0;
1281} 1279}
1282 1280
1283static int amd_iommu_suspend(struct sys_device *dev, pm_message_t state) 1281static int amd_iommu_suspend(void)
1284{ 1282{
1285 /* disable IOMMUs to go out of the way for BIOS */ 1283 /* disable IOMMUs to go out of the way for BIOS */
1286 disable_iommus(); 1284 disable_iommus();
@@ -1288,17 +1286,11 @@ static int amd_iommu_suspend(struct sys_device *dev, pm_message_t state)
1288 return 0; 1286 return 0;
1289} 1287}
1290 1288
1291static struct sysdev_class amd_iommu_sysdev_class = { 1289static struct syscore_ops amd_iommu_syscore_ops = {
1292 .name = "amd_iommu",
1293 .suspend = amd_iommu_suspend, 1290 .suspend = amd_iommu_suspend,
1294 .resume = amd_iommu_resume, 1291 .resume = amd_iommu_resume,
1295}; 1292};
1296 1293
1297static struct sys_device device_amd_iommu = {
1298 .id = 0,
1299 .cls = &amd_iommu_sysdev_class,
1300};
1301
1302/* 1294/*
1303 * This is the core init function for AMD IOMMU hardware in the system. 1295 * This is the core init function for AMD IOMMU hardware in the system.
1304 * This function is called from the generic x86 DMA layer initialization 1296 * This function is called from the generic x86 DMA layer initialization
@@ -1415,14 +1407,6 @@ static int __init amd_iommu_init(void)
1415 goto free; 1407 goto free;
1416 } 1408 }
1417 1409
1418 ret = sysdev_class_register(&amd_iommu_sysdev_class);
1419 if (ret)
1420 goto free;
1421
1422 ret = sysdev_register(&device_amd_iommu);
1423 if (ret)
1424 goto free;
1425
1426 ret = amd_iommu_init_devices(); 1410 ret = amd_iommu_init_devices();
1427 if (ret) 1411 if (ret)
1428 goto free; 1412 goto free;
@@ -1441,6 +1425,8 @@ static int __init amd_iommu_init(void)
1441 1425
1442 amd_iommu_init_notifier(); 1426 amd_iommu_init_notifier();
1443 1427
1428 register_syscore_ops(&amd_iommu_syscore_ops);
1429
1444 if (iommu_pass_through) 1430 if (iommu_pass_through)
1445 goto out; 1431 goto out;
1446 1432
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 966673f44141..fabf01eff771 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -24,7 +24,7 @@
24#include <linux/ftrace.h> 24#include <linux/ftrace.h>
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/sysdev.h> 27#include <linux/syscore_ops.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/timex.h> 29#include <linux/timex.h>
30#include <linux/dmar.h> 30#include <linux/dmar.h>
@@ -2046,7 +2046,7 @@ static struct {
2046 unsigned int apic_thmr; 2046 unsigned int apic_thmr;
2047} apic_pm_state; 2047} apic_pm_state;
2048 2048
2049static int lapic_suspend(struct sys_device *dev, pm_message_t state) 2049static int lapic_suspend(void)
2050{ 2050{
2051 unsigned long flags; 2051 unsigned long flags;
2052 int maxlvt; 2052 int maxlvt;
@@ -2084,23 +2084,21 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
2084 return 0; 2084 return 0;
2085} 2085}
2086 2086
2087static int lapic_resume(struct sys_device *dev) 2087static void lapic_resume(void)
2088{ 2088{
2089 unsigned int l, h; 2089 unsigned int l, h;
2090 unsigned long flags; 2090 unsigned long flags;
2091 int maxlvt; 2091 int maxlvt, ret;
2092 int ret = 0;
2093 struct IO_APIC_route_entry **ioapic_entries = NULL; 2092 struct IO_APIC_route_entry **ioapic_entries = NULL;
2094 2093
2095 if (!apic_pm_state.active) 2094 if (!apic_pm_state.active)
2096 return 0; 2095 return;
2097 2096
2098 local_irq_save(flags); 2097 local_irq_save(flags);
2099 if (intr_remapping_enabled) { 2098 if (intr_remapping_enabled) {
2100 ioapic_entries = alloc_ioapic_entries(); 2099 ioapic_entries = alloc_ioapic_entries();
2101 if (!ioapic_entries) { 2100 if (!ioapic_entries) {
2102 WARN(1, "Alloc ioapic_entries in lapic resume failed."); 2101 WARN(1, "Alloc ioapic_entries in lapic resume failed.");
2103 ret = -ENOMEM;
2104 goto restore; 2102 goto restore;
2105 } 2103 }
2106 2104
@@ -2162,8 +2160,6 @@ static int lapic_resume(struct sys_device *dev)
2162 } 2160 }
2163restore: 2161restore:
2164 local_irq_restore(flags); 2162 local_irq_restore(flags);
2165
2166 return ret;
2167} 2163}
2168 2164
2169/* 2165/*
@@ -2171,17 +2167,11 @@ restore:
2171 * are needed on every CPU up until machine_halt/restart/poweroff. 2167 * are needed on every CPU up until machine_halt/restart/poweroff.
2172 */ 2168 */
2173 2169
2174static struct sysdev_class lapic_sysclass = { 2170static struct syscore_ops lapic_syscore_ops = {
2175 .name = "lapic",
2176 .resume = lapic_resume, 2171 .resume = lapic_resume,
2177 .suspend = lapic_suspend, 2172 .suspend = lapic_suspend,
2178}; 2173};
2179 2174
2180static struct sys_device device_lapic = {
2181 .id = 0,
2182 .cls = &lapic_sysclass,
2183};
2184
2185static void __cpuinit apic_pm_activate(void) 2175static void __cpuinit apic_pm_activate(void)
2186{ 2176{
2187 apic_pm_state.active = 1; 2177 apic_pm_state.active = 1;
@@ -2189,16 +2179,11 @@ static void __cpuinit apic_pm_activate(void)
2189 2179
2190static int __init init_lapic_sysfs(void) 2180static int __init init_lapic_sysfs(void)
2191{ 2181{
2192 int error;
2193
2194 if (!cpu_has_apic)
2195 return 0;
2196 /* XXX: remove suspend/resume procs if !apic_pm_state.active? */ 2182 /* XXX: remove suspend/resume procs if !apic_pm_state.active? */
2183 if (cpu_has_apic)
2184 register_syscore_ops(&lapic_syscore_ops);
2197 2185
2198 error = sysdev_class_register(&lapic_sysclass); 2186 return 0;
2199 if (!error)
2200 error = sysdev_register(&device_lapic);
2201 return error;
2202} 2187}
2203 2188
2204/* local apic needs to resume before other devices access its registers. */ 2189/* local apic needs to resume before other devices access its registers. */
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 180ca240e03c..68df09bba92e 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -30,7 +30,7 @@
30#include <linux/compiler.h> 30#include <linux/compiler.h>
31#include <linux/acpi.h> 31#include <linux/acpi.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/sysdev.h> 33#include <linux/syscore_ops.h>
34#include <linux/msi.h> 34#include <linux/msi.h>
35#include <linux/htirq.h> 35#include <linux/htirq.h>
36#include <linux/freezer.h> 36#include <linux/freezer.h>
@@ -2918,89 +2918,84 @@ static int __init io_apic_bug_finalize(void)
2918 2918
2919late_initcall(io_apic_bug_finalize); 2919late_initcall(io_apic_bug_finalize);
2920 2920
2921struct sysfs_ioapic_data { 2921static struct IO_APIC_route_entry *ioapic_saved_data[MAX_IO_APICS];
2922 struct sys_device dev;
2923 struct IO_APIC_route_entry entry[0];
2924};
2925static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS];
2926 2922
2927static int ioapic_suspend(struct sys_device *dev, pm_message_t state) 2923static void suspend_ioapic(int ioapic_id)
2928{ 2924{
2929 struct IO_APIC_route_entry *entry; 2925 struct IO_APIC_route_entry *saved_data = ioapic_saved_data[ioapic_id];
2930 struct sysfs_ioapic_data *data;
2931 int i; 2926 int i;
2932 2927
2933 data = container_of(dev, struct sysfs_ioapic_data, dev); 2928 if (!saved_data)
2934 entry = data->entry; 2929 return;
2935 for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) 2930
2936 *entry = ioapic_read_entry(dev->id, i); 2931 for (i = 0; i < nr_ioapic_registers[ioapic_id]; i++)
2932 saved_data[i] = ioapic_read_entry(ioapic_id, i);
2933}
2934
2935static int ioapic_suspend(void)
2936{
2937 int ioapic_id;
2938
2939 for (ioapic_id = 0; ioapic_id < nr_ioapics; ioapic_id++)
2940 suspend_ioapic(ioapic_id);
2937 2941
2938 return 0; 2942 return 0;
2939} 2943}
2940 2944
2941static int ioapic_resume(struct sys_device *dev) 2945static void resume_ioapic(int ioapic_id)
2942{ 2946{
2943 struct IO_APIC_route_entry *entry; 2947 struct IO_APIC_route_entry *saved_data = ioapic_saved_data[ioapic_id];
2944 struct sysfs_ioapic_data *data;
2945 unsigned long flags; 2948 unsigned long flags;
2946 union IO_APIC_reg_00 reg_00; 2949 union IO_APIC_reg_00 reg_00;
2947 int i; 2950 int i;
2948 2951
2949 data = container_of(dev, struct sysfs_ioapic_data, dev); 2952 if (!saved_data)
2950 entry = data->entry; 2953 return;
2951 2954
2952 raw_spin_lock_irqsave(&ioapic_lock, flags); 2955 raw_spin_lock_irqsave(&ioapic_lock, flags);
2953 reg_00.raw = io_apic_read(dev->id, 0); 2956 reg_00.raw = io_apic_read(ioapic_id, 0);
2954 if (reg_00.bits.ID != mp_ioapics[dev->id].apicid) { 2957 if (reg_00.bits.ID != mp_ioapics[ioapic_id].apicid) {
2955 reg_00.bits.ID = mp_ioapics[dev->id].apicid; 2958 reg_00.bits.ID = mp_ioapics[ioapic_id].apicid;
2956 io_apic_write(dev->id, 0, reg_00.raw); 2959 io_apic_write(ioapic_id, 0, reg_00.raw);
2957 } 2960 }
2958 raw_spin_unlock_irqrestore(&ioapic_lock, flags); 2961 raw_spin_unlock_irqrestore(&ioapic_lock, flags);
2959 for (i = 0; i < nr_ioapic_registers[dev->id]; i++) 2962 for (i = 0; i < nr_ioapic_registers[ioapic_id]; i++)
2960 ioapic_write_entry(dev->id, i, entry[i]); 2963 ioapic_write_entry(ioapic_id, i, saved_data[i]);
2964}
2961 2965
2962 return 0; 2966static void ioapic_resume(void)
2967{
2968 int ioapic_id;
2969
2970 for (ioapic_id = nr_ioapics - 1; ioapic_id >= 0; ioapic_id--)
2971 resume_ioapic(ioapic_id);
2963} 2972}
2964 2973
2965static struct sysdev_class ioapic_sysdev_class = { 2974static struct syscore_ops ioapic_syscore_ops = {
2966 .name = "ioapic",
2967 .suspend = ioapic_suspend, 2975 .suspend = ioapic_suspend,
2968 .resume = ioapic_resume, 2976 .resume = ioapic_resume,
2969}; 2977};
2970 2978
2971static int __init ioapic_init_sysfs(void) 2979static int __init ioapic_init_ops(void)
2972{ 2980{
2973 struct sys_device * dev; 2981 int i;
2974 int i, size, error;
2975 2982
2976 error = sysdev_class_register(&ioapic_sysdev_class); 2983 for (i = 0; i < nr_ioapics; i++) {
2977 if (error) 2984 unsigned int size;
2978 return error;
2979 2985
2980 for (i = 0; i < nr_ioapics; i++ ) { 2986 size = nr_ioapic_registers[i]
2981 size = sizeof(struct sys_device) + nr_ioapic_registers[i]
2982 * sizeof(struct IO_APIC_route_entry); 2987 * sizeof(struct IO_APIC_route_entry);
2983 mp_ioapic_data[i] = kzalloc(size, GFP_KERNEL); 2988 ioapic_saved_data[i] = kzalloc(size, GFP_KERNEL);
2984 if (!mp_ioapic_data[i]) { 2989 if (!ioapic_saved_data[i])
2985 printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); 2990 pr_err("IOAPIC %d: suspend/resume impossible!\n", i);
2986 continue;
2987 }
2988 dev = &mp_ioapic_data[i]->dev;
2989 dev->id = i;
2990 dev->cls = &ioapic_sysdev_class;
2991 error = sysdev_register(dev);
2992 if (error) {
2993 kfree(mp_ioapic_data[i]);
2994 mp_ioapic_data[i] = NULL;
2995 printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
2996 continue;
2997 }
2998 } 2991 }
2999 2992
2993 register_syscore_ops(&ioapic_syscore_ops);
2994
3000 return 0; 2995 return 0;
3001} 2996}
3002 2997
3003device_initcall(ioapic_init_sysfs); 2998device_initcall(ioapic_init_ops);
3004 2999
3005/* 3000/*
3006 * Dynamic irq allocate and deallocation 3001 * Dynamic irq allocate and deallocation
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index ab1122998dba..5a05ef63eb4a 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -21,6 +21,7 @@
21#include <linux/percpu.h> 21#include <linux/percpu.h>
22#include <linux/string.h> 22#include <linux/string.h>
23#include <linux/sysdev.h> 23#include <linux/sysdev.h>
24#include <linux/syscore_ops.h>
24#include <linux/delay.h> 25#include <linux/delay.h>
25#include <linux/ctype.h> 26#include <linux/ctype.h>
26#include <linux/sched.h> 27#include <linux/sched.h>
@@ -1749,14 +1750,14 @@ static int mce_disable_error_reporting(void)
1749 return 0; 1750 return 0;
1750} 1751}
1751 1752
1752static int mce_suspend(struct sys_device *dev, pm_message_t state) 1753static int mce_suspend(void)
1753{ 1754{
1754 return mce_disable_error_reporting(); 1755 return mce_disable_error_reporting();
1755} 1756}
1756 1757
1757static int mce_shutdown(struct sys_device *dev) 1758static void mce_shutdown(void)
1758{ 1759{
1759 return mce_disable_error_reporting(); 1760 mce_disable_error_reporting();
1760} 1761}
1761 1762
1762/* 1763/*
@@ -1764,14 +1765,18 @@ static int mce_shutdown(struct sys_device *dev)
1764 * Only one CPU is active at this time, the others get re-added later using 1765 * Only one CPU is active at this time, the others get re-added later using
1765 * CPU hotplug: 1766 * CPU hotplug:
1766 */ 1767 */
1767static int mce_resume(struct sys_device *dev) 1768static void mce_resume(void)
1768{ 1769{
1769 __mcheck_cpu_init_generic(); 1770 __mcheck_cpu_init_generic();
1770 __mcheck_cpu_init_vendor(__this_cpu_ptr(&cpu_info)); 1771 __mcheck_cpu_init_vendor(__this_cpu_ptr(&cpu_info));
1771
1772 return 0;
1773} 1772}
1774 1773
1774static struct syscore_ops mce_syscore_ops = {
1775 .suspend = mce_suspend,
1776 .shutdown = mce_shutdown,
1777 .resume = mce_resume,
1778};
1779
1775static void mce_cpu_restart(void *data) 1780static void mce_cpu_restart(void *data)
1776{ 1781{
1777 del_timer_sync(&__get_cpu_var(mce_timer)); 1782 del_timer_sync(&__get_cpu_var(mce_timer));
@@ -1808,9 +1813,6 @@ static void mce_enable_ce(void *all)
1808} 1813}
1809 1814
1810static struct sysdev_class mce_sysclass = { 1815static struct sysdev_class mce_sysclass = {
1811 .suspend = mce_suspend,
1812 .shutdown = mce_shutdown,
1813 .resume = mce_resume,
1814 .name = "machinecheck", 1816 .name = "machinecheck",
1815}; 1817};
1816 1818
@@ -2139,6 +2141,7 @@ static __init int mcheck_init_device(void)
2139 return err; 2141 return err;
2140 } 2142 }
2141 2143
2144 register_syscore_ops(&mce_syscore_ops);
2142 register_hotcpu_notifier(&mce_cpu_notifier); 2145 register_hotcpu_notifier(&mce_cpu_notifier);
2143 misc_register(&mce_log_device); 2146 misc_register(&mce_log_device);
2144 2147
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index bebabec5b448..307dfbbf4a8e 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -45,6 +45,7 @@
45#include <linux/cpu.h> 45#include <linux/cpu.h>
46#include <linux/pci.h> 46#include <linux/pci.h>
47#include <linux/smp.h> 47#include <linux/smp.h>
48#include <linux/syscore_ops.h>
48 49
49#include <asm/processor.h> 50#include <asm/processor.h>
50#include <asm/e820.h> 51#include <asm/e820.h>
@@ -630,7 +631,7 @@ struct mtrr_value {
630 631
631static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES]; 632static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES];
632 633
633static int mtrr_save(struct sys_device *sysdev, pm_message_t state) 634static int mtrr_save(void)
634{ 635{
635 int i; 636 int i;
636 637
@@ -642,7 +643,7 @@ static int mtrr_save(struct sys_device *sysdev, pm_message_t state)
642 return 0; 643 return 0;
643} 644}
644 645
645static int mtrr_restore(struct sys_device *sysdev) 646static void mtrr_restore(void)
646{ 647{
647 int i; 648 int i;
648 649
@@ -653,12 +654,11 @@ static int mtrr_restore(struct sys_device *sysdev)
653 mtrr_value[i].ltype); 654 mtrr_value[i].ltype);
654 } 655 }
655 } 656 }
656 return 0;
657} 657}
658 658
659 659
660 660
661static struct sysdev_driver mtrr_sysdev_driver = { 661static struct syscore_ops mtrr_syscore_ops = {
662 .suspend = mtrr_save, 662 .suspend = mtrr_save,
663 .resume = mtrr_restore, 663 .resume = mtrr_restore,
664}; 664};
@@ -839,7 +839,7 @@ static int __init mtrr_init_finialize(void)
839 * TBD: is there any system with such CPU which supports 839 * TBD: is there any system with such CPU which supports
840 * suspend/resume? If no, we should remove the code. 840 * suspend/resume? If no, we should remove the code.
841 */ 841 */
842 sysdev_driver_register(&cpu_sysdev_class, &mtrr_sysdev_driver); 842 register_syscore_ops(&mtrr_syscore_ops);
843 843
844 return 0; 844 return 0;
845} 845}
diff --git a/arch/x86/kernel/i8237.c b/arch/x86/kernel/i8237.c
index b42ca694dc68..8eeaa81de066 100644
--- a/arch/x86/kernel/i8237.c
+++ b/arch/x86/kernel/i8237.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/sysdev.h> 13#include <linux/syscore_ops.h>
14 14
15#include <asm/dma.h> 15#include <asm/dma.h>
16 16
@@ -21,7 +21,7 @@
21 * in asm/dma.h. 21 * in asm/dma.h.
22 */ 22 */
23 23
24static int i8237A_resume(struct sys_device *dev) 24static void i8237A_resume(void)
25{ 25{
26 unsigned long flags; 26 unsigned long flags;
27 int i; 27 int i;
@@ -41,31 +41,15 @@ static int i8237A_resume(struct sys_device *dev)
41 enable_dma(4); 41 enable_dma(4);
42 42
43 release_dma_lock(flags); 43 release_dma_lock(flags);
44
45 return 0;
46} 44}
47 45
48static int i8237A_suspend(struct sys_device *dev, pm_message_t state) 46static struct syscore_ops i8237_syscore_ops = {
49{
50 return 0;
51}
52
53static struct sysdev_class i8237_sysdev_class = {
54 .name = "i8237",
55 .suspend = i8237A_suspend,
56 .resume = i8237A_resume, 47 .resume = i8237A_resume,
57}; 48};
58 49
59static struct sys_device device_i8237A = { 50static int __init i8237A_init_ops(void)
60 .id = 0,
61 .cls = &i8237_sysdev_class,
62};
63
64static int __init i8237A_init_sysfs(void)
65{ 51{
66 int error = sysdev_class_register(&i8237_sysdev_class); 52 register_syscore_ops(&i8237_syscore_ops);
67 if (!error) 53 return 0;
68 error = sysdev_register(&device_i8237A);
69 return error;
70} 54}
71device_initcall(i8237A_init_sysfs); 55device_initcall(i8237A_init_ops);
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index d9ca749c123b..65b8f5c2eebf 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -8,7 +8,7 @@
8#include <linux/random.h> 8#include <linux/random.h>
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/kernel_stat.h> 10#include <linux/kernel_stat.h>
11#include <linux/sysdev.h> 11#include <linux/syscore_ops.h>
12#include <linux/bitops.h> 12#include <linux/bitops.h>
13#include <linux/acpi.h> 13#include <linux/acpi.h>
14#include <linux/io.h> 14#include <linux/io.h>
@@ -245,20 +245,19 @@ static void save_ELCR(char *trigger)
245 trigger[1] = inb(0x4d1) & 0xDE; 245 trigger[1] = inb(0x4d1) & 0xDE;
246} 246}
247 247
248static int i8259A_resume(struct sys_device *dev) 248static void i8259A_resume(void)
249{ 249{
250 init_8259A(i8259A_auto_eoi); 250 init_8259A(i8259A_auto_eoi);
251 restore_ELCR(irq_trigger); 251 restore_ELCR(irq_trigger);
252 return 0;
253} 252}
254 253
255static int i8259A_suspend(struct sys_device *dev, pm_message_t state) 254static int i8259A_suspend(void)
256{ 255{
257 save_ELCR(irq_trigger); 256 save_ELCR(irq_trigger);
258 return 0; 257 return 0;
259} 258}
260 259
261static int i8259A_shutdown(struct sys_device *dev) 260static void i8259A_shutdown(void)
262{ 261{
263 /* Put the i8259A into a quiescent state that 262 /* Put the i8259A into a quiescent state that
264 * the kernel initialization code can get it 263 * the kernel initialization code can get it
@@ -266,21 +265,14 @@ static int i8259A_shutdown(struct sys_device *dev)
266 */ 265 */
267 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ 266 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
268 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ 267 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */
269 return 0;
270} 268}
271 269
272static struct sysdev_class i8259_sysdev_class = { 270static struct syscore_ops i8259_syscore_ops = {
273 .name = "i8259",
274 .suspend = i8259A_suspend, 271 .suspend = i8259A_suspend,
275 .resume = i8259A_resume, 272 .resume = i8259A_resume,
276 .shutdown = i8259A_shutdown, 273 .shutdown = i8259A_shutdown,
277}; 274};
278 275
279static struct sys_device device_i8259A = {
280 .id = 0,
281 .cls = &i8259_sysdev_class,
282};
283
284static void mask_8259A(void) 276static void mask_8259A(void)
285{ 277{
286 unsigned long flags; 278 unsigned long flags;
@@ -399,17 +391,12 @@ struct legacy_pic default_legacy_pic = {
399 391
400struct legacy_pic *legacy_pic = &default_legacy_pic; 392struct legacy_pic *legacy_pic = &default_legacy_pic;
401 393
402static int __init i8259A_init_sysfs(void) 394static int __init i8259A_init_ops(void)
403{ 395{
404 int error; 396 if (legacy_pic == &default_legacy_pic)
405 397 register_syscore_ops(&i8259_syscore_ops);
406 if (legacy_pic != &default_legacy_pic)
407 return 0;
408 398
409 error = sysdev_class_register(&i8259_sysdev_class); 399 return 0;
410 if (!error)
411 error = sysdev_register(&device_i8259A);
412 return error;
413} 400}
414 401
415device_initcall(i8259A_init_sysfs); 402device_initcall(i8259A_init_ops);
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index 87af68e0e1e1..5ed0ab549eb8 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -82,6 +82,7 @@
82#include <linux/cpu.h> 82#include <linux/cpu.h>
83#include <linux/fs.h> 83#include <linux/fs.h>
84#include <linux/mm.h> 84#include <linux/mm.h>
85#include <linux/syscore_ops.h>
85 86
86#include <asm/microcode.h> 87#include <asm/microcode.h>
87#include <asm/processor.h> 88#include <asm/processor.h>
@@ -438,33 +439,25 @@ static int mc_sysdev_remove(struct sys_device *sys_dev)
438 return 0; 439 return 0;
439} 440}
440 441
441static int mc_sysdev_resume(struct sys_device *dev) 442static struct sysdev_driver mc_sysdev_driver = {
443 .add = mc_sysdev_add,
444 .remove = mc_sysdev_remove,
445};
446
447/**
448 * mc_bp_resume - Update boot CPU microcode during resume.
449 */
450static void mc_bp_resume(void)
442{ 451{
443 int cpu = dev->id; 452 int cpu = smp_processor_id();
444 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 453 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
445 454
446 if (!cpu_online(cpu))
447 return 0;
448
449 /*
450 * All non-bootup cpus are still disabled,
451 * so only CPU 0 will apply ucode here.
452 *
453 * Moreover, there can be no concurrent
454 * updates from any other places at this point.
455 */
456 WARN_ON(cpu != 0);
457
458 if (uci->valid && uci->mc) 455 if (uci->valid && uci->mc)
459 microcode_ops->apply_microcode(cpu); 456 microcode_ops->apply_microcode(cpu);
460
461 return 0;
462} 457}
463 458
464static struct sysdev_driver mc_sysdev_driver = { 459static struct syscore_ops mc_syscore_ops = {
465 .add = mc_sysdev_add, 460 .resume = mc_bp_resume,
466 .remove = mc_sysdev_remove,
467 .resume = mc_sysdev_resume,
468}; 461};
469 462
470static __cpuinit int 463static __cpuinit int
@@ -542,6 +535,7 @@ static int __init microcode_init(void)
542 if (error) 535 if (error)
543 return error; 536 return error;
544 537
538 register_syscore_ops(&mc_syscore_ops);
545 register_hotcpu_notifier(&mc_cpu_notifier); 539 register_hotcpu_notifier(&mc_cpu_notifier);
546 540
547 pr_info("Microcode Update Driver: v" MICROCODE_VERSION 541 pr_info("Microcode Update Driver: v" MICROCODE_VERSION
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index c01ffa5b9b87..82ada01625b9 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -27,7 +27,7 @@
27#include <linux/kdebug.h> 27#include <linux/kdebug.h>
28#include <linux/scatterlist.h> 28#include <linux/scatterlist.h>
29#include <linux/iommu-helper.h> 29#include <linux/iommu-helper.h>
30#include <linux/sysdev.h> 30#include <linux/syscore_ops.h>
31#include <linux/io.h> 31#include <linux/io.h>
32#include <linux/gfp.h> 32#include <linux/gfp.h>
33#include <asm/atomic.h> 33#include <asm/atomic.h>
@@ -589,7 +589,7 @@ void set_up_gart_resume(u32 aper_order, u32 aper_alloc)
589 aperture_alloc = aper_alloc; 589 aperture_alloc = aper_alloc;
590} 590}
591 591
592static void gart_fixup_northbridges(struct sys_device *dev) 592static void gart_fixup_northbridges(void)
593{ 593{
594 int i; 594 int i;
595 595
@@ -613,33 +613,20 @@ static void gart_fixup_northbridges(struct sys_device *dev)
613 } 613 }
614} 614}
615 615
616static int gart_resume(struct sys_device *dev) 616static void gart_resume(void)
617{ 617{
618 pr_info("PCI-DMA: Resuming GART IOMMU\n"); 618 pr_info("PCI-DMA: Resuming GART IOMMU\n");
619 619
620 gart_fixup_northbridges(dev); 620 gart_fixup_northbridges();
621 621
622 enable_gart_translations(); 622 enable_gart_translations();
623
624 return 0;
625} 623}
626 624
627static int gart_suspend(struct sys_device *dev, pm_message_t state) 625static struct syscore_ops gart_syscore_ops = {
628{
629 return 0;
630}
631
632static struct sysdev_class gart_sysdev_class = {
633 .name = "gart",
634 .suspend = gart_suspend,
635 .resume = gart_resume, 626 .resume = gart_resume,
636 627
637}; 628};
638 629
639static struct sys_device device_gart = {
640 .cls = &gart_sysdev_class,
641};
642
643/* 630/*
644 * Private Northbridge GATT initialization in case we cannot use the 631 * Private Northbridge GATT initialization in case we cannot use the
645 * AGP driver for some reason. 632 * AGP driver for some reason.
@@ -650,7 +637,7 @@ static __init int init_amd_gatt(struct agp_kern_info *info)
650 unsigned aper_base, new_aper_base; 637 unsigned aper_base, new_aper_base;
651 struct pci_dev *dev; 638 struct pci_dev *dev;
652 void *gatt; 639 void *gatt;
653 int i, error; 640 int i;
654 641
655 pr_info("PCI-DMA: Disabling AGP.\n"); 642 pr_info("PCI-DMA: Disabling AGP.\n");
656 643
@@ -685,12 +672,7 @@ static __init int init_amd_gatt(struct agp_kern_info *info)
685 672
686 agp_gatt_table = gatt; 673 agp_gatt_table = gatt;
687 674
688 error = sysdev_class_register(&gart_sysdev_class); 675 register_syscore_ops(&gart_syscore_ops);
689 if (!error)
690 error = sysdev_register(&device_gart);
691 if (error)
692 panic("Could not register gart_sysdev -- "
693 "would corrupt data on next suspend");
694 676
695 flush_gart(); 677 flush_gart();
696 678
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index e2b7b0c06cdf..8dace181c88e 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -15,7 +15,7 @@
15#include <linux/notifier.h> 15#include <linux/notifier.h>
16#include <linux/smp.h> 16#include <linux/smp.h>
17#include <linux/oprofile.h> 17#include <linux/oprofile.h>
18#include <linux/sysdev.h> 18#include <linux/syscore_ops.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
21#include <linux/kdebug.h> 21#include <linux/kdebug.h>
@@ -536,7 +536,7 @@ static void nmi_shutdown(void)
536 536
537#ifdef CONFIG_PM 537#ifdef CONFIG_PM
538 538
539static int nmi_suspend(struct sys_device *dev, pm_message_t state) 539static int nmi_suspend(void)
540{ 540{
541 /* Only one CPU left, just stop that one */ 541 /* Only one CPU left, just stop that one */
542 if (nmi_enabled == 1) 542 if (nmi_enabled == 1)
@@ -544,49 +544,31 @@ static int nmi_suspend(struct sys_device *dev, pm_message_t state)
544 return 0; 544 return 0;
545} 545}
546 546
547static int nmi_resume(struct sys_device *dev) 547static void nmi_resume(void)
548{ 548{
549 if (nmi_enabled == 1) 549 if (nmi_enabled == 1)
550 nmi_cpu_start(NULL); 550 nmi_cpu_start(NULL);
551 return 0;
552} 551}
553 552
554static struct sysdev_class oprofile_sysclass = { 553static struct syscore_ops oprofile_syscore_ops = {
555 .name = "oprofile",
556 .resume = nmi_resume, 554 .resume = nmi_resume,
557 .suspend = nmi_suspend, 555 .suspend = nmi_suspend,
558}; 556};
559 557
560static struct sys_device device_oprofile = { 558static void __init init_suspend_resume(void)
561 .id = 0,
562 .cls = &oprofile_sysclass,
563};
564
565static int __init init_sysfs(void)
566{ 559{
567 int error; 560 register_syscore_ops(&oprofile_syscore_ops);
568
569 error = sysdev_class_register(&oprofile_sysclass);
570 if (error)
571 return error;
572
573 error = sysdev_register(&device_oprofile);
574 if (error)
575 sysdev_class_unregister(&oprofile_sysclass);
576
577 return error;
578} 561}
579 562
580static void exit_sysfs(void) 563static void exit_suspend_resume(void)
581{ 564{
582 sysdev_unregister(&device_oprofile); 565 unregister_syscore_ops(&oprofile_syscore_ops);
583 sysdev_class_unregister(&oprofile_sysclass);
584} 566}
585 567
586#else 568#else
587 569
588static inline int init_sysfs(void) { return 0; } 570static inline void init_suspend_resume(void) { }
589static inline void exit_sysfs(void) { } 571static inline void exit_suspend_resume(void) { }
590 572
591#endif /* CONFIG_PM */ 573#endif /* CONFIG_PM */
592 574
@@ -789,9 +771,7 @@ int __init op_nmi_init(struct oprofile_operations *ops)
789 771
790 mux_init(ops); 772 mux_init(ops);
791 773
792 ret = init_sysfs(); 774 init_suspend_resume();
793 if (ret)
794 return ret;
795 775
796 printk(KERN_INFO "oprofile: using NMI interrupt.\n"); 776 printk(KERN_INFO "oprofile: using NMI interrupt.\n");
797 return 0; 777 return 0;
@@ -799,5 +779,5 @@ int __init op_nmi_init(struct oprofile_operations *ops)
799 779
800void op_nmi_exit(void) 780void op_nmi_exit(void)
801{ 781{
802 exit_sysfs(); 782 exit_suspend_resume();
803} 783}