@@ -1182,6 +1182,10 @@ static int amd_pstate_power_supply_notifier(struct notifier_block *nb,
11821182 if (event != PSY_EVENT_PROP_CHANGED )
11831183 return NOTIFY_OK ;
11841184
1185+ /* dynamic actions are only applied while platform profile is in balanced */
1186+ if (cpudata -> current_profile != PLATFORM_PROFILE_BALANCED )
1187+ return 0 ;
1188+
11851189 epp = amd_pstate_get_balanced_epp (policy );
11861190
11871191 ret = amd_pstate_set_epp (policy , epp );
@@ -1190,12 +1194,77 @@ static int amd_pstate_power_supply_notifier(struct notifier_block *nb,
11901194
11911195 return NOTIFY_OK ;
11921196}
1197+
1198+ static int amd_pstate_profile_probe (void * drvdata , unsigned long * choices )
1199+ {
1200+ set_bit (PLATFORM_PROFILE_LOW_POWER , choices );
1201+ set_bit (PLATFORM_PROFILE_BALANCED , choices );
1202+ set_bit (PLATFORM_PROFILE_PERFORMANCE , choices );
1203+
1204+ return 0 ;
1205+ }
1206+
1207+ static int amd_pstate_profile_get (struct device * dev ,
1208+ enum platform_profile_option * profile )
1209+ {
1210+ struct amd_cpudata * cpudata = dev_get_drvdata (dev );
1211+
1212+ * profile = cpudata -> current_profile ;
1213+
1214+ return 0 ;
1215+ }
1216+
1217+ static int amd_pstate_profile_set (struct device * dev ,
1218+ enum platform_profile_option profile )
1219+ {
1220+ struct amd_cpudata * cpudata = dev_get_drvdata (dev );
1221+ struct cpufreq_policy * policy __free (put_cpufreq_policy ) = cpufreq_cpu_get (cpudata -> cpu );
1222+ int ret ;
1223+
1224+ switch (profile ) {
1225+ case PLATFORM_PROFILE_LOW_POWER :
1226+ ret = amd_pstate_set_epp (policy , AMD_CPPC_EPP_POWERSAVE );
1227+ if (ret )
1228+ return ret ;
1229+ break ;
1230+ case PLATFORM_PROFILE_BALANCED :
1231+ ret = amd_pstate_set_epp (policy ,
1232+ amd_pstate_get_balanced_epp (policy ));
1233+ if (ret )
1234+ return ret ;
1235+ break ;
1236+ case PLATFORM_PROFILE_PERFORMANCE :
1237+ ret = amd_pstate_set_epp (policy , AMD_CPPC_EPP_PERFORMANCE );
1238+ if (ret )
1239+ return ret ;
1240+ break ;
1241+ default :
1242+ pr_err ("Unknown Platform Profile %d\n" , profile );
1243+ return - EOPNOTSUPP ;
1244+ }
1245+
1246+ cpudata -> current_profile = profile ;
1247+
1248+ return 0 ;
1249+ }
1250+
1251+ static const struct platform_profile_ops amd_pstate_profile_ops = {
1252+ .probe = amd_pstate_profile_probe ,
1253+ .profile_set = amd_pstate_profile_set ,
1254+ .profile_get = amd_pstate_profile_get ,
1255+ };
1256+
11931257static void amd_pstate_clear_dynamic_epp (struct cpufreq_policy * policy )
11941258{
11951259 struct amd_cpudata * cpudata = policy -> driver_data ;
11961260
11971261 if (cpudata -> power_nb .notifier_call )
11981262 power_supply_unreg_notifier (& cpudata -> power_nb );
1263+ if (cpudata -> ppdev ) {
1264+ platform_profile_remove (cpudata -> ppdev );
1265+ cpudata -> ppdev = NULL ;
1266+ }
1267+ kfree (cpudata -> profile_name );
11991268 cpudata -> dynamic_epp = false;
12001269}
12011270
@@ -1205,11 +1274,35 @@ static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
12051274 int ret ;
12061275 u8 epp ;
12071276
1208- epp = amd_pstate_get_balanced_epp (policy );
1277+ switch (cpudata -> current_profile ) {
1278+ case PLATFORM_PROFILE_PERFORMANCE :
1279+ epp = AMD_CPPC_EPP_PERFORMANCE ;
1280+ break ;
1281+ case PLATFORM_PROFILE_LOW_POWER :
1282+ epp = AMD_CPPC_EPP_POWERSAVE ;
1283+ break ;
1284+ case PLATFORM_PROFILE_BALANCED :
1285+ epp = amd_pstate_get_balanced_epp (policy );
1286+ break ;
1287+ default :
1288+ pr_err ("Unknown Platform Profile %d\n" , cpudata -> current_profile );
1289+ return - EOPNOTSUPP ;
1290+ }
12091291 ret = amd_pstate_set_epp (policy , epp );
12101292 if (ret )
12111293 return ret ;
12121294
1295+ cpudata -> profile_name = kasprintf (GFP_KERNEL , "amd-pstate-epp-cpu%d" , cpudata -> cpu );
1296+
1297+ cpudata -> ppdev = platform_profile_register (get_cpu_device (policy -> cpu ),
1298+ cpudata -> profile_name ,
1299+ policy -> driver_data ,
1300+ & amd_pstate_profile_ops );
1301+ if (IS_ERR (cpudata -> ppdev )) {
1302+ ret = PTR_ERR (cpudata -> ppdev );
1303+ goto cleanup ;
1304+ }
1305+
12131306 /* only enable notifier if things will actually change */
12141307 if (cpudata -> epp_default_ac != cpudata -> epp_default_dc ) {
12151308 cpudata -> power_nb .notifier_call = amd_pstate_power_supply_notifier ;
@@ -1310,8 +1403,8 @@ static ssize_t show_energy_performance_available_preferences(
13101403 return offset ;
13111404}
13121405
1313- static ssize_t store_energy_performance_preference (
1314- struct cpufreq_policy * policy , const char * buf , size_t count )
1406+ static ssize_t store_energy_performance_preference (struct cpufreq_policy * policy ,
1407+ const char * buf , size_t count )
13151408{
13161409 struct amd_cpudata * cpudata = policy -> driver_data ;
13171410 ssize_t ret ;
@@ -1331,7 +1424,7 @@ static ssize_t store_energy_performance_preference(
13311424 else
13321425 epp = amd_pstate_get_balanced_epp (policy );
13331426
1334- if (epp > 0 && policy -> policy == CPUFREQ_POLICY_PERFORMANCE ) {
1427+ if (cpudata -> policy == CPUFREQ_POLICY_PERFORMANCE ) {
13351428 pr_debug ("EPP cannot be set under performance policy\n" );
13361429 return - EBUSY ;
13371430 }
@@ -1343,8 +1436,7 @@ static ssize_t store_energy_performance_preference(
13431436 return ret ? ret : count ;
13441437}
13451438
1346- static ssize_t show_energy_performance_preference (
1347- struct cpufreq_policy * policy , char * buf )
1439+ static ssize_t show_energy_performance_preference (struct cpufreq_policy * policy , char * buf )
13481440{
13491441 struct amd_cpudata * cpudata = policy -> driver_data ;
13501442 u8 preference , epp ;
@@ -1826,10 +1918,12 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
18261918 amd_pstate_acpi_pm_profile_undefined ()) {
18271919 policy -> policy = CPUFREQ_POLICY_PERFORMANCE ;
18281920 cpudata -> epp_default_ac = cpudata -> epp_default_dc = amd_pstate_get_epp (cpudata );
1921+ cpudata -> current_profile = PLATFORM_PROFILE_PERFORMANCE ;
18291922 } else {
18301923 policy -> policy = CPUFREQ_POLICY_POWERSAVE ;
18311924 cpudata -> epp_default_ac = AMD_CPPC_EPP_PERFORMANCE ;
18321925 cpudata -> epp_default_dc = AMD_CPPC_EPP_BALANCE_PERFORMANCE ;
1926+ cpudata -> current_profile = PLATFORM_PROFILE_BALANCED ;
18331927 }
18341928
18351929 if (dynamic_epp )
0 commit comments