rpmsg: imx: bug fix and clean up the codes
- Clean up the codes, move the tx/rx mailbox initializations into one function. - Fix the mu msg data exchange bug. - Fix to stop autoload pingpong test module. Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>5.4-rM2-2.2.x-imx-squashed
parent
928ae4d445
commit
e2de271424
|
@ -329,8 +329,11 @@ static void rpmsg_work_handler(struct work_struct *work)
|
||||||
spin_lock_irqsave(&rpdev->mu_lock, flags);
|
spin_lock_irqsave(&rpdev->mu_lock, flags);
|
||||||
/* handle all incoming mu message */
|
/* handle all incoming mu message */
|
||||||
while (CIRC_CNT(cb->head, cb->tail, PAGE_SIZE)) {
|
while (CIRC_CNT(cb->head, cb->tail, PAGE_SIZE)) {
|
||||||
|
message = cb->buf[cb->tail];
|
||||||
|
message |= (cb->buf[cb->tail + 1] << 8);
|
||||||
|
message |= (cb->buf[cb->tail + 2] << 16);
|
||||||
|
message |= (cb->buf[cb->tail + 3] << 24);
|
||||||
spin_unlock_irqrestore(&rpdev->mu_lock, flags);
|
spin_unlock_irqrestore(&rpdev->mu_lock, flags);
|
||||||
message = (u32) cb->buf[cb->tail];
|
|
||||||
virdev = rpdev->ivdev[(message >> 16) / 2];
|
virdev = rpdev->ivdev[(message >> 16) / 2];
|
||||||
|
|
||||||
dev_dbg(dev, "%s msg: 0x%x\n", __func__, message);
|
dev_dbg(dev, "%s msg: 0x%x\n", __func__, message);
|
||||||
|
@ -406,41 +409,27 @@ static void imx_rpmsg_rx_callback(struct mbox_client *c, void *msg)
|
||||||
|
|
||||||
spin_lock_irqsave(&rpdev->mu_lock, flags);
|
spin_lock_irqsave(&rpdev->mu_lock, flags);
|
||||||
buf_space = CIRC_SPACE(cb->head, cb->tail, PAGE_SIZE);
|
buf_space = CIRC_SPACE(cb->head, cb->tail, PAGE_SIZE);
|
||||||
spin_unlock_irqrestore(&rpdev->mu_lock, flags);
|
|
||||||
if (unlikely(!buf_space)) {
|
if (unlikely(!buf_space)) {
|
||||||
dev_err(c->dev, "RPMSG RX overflow!\n");
|
dev_err(c->dev, "RPMSG RX overflow!\n");
|
||||||
|
spin_unlock_irqrestore(&rpdev->mu_lock, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
spin_lock_irqsave(&rpdev->mu_lock, flags);
|
cb->buf[cb->head] = (u32) *data;
|
||||||
cb->buf[cb->head] = *data;
|
cb->buf[cb->head + 1] = (u32) *data >> 8;
|
||||||
|
cb->buf[cb->head + 2] = (u32) *data >> 16;
|
||||||
|
cb->buf[cb->head + 3] = (u32) *data >> 24;
|
||||||
cb->head = CIRC_ADD(cb->head, PAGE_SIZE, 4);
|
cb->head = CIRC_ADD(cb->head, PAGE_SIZE, 4);
|
||||||
spin_unlock_irqrestore(&rpdev->mu_lock, flags);
|
spin_unlock_irqrestore(&rpdev->mu_lock, flags);
|
||||||
|
|
||||||
schedule_delayed_work(&(rpdev->rpmsg_work), 0);
|
schedule_delayed_work(&(rpdev->rpmsg_work), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int imx_rpmsg_probe(struct platform_device *pdev)
|
static int imx_rpmsg_xtr_channel_init(struct imx_rpmsg_vproc *rpdev)
|
||||||
{
|
{
|
||||||
int j, ret = 0;
|
struct platform_device *pdev = rpdev->pdev;
|
||||||
char *buf;
|
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct device_node *np = pdev->dev.of_node;
|
|
||||||
struct imx_rpmsg_vproc *rpdev;
|
|
||||||
struct mbox_client *cl;
|
struct mbox_client *cl;
|
||||||
|
int ret = 0;
|
||||||
buf = devm_kzalloc(dev, PAGE_SIZE, GFP_KERNEL);
|
|
||||||
if (!buf)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
rpdev = devm_kzalloc(dev, sizeof(*rpdev), GFP_KERNEL);
|
|
||||||
if (!rpdev)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
rpdev->proc_nb.notifier_call = imx_rpmsg_partition_notify;
|
|
||||||
rpdev->variant = (enum imx_rpmsg_variants)of_device_get_match_data(dev);
|
|
||||||
rpdev->rx_buffer.buf = buf;
|
|
||||||
rpdev->rx_buffer.head = 0;
|
|
||||||
rpdev->rx_buffer.tail = 0;
|
|
||||||
|
|
||||||
cl = &rpdev->cl;
|
cl = &rpdev->cl;
|
||||||
cl->dev = dev;
|
cl->dev = dev;
|
||||||
|
@ -452,14 +441,57 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
|
||||||
rpdev->tx_ch = mbox_request_channel_byname(cl, "tx");
|
rpdev->tx_ch = mbox_request_channel_byname(cl, "tx");
|
||||||
if (IS_ERR(rpdev->tx_ch)) {
|
if (IS_ERR(rpdev->tx_ch)) {
|
||||||
ret = PTR_ERR(rpdev->tx_ch);
|
ret = PTR_ERR(rpdev->tx_ch);
|
||||||
goto err_chl;
|
dev_err(cl->dev, "failed to request mbox tx chan, ret %d\n",
|
||||||
|
ret);
|
||||||
|
goto err_out;
|
||||||
}
|
}
|
||||||
rpdev->rx_ch = mbox_request_channel_byname(cl, "rx");
|
rpdev->rx_ch = mbox_request_channel_byname(cl, "rx");
|
||||||
if (IS_ERR(rpdev->rx_ch)) {
|
if (IS_ERR(rpdev->rx_ch)) {
|
||||||
ret = PTR_ERR(rpdev->rx_ch);
|
ret = PTR_ERR(rpdev->rx_ch);
|
||||||
goto err_chl;
|
dev_err(cl->dev, "failed to request mbox rx chan, ret %d\n",
|
||||||
|
ret);
|
||||||
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
if (!IS_ERR(rpdev->tx_ch))
|
||||||
|
mbox_free_channel(rpdev->tx_ch);
|
||||||
|
if (!IS_ERR(rpdev->rx_ch))
|
||||||
|
mbox_free_channel(rpdev->rx_ch);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int imx_rpmsg_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int j, ret = 0;
|
||||||
|
char *buf;
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct device_node *np = pdev->dev.of_node;
|
||||||
|
struct imx_rpmsg_vproc *rpdev;
|
||||||
|
|
||||||
|
buf = devm_kzalloc(dev, PAGE_SIZE, GFP_KERNEL);
|
||||||
|
if (!buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rpdev = devm_kzalloc(dev, sizeof(*rpdev), GFP_KERNEL);
|
||||||
|
if (!rpdev)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rpdev->pdev = pdev;
|
||||||
|
rpdev->proc_nb.notifier_call = imx_rpmsg_partition_notify;
|
||||||
|
rpdev->variant = (enum imx_rpmsg_variants)of_device_get_match_data(dev);
|
||||||
|
rpdev->rx_buffer.buf = buf;
|
||||||
|
rpdev->rx_buffer.head = 0;
|
||||||
|
rpdev->rx_buffer.tail = 0;
|
||||||
|
|
||||||
|
/* Initialize the RX/TX channels. */
|
||||||
|
ret = imx_rpmsg_xtr_channel_init(rpdev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
spin_lock_init(&rpdev->mu_lock);
|
spin_lock_init(&rpdev->mu_lock);
|
||||||
INIT_DELAYED_WORK(&(rpdev->rpmsg_work), rpmsg_work_handler);
|
INIT_DELAYED_WORK(&(rpdev->rpmsg_work), rpmsg_work_handler);
|
||||||
ret = of_property_read_u32(np, "vdev-nums", &rpdev->vdev_nums);
|
ret = of_property_read_u32(np, "vdev-nums", &rpdev->vdev_nums);
|
||||||
|
@ -492,7 +524,6 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
|
||||||
rpdev->ivdev[j]->vring[1]);
|
rpdev->ivdev[j]->vring[1]);
|
||||||
rpdev->ivdev[j]->vdev.id.device = VIRTIO_ID_RPMSG;
|
rpdev->ivdev[j]->vdev.id.device = VIRTIO_ID_RPMSG;
|
||||||
rpdev->ivdev[j]->vdev.config = &imx_rpmsg_config_ops;
|
rpdev->ivdev[j]->vdev.config = &imx_rpmsg_config_ops;
|
||||||
rpdev->pdev = pdev;
|
|
||||||
rpdev->ivdev[j]->vdev.dev.parent = &pdev->dev;
|
rpdev->ivdev[j]->vdev.dev.parent = &pdev->dev;
|
||||||
rpdev->ivdev[j]->vdev.dev.release = imx_rpmsg_vproc_release;
|
rpdev->ivdev[j]->vdev.dev.release = imx_rpmsg_vproc_release;
|
||||||
rpdev->ivdev[j]->base_vq_id = j * 2;
|
rpdev->ivdev[j]->base_vq_id = j * 2;
|
||||||
|
@ -510,14 +541,14 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, rpdev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
if (rpdev->flags & SPECIFIC_DMA_POOL)
|
if (rpdev->flags & SPECIFIC_DMA_POOL)
|
||||||
of_reserved_mem_device_release(dev);
|
of_reserved_mem_device_release(dev);
|
||||||
err_chl:
|
err_chl:
|
||||||
if (!IS_ERR(rpdev->rxdb_ch))
|
|
||||||
mbox_free_channel(rpdev->rxdb_ch);
|
|
||||||
if (!IS_ERR(rpdev->tx_ch))
|
if (!IS_ERR(rpdev->tx_ch))
|
||||||
mbox_free_channel(rpdev->tx_ch);
|
mbox_free_channel(rpdev->tx_ch);
|
||||||
if (!IS_ERR(rpdev->rx_ch))
|
if (!IS_ERR(rpdev->rx_ch))
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
#include <linux/rpmsg.h>
|
#include <linux/rpmsg.h>
|
||||||
|
|
||||||
#define MSG "hello world!"
|
#define MSG "hello world!"
|
||||||
static unsigned int rpmsg_pingpong;
|
|
||||||
|
|
||||||
static int rpmsg_pingpong_cb(struct rpmsg_device *rpdev, void *data, int len,
|
static int rpmsg_pingpong_cb(struct rpmsg_device *rpdev, void *data, int len,
|
||||||
void *priv, u32 src)
|
void *priv, u32 src)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
unsigned int rpmsg_pingpong;
|
||||||
|
|
||||||
/* reply */
|
/* reply */
|
||||||
rpmsg_pingpong = *(unsigned int *)data;
|
rpmsg_pingpong = *(unsigned int *)data;
|
||||||
|
@ -37,6 +37,7 @@ static int rpmsg_pingpong_cb(struct rpmsg_device *rpdev, void *data, int len,
|
||||||
static int rpmsg_pingpong_probe(struct rpmsg_device *rpdev)
|
static int rpmsg_pingpong_probe(struct rpmsg_device *rpdev)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
unsigned int rpmsg_pingpong;
|
||||||
|
|
||||||
dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
|
dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
|
||||||
rpdev->src, rpdev->dst);
|
rpdev->src, rpdev->dst);
|
||||||
|
@ -72,7 +73,6 @@ static struct rpmsg_device_id rpmsg_driver_pingpong_id_table[] = {
|
||||||
{ .name = "rpmsg-openamp-demo-channel-1" },
|
{ .name = "rpmsg-openamp-demo-channel-1" },
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_pingpong_id_table);
|
|
||||||
|
|
||||||
static struct rpmsg_driver rpmsg_pingpong_driver = {
|
static struct rpmsg_driver rpmsg_pingpong_driver = {
|
||||||
.drv.name = KBUILD_MODNAME,
|
.drv.name = KBUILD_MODNAME,
|
||||||
|
|
Loading…
Reference in New Issue