Skip to content

Commit ad7b0b7

Browse files
committed
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
2 parents 7a46b17 + fdd3d14 commit ad7b0b7

File tree

16 files changed

+271
-80
lines changed

16 files changed

+271
-80
lines changed

drivers/soundwire/amd_init.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#include <linux/acpi.h>
11+
#include <linux/cleanup.h>
1112
#include <linux/export.h>
1213
#include <linux/io.h>
1314
#include <linux/module.h>
@@ -69,7 +70,6 @@ static struct sdw_amd_ctx *sdw_amd_probe_controller(struct sdw_amd_res *res)
6970
{
7071
struct sdw_amd_ctx *ctx;
7172
struct acpi_device *adev;
72-
struct resource *sdw_res;
7373
struct acp_sdw_pdata sdw_pdata[2];
7474
struct platform_device_info pdevinfo[2];
7575
u32 link_mask;
@@ -104,7 +104,8 @@ static struct sdw_amd_ctx *sdw_amd_probe_controller(struct sdw_amd_res *res)
104104

105105
ctx->count = count;
106106
ctx->link_mask = res->link_mask;
107-
sdw_res = kzalloc(sizeof(*sdw_res), GFP_KERNEL);
107+
struct resource *sdw_res __free(kfree) = kzalloc(sizeof(*sdw_res),
108+
GFP_KERNEL);
108109
if (!sdw_res) {
109110
kfree(ctx);
110111
return NULL;
@@ -132,7 +133,6 @@ static struct sdw_amd_ctx *sdw_amd_probe_controller(struct sdw_amd_res *res)
132133
if (IS_ERR(ctx->pdev[index]))
133134
goto err;
134135
}
135-
kfree(sdw_res);
136136
return ctx;
137137
err:
138138
while (index--) {
@@ -142,7 +142,6 @@ static struct sdw_amd_ctx *sdw_amd_probe_controller(struct sdw_amd_res *res)
142142
platform_device_unregister(ctx->pdev[index]);
143143
}
144144

145-
kfree(sdw_res);
146145
kfree(ctx);
147146
return NULL;
148147
}

drivers/soundwire/amd_manager.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include <linux/completion.h>
9+
#include <linux/cleanup.h>
910
#include <linux/device.h>
1011
#include <linux/io.h>
1112
#include <linux/jiffies.h>
@@ -603,7 +604,6 @@ static int amd_sdw_hw_params(struct snd_pcm_substream *substream,
603604
struct amd_sdw_manager *amd_manager = snd_soc_dai_get_drvdata(dai);
604605
struct sdw_amd_dai_runtime *dai_runtime;
605606
struct sdw_stream_config sconfig;
606-
struct sdw_port_config *pconfig;
607607
int ch, dir;
608608
int ret;
609609

@@ -626,11 +626,10 @@ static int amd_sdw_hw_params(struct snd_pcm_substream *substream,
626626
sconfig.bps = snd_pcm_format_width(params_format(params));
627627

628628
/* Port configuration */
629-
pconfig = kzalloc(sizeof(*pconfig), GFP_KERNEL);
630-
if (!pconfig) {
631-
ret = -ENOMEM;
632-
goto error;
633-
}
629+
struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig),
630+
GFP_KERNEL);
631+
if (!pconfig)
632+
return -ENOMEM;
634633

635634
pconfig->num = dai->id;
636635
pconfig->ch_mask = (1 << ch) - 1;
@@ -639,8 +638,6 @@ static int amd_sdw_hw_params(struct snd_pcm_substream *substream,
639638
if (ret)
640639
dev_err(amd_manager->dev, "add manager to stream failed:%d\n", ret);
641640

642-
kfree(pconfig);
643-
error:
644641
return ret;
645642
}
646643

