Commit c64a0926710153b9d44c979d2942f4a8648fd74e

Authored by Kevin Hilman
Committed by Greg Kroah-Hartman
1 parent 1037246cac

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>

Showing 2 changed files with 38 additions and 0 deletions Side-by-side Diff

drivers/base/platform.c
... ... @@ -976,6 +976,41 @@
976 976 };
977 977 EXPORT_SYMBOL_GPL(platform_bus_type);
978 978  
  979 +/**
  980 + * platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops
  981 + *
  982 + * This function can be used by platform code to get the current
  983 + * set of dev_pm_ops functions used by the platform_bus_type.
  984 + */
  985 +const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
  986 +{
  987 + return platform_bus_type.pm;
  988 +}
  989 +
  990 +/**
  991 + * platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type
  992 + *
  993 + * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type
  994 + *
  995 + * Platform code can override the dev_pm_ops methods of
  996 + * platform_bus_type by using this function. It is expected that
  997 + * platform code will first do a platform_bus_get_pm_ops(), then
  998 + * kmemdup it, then customize selected methods and pass a pointer to
  999 + * the new struct dev_pm_ops to this function.
  1000 + *
  1001 + * Since platform-specific code is customizing methods for *all*
  1002 + * devices (not just platform-specific devices) it is expected that
  1003 + * any custom overrides of these functions will keep existing behavior
  1004 + * and simply extend it. For example, any customization of the
  1005 + * runtime PM methods should continue to call the pm_generic_*
  1006 + * functions as the default ones do in addition to the
  1007 + * platform-specific behavior.
  1008 + */
  1009 +void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm)
  1010 +{
  1011 + platform_bus_type.pm = pm;
  1012 +}
  1013 +
979 1014 int __init platform_bus_init(void)
980 1015 {
981 1016 int error;
include/linux/platform_device.h
... ... @@ -138,6 +138,9 @@
138 138 struct resource *res, unsigned int n_res,
139 139 const void *data, size_t size);
140 140  
  141 +extern const struct dev_pm_ops * platform_bus_get_pm_ops(void);
  142 +extern void platform_bus_set_pm_ops(const struct dev_pm_ops *pm);
  143 +
141 144 /* early platform driver interface */
142 145 struct early_platform_driver {
143 146 const char *class_str;