Add the new ops introduced by the rpmsg_ns series and used by the rpmsg_ctrl driver to instantiate a new rpmsg channel. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@xxxxxxxxxxx> --- drivers/rpmsg/qcom_smd.c | 57 ++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index 19903de6268d..40853702f54f 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -67,6 +67,7 @@ struct smd_channel_info_word; struct smd_channel_info_word_pair; static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops; +static const struct rpmsg_device_ops qcom_smd_device_ops; #define SMD_ALLOC_TBL_COUNT 2 #define SMD_ALLOC_TBL_SIZE 64 @@ -1013,6 +1014,52 @@ static struct device_node *qcom_smd_match_channel(struct device_node *edge_node, return NULL; } +static void qcom_smd_release_device(struct device *dev) +{ + struct rpmsg_device *rpdev = to_rpmsg_device(dev); + struct qcom_smd_device *qsdev = to_smd_device(rpdev); + + kfree(qsdev); +} + +static struct rpmsg_device * +qcom_smd_create_rpmsg_ch(struct rpmsg_device *rp_parent, + struct rpmsg_channel_info *chinfo) +{ + struct qcom_smd_device *qsdev, *qspdev = to_smd_device(rp_parent); + struct qcom_smd_edge *edge = qspdev->edge; + int ret; + + qsdev = kzalloc(sizeof(*qsdev), GFP_KERNEL); + if (!qsdev) + return ERR_PTR(-ENOMEM); + + qsdev->edge = edge; + strncpy(qsdev->rpdev.id.name, chinfo->name, RPMSG_NAME_SIZE); + qsdev->rpdev.src = chinfo->src; + qsdev->rpdev.dst = chinfo->dst; + qsdev->rpdev.ops = &qcom_smd_device_ops; + qsdev->rpdev.dev.parent = &edge->dev; + qsdev->rpdev.dev.release = qcom_smd_release_device; + qsdev->rpdev.driver_override = (char *)chinfo->driver_override; + + ret = rpmsg_register_device(&qsdev->rpdev); + if (ret) { + kfree(qsdev); + return ERR_PTR(ret); + } + + return &qsdev->rpdev; +} + +static int qcom_smd_release_rpmsg_ch(struct rpmsg_device *rpdev, + struct rpmsg_channel_info *chinfo) +{ + struct qcom_smd_device *qsdev = to_smd_device(rpdev); + + return rpmsg_unregister_device(&qsdev->edge->dev, chinfo); +} + static int qcom_smd_announce_create(struct rpmsg_device *rpdev) { struct qcom_smd_endpoint *qept = to_smd_endpoint(rpdev->ept); @@ -1033,6 +1080,8 @@ static int qcom_smd_announce_create(struct rpmsg_device *rpdev) static const struct rpmsg_device_ops qcom_smd_device_ops = { .create_ept = qcom_smd_create_ept, .announce_create = qcom_smd_announce_create, + .create_channel = qcom_smd_create_rpmsg_ch, + .release_channel = qcom_smd_release_rpmsg_ch, }; static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = { @@ -1042,14 +1091,6 @@ static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = { .poll = qcom_smd_poll, }; -static void qcom_smd_release_device(struct device *dev) -{ - struct rpmsg_device *rpdev = to_rpmsg_device(dev); - struct qcom_smd_device *qsdev = to_smd_device(rpdev); - - kfree(qsdev); -} - /* * Create a smd client device for channel that is being opened. */ -- 2.17.1