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.

drm/imagination: Use dev_pm_domain_attach_list()

This helper handles the attaching and linking of the entire list of power
domains. Besides making pvr_power_domains_init() simpler, this also lays
the groundwork to simplify supporting the varied power domain names used in
Volcanic GPU cores.

Note that we still need to create the links between power domains to ensure
they're brought up in a valid sequence.

Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Link: https://patch.msgid.link/20260123-pm-domain-attach-list-v1-1-d51dd7e43253@imgtec.com
Signed-off-by: Matt Coster <matt.coster@imgtec.com>

+34 -58
+4 -6
drivers/gpu/drm/imagination/pvr_device.h
··· 152 152 * @power: Optional power domain devices. 153 153 * 154 154 * On platforms with more than one power domain for the GPU, they are 155 - * stored here in @domain_devs, along with links between them in 156 - * @domain_links. The size of @domain_devs is given by @domain_count, 157 - * while the size of @domain_links is (2 * @domain_count) - 1. 155 + * stored here in @domains, along with links between them in 156 + * @domain_links. The size of @domain_links is one less than 157 + * struct dev_pm_domain_list->num_pds in @domains. 158 158 */ 159 159 struct pvr_device_power { 160 - struct device **domain_devs; 160 + struct dev_pm_domain_list *domains; 161 161 struct device_link **domain_links; 162 - 163 - u32 domain_count; 164 162 } power; 165 163 166 164 /**
+30 -52
drivers/gpu/drm/imagination/pvr_power.c
··· 593 593 594 594 int pvr_power_domains_init(struct pvr_device *pvr_dev) 595 595 { 596 - struct device *dev = from_pvr_device(pvr_dev)->dev; 596 + static const char *const ROGUE_PD_NAMES[] = { "a", "b", "c", "d", "e" }; 597 + 598 + struct drm_device *drm_dev = from_pvr_device(pvr_dev); 599 + struct device *dev = drm_dev->dev; 597 600 598 601 struct device_link **domain_links __free(kfree) = NULL; 599 - struct device **domain_devs __free(kfree) = NULL; 602 + struct dev_pm_domain_list *domains = NULL; 600 603 int domain_count; 601 604 int link_count; 602 605 603 - char dev_name[2] = "a"; 604 606 int err; 605 607 int i; 606 608 ··· 614 612 if (domain_count <= 1) 615 613 return 0; 616 614 617 - link_count = domain_count + (domain_count - 1); 615 + if (domain_count > ARRAY_SIZE(ROGUE_PD_NAMES)) { 616 + drm_err(drm_dev, "%s() only supports %zu domains on Rogue", 617 + __func__, ARRAY_SIZE(ROGUE_PD_NAMES)); 618 + return -EOPNOTSUPP; 619 + } 618 620 619 - domain_devs = kcalloc(domain_count, sizeof(*domain_devs), GFP_KERNEL); 620 - if (!domain_devs) 621 - return -ENOMEM; 621 + link_count = domain_count - 1; 622 622 623 623 domain_links = kcalloc(link_count, sizeof(*domain_links), GFP_KERNEL); 624 624 if (!domain_links) 625 625 return -ENOMEM; 626 626 627 - for (i = 0; i < domain_count; i++) { 628 - struct device *domain_dev; 627 + const struct dev_pm_domain_attach_data pd_attach_data = { 628 + .pd_names = ROGUE_PD_NAMES, 629 + .num_pd_names = domain_count, 630 + .pd_flags = 0, 631 + }; 629 632 630 - dev_name[0] = 'a' + i; 631 - domain_dev = dev_pm_domain_attach_by_name(dev, dev_name); 632 - if (IS_ERR_OR_NULL(domain_dev)) { 633 - err = domain_dev ? PTR_ERR(domain_dev) : -ENODEV; 634 - goto err_detach; 635 - } 633 + err = dev_pm_domain_attach_list(dev, &pd_attach_data, &domains); 634 + if (err < 0) 635 + return err; 636 636 637 - domain_devs[i] = domain_dev; 638 - } 639 - 640 - for (i = 0; i < domain_count; i++) { 637 + for (i = 0; i < link_count; i++) { 641 638 struct device_link *link; 642 639 643 - link = device_link_add(dev, domain_devs[i], DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME); 644 - if (!link) { 645 - err = -ENODEV; 646 - goto err_unlink; 647 - } 648 - 649 - domain_links[i] = link; 650 - } 651 - 652 - for (i = domain_count; i < link_count; i++) { 653 - struct device_link *link; 654 - 655 - link = device_link_add(domain_devs[i - domain_count + 1], 656 - domain_devs[i - domain_count], 640 + link = device_link_add(domains->pd_devs[i + 1], 641 + domains->pd_devs[i], 657 642 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME); 658 643 if (!link) { 659 644 err = -ENODEV; ··· 651 662 } 652 663 653 664 pvr_dev->power = (struct pvr_device_power){ 654 - .domain_devs = no_free_ptr(domain_devs), 665 + .domains = domains, 655 666 .domain_links = no_free_ptr(domain_links), 656 - .domain_count = domain_count, 657 667 }; 658 668 659 669 return 0; ··· 661 673 while (--i >= 0) 662 674 device_link_del(domain_links[i]); 663 675 664 - i = domain_count; 665 - 666 - err_detach: 667 - while (--i >= 0) 668 - dev_pm_domain_detach(domain_devs[i], true); 669 - 670 676 return err; 671 677 } 672 678 673 679 void pvr_power_domains_fini(struct pvr_device *pvr_dev) 674 680 { 675 - const int domain_count = pvr_dev->power.domain_count; 681 + struct pvr_device_power *pvr_power = &pvr_dev->power; 676 682 677 - int i = domain_count + (domain_count - 1); 678 - 679 - while (--i >= 0) 680 - device_link_del(pvr_dev->power.domain_links[i]); 681 - 682 - i = domain_count; 683 + int i = (int)pvr_power->domains->num_pds - 1; 683 684 684 685 while (--i >= 0) 685 - dev_pm_domain_detach(pvr_dev->power.domain_devs[i], true); 686 + device_link_del(pvr_power->domain_links[i]); 686 687 687 - kfree(pvr_dev->power.domain_links); 688 - kfree(pvr_dev->power.domain_devs); 688 + dev_pm_domain_detach_list(pvr_power->domains); 689 689 690 - pvr_dev->power = (struct pvr_device_power){ 0 }; 690 + kfree(pvr_power->domain_links); 691 + 692 + *pvr_power = (struct pvr_device_power){ 0 }; 691 693 }