summaryrefslogtreecommitdiff
path: root/drivers/soundwire
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/soundwire')
-rw-r--r--drivers/soundwire/bus.c28
-rw-r--r--drivers/soundwire/sysfs_slave_dpn.c1
2 files changed, 28 insertions, 1 deletions
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 8eaf31e76677..ffe4600fd95b 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -1424,6 +1424,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
int port_num, stat, ret, count = 0;
unsigned long port;
bool slave_notify = false;
+ u8 sdca_cascade = 0;
u8 buf, buf2[2], _buf, _buf2[2];
bool parity_check;
bool parity_quirk;
@@ -1453,6 +1454,16 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
goto io_err;
}
+ if (slave->prop.is_sdca) {
+ ret = sdw_read(slave, SDW_DP0_INT);
+ if (ret < 0) {
+ dev_err(slave->bus->dev,
+ "SDW_DP0_INT read failed:%d\n", ret);
+ goto io_err;
+ }
+ sdca_cascade = ret & SDW_DP0_SDCA_CASCADE;
+ }
+
do {
/*
* Check parity, bus clash and Slave (impl defined)
@@ -1489,6 +1500,10 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
clear |= SDW_SCP_INT1_IMPL_DEF;
}
+ /* the SDCA interrupts are cleared in the codec driver .interrupt_callback() */
+ if (sdca_cascade)
+ slave_notify = true;
+
/* Check port 0 - 3 interrupts */
port = buf & SDW_SCP_INT1_PORT0_3;
@@ -1526,6 +1541,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
/* Update the Slave driver */
if (slave_notify && slave->ops &&
slave->ops->interrupt_callback) {
+ slave_intr.sdca_cascade = sdca_cascade;
slave_intr.control_port = clear;
memcpy(slave_intr.port, &port_status,
sizeof(slave_intr.port));
@@ -1563,11 +1579,21 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
goto io_err;
}
+ if (slave->prop.is_sdca) {
+ ret = sdw_read(slave, SDW_DP0_INT);
+ if (ret < 0) {
+ dev_err(slave->bus->dev,
+ "SDW_DP0_INT read failed:%d\n", ret);
+ goto io_err;
+ }
+ sdca_cascade = ret & SDW_DP0_SDCA_CASCADE;
+ }
+
/* Make sure no interrupts are pending */
buf &= _buf;
buf2[0] &= _buf2[0];
buf2[1] &= _buf2[1];
- stat = buf || buf2[0] || buf2[1];
+ stat = buf || buf2[0] || buf2[1] || sdca_cascade;
/*
* Exit loop if Slave is continuously in ALERT state even
diff --git a/drivers/soundwire/sysfs_slave_dpn.c b/drivers/soundwire/sysfs_slave_dpn.c
index 05a721ea9830..c4b6543c09fd 100644
--- a/drivers/soundwire/sysfs_slave_dpn.c
+++ b/drivers/soundwire/sysfs_slave_dpn.c
@@ -37,6 +37,7 @@ static int field##_attribute_alloc(struct device *dev, \
return -ENOMEM; \
dpn_attr->N = N; \
dpn_attr->dir = dir; \
+ sysfs_attr_init(&dpn_attr->dev_attr.attr); \
dpn_attr->format_string = format_string; \
dpn_attr->dev_attr.attr.name = __stringify(field); \
dpn_attr->dev_attr.attr.mode = 0444; \