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:
committed by
Greg Kroah-Hartman
parent
1037246cac
commit
c64a092671
@@ -976,6 +976,41 @@ struct bus_type platform_bus_type = {
|
|||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(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 __init platform_bus_init(void)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
@@ -138,6 +138,9 @@ extern struct platform_device *platform_create_bundle(struct platform_driver *dr
|
|||||||
struct resource *res, unsigned int n_res,
|
struct resource *res, unsigned int n_res,
|
||||||
const void *data, size_t size);
|
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 */
|
/* early platform driver interface */
|
||||||
struct early_platform_driver {
|
struct early_platform_driver {
|
||||||
const char *class_str;
|
const char *class_str;
|
||||||
|
Reference in New Issue
Block a user