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

Merge tag 'pmdomain-v6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm

Pull pmdomain fixes from Ulf Hansson:
"pmdomain core:
- Fix alloc/free in dev_pm_domain_attach|detach_list()

pmdomain providers:
- qcom: Fix the return of uninitialized variable

pmdomain consumers:
- drm/tegra/gr3d: Revert conversion to dev_pm_domain_attach|detach_list()

OPP core:
- Fix error code in dev_pm_opp_set_config()"

* tag 'pmdomain-v6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm:
PM: domains: Fix alloc/free in dev_pm_domain_attach|detach_list()
Revert "drm/tegra: gr3d: Convert into dev_pm_domain_attach|detach_list()"
pmdomain: qcom-cpr: Fix the return of uninitialized variable
OPP: fix error code in dev_pm_opp_set_config()

+52 -25
+15 -10
drivers/base/power/common.c
··· 195 195 struct device *pd_dev = NULL; 196 196 int ret, i, num_pds = 0; 197 197 bool by_id = true; 198 + size_t size; 198 199 u32 pd_flags = data ? data->pd_flags : 0; 199 200 u32 link_flags = pd_flags & PD_FLAG_NO_DEV_LINK ? 0 : 200 201 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME; ··· 218 217 if (num_pds <= 0) 219 218 return 0; 220 219 221 - pds = devm_kzalloc(dev, sizeof(*pds), GFP_KERNEL); 220 + pds = kzalloc(sizeof(*pds), GFP_KERNEL); 222 221 if (!pds) 223 222 return -ENOMEM; 224 223 225 - pds->pd_devs = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_devs), 226 - GFP_KERNEL); 227 - if (!pds->pd_devs) 228 - return -ENOMEM; 229 - 230 - pds->pd_links = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_links), 231 - GFP_KERNEL); 232 - if (!pds->pd_links) 233 - return -ENOMEM; 224 + size = sizeof(*pds->pd_devs) + sizeof(*pds->pd_links); 225 + pds->pd_devs = kcalloc(num_pds, size, GFP_KERNEL); 226 + if (!pds->pd_devs) { 227 + ret = -ENOMEM; 228 + goto free_pds; 229 + } 230 + pds->pd_links = (void *)(pds->pd_devs + num_pds); 234 231 235 232 if (link_flags && pd_flags & PD_FLAG_DEV_LINK_ON) 236 233 link_flags |= DL_FLAG_RPM_ACTIVE; ··· 271 272 device_link_del(pds->pd_links[i]); 272 273 dev_pm_domain_detach(pds->pd_devs[i], true); 273 274 } 275 + kfree(pds->pd_devs); 276 + free_pds: 277 + kfree(pds); 274 278 return ret; 275 279 } 276 280 EXPORT_SYMBOL_GPL(dev_pm_domain_attach_list); ··· 365 363 device_link_del(list->pd_links[i]); 366 364 dev_pm_domain_detach(list->pd_devs[i], true); 367 365 } 366 + 367 + kfree(list->pd_devs); 368 + kfree(list); 368 369 } 369 370 EXPORT_SYMBOL_GPL(dev_pm_domain_detach_list); 370 371
+33 -13
drivers/gpu/drm/tegra/gr3d.c
··· 46 46 unsigned int nclocks; 47 47 struct reset_control_bulk_data resets[RST_GR3D_MAX]; 48 48 unsigned int nresets; 49 - struct dev_pm_domain_list *pd_list; 50 49 51 50 DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS); 52 51 }; ··· 369 370 return 0; 370 371 } 371 372 373 + static void gr3d_del_link(void *link) 374 + { 375 + device_link_del(link); 376 + } 377 + 372 378 static int gr3d_init_power(struct device *dev, struct gr3d *gr3d) 373 379 { 374 - struct dev_pm_domain_attach_data pd_data = { 375 - .pd_names = (const char *[]) { "3d0", "3d1" }, 376 - .num_pd_names = 2, 377 - }; 380 + static const char * const opp_genpd_names[] = { "3d0", "3d1", NULL }; 381 + const u32 link_flags = DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME; 382 + struct device **opp_virt_devs, *pd_dev; 383 + struct device_link *link; 384 + unsigned int i; 378 385 int err; 379 386 380 387 err = of_count_phandle_with_args(dev->of_node, "power-domains", ··· 414 409 if (dev->pm_domain) 415 410 return 0; 416 411 417 - err = dev_pm_domain_attach_list(dev, &pd_data, &gr3d->pd_list); 418 - if (err < 0) 412 + err = devm_pm_opp_attach_genpd(dev, opp_genpd_names, &opp_virt_devs); 413 + if (err) 419 414 return err; 415 + 416 + for (i = 0; opp_genpd_names[i]; i++) { 417 + pd_dev = opp_virt_devs[i]; 418 + if (!pd_dev) { 419 + dev_err(dev, "failed to get %s power domain\n", 420 + opp_genpd_names[i]); 421 + return -EINVAL; 422 + } 423 + 424 + link = device_link_add(dev, pd_dev, link_flags); 425 + if (!link) { 426 + dev_err(dev, "failed to link to %s\n", dev_name(pd_dev)); 427 + return -EINVAL; 428 + } 429 + 430 + err = devm_add_action_or_reset(dev, gr3d_del_link, link); 431 + if (err) 432 + return err; 433 + } 420 434 421 435 return 0; 422 436 } ··· 527 503 528 504 err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); 529 505 if (err) 530 - goto err; 506 + return err; 531 507 532 508 err = host1x_client_register(&gr3d->client.base); 533 509 if (err < 0) { 534 510 dev_err(&pdev->dev, "failed to register host1x client: %d\n", 535 511 err); 536 - goto err; 512 + return err; 537 513 } 538 514 539 515 /* initialize address register map */ ··· 541 517 set_bit(gr3d_addr_regs[i], gr3d->addr_regs); 542 518 543 519 return 0; 544 - err: 545 - dev_pm_domain_detach_list(gr3d->pd_list); 546 - return err; 547 520 } 548 521 549 522 static void gr3d_remove(struct platform_device *pdev) ··· 549 528 550 529 pm_runtime_disable(&pdev->dev); 551 530 host1x_client_unregister(&gr3d->client.base); 552 - dev_pm_domain_detach_list(gr3d->pd_list); 553 531 } 554 532 555 533 static int __maybe_unused gr3d_runtime_suspend(struct device *dev)
+3 -1
drivers/opp/core.c
··· 2630 2630 2631 2631 /* Attach genpds */ 2632 2632 if (config->genpd_names) { 2633 - if (config->required_devs) 2633 + if (config->required_devs) { 2634 + ret = -EINVAL; 2634 2635 goto err; 2636 + } 2635 2637 2636 2638 ret = _opp_attach_genpd(opp_table, dev, config->genpd_names, 2637 2639 config->virt_devs);
+1 -1
drivers/pmdomain/qcom/cpr.c
··· 1052 1052 of_parse_phandle(child_np, "required-opps", 0); 1053 1053 1054 1054 if (child_req_np == ref_np) { 1055 - u64 rate; 1055 + u64 rate = 0; 1056 1056 1057 1057 of_property_read_u64(child_np, "opp-hz", &rate); 1058 1058 return (unsigned long) rate;