diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 493bcdcb826..77e56db7846 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -24,13 +24,6 @@ config PM_NDOMAINS Network domain, shutting down the network when it is not be used, from the UI domain, shutting down the UI when it is not in use. -choice - prompt "PM system governor" - default PM_GOVERNOR_ACTIVITY - ---help--- - A PM governor applies a policy to control the change in power - states. - config PM_GOVERNOR_GREEDY bool "Greedy governor" ---help--- @@ -46,14 +39,6 @@ config PM_GOVERNOR_ACTIVITY The governor will then switch between power states given a set of activity thresholds for each state. -config PM_GOVERNOR_CUSTOM - bool "Custom governor" - ---help--- - By selecting this option, a custom governor can be supplied from - board-logic. - -endchoice - menu "Governor options" if PM_GOVERNOR_GREEDY diff --git a/drivers/power/Make.defs b/drivers/power/Make.defs index c0b79367eeb..e0125473321 100644 --- a/drivers/power/Make.defs +++ b/drivers/power/Make.defs @@ -23,7 +23,7 @@ ifeq ($(CONFIG_PM),y) CSRCS += pm_initialize.c pm_activity.c pm_changestate.c pm_checkstate.c -CSRCS += pm_register.c pm_unregister.c pm_autoupdate.c +CSRCS += pm_register.c pm_unregister.c pm_autoupdate.c pm_governor.c # Governor implementations diff --git a/drivers/power/pm.h b/drivers/power/pm.h index 1f73e780250..42821bf93b2 100644 --- a/drivers/power/pm.h +++ b/drivers/power/pm.h @@ -89,6 +89,10 @@ struct pm_domain_s struct work_s update_work; #endif + + /* A pointer to the PM governor instance */ + + FAR const struct pm_governor_s *governor; }; /* This structure encapsulates all of the global data used by the PM system */ @@ -111,10 +115,6 @@ struct pm_global_s /* The state information for each PM domain */ struct pm_domain_s domain[CONFIG_PM_NDOMAINS]; - - /* A pointer to the PM governor instance */ - - FAR const struct pm_governor_s *governor; }; /**************************************************************************** diff --git a/drivers/power/pm_activity.c b/drivers/power/pm_activity.c index 641b578d0da..d3c73dcb8ef 100644 --- a/drivers/power/pm_activity.c +++ b/drivers/power/pm_activity.c @@ -71,9 +71,9 @@ void pm_activity(int domain, int priority) { DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS); - if (g_pmglobals.governor->activity) + if (g_pmglobals.domain[domain].governor->activity) { - g_pmglobals.governor->activity(domain, priority); + g_pmglobals.domain[domain].governor->activity(domain, priority); } pm_auto_updatestate(domain); diff --git a/drivers/power/pm_changestate.c b/drivers/power/pm_changestate.c index aab79eaea7b..d38dd0d596b 100644 --- a/drivers/power/pm_changestate.c +++ b/drivers/power/pm_changestate.c @@ -242,9 +242,9 @@ int pm_changestate(int domain, enum pm_state_e newstate) /* Notify governor of (possible) state change */ - if (g_pmglobals.governor->statechanged) + if (g_pmglobals.domain[domain].governor->statechanged) { - g_pmglobals.governor->statechanged(domain, newstate); + g_pmglobals.domain[domain].governor->statechanged(domain, newstate); } /* Restore the interrupt state */ diff --git a/drivers/power/pm_checkstate.c b/drivers/power/pm_checkstate.c index 7f454b32933..aaa9764a4df 100644 --- a/drivers/power/pm_checkstate.c +++ b/drivers/power/pm_checkstate.c @@ -71,10 +71,14 @@ enum pm_state_e pm_checkstate(int domain) { - DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS && - g_pmglobals.governor->checkstate); + DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS); - return g_pmglobals.governor->checkstate(domain); + if (g_pmglobals.domain[domain].governor->checkstate) + { + return g_pmglobals.domain[domain].governor->checkstate(domain); + } + + return PM_NORMAL; } #endif /* CONFIG_PM */ diff --git a/drivers/power/pm_governor.c b/drivers/power/pm_governor.c new file mode 100644 index 00000000000..cf587980721 --- /dev/null +++ b/drivers/power/pm_governor.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * drivers/power/pm_governor.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "pm.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pm_set_governor + * + * Description: + * This function set the domain with assigned governor + * + * Input Parameters: + * domain - The PM domain to Set + * gov - The governor to use + * + * Returned Value: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +int pm_set_governor(int domain, FAR const struct pm_governor_s *gov) +{ + if (gov == NULL) + { + return -EINVAL; + } + + if (g_pmglobals.domain[domain].governor && + g_pmglobals.domain[domain].governor->deinitialize) + { + g_pmglobals.domain[domain].governor->deinitialize(); + } + + g_pmglobals.domain[domain].governor = gov; + + if (g_pmglobals.domain[domain].governor->initialize) + { + g_pmglobals.domain[domain].governor->initialize(); + } + + return 0; +} diff --git a/drivers/power/pm_initialize.c b/drivers/power/pm_initialize.c index 282fd28c34c..974da225bb6 100644 --- a/drivers/power/pm_initialize.c +++ b/drivers/power/pm_initialize.c @@ -77,23 +77,23 @@ struct pm_global_s g_pmglobals = void pm_initialize(void) { + FAR const struct pm_governor_s *gov; + int i; + /* Select governor */ -#if defined(CONFIG_PM_GOVERNOR_ACTIVITY) - g_pmglobals.governor = pm_activity_governor_initialize(); -#elif defined(CONFIG_PM_GOVERNOR_GREEDY) - g_pmglobals.governor = pm_greedy_governor_initialize(); -#elif defined(CONFIG_PM_GOVERNOR_CUSTOM) - /* TODO: call to board function to retrieve custom governor, - * such as board_pm_governor_initialize() - */ - -# error "Not supported yet" + for (i = 0; i < CONFIG_PM_NDOMAINS; i++) + { +#if defined(CONFIG_PM_GOVERNOR_GREEDY) + gov = pm_greedy_governor_initialize(); +#elif defined(CONFIG_PM_GOVERNOR_ACTIVITY) + gov = pm_activity_governor_initialize(); +#else + static struct pm_governor_s null; + gov = &null; #endif - - /* Initialize selected governor */ - - g_pmglobals.governor->initialize(); + pm_set_governor(i, gov); + } } #endif /* CONFIG_PM */ diff --git a/include/nuttx/power/pm.h b/include/nuttx/power/pm.h index 2339d496839..d3da7863788 100644 --- a/include/nuttx/power/pm.h +++ b/include/nuttx/power/pm.h @@ -223,6 +223,17 @@ struct pm_governor_s CODE void (*initialize)(void); + /************************************************************************** + * Name: deinitialize + * + * Description: + * Allow the governor to release its internal data. This can be left to + * to NULL if not needed by the governor. + * + **************************************************************************/ + + CODE void (*deinitialize)(void); + /************************************************************************** * Name: statechanged * @@ -313,6 +324,51 @@ extern "C" void pm_initialize(void); +/**************************************************************************** + * Name: pm_greedy_governor_initialize + * + * Description: + * Return the greedy governor instance. + * + * Returned Value: + * A pointer to the governor struct. Otherwise NULL is returned on error. + * + ****************************************************************************/ + +FAR const struct pm_governor_s *pm_greedy_governor_initialize(void); + +/**************************************************************************** + * Name: pm_activity_governor_initialize + * + * Description: + * Return the activity governor instance. + * + * Returned Value: + * A pointer to the governor struct. Otherwise NULL is returned on error. + * + ****************************************************************************/ + +FAR const struct pm_governor_s *pm_activity_governor_initialize(void); + +/**************************************************************************** + * Name: pm_set_governor + * + * Description: + * This function set the domain with assigned governor + * + * Input Parameters: + * domain - The PM domain to Set + * gov - The governor to use + * + * Returned Value: + * On success - OK + * On error - -EINVAL + * + * + ****************************************************************************/ + +int pm_set_governor(int domain, FAR const struct pm_governor_s *gov); + /**************************************************************************** * Name: pm_auto_update *