It was just making the code hard to read. Also it was not following the code guideline because the type was not telling us the sign and size. Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
157 lines
3.2 KiB
C
157 lines
3.2 KiB
C
/*
|
|
* Copyright (c) 2018 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr.h>
|
|
#include <kernel.h>
|
|
#include <string.h>
|
|
#include <device.h>
|
|
#include "policy/pm_policy.h"
|
|
|
|
#if defined(CONFIG_PM)
|
|
#define LOG_LEVEL CONFIG_PM_LOG_LEVEL /* From power module Kconfig */
|
|
#include <logging/log.h>
|
|
LOG_MODULE_DECLARE(power);
|
|
|
|
extern const struct device __device_start[];
|
|
extern const struct device __device_end[];
|
|
|
|
/* Indexes into all_devices for devices that support pm,
|
|
* in dependency order (later may depend on earlier).
|
|
*/
|
|
static const struct device *pm_devices[CONFIG_PM_MAX_DEVICES];
|
|
|
|
/* Number of devices successfully suspended. */
|
|
static size_t num_susp;
|
|
|
|
static bool should_suspend(const struct device *dev, uint32_t state)
|
|
{
|
|
int rc;
|
|
uint32_t current_state;
|
|
|
|
if (device_busy_check(dev) != 0) {
|
|
return false;
|
|
}
|
|
|
|
rc = pm_device_state_get(dev, ¤t_state);
|
|
if ((rc == -ENOSYS) || (rc != 0)) {
|
|
LOG_DBG("Was not possible to get device %s state: %d",
|
|
dev->name, rc);
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* If the device is currently powered off or the request was
|
|
* to go to the same state, just ignore it.
|
|
*/
|
|
if ((current_state == PM_DEVICE_STATE_OFF) ||
|
|
(current_state == state)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static int _pm_devices(uint32_t state)
|
|
{
|
|
const struct device *dev;
|
|
num_susp = 0;
|
|
|
|
for (dev = (__device_end - 1); dev > __device_start; dev--) {
|
|
bool suspend;
|
|
int rc;
|
|
|
|
suspend = should_suspend(dev, state);
|
|
if (suspend) {
|
|
/*
|
|
* Don't bother the device if it is currently
|
|
* in the right state.
|
|
*/
|
|
rc = pm_device_state_set(dev, state, NULL, NULL);
|
|
if ((rc != -ENOSYS) && (rc != 0)) {
|
|
LOG_DBG("%s did not enter %s state: %d",
|
|
dev->name, pm_device_state_str(state),
|
|
rc);
|
|
return rc;
|
|
}
|
|
|
|
pm_devices[num_susp] = dev;
|
|
num_susp++;
|
|
__ASSERT(num_susp < CONFIG_PM_MAX_DEVICES,
|
|
"Number of pm devices > CONFIG_PM_MAX_DEVICES");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pm_suspend_devices(void)
|
|
{
|
|
return _pm_devices(PM_DEVICE_STATE_SUSPEND);
|
|
}
|
|
|
|
int pm_low_power_devices(void)
|
|
{
|
|
return _pm_devices(PM_DEVICE_STATE_LOW_POWER);
|
|
}
|
|
|
|
int pm_force_suspend_devices(void)
|
|
{
|
|
return _pm_devices(PM_DEVICE_STATE_FORCE_SUSPEND);
|
|
}
|
|
|
|
void pm_resume_devices(void)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < num_susp; i++) {
|
|
pm_device_state_set(pm_devices[i],
|
|
PM_DEVICE_STATE_ACTIVE,
|
|
NULL, NULL);
|
|
}
|
|
|
|
num_susp = 0;
|
|
}
|
|
#endif /* defined(CONFIG_PM) */
|
|
|
|
const char *pm_device_state_str(uint32_t state)
|
|
{
|
|
switch (state) {
|
|
case PM_DEVICE_STATE_ACTIVE:
|
|
return "active";
|
|
case PM_DEVICE_STATE_LOW_POWER:
|
|
return "low power";
|
|
case PM_DEVICE_STATE_SUSPEND:
|
|
return "suspend";
|
|
case PM_DEVICE_STATE_FORCE_SUSPEND:
|
|
return "force suspend";
|
|
case PM_DEVICE_STATE_OFF:
|
|
return "off";
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
int pm_device_state_set(const struct device *dev, uint32_t device_power_state,
|
|
pm_device_cb cb, void *arg)
|
|
{
|
|
if (dev->pm_control == NULL) {
|
|
return -ENOSYS;
|
|
}
|
|
|
|
return dev->pm_control(dev, PM_DEVICE_STATE_SET,
|
|
&device_power_state, cb, arg);
|
|
}
|
|
|
|
int pm_device_state_get(const struct device *dev, uint32_t *device_power_state)
|
|
{
|
|
if (dev->pm_control == NULL) {
|
|
return -ENOSYS;
|
|
}
|
|
|
|
return dev->pm_control(dev, PM_DEVICE_STATE_GET,
|
|
device_power_state, NULL, NULL);
|
|
}
|