2022-02-10 14:05:57

by Péter Ujfalusi

[permalink] [raw]
Subject: [PATCH 0/9] ASoC: SOF: IPC client infrastructure

Hi,

The Linux SOF implementation is historically monolithic in a sense that all
features accessible in the firmware can be used via the snd_sof_dev struct in
one way or another.

Support for features can not be added or removed runtime and with the current
way of things it is hard if not impossible to implement support for dynamic
feature support when based on the firmware manifest we can easily enable/access
independent modules with the SOF.

In order to be able to support such modularity this series introduces a small
framework within SOF for client support using the Auxiliary bus.

Client drivers can be removed runtime and later re-loaded if needed without
affecting the core's behaviour, but it is the core's and the platform's duty
to create the Auxiliary devices usable in the platform and via the firmware.

There is still a need for SOF manifest update to convey information about
features to really make the full dynamic client device creation.

The series will introduce the core SOF client support and converts the generic
ipc flood test, ipc message injector and the probes (Intel HDA only) to a client
driver.

Regards,
Peter
---
Peter Ujfalusi (8):
ASoC: SOF: Drop unused DSP power states: D3_HOT and D3_COLD
ASoC: SOF: Move the definition of enum sof_dsp_power_states to global
header
ASoC: SOF: ipc: Read and pass the whole message to handlers for IPC
events
ASoC: SOF: Split up utils.c into sof-utils and iomem-utils
ASoC: SOF: Introduce IPC SOF client support
ASoC: SOF: sof-client: Add support for clients not managed by pm
framework
ASoC: SOF: Convert the generic IPC message injector into SOF client
ASoC: SOF: Convert the generic probe support to SOF client

Ranjani Sridharan (1):
ASoC: SOF: Convert the generic IPC flood test into SOF client

include/sound/sof.h | 8 +
sound/soc/sof/Kconfig | 33 +-
sound/soc/sof/Makefile | 15 +-
sound/soc/sof/core.c | 50 +-
sound/soc/sof/debug.c | 565 --------------
sound/soc/sof/intel/Kconfig | 19 +-
sound/soc/sof/intel/apl.c | 13 +-
sound/soc/sof/intel/cnl.c | 13 +-
sound/soc/sof/intel/hda-dai.c | 19 -
sound/soc/sof/intel/hda-dsp.c | 6 -
sound/soc/sof/intel/hda-probes.c | 72 +-
sound/soc/sof/intel/hda.c | 10 +
sound/soc/sof/intel/hda.h | 49 +-
sound/soc/sof/intel/icl.c | 13 +-
sound/soc/sof/intel/tgl.c | 13 +-
sound/soc/sof/{utils.c => iomem-utils.c} | 61 +-
sound/soc/sof/ipc.c | 88 ++-
sound/soc/sof/ops.h | 43 -
sound/soc/sof/pcm.c | 7 +-
sound/soc/sof/pm.c | 13 +-
sound/soc/sof/sof-client-ipc-flood-test.c | 396 ++++++++++
sound/soc/sof/sof-client-ipc-msg-injector.c | 192 +++++
sound/soc/sof/sof-client-probes.c | 821 ++++++++++++++++++++
sound/soc/sof/sof-client-probes.h | 31 +
sound/soc/sof/sof-client.c | 469 +++++++++++
sound/soc/sof/sof-client.h | 67 ++
sound/soc/sof/sof-priv.h | 139 ++--
sound/soc/sof/sof-probes.c | 364 ---------
sound/soc/sof/sof-probes.h | 38 -
sound/soc/sof/sof-utils.c | 77 ++
sound/soc/sof/sof-utils.h | 19 +
sound/soc/sof/trace.c | 1 +
32 files changed, 2415 insertions(+), 1309 deletions(-)
rename sound/soc/sof/{utils.c => iomem-utils.c} (59%)
create mode 100644 sound/soc/sof/sof-client-ipc-flood-test.c
create mode 100644 sound/soc/sof/sof-client-ipc-msg-injector.c
create mode 100644 sound/soc/sof/sof-client-probes.c
create mode 100644 sound/soc/sof/sof-client-probes.h
create mode 100644 sound/soc/sof/sof-client.c
create mode 100644 sound/soc/sof/sof-client.h
delete mode 100644 sound/soc/sof/sof-probes.c
delete mode 100644 sound/soc/sof/sof-probes.h
create mode 100644 sound/soc/sof/sof-utils.c
create mode 100644 sound/soc/sof/sof-utils.h

--
2.35.1



2022-02-10 16:27:15

by Péter Ujfalusi

[permalink] [raw]
Subject: [PATCH 4/9] ASoC: SOF: Split up utils.c into sof-utils and iomem-utils

The utils.c contains wrappers and implementation for accessing iomem mapped
regions and a single unrelated function to create a compressed page table
from snd_dma_buffer for firmware use.

The latter is used by the PCM and the dma trace code and it needs to be
moved to a generic source/header for the client conversion to be possible.

Signed-off-by: Peter Ujfalusi <[email protected]>
Reviewed-by: Kai Vehmanen <[email protected]>
Reviewed-by: Pierre-Louis Bossart <[email protected]>
Reviewed-by: Ranjani Sridharan <[email protected]>
---
sound/soc/sof/Makefile | 5 +-
sound/soc/sof/{utils.c => iomem-utils.c} | 61 +------------------
sound/soc/sof/pcm.c | 1 +
sound/soc/sof/sof-priv.h | 4 --
sound/soc/sof/sof-utils.c | 77 ++++++++++++++++++++++++
sound/soc/sof/sof-utils.h | 19 ++++++
sound/soc/sof/trace.c | 1 +
7 files changed, 103 insertions(+), 65 deletions(-)
rename sound/soc/sof/{utils.c => iomem-utils.c} (59%)
create mode 100644 sound/soc/sof/sof-utils.c
create mode 100644 sound/soc/sof/sof-utils.h

diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile
index 964b429146be..4b9fccacc2b7 100644
--- a/sound/soc/sof/Makefile
+++ b/sound/soc/sof/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)

snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\
- control.o trace.o utils.o sof-audio.o stream-ipc.o
+ control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o

snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += sof-probes.o
snd-sof-$(CONFIG_SND_SOC_SOF_COMPRESS) += compress.o
@@ -12,9 +12,12 @@ snd-sof-of-objs := sof-of-dev.o

snd-sof-nocodec-objs := nocodec.o

+snd-sof-utils-objs := sof-utils.o
+
obj-$(CONFIG_SND_SOC_SOF) += snd-sof.o
obj-$(CONFIG_SND_SOC_SOF_NOCODEC) += snd-sof-nocodec.o

+obj-$(CONFIG_SND_SOC_SOF) += snd-sof-utils.o

obj-$(CONFIG_SND_SOC_SOF_ACPI_DEV) += snd-sof-acpi.o
obj-$(CONFIG_SND_SOC_SOF_OF_DEV) += snd-sof-of.o
diff --git a/sound/soc/sof/utils.c b/sound/soc/sof/iomem-utils.c
similarity index 59%
rename from sound/soc/sof/utils.c
rename to sound/soc/sof/iomem-utils.c
index 66fa6602fb67..3f57f6cf6542 100644
--- a/sound/soc/sof/utils.c
+++ b/sound/soc/sof/iomem-utils.c
@@ -3,7 +3,7 @@
// This file is provided under a dual BSD/GPLv2 license. When using or
// redistributing this file, you may do so under either license.
//
-// Copyright(c) 2018 Intel Corporation. All rights reserved.
+// Copyright(c) 2018-2022 Intel Corporation. All rights reserved.
//
// Author: Keyon Jie <[email protected]>
//
@@ -125,62 +125,3 @@ int sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
return 0;
}
EXPORT_SYMBOL(sof_block_read);
-
-/*
- * Generic buffer page table creation.
- * Take the each physical page address and drop the least significant unused
- * bits from each (based on PAGE_SIZE). Then pack valid page address bits
- * into compressed page table.
- */
-
-int snd_sof_create_page_table(struct device *dev,
- struct snd_dma_buffer *dmab,
- unsigned char *page_table, size_t size)
-{
- int i, pages;
-
- pages = snd_sgbuf_aligned_pages(size);
-
- dev_dbg(dev, "generating page table for %p size 0x%zx pages %d\n",
- dmab->area, size, pages);
-
- for (i = 0; i < pages; i++) {
- /*
- * The number of valid address bits for each page is 20.
- * idx determines the byte position within page_table
- * where the current page's address is stored
- * in the compressed page_table.
- * This can be calculated by multiplying the page number by 2.5.
- */
- u32 idx = (5 * i) >> 1;
- u32 pfn = snd_sgbuf_get_addr(dmab, i * PAGE_SIZE) >> PAGE_SHIFT;
- u8 *pg_table;
-
- dev_vdbg(dev, "pfn i %i idx %d pfn %x\n", i, idx, pfn);
-
- pg_table = (u8 *)(page_table + idx);
-
- /*
- * pagetable compression:
- * byte 0 byte 1 byte 2 byte 3 byte 4 byte 5
- * ___________pfn 0__________ __________pfn 1___________ _pfn 2...
- * .... .... .... .... .... .... .... .... .... .... ....
- * It is created by:
- * 1. set current location to 0, PFN index i to 0
- * 2. put pfn[i] at current location in Little Endian byte order
- * 3. calculate an intermediate value as
- * x = (pfn[i+1] << 4) | (pfn[i] & 0xf)
- * 4. put x at offset (current location + 2) in LE byte order
- * 5. increment current location by 5 bytes, increment i by 2
- * 6. continue to (2)
- */
- if (i & 1)
- put_unaligned_le32((pg_table[0] & 0xf) | pfn << 4,
- pg_table);
- else
- put_unaligned_le32(pfn, pg_table);
- }
-
- return pages;
-}
-EXPORT_SYMBOL(snd_sof_create_page_table);
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 37fb8e6cd493..62cb61655761 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -19,6 +19,7 @@
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
#include "sof-probes.h"
#endif
+#include "sof-utils.h"

