diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-26 00:07:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-26 00:07:59 -0400 |
commit | 16c29dafcc86024048f1dbb8349d31cb22c7c55a (patch) | |
tree | 100c4fd34903adf02c9b8ae7705a3e1f30c8d712 | |
parent | dc50eddb2f3a0dff365f093b2a93fb4ab4dd4389 (diff) | |
parent | d47d81c0e9abdc3c88653fabff5beae82c949b09 (diff) |
Merge branch 'syscore' of git://git.kernel.org/pub/scm/linux/kernel/git/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
-rw-r--r-- | arch/x86/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 26 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 33 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 97 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 21 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mtrr/main.c | 10 | ||||
-rw-r--r-- | arch/x86/kernel/i8237.c | 30 | ||||
-rw-r--r-- | arch/x86/kernel/i8259.c | 33 | ||||
-rw-r--r-- | arch/x86/kernel/microcode_core.c | 34 | ||||
-rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 32 | ||||
-rw-r--r-- | arch/x86/oprofile/nmi_int.c | 44 | ||||
-rw-r--r-- | drivers/base/Kconfig | 7 | ||||
-rw-r--r-- | drivers/base/sys.c | 3 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 66 | ||||
-rw-r--r-- | drivers/pci/intel-iommu.c | 38 | ||||
-rw-r--r-- | include/linux/device.h | 4 | ||||
-rw-r--r-- | include/linux/pm.h | 10 | ||||
-rw-r--r-- | include/linux/sysdev.h | 7 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 27 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 34 |
20 files changed, 206 insertions, 351 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 140e254fe546..cc6c53a95bfd 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -71,6 +71,7 @@ config X86 | |||
71 | select GENERIC_IRQ_SHOW | 71 | select GENERIC_IRQ_SHOW |
72 | select IRQ_FORCED_THREADING | 72 | select IRQ_FORCED_THREADING |
73 | select USE_GENERIC_SMP_HELPERS if SMP | 73 | select USE_GENERIC_SMP_HELPERS if SMP |
74 | select ARCH_NO_SYSDEV_OPS | ||
74 | 75 | ||
75 | config INSTRUCTION_DECODER | 76 | config INSTRUCTION_DECODER |
76 | def_bool (KPROBES || PERF_EVENTS) | 77 | def_bool (KPROBES || PERF_EVENTS) |
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 | ||
1263 | static int amd_iommu_resume(struct sys_device *dev) | 1263 | static 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 | ||
1283 | static int amd_iommu_suspend(struct sys_device *dev, pm_message_t state) | 1281 | static 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 | ||
1291 | static struct sysdev_class amd_iommu_sysdev_class = { | 1289 | static 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 | ||
1297 | static 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 | ||
2049 | static int lapic_suspend(struct sys_device *dev, pm_message_t state) | 2049 | static 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 | ||
2087 | static int lapic_resume(struct sys_device *dev) | 2087 | static 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 | } |
2163 | restore: | 2161 | restore: |
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 | ||
2174 | static struct sysdev_class lapic_sysclass = { | 2170 | static 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 | ||
2180 | static struct sys_device device_lapic = { | ||
2181 | .id = 0, | ||
2182 | .cls = &lapic_sysclass, | ||
2183 | }; | ||
2184 | |||
2185 | static void __cpuinit apic_pm_activate(void) | 2175 | static 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 | ||
2190 | static int __init init_lapic_sysfs(void) | 2180 | static 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 | ||
2919 | late_initcall(io_apic_bug_finalize); | 2919 | late_initcall(io_apic_bug_finalize); |
2920 | 2920 | ||
2921 | struct sysfs_ioapic_data { | 2921 | static 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 | }; | ||
2925 | static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS]; | ||
2926 | 2922 | ||
2927 | static int ioapic_suspend(struct sys_device *dev, pm_message_t state) | 2923 | static 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 | |||
2935 | static 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 | ||
2941 | static int ioapic_resume(struct sys_device *dev) | 2945 | static 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; | 2966 | static 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 | ||
2965 | static struct sysdev_class ioapic_sysdev_class = { | 2974 | static 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 | ||
2971 | static int __init ioapic_init_sysfs(void) | 2979 | static 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 | ||
3003 | device_initcall(ioapic_init_sysfs); | 2998 | device_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 | ||
1752 | static int mce_suspend(struct sys_device *dev, pm_message_t state) | 1753 | static int mce_suspend(void) |
1753 | { | 1754 | { |
1754 | return mce_disable_error_reporting(); | 1755 | return mce_disable_error_reporting(); |
1755 | } | 1756 | } |
1756 | 1757 | ||
1757 | static int mce_shutdown(struct sys_device *dev) | 1758 | static 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 | */ |
1767 | static int mce_resume(struct sys_device *dev) | 1768 | static 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 | ||
1774 | static struct syscore_ops mce_syscore_ops = { | ||
1775 | .suspend = mce_suspend, | ||
1776 | .shutdown = mce_shutdown, | ||
1777 | .resume = mce_resume, | ||
1778 | }; | ||
1779 | |||
1775 | static void mce_cpu_restart(void *data) | 1780 | static 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 | ||
1810 | static struct sysdev_class mce_sysclass = { | 1815 | static 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 | ||
631 | static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES]; | 632 | static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES]; |
632 | 633 | ||
633 | static int mtrr_save(struct sys_device *sysdev, pm_message_t state) | 634 | static 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 | ||
645 | static int mtrr_restore(struct sys_device *sysdev) | 646 | static 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 | ||
661 | static struct sysdev_driver mtrr_sysdev_driver = { | 661 | static 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 | ||
24 | static int i8237A_resume(struct sys_device *dev) | 24 | static 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 | ||
48 | static int i8237A_suspend(struct sys_device *dev, pm_message_t state) | 46 | static struct syscore_ops i8237_syscore_ops = { |
49 | { | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static 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 | ||
59 | static struct sys_device device_i8237A = { | 50 | static int __init i8237A_init_ops(void) |
60 | .id = 0, | ||
61 | .cls = &i8237_sysdev_class, | ||
62 | }; | ||
63 | |||
64 | static 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 | } |
71 | device_initcall(i8237A_init_sysfs); | 55 | device_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 | ||
248 | static int i8259A_resume(struct sys_device *dev) | 248 | static 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 | ||
255 | static int i8259A_suspend(struct sys_device *dev, pm_message_t state) | 254 | static 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 | ||
261 | static int i8259A_shutdown(struct sys_device *dev) | 260 | static 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 | ||
272 | static struct sysdev_class i8259_sysdev_class = { | 270 | static 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 | ||
279 | static struct sys_device device_i8259A = { | ||
280 | .id = 0, | ||
281 | .cls = &i8259_sysdev_class, | ||
282 | }; | ||
283 | |||
284 | static void mask_8259A(void) | 276 | static 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 | ||
400 | struct legacy_pic *legacy_pic = &default_legacy_pic; | 392 | struct legacy_pic *legacy_pic = &default_legacy_pic; |
401 | 393 | ||
402 | static int __init i8259A_init_sysfs(void) | 394 | static 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 | ||
415 | device_initcall(i8259A_init_sysfs); | 402 | device_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 | ||
441 | static int mc_sysdev_resume(struct sys_device *dev) | 442 | static 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 | */ | ||
450 | static 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 | ||
464 | static struct sysdev_driver mc_sysdev_driver = { | 459 | static 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 | ||
470 | static __cpuinit int | 463 | static __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 | ||
592 | static void gart_fixup_northbridges(struct sys_device *dev) | 592 | static 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 | ||
616 | static int gart_resume(struct sys_device *dev) | 616 | static 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 | ||
627 | static int gart_suspend(struct sys_device *dev, pm_message_t state) | 625 | static struct syscore_ops gart_syscore_ops = { |
628 | { | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | static 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 | ||
639 | static 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 | ||
539 | static int nmi_suspend(struct sys_device *dev, pm_message_t state) | 539 | static 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 | ||
547 | static int nmi_resume(struct sys_device *dev) | 547 | static 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 | ||
554 | static struct sysdev_class oprofile_sysclass = { | 553 | static 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 | ||
560 | static struct sys_device device_oprofile = { | 558 | static void __init init_suspend_resume(void) |
561 | .id = 0, | ||
562 | .cls = &oprofile_sysclass, | ||
563 | }; | ||
564 | |||
565 | static 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 | ||
580 | static void exit_sysfs(void) | 563 | static 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 | ||
588 | static inline int init_sysfs(void) { return 0; } | 570 | static inline void init_suspend_resume(void) { } |
589 | static inline void exit_sysfs(void) { } | 571 | static 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 | ||
800 | void op_nmi_exit(void) | 780 | void op_nmi_exit(void) |
801 | { | 781 | { |
802 | exit_sysfs(); | 782 | exit_suspend_resume(); |
803 | } | 783 | } |
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index d57e8d0fb823..e9e5238f3106 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
@@ -168,4 +168,11 @@ config SYS_HYPERVISOR | |||
168 | bool | 168 | bool |
169 | default n | 169 | default n |
170 | 170 | ||
171 | config ARCH_NO_SYSDEV_OPS | ||
172 | bool | ||
173 | ---help--- | ||
174 | To be selected by architectures that don't use sysdev class or | ||
175 | sysdev driver power management (suspend/resume) and shutdown | ||
176 | operations. | ||
177 | |||
171 | endmenu | 178 | endmenu |
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index f6fb54741602..fbe72da6c414 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -329,7 +329,7 @@ void sysdev_unregister(struct sys_device *sysdev) | |||
329 | } | 329 | } |
330 | 330 | ||
331 | 331 | ||
332 | 332 | #ifndef CONFIG_ARCH_NO_SYSDEV_OPS | |
333 | /** | 333 | /** |
334 | * sysdev_shutdown - Shut down all system devices. | 334 | * sysdev_shutdown - Shut down all system devices. |
335 | * | 335 | * |
@@ -524,6 +524,7 @@ int sysdev_resume(void) | |||
524 | return 0; | 524 | return 0; |
525 | } | 525 | } |
526 | EXPORT_SYMBOL_GPL(sysdev_resume); | 526 | EXPORT_SYMBOL_GPL(sysdev_resume); |
527 | #endif /* CONFIG_ARCH_NO_SYSDEV_OPS */ | ||
527 | 528 | ||
528 | int __init system_bus_init(void) | 529 | int __init system_bus_init(void) |
529 | { | 530 | { |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 0f17ad8585d7..b03771d4787c 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/cpu.h> | 28 | #include <linux/cpu.h> |
29 | #include <linux/completion.h> | 29 | #include <linux/completion.h> |
30 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
31 | #include <linux/syscore_ops.h> | ||
31 | 32 | ||
32 | #include <trace/events/power.h> | 33 | #include <trace/events/power.h> |
33 | 34 | ||
@@ -1340,35 +1341,31 @@ out: | |||
1340 | } | 1341 | } |
1341 | EXPORT_SYMBOL(cpufreq_get); | 1342 | EXPORT_SYMBOL(cpufreq_get); |
1342 | 1343 | ||
1344 | static struct sysdev_driver cpufreq_sysdev_driver = { | ||
1345 | .add = cpufreq_add_dev, | ||
1346 | .remove = cpufreq_remove_dev, | ||
1347 | }; | ||
1348 | |||
1343 | 1349 | ||
1344 | /** | 1350 | /** |
1345 | * cpufreq_suspend - let the low level driver prepare for suspend | 1351 | * cpufreq_bp_suspend - Prepare the boot CPU for system suspend. |
1352 | * | ||
1353 | * This function is only executed for the boot processor. The other CPUs | ||
1354 | * have been put offline by means of CPU hotplug. | ||
1346 | */ | 1355 | */ |
1347 | 1356 | static int cpufreq_bp_suspend(void) | |
1348 | static int cpufreq_suspend(struct sys_device *sysdev, pm_message_t pmsg) | ||
1349 | { | 1357 | { |
1350 | int ret = 0; | 1358 | int ret = 0; |
1351 | 1359 | ||
1352 | int cpu = sysdev->id; | 1360 | int cpu = smp_processor_id(); |
1353 | struct cpufreq_policy *cpu_policy; | 1361 | struct cpufreq_policy *cpu_policy; |
1354 | 1362 | ||
1355 | dprintk("suspending cpu %u\n", cpu); | 1363 | dprintk("suspending cpu %u\n", cpu); |
1356 | 1364 | ||
1357 | if (!cpu_online(cpu)) | 1365 | /* If there's no policy for the boot CPU, we have nothing to do. */ |
1358 | return 0; | ||
1359 | |||
1360 | /* we may be lax here as interrupts are off. Nonetheless | ||
1361 | * we need to grab the correct cpu policy, as to check | ||
1362 | * whether we really run on this CPU. | ||
1363 | */ | ||
1364 | |||
1365 | cpu_policy = cpufreq_cpu_get(cpu); | 1366 | cpu_policy = cpufreq_cpu_get(cpu); |
1366 | if (!cpu_policy) | 1367 | if (!cpu_policy) |
1367 | return -EINVAL; | 1368 | return 0; |
1368 | |||
1369 | /* only handle each CPU group once */ | ||
1370 | if (unlikely(cpu_policy->cpu != cpu)) | ||
1371 | goto out; | ||
1372 | 1369 | ||
1373 | if (cpufreq_driver->suspend) { | 1370 | if (cpufreq_driver->suspend) { |
1374 | ret = cpufreq_driver->suspend(cpu_policy); | 1371 | ret = cpufreq_driver->suspend(cpu_policy); |
@@ -1377,13 +1374,12 @@ static int cpufreq_suspend(struct sys_device *sysdev, pm_message_t pmsg) | |||
1377 | "step on CPU %u\n", cpu_policy->cpu); | 1374 | "step on CPU %u\n", cpu_policy->cpu); |
1378 | } | 1375 | } |
1379 | 1376 | ||
1380 | out: | ||
1381 | cpufreq_cpu_put(cpu_policy); | 1377 | cpufreq_cpu_put(cpu_policy); |
1382 | return ret; | 1378 | return ret; |
1383 | } | 1379 | } |
1384 | 1380 | ||
1385 | /** | 1381 | /** |
1386 | * cpufreq_resume - restore proper CPU frequency handling after resume | 1382 | * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU. |
1387 | * | 1383 | * |
1388 | * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) | 1384 | * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) |
1389 | * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are | 1385 | * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are |
@@ -1391,31 +1387,23 @@ out: | |||
1391 | * what we believe it to be. This is a bit later than when it | 1387 | * what we believe it to be. This is a bit later than when it |
1392 | * should be, but nonethteless it's better than calling | 1388 | * should be, but nonethteless it's better than calling |
1393 | * cpufreq_driver->get() here which might re-enable interrupts... | 1389 | * cpufreq_driver->get() here which might re-enable interrupts... |
1390 | * | ||
1391 | * This function is only executed for the boot CPU. The other CPUs have not | ||
1392 | * been turned on yet. | ||
1394 | */ | 1393 | */ |
1395 | static int cpufreq_resume(struct sys_device *sysdev) | 1394 | static void cpufreq_bp_resume(void) |
1396 | { | 1395 | { |
1397 | int ret = 0; | 1396 | int ret = 0; |
1398 | 1397 | ||
1399 | int cpu = sysdev->id; | 1398 | int cpu = smp_processor_id(); |
1400 | struct cpufreq_policy *cpu_policy; | 1399 | struct cpufreq_policy *cpu_policy; |
1401 | 1400 | ||
1402 | dprintk("resuming cpu %u\n", cpu); | 1401 | dprintk("resuming cpu %u\n", cpu); |
1403 | 1402 | ||
1404 | if (!cpu_online(cpu)) | 1403 | /* If there's no policy for the boot CPU, we have nothing to do. */ |
1405 | return 0; | ||
1406 | |||
1407 | /* we may be lax here as interrupts are off. Nonetheless | ||
1408 | * we need to grab the correct cpu policy, as to check | ||
1409 | * whether we really run on this CPU. | ||
1410 | */ | ||
1411 | |||
1412 | cpu_policy = cpufreq_cpu_get(cpu); | 1404 | cpu_policy = cpufreq_cpu_get(cpu); |
1413 | if (!cpu_policy) | 1405 | if (!cpu_policy) |
1414 | return -EINVAL; | 1406 | return; |
1415 | |||
1416 | /* only handle each CPU group once */ | ||
1417 | if (unlikely(cpu_policy->cpu != cpu)) | ||
1418 | goto fail; | ||
1419 | 1407 | ||
1420 | if (cpufreq_driver->resume) { | 1408 | if (cpufreq_driver->resume) { |
1421 | ret = cpufreq_driver->resume(cpu_policy); | 1409 | ret = cpufreq_driver->resume(cpu_policy); |
@@ -1430,14 +1418,11 @@ static int cpufreq_resume(struct sys_device *sysdev) | |||
1430 | 1418 | ||
1431 | fail: | 1419 | fail: |
1432 | cpufreq_cpu_put(cpu_policy); | 1420 | cpufreq_cpu_put(cpu_policy); |
1433 | return ret; | ||
1434 | } | 1421 | } |
1435 | 1422 | ||
1436 | static struct sysdev_driver cpufreq_sysdev_driver = { | 1423 | static struct syscore_ops cpufreq_syscore_ops = { |
1437 | .add = cpufreq_add_dev, | 1424 | .suspend = cpufreq_bp_suspend, |
1438 | .remove = cpufreq_remove_dev, | 1425 | .resume = cpufreq_bp_resume, |
1439 | .suspend = cpufreq_suspend, | ||
1440 | .resume = cpufreq_resume, | ||
1441 | }; | 1426 | }; |
1442 | 1427 | ||
1443 | 1428 | ||
@@ -2002,6 +1987,7 @@ static int __init cpufreq_core_init(void) | |||
2002 | cpufreq_global_kobject = kobject_create_and_add("cpufreq", | 1987 | cpufreq_global_kobject = kobject_create_and_add("cpufreq", |
2003 | &cpu_sysdev_class.kset.kobj); | 1988 | &cpu_sysdev_class.kset.kobj); |
2004 | BUG_ON(!cpufreq_global_kobject); | 1989 | BUG_ON(!cpufreq_global_kobject); |
1990 | register_syscore_ops(&cpufreq_syscore_ops); | ||
2005 | 1991 | ||
2006 | return 0; | 1992 | return 0; |
2007 | } | 1993 | } |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 4789f8e8bf7a..a4115f1afe1f 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/iova.h> | 36 | #include <linux/iova.h> |
37 | #include <linux/iommu.h> | 37 | #include <linux/iommu.h> |
38 | #include <linux/intel-iommu.h> | 38 | #include <linux/intel-iommu.h> |
39 | #include <linux/sysdev.h> | 39 | #include <linux/syscore_ops.h> |
40 | #include <linux/tboot.h> | 40 | #include <linux/tboot.h> |
41 | #include <linux/dmi.h> | 41 | #include <linux/dmi.h> |
42 | #include <asm/cacheflush.h> | 42 | #include <asm/cacheflush.h> |
@@ -3135,7 +3135,7 @@ static void iommu_flush_all(void) | |||
3135 | } | 3135 | } |
3136 | } | 3136 | } |
3137 | 3137 | ||
3138 | static int iommu_suspend(struct sys_device *dev, pm_message_t state) | 3138 | static int iommu_suspend(void) |
3139 | { | 3139 | { |
3140 | struct dmar_drhd_unit *drhd; | 3140 | struct dmar_drhd_unit *drhd; |
3141 | struct intel_iommu *iommu = NULL; | 3141 | struct intel_iommu *iommu = NULL; |
@@ -3175,7 +3175,7 @@ nomem: | |||
3175 | return -ENOMEM; | 3175 | return -ENOMEM; |
3176 | } | 3176 | } |
3177 | 3177 | ||
3178 | static int iommu_resume(struct sys_device *dev) | 3178 | static void iommu_resume(void) |
3179 | { | 3179 | { |
3180 | struct dmar_drhd_unit *drhd; | 3180 | struct dmar_drhd_unit *drhd; |
3181 | struct intel_iommu *iommu = NULL; | 3181 | struct intel_iommu *iommu = NULL; |
@@ -3183,7 +3183,7 @@ static int iommu_resume(struct sys_device *dev) | |||
3183 | 3183 | ||
3184 | if (init_iommu_hw()) { | 3184 | if (init_iommu_hw()) { |
3185 | WARN(1, "IOMMU setup failed, DMAR can not resume!\n"); | 3185 | WARN(1, "IOMMU setup failed, DMAR can not resume!\n"); |
3186 | return -EIO; | 3186 | return; |
3187 | } | 3187 | } |
3188 | 3188 | ||
3189 | for_each_active_iommu(iommu, drhd) { | 3189 | for_each_active_iommu(iommu, drhd) { |
@@ -3204,40 +3204,20 @@ static int iommu_resume(struct sys_device *dev) | |||
3204 | 3204 | ||
3205 | for_each_active_iommu(iommu, drhd) | 3205 | for_each_active_iommu(iommu, drhd) |
3206 | kfree(iommu->iommu_state); | 3206 | kfree(iommu->iommu_state); |
3207 | |||
3208 | return 0; | ||
3209 | } | 3207 | } |
3210 | 3208 | ||
3211 | static struct sysdev_class iommu_sysclass = { | 3209 | static struct syscore_ops iommu_syscore_ops = { |
3212 | .name = "iommu", | ||
3213 | .resume = iommu_resume, | 3210 | .resume = iommu_resume, |
3214 | .suspend = iommu_suspend, | 3211 | .suspend = iommu_suspend, |
3215 | }; | 3212 | }; |
3216 | 3213 | ||
3217 | static struct sys_device device_iommu = { | 3214 | static void __init init_iommu_pm_ops(void) |
3218 | .cls = &iommu_sysclass, | ||
3219 | }; | ||
3220 | |||
3221 | static int __init init_iommu_sysfs(void) | ||
3222 | { | 3215 | { |
3223 | int error; | 3216 | register_syscore_ops(&iommu_syscore_ops); |
3224 | |||
3225 | error = sysdev_class_register(&iommu_sysclass); | ||
3226 | if (error) | ||
3227 | return error; | ||
3228 | |||
3229 | error = sysdev_register(&device_iommu); | ||
3230 | if (error) | ||
3231 | sysdev_class_unregister(&iommu_sysclass); | ||
3232 | |||
3233 | return error; | ||
3234 | } | 3217 | } |
3235 | 3218 | ||
3236 | #else | 3219 | #else |
3237 | static int __init init_iommu_sysfs(void) | 3220 | static inline int init_iommu_pm_ops(void) { } |
3238 | { | ||
3239 | return 0; | ||
3240 | } | ||
3241 | #endif /* CONFIG_PM */ | 3221 | #endif /* CONFIG_PM */ |
3242 | 3222 | ||
3243 | /* | 3223 | /* |
@@ -3320,7 +3300,7 @@ int __init intel_iommu_init(void) | |||
3320 | #endif | 3300 | #endif |
3321 | dma_ops = &intel_dma_ops; | 3301 | dma_ops = &intel_dma_ops; |
3322 | 3302 | ||
3323 | init_iommu_sysfs(); | 3303 | init_iommu_pm_ops(); |
3324 | 3304 | ||
3325 | register_iommu(&intel_iommu_ops); | 3305 | register_iommu(&intel_iommu_ops); |
3326 | 3306 | ||
diff --git a/include/linux/device.h b/include/linux/device.h index 144ec135875f..ab8dfc095709 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -633,8 +633,12 @@ static inline int devtmpfs_mount(const char *mountpoint) { return 0; } | |||
633 | /* drivers/base/power/shutdown.c */ | 633 | /* drivers/base/power/shutdown.c */ |
634 | extern void device_shutdown(void); | 634 | extern void device_shutdown(void); |
635 | 635 | ||
636 | #ifndef CONFIG_ARCH_NO_SYSDEV_OPS | ||
636 | /* drivers/base/sys.c */ | 637 | /* drivers/base/sys.c */ |
637 | extern void sysdev_shutdown(void); | 638 | extern void sysdev_shutdown(void); |
639 | #else | ||
640 | static inline void sysdev_shutdown(void) { } | ||
641 | #endif | ||
638 | 642 | ||
639 | /* debugging and troubleshooting/diagnostic helpers. */ | 643 | /* debugging and troubleshooting/diagnostic helpers. */ |
640 | extern const char *dev_driver_string(const struct device *dev); | 644 | extern const char *dev_driver_string(const struct device *dev); |
diff --git a/include/linux/pm.h b/include/linux/pm.h index 6618216bb973..512e09177e57 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -529,13 +529,19 @@ struct dev_power_domain { | |||
529 | */ | 529 | */ |
530 | 530 | ||
531 | #ifdef CONFIG_PM_SLEEP | 531 | #ifdef CONFIG_PM_SLEEP |
532 | extern void device_pm_lock(void); | 532 | #ifndef CONFIG_ARCH_NO_SYSDEV_OPS |
533 | extern int sysdev_suspend(pm_message_t state); | ||
533 | extern int sysdev_resume(void); | 534 | extern int sysdev_resume(void); |
535 | #else | ||
536 | static inline int sysdev_suspend(pm_message_t state) { return 0; } | ||
537 | static inline int sysdev_resume(void) { return 0; } | ||
538 | #endif | ||
539 | |||
540 | extern void device_pm_lock(void); | ||
534 | extern void dpm_resume_noirq(pm_message_t state); | 541 | extern void dpm_resume_noirq(pm_message_t state); |
535 | extern void dpm_resume_end(pm_message_t state); | 542 | extern void dpm_resume_end(pm_message_t state); |
536 | 543 | ||
537 | extern void device_pm_unlock(void); | 544 | extern void device_pm_unlock(void); |
538 | extern int sysdev_suspend(pm_message_t state); | ||
539 | extern int dpm_suspend_noirq(pm_message_t state); | 545 | extern int dpm_suspend_noirq(pm_message_t state); |
540 | extern int dpm_suspend_start(pm_message_t state); | 546 | extern int dpm_suspend_start(pm_message_t state); |
541 | 547 | ||
diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h index 1154c29f4101..8a75da551e4e 100644 --- a/include/linux/sysdev.h +++ b/include/linux/sysdev.h | |||
@@ -33,12 +33,13 @@ struct sysdev_class { | |||
33 | const char *name; | 33 | const char *name; |
34 | struct list_head drivers; | 34 | struct list_head drivers; |
35 | struct sysdev_class_attribute **attrs; | 35 | struct sysdev_class_attribute **attrs; |
36 | 36 | struct kset kset; | |
37 | #ifndef CONFIG_ARCH_NO_SYSDEV_OPS | ||
37 | /* Default operations for these types of devices */ | 38 | /* Default operations for these types of devices */ |
38 | int (*shutdown)(struct sys_device *); | 39 | int (*shutdown)(struct sys_device *); |
39 | int (*suspend)(struct sys_device *, pm_message_t state); | 40 | int (*suspend)(struct sys_device *, pm_message_t state); |
40 | int (*resume)(struct sys_device *); | 41 | int (*resume)(struct sys_device *); |
41 | struct kset kset; | 42 | #endif |
42 | }; | 43 | }; |
43 | 44 | ||
44 | struct sysdev_class_attribute { | 45 | struct sysdev_class_attribute { |
@@ -76,9 +77,11 @@ struct sysdev_driver { | |||
76 | struct list_head entry; | 77 | struct list_head entry; |
77 | int (*add)(struct sys_device *); | 78 | int (*add)(struct sys_device *); |
78 | int (*remove)(struct sys_device *); | 79 | int (*remove)(struct sys_device *); |
80 | #ifndef CONFIG_ARCH_NO_SYSDEV_OPS | ||
79 | int (*shutdown)(struct sys_device *); | 81 | int (*shutdown)(struct sys_device *); |
80 | int (*suspend)(struct sys_device *, pm_message_t state); | 82 | int (*suspend)(struct sys_device *, pm_message_t state); |
81 | int (*resume)(struct sys_device *); | 83 | int (*resume)(struct sys_device *); |
84 | #endif | ||
82 | }; | 85 | }; |
83 | 86 | ||
84 | 87 | ||
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 3bd7e3d5c632..8ad5d576755e 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/sysdev.h> | 17 | #include <linux/syscore_ops.h> |
18 | #include <linux/clocksource.h> | 18 | #include <linux/clocksource.h> |
19 | #include <linux/jiffies.h> | 19 | #include <linux/jiffies.h> |
20 | #include <linux/time.h> | 20 | #include <linux/time.h> |
@@ -597,13 +597,12 @@ static struct timespec timekeeping_suspend_time; | |||
597 | 597 | ||
598 | /** | 598 | /** |
599 | * timekeeping_resume - Resumes the generic timekeeping subsystem. | 599 | * timekeeping_resume - Resumes the generic timekeeping subsystem. |
600 | * @dev: unused | ||
601 | * | 600 | * |
602 | * This is for the generic clocksource timekeeping. | 601 | * This is for the generic clocksource timekeeping. |
603 | * xtime/wall_to_monotonic/jiffies/etc are | 602 | * xtime/wall_to_monotonic/jiffies/etc are |
604 | * still managed by arch specific suspend/resume code. | 603 | * still managed by arch specific suspend/resume code. |
605 | */ | 604 | */ |
606 | static int timekeeping_resume(struct sys_device *dev) | 605 | static void timekeeping_resume(void) |
607 | { | 606 | { |
608 | unsigned long flags; | 607 | unsigned long flags; |
609 | struct timespec ts; | 608 | struct timespec ts; |
@@ -632,11 +631,9 @@ static int timekeeping_resume(struct sys_device *dev) | |||
632 | 631 | ||
633 | /* Resume hrtimers */ | 632 | /* Resume hrtimers */ |
634 | hres_timers_resume(); | 633 | hres_timers_resume(); |
635 | |||
636 | return 0; | ||
637 | } | 634 | } |
638 | 635 | ||
639 | static int timekeeping_suspend(struct sys_device *dev, pm_message_t state) | 636 | static int timekeeping_suspend(void) |
640 | { | 637 | { |
641 | unsigned long flags; | 638 | unsigned long flags; |
642 | 639 | ||
@@ -654,26 +651,18 @@ static int timekeeping_suspend(struct sys_device *dev, pm_message_t state) | |||
654 | } | 651 | } |
655 | 652 | ||
656 | /* sysfs resume/suspend bits for timekeeping */ | 653 | /* sysfs resume/suspend bits for timekeeping */ |
657 | static struct sysdev_class timekeeping_sysclass = { | 654 | static struct syscore_ops timekeeping_syscore_ops = { |
658 | .name = "timekeeping", | ||
659 | .resume = timekeeping_resume, | 655 | .resume = timekeeping_resume, |
660 | .suspend = timekeeping_suspend, | 656 | .suspend = timekeeping_suspend, |
661 | }; | 657 | }; |
662 | 658 | ||
663 | static struct sys_device device_timer = { | 659 | static int __init timekeeping_init_ops(void) |
664 | .id = 0, | ||
665 | .cls = &timekeeping_sysclass, | ||
666 | }; | ||
667 | |||
668 | static int __init timekeeping_init_device(void) | ||
669 | { | 660 | { |
670 | int error = sysdev_class_register(&timekeeping_sysclass); | 661 | register_syscore_ops(&timekeeping_syscore_ops); |
671 | if (!error) | 662 | return 0; |
672 | error = sysdev_register(&device_timer); | ||
673 | return error; | ||
674 | } | 663 | } |
675 | 664 | ||
676 | device_initcall(timekeeping_init_device); | 665 | device_initcall(timekeeping_init_ops); |
677 | 666 | ||
678 | /* | 667 | /* |
679 | * If the error is already larger, we look ahead even further | 668 | * If the error is already larger, we look ahead even further |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 7bee6dc8cdb2..556e3efe5325 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/debugfs.h> | 30 | #include <linux/debugfs.h> |
31 | #include <linux/highmem.h> | 31 | #include <linux/highmem.h> |
32 | #include <linux/file.h> | 32 | #include <linux/file.h> |
33 | #include <linux/sysdev.h> | 33 | #include <linux/syscore_ops.h> |
34 | #include <linux/cpu.h> | 34 | #include <linux/cpu.h> |
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/cpumask.h> | 36 | #include <linux/cpumask.h> |
@@ -2446,33 +2446,26 @@ static void kvm_exit_debug(void) | |||
2446 | debugfs_remove(kvm_debugfs_dir); | 2446 | debugfs_remove(kvm_debugfs_dir); |
2447 | } | 2447 | } |
2448 | 2448 | ||
2449 | static int kvm_suspend(struct sys_device *dev, pm_message_t state) | 2449 | static int kvm_suspend(void) |
2450 | { | 2450 | { |
2451 | if (kvm_usage_count) | 2451 | if (kvm_usage_count) |
2452 | hardware_disable_nolock(NULL); | 2452 | hardware_disable_nolock(NULL); |
2453 | return 0; | 2453 | return 0; |
2454 | } | 2454 | } |
2455 | 2455 | ||
2456 | static int kvm_resume(struct sys_device *dev) | 2456 | static void kvm_resume(void) |
2457 | { | 2457 | { |
2458 | if (kvm_usage_count) { | 2458 | if (kvm_usage_count) { |
2459 | WARN_ON(raw_spin_is_locked(&kvm_lock)); | 2459 | WARN_ON(raw_spin_is_locked(&kvm_lock)); |
2460 | hardware_enable_nolock(NULL); | 2460 | hardware_enable_nolock(NULL); |
2461 | } | 2461 | } |
2462 | return 0; | ||
2463 | } | 2462 | } |
2464 | 2463 | ||
2465 | static struct sysdev_class kvm_sysdev_class = { | 2464 | static struct syscore_ops kvm_syscore_ops = { |
2466 | .name = "kvm", | ||
2467 | .suspend = kvm_suspend, | 2465 | .suspend = kvm_suspend, |
2468 | .resume = kvm_resume, | 2466 | .resume = kvm_resume, |
2469 | }; | 2467 | }; |
2470 | 2468 | ||
2471 | static struct sys_device kvm_sysdev = { | ||
2472 | .id = 0, | ||
2473 | .cls = &kvm_sysdev_class, | ||
2474 | }; | ||
2475 | |||
2476 | struct page *bad_page; | 2469 | struct page *bad_page; |
2477 | pfn_t bad_pfn; | 2470 | pfn_t bad_pfn; |
2478 | 2471 | ||
@@ -2556,14 +2549,6 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, | |||
2556 | goto out_free_2; | 2549 | goto out_free_2; |
2557 | register_reboot_notifier(&kvm_reboot_notifier); | 2550 | register_reboot_notifier(&kvm_reboot_notifier); |
2558 | 2551 | ||
2559 | r = sysdev_class_register(&kvm_sysdev_class); | ||
2560 | if (r) | ||
2561 | goto out_free_3; | ||
2562 | |||
2563 | r = sysdev_register(&kvm_sysdev); | ||
2564 | if (r) | ||
2565 | goto out_free_4; | ||
2566 | |||
2567 | /* A kmem cache lets us meet the alignment requirements of fx_save. */ | 2552 | /* A kmem cache lets us meet the alignment requirements of fx_save. */ |
2568 | if (!vcpu_align) | 2553 | if (!vcpu_align) |
2569 | vcpu_align = __alignof__(struct kvm_vcpu); | 2554 | vcpu_align = __alignof__(struct kvm_vcpu); |
@@ -2571,7 +2556,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, | |||
2571 | 0, NULL); | 2556 | 0, NULL); |
2572 | if (!kvm_vcpu_cache) { | 2557 | if (!kvm_vcpu_cache) { |
2573 | r = -ENOMEM; | 2558 | r = -ENOMEM; |
2574 | goto out_free_5; | 2559 | goto out_free_3; |
2575 | } | 2560 | } |
2576 | 2561 | ||
2577 | r = kvm_async_pf_init(); | 2562 | r = kvm_async_pf_init(); |
@@ -2588,6 +2573,8 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, | |||
2588 | goto out_unreg; | 2573 | goto out_unreg; |
2589 | } | 2574 | } |
2590 | 2575 | ||
2576 | register_syscore_ops(&kvm_syscore_ops); | ||
2577 | |||
2591 | kvm_preempt_ops.sched_in = kvm_sched_in; | 2578 | kvm_preempt_ops.sched_in = kvm_sched_in; |
2592 | kvm_preempt_ops.sched_out = kvm_sched_out; | 2579 | kvm_preempt_ops.sched_out = kvm_sched_out; |
2593 | 2580 | ||
@@ -2599,10 +2586,6 @@ out_unreg: | |||
2599 | kvm_async_pf_deinit(); | 2586 | kvm_async_pf_deinit(); |
2600 | out_free: | 2587 | out_free: |
2601 | kmem_cache_destroy(kvm_vcpu_cache); | 2588 | kmem_cache_destroy(kvm_vcpu_cache); |
2602 | out_free_5: | ||
2603 | sysdev_unregister(&kvm_sysdev); | ||
2604 | out_free_4: | ||
2605 | sysdev_class_unregister(&kvm_sysdev_class); | ||
2606 | out_free_3: | 2589 | out_free_3: |
2607 | unregister_reboot_notifier(&kvm_reboot_notifier); | 2590 | unregister_reboot_notifier(&kvm_reboot_notifier); |
2608 | unregister_cpu_notifier(&kvm_cpu_notifier); | 2591 | unregister_cpu_notifier(&kvm_cpu_notifier); |
@@ -2630,8 +2613,7 @@ void kvm_exit(void) | |||
2630 | misc_deregister(&kvm_dev); | 2613 | misc_deregister(&kvm_dev); |
2631 | kmem_cache_destroy(kvm_vcpu_cache); | 2614 | kmem_cache_destroy(kvm_vcpu_cache); |
2632 | kvm_async_pf_deinit(); | 2615 | kvm_async_pf_deinit(); |
2633 | sysdev_unregister(&kvm_sysdev); | 2616 | unregister_syscore_ops(&kvm_syscore_ops); |
2634 | sysdev_class_unregister(&kvm_sysdev_class); | ||
2635 | unregister_reboot_notifier(&kvm_reboot_notifier); | 2617 | unregister_reboot_notifier(&kvm_reboot_notifier); |
2636 | unregister_cpu_notifier(&kvm_cpu_notifier); | 2618 | unregister_cpu_notifier(&kvm_cpu_notifier); |
2637 | on_each_cpu(hardware_disable_nolock, NULL, 1); | 2619 | on_each_cpu(hardware_disable_nolock, NULL, 1); |