drivers/soundwire/bus.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,7 +1410,7 @@ static int sdw_initialize_slave(struct sdw_slave *slave)
14101410
}
14111411
}
14121412
if ((slave->bus->prop.quirks & SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY) &&
1413-
!(slave->prop.quirks & SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY)) {
1413+
!(prop->quirks & SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY)) {
14141414
/* Clear parity interrupt before enabling interrupt mask */
14151415
status = sdw_read_no_pm(slave, SDW_SCP_INT1);
14161416
if (status < 0) {
@@ -1436,7 +1436,7 @@ static int sdw_initialize_slave(struct sdw_slave *slave)
14361436
* device-dependent, it might e.g. only be enabled in
14371437
* steady-state after a couple of frames.
14381438
*/
1439-
val = slave->prop.scp_int1_mask;
1439+
val = prop->scp_int1_mask;
14401440

14411441
/* Enable SCP interrupts */
14421442
ret = sdw_update_no_pm(slave, SDW_SCP_INTMASK1, val, val);
@@ -1447,7 +1447,7 @@ static int sdw_initialize_slave(struct sdw_slave *slave)
14471447
}
14481448

14491449
/* No need to continue if DP0 is not present */
1450-
if (!slave->prop.dp0_prop)
1450+
if (!prop->dp0_prop)
14511451
return 0;
14521452

14531453
/* Enable DP0 interrupts */

drivers/soundwire/cadence_master.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Used by Master driver
77
*/
88

9+
#include <linux/cleanup.h>
910
#include <linux/delay.h>
1011
#include <linux/device.h>
1112
#include <linux/debugfs.h>
@@ -323,12 +324,11 @@ static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
323324
static int cdns_reg_show(struct seq_file *s, void *data)
324325
{
325326
struct sdw_cdns *cdns = s->private;
326-
char *buf;
327327
ssize_t ret;
328328
int num_ports;
329329
int i, j;
330330

331-
buf = kzalloc(RD_BUF, GFP_KERNEL);
331+
char *buf __free(kfree) = kzalloc(RD_BUF, GFP_KERNEL);
332332
if (!buf)
333333
return -ENOMEM;
334334

@@ -389,7 +389,6 @@ static int cdns_reg_show(struct seq_file *s, void *data)
389389
ret += cdns_sprintf(cdns, buf, ret, CDNS_PDI_CONFIG(i));
390390

391391
seq_printf(s, "%s", buf);
392-
kfree(buf);
393392

394393
return 0;
395394
}

drivers/soundwire/debugfs.c

Lines changed: 152 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
// Copyright(c) 2017-2019 Intel Corporation.
33

4+
#include <linux/cleanup.h>
45
#include <linux/device.h>
56
#include <linux/debugfs.h>
7+
#include <linux/firmware.h>
68
#include <linux/mod_devicetable.h>
79
#include <linux/pm_runtime.h>
810
#include <linux/slab.h>
@@ -48,18 +50,16 @@ static ssize_t sdw_sprintf(struct sdw_slave *slave,
4850
static int sdw_slave_reg_show(struct seq_file *s_file, void *data)
4951
{
5052
struct sdw_slave *slave = s_file->private;
51-
char *buf;
5253
ssize_t ret;
5354
int i, j;
5455

55-
buf = kzalloc(RD_BUF, GFP_KERNEL);
56+
char *buf __free(kfree) = kzalloc(RD_BUF, GFP_KERNEL);
5657
if (!buf)
5758
return -ENOMEM;
5859

5960
ret = pm_runtime_get_sync(&slave->dev);
6061
if (ret < 0 && ret != -EACCES) {
6162
pm_runtime_put_noidle(&slave->dev);
62-
kfree(buf);
6363
return ret;
6464
}
6565

@@ -131,12 +131,149 @@ static int sdw_slave_reg_show(struct seq_file *s_file, void *data)
131131
pm_runtime_mark_last_busy(&slave->dev);
132132
pm_runtime_put(&slave->dev);
133133

134-
kfree(buf);
135-
136134
return 0;
137135
}
138136
DEFINE_SHOW_ATTRIBUTE(sdw_slave_reg);
139137

138+
#define MAX_CMD_BYTES 256
139+
140+
static int cmd;
141+
static u32 start_addr;
142+
static size_t num_bytes;
143+
static u8 read_buffer[MAX_CMD_BYTES];
144+
static char *firmware_file;
145+
146+
static int set_command(void *data, u64 value)
147+
{
148+
struct sdw_slave *slave = data;
149+
150+
if (value > 1)
151+
return -EINVAL;
152+
153+
/* Userspace changed the hardware state behind the kernel's back */
154+
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
155+
156+
dev_dbg(&slave->dev, "command: %s\n", value ? "read" : "write");
157+
cmd = value;
158+
159+
return 0;
160+
}
161+
DEFINE_DEBUGFS_ATTRIBUTE(set_command_fops, NULL,
162+
set_command, "%llu\n");
163+
164+
static int set_start_address(void *data, u64 value)
165+
{
166+
struct sdw_slave *slave = data;
167+
168+
/* Userspace changed the hardware state behind the kernel's back */
169+
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
170+
171+
dev_dbg(&slave->dev, "start address %#llx\n", value);
172+
173+
start_addr = value;
174+
175+
return 0;
176+
}
177+
DEFINE_DEBUGFS_ATTRIBUTE(set_start_address_fops, NULL,
178+
set_start_address, "%llu\n");
179+
180+
static int set_num_bytes(void *data, u64 value)
181+
{
182+
struct sdw_slave *slave = data;
183+
184+
if (value == 0 || value > MAX_CMD_BYTES)
185+
return -EINVAL;
186+
187+
/* Userspace changed the hardware state behind the kernel's back */
188+
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
189+
190+
dev_dbg(&slave->dev, "number of bytes %lld\n", value);
191+
192+
num_bytes = value;
193+
194+
return 0;
195+
}
196+
DEFINE_DEBUGFS_ATTRIBUTE(set_num_bytes_fops, NULL,
197+
set_num_bytes, "%llu\n");
198+
199+
static int cmd_go(void *data, u64 value)
200+
{
201+
struct sdw_slave *slave = data;
202+
int ret;
203+
204+
if (value != 1)
205+
return -EINVAL;
206+
207+
/* one last check */
208+
if (start_addr > SDW_REG_MAX ||
209+
num_bytes == 0 || num_bytes > MAX_CMD_BYTES)
210+
return -EINVAL;
211+
212+
ret = pm_runtime_get_sync(&slave->dev);
213+
if (ret < 0 && ret != -EACCES) {
214+
pm_runtime_put_noidle(&slave->dev);
215+
return ret;
216+
}
217+
218+
/* Userspace changed the hardware state behind the kernel's back */
219+
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
220+
221+
dev_dbg(&slave->dev, "starting command\n");
222+
223+
if (cmd == 0) {
224+
const struct firmware *fw;
225+
226+
ret = request_firmware(&fw, firmware_file, &slave->dev);
227+
if (ret < 0) {
228+
dev_err(&slave->dev, "firmware %s not found\n", firmware_file);
229+
goto out;
230+
}
231+
232+
if (fw->size != num_bytes) {
233+
dev_err(&slave->dev,
234+
"firmware %s: unexpected size %zd, desired %zd\n",
235+
firmware_file, fw->size, num_bytes);
236+
release_firmware(fw);
237+
goto out;
238+
}
239+
240+
ret = sdw_nwrite_no_pm(slave, start_addr, num_bytes, fw->data);
241+
release_firmware(fw);
242+
} else {
243+
ret = sdw_nread_no_pm(slave, start_addr, num_bytes, read_buffer);
244+
}
245+
246+
dev_dbg(&slave->dev, "command completed %d\n", ret);
247+
248+
out:
249+
pm_runtime_mark_last_busy(&slave->dev);
250+
pm_runtime_put(&slave->dev);
251+
252+
return ret;
253+
}
254+
DEFINE_DEBUGFS_ATTRIBUTE(cmd_go_fops, NULL,
255+
cmd_go, "%llu\n");
256+
257+
#define MAX_LINE_LEN 128
258+
259+
static int read_buffer_show(struct seq_file *s_file, void *data)
260+
{
261+
char buf[MAX_LINE_LEN];
262+
int i;
263+
264+
if (num_bytes == 0 || num_bytes > MAX_CMD_BYTES)
265+
return -EINVAL;
266+
267+
for (i = 0; i < num_bytes; i++) {
268+
scnprintf(buf, MAX_LINE_LEN, "address %#x val 0x%02x\n",
269+
start_addr + i, read_buffer[i]);
270+
seq_printf(s_file, "%s", buf);
271+
}
272+
273+
return 0;
274+
}
275+
DEFINE_SHOW_ATTRIBUTE(read_buffer);
276+
140277
void sdw_slave_debugfs_init(struct sdw_slave *slave)
141278
{
142279
struct dentry *master;
@@ -151,6 +288,16 @@ void sdw_slave_debugfs_init(struct sdw_slave *slave)
151288

152289
debugfs_create_file("registers", 0400, d, slave, &sdw_slave_reg_fops);
153290

291+
/* interface to send arbitrary commands */
292+
debugfs_create_file("command", 0200, d, slave, &set_command_fops);
293+
debugfs_create_file("start_address", 0200, d, slave, &set_start_address_fops);
294+
debugfs_create_file("num_bytes", 0200, d, slave, &set_num_bytes_fops);
295+
debugfs_create_file("go", 0200, d, slave, &cmd_go_fops);
296+
297+
debugfs_create_file("read_buffer", 0400, d, slave, &read_buffer_fops);
298+
firmware_file = NULL;
299+
debugfs_create_str("firmware_file", 0200, d, &firmware_file);
300+
154301
slave->debugfs = d;
155302
}
156303

drivers/soundwire/generic_bandwidth_allocation.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ EXPORT_SYMBOL(sdw_compute_slave_ports);
8383

8484
static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
8585
struct sdw_group_params *params,
86-
int port_bo, int hstop)
86+
int *port_bo, int hstop)
8787
{
8888
struct sdw_transport_data t_data = {0};
8989
struct sdw_port_runtime *p_rt;
@@ -108,7 +108,7 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
108108

109109
sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
110110
false, SDW_BLK_GRP_CNT_1, sample_int,
111-
port_bo, port_bo >> 8, hstart, hstop,
111+
*port_bo, (*port_bo) >> 8, hstart, hstop,
112112
SDW_BLK_PKG_PER_PORT, 0x0);
113113

