mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 01:21:26 +08:00
regulator:optimize the lock to support call the interface in idle task by pm
support call api in idle task Signed-off-by: dulibo1 <dulibo1@xiaomi.com>
This commit is contained in:
@@ -54,6 +54,8 @@ static int _regulator_set_voltage_unlocked(FAR struct regulator_s *regulator,
|
|||||||
int min_uv, int max_uv);
|
int min_uv, int max_uv);
|
||||||
static int _regulator_do_enable_pulldown(FAR struct regulator_dev_s *rdev);
|
static int _regulator_do_enable_pulldown(FAR struct regulator_dev_s *rdev);
|
||||||
static int _regulator_do_disable_pulldown(FAR struct regulator_dev_s *rdev);
|
static int _regulator_do_disable_pulldown(FAR struct regulator_dev_s *rdev);
|
||||||
|
static irqstate_t regulator_lock(FAR mutex_t *lock);
|
||||||
|
static void regulator_unlock(FAR mutex_t *lock, irqstate_t flags);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
@@ -200,10 +202,11 @@ static int regulator_check_consumers(FAR struct regulator_dev_s *rdev,
|
|||||||
|
|
||||||
static FAR struct regulator_dev_s *regulator_dev_lookup(const char *supply)
|
static FAR struct regulator_dev_s *regulator_dev_lookup(const char *supply)
|
||||||
{
|
{
|
||||||
|
irqstate_t flags;
|
||||||
FAR struct regulator_dev_s *rdev;
|
FAR struct regulator_dev_s *rdev;
|
||||||
FAR struct regulator_dev_s *rdev_found = NULL;
|
FAR struct regulator_dev_s *rdev_found = NULL;
|
||||||
|
|
||||||
nxmutex_lock(&g_reg_lock);
|
flags = regulator_lock(&g_reg_lock);
|
||||||
list_for_every_entry(&g_reg_list, rdev, struct regulator_dev_s, list)
|
list_for_every_entry(&g_reg_list, rdev, struct regulator_dev_s, list)
|
||||||
{
|
{
|
||||||
if (rdev->desc->name && strcmp(rdev->desc->name, supply) == 0)
|
if (rdev->desc->name && strcmp(rdev->desc->name, supply) == 0)
|
||||||
@@ -213,7 +216,7 @@ static FAR struct regulator_dev_s *regulator_dev_lookup(const char *supply)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nxmutex_unlock(&g_reg_lock);
|
regulator_unlock(&g_reg_lock, flags);
|
||||||
|
|
||||||
#if defined(CONFIG_REGULATOR_RPMSG)
|
#if defined(CONFIG_REGULATOR_RPMSG)
|
||||||
if (rdev_found == NULL && strchr(supply, '/'))
|
if (rdev_found == NULL && strchr(supply, '/'))
|
||||||
@@ -514,6 +517,27 @@ static void regulator_pm_notify(struct pm_callback_s *cb, int domain,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static irqstate_t regulator_lock(FAR mutex_t *lock)
|
||||||
|
{
|
||||||
|
if (!up_interrupt_context() && !sched_idletask())
|
||||||
|
{
|
||||||
|
nxmutex_lock(lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return enter_critical_section();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void regulator_unlock(FAR mutex_t *lock, irqstate_t flags)
|
||||||
|
{
|
||||||
|
leave_critical_section(flags);
|
||||||
|
|
||||||
|
if (!up_interrupt_context() && !sched_idletask())
|
||||||
|
{
|
||||||
|
nxmutex_unlock(lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -534,6 +558,7 @@ static void regulator_pm_notify(struct pm_callback_s *cb, int domain,
|
|||||||
|
|
||||||
FAR struct regulator_s *regulator_get(FAR const char *id)
|
FAR struct regulator_s *regulator_get(FAR const char *id)
|
||||||
{
|
{
|
||||||
|
irqstate_t flags;
|
||||||
FAR struct regulator_dev_s *rdev;
|
FAR struct regulator_dev_s *rdev;
|
||||||
FAR struct regulator_s *regulator = NULL;
|
FAR struct regulator_s *regulator = NULL;
|
||||||
|
|
||||||
@@ -560,10 +585,10 @@ FAR struct regulator_s *regulator_get(FAR const char *id)
|
|||||||
regulator->rdev = rdev;
|
regulator->rdev = rdev;
|
||||||
list_initialize(®ulator->list);
|
list_initialize(®ulator->list);
|
||||||
|
|
||||||
nxmutex_lock(&rdev->regulator_lock);
|
flags = regulator_lock(&rdev->regulator_lock);
|
||||||
rdev->open_count++;
|
rdev->open_count++;
|
||||||
list_add_tail(&rdev->consumer_list, ®ulator->list);
|
list_add_tail(&rdev->consumer_list, ®ulator->list);
|
||||||
nxmutex_unlock(&rdev->regulator_lock);
|
regulator_unlock(&rdev->regulator_lock, flags);
|
||||||
|
|
||||||
return regulator;
|
return regulator;
|
||||||
}
|
}
|
||||||
@@ -584,6 +609,7 @@ FAR struct regulator_s *regulator_get(FAR const char *id)
|
|||||||
void regulator_put(FAR struct regulator_s *regulator)
|
void regulator_put(FAR struct regulator_s *regulator)
|
||||||
{
|
{
|
||||||
FAR struct regulator_dev_s *rdev;
|
FAR struct regulator_dev_s *rdev;
|
||||||
|
irqstate_t flags;
|
||||||
|
|
||||||
if (regulator == NULL)
|
if (regulator == NULL)
|
||||||
{
|
{
|
||||||
@@ -591,15 +617,10 @@ void regulator_put(FAR struct regulator_s *regulator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rdev = regulator->rdev;
|
rdev = regulator->rdev;
|
||||||
|
flags = regulator_lock(&rdev->regulator_lock);
|
||||||
nxmutex_lock(&g_reg_lock);
|
|
||||||
|
|
||||||
nxmutex_lock(&rdev->regulator_lock);
|
|
||||||
list_delete(®ulator->list);
|
list_delete(®ulator->list);
|
||||||
rdev->open_count--;
|
rdev->open_count--;
|
||||||
nxmutex_unlock(&rdev->regulator_lock);
|
regulator_unlock(&rdev->regulator_lock, flags);
|
||||||
|
|
||||||
nxmutex_unlock(&g_reg_lock);
|
|
||||||
|
|
||||||
kmm_free(regulator);
|
kmm_free(regulator);
|
||||||
}
|
}
|
||||||
@@ -621,6 +642,7 @@ void regulator_put(FAR struct regulator_s *regulator)
|
|||||||
int regulator_is_enabled(FAR struct regulator_s *regulator)
|
int regulator_is_enabled(FAR struct regulator_s *regulator)
|
||||||
{
|
{
|
||||||
FAR struct regulator_dev_s *rdev;
|
FAR struct regulator_dev_s *rdev;
|
||||||
|
irqstate_t flags;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (regulator == NULL)
|
if (regulator == NULL)
|
||||||
@@ -636,10 +658,9 @@ int regulator_is_enabled(FAR struct regulator_s *regulator)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxmutex_lock(&rdev->regulator_lock);
|
flags = regulator_lock(&rdev->regulator_lock);
|
||||||
ret = _regulator_is_enabled(rdev);
|
ret = _regulator_is_enabled(rdev);
|
||||||
nxmutex_unlock(&rdev->regulator_lock);
|
regulator_unlock(&rdev->regulator_lock, flags);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,6 +681,7 @@ int regulator_is_enabled(FAR struct regulator_s *regulator)
|
|||||||
int regulator_enable(FAR struct regulator_s *regulator)
|
int regulator_enable(FAR struct regulator_s *regulator)
|
||||||
{
|
{
|
||||||
FAR struct regulator_dev_s *rdev;
|
FAR struct regulator_dev_s *rdev;
|
||||||
|
irqstate_t flags;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (regulator == NULL)
|
if (regulator == NULL)
|
||||||
@@ -670,7 +692,7 @@ int regulator_enable(FAR struct regulator_s *regulator)
|
|||||||
|
|
||||||
rdev = regulator->rdev;
|
rdev = regulator->rdev;
|
||||||
|
|
||||||
nxmutex_lock(&rdev->regulator_lock);
|
flags = regulator_lock(&rdev->regulator_lock);
|
||||||
if (rdev->use_count == 0 && !rdev->desc->always_on)
|
if (rdev->use_count == 0 && !rdev->desc->always_on)
|
||||||
{
|
{
|
||||||
ret = _regulator_do_enable(rdev);
|
ret = _regulator_do_enable(rdev);
|
||||||
@@ -683,7 +705,7 @@ int regulator_enable(FAR struct regulator_s *regulator)
|
|||||||
rdev->use_count++;
|
rdev->use_count++;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
nxmutex_unlock(&rdev->regulator_lock);
|
regulator_unlock(&rdev->regulator_lock, flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -732,6 +754,7 @@ int regulator_enable_delay(FAR struct regulator_s *regulator, int ms)
|
|||||||
int regulator_disable(FAR struct regulator_s *regulator)
|
int regulator_disable(FAR struct regulator_s *regulator)
|
||||||
{
|
{
|
||||||
FAR struct regulator_dev_s *rdev;
|
FAR struct regulator_dev_s *rdev;
|
||||||
|
irqstate_t flags;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (regulator == NULL)
|
if (regulator == NULL)
|
||||||
@@ -742,7 +765,7 @@ int regulator_disable(FAR struct regulator_s *regulator)
|
|||||||
|
|
||||||
rdev = regulator->rdev;
|
rdev = regulator->rdev;
|
||||||
|
|
||||||
nxmutex_lock(&rdev->regulator_lock);
|
flags = regulator_lock(&rdev->regulator_lock);
|
||||||
if (rdev->use_count <= 0)
|
if (rdev->use_count <= 0)
|
||||||
{
|
{
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
@@ -761,7 +784,7 @@ int regulator_disable(FAR struct regulator_s *regulator)
|
|||||||
rdev->use_count--;
|
rdev->use_count--;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
nxmutex_unlock(&rdev->regulator_lock);
|
regulator_unlock(&rdev->regulator_lock, flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -811,6 +834,7 @@ int regulator_set_voltage(FAR struct regulator_s *regulator,
|
|||||||
int min_uv, int max_uv)
|
int min_uv, int max_uv)
|
||||||
{
|
{
|
||||||
FAR struct regulator_dev_s *rdev;
|
FAR struct regulator_dev_s *rdev;
|
||||||
|
irqstate_t flags;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (regulator == NULL)
|
if (regulator == NULL)
|
||||||
@@ -821,9 +845,9 @@ int regulator_set_voltage(FAR struct regulator_s *regulator,
|
|||||||
|
|
||||||
rdev = regulator->rdev;
|
rdev = regulator->rdev;
|
||||||
|
|
||||||
nxmutex_lock(&rdev->regulator_lock);
|
flags = regulator_lock(&rdev->regulator_lock);
|
||||||
ret = _regulator_set_voltage_unlocked(regulator, min_uv, max_uv);
|
ret = _regulator_set_voltage_unlocked(regulator, min_uv, max_uv);
|
||||||
nxmutex_unlock(&rdev->regulator_lock);
|
regulator_unlock(&rdev->regulator_lock, flags);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -845,6 +869,7 @@ int regulator_set_voltage(FAR struct regulator_s *regulator,
|
|||||||
int regulator_get_voltage(FAR struct regulator_s *regulator)
|
int regulator_get_voltage(FAR struct regulator_s *regulator)
|
||||||
{
|
{
|
||||||
FAR struct regulator_dev_s *rdev;
|
FAR struct regulator_dev_s *rdev;
|
||||||
|
irqstate_t flags;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (regulator == NULL)
|
if (regulator == NULL)
|
||||||
@@ -855,9 +880,9 @@ int regulator_get_voltage(FAR struct regulator_s *regulator)
|
|||||||
|
|
||||||
rdev = regulator->rdev;
|
rdev = regulator->rdev;
|
||||||
|
|
||||||
nxmutex_lock(&rdev->regulator_lock);
|
flags = regulator_lock(&rdev->regulator_lock);
|
||||||
ret = _regulator_get_voltage(rdev);
|
ret = _regulator_get_voltage(rdev);
|
||||||
nxmutex_unlock(&rdev->regulator_lock);
|
regulator_unlock(&rdev->regulator_lock, flags);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -883,9 +908,10 @@ int regulator_set_mode(FAR struct regulator_s *regulator,
|
|||||||
{
|
{
|
||||||
FAR struct regulator_dev_s *rdev = regulator->rdev;
|
FAR struct regulator_dev_s *rdev = regulator->rdev;
|
||||||
unsigned int curr_mode;
|
unsigned int curr_mode;
|
||||||
|
irqstate_t flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
nxmutex_lock(&rdev->regulator_lock);
|
flags = regulator_lock(&rdev->regulator_lock);
|
||||||
if (!rdev->ops->set_mode || mode == REGULATOR_MODE_INVALID)
|
if (!rdev->ops->set_mode || mode == REGULATOR_MODE_INVALID)
|
||||||
{
|
{
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
@@ -904,7 +930,7 @@ int regulator_set_mode(FAR struct regulator_s *regulator,
|
|||||||
|
|
||||||
ret = rdev->ops->set_mode(rdev, mode);
|
ret = rdev->ops->set_mode(rdev, mode);
|
||||||
out:
|
out:
|
||||||
nxmutex_unlock(&rdev->regulator_lock);
|
regulator_unlock(&rdev->regulator_lock, flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -923,6 +949,7 @@ regulator_register(FAR const struct regulator_desc_s *regulator_desc,
|
|||||||
FAR void *priv)
|
FAR void *priv)
|
||||||
{
|
{
|
||||||
FAR struct regulator_dev_s *rdev;
|
FAR struct regulator_dev_s *rdev;
|
||||||
|
irqstate_t flags;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (regulator_desc == NULL)
|
if (regulator_desc == NULL)
|
||||||
@@ -1015,9 +1042,9 @@ regulator_register(FAR const struct regulator_desc_s *regulator_desc,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nxmutex_lock(&g_reg_lock);
|
flags = regulator_lock(&g_reg_lock);
|
||||||
list_add_tail(&g_reg_list, &rdev->list);
|
list_add_tail(&g_reg_list, &rdev->list);
|
||||||
nxmutex_unlock(&g_reg_lock);
|
regulator_unlock(&g_reg_lock, flags);
|
||||||
|
|
||||||
return rdev;
|
return rdev;
|
||||||
}
|
}
|
||||||
@@ -1033,21 +1060,23 @@ regulator_register(FAR const struct regulator_desc_s *regulator_desc,
|
|||||||
|
|
||||||
void regulator_unregister(FAR struct regulator_dev_s *rdev)
|
void regulator_unregister(FAR struct regulator_dev_s *rdev)
|
||||||
{
|
{
|
||||||
|
irqstate_t flags;
|
||||||
|
|
||||||
if (rdev == NULL)
|
if (rdev == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxmutex_lock(&g_reg_lock);
|
flags = regulator_lock(&g_reg_lock);
|
||||||
if (rdev->open_count)
|
if (rdev->open_count)
|
||||||
{
|
{
|
||||||
pwrerr("unregister, open %" PRIu32 "\n", rdev->open_count);
|
pwrerr("unregister, open %" PRIu32 "\n", rdev->open_count);
|
||||||
nxmutex_unlock(&g_reg_lock);
|
regulator_unlock(&g_reg_lock, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_delete(&rdev->list);
|
list_delete(&rdev->list);
|
||||||
nxmutex_unlock(&g_reg_lock);
|
regulator_unlock(&g_reg_lock, flags);
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
if (rdev->desc->auto_lp)
|
if (rdev->desc->auto_lp)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user