Skip to content

Commit 2db471f

Browse files
dulibo1Alan Carvalho de Assis
authored andcommitted
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 <[email protected]>
1 parent da1cd59 commit 2db471f

File tree

1 file changed

+80
-28
lines changed

1 file changed

+80
-28
lines changed

drivers/power/supply/regulator_rpmsg.c

Lines changed: 80 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ struct regulator_rpmsg_s
103103
{
104104
FAR struct regulator_s *regulator;
105105
struct list_node node;
106+
bool enable;
106107
};
107108

108109
/****************************************************************************
@@ -204,7 +205,7 @@ regulator_rpmsg_get_client(FAR const char *name)
204205
}
205206
}
206207

207-
client = kmm_zalloc(sizeof(*client) + slash - name);
208+
client = kmm_zalloc(sizeof(*client) + slash - name + 1);
208209
if (client == NULL)
209210
{
210211
goto out;
@@ -253,9 +254,8 @@ regulator_rpmsg_get_ept(FAR const char **name)
253254
return &client->ept;
254255
}
255256

256-
static FAR struct regulator_s *
257-
regulator_rpmsg_get_regulator(FAR struct rpmsg_endpoint *ept,
258-
FAR const char *name)
257+
static FAR struct regulator_rpmsg_s *
258+
regulator_rpmsg_get_reg(FAR struct rpmsg_endpoint *ept, FAR const char *name)
259259
{
260260
FAR struct regulator_rpmsg_server_s *server = ept->priv;
261261
FAR struct list_node *regulator_list = &server->regulator_list;
@@ -268,13 +268,14 @@ regulator_rpmsg_get_regulator(FAR struct rpmsg_endpoint *ept,
268268
if (strcmp(reg->regulator->rdev->desc->name, name) == 0)
269269
{
270270
nxmutex_unlock(&server->lock);
271-
return reg->regulator;
271+
return reg;
272272
}
273273
}
274274

275275
reg = kmm_zalloc(sizeof(*reg));
276276
if (reg == NULL)
277277
{
278+
nxmutex_unlock(&server->lock);
278279
return NULL;
279280
}
280281

@@ -287,8 +288,9 @@ regulator_rpmsg_get_regulator(FAR struct rpmsg_endpoint *ept,
287288
}
288289

289290
list_add_head(regulator_list, &reg->node);
291+
290292
nxmutex_unlock(&server->lock);
291-
return reg->regulator;
293+
return reg;
292294
}
293295

294296
static void regulator_rpmsg_client_created(struct rpmsg_device *rdev,
@@ -321,8 +323,11 @@ static void regulator_rpmsg_client_destroy(struct rpmsg_device *rdev,
321323
return;
322324
}
323325

324-
nxsem_wait(&client->sem);
325-
rpmsg_destroy_ept(&client->ept);
326+
if (strcmp(client->cpuname, rpmsg_get_cpuname(rdev)) == 0)
327+
{
328+
nxsem_wait(&client->sem);
329+
rpmsg_destroy_ept(&client->ept);
330+
}
326331
}
327332

328333
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)
334339
list_for_every_entry_safe(&server->regulator_list, reg, tmp,
335340
struct regulator_rpmsg_s, node)
336341
{
337-
while (regulator_is_enabled(reg->regulator))
342+
if (reg->enable)
338343
{
339344
regulator_disable(reg->regulator);
340345
}
@@ -411,10 +416,24 @@ static int regulator_rpmsg_enable_handler(FAR struct rpmsg_endpoint *ept,
411416
uint32_t src, FAR void *priv)
412417
{
413418
FAR struct regulator_rpmsg_enable_s *msg = data;
414-
FAR struct regulator_s *regulator =
415-
regulator_rpmsg_get_regulator(ept, msg->name);
419+
FAR struct regulator_rpmsg_s *reg =
420+
regulator_rpmsg_get_reg(ept, msg->name);
421+
int ret = -ENOENT;
416422

417-
msg->header.result = regulator_enable(regulator);
423+
if (reg && !reg->enable)
424+
{
425+
ret = regulator_enable(reg->regulator);
426+
if (ret >= 0)
427+
{
428+
reg->enable = true;
429+
}
430+
}
431+
else if (reg && reg->enable)
432+
{
433+
ret = 0;
434+
}
435+
436+
msg->header.result = ret;
418437
return rpmsg_send(ept, data, len);
419438
}
420439

@@ -423,10 +442,24 @@ static int regulator_rpmsg_disable_handler(FAR struct rpmsg_endpoint *ept,
423442
uint32_t src, FAR void *priv)
424443
{
425444
FAR struct regulator_rpmsg_disable_s *msg = data;
426-
FAR struct regulator_s *regulator =
427-
regulator_rpmsg_get_regulator(ept, msg->name);
445+
FAR struct regulator_rpmsg_s *reg =
446+
regulator_rpmsg_get_reg(ept, msg->name);
447+
int ret = -ENOENT;
428448

429-
msg->header.result = regulator_disable(regulator);
449+
if (reg && reg->enable)
450+
{
451+
ret = regulator_disable(reg->regulator);
452+
if (ret >= 0)
453+
{
454+
reg->enable = false;
455+
}
456+
}
457+
else if (reg && !reg->enable)
458+
{
459+
ret = 0;
460+
}
461+
462+
msg->header.result = ret;
430463
return rpmsg_send(ept, data, len);
431464
}
432465

@@ -435,10 +468,16 @@ static int regulator_rpmsg_getvol_handler(FAR struct rpmsg_endpoint *ept,
435468
uint32_t src, FAR void *priv)
436469
{
437470
FAR struct regulator_rpmsg_getvol_s *msg = data;
438-
FAR struct regulator_s *regulator =
439-
regulator_rpmsg_get_regulator(ept, msg->name);
471+
FAR struct regulator_rpmsg_s *reg =
472+
regulator_rpmsg_get_reg(ept, msg->name);
473+
int ret = -ENOENT;
474+
475+
if (reg)
476+
{
477+
ret = regulator_get_voltage(reg->regulator);
478+
}
440479

441-
msg->header.result = regulator_get_voltage(regulator);
480+
msg->header.result = ret;
442481
return rpmsg_send(ept, data, len);
443482
}
444483

@@ -447,11 +486,17 @@ static int regulator_rpmsg_setvol_handler(FAR struct rpmsg_endpoint *ept,
447486
uint32_t src, FAR void *priv)
448487
{
449488
FAR struct regulator_rpmsg_setvol_s *msg = data;
450-
FAR struct regulator_s *regulator =
451-
regulator_rpmsg_get_regulator(ept, msg->name);
489+
FAR struct regulator_rpmsg_s *reg =
490+
regulator_rpmsg_get_reg(ept, msg->name);
491+
int ret = -ENOENT;
492+
493+
if (reg)
494+
{
495+
ret = regulator_set_voltage(reg->regulator,
496+
msg->min_uv, msg->max_uv);
497+
}
452498

453-
msg->header.result =
454-
regulator_set_voltage(regulator, msg->min_uv, msg->max_uv);
499+
msg->header.result = ret;
455500
return rpmsg_send(ept, data, len);
456501
}
457502

@@ -460,10 +505,16 @@ static int regulator_rpmsg_isenabled_handler(FAR struct rpmsg_endpoint *ept,
460505
uint32_t src, FAR void *priv)
461506
{
462507
FAR struct regulator_rpmsg_isenabled_s *msg = data;
463-
FAR struct regulator_s *regulator =
464-
regulator_rpmsg_get_regulator(ept, msg->name);
508+
FAR struct regulator_rpmsg_s *reg =
509+
regulator_rpmsg_get_reg(ept, msg->name);
510+
int ret = -ENOENT;
465511

466-
msg->header.result = regulator_is_enabled(regulator);
512+
if (reg)
513+
{
514+
ret = reg->enable;
515+
}
516+
517+
msg->header.result = ret;
467518
return rpmsg_send(ept, data, len);
468519
}
469520

@@ -658,6 +709,7 @@ FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name)
658709
{
659710
FAR struct regulator_desc_s *desc;
660711
FAR struct regulator_dev_s *dev;
712+
FAR char *pname;
661713
size_t len = strlen(name) + 1;
662714

663715
desc = kmm_zalloc(sizeof(*desc) + len);
@@ -666,9 +718,9 @@ FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name)
666718
return NULL;
667719
}
668720

669-
desc->name = desc + 1;
670-
memcpy(desc->name, name, len);
671-
721+
pname = (FAR char *)(desc + 1);
722+
memcpy(pname, name, len);
723+
desc->name = pname;
672724
dev = regulator_register(desc, &g_regulator_rpmsg_ops, NULL);
673725
if (dev == NULL)
674726
{

0 commit comments

Comments
 (0)