From patchwork Fri Nov 24 14:36:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud POULIQUEN X-Patchwork-Id: 10074129 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 6F7AF6056E for ; Fri, 24 Nov 2017 14:38:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 60B542A306 for ; Fri, 24 Nov 2017 14:38:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 55B3A2A356; Fri, 24 Nov 2017 14:38:59 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham 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 7DA9D2A320 for ; Fri, 24 Nov 2017 14:38:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753855AbdKXOi5 (ORCPT ); Fri, 24 Nov 2017 09:38:57 -0500 Received: from mx08-00178001.pphosted.com ([91.207.212.93]:41094 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753853AbdKXOiw (ORCPT ); Fri, 24 Nov 2017 09:38:52 -0500 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx08-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id vAOEYcUj012072; Fri, 24 Nov 2017 15:38:47 +0100 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-00178001.pphosted.com with ESMTP id 2eacmgw05m-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Fri, 24 Nov 2017 15:38:47 +0100 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id C82A134; Fri, 24 Nov 2017 14:38:46 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas21.st.com [10.75.90.44]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id AAE0951FA; Fri, 24 Nov 2017 14:38:46 +0000 (GMT) Received: from SAFEX1HUBCAS22.st.com (10.75.90.93) by SAFEX1HUBCAS21.st.com (10.75.90.44) with Microsoft SMTP Server (TLS) id 14.3.352.0; Fri, 24 Nov 2017 15:38:46 +0100 Received: from localhost (10.201.23.162) by Webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.352.0; Fri, 24 Nov 2017 15:38:46 +0100 From: Arnaud Pouliquen To: Bjorn Andersson CC: , , "Loic PALLARDY" , Fabien DESSENNE , Suman Anna Subject: [RFC 1/6] remoteproc: add early probed subdevices Date: Fri, 24 Nov 2017 15:36:37 +0100 Message-ID: <1511534202-12995-2-git-send-email-arnaud.pouliquen@st.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1511534202-12995-1-git-send-email-arnaud.pouliquen@st.com> References: <1511534202-12995-1-git-send-email-arnaud.pouliquen@st.com> MIME-Version: 1.0 X-Originating-IP: [10.201.23.162] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-11-24_05:, , signatures=0 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 From: Fabien Dessenne Add the option to use rproc subdevices that are probed *before* the remote processor firmware boot. Signed-off-by: Fabien Dessenne Signed-off-by: Arnaud Pouliquen Signed-off-by: Loic Pallardy --- drivers/remoteproc/remoteproc_core.c | 62 +++++++++++++++++++++++++++++------- include/linux/remoteproc.h | 7 ++++ 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index eab14b4..870b1fb 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -770,12 +770,12 @@ static int rproc_handle_resources(struct rproc *rproc, int len, return ret; } -static int rproc_probe_subdevices(struct rproc *rproc) +static int rproc_probe_subdevices(struct list_head *head) { struct rproc_subdev *subdev; int ret; - list_for_each_entry(subdev, &rproc->subdevs, node) { + list_for_each_entry(subdev, head, node) { ret = subdev->probe(subdev); if (ret) goto unroll_registration; @@ -784,17 +784,17 @@ static int rproc_probe_subdevices(struct rproc *rproc) return 0; unroll_registration: - list_for_each_entry_continue_reverse(subdev, &rproc->subdevs, node) + list_for_each_entry_continue_reverse(subdev, head, node) subdev->remove(subdev); return ret; } -static void rproc_remove_subdevices(struct rproc *rproc) +static void rproc_remove_subdevices(struct list_head *head) { struct rproc_subdev *subdev; - list_for_each_entry_reverse(subdev, &rproc->subdevs, node) + list_for_each_entry_reverse(subdev, head, node) subdev->remove(subdev); } @@ -881,20 +881,27 @@ static int rproc_start(struct rproc *rproc, const struct firmware *fw) rproc->table_ptr = loaded_table; } + /* early probe any subdevices for the remote processor */ + ret = rproc_probe_subdevices(&rproc->early_subdevs); + if (ret) { + dev_err(dev, "failed to early probe subdevices for %s: %d\n", + rproc->name, ret); + return ret; + } + /* power up the remote processor */ ret = rproc->ops->start(rproc); if (ret) { dev_err(dev, "can't start rproc %s: %d\n", rproc->name, ret); - return ret; + goto remove_early; } /* probe any subdevices for the remote processor */ - ret = rproc_probe_subdevices(rproc); + ret = rproc_probe_subdevices(&rproc->subdevs); if (ret) { dev_err(dev, "failed to probe subdevices for %s: %d\n", rproc->name, ret); - rproc->ops->stop(rproc); - return ret; + goto stop_rproc; } rproc->state = RPROC_RUNNING; @@ -902,6 +909,12 @@ static int rproc_start(struct rproc *rproc, const struct firmware *fw) dev_info(dev, "remote processor %s is now up\n", rproc->name); return 0; + +stop_rproc: + rproc->ops->stop(rproc); +remove_early: + rproc_remove_subdevices(&rproc->early_subdevs); + return ret; } /* @@ -1019,7 +1032,7 @@ static int rproc_stop(struct rproc *rproc) int ret; /* remove any subdevices for the remote processor */ - rproc_remove_subdevices(rproc); + rproc_remove_subdevices(&rproc->subdevs); /* power off the remote processor */ ret = rproc->ops->stop(rproc); @@ -1028,6 +1041,9 @@ static int rproc_stop(struct rproc *rproc) return ret; } + /* remove any early-probed subdevices for the remote processor */ + rproc_remove_subdevices(&rproc->early_subdevs); + /* if in crash state, unlock crash handler */ if (rproc->state == RPROC_CRASHED) complete_all(&rproc->crash_comp); @@ -1457,6 +1473,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, INIT_LIST_HEAD(&rproc->traces); INIT_LIST_HEAD(&rproc->rvdevs); INIT_LIST_HEAD(&rproc->subdevs); + INIT_LIST_HEAD(&rproc->early_subdevs); INIT_WORK(&rproc->crash_handler, rproc_crash_handler_work); init_completion(&rproc->crash_comp); @@ -1560,9 +1577,32 @@ void rproc_add_subdev(struct rproc *rproc, EXPORT_SYMBOL(rproc_add_subdev); /** + * rproc_add_early_subdev() - add an early subdevice to a remoteproc + * @rproc: rproc handle to add the subdevice to + * @subdev: subdev handle to register + * @probe: function to call before the rproc boots + * @remove: function to call after the rproc shuts down + * + * This function differs from rproc_add_subdev() in the sense that the added + * subdevices are probed BEFORE the rproc boots. + */ +void rproc_add_early_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->early_subdevs); +} +EXPORT_SYMBOL(rproc_add_early_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() + * @subdev: subdev handle, previously registered with rproc_add_subdev() or + * rproc_add_early_subdev() */ void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev) { diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 44e630e..e6b02d8 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -402,6 +402,7 @@ enum rproc_crash_type { * @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 + * @early_subdevs: list of early-probed subdevices * @notifyids: idr for dynamically assigning rproc-wide unique notify ids * @index: index of this rproc device * @crash_handler: workqueue for handling a crash @@ -433,6 +434,7 @@ struct rproc { u32 bootaddr; struct list_head rvdevs; struct list_head subdevs; + struct list_head early_subdevs; struct idr notifyids; int index; struct work_struct crash_handler; @@ -541,6 +543,11 @@ void rproc_add_subdev(struct rproc *rproc, int (*probe)(struct rproc_subdev *subdev), void (*remove)(struct rproc_subdev *subdev)); +void rproc_add_early_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 */