From patchwork Mon May 21 17:27:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sibi Sankar X-Patchwork-Id: 10416031 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 41F446032C for ; Mon, 21 May 2018 17:29:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3130D2897E for ; Mon, 21 May 2018 17:29:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 25C1C28991; Mon, 21 May 2018 17:29:34 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, 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 A1D472897E for ; Mon, 21 May 2018 17:29:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753247AbeEUR3c (ORCPT ); Mon, 21 May 2018 13:29:32 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:56598 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753408AbeEUR16 (ORCPT ); Mon, 21 May 2018 13:27:58 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 403D060C65; Mon, 21 May 2018 17:27:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1526923678; bh=LCv+giCeBvplG9S2d440B28l/AH7u4YELWkztjDFXlg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eXdTJLhS+CbJ6bTfq12q+GTnTNpwQsu0kVLAgd9uuwqFk2uZ+CAsuRBJuC7a7lum0 wIIGPwYX11V8MfqRfVvQz5iBUA9h1xcOgwyDkoYJZGxfuE044GA2DukLfB1WJ641ri ZMRNfsC9MvgrYpt3rJBJaiChT3lwNEVCBJ3y/bhs= Received: from blr-ubuntu-87.qualcomm.com (blr-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.18.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: sibis@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id E767960A06; Mon, 21 May 2018 17:27:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1526923677; bh=LCv+giCeBvplG9S2d440B28l/AH7u4YELWkztjDFXlg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AwBVFKNFaEgPMXbRoZSdEjjb49F3krld2cAkNbezM1gQuK+MViPz2Isid+U11jxqS ZX0G7QFTloBKUILKDZnasJmazbiOdqFA+mxF4ymYZ+DdOJ2otSowEAxUAGUyj9RqTl yNOt7SeW2ESPhDmYi6YN7Yhyo6aSJNAaNpoF4DX4= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org E767960A06 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=sibis@codeaurora.org From: Sibi Sankar To: bjorn.andersson@linaro.org, p.zabel@pengutronix.de, robh+dt@kernel.org Cc: linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, sibis@codeaurora.org, georgi.djakov@linaro.org, jassisinghbrar@gmail.com, ohad@wizery.com, mark.rutland@arm.com, kyan@codeaurora.org, sricharan@codeaurora.org, akdwived@codeaurora.org, linux-arm-msm@vger.kernel.org, tsoni@codeaurora.org Subject: [PATCH v5 4/8] remoteproc: Synchronize proxy unvote from multiple contexts Date: Mon, 21 May 2018 22:57:10 +0530 Message-Id: <20180521172714.8551-5-sibis@codeaurora.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180521172714.8551-1-sibis@codeaurora.org> References: <20180521172714.8551-1-sibis@codeaurora.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 Synchronize proxy unvote of clks/regs from q6v5_stop and handover interrupt to prevent multiple proxy unvotes for a single rproc start. Signed-off-by: Sibi Sankar --- drivers/remoteproc/qcom_q6v5_pil.c | 73 ++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c index 6333bdcd9448..a5fa6521bb83 100644 --- a/drivers/remoteproc/qcom_q6v5_pil.c +++ b/drivers/remoteproc/qcom_q6v5_pil.c @@ -143,6 +143,10 @@ struct q6v5 { struct qcom_smem_state *state; unsigned stop_bit; + int handover_irq; + int wdog_irq; + int fatal_irq; + struct clk *active_clks[8]; struct clk *proxy_clks[4]; int active_clk_count; @@ -170,6 +174,7 @@ struct q6v5 { struct qcom_rproc_ssr ssr_subdev; struct qcom_sysmon *sysmon; bool need_mem_protection; + bool unvoted_flag; int mpss_perm; int mba_perm; int version; @@ -304,6 +309,20 @@ static void q6v5_clk_disable(struct device *dev, clk_disable_unprepare(clks[i]); } +static void q6v5_enable_irqs(struct q6v5 *qproc) +{ + enable_irq(qproc->wdog_irq); + enable_irq(qproc->fatal_irq); + enable_irq(qproc->handover_irq); +} + +static void q6v5_disable_irqs(struct q6v5 *qproc) +{ + disable_irq(qproc->handover_irq); + disable_irq(qproc->fatal_irq); + disable_irq(qproc->wdog_irq); +} + static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, int *current_perm, bool remote_owner, phys_addr_t addr, size_t size) @@ -727,6 +746,7 @@ static int q6v5_start(struct rproc *rproc) int xfermemop_ret; int ret; + qproc->unvoted_flag = false; ret = q6v5_regulator_enable(qproc, qproc->proxy_regs, qproc->proxy_reg_count); if (ret) { @@ -793,9 +813,12 @@ static int q6v5_start(struct rproc *rproc) if (ret) goto reclaim_mpss; + q6v5_enable_irqs(qproc); + ret = wait_for_completion_timeout(&qproc->start_done, msecs_to_jiffies(5000)); if (ret == 0) { + q6v5_disable_irqs(qproc); dev_err(qproc->dev, "start timed out\n"); ret = -ETIMEDOUT; goto reclaim_mpss; @@ -887,11 +910,14 @@ static int q6v5_stop(struct rproc *rproc) WARN_ON(ret); reset_control_assert(qproc->mss_restart); + q6v5_disable_irqs(qproc); - q6v5_clk_disable(qproc->dev, qproc->proxy_clks, - qproc->proxy_clk_count); - q6v5_regulator_disable(qproc, qproc->proxy_regs, - qproc->proxy_reg_count); + if (!qproc->unvoted_flag) { + q6v5_clk_disable(qproc->dev, qproc->proxy_clks, + qproc->proxy_clk_count); + q6v5_regulator_disable(qproc, qproc->proxy_regs, + qproc->proxy_reg_count); + } q6v5_clk_disable(qproc->dev, qproc->active_clks, qproc->active_clk_count); @@ -972,10 +998,13 @@ static irqreturn_t q6v5_handover_interrupt(int irq, void *dev) { struct q6v5 *qproc = dev; - q6v5_clk_disable(qproc->dev, qproc->proxy_clks, - qproc->proxy_clk_count); - q6v5_regulator_disable(qproc, qproc->proxy_regs, - qproc->proxy_reg_count); + if (!qproc->unvoted_flag) { + qproc->unvoted_flag = true; + q6v5_clk_disable(qproc->dev, qproc->proxy_clks, + qproc->proxy_clk_count); + q6v5_regulator_disable(qproc, qproc->proxy_regs, + qproc->proxy_reg_count); + } return IRQ_HANDLED; } @@ -1058,18 +1087,18 @@ static int q6v5_init_reset(struct q6v5 *qproc) return 0; } -static int q6v5_request_irq(struct q6v5 *qproc, +static inline int q6v5_request_irq(struct q6v5 *qproc, struct platform_device *pdev, const char *name, - irq_handler_t thread_fn) + irq_handler_t thread_fn, + unsigned int *irq_num) { int ret; ret = platform_get_irq_byname(pdev, name); - if (ret < 0) { - dev_err(&pdev->dev, "no %s IRQ defined\n", name); - return ret; - } + + if (irq_num) + *irq_num = ret; ret = devm_request_threaded_irq(&pdev->dev, ret, NULL, thread_fn, @@ -1199,26 +1228,32 @@ static int q6v5_probe(struct platform_device *pdev) qproc->version = desc->version; qproc->need_mem_protection = desc->need_mem_protection; - ret = q6v5_request_irq(qproc, pdev, "wdog", q6v5_wdog_interrupt); + ret = q6v5_request_irq(qproc, pdev, "wdog", q6v5_wdog_interrupt, + &qproc->wdog_irq); if (ret < 0) goto free_rproc; - ret = q6v5_request_irq(qproc, pdev, "fatal", q6v5_fatal_interrupt); + ret = q6v5_request_irq(qproc, pdev, "fatal", q6v5_fatal_interrupt, + &qproc->fatal_irq); if (ret < 0) goto free_rproc; - ret = q6v5_request_irq(qproc, pdev, "ready", q6v5_ready_interrupt); + ret = q6v5_request_irq(qproc, pdev, "ready", q6v5_ready_interrupt, + NULL); if (ret < 0) goto free_rproc; - ret = q6v5_request_irq(qproc, pdev, "handover", q6v5_handover_interrupt); + ret = q6v5_request_irq(qproc, pdev, "handover", q6v5_handover_interrupt, + &qproc->handover_irq); if (ret < 0) goto free_rproc; - ret = q6v5_request_irq(qproc, pdev, "stop-ack", q6v5_stop_ack_interrupt); + ret = q6v5_request_irq(qproc, pdev, "stop-ack", q6v5_stop_ack_interrupt, + NULL); if (ret < 0) goto free_rproc; + q6v5_disable_irqs(qproc); qproc->state = qcom_smem_state_get(&pdev->dev, "stop", &qproc->stop_bit); if (IS_ERR(qproc->state)) { ret = PTR_ERR(qproc->state);