aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/Makefile2
-rw-r--r--drivers/base/bus.c1
-rw-r--r--drivers/base/core.c7
-rw-r--r--drivers/base/interface.c51
-rw-r--r--drivers/base/power/power.h11
-rw-r--r--drivers/base/power/resume.c11
-rw-r--r--drivers/base/power/shutdown.c23
-rw-r--r--drivers/base/power/suspend.c17
8 files changed, 32 insertions, 91 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 6662b545e0a9..a47928a2e575 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -1,6 +1,6 @@
1# Makefile for the Linux device tree 1# Makefile for the Linux device tree
2 2
3obj-y := core.o sys.o interface.o bus.o \ 3obj-y := core.o sys.o bus.o \
4 driver.o class.o class_simple.o platform.o \ 4 driver.o class.o class_simple.o platform.o \
5 cpu.o firmware.o init.o map.o dmapool.o \ 5 cpu.o firmware.o init.o map.o dmapool.o \
6 attribute_container.o transport_class.o 6 attribute_container.o transport_class.o
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 2b3902c867da..3cb04bb04c2b 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -390,7 +390,6 @@ void device_release_driver(struct device * dev)
390 sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); 390 sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
391 sysfs_remove_link(&dev->kobj, "driver"); 391 sysfs_remove_link(&dev->kobj, "driver");
392 list_del_init(&dev->driver_list); 392 list_del_init(&dev->driver_list);
393 device_detach_shutdown(dev);
394 if (drv->remove) 393 if (drv->remove)
395 drv->remove(dev); 394 drv->remove(dev);
396 dev->driver = NULL; 395 dev->driver = NULL;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 268a9c8d168b..fbc223486f81 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -31,8 +31,6 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
31#define to_dev(obj) container_of(obj, struct device, kobj) 31#define to_dev(obj) container_of(obj, struct device, kobj)
32#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) 32#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
33 33
34extern struct attribute * dev_default_attrs[];
35
36static ssize_t 34static ssize_t
37dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) 35dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
38{ 36{
@@ -89,7 +87,6 @@ static void device_release(struct kobject * kobj)
89static struct kobj_type ktype_device = { 87static struct kobj_type ktype_device = {
90 .release = device_release, 88 .release = device_release,
91 .sysfs_ops = &dev_sysfs_ops, 89 .sysfs_ops = &dev_sysfs_ops,
92 .default_attrs = dev_default_attrs,
93}; 90};
94 91
95 92
@@ -248,6 +245,7 @@ int device_add(struct device *dev)
248 245
249 if ((error = kobject_add(&dev->kobj))) 246 if ((error = kobject_add(&dev->kobj)))
250 goto Error; 247 goto Error;
248 kobject_hotplug(&dev->kobj, KOBJ_ADD);
251 if ((error = device_pm_add(dev))) 249 if ((error = device_pm_add(dev)))
252 goto PMError; 250 goto PMError;
253 if ((error = bus_add_device(dev))) 251 if ((error = bus_add_device(dev)))
@@ -260,14 +258,13 @@ int device_add(struct device *dev)
260 /* notify platform of device entry */ 258 /* notify platform of device entry */
261 if (platform_notify) 259 if (platform_notify)
262 platform_notify(dev); 260 platform_notify(dev);
263
264 kobject_hotplug(&dev->kobj, KOBJ_ADD);
265 Done: 261 Done:
266 put_device(dev); 262 put_device(dev);
267 return error; 263 return error;
268 BusError: 264 BusError:
269 device_pm_remove(dev); 265 device_pm_remove(dev);
270 PMError: 266 PMError:
267 kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
271 kobject_del(&dev->kobj); 268 kobject_del(&dev->kobj);
272 Error: 269 Error:
273 if (parent) 270 if (parent)
diff --git a/drivers/base/interface.c b/drivers/base/interface.c
deleted file mode 100644
index bd515843a0cb..000000000000
--- a/drivers/base/interface.c
+++ /dev/null
@@ -1,51 +0,0 @@
1/*
2 * drivers/base/interface.c - common driverfs interface that's exported to
3 * the world for all devices.
4 *
5 * Copyright (c) 2002-3 Patrick Mochel
6 * Copyright (c) 2002-3 Open Source Development Labs
7 *
8 * This file is released under the GPLv2
9 *
10 */
11
12#include <linux/device.h>
13#include <linux/err.h>
14#include <linux/stat.h>
15#include <linux/string.h>
16
17/**
18 * detach_state - control the default power state for the device.
19 *
20 * This is the state the device enters when it's driver module is
21 * unloaded. The value is an unsigned integer, in the range of 0-4.
22 * '0' indicates 'On', so no action will be taken when the driver is
23 * unloaded. This is the default behavior.
24 * '4' indicates 'Off', meaning the driver core will call the driver's
25 * shutdown method to quiesce the device.
26 * 1-3 indicate a low-power state for the device to enter via the
27 * driver's suspend method.
28 */
29
30static ssize_t detach_show(struct device * dev, char * buf)
31{
32 return sprintf(buf, "%u\n", dev->detach_state);
33}
34
35static ssize_t detach_store(struct device * dev, const char * buf, size_t n)
36{
37 u32 state;
38 state = simple_strtoul(buf, NULL, 10);
39 if (state > 4)
40 return -EINVAL;
41 dev->detach_state = state;
42 return n;
43}
44
45static DEVICE_ATTR(detach_state, 0644, detach_show, detach_store);
46
47
48struct attribute * dev_default_attrs[] = {
49 &dev_attr_detach_state.attr,
50 NULL,
51};
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index e5eda746f2a6..2e700d795cf1 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -1,18 +1,7 @@
1
2
3enum {
4 DEVICE_PM_ON,
5 DEVICE_PM1,
6 DEVICE_PM2,
7 DEVICE_PM3,
8 DEVICE_PM_OFF,
9};
10
11/* 1/*
12 * shutdown.c 2 * shutdown.c
13 */ 3 */
14 4
15extern int device_detach_shutdown(struct device *);
16extern void device_shutdown(void); 5extern void device_shutdown(void);
17 6
18 7
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index f8f5055754d6..26468971ef5a 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -22,8 +22,17 @@ extern int sysdev_resume(void);
22 22
23int resume_device(struct device * dev) 23int resume_device(struct device * dev)
24{ 24{
25 if (dev->bus && dev->bus->resume) 25 if (dev->power.pm_parent
26 && dev->power.pm_parent->power.power_state) {
27 dev_err(dev, "PM: resume from %d, parent %s still %d\n",
28 dev->power.power_state,
29 dev->power.pm_parent->bus_id,
30 dev->power.pm_parent->power.power_state);
31 }
32 if (dev->bus && dev->bus->resume) {
33 dev_dbg(dev,"resuming\n");
26 return dev->bus->resume(dev); 34 return dev->bus->resume(dev);
35 }
27 return 0; 36 return 0;
28} 37}
29 38
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c
index d1e023fbe169..f50a08be424b 100644
--- a/drivers/base/power/shutdown.c
+++ b/drivers/base/power/shutdown.c
@@ -19,20 +19,6 @@
19extern struct subsystem devices_subsys; 19extern struct subsystem devices_subsys;
20 20
21 21
22int device_detach_shutdown(struct device * dev)
23{
24 if (!dev->detach_state)
25 return 0;
26
27 if (dev->detach_state == DEVICE_PM_OFF) {
28 if (dev->driver && dev->driver->shutdown)
29 dev->driver->shutdown(dev);
30 return 0;
31 }
32 return dpm_runtime_suspend(dev, dev->detach_state);
33}
34
35
36/** 22/**
37 * We handle system devices differently - we suspend and shut them 23 * We handle system devices differently - we suspend and shut them
38 * down last and resume them first. That way, we don't do anything stupid like 24 * down last and resume them first. That way, we don't do anything stupid like
@@ -52,13 +38,12 @@ void device_shutdown(void)
52 struct device * dev; 38 struct device * dev;
53 39
54 down_write(&devices_subsys.rwsem); 40 down_write(&devices_subsys.rwsem);
55 list_for_each_entry_reverse(dev, &devices_subsys.kset.list, kobj.entry) { 41 list_for_each_entry_reverse(dev, &devices_subsys.kset.list,
56 pr_debug("shutting down %s: ", dev->bus_id); 42 kobj.entry) {
57 if (dev->driver && dev->driver->shutdown) { 43 if (dev->driver && dev->driver->shutdown) {
58 pr_debug("Ok\n"); 44 dev_dbg(dev, "shutdown\n");
59 dev->driver->shutdown(dev); 45 dev->driver->shutdown(dev);
60 } else 46 }
61 pr_debug("Ignored.\n");
62 } 47 }
63 up_write(&devices_subsys.rwsem); 48 up_write(&devices_subsys.rwsem);
64 49
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index a0b5cf689e63..0ec44ef840be 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -39,12 +39,25 @@ int suspend_device(struct device * dev, pm_message_t state)
39{ 39{
40 int error = 0; 40 int error = 0;
41 41
42 dev_dbg(dev, "suspending\n"); 42 if (dev->power.power_state) {
43 dev_dbg(dev, "PM: suspend %d-->%d\n",
44 dev->power.power_state, state);
45 }
46 if (dev->power.pm_parent
47 && dev->power.pm_parent->power.power_state) {
48 dev_err(dev,
49 "PM: suspend %d->%d, parent %s already %d\n",
50 dev->power.power_state, state,
51 dev->power.pm_parent->bus_id,
52 dev->power.pm_parent->power.power_state);
53 }
43 54
44 dev->power.prev_state = dev->power.power_state; 55 dev->power.prev_state = dev->power.power_state;
45 56
46 if (dev->bus && dev->bus->suspend && !dev->power.power_state) 57 if (dev->bus && dev->bus->suspend && !dev->power.power_state) {
58 dev_dbg(dev, "suspending\n");
47 error = dev->bus->suspend(dev, state); 59 error = dev->bus->suspend(dev, state);
60 }
48 61
49 return error; 62 return error;
50} 63}