@@ -947,6 +947,8 @@ static int cs35l45_enter_hibernate(struct cs35l45_private *cs35l45)
947947
948948 cs35l45_setup_hibernate (cs35l45 );
949949
950+ regmap_set_bits (cs35l45 -> regmap , CS35L45_IRQ1_MASK_2 , CS35L45_DSP_VIRT2_MBOX_MASK );
951+
950952 // Don't wait for ACK since bus activity would wake the device
951953 regmap_write (cs35l45 -> regmap , CS35L45_DSP_VIRT1_MBOX_1 , CSPL_MBOX_CMD_HIBERNATE );
952954
@@ -967,6 +969,8 @@ static int cs35l45_exit_hibernate(struct cs35l45_private *cs35l45)
967969 CSPL_MBOX_CMD_OUT_OF_HIBERNATE );
968970 if (!ret ) {
969971 dev_dbg (cs35l45 -> dev , "Wake success at cycle: %d\n" , j );
972+ regmap_clear_bits (cs35l45 -> regmap , CS35L45_IRQ1_MASK_2 ,
973+ CS35L45_DSP_VIRT2_MBOX_MASK );
970974 return 0 ;
971975 }
972976 usleep_range (100 , 200 );
@@ -982,7 +986,7 @@ static int cs35l45_exit_hibernate(struct cs35l45_private *cs35l45)
982986 return - ETIMEDOUT ;
983987}
984988
985- static int __maybe_unused cs35l45_runtime_suspend (struct device * dev )
989+ static int cs35l45_runtime_suspend (struct device * dev )
986990{
987991 struct cs35l45_private * cs35l45 = dev_get_drvdata (dev );
988992
@@ -999,7 +1003,7 @@ static int __maybe_unused cs35l45_runtime_suspend(struct device *dev)
9991003 return 0 ;
10001004}
10011005
1002- static int __maybe_unused cs35l45_runtime_resume (struct device * dev )
1006+ static int cs35l45_runtime_resume (struct device * dev )
10031007{
10041008 struct cs35l45_private * cs35l45 = dev_get_drvdata (dev );
10051009 int ret ;
@@ -1026,6 +1030,46 @@ static int __maybe_unused cs35l45_runtime_resume(struct device *dev)
10261030 return ret ;
10271031}
10281032
1033+ static int cs35l45_sys_suspend (struct device * dev )
1034+ {
1035+ struct cs35l45_private * cs35l45 = dev_get_drvdata (dev );
1036+
1037+ dev_dbg (cs35l45 -> dev , "System suspend, disabling IRQ\n" );
1038+ disable_irq (cs35l45 -> irq );
1039+
1040+ return 0 ;
1041+ }
1042+
1043+ static int cs35l45_sys_suspend_noirq (struct device * dev )
1044+ {
1045+ struct cs35l45_private * cs35l45 = dev_get_drvdata (dev );
1046+
1047+ dev_dbg (cs35l45 -> dev , "Late system suspend, reenabling IRQ\n" );
1048+ enable_irq (cs35l45 -> irq );
1049+
1050+ return 0 ;
1051+ }
1052+
1053+ static int cs35l45_sys_resume_noirq (struct device * dev )
1054+ {
1055+ struct cs35l45_private * cs35l45 = dev_get_drvdata (dev );
1056+
1057+ dev_dbg (cs35l45 -> dev , "Early system resume, disabling IRQ\n" );
1058+ disable_irq (cs35l45 -> irq );
1059+
1060+ return 0 ;
1061+ }
1062+
1063+ static int cs35l45_sys_resume (struct device * dev )
1064+ {
1065+ struct cs35l45_private * cs35l45 = dev_get_drvdata (dev );
1066+
1067+ dev_dbg (cs35l45 -> dev , "System resume, reenabling IRQ\n" );
1068+ enable_irq (cs35l45 -> irq );
1069+
1070+ return 0 ;
1071+ }
1072+
10291073static int cs35l45_apply_property_config (struct cs35l45_private * cs35l45 )
10301074{
10311075 struct device_node * node = cs35l45 -> dev -> of_node ;
@@ -1466,10 +1510,12 @@ void cs35l45_remove(struct cs35l45_private *cs35l45)
14661510}
14671511EXPORT_SYMBOL_NS_GPL (cs35l45_remove , SND_SOC_CS35L45 );
14681512
1469- const struct dev_pm_ops cs35l45_pm_ops = {
1470- SET_RUNTIME_PM_OPS (cs35l45_runtime_suspend , cs35l45_runtime_resume , NULL )
1513+ EXPORT_GPL_DEV_PM_OPS (cs35l45_pm_ops ) = {
1514+ RUNTIME_PM_OPS (cs35l45_runtime_suspend , cs35l45_runtime_resume , NULL )
1515+
1516+ SYSTEM_SLEEP_PM_OPS (cs35l45_sys_suspend , cs35l45_sys_resume )
1517+ NOIRQ_SYSTEM_SLEEP_PM_OPS (cs35l45_sys_suspend_noirq , cs35l45_sys_resume_noirq )
14711518};
1472- EXPORT_SYMBOL_NS_GPL (cs35l45_pm_ops , SND_SOC_CS35L45 );
14731519
14741520MODULE_DESCRIPTION ("ASoC CS35L45 driver" );
14751521MODULE_AUTHOR ("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>" );
0 commit comments