soundwire: bus: only use CLOCK_STOP_MODE0 and fix confusions
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Tue, 11 May 2021 03:00:45 +0000 (11:00 +0800)
committerVinod Koul <vkoul@kernel.org>
Tue, 11 May 2021 12:20:32 +0000 (17:50 +0530)
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>
drivers/soundwire/bus.c
include/linux/soundwire/sdw.h

index a9e0aa72654dd8a940c0d4e8773920405843ab0a..dc4033b6f2e9fdb0f278c26679ed0b6e16bb254f 100644 (file)
@@ -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);
        }
 
index ced07f8fde8701fddbd814b10d8e5eb645744a77..5d93d9949653828a1855435d8b071c2c4193856d 100644 (file)
@@ -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;