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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull soundwire updates from Vinod Koul:

- bus cleanup for warnings and probe deferral errors suppression

- cadence recheck for status with a delayed work

- intel interrupt rework on reset exit

* tag 'soundwire-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire:
soundwire: intel_bus_common: enable interrupts before exiting reset
soundwire: cadence: re-check Peripheral status with delayed_work
soundwire: bus: clean up probe warnings
soundwire: bus: drop unused driver name field
soundwire: bus: suppress probe deferral errors

+72 -31
+4 -15
drivers/soundwire/bus_type.c
··· 83 83 struct sdw_slave *slave = dev_to_sdw_dev(dev); 84 84 struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); 85 85 const struct sdw_device_id *id; 86 - const char *name; 87 86 int ret; 88 87 89 88 /* ··· 107 108 108 109 ret = drv->probe(slave, id); 109 110 if (ret) { 110 - name = drv->name; 111 - if (!name) 112 - name = drv->driver.name; 113 - 114 - dev_err(dev, "Probe of %s failed: %d\n", name, ret); 115 111 dev_pm_domain_detach(dev, false); 116 112 return ret; 117 113 } ··· 123 129 /* init the dynamic sysfs attributes we need */ 124 130 ret = sdw_slave_sysfs_dpn_init(slave); 125 131 if (ret < 0) 126 - dev_warn(dev, "Slave sysfs init failed:%d\n", ret); 132 + dev_warn(dev, "failed to initialise sysfs: %d\n", ret); 127 133 128 134 /* 129 135 * Check for valid clk_stop_timeout, use DisCo worst case value of ··· 147 153 if (drv->ops && drv->ops->update_status) { 148 154 ret = drv->ops->update_status(slave, slave->status); 149 155 if (ret < 0) 150 - dev_warn(dev, "%s: update_status failed with status %d\n", __func__, ret); 156 + dev_warn(dev, "failed to update status at probe: %d\n", ret); 151 157 } 152 158 153 159 mutex_unlock(&slave->sdw_dev_lock); ··· 198 204 */ 199 205 int __sdw_register_driver(struct sdw_driver *drv, struct module *owner) 200 206 { 201 - const char *name; 202 - 203 207 drv->driver.bus = &sdw_bus_type; 204 208 205 209 if (!drv->probe) { 206 - name = drv->name; 207 - if (!name) 208 - name = drv->driver.name; 209 - 210 - pr_err("driver %s didn't provide SDW probe routine\n", name); 210 + pr_err("driver %s didn't provide SDW probe routine\n", 211 + drv->driver.name); 211 212 return -EINVAL; 212 213 } 213 214
+37 -2
drivers/soundwire/cadence_master.c
··· 890 890 } 891 891 } 892 892 893 - if (is_slave) 894 - return sdw_handle_slave_status(&cdns->bus, status); 893 + if (is_slave) { 894 + int ret; 895 + 896 + mutex_lock(&cdns->status_update_lock); 897 + ret = sdw_handle_slave_status(&cdns->bus, status); 898 + mutex_unlock(&cdns->status_update_lock); 899 + return ret; 900 + } 895 901 896 902 return 0; 897 903 } ··· 993 987 return IRQ_HANDLED; 994 988 } 995 989 EXPORT_SYMBOL(sdw_cdns_irq); 990 + 991 + static void cdns_check_attached_status_dwork(struct work_struct *work) 992 + { 993 + struct sdw_cdns *cdns = 994 + container_of(work, struct sdw_cdns, attach_dwork.work); 995 + enum sdw_slave_status status[SDW_MAX_DEVICES + 1]; 996 + u32 val; 997 + int ret; 998 + int i; 999 + 1000 + val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT); 1001 + 1002 + for (i = 0; i <= SDW_MAX_DEVICES; i++) { 1003 + status[i] = val & 0x3; 1004 + if (status[i]) 1005 + dev_dbg(cdns->dev, "Peripheral %d status: %d\n", i, status[i]); 1006 + val >>= 2; 1007 + } 1008 + 1009 + mutex_lock(&cdns->status_update_lock); 1010 + ret = sdw_handle_slave_status(&cdns->bus, status); 1011 + mutex_unlock(&cdns->status_update_lock); 1012 + if (ret < 0) 1013 + dev_err(cdns->dev, "%s: sdw_handle_slave_status failed: %d\n", __func__, ret); 1014 + } 996 1015 997 1016 /** 998 1017 * cdns_update_slave_status_work - update slave status in a work since we will need to handle ··· 1771 1740 init_completion(&cdns->tx_complete); 1772 1741 cdns->bus.port_ops = &cdns_port_ops; 1773 1742 1743 + mutex_init(&cdns->status_update_lock); 1744 + 1774 1745 INIT_WORK(&cdns->work, cdns_update_slave_status_work); 1746 + INIT_DELAYED_WORK(&cdns->attach_dwork, cdns_check_attached_status_dwork); 1747 + 1775 1748 return 0; 1776 1749 } 1777 1750 EXPORT_SYMBOL(sdw_cdns_probe);
+5
drivers/soundwire/cadence_master.h
··· 117 117 * @link_up: Link status 118 118 * @msg_count: Messages sent on bus 119 119 * @dai_runtime_array: runtime context for each allocated DAI. 120 + * @status_update_lock: protect concurrency between interrupt-based and delayed work 121 + * status update 120 122 */ 121 123 struct sdw_cdns { 122 124 struct device *dev; ··· 150 148 bool interrupt_enabled; 151 149 152 150 struct work_struct work; 151 + struct delayed_work attach_dwork; 153 152 154 153 struct list_head list; 155 154 156 155 struct sdw_cdns_dai_runtime **dai_runtime_array; 156 + 157 + struct mutex status_update_lock; /* add mutual exclusion to sdw_handle_slave_status() */ 157 158 }; 158 159 159 160 #define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus)
+2
drivers/soundwire/intel.h
··· 103 103 104 104 #define INTEL_MASTER_RESET_ITERATIONS 10 105 105 106 + #define SDW_INTEL_DELAYED_ENUMERATION_MS 100 107 + 106 108 #define SDW_INTEL_CHECK_OPS(sdw, cb) ((sdw) && (sdw)->link_res && (sdw)->link_res->hw_ops && \ 107 109 (sdw)->link_res->hw_ops->cb) 108 110 #define SDW_INTEL_OPS(sdw, cb) ((sdw)->link_res->hw_ops->cb)
+1
drivers/soundwire/intel_auxdevice.c
··· 489 489 */ 490 490 if (!bus->prop.hw_disabled) { 491 491 sdw_intel_debugfs_exit(sdw); 492 + cancel_delayed_work_sync(&cdns->attach_dwork); 492 493 sdw_cdns_enable_interrupt(cdns, false); 493 494 } 494 495 sdw_bus_master_delete(bus);
+23 -12
drivers/soundwire/intel_bus_common.c
··· 45 45 return ret; 46 46 } 47 47 48 - ret = sdw_cdns_exit_reset(cdns); 49 - if (ret < 0) { 50 - dev_err(dev, "%s: unable to exit bus reset sequence: %d\n", __func__, ret); 51 - return ret; 52 - } 53 - 54 48 ret = sdw_cdns_enable_interrupt(cdns, true); 55 49 if (ret < 0) { 56 50 dev_err(dev, "%s: cannot enable interrupts: %d\n", __func__, ret); 57 51 return ret; 58 52 } 59 53 54 + ret = sdw_cdns_exit_reset(cdns); 55 + if (ret < 0) { 56 + dev_err(dev, "%s: unable to exit bus reset sequence: %d\n", __func__, ret); 57 + return ret; 58 + } 59 + 60 60 sdw_cdns_check_self_clearing_bits(cdns, __func__, 61 61 true, INTEL_MASTER_RESET_ITERATIONS); 62 + 63 + schedule_delayed_work(&cdns->attach_dwork, 64 + msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS)); 62 65 63 66 return 0; 64 67 } ··· 139 136 return ret; 140 137 } 141 138 142 - ret = sdw_cdns_exit_reset(cdns); 143 - if (ret < 0) { 144 - dev_err(dev, "unable to exit bus reset sequence during resume\n"); 145 - return ret; 146 - } 147 - 148 139 ret = sdw_cdns_enable_interrupt(cdns, true); 149 140 if (ret < 0) { 150 141 dev_err(dev, "cannot enable interrupts during resume\n"); 151 142 return ret; 152 143 } 153 144 145 + ret = sdw_cdns_exit_reset(cdns); 146 + if (ret < 0) { 147 + dev_err(dev, "unable to exit bus reset sequence during resume\n"); 148 + return ret; 149 + } 150 + 154 151 } 155 152 sdw_cdns_check_self_clearing_bits(cdns, __func__, true, INTEL_MASTER_RESET_ITERATIONS); 153 + 154 + schedule_delayed_work(&cdns->attach_dwork, 155 + msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS)); 156 156 157 157 return 0; 158 158 } ··· 190 184 191 185 sdw_cdns_check_self_clearing_bits(cdns, __func__, true, INTEL_MASTER_RESET_ITERATIONS); 192 186 187 + schedule_delayed_work(&cdns->attach_dwork, 188 + msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS)); 189 + 193 190 return 0; 194 191 } 195 192 ··· 202 193 struct sdw_cdns *cdns = &sdw->cdns; 203 194 bool wake_enable = false; 204 195 int ret; 196 + 197 + cancel_delayed_work_sync(&cdns->attach_dwork); 205 198 206 199 if (clock_stop) { 207 200 ret = sdw_cdns_clock_stop(cdns, true);
-2
include/linux/soundwire/sdw.h
··· 704 704 container_of(d, struct sdw_master_device, dev) 705 705 706 706 struct sdw_driver { 707 - const char *name; 708 - 709 707 int (*probe)(struct sdw_slave *sdw, 710 708 const struct sdw_device_id *id); 711 709 int (*remove)(struct sdw_slave *sdw);