/* Create DMA buffer page table for DSP */
static int create_page_table(struct snd_soc_component *component,
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 2e474048d708..27d2f3ca2f06 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -502,10 +502,6 @@ void snd_sof_complete(struct device *dev);

void snd_sof_new_platform_drv(struct snd_sof_dev *sdev);

-int snd_sof_create_page_table(struct device *dev,
- struct snd_dma_buffer *dmab,
- unsigned char *page_table, size_t size);
-
/*
* Firmware loading.
*/
diff --git a/sound/soc/sof/sof-utils.c b/sound/soc/sof/sof-utils.c
new file mode 100644
index 000000000000..a3300ecee062
--- /dev/null
+++ b/sound/soc/sof/sof-utils.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2018-2022 Intel Corporation. All rights reserved.
+//
+// Author: Keyon Jie <[email protected]>
+//
+
+#include <asm/unaligned.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/device.h>
+#include <sound/memalloc.h>
+#include <linux/module.h>
+#include "sof-utils.h"
+
+/*
+ * Generic buffer page table creation.
+ * Take the each physical page address and drop the least significant unused
+ * bits from each (based on PAGE_SIZE). Then pack valid page address bits
+ * into compressed page table.
+ */
+
+int snd_sof_create_page_table(struct device *dev,
+ struct snd_dma_buffer *dmab,
+ unsigned char *page_table, size_t size)
+{
+ int i, pages;
+
+ pages = snd_sgbuf_aligned_pages(size);
+
+ dev_dbg(dev, "generating page table for %p size 0x%zx pages %d\n",
+ dmab->area, size, pages);
+
+ for (i = 0; i < pages; i++) {
+ /*
+ * The number of valid address bits for each page is 20.
+ * idx determines the byte position within page_table
+ * where the current page's address is stored
+ * in the compressed page_table.
+ * This can be calculated by multiplying the page number by 2.5.
+ */
+ u32 idx = (5 * i) >> 1;
+ u32 pfn = snd_sgbuf_get_addr(dmab, i * PAGE_SIZE) >> PAGE_SHIFT;
+ u8 *pg_table;
+
+ dev_vdbg(dev, "pfn i %i idx %d pfn %x\n", i, idx, pfn);
+
+ pg_table = (u8 *)(page_table + idx);
+
+ /*
+ * pagetable compression:
+ * byte 0 byte 1 byte 2 byte 3 byte 4 byte 5
+ * ___________pfn 0__________ __________pfn 1___________ _pfn 2...
+ * .... .... .... .... .... .... .... .... .... .... ....
+ * It is created by:
+ * 1. set current location to 0, PFN index i to 0
+ * 2. put pfn[i] at current location in Little Endian byte order
+ * 3. calculate an intermediate value as
+ * x = (pfn[i+1] << 4) | (pfn[i] & 0xf)
+ * 4. put x at offset (current location + 2) in LE byte order
+ * 5. increment current location by 5 bytes, increment i by 2
+ * 6. continue to (2)
+ */
+ if (i & 1)
+ put_unaligned_le32((pg_table[0] & 0xf) | pfn << 4,
+ pg_table);
+ else
+ put_unaligned_le32(pfn, pg_table);
+ }
+
+ return pages;
+}
+EXPORT_SYMBOL(snd_sof_create_page_table);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sound/soc/sof/sof-utils.h b/sound/soc/sof/sof-utils.h
new file mode 100644
index 000000000000..6f902893807e
--- /dev/null
+++ b/sound/soc/sof/sof-utils.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Copyright(c) 2022 Intel Corporation. All rights reserved.
+ */
+
+#ifndef __SOC_SOF_UTILS_H
+#define __SOC_SOF_UTILS_H
+
+struct snd_dma_buffer;
+struct device;
+
+int snd_sof_create_page_table(struct device *dev,
+ struct snd_dma_buffer *dmab,
+ unsigned char *page_table, size_t size);
+
+#endif
diff --git a/sound/soc/sof/trace.c b/sound/soc/sof/trace.c
index 2335d0f06d42..104388c551cb 100644
--- a/sound/soc/sof/trace.c
+++ b/sound/soc/sof/trace.c
@@ -12,6 +12,7 @@
#include <linux/sched/signal.h>
#include "sof-priv.h"
#include "ops.h"
+#include "sof-utils.h"

#define TRACE_FILTER_ELEMENTS_PER_ENTRY 4
#define TRACE_FILTER_MAX_CONFIG_STRING_LENGTH 1024
--
2.35.1


2022-02-10 16:41:38

by Péter Ujfalusi

[permalink] [raw]
Subject: [PATCH 2/9] ASoC: SOF: Move the definition of enum sof_dsp_power_states to global header

Move the enum sof_dsp_power_states to include/sound/sof.h
to be accessible outside of the core SOF stack.

Signed-off-by: Peter Ujfalusi <[email protected]>
Reviewed-by: Kai Vehmanen <[email protected]>
Reviewed-by: Pierre-Louis Bossart <[email protected]>
Reviewed-by: Ranjani Sridharan <[email protected]>
---
include/sound/sof.h | 8 ++++++++
sound/soc/sof/sof-priv.h | 8 --------
2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/sound/sof.h b/include/sound/sof.h
index 813680ab9aad..7cdfc954df12 100644
--- a/include/sound/sof.h
+++ b/include/sound/sof.h
@@ -39,6 +39,14 @@ enum sof_fw_state {
SOF_FW_CRASHED,
};

+/* DSP power states */
+enum sof_dsp_power_states {
+ SOF_DSP_PM_D0,
+ SOF_DSP_PM_D1,
+ SOF_DSP_PM_D2,
+ SOF_DSP_PM_D3,
+};
+
/*
* SOF Platform data.
*/
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 6358f8c84cce..2e474048d708 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -79,14 +79,6 @@ bool sof_debug_check_flag(int mask);
/* max number of DSP cores */
#define SOF_MAX_DSP_NUM_CORES 8

-/* DSP power state */
-enum sof_dsp_power_states {
- SOF_DSP_PM_D0,
- SOF_DSP_PM_D1,
- SOF_DSP_PM_D2,
- SOF_DSP_PM_D3,
-};
-
struct sof_dsp_power_state {
u32 state;
u32 substate; /* platform-specific */
--
2.35.1


2022-02-10 16:53:51

by Péter Ujfalusi

[permalink] [raw]
Subject: [PATCH 6/9] ASoC: SOF: sof-client: Add support for clients not managed by pm framework

Some SOF client can be of 'passive' type, meaning that they do not handle
PM framework callbacks by themselves but rely on the auxiliary driver's
suspend and resume callbacks to be notified about the core's suspend or
resume event.

Signed-off-by: Peter Ujfalusi <[email protected]>
Reviewed-by: Kai Vehmanen <[email protected]>
Reviewed-by: Pierre-Louis Bossart <[email protected]>
Reviewed-by: Ranjani Sridharan <[email protected]>
---
sound/soc/sof/pm.c | 13 ++++++++++-
sound/soc/sof/sof-client.c | 46 ++++++++++++++++++++++++++++++++++++++
sound/soc/sof/sof-priv.h | 12 ++++++++++
3 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c
index 197a88695fef..7300ecadabd9 100644
--- a/sound/soc/sof/pm.c
+++ b/sound/soc/sof/pm.c
@@ -167,6 +167,9 @@ static int sof_resume(struct device *dev, bool runtime_resume)
return ret;
}

+ /* Notify clients not managed by pm framework about core resume */
+ sof_resume_clients(sdev);
+
/* notify DSP of system resume */
ret = sof_send_pm_ctx_ipc(sdev, SOF_IPC_PM_CTX_RESTORE);
if (ret < 0)
@@ -180,6 +183,7 @@ static int sof_resume(struct device *dev, bool runtime_resume)
static int sof_suspend(struct device *dev, bool runtime_suspend)
{
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
+ pm_message_t pm_state;
u32 target_state = 0;
int ret;

@@ -205,16 +209,23 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
}

target_state = snd_sof_dsp_power_target(sdev);
+ pm_state.event = target_state;

/* Skip to platform-specific suspend if DSP is entering D0 */
- if (target_state == SOF_DSP_PM_D0)
+ if (target_state == SOF_DSP_PM_D0) {
+ /* Notify clients not managed by pm framework about core suspend */
+ sof_suspend_clients(sdev, pm_state);
goto suspend;
+ }

sof_tear_down_pipelines(sdev, false);

/* release trace */
snd_sof_release_trace(sdev);

+ /* Notify clients not managed by pm framework about core suspend */
+ sof_suspend_clients(sdev, pm_state);
+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE)
/* cache debugfs contents during runtime suspend */
if (runtime_suspend)
diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c
index 6f747d051b59..932bdea49c24 100644
--- a/sound/soc/sof/sof-client.c
+++ b/sound/soc/sof/sof-client.c
@@ -169,6 +169,52 @@ int sof_client_ipc_tx_message(struct sof_client_dev *cdev, void *ipc_msg,
}
EXPORT_SYMBOL_NS_GPL(sof_client_ipc_tx_message, SND_SOC_SOF_CLIENT);

