drivers/base/power/common.c

Source file repositories/reference/linux-study-clean/drivers/base/power/common.c

File Facts

System
Linux kernel
Corpus path
drivers/base/power/common.c
Extension
.c
Size
13587 bytes
Lines
458
Domain
Driver Families
Bucket
drivers/base
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (IS_ERR_OR_NULL(pd_dev)) {
			ret = pd_dev ? PTR_ERR(pd_dev) : -ENODEV;
			goto err_attach;
		}

		if (pd_flags & PD_FLAG_REQUIRED_OPP) {
			struct dev_pm_opp_config config = {
				.required_dev = pd_dev,
				.required_dev_index = i,
			};

			ret = dev_pm_opp_set_config(dev, &config);
			if (ret < 0)
				goto err_link;

			pds->opp_tokens[i] = ret;
		}

		if (link_flags) {
			struct device_link *link;

			link = device_link_add(dev, pd_dev, link_flags);
			if (!link) {
				ret = -ENODEV;
				goto err_link;
			}

			pds->pd_links[i] = link;
		}

		pds->pd_devs[i] = pd_dev;
	}

	pds->num_pds = num_pds;
	*list = pds;
	return num_pds;

err_link:
	dev_pm_opp_clear_config(pds->opp_tokens[i]);
	dev_pm_domain_detach(pd_dev, true);
err_attach:
	while (--i >= 0) {
		dev_pm_opp_clear_config(pds->opp_tokens[i]);
		if (pds->pd_links[i])
			device_link_del(pds->pd_links[i]);
		dev_pm_domain_detach(pds->pd_devs[i], true);
	}
	kfree(pds->pd_devs);
free_pds:
	kfree(pds);
	return ret;
}
EXPORT_SYMBOL_GPL(dev_pm_domain_attach_list);

/**
 * devm_pm_domain_detach_list - devres-enabled version of dev_pm_domain_detach_list.
 * @_list: The list of PM domains to detach.
 *
 * This function reverse the actions from devm_pm_domain_attach_list().
 * it will be invoked during the remove phase from drivers implicitly if driver
 * uses devm_pm_domain_attach_list() to attach the PM domains.
 */
static void devm_pm_domain_detach_list(void *_list)
{
	struct dev_pm_domain_list *list = _list;

	dev_pm_domain_detach_list(list);
}

/**
 * devm_pm_domain_attach_list - devres-enabled version of dev_pm_domain_attach_list
 * @dev: The device used to lookup the PM domains for.
 * @data: The data used for attaching to the PM domains.
 * @list: An out-parameter with an allocated list of attached PM domains.
 *
 * NOTE: this will also handle calling devm_pm_domain_detach_list() for
 * you during remove phase.
 *
 * Returns the number of attached PM domains or a negative error code in case of
 * a failure.
 */
int devm_pm_domain_attach_list(struct device *dev,
			       const struct dev_pm_domain_attach_data *data,
			       struct dev_pm_domain_list **list)
{
	int ret, num_pds;

	num_pds = dev_pm_domain_attach_list(dev, data, list);
	if (num_pds <= 0)
		return num_pds;

Annotation

Implementation Notes