@@ -394,13 +394,13 @@ sdw_nread_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
394394}
395395
396396static int
397- sdw_nwrite_no_pm (struct sdw_slave * slave , u32 addr , size_t count , u8 * val )
397+ sdw_nwrite_no_pm (struct sdw_slave * slave , u32 addr , size_t count , const u8 * val )
398398{
399399 struct sdw_msg msg ;
400400 int ret ;
401401
402402 ret = sdw_fill_msg (& msg , slave , addr , count ,
403- slave -> dev_num , SDW_MSG_FLAG_WRITE , val );
403+ slave -> dev_num , SDW_MSG_FLAG_WRITE , ( u8 * ) val );
404404 if (ret < 0 )
405405 return ret ;
406406
@@ -550,9 +550,9 @@ EXPORT_SYMBOL(sdw_nread);
550550 * @slave: SDW Slave
551551 * @addr: Register address
552552 * @count: length
553- * @val: Buffer for values to be read
553+ * @val: Buffer for values to be written
554554 */
555- int sdw_nwrite (struct sdw_slave * slave , u32 addr , size_t count , u8 * val )
555+ int sdw_nwrite (struct sdw_slave * slave , u32 addr , size_t count , const u8 * val )
556556{
557557 int ret ;
558558
@@ -836,26 +836,6 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
836836 mutex_unlock (& bus -> bus_lock );
837837}
838838
839- static enum sdw_clk_stop_mode sdw_get_clk_stop_mode (struct sdw_slave * slave )
840- {
841- enum sdw_clk_stop_mode mode ;
842-
843- /*
844- * Query for clock stop mode if Slave implements
845- * ops->get_clk_stop_mode, else read from property.
846- */
847- if (slave -> ops && slave -> ops -> get_clk_stop_mode ) {
848- mode = slave -> ops -> get_clk_stop_mode (slave );
849- } else {
850- if (slave -> prop .clk_stop_mode1 )
851- mode = SDW_CLK_STOP_MODE1 ;
852- else
853- mode = SDW_CLK_STOP_MODE0 ;
854- }
855-
856- return mode ;
857- }
858-
859839static int sdw_slave_clk_stop_callback (struct sdw_slave * slave ,
860840 enum sdw_clk_stop_mode mode ,
861841 enum sdw_clk_stop_type type )
@@ -864,11 +844,8 @@ static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
864844
865845 if (slave -> ops && slave -> ops -> clk_stop ) {
866846 ret = slave -> ops -> clk_stop (slave , mode , type );
867- if (ret < 0 ) {
868- dev_err (& slave -> dev ,
869- "Clk Stop type =%d failed: %d\n" , type , ret );
847+ if (ret < 0 )
870848 return ret ;
871- }
872849 }
873850
874851 return 0 ;
@@ -895,7 +872,8 @@ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
895872 } else {
896873 ret = sdw_read_no_pm (slave , SDW_SCP_SYSTEMCTRL );
897874 if (ret < 0 ) {
898- dev_err (& slave -> dev , "SDW_SCP_SYSTEMCTRL read failed:%d\n" , ret );
875+ if (ret != - ENODATA )
876+ dev_err (& slave -> dev , "SDW_SCP_SYSTEMCTRL read failed:%d\n" , ret );
899877 return ret ;
900878 }
901879 val = ret ;
@@ -904,9 +882,8 @@ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
904882
905883 ret = sdw_write_no_pm (slave , SDW_SCP_SYSTEMCTRL , val );
906884
907- if (ret < 0 )
908- dev_err (& slave -> dev ,
909- "Clock Stop prepare failed for slave: %d" , ret );
885+ if (ret < 0 && ret != - ENODATA )
886+ dev_err (& slave -> dev , "SDW_SCP_SYSTEMCTRL write failed:%d\n" , ret );
910887
911888 return ret ;
912889}
@@ -924,7 +901,7 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
924901 }
925902 val &= SDW_SCP_STAT_CLK_STP_NF ;
926903 if (!val ) {
927- dev_dbg (bus -> dev , "clock stop prep/de-prep done slave:%d" ,
904+ dev_dbg (bus -> dev , "clock stop prep/de-prep done slave:%d\n " ,
928905 dev_num );
929906 return 0 ;
930907 }
@@ -933,7 +910,7 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
933910 retry -- ;
934911 } while (retry );
935912
936- dev_err (bus -> dev , "clock stop prep/de-prep failed slave:%d" ,
913+ dev_err (bus -> dev , "clock stop prep/de-prep failed slave:%d\n " ,
937914 dev_num );
938915
939916 return - ETIMEDOUT ;
@@ -948,7 +925,6 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
948925 */
949926int sdw_bus_prep_clk_stop (struct sdw_bus * bus )
950927{
951- enum sdw_clk_stop_mode slave_mode ;
952928 bool simple_clk_stop = true;
953929 struct sdw_slave * slave ;
954930 bool is_slave = false;
@@ -958,6 +934,9 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
958934 * In order to save on transition time, prepare
959935 * each Slave and then wait for all Slave(s) to be
960936 * prepared for clock stop.
937+ * If one of the Slave devices has lost sync and
938+ * replies with Command Ignored/-ENODATA, we continue
939+ * the loop
961940 */
962941 list_for_each_entry (slave , & bus -> slaves , node ) {
963942 if (!slave -> dev_num )
@@ -970,36 +949,45 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
970949 /* Identify if Slave(s) are available on Bus */
971950 is_slave = true;
972951
973- slave_mode = sdw_get_clk_stop_mode (slave );
974- slave -> curr_clk_stop_mode = slave_mode ;
975-
976- ret = sdw_slave_clk_stop_callback (slave , slave_mode ,
952+ ret = sdw_slave_clk_stop_callback (slave ,
953+ SDW_CLK_STOP_MODE0 ,
977954 SDW_CLK_PRE_PREPARE );
978- if (ret < 0 ) {
979- dev_err (& slave -> dev ,
980- "pre-prepare failed:%d" , ret );
981- return ret ;
982- }
983-
984- ret = sdw_slave_clk_stop_prepare (slave ,
985- slave_mode , true);
986- if (ret < 0 ) {
987- dev_err (& slave -> dev ,
988- "pre-prepare failed:%d" , ret );
955+ if (ret < 0 && ret != - ENODATA ) {
956+ dev_err (& slave -> dev , "clock stop pre-prepare cb failed:%d\n" , ret );
989957 return ret ;
990958 }
991959
992- if (slave_mode == SDW_CLK_STOP_MODE1 )
960+ /* Only prepare a Slave device if needed */
961+ if (!slave -> prop .simple_clk_stop_capable ) {
993962 simple_clk_stop = false;
963+
964+ ret = sdw_slave_clk_stop_prepare (slave ,
965+ SDW_CLK_STOP_MODE0 ,
966+ true);
967+ if (ret < 0 && ret != - ENODATA ) {
968+ dev_err (& slave -> dev , "clock stop prepare failed:%d\n" , ret );
969+ return ret ;
970+ }
971+ }
994972 }
995973
996974 /* Skip remaining clock stop preparation if no Slave is attached */
997975 if (!is_slave )
998- return ret ;
976+ return 0 ;
999977
978+ /*
979+ * Don't wait for all Slaves to be ready if they follow the simple
980+ * state machine
981+ */
1000982 if (!simple_clk_stop ) {
1001983 ret = sdw_bus_wait_for_clk_prep_deprep (bus ,
1002984 SDW_BROADCAST_DEV_NUM );
985+ /*
986+ * if there are no Slave devices present and the reply is
987+ * Command_Ignored/-ENODATA, we don't need to continue with the
988+ * flow and can just return here. The error code is not modified
989+ * and its handling left as an exercise for the caller.
990+ */
1003991 if (ret < 0 )
1004992 return ret ;
1005993 }
@@ -1013,21 +1001,17 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
10131001 slave -> status != SDW_SLAVE_ALERT )
10141002 continue ;
10151003
1016- slave_mode = slave -> curr_clk_stop_mode ;
1017-
1018- if (slave_mode == SDW_CLK_STOP_MODE1 ) {
1019- ret = sdw_slave_clk_stop_callback (slave ,
1020- slave_mode ,
1021- SDW_CLK_POST_PREPARE );
1004+ ret = sdw_slave_clk_stop_callback (slave ,
1005+ SDW_CLK_STOP_MODE0 ,
1006+ SDW_CLK_POST_PREPARE );
10221007
1023- if (ret < 0 ) {
1024- dev_err (& slave -> dev ,
1025- "post-prepare failed:%d" , ret );
1026- }
1008+ if (ret < 0 && ret != - ENODATA ) {
1009+ dev_err (& slave -> dev , "clock stop post-prepare cb failed:%d\n" , ret );
1010+ return ret ;
10271011 }
10281012 }
10291013
1030- return ret ;
1014+ return 0 ;
10311015}
10321016EXPORT_SYMBOL (sdw_bus_prep_clk_stop );
10331017
@@ -1050,12 +1034,8 @@ int sdw_bus_clk_stop(struct sdw_bus *bus)
10501034 ret = sdw_bwrite_no_pm (bus , SDW_BROADCAST_DEV_NUM ,
10511035 SDW_SCP_CTRL , SDW_SCP_CTRL_CLK_STP_NOW );
10521036 if (ret < 0 ) {
1053- if (ret == - ENODATA )
1054- dev_dbg (bus -> dev ,
1055- "ClockStopNow Broadcast msg ignored %d" , ret );
1056- else
1057- dev_err (bus -> dev ,
1058- "ClockStopNow Broadcast msg failed %d" , ret );
1037+ if (ret != - ENODATA )
1038+ dev_err (bus -> dev , "ClockStopNow Broadcast msg failed %d\n" , ret );
10591039 return ret ;
10601040 }
10611041
@@ -1074,7 +1054,6 @@ EXPORT_SYMBOL(sdw_bus_clk_stop);
10741054 */
10751055int sdw_bus_exit_clk_stop (struct sdw_bus * bus )
10761056{
1077- enum sdw_clk_stop_mode mode ;
10781057 bool simple_clk_stop = true;
10791058 struct sdw_slave * slave ;
10801059 bool is_slave = false;
@@ -1096,33 +1075,36 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
10961075 /* Identify if Slave(s) are available on Bus */
10971076 is_slave = true;
10981077
1099- mode = slave -> curr_clk_stop_mode ;
1100-
1101- if (mode == SDW_CLK_STOP_MODE1 ) {
1102- simple_clk_stop = false;
1103- continue ;
1104- }
1105-
1106- ret = sdw_slave_clk_stop_callback (slave , mode ,
1078+ ret = sdw_slave_clk_stop_callback (slave , SDW_CLK_STOP_MODE0 ,
11071079 SDW_CLK_PRE_DEPREPARE );
11081080 if (ret < 0 )
1109- dev_warn (& slave -> dev ,
1110- "clk stop deprep failed:%d" , ret );
1081+ dev_warn (& slave -> dev , "clock stop pre-deprepare cb failed:%d\n" , ret );
11111082
1112- ret = sdw_slave_clk_stop_prepare (slave , mode ,
1113- false);
1083+ /* Only de-prepare a Slave device if needed */
1084+ if (!slave -> prop .simple_clk_stop_capable ) {
1085+ simple_clk_stop = false;
11141086
1115- if (ret < 0 )
1116- dev_warn (& slave -> dev ,
1117- "clk stop deprep failed:%d" , ret );
1087+ ret = sdw_slave_clk_stop_prepare (slave , SDW_CLK_STOP_MODE0 ,
1088+ false);
1089+
1090+ if (ret < 0 )
1091+ dev_warn (& slave -> dev , "clock stop deprepare failed:%d\n" , ret );
1092+ }
11181093 }
11191094
11201095 /* Skip remaining clock stop de-preparation if no Slave is attached */
11211096 if (!is_slave )
11221097 return 0 ;
11231098
1124- if (!simple_clk_stop )
1125- sdw_bus_wait_for_clk_prep_deprep (bus , SDW_BROADCAST_DEV_NUM );
1099+ /*
1100+ * Don't wait for all Slaves to be ready if they follow the simple
1101+ * state machine
1102+ */
1103+ if (!simple_clk_stop ) {
1104+ ret = sdw_bus_wait_for_clk_prep_deprep (bus , SDW_BROADCAST_DEV_NUM );
1105+ if (ret < 0 )
1106+ dev_warn (& slave -> dev , "clock stop deprepare wait failed:%d\n" , ret );
1107+ }
11261108
11271109 list_for_each_entry (slave , & bus -> slaves , node ) {
11281110 if (!slave -> dev_num )
@@ -1132,9 +1114,10 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
11321114 slave -> status != SDW_SLAVE_ALERT )
11331115 continue ;
11341116
1135- mode = slave -> curr_clk_stop_mode ;
1136- sdw_slave_clk_stop_callback (slave , mode ,
1137- SDW_CLK_POST_DEPREPARE );
1117+ ret = sdw_slave_clk_stop_callback (slave , SDW_CLK_STOP_MODE0 ,
1118+ SDW_CLK_POST_DEPREPARE );
1119+ if (ret < 0 )
1120+ dev_warn (& slave -> dev , "clock stop post-deprepare cb failed:%d\n" , ret );
11381121 }
11391122
11401123 return 0 ;
0 commit comments