On 24-06-20, 01:35, Bard Liao wrote: > From: Rander Wang <rander.wang@xxxxxxxxx> > > When system is suspended in clock stop mode on intel platforms, both > master and slave are in clock stop mode and soundwire bus is taken > over by a glue hardware. The bus message for jack event is processed > by this glue hardware, which will trigger an interrupt to resume audio > pci device. Then audio pci driver will resume soundwire master and slave, > transfer bus ownership to master, finally slave will report jack event > to master and codec driver is triggered to check jack status. > > if a slave has been attached to a bus, the slave->dev_num_sticky > should be non-zero, so we can check this value to skip the > ghost devices defined in ACPI table but not populated in hardware. > > Signed-off-by: Rander Wang <rander.wang@xxxxxxxxx> > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx> > Signed-off-by: Bard Liao <yung-chuan.liao@xxxxxxxxxxxxxxx> > --- > drivers/soundwire/intel.c | 48 +++++++++++++++++++++++++++++++++- > drivers/soundwire/intel.h | 1 + > drivers/soundwire/intel_init.c | 22 ++++++++++++++++ > 3 files changed, 70 insertions(+), 1 deletion(-) > > diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c > index 06c553d94890..22d9fd3e34fa 100644 > --- a/drivers/soundwire/intel.c > +++ b/drivers/soundwire/intel.c > @@ -13,6 +13,7 @@ > #include <linux/io.h> > #include <linux/platform_device.h> > #include <sound/pcm_params.h> > +#include <linux/pm_runtime.h> > #include <sound/soc.h> > #include <linux/soundwire/sdw_registers.h> > #include <linux/soundwire/sdw.h> > @@ -436,7 +437,7 @@ static int intel_shim_init(struct sdw_intel *sdw, bool clock_stop) > return ret; > } > > -static void __maybe_unused intel_shim_wake(struct sdw_intel *sdw, bool wake_enable) > +static void intel_shim_wake(struct sdw_intel *sdw, bool wake_enable) why drop __maybe? > { > void __iomem *shim = sdw->link_res->shim; > unsigned int link_id = sdw->instance; > @@ -1337,6 +1338,51 @@ static int intel_master_remove(struct platform_device *pdev) > return 0; > } > > +int intel_master_process_wakeen_event(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct sdw_intel *sdw; > + struct sdw_bus *bus; > + struct sdw_slave *slave; > + void __iomem *shim; > + u16 wake_sts; > + > + sdw = platform_get_drvdata(pdev); > + bus = &sdw->cdns.bus; > + > + if (bus->prop.hw_disabled) { > + dev_dbg(dev, > + "SoundWire master %d is disabled, ignoring\n", > + bus->link_id); single line pls > + return 0; > + } > + > + shim = sdw->link_res->shim; > + wake_sts = intel_readw(shim, SDW_SHIM_WAKESTS); > + > + if (!(wake_sts & BIT(sdw->instance))) > + return 0; > + > + /* disable WAKEEN interrupt ASAP to prevent interrupt flood */ > + intel_shim_wake(sdw, false); when & where is this enabled? > + > + /* > + * wake up master and slave so that slave can notify master > + * the wakeen event and let codec driver check codec status > + */ > + list_for_each_entry(slave, &bus->slaves, node) { > + /* > + * discard devices that are defined in ACPI tables but > + * not physically present and devices that cannot > + * generate wakes > + */ > + if (slave->dev_num_sticky && slave->prop.wake_capable) > + pm_request_resume(&slave->dev); Hmmm, shouldn't slave do this? would it not make sense to notify the slave thru callback and then slave decides to resume or not..? -- ~Vinod