From patchwork Thu Oct 20 02:40:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 78387 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp561093qge; Wed, 19 Oct 2016 19:42:31 -0700 (PDT) X-Received: by 10.98.216.194 with SMTP id e185mr16820315pfg.148.1476931351284; Wed, 19 Oct 2016 19:42:31 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t8si7071410pgn.52.2016.10.19.19.42.31; Wed, 19 Oct 2016 19:42:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757554AbcJTCm1 (ORCPT + 27 others); Wed, 19 Oct 2016 22:42:27 -0400 Received: from mail-pf0-f171.google.com ([209.85.192.171]:35076 "EHLO mail-pf0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757442AbcJTCkR (ORCPT ); Wed, 19 Oct 2016 22:40:17 -0400 Received: by mail-pf0-f171.google.com with SMTP id s8so26521809pfj.2 for ; Wed, 19 Oct 2016 19:40:17 -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=8fMae8eaHFGmPyWCRT9Ed963z+qn4I90ZPoxEw9s0oc=; b=GArK8GBnO1R11KgXo8VLVJgX9RKFdjpTfCOxrEqTd7ShEoOhMmsLu1P/Svu/yooMDe ScYmNbtPxXrLNfxiXIhFpOMaUv85+SU//Kvzmu9f/L9iATwM0usabQnmNuvaCPi79Ogr hBluSDZB0aCtHjDdT6432wBs4E42UlxVgcRDs= 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=8fMae8eaHFGmPyWCRT9Ed963z+qn4I90ZPoxEw9s0oc=; b=KaGZGxgcsAA/yZ1jS+EXU1L4kcSJurRbTpW8bqaA4140xF2tacYGV8BnlyaZ+ue3id jWeZuogXF5Nq1D9ZaE9nk6j2rEJOicM1LKWAIKBU1KeyGzNiQvJQm3kIWn0oQkWofDaX Fbq7EG70J8n/uHkKNfW83Fs/L+UFljTmnPB8jx4/7cgGkcskV5GmAHyWY8aipyGi0X9X QAWlojRw6mSCfBZpSdZEcJyvx1Ib00Iif5MwPmHsoliL70WE3fZsisG0LN81vbhjLX4V UEyQXlLojlxNy3MhiZpSM1h9R8SzUxVkKqady6lXOt3cJF5JNzGw239RqAeZybGWgmxZ 4KnA== X-Gm-Message-State: AA6/9Rm5Jr/urViNYRLkt0uoTi00TDCqLXWRDoxgp/pmqB68uN2r23M8QGs+X1B4+6aTUmKp X-Received: by 10.99.67.7 with SMTP id q7mr13881862pga.74.1476931216528; Wed, 19 Oct 2016 19:40:16 -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 s85sm66780616pfi.17.2016.10.19.19.40.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 19 Oct 2016 19:40:15 -0700 (PDT) From: Bjorn Andersson To: Ohad Ben-Cohen , Bjorn Andersson Cc: linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, Sarangdhar Joshi , linux-arm-msm@vger.kernel.org Subject: [PATCH 01/11] remoteproc: Introduce subdevices Date: Wed, 19 Oct 2016 19:40:02 -0700 Message-Id: <1476931212-1806-2-git-send-email-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1476931212-1806-1-git-send-email-bjorn.andersson@linaro.org> References: <1476931212-1806-1-git-send-email-bjorn.andersson@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org A subdevice is an abstract entity that can be used to tie actions to the booting and shutting down of a remote processor. The subdevice object is expected to be embedded in concrete implementations, allowing for a variety of use cases to be implemented. Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 72 ++++++++++++++++++++++++++++++++++++ include/linux/remoteproc.h | 22 +++++++++++ 2 files changed, 94 insertions(+) -- 2.5.0 diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index c6bfb3496684..4309996f4335 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -736,6 +736,34 @@ static int rproc_handle_resources(struct rproc *rproc, int len, return ret; } +static int rproc_probe_subdevices(struct rproc *rproc) +{ + struct rproc_subdev *subdev; + int ret; + + list_for_each_entry(subdev, &rproc->subdevs, node) { + ret = subdev->probe(subdev); + if (ret) + goto unroll_registration; + } + + return 0; + +unroll_registration: + list_for_each_entry_continue_reverse(subdev, &rproc->subdevs, node) + subdev->remove(subdev); + + return ret; +} + +static void rproc_remove_subdevices(struct rproc *rproc) +{ + struct rproc_subdev *subdev; + + list_for_each_entry(subdev, &rproc->subdevs, node) + subdev->remove(subdev); +} + /** * rproc_resource_cleanup() - clean up and free all acquired resources * @rproc: rproc handle @@ -878,12 +906,22 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) goto clean_up_resources; } + /* probe any subdevices for the remote processor */ + ret = rproc_probe_subdevices(rproc); + if (ret) { + dev_err(dev, "failed to probe subdevices for %s: %d\n", + rproc->name, ret); + goto stop_rproc; + } + rproc->state = RPROC_RUNNING; dev_info(dev, "remote processor %s is now up\n", rproc->name); return 0; +stop_rproc: + rproc->ops->stop(rproc); clean_up_resources: rproc_resource_cleanup(rproc); clean_up: @@ -1121,6 +1159,9 @@ void rproc_shutdown(struct rproc *rproc) if (!atomic_dec_and_test(&rproc->power)) goto out; + /* remove any subdevices for the remote processor */ + rproc_remove_subdevices(rproc); + /* power off the remote processor */ ret = rproc->ops->stop(rproc); if (ret) { @@ -1370,6 +1411,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, INIT_LIST_HEAD(&rproc->mappings); INIT_LIST_HEAD(&rproc->traces); INIT_LIST_HEAD(&rproc->rvdevs); + INIT_LIST_HEAD(&rproc->subdevs); INIT_WORK(&rproc->crash_handler, rproc_crash_handler_work); init_completion(&rproc->crash_comp); @@ -1457,6 +1499,36 @@ int rproc_del(struct rproc *rproc) EXPORT_SYMBOL(rproc_del); /** + * rproc_add_subdev() - add a subdevice to a remoteproc + * @rproc: rproc handle to add the subdevice to + * @subdev: subdev handle to register + * @probe: function to call when the rproc boots + * @remove: function to call when the rproc shuts down + */ +void rproc_add_subdev(struct rproc *rproc, + struct rproc_subdev *subdev, + int (*probe)(struct rproc_subdev *subdev), + void (*remove)(struct rproc_subdev *subdev)) +{ + subdev->probe = probe; + subdev->remove = remove; + + list_add_tail(&subdev->node, &rproc->subdevs); +} +EXPORT_SYMBOL(rproc_add_subdev); + +/** + * rproc_remove_subdev() - remove a subdevice from a remoteproc + * @rproc: rproc handle to remove the subdevice from + * @subdev: subdev handle, previously registered with rproc_add_subdev() + */ +void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev) +{ + list_del(&subdev->node); +} +EXPORT_SYMBOL(rproc_remove_subdev); + +/** * rproc_report_crash() - rproc crash reporter function * @rproc: remote processor * @type: crash type diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 930023b7c825..a05f4569a2a0 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -400,6 +400,7 @@ enum rproc_crash_type { * @firmware_loading_complete: marks e/o asynchronous firmware loading * @bootaddr: address of first instruction to boot rproc with (optional) * @rvdevs: list of remote virtio devices + * @subdevs: list of subdevices, to following the running state * @notifyids: idr for dynamically assigning rproc-wide unique notify ids * @index: index of this rproc device * @crash_handler: workqueue for handling a crash @@ -431,6 +432,7 @@ struct rproc { struct completion firmware_loading_complete; u32 bootaddr; struct list_head rvdevs; + struct list_head subdevs; struct idr notifyids; int index; struct work_struct crash_handler; @@ -444,6 +446,19 @@ struct rproc { bool auto_boot; }; +/** + * struct rproc_subdev - subdevice tied to a remoteproc + * @node: list node related to the rproc subdevs list + * @probe: probe function, called as the rproc is started + * @remove: remove function, called as the rproc is stopped + */ +struct rproc_subdev { + struct list_head node; + + int (*probe)(struct rproc_subdev *subdev); + void (*remove)(struct rproc_subdev *subdev); +}; + /* we currently support only two vrings per rvdev */ #define RVDEV_NUM_VRINGS 2 @@ -511,4 +526,11 @@ static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev) return rvdev->rproc; } +void rproc_add_subdev(struct rproc *rproc, + struct rproc_subdev *subdev, + int (*probe)(struct rproc_subdev *subdev), + void (*remove)(struct rproc_subdev *subdev)); + +void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev); + #endif /* REMOTEPROC_H */