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

Merge tag 'soundwire-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire

Pull soundwire updates from Vinod Koul:
"A couple of small core changes and an Intel driver change:

- sdw_assign_device_num() logic simplification, using internal slave
id for irqs and optimizing computing of port params in specific
stream states

- Intel driver updates for ACE3+ microphone privacy status reporting
and enabling the status in HDA Intel driver"

* tag 'soundwire-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire:
soundwire: only compute port params in specific stream states
ASoC: SOF: Intel: hda: Set the mic_privacy flag for soundwire with ACE3+
soundwire: intel: Add awareness of ACE3+ microphone privacy
soundwire: bus: Add internal slave ID and use for IRQs
soundwire: bus: Simplify sdw_assign_device_num()

+57 -20
+14 -17
drivers/soundwire/bus.c
··· 56 56 return ret; 57 57 } 58 58 59 + ida_init(&bus->slave_ida); 60 + 59 61 ret = sdw_master_device_add(bus, parent, fwnode); 60 62 if (ret < 0) { 61 63 dev_err(parent, "Failed to add master device at link %d\n", ··· 753 751 static int sdw_assign_device_num(struct sdw_slave *slave) 754 752 { 755 753 struct sdw_bus *bus = slave->bus; 756 - int ret, dev_num; 757 - bool new_device = false; 754 + struct device *dev = bus->dev; 755 + int ret; 758 756 759 757 /* check first if device number is assigned, if so reuse that */ 760 758 if (!slave->dev_num) { 761 759 if (!slave->dev_num_sticky) { 760 + int dev_num; 761 + 762 762 mutex_lock(&slave->bus->bus_lock); 763 763 dev_num = sdw_get_device_num(slave); 764 764 mutex_unlock(&slave->bus->bus_lock); 765 765 if (dev_num < 0) { 766 - dev_err(bus->dev, "Get dev_num failed: %d\n", 767 - dev_num); 766 + dev_err(dev, "Get dev_num failed: %d\n", dev_num); 768 767 return dev_num; 769 768 } 770 - slave->dev_num = dev_num; 769 + 771 770 slave->dev_num_sticky = dev_num; 772 - new_device = true; 773 771 } else { 774 - slave->dev_num = slave->dev_num_sticky; 772 + dev_dbg(dev, "Slave already registered, reusing dev_num: %d\n", 773 + slave->dev_num_sticky); 775 774 } 776 775 } 777 776 778 - if (!new_device) 779 - dev_dbg(bus->dev, 780 - "Slave already registered, reusing dev_num:%d\n", 781 - slave->dev_num); 782 - 783 777 /* Clear the slave->dev_num to transfer message on device 0 */ 784 - dev_num = slave->dev_num; 785 778 slave->dev_num = 0; 786 779 787 - ret = sdw_write_no_pm(slave, SDW_SCP_DEVNUMBER, dev_num); 780 + ret = sdw_write_no_pm(slave, SDW_SCP_DEVNUMBER, slave->dev_num_sticky); 788 781 if (ret < 0) { 789 - dev_err(bus->dev, "Program device_num %d failed: %d\n", 790 - dev_num, ret); 782 + dev_err(dev, "Program device_num %d failed: %d\n", 783 + slave->dev_num_sticky, ret); 791 784 return ret; 792 785 } 793 786 ··· 790 793 slave->dev_num = slave->dev_num_sticky; 791 794 792 795 if (bus->ops && bus->ops->new_peripheral_assigned) 793 - bus->ops->new_peripheral_assigned(bus, slave, dev_num); 796 + bus->ops->new_peripheral_assigned(bus, slave, slave->dev_num); 794 797 795 798 return 0; 796 799 }
+10
drivers/soundwire/bus_type.c
··· 105 105 if (ret) 106 106 return ret; 107 107 108 + ret = ida_alloc_max(&slave->bus->slave_ida, SDW_FW_MAX_DEVICES, GFP_KERNEL); 109 + if (ret < 0) { 110 + dev_err(dev, "Failed to allocated ID: %d\n", ret); 111 + return ret; 112 + } 113 + slave->index = ret; 114 + 108 115 ret = drv->probe(slave, id); 109 116 if (ret) { 110 117 dev_pm_domain_detach(dev, false); 118 + ida_free(&slave->bus->slave_ida, slave->index); 111 119 return ret; 112 120 } 113 121 ··· 181 173 ret = drv->remove(slave); 182 174 183 175 dev_pm_domain_detach(dev, false); 176 + 177 + ida_free(&slave->bus->slave_ida, slave->index); 184 178 185 179 return ret; 186 180 }
+7
drivers/soundwire/generic_bandwidth_allocation.c
··· 204 204 port_bo = 1; 205 205 206 206 list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) { 207 + /* 208 + * Only runtimes with CONFIGURED, PREPARED, ENABLED, and DISABLED 209 + * states should be included in the bandwidth calculation. 210 + */ 211 + if (m_rt->stream->state > SDW_STREAM_DISABLED || 212 + m_rt->stream->state < SDW_STREAM_CONFIGURED) 213 + continue; 207 214 sdw_compute_master_ports(m_rt, &params[i], &port_bo, hstop); 208 215 } 209 216
+2
drivers/soundwire/intel.h
··· 22 22 * @shim_lock: mutex to handle access to shared SHIM registers 23 23 * @shim_mask: global pointer to check SHIM register initialization 24 24 * @clock_stop_quirks: mask defining requested behavior on pm_suspend 25 + * @mic_privacy: ACE version supports microphone privacy 25 26 * @link_mask: global mask needed for power-up/down sequences 26 27 * @cdns: Cadence master descriptor 27 28 * @list: used to walk-through all masters exposed by the same controller ··· 43 42 struct mutex *shim_lock; /* protect shared registers */ 44 43 u32 *shim_mask; 45 44 u32 clock_stop_quirks; 45 + bool mic_privacy; 46 46 u32 link_mask; 47 47 struct sdw_cdns *cdns; 48 48 struct list_head list;
+6
drivers/soundwire/intel_ace2x_debugfs.c
··· 76 76 ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_IOCTL); 77 77 ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_ACTMCTL); 78 78 79 + if (sdw->link_res->mic_privacy) { 80 + ret += scnprintf(buf + ret, RD_BUF - ret, "\nVS PVCCS\n"); 81 + ret += intel_sprintf(vs_s, false, buf, ret, 82 + SDW_SHIM2_INTEL_VS_PVCCS); 83 + } 84 + 79 85 seq_printf(s_file, "%s", buf); 80 86 kfree(buf); 81 87
+1
drivers/soundwire/intel_init.c
··· 77 77 link->shim = res->mmio_base + SDW_SHIM2_GENERIC_BASE(link_id); 78 78 link->shim_vs = res->mmio_base + SDW_SHIM2_VS_BASE(link_id); 79 79 link->shim_lock = res->eml_lock; 80 + link->mic_privacy = res->mic_privacy; 80 81 } 81 82 82 83 link->ops = res->ops;
+3 -3
drivers/soundwire/irq.c
··· 31 31 { 32 32 bus->irq_chip.name = dev_name(bus->dev); 33 33 34 - bus->domain = irq_domain_create_linear(fwnode, SDW_MAX_DEVICES, 34 + bus->domain = irq_domain_create_linear(fwnode, SDW_FW_MAX_DEVICES, 35 35 &sdw_domain_ops, bus); 36 36 if (!bus->domain) { 37 37 dev_err(bus->dev, "Failed to add IRQ domain\n"); ··· 50 50 { 51 51 struct sdw_slave *slave = data; 52 52 53 - irq_dispose_mapping(irq_find_mapping(slave->bus->domain, slave->dev_num)); 53 + irq_dispose_mapping(slave->irq); 54 54 } 55 55 56 56 void sdw_irq_create_mapping(struct sdw_slave *slave) 57 57 { 58 - slave->irq = irq_create_mapping(slave->bus->domain, slave->dev_num); 58 + slave->irq = irq_create_mapping(slave->bus->domain, slave->index); 59 59 if (!slave->irq) 60 60 dev_warn(&slave->dev, "Failed to map IRQ\n"); 61 61
+6
include/linux/soundwire/sdw.h
··· 8 8 #include <linux/bug.h> 9 9 #include <linux/completion.h> 10 10 #include <linux/device.h> 11 + #include <linux/idr.h> 11 12 #include <linux/irq.h> 12 13 #include <linux/irqdomain.h> 13 14 #include <linux/lockdep_types.h> ··· 51 50 52 51 #define SDW_FRAME_CTRL_BITS 48 53 52 #define SDW_MAX_DEVICES 11 53 + #define SDW_FW_MAX_DEVICES 16 54 54 55 55 #define SDW_MAX_PORTS 15 56 56 #define SDW_VALID_PORT_RANGE(n) ((n) < SDW_MAX_PORTS && (n) >= 1) ··· 632 630 * struct sdw_slave - SoundWire Slave 633 631 * @id: MIPI device ID 634 632 * @dev: Linux device 633 + * @index: internal ID for this slave 635 634 * @irq: IRQ number 636 635 * @status: Status reported by the Slave 637 636 * @bus: Bus handle ··· 664 661 struct sdw_slave { 665 662 struct sdw_slave_id id; 666 663 struct device dev; 664 + int index; 667 665 int irq; 668 666 enum sdw_slave_status status; 669 667 struct sdw_bus *bus; ··· 972 968 * @md: Master device 973 969 * @bus_lock_key: bus lock key associated to @bus_lock 974 970 * @bus_lock: bus lock 971 + * @slave_ida: IDA for allocating internal slave IDs 975 972 * @slaves: list of Slaves on this bus 976 973 * @msg_lock_key: message lock key associated to @msg_lock 977 974 * @msg_lock: message lock ··· 1015 1010 struct sdw_master_device *md; 1016 1011 struct lock_class_key bus_lock_key; 1017 1012 struct mutex bus_lock; 1013 + struct ida slave_ida; 1018 1014 struct list_head slaves; 1019 1015 struct lock_class_key msg_lock_key; 1020 1016 struct mutex msg_lock;
+5
include/linux/soundwire/sdw_intel.h
··· 189 189 #define SDW_SHIM3_INTEL_VS_ACTMCTL_DOAISE2 BIT(14) 190 190 #define SDW_SHIM3_INTEL_VS_ACTMCTL_CLDE BIT(15) 191 191 192 + /* ACE3+ Mic privacy control and status register */ 193 + #define SDW_SHIM2_INTEL_VS_PVCCS 0x10 194 + 192 195 /** 193 196 * struct sdw_intel_stream_params_data: configuration passed during 194 197 * the @params_stream callback, e.g. for interaction with DSP ··· 334 331 * @shim_base: sdw shim base. 335 332 * @alh_base: sdw alh base. 336 333 * @ext: extended HDaudio link support 334 + * @mic_privacy: ACE version supports microphone privacy 337 335 * @hbus: hdac_bus pointer, needed for power management 338 336 * @eml_lock: mutex protecting shared registers in the HDaudio multi-link 339 337 * space ··· 353 349 u32 shim_base; 354 350 u32 alh_base; 355 351 bool ext; 352 + bool mic_privacy; 356 353 struct hdac_bus *hbus; 357 354 struct mutex *eml_lock; 358 355 };
+3
sound/soc/sof/intel/hda.c
··· 192 192 res.ext = true; 193 193 res.ops = &sdw_ace2x_callback; 194 194 195 + /* ACE3+ supports microphone privacy */ 196 + if (chip->hw_ip_version >= SOF_INTEL_ACE_3_0) 197 + res.mic_privacy = true; 195 198 } 196 199 res.irq = sdev->ipc_irq; 197 200 res.handle = hdev->info.handle;