driver core: platform_bus: allow runtime override of dev_pm_ops
Currently, the platform_bus allows customization of several of the busses dev_pm_ops methods by using weak symbols so that platform code can override them. The weak-symbol approach is not scalable when wanting to support multiple platforms in a single kernel binary. Instead, provide __init methods for platform code to customize the dev_pm_ops methods at runtime. NOTE: after these dynamic methods are merged, the weak symbols should be removed from drivers/base/platform.c. AFAIK, this will only affect SH and sh-mobile which should be converted to use this runtime approach instead of the weak symbols. After SH & sh-mobile are converted, the weak symobols could be removed. Tested on OMAP3. Cc: Magnus Damm <magnus.damm@gmail.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
1037246cac
commit
c64a092671
|
@ -976,6 +976,41 @@ struct bus_type platform_bus_type = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(platform_bus_type);
|
||||
|
||||
/**
|
||||
* platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops
|
||||
*
|
||||
* This function can be used by platform code to get the current
|
||||
* set of dev_pm_ops functions used by the platform_bus_type.
|
||||
*/
|
||||
const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
|
||||
{
|
||||
return platform_bus_type.pm;
|
||||
}
|
||||
|
||||
/**
|
||||
* platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type
|
||||
*
|
||||
* @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type
|
||||
*
|
||||
* Platform code can override the dev_pm_ops methods of
|
||||
* platform_bus_type by using this function. It is expected that
|
||||
* platform code will first do a platform_bus_get_pm_ops(), then
|
||||
* kmemdup it, then customize selected methods and pass a pointer to
|
||||
* the new struct dev_pm_ops to this function.
|
||||
*
|
||||
* Since platform-specific code is customizing methods for *all*
|
||||
* devices (not just platform-specific devices) it is expected that
|
||||
* any custom overrides of these functions will keep existing behavior
|
||||
* and simply extend it. For example, any customization of the
|
||||
* runtime PM methods should continue to call the pm_generic_*
|
||||
* functions as the default ones do in addition to the
|
||||
* platform-specific behavior.
|
||||
*/
|
||||
void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm)
|
||||
{
|
||||
platform_bus_type.pm = pm;
|
||||
}
|
||||
|
||||
int __init platform_bus_init(void)
|
||||
{
|
||||
int error;
|
||||
|
|
|
@ -138,6 +138,9 @@ extern struct platform_device *platform_create_bundle(struct platform_driver *dr
|
|||
struct resource *res, unsigned int n_res,
|
||||
const void *data, size_t size);
|
||||
|
||||
extern const struct dev_pm_ops * platform_bus_get_pm_ops(void);
|
||||
extern void platform_bus_set_pm_ops(const struct dev_pm_ops *pm);
|
||||
|
||||
/* early platform driver interface */
|
||||
struct early_platform_driver {
|
||||
const char *class_str;
|
||||
|
|
Loading…
Reference in New Issue