From 6b6e39a6a8da7234c538d14c43d3583da8875f9c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 15 Nov 2010 23:13:18 +0100 Subject: driver-core: merge private parts of class and bus As classes and busses are pretty much the same thing, and we want to merge them together into a 'subsystem' in the future, let us share the same private data parts to make that merge easier. Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index dd4895313468..1e2d335ab683 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -30,9 +30,8 @@ struct device_private; struct device_driver; struct driver_private; struct class; -struct class_private; +struct subsys_private; struct bus_type; -struct bus_type_private; struct device_node; struct bus_attribute { @@ -65,7 +64,7 @@ struct bus_type { const struct dev_pm_ops *pm; - struct bus_type_private *p; + struct subsys_private *p; }; extern int __must_check bus_register(struct bus_type *bus); @@ -213,7 +212,7 @@ struct class { const struct dev_pm_ops *pm; - struct class_private *p; + struct subsys_private *p; }; struct class_dev_iter { -- cgit v1.2.3 From b8c76f6aed0ab7df73a6410f3f82de2c831bb144 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 16 Dec 2010 00:51:21 +0100 Subject: PM: Replace the device power.status field with a bit field The device power.status field is too complicated for its purpose (storing the information about whether or not the device is in the "active" state from the PM core's point of view), so replace it with a bit field and modify all of its users accordingly. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 17 +++++------------ drivers/usb/core/driver.c | 7 +++---- include/linux/device.h | 4 ++-- include/linux/pm.h | 43 ++----------------------------------------- 4 files changed, 12 insertions(+), 59 deletions(-) (limited to 'include/linux/device.h') diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index bb5c8cb64174..a90480baa850 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -63,7 +63,7 @@ static int async_error; */ void device_pm_init(struct device *dev) { - dev->power.status = DPM_ON; + dev->power.in_suspend = false; init_completion(&dev->power.completion); complete_all(&dev->power.completion); dev->power.wakeup = NULL; @@ -98,7 +98,7 @@ void device_pm_add(struct device *dev) kobject_name(&dev->kobj)); mutex_lock(&dpm_list_mtx); if (dev->parent) { - if (dev->parent->power.status >= DPM_SUSPENDING) + if (dev->parent->power.in_suspend) dev_warn(dev, "parent %s should not be sleeping\n", dev_name(dev->parent)); } else if (transition_started) { @@ -488,7 +488,6 @@ void dpm_resume_noirq(pm_message_t state) int error; get_device(dev); - dev->power.status = DPM_OFF; list_move_tail(&dev->power.entry, &dpm_suspended_list); mutex_unlock(&dpm_list_mtx); @@ -541,7 +540,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) dpm_wait(dev->parent, async); device_lock(dev); - dev->power.status = DPM_RESUMING; + dev->power.in_suspend = false; if (dev->bus) { if (dev->bus->pm) { @@ -690,7 +689,7 @@ static void dpm_complete(pm_message_t state) struct device *dev = to_device(dpm_prepared_list.prev); get_device(dev); - dev->power.status = DPM_ON; + dev->power.in_suspend = false; list_move(&dev->power.entry, &list); mutex_unlock(&dpm_list_mtx); @@ -806,7 +805,6 @@ int dpm_suspend_noirq(pm_message_t state) put_device(dev); break; } - dev->power.status = DPM_OFF_IRQ; if (!list_empty(&dev->power.entry)) list_move(&dev->power.entry, &dpm_noirq_list); put_device(dev); @@ -894,9 +892,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) } } - if (!error) - dev->power.status = DPM_OFF; - End: device_unlock(dev); complete_all(&dev->power.completion); @@ -1030,7 +1025,6 @@ static int dpm_prepare(pm_message_t state) struct device *dev = to_device(dpm_list.next); get_device(dev); - dev->power.status = DPM_PREPARING; mutex_unlock(&dpm_list_mtx); pm_runtime_get_noresume(dev); @@ -1046,7 +1040,6 @@ static int dpm_prepare(pm_message_t state) mutex_lock(&dpm_list_mtx); if (error) { - dev->power.status = DPM_ON; if (error == -EAGAIN) { put_device(dev); error = 0; @@ -1058,7 +1051,7 @@ static int dpm_prepare(pm_message_t state) put_device(dev); break; } - dev->power.status = DPM_SUSPENDING; + dev->power.in_suspend = true; if (!list_empty(&dev->power.entry)) list_move_tail(&dev->power.entry, &dpm_prepared_list); put_device(dev); diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index c0e60fbcb048..4ec50224ee86 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -376,7 +376,7 @@ static int usb_unbind_interface(struct device *dev) * Just re-enable it without affecting the endpoint toggles. */ usb_enable_interface(udev, intf, false); - } else if (!error && intf->dev.power.status == DPM_ON) { + } else if (!error && !intf->dev.power.in_suspend) { r = usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); if (r < 0) @@ -961,7 +961,7 @@ void usb_rebind_intf(struct usb_interface *intf) } /* Try to rebind the interface */ - if (intf->dev.power.status == DPM_ON) { + if (!intf->dev.power.in_suspend) { intf->needs_binding = 0; rc = device_attach(&intf->dev); if (rc < 0) @@ -1108,8 +1108,7 @@ static int usb_resume_interface(struct usb_device *udev, if (intf->condition == USB_INTERFACE_UNBOUND) { /* Carry out a deferred switch to altsetting 0 */ - if (intf->needs_altsetting0 && - intf->dev.power.status == DPM_ON) { + if (intf->needs_altsetting0 && !intf->dev.power.in_suspend) { usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); intf->needs_altsetting0 = 0; diff --git a/include/linux/device.h b/include/linux/device.h index dd4895313468..45bc8c1669d2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -508,13 +508,13 @@ static inline int device_is_registered(struct device *dev) static inline void device_enable_async_suspend(struct device *dev) { - if (dev->power.status == DPM_ON) + if (!dev->power.in_suspend) dev->power.async_suspend = true; } static inline void device_disable_async_suspend(struct device *dev) { - if (dev->power.status == DPM_ON) + if (!dev->power.in_suspend) dev->power.async_suspend = false; } diff --git a/include/linux/pm.h b/include/linux/pm.h index 61f2066e6852..c1756dfeb8c5 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -366,45 +366,6 @@ extern struct dev_pm_ops generic_subsys_pm_ops; #define PMSG_AUTO_RESUME ((struct pm_message) \ { .event = PM_EVENT_AUTO_RESUME, }) -/** - * Device power management states - * - * These state labels are used internally by the PM core to indicate the current - * status of a device with respect to the PM core operations. - * - * DPM_ON Device is regarded as operational. Set this way - * initially and when ->complete() is about to be called. - * Also set when ->prepare() fails. - * - * DPM_PREPARING Device is going to be prepared for a PM transition. Set - * when ->prepare() is about to be called. - * - * DPM_RESUMING Device is going to be resumed. Set when ->resume(), - * ->thaw(), or ->restore() is about to be called. - * - * DPM_SUSPENDING Device has been prepared for a power transition. Set - * when ->prepare() has just succeeded. - * - * DPM_OFF Device is regarded as inactive. Set immediately after - * ->suspend(), ->freeze(), or ->poweroff() has succeeded. - * Also set when ->resume()_noirq, ->thaw_noirq(), or - * ->restore_noirq() is about to be called. - * - * DPM_OFF_IRQ Device is in a "deep sleep". Set immediately after - * ->suspend_noirq(), ->freeze_noirq(), or - * ->poweroff_noirq() has just succeeded. - */ - -enum dpm_state { - DPM_INVALID, - DPM_ON, - DPM_PREPARING, - DPM_RESUMING, - DPM_SUSPENDING, - DPM_OFF, - DPM_OFF_IRQ, -}; - /** * Device run-time power management status. * @@ -463,8 +424,8 @@ struct wakeup_source; struct dev_pm_info { pm_message_t power_state; unsigned int can_wakeup:1; - unsigned async_suspend:1; - enum dpm_state status; /* Owned by the PM core */ + unsigned int async_suspend:1; + unsigned int in_suspend:1; /* Owned by the PM core */ spinlock_t lock; #ifdef CONFIG_PM_SLEEP struct list_head entry; -- cgit v1.2.3 From c97415a72521071c235e0879f9a600014afd87b1 Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Fri, 26 Nov 2010 19:57:29 +0000 Subject: sysfs: Introducing binary attributes for struct class Added dev_bin_attrs to struct class similar to existing dev_attrs. Signed-off-by: Stefan Achatz Acked-by: Greg Kroah-Hartman Signed-off-by: Jiri Kosina --- drivers/base/core.c | 41 +++++++++++++++++++++++++++++++++++++++-- include/linux/device.h | 1 + 2 files changed, 40 insertions(+), 2 deletions(-) (limited to 'include/linux/device.h') diff --git a/drivers/base/core.c b/drivers/base/core.c index 6ed645411c40..761359261589 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -338,6 +338,35 @@ static void device_remove_attributes(struct device *dev, device_remove_file(dev, &attrs[i]); } +static int device_add_bin_attributes(struct device *dev, + struct bin_attribute *attrs) +{ + int error = 0; + int i; + + if (attrs) { + for (i = 0; attr_name(attrs[i]); i++) { + error = device_create_bin_file(dev, &attrs[i]); + if (error) + break; + } + if (error) + while (--i >= 0) + device_remove_bin_file(dev, &attrs[i]); + } + return error; +} + +static void device_remove_bin_attributes(struct device *dev, + struct bin_attribute *attrs) +{ + int i; + + if (attrs) + for (i = 0; attr_name(attrs[i]); i++) + device_remove_bin_file(dev, &attrs[i]); +} + static int device_add_groups(struct device *dev, const struct attribute_group **groups) { @@ -378,12 +407,15 @@ static int device_add_attrs(struct device *dev) error = device_add_attributes(dev, class->dev_attrs); if (error) return error; + error = device_add_bin_attributes(dev, class->dev_bin_attrs); + if (error) + goto err_remove_class_attrs; } if (type) { error = device_add_groups(dev, type->groups); if (error) - goto err_remove_class_attrs; + goto err_remove_class_bin_attrs; } error = device_add_groups(dev, dev->groups); @@ -395,6 +427,9 @@ static int device_add_attrs(struct device *dev) err_remove_type_groups: if (type) device_remove_groups(dev, type->groups); + err_remove_class_bin_attrs: + if (class) + device_remove_bin_attributes(dev, class->dev_bin_attrs); err_remove_class_attrs: if (class) device_remove_attributes(dev, class->dev_attrs); @@ -412,8 +447,10 @@ static void device_remove_attrs(struct device *dev) if (type) device_remove_groups(dev, type->groups); - if (class) + if (class) { device_remove_attributes(dev, class->dev_attrs); + device_remove_bin_attributes(dev, class->dev_bin_attrs); + } } diff --git a/include/linux/device.h b/include/linux/device.h index dd4895313468..032bdb5406a2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -197,6 +197,7 @@ struct class { struct class_attribute *class_attrs; struct device_attribute *dev_attrs; + struct bin_attribute *dev_bin_attrs; struct kobject *dev_kobj; int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); -- cgit v1.2.3