@@ -515,6 +515,7 @@ void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root)
515515
516516 debugfs_create_bool ("booted" , 0444 , root , & dsp -> booted );
517517 debugfs_create_bool ("running" , 0444 , root , & dsp -> running );
518+ debugfs_create_bool ("hibernating" , 0444 , root , & dsp -> hibernating );
518519 debugfs_create_x32 ("fw_id" , 0444 , root , & dsp -> fw_id );
519520 debugfs_create_x32 ("fw_version" , 0444 , root , & dsp -> fw_id_version );
520521
@@ -703,7 +704,7 @@ int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int
703704
704705 lockdep_assert_held (& dsp -> pwr_lock );
705706
706- if (!dsp -> running )
707+ if (!dsp -> running || dsp -> hibernating )
707708 return - EPERM ;
708709
709710 ret = cs_dsp_coeff_base_reg (ctl , & reg , 0 );
@@ -827,7 +828,7 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl,
827828 }
828829
829830 ctl -> set = 1 ;
830- if (ctl -> enabled && ctl -> dsp -> running )
831+ if (ctl -> enabled && ctl -> dsp -> running && ! ctl -> dsp -> hibernating )
831832 ret = cs_dsp_coeff_write_ctrl_raw (ctl , off , buf , len );
832833
833834 if (ret < 0 )
@@ -920,12 +921,12 @@ int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl,
920921 return - EINVAL ;
921922
922923 if (ctl -> flags & WMFW_CTL_FLAG_VOLATILE ) {
923- if (ctl -> enabled && ctl -> dsp -> running )
924+ if (ctl -> enabled && ctl -> dsp -> running && ! ctl -> dsp -> hibernating )
924925 return cs_dsp_coeff_read_ctrl_raw (ctl , off , buf , len );
925926 else
926927 return - EPERM ;
927928 } else {
928- if (!ctl -> flags && ctl -> enabled && ctl -> dsp -> running )
929+ if (!ctl -> flags && ctl -> enabled && ctl -> dsp -> running && ! ctl -> dsp -> hibernating )
929930 ret = cs_dsp_coeff_read_ctrl_raw (ctl , 0 , ctl -> cache , ctl -> len );
930931
931932 if (buf != ctl -> cache )
@@ -1108,6 +1109,44 @@ static int cs_dsp_create_control(struct cs_dsp *dsp,
11081109 return ret ;
11091110}
11101111
1112+
1113+ /**
1114+ * cs_dsp_hibernate() - Disable or enable all controls for a DSP
1115+ * @dsp: pointer to DSP structure
1116+ * @hibernate: whether to set controls to cache only mode
1117+ *
1118+ * When @hibernate is true, the DSP is entering hibernation mode where the
1119+ * regmap is inaccessible, and all controls become cache only.
1120+ * When @hibernate is false, the DSP has exited hibernation mode. If the DSP
1121+ * is running, all controls are re-synced to the DSP.
1122+ *
1123+ */
1124+ void cs_dsp_hibernate (struct cs_dsp * dsp , bool hibernate )
1125+ {
1126+ mutex_lock (& dsp -> pwr_lock );
1127+
1128+ if (!dsp -> running ) {
1129+ cs_dsp_dbg (dsp , "Cannot hibernate, DSP not running\n" );
1130+ goto out ;
1131+ }
1132+
1133+ if (dsp -> hibernating == hibernate )
1134+ goto out ;
1135+
1136+ cs_dsp_dbg (dsp , "Set hibernating to %d\n" , hibernate );
1137+ dsp -> hibernating = hibernate ;
1138+
1139+ if (!dsp -> hibernating && dsp -> running ) {
1140+ int ret = cs_dsp_coeff_sync_controls (dsp );
1141+
1142+ if (ret )
1143+ cs_dsp_err (dsp , "Error syncing controls: %d\n" , ret );
1144+ }
1145+ out :
1146+ mutex_unlock (& dsp -> pwr_lock );
1147+ }
1148+ EXPORT_SYMBOL_NS_GPL (cs_dsp_hibernate , "FW_CS_DSP" );
1149+
11111150struct cs_dsp_coeff_parsed_alg {
11121151 int id ;
11131152 const u8 * name ;
@@ -2498,6 +2537,7 @@ int cs_dsp_adsp1_power_up(struct cs_dsp *dsp,
24982537 goto err_ena ;
24992538
25002539 dsp -> booted = true;
2540+ dsp -> hibernating = false;
25012541
25022542 /* Start the core running */
25032543 regmap_update_bits (dsp -> regmap , dsp -> base + ADSP1_CONTROL_30 ,
@@ -2776,6 +2816,7 @@ int cs_dsp_power_up(struct cs_dsp *dsp,
27762816 dsp -> ops -> disable_core (dsp );
27772817
27782818 dsp -> booted = true;
2819+ dsp -> hibernating = false;
27792820
27802821 mutex_unlock (& dsp -> pwr_lock );
27812822
0 commit comments