From patchwork Tue May 15 20:53:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 135931 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp27912lji; Tue, 15 May 2018 13:54:22 -0700 (PDT) X-Google-Smtp-Source: AB8JxZohWwtZEcxVwPjolM+Ig4geW+JkkN/px3qLm/HEEIch61qf1HIzjAriTNntHCFLQwWxRklp X-Received: by 2002:a62:df4c:: with SMTP id u73-v6mr16576620pfg.10.1526417662587; Tue, 15 May 2018 13:54:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526417662; cv=none; d=google.com; s=arc-20160816; b=eaPHxAFHYrYpkx/GVyUBfa+y00SklsLbYWybmuRbjTcUTBWZ19GFd1ujEs/mnMW5el FKxqQNX4+Xde1eqCqASChtw0txnRlEJzuyedd7ejzOa8mT03dcSndqmY5JvZibTMRKBY QqD4SqwXOKe2Nh1qWYTYqSgBGD14X811cvLDh2DpIFgbPBAD7Ho8ZR4mPG9OyV26KvFg 4PT9kipn0hHjLn2vC3yqUtDMWElfB9dPztDb7wV0XXZEVGxuqppe2iSgK0DkfdlsvoG+ Xe+LYxKZsKF7aHqUmocKTImnO2LywCy13lRg7sMDD+fIzxCiBJY9l9JNPajJX1jzVD2E 7xNw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=D3N7W54F0ZPkdgLap0aIOEK/9V7dheITVPxXL9WueC0=; b=BjyDE90SmjPYkHJnes72yevipsj0lo9zIVfe70umMvbP03wfjM7juB3wUTiozGGzn6 vQ/WWIIVYWkvESB8pYhJEI+SrxcEFeKJinqnoyy6ElLOPLEUJACVvy31rXJZyjzJHcpn v/oEs566f5kazsP/7aFcoPFG8VTw2ILSnOW/lICzA7sczHM8R7qwPaBpmnEoN95ESLdS AeJ6//0f9F/X/J8m6x6f+VOq4BLCmgJ/4P1W9xKOMvK7vICdyRoYmJmehf+ibwuRc6c1 sTbWkxIxlkuZSPkAK2CkUr+EeeJQvF6YKDZiY54L4E08K8aZSwLezyHAdF11KpXeQk/Y 4//Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=aaI8htk1; 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 sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d29-v6si916056pfb.232.2018.05.15.13.54.22; Tue, 15 May 2018 13:54:22 -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 header.s=google header.b=aaI8htk1; 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 sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752751AbeEOUyT (ORCPT + 29 others); Tue, 15 May 2018 16:54:19 -0400 Received: from mail-it0-f66.google.com ([209.85.214.66]:34370 "EHLO mail-it0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752642AbeEOUyA (ORCPT ); Tue, 15 May 2018 16:54:00 -0400 Received: by mail-it0-f66.google.com with SMTP id c5-v6so14063857itj.1 for ; Tue, 15 May 2018 13:53:59 -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=D3N7W54F0ZPkdgLap0aIOEK/9V7dheITVPxXL9WueC0=; b=aaI8htk1b/jN2V0OKUGjQaedzxYsEJbuzR7/72euqPeC1VGXXs/oWiisdetOr69HDn /2FZa+aWQAK3wRXZyTouQ+ONShmdI9BGFWHg09f0ZUsaQfeqWL3C+x0RrYM3jiuHdIzT RlMXWThDhr86vPy0EfyvIL/0mKJRnWfXtCIDE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=D3N7W54F0ZPkdgLap0aIOEK/9V7dheITVPxXL9WueC0=; b=WouWOBseMmI7bzKKjEKPs0GXBStkPkjXN4SPxvBhdFoqVZGk17OaAbbcmrBa+Dbo8t 6Vu0jKjz/0hH2I04WMsXSTQNa+c9q0gQvhWAKsmDqnuGo2VgIGm/ziQG9fGXgGPBfmo2 1o2c3mdgezdetwstuH8ktYjdY+kt7Mc38SW39UUFGtPqe2zWStZ7dCyuO3gCPEgwVHGk OjIF9G19Eek6gJ9gykYp1QJnihB7yFw0tDBN/68jLgOKmnzoNSC03eMu64JROQbOXhHy 72dkYKOQK4JbDY1Uy6mJFWm/ek6w2Ma9yF6x+gEk6oot6LDA/pt1BFdd38qbKdamP36x aOXg== X-Gm-Message-State: ALKqPwcLEYL8L3yIOJ9uijyVukStXvMBTzdS3J/YfQoBYrKTQRgM0T2H wOehAjoFNPkQreNiWIlHvr9qtQ== X-Received: by 2002:a24:ca87:: with SMTP id k129-v6mr16253686itg.140.1526417639296; Tue, 15 May 2018 13:53:59 -0700 (PDT) Received: from localhost.localdomain (c-71-195-29-92.hsd1.mn.comcast.net. [71.195.29.92]) by smtp.gmail.com with ESMTPSA id t9-v6sm440407ioa.82.2018.05.15.13.53.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 15 May 2018 13:53:58 -0700 (PDT) From: Alex Elder To: ohad@wizery.com, bjorn.andersson@linaro.org Cc: linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 5/5] remoteproc: Introduce prepare and unprepare for subdevices Date: Tue, 15 May 2018 15:53:45 -0500 Message-Id: <20180515205345.8090-6-elder@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180515205345.8090-1-elder@linaro.org> References: <20180515205345.8090-1-elder@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Bjorn Andersson On rare occasions a subdevice might need to prepare some hardware resources before a remote processor is booted, and clean up some state after it has been shut down. One such example is the IP Accelerator found in various Qualcomm platforms, which is accessed directly from both the modem remoteproc and the application subsystem and requires an intricate lockstep process when bringing the modem up and down. [elder@linaro.org: minor description and comment edits] Signed-off-by: Bjorn Andersson Acked-by: Alex Elder --- drivers/remoteproc/remoteproc_core.c | 56 ++++++++++++++++++++++++++-- include/linux/remoteproc.h | 4 ++ 2 files changed, 57 insertions(+), 3 deletions(-) -- 2.17.0 Tested-by: Fabien Dessenne diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 2ede7ae6f5bc..283b258f5e0f 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -776,6 +776,30 @@ static int rproc_handle_resources(struct rproc *rproc, return ret; } +static int rproc_prepare_subdevices(struct rproc *rproc) +{ + struct rproc_subdev *subdev; + int ret; + + list_for_each_entry(subdev, &rproc->subdevs, node) { + if (subdev->prepare) { + ret = subdev->prepare(subdev); + if (ret) + goto unroll_preparation; + } + } + + return 0; + +unroll_preparation: + list_for_each_entry_continue_reverse(subdev, &rproc->subdevs, node) { + if (subdev->unprepare) + subdev->unprepare(subdev); + } + + return ret; +} + static int rproc_start_subdevices(struct rproc *rproc) { struct rproc_subdev *subdev; @@ -810,6 +834,16 @@ static void rproc_stop_subdevices(struct rproc *rproc, bool crashed) } } +static void rproc_unprepare_subdevices(struct rproc *rproc) +{ + struct rproc_subdev *subdev; + + list_for_each_entry_reverse(subdev, &rproc->subdevs, node) { + if (subdev->unprepare) + subdev->unprepare(subdev); + } +} + /** * rproc_coredump_cleanup() - clean up dump_segments list * @rproc: the remote processor handle @@ -902,11 +936,18 @@ static int rproc_start(struct rproc *rproc, const struct firmware *fw) rproc->table_ptr = loaded_table; } + ret = rproc_prepare_subdevices(rproc); + if (ret) { + dev_err(dev, "failed to prepare 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 unprepare_subdevices; } /* Start any subdevices for the remote processor */ @@ -914,8 +955,7 @@ static int rproc_start(struct rproc *rproc, const struct firmware *fw) 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; @@ -923,6 +963,14 @@ 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); + +unprepare_subdevices: + rproc_unprepare_subdevices(rproc); + + return ret; } /* @@ -1035,6 +1083,8 @@ static int rproc_stop(struct rproc *rproc, bool crashed) return ret; } + rproc_unprepare_subdevices(rproc); + rproc->state = RPROC_OFFLINE; dev_info(dev, "stopped remote processor %s\n", rproc->name); diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 8f1426330cca..e3c5d856b6da 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -477,15 +477,19 @@ struct rproc { /** * struct rproc_subdev - subdevice tied to a remoteproc * @node: list node related to the rproc subdevs list + * @prepare: prepare function, called before the rproc is started * @start: start function, called after the rproc has been started * @stop: stop function, called before the rproc is stopped; the @crashed * parameter indicates if this originates from a recovery + * @unprepare: unprepare function, called after the rproc has been stopped */ struct rproc_subdev { struct list_head node; + int (*prepare)(struct rproc_subdev *subdev); int (*start)(struct rproc_subdev *subdev); void (*stop)(struct rproc_subdev *subdev, bool crashed); + void (*unprepare)(struct rproc_subdev *subdev); }; /* we currently support only two vrings per rvdev */