diff --git a/arch/arm/mach-omap2/dvfs.c b/arch/arm/mach-omap2/dvfs.c index 24fbf1b..4d5c661 100644 --- a/arch/arm/mach-omap2/dvfs.c +++ b/arch/arm/mach-omap2/dvfs.c @@ -26,6 +26,7 @@ #include #include "smartreflex.h" #include "powerdomain.h" +#include "pm.h" /** * DOC: Introduction @@ -839,6 +840,11 @@ int omap_device_scale(struct device *req_dev, struct device *target_dev, return -EINVAL; } + if (!omap_pm_is_ready()) { + dev_dbg(target_dev, "%s: pm is not ready yet\n", __func__); + return -EBUSY; + } + /* Lock me to ensure cross domain scaling is secure */ mutex_lock(&omap_dvfs_lock); diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 7070423..1c32261 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -26,6 +26,10 @@ static struct omap_device_pm_latency *pm_lats; +static int _init_omap_device(char *name); + +bool omap_pm_is_ready_status; + static int _init_omap_device(char *name) { struct omap_hwmod *oh; @@ -288,6 +292,10 @@ static int __init omap2_common_pm_late_init(void) /* Smartreflex device init */ omap_devinit_smartreflex(); + omap_pm_is_ready_status = true; + /* let the other CPU know as well */ + smp_wmb(); + return 0; } late_initcall(omap2_common_pm_late_init); diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 4e166ad..4d8da43 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -134,4 +134,22 @@ static inline int omap4_twl_init(void) } #endif +#ifdef CONFIG_PM +extern bool omap_pm_is_ready_status; +/** + * omap_pm_is_ready() - tells if OMAP pm framework is done it's initialization + * + * In few cases, to sequence operations properly, we'd like to know if OMAP's PM + * framework has completed all it's expected initializations. + */ +static inline bool omap_pm_is_ready(void) +{ + return omap_pm_is_ready_status; +} +#else +static inline bool omap_pm_is_ready(void) +{ + return false; +} +#endif #endif