lkml.org 
[lkml]   [2021]   [Jul]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.13 045/351] soundwire: bus: only use CLOCK_STOP_MODE0 and fix confusions
    Date
    From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

    [ Upstream commit 345e9f5ca798600e44c0843646621f2804eb99f4 ]

    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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/soundwire/bus.c | 100 ++++++++++++++--------------------
    include/linux/soundwire/sdw.h | 2 -
    2 files changed, 40 insertions(+), 62 deletions(-)

    diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
    index a9e0aa72654d..dc4033b6f2e9 100644
    --- a/drivers/soundwire/bus.c
    +++ b/drivers/soundwire/bus.c
    @@ -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;
    -
    - if (slave_mode == SDW_CLK_STOP_MODE1) {
    - ret = sdw_slave_clk_stop_callback(slave,
    - slave_mode,
    - SDW_CLK_POST_PREPARE);
    + ret = sdw_slave_clk_stop_callback(slave,
    + SDW_CLK_STOP_MODE0,
    + 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);
    }

    diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
    index ced07f8fde87..5d93d9949653 100644
    --- a/include/linux/soundwire/sdw.h
    +++ b/include/linux/soundwire/sdw.h
    @@ -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;
    --
    2.30.2


    \
     
     \ /
      Last update: 2021-07-19 19:23    [W:4.075 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site