@@ -123,16 +123,25 @@ struct msi_wmi_platform_quirk {
123123 bool shift_mode ; /* Shift mode is supported */
124124 bool charge_threshold ; /* Charge threshold is supported */
125125 bool dual_fans ; /* For devices with two hwmon fans */
126+ bool restore_curves ; /* Restore factory curves on unload */
126127 int pl_min ; /* Minimum PLx value */
127128 int pl1_max ; /* Maximum PL1 value */
128129 int pl2_max ; /* Maximum PL2 value */
129130};
130131
132+ struct msi_wmi_platform_factory_curves {
133+ u8 cpu_fan_table [32 ];
134+ u8 gpu_fan_table [32 ];
135+ u8 cpu_temp_table [32 ];
136+ u8 gpu_temp_table [32 ];
137+ };
138+
131139struct msi_wmi_platform_data {
132140 struct wmi_device * wdev ;
133141 struct msi_wmi_platform_quirk * quirks ;
134142 struct mutex wmi_lock ; /* Necessary when calling WMI methods */
135143 struct device * ppdev ;
144+ struct msi_wmi_platform_factory_curves factory_curves ;
136145 struct acpi_battery_hook battery_hook ;
137146 struct device * fw_attrs_dev ;
138147 struct kset * fw_attrs_kset ;
@@ -219,6 +228,7 @@ static struct msi_wmi_platform_quirk quirk_gen1 = {
219228 .shift_mode = true,
220229 .charge_threshold = true,
221230 .dual_fans = true,
231+ .restore_curves = true,
222232 .pl_min = 8 ,
223233 .pl1_max = 43 ,
224234 .pl2_max = 45
@@ -227,6 +237,7 @@ static struct msi_wmi_platform_quirk quirk_gen2 = {
227237 .shift_mode = true,
228238 .charge_threshold = true,
229239 .dual_fans = true,
240+ .restore_curves = true,
230241 .pl_min = 8 ,
231242 .pl1_max = 30 ,
232243 .pl2_max = 37
@@ -507,6 +518,94 @@ static struct attribute *msi_wmi_platform_hwmon_attrs[] = {
507518};
508519ATTRIBUTE_GROUPS (msi_wmi_platform_hwmon );
509520
521+ static int msi_wmi_platform_curves_save (struct msi_wmi_platform_data * data )
522+ {
523+ int ret ;
524+
525+ data -> factory_curves .cpu_fan_table [0 ] =
526+ MSI_PLATFORM_FAN_SUBFEATURE_CPU_FAN_TABLE ;
527+ ret = msi_wmi_platform_query_unlocked (
528+ data , MSI_PLATFORM_GET_FAN ,
529+ data -> factory_curves .cpu_fan_table ,
530+ sizeof (data -> factory_curves .cpu_fan_table ));
531+ if (ret < 0 )
532+ return ret ;
533+ data -> factory_curves .cpu_fan_table [0 ] =
534+ MSI_PLATFORM_FAN_SUBFEATURE_CPU_FAN_TABLE ;
535+
536+ data -> factory_curves .gpu_fan_table [0 ] =
537+ MSI_PLATFORM_FAN_SUBFEATURE_GPU_FAN_TABLE ;
538+ ret = msi_wmi_platform_query_unlocked (
539+ data , MSI_PLATFORM_GET_FAN ,
540+ data -> factory_curves .gpu_fan_table ,
541+ sizeof (data -> factory_curves .gpu_fan_table ));
542+ if (ret < 0 )
543+ return ret ;
544+ data -> factory_curves .gpu_fan_table [0 ] =
545+ MSI_PLATFORM_FAN_SUBFEATURE_GPU_FAN_TABLE ;
546+
547+ data -> factory_curves .cpu_temp_table [0 ] =
548+ MSI_PLATFORM_FAN_SUBFEATURE_CPU_TEMP_TABLE ;
549+ ret = msi_wmi_platform_query_unlocked (
550+ data , MSI_PLATFORM_GET_TEMPERATURE ,
551+ data -> factory_curves .cpu_temp_table ,
552+ sizeof (data -> factory_curves .cpu_temp_table ));
553+ if (ret < 0 )
554+ return ret ;
555+ data -> factory_curves .cpu_temp_table [0 ] =
556+ MSI_PLATFORM_FAN_SUBFEATURE_CPU_TEMP_TABLE ;
557+
558+ data -> factory_curves .gpu_temp_table [0 ] =
559+ MSI_PLATFORM_FAN_SUBFEATURE_GPU_TEMP_TABLE ;
560+ ret = msi_wmi_platform_query_unlocked (
561+ data , MSI_PLATFORM_GET_TEMPERATURE ,
562+ data -> factory_curves .gpu_temp_table ,
563+ sizeof (data -> factory_curves .gpu_temp_table ));
564+ if (ret < 0 )
565+ return ret ;
566+ data -> factory_curves .gpu_temp_table [0 ] =
567+ MSI_PLATFORM_FAN_SUBFEATURE_GPU_TEMP_TABLE ;
568+
569+ return 0 ;
570+ }
571+
572+ static int msi_wmi_platform_curves_load (struct msi_wmi_platform_data * data )
573+ {
574+ u8 buffer [32 ] = { };
575+ int ret ;
576+
577+ memcpy (buffer , data -> factory_curves .cpu_fan_table ,
578+ sizeof (data -> factory_curves .cpu_fan_table ));
579+ ret = msi_wmi_platform_query_unlocked (data , MSI_PLATFORM_SET_FAN ,
580+ buffer , sizeof (buffer ));
581+ if (ret < 0 )
582+ return ret ;
583+
584+ memcpy (buffer , data -> factory_curves .gpu_fan_table ,
585+ sizeof (data -> factory_curves .gpu_fan_table ));
586+ ret = msi_wmi_platform_query_unlocked (data , MSI_PLATFORM_SET_FAN ,
587+ buffer , sizeof (buffer ));
588+ if (ret < 0 )
589+ return ret ;
590+
591+ memcpy (buffer , data -> factory_curves .cpu_temp_table ,
592+ sizeof (data -> factory_curves .cpu_temp_table ));
593+ ret = msi_wmi_platform_query_unlocked (
594+ data , MSI_PLATFORM_SET_TEMPERATURE , buffer , sizeof (buffer ));
595+ if (ret < 0 )
596+ return ret ;
597+
598+ memcpy (buffer , data -> factory_curves .gpu_temp_table ,
599+ sizeof (data -> factory_curves .gpu_temp_table ));
600+ ret = msi_wmi_platform_query_unlocked (
601+ data , MSI_PLATFORM_SET_TEMPERATURE , buffer , sizeof (buffer ));
602+ if (ret < 0 )
603+ return ret ;
604+
605+ return 0 ;
606+ }
607+
608+
510609static umode_t msi_wmi_platform_is_visible (const void * drvdata , enum hwmon_sensor_types type ,
511610 u32 attr , int channel )
512611{
@@ -603,9 +702,19 @@ static int msi_wmi_platform_write(struct device *dev, enum hwmon_sensor_types ty
603702 return - EINVAL ;
604703 }
605704
606- return msi_wmi_platform_query_unlocked (
705+ ret = msi_wmi_platform_query_unlocked (
607706 data , MSI_PLATFORM_SET_AP , buffer ,
608707 sizeof (buffer ));
708+ if (ret < 0 )
709+ return ret ;
710+
711+ if (val == 2 && data -> quirks -> restore_curves ) {
712+ ret = msi_wmi_platform_curves_load (data );
713+ if (ret < 0 )
714+ return ret ;
715+ }
716+
717+ return 0 ;
609718 default :
610719 return - EOPNOTSUPP ;
611720 }
@@ -1373,6 +1482,13 @@ static int msi_wmi_platform_probe(struct wmi_device *wdev, const void *context)
13731482
13741483 msi_wmi_platform_profile_setup (data );
13751484
1485+ if (data -> quirks -> restore_curves ) {
1486+ guard (mutex )(& data -> wmi_lock );
1487+ ret = msi_wmi_platform_curves_save (data );
1488+ if (ret < 0 )
1489+ return ret ;
1490+ }
1491+
13761492 return msi_wmi_platform_hwmon_init (data );
13771493}
13781494
@@ -1382,6 +1498,11 @@ static void msi_wmi_platform_remove(struct wmi_device *wdev)
13821498
13831499 if (data -> quirks -> charge_threshold )
13841500 battery_hook_unregister (& data -> battery_hook );
1501+
1502+ if (data -> quirks -> restore_curves ) {
1503+ guard (mutex )(& data -> wmi_lock );
1504+ msi_wmi_platform_curves_load (data );
1505+ }
13851506}
13861507
13871508static const struct wmi_device_id msi_wmi_platform_id_table [] = {
0 commit comments