Message ID | 20221114015749.28490-4-samuel@sholland.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp1915994wru; Sun, 13 Nov 2022 18:00:27 -0800 (PST) X-Google-Smtp-Source: AA0mqf4NIKKxPCM2WFLZt+o+Rg/GXKTk/KJVBSS4rkt9bYSdfNY5wAAwnasTbxCsyF8sk0AMR8HA X-Received: by 2002:a17:906:b294:b0:7a0:b505:e8fb with SMTP id q20-20020a170906b29400b007a0b505e8fbmr8867853ejz.281.1668391227612; Sun, 13 Nov 2022 18:00:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668391227; cv=none; d=google.com; s=arc-20160816; b=nMessAVst8Rfv7IYco+ie75rqfZFt+dPEafXgZkAML9/ny3EjY/m2zJtPs0xtudv1c NTIkmfNCt8ZpU5Ff13xIG8eg60NgMTUZhFanR9F6qLCEAoNVbODr3y4GTXdlDfZ5m9PQ fjDtPpPeYmu2mXmySVYuOrgTHY2HKYxd3pY3qbxwjgV+aJ3ASwexs5qkNJApPZpZAosS xD81T7RZiwkt4P5KfXG8LbJHqy5fWk68+LTQBDzqgLpsxoAq+bo5hfO30RdLaNXESX5D RbdURSPMlUOzwaoSO72CcAq7QI0uRm7pkYgxsj5gal+lihIMRdwsOlC7AGsX6VFSl/JI OAJA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :feedback-id:dkim-signature:dkim-signature; bh=zX+HYuy4GvidniLAd+lpqew4/s4ii686Qj3H9Jd2qG0=; b=qfWDq3t2oiYGadoD+nweOEif0xOIemhjHY4qL0OjNAS7xabAHryZWvGgyq1SacLMxv oytPIE40jkru2FvREV19Gfit1ZkYT6isPxSUmnvBnngGippxTWs1T09lxmHgULSCOmBk sMk8n1BZKfuFwWqgypLERPxdhNgJArRtjNBQsUZLCV+qh76ee715VBJAWsOMUsH28qzh bfZhVpasGwQ25M46PcQC8QPNcn5BSMrStrGWkt8yI9a/iaod+9A1MvrwJ+oa6RO6PRe8 EXonB9OhAFJrrJbFtrFzYJZnNLT+UKaWssyWayrQszJXSAxrwx8wQ6tXeV0AFdEGYBbh RZMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sholland.org header.s=fm2 header.b=rXsRbMYF; dkim=pass header.i=@messagingengine.com header.s=fm1 header.b=MH1Dg8+T; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sholland.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id xj10-20020a170906db0a00b00791910ecd0fsi8100860ejb.540.2022.11.13.18.00.03; Sun, 13 Nov 2022 18:00:27 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@sholland.org header.s=fm2 header.b=rXsRbMYF; dkim=pass header.i=@messagingengine.com header.s=fm1 header.b=MH1Dg8+T; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sholland.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235484AbiKNB6Q (ORCPT <rfc822;winker.wchi@gmail.com> + 99 others); Sun, 13 Nov 2022 20:58:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235589AbiKNB57 (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sun, 13 Nov 2022 20:57:59 -0500 Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AA0ECB86F for <linux-kernel@vger.kernel.org>; Sun, 13 Nov 2022 17:57:58 -0800 (PST) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id ACDC8320091A; Sun, 13 Nov 2022 20:57:57 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Sun, 13 Nov 2022 20:57:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sholland.org; h= cc:cc:content-transfer-encoding:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm2; t=1668391077; x=1668477477; bh=zX +HYuy4GvidniLAd+lpqew4/s4ii686Qj3H9Jd2qG0=; b=rXsRbMYFTaUdR2U+Mk VNvxUrkjZXlEk44QuPfO3v95apqzkYDbTcuAIKi3cFSmP1R5I36syDaXMzUiRXV5 ZUG23SwDwoYqTOgIQt7vg0VHxW/GFVMDFVeoQSX5WU3iAAln+nsR8Q5Bni10xOaX B9M+OAK5vMjbNdi7pRHiBVwVvw7y1j0WyajuPvNXe7Zz4PPjTQEaLOnmvpLChWLW 5Qk/M3W2QI0t99TuVFL04WYT5ysYIs4q5r/B1QuF3lVUzgOjhm3yJoFDmy1aepYi jVupkZ6508nbFlesKkfDqFbbhzMzUE3O6HnCuo3dGPf7m1foGPbVFgxwxm4j0ana TIqw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; t=1668391077; x=1668477477; bh=zX+HYuy4Gvidn iLAd+lpqew4/s4ii686Qj3H9Jd2qG0=; b=MH1Dg8+TQL2ERs5dtT00JLdXcQfB6 c2fJd7iyyNYKiV/keuHUtO6s2q1mAAs6HS9VQfpUKkBh/fzKgWvN3c3XMfGqpLoX IQqwXXVRlCKH08XEQswZG0lmo8pkgPjSYIa6qxzlanDSmxgWxSE1bVCDRvj0Ya/j NCtIEjGEjLozLrclr0QJIcrAPF9XoQjw+Z3YTnPiOmjimezhLNMWUalzf7c1jF/o G6jTQOKLHpk2TEMvbpSxskt+xPzUJbh5Ri0sfmfdMOmUSGyTQlbqSloJo1lL7MQ/ l6OFLXUZTm1jtwlWJwRzZFyvTgu19aeGBsM+ciohTPYAFEQrIpP6ClF1w== X-ME-Sender: <xms:paBxYwzFzBpsmYA5G3d8_mdiQ5Rp9N1A74OMDdOLtxX2cusov1IEVg> <xme:paBxY0TKPrle0i3DLAcjyf1VGiLiHt35tyo2Um1x6kqNg_9GMxe9xBVnf_JurIhif 7kPPvORqZA3yDjkTw> X-ME-Received: <xmr:paBxYyWPha9XnSmkJHXJgmw8GvDXF4tA3lpT_I5y-SEppvRyT7eYInOX2cZMbcUc9DLpECB1gvTLoqm_9vwwTtkU62ndZoffwBNkZNItBoWvlc9vfIwACuyL1_zDBb99ynqm1Q> X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvgedrgedugdegtdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefurghmuhgv lhcujfholhhlrghnugcuoehsrghmuhgvlhesshhhohhllhgrnhgurdhorhhgqeenucggtf frrghtthgvrhhnpedukeetueduhedtleetvefguddvvdejhfefudelgfduveeggeehgfdu feeitdevteenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhroh hmpehsrghmuhgvlhesshhhohhllhgrnhgurdhorhhg X-ME-Proxy: <xmx:paBxY-iceAsZOzFz5ixstXpEwbG4H_4jWxADGwbtl8vDPr-SVoN3Uw> <xmx:paBxYyADd1F0DtuiYWLGr2rwjJGyNPRYnuh22E9bD4PjxR-wULLfcg> <xmx:paBxY_Kw4b4jj1WmI9RqoFrFSJo-ShX6XSAnMUIC-H5VWiDohh1dNQ> <xmx:paBxY02FZdzNDgWMItFs0hdh2CaUWFJYHKbI7YmymrC5UaWFapnLFA> Feedback-ID: i0ad843c9:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sun, 13 Nov 2022 20:57:56 -0500 (EST) From: Samuel Holland <samuel@sholland.org> To: Chen-Yu Tsai <wens@csie.org>, Jernej Skrabec <jernej.skrabec@gmail.com> Cc: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-sunxi@lists.linux.dev, Andre Przywara <andre.przywara@arm.com>, Samuel Holland <samuel@sholland.org> Subject: [PATCH v3 3/3] bus: sunxi-rsb: Clear interrupt status before each transfer Date: Sun, 13 Nov 2022 19:57:49 -0600 Message-Id: <20221114015749.28490-4-samuel@sholland.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221114015749.28490-1-samuel@sholland.org> References: <20221114015749.28490-1-samuel@sholland.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749435000140145209?= X-GMAIL-MSGID: =?utf-8?q?1749435000140145209?= |
Series |
bus: sunxi-rsb: Fix poweroff issues
|
|
Commit Message
Samuel Holland
Nov. 14, 2022, 1:57 a.m. UTC
Currently, the driver clears the interrupt status bits after anything
could have set them. However, this requires duplicating the same logic
in several places.
Instead of clearing the status flags in the interrupt handler, disable
all further interrupts by clearing the RSB_CTRL_GLOBAL_INT_ENB bit.
Then we can delay the status register write until the start of the next
transfer, so it only has to be done in one place.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
Changes in v3:
- Add a patch refactoring how the status bits are cleared
drivers/bus/sunxi-rsb.c | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)
Comments
Hi Samuel, Dne ponedeljek, 14. november 2022 ob 02:57:49 CET je Samuel Holland napisal(a): > Currently, the driver clears the interrupt status bits after anything > could have set them. However, this requires duplicating the same logic > in several places. > > Instead of clearing the status flags in the interrupt handler, disable > all further interrupts by clearing the RSB_CTRL_GLOBAL_INT_ENB bit. where is this bit cleared? > Then we can delay the status register write until the start of the next > transfer, so it only has to be done in one place. > > Signed-off-by: Samuel Holland <samuel@sholland.org> > --- > > Changes in v3: > - Add a patch refactoring how the status bits are cleared > > drivers/bus/sunxi-rsb.c | 20 +++++--------------- > 1 file changed, 5 insertions(+), 15 deletions(-) > > diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c > index 3aa91aed3bf7..cb622e60897b 100644 > --- a/drivers/bus/sunxi-rsb.c > +++ b/drivers/bus/sunxi-rsb.c > @@ -279,6 +279,7 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) > > int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER; > writel(int_mask, rsb->regs + RSB_INTE); > + writel(int_mask, rsb->regs + RSB_INTS); Wouldn't be better to clear status before enabling interrupts? Unless global interrupt flag is cleared beforehand, but I don't see that anywhere. Best regards, Jernej > writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, > rsb->regs + RSB_CTRL); > > @@ -286,7 +287,6 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) > timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, > status, (status & int_mask), > 10, 100000); > - writel(status, rsb->regs + RSB_INTS); > } else { > timeout = !wait_for_completion_io_timeout(&rsb- >complete, > msecs_to_jiffies(100)); > @@ -296,12 +296,9 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) > if (timeout) { > dev_dbg(rsb->dev, "RSB timeout\n"); > > - /* abort the transfer */ > + /* abort the transfer and disable interrupts */ > writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL); > > - /* clear any interrupt flags */ > - writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS); > - > return -ETIMEDOUT; > } > > @@ -503,15 +500,11 @@ EXPORT_SYMBOL_GPL(__devm_regmap_init_sunxi_rsb); > static irqreturn_t sunxi_rsb_irq(int irq, void *dev_id) > { > struct sunxi_rsb *rsb = dev_id; > - u32 status; > > - status = readl(rsb->regs + RSB_INTS); > - rsb->status = status; > + /* disable interrupts */ > + writel(0, rsb->regs + RSB_CTRL); > > - /* Clear interrupts */ > - status &= (RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | > - RSB_INTS_TRANS_OVER); > - writel(status, rsb->regs + RSB_INTS); > + rsb->status = readl(rsb->regs + RSB_INTS); > > complete(&rsb->complete); > > @@ -532,9 +525,6 @@ static int sunxi_rsb_init_device_mode(struct sunxi_rsb > *rsb) if (reg & RSB_DMCR_DEVICE_START) > ret = -ETIMEDOUT; > > - /* clear interrupt status bits */ > - writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS); > - > return ret; > }
On 11/14/22 15:00, Jernej Škrabec wrote: > Hi Samuel, > > Dne ponedeljek, 14. november 2022 ob 02:57:49 CET je Samuel Holland > napisal(a): >> Currently, the driver clears the interrupt status bits after anything >> could have set them. However, this requires duplicating the same logic >> in several places. >> >> Instead of clearing the status flags in the interrupt handler, disable >> all further interrupts by clearing the RSB_CTRL_GLOBAL_INT_ENB bit. > > where is this bit cleared? It is cleared by any write to RSB_CTRL that does not include it. I noted it below with the "disable interrupts" comments. >> Then we can delay the status register write until the start of the next >> transfer, so it only has to be done in one place. >> >> Signed-off-by: Samuel Holland <samuel@sholland.org> >> --- >> >> Changes in v3: >> - Add a patch refactoring how the status bits are cleared >> >> drivers/bus/sunxi-rsb.c | 20 +++++--------------- >> 1 file changed, 5 insertions(+), 15 deletions(-) >> >> diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c >> index 3aa91aed3bf7..cb622e60897b 100644 >> --- a/drivers/bus/sunxi-rsb.c >> +++ b/drivers/bus/sunxi-rsb.c >> @@ -279,6 +279,7 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) >> >> int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER; >> writel(int_mask, rsb->regs + RSB_INTE); >> + writel(int_mask, rsb->regs + RSB_INTS); > > Wouldn't be better to clear status before enabling interrupts? Unless global > interrupt flag is cleared beforehand, but I don't see that anywhere. Indeed the intention was that the global interrupt flag is cleared beforehand, and only enabled on the next line below. However, I realize I missed disabling it for the new atomic case. I'm not so sure anymore that this patch is an improvement. What do you think? I can send a v4 with a fix, or I am fine with skipping this patch. I would at least like the other two to be merged for -fixes. Regards, Samuel >> writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, >> rsb->regs + RSB_CTRL); >> >> @@ -286,7 +287,6 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) >> timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, >> status, (status & int_mask), >> 10, 100000); >> - writel(status, rsb->regs + RSB_INTS); >> } else { >> timeout = !wait_for_completion_io_timeout(&rsb- >> complete, >> msecs_to_jiffies(100)); >> @@ -296,12 +296,9 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) >> if (timeout) { >> dev_dbg(rsb->dev, "RSB timeout\n"); >> >> - /* abort the transfer */ >> + /* abort the transfer and disable interrupts */ >> writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL); >> >> - /* clear any interrupt flags */ >> - writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS); >> - >> return -ETIMEDOUT; >> } >> >> @@ -503,15 +500,11 @@ EXPORT_SYMBOL_GPL(__devm_regmap_init_sunxi_rsb); >> static irqreturn_t sunxi_rsb_irq(int irq, void *dev_id) >> { >> struct sunxi_rsb *rsb = dev_id; >> - u32 status; >> >> - status = readl(rsb->regs + RSB_INTS); >> - rsb->status = status; >> + /* disable interrupts */ >> + writel(0, rsb->regs + RSB_CTRL); >> >> - /* Clear interrupts */ >> - status &= (RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | >> - RSB_INTS_TRANS_OVER); >> - writel(status, rsb->regs + RSB_INTS); >> + rsb->status = readl(rsb->regs + RSB_INTS); >> >> complete(&rsb->complete); >> >> @@ -532,9 +525,6 @@ static int sunxi_rsb_init_device_mode(struct sunxi_rsb >> *rsb) if (reg & RSB_DMCR_DEVICE_START) >> ret = -ETIMEDOUT; >> >> - /* clear interrupt status bits */ >> - writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS); >> - >> return ret; >> }
Dne torek, 15. november 2022 ob 07:08:12 CET je Samuel Holland napisal(a): > On 11/14/22 15:00, Jernej Škrabec wrote: > > Hi Samuel, > > > > Dne ponedeljek, 14. november 2022 ob 02:57:49 CET je Samuel Holland > > > > napisal(a): > >> Currently, the driver clears the interrupt status bits after anything > >> could have set them. However, this requires duplicating the same logic > >> in several places. > >> > >> Instead of clearing the status flags in the interrupt handler, disable > >> all further interrupts by clearing the RSB_CTRL_GLOBAL_INT_ENB bit. > > > > where is this bit cleared? > > It is cleared by any write to RSB_CTRL that does not include it. I noted > it below with the "disable interrupts" comments. Right. > > >> Then we can delay the status register write until the start of the next > >> transfer, so it only has to be done in one place. > >> > >> Signed-off-by: Samuel Holland <samuel@sholland.org> > >> --- > >> > >> Changes in v3: > >> - Add a patch refactoring how the status bits are cleared > >> > >> drivers/bus/sunxi-rsb.c | 20 +++++--------------- > >> 1 file changed, 5 insertions(+), 15 deletions(-) > >> > >> diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c > >> index 3aa91aed3bf7..cb622e60897b 100644 > >> --- a/drivers/bus/sunxi-rsb.c > >> +++ b/drivers/bus/sunxi-rsb.c > >> @@ -279,6 +279,7 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) > >> > >> int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | > >> RSB_INTS_TRANS_OVER; > >> writel(int_mask, rsb->regs + RSB_INTE); > >> > >> + writel(int_mask, rsb->regs + RSB_INTS); > > > > Wouldn't be better to clear status before enabling interrupts? Unless > > global interrupt flag is cleared beforehand, but I don't see that > > anywhere. > Indeed the intention was that the global interrupt flag is cleared > beforehand, and only enabled on the next line below. However, I realize > I missed disabling it for the new atomic case. > > I'm not so sure anymore that this patch is an improvement. What do you > think? I can send a v4 with a fix, or I am fine with skipping this > patch. I would at least like the other two to be merged for -fixes. Sure, first two patches will go in regardless. I'm not convinced of value of this patch either. I guess we can skip it. Best regards, Jernej > > Regards, > Samuel > > >> writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, > >> > >> rsb->regs + RSB_CTRL); > >> > >> @@ -286,7 +287,6 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) > >> > >> timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, > >> > >> status, (status & int_mask), > >> 10, 100000); > >> > >> - writel(status, rsb->regs + RSB_INTS); > >> > >> } else { > >> > >> timeout = !wait_for_completion_io_timeout(&rsb- > >> > >> complete, > >> > >> msecs_to_jiffies(100)); > >> > >> @@ -296,12 +296,9 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb > >> *rsb) > >> > >> if (timeout) { > >> > >> dev_dbg(rsb->dev, "RSB timeout\n"); > >> > >> - /* abort the transfer */ > >> + /* abort the transfer and disable interrupts */ > >> > >> writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL); > >> > >> - /* clear any interrupt flags */ > >> - writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS); > >> - > >> > >> return -ETIMEDOUT; > >> > >> } > >> > >> @@ -503,15 +500,11 @@ EXPORT_SYMBOL_GPL(__devm_regmap_init_sunxi_rsb); > >> > >> static irqreturn_t sunxi_rsb_irq(int irq, void *dev_id) > >> { > >> > >> struct sunxi_rsb *rsb = dev_id; > >> > >> - u32 status; > >> > >> - status = readl(rsb->regs + RSB_INTS); > >> - rsb->status = status; > >> + /* disable interrupts */ > >> + writel(0, rsb->regs + RSB_CTRL); > >> > >> - /* Clear interrupts */ > >> - status &= (RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | > >> - RSB_INTS_TRANS_OVER); > >> - writel(status, rsb->regs + RSB_INTS); > >> + rsb->status = readl(rsb->regs + RSB_INTS); > >> > >> complete(&rsb->complete); > >> > >> @@ -532,9 +525,6 @@ static int sunxi_rsb_init_device_mode(struct > >> sunxi_rsb > >> *rsb) if (reg & RSB_DMCR_DEVICE_START) > >> > >> ret = -ETIMEDOUT; > >> > >> - /* clear interrupt status bits */ > >> - writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS); > >> - > >> > >> return ret; > >> > >> }
diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 3aa91aed3bf7..cb622e60897b 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -279,6 +279,7 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER; writel(int_mask, rsb->regs + RSB_INTE); + writel(int_mask, rsb->regs + RSB_INTS); writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, rsb->regs + RSB_CTRL); @@ -286,7 +287,6 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, status, (status & int_mask), 10, 100000); - writel(status, rsb->regs + RSB_INTS); } else { timeout = !wait_for_completion_io_timeout(&rsb->complete, msecs_to_jiffies(100)); @@ -296,12 +296,9 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) if (timeout) { dev_dbg(rsb->dev, "RSB timeout\n"); - /* abort the transfer */ + /* abort the transfer and disable interrupts */ writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL); - /* clear any interrupt flags */ - writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS); - return -ETIMEDOUT; } @@ -503,15 +500,11 @@ EXPORT_SYMBOL_GPL(__devm_regmap_init_sunxi_rsb); static irqreturn_t sunxi_rsb_irq(int irq, void *dev_id) { struct sunxi_rsb *rsb = dev_id; - u32 status; - status = readl(rsb->regs + RSB_INTS); - rsb->status = status; + /* disable interrupts */ + writel(0, rsb->regs + RSB_CTRL); - /* Clear interrupts */ - status &= (RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | - RSB_INTS_TRANS_OVER); - writel(status, rsb->regs + RSB_INTS); + rsb->status = readl(rsb->regs + RSB_INTS); complete(&rsb->complete); @@ -532,9 +525,6 @@ static int sunxi_rsb_init_device_mode(struct sunxi_rsb *rsb) if (reg & RSB_DMCR_DEVICE_START) ret = -ETIMEDOUT; - /* clear interrupt status bits */ - writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS); - return ret; }