You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2023/09/21 23:41:44 UTC
[nuttx] 02/02: regulator:fix some issues when use rpmsg
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 2db471fab3ee2bc76e6ae388ed2dd7a4977c8fce
Author: dulibo1 <du...@xiaomi.com>
AuthorDate: Tue Sep 19 19:40:01 2023 +0800
regulator:fix some issues when use rpmsg
1.client get the regualtor which is enabled by server, will disable the regualtor.
2.regulator_rpmsg_server_unbind will disable regualtor which maybe used by other client.
3.regulator_rpmsg_server_unbind will be deadloop when the regulator is always_on;
4.regulator_rpmsg_client_destroy does not match server cpu name,may destory by stop other rptun dev
Signed-off-by: dulibo1 <du...@xiaomi.com>
---
drivers/power/supply/regulator_rpmsg.c | 108 ++++++++++++++++++++++++---------
1 file changed, 80 insertions(+), 28 deletions(-)
diff --git a/drivers/power/supply/regulator_rpmsg.c b/drivers/power/supply/regulator_rpmsg.c
index f389e872b2..5994949464 100644
--- a/drivers/power/supply/regulator_rpmsg.c
+++ b/drivers/power/supply/regulator_rpmsg.c
@@ -103,6 +103,7 @@ struct regulator_rpmsg_s
{
FAR struct regulator_s *regulator;
struct list_node node;
+ bool enable;
};
/****************************************************************************
@@ -204,7 +205,7 @@ regulator_rpmsg_get_client(FAR const char *name)
}
}
- client = kmm_zalloc(sizeof(*client) + slash - name);
+ client = kmm_zalloc(sizeof(*client) + slash - name + 1);
if (client == NULL)
{
goto out;
@@ -253,9 +254,8 @@ regulator_rpmsg_get_ept(FAR const char **name)
return &client->ept;
}
-static FAR struct regulator_s *
-regulator_rpmsg_get_regulator(FAR struct rpmsg_endpoint *ept,
- FAR const char *name)
+static FAR struct regulator_rpmsg_s *
+regulator_rpmsg_get_reg(FAR struct rpmsg_endpoint *ept, FAR const char *name)
{
FAR struct regulator_rpmsg_server_s *server = ept->priv;
FAR struct list_node *regulator_list = &server->regulator_list;
@@ -268,13 +268,14 @@ regulator_rpmsg_get_regulator(FAR struct rpmsg_endpoint *ept,
if (strcmp(reg->regulator->rdev->desc->name, name) == 0)
{
nxmutex_unlock(&server->lock);
- return reg->regulator;
+ return reg;
}
}
reg = kmm_zalloc(sizeof(*reg));
if (reg == NULL)
{
+ nxmutex_unlock(&server->lock);
return NULL;
}
@@ -287,8 +288,9 @@ regulator_rpmsg_get_regulator(FAR struct rpmsg_endpoint *ept,
}
list_add_head(regulator_list, ®->node);
+
nxmutex_unlock(&server->lock);
- return reg->regulator;
+ return reg;
}
static void regulator_rpmsg_client_created(struct rpmsg_device *rdev,
@@ -321,8 +323,11 @@ static void regulator_rpmsg_client_destroy(struct rpmsg_device *rdev,
return;
}
- nxsem_wait(&client->sem);
- rpmsg_destroy_ept(&client->ept);
+ if (strcmp(client->cpuname, rpmsg_get_cpuname(rdev)) == 0)
+ {
+ nxsem_wait(&client->sem);
+ rpmsg_destroy_ept(&client->ept);
+ }
}
static void regulator_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept)
@@ -334,7 +339,7 @@ static void regulator_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept)
list_for_every_entry_safe(&server->regulator_list, reg, tmp,
struct regulator_rpmsg_s, node)
{
- while (regulator_is_enabled(reg->regulator))
+ if (reg->enable)
{
regulator_disable(reg->regulator);
}
@@ -411,10 +416,24 @@ static int regulator_rpmsg_enable_handler(FAR struct rpmsg_endpoint *ept,
uint32_t src, FAR void *priv)
{
FAR struct regulator_rpmsg_enable_s *msg = data;
- FAR struct regulator_s *regulator =
- regulator_rpmsg_get_regulator(ept, msg->name);
+ FAR struct regulator_rpmsg_s *reg =
+ regulator_rpmsg_get_reg(ept, msg->name);
+ int ret = -ENOENT;
- msg->header.result = regulator_enable(regulator);
+ if (reg && !reg->enable)
+ {
+ ret = regulator_enable(reg->regulator);
+ if (ret >= 0)
+ {
+ reg->enable = true;
+ }
+ }
+ else if (reg && reg->enable)
+ {
+ ret = 0;
+ }
+
+ msg->header.result = ret;
return rpmsg_send(ept, data, len);
}
@@ -423,10 +442,24 @@ static int regulator_rpmsg_disable_handler(FAR struct rpmsg_endpoint *ept,
uint32_t src, FAR void *priv)
{
FAR struct regulator_rpmsg_disable_s *msg = data;
- FAR struct regulator_s *regulator =
- regulator_rpmsg_get_regulator(ept, msg->name);
+ FAR struct regulator_rpmsg_s *reg =
+ regulator_rpmsg_get_reg(ept, msg->name);
+ int ret = -ENOENT;
- msg->header.result = regulator_disable(regulator);
+ if (reg && reg->enable)
+ {
+ ret = regulator_disable(reg->regulator);
+ if (ret >= 0)
+ {
+ reg->enable = false;
+ }
+ }
+ else if (reg && !reg->enable)
+ {
+ ret = 0;
+ }
+
+ msg->header.result = ret;
return rpmsg_send(ept, data, len);
}
@@ -435,10 +468,16 @@ static int regulator_rpmsg_getvol_handler(FAR struct rpmsg_endpoint *ept,
uint32_t src, FAR void *priv)
{
FAR struct regulator_rpmsg_getvol_s *msg = data;
- FAR struct regulator_s *regulator =
- regulator_rpmsg_get_regulator(ept, msg->name);
+ FAR struct regulator_rpmsg_s *reg =
+ regulator_rpmsg_get_reg(ept, msg->name);
+ int ret = -ENOENT;
+
+ if (reg)
+ {
+ ret = regulator_get_voltage(reg->regulator);
+ }
- msg->header.result = regulator_get_voltage(regulator);
+ msg->header.result = ret;
return rpmsg_send(ept, data, len);
}
@@ -447,11 +486,17 @@ static int regulator_rpmsg_setvol_handler(FAR struct rpmsg_endpoint *ept,
uint32_t src, FAR void *priv)
{
FAR struct regulator_rpmsg_setvol_s *msg = data;
- FAR struct regulator_s *regulator =
- regulator_rpmsg_get_regulator(ept, msg->name);
+ FAR struct regulator_rpmsg_s *reg =
+ regulator_rpmsg_get_reg(ept, msg->name);
+ int ret = -ENOENT;
+
+ if (reg)
+ {
+ ret = regulator_set_voltage(reg->regulator,
+ msg->min_uv, msg->max_uv);
+ }
- msg->header.result =
- regulator_set_voltage(regulator, msg->min_uv, msg->max_uv);
+ msg->header.result = ret;
return rpmsg_send(ept, data, len);
}
@@ -460,10 +505,16 @@ static int regulator_rpmsg_isenabled_handler(FAR struct rpmsg_endpoint *ept,
uint32_t src, FAR void *priv)
{
FAR struct regulator_rpmsg_isenabled_s *msg = data;
- FAR struct regulator_s *regulator =
- regulator_rpmsg_get_regulator(ept, msg->name);
+ FAR struct regulator_rpmsg_s *reg =
+ regulator_rpmsg_get_reg(ept, msg->name);
+ int ret = -ENOENT;
- msg->header.result = regulator_is_enabled(regulator);
+ if (reg)
+ {
+ ret = reg->enable;
+ }
+
+ msg->header.result = ret;
return rpmsg_send(ept, data, len);
}
@@ -658,6 +709,7 @@ FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name)
{
FAR struct regulator_desc_s *desc;
FAR struct regulator_dev_s *dev;
+ FAR char *pname;
size_t len = strlen(name) + 1;
desc = kmm_zalloc(sizeof(*desc) + len);
@@ -666,9 +718,9 @@ FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name)
return NULL;
}
- desc->name = desc + 1;
- memcpy(desc->name, name, len);
-
+ pname = (FAR char *)(desc + 1);
+ memcpy(pname, name, len);
+ desc->name = pname;
dev = regulator_register(desc, &g_regulator_rpmsg_ops, NULL);
if (dev == NULL)
{