* [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file
@ 2022-11-11 1:31 Bard Liao
2022-11-11 1:31 ` [PATCH 1/7] soundwire: intel: start using hw_ops Bard Liao
` (7 more replies)
0 siblings, 8 replies; 10+ messages in thread
From: Bard Liao @ 2022-11-11 1:31 UTC (permalink / raw)
To: alsa-devel, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, bard.liao
This series adds yet another set of cleanups
a) all the helpers are now exposed as hw_ops callbacks
b) the auxiliary device code is now completely generic.
This will allow for easier introduction of new hw_ops implementations in
the future without throwing away all the goodness of the auxiliary device
handling. Since there will be a tighter coupling with HDaudio, it's likely
that future hw_ops are implemented in the SOF driver directly.
Pierre-Louis Bossart (7):
soundwire: intel: start using hw_ops
soundwire: intel: add debugfs callbacks in hw_ops
soundwire: intel: add register_dai callback in hw_ops
soundwire: intel: add bus management callbacks in hw_ops
soundwire: intel: add link power management callbacks in hw_ops
soundwire: intel: add in-band wake callbacks in hw_ops
soundwire: intel: split auxdevice to different file
drivers/soundwire/Makefile | 2 +-
drivers/soundwire/intel.c | 658 +--------------------------
drivers/soundwire/intel.h | 96 +++-
drivers/soundwire/intel_auxdevice.c | 678 ++++++++++++++++++++++++++++
drivers/soundwire/intel_auxdevice.h | 18 +
drivers/soundwire/intel_init.c | 2 +
include/linux/soundwire/sdw_intel.h | 44 ++
sound/soc/sof/intel/hda.c | 2 +
8 files changed, 853 insertions(+), 647 deletions(-)
create mode 100644 drivers/soundwire/intel_auxdevice.c
create mode 100644 drivers/soundwire/intel_auxdevice.h
--
2.25.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/7] soundwire: intel: start using hw_ops
2022-11-11 1:31 [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Bard Liao
@ 2022-11-11 1:31 ` Bard Liao
2022-11-11 1:31 ` [PATCH 2/7] soundwire: intel: add debugfs callbacks in hw_ops Bard Liao
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Bard Liao @ 2022-11-11 1:31 UTC (permalink / raw)
To: alsa-devel, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, bard.liao
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Before introducing new hardware with completely different register
spaces and programming sequences, we need to abstract some of the
existing routines in hw_ops that will be platform-specific. For now we
only use the 'cnl' ops - after the first Intel platform with SoundWire
capabilities.
Rather than one big intrusive patch, hw_ops are introduced in this
patch so show the dependencies between drivers. Follow-up patches will
introduce callbacks for debugfs, power and bus management.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
---
drivers/soundwire/intel.c | 38 +++++++++++++++++++++++------
drivers/soundwire/intel.h | 3 +++
drivers/soundwire/intel_init.c | 1 +
include/linux/soundwire/sdw_intel.h | 15 ++++++++++++
sound/soc/sof/intel/hda.c | 2 ++
5 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index b9cb7e31ddb3..f88319f8ded4 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -745,10 +745,10 @@ static int intel_free_stream(struct sdw_intel *sdw,
* bank switch routines
*/
-static int intel_pre_bank_switch(struct sdw_bus *bus)
+static int intel_pre_bank_switch(struct sdw_intel *sdw)
{
- struct sdw_cdns *cdns = bus_to_cdns(bus);
- struct sdw_intel *sdw = cdns_to_intel(cdns);
+ struct sdw_cdns *cdns = &sdw->cdns;
+ struct sdw_bus *bus = &cdns->bus;
/* Write to register only for multi-link */
if (!bus->multi_link)
@@ -759,10 +759,10 @@ static int intel_pre_bank_switch(struct sdw_bus *bus)
return 0;
}
-static int intel_post_bank_switch(struct sdw_bus *bus)
+static int intel_post_bank_switch(struct sdw_intel *sdw)
{
- struct sdw_cdns *cdns = bus_to_cdns(bus);
- struct sdw_intel *sdw = cdns_to_intel(cdns);
+ struct sdw_cdns *cdns = &sdw->cdns;
+ struct sdw_bus *bus = &cdns->bus;
void __iomem *shim = sdw->link_res->shim;
int sync_reg, ret;
@@ -1422,6 +1422,28 @@ static int intel_stop_bus(struct sdw_intel *sdw, bool clock_stop)
return 0;
}
+const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops = {
+ .pre_bank_switch = intel_pre_bank_switch,
+ .post_bank_switch = intel_post_bank_switch,
+};
+EXPORT_SYMBOL_NS(sdw_intel_cnl_hw_ops, SOUNDWIRE_INTEL);
+
+static int generic_pre_bank_switch(struct sdw_bus *bus)
+{
+ struct sdw_cdns *cdns = bus_to_cdns(bus);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+
+ return sdw->link_res->hw_ops->pre_bank_switch(sdw);
+}
+
+static int generic_post_bank_switch(struct sdw_bus *bus)
+{
+ struct sdw_cdns *cdns = bus_to_cdns(bus);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+
+ return sdw->link_res->hw_ops->post_bank_switch(sdw);
+}
+
static int sdw_master_read_intel_prop(struct sdw_bus *bus)
{
struct sdw_master_prop *prop = &bus->prop;
@@ -1477,8 +1499,8 @@ static struct sdw_master_ops sdw_intel_ops = {
.xfer_msg_defer = cdns_xfer_msg_defer,
.reset_page_addr = cdns_reset_page_addr,
.set_bus_conf = cdns_bus_conf,
- .pre_bank_switch = intel_pre_bank_switch,
- .post_bank_switch = intel_post_bank_switch,
+ .pre_bank_switch = generic_pre_bank_switch,
+ .post_bank_switch = generic_post_bank_switch,
.read_ping_status = cdns_read_ping_status,
};
diff --git a/drivers/soundwire/intel.h b/drivers/soundwire/intel.h
index cd93a44dba9a..3170df76b411 100644
--- a/drivers/soundwire/intel.h
+++ b/drivers/soundwire/intel.h
@@ -7,6 +7,7 @@
/**
* struct sdw_intel_link_res - Soundwire Intel link resource structure,
* typically populated by the controller driver.
+ * @hw_ops: platform-specific ops
* @mmio_base: mmio base of SoundWire registers
* @registers: Link IO registers base
* @shim: Audio shim pointer
@@ -22,6 +23,8 @@
* @list: used to walk-through all masters exposed by the same controller
*/
struct sdw_intel_link_res {
+ const struct sdw_intel_hw_ops *hw_ops;
+
void __iomem *mmio_base; /* not strictly needed, useful for debug */
void __iomem *registers;
void __iomem *shim;
diff --git a/drivers/soundwire/intel_init.c b/drivers/soundwire/intel_init.c
index d091513919df..1e6d74b3e773 100644
--- a/drivers/soundwire/intel_init.c
+++ b/drivers/soundwire/intel_init.c
@@ -60,6 +60,7 @@ static struct sdw_intel_link_dev *intel_link_dev_register(struct sdw_intel_res *
/* Add link information used in the driver probe */
link = &ldev->link_res;
+ link->hw_ops = res->hw_ops;
link->mmio_base = res->mmio_base;
link->registers = res->mmio_base + SDW_LINK_BASE
+ (SDW_LINK_SIZE * link_id);
diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h
index 2e9fd91572d4..2dbe34b41ef1 100644
--- a/include/linux/soundwire/sdw_intel.h
+++ b/include/linux/soundwire/sdw_intel.h
@@ -233,6 +233,7 @@ struct sdw_intel_ctx {
* struct sdw_intel_res - Soundwire Intel global resource structure,
* typically populated by the DSP driver
*
+ * @hw_ops: abstraction for platform ops
* @count: link count
* @mmio_base: mmio base of SoundWire registers
* @irq: interrupt number
@@ -249,6 +250,7 @@ struct sdw_intel_ctx {
* @alh_base: sdw alh base.
*/
struct sdw_intel_res {
+ const struct sdw_intel_hw_ops *hw_ops;
int count;
void __iomem *mmio_base;
int irq;
@@ -292,4 +294,17 @@ irqreturn_t sdw_intel_thread(int irq, void *dev_id);
#define SDW_INTEL_QUIRK_MASK_BUS_DISABLE BIT(1)
+struct sdw_intel;
+
+/* struct intel_sdw_hw_ops - SoundWire ops for Intel platforms.
+ * @pre_bank_switch: helper for bus management
+ * @post_bank_switch: helper for bus management
+ */
+struct sdw_intel_hw_ops {
+ int (*pre_bank_switch)(struct sdw_intel *sdw);
+ int (*post_bank_switch)(struct sdw_intel *sdw);
+};
+
+extern const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops;
+
#endif
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 1188ec51816b..3d6254489056 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -188,6 +188,7 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev)
memset(&res, 0, sizeof(res));
+ res.hw_ops = &sdw_intel_cnl_hw_ops;
res.mmio_base = sdev->bar[HDA_DSP_BAR];
res.shim_base = hdev->desc->sdw_shim_base;
res.alh_base = hdev->desc->sdw_alh_base;
@@ -1694,3 +1695,4 @@ MODULE_IMPORT_NS(SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI);
MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT);
+MODULE_IMPORT_NS(SOUNDWIRE_INTEL);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/7] soundwire: intel: add debugfs callbacks in hw_ops
2022-11-11 1:31 [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Bard Liao
2022-11-11 1:31 ` [PATCH 1/7] soundwire: intel: start using hw_ops Bard Liao
@ 2022-11-11 1:31 ` Bard Liao
2022-11-11 1:31 ` [PATCH 3/7] soundwire: intel: add register_dai callback " Bard Liao
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Bard Liao @ 2022-11-11 1:31 UTC (permalink / raw)
To: alsa-devel, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, bard.liao
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
No functionality change, only add indirection for debugfs helpers.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
---
drivers/soundwire/intel.c | 7 +++++--
drivers/soundwire/intel.h | 16 ++++++++++++++++
include/linux/soundwire/sdw_intel.h | 5 +++++
3 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index f88319f8ded4..914f2fb43721 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -1423,6 +1423,9 @@ static int intel_stop_bus(struct sdw_intel *sdw, bool clock_stop)
}
const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops = {
+ .debugfs_init = intel_debugfs_init,
+ .debugfs_exit = intel_debugfs_exit,
+
.pre_bank_switch = intel_pre_bank_switch,
.post_bank_switch = intel_post_bank_switch,
};
@@ -1614,7 +1617,7 @@ int intel_link_startup(struct auxiliary_device *auxdev)
goto err_power_up;
}
- intel_debugfs_init(sdw);
+ sdw_intel_debugfs_init(sdw);
/* start bus */
ret = intel_start_bus(sdw);
@@ -1685,7 +1688,7 @@ static void intel_link_remove(struct auxiliary_device *auxdev)
* SDW_INTEL_CLK_STOP_NOT_ALLOWED
*/
if (!bus->prop.hw_disabled) {
- intel_debugfs_exit(sdw);
+ sdw_intel_debugfs_exit(sdw);
sdw_cdns_enable_interrupt(cdns, false);
}
sdw_bus_master_delete(bus);
diff --git a/drivers/soundwire/intel.h b/drivers/soundwire/intel.h
index 3170df76b411..5548b8451d01 100644
--- a/drivers/soundwire/intel.h
+++ b/drivers/soundwire/intel.h
@@ -61,4 +61,20 @@ struct sdw_intel_link_dev {
#define auxiliary_dev_to_sdw_intel_link_dev(auxiliary_dev) \
container_of(auxiliary_dev, struct sdw_intel_link_dev, auxdev)
+#define SDW_INTEL_CHECK_OPS(sdw, cb) ((sdw) && (sdw)->link_res && (sdw)->link_res->hw_ops && \
+ (sdw)->link_res->hw_ops->cb)
+#define SDW_INTEL_OPS(sdw, cb) ((sdw)->link_res->hw_ops->cb)
+
+static inline void sdw_intel_debugfs_init(struct sdw_intel *sdw)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, debugfs_init))
+ SDW_INTEL_OPS(sdw, debugfs_init)(sdw);
+}
+
+static inline void sdw_intel_debugfs_exit(struct sdw_intel *sdw)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, debugfs_exit))
+ SDW_INTEL_OPS(sdw, debugfs_exit)(sdw);
+}
+
#endif /* __SDW_INTEL_LOCAL_H */
diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h
index 2dbe34b41ef1..211924e4ebf2 100644
--- a/include/linux/soundwire/sdw_intel.h
+++ b/include/linux/soundwire/sdw_intel.h
@@ -297,10 +297,15 @@ irqreturn_t sdw_intel_thread(int irq, void *dev_id);
struct sdw_intel;
/* struct intel_sdw_hw_ops - SoundWire ops for Intel platforms.
+ * @debugfs_init: initialize all debugfs capabilities
+ * @debugfs_exit: close and cleanup debugfs capabilities
* @pre_bank_switch: helper for bus management
* @post_bank_switch: helper for bus management
*/
struct sdw_intel_hw_ops {
+ void (*debugfs_init)(struct sdw_intel *sdw);
+ void (*debugfs_exit)(struct sdw_intel *sdw);
+
int (*pre_bank_switch)(struct sdw_intel *sdw);
int (*post_bank_switch)(struct sdw_intel *sdw);
};
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/7] soundwire: intel: add register_dai callback in hw_ops
2022-11-11 1:31 [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Bard Liao
2022-11-11 1:31 ` [PATCH 1/7] soundwire: intel: start using hw_ops Bard Liao
2022-11-11 1:31 ` [PATCH 2/7] soundwire: intel: add debugfs callbacks in hw_ops Bard Liao
@ 2022-11-11 1:31 ` Bard Liao
2022-11-11 1:31 ` [PATCH 4/7] soundwire: intel: add bus management callbacks " Bard Liao
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Bard Liao @ 2022-11-11 1:31 UTC (permalink / raw)
To: alsa-devel, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, bard.liao
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
No functionality change, only add indirection for DAI registration
helper.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
---
drivers/soundwire/intel.c | 4 +++-
drivers/soundwire/intel.h | 7 +++++++
include/linux/soundwire/sdw_intel.h | 3 +++
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 914f2fb43721..0496eb0d6084 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -1426,6 +1426,8 @@ const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops = {
.debugfs_init = intel_debugfs_init,
.debugfs_exit = intel_debugfs_exit,
+ .register_dai = intel_register_dai,
+
.pre_bank_switch = intel_pre_bank_switch,
.post_bank_switch = intel_post_bank_switch,
};
@@ -1611,7 +1613,7 @@ int intel_link_startup(struct auxiliary_device *auxdev)
goto err_init;
/* Register DAIs */
- ret = intel_register_dai(sdw);
+ ret = sdw_intel_register_dai(sdw);
if (ret) {
dev_err(dev, "DAI registration failed: %d\n", ret);
goto err_power_up;
diff --git a/drivers/soundwire/intel.h b/drivers/soundwire/intel.h
index 5548b8451d01..0521cab311a3 100644
--- a/drivers/soundwire/intel.h
+++ b/drivers/soundwire/intel.h
@@ -77,4 +77,11 @@ static inline void sdw_intel_debugfs_exit(struct sdw_intel *sdw)
SDW_INTEL_OPS(sdw, debugfs_exit)(sdw);
}
+static inline int sdw_intel_register_dai(struct sdw_intel *sdw)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, register_dai))
+ return SDW_INTEL_OPS(sdw, register_dai)(sdw);
+ return -ENOTSUPP;
+}
+
#endif /* __SDW_INTEL_LOCAL_H */
diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h
index 211924e4ebf2..5be63d4fe62e 100644
--- a/include/linux/soundwire/sdw_intel.h
+++ b/include/linux/soundwire/sdw_intel.h
@@ -299,6 +299,7 @@ struct sdw_intel;
/* struct intel_sdw_hw_ops - SoundWire ops for Intel platforms.
* @debugfs_init: initialize all debugfs capabilities
* @debugfs_exit: close and cleanup debugfs capabilities
+ * @register_dai: read all PDI information and register DAIs
* @pre_bank_switch: helper for bus management
* @post_bank_switch: helper for bus management
*/
@@ -306,6 +307,8 @@ struct sdw_intel_hw_ops {
void (*debugfs_init)(struct sdw_intel *sdw);
void (*debugfs_exit)(struct sdw_intel *sdw);
+ int (*register_dai)(struct sdw_intel *sdw);
+
int (*pre_bank_switch)(struct sdw_intel *sdw);
int (*post_bank_switch)(struct sdw_intel *sdw);
};
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/7] soundwire: intel: add bus management callbacks in hw_ops
2022-11-11 1:31 [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Bard Liao
` (2 preceding siblings ...)
2022-11-11 1:31 ` [PATCH 3/7] soundwire: intel: add register_dai callback " Bard Liao
@ 2022-11-11 1:31 ` Bard Liao
2022-11-11 1:31 ` [PATCH 5/7] soundwire: intel: add link power " Bard Liao
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Bard Liao @ 2022-11-11 1:31 UTC (permalink / raw)
To: alsa-devel, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, bard.liao
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
No functionality change, only add indirection for bus management
helpers.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
---
drivers/soundwire/intel.c | 24 ++++++++++++--------
drivers/soundwire/intel.h | 34 +++++++++++++++++++++++++++++
include/linux/soundwire/sdw_intel.h | 11 ++++++++++
3 files changed, 60 insertions(+), 9 deletions(-)
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 0496eb0d6084..6d2fdf3a01fd 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -1428,6 +1428,12 @@ const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops = {
.register_dai = intel_register_dai,
+ .check_clock_stop = intel_check_clock_stop,
+ .start_bus = intel_start_bus,
+ .start_bus_after_reset = intel_start_bus_after_reset,
+ .start_bus_after_clock_stop = intel_start_bus_after_clock_stop,
+ .stop_bus = intel_stop_bus,
+
.pre_bank_switch = intel_pre_bank_switch,
.post_bank_switch = intel_post_bank_switch,
};
@@ -1622,7 +1628,7 @@ int intel_link_startup(struct auxiliary_device *auxdev)
sdw_intel_debugfs_init(sdw);
/* start bus */
- ret = intel_start_bus(sdw);
+ ret = sdw_intel_start_bus(sdw);
if (ret) {
dev_err(dev, "bus start failed: %d\n", ret);
goto err_power_up;
@@ -1850,7 +1856,7 @@ static int __maybe_unused intel_suspend(struct device *dev)
return 0;
}
- ret = intel_stop_bus(sdw, false);
+ ret = sdw_intel_stop_bus(sdw, false);
if (ret < 0) {
dev_err(dev, "%s: cannot stop bus: %d\n", __func__, ret);
return ret;
@@ -1876,14 +1882,14 @@ static int __maybe_unused intel_suspend_runtime(struct device *dev)
clock_stop_quirks = sdw->link_res->clock_stop_quirks;
if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) {
- ret = intel_stop_bus(sdw, false);
+ ret = sdw_intel_stop_bus(sdw, false);
if (ret < 0) {
dev_err(dev, "%s: cannot stop bus during teardown: %d\n",
__func__, ret);
return ret;
}
} else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET || !clock_stop_quirks) {
- ret = intel_stop_bus(sdw, true);
+ ret = sdw_intel_stop_bus(sdw, true);
if (ret < 0) {
dev_err(dev, "%s: cannot stop bus during clock_stop: %d\n",
__func__, ret);
@@ -1941,7 +1947,7 @@ static int __maybe_unused intel_resume(struct device *dev)
*/
sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
- ret = intel_start_bus(sdw);
+ ret = sdw_intel_start_bus(sdw);
if (ret < 0) {
dev_err(dev, "cannot start bus during resume\n");
intel_link_power_down(sdw);
@@ -1995,7 +2001,7 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
*/
sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
- ret = intel_start_bus(sdw);
+ ret = sdw_intel_start_bus(sdw);
if (ret < 0) {
dev_err(dev, "%s: cannot start bus after teardown: %d\n", __func__, ret);
intel_link_power_down(sdw);
@@ -2010,7 +2016,7 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
return ret;
}
- ret = intel_start_bus_after_reset(sdw);
+ ret = sdw_intel_start_bus_after_reset(sdw);
if (ret < 0) {
dev_err(dev, "%s: cannot start bus after reset: %d\n", __func__, ret);
intel_link_power_down(sdw);
@@ -2018,7 +2024,7 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
}
} else if (!clock_stop_quirks) {
- intel_check_clock_stop(sdw);
+ sdw_intel_check_clock_stop(sdw);
ret = intel_link_power_up(sdw);
if (ret) {
@@ -2026,7 +2032,7 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
return ret;
}
- ret = intel_start_bus_after_clock_stop(sdw);
+ ret = sdw_intel_start_bus_after_clock_stop(sdw);
if (ret < 0) {
dev_err(dev, "%s: cannot start bus after clock stop: %d\n", __func__, ret);
intel_link_power_down(sdw);
diff --git a/drivers/soundwire/intel.h b/drivers/soundwire/intel.h
index 0521cab311a3..99a2d875a331 100644
--- a/drivers/soundwire/intel.h
+++ b/drivers/soundwire/intel.h
@@ -84,4 +84,38 @@ static inline int sdw_intel_register_dai(struct sdw_intel *sdw)
return -ENOTSUPP;
}
+static inline void sdw_intel_check_clock_stop(struct sdw_intel *sdw)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, check_clock_stop))
+ SDW_INTEL_OPS(sdw, check_clock_stop)(sdw);
+}
+
+static inline int sdw_intel_start_bus(struct sdw_intel *sdw)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, start_bus))
+ return SDW_INTEL_OPS(sdw, start_bus)(sdw);
+ return -ENOTSUPP;
+}
+
+static inline int sdw_intel_start_bus_after_reset(struct sdw_intel *sdw)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_reset))
+ return SDW_INTEL_OPS(sdw, start_bus_after_reset)(sdw);
+ return -ENOTSUPP;
+}
+
+static inline int sdw_intel_start_bus_after_clock_stop(struct sdw_intel *sdw)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_clock_stop))
+ return SDW_INTEL_OPS(sdw, start_bus_after_clock_stop)(sdw);
+ return -ENOTSUPP;
+}
+
+static inline int sdw_intel_stop_bus(struct sdw_intel *sdw, bool clock_stop)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, stop_bus))
+ return SDW_INTEL_OPS(sdw, stop_bus)(sdw, clock_stop);
+ return -ENOTSUPP;
+}
+
#endif /* __SDW_INTEL_LOCAL_H */
diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h
index 5be63d4fe62e..cee61bc9af8a 100644
--- a/include/linux/soundwire/sdw_intel.h
+++ b/include/linux/soundwire/sdw_intel.h
@@ -300,6 +300,11 @@ struct sdw_intel;
* @debugfs_init: initialize all debugfs capabilities
* @debugfs_exit: close and cleanup debugfs capabilities
* @register_dai: read all PDI information and register DAIs
+ * @check_clock_stop: throw error message if clock is not stopped.
+ * @start_bus: normal start
+ * @start_bus_after_reset: start after reset
+ * @start_bus_after_clock_stop: start after mode0 clock stop
+ * @stop_bus: stop all bus
* @pre_bank_switch: helper for bus management
* @post_bank_switch: helper for bus management
*/
@@ -309,6 +314,12 @@ struct sdw_intel_hw_ops {
int (*register_dai)(struct sdw_intel *sdw);
+ void (*check_clock_stop)(struct sdw_intel *sdw);
+ int (*start_bus)(struct sdw_intel *sdw);
+ int (*start_bus_after_reset)(struct sdw_intel *sdw);
+ int (*start_bus_after_clock_stop)(struct sdw_intel *sdw);
+ int (*stop_bus)(struct sdw_intel *sdw, bool clock_stop);
+
int (*pre_bank_switch)(struct sdw_intel *sdw);
int (*post_bank_switch)(struct sdw_intel *sdw);
};
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/7] soundwire: intel: add link power management callbacks in hw_ops
2022-11-11 1:31 [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Bard Liao
` (3 preceding siblings ...)
2022-11-11 1:31 ` [PATCH 4/7] soundwire: intel: add bus management callbacks " Bard Liao
@ 2022-11-11 1:31 ` Bard Liao
2022-11-11 1:31 ` [PATCH 6/7] soundwire: intel: add in-band wake " Bard Liao
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Bard Liao @ 2022-11-11 1:31 UTC (permalink / raw)
To: alsa-devel, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, bard.liao
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
No functionality change, only add indirection for link power
management helpers.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
---
drivers/soundwire/intel.c | 23 +++++++++++++----------
drivers/soundwire/intel.h | 14 ++++++++++++++
include/linux/soundwire/sdw_intel.h | 5 +++++
3 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 6d2fdf3a01fd..2320f1b8a2d1 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -1434,6 +1434,9 @@ const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops = {
.start_bus_after_clock_stop = intel_start_bus_after_clock_stop,
.stop_bus = intel_stop_bus,
+ .link_power_up = intel_link_power_up,
+ .link_power_down = intel_link_power_down,
+
.pre_bank_switch = intel_pre_bank_switch,
.post_bank_switch = intel_post_bank_switch,
};
@@ -1614,7 +1617,7 @@ int intel_link_startup(struct auxiliary_device *auxdev)
bus->multi_link = multi_link;
/* Initialize shim, controller */
- ret = intel_link_power_up(sdw);
+ ret = sdw_intel_link_power_up(sdw);
if (ret)
goto err_init;
@@ -1679,7 +1682,7 @@ int intel_link_startup(struct auxiliary_device *auxdev)
return 0;
err_power_up:
- intel_link_power_down(sdw);
+ sdw_intel_link_power_down(sdw);
err_init:
return ret;
}
@@ -1935,7 +1938,7 @@ static int __maybe_unused intel_resume(struct device *dev)
pm_runtime_idle(dev);
}
- ret = intel_link_power_up(sdw);
+ ret = sdw_intel_link_power_up(sdw);
if (ret) {
dev_err(dev, "%s failed: %d\n", __func__, ret);
return ret;
@@ -1950,7 +1953,7 @@ static int __maybe_unused intel_resume(struct device *dev)
ret = sdw_intel_start_bus(sdw);
if (ret < 0) {
dev_err(dev, "cannot start bus during resume\n");
- intel_link_power_down(sdw);
+ sdw_intel_link_power_down(sdw);
return ret;
}
@@ -1989,7 +1992,7 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
clock_stop_quirks = sdw->link_res->clock_stop_quirks;
if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) {
- ret = intel_link_power_up(sdw);
+ ret = sdw_intel_link_power_up(sdw);
if (ret) {
dev_err(dev, "%s: power_up failed after teardown: %d\n", __func__, ret);
return ret;
@@ -2004,13 +2007,13 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
ret = sdw_intel_start_bus(sdw);
if (ret < 0) {
dev_err(dev, "%s: cannot start bus after teardown: %d\n", __func__, ret);
- intel_link_power_down(sdw);
+ sdw_intel_link_power_down(sdw);
return ret;
}
} else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) {
- ret = intel_link_power_up(sdw);
+ ret = sdw_intel_link_power_up(sdw);
if (ret) {
dev_err(dev, "%s: power_up failed after bus reset: %d\n", __func__, ret);
return ret;
@@ -2019,14 +2022,14 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
ret = sdw_intel_start_bus_after_reset(sdw);
if (ret < 0) {
dev_err(dev, "%s: cannot start bus after reset: %d\n", __func__, ret);
- intel_link_power_down(sdw);
+ sdw_intel_link_power_down(sdw);
return ret;
}
} else if (!clock_stop_quirks) {
sdw_intel_check_clock_stop(sdw);
- ret = intel_link_power_up(sdw);
+ ret = sdw_intel_link_power_up(sdw);
if (ret) {
dev_err(dev, "%s: power_up failed: %d\n", __func__, ret);
return ret;
@@ -2035,7 +2038,7 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
ret = sdw_intel_start_bus_after_clock_stop(sdw);
if (ret < 0) {
dev_err(dev, "%s: cannot start bus after clock stop: %d\n", __func__, ret);
- intel_link_power_down(sdw);
+ sdw_intel_link_power_down(sdw);
return ret;
}
} else {
diff --git a/drivers/soundwire/intel.h b/drivers/soundwire/intel.h
index 99a2d875a331..0f63e7584132 100644
--- a/drivers/soundwire/intel.h
+++ b/drivers/soundwire/intel.h
@@ -118,4 +118,18 @@ static inline int sdw_intel_stop_bus(struct sdw_intel *sdw, bool clock_stop)
return -ENOTSUPP;
}
+static inline int sdw_intel_link_power_up(struct sdw_intel *sdw)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, link_power_up))
+ return SDW_INTEL_OPS(sdw, link_power_up)(sdw);
+ return -ENOTSUPP;
+}
+
+static inline int sdw_intel_link_power_down(struct sdw_intel *sdw)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, link_power_down))
+ return SDW_INTEL_OPS(sdw, link_power_down)(sdw);
+ return -ENOTSUPP;
+}
+
#endif /* __SDW_INTEL_LOCAL_H */
diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h
index cee61bc9af8a..81430201b8b9 100644
--- a/include/linux/soundwire/sdw_intel.h
+++ b/include/linux/soundwire/sdw_intel.h
@@ -305,6 +305,8 @@ struct sdw_intel;
* @start_bus_after_reset: start after reset
* @start_bus_after_clock_stop: start after mode0 clock stop
* @stop_bus: stop all bus
+ * @link_power_up: power-up using chip-specific helpers
+ * @link_power_down: power-down with chip-specific helpers
* @pre_bank_switch: helper for bus management
* @post_bank_switch: helper for bus management
*/
@@ -320,6 +322,9 @@ struct sdw_intel_hw_ops {
int (*start_bus_after_clock_stop)(struct sdw_intel *sdw);
int (*stop_bus)(struct sdw_intel *sdw, bool clock_stop);
+ int (*link_power_up)(struct sdw_intel *sdw);
+ int (*link_power_down)(struct sdw_intel *sdw);
+
int (*pre_bank_switch)(struct sdw_intel *sdw);
int (*post_bank_switch)(struct sdw_intel *sdw);
};
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/7] soundwire: intel: add in-band wake callbacks in hw_ops
2022-11-11 1:31 [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Bard Liao
` (4 preceding siblings ...)
2022-11-11 1:31 ` [PATCH 5/7] soundwire: intel: add link power " Bard Liao
@ 2022-11-11 1:31 ` Bard Liao
2022-11-11 1:31 ` [PATCH 7/7] soundwire: intel: split auxdevice to different file Bard Liao
2022-11-23 14:42 ` [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Vinod Koul
7 siblings, 0 replies; 10+ messages in thread
From: Bard Liao @ 2022-11-11 1:31 UTC (permalink / raw)
To: alsa-devel, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, bard.liao
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
No functionality change, only add indirection for in-band wake
management helpers.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
---
drivers/soundwire/intel.c | 11 +++++++----
drivers/soundwire/intel.h | 13 +++++++++++++
include/linux/soundwire/sdw_intel.h | 5 +++++
3 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 2320f1b8a2d1..ea6479b4010d 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -1437,6 +1437,9 @@ const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops = {
.link_power_up = intel_link_power_up,
.link_power_down = intel_link_power_down,
+ .shim_check_wake = intel_shim_check_wake,
+ .shim_wake = intel_shim_wake,
+
.pre_bank_switch = intel_pre_bank_switch,
.post_bank_switch = intel_post_bank_switch,
};
@@ -1720,11 +1723,11 @@ int intel_link_process_wakeen_event(struct auxiliary_device *auxdev)
return 0;
}
- if (!intel_shim_check_wake(sdw))
+ if (!sdw_intel_shim_check_wake(sdw))
return 0;
/* disable WAKEEN interrupt ASAP to prevent interrupt flood */
- intel_shim_wake(sdw, false);
+ sdw_intel_shim_wake(sdw, false);
/*
* resume the Master, which will generate a bus reset and result in
@@ -1852,7 +1855,7 @@ static int __maybe_unused intel_suspend(struct device *dev)
*/
dev_err(dev, "%s: invalid config: parent is suspended\n", __func__);
} else {
- intel_shim_wake(sdw, false);
+ sdw_intel_shim_wake(sdw, false);
}
}
@@ -1987,7 +1990,7 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
}
/* unconditionally disable WAKEEN interrupt */
- intel_shim_wake(sdw, false);
+ sdw_intel_shim_wake(sdw, false);
clock_stop_quirks = sdw->link_res->clock_stop_quirks;
diff --git a/drivers/soundwire/intel.h b/drivers/soundwire/intel.h
index 0f63e7584132..9ac3397757a0 100644
--- a/drivers/soundwire/intel.h
+++ b/drivers/soundwire/intel.h
@@ -132,4 +132,17 @@ static inline int sdw_intel_link_power_down(struct sdw_intel *sdw)
return -ENOTSUPP;
}
+static inline int sdw_intel_shim_check_wake(struct sdw_intel *sdw)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, shim_check_wake))
+ return SDW_INTEL_OPS(sdw, shim_check_wake)(sdw);
+ return -ENOTSUPP;
+}
+
+static inline void sdw_intel_shim_wake(struct sdw_intel *sdw, bool wake_enable)
+{
+ if (SDW_INTEL_CHECK_OPS(sdw, shim_wake))
+ SDW_INTEL_OPS(sdw, shim_wake)(sdw, wake_enable);
+}
+
#endif /* __SDW_INTEL_LOCAL_H */
diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h
index 81430201b8b9..0942cd464095 100644
--- a/include/linux/soundwire/sdw_intel.h
+++ b/include/linux/soundwire/sdw_intel.h
@@ -307,6 +307,8 @@ struct sdw_intel;
* @stop_bus: stop all bus
* @link_power_up: power-up using chip-specific helpers
* @link_power_down: power-down with chip-specific helpers
+ * @shim_check_wake: check if a wake was received
+ * @shim_wake: enable/disable in-band wake management
* @pre_bank_switch: helper for bus management
* @post_bank_switch: helper for bus management
*/
@@ -325,6 +327,9 @@ struct sdw_intel_hw_ops {
int (*link_power_up)(struct sdw_intel *sdw);
int (*link_power_down)(struct sdw_intel *sdw);
+ int (*shim_check_wake)(struct sdw_intel *sdw);
+ void (*shim_wake)(struct sdw_intel *sdw, bool wake_enable);
+
int (*pre_bank_switch)(struct sdw_intel *sdw);
int (*post_bank_switch)(struct sdw_intel *sdw);
};
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/7] soundwire: intel: split auxdevice to different file
2022-11-11 1:31 [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Bard Liao
` (5 preceding siblings ...)
2022-11-11 1:31 ` [PATCH 6/7] soundwire: intel: add in-band wake " Bard Liao
@ 2022-11-11 1:31 ` Bard Liao
2022-11-11 1:47 ` Liao, Bard
2022-11-23 14:42 ` [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Vinod Koul
7 siblings, 1 reply; 10+ messages in thread
From: Bard Liao @ 2022-11-11 1:31 UTC (permalink / raw)
To: alsa-devel, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, bard.liao
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
The auxdevice layer is completely generic, it should be split from
intel.c which is only geared to the 'cnl' hw_ops now.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
---
drivers/soundwire/Makefile | 2 +-
drivers/soundwire/intel.c | 657 ---------------------------
drivers/soundwire/intel.h | 11 +-
drivers/soundwire/intel_auxdevice.c | 678 ++++++++++++++++++++++++++++
drivers/soundwire/intel_auxdevice.h | 18 +
drivers/soundwire/intel_init.c | 1 +
6 files changed, 700 insertions(+), 667 deletions(-)
create mode 100644 drivers/soundwire/intel_auxdevice.c
create mode 100644 drivers/soundwire/intel_auxdevice.h
diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
index 986776787b9e..ca97414ada70 100644
--- a/drivers/soundwire/Makefile
+++ b/drivers/soundwire/Makefile
@@ -20,7 +20,7 @@ soundwire-cadence-y := cadence_master.o
obj-$(CONFIG_SOUNDWIRE_CADENCE) += soundwire-cadence.o
#Intel driver
-soundwire-intel-y := intel.o intel_init.o dmi-quirks.o
+soundwire-intel-y := intel.o intel_auxdevice.o intel_init.o dmi-quirks.o
obj-$(CONFIG_SOUNDWIRE_INTEL) += soundwire-intel.o
#Qualcomm driver
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index ea6479b4010d..bc9c50bacc49 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -8,10 +8,7 @@
#include <linux/acpi.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
-#include <linux/auxiliary_bus.h>
#include <sound/pcm_params.h>
#include <linux/pm_runtime.h>
#include <sound/soc.h>
@@ -22,27 +19,6 @@
#include "bus.h"
#include "intel.h"
-/* IDA min selected to avoid conflicts with HDaudio/iDISP SDI values */
-#define INTEL_DEV_NUM_IDA_MIN 4
-
-#define INTEL_MASTER_SUSPEND_DELAY_MS 3000
-#define INTEL_MASTER_RESET_ITERATIONS 10
-
-/*
- * debug/config flags for the Intel SoundWire Master.
- *
- * Since we may have multiple masters active, we can have up to 8
- * flags reused in each byte, with master0 using the ls-byte, etc.
- */
-
-#define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME BIT(0)
-#define SDW_INTEL_MASTER_DISABLE_CLOCK_STOP BIT(1)
-#define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE BIT(2)
-#define SDW_INTEL_MASTER_DISABLE_MULTI_LINK BIT(3)
-
-static int md_flags;
-module_param_named(sdw_md_flags, md_flags, int, 0444);
-MODULE_PARM_DESC(sdw_md_flags, "SoundWire Intel Master device flags (0x0 all off)");
enum intel_pdi_type {
INTEL_PDI_IN = 0,
@@ -1445,636 +1421,3 @@ const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops = {
};
EXPORT_SYMBOL_NS(sdw_intel_cnl_hw_ops, SOUNDWIRE_INTEL);
-static int generic_pre_bank_switch(struct sdw_bus *bus)
-{
- struct sdw_cdns *cdns = bus_to_cdns(bus);
- struct sdw_intel *sdw = cdns_to_intel(cdns);
-
- return sdw->link_res->hw_ops->pre_bank_switch(sdw);
-}
-
-static int generic_post_bank_switch(struct sdw_bus *bus)
-{
- struct sdw_cdns *cdns = bus_to_cdns(bus);
- struct sdw_intel *sdw = cdns_to_intel(cdns);
-
- return sdw->link_res->hw_ops->post_bank_switch(sdw);
-}
-
-static int sdw_master_read_intel_prop(struct sdw_bus *bus)
-{
- struct sdw_master_prop *prop = &bus->prop;
- struct fwnode_handle *link;
- char name[32];
- u32 quirk_mask;
-
- /* Find master handle */
- snprintf(name, sizeof(name),
- "mipi-sdw-link-%d-subproperties", bus->link_id);
-
- link = device_get_named_child_node(bus->dev, name);
- if (!link) {
- dev_err(bus->dev, "Master node %s not found\n", name);
- return -EIO;
- }
-
- fwnode_property_read_u32(link,
- "intel-sdw-ip-clock",
- &prop->mclk_freq);
-
- /* the values reported by BIOS are the 2x clock, not the bus clock */
- prop->mclk_freq /= 2;
-
- fwnode_property_read_u32(link,
- "intel-quirk-mask",
- &quirk_mask);
-
- if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
- prop->hw_disabled = true;
-
- prop->quirks = SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH |
- SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY;
-
- return 0;
-}
-
-static int intel_prop_read(struct sdw_bus *bus)
-{
- /* Initialize with default handler to read all DisCo properties */
- sdw_master_read_prop(bus);
-
- /* read Intel-specific properties */
- sdw_master_read_intel_prop(bus);
-
- return 0;
-}
-
-static struct sdw_master_ops sdw_intel_ops = {
- .read_prop = intel_prop_read,
- .override_adr = sdw_dmi_override_adr,
- .xfer_msg = cdns_xfer_msg,
- .xfer_msg_defer = cdns_xfer_msg_defer,
- .reset_page_addr = cdns_reset_page_addr,
- .set_bus_conf = cdns_bus_conf,
- .pre_bank_switch = generic_pre_bank_switch,
- .post_bank_switch = generic_post_bank_switch,
- .read_ping_status = cdns_read_ping_status,
-};
-
-/*
- * probe and init (aux_dev_id argument is required by function prototype but not used)
- */
-static int intel_link_probe(struct auxiliary_device *auxdev,
- const struct auxiliary_device_id *aux_dev_id)
-
-{
- struct device *dev = &auxdev->dev;
- struct sdw_intel_link_dev *ldev = auxiliary_dev_to_sdw_intel_link_dev(auxdev);
- struct sdw_intel *sdw;
- struct sdw_cdns *cdns;
- struct sdw_bus *bus;
- int ret;
-
- sdw = devm_kzalloc(dev, sizeof(*sdw), GFP_KERNEL);
- if (!sdw)
- return -ENOMEM;
-
- cdns = &sdw->cdns;
- bus = &cdns->bus;
-
- sdw->instance = auxdev->id;
- sdw->link_res = &ldev->link_res;
- cdns->dev = dev;
- cdns->registers = sdw->link_res->registers;
- cdns->instance = sdw->instance;
- cdns->msg_count = 0;
-
- bus->link_id = auxdev->id;
- bus->dev_num_ida_min = INTEL_DEV_NUM_IDA_MIN;
- bus->clk_stop_timeout = 1;
-
- sdw_cdns_probe(cdns);
-
- /* Set ops */
- bus->ops = &sdw_intel_ops;
-
- /* set driver data, accessed by snd_soc_dai_get_drvdata() */
- auxiliary_set_drvdata(auxdev, cdns);
-
- /* use generic bandwidth allocation algorithm */
- sdw->cdns.bus.compute_params = sdw_compute_params;
-
- /* avoid resuming from pm_runtime suspend if it's not required */
- dev_pm_set_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
-
- ret = sdw_bus_master_add(bus, dev, dev->fwnode);
- if (ret) {
- dev_err(dev, "sdw_bus_master_add fail: %d\n", ret);
- return ret;
- }
-
- if (bus->prop.hw_disabled)
- dev_info(dev,
- "SoundWire master %d is disabled, will be ignored\n",
- bus->link_id);
- /*
- * Ignore BIOS err_threshold, it's a really bad idea when dealing
- * with multiple hardware synchronized links
- */
- bus->prop.err_threshold = 0;
-
- return 0;
-}
-
-int intel_link_startup(struct auxiliary_device *auxdev)
-{
- struct device *dev = &auxdev->dev;
- struct sdw_cdns *cdns = auxiliary_get_drvdata(auxdev);
- struct sdw_intel *sdw = cdns_to_intel(cdns);
- struct sdw_bus *bus = &cdns->bus;
- int link_flags;
- bool multi_link;
- u32 clock_stop_quirks;
- int ret;
-
- if (bus->prop.hw_disabled) {
- dev_info(dev,
- "SoundWire master %d is disabled, ignoring\n",
- sdw->instance);
- return 0;
- }
-
- link_flags = md_flags >> (bus->link_id * 8);
- multi_link = !(link_flags & SDW_INTEL_MASTER_DISABLE_MULTI_LINK);
- if (!multi_link) {
- dev_dbg(dev, "Multi-link is disabled\n");
- } else {
- /*
- * hardware-based synchronization is required regardless
- * of the number of segments used by a stream: SSP-based
- * synchronization is gated by gsync when the multi-master
- * mode is set.
- */
- bus->hw_sync_min_links = 1;
- }
- bus->multi_link = multi_link;
-
- /* Initialize shim, controller */
- ret = sdw_intel_link_power_up(sdw);
- if (ret)
- goto err_init;
-
- /* Register DAIs */
- ret = sdw_intel_register_dai(sdw);
- if (ret) {
- dev_err(dev, "DAI registration failed: %d\n", ret);
- goto err_power_up;
- }
-
- sdw_intel_debugfs_init(sdw);
-
- /* start bus */
- ret = sdw_intel_start_bus(sdw);
- if (ret) {
- dev_err(dev, "bus start failed: %d\n", ret);
- goto err_power_up;
- }
-
- /* Enable runtime PM */
- if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME)) {
- pm_runtime_set_autosuspend_delay(dev,
- INTEL_MASTER_SUSPEND_DELAY_MS);
- pm_runtime_use_autosuspend(dev);
- pm_runtime_mark_last_busy(dev);
-
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
- }
-
- clock_stop_quirks = sdw->link_res->clock_stop_quirks;
- if (clock_stop_quirks & SDW_INTEL_CLK_STOP_NOT_ALLOWED) {
- /*
- * To keep the clock running we need to prevent
- * pm_runtime suspend from happening by increasing the
- * reference count.
- * This quirk is specified by the parent PCI device in
- * case of specific latency requirements. It will have
- * no effect if pm_runtime is disabled by the user via
- * a module parameter for testing purposes.
- */
- pm_runtime_get_noresume(dev);
- }
-
- /*
- * The runtime PM status of Slave devices is "Unsupported"
- * until they report as ATTACHED. If they don't, e.g. because
- * there are no Slave devices populated or if the power-on is
- * delayed or dependent on a power switch, the Master will
- * remain active and prevent its parent from suspending.
- *
- * Conditionally force the pm_runtime core to re-evaluate the
- * Master status in the absence of any Slave activity. A quirk
- * is provided to e.g. deal with Slaves that may be powered on
- * with a delay. A more complete solution would require the
- * definition of Master properties.
- */
- if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE))
- pm_runtime_idle(dev);
-
- sdw->startup_done = true;
- return 0;
-
-err_power_up:
- sdw_intel_link_power_down(sdw);
-err_init:
- return ret;
-}
-
-static void intel_link_remove(struct auxiliary_device *auxdev)
-{
- struct sdw_cdns *cdns = auxiliary_get_drvdata(auxdev);
- struct sdw_intel *sdw = cdns_to_intel(cdns);
- struct sdw_bus *bus = &cdns->bus;
-
- /*
- * Since pm_runtime is already disabled, we don't decrease
- * the refcount when the clock_stop_quirk is
- * SDW_INTEL_CLK_STOP_NOT_ALLOWED
- */
- if (!bus->prop.hw_disabled) {
- sdw_intel_debugfs_exit(sdw);
- sdw_cdns_enable_interrupt(cdns, false);
- }
- sdw_bus_master_delete(bus);
-}
-
-int intel_link_process_wakeen_event(struct auxiliary_device *auxdev)
-{
- struct device *dev = &auxdev->dev;
- struct sdw_intel *sdw;
- struct sdw_bus *bus;
-
- sdw = auxiliary_get_drvdata(auxdev);
- bus = &sdw->cdns.bus;
-
- if (bus->prop.hw_disabled || !sdw->startup_done) {
- dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
- bus->link_id);
- return 0;
- }
-
- if (!sdw_intel_shim_check_wake(sdw))
- return 0;
-
- /* disable WAKEEN interrupt ASAP to prevent interrupt flood */
- sdw_intel_shim_wake(sdw, false);
-
- /*
- * resume the Master, which will generate a bus reset and result in
- * Slaves re-attaching and be re-enumerated. The SoundWire physical
- * device which generated the wake will trigger an interrupt, which
- * will in turn cause the corresponding Linux Slave device to be
- * resumed and the Slave codec driver to check the status.
- */
- pm_request_resume(dev);
-
- return 0;
-}
-
-/*
- * PM calls
- */
-
-static int intel_resume_child_device(struct device *dev, void *data)
-{
- int ret;
- struct sdw_slave *slave = dev_to_sdw_dev(dev);
-
- if (!slave->probed) {
- dev_dbg(dev, "skipping device, no probed driver\n");
- return 0;
- }
- if (!slave->dev_num_sticky) {
- dev_dbg(dev, "skipping device, never detected on bus\n");
- return 0;
- }
-
- ret = pm_request_resume(dev);
- if (ret < 0)
- dev_err(dev, "%s: pm_request_resume failed: %d\n", __func__, ret);
-
- return ret;
-}
-
-static int __maybe_unused intel_pm_prepare(struct device *dev)
-{
- struct sdw_cdns *cdns = dev_get_drvdata(dev);
- struct sdw_intel *sdw = cdns_to_intel(cdns);
- struct sdw_bus *bus = &cdns->bus;
- u32 clock_stop_quirks;
- int ret;
-
- if (bus->prop.hw_disabled || !sdw->startup_done) {
- dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
- bus->link_id);
- return 0;
- }
-
- clock_stop_quirks = sdw->link_res->clock_stop_quirks;
-
- if (pm_runtime_suspended(dev) &&
- pm_runtime_suspended(dev->parent) &&
- ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) ||
- !clock_stop_quirks)) {
- /*
- * if we've enabled clock stop, and the parent is suspended, the SHIM registers
- * are not accessible and the shim wake cannot be disabled.
- * The only solution is to resume the entire bus to full power
- */
-
- /*
- * If any operation in this block fails, we keep going since we don't want
- * to prevent system suspend from happening and errors should be recoverable
- * on resume.
- */
-
- /*
- * first resume the device for this link. This will also by construction
- * resume the PCI parent device.
- */
- ret = pm_request_resume(dev);
- if (ret < 0) {
- dev_err(dev, "%s: pm_request_resume failed: %d\n", __func__, ret);
- return 0;
- }
-
- /*
- * Continue resuming the entire bus (parent + child devices) to exit
- * the clock stop mode. If there are no devices connected on this link
- * this is a no-op.
- * The resume to full power could have been implemented with a .prepare
- * step in SoundWire codec drivers. This would however require a lot
- * of code to handle an Intel-specific corner case. It is simpler in
- * practice to add a loop at the link level.
- */
- ret = device_for_each_child(bus->dev, NULL, intel_resume_child_device);
-
- if (ret < 0)
- dev_err(dev, "%s: intel_resume_child_device failed: %d\n", __func__, ret);
- }
-
- return 0;
-}
-
-static int __maybe_unused intel_suspend(struct device *dev)
-{
- struct sdw_cdns *cdns = dev_get_drvdata(dev);
- struct sdw_intel *sdw = cdns_to_intel(cdns);
- struct sdw_bus *bus = &cdns->bus;
- u32 clock_stop_quirks;
- int ret;
-
- if (bus->prop.hw_disabled || !sdw->startup_done) {
- dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
- bus->link_id);
- return 0;
- }
-
- if (pm_runtime_suspended(dev)) {
- dev_dbg(dev, "pm_runtime status: suspended\n");
-
- clock_stop_quirks = sdw->link_res->clock_stop_quirks;
-
- if ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) ||
- !clock_stop_quirks) {
-
- if (pm_runtime_suspended(dev->parent)) {
- /*
- * paranoia check: this should not happen with the .prepare
- * resume to full power
- */
- dev_err(dev, "%s: invalid config: parent is suspended\n", __func__);
- } else {
- sdw_intel_shim_wake(sdw, false);
- }
- }
-
- return 0;
- }
-
- ret = sdw_intel_stop_bus(sdw, false);
- if (ret < 0) {
- dev_err(dev, "%s: cannot stop bus: %d\n", __func__, ret);
- return ret;
- }
-
- return 0;
-}
-
-static int __maybe_unused intel_suspend_runtime(struct device *dev)
-{
- struct sdw_cdns *cdns = dev_get_drvdata(dev);
- struct sdw_intel *sdw = cdns_to_intel(cdns);
- struct sdw_bus *bus = &cdns->bus;
- u32 clock_stop_quirks;
- int ret;
-
- if (bus->prop.hw_disabled || !sdw->startup_done) {
- dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
- bus->link_id);
- return 0;
- }
-
- clock_stop_quirks = sdw->link_res->clock_stop_quirks;
-
- if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) {
- ret = sdw_intel_stop_bus(sdw, false);
- if (ret < 0) {
- dev_err(dev, "%s: cannot stop bus during teardown: %d\n",
- __func__, ret);
- return ret;
- }
- } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET || !clock_stop_quirks) {
- ret = sdw_intel_stop_bus(sdw, true);
- if (ret < 0) {
- dev_err(dev, "%s: cannot stop bus during clock_stop: %d\n",
- __func__, ret);
- return ret;
- }
- } else {
- dev_err(dev, "%s clock_stop_quirks %x unsupported\n",
- __func__, clock_stop_quirks);
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int __maybe_unused intel_resume(struct device *dev)
-{
- struct sdw_cdns *cdns = dev_get_drvdata(dev);
- struct sdw_intel *sdw = cdns_to_intel(cdns);
- struct sdw_bus *bus = &cdns->bus;
- int link_flags;
- int ret;
-
- if (bus->prop.hw_disabled || !sdw->startup_done) {
- dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
- bus->link_id);
- return 0;
- }
-
- link_flags = md_flags >> (bus->link_id * 8);
-
- if (pm_runtime_suspended(dev)) {
- dev_dbg(dev, "pm_runtime status was suspended, forcing active\n");
-
- /* follow required sequence from runtime_pm.rst */
- pm_runtime_disable(dev);
- pm_runtime_set_active(dev);
- pm_runtime_mark_last_busy(dev);
- pm_runtime_enable(dev);
-
- link_flags = md_flags >> (bus->link_id * 8);
-
- if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE))
- pm_runtime_idle(dev);
- }
-
- ret = sdw_intel_link_power_up(sdw);
- if (ret) {
- dev_err(dev, "%s failed: %d\n", __func__, ret);
- return ret;
- }
-
- /*
- * make sure all Slaves are tagged as UNATTACHED and provide
- * reason for reinitialization
- */
- sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
-
- ret = sdw_intel_start_bus(sdw);
- if (ret < 0) {
- dev_err(dev, "cannot start bus during resume\n");
- sdw_intel_link_power_down(sdw);
- return ret;
- }
-
- /*
- * after system resume, the pm_runtime suspend() may kick in
- * during the enumeration, before any children device force the
- * master device to remain active. Using pm_runtime_get()
- * routines is not really possible, since it'd prevent the
- * master from suspending.
- * A reasonable compromise is to update the pm_runtime
- * counters and delay the pm_runtime suspend by several
- * seconds, by when all enumeration should be complete.
- */
- pm_runtime_mark_last_busy(dev);
-
- return 0;
-}
-
-static int __maybe_unused intel_resume_runtime(struct device *dev)
-{
- struct sdw_cdns *cdns = dev_get_drvdata(dev);
- struct sdw_intel *sdw = cdns_to_intel(cdns);
- struct sdw_bus *bus = &cdns->bus;
- u32 clock_stop_quirks;
- int ret;
-
- if (bus->prop.hw_disabled || !sdw->startup_done) {
- dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
- bus->link_id);
- return 0;
- }
-
- /* unconditionally disable WAKEEN interrupt */
- sdw_intel_shim_wake(sdw, false);
-
- clock_stop_quirks = sdw->link_res->clock_stop_quirks;
-
- if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) {
- ret = sdw_intel_link_power_up(sdw);
- if (ret) {
- dev_err(dev, "%s: power_up failed after teardown: %d\n", __func__, ret);
- return ret;
- }
-
- /*
- * make sure all Slaves are tagged as UNATTACHED and provide
- * reason for reinitialization
- */
- sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
-
- ret = sdw_intel_start_bus(sdw);
- if (ret < 0) {
- dev_err(dev, "%s: cannot start bus after teardown: %d\n", __func__, ret);
- sdw_intel_link_power_down(sdw);
- return ret;
- }
-
-
- } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) {
- ret = sdw_intel_link_power_up(sdw);
- if (ret) {
- dev_err(dev, "%s: power_up failed after bus reset: %d\n", __func__, ret);
- return ret;
- }
-
- ret = sdw_intel_start_bus_after_reset(sdw);
- if (ret < 0) {
- dev_err(dev, "%s: cannot start bus after reset: %d\n", __func__, ret);
- sdw_intel_link_power_down(sdw);
- return ret;
- }
- } else if (!clock_stop_quirks) {
-
- sdw_intel_check_clock_stop(sdw);
-
- ret = sdw_intel_link_power_up(sdw);
- if (ret) {
- dev_err(dev, "%s: power_up failed: %d\n", __func__, ret);
- return ret;
- }
-
- ret = sdw_intel_start_bus_after_clock_stop(sdw);
- if (ret < 0) {
- dev_err(dev, "%s: cannot start bus after clock stop: %d\n", __func__, ret);
- sdw_intel_link_power_down(sdw);
- return ret;
- }
- } else {
- dev_err(dev, "%s: clock_stop_quirks %x unsupported\n",
- __func__, clock_stop_quirks);
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static const struct dev_pm_ops intel_pm = {
- .prepare = intel_pm_prepare,
- SET_SYSTEM_SLEEP_PM_OPS(intel_suspend, intel_resume)
- SET_RUNTIME_PM_OPS(intel_suspend_runtime, intel_resume_runtime, NULL)
-};
-
-static const struct auxiliary_device_id intel_link_id_table[] = {
- { .name = "soundwire_intel.link" },
- {},
-};
-MODULE_DEVICE_TABLE(auxiliary, intel_link_id_table);
-
-static struct auxiliary_driver sdw_intel_drv = {
- .probe = intel_link_probe,
- .remove = intel_link_remove,
- .driver = {
- /* auxiliary_driver_register() sets .name to be the modname */
- .pm = &intel_pm,
- },
- .id_table = intel_link_id_table
-};
-module_auxiliary_driver(sdw_intel_drv);
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_DESCRIPTION("Intel Soundwire Link Driver");
diff --git a/drivers/soundwire/intel.h b/drivers/soundwire/intel.h
index 9ac3397757a0..de9883313c8f 100644
--- a/drivers/soundwire/intel.h
+++ b/drivers/soundwire/intel.h
@@ -50,16 +50,9 @@ struct sdw_intel {
#endif
};
-int intel_link_startup(struct auxiliary_device *auxdev);
-int intel_link_process_wakeen_event(struct auxiliary_device *auxdev);
+#define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns)
-struct sdw_intel_link_dev {
- struct auxiliary_device auxdev;
- struct sdw_intel_link_res link_res;
-};
-
-#define auxiliary_dev_to_sdw_intel_link_dev(auxiliary_dev) \
- container_of(auxiliary_dev, struct sdw_intel_link_dev, auxdev)
+#define INTEL_MASTER_RESET_ITERATIONS 10
#define SDW_INTEL_CHECK_OPS(sdw, cb) ((sdw) && (sdw)->link_res && (sdw)->link_res->hw_ops && \
(sdw)->link_res->hw_ops->cb)
diff --git a/drivers/soundwire/intel_auxdevice.c b/drivers/soundwire/intel_auxdevice.c
new file mode 100644
index 000000000000..96c6b2112feb
--- /dev/null
+++ b/drivers/soundwire/intel_auxdevice.c
@@ -0,0 +1,678 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+// Copyright(c) 2015-22 Intel Corporation.
+
+/*
+ * Soundwire Intel Manager Driver
+ */
+
+#include <linux/acpi.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/auxiliary_bus.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>
+#include <linux/soundwire/sdw_intel.h>
+#include "cadence_master.h"
+#include "bus.h"
+#include "intel.h"
+#include "intel_auxdevice.h"
+
+/* IDA min selected to avoid conflicts with HDaudio/iDISP SDI values */
+#define INTEL_DEV_NUM_IDA_MIN 4
+
+#define INTEL_MASTER_SUSPEND_DELAY_MS 3000
+
+/*
+ * debug/config flags for the Intel SoundWire Master.
+ *
+ * Since we may have multiple masters active, we can have up to 8
+ * flags reused in each byte, with master0 using the ls-byte, etc.
+ */
+
+#define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME BIT(0)
+#define SDW_INTEL_MASTER_DISABLE_CLOCK_STOP BIT(1)
+#define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE BIT(2)
+#define SDW_INTEL_MASTER_DISABLE_MULTI_LINK BIT(3)
+
+static int md_flags;
+module_param_named(sdw_md_flags, md_flags, int, 0444);
+MODULE_PARM_DESC(sdw_md_flags, "SoundWire Intel Master device flags (0x0 all off)");
+
+static int generic_pre_bank_switch(struct sdw_bus *bus)
+{
+ struct sdw_cdns *cdns = bus_to_cdns(bus);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+
+ return sdw->link_res->hw_ops->pre_bank_switch(sdw);
+}
+
+static int generic_post_bank_switch(struct sdw_bus *bus)
+{
+ struct sdw_cdns *cdns = bus_to_cdns(bus);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+
+ return sdw->link_res->hw_ops->post_bank_switch(sdw);
+}
+
+static int sdw_master_read_intel_prop(struct sdw_bus *bus)
+{
+ struct sdw_master_prop *prop = &bus->prop;
+ struct fwnode_handle *link;
+ char name[32];
+ u32 quirk_mask;
+
+ /* Find master handle */
+ snprintf(name, sizeof(name),
+ "mipi-sdw-link-%d-subproperties", bus->link_id);
+
+ link = device_get_named_child_node(bus->dev, name);
+ if (!link) {
+ dev_err(bus->dev, "Master node %s not found\n", name);
+ return -EIO;
+ }
+
+ fwnode_property_read_u32(link,
+ "intel-sdw-ip-clock",
+ &prop->mclk_freq);
+
+ /* the values reported by BIOS are the 2x clock, not the bus clock */
+ prop->mclk_freq /= 2;
+
+ fwnode_property_read_u32(link,
+ "intel-quirk-mask",
+ &quirk_mask);
+
+ if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
+ prop->hw_disabled = true;
+
+ prop->quirks = SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH |
+ SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY;
+
+ return 0;
+}
+
+static int intel_prop_read(struct sdw_bus *bus)
+{
+ /* Initialize with default handler to read all DisCo properties */
+ sdw_master_read_prop(bus);
+
+ /* read Intel-specific properties */
+ sdw_master_read_intel_prop(bus);
+
+ return 0;
+}
+
+static struct sdw_master_ops sdw_intel_ops = {
+ .read_prop = intel_prop_read,
+ .override_adr = sdw_dmi_override_adr,
+ .xfer_msg = cdns_xfer_msg,
+ .xfer_msg_defer = cdns_xfer_msg_defer,
+ .reset_page_addr = cdns_reset_page_addr,
+ .set_bus_conf = cdns_bus_conf,
+ .pre_bank_switch = generic_pre_bank_switch,
+ .post_bank_switch = generic_post_bank_switch,
+ .read_ping_status = cdns_read_ping_status,
+};
+
+/*
+ * probe and init (aux_dev_id argument is required by function prototype but not used)
+ */
+static int intel_link_probe(struct auxiliary_device *auxdev,
+ const struct auxiliary_device_id *aux_dev_id)
+
+{
+ struct device *dev = &auxdev->dev;
+ struct sdw_intel_link_dev *ldev = auxiliary_dev_to_sdw_intel_link_dev(auxdev);
+ struct sdw_intel *sdw;
+ struct sdw_cdns *cdns;
+ struct sdw_bus *bus;
+ int ret;
+
+ sdw = devm_kzalloc(dev, sizeof(*sdw), GFP_KERNEL);
+ if (!sdw)
+ return -ENOMEM;
+
+ cdns = &sdw->cdns;
+ bus = &cdns->bus;
+
+ sdw->instance = auxdev->id;
+ sdw->link_res = &ldev->link_res;
+ cdns->dev = dev;
+ cdns->registers = sdw->link_res->registers;
+ cdns->instance = sdw->instance;
+ cdns->msg_count = 0;
+
+ bus->link_id = auxdev->id;
+ bus->dev_num_ida_min = INTEL_DEV_NUM_IDA_MIN;
+ bus->clk_stop_timeout = 1;
+
+ sdw_cdns_probe(cdns);
+
+ /* Set ops */
+ bus->ops = &sdw_intel_ops;
+
+ /* set driver data, accessed by snd_soc_dai_get_drvdata() */
+ auxiliary_set_drvdata(auxdev, cdns);
+
+ /* use generic bandwidth allocation algorithm */
+ sdw->cdns.bus.compute_params = sdw_compute_params;
+
+ /* avoid resuming from pm_runtime suspend if it's not required */
+ dev_pm_set_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
+
+ ret = sdw_bus_master_add(bus, dev, dev->fwnode);
+ if (ret) {
+ dev_err(dev, "sdw_bus_master_add fail: %d\n", ret);
+ return ret;
+ }
+
+ if (bus->prop.hw_disabled)
+ dev_info(dev,
+ "SoundWire master %d is disabled, will be ignored\n",
+ bus->link_id);
+ /*
+ * Ignore BIOS err_threshold, it's a really bad idea when dealing
+ * with multiple hardware synchronized links
+ */
+ bus->prop.err_threshold = 0;
+
+ return 0;
+}
+
+int intel_link_startup(struct auxiliary_device *auxdev)
+{
+ struct device *dev = &auxdev->dev;
+ struct sdw_cdns *cdns = auxiliary_get_drvdata(auxdev);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+ struct sdw_bus *bus = &cdns->bus;
+ int link_flags;
+ bool multi_link;
+ u32 clock_stop_quirks;
+ int ret;
+
+ if (bus->prop.hw_disabled) {
+ dev_info(dev,
+ "SoundWire master %d is disabled, ignoring\n",
+ sdw->instance);
+ return 0;
+ }
+
+ link_flags = md_flags >> (bus->link_id * 8);
+ multi_link = !(link_flags & SDW_INTEL_MASTER_DISABLE_MULTI_LINK);
+ if (!multi_link) {
+ dev_dbg(dev, "Multi-link is disabled\n");
+ } else {
+ /*
+ * hardware-based synchronization is required regardless
+ * of the number of segments used by a stream: SSP-based
+ * synchronization is gated by gsync when the multi-master
+ * mode is set.
+ */
+ bus->hw_sync_min_links = 1;
+ }
+ bus->multi_link = multi_link;
+
+ /* Initialize shim, controller */
+ ret = sdw_intel_link_power_up(sdw);
+ if (ret)
+ goto err_init;
+
+ /* Register DAIs */
+ ret = sdw_intel_register_dai(sdw);
+ if (ret) {
+ dev_err(dev, "DAI registration failed: %d\n", ret);
+ goto err_power_up;
+ }
+
+ sdw_intel_debugfs_init(sdw);
+
+ /* start bus */
+ ret = sdw_intel_start_bus(sdw);
+ if (ret) {
+ dev_err(dev, "bus start failed: %d\n", ret);
+ goto err_power_up;
+ }
+
+ /* Enable runtime PM */
+ if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME)) {
+ pm_runtime_set_autosuspend_delay(dev,
+ INTEL_MASTER_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_mark_last_busy(dev);
+
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ }
+
+ clock_stop_quirks = sdw->link_res->clock_stop_quirks;
+ if (clock_stop_quirks & SDW_INTEL_CLK_STOP_NOT_ALLOWED) {
+ /*
+ * To keep the clock running we need to prevent
+ * pm_runtime suspend from happening by increasing the
+ * reference count.
+ * This quirk is specified by the parent PCI device in
+ * case of specific latency requirements. It will have
+ * no effect if pm_runtime is disabled by the user via
+ * a module parameter for testing purposes.
+ */
+ pm_runtime_get_noresume(dev);
+ }
+
+ /*
+ * The runtime PM status of Slave devices is "Unsupported"
+ * until they report as ATTACHED. If they don't, e.g. because
+ * there are no Slave devices populated or if the power-on is
+ * delayed or dependent on a power switch, the Master will
+ * remain active and prevent its parent from suspending.
+ *
+ * Conditionally force the pm_runtime core to re-evaluate the
+ * Master status in the absence of any Slave activity. A quirk
+ * is provided to e.g. deal with Slaves that may be powered on
+ * with a delay. A more complete solution would require the
+ * definition of Master properties.
+ */
+ if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE))
+ pm_runtime_idle(dev);
+
+ sdw->startup_done = true;
+ return 0;
+
+err_power_up:
+ sdw_intel_link_power_down(sdw);
+err_init:
+ return ret;
+}
+
+static void intel_link_remove(struct auxiliary_device *auxdev)
+{
+ struct sdw_cdns *cdns = auxiliary_get_drvdata(auxdev);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+ struct sdw_bus *bus = &cdns->bus;
+
+ /*
+ * Since pm_runtime is already disabled, we don't decrease
+ * the refcount when the clock_stop_quirk is
+ * SDW_INTEL_CLK_STOP_NOT_ALLOWED
+ */
+ if (!bus->prop.hw_disabled) {
+ sdw_intel_debugfs_exit(sdw);
+ sdw_cdns_enable_interrupt(cdns, false);
+ }
+ sdw_bus_master_delete(bus);
+}
+
+int intel_link_process_wakeen_event(struct auxiliary_device *auxdev)
+{
+ struct device *dev = &auxdev->dev;
+ struct sdw_intel *sdw;
+ struct sdw_bus *bus;
+
+ sdw = auxiliary_get_drvdata(auxdev);
+ bus = &sdw->cdns.bus;
+
+ if (bus->prop.hw_disabled || !sdw->startup_done) {
+ dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
+ bus->link_id);
+ return 0;
+ }
+
+ if (!sdw_intel_shim_check_wake(sdw))
+ return 0;
+
+ /* disable WAKEEN interrupt ASAP to prevent interrupt flood */
+ sdw_intel_shim_wake(sdw, false);
+
+ /*
+ * resume the Master, which will generate a bus reset and result in
+ * Slaves re-attaching and be re-enumerated. The SoundWire physical
+ * device which generated the wake will trigger an interrupt, which
+ * will in turn cause the corresponding Linux Slave device to be
+ * resumed and the Slave codec driver to check the status.
+ */
+ pm_request_resume(dev);
+
+ return 0;
+}
+
+/*
+ * PM calls
+ */
+
+static int intel_resume_child_device(struct device *dev, void *data)
+{
+ int ret;
+ struct sdw_slave *slave = dev_to_sdw_dev(dev);
+
+ if (!slave->probed) {
+ dev_dbg(dev, "skipping device, no probed driver\n");
+ return 0;
+ }
+ if (!slave->dev_num_sticky) {
+ dev_dbg(dev, "skipping device, never detected on bus\n");
+ return 0;
+ }
+
+ ret = pm_request_resume(dev);
+ if (ret < 0)
+ dev_err(dev, "%s: pm_request_resume failed: %d\n", __func__, ret);
+
+ return ret;
+}
+
+static int __maybe_unused intel_pm_prepare(struct device *dev)
+{
+ struct sdw_cdns *cdns = dev_get_drvdata(dev);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+ struct sdw_bus *bus = &cdns->bus;
+ u32 clock_stop_quirks;
+ int ret;
+
+ if (bus->prop.hw_disabled || !sdw->startup_done) {
+ dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
+ bus->link_id);
+ return 0;
+ }
+
+ clock_stop_quirks = sdw->link_res->clock_stop_quirks;
+
+ if (pm_runtime_suspended(dev) &&
+ pm_runtime_suspended(dev->parent) &&
+ ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) ||
+ !clock_stop_quirks)) {
+ /*
+ * if we've enabled clock stop, and the parent is suspended, the SHIM registers
+ * are not accessible and the shim wake cannot be disabled.
+ * The only solution is to resume the entire bus to full power
+ */
+
+ /*
+ * If any operation in this block fails, we keep going since we don't want
+ * to prevent system suspend from happening and errors should be recoverable
+ * on resume.
+ */
+
+ /*
+ * first resume the device for this link. This will also by construction
+ * resume the PCI parent device.
+ */
+ ret = pm_request_resume(dev);
+ if (ret < 0) {
+ dev_err(dev, "%s: pm_request_resume failed: %d\n", __func__, ret);
+ return 0;
+ }
+
+ /*
+ * Continue resuming the entire bus (parent + child devices) to exit
+ * the clock stop mode. If there are no devices connected on this link
+ * this is a no-op.
+ * The resume to full power could have been implemented with a .prepare
+ * step in SoundWire codec drivers. This would however require a lot
+ * of code to handle an Intel-specific corner case. It is simpler in
+ * practice to add a loop at the link level.
+ */
+ ret = device_for_each_child(bus->dev, NULL, intel_resume_child_device);
+
+ if (ret < 0)
+ dev_err(dev, "%s: intel_resume_child_device failed: %d\n", __func__, ret);
+ }
+
+ return 0;
+}
+
+static int __maybe_unused intel_suspend(struct device *dev)
+{
+ struct sdw_cdns *cdns = dev_get_drvdata(dev);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+ struct sdw_bus *bus = &cdns->bus;
+ u32 clock_stop_quirks;
+ int ret;
+
+ if (bus->prop.hw_disabled || !sdw->startup_done) {
+ dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
+ bus->link_id);
+ return 0;
+ }
+
+ if (pm_runtime_suspended(dev)) {
+ dev_dbg(dev, "pm_runtime status: suspended\n");
+
+ clock_stop_quirks = sdw->link_res->clock_stop_quirks;
+
+ if ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) ||
+ !clock_stop_quirks) {
+
+ if (pm_runtime_suspended(dev->parent)) {
+ /*
+ * paranoia check: this should not happen with the .prepare
+ * resume to full power
+ */
+ dev_err(dev, "%s: invalid config: parent is suspended\n", __func__);
+ } else {
+ sdw_intel_shim_wake(sdw, false);
+ }
+ }
+
+ return 0;
+ }
+
+ ret = sdw_intel_stop_bus(sdw, false);
+ if (ret < 0) {
+ dev_err(dev, "%s: cannot stop bus: %d\n", __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __maybe_unused intel_suspend_runtime(struct device *dev)
+{
+ struct sdw_cdns *cdns = dev_get_drvdata(dev);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+ struct sdw_bus *bus = &cdns->bus;
+ u32 clock_stop_quirks;
+ int ret;
+
+ if (bus->prop.hw_disabled || !sdw->startup_done) {
+ dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
+ bus->link_id);
+ return 0;
+ }
+
+ clock_stop_quirks = sdw->link_res->clock_stop_quirks;
+
+ if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) {
+ ret = sdw_intel_stop_bus(sdw, false);
+ if (ret < 0) {
+ dev_err(dev, "%s: cannot stop bus during teardown: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET || !clock_stop_quirks) {
+ ret = sdw_intel_stop_bus(sdw, true);
+ if (ret < 0) {
+ dev_err(dev, "%s: cannot stop bus during clock_stop: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ } else {
+ dev_err(dev, "%s clock_stop_quirks %x unsupported\n",
+ __func__, clock_stop_quirks);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int __maybe_unused intel_resume(struct device *dev)
+{
+ struct sdw_cdns *cdns = dev_get_drvdata(dev);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+ struct sdw_bus *bus = &cdns->bus;
+ int link_flags;
+ int ret;
+
+ if (bus->prop.hw_disabled || !sdw->startup_done) {
+ dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
+ bus->link_id);
+ return 0;
+ }
+
+ link_flags = md_flags >> (bus->link_id * 8);
+
+ if (pm_runtime_suspended(dev)) {
+ dev_dbg(dev, "pm_runtime status was suspended, forcing active\n");
+
+ /* follow required sequence from runtime_pm.rst */
+ pm_runtime_disable(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_enable(dev);
+
+ link_flags = md_flags >> (bus->link_id * 8);
+
+ if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE))
+ pm_runtime_idle(dev);
+ }
+
+ ret = sdw_intel_link_power_up(sdw);
+ if (ret) {
+ dev_err(dev, "%s failed: %d\n", __func__, ret);
+ return ret;
+ }
+
+ /*
+ * make sure all Slaves are tagged as UNATTACHED and provide
+ * reason for reinitialization
+ */
+ sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
+
+ ret = sdw_intel_start_bus(sdw);
+ if (ret < 0) {
+ dev_err(dev, "cannot start bus during resume\n");
+ sdw_intel_link_power_down(sdw);
+ return ret;
+ }
+
+ /*
+ * after system resume, the pm_runtime suspend() may kick in
+ * during the enumeration, before any children device force the
+ * master device to remain active. Using pm_runtime_get()
+ * routines is not really possible, since it'd prevent the
+ * master from suspending.
+ * A reasonable compromise is to update the pm_runtime
+ * counters and delay the pm_runtime suspend by several
+ * seconds, by when all enumeration should be complete.
+ */
+ pm_runtime_mark_last_busy(dev);
+
+ return 0;
+}
+
+static int __maybe_unused intel_resume_runtime(struct device *dev)
+{
+ struct sdw_cdns *cdns = dev_get_drvdata(dev);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+ struct sdw_bus *bus = &cdns->bus;
+ u32 clock_stop_quirks;
+ int ret;
+
+ if (bus->prop.hw_disabled || !sdw->startup_done) {
+ dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
+ bus->link_id);
+ return 0;
+ }
+
+ /* unconditionally disable WAKEEN interrupt */
+ sdw_intel_shim_wake(sdw, false);
+
+ clock_stop_quirks = sdw->link_res->clock_stop_quirks;
+
+ if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) {
+ ret = sdw_intel_link_power_up(sdw);
+ if (ret) {
+ dev_err(dev, "%s: power_up failed after teardown: %d\n", __func__, ret);
+ return ret;
+ }
+
+ /*
+ * make sure all Slaves are tagged as UNATTACHED and provide
+ * reason for reinitialization
+ */
+ sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
+
+ ret = sdw_intel_start_bus(sdw);
+ if (ret < 0) {
+ dev_err(dev, "%s: cannot start bus after teardown: %d\n", __func__, ret);
+ sdw_intel_link_power_down(sdw);
+ return ret;
+ }
+
+ } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) {
+ ret = sdw_intel_link_power_up(sdw);
+ if (ret) {
+ dev_err(dev, "%s: power_up failed after bus reset: %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = sdw_intel_start_bus_after_reset(sdw);
+ if (ret < 0) {
+ dev_err(dev, "%s: cannot start bus after reset: %d\n", __func__, ret);
+ sdw_intel_link_power_down(sdw);
+ return ret;
+ }
+ } else if (!clock_stop_quirks) {
+
+ sdw_intel_check_clock_stop(sdw);
+
+ ret = sdw_intel_link_power_up(sdw);
+ if (ret) {
+ dev_err(dev, "%s: power_up failed: %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = sdw_intel_start_bus_after_clock_stop(sdw);
+ if (ret < 0) {
+ dev_err(dev, "%s: cannot start bus after clock stop: %d\n", __func__, ret);
+ sdw_intel_link_power_down(sdw);
+ return ret;
+ }
+ } else {
+ dev_err(dev, "%s: clock_stop_quirks %x unsupported\n",
+ __func__, clock_stop_quirks);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct dev_pm_ops intel_pm = {
+ .prepare = intel_pm_prepare,
+ SET_SYSTEM_SLEEP_PM_OPS(intel_suspend, intel_resume)
+ SET_RUNTIME_PM_OPS(intel_suspend_runtime, intel_resume_runtime, NULL)
+};
+
+static const struct auxiliary_device_id intel_link_id_table[] = {
+ { .name = "soundwire_intel.link" },
+ {},
+};
+MODULE_DEVICE_TABLE(auxiliary, intel_link_id_table);
+
+static struct auxiliary_driver sdw_intel_drv = {
+ .probe = intel_link_probe,
+ .remove = intel_link_remove,
+ .driver = {
+ /* auxiliary_driver_register() sets .name to be the modname */
+ .pm = &intel_pm,
+ },
+ .id_table = intel_link_id_table
+};
+module_auxiliary_driver(sdw_intel_drv);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("Intel Soundwire Link Driver");
diff --git a/drivers/soundwire/intel_auxdevice.h b/drivers/soundwire/intel_auxdevice.h
new file mode 100644
index 000000000000..a00ecde95563
--- /dev/null
+++ b/drivers/soundwire/intel_auxdevice.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
+/* Copyright(c) 2015-2022 Intel Corporation. */
+
+#ifndef __SDW_INTEL_AUXDEVICE_H
+#define __SDW_INTEL_AUXDEVICE_H
+
+int intel_link_startup(struct auxiliary_device *auxdev);
+int intel_link_process_wakeen_event(struct auxiliary_device *auxdev);
+
+struct sdw_intel_link_dev {
+ struct auxiliary_device auxdev;
+ struct sdw_intel_link_res link_res;
+};
+
+#define auxiliary_dev_to_sdw_intel_link_dev(auxiliary_dev) \
+ container_of(auxiliary_dev, struct sdw_intel_link_dev, auxdev)
+
+#endif /* __SDW_INTEL_AUXDEVICE_H */
diff --git a/drivers/soundwire/intel_init.c b/drivers/soundwire/intel_init.c
index 1e6d74b3e773..b3a8db7c3b77 100644
--- a/drivers/soundwire/intel_init.c
+++ b/drivers/soundwire/intel_init.c
@@ -17,6 +17,7 @@
#include <linux/soundwire/sdw_intel.h>
#include "cadence_master.h"
#include "intel.h"
+#include "intel_auxdevice.h"
static void intel_link_dev_release(struct device *dev)
{
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* RE: [PATCH 7/7] soundwire: intel: split auxdevice to different file
2022-11-11 1:31 ` [PATCH 7/7] soundwire: intel: split auxdevice to different file Bard Liao
@ 2022-11-11 1:47 ` Liao, Bard
0 siblings, 0 replies; 10+ messages in thread
From: Liao, Bard @ 2022-11-11 1:47 UTC (permalink / raw)
To: Bard Liao, alsa-devel, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart
> -----Original Message-----
> From: Bard Liao <yung-chuan.liao@linux.intel.com>
> Sent: Friday, November 11, 2022 9:32 AM
> To: alsa-devel@alsa-project.org; vkoul@kernel.org
> Cc: vinod.koul@linaro.org; linux-kernel@vger.kernel.org; pierre-
> louis.bossart@linux.intel.com; Liao, Bard <bard.liao@intel.com>
> Subject: [PATCH 7/7] soundwire: intel: split auxdevice to different file
>
> From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>
> The auxdevice layer is completely generic, it should be split from
> intel.c which is only geared to the 'cnl' hw_ops now.
>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Reviewed-by: Rander Wang <rander.wang@intel.com>
> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Hi Vinod,
Note that "soundwire: intel: Initialize clock stop timeout" which is in
your fixes branch, but not in your next branch is needed before applying
this patch.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file
2022-11-11 1:31 [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Bard Liao
` (6 preceding siblings ...)
2022-11-11 1:31 ` [PATCH 7/7] soundwire: intel: split auxdevice to different file Bard Liao
@ 2022-11-23 14:42 ` Vinod Koul
7 siblings, 0 replies; 10+ messages in thread
From: Vinod Koul @ 2022-11-23 14:42 UTC (permalink / raw)
To: Bard Liao; +Cc: alsa-devel, linux-kernel, pierre-louis.bossart, bard.liao
On 11-11-22, 09:31, Bard Liao wrote:
> This series adds yet another set of cleanups
> a) all the helpers are now exposed as hw_ops callbacks
> b) the auxiliary device code is now completely generic.
>
> This will allow for easier introduction of new hw_ops implementations in
> the future without throwing away all the goodness of the auxiliary device
> handling. Since there will be a tighter coupling with HDaudio, it's likely
> that future hw_ops are implemented in the SOF driver directly.
Applied, thanks
--
~Vinod
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2022-11-23 14:42 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-11 1:31 [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Bard Liao
2022-11-11 1:31 ` [PATCH 1/7] soundwire: intel: start using hw_ops Bard Liao
2022-11-11 1:31 ` [PATCH 2/7] soundwire: intel: add debugfs callbacks in hw_ops Bard Liao
2022-11-11 1:31 ` [PATCH 3/7] soundwire: intel: add register_dai callback " Bard Liao
2022-11-11 1:31 ` [PATCH 4/7] soundwire: intel: add bus management callbacks " Bard Liao
2022-11-11 1:31 ` [PATCH 5/7] soundwire: intel: add link power " Bard Liao
2022-11-11 1:31 ` [PATCH 6/7] soundwire: intel: add in-band wake " Bard Liao
2022-11-11 1:31 ` [PATCH 7/7] soundwire: intel: split auxdevice to different file Bard Liao
2022-11-11 1:47 ` Liao, Bard
2022-11-23 14:42 ` [PATCH 0/7] soundwire: intel: introduce hw_ops and move auxdevice handling to dedicated file Vinod Koul
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).