Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: Intel: Remove unused code

After removal of Skylake driver there is no users left for sst-dsp and
sst-ipc interfaces. Remove them.

Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Link: https://patch.msgid.link/20241009083419.319038-1-amadeuszx.slawinski@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Amadeusz Sławiński and committed by
Mark Brown
970d299b f8199bbc

-798
-3
sound/soc/intel/Kconfig
··· 15 15 16 16 if SND_SOC_INTEL_SST_TOPLEVEL 17 17 18 - config SND_SOC_INTEL_SST 19 - tristate 20 - 21 18 config SND_SOC_INTEL_CATPT 22 19 tristate "Haswell and Broadwell" 23 20 depends on ACPI || COMPILE_TEST
-3
sound/soc/intel/common/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - snd-soc-sst-dsp-y := sst-dsp.o 3 - snd-soc-sst-ipc-y := sst-ipc.o 4 2 snd-soc-acpi-intel-match-y := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-match.o \ 5 3 soc-acpi-intel-hsw-bdw-match.o \ 6 4 soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \ ··· 16 18 17 19 snd-soc-acpi-intel-match-y += soc-acpi-intel-ssp-common.o 18 20 19 - obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o 20 21 obj-$(CONFIG_SND_SOC_ACPI_INTEL_MATCH) += snd-soc-acpi-intel-match.o
-101
sound/soc/intel/common/sst-dsp-priv.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Intel Smart Sound Technology 4 - * 5 - * Copyright (C) 2013, Intel Corporation 6 - */ 7 - 8 - #ifndef __SOUND_SOC_SST_DSP_PRIV_H 9 - #define __SOUND_SOC_SST_DSP_PRIV_H 10 - 11 - #include <linux/kernel.h> 12 - #include <linux/types.h> 13 - #include <linux/interrupt.h> 14 - #include <linux/firmware.h> 15 - 16 - #include "../skylake/skl-sst-dsp.h" 17 - 18 - /* 19 - * DSP Operations exported by platform Audio DSP driver. 20 - */ 21 - struct sst_ops { 22 - /* Shim IO */ 23 - void (*write)(void __iomem *addr, u32 offset, u32 value); 24 - u32 (*read)(void __iomem *addr, u32 offset); 25 - 26 - /* IRQ handlers */ 27 - irqreturn_t (*irq_handler)(int irq, void *context); 28 - 29 - /* SST init and free */ 30 - int (*init)(struct sst_dsp *sst); 31 - void (*free)(struct sst_dsp *sst); 32 - }; 33 - 34 - /* 35 - * Audio DSP memory offsets and addresses. 36 - */ 37 - struct sst_addr { 38 - u32 sram0_base; 39 - u32 sram1_base; 40 - u32 w0_stat_sz; 41 - u32 w0_up_sz; 42 - void __iomem *lpe; 43 - void __iomem *shim; 44 - }; 45 - 46 - /* 47 - * Audio DSP Mailbox configuration. 48 - */ 49 - struct sst_mailbox { 50 - void __iomem *in_base; 51 - void __iomem *out_base; 52 - size_t in_size; 53 - size_t out_size; 54 - }; 55 - 56 - /* 57 - * Generic SST Shim Interface. 58 - */ 59 - struct sst_dsp { 60 - 61 - /* Shared for all platforms */ 62 - 63 - /* runtime */ 64 - struct sst_dsp_device *sst_dev; 65 - spinlock_t spinlock; /* IPC locking */ 66 - struct mutex mutex; /* DSP FW lock */ 67 - struct device *dev; 68 - void *thread_context; 69 - int irq; 70 - u32 id; 71 - 72 - /* operations */ 73 - struct sst_ops *ops; 74 - 75 - /* debug FS */ 76 - struct dentry *debugfs_root; 77 - 78 - /* base addresses */ 79 - struct sst_addr addr; 80 - 81 - /* mailbox */ 82 - struct sst_mailbox mailbox; 83 - 84 - /* SST FW files loaded and their modules */ 85 - struct list_head module_list; 86 - 87 - /* SKL data */ 88 - 89 - const char *fw_name; 90 - 91 - /* To allocate CL dma buffers */ 92 - struct skl_dsp_loader_ops dsp_ops; 93 - struct skl_dsp_fw_ops fw_ops; 94 - int sst_state; 95 - struct skl_cl_dev cl_dev; 96 - u32 intr_status; 97 - const struct firmware *fw; 98 - struct snd_dma_buffer dmab; 99 - }; 100 - 101 - #endif
-250
sound/soc/intel/common/sst-dsp.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Intel Smart Sound Technology (SST) DSP Core Driver 4 - * 5 - * Copyright (C) 2013, Intel Corporation 6 - */ 7 - 8 - #include <linux/slab.h> 9 - #include <linux/export.h> 10 - #include <linux/interrupt.h> 11 - #include <linux/module.h> 12 - #include <linux/platform_device.h> 13 - #include <linux/io-64-nonatomic-lo-hi.h> 14 - #include <linux/delay.h> 15 - 16 - #include "sst-dsp.h" 17 - #include "sst-dsp-priv.h" 18 - 19 - #define CREATE_TRACE_POINTS 20 - #include <trace/events/intel-sst.h> 21 - 22 - /* Internal generic low-level SST IO functions - can be overidden */ 23 - void sst_shim32_write(void __iomem *addr, u32 offset, u32 value) 24 - { 25 - writel(value, addr + offset); 26 - } 27 - EXPORT_SYMBOL_GPL(sst_shim32_write); 28 - 29 - u32 sst_shim32_read(void __iomem *addr, u32 offset) 30 - { 31 - return readl(addr + offset); 32 - } 33 - EXPORT_SYMBOL_GPL(sst_shim32_read); 34 - 35 - void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value) 36 - { 37 - writeq(value, addr + offset); 38 - } 39 - EXPORT_SYMBOL_GPL(sst_shim32_write64); 40 - 41 - u64 sst_shim32_read64(void __iomem *addr, u32 offset) 42 - { 43 - return readq(addr + offset); 44 - } 45 - EXPORT_SYMBOL_GPL(sst_shim32_read64); 46 - 47 - /* Public API */ 48 - void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value) 49 - { 50 - unsigned long flags; 51 - 52 - spin_lock_irqsave(&sst->spinlock, flags); 53 - sst->ops->write(sst->addr.shim, offset, value); 54 - spin_unlock_irqrestore(&sst->spinlock, flags); 55 - } 56 - EXPORT_SYMBOL_GPL(sst_dsp_shim_write); 57 - 58 - u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset) 59 - { 60 - unsigned long flags; 61 - u32 val; 62 - 63 - spin_lock_irqsave(&sst->spinlock, flags); 64 - val = sst->ops->read(sst->addr.shim, offset); 65 - spin_unlock_irqrestore(&sst->spinlock, flags); 66 - 67 - return val; 68 - } 69 - EXPORT_SYMBOL_GPL(sst_dsp_shim_read); 70 - 71 - void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value) 72 - { 73 - sst->ops->write(sst->addr.shim, offset, value); 74 - } 75 - EXPORT_SYMBOL_GPL(sst_dsp_shim_write_unlocked); 76 - 77 - u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset) 78 - { 79 - return sst->ops->read(sst->addr.shim, offset); 80 - } 81 - EXPORT_SYMBOL_GPL(sst_dsp_shim_read_unlocked); 82 - 83 - int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset, 84 - u32 mask, u32 value) 85 - { 86 - bool change; 87 - unsigned int old, new; 88 - u32 ret; 89 - 90 - ret = sst_dsp_shim_read_unlocked(sst, offset); 91 - 92 - old = ret; 93 - new = (old & (~mask)) | (value & mask); 94 - 95 - change = (old != new); 96 - if (change) 97 - sst_dsp_shim_write_unlocked(sst, offset, new); 98 - 99 - return change; 100 - } 101 - EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_unlocked); 102 - 103 - /* This is for registers bits with attribute RWC */ 104 - void sst_dsp_shim_update_bits_forced_unlocked(struct sst_dsp *sst, u32 offset, 105 - u32 mask, u32 value) 106 - { 107 - unsigned int old, new; 108 - u32 ret; 109 - 110 - ret = sst_dsp_shim_read_unlocked(sst, offset); 111 - 112 - old = ret; 113 - new = (old & (~mask)) | (value & mask); 114 - 115 - sst_dsp_shim_write_unlocked(sst, offset, new); 116 - } 117 - EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_forced_unlocked); 118 - 119 - int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset, 120 - u32 mask, u32 value) 121 - { 122 - unsigned long flags; 123 - bool change; 124 - 125 - spin_lock_irqsave(&sst->spinlock, flags); 126 - change = sst_dsp_shim_update_bits_unlocked(sst, offset, mask, value); 127 - spin_unlock_irqrestore(&sst->spinlock, flags); 128 - return change; 129 - } 130 - EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits); 131 - 132 - /* This is for registers bits with attribute RWC */ 133 - void sst_dsp_shim_update_bits_forced(struct sst_dsp *sst, u32 offset, 134 - u32 mask, u32 value) 135 - { 136 - unsigned long flags; 137 - 138 - spin_lock_irqsave(&sst->spinlock, flags); 139 - sst_dsp_shim_update_bits_forced_unlocked(sst, offset, mask, value); 140 - spin_unlock_irqrestore(&sst->spinlock, flags); 141 - } 142 - EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_forced); 143 - 144 - int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask, 145 - u32 target, u32 time, char *operation) 146 - { 147 - u32 reg; 148 - unsigned long timeout; 149 - int k = 0, s = 500; 150 - 151 - /* 152 - * split the loop into sleeps of varying resolution. more accurately, 153 - * the range of wakeups are: 154 - * Phase 1(first 5ms): min sleep 0.5ms; max sleep 1ms. 155 - * Phase 2:( 5ms to 10ms) : min sleep 0.5ms; max sleep 10ms 156 - * (usleep_range (500, 1000) and usleep_range(5000, 10000) are 157 - * both possible in this phase depending on whether k > 10 or not). 158 - * Phase 3: (beyond 10 ms) min sleep 5ms; max sleep 10ms. 159 - */ 160 - 161 - timeout = jiffies + msecs_to_jiffies(time); 162 - while ((((reg = sst_dsp_shim_read_unlocked(ctx, offset)) & mask) != target) 163 - && time_before(jiffies, timeout)) { 164 - k++; 165 - if (k > 10) 166 - s = 5000; 167 - 168 - usleep_range(s, 2*s); 169 - } 170 - 171 - if ((reg & mask) == target) { 172 - dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s successful\n", 173 - reg, operation); 174 - 175 - return 0; 176 - } 177 - 178 - dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s timedout\n", 179 - reg, operation); 180 - return -ETIME; 181 - } 182 - EXPORT_SYMBOL_GPL(sst_dsp_register_poll); 183 - 184 - int sst_dsp_mailbox_init(struct sst_dsp *sst, u32 inbox_offset, size_t inbox_size, 185 - u32 outbox_offset, size_t outbox_size) 186 - { 187 - sst->mailbox.in_base = sst->addr.lpe + inbox_offset; 188 - sst->mailbox.out_base = sst->addr.lpe + outbox_offset; 189 - sst->mailbox.in_size = inbox_size; 190 - sst->mailbox.out_size = outbox_size; 191 - return 0; 192 - } 193 - EXPORT_SYMBOL_GPL(sst_dsp_mailbox_init); 194 - 195 - void sst_dsp_outbox_write(struct sst_dsp *sst, void *message, size_t bytes) 196 - { 197 - u32 i; 198 - 199 - trace_sst_ipc_outbox_write(bytes); 200 - 201 - memcpy_toio(sst->mailbox.out_base, message, bytes); 202 - 203 - for (i = 0; i < bytes; i += 4) 204 - trace_sst_ipc_outbox_wdata(i, *(u32 *)(message + i)); 205 - } 206 - EXPORT_SYMBOL_GPL(sst_dsp_outbox_write); 207 - 208 - void sst_dsp_outbox_read(struct sst_dsp *sst, void *message, size_t bytes) 209 - { 210 - u32 i; 211 - 212 - trace_sst_ipc_outbox_read(bytes); 213 - 214 - memcpy_fromio(message, sst->mailbox.out_base, bytes); 215 - 216 - for (i = 0; i < bytes; i += 4) 217 - trace_sst_ipc_outbox_rdata(i, *(u32 *)(message + i)); 218 - } 219 - EXPORT_SYMBOL_GPL(sst_dsp_outbox_read); 220 - 221 - void sst_dsp_inbox_write(struct sst_dsp *sst, void *message, size_t bytes) 222 - { 223 - u32 i; 224 - 225 - trace_sst_ipc_inbox_write(bytes); 226 - 227 - memcpy_toio(sst->mailbox.in_base, message, bytes); 228 - 229 - for (i = 0; i < bytes; i += 4) 230 - trace_sst_ipc_inbox_wdata(i, *(u32 *)(message + i)); 231 - } 232 - EXPORT_SYMBOL_GPL(sst_dsp_inbox_write); 233 - 234 - void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes) 235 - { 236 - u32 i; 237 - 238 - trace_sst_ipc_inbox_read(bytes); 239 - 240 - memcpy_fromio(message, sst->mailbox.in_base, bytes); 241 - 242 - for (i = 0; i < bytes; i += 4) 243 - trace_sst_ipc_inbox_rdata(i, *(u32 *)(message + i)); 244 - } 245 - EXPORT_SYMBOL_GPL(sst_dsp_inbox_read); 246 - 247 - /* Module information */ 248 - MODULE_AUTHOR("Liam Girdwood"); 249 - MODULE_DESCRIPTION("Intel SST Core"); 250 - MODULE_LICENSE("GPL v2");
-61
sound/soc/intel/common/sst-dsp.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Intel Smart Sound Technology (SST) Core 4 - * 5 - * Copyright (C) 2013, Intel Corporation 6 - */ 7 - 8 - #ifndef __SOUND_SOC_SST_DSP_H 9 - #define __SOUND_SOC_SST_DSP_H 10 - 11 - #include <linux/kernel.h> 12 - #include <linux/types.h> 13 - #include <linux/interrupt.h> 14 - 15 - struct sst_dsp; 16 - 17 - /* 18 - * SST Device. 19 - * 20 - * This structure is populated by the SST core driver. 21 - */ 22 - struct sst_dsp_device { 23 - /* Mandatory fields */ 24 - struct sst_ops *ops; 25 - irqreturn_t (*thread)(int irq, void *context); 26 - void *thread_context; 27 - }; 28 - 29 - /* SHIM Read / Write */ 30 - void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value); 31 - u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset); 32 - int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset, 33 - u32 mask, u32 value); 34 - void sst_dsp_shim_update_bits_forced(struct sst_dsp *sst, u32 offset, 35 - u32 mask, u32 value); 36 - 37 - /* SHIM Read / Write Unlocked for callers already holding sst lock */ 38 - void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value); 39 - u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset); 40 - int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset, 41 - u32 mask, u32 value); 42 - void sst_dsp_shim_update_bits_forced_unlocked(struct sst_dsp *sst, u32 offset, 43 - u32 mask, u32 value); 44 - 45 - /* Internal generic low-level SST IO functions - can be overidden */ 46 - void sst_shim32_write(void __iomem *addr, u32 offset, u32 value); 47 - u32 sst_shim32_read(void __iomem *addr, u32 offset); 48 - void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value); 49 - u64 sst_shim32_read64(void __iomem *addr, u32 offset); 50 - 51 - /* Mailbox management */ 52 - int sst_dsp_mailbox_init(struct sst_dsp *sst, u32 inbox_offset, 53 - size_t inbox_size, u32 outbox_offset, size_t outbox_size); 54 - void sst_dsp_inbox_write(struct sst_dsp *sst, void *message, size_t bytes); 55 - void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes); 56 - void sst_dsp_outbox_write(struct sst_dsp *sst, void *message, size_t bytes); 57 - void sst_dsp_outbox_read(struct sst_dsp *sst, void *message, size_t bytes); 58 - int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask, 59 - u32 target, u32 time, char *operation); 60 - 61 - #endif
-294
sound/soc/intel/common/sst-ipc.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Intel SST generic IPC Support 4 - * 5 - * Copyright (C) 2015, Intel Corporation 6 - */ 7 - 8 - #include <linux/types.h> 9 - #include <linux/kernel.h> 10 - #include <linux/list.h> 11 - #include <linux/wait.h> 12 - #include <linux/module.h> 13 - #include <linux/spinlock.h> 14 - #include <linux/device.h> 15 - #include <linux/slab.h> 16 - #include <linux/workqueue.h> 17 - #include <linux/sched.h> 18 - #include <linux/delay.h> 19 - #include <linux/platform_device.h> 20 - #include <sound/asound.h> 21 - 22 - #include "sst-dsp.h" 23 - #include "sst-dsp-priv.h" 24 - #include "sst-ipc.h" 25 - 26 - /* IPC message timeout (msecs) */ 27 - #define IPC_TIMEOUT_MSECS 300 28 - 29 - #define IPC_EMPTY_LIST_SIZE 8 30 - 31 - /* locks held by caller */ 32 - static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc) 33 - { 34 - struct ipc_message *msg = NULL; 35 - 36 - if (!list_empty(&ipc->empty_list)) { 37 - msg = list_first_entry(&ipc->empty_list, struct ipc_message, 38 - list); 39 - list_del(&msg->list); 40 - } 41 - 42 - return msg; 43 - } 44 - 45 - static int tx_wait_done(struct sst_generic_ipc *ipc, 46 - struct ipc_message *msg, struct sst_ipc_message *reply) 47 - { 48 - unsigned long flags; 49 - int ret; 50 - 51 - /* wait for DSP completion (in all cases atm inc pending) */ 52 - ret = wait_event_timeout(msg->waitq, msg->complete, 53 - msecs_to_jiffies(IPC_TIMEOUT_MSECS)); 54 - 55 - spin_lock_irqsave(&ipc->dsp->spinlock, flags); 56 - if (ret == 0) { 57 - if (ipc->ops.shim_dbg != NULL) 58 - ipc->ops.shim_dbg(ipc, "message timeout"); 59 - 60 - list_del(&msg->list); 61 - ret = -ETIMEDOUT; 62 - } else { 63 - 64 - /* copy the data returned from DSP */ 65 - if (reply) { 66 - reply->header = msg->rx.header; 67 - if (reply->data) 68 - memcpy(reply->data, msg->rx.data, msg->rx.size); 69 - } 70 - ret = msg->errno; 71 - } 72 - 73 - list_add_tail(&msg->list, &ipc->empty_list); 74 - spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); 75 - return ret; 76 - } 77 - 78 - static int ipc_tx_message(struct sst_generic_ipc *ipc, 79 - struct sst_ipc_message request, 80 - struct sst_ipc_message *reply, int wait) 81 - { 82 - struct ipc_message *msg; 83 - unsigned long flags; 84 - 85 - spin_lock_irqsave(&ipc->dsp->spinlock, flags); 86 - 87 - msg = msg_get_empty(ipc); 88 - if (msg == NULL) { 89 - spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); 90 - return -EBUSY; 91 - } 92 - 93 - msg->tx.header = request.header; 94 - msg->tx.size = request.size; 95 - msg->rx.header = 0; 96 - msg->rx.size = reply ? reply->size : 0; 97 - msg->wait = wait; 98 - msg->errno = 0; 99 - msg->pending = false; 100 - msg->complete = false; 101 - 102 - if ((request.size) && (ipc->ops.tx_data_copy != NULL)) 103 - ipc->ops.tx_data_copy(msg, request.data, request.size); 104 - 105 - list_add_tail(&msg->list, &ipc->tx_list); 106 - schedule_work(&ipc->kwork); 107 - spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); 108 - 109 - if (wait) 110 - return tx_wait_done(ipc, msg, reply); 111 - else 112 - return 0; 113 - } 114 - 115 - static int msg_empty_list_init(struct sst_generic_ipc *ipc) 116 - { 117 - int i; 118 - 119 - ipc->msg = kcalloc(IPC_EMPTY_LIST_SIZE, sizeof(struct ipc_message), 120 - GFP_KERNEL); 121 - if (ipc->msg == NULL) 122 - return -ENOMEM; 123 - 124 - for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { 125 - ipc->msg[i].tx.data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); 126 - if (ipc->msg[i].tx.data == NULL) 127 - goto free_mem; 128 - 129 - ipc->msg[i].rx.data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); 130 - if (ipc->msg[i].rx.data == NULL) { 131 - kfree(ipc->msg[i].tx.data); 132 - goto free_mem; 133 - } 134 - 135 - init_waitqueue_head(&ipc->msg[i].waitq); 136 - list_add(&ipc->msg[i].list, &ipc->empty_list); 137 - } 138 - 139 - return 0; 140 - 141 - free_mem: 142 - while (i > 0) { 143 - kfree(ipc->msg[i-1].tx.data); 144 - kfree(ipc->msg[i-1].rx.data); 145 - --i; 146 - } 147 - kfree(ipc->msg); 148 - 149 - return -ENOMEM; 150 - } 151 - 152 - static void ipc_tx_msgs(struct work_struct *work) 153 - { 154 - struct sst_generic_ipc *ipc = 155 - container_of(work, struct sst_generic_ipc, kwork); 156 - struct ipc_message *msg; 157 - 158 - spin_lock_irq(&ipc->dsp->spinlock); 159 - 160 - while (!list_empty(&ipc->tx_list) && !ipc->pending) { 161 - /* if the DSP is busy, we will TX messages after IRQ. 162 - * also postpone if we are in the middle of processing 163 - * completion irq 164 - */ 165 - if (ipc->ops.is_dsp_busy && ipc->ops.is_dsp_busy(ipc->dsp)) { 166 - dev_dbg(ipc->dev, "ipc_tx_msgs dsp busy\n"); 167 - break; 168 - } 169 - 170 - msg = list_first_entry(&ipc->tx_list, struct ipc_message, list); 171 - list_move(&msg->list, &ipc->rx_list); 172 - 173 - if (ipc->ops.tx_msg != NULL) 174 - ipc->ops.tx_msg(ipc, msg); 175 - } 176 - 177 - spin_unlock_irq(&ipc->dsp->spinlock); 178 - } 179 - 180 - int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, 181 - struct sst_ipc_message request, struct sst_ipc_message *reply) 182 - { 183 - int ret; 184 - 185 - /* 186 - * DSP maybe in lower power active state, so 187 - * check if the DSP supports DSP lp On method 188 - * if so invoke that before sending IPC 189 - */ 190 - if (ipc->ops.check_dsp_lp_on) 191 - if (ipc->ops.check_dsp_lp_on(ipc->dsp, true)) 192 - return -EIO; 193 - 194 - ret = ipc_tx_message(ipc, request, reply, 1); 195 - 196 - if (ipc->ops.check_dsp_lp_on) 197 - if (ipc->ops.check_dsp_lp_on(ipc->dsp, false)) 198 - return -EIO; 199 - 200 - return ret; 201 - } 202 - EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait); 203 - 204 - int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, 205 - struct sst_ipc_message request) 206 - { 207 - return ipc_tx_message(ipc, request, NULL, 0); 208 - } 209 - EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait); 210 - 211 - int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, 212 - struct sst_ipc_message request, struct sst_ipc_message *reply) 213 - { 214 - return ipc_tx_message(ipc, request, reply, 1); 215 - } 216 - EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm); 217 - 218 - struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, 219 - u64 header) 220 - { 221 - struct ipc_message *msg; 222 - u64 mask; 223 - 224 - if (ipc->ops.reply_msg_match != NULL) 225 - header = ipc->ops.reply_msg_match(header, &mask); 226 - else 227 - mask = (u64)-1; 228 - 229 - if (list_empty(&ipc->rx_list)) { 230 - dev_err(ipc->dev, "error: rx list empty but received 0x%llx\n", 231 - header); 232 - return NULL; 233 - } 234 - 235 - list_for_each_entry(msg, &ipc->rx_list, list) { 236 - if ((msg->tx.header & mask) == header) 237 - return msg; 238 - } 239 - 240 - return NULL; 241 - } 242 - EXPORT_SYMBOL_GPL(sst_ipc_reply_find_msg); 243 - 244 - /* locks held by caller */ 245 - void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc, 246 - struct ipc_message *msg) 247 - { 248 - msg->complete = true; 249 - 250 - if (!msg->wait) 251 - list_add_tail(&msg->list, &ipc->empty_list); 252 - else 253 - wake_up(&msg->waitq); 254 - } 255 - EXPORT_SYMBOL_GPL(sst_ipc_tx_msg_reply_complete); 256 - 257 - int sst_ipc_init(struct sst_generic_ipc *ipc) 258 - { 259 - int ret; 260 - 261 - INIT_LIST_HEAD(&ipc->tx_list); 262 - INIT_LIST_HEAD(&ipc->rx_list); 263 - INIT_LIST_HEAD(&ipc->empty_list); 264 - init_waitqueue_head(&ipc->wait_txq); 265 - 266 - ret = msg_empty_list_init(ipc); 267 - if (ret < 0) 268 - return -ENOMEM; 269 - 270 - INIT_WORK(&ipc->kwork, ipc_tx_msgs); 271 - return 0; 272 - } 273 - EXPORT_SYMBOL_GPL(sst_ipc_init); 274 - 275 - void sst_ipc_fini(struct sst_generic_ipc *ipc) 276 - { 277 - int i; 278 - 279 - cancel_work_sync(&ipc->kwork); 280 - 281 - if (ipc->msg) { 282 - for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { 283 - kfree(ipc->msg[i].tx.data); 284 - kfree(ipc->msg[i].rx.data); 285 - } 286 - kfree(ipc->msg); 287 - } 288 - } 289 - EXPORT_SYMBOL_GPL(sst_ipc_fini); 290 - 291 - /* Module information */ 292 - MODULE_AUTHOR("Jin Yao"); 293 - MODULE_DESCRIPTION("Intel SST IPC generic"); 294 - MODULE_LICENSE("GPL v2");
-86
sound/soc/intel/common/sst-ipc.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Intel SST generic IPC Support 4 - * 5 - * Copyright (C) 2015, Intel Corporation 6 - */ 7 - 8 - #ifndef __SST_GENERIC_IPC_H 9 - #define __SST_GENERIC_IPC_H 10 - 11 - #include <linux/types.h> 12 - #include <linux/kernel.h> 13 - #include <linux/wait.h> 14 - #include <linux/list.h> 15 - #include <linux/workqueue.h> 16 - #include <linux/sched.h> 17 - 18 - struct sst_ipc_message { 19 - u64 header; 20 - void *data; 21 - size_t size; 22 - }; 23 - 24 - struct ipc_message { 25 - struct list_head list; 26 - struct sst_ipc_message tx; 27 - struct sst_ipc_message rx; 28 - 29 - wait_queue_head_t waitq; 30 - bool pending; 31 - bool complete; 32 - bool wait; 33 - int errno; 34 - }; 35 - 36 - struct sst_generic_ipc; 37 - struct sst_dsp; 38 - 39 - struct sst_plat_ipc_ops { 40 - void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *); 41 - void (*shim_dbg)(struct sst_generic_ipc *, const char *); 42 - void (*tx_data_copy)(struct ipc_message *, char *, size_t); 43 - u64 (*reply_msg_match)(u64 header, u64 *mask); 44 - bool (*is_dsp_busy)(struct sst_dsp *dsp); 45 - int (*check_dsp_lp_on)(struct sst_dsp *dsp, bool state); 46 - }; 47 - 48 - /* SST generic IPC data */ 49 - struct sst_generic_ipc { 50 - struct device *dev; 51 - struct sst_dsp *dsp; 52 - 53 - /* IPC messaging */ 54 - struct list_head tx_list; 55 - struct list_head rx_list; 56 - struct list_head empty_list; 57 - wait_queue_head_t wait_txq; 58 - struct task_struct *tx_thread; 59 - struct work_struct kwork; 60 - bool pending; 61 - struct ipc_message *msg; 62 - int tx_data_max_size; 63 - int rx_data_max_size; 64 - 65 - struct sst_plat_ipc_ops ops; 66 - }; 67 - 68 - int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, 69 - struct sst_ipc_message request, struct sst_ipc_message *reply); 70 - 71 - int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, 72 - struct sst_ipc_message request); 73 - 74 - int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, 75 - struct sst_ipc_message request, struct sst_ipc_message *reply); 76 - 77 - struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, 78 - u64 header); 79 - 80 - void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc, 81 - struct ipc_message *msg); 82 - 83 - int sst_ipc_init(struct sst_generic_ipc *ipc); 84 - void sst_ipc_fini(struct sst_generic_ipc *ipc); 85 - 86 - #endif