Skip to content

Commit 881eccb

Browse files
committed
Merge tag 'soundwire-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire
Pull soundwire updates from Vinod Koul: "Updates for Intel, Cadence and Qualcomm drivers: - another round of Intel driver cleanup to prepare for future code reorg which is expected in next cycle (Pierre-Louis Bossart) - bus unattach notifications processing during re-enumeration along with Cadence driver updates for this (Richard Fitzgerald) - Qualcomm driver updates to handle device0 status (Srinivas Kandagatla)" * tag 'soundwire-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire: (42 commits) soundwire: intel: add helper to stop bus soundwire: intel: introduce helpers to start bus soundwire: intel: introduce intel_shim_check_wake() helper soundwire: intel: simplify read ops assignment soundwire: intel: remove intel_init() wrapper soundwire: intel: move shim initialization before power up/down soundwire: intel: remove clock_stop parameter in intel_shim_init() soundwire: intel: move all PDI initialization under intel_register_dai() soundwire: intel: move DAI registration and debugfs init earlier soundwire: intel: simplify flow and use devm_ for DAI registration soundwire: intel: fix error handling on dai registration issues soundwire: cadence: Simplify error paths in cdns_xfer_msg() soundwire: cadence: Fix error check in cdns_xfer_msg() soundwire: cadence: Write to correct address for each FIFO chunk soundwire: bus: Fix wrong port number in sdw_handle_slave_alerts() soundwire: qcom: do not send status of device 0 during alert soundwire: qcom: update status from device id 1 soundwire: cadence: Don't overwrite msg->buf during write commands soundwire: bus: Don't exit early if no device IDs were programmed soundwire: cadence: Fix lost ATTACHED interrupts when enumerating ...
2 parents 33e591d + 503ae28 commit 881eccb

8 files changed

Lines changed: 557 additions & 480 deletions

File tree

drivers/soundwire/bus.c

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
#include "bus.h"
1212
#include "sysfs_local.h"
1313

14-
static DEFINE_IDA(sdw_ida);
14+
static DEFINE_IDA(sdw_bus_ida);
15+
static DEFINE_IDA(sdw_peripheral_ida);
1516

