Skip to content

Commit 494fd7b

Browse files
apmswrafaeljw
authored andcommitted
PM / core: fix deferred probe breaking suspend resume order
When bridge and its endpoint is enumerated the devices are added to the dpm list. Afterward, the bridge defers probe when IOMMU is not ready. This causes the bridge to be moved to the end of the dpm list when deferred probe kicks in. The order of the dpm list for bridge and endpoint is reversed. Add reordering code to move the bridge and its children and consumers to the end of the pm list so the order for suspend and resume is not altered. The code also move device and its children and consumers to the tail of device_kset list if it is registered. Signed-off-by: Toan Le <[email protected]> Signed-off-by: Feng Kan <[email protected]> Reviewed-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 6d08b06 commit 494fd7b

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

drivers/base/base.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,6 @@ extern void device_links_driver_cleanup(struct device *dev);
161161
extern void device_links_no_driver(struct device *dev);
162162
extern bool device_links_busy(struct device *dev);
163163
extern void device_links_unbind_consumers(struct device *dev);
164+
165+
/* device pm support */
166+
void device_pm_move_to_tail(struct device *dev);

drivers/base/core.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,26 @@ static int device_reorder_to_tail(struct device *dev, void *not_used)
144144
return 0;
145145
}
146146

147+
/**
148+
* device_pm_move_to_tail - Move set of devices to the end of device lists
149+
* @dev: Device to move
150+
*
151+
* This is a device_reorder_to_tail() wrapper taking the requisite locks.
152+
*
153+
* It moves the @dev along with all of its children and all of its consumers
154+
* to the ends of the device_kset and dpm_list, recursively.
155+
*/
156+
void device_pm_move_to_tail(struct device *dev)
157+
{
158+
int idx;
159+
160+
idx = device_links_read_lock();
161+
device_pm_lock();
162+
device_reorder_to_tail(dev, NULL);
163+
device_pm_unlock();
164+
device_links_read_unlock(idx);
165+
}
166+
147167
/**
148168
* device_link_add - Create a link between two devices.
149169
* @consumer: Consumer end of the link.

drivers/base/dd.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,7 @@ static void deferred_probe_work_func(struct work_struct *work)
122122
* the list is a good order for suspend but deferred
123123
* probe makes that very unsafe.
124124
*/
125-
device_pm_lock();
126-
device_pm_move_last(dev);
127-
device_pm_unlock();
125+
device_pm_move_to_tail(dev);
128126

129127
dev_dbg(dev, "Retrying from deferred list\n");
130128
if (initcall_debug && !initcalls_done)

0 commit comments

Comments
 (0)