mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
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:
+64
-30
@@ -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(¶ms);
|
ret = metal_init(¶ms);
|
||||||
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user