soundwire: bus: only use CLOCK_STOP_MODE0 and fix confusions
Existing devices and implementations only support the required CLOCK_STOP_MODE0. All the code related to CLOCK_STOP_MODE1 has not been tested and is highly questionable, with a clear confusion between CLOCK_STOP_MODE1 and the simple clock stop state machine. This patch removes all usages of CLOCK_STOP_MODE1 - which has no impact on any solution - and fixes the use of the simple clock stop state machine. The resulting code should be a lot more symmetrical and easier to maintain. Note that CLOCK_STOP_MODE1 is not supported in the SoundWire Device Class specification so it's rather unlikely that we need to re-add this mode later. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> Reviewed-by: Rander Wang <rander.wang@intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://lore.kernel.org/r/20210511030048.25622-2-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
0531e6b605
commit
345e9f5ca7
|
@ -821,26 +821,6 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
|
|||
mutex_unlock(&bus->bus_lock);
|
||||
}
|
||||
|
||||
static enum sdw_clk_stop_mode sdw_get_clk_stop_mode(struct sdw_slave *slave)
|
||||
{
|
||||
enum sdw_clk_stop_mode mode;
|
||||
|
||||
/*
|
||||
* Query for clock stop mode if Slave implements
|
||||
* ops->get_clk_stop_mode, else read from property.
|
||||
*/
|
||||
if (slave->ops && slave->ops->get_clk_stop_mode) {
|
||||
mode = slave->ops->get_clk_stop_mode(slave);
|
||||
} else {
|
||||
if (slave->prop.clk_stop_mode1)
|
||||
mode = SDW_CLK_STOP_MODE1;
|
||||
else
|
||||
mode = SDW_CLK_STOP_MODE0;
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
|
||||
enum sdw_clk_stop_mode mode,
|
||||
enum sdw_clk_stop_type type)
|
||||
|
@ -933,7 +913,6 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
|
|||
*/
|
||||
int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
|
||||
{
|
||||
enum sdw_clk_stop_mode slave_mode;
|
||||
bool simple_clk_stop = true;
|
||||
struct sdw_slave *slave;
|
||||
bool is_slave = false;
|
||||
|
@ -955,10 +934,8 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
|
|||
/* Identify if Slave(s) are available on Bus */
|
||||
is_slave = true;
|
||||
|
||||
slave_mode = sdw_get_clk_stop_mode(slave);
|
||||
slave->curr_clk_stop_mode = slave_mode;
|
||||
|
||||
ret = sdw_slave_clk_stop_callback(slave, slave_mode,
|
||||
ret = sdw_slave_clk_stop_callback(slave,
|
||||
SDW_CLK_STOP_MODE0,
|
||||
SDW_CLK_PRE_PREPARE);
|
||||
if (ret < 0) {
|
||||
dev_err(&slave->dev,
|
||||
|
@ -966,22 +943,29 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = sdw_slave_clk_stop_prepare(slave,
|
||||
slave_mode, true);
|
||||
if (ret < 0) {
|
||||
dev_err(&slave->dev,
|
||||
"pre-prepare failed:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (slave_mode == SDW_CLK_STOP_MODE1)
|
||||
/* 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) {
|
||||
dev_err(&slave->dev,
|
||||
"pre-prepare failed:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip remaining clock stop preparation if no Slave is attached */
|
||||
if (!is_slave)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
@ -998,17 +982,13 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
|
|||
slave->status != SDW_SLAVE_ALERT)
|
||||
continue;
|
||||
|
||||
slave_mode = slave->curr_clk_stop_mode;
|
||||
ret = sdw_slave_clk_stop_callback(slave,
|
||||
SDW_CLK_STOP_MODE0,
|
||||
SDW_CLK_POST_PREPARE);
|
||||
|
||||
if (slave_mode == SDW_CLK_STOP_MODE1) {
|
||||
ret = sdw_slave_clk_stop_callback(slave,
|
||||
slave_mode,
|
||||
SDW_CLK_POST_PREPARE);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(&slave->dev,
|
||||
"post-prepare failed:%d", ret);
|
||||
}
|
||||
if (ret < 0) {
|
||||
dev_err(&slave->dev,
|
||||
"post-prepare failed:%d", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1059,7 +1039,6 @@ EXPORT_SYMBOL(sdw_bus_clk_stop);
|
|||
*/
|
||||
int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
|
||||
{
|
||||
enum sdw_clk_stop_mode mode;
|
||||
bool simple_clk_stop = true;
|
||||
struct sdw_slave *slave;
|
||||
bool is_slave = false;
|
||||
|
@ -1081,31 +1060,33 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
|
|||
/* Identify if Slave(s) are available on Bus */
|
||||
is_slave = true;
|
||||
|
||||
mode = slave->curr_clk_stop_mode;
|
||||
|
||||
if (mode == SDW_CLK_STOP_MODE1) {
|
||||
simple_clk_stop = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = sdw_slave_clk_stop_callback(slave, mode,
|
||||
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);
|
||||
|
||||
ret = sdw_slave_clk_stop_prepare(slave, mode,
|
||||
false);
|
||||
/* Only de-prepare a Slave device if needed */
|
||||
if (!slave->prop.simple_clk_stop_capable) {
|
||||
simple_clk_stop = false;
|
||||
|
||||
if (ret < 0)
|
||||
dev_warn(&slave->dev,
|
||||
"clk stop deprep failed:%d", ret);
|
||||
ret = sdw_slave_clk_stop_prepare(slave, SDW_CLK_STOP_MODE0,
|
||||
false);
|
||||
|
||||
if (ret < 0)
|
||||
dev_warn(&slave->dev,
|
||||
"clk stop deprep failed:%d", ret);
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip remaining clock stop de-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)
|
||||
sdw_bus_wait_for_clk_prep_deprep(bus, SDW_BROADCAST_DEV_NUM);
|
||||
|
||||
|
@ -1117,8 +1098,7 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
|
|||
slave->status != SDW_SLAVE_ALERT)
|
||||
continue;
|
||||
|
||||
mode = slave->curr_clk_stop_mode;
|
||||
sdw_slave_clk_stop_callback(slave, mode,
|
||||
sdw_slave_clk_stop_callback(slave, SDW_CLK_STOP_MODE0,
|
||||
SDW_CLK_POST_DEPREPARE);
|
||||
}
|
||||
|
||||
|
|
|
@ -624,7 +624,6 @@ struct sdw_slave_ops {
|
|||
int (*port_prep)(struct sdw_slave *slave,
|
||||
struct sdw_prepare_ch *prepare_ch,
|
||||
enum sdw_port_prep_ops pre_ops);
|
||||
int (*get_clk_stop_mode)(struct sdw_slave *slave);
|
||||
int (*clk_stop)(struct sdw_slave *slave,
|
||||
enum sdw_clk_stop_mode mode,
|
||||
enum sdw_clk_stop_type type);
|
||||
|
@ -675,7 +674,6 @@ struct sdw_slave {
|
|||
struct list_head node;
|
||||
struct completion port_ready[SDW_MAX_PORTS];
|
||||
unsigned int m_port_map[SDW_MAX_PORTS];
|
||||
enum sdw_clk_stop_mode curr_clk_stop_mode;
|
||||
u16 dev_num;
|
||||
u16 dev_num_sticky;
|
||||
bool probed;
|
||||
|
|
Loading…
Reference in New Issue