diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-24 22:04:43 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-24 22:04:43 +0200 |
commit | ad7b0b7b87bb19ea7ee71e165e597f5fbfac76ab (patch) | |
tree | 5e2fcbde1d28e13a2a6086ecfb183257a0a53ed1 /drivers/soundwire | |
parent | Merge tag 'dmaengine-6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/g... (diff) | |
parent | soundwire: debugfs: simplify with cleanup.h (diff) | |
download | linux-ad7b0b7b87bb19ea7ee71e165e597f5fbfac76ab.tar.xz linux-ad7b0b7b87bb19ea7ee71e165e597f5fbfac76ab.zip |
Merge tag 'soundwire-6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire
Pull soundwire updates from Vinod Koul:
- Simplification across subsystem using cleanup.h
- Support for debugfs to read/write commands
- Few Intel and Qualcomm driver updates
* tag 'soundwire-6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire:
soundwire: debugfs: simplify with cleanup.h
soundwire: cadence: simplify with cleanup.h
soundwire: intel_ace2x: simplify with cleanup.h
soundwire: intel_ace2x: simplify return path in hw_params
soundwire: intel: simplify with cleanup.h
soundwire: intel: simplify return path in hw_params
soundwire: amd_init: simplify with cleanup.h
soundwire: amd: simplify with cleanup.h
soundwire: amd: simplify return path in hw_params
soundwire: intel_auxdevice: start the bus at default frequency
soundwire: intel_auxdevice: add cs42l43 codec to wake_capable_list
drivers:soundwire: qcom: cleanup port maask calculations
soundwire: bus: simplify by using local slave->prop
soundwire: generic_bandwidth_allocation: change port_bo parameter to pointer
soundwire: Intel: clarify Copyright information
soundwire: intel_ace2.x: add AC timing extensions for PantherLake
soundwire: bus: add stream refcount
soundwire: debugfs: add interface to read/write commands
Diffstat (limited to 'drivers/soundwire')
-rw-r--r-- | drivers/soundwire/amd_init.c | 7 | ||||
-rw-r--r-- | drivers/soundwire/amd_manager.c | 13 | ||||
-rw-r--r-- | drivers/soundwire/bus.c | 6 | ||||
-rw-r--r-- | drivers/soundwire/cadence_master.c | 5 | ||||
-rw-r--r-- | drivers/soundwire/debugfs.c | 157 | ||||
-rw-r--r-- | drivers/soundwire/generic_bandwidth_allocation.c | 14 | ||||
-rw-r--r-- | drivers/soundwire/intel.c | 25 | ||||
-rw-r--r-- | drivers/soundwire/intel.h | 5 | ||||
-rw-r--r-- | drivers/soundwire/intel_ace2x.c | 39 | ||||
-rw-r--r-- | drivers/soundwire/intel_ace2x_debugfs.c | 2 | ||||
-rw-r--r-- | drivers/soundwire/intel_auxdevice.c | 42 | ||||
-rw-r--r-- | drivers/soundwire/intel_bus_common.c | 2 | ||||
-rw-r--r-- | drivers/soundwire/qcom.c | 22 | ||||
-rw-r--r-- | drivers/soundwire/stream.c | 5 |
14 files changed, 264 insertions, 80 deletions
diff --git a/drivers/soundwire/amd_init.c b/drivers/soundwire/amd_init.c index 4cd26f3a21f5..db040f435059 100644 --- a/drivers/soundwire/amd_init.c +++ b/drivers/soundwire/amd_init.c @@ -8,6 +8,7 @@ */ #include <linux/acpi.h> +#include <linux/cleanup.h> #include <linux/export.h> #include <linux/io.h> #include <linux/module.h> @@ -69,7 +70,6 @@ static struct sdw_amd_ctx *sdw_amd_probe_controller(struct sdw_amd_res *res) { struct sdw_amd_ctx *ctx; struct acpi_device *adev; - struct resource *sdw_res; struct acp_sdw_pdata sdw_pdata[2]; struct platform_device_info pdevinfo[2]; u32 link_mask; @@ -104,7 +104,8 @@ static struct sdw_amd_ctx *sdw_amd_probe_controller(struct sdw_amd_res *res) ctx->count = count; ctx->link_mask = res->link_mask; - sdw_res = kzalloc(sizeof(*sdw_res), GFP_KERNEL); + struct resource *sdw_res __free(kfree) = kzalloc(sizeof(*sdw_res), + GFP_KERNEL); if (!sdw_res) { kfree(ctx); return NULL; @@ -132,7 +133,6 @@ static struct sdw_amd_ctx *sdw_amd_probe_controller(struct sdw_amd_res *res) if (IS_ERR(ctx->pdev[index])) goto err; } - kfree(sdw_res); return ctx; err: while (index--) { @@ -142,7 +142,6 @@ err: platform_device_unregister(ctx->pdev[index]); } - kfree(sdw_res); kfree(ctx); return NULL; } diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c index 795e223f7e5c..0d01849c3586 100644 --- a/drivers/soundwire/amd_manager.c +++ b/drivers/soundwire/amd_manager.c @@ -6,6 +6,7 @@ */ #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/device.h> #include <linux/io.h> #include <linux/jiffies.h> @@ -603,7 +604,6 @@ static int amd_sdw_hw_params(struct snd_pcm_substream *substream, struct amd_sdw_manager *amd_manager = snd_soc_dai_get_drvdata(dai); struct sdw_amd_dai_runtime *dai_runtime; struct sdw_stream_config sconfig; - struct sdw_port_config *pconfig; int ch, dir; int ret; @@ -626,11 +626,10 @@ static int amd_sdw_hw_params(struct snd_pcm_substream *substream, sconfig.bps = snd_pcm_format_width(params_format(params)); /* Port configuration */ - pconfig = kzalloc(sizeof(*pconfig), GFP_KERNEL); - if (!pconfig) { - ret = -ENOMEM; - goto error; - } + struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig), + GFP_KERNEL); + if (!pconfig) + return -ENOMEM; pconfig->num = dai->id; pconfig->ch_mask = (1 << ch) - 1; @@ -639,8 +638,6 @@ static int amd_sdw_hw_params(struct snd_pcm_substream *substream, if (ret) dev_err(amd_manager->dev, "add manager to stream failed:%d\n", ret); - kfree(pconfig); -error: return ret; } diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c index 191e6cc6f962..263ca32f0c5c 100644 --- a/drivers/soundwire/bus.c +++ b/drivers/soundwire/bus.c @@ -1410,7 +1410,7 @@ static int sdw_initialize_slave(struct sdw_slave *slave) } } if ((slave->bus->prop.quirks & SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY) && - !(slave->prop.quirks & SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY)) { + !(prop->quirks & SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY)) { /* Clear parity interrupt before enabling interrupt mask */ status = sdw_read_no_pm(slave, SDW_SCP_INT1); if (status < 0) { @@ -1436,7 +1436,7 @@ static int sdw_initialize_slave(struct sdw_slave *slave) * device-dependent, it might e.g. only be enabled in * steady-state after a couple of frames. */ - val = slave->prop.scp_int1_mask; + val = prop->scp_int1_mask; /* Enable SCP interrupts */ ret = sdw_update_no_pm(slave, SDW_SCP_INTMASK1, val, val); @@ -1447,7 +1447,7 @@ static int sdw_initialize_slave(struct sdw_slave *slave) } /* No need to continue if DP0 is not present */ - if (!slave->prop.dp0_prop) + if (!prop->dp0_prop) return 0; /* Enable DP0 interrupts */ diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index 74da99034dab..e0683a5975d1 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -6,6 +6,7 @@ * Used by Master driver */ +#include <linux/cleanup.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/debugfs.h> @@ -323,12 +324,11 @@ static ssize_t cdns_sprintf(struct sdw_cdns *cdns, static int cdns_reg_show(struct seq_file *s, void *data) { struct sdw_cdns *cdns = s->private; - char *buf; ssize_t ret; int num_ports; int i, j; - buf = kzalloc(RD_BUF, GFP_KERNEL); + char *buf __free(kfree) = kzalloc(RD_BUF, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -389,7 +389,6 @@ static int cdns_reg_show(struct seq_file *s, void *data) ret += cdns_sprintf(cdns, buf, ret, CDNS_PDI_CONFIG(i)); seq_printf(s, "%s", buf); - kfree(buf); return 0; } diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c index 67abd7e52f09..c30f571934ee 100644 --- a/drivers/soundwire/debugfs.c +++ b/drivers/soundwire/debugfs.c @@ -1,8 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only // Copyright(c) 2017-2019 Intel Corporation. +#include <linux/cleanup.h> #include <linux/device.h> #include <linux/debugfs.h> +#include <linux/firmware.h> #include <linux/mod_devicetable.h> #include <linux/pm_runtime.h> #include <linux/slab.h> @@ -48,18 +50,16 @@ static ssize_t sdw_sprintf(struct sdw_slave *slave, static int sdw_slave_reg_show(struct seq_file *s_file, void *data) { struct sdw_slave *slave = s_file->private; - char *buf; ssize_t ret; int i, j; - buf = kzalloc(RD_BUF, GFP_KERNEL); + char *buf __free(kfree) = kzalloc(RD_BUF, GFP_KERNEL); if (!buf) return -ENOMEM; ret = pm_runtime_get_sync(&slave->dev); if (ret < 0 && ret != -EACCES) { pm_runtime_put_noidle(&slave->dev); - kfree(buf); return ret; } @@ -131,12 +131,149 @@ static int sdw_slave_reg_show(struct seq_file *s_file, void *data) pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put(&slave->dev); - kfree(buf); - return 0; } DEFINE_SHOW_ATTRIBUTE(sdw_slave_reg); +#define MAX_CMD_BYTES 256 + +static int cmd; +static u32 start_addr; +static size_t num_bytes; +static u8 read_buffer[MAX_CMD_BYTES]; +static char *firmware_file; + +static int set_command(void *data, u64 value) +{ + struct sdw_slave *slave = data; + + if (value > 1) + return -EINVAL; + + /* Userspace changed the hardware state behind the kernel's back */ + add_taint(TAINT_USER, LOCKDEP_STILL_OK); + + dev_dbg(&slave->dev, "command: %s\n", value ? "read" : "write"); + cmd = value; + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(set_command_fops, NULL, + set_command, "%llu\n"); + +static int set_start_address(void *data, u64 value) +{ + struct sdw_slave *slave = data; + + /* Userspace changed the hardware state behind the kernel's back */ + add_taint(TAINT_USER, LOCKDEP_STILL_OK); + + dev_dbg(&slave->dev, "start address %#llx\n", value); + + start_addr = value; + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(set_start_address_fops, NULL, + set_start_address, "%llu\n"); + +static int set_num_bytes(void *data, u64 value) +{ + struct sdw_slave *slave = data; + + if (value == 0 || value > MAX_CMD_BYTES) + return -EINVAL; + + /* Userspace changed the hardware state behind the kernel's back */ + add_taint(TAINT_USER, LOCKDEP_STILL_OK); + + dev_dbg(&slave->dev, "number of bytes %lld\n", value); + + num_bytes = value; + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(set_num_bytes_fops, NULL, + set_num_bytes, "%llu\n"); + +static int cmd_go(void *data, u64 value) +{ + struct sdw_slave *slave = data; + int ret; + + if (value != 1) + return -EINVAL; + + /* one last check */ + if (start_addr > SDW_REG_MAX || + num_bytes == 0 || num_bytes > MAX_CMD_BYTES) + return -EINVAL; + + ret = pm_runtime_get_sync(&slave->dev); + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_noidle(&slave->dev); + return ret; + } + + /* Userspace changed the hardware state behind the kernel's back */ + add_taint(TAINT_USER, LOCKDEP_STILL_OK); + + dev_dbg(&slave->dev, "starting command\n"); + + if (cmd == 0) { + const struct firmware *fw; + + ret = request_firmware(&fw, firmware_file, &slave->dev); + if (ret < 0) { + dev_err(&slave->dev, "firmware %s not found\n", firmware_file); + goto out; + } + + if (fw->size != num_bytes) { + dev_err(&slave->dev, + "firmware %s: unexpected size %zd, desired %zd\n", + firmware_file, fw->size, num_bytes); + release_firmware(fw); + goto out; + } + + ret = sdw_nwrite_no_pm(slave, start_addr, num_bytes, fw->data); + release_firmware(fw); + } else { + ret = sdw_nread_no_pm(slave, start_addr, num_bytes, read_buffer); + } + + dev_dbg(&slave->dev, "command completed %d\n", ret); + +out: + pm_runtime_mark_last_busy(&slave->dev); + pm_runtime_put(&slave->dev); + + return ret; +} +DEFINE_DEBUGFS_ATTRIBUTE(cmd_go_fops, NULL, + cmd_go, "%llu\n"); + +#define MAX_LINE_LEN 128 + +static int read_buffer_show(struct seq_file *s_file, void *data) +{ + char buf[MAX_LINE_LEN]; + int i; + + if (num_bytes == 0 || num_bytes > MAX_CMD_BYTES) + return -EINVAL; + + for (i = 0; i < num_bytes; i++) { + scnprintf(buf, MAX_LINE_LEN, "address %#x val 0x%02x\n", + start_addr + i, read_buffer[i]); + seq_printf(s_file, "%s", buf); + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(read_buffer); + void sdw_slave_debugfs_init(struct sdw_slave *slave) { struct dentry *master; @@ -151,6 +288,16 @@ void sdw_slave_debugfs_init(struct sdw_slave *slave) debugfs_create_file("registers", 0400, d, slave, &sdw_slave_reg_fops); + /* interface to send arbitrary commands */ + debugfs_create_file("command", 0200, d, slave, &set_command_fops); + debugfs_create_file("start_address", 0200, d, slave, &set_start_address_fops); + debugfs_create_file("num_bytes", 0200, d, slave, &set_num_bytes_fops); + debugfs_create_file("go", 0200, d, slave, &cmd_go_fops); + + debugfs_create_file("read_buffer", 0400, d, slave, &read_buffer_fops); + firmware_file = NULL; + debugfs_create_str("firmware_file", 0200, d, &firmware_file); + slave->debugfs = d; } diff --git a/drivers/soundwire/generic_bandwidth_allocation.c b/drivers/soundwire/generic_bandwidth_allocation.c index c70a63d009ae..b9316207c3ab 100644 --- a/drivers/soundwire/generic_bandwidth_allocation.c +++ b/drivers/soundwire/generic_bandwidth_allocation.c @@ -83,7 +83,7 @@ EXPORT_SYMBOL(sdw_compute_slave_ports); static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt, struct sdw_group_params *params, - int port_bo, int hstop) + int *port_bo, int hstop) { struct sdw_transport_data t_data = {0}; struct sdw_port_runtime *p_rt; @@ -108,7 +108,7 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt, sdw_fill_xport_params(&p_rt->transport_params, p_rt->num, false, SDW_BLK_GRP_CNT_1, sample_int, - port_bo, port_bo >> 8, hstart, hstop, + *port_bo, (*port_bo) >> 8, hstart, hstop, SDW_BLK_PKG_PER_PORT, 0x0); sdw_fill_port_params(&p_rt->port_params, @@ -120,15 +120,15 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt, if (!(p_rt == list_first_entry(&m_rt->port_list, struct sdw_port_runtime, port_node))) { - port_bo += bps * ch; + (*port_bo) += bps * ch; continue; } t_data.hstart = hstart; t_data.hstop = hstop; - t_data.block_offset = port_bo; + t_data.block_offset = *port_bo; t_data.sub_block_offset = 0; - port_bo += bps * ch; + (*port_bo) += bps * ch; } sdw_compute_slave_ports(m_rt, &t_data); @@ -146,9 +146,7 @@ static void _sdw_compute_port_params(struct sdw_bus *bus, port_bo = 1; list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) { - sdw_compute_master_ports(m_rt, ¶ms[i], port_bo, hstop); - - port_bo += m_rt->ch_count * m_rt->stream->params.bps; + sdw_compute_master_ports(m_rt, ¶ms[i], &port_bo, hstop); } hstop = hstop - params[i].hwidth; diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 01e1a0f3ec39..421da0f86fad 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -6,6 +6,7 @@ */ #include <linux/acpi.h> +#include <linux/cleanup.h> #include <linux/debugfs.h> #include <linux/delay.h> #include <linux/io.h> @@ -73,12 +74,11 @@ static int intel_reg_show(struct seq_file *s_file, void *data) struct sdw_intel *sdw = s_file->private; void __iomem *s = sdw->link_res->shim; void __iomem *a = sdw->link_res->alh; - char *buf; ssize_t ret; int i, j; unsigned int links, reg; - buf = kzalloc(RD_BUF, GFP_KERNEL); + char *buf __free(kfree) = kzalloc(RD_BUF, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -129,7 +129,6 @@ static int intel_reg_show(struct seq_file *s_file, void *data) ret += intel_sprintf(a, true, buf, ret, SDW_ALH_STRMZCFG(i)); seq_printf(s_file, "%s", buf); - kfree(buf); return 0; } @@ -727,7 +726,6 @@ static int intel_hw_params(struct snd_pcm_substream *substream, struct sdw_cdns_dai_runtime *dai_runtime; struct sdw_cdns_pdi *pdi; struct sdw_stream_config sconfig; - struct sdw_port_config *pconfig; int ch, dir; int ret; @@ -743,10 +741,8 @@ static int intel_hw_params(struct snd_pcm_substream *substream, pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, ch, dir, dai->id); - if (!pdi) { - ret = -EINVAL; - goto error; - } + if (!pdi) + return -EINVAL; /* do run-time configurations for SHIM, ALH and PDI/PORT */ intel_pdi_shim_configure(sdw, pdi); @@ -763,7 +759,7 @@ static int intel_hw_params(struct snd_pcm_substream *substream, sdw->instance, pdi->intel_alh_id); if (ret) - goto error; + return ret; sconfig.direction = dir; sconfig.ch_count = ch; @@ -773,11 +769,10 @@ static int intel_hw_params(struct snd_pcm_substream *substream, sconfig.bps = snd_pcm_format_width(params_format(params)); /* Port configuration */ - pconfig = kzalloc(sizeof(*pconfig), GFP_KERNEL); - if (!pconfig) { - ret = -ENOMEM; - goto error; - } + struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig), + GFP_KERNEL); + if (!pconfig) + return -ENOMEM; pconfig->num = pdi->num; pconfig->ch_mask = (1 << ch) - 1; @@ -787,8 +782,6 @@ static int intel_hw_params(struct snd_pcm_substream *substream, if (ret) dev_err(cdns->dev, "add master to stream failed:%d\n", ret); - kfree(pconfig); -error: return ret; } diff --git a/drivers/soundwire/intel.h b/drivers/soundwire/intel.h index b68e74c294e7..68838e843b54 100644 --- a/drivers/soundwire/intel.h +++ b/drivers/soundwire/intel.h @@ -59,6 +59,11 @@ struct sdw_intel { }; struct sdw_intel_prop { + u16 clde; + u16 doaise2; + u16 dodse2; + u16 clds; + u16 clss; u16 doaise; u16 doais; u16 dodse; diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c index 8b1b6ad420cf..781fe0aefa68 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -1,11 +1,12 @@ // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) -// Copyright(c) 2023 Intel Corporation. All rights reserved. +// Copyright(c) 2023 Intel Corporation /* * Soundwire Intel ops for LunarLake */ #include <linux/acpi.h> +#include <linux/cleanup.h> #include <linux/device.h> #include <linux/soundwire/sdw_registers.h> #include <linux/soundwire/sdw.h> @@ -27,6 +28,11 @@ static void intel_shim_vs_init(struct sdw_intel *sdw) void __iomem *shim_vs = sdw->link_res->shim_vs; struct sdw_bus *bus = &sdw->cdns.bus; struct sdw_intel_prop *intel_prop; + u16 clde; + u16 doaise2; + u16 dodse2; + u16 clds; + u16 clss; u16 doaise; u16 doais; u16 dodse; @@ -34,12 +40,22 @@ static void intel_shim_vs_init(struct sdw_intel *sdw) u16 act; intel_prop = bus->vendor_specific_prop; + clde = intel_prop->clde; + doaise2 = intel_prop->doaise2; + dodse2 = intel_prop->dodse2; + clds = intel_prop->clds; + clss = intel_prop->clss; doaise = intel_prop->doaise; doais = intel_prop->doais; dodse = intel_prop->dodse; dods = intel_prop->dods; act = intel_readw(shim_vs, SDW_SHIM2_INTEL_VS_ACTMCTL); + u16p_replace_bits(&act, clde, SDW_SHIM3_INTEL_VS_ACTMCTL_CLDE); + u16p_replace_bits(&act, doaise2, SDW_SHIM3_INTEL_VS_ACTMCTL_DOAISE2); + u16p_replace_bits(&act, dodse2, SDW_SHIM3_INTEL_VS_ACTMCTL_DODSE2); + u16p_replace_bits(&act, clds, SDW_SHIM3_INTEL_VS_ACTMCTL_CLDS); + u16p_replace_bits(&act, clss, SDW_SHIM3_INTEL_VS_ACTMCTL_CLSS); u16p_replace_bits(&act, doaise, SDW_SHIM2_INTEL_VS_ACTMCTL_DOAISE); u16p_replace_bits(&act, doais, SDW_SHIM2_INTEL_VS_ACTMCTL_DOAIS); u16p_replace_bits(&act, dodse, SDW_SHIM2_INTEL_VS_ACTMCTL_DODSE); @@ -295,7 +311,6 @@ static int intel_hw_params(struct snd_pcm_substream *substream, struct sdw_cdns_dai_runtime *dai_runtime; struct sdw_cdns_pdi *pdi; struct sdw_stream_config sconfig; - struct sdw_port_config *pconfig; int ch, dir; int ret; @@ -310,11 +325,8 @@ static int intel_hw_params(struct snd_pcm_substream *substream, dir = SDW_DATA_DIR_TX; pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, ch, dir, dai->id); - - if (!pdi) { - ret = -EINVAL; - goto error; - } + if (!pdi) + return -EINVAL; /* use same definitions for alh_id as previous generations */ pdi->intel_alh_id = (sdw->instance * 16) + pdi->num + 3; @@ -335,7 +347,7 @@ static int intel_hw_params(struct snd_pcm_substream *substream, sdw->instance, pdi->intel_alh_id); if (ret) - goto error; + return ret; sconfig.direction = dir; sconfig.ch_count = ch; @@ -345,11 +357,10 @@ static int intel_hw_params(struct snd_pcm_substream *substream, sconfig.bps = snd_pcm_format_width(params_format(params)); /* Port configuration */ - pconfig = kzalloc(sizeof(*pconfig), GFP_KERNEL); - if (!pconfig) { - ret = -ENOMEM; - goto error; - } + struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig), + GFP_KERNEL); + if (!pconfig) + return -ENOMEM; pconfig->num = pdi->num; pconfig->ch_mask = (1 << ch) - 1; @@ -359,8 +370,6 @@ static int intel_hw_params(struct snd_pcm_substream *substream, if (ret) dev_err(cdns->dev, "add master to stream failed:%d\n", ret); - kfree(pconfig); -error: return ret; } diff --git a/drivers/soundwire/intel_ace2x_debugfs.c b/drivers/soundwire/intel_ace2x_debugfs.c index 3d24661ffd37..206a8d511ebd 100644 --- a/drivers/soundwire/intel_ace2x_debugfs.c +++ b/drivers/soundwire/intel_ace2x_debugfs.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -// Copyright(c) 2023 Intel Corporation. All rights reserved. +// Copyright(c) 2023 Intel Corporation #include <linux/acpi.h> #include <linux/debugfs.h> diff --git a/drivers/soundwire/intel_auxdevice.c b/drivers/soundwire/intel_auxdevice.c index 18517121cc89..8807e01cbf7c 100644 --- a/drivers/soundwire/intel_auxdevice.c +++ b/drivers/soundwire/intel_auxdevice.c @@ -47,6 +47,7 @@ struct wake_capable_part { }; static struct wake_capable_part wake_capable_list[] = { + {0x01fa, 0x4243}, {0x025d, 0x5682}, {0x025d, 0x700}, {0x025d, 0x711}, @@ -161,12 +162,32 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus) } /* initialize with hardware defaults, in case the properties are not found */ + intel_prop->clde = 0x0; + intel_prop->doaise2 = 0x0; + intel_prop->dodse2 = 0x0; + intel_prop->clds = 0x0; + intel_prop->clss = 0x0; intel_prop->doaise = 0x1; intel_prop->doais = 0x3; intel_prop->dodse = 0x0; intel_prop->dods = 0x1; fwnode_property_read_u16(link, + "intel-sdw-clde", + &intel_prop->clde); + fwnode_property_read_u16(link, + "intel-sdw-doaise2", + &intel_prop->doaise2); + fwnode_property_read_u16(link, + "intel-sdw-dodse2", + &intel_prop->dodse2); + fwnode_property_read_u16(link, + "intel-sdw-clds", + &intel_prop->clds); + fwnode_property_read_u16(link, + "intel-sdw-clss", + &intel_prop->clss); + fwnode_property_read_u16(link, "intel-sdw-doaise", &intel_prop->doaise); fwnode_property_read_u16(link, @@ -193,9 +214,30 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus) static int intel_prop_read(struct sdw_bus *bus) { + struct sdw_master_prop *prop; + /* Initialize with default handler to read all DisCo properties */ sdw_master_read_prop(bus); + /* + * Only one bus frequency is supported so far, filter + * frequencies reported in the DSDT + */ + prop = &bus->prop; + if (prop->clk_freq && prop->num_clk_freq > 1) { + unsigned int default_bus_frequency; + + default_bus_frequency = + prop->default_frame_rate * + prop->default_row * + prop->default_col / + SDW_DOUBLE_RATE_FACTOR; + + prop->num_clk_freq = 1; + prop->clk_freq[0] = default_bus_frequency; + prop->max_clk_freq = default_bus_frequency; + } + /* read Intel-specific properties */ sdw_master_read_intel_prop(bus); diff --git a/drivers/soundwire/intel_bus_common.c b/drivers/soundwire/intel_bus_common.c index e5ac3cc7cb79..df944e11b9ca 100644 --- a/drivers/soundwire/intel_bus_common.c +++ b/drivers/soundwire/intel_bus_common.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) -// Copyright(c) 2015-2023 Intel Corporation. All rights reserved. +// Copyright(c) 2015-2023 Intel Corporation #include <linux/acpi.h> #include <linux/soundwire/sdw_registers.h> diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index ce5cf3ecceb5..aed57002fd0e 100644 --- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -197,8 +197,7 @@ struct qcom_swrm_ctrl { int num_dout_ports; int cols_index; int rows_index; - unsigned long dout_port_mask; - unsigned long din_port_mask; + unsigned long port_mask; u32 intr_mask; u8 rcmd_id; u8 wcmd_id; @@ -1146,11 +1145,7 @@ static void qcom_swrm_stream_free_ports(struct qcom_swrm_ctrl *ctrl, mutex_lock(&ctrl->port_lock); list_for_each_entry(m_rt, &stream->master_list, stream_node) { - if (m_rt->direction == SDW_DATA_DIR_RX) - port_mask = &ctrl->dout_port_mask; - else - port_mask = &ctrl->din_port_mask; - + port_mask = &ctrl->port_mask; list_for_each_entry(p_rt, &m_rt->port_list, port_node) clear_bit(p_rt->num, port_mask); } @@ -1195,13 +1190,9 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl, if (ctrl->bus.id != m_rt->bus->id) continue; - if (m_rt->direction == SDW_DATA_DIR_RX) { - maxport = ctrl->num_dout_ports; - port_mask = &ctrl->dout_port_mask; - } else { - maxport = ctrl->num_din_ports; - port_mask = &ctrl->din_port_mask; - } + port_mask = &ctrl->port_mask; + maxport = ctrl->num_dout_ports + ctrl->num_din_ports; + list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) { slave = s_rt->slave; @@ -1401,8 +1392,7 @@ static int qcom_swrm_get_port_config(struct qcom_swrm_ctrl *ctrl) return -EINVAL; /* Valid port numbers are from 1-14, so mask out port 0 explicitly */ - set_bit(0, &ctrl->dout_port_mask); - set_bit(0, &ctrl->din_port_mask); + set_bit(0, &ctrl->port_mask); ret = of_property_read_u8_array(np, "qcom,ports-offset1", off1, nports); diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index 4e9e7d2a942d..7aa4900dcf31 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -1181,6 +1181,8 @@ static struct sdw_master_runtime m_rt->bus = bus; m_rt->stream = stream; + bus->stream_refcount++; + return m_rt; } @@ -1217,6 +1219,7 @@ static void sdw_master_rt_free(struct sdw_master_runtime *m_rt, struct sdw_stream_runtime *stream) { struct sdw_slave_runtime *s_rt, *_s_rt; + struct sdw_bus *bus = m_rt->bus; list_for_each_entry_safe(s_rt, _s_rt, &m_rt->slave_rt_list, m_rt_node) { sdw_slave_port_free(s_rt->slave, stream); @@ -1226,6 +1229,8 @@ static void sdw_master_rt_free(struct sdw_master_runtime *m_rt, list_del(&m_rt->stream_node); list_del(&m_rt->bus_node); kfree(m_rt); + + bus->stream_refcount--; } /** |