diff options
| -rw-r--r-- | Documentation/filesystems/sysfs-pci.txt | 6 | ||||
| -rw-r--r-- | Documentation/power/devices.txt | 21 | ||||
| -rw-r--r-- | Documentation/powerpc/hvcs.txt | 4 | ||||
| -rw-r--r-- | drivers/base/Makefile | 2 | ||||
| -rw-r--r-- | drivers/base/bus.c | 1 | ||||
| -rw-r--r-- | drivers/base/core.c | 3 | ||||
| -rw-r--r-- | drivers/base/interface.c | 51 | ||||
| -rw-r--r-- | drivers/base/power/power.h | 11 | ||||
| -rw-r--r-- | drivers/base/power/resume.c | 11 | ||||
| -rw-r--r-- | drivers/base/power/shutdown.c | 23 | ||||
| -rw-r--r-- | drivers/base/power/suspend.c | 17 | ||||
| -rw-r--r-- | include/linux/device.h | 3 | ||||
| -rw-r--r-- | kernel/power/main.c | 6 |
13 files changed, 37 insertions, 122 deletions
diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt index e97d024eae77..988a62fae11f 100644 --- a/Documentation/filesystems/sysfs-pci.txt +++ b/Documentation/filesystems/sysfs-pci.txt | |||
| @@ -7,7 +7,6 @@ that support it. For example, a given bus might look like this: | |||
| 7 | |-- 0000:17:00.0 | 7 | |-- 0000:17:00.0 |
| 8 | | |-- class | 8 | | |-- class |
| 9 | | |-- config | 9 | | |-- config |
| 10 | | |-- detach_state | ||
| 11 | | |-- device | 10 | | |-- device |
| 12 | | |-- irq | 11 | | |-- irq |
| 13 | | |-- local_cpus | 12 | | |-- local_cpus |
| @@ -19,7 +18,7 @@ that support it. For example, a given bus might look like this: | |||
| 19 | | |-- subsystem_device | 18 | | |-- subsystem_device |
| 20 | | |-- subsystem_vendor | 19 | | |-- subsystem_vendor |
| 21 | | `-- vendor | 20 | | `-- vendor |
| 22 | `-- detach_state | 21 | `-- ... |
| 23 | 22 | ||
| 24 | The topmost element describes the PCI domain and bus number. In this case, | 23 | The topmost element describes the PCI domain and bus number. In this case, |
| 25 | the domain number is 0000 and the bus number is 17 (both values are in hex). | 24 | the domain number is 0000 and the bus number is 17 (both values are in hex). |
| @@ -31,7 +30,6 @@ files, each with their own function. | |||
| 31 | ---- -------- | 30 | ---- -------- |
| 32 | class PCI class (ascii, ro) | 31 | class PCI class (ascii, ro) |
| 33 | config PCI config space (binary, rw) | 32 | config PCI config space (binary, rw) |
| 34 | detach_state connection status (bool, rw) | ||
| 35 | device PCI device (ascii, ro) | 33 | device PCI device (ascii, ro) |
| 36 | irq IRQ number (ascii, ro) | 34 | irq IRQ number (ascii, ro) |
| 37 | local_cpus nearby CPU mask (cpumask, ro) | 35 | local_cpus nearby CPU mask (cpumask, ro) |
| @@ -85,4 +83,4 @@ useful return codes should be provided. | |||
| 85 | 83 | ||
| 86 | Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms | 84 | Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms |
| 87 | wishing to support legacy functionality should define it and provide | 85 | wishing to support legacy functionality should define it and provide |
| 88 | pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions. \ No newline at end of file | 86 | pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions. |
diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index 5d4ae9a39f1d..f987afe43e28 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt | |||
| @@ -207,27 +207,6 @@ SYSTEM_SHUTDOWN, I do not understand this one too much. probably event | |||
| 207 | #READY_AFTER_RESUME | 207 | #READY_AFTER_RESUME |
| 208 | # | 208 | # |
| 209 | 209 | ||
| 210 | Driver Detach Power Management | ||
| 211 | |||
| 212 | The kernel now supports the ability to place a device in a low-power | ||
| 213 | state when it is detached from its driver, which happens when its | ||
| 214 | module is removed. | ||
| 215 | |||
| 216 | Each device contains a 'detach_state' file in its sysfs directory | ||
| 217 | which can be used to control this state. Reading from this file | ||
| 218 | displays what the current detach state is set to. This is 0 (On) by | ||
| 219 | default. A user may write a positive integer value to this file in the | ||
| 220 | range of 1-4 inclusive. | ||
| 221 | |||
| 222 | A value of 1-3 will indicate the device should be placed in that | ||
| 223 | low-power state, which will cause ->suspend() to be called for that | ||
| 224 | device. A value of 4 indicates that the device should be shutdown, so | ||
| 225 | ->shutdown() will be called for that device. | ||
| 226 | |||
| 227 | The driver is responsible for reinitializing the device when the | ||
| 228 | module is re-inserted during it's ->probe() (or equivalent) method. | ||
| 229 | The driver core will not call any extra functions when binding the | ||
| 230 | device to the driver. | ||
| 231 | 210 | ||
| 232 | pm_message_t meaning | 211 | pm_message_t meaning |
| 233 | 212 | ||
diff --git a/Documentation/powerpc/hvcs.txt b/Documentation/powerpc/hvcs.txt index c0a62e116e6e..dca75cbda6f8 100644 --- a/Documentation/powerpc/hvcs.txt +++ b/Documentation/powerpc/hvcs.txt | |||
| @@ -347,8 +347,8 @@ address that is created by firmware. An example vty-server sysfs entry | |||
| 347 | looks like the following: | 347 | looks like the following: |
| 348 | 348 | ||
| 349 | Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls | 349 | Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls |
| 350 | . current_vty devspec name partner_vtys | 350 | . current_vty devspec name partner_vtys |
| 351 | .. detach_state index partner_clcs vterm_state | 351 | .. index partner_clcs vterm_state |
| 352 | 352 | ||
| 353 | Each entry is provided, by default with a "name" attribute. Reading the | 353 | Each entry is provided, by default with a "name" attribute. Reading the |
| 354 | "name" attribute will reveal the device type as shown in the following | 354 | "name" attribute will reveal the device type as shown in the following |
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 | ||
| 3 | obj-y := core.o sys.o interface.o bus.o \ | 3 | obj-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..d21eb7744496 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 | ||
| 34 | extern struct attribute * dev_default_attrs[]; | ||
| 35 | |||
| 36 | static ssize_t | 34 | static ssize_t |
| 37 | dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | 35 | dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) |
| 38 | { | 36 | { |
| @@ -89,7 +87,6 @@ static void device_release(struct kobject * kobj) | |||
| 89 | static struct kobj_type ktype_device = { | 87 | static 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 | ||
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 | |||
| 30 | static ssize_t detach_show(struct device * dev, char * buf) | ||
| 31 | { | ||
| 32 | return sprintf(buf, "%u\n", dev->detach_state); | ||
| 33 | } | ||
| 34 | |||
| 35 | static 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 | |||
| 45 | static DEVICE_ATTR(detach_state, 0644, detach_show, detach_store); | ||
| 46 | |||
| 47 | |||
| 48 | struct 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 | |||
| 3 | enum { | ||
| 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 | ||
| 15 | extern int device_detach_shutdown(struct device *); | ||
| 16 | extern void device_shutdown(void); | 5 | extern 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 | ||
| 23 | int resume_device(struct device * dev) | 23 | int 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 @@ | |||
| 19 | extern struct subsystem devices_subsys; | 19 | extern struct subsystem devices_subsys; |
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | int 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 | } |
diff --git a/include/linux/device.h b/include/linux/device.h index cf470459fa69..df94c0de53f2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
| @@ -273,9 +273,6 @@ struct device { | |||
| 273 | BIOS data relevant to device) */ | 273 | BIOS data relevant to device) */ |
| 274 | struct dev_pm_info power; | 274 | struct dev_pm_info power; |
| 275 | 275 | ||
| 276 | u32 detach_state; /* State to enter when device is | ||
| 277 | detached from its driver. */ | ||
| 278 | |||
| 279 | u64 *dma_mask; /* dma mask (if dma'able device) */ | 276 | u64 *dma_mask; /* dma mask (if dma'able device) */ |
| 280 | u64 coherent_dma_mask;/* Like dma_mask, but for | 277 | u64 coherent_dma_mask;/* Like dma_mask, but for |
| 281 | alloc_coherent mappings as | 278 | alloc_coherent mappings as |
diff --git a/kernel/power/main.c b/kernel/power/main.c index 7960ddf04a57..4cdebc972ff2 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
| @@ -156,14 +156,14 @@ static int enter_state(suspend_state_t state) | |||
| 156 | goto Unlock; | 156 | goto Unlock; |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | pr_debug("PM: Preparing system for suspend\n"); | 159 | pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); |
| 160 | if ((error = suspend_prepare(state))) | 160 | if ((error = suspend_prepare(state))) |
| 161 | goto Unlock; | 161 | goto Unlock; |
| 162 | 162 | ||
| 163 | pr_debug("PM: Entering state.\n"); | 163 | pr_debug("PM: Entering %s sleep\n", pm_states[state]); |
| 164 | error = suspend_enter(state); | 164 | error = suspend_enter(state); |
| 165 | 165 | ||
| 166 | pr_debug("PM: Finishing up.\n"); | 166 | pr_debug("PM: Finishing wakeup.\n"); |
| 167 | suspend_finish(state); | 167 | suspend_finish(state); |
| 168 | Unlock: | 168 | Unlock: |
| 169 | up(&pm_sem); | 169 | up(&pm_sem); |
