summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/soundwire/bus.c69
1 files changed, 36 insertions, 33 deletions
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index dc4033b6f2e9..100d904bf700 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -829,11 +829,8 @@ static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
if (slave->ops && slave->ops->clk_stop) {
ret = slave->ops->clk_stop(slave, mode, type);
- if (ret < 0) {
- dev_err(&slave->dev,
- "Clk Stop type =%d failed: %d\n", type, ret);
+ if (ret < 0)
return ret;
- }
}
return 0;
@@ -860,7 +857,8 @@ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
} else {
ret = sdw_read_no_pm(slave, SDW_SCP_SYSTEMCTRL);
if (ret < 0) {
- dev_err(&slave->dev, "SDW_SCP_SYSTEMCTRL read failed:%d\n", ret);
+ if (ret != -ENODATA)
+ dev_err(&slave->dev, "SDW_SCP_SYSTEMCTRL read failed:%d\n", ret);
return ret;
}
val = ret;
@@ -869,9 +867,8 @@ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
ret = sdw_write_no_pm(slave, SDW_SCP_SYSTEMCTRL, val);
- if (ret < 0)
- dev_err(&slave->dev,
- "Clock Stop prepare failed for slave: %d", ret);
+ if (ret < 0 && ret != -ENODATA)
+ dev_err(&slave->dev, "SDW_SCP_SYSTEMCTRL write failed:%d\n", ret);
return ret;
}
@@ -922,6 +919,9 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
* In order to save on transition time, prepare
* each Slave and then wait for all Slave(s) to be
* prepared for clock stop.
+ * If one of the Slave devices has lost sync and
+ * replies with Command Ignored/-ENODATA, we continue
+ * the loop
*/
list_for_each_entry(slave, &bus->slaves, node) {
if (!slave->dev_num)
@@ -937,9 +937,8 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
ret = sdw_slave_clk_stop_callback(slave,
SDW_CLK_STOP_MODE0,
SDW_CLK_PRE_PREPARE);
- if (ret < 0) {
- dev_err(&slave->dev,
- "pre-prepare failed:%d", ret);
+ if (ret < 0 && ret != -ENODATA) {
+ dev_err(&slave->dev, "clock stop pre-prepare cb failed:%d\n", ret);
return ret;
}
@@ -950,9 +949,8 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
ret = sdw_slave_clk_stop_prepare(slave,
SDW_CLK_STOP_MODE0,
true);
- if (ret < 0) {
- dev_err(&slave->dev,
- "pre-prepare failed:%d", ret);
+ if (ret < 0 && ret != -ENODATA) {
+ dev_err(&slave->dev, "clock stop prepare failed:%d\n", ret);
return ret;
}
}
@@ -960,7 +958,7 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
/* Skip remaining clock stop preparation if no Slave is attached */
if (!is_slave)
- return ret;
+ return 0;
/*
* Don't wait for all Slaves to be ready if they follow the simple
@@ -969,6 +967,12 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
if (!simple_clk_stop) {
ret = sdw_bus_wait_for_clk_prep_deprep(bus,
SDW_BROADCAST_DEV_NUM);
+ /*
+ * if there are no Slave devices present and the reply is
+ * Command_Ignored/-ENODATA, we don't need to continue with the
+ * flow and can just return here. The error code is not modified
+ * and its handling left as an exercise for the caller.
+ */
if (ret < 0)
return ret;
}
@@ -986,13 +990,13 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
SDW_CLK_STOP_MODE0,
SDW_CLK_POST_PREPARE);
- if (ret < 0) {
- dev_err(&slave->dev,
- "post-prepare failed:%d", ret);
+ if (ret < 0 && ret != -ENODATA) {
+ dev_err(&slave->dev, "clock stop post-prepare cb failed:%d\n", ret);
+ return ret;
}
}
- return ret;
+ return 0;
}
EXPORT_SYMBOL(sdw_bus_prep_clk_stop);
@@ -1015,12 +1019,8 @@ int sdw_bus_clk_stop(struct sdw_bus *bus)
ret = sdw_bwrite_no_pm(bus, SDW_BROADCAST_DEV_NUM,
SDW_SCP_CTRL, SDW_SCP_CTRL_CLK_STP_NOW);
if (ret < 0) {
- if (ret == -ENODATA)
- dev_dbg(bus->dev,
- "ClockStopNow Broadcast msg ignored %d", ret);
- else
- dev_err(bus->dev,
- "ClockStopNow Broadcast msg failed %d", ret);
+ if (ret != -ENODATA)
+ dev_err(bus->dev, "ClockStopNow Broadcast msg failed %d\n", ret);
return ret;
}
@@ -1063,8 +1063,7 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_STOP_MODE0,
SDW_CLK_PRE_DEPREPARE);
if (ret < 0)
- dev_warn(&slave->dev,
- "clk stop deprep failed:%d", ret);
+ dev_warn(&slave->dev, "clock stop pre-deprepare cb failed:%d\n", ret);
/* Only de-prepare a Slave device if needed */
if (!slave->prop.simple_clk_stop_capable) {
@@ -1074,8 +1073,7 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
false);
if (ret < 0)
- dev_warn(&slave->dev,
- "clk stop deprep failed:%d", ret);
+ dev_warn(&slave->dev, "clock stop deprepare failed:%d\n", ret);
}
}
@@ -1087,8 +1085,11 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
* Don't wait for all Slaves to be ready if they follow the simple
* state machine
*/
- if (!simple_clk_stop)
- sdw_bus_wait_for_clk_prep_deprep(bus, SDW_BROADCAST_DEV_NUM);
+ if (!simple_clk_stop) {
+ ret = sdw_bus_wait_for_clk_prep_deprep(bus, SDW_BROADCAST_DEV_NUM);
+ if (ret < 0)
+ dev_warn(&slave->dev, "clock stop deprepare wait failed:%d\n", ret);
+ }
list_for_each_entry(slave, &bus->slaves, node) {
if (!slave->dev_num)
@@ -1098,8 +1099,10 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
slave->status != SDW_SLAVE_ALERT)
continue;
- sdw_slave_clk_stop_callback(slave, SDW_CLK_STOP_MODE0,
- SDW_CLK_POST_DEPREPARE);
+ ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_STOP_MODE0,
+ SDW_CLK_POST_DEPREPARE);
+ if (ret < 0)
+ dev_warn(&slave->dev, "clock stop post-deprepare cb failed:%d\n", ret);
}
return 0;