aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-26 00:07:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-26 00:07:59 -0400
commit16c29dafcc86024048f1dbb8349d31cb22c7c55a (patch)
tree100c4fd34903adf02c9b8ae7705a3e1f30c8d712 /drivers
parentdc50eddb2f3a0dff365f093b2a93fb4ab4dd4389 (diff)
parentd47d81c0e9abdc3c88653fabff5beae82c949b09 (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/Kconfig7
-rw-r--r--drivers/base/sys.c3
-rw-r--r--drivers/cpufreq/cpufreq.c66
-rw-r--r--drivers/pci/intel-iommu.c38
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
171config 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
171endmenu 178endmenu
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}
526EXPORT_SYMBOL_GPL(sysdev_resume); 526EXPORT_SYMBOL_GPL(sysdev_resume);
527#endif /* CONFIG_ARCH_NO_SYSDEV_OPS */
527 528
528int __init system_bus_init(void) 529int __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}
1341EXPORT_SYMBOL(cpufreq_get); 1342EXPORT_SYMBOL(cpufreq_get);
1342 1343
1344static 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 1356static int cpufreq_bp_suspend(void)
1348static 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
1380out:
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 */
1395static int cpufreq_resume(struct sys_device *sysdev) 1394static 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
1431fail: 1419fail:
1432 cpufreq_cpu_put(cpu_policy); 1420 cpufreq_cpu_put(cpu_policy);
1433 return ret;
1434} 1421}
1435 1422
1436static struct sysdev_driver cpufreq_sysdev_driver = { 1423static 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
3138static int iommu_suspend(struct sys_device *dev, pm_message_t state) 3138static 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
3178static int iommu_resume(struct sys_device *dev) 3178static 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
3211static struct sysdev_class iommu_sysclass = { 3209static 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
3217static struct sys_device device_iommu = { 3214static void __init init_iommu_pm_ops(void)
3218 .cls = &iommu_sysclass,
3219};
3220
3221static 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
3237static int __init init_iommu_sysfs(void) 3220static 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