summaryrefslogtreecommitdiff
path: root/components/drivers
diff options
context:
space:
mode:
authorwdfk-prog <[email protected]>2024-07-11 15:57:51 +0800
committerRbb666 <[email protected]>2024-07-19 11:51:39 +0800
commitbceb6635b09451e9d8ec150cd57f82b6a8cedfc1 (patch)
tree3a1864cb33151fe47840b21bb99e2f2b6f7b4212 /components/drivers
parent8d3ad68caf91f12d11cc25bfb53f0cedb5eae380 (diff)
[compoents][pm]The device is registered and uninstalled by linked list
Diffstat (limited to 'components/drivers')
-rw-r--r--components/drivers/include/drivers/pm.h40
-rw-r--r--components/drivers/pm/pm.c287
2 files changed, 178 insertions, 149 deletions
diff --git a/components/drivers/include/drivers/pm.h b/components/drivers/include/drivers/pm.h
index 45b3ae09e6..f625782616 100644
--- a/components/drivers/include/drivers/pm.h
+++ b/components/drivers/include/drivers/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
*/
#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__ */
diff --git a/components/drivers/pm/pm.c b/components/drivers/pm/pm.c
index 024e301792..b4ad3b2bbd 100644
--- a/components/drivers/pm/pm.c
+++ b/components/drivers/pm/pm.c
@@ -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,17 +108,22 @@ 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;
+ }
}
}
@@ -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 */
- pm->ops->run(pm, pm->run_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;
@@ -419,14 +432,7 @@ static void _pm_change_sleep_mode(struct rt_pm *pm)
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);
- }
+ pm_lptimer_start(pm, timeout_tick);
}
}
@@ -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 */
- pm->ops->run(pm, 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!"