Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm-6.10-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
"These fix the amd-pstate driver and the operating performance point
(OPP) handling related to generic PM domains.

Specifics:

- Fix a memory leak in the exit path of amd-pstate (Peng Ma)

- Fix required_opp_tables handling in the cases when multiple generic
PM domains share one OPP table (Viresh Kumar)"

* tag 'pm-6.10-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
OPP: Fix required_opp_tables for multiple genpds using same table
cpufreq: amd-pstate: fix memory leak on CPU EPP exit

+53 -1
+7
drivers/cpufreq/amd-pstate.c
··· 1441 1441 1442 1442 static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) 1443 1443 { 1444 + struct amd_cpudata *cpudata = policy->driver_data; 1445 + 1446 + if (cpudata) { 1447 + kfree(cpudata); 1448 + policy->driver_data = NULL; 1449 + } 1450 + 1444 1451 pr_debug("CPU %d exiting\n", policy->cpu); 1445 1452 return 0; 1446 1453 }
+30 -1
drivers/opp/core.c
··· 2394 2394 static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev, 2395 2395 const char * const *names, struct device ***virt_devs) 2396 2396 { 2397 - struct device *virt_dev; 2397 + struct device *virt_dev, *gdev; 2398 + struct opp_table *genpd_table; 2398 2399 int index = 0, ret = -EINVAL; 2399 2400 const char * const *name = names; 2400 2401 ··· 2426 2425 ret = virt_dev ? PTR_ERR(virt_dev) : -ENODEV; 2427 2426 dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret); 2428 2427 goto err; 2428 + } 2429 + 2430 + /* 2431 + * The required_opp_tables parsing is not perfect, as the OPP 2432 + * core does the parsing solely based on the DT node pointers. 2433 + * The core sets the required_opp_tables entry to the first OPP 2434 + * table in the "opp_tables" list, that matches with the node 2435 + * pointer. 2436 + * 2437 + * If the target DT OPP table is used by multiple devices and 2438 + * they all create separate instances of 'struct opp_table' from 2439 + * it, then it is possible that the required_opp_tables entry 2440 + * may be set to the incorrect sibling device. 2441 + * 2442 + * Cross check it again and fix if required. 2443 + */ 2444 + gdev = dev_to_genpd_dev(virt_dev); 2445 + if (IS_ERR(gdev)) 2446 + return PTR_ERR(gdev); 2447 + 2448 + genpd_table = _find_opp_table(gdev); 2449 + if (!IS_ERR(genpd_table)) { 2450 + if (genpd_table != opp_table->required_opp_tables[index]) { 2451 + dev_pm_opp_put_opp_table(opp_table->required_opp_tables[index]); 2452 + opp_table->required_opp_tables[index] = genpd_table; 2453 + } else { 2454 + dev_pm_opp_put_opp_table(genpd_table); 2455 + } 2429 2456 } 2430 2457 2431 2458 /*
+10
drivers/pmdomain/core.c
··· 184 184 return pd_to_genpd(dev->pm_domain); 185 185 } 186 186 187 + struct device *dev_to_genpd_dev(struct device *dev) 188 + { 189 + struct generic_pm_domain *genpd = dev_to_genpd(dev); 190 + 191 + if (IS_ERR(genpd)) 192 + return ERR_CAST(genpd); 193 + 194 + return &genpd->dev; 195 + } 196 + 187 197 static int genpd_stop_dev(const struct generic_pm_domain *genpd, 188 198 struct device *dev) 189 199 {
+6
include/linux/pm_domain.h
··· 260 260 int pm_genpd_init(struct generic_pm_domain *genpd, 261 261 struct dev_power_governor *gov, bool is_off); 262 262 int pm_genpd_remove(struct generic_pm_domain *genpd); 263 + struct device *dev_to_genpd_dev(struct device *dev); 263 264 int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state); 264 265 int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb); 265 266 int dev_pm_genpd_remove_notifier(struct device *dev); ··· 306 305 static inline int pm_genpd_remove(struct generic_pm_domain *genpd) 307 306 { 308 307 return -EOPNOTSUPP; 308 + } 309 + 310 + static inline struct device *dev_to_genpd_dev(struct device *dev) 311 + { 312 + return ERR_PTR(-EOPNOTSUPP); 309 313 } 310 314 311 315 static inline int dev_pm_genpd_set_performance_state(struct device *dev,