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

View File

@ -48,6 +48,8 @@
# define ALIGN_UP(s, a) (((s) + (a) - 1) & ~((a) - 1))
#endif
#define RPTUNIOC_NONE 0
/****************************************************************************
* Private Types
****************************************************************************/
@ -61,6 +63,7 @@ struct rptun_priv_s
struct metal_list bind;
struct metal_list node;
sem_t sem;
unsigned long cmd;
};
struct rptun_bind_s
@ -169,19 +172,37 @@ static int rptun_thread(int argc, FAR char *argv[])
FAR struct rptun_priv_s *priv;
priv = (FAR struct rptun_priv_s *)((uintptr_t)strtoul(argv[2], NULL, 0));
remoteproc_init(&priv->rproc, &g_rptun_ops, priv);
while (1)
{
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;
}
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;
nxsem_get_value(&priv->sem, &semcount);
@ -189,7 +210,11 @@ static int rptun_callback(FAR void *arg, uint32_t vqid)
{
nxsem_post(&priv->sem);
}
}
static int rptun_callback(FAR void *arg, uint32_t vqid)
{
rptun_wakeup(arg);
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 rptun_priv_s *priv = inode->i_private;
int ret = -ENOTTY;
int ret = OK;
switch (cmd)
{
case RPTUNIOC_START:
if (priv->rproc.state == RPROC_OFFLINE)
{
ret = rptun_dev_start(&priv->rproc);
}
case RPTUNIOC_STOP:
priv->cmd = cmd;
rptun_wakeup(priv);
break;
case RPTUNIOC_STOP:
if (priv->rproc.state != RPROC_OFFLINE)
{
ret = rptun_dev_stop(&priv->rproc);
}
default:
ret = -ENOTTY;
break;
}
@ -802,7 +823,7 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
int ret;
ret = metal_init(&params);
if (ret)
if (ret < 0)
{
return ret;
}
@ -810,18 +831,32 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
priv = kmm_zalloc(sizeof(struct rptun_priv_s));
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);
argv[0] = (void *)RPTUN_GET_CPUNAME(dev);
argv[1] = arg1;
argv[2] = NULL;
nxsem_init(&priv->sem, 0, 0);
nxsem_set_protocol(&priv->sem, SEM_PRIO_NONE);
ret = kthread_create("rptun",
CONFIG_RPTUN_PRIORITY,
CONFIG_RPTUN_STACKSIZE,
@ -829,22 +864,21 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
argv);
if (ret < 0)
{
kmm_free(priv);
return ret;
goto err_thread;
}
priv->dev = dev;
return OK;
metal_list_init(&priv->bind);
remoteproc_init(&priv->rproc, &g_rptun_ops, priv);
err_thread:
unregister_driver(name);
if (RPTUN_IS_AUTOSTART(dev))
{
rptun_dev_start(&priv->rproc);
}
err_driver:
nxsem_destroy(&priv->sem);
kmm_free(priv);
snprintf(name, 32, "/dev/rptun/%s", RPTUN_GET_CPUNAME(dev));
return register_driver(name, &g_rptun_devops, 0666, priv);
err_mem:
metal_finish();
return ret;
}
int rptun_boot(FAR const char *cpuname)