in bus.c [933:1022]
int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
{
bool simple_clk_stop = true;
struct sdw_slave *slave;
bool is_slave = false;
int ret = 0;
/*
* 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)
continue;
if (slave->status != SDW_SLAVE_ATTACHED &&
slave->status != SDW_SLAVE_ALERT)
continue;
/* Identify if Slave(s) are available on Bus */
is_slave = true;
ret = sdw_slave_clk_stop_callback(slave,
SDW_CLK_STOP_MODE0,
SDW_CLK_PRE_PREPARE);
if (ret < 0 && ret != -ENODATA) {
dev_err(&slave->dev, "clock stop pre-prepare cb failed:%d\n", ret);
return ret;
}
/* Only prepare a Slave device if needed */
if (!slave->prop.simple_clk_stop_capable) {
simple_clk_stop = false;
ret = sdw_slave_clk_stop_prepare(slave,
SDW_CLK_STOP_MODE0,
true);
if (ret < 0 && ret != -ENODATA) {
dev_err(&slave->dev, "clock stop prepare failed:%d\n", ret);
return ret;
}
}
}
/* Skip remaining clock stop preparation if no Slave is attached */
if (!is_slave)
return 0;
/*
* Don't wait for all Slaves to be ready if they follow the simple
* state machine
*/
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;
}
/* Inform slaves that prep is done */
list_for_each_entry(slave, &bus->slaves, node) {
if (!slave->dev_num)
continue;
if (slave->status != SDW_SLAVE_ATTACHED &&
slave->status != SDW_SLAVE_ALERT)
continue;
ret = sdw_slave_clk_stop_callback(slave,
SDW_CLK_STOP_MODE0,
SDW_CLK_POST_PREPARE);
if (ret < 0 && ret != -ENODATA) {
dev_err(&slave->dev, "clock stop post-prepare cb failed:%d\n", ret);
return ret;
}
}
return 0;
}