regulator/rpmsg: pending in wait ept ready for regulator client
Signed-off-by: zhuyanlin <zhuyanlin1@xiaomi.com>
This commit is contained in:
parent
cbd82f1c1b
commit
a22dae19c1
@ -353,6 +353,7 @@ config REGULATOR
|
|||||||
|
|
||||||
config REGULATOR_RPMSG
|
config REGULATOR_RPMSG
|
||||||
bool "Regulator rpmsg driver support"
|
bool "Regulator rpmsg driver support"
|
||||||
|
depends on OPENAMP
|
||||||
default n
|
default n
|
||||||
---help---
|
---help---
|
||||||
The rpmsg regulator driver implements the common regulator APIs, inside which
|
The rpmsg regulator driver implements the common regulator APIs, inside which
|
||||||
|
@ -86,11 +86,17 @@ struct regulator_rpmsg_cookie_s
|
|||||||
sem_t sem;
|
sem_t sem;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct regulator_rpmsg_priv_s
|
struct regulator_rpmsg_client_s
|
||||||
{
|
{
|
||||||
struct rpmsg_endpoint ept;
|
struct rpmsg_endpoint ept;
|
||||||
FAR const char *cpuname;
|
FAR const char *cpuname;
|
||||||
struct list_node node;
|
struct list_node node;
|
||||||
|
sem_t sem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct regulator_rpmsg_server_s
|
||||||
|
{
|
||||||
|
struct rpmsg_endpoint ept;
|
||||||
struct list_node regulator_list;
|
struct list_node regulator_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,6 +130,17 @@ static int regulator_rpmsg_isenabled_handler(FAR struct rpmsg_endpoint *ept,
|
|||||||
FAR void *data, size_t len,
|
FAR void *data, size_t len,
|
||||||
uint32_t src, FAR void *priv_);
|
uint32_t src, FAR void *priv_);
|
||||||
|
|
||||||
|
static void regulator_rpmsg_client_created(struct rpmsg_device *rdev,
|
||||||
|
FAR void *priv_);
|
||||||
|
static void regulator_rpmsg_client_destroy(struct rpmsg_device *rdev,
|
||||||
|
FAR void *priv_);
|
||||||
|
|
||||||
|
static void regulator_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept);
|
||||||
|
static void regulator_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
|
||||||
|
FAR void *priv_,
|
||||||
|
FAR const char *name,
|
||||||
|
uint32_t dest);
|
||||||
|
|
||||||
static int regulator_rpmsg_set_voltage(FAR struct regulator_dev_s *rdev,
|
static int regulator_rpmsg_set_voltage(FAR struct regulator_dev_s *rdev,
|
||||||
int min_uv, int max_uv,
|
int min_uv, int max_uv,
|
||||||
FAR unsigned *selector);
|
FAR unsigned *selector);
|
||||||
@ -162,26 +179,46 @@ static const struct regulator_ops_s g_regulator_rpmsg_ops =
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static struct regulator_rpmsg_priv_s *
|
static struct regulator_rpmsg_client_s *
|
||||||
regulator_rpmsg_get_priv(FAR const char *name)
|
regulator_rpmsg_get_priv(FAR const char *name)
|
||||||
{
|
{
|
||||||
FAR struct regulator_rpmsg_priv_s *priv;
|
FAR struct regulator_rpmsg_client_s *priv;
|
||||||
|
FAR const char *slash = strchr(name, '/');
|
||||||
|
|
||||||
|
if (!slash)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
nxmutex_lock(&g_regulator_rpmsg_lock);
|
nxmutex_lock(&g_regulator_rpmsg_lock);
|
||||||
|
|
||||||
list_for_every_entry(&g_regulator_rpmsg_priv, priv,
|
list_for_every_entry(&g_regulator_rpmsg_priv, priv,
|
||||||
struct regulator_rpmsg_priv_s, node)
|
struct regulator_rpmsg_client_s, node)
|
||||||
{
|
{
|
||||||
size_t len = strlen(priv->cpuname);
|
if (!strncmp(priv->cpuname, name, slash - name))
|
||||||
|
|
||||||
if (!strncmp(priv->cpuname, name, len) &&
|
|
||||||
(name[len] == '/' || name[len] == 0))
|
|
||||||
{
|
{
|
||||||
goto out; /* Find the target, exit */
|
goto out; /* Find the target, exit */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
priv = NULL;
|
priv = kmm_zalloc(sizeof(struct regulator_rpmsg_client_s));
|
||||||
|
if (!priv)
|
||||||
|
{
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->cpuname = strndup(name, slash - name);
|
||||||
|
|
||||||
|
list_add_head(&g_regulator_rpmsg_priv, &priv->node);
|
||||||
|
|
||||||
|
nxmutex_unlock(&g_regulator_rpmsg_lock);
|
||||||
|
|
||||||
|
rpmsg_register_callback(priv,
|
||||||
|
regulator_rpmsg_client_created,
|
||||||
|
regulator_rpmsg_client_destroy,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return priv;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
nxmutex_unlock(&g_regulator_rpmsg_lock);
|
nxmutex_unlock(&g_regulator_rpmsg_lock);
|
||||||
@ -190,14 +227,27 @@ out:
|
|||||||
|
|
||||||
static struct rpmsg_endpoint *regulator_rpmsg_get_ept(FAR const char **name)
|
static struct rpmsg_endpoint *regulator_rpmsg_get_ept(FAR const char **name)
|
||||||
{
|
{
|
||||||
FAR struct regulator_rpmsg_priv_s *priv;
|
FAR struct regulator_rpmsg_client_s *priv;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
priv = regulator_rpmsg_get_priv(*name);
|
priv = regulator_rpmsg_get_priv(*name);
|
||||||
if (priv == NULL)
|
|
||||||
|
if (!priv)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_rpmsg_ept_ready(&priv->ept))
|
||||||
|
{
|
||||||
|
ret = nxsem_wait_uninterruptible(&priv->sem);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxsem_post(&priv->sem);
|
||||||
|
}
|
||||||
|
|
||||||
*name += strlen(priv->cpuname) + 1;
|
*name += strlen(priv->cpuname) + 1;
|
||||||
|
|
||||||
return &priv->ept;
|
return &priv->ept;
|
||||||
@ -206,7 +256,7 @@ static struct rpmsg_endpoint *regulator_rpmsg_get_ept(FAR const char **name)
|
|||||||
static FAR struct regulator_s *
|
static FAR struct regulator_s *
|
||||||
regulator_rpmsg_get_reg(FAR struct rpmsg_endpoint *ept, FAR const char *name)
|
regulator_rpmsg_get_reg(FAR struct rpmsg_endpoint *ept, FAR const char *name)
|
||||||
{
|
{
|
||||||
FAR struct regulator_rpmsg_priv_s *priv = ept->priv;
|
FAR struct regulator_rpmsg_server_s *priv = ept->priv;
|
||||||
FAR struct list_node *regulator_list = &priv->regulator_list;
|
FAR struct list_node *regulator_list = &priv->regulator_list;
|
||||||
FAR struct regulator_rpmsg_s *reg;
|
FAR struct regulator_rpmsg_s *reg;
|
||||||
|
|
||||||
@ -237,48 +287,47 @@ regulator_rpmsg_get_reg(FAR struct rpmsg_endpoint *ept, FAR const char *name)
|
|||||||
return reg->regulator;
|
return reg->regulator;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void regulator_rpmsg_device_created(struct rpmsg_device *rdev,
|
static void regulator_rpmsg_client_created(struct rpmsg_device *rdev,
|
||||||
FAR void *priv_)
|
FAR void *priv_)
|
||||||
{
|
{
|
||||||
FAR struct regulator_rpmsg_priv_s *priv;
|
FAR struct regulator_rpmsg_client_s *priv = priv_;
|
||||||
int ret;
|
|
||||||
|
|
||||||
priv = kmm_zalloc(sizeof(struct regulator_rpmsg_priv_s));
|
|
||||||
if (!priv)
|
if (!priv)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->ept.priv = priv;
|
if (!strcmp(priv->cpuname, rpmsg_get_cpuname(rdev)))
|
||||||
priv->cpuname = rpmsg_get_cpuname(rdev);
|
|
||||||
|
|
||||||
list_initialize(&priv->regulator_list);
|
|
||||||
nxmutex_lock(&g_regulator_rpmsg_lock);
|
|
||||||
list_add_head(&g_regulator_rpmsg_priv, &priv->node);
|
|
||||||
nxmutex_unlock(&g_regulator_rpmsg_lock);
|
|
||||||
|
|
||||||
ret = rpmsg_create_ept(&priv->ept, rdev, REGULATOR_RPMSG_EPT_NAME,
|
|
||||||
RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
|
|
||||||
regulator_rpmsg_ept_cb, NULL);
|
|
||||||
if (ret)
|
|
||||||
{
|
{
|
||||||
free(priv);
|
priv->ept.priv = priv;
|
||||||
|
|
||||||
|
rpmsg_create_ept(&priv->ept, rdev, REGULATOR_RPMSG_EPT_NAME,
|
||||||
|
RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
|
||||||
|
regulator_rpmsg_ept_cb, NULL);
|
||||||
|
|
||||||
|
nxsem_post(&priv->sem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void regulator_rpmsg_device_destroy(struct rpmsg_device *rdev,
|
static void regulator_rpmsg_client_destroy(struct rpmsg_device *rdev,
|
||||||
FAR void *priv_)
|
FAR void *priv_)
|
||||||
{
|
{
|
||||||
FAR struct regulator_rpmsg_priv_s *priv;
|
FAR struct regulator_rpmsg_client_s *priv = priv_;
|
||||||
FAR struct regulator_rpmsg_s *reg;
|
|
||||||
|
|
||||||
priv = regulator_rpmsg_get_priv(rpmsg_get_cpuname(rdev));
|
|
||||||
|
|
||||||
if (!priv)
|
if (!priv)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nxsem_wait(&priv->sem);
|
||||||
|
rpmsg_destroy_ept(&priv->ept);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void regulator_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept)
|
||||||
|
{
|
||||||
|
FAR struct regulator_rpmsg_server_s *priv = ept->priv;
|
||||||
|
FAR struct regulator_rpmsg_s *reg;
|
||||||
|
|
||||||
list_for_every_entry(&priv->regulator_list, reg,
|
list_for_every_entry(&priv->regulator_list, reg,
|
||||||
struct regulator_rpmsg_s, node)
|
struct regulator_rpmsg_s, node)
|
||||||
{
|
{
|
||||||
@ -292,14 +341,37 @@ static void regulator_rpmsg_device_destroy(struct rpmsg_device *rdev,
|
|||||||
kmm_free(reg);
|
kmm_free(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
nxmutex_lock(&g_regulator_rpmsg_lock);
|
rpmsg_destroy_ept(ept);
|
||||||
list_delete(&priv->node);
|
|
||||||
nxmutex_unlock(&g_regulator_rpmsg_lock);
|
|
||||||
|
|
||||||
rpmsg_destroy_ept(&priv->ept);
|
|
||||||
kmm_free(priv);
|
kmm_free(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void regulator_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
|
||||||
|
FAR void *priv_,
|
||||||
|
FAR const char *name,
|
||||||
|
uint32_t dest)
|
||||||
|
{
|
||||||
|
FAR struct regulator_rpmsg_server_s *priv;
|
||||||
|
|
||||||
|
if (!strcmp(name, REGULATOR_RPMSG_EPT_NAME))
|
||||||
|
{
|
||||||
|
priv = kmm_zalloc(sizeof(struct regulator_rpmsg_server_s));
|
||||||
|
if (!priv)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->ept.priv = priv;
|
||||||
|
|
||||||
|
list_initialize(&priv->regulator_list);
|
||||||
|
|
||||||
|
rpmsg_create_ept(&priv->ept, rdev, name,
|
||||||
|
RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
|
||||||
|
regulator_rpmsg_ept_cb,
|
||||||
|
regulator_rpmsg_server_unbind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int regulator_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept,
|
static int regulator_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept,
|
||||||
FAR void *data, size_t len,
|
FAR void *data, size_t len,
|
||||||
uint32_t src, FAR void *priv_)
|
uint32_t src, FAR void *priv_)
|
||||||
@ -584,6 +656,7 @@ static int regulator_rpmsg_is_enabled(FAR struct regulator_dev_s *rdev)
|
|||||||
FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name)
|
FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name)
|
||||||
{
|
{
|
||||||
FAR struct regulator_desc_s *desc;
|
FAR struct regulator_desc_s *desc;
|
||||||
|
FAR struct regulator_dev_s *dev;
|
||||||
|
|
||||||
desc = kmm_zalloc(sizeof(struct regulator_desc_s));
|
desc = kmm_zalloc(sizeof(struct regulator_desc_s));
|
||||||
if (!desc)
|
if (!desc)
|
||||||
@ -593,11 +666,17 @@ FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name)
|
|||||||
|
|
||||||
desc->name = name;
|
desc->name = name;
|
||||||
|
|
||||||
return regulator_register(desc, &g_regulator_rpmsg_ops, NULL);
|
dev = regulator_register(desc, &g_regulator_rpmsg_ops, NULL);
|
||||||
|
if (!dev)
|
||||||
|
{
|
||||||
|
kmm_free(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: regulator_rpmsg_init
|
* Name: regulator_rpmsg_server_init
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
*
|
*
|
||||||
@ -610,10 +689,10 @@ FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int regulator_rpmsg_init(void)
|
int regulator_rpmsg_server_init(void)
|
||||||
{
|
{
|
||||||
return rpmsg_register_callback(NULL,
|
return rpmsg_register_callback(NULL,
|
||||||
regulator_rpmsg_device_created,
|
NULL,
|
||||||
regulator_rpmsg_device_destroy,
|
NULL,
|
||||||
NULL);
|
regulator_rpmsg_server_bind);
|
||||||
}
|
}
|
||||||
|
@ -197,19 +197,20 @@ int regulator_gpio_init(FAR struct ioexpander_dev_s *iodev,
|
|||||||
FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name);
|
FAR struct regulator_dev_s *regulator_rpmsg_get(FAR const char *name);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: regulator_rpmsg_init
|
* Name: regulator_rpmsg_server_init
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
*
|
*
|
||||||
|
* Establish rpmsg channel for the operations of the remote regulator
|
||||||
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
*
|
|
||||||
* Zero (OK) on success; a negated errno on failure
|
* Zero (OK) on success; a negated errno on failure
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int regulator_rpmsg_init(void);
|
int regulator_rpmsg_server_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user