Skip to content

Commit 82e12d9

Browse files
storulfrafaeljw
authored andcommitted
PM / Domains: Add dev_pm_domain_attach_by_id() to manage multi PM domains
The existing dev_pm_domain_attach() function, allows a single PM domain to be attached per device. To be able to support devices that are partitioned across multiple PM domains, let's introduce a new interface, dev_pm_domain_attach_by_id(). The dev_pm_domain_attach_by_id() returns a new allocated struct device with the corresponding attached PM domain. This enables for example a driver to operate on the new device from a power management point of view. The driver may then also benefit from using the received device, to set up so called device-links towards its original device. Depending on the situation, these links may then be dynamically changed. The new interface is typically called by drivers during their probe phase, in case they manages devices which uses multiple PM domains. If that is the case, the driver also becomes responsible of managing the detaching of the PM domains, which typically should be done at the remove phase. Detaching is done by calling the existing dev_pm_domain_detach() function and for each of the received devices from dev_pm_domain_attach_by_id(). Note, currently its only genpd that supports multiple PM domains per device, but dev_pm_domain_attach_by_id() can easily by extended to cover other PM domain types, if/when needed. Signed-off-by: Ulf Hansson <[email protected]> Acked-by: Jon Hunter <[email protected]> Tested-by: Jon Hunter <[email protected]> Reviewed-by: Viresh Kumar <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 3c095f3 commit 82e12d9

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

drivers/base/power/common.c

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,51 @@ int dev_pm_domain_attach(struct device *dev, bool power_on)
116116
}
117117
EXPORT_SYMBOL_GPL(dev_pm_domain_attach);
118118

119+
/**
120+
* dev_pm_domain_attach_by_id - Associate a device with one of its PM domains.
121+
* @dev: The device used to lookup the PM domain.
122+
* @index: The index of the PM domain.
123+
*
124+
* As @dev may only be attached to a single PM domain, the backend PM domain
125+
* provider creates a virtual device to attach instead. If attachment succeeds,
126+
* the ->detach() callback in the struct dev_pm_domain are assigned by the
127+
* corresponding backend attach function, as to deal with detaching of the
128+
* created virtual device.
129+
*
130+
* This function should typically be invoked by a driver during the probe phase,
131+
* in case its device requires power management through multiple PM domains. The
132+
* driver may benefit from using the received device, to configure device-links
133+
* towards its original device. Depending on the use-case and if needed, the
134+
* links may be dynamically changed by the driver, which allows it to control
135+
* the power to the PM domains independently from each other.
136+
*
137+
* Callers must ensure proper synchronization of this function with power
138+
* management callbacks.
139+
*
140+
* Returns the virtual created device when successfully attached to its PM
141+
* domain, NULL in case @dev don't need a PM domain, else an ERR_PTR().
142+
* Note that, to detach the returned virtual device, the driver shall call
143+
* dev_pm_domain_detach() on it, typically during the remove phase.
144+
*/
145+
struct device *dev_pm_domain_attach_by_id(struct device *dev,
146+
unsigned int index)
147+
{
148+
if (dev->pm_domain)
149+
return ERR_PTR(-EEXIST);
150+
151+
return genpd_dev_pm_attach_by_id(dev, index);
152+
}
153+
EXPORT_SYMBOL_GPL(dev_pm_domain_attach_by_id);
154+
119155
/**
120156
* dev_pm_domain_detach - Detach a device from its PM domain.
121157
* @dev: Device to detach.
122158
* @power_off: Used to indicate whether we should power off the device.
123159
*
124-
* This functions will reverse the actions from dev_pm_domain_attach() and thus
125-
* try to detach the @dev from its PM domain. Typically it should be invoked
126-
* from subsystem level code during the remove phase.
160+
* This functions will reverse the actions from dev_pm_domain_attach() and
161+
* dev_pm_domain_attach_by_id(), thus it detaches @dev from its PM domain.
162+
* Typically it should be invoked during the remove phase, either from
163+
* subsystem level code or from drivers.
127164
*
128165
* Callers must ensure proper synchronization of this function with power
129166
* management callbacks.

include/linux/pm_domain.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,13 +299,20 @@ struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
299299

300300
#ifdef CONFIG_PM
301301
int dev_pm_domain_attach(struct device *dev, bool power_on);
302+
struct device *dev_pm_domain_attach_by_id(struct device *dev,
303+
unsigned int index);
302304
void dev_pm_domain_detach(struct device *dev, bool power_off);
303305
void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd);
304306
#else
305307
static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
306308
{
307309
return 0;
308310
}
311+
static inline struct device *dev_pm_domain_attach_by_id(struct device *dev,
312+
unsigned int index)
313+
{
314+
return NULL;
315+
}
309316
static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {}
310317
static inline void dev_pm_domain_set(struct device *dev,
311318
struct dev_pm_domain *pd) {}

0 commit comments

Comments
 (0)