@@ -956,6 +956,28 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
956956 mutex_unlock (& bus -> bus_lock );
957957}
958958
959+ static enum sdw_clk_stop_mode sdw_get_clk_stop_mode (struct sdw_slave * slave )
960+ {
961+ struct device * dev = & slave -> dev ;
962+ struct sdw_driver * drv = drv_to_sdw_driver (dev -> driver );
963+ enum sdw_clk_stop_mode mode ;
964+
965+ /*
966+ * Query for clock stop mode if Slave implements
967+ * ops->get_clk_stop_mode, else read from property.
968+ */
969+ if (drv -> ops && drv -> ops -> get_clk_stop_mode ) {
970+ mode = drv -> ops -> get_clk_stop_mode (slave );
971+ } else {
972+ if (slave -> prop .clk_stop_mode1 )
973+ mode = SDW_CLK_STOP_MODE1 ;
974+ else
975+ mode = SDW_CLK_STOP_MODE0 ;
976+ }
977+
978+ return mode ;
979+ }
980+
959981static int sdw_slave_clk_stop_callback (struct sdw_slave * slave ,
960982 enum sdw_clk_stop_mode mode ,
961983 enum sdw_clk_stop_type type )
@@ -1054,6 +1076,7 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num, bo
10541076 */
10551077int sdw_bus_prep_clk_stop (struct sdw_bus * bus )
10561078{
1079+ enum sdw_clk_stop_mode mode ;
10571080 bool simple_clk_stop = true;
10581081 struct sdw_slave * slave ;
10591082 bool is_slave = false;
@@ -1078,8 +1101,10 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
10781101 /* Identify if Slave(s) are available on Bus */
10791102 is_slave = true;
10801103
1081- ret = sdw_slave_clk_stop_callback (slave ,
1082- SDW_CLK_STOP_MODE0 ,
1104+ mode = sdw_get_clk_stop_mode (slave );
1105+ slave -> curr_clk_stop_mode = mode ;
1106+
1107+ ret = sdw_slave_clk_stop_callback (slave , mode ,
10831108 SDW_CLK_PRE_PREPARE );
10841109 if (ret < 0 && ret != - ENODATA ) {
10851110 dev_err (& slave -> dev , "clock stop pre-prepare cb failed:%d\n" , ret );
@@ -1091,8 +1116,7 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
10911116 simple_clk_stop = false;
10921117
10931118 ret = sdw_slave_clk_stop_prepare (slave ,
1094- SDW_CLK_STOP_MODE0 ,
1095- true);
1119+ mode , true);
10961120 if (ret < 0 && ret != - ENODATA ) {
10971121 dev_err (& slave -> dev , "clock stop prepare failed:%d\n" , ret );
10981122 return ret ;
@@ -1129,9 +1153,9 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
11291153 if (slave -> status != SDW_SLAVE_ATTACHED &&
11301154 slave -> status != SDW_SLAVE_ALERT )
11311155 continue ;
1156+ mode = slave -> curr_clk_stop_mode ;
11321157
1133- ret = sdw_slave_clk_stop_callback (slave ,
1134- SDW_CLK_STOP_MODE0 ,
1158+ ret = sdw_slave_clk_stop_callback (slave , mode ,
11351159 SDW_CLK_POST_PREPARE );
11361160
11371161 if (ret < 0 && ret != - ENODATA ) {
@@ -1183,6 +1207,7 @@ EXPORT_SYMBOL(sdw_bus_clk_stop);
11831207 */
11841208int sdw_bus_exit_clk_stop (struct sdw_bus * bus )
11851209{
1210+ enum sdw_clk_stop_mode mode ;
11861211 bool simple_clk_stop = true;
11871212 struct sdw_slave * slave ;
11881213 bool is_slave = false;
@@ -1204,18 +1229,20 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
12041229 /* Identify if Slave(s) are available on Bus */
12051230 is_slave = true;
12061231
1207- ret = sdw_slave_clk_stop_callback (slave , SDW_CLK_STOP_MODE0 ,
1232+ mode = slave -> curr_clk_stop_mode ;
1233+
1234+ ret = sdw_slave_clk_stop_callback (slave , mode ,
12081235 SDW_CLK_PRE_DEPREPARE );
12091236 if (ret < 0 )
12101237 dev_warn (& slave -> dev , "clock stop pre-deprepare cb failed:%d\n" , ret );
12111238
1239+
12121240 /* Only de-prepare a Slave device if needed */
12131241 if (!slave -> prop .simple_clk_stop_capable ) {
12141242 simple_clk_stop = false;
12151243
1216- ret = sdw_slave_clk_stop_prepare (slave , SDW_CLK_STOP_MODE0 ,
1244+ ret = sdw_slave_clk_stop_prepare (slave , mode ,
12171245 false);
1218-
12191246 if (ret < 0 )
12201247 dev_warn (& slave -> dev , "clock stop deprepare failed:%d\n" , ret );
12211248 }
@@ -1243,7 +1270,9 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
12431270 slave -> status != SDW_SLAVE_ALERT )
12441271 continue ;
12451272
1246- ret = sdw_slave_clk_stop_callback (slave , SDW_CLK_STOP_MODE0 ,
1273+ mode = slave -> curr_clk_stop_mode ;
1274+
1275+ ret = sdw_slave_clk_stop_callback (slave , mode ,
12471276 SDW_CLK_POST_DEPREPARE );
12481277 if (ret < 0 )
12491278 dev_warn (& slave -> dev , "clock stop post-deprepare cb failed:%d\n" , ret );
0 commit comments