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..?