+int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state)
+{
+ struct auxiliary_driver *adrv;
+ struct sof_client_dev *cdev;
+
+ mutex_lock(&sdev->ipc_client_mutex);
+
+ list_for_each_entry(cdev, &sdev->ipc_client_list, list) {
+ /* Skip devices without loaded driver */
+ if (!cdev->auxdev.dev.driver)
+ continue;
+
+ adrv = to_auxiliary_drv(cdev->auxdev.dev.driver);
+ if (adrv->suspend)
+ adrv->suspend(&cdev->auxdev, state);
+ }
+
+ mutex_unlock(&sdev->ipc_client_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(sof_suspend_clients, SND_SOC_SOF_CLIENT);
+
+int sof_resume_clients(struct snd_sof_dev *sdev)
+{
+ struct auxiliary_driver *adrv;
+ struct sof_client_dev *cdev;
+
+ mutex_lock(&sdev->ipc_client_mutex);
+
+ list_for_each_entry(cdev, &sdev->ipc_client_list, list) {
+ /* Skip devices without loaded driver */
+ if (!cdev->auxdev.dev.driver)
+ continue;
+
+ adrv = to_auxiliary_drv(cdev->auxdev.dev.driver);
+ if (adrv->resume)
+ adrv->resume(&cdev->auxdev);
+ }
+
+ mutex_unlock(&sdev->ipc_client_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(sof_resume_clients, SND_SOC_SOF_CLIENT);
+
struct dentry *sof_client_get_debugfs_root(struct sof_client_dev *cdev)
{
return cdev->sdev->debugfs_root;
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index f641833f3ff9..39bbba5aeab2 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -653,6 +653,8 @@ int sof_register_clients(struct snd_sof_dev *sdev);
void sof_unregister_clients(struct snd_sof_dev *sdev);
void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf);
void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev);
+int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state);
+int sof_resume_clients(struct snd_sof_dev *sdev);
#else /* CONFIG_SND_SOC_SOF_CLIENT */
static inline int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name,
u32 id, const void *data, size_t size)
@@ -681,6 +683,16 @@ static inline void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *
static inline void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev)
{
}
+
+static inline int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state)
+{
+ return 0;
+}
+
+static inline int sof_resume_clients(struct snd_sof_dev *sdev)
+{
+ return 0;
+}
#endif /* CONFIG_SND_SOC_SOF_CLIENT */

#endif
--
2.35.1


2022-02-10 18:45:48

by Péter Ujfalusi

[permalink] [raw]
Subject: [PATCH 3/9] ASoC: SOF: ipc: Read and pass the whole message to handlers for IPC events

Change the parameter list for the firmware initiated message (IPC event)
handler functions to:
handler(struct snd_sof_dev *sdev, void *full_msg);

Allocate memory and read the whole message in snd_sof_ipc_msgs_rx() then
pass the pointer to the function handling the message.
Do this only if we actually have a function which is tasked to process the
given type.

Signed-off-by: Peter Ujfalusi <[email protected]>
Reviewed-by: Kai Vehmanen <[email protected]>
Reviewed-by: Pierre-Louis Bossart <[email protected]>
Reviewed-by: Ranjani Sridharan <[email protected]>
---
sound/soc/sof/ipc.c | 85 +++++++++++++++++++++++----------------------
1 file changed, 44 insertions(+), 41 deletions(-)

diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c
index 16a0d7a059f3..ee56d4fa4053 100644
--- a/sound/soc/sof/ipc.c
+++ b/sound/soc/sof/ipc.c
@@ -18,8 +18,10 @@
#include "sof-audio.h"
#include "ops.h"

-static void ipc_trace_message(struct snd_sof_dev *sdev, u32 msg_type);
-static void ipc_stream_message(struct snd_sof_dev *sdev, u32 msg_cmd);
+typedef void (*ipc_rx_callback)(struct snd_sof_dev *sdev, void *msg_buf);
+
+static void ipc_trace_message(struct snd_sof_dev *sdev, void *msg_buf);
+static void ipc_stream_message(struct snd_sof_dev *sdev, void *msg_buf);

/*
* IPC message Tx/Rx message handling.
@@ -477,44 +479,30 @@ void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id)
}
EXPORT_SYMBOL(snd_sof_ipc_reply);

-static void ipc_comp_notification(struct snd_sof_dev *sdev,
- struct sof_ipc_cmd_hdr *hdr)
+static void ipc_comp_notification(struct snd_sof_dev *sdev, void *msg_buf)
{
+ struct sof_ipc_cmd_hdr *hdr = msg_buf;
u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;
- struct sof_ipc_ctrl_data *cdata;
- int ret;

switch (msg_type) {
case SOF_IPC_COMP_GET_VALUE:
case SOF_IPC_COMP_GET_DATA:
- cdata = kmalloc(hdr->size, GFP_KERNEL);
- if (!cdata)
- return;
-
- /* read back full message */
- ret = snd_sof_ipc_msg_data(sdev, NULL, cdata, hdr->size);
- if (ret < 0) {
- dev_err(sdev->dev,
- "error: failed to read component event: %d\n", ret);
- goto err;
- }
break;
default:
dev_err(sdev->dev, "error: unhandled component message %#x\n", msg_type);
return;
}

