X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fbase%2Fpower%2Fmain.c;h=fdfa3d0cf6afa6f0bf2fb247f54333abfab8f1fc;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=634c98f5c43756d30c13051ac00190bd98c53573;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 634c98f5c..fdfa3d0cf 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -12,14 +12,13 @@ * and add it to the list of power-controlled devices. sysfs entries for * controlling device power management will also be added. * - * A different set of lists than the global subsystem list are used to - * keep track of power info because we use different lists to hold - * devices based on what stage of the power management process they - * are in. The power domain dependencies may also differ from the + * A different set of lists than the global subsystem list are used to + * keep track of power info because we use different lists to hold + * devices based on what stage of the power management process they + * are in. The power domain dependencies may also differ from the * ancestral dependencies that the subsystem list maintains. */ -#include #include #include "power.h" @@ -28,23 +27,7 @@ LIST_HEAD(dpm_off); LIST_HEAD(dpm_off_irq); DECLARE_MUTEX(dpm_sem); - -/* - * PM Reference Counting. - */ - -static inline void device_pm_hold(struct device * dev) -{ - if (dev) - atomic_inc(&dev->power.pm_users); -} - -static inline void device_pm_release(struct device * dev) -{ - if (dev) - atomic_dec(&dev->power.pm_users); -} - +DECLARE_MUTEX(dpm_list_sem); /** * device_pm_set_parent - Specify power dependency. @@ -61,12 +44,10 @@ static inline void device_pm_release(struct device * dev) void device_pm_set_parent(struct device * dev, struct device * parent) { - struct device * old_parent = dev->power.pm_parent; - device_pm_release(old_parent); - dev->power.pm_parent = parent; - device_pm_hold(parent); + put_device(dev->power.pm_parent); + dev->power.pm_parent = get_device(parent); } -EXPORT_SYMBOL(device_pm_set_parent); +EXPORT_SYMBOL_GPL(device_pm_set_parent); int device_pm_add(struct device * dev) { @@ -74,13 +55,12 @@ int device_pm_add(struct device * dev) pr_debug("PM: Adding info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); - atomic_set(&dev->power.pm_users,0); - down(&dpm_sem); - list_add_tail(&dev->power.entry,&dpm_active); - device_pm_set_parent(dev,dev->parent); + down(&dpm_list_sem); + list_add_tail(&dev->power.entry, &dpm_active); + device_pm_set_parent(dev, dev->parent); if ((error = dpm_sysfs_add(dev))) list_del(&dev->power.entry); - up(&dpm_sem); + up(&dpm_list_sem); return error; } @@ -88,11 +68,11 @@ void device_pm_remove(struct device * dev) { pr_debug("PM: Removing info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); - down(&dpm_sem); + down(&dpm_list_sem); dpm_sysfs_remove(dev); - device_pm_release(dev->power.pm_parent); - list_del(&dev->power.entry); - up(&dpm_sem); + put_device(dev->power.pm_parent); + list_del_init(&dev->power.entry); + up(&dpm_list_sem); }