From patchwork Thu Sep 1 22:27:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 9309877 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id EA0D060756 for ; Thu, 1 Sep 2016 22:28:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 92A9B2952E for ; Thu, 1 Sep 2016 22:28:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8752829566; Thu, 1 Sep 2016 22:28:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7C43329565 for ; Thu, 1 Sep 2016 22:28:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752043AbcIAW2Z (ORCPT ); Thu, 1 Sep 2016 18:28:25 -0400 Received: from mail-pa0-f45.google.com ([209.85.220.45]:32890 "EHLO mail-pa0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752007AbcIAW2U (ORCPT ); Thu, 1 Sep 2016 18:28:20 -0400 Received: by mail-pa0-f45.google.com with SMTP id cy9so33876642pac.0 for ; Thu, 01 Sep 2016 15:28:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=XFZ9I0BQtdSn/MnNXQrXFXBAcZOa5O5Ijp5JSlzHKh8=; b=eWbXyppOZGEXVOwegKe1zmV2LW+fq0DUNdUqpMzkQZN/uBL7SclAeoGDvUCtIpOPmz AIc/vrG1jkTVYQx00Z88VHm2r7t3PMVmyZLoqiLgKfNozGtLurfCbJIGYSMyURd9OdNN tLV2k9brB1JIwGTUCAJy5UWY5AaXvp32V1RPw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=XFZ9I0BQtdSn/MnNXQrXFXBAcZOa5O5Ijp5JSlzHKh8=; b=DsxymmXErO6UFXkAOngpVhcZfvZ1EY9gxyvZhCh/cHeans9fl3KnsRAJa1KN8/FY3D ZqatAeq2i/w1WnAdfPU8SVscsamkrlvlvao+vlRBH5vskGnpWhlTMUK/CeMfECl6Z8+L 9p40ZOFx1jF23PrIUMFYH1EGo/TuLYKHckZ5s3eDo3VpyWIm10ecclqMVH1SdmVko9BV nusiqktIeWPo/M/9RQ2tVdp2Mx6nI8gU4dB9WJzpS8qxKY6BQhaHB3z2rjHR9SoSZopr pkx1xEwd7plJcvKBXyj1lcNb3HjmL4cRH4HV7nuoZnReoOXXTR6u5YMTPL/kfE8L7l0q S3ng== X-Gm-Message-State: AE9vXwOR3ke43bb91q3fKaGRbyDOeRKktSG1SoMBB7oOPuzzYoKV20jAnSGcEhVpGfox+Ren X-Received: by 10.66.170.44 with SMTP id aj12mr30910737pac.131.1472768899460; Thu, 01 Sep 2016 15:28:19 -0700 (PDT) Received: from localhost.localdomain (ip68-111-223-48.sd.sd.cox.net. [68.111.223.48]) by smtp.gmail.com with ESMTPSA id iw10sm8887131pac.14.2016.09.01.15.28.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 01 Sep 2016 15:28:18 -0700 (PDT) From: Bjorn Andersson To: Ohad Ben-Cohen , Bjorn Andersson Cc: linux-remoteproc@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 06/17] rpmsg: Introduce indirection table for rpmsg_device operations Date: Thu, 1 Sep 2016 15:27:58 -0700 Message-Id: <1472768889-3906-7-git-send-email-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1472768889-3906-1-git-send-email-bjorn.andersson@linaro.org> References: <1472768889-3906-1-git-send-email-bjorn.andersson@linaro.org> Sender: linux-remoteproc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-remoteproc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP To allow for multiple backend implementations add an indireection table for rpmsg_device related operations and move the virtio implementation behind this table. Signed-off-by: Bjorn Andersson --- Per Loic's comment I did consider adding parameter validation to the exposed functions in this patch, but as the previous implementation did not gracefully handle bad input parameters I decided to defer this until after this series has been merged. Changes since v1: - Split table in device vs endpoint - Moved ops pointer to the public structs to reduce code clutter - Kerneldoc for rpmsg_device_ops drivers/rpmsg/virtio_rpmsg_bus.c | 48 +++++++++++++++++++++++++++++++++++----- include/linux/rpmsg.h | 23 +++++++++++++++++++ 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 1ac9fd871760..088203ed1df8 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -286,10 +286,18 @@ struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *rpdev, rpmsg_rx_cb_t cb, void *priv, struct rpmsg_channel_info chinfo) { - return __rpmsg_create_ept(rpdev->vrp, rpdev, cb, priv, chinfo.src); + return rpdev->ops->create_ept(rpdev, cb, priv, chinfo); } EXPORT_SYMBOL(rpmsg_create_ept); +static struct rpmsg_endpoint *virtio_rpmsg_create_ept(struct rpmsg_device *rpdev, + rpmsg_rx_cb_t cb, + void *priv, + struct rpmsg_channel_info chinfo) +{ + return __rpmsg_create_ept(rpdev->vrp, rpdev, cb, priv, chinfo.src); +} + /** * __rpmsg_destroy_ept() - destroy an existing rpmsg endpoint * @vrp: virtproc which owns this ept @@ -341,7 +349,6 @@ static int rpmsg_dev_probe(struct device *dev) { struct rpmsg_device *rpdev = to_rpmsg_device(dev); struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); - struct virtproc_info *vrp = rpdev->vrp; struct rpmsg_channel_info chinfo = {}; struct rpmsg_endpoint *ept; int err; @@ -367,6 +374,18 @@ static int rpmsg_dev_probe(struct device *dev) goto out; } + if (rpdev->ops->announce_create) + err = rpdev->ops->announce_create(rpdev); +out: + return err; +} + +static int virtio_rpmsg_announce_create(struct rpmsg_device *rpdev) +{ + struct virtproc_info *vrp = rpdev->vrp; + struct device *dev = &rpdev->dev; + int err = 0; + /* need to tell remote processor's name service about this channel ? */ if (rpdev->announce && virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) { @@ -381,15 +400,13 @@ static int rpmsg_dev_probe(struct device *dev) dev_err(dev, "failed to announce service %d\n", err); } -out: return err; } -static int rpmsg_dev_remove(struct device *dev) +static int virtio_rpmsg_announce_destroy(struct rpmsg_device *rpdev) { - struct rpmsg_device *rpdev = to_rpmsg_device(dev); - struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); struct virtproc_info *vrp = rpdev->vrp; + struct device *dev = &rpdev->dev; int err = 0; /* tell remote processor's name service we're removing this channel */ @@ -406,6 +423,18 @@ static int rpmsg_dev_remove(struct device *dev) dev_err(dev, "failed to announce service %d\n", err); } + return err; +} + +static int rpmsg_dev_remove(struct device *dev) +{ + struct rpmsg_device *rpdev = to_rpmsg_device(dev); + struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); + int err = 0; + + if (rpdev->ops->announce_destroy) + err = rpdev->ops->announce_destroy(rpdev); + rpdrv->remove(rpdev); rpmsg_destroy_ept(rpdev->ept); @@ -479,6 +508,12 @@ static int rpmsg_device_match(struct device *dev, void *data) return 1; } +static const struct rpmsg_device_ops virtio_rpmsg_ops = { + .create_ept = virtio_rpmsg_create_ept, + .announce_create = virtio_rpmsg_announce_create, + .announce_destroy = virtio_rpmsg_announce_destroy, +}; + /* * create an rpmsg channel using its name and address info. * this function will be used to create both static and dynamic @@ -508,6 +543,7 @@ static struct rpmsg_device *rpmsg_create_channel(struct virtproc_info *vrp, rpdev->vrp = vrp; rpdev->src = chinfo->src; rpdev->dst = chinfo->dst; + rpdev->ops = &virtio_rpmsg_ops; /* * rpmsg server channels has predefined local address (for now), diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h index 35a0f39fd09b..9fdcfc7c7837 100644 --- a/include/linux/rpmsg.h +++ b/include/linux/rpmsg.h @@ -96,6 +96,8 @@ enum rpmsg_ns_flags { #define RPMSG_ADDR_ANY 0xFFFFFFFF struct virtproc_info; +struct rpmsg_endpoint; +struct rpmsg_device_ops; /** * struct rpmsg_channel_info - channel info representation @@ -127,11 +129,32 @@ struct rpmsg_device { u32 dst; struct rpmsg_endpoint *ept; bool announce; + + const struct rpmsg_device_ops *ops; }; typedef void (*rpmsg_rx_cb_t)(struct rpmsg_device *, void *, int, void *, u32); /** + * struct rpmsg_device_ops - indirection table for the rpmsg_device operations + * @create_ept: create backend-specific endpoint, requried + * @announce_create: announce presence of new channel, optional + * @announce_destroy: announce destruction of channel, optional + * + * Indirection table for the operations that a rpmsg backend should implement. + * @announce_create and @announce_destroy are optional as the backend might + * advertise new channels implicitly by creating the endpoints. + */ +struct rpmsg_device_ops { + struct rpmsg_endpoint *(*create_ept)(struct rpmsg_device *rpdev, + rpmsg_rx_cb_t cb, void *priv, + struct rpmsg_channel_info chinfo); + + int (*announce_create)(struct rpmsg_device *ept); + int (*announce_destroy)(struct rpmsg_device *ept); +}; + +/** * struct rpmsg_endpoint - binds a local rpmsg address to its user * @rpdev: rpmsg channel device * @refcount: when this drops to zero, the ept is deallocated