- snd_sof_control_notify(sdev, cdata);
-
-err:
- kfree(cdata);
+ snd_sof_control_notify(sdev, msg_buf);
}

/* DSP firmware has sent host a message */
void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
{
+ ipc_rx_callback rx_callback = NULL;
struct sof_ipc_cmd_hdr hdr;
- u32 cmd, type;
+ void *msg_buf;
+ u32 cmd;
int err;

/* read back header */
@@ -523,10 +511,15 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
dev_warn(sdev->dev, "failed to read IPC header: %d\n", err);
return;
}
+
+ if (hdr.size < sizeof(hdr)) {
+ dev_err(sdev->dev, "The received message size is invalid\n");
+ return;
+ }
+
ipc_log_header(sdev->dev, "ipc rx", hdr.cmd);

cmd = hdr.cmd & SOF_GLB_TYPE_MASK;
- type = hdr.cmd & SOF_CMD_TYPE_MASK;

/* check message type */
switch (cmd) {
@@ -551,20 +544,35 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
case SOF_IPC_GLB_PM_MSG:
break;
case SOF_IPC_GLB_COMP_MSG:
- ipc_comp_notification(sdev, &hdr);
+ rx_callback = ipc_comp_notification;
break;
case SOF_IPC_GLB_STREAM_MSG:
- /* need to pass msg id into the function */
- ipc_stream_message(sdev, hdr.cmd);
+ rx_callback = ipc_stream_message;
break;
case SOF_IPC_GLB_TRACE_MSG:
- ipc_trace_message(sdev, type);
+ rx_callback = ipc_trace_message;
break;
default:
- dev_err(sdev->dev, "error: unknown DSP message 0x%x\n", cmd);
+ dev_err(sdev->dev, "%s: Unknown DSP message: 0x%x\n", __func__, cmd);
break;
}

+ if (rx_callback) {
+ /* read the full message as we have rx handler for it */
+ msg_buf = kmalloc(hdr.size, GFP_KERNEL);
+ if (!msg_buf)
+ return;
+
+ err = snd_sof_ipc_msg_data(sdev, NULL, msg_buf, hdr.size);
+ if (err < 0)
+ dev_err(sdev->dev, "%s: Failed to read message: %d\n",
+ __func__, err);
+ else
+ rx_callback(sdev, msg_buf);
+
+ kfree(msg_buf);
+ }
+
ipc_log_header(sdev->dev, "ipc rx done", hdr.cmd);
}
EXPORT_SYMBOL(snd_sof_ipc_msgs_rx);
@@ -573,19 +581,14 @@ EXPORT_SYMBOL(snd_sof_ipc_msgs_rx);
* IPC trace mechanism.
*/

