[compoents][pm]The device is registered and uninstalled by linked list
This commit is contained in:
parent
8d3ad68caf
commit
bceb6635b0
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
|
@ -10,6 +10,7 @@
|
|||
* 2019-04-28 Zero-Free improve PM mode and device ops interface
|
||||
* 2020-11-23 zhangsz update pm mode select
|
||||
* 2020-11-27 zhangsz update pm 2.0
|
||||
* 2024-07-04 wdfk-prog The device is registered and uninstalled by linked list
|
||||
*/
|
||||
|
||||
#ifndef __PM_H__
|
||||
|
@ -134,15 +135,16 @@ struct rt_pm_ops
|
|||
|
||||
struct rt_device_pm_ops
|
||||
{
|
||||
int (*suspend)(const struct rt_device *device, rt_uint8_t mode);
|
||||
rt_err_t (*suspend)(const struct rt_device *device, rt_uint8_t mode);
|
||||
void (*resume)(const struct rt_device *device, rt_uint8_t mode);
|
||||
int (*frequency_change)(const struct rt_device *device, rt_uint8_t mode);
|
||||
rt_err_t (*frequency_change)(const struct rt_device *device, rt_uint8_t mode);
|
||||
};
|
||||
|
||||
struct rt_device_pm
|
||||
{
|
||||
const struct rt_device *device;
|
||||
const struct rt_device_pm_ops *ops;
|
||||
rt_slist_t list;
|
||||
};
|
||||
|
||||
struct rt_pm_module
|
||||
|
@ -172,7 +174,7 @@ struct rt_pm
|
|||
rt_uint32_t sleep_status[PM_SLEEP_MODE_MAX - 1][(PM_MODULE_MAX_ID + 31) / 32];
|
||||
|
||||
/* the list of device, which has PM feature */
|
||||
rt_uint8_t device_pm_number;
|
||||
rt_slist_t device_list;
|
||||
struct rt_device_pm *device_pm;
|
||||
|
||||
/* if the mode has timer, the corresponding bit is 1*/
|
||||
|
@ -194,10 +196,10 @@ struct rt_pm_notify
|
|||
void *data;
|
||||
};
|
||||
|
||||
void rt_pm_request(rt_uint8_t sleep_mode);
|
||||
void rt_pm_release(rt_uint8_t sleep_mode);
|
||||
void rt_pm_release_all(rt_uint8_t sleep_mode);
|
||||
int rt_pm_run_enter(rt_uint8_t run_mode);
|
||||
rt_err_t rt_pm_request(rt_uint8_t sleep_mode);
|
||||
rt_err_t rt_pm_release(rt_uint8_t sleep_mode);
|
||||
rt_err_t rt_pm_release_all(rt_uint8_t sleep_mode);
|
||||
rt_err_t rt_pm_run_enter(rt_uint8_t run_mode);
|
||||
|
||||
void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops);
|
||||
void rt_pm_device_unregister(struct rt_device *device);
|
||||
|
@ -208,22 +210,22 @@ void rt_pm_default_set(rt_uint8_t sleep_mode);
|
|||
void rt_system_pm_init(const struct rt_pm_ops *ops,
|
||||
rt_uint8_t timer_mask,
|
||||
void *user_data);
|
||||
void rt_pm_module_request(uint8_t module_id, rt_uint8_t sleep_mode);
|
||||
void rt_pm_module_release(uint8_t module_id, rt_uint8_t sleep_mode);
|
||||
void rt_pm_module_release_all(uint8_t module_id, rt_uint8_t sleep_mode);
|
||||
rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t sleep_mode);
|
||||
rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t sleep_mode);
|
||||
rt_err_t rt_pm_module_release_all(uint8_t module_id, rt_uint8_t sleep_mode);
|
||||
void rt_pm_module_delay_sleep(rt_uint8_t module_id, rt_tick_t timeout);
|
||||
rt_uint32_t rt_pm_module_get_status(void);
|
||||
rt_uint8_t rt_pm_get_sleep_mode(void);
|
||||
struct rt_pm *rt_pm_get_handle(void);
|
||||
|
||||
/* sleep : request or release */
|
||||
void rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode);
|
||||
void rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode);
|
||||
void rt_pm_sleep_none_request(rt_uint16_t module_id);
|
||||
void rt_pm_sleep_none_release(rt_uint16_t module_id);
|
||||
void rt_pm_sleep_idle_request(rt_uint16_t module_id);
|
||||
void rt_pm_sleep_idle_release(rt_uint16_t module_id);
|
||||
void rt_pm_sleep_light_request(rt_uint16_t module_id);
|
||||
void rt_pm_sleep_light_release(rt_uint16_t module_id);
|
||||
rt_err_t rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode);
|
||||
rt_err_t rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode);
|
||||
rt_err_t rt_pm_sleep_none_request(rt_uint16_t module_id);
|
||||
rt_err_t rt_pm_sleep_none_release(rt_uint16_t module_id);
|
||||
rt_err_t rt_pm_sleep_idle_request(rt_uint16_t module_id);
|
||||
rt_err_t rt_pm_sleep_idle_release(rt_uint16_t module_id);
|
||||
rt_err_t rt_pm_sleep_light_request(rt_uint16_t module_id);
|
||||
rt_err_t rt_pm_sleep_light_release(rt_uint16_t module_id);
|
||||
|
||||
#endif /* __PM_H__ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
|
@ -10,6 +10,7 @@
|
|||
* 2019-04-28 Zero-Free improve PM mode and device ops interface
|
||||
* 2020-11-23 zhangsz update pm mode select
|
||||
* 2020-11-27 zhangsz update pm 2.0
|
||||
* 2024-07-04 wdfk-prog The device is registered and uninstalled by linked list
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
|
@ -77,9 +78,6 @@ rt_weak void rt_pm_exit_critical(rt_uint32_t ctx, rt_uint8_t sleep_mode)
|
|||
/* lptimer start */
|
||||
static void pm_lptimer_start(struct rt_pm *pm, uint32_t timeout)
|
||||
{
|
||||
if (_pm.ops == RT_NULL)
|
||||
return;
|
||||
|
||||
if (_pm.ops->timer_start != RT_NULL)
|
||||
_pm.ops->timer_start(pm, timeout);
|
||||
}
|
||||
|
@ -87,9 +85,6 @@ static void pm_lptimer_start(struct rt_pm *pm, uint32_t timeout)
|
|||
/* lptimer stop */
|
||||
static void pm_lptimer_stop(struct rt_pm *pm)
|
||||
{
|
||||
if (_pm.ops == RT_NULL)
|
||||
return;
|
||||
|
||||
if (_pm.ops->timer_stop != RT_NULL)
|
||||
_pm.ops->timer_stop(pm);
|
||||
}
|
||||
|
@ -97,9 +92,6 @@ static void pm_lptimer_stop(struct rt_pm *pm)
|
|||
/* lptimer get timeout tick */
|
||||
static rt_tick_t pm_lptimer_get_timeout(struct rt_pm *pm)
|
||||
{
|
||||
if (_pm.ops == RT_NULL)
|
||||
return RT_TICK_MAX;
|
||||
|
||||
if (_pm.ops->timer_get_tick != RT_NULL)
|
||||
return _pm.ops->timer_get_tick(pm);
|
||||
|
||||
|
@ -109,9 +101,6 @@ static rt_tick_t pm_lptimer_get_timeout(struct rt_pm *pm)
|
|||
/* enter sleep mode */
|
||||
static void pm_sleep(struct rt_pm *pm, uint8_t sleep_mode)
|
||||
{
|
||||
if (_pm.ops == RT_NULL)
|
||||
return;
|
||||
|
||||
if (_pm.ops->sleep != RT_NULL)
|
||||
_pm.ops->sleep(pm, sleep_mode);
|
||||
}
|
||||
|
@ -119,19 +108,24 @@ static void pm_sleep(struct rt_pm *pm, uint8_t sleep_mode)
|
|||
/**
|
||||
* This function will suspend all registered devices
|
||||
*/
|
||||
static int _pm_device_suspend(rt_uint8_t mode)
|
||||
static rt_err_t _pm_device_suspend(rt_uint8_t mode)
|
||||
{
|
||||
int index, ret = RT_EOK;
|
||||
rt_err_t ret = RT_EOK;
|
||||
struct rt_device_pm *device_pm = RT_NULL;
|
||||
rt_slist_t *node = RT_NULL;
|
||||
|
||||
for (index = 0; index < _pm.device_pm_number; index++)
|
||||
for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node))
|
||||
{
|
||||
if (_pm.device_pm[index].ops->suspend != RT_NULL)
|
||||
device_pm = rt_slist_entry(node, struct rt_device_pm, list);
|
||||
if (device_pm->ops != RT_NULL && device_pm->ops->suspend != RT_NULL)
|
||||
{
|
||||
ret = _pm.device_pm[index].ops->suspend(_pm.device_pm[index].device, mode);
|
||||
ret = device_pm->ops->suspend(device_pm->device, mode);
|
||||
if(ret != RT_EOK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -141,13 +135,15 @@ static int _pm_device_suspend(rt_uint8_t mode)
|
|||
*/
|
||||
static void _pm_device_resume(rt_uint8_t mode)
|
||||
{
|
||||
int index;
|
||||
struct rt_device_pm *device_pm = RT_NULL;
|
||||
rt_slist_t *node = RT_NULL;
|
||||
|
||||
for (index = 0; index < _pm.device_pm_number; index++)
|
||||
for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node))
|
||||
{
|
||||
if (_pm.device_pm[index].ops->resume != RT_NULL)
|
||||
device_pm = rt_slist_entry(node, struct rt_device_pm, list);
|
||||
if (device_pm->ops != RT_NULL && device_pm->ops->resume != RT_NULL)
|
||||
{
|
||||
_pm.device_pm[index].ops->resume(_pm.device_pm[index].device, mode);
|
||||
device_pm->ops->resume(device_pm->device, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,13 +153,16 @@ static void _pm_device_resume(rt_uint8_t mode)
|
|||
*/
|
||||
static void _pm_device_frequency_change(rt_uint8_t mode)
|
||||
{
|
||||
rt_uint32_t index;
|
||||
struct rt_device_pm *device_pm = RT_NULL;
|
||||
rt_slist_t *node = RT_NULL;
|
||||
|
||||
/* make the frequency change */
|
||||
for (index = 0; index < _pm.device_pm_number; index ++)
|
||||
for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node))
|
||||
{
|
||||
if (_pm.device_pm[index].ops->frequency_change != RT_NULL)
|
||||
_pm.device_pm[index].ops->frequency_change(_pm.device_pm[index].device, mode);
|
||||
device_pm = rt_slist_entry(node, struct rt_device_pm, list);
|
||||
if (device_pm->ops->frequency_change != RT_NULL)
|
||||
{
|
||||
device_pm->ops->frequency_change(device_pm->device, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,13 +171,16 @@ static void _pm_device_frequency_change(rt_uint8_t mode)
|
|||
*/
|
||||
static void _pm_frequency_scaling(struct rt_pm *pm)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_base_t level = 0;
|
||||
|
||||
if (pm->flags & RT_PM_FREQUENCY_PENDING)
|
||||
{
|
||||
level = rt_hw_interrupt_disable();
|
||||
/* change system runing mode */
|
||||
if(pm->ops->run != RT_NULL)
|
||||
{
|
||||
pm->ops->run(pm, pm->run_mode);
|
||||
}
|
||||
/* changer device frequency */
|
||||
_pm_device_frequency_change(pm->run_mode);
|
||||
pm->flags &= ~RT_PM_FREQUENCY_PENDING;
|
||||
|
@ -288,6 +290,12 @@ static rt_bool_t _pm_device_check_idle(void)
|
|||
return RT_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the next system wake-up time
|
||||
* @note When used by default, it goes into STANDBY mode and sleeps forever. tickless external rewriting is required
|
||||
* @param mode: sleep mode
|
||||
* @retval timeout_tick
|
||||
*/
|
||||
rt_weak rt_tick_t pm_timer_next_timeout_tick(rt_uint8_t mode)
|
||||
{
|
||||
switch (mode)
|
||||
|
@ -344,6 +352,7 @@ rt_weak rt_uint8_t pm_get_sleep_threshold_mode(rt_uint8_t cur_mode, rt_tick_t ti
|
|||
else if (timeout_tick < PM_STANDBY_THRESHOLD_TIME)
|
||||
sleep_mode = PM_SLEEP_MODE_DEEP;
|
||||
}
|
||||
cur_mode = sleep_mode;
|
||||
#else
|
||||
if (timeout_tick < PM_TICKLESS_THRESHOLD_TIME)
|
||||
{
|
||||
|
@ -359,8 +368,8 @@ rt_weak rt_uint8_t pm_get_sleep_threshold_mode(rt_uint8_t cur_mode, rt_tick_t ti
|
|||
*/
|
||||
static void _pm_change_sleep_mode(struct rt_pm *pm)
|
||||
{
|
||||
rt_tick_t timeout_tick, delta_tick;
|
||||
rt_base_t level;
|
||||
rt_tick_t timeout_tick = 0, delta_tick = 0;
|
||||
rt_base_t level = 0;
|
||||
uint8_t sleep_mode = PM_SLEEP_MODE_DEEP;
|
||||
|
||||
level = rt_pm_enter_critical(pm->sleep_mode);
|
||||
|
@ -380,23 +389,27 @@ static void _pm_change_sleep_mode(struct rt_pm *pm)
|
|||
|
||||
if (_pm.sleep_mode == PM_SLEEP_MODE_NONE)
|
||||
{
|
||||
pm->ops->sleep(pm, PM_SLEEP_MODE_NONE);
|
||||
pm_sleep(pm, PM_SLEEP_MODE_NONE);
|
||||
rt_pm_exit_critical(level, pm->sleep_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Notify app will enter sleep mode */
|
||||
if (_pm_notify.notify)
|
||||
{
|
||||
_pm_notify.notify(RT_PM_ENTER_SLEEP, pm->sleep_mode, _pm_notify.data);
|
||||
}
|
||||
|
||||
/* Suspend all peripheral device */
|
||||
#ifdef PM_ENABLE_SUSPEND_SLEEP_MODE
|
||||
int ret = _pm_device_suspend(pm->sleep_mode);
|
||||
rt_err_t ret = _pm_device_suspend(pm->sleep_mode);
|
||||
if (ret != RT_EOK)
|
||||
{
|
||||
_pm_device_resume(pm->sleep_mode);
|
||||
if (_pm_notify.notify)
|
||||
{
|
||||
_pm_notify.notify(RT_PM_EXIT_SLEEP, pm->sleep_mode, _pm_notify.data);
|
||||
}
|
||||
if (pm->sleep_mode > PM_SUSPEND_SLEEP_MODE)
|
||||
{
|
||||
pm->sleep_mode = PM_SUSPEND_SLEEP_MODE;
|
||||
|
@ -418,17 +431,10 @@ static void _pm_change_sleep_mode(struct rt_pm *pm)
|
|||
pm->sleep_mode = pm_get_sleep_threshold_mode(pm->sleep_mode, timeout_tick);
|
||||
|
||||
if (pm->timer_mask & (0x01 << pm->sleep_mode))
|
||||
{
|
||||
if (timeout_tick == RT_TICK_MAX)
|
||||
{
|
||||
pm_lptimer_start(pm, RT_TICK_MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
pm_lptimer_start(pm, timeout_tick);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* enter lower power state */
|
||||
pm_sleep(pm, pm->sleep_mode);
|
||||
|
@ -440,7 +446,9 @@ static void _pm_change_sleep_mode(struct rt_pm *pm)
|
|||
pm_lptimer_stop(pm);
|
||||
if (delta_tick)
|
||||
{
|
||||
rt_tick_set(rt_tick_get() + delta_tick);
|
||||
rt_interrupt_enter();
|
||||
rt_tick_increase_tick(delta_tick);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,14 +459,6 @@ static void _pm_change_sleep_mode(struct rt_pm *pm)
|
|||
_pm_notify.notify(RT_PM_EXIT_SLEEP, pm->sleep_mode, _pm_notify.data);
|
||||
|
||||
rt_pm_exit_critical(level, pm->sleep_mode);
|
||||
|
||||
if (pm->timer_mask & (0x01 << pm->sleep_mode))
|
||||
{
|
||||
if (delta_tick)
|
||||
{
|
||||
rt_timer_check();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,8 +467,10 @@ static void _pm_change_sleep_mode(struct rt_pm *pm)
|
|||
*/
|
||||
void rt_system_power_manager(void)
|
||||
{
|
||||
if (_pm_init_flag == 0)
|
||||
if (_pm_init_flag == 0 || _pm.ops == RT_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* CPU frequency scaling according to the runing mode settings */
|
||||
_pm_frequency_scaling(&_pm);
|
||||
|
@ -483,22 +485,28 @@ void rt_system_power_manager(void)
|
|||
*
|
||||
* @param parameter the parameter of run mode or sleep mode
|
||||
*/
|
||||
void rt_pm_request(rt_uint8_t mode)
|
||||
rt_err_t rt_pm_request(rt_uint8_t mode)
|
||||
{
|
||||
rt_base_t level;
|
||||
struct rt_pm *pm;
|
||||
|
||||
if (_pm_init_flag == 0)
|
||||
return;
|
||||
{
|
||||
return -RT_EPERM;
|
||||
}
|
||||
|
||||
if (mode > (PM_SLEEP_MODE_MAX - 1))
|
||||
return;
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
pm = &_pm;
|
||||
if (pm->modes[mode] < 255)
|
||||
pm->modes[mode] ++;
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -508,22 +516,28 @@ void rt_pm_request(rt_uint8_t mode)
|
|||
* @param parameter the parameter of run mode or sleep mode
|
||||
*
|
||||
*/
|
||||
void rt_pm_release(rt_uint8_t mode)
|
||||
rt_err_t rt_pm_release(rt_uint8_t mode)
|
||||
{
|
||||
rt_base_t level;
|
||||
struct rt_pm *pm;
|
||||
|
||||
if (_pm_init_flag == 0)
|
||||
return;
|
||||
{
|
||||
return -RT_EPERM;
|
||||
}
|
||||
|
||||
if (mode > (PM_SLEEP_MODE_MAX - 1))
|
||||
return;
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
pm = &_pm;
|
||||
if (pm->modes[mode] > 0)
|
||||
pm->modes[mode] --;
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -533,21 +547,27 @@ void rt_pm_release(rt_uint8_t mode)
|
|||
* @param parameter the parameter of run mode or sleep mode
|
||||
*
|
||||
*/
|
||||
void rt_pm_release_all(rt_uint8_t mode)
|
||||
rt_err_t rt_pm_release_all(rt_uint8_t mode)
|
||||
{
|
||||
rt_base_t level;
|
||||
struct rt_pm *pm;
|
||||
|
||||
if (_pm_init_flag == 0)
|
||||
return;
|
||||
{
|
||||
return -RT_EPERM;
|
||||
}
|
||||
|
||||
if (mode > (PM_SLEEP_MODE_MAX - 1))
|
||||
return;
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
pm = &_pm;
|
||||
pm->modes[mode] = 0;
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -557,19 +577,25 @@ void rt_pm_release_all(rt_uint8_t mode)
|
|||
* @param module_id the application or device module id
|
||||
* @param mode the system power sleep mode
|
||||
*/
|
||||
void rt_pm_module_request(uint8_t module_id, rt_uint8_t mode)
|
||||
rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t mode)
|
||||
{
|
||||
rt_base_t level;
|
||||
struct rt_pm *pm;
|
||||
|
||||
if (_pm_init_flag == 0)
|
||||
return;
|
||||
{
|
||||
return -RT_EPERM;
|
||||
}
|
||||
|
||||
if (mode > (PM_SLEEP_MODE_MAX - 1))
|
||||
return;
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if (module_id > (PM_MODULE_MAX_ID - 1))
|
||||
return;
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
pm = &_pm;
|
||||
|
@ -577,6 +603,8 @@ void rt_pm_module_request(uint8_t module_id, rt_uint8_t mode)
|
|||
if (pm->modes[mode] < 255)
|
||||
pm->modes[mode] ++;
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -587,19 +615,25 @@ void rt_pm_module_request(uint8_t module_id, rt_uint8_t mode)
|
|||
* @param mode the system power sleep mode
|
||||
*
|
||||
*/
|
||||
void rt_pm_module_release(uint8_t module_id, rt_uint8_t mode)
|
||||
rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t mode)
|
||||
{
|
||||
rt_base_t level;
|
||||
struct rt_pm *pm;
|
||||
|
||||
if (_pm_init_flag == 0)
|
||||
return;
|
||||
{
|
||||
return -RT_EPERM;
|
||||
}
|
||||
|
||||
if (mode > (PM_SLEEP_MODE_MAX - 1))
|
||||
return;
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if (module_id > (PM_MODULE_MAX_ID - 1))
|
||||
return;
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
pm = &_pm;
|
||||
|
@ -608,6 +642,8 @@ void rt_pm_module_release(uint8_t module_id, rt_uint8_t mode)
|
|||
if (pm->modes[mode] == 0)
|
||||
pm->module_status[module_id].req_status = 0x00;
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -618,22 +654,28 @@ void rt_pm_module_release(uint8_t module_id, rt_uint8_t mode)
|
|||
* @param mode the system power sleep mode
|
||||
*
|
||||
*/
|
||||
void rt_pm_module_release_all(uint8_t module_id, rt_uint8_t mode)
|
||||
rt_err_t rt_pm_module_release_all(uint8_t module_id, rt_uint8_t mode)
|
||||
{
|
||||
rt_base_t level;
|
||||
struct rt_pm *pm;
|
||||
|
||||
if (_pm_init_flag == 0)
|
||||
return;
|
||||
{
|
||||
return -RT_EPERM;
|
||||
}
|
||||
|
||||
if (mode > (PM_SLEEP_MODE_MAX - 1))
|
||||
return;
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
pm = &_pm;
|
||||
pm->modes[mode] = 0;
|
||||
pm->module_status[module_id].req_status = 0x00;
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -644,23 +686,24 @@ void rt_pm_module_release_all(uint8_t module_id, rt_uint8_t mode)
|
|||
*
|
||||
* @return none
|
||||
*/
|
||||
void rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode)
|
||||
rt_err_t rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
if (module_id >= PM_MODULE_MAX_ID)
|
||||
{
|
||||
return;
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if (mode >= (PM_SLEEP_MODE_MAX - 1))
|
||||
{
|
||||
return;
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
_pm.sleep_status[mode][module_id / 32] |= 1 << (module_id % 32);
|
||||
rt_hw_interrupt_enable(level);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -670,9 +713,9 @@ void rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode)
|
|||
*
|
||||
* @return NULL
|
||||
*/
|
||||
void rt_pm_sleep_none_request(rt_uint16_t module_id)
|
||||
rt_err_t rt_pm_sleep_none_request(rt_uint16_t module_id)
|
||||
{
|
||||
rt_pm_sleep_request(module_id, PM_SLEEP_MODE_NONE);
|
||||
return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -682,9 +725,9 @@ void rt_pm_sleep_none_request(rt_uint16_t module_id)
|
|||
*
|
||||
* @return NULL
|
||||
*/
|
||||
void rt_pm_sleep_idle_request(rt_uint16_t module_id)
|
||||
rt_err_t rt_pm_sleep_idle_request(rt_uint16_t module_id)
|
||||
{
|
||||
rt_pm_sleep_request(module_id, PM_SLEEP_MODE_IDLE);
|
||||
return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_IDLE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -694,9 +737,9 @@ void rt_pm_sleep_idle_request(rt_uint16_t module_id)
|
|||
*
|
||||
* @return NULL
|
||||
*/
|
||||
void rt_pm_sleep_light_request(rt_uint16_t module_id)
|
||||
rt_err_t rt_pm_sleep_light_request(rt_uint16_t module_id)
|
||||
{
|
||||
rt_pm_sleep_request(module_id, PM_SLEEP_MODE_LIGHT);
|
||||
return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_LIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -707,23 +750,24 @@ void rt_pm_sleep_light_request(rt_uint16_t module_id)
|
|||
*
|
||||
* @return NULL
|
||||
*/
|
||||
void rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode)
|
||||
rt_err_t rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
if (module_id >= PM_MODULE_MAX_ID)
|
||||
{
|
||||
return;
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if (mode >= (PM_SLEEP_MODE_MAX - 1))
|
||||
{
|
||||
return;
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
_pm.sleep_status[mode][module_id / 32] &= ~(1 << (module_id % 32));
|
||||
rt_hw_interrupt_enable(level);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -733,9 +777,9 @@ void rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode)
|
|||
*
|
||||
* @return none
|
||||
*/
|
||||
void rt_pm_sleep_none_release(rt_uint16_t module_id)
|
||||
rt_err_t rt_pm_sleep_none_release(rt_uint16_t module_id)
|
||||
{
|
||||
rt_pm_sleep_release(module_id, PM_SLEEP_MODE_NONE);
|
||||
return rt_pm_sleep_release(module_id, PM_SLEEP_MODE_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -745,9 +789,9 @@ void rt_pm_sleep_none_release(rt_uint16_t module_id)
|
|||
*
|
||||
* @return none
|
||||
*/
|
||||
void rt_pm_sleep_idle_release(rt_uint16_t module_id)
|
||||
rt_err_t rt_pm_sleep_idle_release(rt_uint16_t module_id)
|
||||
{
|
||||
rt_pm_sleep_release(module_id, PM_SLEEP_MODE_IDLE);
|
||||
return rt_pm_sleep_release(module_id, PM_SLEEP_MODE_IDLE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -757,9 +801,9 @@ void rt_pm_sleep_idle_release(rt_uint16_t module_id)
|
|||
*
|
||||
* @return none
|
||||
*/
|
||||
void rt_pm_sleep_light_release(rt_uint16_t module_id)
|
||||
rt_err_t rt_pm_sleep_light_release(rt_uint16_t module_id)
|
||||
{
|
||||
rt_pm_sleep_release(module_id, PM_SLEEP_MODE_LIGHT);
|
||||
return rt_pm_sleep_release(module_id, PM_SLEEP_MODE_LIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -770,24 +814,15 @@ void rt_pm_sleep_light_release(rt_uint16_t module_id)
|
|||
*/
|
||||
void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops)
|
||||
{
|
||||
rt_base_t level;
|
||||
struct rt_device_pm *device_pm;
|
||||
|
||||
RT_DEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
device_pm = (struct rt_device_pm *)RT_KERNEL_REALLOC(_pm.device_pm,
|
||||
(_pm.device_pm_number + 1) * sizeof(struct rt_device_pm));
|
||||
device_pm = RT_KERNEL_MALLOC(sizeof(struct rt_device_pm));
|
||||
if (device_pm != RT_NULL)
|
||||
{
|
||||
_pm.device_pm = device_pm;
|
||||
_pm.device_pm[_pm.device_pm_number].device = device;
|
||||
_pm.device_pm[_pm.device_pm_number].ops = ops;
|
||||
_pm.device_pm_number += 1;
|
||||
rt_slist_append(&_pm.device_list, &device_pm->list);
|
||||
device_pm->device = device;
|
||||
device_pm->ops = ops;
|
||||
}
|
||||
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -797,32 +832,18 @@ void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_o
|
|||
*/
|
||||
void rt_pm_device_unregister(struct rt_device *device)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_uint32_t index;
|
||||
RT_DEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
for (index = 0; index < _pm.device_pm_number; index ++)
|
||||
struct rt_device_pm *device_pm = RT_NULL;
|
||||
rt_slist_t *node = RT_NULL;
|
||||
for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node))
|
||||
{
|
||||
if (_pm.device_pm[index].device == device)
|
||||
device_pm = rt_slist_entry(node, struct rt_device_pm, list);
|
||||
if (device_pm->device == device)
|
||||
{
|
||||
/* remove current entry */
|
||||
for (; index < _pm.device_pm_number - 1; index ++)
|
||||
{
|
||||
_pm.device_pm[index] = _pm.device_pm[index + 1];
|
||||
}
|
||||
|
||||
_pm.device_pm[_pm.device_pm_number - 1].device = RT_NULL;
|
||||
_pm.device_pm[_pm.device_pm_number - 1].ops = RT_NULL;
|
||||
|
||||
_pm.device_pm_number -= 1;
|
||||
/* break out and not touch memory */
|
||||
rt_slist_remove(&_pm.device_list, &device_pm->list);
|
||||
RT_KERNEL_FREE(device_pm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -914,10 +935,11 @@ static rt_err_t _rt_pm_device_control(rt_device_t dev,
|
|||
return RT_EOK;
|
||||
}
|
||||
|
||||
int rt_pm_run_enter(rt_uint8_t mode)
|
||||
rt_err_t rt_pm_run_enter(rt_uint8_t mode)
|
||||
{
|
||||
rt_base_t level;
|
||||
struct rt_pm *pm;
|
||||
rt_base_t level = 0;
|
||||
struct rt_pm *pm = RT_NULL;
|
||||
rt_err_t ret = RT_EOK;
|
||||
|
||||
if (_pm_init_flag == 0)
|
||||
return -RT_EIO;
|
||||
|
@ -925,12 +947,16 @@ int rt_pm_run_enter(rt_uint8_t mode)
|
|||
if (mode > PM_RUN_MODE_MAX)
|
||||
return -RT_EINVAL;
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
pm = &_pm;
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
if (mode < pm->run_mode)
|
||||
{
|
||||
/* change system runing mode */
|
||||
if(pm->ops != RT_NULL && pm->ops->run != RT_NULL)
|
||||
{
|
||||
pm->ops->run(pm, mode);
|
||||
}
|
||||
/* changer device frequency */
|
||||
_pm_device_frequency_change(mode);
|
||||
}
|
||||
|
@ -941,7 +967,7 @@ int rt_pm_run_enter(rt_uint8_t mode)
|
|||
pm->run_mode = mode;
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
return RT_EOK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
|
@ -1004,7 +1030,8 @@ void rt_system_pm_init(const struct rt_pm_ops *ops,
|
|||
pm->ops = ops;
|
||||
|
||||
pm->device_pm = RT_NULL;
|
||||
pm->device_pm_number = 0;
|
||||
|
||||
rt_slist_init(&pm->device_list);
|
||||
|
||||
#if IDLE_THREAD_STACK_SIZE <= 256
|
||||
#error "[pm.c ERR] IDLE Stack Size Too Small!"
|
||||
|
|
Loading…
Reference in New Issue