Skip to content

Commit 7116747

Browse files
committed
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
2 parents f34c512 + 5aedb8d commit 7116747

File tree

7 files changed

+68
-27
lines changed

7 files changed

+68
-27
lines changed

drivers/soundwire/bus_type.c

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ static int sdw_drv_probe(struct device *dev)
8383
struct sdw_slave *slave = dev_to_sdw_dev(dev);
8484
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
8585
const struct sdw_device_id *id;
86-
const char *name;
8786
int ret;
8887

8988
/*
@@ -108,11 +107,6 @@ static int sdw_drv_probe(struct device *dev)
108107

109108
ret = drv->probe(slave, id);
110109
if (ret) {
111-
name = drv->name;
112-
if (!name)
113-
name = drv->driver.name;
114-
115-
dev_err(dev, "Probe of %s failed: %d\n", name, ret);
116110
dev_pm_domain_detach(dev, false);
117111
return ret;
118112
}
@@ -129,7 +123,7 @@ static int sdw_drv_probe(struct device *dev)
129123
/* init the dynamic sysfs attributes we need */
130124
ret = sdw_slave_sysfs_dpn_init(slave);
131125
if (ret < 0)
132-
dev_warn(dev, "Slave sysfs init failed:%d\n", ret);
126+
dev_warn(dev, "failed to initialise sysfs: %d\n", ret);
133127

134128
/*
135129
* Check for valid clk_stop_timeout, use DisCo worst case value of
@@ -153,7 +147,7 @@ static int sdw_drv_probe(struct device *dev)
153147
if (drv->ops && drv->ops->update_status) {
154148
ret = drv->ops->update_status(slave, slave->status);
155149
if (ret < 0)
156-
dev_warn(dev, "%s: update_status failed with status %d\n", __func__, ret);
150+
dev_warn(dev, "failed to update status at probe: %d\n", ret);
157151
}
158152

159153
mutex_unlock(&slave->sdw_dev_lock);
@@ -204,16 +198,11 @@ static void sdw_drv_shutdown(struct device *dev)
204198
*/
205199
int __sdw_register_driver(struct sdw_driver *drv, struct module *owner)
206200
{
207-
const char *name;
208-
209201
drv->driver.bus = &sdw_bus_type;
210202

211203
if (!drv->probe) {
212-
name = drv->name;
213-
if (!name)
214-
name = drv->driver.name;
215-
216-
pr_err("driver %s didn't provide SDW probe routine\n", name);
204+
pr_err("driver %s didn't provide SDW probe routine\n",
205+
drv->driver.name);
217206
return -EINVAL;
218207
}
219208

drivers/soundwire/cadence_master.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -890,8 +890,14 @@ static int cdns_update_slave_status(struct sdw_cdns *cdns,
890890
}
891891
}
892892

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+
}
895901

896902
return 0;
897903
}
@@ -988,6 +994,31 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
988994
}
989995
EXPORT_SYMBOL(sdw_cdns_irq);
990996

997+
static void cdns_check_attached_status_dwork(struct work_struct *work)
998+
{
999+
struct sdw_cdns *cdns =
1000+
container_of(work, struct sdw_cdns, attach_dwork.work);
1001+
enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
1002+
u32 val;
1003+
int ret;
1004+
int i;
1005+
1006+
val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
1007+
1008+
for (i = 0; i <= SDW_MAX_DEVICES; i++) {
1009+
status[i] = val & 0x3;
1010+
if (status[i])
1011+
dev_dbg(cdns->dev, "Peripheral %d status: %d\n", i, status[i]);
1012+
val >>= 2;
1013+
}
1014+
1015+
mutex_lock(&cdns->status_update_lock);
1016+
ret = sdw_handle_slave_status(&cdns->bus, status);
1017+
mutex_unlock(&cdns->status_update_lock);
1018+
if (ret < 0)
1019+
dev_err(cdns->dev, "%s: sdw_handle_slave_status failed: %d\n", __func__, ret);
1020+
}
1021+
9911022
/**
9921023
* cdns_update_slave_status_work - update slave status in a work since we will need to handle
9931024
* other interrupts eg. CDNS_MCP_INT_RX_WL during the update slave
@@ -1740,7 +1771,11 @@ int sdw_cdns_probe(struct sdw_cdns *cdns)
17401771
init_completion(&cdns->tx_complete);
17411772
cdns->bus.port_ops = &cdns_port_ops;
17421773

1774+
mutex_init(&cdns->status_update_lock);
1775+
17431776
INIT_WORK(&cdns->work, cdns_update_slave_status_work);
1777+
INIT_DELAYED_WORK(&cdns->attach_dwork, cdns_check_attached_status_dwork);
1778+
17441779
return 0;
17451780
}
17461781
EXPORT_SYMBOL(sdw_cdns_probe);

drivers/soundwire/cadence_master.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ struct sdw_cdns_dai_runtime {
117117
* @link_up: Link status
118118
* @msg_count: Messages sent on bus
119119
* @dai_runtime_array: runtime context for each allocated DAI.
120+
* @status_update_lock: protect concurrency between interrupt-based and delayed work
121+
* status update
120122
*/
121123
struct sdw_cdns {
122124
struct device *dev;
@@ -148,10 +150,13 @@ struct sdw_cdns {
148150
bool interrupt_enabled;
149151

150152
struct work_struct work;
153+
struct delayed_work attach_dwork;
151154

152155
struct list_head list;
153156

154157
struct sdw_cdns_dai_runtime **dai_runtime_array;
158+
159+
struct mutex status_update_lock; /* add mutual exclusion to sdw_handle_slave_status() */
155160
};
156161

157162
#define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus)

drivers/soundwire/intel.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ static inline void intel_writew(void __iomem *base, int offset, u16 value)
103103

104104
#define INTEL_MASTER_RESET_ITERATIONS 10
105105

106+
#define SDW_INTEL_DELAYED_ENUMERATION_MS 100
107+
106108
#define SDW_INTEL_CHECK_OPS(sdw, cb) ((sdw) && (sdw)->link_res && (sdw)->link_res->hw_ops && \
107109
(sdw)->link_res->hw_ops->cb)
108110
#define SDW_INTEL_OPS(sdw, cb) ((sdw)->link_res->hw_ops->cb)

