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:
parent
2d676f5e46
commit
068353bba7
@ -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(¶ms);
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user