Skip to content

Commit 4cd5ea6

Browse files
bardliaovinodkoul
authored andcommitted
soundwire: intel_init: resume all devices on exit.
When the manager becomes pm_runtime active in the remove procedure, peripherals will become attached, and do the initialization process. We have to wait until all the devices are fully resumed before the cleanup, otherwise there is a possible race condition where asynchronous workqueues initiate transfers on the bus that cannot complete. This will ensure there are no SoundWire registers accessed after the bus is powered-down. Signed-off-by: Bard Liao <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent f2fa686 commit 4cd5ea6

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

drivers/soundwire/intel_init.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/pm_runtime.h>
1717
#include <linux/soundwire/sdw_intel.h>
1818
#include "cadence_master.h"
19+
#include "bus.h"
1920
#include "intel.h"
2021
#include "intel_auxdevice.h"
2122

@@ -356,6 +357,19 @@ EXPORT_SYMBOL_NS(sdw_intel_startup, SOUNDWIRE_INTEL_INIT);
356357
*/
357358
void sdw_intel_exit(struct sdw_intel_ctx *ctx)
358359
{
360+
struct sdw_intel_link_res *link;
361+
362+
/* we first resume links and devices and wait synchronously before the cleanup */
363+
list_for_each_entry(link, &ctx->link_list, list) {
364+
struct sdw_bus *bus = &link->cdns->bus;
365+
int ret;
366+
367+
ret = device_for_each_child(bus->dev, NULL, intel_resume_child_device);
368+
if (ret < 0)
369+
dev_err(bus->dev, "%s: intel_resume_child_device failed: %d\n",
370+
__func__, ret);
371+
}
372+
359373
sdw_intel_cleanup(ctx);
360374
kfree(ctx->ids);
361375
kfree(ctx->ldev);

0 commit comments

Comments
 (0)