From patchwork Wed Jun 27 08:06:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabien DESSENNE X-Patchwork-Id: 10490785 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 D2FCB602B3 for ; Wed, 27 Jun 2018 08:07:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C4C62285F9 for ; Wed, 27 Jun 2018 08:07:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B892B28A40; Wed, 27 Jun 2018 08:07:10 +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=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, 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 F3031285F9 for ; Wed, 27 Jun 2018 08:07:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753282AbeF0IHJ (ORCPT ); Wed, 27 Jun 2018 04:07:09 -0400 Received: from mx08-00178001.pphosted.com ([91.207.212.93]:7377 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753232AbeF0IHI (ORCPT ); Wed, 27 Jun 2018 04:07:08 -0400 Received: from pps.filterd (m0046660.ppops.net [127.0.0.1]) by mx08-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id w5R83c2b010347; Wed, 27 Jun 2018 10:07:04 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-00178001.pphosted.com with ESMTP id 2jv6gxr35h-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 27 Jun 2018 10:07:04 +0200 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 E69504A; Wed, 27 Jun 2018 08:06:48 +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 B635013B4; Wed, 27 Jun 2018 08:06:48 +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.361.1; Wed, 27 Jun 2018 10:06:48 +0200 Received: from localhost (10.201.23.25) by Webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.361.1; Wed, 27 Jun 2018 10:06:48 +0200 From: Fabien Dessenne To: Bjorn Andersson , , Arnaud Pouliquen , Loic Pallardy , "Oleksij Rempel" CC: Fabien Dessenne , Suman Anna , "Alex Elder" Subject: [RFC v2 2/5] remoteproc: add system resource manager core Date: Wed, 27 Jun 2018 10:06:19 +0200 Message-ID: <1530086782-5046-3-git-send-email-fabien.dessenne@st.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1530086782-5046-1-git-send-email-fabien.dessenne@st.com> References: <1530086782-5046-1-git-send-email-fabien.dessenne@st.com> MIME-Version: 1.0 X-Originating-IP: [10.201.23.25] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-06-27_02:, , 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 The remoteproc SRM (System Resource Manager) handles resources allocated to remote processors. This makes it possible for remote proc to reserve and initialize system resources for a peripheral assigned to a coprocessor. This is the core part which is in charge of controlling the device children. Signed-off-by: Fabien Dessenne Signed-off-by: Arnaud Pouliquen Signed-off-by: Loic Pallardy --- Documentation/remoteproc.txt | 23 ++++ drivers/remoteproc/Kconfig | 8 ++ drivers/remoteproc/Makefile | 1 + drivers/remoteproc/rproc_srm_core.c | 205 ++++++++++++++++++++++++++++++++++++ 4 files changed, 237 insertions(+) create mode 100644 drivers/remoteproc/rproc_srm_core.c diff --git a/Documentation/remoteproc.txt b/Documentation/remoteproc.txt index 77fb03a..bec2177 100644 --- a/Documentation/remoteproc.txt +++ b/Documentation/remoteproc.txt @@ -353,3 +353,26 @@ Of course, RSC_VDEV resource entries are only good enough for static allocation of virtio devices. Dynamic allocations will also be made possible using the rpmsg bus (similar to how we already do dynamic allocations of rpmsg channels; read more about it in rpmsg.txt). + +8. System Resource Manager (SRM) + +Since some resources are shared (directly or not) between the processors, a +processor cannot manage such resources without potentially impacting the other +processors : as an example, if a processor changes the frequency of a clock, the +frequency of another clock managed by another processor may be updated too. + +The System Resource Manager prevents such resource conflicts between the +processors : it reserves and initializes the system resources of the peripherals +assigned to a remote processor. + +As of today the following resources are controlled by the SRM: +- clocks +- gpios (pinctrl) +- regulators (power supplies) + +The SRM is implemented as an 'rproc_subdev' and registered to remoteproc_core. +Unlike the virtio device (vdev), the SRM subdev is probed *before* the rproc +boots, ensuring the availability of the resources before the remoteproc starts. + +The resources handled by the SRM are defined in the DeviceTree: please read +Documentation/devicetree/bindings/remoteproc/rproc-srm.txt for details. diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index cd1c168..e981831 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -13,6 +13,14 @@ config REMOTEPROC if REMOTEPROC +config REMOTEPROC_SRM_CORE + tristate "Remoteproc System Resource Manager core" + help + Say y here to enable the core driver of the remoteproc System Resource + Manager (SRM). + The SRM handles resources allocated to remote processors. + The core part is in charge of controlling the device children. + config IMX_REMOTEPROC tristate "IMX6/7 remoteproc support" depends on SOC_IMX6SX || SOC_IMX7D diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index 02627ed..2be447a 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -9,6 +9,7 @@ remoteproc-y += remoteproc_debugfs.o remoteproc-y += remoteproc_sysfs.o remoteproc-y += remoteproc_virtio.o remoteproc-y += remoteproc_elf_loader.o +obj-$(CONFIG_REMOTEPROC_SRM_CORE) += rproc_srm_core.o obj-$(CONFIG_IMX_REMOTEPROC) += imx_rproc.o obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o diff --git a/drivers/remoteproc/rproc_srm_core.c b/drivers/remoteproc/rproc_srm_core.c new file mode 100644 index 0000000..29fcc73 --- /dev/null +++ b/drivers/remoteproc/rproc_srm_core.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved + * Author: Fabien Dessenne . + * + * License type: GPLv2 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#define BIND_TIMEOUT 10000 + +struct rproc_srm_core { + struct device *dev; + struct completion all_bound; + int bind_status; + atomic_t prepared; + struct rproc_subdev subdev; +}; + +#define to_rproc_srm_core(s) container_of(s, struct rproc_srm_core, subdev) + +static int compare_of(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +static void release_of(struct device *dev, void *data) +{ + of_node_put(data); +} + +static void rproc_srm_core_unbind(struct device *dev) +{ + component_unbind_all(dev, NULL); +} + +static int rproc_srm_core_bind(struct device *dev) +{ + struct rproc_srm_core *rproc_srm_core = dev_get_drvdata(dev); + + rproc_srm_core->bind_status = component_bind_all(dev, NULL); + complete(&rproc_srm_core->all_bound); + + return rproc_srm_core->bind_status; +} + +static const struct component_master_ops srm_comp_ops = { + .bind = rproc_srm_core_bind, + .unbind = rproc_srm_core_unbind, +}; + +static int rproc_srm_core_prepare(struct rproc_subdev *subdev) +{ + struct rproc_srm_core *rproc_srm_core = to_rproc_srm_core(subdev); + struct device *dev = rproc_srm_core->dev; + struct device_node *node = dev->of_node; + struct device_node *child_np; + struct component_match *match = NULL; + int ret; + + dev_dbg(dev, "%s\n", __func__); + + init_completion(&rproc_srm_core->all_bound); + + ret = devm_of_platform_populate(dev); + if (ret) { + dev_err(dev, "cannot populate node (%d)\n", ret); + return ret; + } + + child_np = of_get_next_available_child(node, NULL); + + while (child_np) { + of_node_get(child_np); + component_match_add_release(dev, &match, release_of, compare_of, + child_np); + child_np = of_get_next_available_child(node, child_np); + } + + if (!match) { + dev_dbg(dev, "No available child\n"); + goto done; + } + + ret = component_master_add_with_match(dev, &srm_comp_ops, match); + if (ret) + goto depopulate; + + /* Wait for every child to be bound */ + if (!wait_for_completion_timeout(&rproc_srm_core->all_bound, + msecs_to_jiffies(BIND_TIMEOUT))) { + dev_err(dev, "bind timeout\n"); + ret = -ETIMEDOUT; + goto master; + } + + ret = rproc_srm_core->bind_status; + if (ret) { + dev_err(dev, "failed to bind\n"); + goto master; + } +done: + atomic_inc(&rproc_srm_core->prepared); + + return 0; + +master: + component_master_del(dev, &srm_comp_ops); +depopulate: + devm_of_platform_depopulate(dev); + return ret; +} + +static void rproc_srm_core_do_unprepare(struct rproc_subdev *subdev) +{ + struct rproc_srm_core *rproc_srm_core = to_rproc_srm_core(subdev); + struct device *dev = rproc_srm_core->dev; + + dev_dbg(dev, "%s\n", __func__); + + atomic_dec(&rproc_srm_core->prepared); + + component_master_del(dev, &srm_comp_ops); + devm_of_platform_depopulate(dev); +} + +static int rproc_srm_core_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rproc *rproc = dev_get_drvdata(dev->parent); + struct rproc_srm_core *rproc_srm_core; + + dev_dbg(dev, "%s\n", __func__); + + rproc_srm_core = devm_kzalloc(dev, sizeof(struct rproc_srm_core), + GFP_KERNEL); + if (!rproc_srm_core) + return -ENOMEM; + + rproc_srm_core->dev = dev; + + /* Register rproc subdevice with (un)prepare ops */ + rproc_srm_core->subdev.prepare = rproc_srm_core_prepare; + rproc_srm_core->subdev.unprepare = rproc_srm_core_unprepare; + rproc_add_subdev(rproc, &rproc_srm_core->subdev); + + dev_set_drvdata(dev, rproc_srm_core); + + return 0; +} + +static int rproc_srm_core_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rproc_srm_core *rproc_srm_core = dev_get_drvdata(dev); + struct rproc *rproc = dev_get_drvdata(dev->parent); + + dev_dbg(dev, "%s\n", __func__); + + if (atomic_read(&rproc->power) > 0) + dev_warn(dev, "Releasing resources while firmware running!\n"); + + if (atomic_read(&rproc_srm_core->prepared)) + rproc_srm_core_unprepare(&rproc_srm_core->subdev); + + return 0; +} + +static const struct of_device_id rproc_srm_core_match[] = { + { .compatible = "rproc-srm-core", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, rproc_srm_core_match); + +static struct platform_driver rproc_srm_core_driver = { + .probe = rproc_srm_core_probe, + .remove = rproc_srm_core_remove, + .driver = { + .name = "rproc-srm-core", + .of_match_table = of_match_ptr(rproc_srm_core_match), + }, +}; + +module_platform_driver(rproc_srm_core_driver); + +MODULE_AUTHOR("Fabien Dessenne "); +MODULE_DESCRIPTION("Remoteproc System Resource Manager driver - core"); +MODULE_LICENSE("GPL v2");