aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2009-03-04 06:44:00 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-24 19:38:26 -0400
commitffa6a7054d172a2f57248dff2de600ca795c5656 (patch)
treef93c6234bb90295c52fcef09e367ed77ff6c3645 /drivers/base/core.c
parent60530afe1ee8a5532cb09d0ab5bc3f1a6495b780 (diff)
Driver core: Fix device_move() vs. dpm list ordering, v2
dpm_list currently relies on the fact that child devices will be registered after their parents to get a correct suspend order. Using device_move() however destroys this assumption, as an already registered device may be moved under a newly registered one. This patch adds a new argument to device_move(), allowing callers to specify how dpm_list should be adapted. Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 95c67ffd71da..e73c92d13a23 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1561,8 +1561,10 @@ out:
1561 * device_move - moves a device to a new parent 1561 * device_move - moves a device to a new parent
1562 * @dev: the pointer to the struct device to be moved 1562 * @dev: the pointer to the struct device to be moved
1563 * @new_parent: the new parent of the device (can by NULL) 1563 * @new_parent: the new parent of the device (can by NULL)
1564 * @dpm_order: how to reorder the dpm_list
1564 */ 1565 */
1565int device_move(struct device *dev, struct device *new_parent) 1566int device_move(struct device *dev, struct device *new_parent,
1567 enum dpm_order dpm_order)
1566{ 1568{
1567 int error; 1569 int error;
1568 struct device *old_parent; 1570 struct device *old_parent;
@@ -1572,6 +1574,7 @@ int device_move(struct device *dev, struct device *new_parent)
1572 if (!dev) 1574 if (!dev)
1573 return -EINVAL; 1575 return -EINVAL;
1574 1576
1577 device_pm_lock();
1575 new_parent = get_device(new_parent); 1578 new_parent = get_device(new_parent);
1576 new_parent_kobj = get_device_parent(dev, new_parent); 1579 new_parent_kobj = get_device_parent(dev, new_parent);
1577 1580
@@ -1613,9 +1616,23 @@ int device_move(struct device *dev, struct device *new_parent)
1613 put_device(new_parent); 1616 put_device(new_parent);
1614 goto out; 1617 goto out;
1615 } 1618 }
1619 switch (dpm_order) {
1620 case DPM_ORDER_NONE:
1621 break;
1622 case DPM_ORDER_DEV_AFTER_PARENT:
1623 device_pm_move_after(dev, new_parent);
1624 break;
1625 case DPM_ORDER_PARENT_BEFORE_DEV:
1626 device_pm_move_before(new_parent, dev);
1627 break;
1628 case DPM_ORDER_DEV_LAST:
1629 device_pm_move_last(dev);
1630 break;
1631 }
1616out_put: 1632out_put:
1617 put_device(old_parent); 1633 put_device(old_parent);
1618out: 1634out:
1635 device_pm_unlock();
1619 put_device(dev); 1636 put_device(dev);
1620 return error; 1637 return error;
1621} 1638}