drivers/rptun: Start/stop remote processor in the background thread

to avoid blocking the main thread initialization process

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: Ib8ab2a661ee9540bb03d9d4d851a8d8ee212404e
This commit is contained in:
Xiang Xiao
2021-07-15 15:47:42 +08:00
committed by Xiang Xiao
parent 2d676f5e46
commit 068353bba7
+64 -30
View File
@@ -48,6 +48,8 @@
# define ALIGN_UP(s, a) (((s) + (a) - 1) & ~((a) - 1)) # define ALIGN_UP(s, a) (((s) + (a) - 1) & ~((a) - 1))
#endif #endif
#define RPTUNIOC_NONE 0
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
@@ -61,6 +63,7 @@ struct rptun_priv_s
struct metal_list bind; struct metal_list bind;
struct metal_list node; struct metal_list node;
sem_t sem; sem_t sem;
unsigned long cmd;
}; };
struct rptun_bind_s struct rptun_bind_s
@@ -169,19 +172,37 @@ static int rptun_thread(int argc, FAR char *argv[])
FAR struct rptun_priv_s *priv; FAR struct rptun_priv_s *priv;
priv = (FAR struct rptun_priv_s *)((uintptr_t)strtoul(argv[2], NULL, 0)); priv = (FAR struct rptun_priv_s *)((uintptr_t)strtoul(argv[2], NULL, 0));
remoteproc_init(&priv->rproc, &g_rptun_ops, priv);
while (1) while (1)
{ {
nxsem_wait_uninterruptible(&priv->sem); nxsem_wait_uninterruptible(&priv->sem);
remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL); switch (priv->cmd)
{
case RPTUNIOC_START:
if (priv->rproc.state == RPROC_OFFLINE)
{
rptun_dev_start(&priv->rproc);
}
break;
case RPTUNIOC_STOP:
if (priv->rproc.state != RPROC_OFFLINE)
{
rptun_dev_stop(&priv->rproc);
}
break;
}
priv->cmd = RPTUNIOC_NONE;
remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL);
} }
return 0; return 0;
} }
static int rptun_callback(FAR void *arg, uint32_t vqid) static void rptun_wakeup(FAR struct rptun_priv_s *priv)
{ {
FAR struct rptun_priv_s *priv = arg;
int semcount; int semcount;
nxsem_get_value(&priv->sem, &semcount); nxsem_get_value(&priv->sem, &semcount);
@@ -189,7 +210,11 @@ static int rptun_callback(FAR void *arg, uint32_t vqid)
{ {
nxsem_post(&priv->sem); nxsem_post(&priv->sem);
} }
}
static int rptun_callback(FAR void *arg, uint32_t vqid)
{
rptun_wakeup(arg);
return OK; return OK;
} }
@@ -553,22 +578,18 @@ static int rptun_dev_ioctl(FAR struct file *filep, int cmd,
{ {
FAR struct inode *inode = filep->f_inode; FAR struct inode *inode = filep->f_inode;
FAR struct rptun_priv_s *priv = inode->i_private; FAR struct rptun_priv_s *priv = inode->i_private;
int ret = -ENOTTY; int ret = OK;
switch (cmd) switch (cmd)
{ {
case RPTUNIOC_START: case RPTUNIOC_START:
if (priv->rproc.state == RPROC_OFFLINE) case RPTUNIOC_STOP:
{ priv->cmd = cmd;
ret = rptun_dev_start(&priv->rproc); rptun_wakeup(priv);
}
break; break;
case RPTUNIOC_STOP: default:
if (priv->rproc.state != RPROC_OFFLINE) ret = -ENOTTY;
{
ret = rptun_dev_stop(&priv->rproc);
}
break; break;
} }
@@ -802,7 +823,7 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
int ret; int ret;
ret = metal_init(&params); ret = metal_init(&params);
if (ret) if (ret < 0)
{ {
return ret; return ret;
} }
@@ -810,18 +831,32 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
priv = kmm_zalloc(sizeof(struct rptun_priv_s)); priv = kmm_zalloc(sizeof(struct rptun_priv_s));
if (priv == NULL) if (priv == NULL)
{ {
return -ENOMEM; ret = -ENOMEM;
goto err_mem;
}
priv->dev = dev;
if (RPTUN_IS_AUTOSTART(dev))
{
priv->cmd = RPTUNIOC_START;
}
metal_list_init(&priv->bind);
nxsem_init(&priv->sem, 0, RPTUN_IS_AUTOSTART(dev) ? 1 : 0);
nxsem_set_protocol(&priv->sem, SEM_PRIO_NONE);
snprintf(name, 32, "/dev/rptun/%s", RPTUN_GET_CPUNAME(dev));
ret = register_driver(name, &g_rptun_devops, 0666, priv);
if (ret < 0)
{
goto err_driver;
} }
snprintf(arg1, 16, "0x%" PRIxPTR, (uintptr_t)priv); snprintf(arg1, 16, "0x%" PRIxPTR, (uintptr_t)priv);
argv[0] = (void *)RPTUN_GET_CPUNAME(dev); argv[0] = (void *)RPTUN_GET_CPUNAME(dev);
argv[1] = arg1; argv[1] = arg1;
argv[2] = NULL; argv[2] = NULL;
nxsem_init(&priv->sem, 0, 0);
nxsem_set_protocol(&priv->sem, SEM_PRIO_NONE);
ret = kthread_create("rptun", ret = kthread_create("rptun",
CONFIG_RPTUN_PRIORITY, CONFIG_RPTUN_PRIORITY,
CONFIG_RPTUN_STACKSIZE, CONFIG_RPTUN_STACKSIZE,
@@ -829,22 +864,21 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
argv); argv);
if (ret < 0) if (ret < 0)
{ {
kmm_free(priv); goto err_thread;
return ret;
} }
priv->dev = dev; return OK;
metal_list_init(&priv->bind); err_thread:
remoteproc_init(&priv->rproc, &g_rptun_ops, priv); unregister_driver(name);
if (RPTUN_IS_AUTOSTART(dev)) err_driver:
{ nxsem_destroy(&priv->sem);
rptun_dev_start(&priv->rproc); kmm_free(priv);
}
snprintf(name, 32, "/dev/rptun/%s", RPTUN_GET_CPUNAME(dev)); err_mem:
return register_driver(name, &g_rptun_devops, 0666, priv); metal_finish();
return ret;
} }
int rptun_boot(FAR const char *cpuname) int rptun_boot(FAR const char *cpuname)