mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 01:21:26 +08:00
regualtor:adjust the critical area protected
Signed-off-by: dulibo1 <dulibo1@xiaomi.com> Signed-off-by: buxiasen <buxiasen@xiaomi.com>
This commit is contained in:
@@ -57,13 +57,15 @@ 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 irqstate_t regulator_lock(FAR mutex_t *lock);
|
||||||
static void regulator_unlock(FAR mutex_t *lock, irqstate_t flags);
|
static void regulator_unlock(FAR mutex_t *lock, irqstate_t flags);
|
||||||
|
static irqstate_t regulator_list_lock(void);
|
||||||
|
static void regulator_list_unlock(irqstate_t flags);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static struct list_node g_reg_list = LIST_INITIAL_VALUE(g_reg_list);
|
static struct list_node g_reg_list = LIST_INITIAL_VALUE(g_reg_list);
|
||||||
static mutex_t g_reg_lock = NXMUTEX_INITIALIZER;
|
static rmutex_t g_reg_lock = NXRMUTEX_INITIALIZER;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
@@ -203,11 +205,9 @@ 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;
|
||||||
|
|
||||||
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)
|
||||||
@@ -217,7 +217,6 @@ static FAR struct regulator_dev_s *regulator_dev_lookup(const char *supply)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
regulator_unlock(&g_reg_lock, flags);
|
|
||||||
return rdev_found;
|
return rdev_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,6 +530,26 @@ static void regulator_unlock(FAR mutex_t *lock, irqstate_t flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static irqstate_t regulator_list_lock(void)
|
||||||
|
{
|
||||||
|
if (!up_interrupt_context() && !sched_idletask())
|
||||||
|
{
|
||||||
|
nxrmutex_lock(&g_reg_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return enter_critical_section();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void regulator_list_unlock(irqstate_t flags)
|
||||||
|
{
|
||||||
|
leave_critical_section(flags);
|
||||||
|
|
||||||
|
if (!up_interrupt_context() && !sched_idletask())
|
||||||
|
{
|
||||||
|
nxrmutex_unlock(&g_reg_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -561,6 +580,7 @@ FAR struct regulator_s *regulator_get(FAR const char *id)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flags = regulator_list_lock();
|
||||||
rdev = regulator_dev_lookup(id);
|
rdev = regulator_dev_lookup(id);
|
||||||
|
|
||||||
#if defined(CONFIG_REGULATOR_RPMSG)
|
#if defined(CONFIG_REGULATOR_RPMSG)
|
||||||
@@ -570,6 +590,8 @@ FAR struct regulator_s *regulator_get(FAR const char *id)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
regulator_list_unlock(flags);
|
||||||
|
|
||||||
if (rdev == NULL)
|
if (rdev == NULL)
|
||||||
{
|
{
|
||||||
pwrerr("regulator %s not found\n", id);
|
pwrerr("regulator %s not found\n", id);
|
||||||
@@ -949,57 +971,59 @@ regulator_register(FAR const struct regulator_desc_s *regulator_desc,
|
|||||||
FAR const struct regulator_ops_s *regulator_ops,
|
FAR const struct regulator_ops_s *regulator_ops,
|
||||||
FAR void *priv)
|
FAR void *priv)
|
||||||
{
|
{
|
||||||
FAR struct regulator_dev_s *rdev;
|
FAR struct regulator_dev_s *rdev = NULL;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
flags = regulator_list_lock();
|
||||||
|
|
||||||
if (regulator_desc == NULL)
|
if (regulator_desc == NULL)
|
||||||
{
|
{
|
||||||
pwrerr("regulator desc is null\n");
|
pwrerr("regulator desc is null\n");
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regulator_desc->name == NULL || regulator_ops == NULL)
|
if (regulator_desc->name == NULL || regulator_ops == NULL)
|
||||||
{
|
{
|
||||||
pwrerr("regulator name or ops is null\n");
|
pwrerr("regulator name or ops is null\n");
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regulator_dev_lookup(regulator_desc->name))
|
if (regulator_dev_lookup(regulator_desc->name))
|
||||||
{
|
{
|
||||||
pwrerr("regulator name is registered\n");
|
pwrerr("regulator name is registered\n");
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regulator_ops->get_voltage && regulator_ops->get_voltage_sel)
|
if (regulator_ops->get_voltage && regulator_ops->get_voltage_sel)
|
||||||
{
|
{
|
||||||
pwrerr("get_voltage and get_voltage_sel are both assigned\n");
|
pwrerr("get_voltage and get_voltage_sel are both assigned\n");
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regulator_ops->set_voltage && regulator_ops->set_voltage_sel)
|
if (regulator_ops->set_voltage && regulator_ops->set_voltage_sel)
|
||||||
{
|
{
|
||||||
pwrerr("set_voltage and set_voltage_sel are both assigned\n");
|
pwrerr("set_voltage and set_voltage_sel are both assigned\n");
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regulator_ops->get_voltage_sel && !regulator_ops->list_voltage)
|
if (regulator_ops->get_voltage_sel && !regulator_ops->list_voltage)
|
||||||
{
|
{
|
||||||
pwrerr("list voltage is null\n");
|
pwrerr("list voltage is null\n");
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regulator_ops->set_voltage_sel && !regulator_ops->list_voltage)
|
if (regulator_ops->set_voltage_sel && !regulator_ops->list_voltage)
|
||||||
{
|
{
|
||||||
pwrerr("list voltage is null\n");
|
pwrerr("list voltage is null\n");
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdev = kmm_zalloc(sizeof(struct regulator_dev_s));
|
rdev = kmm_zalloc(sizeof(struct regulator_dev_s));
|
||||||
if (rdev == NULL)
|
if (rdev == NULL)
|
||||||
{
|
{
|
||||||
pwrerr("failed to get memory\n");
|
pwrerr("failed to get memory\n");
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdev->desc = regulator_desc;
|
rdev->desc = regulator_desc;
|
||||||
@@ -1016,7 +1040,8 @@ regulator_register(FAR const struct regulator_desc_s *regulator_desc,
|
|||||||
{
|
{
|
||||||
pwrerr("failed to enable regulator\n");
|
pwrerr("failed to enable regulator\n");
|
||||||
kmm_free(rdev);
|
kmm_free(rdev);
|
||||||
return NULL;
|
rdev = NULL;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!rdev->desc->boot_on && !rdev->desc->always_on
|
else if (!rdev->desc->boot_on && !rdev->desc->always_on
|
||||||
@@ -1049,10 +1074,10 @@ regulator_register(FAR const struct regulator_desc_s *regulator_desc,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
flags = regulator_lock(&g_reg_lock);
|
|
||||||
list_add_tail(&g_reg_list, &rdev->list);
|
list_add_tail(&g_reg_list, &rdev->list);
|
||||||
regulator_unlock(&g_reg_lock, flags);
|
|
||||||
|
|
||||||
|
out:
|
||||||
|
regulator_list_unlock(flags);
|
||||||
return rdev;
|
return rdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1074,16 +1099,16 @@ void regulator_unregister(FAR struct regulator_dev_s *rdev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = regulator_lock(&g_reg_lock);
|
flags = regulator_list_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);
|
||||||
regulator_unlock(&g_reg_lock, flags);
|
regulator_list_unlock(flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_delete(&rdev->list);
|
list_delete(&rdev->list);
|
||||||
regulator_unlock(&g_reg_lock, flags);
|
regulator_list_unlock(flags);
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
if (rdev->desc->auto_lp)
|
if (rdev->desc->auto_lp)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user