Unverified Commit 144d47f9 authored by Matt Coster's avatar Matt Coster
Browse files

drm/imagination: Ensure struct pvr_device->power is initialized



When pvr_power_domains_init() handles <=1 power domains, the content of
struct pvr_device->power was previously left uninitialized.

Fixes: e19cc5ab ("drm/imagination: Use dev_pm_domain_attach_list()")
Reviewed-by: default avatarAlessio Belle <alessio.belle@imgtec.com>
Link: https://patch.msgid.link/20260227-single-domain-power-fixes-v1-3-d37ba0825f7c@imgtec.com


Signed-off-by: default avatarMatt Coster <matt.coster@imgtec.com>
parent 218ea788
Loading
Loading
Loading
Loading
+29 −15
Original line number Diff line number Diff line
@@ -598,8 +598,8 @@ int pvr_power_domains_init(struct pvr_device *pvr_dev)
	struct drm_device *drm_dev = from_pvr_device(pvr_dev);
	struct device *dev = drm_dev->dev;

	struct device_link **domain_links __free(kfree) = NULL;
	struct dev_pm_domain_list *domains = NULL;
	struct device_link **domain_links = NULL;
	int domain_count;
	int link_count;

@@ -608,23 +608,30 @@ int pvr_power_domains_init(struct pvr_device *pvr_dev)

	domain_count = of_count_phandle_with_args(dev->of_node, "power-domains",
						  "#power-domain-cells");
	if (domain_count < 0)
		return domain_count;
	if (domain_count < 0) {
		err = domain_count;
		goto out;
	}

	if (domain_count <= 1)
		return 0;
	if (domain_count <= 1) {
		err = 0;
		goto out;
	}

	if (domain_count > ARRAY_SIZE(ROGUE_PD_NAMES)) {
		drm_err(drm_dev, "%s() only supports %zu domains on Rogue",
			__func__, ARRAY_SIZE(ROGUE_PD_NAMES));
		return -EOPNOTSUPP;
		err = -EOPNOTSUPP;
		goto out;
	}

	link_count = domain_count - 1;

	domain_links = kzalloc_objs(*domain_links, link_count);
	if (!domain_links)
		return -ENOMEM;
	if (!domain_links) {
		err = -ENOMEM;
		goto out;
	}

	const struct dev_pm_domain_attach_data pd_attach_data = {
		.pd_names = ROGUE_PD_NAMES,
@@ -634,7 +641,7 @@ int pvr_power_domains_init(struct pvr_device *pvr_dev)

	err = dev_pm_domain_attach_list(dev, &pd_attach_data, &domains);
	if (err < 0)
		return err;
		goto err_free_links;

	for (i = 0; i < link_count; i++) {
		struct device_link *link;
@@ -650,18 +657,25 @@ int pvr_power_domains_init(struct pvr_device *pvr_dev)
		domain_links[i] = link;
	}

	pvr_dev->power = (struct pvr_device_power){
		.domains = domains,
		.domain_links = no_free_ptr(domain_links),
	};

	return 0;
	err = 0;
	goto out;

err_unlink:
	while (--i >= 0)
		device_link_del(domain_links[i]);

	dev_pm_domain_detach_list(domains);
	domains = NULL;

err_free_links:
	kfree(domain_links);
	domain_links = NULL;

out:
	pvr_dev->power = (struct pvr_device_power){
		.domains = domains,
		.domain_links = domain_links,
	};

	return err;
}