-static void ipc_trace_message(struct snd_sof_dev *sdev, u32 msg_type)
+static void ipc_trace_message(struct snd_sof_dev *sdev, void *msg_buf)
{
- struct sof_ipc_dma_trace_posn posn;
- int ret;
+ struct sof_ipc_cmd_hdr *hdr = msg_buf;
+ u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;

switch (msg_type) {
case SOF_IPC_TRACE_DMA_POSITION:
- /* read back full message */
- ret = snd_sof_ipc_msg_data(sdev, NULL, &posn, sizeof(posn));
- if (ret < 0)
- dev_warn(sdev->dev, "failed to read trace position: %d\n", ret);
- else
- snd_sof_trace_update_pos(sdev, &posn);
+ snd_sof_trace_update_pos(sdev, msg_buf);
break;
default:
dev_err(sdev->dev, "error: unhandled trace message %#x\n", msg_type);
@@ -667,11 +670,11 @@ static void ipc_xrun(struct snd_sof_dev *sdev, u32 msg_id)
}

/* stream notifications from DSP FW */
-static void ipc_stream_message(struct snd_sof_dev *sdev, u32 msg_cmd)
+static void ipc_stream_message(struct snd_sof_dev *sdev, void *msg_buf)
{
- /* get msg cmd type and msd id */
- u32 msg_type = msg_cmd & SOF_CMD_TYPE_MASK;
- u32 msg_id = SOF_IPC_MESSAGE_ID(msg_cmd);
+ struct sof_ipc_cmd_hdr *hdr = msg_buf;
+ u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;
+ u32 msg_id = SOF_IPC_MESSAGE_ID(hdr->cmd);

switch (msg_type) {
case SOF_IPC_STREAM_POSITION:
--
2.35.1


2022-02-10 21:36:09

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH 0/9] ASoC: SOF: IPC client infrastructure

On Thu, 10 Feb 2022 12:55:10 +0200, Peter Ujfalusi wrote:
> The Linux SOF implementation is historically monolithic in a sense that all
> features accessible in the firmware can be used via the snd_sof_dev struct in
> one way or another.
>
> Support for features can not be added or removed runtime and with the current
> way of things it is hard if not impossible to implement support for dynamic
> feature support when based on the firmware manifest we can easily enable/access
> independent modules with the SOF.
>
> [...]

Applied to

https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/9] ASoC: SOF: Drop unused DSP power states: D3_HOT and D3_COLD
commit: 2439a35508277922ea116c99ff4d4a32c607464c
[2/9] ASoC: SOF: Move the definition of enum sof_dsp_power_states to global header
commit: 5fdc1242453e2ae88b2cdb607e4eda6b687f084c
[3/9] ASoC: SOF: ipc: Read and pass the whole message to handlers for IPC events
commit: ab3a2189a3744527f54ace1be19eb13e6c3d24df
[4/9] ASoC: SOF: Split up utils.c into sof-utils and iomem-utils
commit: ee8443050b2bf06d80fdd2c78cc25cae2abdedcd
[5/9] ASoC: SOF: Introduce IPC SOF client support
commit: 6955d9512d0ea814f1c2761bef7ad7b3cedf4d68
[6/9] ASoC: SOF: sof-client: Add support for clients not managed by pm framework
commit: 1069967afe1e6b728061682ff99ec534a55a5613
[7/9] ASoC: SOF: Convert the generic IPC flood test into SOF client
commit: 6e9548cdb30e5d6724236dd7b89a79a270751485
[8/9] ASoC: SOF: Convert the generic IPC message injector into SOF client
commit: cac0b0887e5304bddfda91a4a7106f9328c31318
[9/9] ASoC: SOF: Convert the generic probe support to SOF client
commit: 3dc0d709177828a22dfc9d0072e3ac937ef90d06

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

2022-02-10 23:32:24

by Péter Ujfalusi

[permalink] [raw]
Subject: [PATCH 8/9] ASoC: SOF: Convert the generic IPC message injector into SOF client

Move the IPC message injection code out from the debug file as separate
SOF client driver.

Based on the kernel configuration, the device registration for the new IPC
message injector is going to happen in the core.

Signed-off-by: Peter Ujfalusi <[email protected]>
Reviewed-by: Kai Vehmanen <[email protected]>
Reviewed-by: Pierre-Louis Bossart <[email protected]>
Reviewed-by: Ranjani Sridharan <[email protected]>
---
sound/soc/sof/Kconfig | 3 +-
sound/soc/sof/Makefile | 2 +
sound/soc/sof/debug.c | 108 -----------
sound/soc/sof/sof-client-ipc-msg-injector.c | 192 ++++++++++++++++++++
sound/soc/sof/sof-client.c | 35 +++-
sound/soc/sof/sof-priv.h | 4 -
6 files changed, 229 insertions(+), 115 deletions(-)
create mode 100644 sound/soc/sof/sof-client-ipc-msg-injector.c

diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig
index 3f8a2cadd2f8..203b086ac22c 100644
--- a/sound/soc/sof/Kconfig
+++ b/sound/soc/sof/Kconfig
@@ -212,7 +212,8 @@ config SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST_NUM
Select the number of IPC flood test clients to be created.

config SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR
- bool "SOF enable IPC message injector"
+ tristate "SOF enable IPC message injector"
+ select SND_SOC_SOF_CLIENT
help
This option enables the IPC message injector which can be used to send
crafted IPC messages to the DSP to test its robustness.
diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile
index 964eff43c9ba..a2ae79ebf756 100644
--- a/sound/soc/sof/Makefile
+++ b/sound/soc/sof/Makefile
@@ -12,6 +12,7 @@ snd-sof-acpi-objs := sof-acpi-dev.o
snd-sof-of-objs := sof-of-dev.o

snd-sof-ipc-flood-test-objs := sof-client-ipc-flood-test.o
+snd-sof-ipc-msg-injector-objs := sof-client-ipc-msg-injector.o

snd-sof-nocodec-objs := nocodec.o

@@ -27,6 +28,7 @@ obj-$(CONFIG_SND_SOC_SOF_OF_DEV) += snd-sof-of.o
obj-$(CONFIG_SND_SOC_SOF_PCI_DEV) += snd-sof-pci.o

obj-$(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST) += snd-sof-ipc-flood-test.o
+obj-$(CONFIG_SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR) += snd-sof-ipc-msg-injector.o

obj-$(CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL) += intel/
obj-$(CONFIG_SND_SOC_SOF_IMX_TOPLEVEL) += imx/
diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c
index e3a5f77bbd4d..937fe6e11d0d 100644
--- a/sound/soc/sof/debug.c
+++ b/sound/soc/sof/debug.c
@@ -234,105 +234,6 @@ static int snd_sof_debugfs_probe_item(struct snd_sof_dev *sdev,
}
#endif

-
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR)
-static ssize_t msg_inject_read(struct file *file, char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct snd_sof_dfsentry *dfse = file->private_data;
- struct sof_ipc_reply *rhdr = dfse->msg_inject_rx;
-
- if (!rhdr->hdr.size || !count || *ppos)
- return 0;
-
- if (count > rhdr->hdr.size)
- count = rhdr->hdr.size;
-
- if (copy_to_user(buffer, dfse->msg_inject_rx, count))
- return -EFAULT;
-
- *ppos += count;
- return count;
-}
-
-static ssize_t msg_inject_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct snd_sof_dfsentry *dfse = file->private_data;
- struct snd_sof_dev *sdev = dfse->sdev;
- struct sof_ipc_cmd_hdr *hdr = dfse->msg_inject_tx;
- size_t size;
- int ret, err;
-
- if (*ppos)
- return 0;
-
- size = simple_write_to_buffer(dfse->msg_inject_tx, SOF_IPC_MSG_MAX_SIZE,
- ppos, buffer, count);
- if (size != count)
- return size > 0 ? -EFAULT : size;
-
- ret = pm_runtime_get_sync(sdev->dev);
- if (ret < 0 && ret != -EACCES) {
- dev_err_ratelimited(sdev->dev, "%s: DSP resume failed: %d\n",
- __func__, ret);
- pm_runtime_put_noidle(sdev->dev);
- goto out;
- }
-
- /* send the message */
- memset(dfse->msg_inject_rx, 0, SOF_IPC_MSG_MAX_SIZE);
- ret = sof_ipc_tx_message(sdev->ipc, hdr->cmd, dfse->msg_inject_tx, count,
- dfse->msg_inject_rx, SOF_IPC_MSG_MAX_SIZE);
-
- pm_runtime_mark_last_busy(sdev->dev);
- err = pm_runtime_put_autosuspend(sdev->dev);
- if (err < 0)
- dev_err_ratelimited(sdev->dev, "%s: DSP idle failed: %d\n",
- __func__, err);
-
- /* return size if test is successful */
- if (ret >= 0)
- ret = size;
-
-out:
- return ret;
-}
-
-static const struct file_operations msg_inject_fops = {
- .open = simple_open,
- .read = msg_inject_read,
- .write = msg_inject_write,
- .llseek = default_llseek,
-};
-
-static int snd_sof_debugfs_msg_inject_item(struct snd_sof_dev *sdev,
- const char *name, mode_t mode,
- const struct file_operations *fops)
-{
- struct snd_sof_dfsentry *dfse;
-
- dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL);
- if (!dfse)
- return -ENOMEM;
-
- /* pre allocate the tx and rx buffers */
- dfse->msg_inject_tx = devm_kzalloc(sdev->dev, SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL);
- dfse->msg_inject_rx = devm_kzalloc(sdev->dev, SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL);
- if (!dfse->msg_inject_tx || !dfse->msg_inject_rx)
- return -ENOMEM;
-
- dfse->type = SOF_DFSENTRY_TYPE_BUF;
- dfse->sdev = sdev;
-
- debugfs_create_file(name, mode, sdev->debugfs_root, dfse, fops);
- /* add to dfsentry list */
- list_add(&dfse->list, &sdev->dfsentry_list);
-
- return 0;
-}
-#endif
-
static ssize_t sof_dfsentry_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
@@ -679,15 +580,6 @@ int snd_sof_dbg_init(struct snd_sof_dev *sdev)
return err;
#endif

