From fe46d2a4301de1299fb32c0317ec316706ceaad6 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 3 Jun 2024 14:58:40 +0800 Subject: [PATCH 01/18] soundwire: debugfs: add interface to read/write commands We have an existing debugfs files to read standard registers (DP0/SCP/DPn). This patch provides a more generic interface to ANY set of read/write contiguous registers in a peripheral device. In follow-up patches, this interface will be extended to use BRA transfers. The sequence is to use the following files added under the existing debugsfs directory for each peripheral device: command (write 0, read 1) num_bytes start_address firmware_file (only for writes) read_buffer (only for reads) Example for a read command - this checks the 6 bytes used for enumeration. cd /sys/kernel/debug/soundwire/master-0-0/sdw\:0\:025d\:0711\:01/ echo 1 > command echo 6 > num_bytes echo 0x50 > start_address echo 1 > go cat read_buffer address 0x50 val 0x30 address 0x51 val 0x02 address 0x52 val 0x5d address 0x53 val 0x07 address 0x54 val 0x11 address 0x55 val 0x01 Example with a 2-byte firmware file written in DP0 address 0x22 od -x /lib/firmware/test_firmware 0000000 0a37 0000002 cd /sys/kernel/debug/soundwire/master-0-0/sdw\:0\:025d\:0711\:01/ echo 0 > command echo 2 > num_bytes echo 0x22 > start_address echo "test_firmware" > firmware_file echo 1 > go cd /sys/kernel/debug/soundwire/master-0-0/sdw\:0\:025d\:0711\:01/ echo 1 > command echo 2 > num_bytes echo 0x22 > start_address echo 1 > go cat read_buffer address 0x22 val 0x37 address 0x23 val 0x0a Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240603065841.4860-1-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- drivers/soundwire/debugfs.c | 150 ++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c index 67abd7e52f092..6d253d69871d9 100644 --- a/drivers/soundwire/debugfs.c +++ b/drivers/soundwire/debugfs.c @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -137,6 +138,145 @@ static int sdw_slave_reg_show(struct seq_file *s_file, void *data) } 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 +291,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; } From a5b7365f28c191df6b93f60942d2b9a9fe71746c Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 3 Jun 2024 14:58:41 +0800 Subject: [PATCH 02/18] soundwire: bus: add stream refcount The notion of stream is by construction based on a multi-bus capability, to allow for aggregation of Peripheral devices or functions located on different segments. We currently count how many master_rt contexts are used by a stream, but we don't have the dual refcount of how many streams are allocated on a given bus. This refcount will be useful to check if BTP/BRA streams can be allocated. Note that the stream_refcount is modified in sdw_master_rt_alloc() and sdw_master_rt_free() which are both called with the bus_lock mutex held, so there's no need for refcount_ primitives for additional protection. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240603065841.4860-2-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- drivers/soundwire/stream.c | 5 +++++ include/linux/soundwire/sdw.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index 4e9e7d2a942d8..7aa4900dcf317 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--; } /** diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index 13e96d8b7423c..94fc1b57c57ba 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -903,6 +903,7 @@ struct sdw_master_ops { * meaningful if multi_link is set. If set to 1, hardware-based * synchronization will be used even if a stream only uses a single * SoundWire segment. + * @stream_refcount: number of streams currently using this bus */ struct sdw_bus { struct device *dev; @@ -933,6 +934,7 @@ struct sdw_bus { u32 bank_switch_timeout; bool multi_link; int hw_sync_min_links; + int stream_refcount; }; int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent, From 9b5fd115e7d5a98b82054cff5c96f6768ee06845 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 3 Jun 2024 15:02:40 +0800 Subject: [PATCH 03/18] soundwire: intel_ace2.x: add AC timing extensions for PantherLake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ACE3 IP used in PantherLake exposes new bitfields in the ACTMCTL register to better control clocks/delays. These bitfields were reserved/zero in the ACE2.x IP, to simplify the integration the new bifields are added unconditionally. The behavior will only be impacted when the firmware exposes DSD properties to set non-zero values. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Ranjani Sridharan Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240603070240.5165-1-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- drivers/soundwire/intel.h | 5 +++++ drivers/soundwire/intel_ace2x.c | 15 +++++++++++++++ drivers/soundwire/intel_auxdevice.c | 20 ++++++++++++++++++++ include/linux/soundwire/sdw_intel.h | 5 +++++ 4 files changed, 45 insertions(+) diff --git a/drivers/soundwire/intel.h b/drivers/soundwire/intel.h index b68e74c294e70..68838e843b543 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 8b1b6ad420cf1..0dadf46faca6a 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -27,6 +27,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 +39,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); diff --git a/drivers/soundwire/intel_auxdevice.c b/drivers/soundwire/intel_auxdevice.c index 17cf27e6ea738..54cb455ed8706 100644 --- a/drivers/soundwire/intel_auxdevice.c +++ b/drivers/soundwire/intel_auxdevice.c @@ -159,11 +159,31 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus) return -ENOMEM; /* 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); diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h index 8e78417156e3c..d537587b44992 100644 --- a/include/linux/soundwire/sdw_intel.h +++ b/include/linux/soundwire/sdw_intel.h @@ -182,6 +182,11 @@ #define SDW_SHIM2_INTEL_VS_ACTMCTL_DODSE BIT(2) #define SDW_SHIM2_INTEL_VS_ACTMCTL_DOAIS GENMASK(4, 3) #define SDW_SHIM2_INTEL_VS_ACTMCTL_DOAISE BIT(5) +#define SDW_SHIM3_INTEL_VS_ACTMCTL_CLSS BIT(6) +#define SDW_SHIM3_INTEL_VS_ACTMCTL_CLDS GENMASK(11, 7) +#define SDW_SHIM3_INTEL_VS_ACTMCTL_DODSE2 GENMASK(13, 12) +#define SDW_SHIM3_INTEL_VS_ACTMCTL_DOAISE2 BIT(14) +#define SDW_SHIM3_INTEL_VS_ACTMCTL_CLDE BIT(15) /** * struct sdw_intel_stream_params_data: configuration passed during From b96f16bdf58dae08d841536820269c6b0d9c976b Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 17 Jun 2024 20:13:18 +0800 Subject: [PATCH 04/18] soundwire: Intel: clarify Copyright information MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reason a number of files included the "All rights reserved" statement. Good old copy-paste made sure this mistake proliferated. Remove the "All rights reserved" in all Intel-copyright to align with internal guidance. Reviewed-by: Cezary Rojewski Signed-off-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240617121318.14037-1-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- drivers/soundwire/intel_ace2x.c | 2 +- drivers/soundwire/intel_ace2x_debugfs.c | 2 +- drivers/soundwire/intel_bus_common.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c index 0dadf46faca6a..4f78b7f99e441 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -1,5 +1,5 @@ // 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 diff --git a/drivers/soundwire/intel_ace2x_debugfs.c b/drivers/soundwire/intel_ace2x_debugfs.c index 3d24661ffd370..206a8d511ebdc 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 #include diff --git a/drivers/soundwire/intel_bus_common.c b/drivers/soundwire/intel_bus_common.c index e5ac3cc7cb79b..df944e11b9caa 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 #include From 8e8c0dfc828c3f3ba5ebcee076b979d2134a6e27 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 17 Jun 2024 20:13:50 +0800 Subject: [PATCH 05/18] soundwire: generic_bandwidth_allocation: change port_bo parameter to pointer Currently, we do port_bo += bps * ch in both inside and outside sdw_compute_master_ports(). We can pass port_bo as a pointer and only calculate port_bo in sdw_compute_master_ports(). Besides, different port could use different lanes and we can't just add port_bo based on total channels in a manager. Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240617121350.14074-1-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- drivers/soundwire/generic_bandwidth_allocation.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/soundwire/generic_bandwidth_allocation.c b/drivers/soundwire/generic_bandwidth_allocation.c index c70a63d009ae4..b9316207c3ab2 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; From 5a4c1f0207d8925c45a516d8dc85f0dd70c020ef Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 20 Jun 2024 11:10:46 +0200 Subject: [PATCH 06/18] soundwire: bus: simplify by using local slave->prop The sdw_initialize_slave() function stores 'slave->prop' as local 'prop' variable, so use it in all applicable places to make code a bit simpler. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20240620091046.12426-1-krzysztof.kozlowski@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/bus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c index 191e6cc6f9627..263ca32f0c5c3 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 */ From 518aee32c551d2f7d1e577f63df6dfcc80259b50 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 18 Jun 2024 14:55:15 +0100 Subject: [PATCH 07/18] drivers:soundwire: qcom: cleanup port maask calculations Cleanup the port map calculations, existing masks of having separate masks for in and out ports is not really required. Having a single mask for all the ports in the controller is simple and cuts of some unnecessary code. Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20240618-soundwire-port-map-v1-1-9644e5545b9b@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/qcom.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index ce5cf3ecceb58..aed57002fd0e6 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); From fe600c8e2dc5dde62aefc73cb1cdcc5bff3dfed7 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Fri, 5 Jul 2024 11:43:05 +0000 Subject: [PATCH 08/18] soundwire: intel_auxdevice: add cs42l43 codec to wake_capable_list cs42l43 has wake capability. Add it to the wake_capable_list. Signed-off-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20240705114305.160233-1-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- drivers/soundwire/intel_auxdevice.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soundwire/intel_auxdevice.c b/drivers/soundwire/intel_auxdevice.c index 54cb455ed8706..b109fa84d7549 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}, From c326356188f1dc2d7a2c55b30dac6a8b76087bc6 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 4 Jul 2024 08:34:11 +0800 Subject: [PATCH 09/18] soundwire: intel_auxdevice: start the bus at default frequency When platform firmware exposes multiple supported bus frequencies, the existing SoundWire support selects the maximum frequency. This is not aligned with the SoundWire 1.2 directions: the MIPI recommendation is to start at a 'safe' speed, compatible with the default frame rate and shape, and only increase the clock when vendor and codec PHY parameters are updated. However, clock changes are not supported for now by the SoundWire core, so in practice this patch has the effect of discarding frequencies different to the implicit default. Dynamic clock changes will be required at some point, and this limitation will be removed after the core is updated, specifically to perform synchronous clock scale changes on manager and peripheral sides with a bank switch. On Intel LunarLake platforms with a 'standard' DSDT, this forces the use of 4.8MHz. On older platforms this patch has no effect. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240704003411.10347-1-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- drivers/soundwire/intel_auxdevice.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/soundwire/intel_auxdevice.c b/drivers/soundwire/intel_auxdevice.c index b109fa84d7549..b8b317b0ab48a 100644 --- a/drivers/soundwire/intel_auxdevice.c +++ b/drivers/soundwire/intel_auxdevice.c @@ -210,9 +210,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); From 89cc1354d388ba8c8f8b41095736202a83591497 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 3 Jul 2024 12:15:53 +0200 Subject: [PATCH 10/18] soundwire: amd: simplify return path in hw_params Remove unused error path (label+goto) to make the code a bit simpler. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240703-soundwire-cleanup-h-v1-1-24fa0dbb948f@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/amd_manager.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c index 20d94bcfc9b4f..97720900818e5 100644 --- a/drivers/soundwire/amd_manager.c +++ b/drivers/soundwire/amd_manager.c @@ -624,10 +624,8 @@ static int amd_sdw_hw_params(struct snd_pcm_substream *substream, /* Port configuration */ pconfig = kzalloc(sizeof(*pconfig), GFP_KERNEL); - if (!pconfig) { - ret = -ENOMEM; - goto error; - } + if (!pconfig) + return -ENOMEM; pconfig->num = dai->id; pconfig->ch_mask = (1 << ch) - 1; @@ -637,7 +635,7 @@ static int amd_sdw_hw_params(struct snd_pcm_substream *substream, dev_err(amd_manager->dev, "add manager to stream failed:%d\n", ret); kfree(pconfig); -error: + return ret; } From 02611eeec5893c17ad85769007ecfb5cbe7a5987 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 3 Jul 2024 12:15:54 +0200 Subject: [PATCH 11/18] soundwire: amd: simplify with cleanup.h Allocate the memory with scoped/cleanup.h to reduce error handling and make the code a bit simpler. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240703-soundwire-cleanup-h-v1-2-24fa0dbb948f@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/amd_manager.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c index 97720900818e5..883b83b7bdacc 100644 --- a/drivers/soundwire/amd_manager.c +++ b/drivers/soundwire/amd_manager.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -600,7 +601,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; @@ -623,7 +623,8 @@ 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); + struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig), + GFP_KERNEL); if (!pconfig) return -ENOMEM; @@ -634,8 +635,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); - return ret; } From 1f93cb229b0e2d78233690c9ca65715e1f798803 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 3 Jul 2024 12:15:55 +0200 Subject: [PATCH 12/18] soundwire: amd_init: simplify with cleanup.h Allocate the memory with scoped/cleanup.h to reduce error handling and make the code a bit simpler. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240703-soundwire-cleanup-h-v1-3-24fa0dbb948f@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/amd_init.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/soundwire/amd_init.c b/drivers/soundwire/amd_init.c index 4cd26f3a21f5d..db040f4350599 100644 --- a/drivers/soundwire/amd_init.c +++ b/drivers/soundwire/amd_init.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -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 @@ static struct sdw_amd_ctx *sdw_amd_probe_controller(struct sdw_amd_res *res) platform_device_unregister(ctx->pdev[index]); } - kfree(sdw_res); kfree(ctx); return NULL; } From ba874a8c2f895d898bbaf67f9e952425aff1557d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 3 Jul 2024 12:15:56 +0200 Subject: [PATCH 13/18] soundwire: intel: simplify return path in hw_params Remove unused error path (label+goto) to make the code a bit simpler. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240703-soundwire-cleanup-h-v1-4-24fa0dbb948f@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/intel.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 01e1a0f3ec394..b4449095b4238 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -743,10 +743,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 +761,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; @@ -774,10 +772,8 @@ static int intel_hw_params(struct snd_pcm_substream *substream, /* Port configuration */ pconfig = kzalloc(sizeof(*pconfig), GFP_KERNEL); - if (!pconfig) { - ret = -ENOMEM; - goto error; - } + if (!pconfig) + return -ENOMEM; pconfig->num = pdi->num; pconfig->ch_mask = (1 << ch) - 1; @@ -788,7 +784,7 @@ static int intel_hw_params(struct snd_pcm_substream *substream, dev_err(cdns->dev, "add master to stream failed:%d\n", ret); kfree(pconfig); -error: + return ret; } From e4fcf153d91809aefa6860d285e747fd7dd9e61c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 3 Jul 2024 12:15:57 +0200 Subject: [PATCH 14/18] soundwire: intel: simplify with cleanup.h Allocate the memory with scoped/cleanup.h to reduce error handling and make the code a bit simpler. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240703-soundwire-cleanup-h-v1-5-24fa0dbb948f@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/intel.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index b4449095b4238..421da0f86fad6 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -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; @@ -771,7 +769,8 @@ 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); + struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig), + GFP_KERNEL); if (!pconfig) return -ENOMEM; @@ -783,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); - return ret; } From 13814ed162687be08e34762040cfc2e58831219d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 3 Jul 2024 12:15:58 +0200 Subject: [PATCH 15/18] soundwire: intel_ace2x: simplify return path in hw_params Remove unused error path (label+goto) to make the code a bit simpler. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240703-soundwire-cleanup-h-v1-6-24fa0dbb948f@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/intel_ace2x.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c index 4f78b7f99e441..f0008ff84ab40 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -325,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; @@ -350,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; @@ -361,10 +358,8 @@ static int intel_hw_params(struct snd_pcm_substream *substream, /* Port configuration */ pconfig = kzalloc(sizeof(*pconfig), GFP_KERNEL); - if (!pconfig) { - ret = -ENOMEM; - goto error; - } + if (!pconfig) + return -ENOMEM; pconfig->num = pdi->num; pconfig->ch_mask = (1 << ch) - 1; @@ -375,7 +370,7 @@ static int intel_hw_params(struct snd_pcm_substream *substream, dev_err(cdns->dev, "add master to stream failed:%d\n", ret); kfree(pconfig); -error: + return ret; } From 3dce65898e0911aa76a0a321540b78e9218b9a6a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 3 Jul 2024 12:15:59 +0200 Subject: [PATCH 16/18] soundwire: intel_ace2x: simplify with cleanup.h Allocate the memory with scoped/cleanup.h to reduce error handling and make the code a bit simpler. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240703-soundwire-cleanup-h-v1-7-24fa0dbb948f@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/intel_ace2x.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c index f0008ff84ab40..781fe0aefa68f 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -310,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; @@ -357,7 +357,8 @@ 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); + struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig), + GFP_KERNEL); if (!pconfig) return -ENOMEM; @@ -369,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); - return ret; } From b72d4af98cae2f74dc8061befcc3c0c2a174894f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 3 Jul 2024 12:16:00 +0200 Subject: [PATCH 17/18] soundwire: cadence: simplify with cleanup.h Allocate the memory with scoped/cleanup.h to reduce error handling and make the code a bit simpler. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240703-soundwire-cleanup-h-v1-8-24fa0dbb948f@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/cadence_master.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index 74da99034dab5..e0683a5975d10 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -6,6 +6,7 @@ * Used by Master driver */ +#include #include #include #include @@ -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; } From fdd3d14ca3c8c5269174f10d33d6181173cbd0b4 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 3 Jul 2024 12:16:01 +0200 Subject: [PATCH 18/18] soundwire: debugfs: simplify with cleanup.h Allocate the memory with scoped/cleanup.h to reduce error handling and make the code a bit simpler. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240703-soundwire-cleanup-h-v1-9-24fa0dbb948f@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/debugfs.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c index 6d253d69871d9..c30f571934ee2 100644 --- a/drivers/soundwire/debugfs.c +++ b/drivers/soundwire/debugfs.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only // Copyright(c) 2017-2019 Intel Corporation. +#include #include #include #include @@ -49,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; } @@ -132,8 +131,6 @@ 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);