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 /drivers | |
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
Diffstat (limited to 'drivers')
-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 |
4 files changed, 44 insertions, 70 deletions
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 | ||