1617
static int sdw_get_id(struct sdw_bus *bus)
1718
{
18-
int rc = ida_alloc(&sdw_ida, GFP_KERNEL);
19+
int rc = ida_alloc(&sdw_bus_ida, GFP_KERNEL);
1920

2021
if (rc < 0)
2122
return rc;
@@ -75,7 +76,6 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
7576

7677
/*
7778
* Initialize multi_link flag
78-
* TODO: populate this flag by reading property from FW node
7979
*/
8080
bus->multi_link = false;
8181
if (bus->ops->read_prop) {
@@ -157,9 +157,11 @@ static int sdw_delete_slave(struct device *dev, void *data)
157157

158158
mutex_lock(&bus->bus_lock);
159159

160-
if (slave->dev_num) /* clear dev_num if assigned */
160+
if (slave->dev_num) { /* clear dev_num if assigned */
161161
clear_bit(slave->dev_num, bus->assigned);
162-
162+
if (bus->dev_num_ida_min)
163+
ida_free(&sdw_peripheral_ida, slave->dev_num);
164+
}
163165
list_del_init(&slave->node);
164166
mutex_unlock(&bus->bus_lock);
165167

@@ -179,7 +181,7 @@ void sdw_bus_master_delete(struct sdw_bus *bus)
179181
sdw_master_device_del(bus);
180182

181183
sdw_bus_debugfs_exit(bus);
182-
ida_free(&sdw_ida, bus->id);
184+
ida_free(&sdw_bus_ida, bus->id);
183185
}
184186
EXPORT_SYMBOL(sdw_bus_master_delete);
185187

@@ -671,10 +673,18 @@ static int sdw_get_device_num(struct sdw_slave *slave)
671673
{
672674
int bit;
673675

674-
bit = find_first_zero_bit(slave->bus->assigned, SDW_MAX_DEVICES);
675-
if (bit == SDW_MAX_DEVICES) {
676-
bit = -ENODEV;
677-
goto err;
676+
if (slave->bus->dev_num_ida_min) {
677+
bit = ida_alloc_range(&sdw_peripheral_ida,
678+
slave->bus->dev_num_ida_min, SDW_MAX_DEVICES,
679+
GFP_KERNEL);
680+
if (bit < 0)
681+
goto err;
682+
} else {
683+
bit = find_first_zero_bit(slave->bus->assigned, SDW_MAX_DEVICES);
684+
if (bit == SDW_MAX_DEVICES) {
685+
bit = -ENODEV;
686+
goto err;
687+
}
678688
}
679689

680690
/*
@@ -751,7 +761,7 @@ void sdw_extract_slave_id(struct sdw_bus *bus,
751761
}
752762
EXPORT_SYMBOL(sdw_extract_slave_id);
753763

754-
static int sdw_program_device_num(struct sdw_bus *bus)
764+
static int sdw_program_device_num(struct sdw_bus *bus, bool *programmed)
755765
{
756766
u8 buf[SDW_NUM_DEV_ID_REGISTERS] = {0};
757767
struct sdw_slave *slave, *_s;
@@ -761,6 +771,8 @@ static int sdw_program_device_num(struct sdw_bus *bus)
761771
int count = 0, ret;
762772
u64 addr;
763773

774+
*programmed = false;
775+
764776
/* No Slave, so use raw xfer api */
765777
ret = sdw_fill_msg(&msg, NULL, SDW_SCP_DEVID_0,
766778
SDW_NUM_DEV_ID_REGISTERS, 0, SDW_MSG_FLAG_READ, buf);
@@ -795,6 +807,16 @@ static int sdw_program_device_num(struct sdw_bus *bus)
795807
if (sdw_compare_devid(slave, id) == 0) {
796808
found = true;
797809

810+
/*
811+
* To prevent skipping state-machine stages don't
812+
* program a device until we've seen it UNATTACH.
813+
* Must return here because no other device on #0
814+
* can be detected until this one has been
815+
* assigned a device ID.
816+
*/
817+
if (slave->status != SDW_SLAVE_UNATTACHED)
818+
return 0;
819+
798820
/*
799821
* Assign a new dev_num to this Slave and
800822
* not mark it present. It will be marked
@@ -809,6 +831,8 @@ static int sdw_program_device_num(struct sdw_bus *bus)
809831
return ret;
810832
}
811833

834+
*programmed = true;
835+
812836
break;
813837
}
814838
}
@@ -848,22 +872,22 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
848872
mutex_lock(&bus->bus_lock);
849873

850874
dev_vdbg(bus->dev,
851-
"%s: changing status slave %d status %d new status %d\n",
852-
__func__, slave->dev_num, slave->status, status);
875+
"changing status slave %d status %d new status %d\n",
876+
slave->dev_num, slave->status, status);
853877

854878
if (status == SDW_SLAVE_UNATTACHED) {
855879
dev_dbg(&slave->dev,
856-
"%s: initializing enumeration and init completion for Slave %d\n",
857-
__func__, slave->dev_num);
880+
"initializing enumeration and init completion for Slave %d\n",
881+
slave->dev_num);
858882

859883
init_completion(&slave->enumeration_complete);
860884
init_completion(&slave->initialization_complete);
861885

862886
} else if ((status == SDW_SLAVE_ATTACHED) &&
863887
(slave->status == SDW_SLAVE_UNATTACHED)) {
864888
dev_dbg(&slave->dev,
865-
"%s: signaling enumeration completion for Slave %d\n",
866-
__func__, slave->dev_num);
889+
"signaling enumeration completion for Slave %d\n",
890+
slave->dev_num);
867891

868892
complete(&slave->enumeration_complete);
869893
}
@@ -1630,7 +1654,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
16301654
port = buf2[0] & SDW_SCP_INTSTAT2_PORT4_10;
16311655
for_each_set_bit(bit, &port, 8) {
16321656
/* scp2 ports start from 4 */
1633-
port_num = bit + 3;
1657+
port_num = bit + 4;
16341658
sdw_handle_port_interrupt(slave,
16351659
port_num,
16361660
&port_status[port_num]);
@@ -1642,7 +1666,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
16421666
port = buf2[1] & SDW_SCP_INTSTAT3_PORT11_14;
16431667
for_each_set_bit(bit, &port, 8) {
16441668
/* scp3 ports start from 11 */
1645-
port_num = bit + 10;
1669+
port_num = bit + 11;
16461670
sdw_handle_port_interrupt(slave,
16471671
port_num,
16481672
&port_status[port_num]);
@@ -1768,7 +1792,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
17681792
{
17691793
enum sdw_slave_status prev_status;
17701794
struct sdw_slave *slave;
1771-
bool attached_initializing;
1795+
bool attached_initializing, id_programmed;
17721796
int i, ret = 0;
17731797

17741798
/* first check if any Slaves fell off the bus */
@@ -1789,19 +1813,33 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
17891813
dev_warn(&slave->dev, "Slave %d state check1: UNATTACHED, status was %d\n",
17901814
i, slave->status);
17911815
sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
1816+
1817+
/* Ensure driver knows that peripheral unattached */
1818+
ret = sdw_update_slave_status(slave, status[i]);
1819+
if (ret < 0)
1820+
dev_warn(&slave->dev, "Update Slave status failed:%d\n", ret);
17921821
}
17931822
}
17941823

17951824
if (status[0] == SDW_SLAVE_ATTACHED) {
17961825
dev_dbg(bus->dev, "Slave attached, programming device number\n");
1797-
ret = sdw_program_device_num(bus);
1798-
if (ret < 0)
1799-
dev_err(bus->dev, "Slave attach failed: %d\n", ret);
1826+
18001827
/*
1801-
* programming a device number will have side effects,
1802-
* so we deal with other devices at a later time
1828+
* Programming a device number will have side effects,
1829+
* so we deal with other devices at a later time.
1830+
* This relies on those devices reporting ATTACHED, which will
1831+
* trigger another call to this function. This will only
1832+
* happen if at least one device ID was programmed.
1833+
* Error returns from sdw_program_device_num() are currently
1834+
* ignored because there's no useful recovery that can be done.
1835+
* Returning the error here could result in the current status
1836+
* of other devices not being handled, because if no device IDs
1837+
* were programmed there's nothing to guarantee a status change
1838+
* to trigger another call to this function.
18031839
*/
1804-
return ret;
1840+
sdw_program_device_num(bus, &id_programmed);
1841+
if (id_programmed)
1842+
return 0;
18051843
}
18061844

18071845
/* Continue to check other slave statuses */
@@ -1870,8 +1908,8 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
18701908
"Update Slave status failed:%d\n", ret);
18711909
if (attached_initializing) {
18721910
dev_dbg(&slave->dev,
1873-
"%s: signaling initialization completion for Slave %d\n",
1874-
__func__, slave->dev_num);
1911+
"signaling initialization completion for Slave %d\n",
1912+
slave->dev_num);
18751913

18761914
complete(&slave->initialization_complete);
18771915

0 commit comments

Comments
 (0)