drivers/soundwire/intel_auxdevice.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ static void intel_link_remove(struct auxiliary_device *auxdev)
489489
*/
490490
if (!bus->prop.hw_disabled) {
491491
sdw_intel_debugfs_exit(sdw);
492+
cancel_delayed_work_sync(&cdns->attach_dwork);
492493
sdw_cdns_enable_interrupt(cdns, false);
493494
}
494495
sdw_bus_master_delete(bus);

drivers/soundwire/intel_bus_common.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,24 @@ int intel_start_bus(struct sdw_intel *sdw)
4545
return ret;
4646
}
4747

48-
ret = sdw_cdns_exit_reset(cdns);
48+
ret = sdw_cdns_enable_interrupt(cdns, true);
4949
if (ret < 0) {
50-
dev_err(dev, "%s: unable to exit bus reset sequence: %d\n", __func__, ret);
50+
dev_err(dev, "%s: cannot enable interrupts: %d\n", __func__, ret);
5151
return ret;
5252
}
5353

54-
ret = sdw_cdns_enable_interrupt(cdns, true);
54+
ret = sdw_cdns_exit_reset(cdns);
5555
if (ret < 0) {
56-
dev_err(dev, "%s: cannot enable interrupts: %d\n", __func__, ret);
56+
dev_err(dev, "%s: unable to exit bus reset sequence: %d\n", __func__, ret);
5757
return ret;
5858
}
5959

6060
sdw_cdns_check_self_clearing_bits(cdns, __func__,
6161
true, INTEL_MASTER_RESET_ITERATIONS);
6262

63+
schedule_delayed_work(&cdns->attach_dwork,
64+
msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS));
65+
6366
return 0;
6467
}
6568

@@ -136,21 +139,24 @@ int intel_start_bus_after_reset(struct sdw_intel *sdw)
136139
return ret;
137140
}
138141

139-
ret = sdw_cdns_exit_reset(cdns);
142+
ret = sdw_cdns_enable_interrupt(cdns, true);
140143
if (ret < 0) {
141-
dev_err(dev, "unable to exit bus reset sequence during resume\n");
144+
dev_err(dev, "cannot enable interrupts during resume\n");
142145
return ret;
143146
}
144147

145-
ret = sdw_cdns_enable_interrupt(cdns, true);
148+
ret = sdw_cdns_exit_reset(cdns);
146149
if (ret < 0) {
147-
dev_err(dev, "cannot enable interrupts during resume\n");
150+
dev_err(dev, "unable to exit bus reset sequence during resume\n");
148151
return ret;
149152
}
150153

151154
}
152155
sdw_cdns_check_self_clearing_bits(cdns, __func__, true, INTEL_MASTER_RESET_ITERATIONS);
153156

157+
schedule_delayed_work(&cdns->attach_dwork,
158+
msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS));
159+
154160
return 0;
155161
}
156162

@@ -184,6 +190,9 @@ int intel_start_bus_after_clock_stop(struct sdw_intel *sdw)
184190

185191
sdw_cdns_check_self_clearing_bits(cdns, __func__, true, INTEL_MASTER_RESET_ITERATIONS);
186192

193+
schedule_delayed_work(&cdns->attach_dwork,
194+
msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS));
195+
187196
return 0;
188197
}
189198

@@ -194,6 +203,8 @@ int intel_stop_bus(struct sdw_intel *sdw, bool clock_stop)
194203
bool wake_enable = false;
195204
int ret;
196205

206+
cancel_delayed_work_sync(&cdns->attach_dwork);
207+
197208
if (clock_stop) {
198209
ret = sdw_cdns_clock_stop(cdns, true);
199210
if (ret < 0)

include/linux/soundwire/sdw.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,6 @@ struct sdw_master_device {
704704
container_of(d, struct sdw_master_device, dev)
705705

706706
struct sdw_driver {
707-
const char *name;
708-
709707
int (*probe)(struct sdw_slave *sdw,
710708
const struct sdw_device_id *id);
711709
int (*remove)(struct sdw_slave *sdw);

0 commit comments

Comments
 (0)