aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2013-08-28 18:41:59 -0400
committerAlexander Graf <agraf@suse.de>2013-08-28 18:41:59 -0400
commitbf550fc93d9855872a95e69e4002256110d89858 (patch)
tree10876bb4304bffe54c4160a132e7b8de6577ac4e /drivers/base
parent7e48c101e0c53e6095c5f4f5e63d14df50aae8fc (diff)
parentcc2df20c7c4ce594c3e17e9cc260c330646012c8 (diff)
Merge remote-tracking branch 'origin/next' into kvm-ppc-next
Conflicts: mm/Kconfig CMA DMA split and ZSWAP introduction were conflicting, fix up manually.
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/Makefile2
-rw-r--r--drivers/base/attribute_container.c2
-rw-r--r--drivers/base/core.c130
-rw-r--r--drivers/base/cpu.c101
-rw-r--r--drivers/base/dma-buf.c5
-rw-r--r--drivers/base/memory.c114
-rw-r--r--drivers/base/platform.c4
-rw-r--r--drivers/base/power/domain.c1
-rw-r--r--drivers/base/power/generic_ops.c23
-rw-r--r--drivers/base/power/opp.c4
-rw-r--r--drivers/base/power/qos.c6
-rw-r--r--drivers/base/power/runtime.c12
-rw-r--r--drivers/base/power/wakeup.c9
-rw-r--r--drivers/base/reservation.c39
14 files changed, 309 insertions, 143 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 5d93bb519753..94e8a80e87f8 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -10,7 +10,7 @@ obj-$(CONFIG_DMA_CMA) += dma-contiguous.o
10obj-y += power/ 10obj-y += power/
11obj-$(CONFIG_HAS_DMA) += dma-mapping.o 11obj-$(CONFIG_HAS_DMA) += dma-mapping.o
12obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o 12obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
13obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o 13obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o reservation.o
14obj-$(CONFIG_ISA) += isa.o 14obj-$(CONFIG_ISA) += isa.o
15obj-$(CONFIG_FW_LOADER) += firmware_class.o 15obj-$(CONFIG_FW_LOADER) += firmware_class.o
16obj-$(CONFIG_NUMA) += node.o 16obj-$(CONFIG_NUMA) += node.o
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index d78b204e65c1..ecc1929d7f6a 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -167,7 +167,7 @@ attribute_container_add_device(struct device *dev,
167 ic->classdev.parent = get_device(dev); 167 ic->classdev.parent = get_device(dev);
168 ic->classdev.class = cont->class; 168 ic->classdev.class = cont->class;
169 cont->class->dev_release = attribute_container_release; 169 cont->class->dev_release = attribute_container_release;
170 dev_set_name(&ic->classdev, dev_name(dev)); 170 dev_set_name(&ic->classdev, "%s", dev_name(dev));
171 if (fn) 171 if (fn)
172 fn(cont, dev, &ic->classdev); 172 fn(cont, dev, &ic->classdev);
173 else 173 else
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6fdc53d46fa0..dc3ea237f086 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -403,6 +403,36 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
403static struct device_attribute uevent_attr = 403static struct device_attribute uevent_attr =
404 __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent); 404 __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);
405 405
406static ssize_t show_online(struct device *dev, struct device_attribute *attr,
407 char *buf)
408{
409 bool val;
410
411 lock_device_hotplug();
412 val = !dev->offline;
413 unlock_device_hotplug();
414 return sprintf(buf, "%u\n", val);
415}
416
417static ssize_t store_online(struct device *dev, struct device_attribute *attr,
418 const char *buf, size_t count)
419{
420 bool val;
421 int ret;
422
423 ret = strtobool(buf, &val);
424 if (ret < 0)
425 return ret;
426
427 lock_device_hotplug();
428 ret = val ? device_online(dev) : device_offline(dev);
429 unlock_device_hotplug();
430 return ret < 0 ? ret : count;
431}
432
433static struct device_attribute online_attr =
434 __ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online);
435
406static int device_add_attributes(struct device *dev, 436static int device_add_attributes(struct device *dev,
407 struct device_attribute *attrs) 437 struct device_attribute *attrs)
408{ 438{
@@ -516,6 +546,12 @@ static int device_add_attrs(struct device *dev)
516 if (error) 546 if (error)
517 goto err_remove_type_groups; 547 goto err_remove_type_groups;
518 548
549 if (device_supports_offline(dev) && !dev->offline_disabled) {
550 error = device_create_file(dev, &online_attr);
551 if (error)
552 goto err_remove_type_groups;
553 }
554
519 return 0; 555 return 0;
520 556
521 err_remove_type_groups: 557 err_remove_type_groups:
@@ -536,6 +572,7 @@ static void device_remove_attrs(struct device *dev)
536 struct class *class = dev->class; 572 struct class *class = dev->class;
537 const struct device_type *type = dev->type; 573 const struct device_type *type = dev->type;
538 574
575 device_remove_file(dev, &online_attr);
539 device_remove_groups(dev, dev->groups); 576 device_remove_groups(dev, dev->groups);
540 577
541 if (type) 578 if (type)
@@ -1435,6 +1472,99 @@ EXPORT_SYMBOL_GPL(put_device);
1435EXPORT_SYMBOL_GPL(device_create_file); 1472EXPORT_SYMBOL_GPL(device_create_file);
1436EXPORT_SYMBOL_GPL(device_remove_file); 1473EXPORT_SYMBOL_GPL(device_remove_file);
1437 1474
1475static DEFINE_MUTEX(device_hotplug_lock);
1476
1477void lock_device_hotplug(void)
1478{
1479 mutex_lock(&device_hotplug_lock);
1480}
1481
1482void unlock_device_hotplug(void)
1483{
1484 mutex_unlock(&device_hotplug_lock);
1485}
1486
1487static int device_check_offline(struct device *dev, void *not_used)
1488{
1489 int ret;
1490
1491 ret = device_for_each_child(dev, NULL, device_check_offline);
1492 if (ret)
1493 return ret;
1494
1495 return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0;
1496}
1497
1498/**
1499 * device_offline - Prepare the device for hot-removal.
1500 * @dev: Device to be put offline.
1501 *
1502 * Execute the device bus type's .offline() callback, if present, to prepare
1503 * the device for a subsequent hot-removal. If that succeeds, the device must
1504 * not be used until either it is removed or its bus type's .online() callback
1505 * is executed.
1506 *
1507 * Call under device_hotplug_lock.
1508 */
1509int device_offline(struct device *dev)
1510{
1511 int ret;
1512
1513 if (dev->offline_disabled)
1514 return -EPERM;
1515
1516 ret = device_for_each_child(dev, NULL, device_check_offline);
1517 if (ret)
1518 return ret;
1519
1520 device_lock(dev);
1521 if (device_supports_offline(dev)) {
1522 if (dev->offline) {
1523 ret = 1;
1524 } else {
1525 ret = dev->bus->offline(dev);
1526 if (!ret) {
1527 kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
1528 dev->offline = true;
1529 }
1530 }
1531 }
1532 device_unlock(dev);
1533
1534 return ret;
1535}
1536
1537/**
1538 * device_online - Put the device back online after successful device_offline().
1539 * @dev: Device to be put back online.
1540 *
1541 * If device_offline() has been successfully executed for @dev, but the device
1542 * has not been removed subsequently, execute its bus type's .online() callback
1543 * to indicate that the device can be used again.
1544 *
1545 * Call under device_hotplug_lock.
1546 */
1547int device_online(struct device *dev)
1548{
1549 int ret = 0;
1550
1551 device_lock(dev);
1552 if (device_supports_offline(dev)) {
1553 if (dev->offline) {
1554 ret = dev->bus->online(dev);
1555 if (!ret) {
1556 kobject_uevent(&dev->kobj, KOBJ_ONLINE);
1557 dev->offline = false;
1558 }
1559 } else {
1560 ret = 1;
1561 }
1562 }
1563 device_unlock(dev);
1564
1565 return ret;
1566}
1567
1438struct root_device { 1568struct root_device {
1439 struct device dev; 1569 struct device dev;
1440 struct module *owner; 1570 struct module *owner;
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index c377673320ed..a16d20e389f0 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -13,17 +13,21 @@
13#include <linux/gfp.h> 13#include <linux/gfp.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/percpu.h> 15#include <linux/percpu.h>
16#include <linux/acpi.h>
16 17
17#include "base.h" 18#include "base.h"
18 19
19struct bus_type cpu_subsys = {
20 .name = "cpu",
21 .dev_name = "cpu",
22};
23EXPORT_SYMBOL_GPL(cpu_subsys);
24
25static DEFINE_PER_CPU(struct device *, cpu_sys_devices); 20static DEFINE_PER_CPU(struct device *, cpu_sys_devices);
26 21
22static int cpu_subsys_match(struct device *dev, struct device_driver *drv)
23{
24 /* ACPI style match is the only one that may succeed. */
25 if (acpi_driver_match_device(dev, drv))
26 return 1;
27
28 return 0;
29}
30
27#ifdef CONFIG_HOTPLUG_CPU 31#ifdef CONFIG_HOTPLUG_CPU
28static void change_cpu_under_node(struct cpu *cpu, 32static void change_cpu_under_node(struct cpu *cpu,
29 unsigned int from_nid, unsigned int to_nid) 33 unsigned int from_nid, unsigned int to_nid)
@@ -34,65 +38,38 @@ static void change_cpu_under_node(struct cpu *cpu,
34 cpu->node_id = to_nid; 38 cpu->node_id = to_nid;
35} 39}
36 40
37static ssize_t show_online(struct device *dev, 41static int __ref cpu_subsys_online(struct device *dev)
38 struct device_attribute *attr,
39 char *buf)
40{ 42{
41 struct cpu *cpu = container_of(dev, struct cpu, dev); 43 struct cpu *cpu = container_of(dev, struct cpu, dev);
44 int cpuid = dev->id;
45 int from_nid, to_nid;
46 int ret;
47
48 cpu_hotplug_driver_lock();
42 49
43 return sprintf(buf, "%u\n", !!cpu_online(cpu->dev.id)); 50 from_nid = cpu_to_node(cpuid);
51 ret = cpu_up(cpuid);
52 /*
53 * When hot adding memory to memoryless node and enabling a cpu
54 * on the node, node number of the cpu may internally change.
55 */
56 to_nid = cpu_to_node(cpuid);
57 if (from_nid != to_nid)
58 change_cpu_under_node(cpu, from_nid, to_nid);
59
60 cpu_hotplug_driver_unlock();
61 return ret;
44} 62}
45 63
46static ssize_t __ref store_online(struct device *dev, 64static int cpu_subsys_offline(struct device *dev)
47 struct device_attribute *attr,
48 const char *buf, size_t count)
49{ 65{
50 struct cpu *cpu = container_of(dev, struct cpu, dev); 66 int ret;
51 int cpuid = cpu->dev.id;
52 int from_nid, to_nid;
53 ssize_t ret;
54 67
55 cpu_hotplug_driver_lock(); 68 cpu_hotplug_driver_lock();
56 switch (buf[0]) { 69 ret = cpu_down(dev->id);
57 case '0':
58 ret = cpu_down(cpuid);
59 if (!ret)
60 kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
61 break;
62 case '1':
63 from_nid = cpu_to_node(cpuid);
64 ret = cpu_up(cpuid);
65
66 /*
67 * When hot adding memory to memoryless node and enabling a cpu
68 * on the node, node number of the cpu may internally change.
69 */
70 to_nid = cpu_to_node(cpuid);
71 if (from_nid != to_nid)
72 change_cpu_under_node(cpu, from_nid, to_nid);
73
74 if (!ret)
75 kobject_uevent(&dev->kobj, KOBJ_ONLINE);
76 break;
77 default:
78 ret = -EINVAL;
79 }
80 cpu_hotplug_driver_unlock(); 70 cpu_hotplug_driver_unlock();
81
82 if (ret >= 0)
83 ret = count;
84 return ret; 71 return ret;
85} 72}
86static DEVICE_ATTR(online, 0644, show_online, store_online);
87
88static struct attribute *hotplug_cpu_attrs[] = {
89 &dev_attr_online.attr,
90 NULL
91};
92
93static struct attribute_group hotplug_cpu_attr_group = {
94 .attrs = hotplug_cpu_attrs,
95};
96 73
97void unregister_cpu(struct cpu *cpu) 74void unregister_cpu(struct cpu *cpu)
98{ 75{
@@ -127,6 +104,17 @@ static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
127#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ 104#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
128#endif /* CONFIG_HOTPLUG_CPU */ 105#endif /* CONFIG_HOTPLUG_CPU */
129 106
107struct bus_type cpu_subsys = {
108 .name = "cpu",
109 .dev_name = "cpu",
110 .match = cpu_subsys_match,
111#ifdef CONFIG_HOTPLUG_CPU
112 .online = cpu_subsys_online,
113 .offline = cpu_subsys_offline,
114#endif
115};
116EXPORT_SYMBOL_GPL(cpu_subsys);
117
130#ifdef CONFIG_KEXEC 118#ifdef CONFIG_KEXEC
131#include <linux/kexec.h> 119#include <linux/kexec.h>
132 120
@@ -185,9 +173,6 @@ static const struct attribute_group *hotplugable_cpu_attr_groups[] = {
185#ifdef CONFIG_KEXEC 173#ifdef CONFIG_KEXEC
186 &crash_note_cpu_attr_group, 174 &crash_note_cpu_attr_group,
187#endif 175#endif
188#ifdef CONFIG_HOTPLUG_CPU
189 &hotplug_cpu_attr_group,
190#endif
191 NULL 176 NULL
192}; 177};
193 178
@@ -302,6 +287,8 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
302 cpu->dev.id = num; 287 cpu->dev.id = num;
303 cpu->dev.bus = &cpu_subsys; 288 cpu->dev.bus = &cpu_subsys;
304 cpu->dev.release = cpu_device_release; 289 cpu->dev.release = cpu_device_release;
290 cpu->dev.offline_disabled = !cpu->hotpluggable;
291 cpu->dev.offline = !cpu_online(num);
305#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE 292#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
306 cpu->dev.bus->uevent = arch_cpu_uevent; 293 cpu->dev.bus->uevent = arch_cpu_uevent;
307#endif 294#endif
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index 08fe897c0b4c..6687ba741879 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -680,10 +680,7 @@ int dma_buf_debugfs_create_file(const char *name,
680 d = debugfs_create_file(name, S_IRUGO, dma_buf_debugfs_dir, 680 d = debugfs_create_file(name, S_IRUGO, dma_buf_debugfs_dir,
681 write, &dma_buf_debug_fops); 681 write, &dma_buf_debug_fops);
682 682
683 if (IS_ERR(d)) 683 return PTR_RET(d);
684 return PTR_ERR(d);
685
686 return 0;
687} 684}
688#else 685#else
689static inline int dma_buf_init_debugfs(void) 686static inline int dma_buf_init_debugfs(void)
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index e315051cfeeb..2b7813ec6d02 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -37,9 +37,14 @@ static inline int base_memory_block_id(int section_nr)
37 return section_nr / sections_per_block; 37 return section_nr / sections_per_block;
38} 38}
39 39
40static int memory_subsys_online(struct device *dev);
41static int memory_subsys_offline(struct device *dev);
42
40static struct bus_type memory_subsys = { 43static struct bus_type memory_subsys = {
41 .name = MEMORY_CLASS_NAME, 44 .name = MEMORY_CLASS_NAME,
42 .dev_name = MEMORY_CLASS_NAME, 45 .dev_name = MEMORY_CLASS_NAME,
46 .online = memory_subsys_online,
47 .offline = memory_subsys_offline,
43}; 48};
44 49
45static BLOCKING_NOTIFIER_HEAD(memory_chain); 50static BLOCKING_NOTIFIER_HEAD(memory_chain);
@@ -262,33 +267,64 @@ static int __memory_block_change_state(struct memory_block *mem,
262{ 267{
263 int ret = 0; 268 int ret = 0;
264 269
265 if (mem->state != from_state_req) { 270 if (mem->state != from_state_req)
266 ret = -EINVAL; 271 return -EINVAL;
267 goto out;
268 }
269 272
270 if (to_state == MEM_OFFLINE) 273 if (to_state == MEM_OFFLINE)
271 mem->state = MEM_GOING_OFFLINE; 274 mem->state = MEM_GOING_OFFLINE;
272 275
273 ret = memory_block_action(mem->start_section_nr, to_state, online_type); 276 ret = memory_block_action(mem->start_section_nr, to_state, online_type);
277 mem->state = ret ? from_state_req : to_state;
278 return ret;
279}
274 280
275 if (ret) { 281static int memory_subsys_online(struct device *dev)
276 mem->state = from_state_req; 282{
277 goto out; 283 struct memory_block *mem = container_of(dev, struct memory_block, dev);
278 } 284 int ret;
279 285
280 mem->state = to_state; 286 mutex_lock(&mem->state_mutex);
281 switch (mem->state) { 287
282 case MEM_OFFLINE: 288 ret = mem->state == MEM_ONLINE ? 0 :
283 kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE); 289 __memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE,
284 break; 290 ONLINE_KEEP);
285 case MEM_ONLINE: 291
286 kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE); 292 mutex_unlock(&mem->state_mutex);
287 break; 293 return ret;
288 default: 294}
289 break; 295
296static int memory_subsys_offline(struct device *dev)
297{
298 struct memory_block *mem = container_of(dev, struct memory_block, dev);
299 int ret;
300
301 mutex_lock(&mem->state_mutex);
302
303 ret = mem->state == MEM_OFFLINE ? 0 :
304 __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
305
306 mutex_unlock(&mem->state_mutex);
307 return ret;
308}
309
310static int __memory_block_change_state_uevent(struct memory_block *mem,
311 unsigned long to_state, unsigned long from_state_req,
312 int online_type)
313{
314 int ret = __memory_block_change_state(mem, to_state, from_state_req,
315 online_type);
316 if (!ret) {
317 switch (mem->state) {
318 case MEM_OFFLINE:
319 kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE);
320 break;
321 case MEM_ONLINE:
322 kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE);
323 break;
324 default:
325 break;
326 }
290 } 327 }
291out:
292 return ret; 328 return ret;
293} 329}
294 330
@@ -299,8 +335,8 @@ static int memory_block_change_state(struct memory_block *mem,
299 int ret; 335 int ret;
300 336
301 mutex_lock(&mem->state_mutex); 337 mutex_lock(&mem->state_mutex);
302 ret = __memory_block_change_state(mem, to_state, from_state_req, 338 ret = __memory_block_change_state_uevent(mem, to_state, from_state_req,
303 online_type); 339 online_type);
304 mutex_unlock(&mem->state_mutex); 340 mutex_unlock(&mem->state_mutex);
305 341
306 return ret; 342 return ret;
@@ -310,22 +346,34 @@ store_mem_state(struct device *dev,
310 struct device_attribute *attr, const char *buf, size_t count) 346 struct device_attribute *attr, const char *buf, size_t count)
311{ 347{
312 struct memory_block *mem; 348 struct memory_block *mem;
349 bool offline;
313 int ret = -EINVAL; 350 int ret = -EINVAL;
314 351
315 mem = container_of(dev, struct memory_block, dev); 352 mem = container_of(dev, struct memory_block, dev);
316 353
317 if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) 354 lock_device_hotplug();
355
356 if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) {
357 offline = false;
318 ret = memory_block_change_state(mem, MEM_ONLINE, 358 ret = memory_block_change_state(mem, MEM_ONLINE,
319 MEM_OFFLINE, ONLINE_KERNEL); 359 MEM_OFFLINE, ONLINE_KERNEL);
320 else if (!strncmp(buf, "online_movable", min_t(int, count, 14))) 360 } else if (!strncmp(buf, "online_movable", min_t(int, count, 14))) {
361 offline = false;
321 ret = memory_block_change_state(mem, MEM_ONLINE, 362 ret = memory_block_change_state(mem, MEM_ONLINE,
322 MEM_OFFLINE, ONLINE_MOVABLE); 363 MEM_OFFLINE, ONLINE_MOVABLE);
323 else if (!strncmp(buf, "online", min_t(int, count, 6))) 364 } else if (!strncmp(buf, "online", min_t(int, count, 6))) {
365 offline = false;
324 ret = memory_block_change_state(mem, MEM_ONLINE, 366 ret = memory_block_change_state(mem, MEM_ONLINE,
325 MEM_OFFLINE, ONLINE_KEEP); 367 MEM_OFFLINE, ONLINE_KEEP);
326 else if(!strncmp(buf, "offline", min_t(int, count, 7))) 368 } else if(!strncmp(buf, "offline", min_t(int, count, 7))) {
369 offline = true;
327 ret = memory_block_change_state(mem, MEM_OFFLINE, 370 ret = memory_block_change_state(mem, MEM_OFFLINE,
328 MEM_ONLINE, -1); 371 MEM_ONLINE, -1);
372 }
373 if (!ret)
374 dev->offline = offline;
375
376 unlock_device_hotplug();
329 377
330 if (ret) 378 if (ret)
331 return ret; 379 return ret;
@@ -523,6 +571,7 @@ int register_memory(struct memory_block *memory)
523 memory->dev.id = memory->start_section_nr / sections_per_block; 571 memory->dev.id = memory->start_section_nr / sections_per_block;
524 memory->dev.release = memory_block_release; 572 memory->dev.release = memory_block_release;
525 memory->dev.groups = memory_memblk_attr_groups; 573 memory->dev.groups = memory_memblk_attr_groups;
574 memory->dev.offline = memory->state == MEM_OFFLINE;
526 575
527 error = device_register(&memory->dev); 576 error = device_register(&memory->dev);
528 return error; 577 return error;
@@ -646,21 +695,6 @@ int unregister_memory_section(struct mem_section *section)
646} 695}
647#endif /* CONFIG_MEMORY_HOTREMOVE */ 696#endif /* CONFIG_MEMORY_HOTREMOVE */
648 697
649/*
650 * offline one memory block. If the memory block has been offlined, do nothing.
651 */
652int offline_memory_block(struct memory_block *mem)
653{
654 int ret = 0;
655
656 mutex_lock(&mem->state_mutex);
657 if (mem->state != MEM_OFFLINE)
658 ret = __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
659 mutex_unlock(&mem->state_mutex);
660
661 return ret;
662}
663
664/* return true if the memory block is offlined, otherwise, return false */ 698/* return true if the memory block is offlined, otherwise, return false */
665bool is_memblock_offlined(struct memory_block *mem) 699bool is_memblock_offlined(struct memory_block *mem)
666{ 700{
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index ed75cf6ef9c9..15789875128e 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -29,9 +29,6 @@
29/* For automatically allocated device IDs */ 29/* For automatically allocated device IDs */
30static DEFINE_IDA(platform_devid_ida); 30static DEFINE_IDA(platform_devid_ida);
31 31
32#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \
33 driver))
34
35struct device platform_bus = { 32struct device platform_bus = {
36 .init_name = "platform", 33 .init_name = "platform",
37}; 34};
@@ -890,7 +887,6 @@ int platform_pm_restore(struct device *dev)
890static const struct dev_pm_ops platform_dev_pm_ops = { 887static const struct dev_pm_ops platform_dev_pm_ops = {
891 .runtime_suspend = pm_generic_runtime_suspend, 888 .runtime_suspend = pm_generic_runtime_suspend,
892 .runtime_resume = pm_generic_runtime_resume, 889 .runtime_resume = pm_generic_runtime_resume,
893 .runtime_idle = pm_generic_runtime_idle,
894 USE_PLATFORM_PM_SLEEP_OPS 890 USE_PLATFORM_PM_SLEEP_OPS
895}; 891};
896 892
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 7072404c8b6d..bfb8955c406c 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -2143,7 +2143,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
2143 genpd->max_off_time_changed = true; 2143 genpd->max_off_time_changed = true;
2144 genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend; 2144 genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
2145 genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume; 2145 genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
2146 genpd->domain.ops.runtime_idle = pm_generic_runtime_idle;
2147 genpd->domain.ops.prepare = pm_genpd_prepare; 2146 genpd->domain.ops.prepare = pm_genpd_prepare;
2148 genpd->domain.ops.suspend = pm_genpd_suspend; 2147 genpd->domain.ops.suspend = pm_genpd_suspend;
2149 genpd->domain.ops.suspend_late = pm_genpd_suspend_late; 2148 genpd->domain.ops.suspend_late = pm_genpd_suspend_late;
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
index bfd898b8988e..5ee030a864f9 100644
--- a/drivers/base/power/generic_ops.c
+++ b/drivers/base/power/generic_ops.c
@@ -12,29 +12,6 @@
12 12
13#ifdef CONFIG_PM_RUNTIME 13#ifdef CONFIG_PM_RUNTIME
14/** 14/**
15 * pm_generic_runtime_idle - Generic runtime idle callback for subsystems.
16 * @dev: Device to handle.
17 *
18 * If PM operations are defined for the @dev's driver and they include
19 * ->runtime_idle(), execute it and return its error code, if nonzero.
20 * Otherwise, execute pm_runtime_suspend() for the device and return 0.
21 */
22int pm_generic_runtime_idle(struct device *dev)
23{
24 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
25
26 if (pm && pm->runtime_idle) {
27 int ret = pm->runtime_idle(dev);
28 if (ret)
29 return ret;
30 }
31
32 pm_runtime_suspend(dev);
33 return 0;
34}
35EXPORT_SYMBOL_GPL(pm_generic_runtime_idle);
36
37/**
38 * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. 15 * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems.
39 * @dev: Device to suspend. 16 * @dev: Device to suspend.
40 * 17 *
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index f0077cb8e249..c8ec186303db 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -648,14 +648,14 @@ int opp_init_cpufreq_table(struct device *dev,
648 648
649 list_for_each_entry(opp, &dev_opp->opp_list, node) { 649 list_for_each_entry(opp, &dev_opp->opp_list, node) {
650 if (opp->available) { 650 if (opp->available) {
651 freq_table[i].index = i; 651 freq_table[i].driver_data = i;
652 freq_table[i].frequency = opp->rate / 1000; 652 freq_table[i].frequency = opp->rate / 1000;
653 i++; 653 i++;
654 } 654 }
655 } 655 }
656 mutex_unlock(&dev_opp_list_lock); 656 mutex_unlock(&dev_opp_list_lock);
657 657
658 freq_table[i].index = i; 658 freq_table[i].driver_data = i;
659 freq_table[i].frequency = CPUFREQ_TABLE_END; 659 freq_table[i].frequency = CPUFREQ_TABLE_END;
660 660
661 *table = &freq_table[0]; 661 *table = &freq_table[0];
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index 71671c42ef45..5c1361a9e5dd 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -42,6 +42,7 @@
42#include <linux/export.h> 42#include <linux/export.h>
43#include <linux/pm_runtime.h> 43#include <linux/pm_runtime.h>
44#include <linux/err.h> 44#include <linux/err.h>
45#include <trace/events/power.h>
45 46
46#include "power.h" 47#include "power.h"
47 48
@@ -305,6 +306,7 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
305 else if (!dev->power.qos) 306 else if (!dev->power.qos)
306 ret = dev_pm_qos_constraints_allocate(dev); 307 ret = dev_pm_qos_constraints_allocate(dev);
307 308
309 trace_dev_pm_qos_add_request(dev_name(dev), type, value);
308 if (!ret) { 310 if (!ret) {
309 req->dev = dev; 311 req->dev = dev;
310 req->type = type; 312 req->type = type;
@@ -349,6 +351,8 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req,
349 return -EINVAL; 351 return -EINVAL;
350 } 352 }
351 353
354 trace_dev_pm_qos_update_request(dev_name(req->dev), req->type,
355 new_value);
352 if (curr_value != new_value) 356 if (curr_value != new_value)
353 ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value); 357 ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value);
354 358
@@ -398,6 +402,8 @@ static int __dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
398 if (IS_ERR_OR_NULL(req->dev->power.qos)) 402 if (IS_ERR_OR_NULL(req->dev->power.qos))
399 return -ENODEV; 403 return -ENODEV;
400 404
405 trace_dev_pm_qos_remove_request(dev_name(req->dev), req->type,
406 PM_QOS_DEFAULT_VALUE);
401 ret = apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); 407 ret = apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
402 memset(req, 0, sizeof(*req)); 408 memset(req, 0, sizeof(*req));
403 return ret; 409 return ret;
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index ef13ad08afb2..268a35097578 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -293,11 +293,8 @@ static int rpm_idle(struct device *dev, int rpmflags)
293 /* Pending requests need to be canceled. */ 293 /* Pending requests need to be canceled. */
294 dev->power.request = RPM_REQ_NONE; 294 dev->power.request = RPM_REQ_NONE;
295 295
296 if (dev->power.no_callbacks) { 296 if (dev->power.no_callbacks)
297 /* Assume ->runtime_idle() callback would have suspended. */
298 retval = rpm_suspend(dev, rpmflags);
299 goto out; 297 goto out;
300 }
301 298
302 /* Carry out an asynchronous or a synchronous idle notification. */ 299 /* Carry out an asynchronous or a synchronous idle notification. */
303 if (rpmflags & RPM_ASYNC) { 300 if (rpmflags & RPM_ASYNC) {
@@ -306,7 +303,8 @@ static int rpm_idle(struct device *dev, int rpmflags)
306 dev->power.request_pending = true; 303 dev->power.request_pending = true;
307 queue_work(pm_wq, &dev->power.work); 304 queue_work(pm_wq, &dev->power.work);
308 } 305 }
309 goto out; 306 trace_rpm_return_int(dev, _THIS_IP_, 0);
307 return 0;
310 } 308 }
311 309
312 dev->power.idle_notification = true; 310 dev->power.idle_notification = true;
@@ -326,14 +324,14 @@ static int rpm_idle(struct device *dev, int rpmflags)
326 callback = dev->driver->pm->runtime_idle; 324 callback = dev->driver->pm->runtime_idle;
327 325
328 if (callback) 326 if (callback)
329 __rpm_callback(callback, dev); 327 retval = __rpm_callback(callback, dev);
330 328
331 dev->power.idle_notification = false; 329 dev->power.idle_notification = false;
332 wake_up_all(&dev->power.wait_queue); 330 wake_up_all(&dev->power.wait_queue);
333 331
334 out: 332 out:
335 trace_rpm_return_int(dev, _THIS_IP_, retval); 333 trace_rpm_return_int(dev, _THIS_IP_, retval);
336 return retval; 334 return retval ? retval : rpm_suspend(dev, rpmflags);
337} 335}
338 336
339/** 337/**
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index 79715e7fa43e..2d56f4113ae7 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -659,7 +659,7 @@ void pm_wakeup_event(struct device *dev, unsigned int msec)
659} 659}
660EXPORT_SYMBOL_GPL(pm_wakeup_event); 660EXPORT_SYMBOL_GPL(pm_wakeup_event);
661 661
662static void print_active_wakeup_sources(void) 662void pm_print_active_wakeup_sources(void)
663{ 663{
664 struct wakeup_source *ws; 664 struct wakeup_source *ws;
665 int active = 0; 665 int active = 0;
@@ -683,6 +683,7 @@ static void print_active_wakeup_sources(void)
683 last_activity_ws->name); 683 last_activity_ws->name);
684 rcu_read_unlock(); 684 rcu_read_unlock();
685} 685}
686EXPORT_SYMBOL_GPL(pm_print_active_wakeup_sources);
686 687
687/** 688/**
688 * pm_wakeup_pending - Check if power transition in progress should be aborted. 689 * pm_wakeup_pending - Check if power transition in progress should be aborted.
@@ -707,8 +708,10 @@ bool pm_wakeup_pending(void)
707 } 708 }
708 spin_unlock_irqrestore(&events_lock, flags); 709 spin_unlock_irqrestore(&events_lock, flags);
709 710
710 if (ret) 711 if (ret) {
711 print_active_wakeup_sources(); 712 pr_info("PM: Wakeup pending, aborting suspend\n");
713 pm_print_active_wakeup_sources();
714 }
712 715
713 return ret; 716 return ret;
714} 717}
diff --git a/drivers/base/reservation.c b/drivers/base/reservation.c
new file mode 100644
index 000000000000..a73fbf3b8e56
--- /dev/null
+++ b/drivers/base/reservation.c
@@ -0,0 +1,39 @@
1/*
2 * Copyright (C) 2012-2013 Canonical Ltd
3 *
4 * Based on bo.c which bears the following copyright notice,
5 * but is dual licensed:
6 *
7 * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
8 * All Rights Reserved.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the
12 * "Software"), to deal in the Software without restriction, including
13 * without limitation the rights to use, copy, modify, merge, publish,
14 * distribute, sub license, and/or sell copies of the Software, and to
15 * permit persons to whom the Software is furnished to do so, subject to
16 * the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the
19 * next paragraph) shall be included in all copies or substantial portions
20 * of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
25 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
26 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
27 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
28 * USE OR OTHER DEALINGS IN THE SOFTWARE.
29 *
30 **************************************************************************/
31/*
32 * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
33 */
34
35#include <linux/reservation.h>
36#include <linux/export.h>
37
38DEFINE_WW_CLASS(reservation_ww_class);
39EXPORT_SYMBOL(reservation_ww_class);