summaryrefslogtreecommitdiff
path: root/drivers/soundwire/bus.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-01-29 10:35:54 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2020-01-29 10:35:54 -0800
commit701a9c8092ddf299d7f90ab2d66b19b4526d1186 (patch)
tree36c29b7c56a505fa8a051286867b296820e2fc67 /drivers/soundwire/bus.c
parent975f9ce9a067a82b89d49e63938e01b2773ac9d4 (diff)
parent0db4a15d4c2787b1112001790d4f95bd2c5fed6f (diff)
downloadlwn-701a9c8092ddf299d7f90ab2d66b19b4526d1186.tar.gz
lwn-701a9c8092ddf299d7f90ab2d66b19b4526d1186.zip
Merge tag 'char-misc-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here is the big char/misc/whatever driver changes for 5.6-rc1 Included in here are loads of things from a variety of different driver subsystems: - soundwire updates - binder updates - nvmem updates - firmware drivers updates - extcon driver updates - various misc driver updates - fpga driver updates - interconnect subsystem and driver updates - bus driver updates - uio driver updates - mei driver updates - w1 driver cleanups - various other small driver updates All of these have been in linux-next for a while with no reported issues" * tag 'char-misc-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (86 commits) mei: me: add jasper point DID char: hpet: Use flexible-array member binder: fix log spam for existing debugfs file creation. mei: me: add comet point (lake) H device ids nvmem: add QTI SDAM driver dt-bindings: nvmem: add binding for QTI SPMI SDAM dt-bindings: imx-ocotp: Add i.MX8MP compatible dt-bindings: soundwire: fix example soundwire: cadence: fix kernel-doc parameter descriptions soundwire: intel: report slave_ids for each link to SOF driver siox: Use the correct style for SPDX License Identifier w1: omap-hdq: Simplify driver with PM runtime autosuspend firmware: stratix10-svc: Remove unneeded semicolon firmware: google: Probe for a GSMI handler in firmware firmware: google: Unregister driver_info on failure and exit in gsmi firmware: google: Release devices before unregistering the bus slimbus: qcom: add missed clk_disable_unprepare in remove slimbus: Use the correct style for SPDX License Identifier slimbus: qcom-ngd-ctrl: Use dma_request_chan() instead dma_request_slave_channel() dt-bindings: SLIMBus: add slim devices optional properties ...
Diffstat (limited to 'drivers/soundwire/bus.c')
-rw-r--r--drivers/soundwire/bus.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index be5d437058ed..6106577fb3ed 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -456,26 +456,35 @@ err:
static int sdw_assign_device_num(struct sdw_slave *slave)
{
int ret, dev_num;
+ bool new_device = false;
/* check first if device number is assigned, if so reuse that */
if (!slave->dev_num) {
- mutex_lock(&slave->bus->bus_lock);
- dev_num = sdw_get_device_num(slave);
- mutex_unlock(&slave->bus->bus_lock);
- if (dev_num < 0) {
- dev_err(slave->bus->dev, "Get dev_num failed: %d\n",
- dev_num);
- return dev_num;
+ if (!slave->dev_num_sticky) {
+ mutex_lock(&slave->bus->bus_lock);
+ dev_num = sdw_get_device_num(slave);
+ mutex_unlock(&slave->bus->bus_lock);
+ if (dev_num < 0) {
+ dev_err(slave->bus->dev, "Get dev_num failed: %d\n",
+ dev_num);
+ return dev_num;
+ }
+ slave->dev_num = dev_num;
+ slave->dev_num_sticky = dev_num;
+ new_device = true;
+ } else {
+ slave->dev_num = slave->dev_num_sticky;
}
- } else {
+ }
+
+ if (!new_device)
dev_info(slave->bus->dev,
- "Slave already registered dev_num:%d\n",
+ "Slave already registered, reusing dev_num:%d\n",
slave->dev_num);
- /* Clear the slave->dev_num to transfer message on device 0 */
- dev_num = slave->dev_num;
- slave->dev_num = 0;
- }
+ /* Clear the slave->dev_num to transfer message on device 0 */
+ dev_num = slave->dev_num;
+ slave->dev_num = 0;
ret = sdw_write(slave, SDW_SCP_DEVNUMBER, dev_num);
if (ret < 0) {
@@ -485,7 +494,7 @@ static int sdw_assign_device_num(struct sdw_slave *slave)
}
/* After xfer of msg, restore dev_num */
- slave->dev_num = dev_num;
+ slave->dev_num = slave->dev_num_sticky;
return 0;
}
@@ -979,6 +988,24 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
struct sdw_slave *slave;
int i, ret = 0;
+ /* first check if any Slaves fell off the bus */
+ for (i = 1; i <= SDW_MAX_DEVICES; i++) {
+ mutex_lock(&bus->bus_lock);
+ if (test_bit(i, bus->assigned) == false) {
+ mutex_unlock(&bus->bus_lock);
+ continue;
+ }
+ mutex_unlock(&bus->bus_lock);
+
+ slave = sdw_get_slave(bus, i);
+ if (!slave)
+ continue;
+
+ if (status[i] == SDW_SLAVE_UNATTACHED &&
+ slave->status != SDW_SLAVE_UNATTACHED)
+ sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
+ }
+
if (status[0] == SDW_SLAVE_ATTACHED) {
dev_dbg(bus->dev, "Slave attached, programming device number\n");
ret = sdw_program_device_num(bus);