-#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR)
- err = snd_sof_debugfs_msg_inject_item(sdev, "ipc_msg_inject", 0644,
- &msg_inject_fops);
-
- /* errors are only due to memory allocation, not debugfs */
- if (err < 0)
- return err;
-#endif
-
return 0;
}
EXPORT_SYMBOL_GPL(snd_sof_dbg_init);
diff --git a/sound/soc/sof/sof-client-ipc-msg-injector.c b/sound/soc/sof/sof-client-ipc-msg-injector.c
new file mode 100644
index 000000000000..bce103da4c49
--- /dev/null
+++ b/sound/soc/sof/sof-client-ipc-msg-injector.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2022 Intel Corporation. All rights reserved.
+//
+// Author: Peter Ujfalusi <[email protected]>
+//
+
+#include <linux/auxiliary_bus.h>
+#include <linux/completion.h>
+#include <linux/debugfs.h>
+#include <linux/ktime.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <sound/sof/header.h>
+
+#include "sof-client.h"
+
+#define SOF_IPC_CLIENT_SUSPEND_DELAY_MS 3000
+
+struct sof_msg_inject_priv {
+ struct dentry *dfs_file;
+
+ void *tx_buffer;
+ void *rx_buffer;
+};
+
+static int sof_msg_inject_dfs_open(struct inode *inode, struct file *file)
+{
+ struct sof_client_dev *cdev = inode->i_private;
+ int ret;
+
+ if (sof_client_get_fw_state(cdev) == SOF_FW_CRASHED)
+ return -ENODEV;
+
+ ret = debugfs_file_get(file->f_path.dentry);
+ if (unlikely(ret))
+ return ret;
+
+ ret = simple_open(inode, file);
+ if (ret)
+ debugfs_file_put(file->f_path.dentry);
+
+ return ret;
+}
+
+static ssize_t sof_msg_inject_dfs_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct sof_client_dev *cdev = file->private_data;
+ struct sof_msg_inject_priv *priv = cdev->data;
+ struct sof_ipc_reply *rhdr = priv->rx_buffer;
+
+ if (!rhdr->hdr.size || !count || *ppos)
+ return 0;
+
+ if (count > rhdr->hdr.size)
+ count = rhdr->hdr.size;
+
+ if (copy_to_user(buffer, priv->rx_buffer, count))
+ return -EFAULT;
+
+ *ppos += count;
+ return count;
+}
+
+static ssize_t sof_msg_inject_dfs_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct sof_client_dev *cdev = file->private_data;
+ struct sof_msg_inject_priv *priv = cdev->data;
+ struct device *dev = &cdev->auxdev.dev;
+ int ret, err;
+ size_t size;
+
+ if (*ppos)
+ return 0;
+
+ size = simple_write_to_buffer(priv->tx_buffer, SOF_IPC_MSG_MAX_SIZE,
+ ppos, buffer, count);
+ if (size != count)
+ return size > 0 ? -EFAULT : size;
+
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0 && ret != -EACCES) {
+ dev_err_ratelimited(dev, "debugfs write failed to resume %d\n", ret);
+ pm_runtime_put_noidle(dev);
+ return ret;
+ }
+
+ /* send the message */
+ memset(priv->rx_buffer, 0, SOF_IPC_MSG_MAX_SIZE);
+ ret = sof_client_ipc_tx_message(cdev, priv->tx_buffer, priv->rx_buffer,
+ SOF_IPC_MSG_MAX_SIZE);
+ pm_runtime_mark_last_busy(dev);
+ err = pm_runtime_put_autosuspend(dev);
+ if (err < 0)
+ dev_err_ratelimited(dev, "debugfs write failed to idle %d\n", err);
+
+ /* return size if test is successful */
+ if (ret >= 0)
+ ret = size;
+
+ return ret;
+};
+
+static int sof_msg_inject_dfs_release(struct inode *inode, struct file *file)
+{
+ debugfs_file_put(file->f_path.dentry);
+
+ return 0;
+}
+
+static const struct file_operations sof_msg_inject_fops = {
+ .open = sof_msg_inject_dfs_open,
+ .read = sof_msg_inject_dfs_read,
+ .write = sof_msg_inject_dfs_write,
+ .llseek = default_llseek,
+ .release = sof_msg_inject_dfs_release,
+
+ .owner = THIS_MODULE,
+};
+
+static int sof_msg_inject_probe(struct auxiliary_device *auxdev,
+ const struct auxiliary_device_id *id)
+{
+ struct sof_client_dev *cdev = auxiliary_dev_to_sof_client_dev(auxdev);
+ struct dentry *debugfs_root = sof_client_get_debugfs_root(cdev);
+ struct device *dev = &auxdev->dev;
+ struct sof_msg_inject_priv *priv;
+
+ /* allocate memory for client data */
+ priv = devm_kzalloc(&auxdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->tx_buffer = devm_kmalloc(dev, SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL);
+ priv->rx_buffer = devm_kmalloc(dev, SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL);
+ if (!priv->tx_buffer || !priv->rx_buffer)
+ return -ENOMEM;
+
+ cdev->data = priv;
+
+ priv->dfs_file = debugfs_create_file("ipc_msg_inject", 0644, debugfs_root,
+ cdev, &sof_msg_inject_fops);
+
+ /* enable runtime PM */
+ pm_runtime_set_autosuspend_delay(dev, SOF_IPC_CLIENT_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_enable(dev);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_idle(dev);
+
+ return 0;
+}
+
+static void sof_msg_inject_remove(struct auxiliary_device *auxdev)
+{
+ struct sof_client_dev *cdev = auxiliary_dev_to_sof_client_dev(auxdev);
+ struct sof_msg_inject_priv *priv = cdev->data;
+
+ pm_runtime_disable(&auxdev->dev);
+
+ debugfs_remove(priv->dfs_file);
+}
+
+static const struct auxiliary_device_id sof_msg_inject_client_id_table[] = {
+ { .name = "snd_sof.msg_injector" },
+ {},
+};
+MODULE_DEVICE_TABLE(auxiliary, sof_msg_inject_client_id_table);
+
+/*
+ * No need for driver pm_ops as the generic pm callbacks in the auxiliary bus
+ * type are enough to ensure that the parent SOF device resumes to bring the DSP
+ * back to D0.
+ * Driver name will be set based on KBUILD_MODNAME.
+ */
+static struct auxiliary_driver sof_msg_inject_client_drv = {
+ .probe = sof_msg_inject_probe,
+ .remove = sof_msg_inject_remove,
+
+ .id_table = sof_msg_inject_client_id_table,
+};
+
+module_auxiliary_driver(sof_msg_inject_client_drv);
+
+MODULE_DESCRIPTION("SOF IPC Message Injector Client Driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT);
diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c
index 0ffe7a26a19a..686ad0c3bb61 100644
--- a/sound/soc/sof/sof-client.c
+++ b/sound/soc/sof/sof-client.c
@@ -102,6 +102,25 @@ static inline int sof_register_ipc_flood_test(struct snd_sof_dev *sdev)
static inline void sof_unregister_ipc_flood_test(struct snd_sof_dev *sdev) {}
#endif /* CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST */

+#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR)
+static int sof_register_ipc_msg_injector(struct snd_sof_dev *sdev)
+{
+ return sof_client_dev_register(sdev, "msg_injector", 0, NULL, 0);
+}
+
+static void sof_unregister_ipc_msg_injector(struct snd_sof_dev *sdev)
+{
+ sof_client_dev_unregister(sdev, "msg_injector", 0);
+}
+#else
+static inline int sof_register_ipc_msg_injector(struct snd_sof_dev *sdev)
+{
+ return 0;
+}
+
+static inline void sof_unregister_ipc_msg_injector(struct snd_sof_dev *sdev) {}
+#endif /* CONFIG_SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR */
+
int sof_register_clients(struct snd_sof_dev *sdev)
{
int ret;
@@ -113,13 +132,24 @@ int sof_register_clients(struct snd_sof_dev *sdev)
return ret;
}

+ ret = sof_register_ipc_msg_injector(sdev);
+ if (ret) {
+ dev_err(sdev->dev, "IPC message injector client registration failed\n");
+ goto err_msg_injector;
+ }
+
/* Platform depndent client device registration */

if (sof_ops(sdev) && sof_ops(sdev)->register_ipc_clients)
ret = sof_ops(sdev)->register_ipc_clients(sdev);

- if (ret)
- sof_unregister_ipc_flood_test(sdev);
+ if (!ret)
+ return 0;
+
+ sof_unregister_ipc_msg_injector(sdev);
+
+err_msg_injector:
+ sof_unregister_ipc_flood_test(sdev);

return ret;
}
@@ -129,6 +159,7 @@ void sof_unregister_clients(struct snd_sof_dev *sdev)
if (sof_ops(sdev) && sof_ops(sdev)->unregister_ipc_clients)
sof_ops(sdev)->unregister_ipc_clients(sdev);

+ sof_unregister_ipc_msg_injector(sdev);
sof_unregister_ipc_flood_test(sdev);
}

diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 1af61ff89345..2529408a4e90 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -324,10 +324,6 @@ struct snd_sof_dfsentry {
enum sof_debugfs_access_type access_type;
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE)
char *cache_buf; /* buffer to cache the contents of debugfs memory */
-#endif
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR)
- void *msg_inject_tx;
- void *msg_inject_rx;
#endif
struct snd_sof_dev *sdev;
struct list_head list; /* list in sdev dfsentry list */
--
2.35.1