114114
sdw_fill_port_params(&p_rt->port_params,
@@ -120,15 +120,15 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
120120
if (!(p_rt == list_first_entry(&m_rt->port_list,
121121
struct sdw_port_runtime,
122122
port_node))) {
123-
port_bo += bps * ch;
123+
(*port_bo) += bps * ch;
124124
continue;
125125
}
126126

127127
t_data.hstart = hstart;
128128
t_data.hstop = hstop;
129-
t_data.block_offset = port_bo;
129+
t_data.block_offset = *port_bo;
130130
t_data.sub_block_offset = 0;
131-
port_bo += bps * ch;
131+
(*port_bo) += bps * ch;
132132
}
133133

134134
sdw_compute_slave_ports(m_rt, &t_data);
@@ -146,9 +146,7 @@ static void _sdw_compute_port_params(struct sdw_bus *bus,
146146
port_bo = 1;
147147

148148
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
149-
sdw_compute_master_ports(m_rt, &params[i], port_bo, hstop);
150-
151-
port_bo += m_rt->ch_count * m_rt->stream->params.bps;
149+
sdw_compute_master_ports(m_rt, &params[i], &port_bo, hstop);
152150
}
153151

154152
hstop = hstop - params[i].hwidth;

0 commit comments

Comments
 (0)