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

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

+271 -80
+3 -4
drivers/soundwire/amd_init.c
··· 8 8 */ 9 9 10 10 #include <linux/acpi.h> 11 + #include <linux/cleanup.h> 11 12 #include <linux/export.h> 12 13 #include <linux/io.h> 13 14 #include <linux/module.h> ··· 70 69 { 71 70 struct sdw_amd_ctx *ctx; 72 71 struct acpi_device *adev; 73 - struct resource *sdw_res; 74 72 struct acp_sdw_pdata sdw_pdata[2]; 75 73 struct platform_device_info pdevinfo[2]; 76 74 u32 link_mask; ··· 104 104 105 105 ctx->count = count; 106 106 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); 108 109 if (!sdw_res) { 109 110 kfree(ctx); 110 111 return NULL; ··· 133 132 if (IS_ERR(ctx->pdev[index])) 134 133 goto err; 135 134 } 136 - kfree(sdw_res); 137 135 return ctx; 138 136 err: 139 137 while (index--) { ··· 142 142 platform_device_unregister(ctx->pdev[index]); 143 143 } 144 144 145 - kfree(sdw_res); 146 145 kfree(ctx); 147 146 return NULL; 148 147 }
+5 -8
drivers/soundwire/amd_manager.c
··· 6 6 */ 7 7 8 8 #include <linux/completion.h> 9 + #include <linux/cleanup.h> 9 10 #include <linux/device.h> 10 11 #include <linux/io.h> 11 12 #include <linux/jiffies.h> ··· 604 603 struct amd_sdw_manager *amd_manager = snd_soc_dai_get_drvdata(dai); 605 604 struct sdw_amd_dai_runtime *dai_runtime; 606 605 struct sdw_stream_config sconfig; 607 - struct sdw_port_config *pconfig; 608 606 int ch, dir; 609 607 int ret; 610 608 ··· 626 626 sconfig.bps = snd_pcm_format_width(params_format(params)); 627 627 628 628 /* 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; 634 633 635 634 pconfig->num = dai->id; 636 635 pconfig->ch_mask = (1 << ch) - 1; ··· 638 639 if (ret) 639 640 dev_err(amd_manager->dev, "add manager to stream failed:%d\n", ret); 640 641 641 - kfree(pconfig); 642 - error: 643 642 return ret; 644 643 } 645 644
+3 -3
drivers/soundwire/bus.c
··· 1410 1410 } 1411 1411 } 1412 1412 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)) { 1414 1414 /* Clear parity interrupt before enabling interrupt mask */ 1415 1415 status = sdw_read_no_pm(slave, SDW_SCP_INT1); 1416 1416 if (status < 0) { ··· 1436 1436 * device-dependent, it might e.g. only be enabled in 1437 1437 * steady-state after a couple of frames. 1438 1438 */ 1439 - val = slave->prop.scp_int1_mask; 1439 + val = prop->scp_int1_mask; 1440 1440 1441 1441 /* Enable SCP interrupts */ 1442 1442 ret = sdw_update_no_pm(slave, SDW_SCP_INTMASK1, val, val); ··· 1447 1447 } 1448 1448 1449 1449 /* No need to continue if DP0 is not present */ 1450 - if (!slave->prop.dp0_prop) 1450 + if (!prop->dp0_prop) 1451 1451 return 0; 1452 1452 1453 1453 /* Enable DP0 interrupts */
+2 -3
drivers/soundwire/cadence_master.c
··· 6 6 * Used by Master driver 7 7 */ 8 8 9 + #include <linux/cleanup.h> 9 10 #include <linux/delay.h> 10 11 #include <linux/device.h> 11 12 #include <linux/debugfs.h> ··· 324 323 static int cdns_reg_show(struct seq_file *s, void *data) 325 324 { 326 325 struct sdw_cdns *cdns = s->private; 327 - char *buf; 328 326 ssize_t ret; 329 327 int num_ports; 330 328 int i, j; 331 329 332 - buf = kzalloc(RD_BUF, GFP_KERNEL); 330 + char *buf __free(kfree) = kzalloc(RD_BUF, GFP_KERNEL); 333 331 if (!buf) 334 332 return -ENOMEM; 335 333 ··· 389 389 ret += cdns_sprintf(cdns, buf, ret, CDNS_PDI_CONFIG(i)); 390 390 391 391 seq_printf(s, "%s", buf); 392 - kfree(buf); 393 392 394 393 return 0; 395 394 }
+152 -5
drivers/soundwire/debugfs.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 // Copyright(c) 2017-2019 Intel Corporation. 3 3 4 + #include <linux/cleanup.h> 4 5 #include <linux/device.h> 5 6 #include <linux/debugfs.h> 7 + #include <linux/firmware.h> 6 8 #include <linux/mod_devicetable.h> 7 9 #include <linux/pm_runtime.h> 8 10 #include <linux/slab.h> ··· 50 48 static int sdw_slave_reg_show(struct seq_file *s_file, void *data) 51 49 { 52 50 struct sdw_slave *slave = s_file->private; 53 - char *buf; 54 51 ssize_t ret; 55 52 int i, j; 56 53 57 - buf = kzalloc(RD_BUF, GFP_KERNEL); 54 + char *buf __free(kfree) = kzalloc(RD_BUF, GFP_KERNEL); 58 55 if (!buf) 59 56 return -ENOMEM; 60 57 61 58 ret = pm_runtime_get_sync(&slave->dev); 62 59 if (ret < 0 && ret != -EACCES) { 63 60 pm_runtime_put_noidle(&slave->dev); 64 - kfree(buf); 65 61 return ret; 66 62 } 67 63 ··· 131 131 pm_runtime_mark_last_busy(&slave->dev); 132 132 pm_runtime_put(&slave->dev); 133 133 134 - kfree(buf); 135 - 136 134 return 0; 137 135 } 138 136 DEFINE_SHOW_ATTRIBUTE(sdw_slave_reg); 137 + 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); 139 276 140 277 void sdw_slave_debugfs_init(struct sdw_slave *slave) 141 278 { ··· 287 150 d = debugfs_create_dir(name, master); 288 151 289 152 debugfs_create_file("registers", 0400, d, slave, &sdw_slave_reg_fops); 153 + 154 + /* interface to send arbitrary commands */ 155 + debugfs_create_file("command", 0200, d, slave, &set_command_fops); 156 + debugfs_create_file("start_address", 0200, d, slave, &set_start_address_fops); 157 + debugfs_create_file("num_bytes", 0200, d, slave, &set_num_bytes_fops); 158 + debugfs_create_file("go", 0200, d, slave, &cmd_go_fops); 159 + 160 + debugfs_create_file("read_buffer", 0400, d, slave, &read_buffer_fops); 161 + firmware_file = NULL; 162 + debugfs_create_str("firmware_file", 0200, d, &firmware_file); 290 163 291 164 slave->debugfs = d; 292 165 }
+6 -8
drivers/soundwire/generic_bandwidth_allocation.c
··· 83 83 84 84 static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt, 85 85 struct sdw_group_params *params, 86 - int port_bo, int hstop) 86 + int *port_bo, int hstop) 87 87 { 88 88 struct sdw_transport_data t_data = {0}; 89 89 struct sdw_port_runtime *p_rt; ··· 108 108 109 109 sdw_fill_xport_params(&p_rt->transport_params, p_rt->num, 110 110 false, SDW_BLK_GRP_CNT_1, sample_int, 111 - port_bo, port_bo >> 8, hstart, hstop, 111 + *port_bo, (*port_bo) >> 8, hstart, hstop, 112 112 SDW_BLK_PKG_PER_PORT, 0x0); 113 113 114 114 sdw_fill_port_params(&p_rt->port_params, ··· 120 120 if (!(p_rt == list_first_entry(&m_rt->port_list, 121 121 struct sdw_port_runtime, 122 122 port_node))) { 123 - port_bo += bps * ch; 123 + (*port_bo) += bps * ch; 124 124 continue; 125 125 } 126 126 127 127 t_data.hstart = hstart; 128 128 t_data.hstop = hstop; 129 - t_data.block_offset = port_bo; 129 + t_data.block_offset = *port_bo; 130 130 t_data.sub_block_offset = 0; 131 - port_bo += bps * ch; 131 + (*port_bo) += bps * ch; 132 132 } 133 133 134 134 sdw_compute_slave_ports(m_rt, &t_data); ··· 146 146 port_bo = 1; 147 147 148 148 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); 152 150 } 153 151 154 152 hstop = hstop - params[i].hwidth;
+9 -16
drivers/soundwire/intel.c
··· 6 6 */ 7 7 8 8 #include <linux/acpi.h> 9 + #include <linux/cleanup.h> 9 10 #include <linux/debugfs.h> 10 11 #include <linux/delay.h> 11 12 #include <linux/io.h> ··· 74 73 struct sdw_intel *sdw = s_file->private; 75 74 void __iomem *s = sdw->link_res->shim; 76 75 void __iomem *a = sdw->link_res->alh; 77 - char *buf; 78 76 ssize_t ret; 79 77 int i, j; 80 78 unsigned int links, reg; 81 79 82 - buf = kzalloc(RD_BUF, GFP_KERNEL); 80 + char *buf __free(kfree) = kzalloc(RD_BUF, GFP_KERNEL); 83 81 if (!buf) 84 82 return -ENOMEM; 85 83 ··· 129 129 ret += intel_sprintf(a, true, buf, ret, SDW_ALH_STRMZCFG(i)); 130 130 131 131 seq_printf(s_file, "%s", buf); 132 - kfree(buf); 133 132 134 133 return 0; 135 134 } ··· 726 727 struct sdw_cdns_dai_runtime *dai_runtime; 727 728 struct sdw_cdns_pdi *pdi; 728 729 struct sdw_stream_config sconfig; 729 - struct sdw_port_config *pconfig; 730 730 int ch, dir; 731 731 int ret; 732 732 ··· 741 743 742 744 pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, ch, dir, dai->id); 743 745 744 - if (!pdi) { 745 - ret = -EINVAL; 746 - goto error; 747 - } 746 + if (!pdi) 747 + return -EINVAL; 748 748 749 749 /* do run-time configurations for SHIM, ALH and PDI/PORT */ 750 750 intel_pdi_shim_configure(sdw, pdi); ··· 759 763 sdw->instance, 760 764 pdi->intel_alh_id); 761 765 if (ret) 762 - goto error; 766 + return ret; 763 767 764 768 sconfig.direction = dir; 765 769 sconfig.ch_count = ch; ··· 769 773 sconfig.bps = snd_pcm_format_width(params_format(params)); 770 774 771 775 /* Port configuration */ 772 - pconfig = kzalloc(sizeof(*pconfig), GFP_KERNEL); 773 - if (!pconfig) { 774 - ret = -ENOMEM; 775 - goto error; 776 - } 776 + struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig), 777 + GFP_KERNEL); 778 + if (!pconfig) 779 + return -ENOMEM; 777 780 778 781 pconfig->num = pdi->num; 779 782 pconfig->ch_mask = (1 << ch) - 1; ··· 782 787 if (ret) 783 788 dev_err(cdns->dev, "add master to stream failed:%d\n", ret); 784 789 785 - kfree(pconfig); 786 - error: 787 790 return ret; 788 791 } 789 792
+5
drivers/soundwire/intel.h
··· 59 59 }; 60 60 61 61 struct sdw_intel_prop { 62 + u16 clde; 63 + u16 doaise2; 64 + u16 dodse2; 65 + u16 clds; 66 + u16 clss; 62 67 u16 doaise; 63 68 u16 doais; 64 69 u16 dodse;
+24 -15
drivers/soundwire/intel_ace2x.c
··· 1 1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 - // Copyright(c) 2023 Intel Corporation. All rights reserved. 2 + // Copyright(c) 2023 Intel Corporation 3 3 4 4 /* 5 5 * Soundwire Intel ops for LunarLake 6 6 */ 7 7 8 8 #include <linux/acpi.h> 9 + #include <linux/cleanup.h> 9 10 #include <linux/device.h> 10 11 #include <linux/soundwire/sdw_registers.h> 11 12 #include <linux/soundwire/sdw.h> ··· 28 27 void __iomem *shim_vs = sdw->link_res->shim_vs; 29 28 struct sdw_bus *bus = &sdw->cdns.bus; 30 29 struct sdw_intel_prop *intel_prop; 30 + u16 clde; 31 + u16 doaise2; 32 + u16 dodse2; 33 + u16 clds; 34 + u16 clss; 31 35 u16 doaise; 32 36 u16 doais; 33 37 u16 dodse; ··· 40 34 u16 act; 41 35 42 36 intel_prop = bus->vendor_specific_prop; 37 + clde = intel_prop->clde; 38 + doaise2 = intel_prop->doaise2; 39 + dodse2 = intel_prop->dodse2; 40 + clds = intel_prop->clds; 41 + clss = intel_prop->clss; 43 42 doaise = intel_prop->doaise; 44 43 doais = intel_prop->doais; 45 44 dodse = intel_prop->dodse; 46 45 dods = intel_prop->dods; 47 46 48 47 act = intel_readw(shim_vs, SDW_SHIM2_INTEL_VS_ACTMCTL); 48 + u16p_replace_bits(&act, clde, SDW_SHIM3_INTEL_VS_ACTMCTL_CLDE); 49 + u16p_replace_bits(&act, doaise2, SDW_SHIM3_INTEL_VS_ACTMCTL_DOAISE2); 50 + u16p_replace_bits(&act, dodse2, SDW_SHIM3_INTEL_VS_ACTMCTL_DODSE2); 51 + u16p_replace_bits(&act, clds, SDW_SHIM3_INTEL_VS_ACTMCTL_CLDS); 52 + u16p_replace_bits(&act, clss, SDW_SHIM3_INTEL_VS_ACTMCTL_CLSS); 49 53 u16p_replace_bits(&act, doaise, SDW_SHIM2_INTEL_VS_ACTMCTL_DOAISE); 50 54 u16p_replace_bits(&act, doais, SDW_SHIM2_INTEL_VS_ACTMCTL_DOAIS); 51 55 u16p_replace_bits(&act, dodse, SDW_SHIM2_INTEL_VS_ACTMCTL_DODSE); ··· 311 295 struct sdw_cdns_dai_runtime *dai_runtime; 312 296 struct sdw_cdns_pdi *pdi; 313 297 struct sdw_stream_config sconfig; 314 - struct sdw_port_config *pconfig; 315 298 int ch, dir; 316 299 int ret; 317 300 ··· 325 310 dir = SDW_DATA_DIR_TX; 326 311 327 312 pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, ch, dir, dai->id); 328 - 329 - if (!pdi) { 330 - ret = -EINVAL; 331 - goto error; 332 - } 313 + if (!pdi) 314 + return -EINVAL; 333 315 334 316 /* use same definitions for alh_id as previous generations */ 335 317 pdi->intel_alh_id = (sdw->instance * 16) + pdi->num + 3; ··· 347 335 sdw->instance, 348 336 pdi->intel_alh_id); 349 337 if (ret) 350 - goto error; 338 + return ret; 351 339 352 340 sconfig.direction = dir; 353 341 sconfig.ch_count = ch; ··· 357 345 sconfig.bps = snd_pcm_format_width(params_format(params)); 358 346 359 347 /* Port configuration */ 360 - pconfig = kzalloc(sizeof(*pconfig), GFP_KERNEL); 361 - if (!pconfig) { 362 - ret = -ENOMEM; 363 - goto error; 364 - } 348 + struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig), 349 + GFP_KERNEL); 350 + if (!pconfig) 351 + return -ENOMEM; 365 352 366 353 pconfig->num = pdi->num; 367 354 pconfig->ch_mask = (1 << ch) - 1; ··· 370 359 if (ret) 371 360 dev_err(cdns->dev, "add master to stream failed:%d\n", ret); 372 361 373 - kfree(pconfig); 374 - error: 375 362 return ret; 376 363 } 377 364
+1 -1
drivers/soundwire/intel_ace2x_debugfs.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - // Copyright(c) 2023 Intel Corporation. All rights reserved. 2 + // Copyright(c) 2023 Intel Corporation 3 3 4 4 #include <linux/acpi.h> 5 5 #include <linux/debugfs.h>
+42
drivers/soundwire/intel_auxdevice.c
··· 47 47 }; 48 48 49 49 static struct wake_capable_part wake_capable_list[] = { 50 + {0x01fa, 0x4243}, 50 51 {0x025d, 0x5682}, 51 52 {0x025d, 0x700}, 52 53 {0x025d, 0x711}, ··· 162 161 } 163 162 164 163 /* initialize with hardware defaults, in case the properties are not found */ 164 + intel_prop->clde = 0x0; 165 + intel_prop->doaise2 = 0x0; 166 + intel_prop->dodse2 = 0x0; 167 + intel_prop->clds = 0x0; 168 + intel_prop->clss = 0x0; 165 169 intel_prop->doaise = 0x1; 166 170 intel_prop->doais = 0x3; 167 171 intel_prop->dodse = 0x0; 168 172 intel_prop->dods = 0x1; 169 173 174 + fwnode_property_read_u16(link, 175 + "intel-sdw-clde", 176 + &intel_prop->clde); 177 + fwnode_property_read_u16(link, 178 + "intel-sdw-doaise2", 179 + &intel_prop->doaise2); 180 + fwnode_property_read_u16(link, 181 + "intel-sdw-dodse2", 182 + &intel_prop->dodse2); 183 + fwnode_property_read_u16(link, 184 + "intel-sdw-clds", 185 + &intel_prop->clds); 186 + fwnode_property_read_u16(link, 187 + "intel-sdw-clss", 188 + &intel_prop->clss); 170 189 fwnode_property_read_u16(link, 171 190 "intel-sdw-doaise", 172 191 &intel_prop->doaise); ··· 214 193 215 194 static int intel_prop_read(struct sdw_bus *bus) 216 195 { 196 + struct sdw_master_prop *prop; 197 + 217 198 /* Initialize with default handler to read all DisCo properties */ 218 199 sdw_master_read_prop(bus); 200 + 201 + /* 202 + * Only one bus frequency is supported so far, filter 203 + * frequencies reported in the DSDT 204 + */ 205 + prop = &bus->prop; 206 + if (prop->clk_freq && prop->num_clk_freq > 1) { 207 + unsigned int default_bus_frequency; 208 + 209 + default_bus_frequency = 210 + prop->default_frame_rate * 211 + prop->default_row * 212 + prop->default_col / 213 + SDW_DOUBLE_RATE_FACTOR; 214 + 215 + prop->num_clk_freq = 1; 216 + prop->clk_freq[0] = default_bus_frequency; 217 + prop->max_clk_freq = default_bus_frequency; 218 + } 219 219 220 220 /* read Intel-specific properties */ 221 221 sdw_master_read_intel_prop(bus);
+1 -1
drivers/soundwire/intel_bus_common.c
··· 1 1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 - // Copyright(c) 2015-2023 Intel Corporation. All rights reserved. 2 + // Copyright(c) 2015-2023 Intel Corporation 3 3 4 4 #include <linux/acpi.h> 5 5 #include <linux/soundwire/sdw_registers.h>
+6 -16
drivers/soundwire/qcom.c
··· 197 197 int num_dout_ports; 198 198 int cols_index; 199 199 int rows_index; 200 - unsigned long dout_port_mask; 201 - unsigned long din_port_mask; 200 + unsigned long port_mask; 202 201 u32 intr_mask; 203 202 u8 rcmd_id; 204 203 u8 wcmd_id; ··· 1145 1146 mutex_lock(&ctrl->port_lock); 1146 1147 1147 1148 list_for_each_entry(m_rt, &stream->master_list, stream_node) { 1148 - if (m_rt->direction == SDW_DATA_DIR_RX) 1149 - port_mask = &ctrl->dout_port_mask; 1150 - else 1151 - port_mask = &ctrl->din_port_mask; 1152 - 1149 + port_mask = &ctrl->port_mask; 1153 1150 list_for_each_entry(p_rt, &m_rt->port_list, port_node) 1154 1151 clear_bit(p_rt->num, port_mask); 1155 1152 } ··· 1190 1195 if (ctrl->bus.id != m_rt->bus->id) 1191 1196 continue; 1192 1197 1193 - if (m_rt->direction == SDW_DATA_DIR_RX) { 1194 - maxport = ctrl->num_dout_ports; 1195 - port_mask = &ctrl->dout_port_mask; 1196 - } else { 1197 - maxport = ctrl->num_din_ports; 1198 - port_mask = &ctrl->din_port_mask; 1199 - } 1198 + port_mask = &ctrl->port_mask; 1199 + maxport = ctrl->num_dout_ports + ctrl->num_din_ports; 1200 + 1200 1201 1201 1202 list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) { 1202 1203 slave = s_rt->slave; ··· 1392 1401 return -EINVAL; 1393 1402 1394 1403 /* Valid port numbers are from 1-14, so mask out port 0 explicitly */ 1395 - set_bit(0, &ctrl->dout_port_mask); 1396 - set_bit(0, &ctrl->din_port_mask); 1404 + set_bit(0, &ctrl->port_mask); 1397 1405 1398 1406 ret = of_property_read_u8_array(np, "qcom,ports-offset1", 1399 1407 off1, nports);
+5
drivers/soundwire/stream.c
··· 1181 1181 m_rt->bus = bus; 1182 1182 m_rt->stream = stream; 1183 1183 1184 + bus->stream_refcount++; 1185 + 1184 1186 return m_rt; 1185 1187 } 1186 1188 ··· 1219 1217 struct sdw_stream_runtime *stream) 1220 1218 { 1221 1219 struct sdw_slave_runtime *s_rt, *_s_rt; 1220 + struct sdw_bus *bus = m_rt->bus; 1222 1221 1223 1222 list_for_each_entry_safe(s_rt, _s_rt, &m_rt->slave_rt_list, m_rt_node) { 1224 1223 sdw_slave_port_free(s_rt->slave, stream); ··· 1229 1226 list_del(&m_rt->stream_node); 1230 1227 list_del(&m_rt->bus_node); 1231 1228 kfree(m_rt); 1229 + 1230 + bus->stream_refcount--; 1232 1231 } 1233 1232 1234 1233 /**
+2
include/linux/soundwire/sdw.h
··· 903 903 * meaningful if multi_link is set. If set to 1, hardware-based 904 904 * synchronization will be used even if a stream only uses a single 905 905 * SoundWire segment. 906 + * @stream_refcount: number of streams currently using this bus 906 907 */ 907 908 struct sdw_bus { 908 909 struct device *dev; ··· 934 933 u32 bank_switch_timeout; 935 934 bool multi_link; 936 935 int hw_sync_min_links; 936 + int stream_refcount; 937 937 }; 938 938 939 939 int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
+5
include/linux/soundwire/sdw_intel.h
··· 182 182 #define SDW_SHIM2_INTEL_VS_ACTMCTL_DODSE BIT(2) 183 183 #define SDW_SHIM2_INTEL_VS_ACTMCTL_DOAIS GENMASK(4, 3) 184 184 #define SDW_SHIM2_INTEL_VS_ACTMCTL_DOAISE BIT(5) 185 + #define SDW_SHIM3_INTEL_VS_ACTMCTL_CLSS BIT(6) 186 + #define SDW_SHIM3_INTEL_VS_ACTMCTL_CLDS GENMASK(11, 7) 187 + #define SDW_SHIM3_INTEL_VS_ACTMCTL_DODSE2 GENMASK(13, 12) 188 + #define SDW_SHIM3_INTEL_VS_ACTMCTL_DOAISE2 BIT(14) 189 + #define SDW_SHIM3_INTEL_VS_ACTMCTL_CLDE BIT(15) 185 190 186 191 /** 187 192 * struct sdw_intel_stream_params_data: configuration passed during