2022-02-11 01:38:11

by Péter Ujfalusi

[permalink] [raw]
Subject: [PATCH 1/9] ASoC: SOF: Drop unused DSP power states: D3_HOT and D3_COLD

The only reference to D3_HOT and D3_COLD DSP power state is in
intel/hda-dsp.c in form of a dev_dbg() print.

Remove them as they are not used and even if they are they could be
re-added via the substate.

Signed-off-by: Peter Ujfalusi <[email protected]>
Reviewed-by: Kai Vehmanen <[email protected]>
Reviewed-by: Pierre-Louis Bossart <[email protected]>
Reviewed-by: Ranjani Sridharan <[email protected]>
---
sound/soc/sof/intel/hda-dsp.c | 6 ------
sound/soc/sof/sof-priv.h | 2 --
2 files changed, 8 deletions(-)

diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index 0fe522549c91..8ddde60c56b3 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -498,15 +498,9 @@ static void hda_dsp_state_log(struct snd_sof_dev *sdev)
case SOF_DSP_PM_D2:
dev_dbg(sdev->dev, "Current DSP power state: D2\n");
break;
- case SOF_DSP_PM_D3_HOT:
- dev_dbg(sdev->dev, "Current DSP power state: D3_HOT\n");
- break;
case SOF_DSP_PM_D3:
dev_dbg(sdev->dev, "Current DSP power state: D3\n");
break;
- case SOF_DSP_PM_D3_COLD:
- dev_dbg(sdev->dev, "Current DSP power state: D3_COLD\n");
- break;
default:
dev_dbg(sdev->dev, "Unknown DSP power state: %d\n",
sdev->dsp_power_state.state);
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index e48402ce4bdb..6358f8c84cce 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -84,9 +84,7 @@ enum sof_dsp_power_states {
SOF_DSP_PM_D0,
SOF_DSP_PM_D1,
SOF_DSP_PM_D2,
- SOF_DSP_PM_D3_HOT,
SOF_DSP_PM_D3,
- SOF_DSP_PM_D3_COLD,
};

struct sof_dsp_power_state {
--
2.35.1