Message ID | 20221107052201.65477-3-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 l7csp1849269wru; Sun, 6 Nov 2022 21:33:16 -0800 (PST) X-Google-Smtp-Source: AMsMyM4QqujXJpPIjuBRJoR2P3VLpjB/UcCz0kh5JUwwlzL1Iq06WpqFQ1xPdDBbqgWDyCyCov5p X-Received: by 2002:a17:90b:8c5:b0:213:de45:d126 with SMTP id ds5-20020a17090b08c500b00213de45d126mr41806657pjb.34.1667799196588; Sun, 06 Nov 2022 21:33:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1667799196; cv=none; d=google.com; s=arc-20160816; b=B45mmjgu61a0ttDpfud/feP0gZtNL1A+amDs/35Azqv9He0EEyooJ5InCR5j8fPIrs qfiiINsV7hjJbyBKnr0nbQzp9ylIBHQEVgNHokpVALGMoju6Cb2zFLit34a1Xg4f2qK0 FVrfEB5a/C6u0orBhCQ9APGAoJqEBbIboJLTdnw0YsR5C5DUny5nA4SHWTMmJDXtPWaP LKpj1Ms8P9bBfPxSxYBYm9RelF5TJHDbbyXJ1EHlzhulsMd00qz2B9sW7ejymi2qdgRD L6VV1VDAsyGX4Qlyhz6Lz6F7owVERTk3e4O/iHLsO1eroipafI67wRWB0QuLJTpx+u8w 8dZw== 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=gyBTq0Ma+GLkWBSiLTWQDQZqxoZ0z5X/rfo9ICAimTw=; b=Awrevg33GORSJAU4Ycbvky0YDXixhbcnZaAIK0OcSs9DoKN5r7JZZ+VOW/tG/6Vgfy 1KgKMuu+1TcssAs1TqwH88u+sDjuN07riBn2zOuOF8C0MvH4FC1pDXue5CyiecAlHszu 5i60MyFbaGnrDmrR5MGZkJ+pUBFNZa+j1XG4fv3+3GjdWIpINa05w6jcqEHL+tkAZrVu yktbgtnuM0jad6oLNNJ4fQhM+8he8omHVcA/pd/NZKvvVQHRUN8BH17SK9h6B0T//T6F xVR281xRRx5pej2qAnqGBVm0sYV6VdsDFXU4kIUoXqqEOij3TDN8jZ9DL8sadSpVrXid oZNg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sholland.org header.s=fm1 header.b=XyxbUEkp; dkim=pass header.i=@messagingengine.com header.s=fm3 header.b=D5VXd4bh; 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 p8-20020a63f448000000b0046fec9f9ed8si9433211pgk.704.2022.11.06.21.33.03; Sun, 06 Nov 2022 21:33:16 -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=fm1 header.b=XyxbUEkp; dkim=pass header.i=@messagingengine.com header.s=fm3 header.b=D5VXd4bh; 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 S230160AbiKGFWP (ORCPT <rfc822;hjfbswb@gmail.com> + 99 others); Mon, 7 Nov 2022 00:22:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49690 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229705AbiKGFWJ (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 7 Nov 2022 00:22:09 -0500 Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D06BBB4AD for <linux-kernel@vger.kernel.org>; Sun, 6 Nov 2022 21:22:05 -0800 (PST) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id 2BDB75C00F1; Mon, 7 Nov 2022 00:22:05 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 07 Nov 2022 00:22:05 -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=fm1; t=1667798525; x=1667884925; bh=gy BTq0Ma+GLkWBSiLTWQDQZqxoZ0z5X/rfo9ICAimTw=; b=XyxbUEkpXnskgkAOAR behrCDtU7Ew7aMxM2Kp2Mglueji47RiwJrlzAGNi5w9qeIRRl7qMpYrF7n2SiZmx 9FF1/37mgac7NXvl3ytu409Z9+m0xTi4tAZ9M0bjNZMZRvMxaMscffBLP+7K0nu/ quw0b/Q33zHzOG2h7PYg+OidbtF8Igy1gWpXuXTdxWkREgXOClxNK0MZHix4kk5i Vz45S1KZjeWXdVpQnx9Y8ACymyT6FFldCkIZunlR21zahuQDhpRKM0YODD6tUBjy 5oUE1i24Jrn5/F+TGhr5EfXB0KzwREA1hrLFcbjjq0yjUnPOekHVgUIPeTbBPFSx De2w== 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=fm3; t=1667798525; x=1667884925; bh=gyBTq0Ma+GLkW BSiLTWQDQZqxoZ0z5X/rfo9ICAimTw=; b=D5VXd4bh7p2i046046Vm1vikWqeDc ZG/RyLXHdQLAz0Zex1DPoIkbuHmh+MMznDKd1fg4pI950jEzH6U6I6z60xnvaR+V lWxhL0HTwZcyHBY26iS6fgU4kj3OxwzOrajcJZaB9U0rxKyf6IL87xIb1dj5bQrX iyRtV9D4BFNWlStOuRsLYMVuGyZ3+Du60aEXjublB5P37TeJ08IvzgoDqoW6kX2M US/js3eal7uZPyKdS+pgOYd7rRHp7r2iWOog01e1dikFp6g2lb99lbDEjvCsae0F p/2eidHX3YrDsZXJAVBZ3JoFiMVwlplu3nOieSmc5UgvJcbL4dDQF5JKQ== X-ME-Sender: <xms:_ZVoY5gsYOTusT8NuH8VQioRrvPAkYa5sApnhDNSF0ya66cM-kVngA> <xme:_ZVoY-CoGdnkWH8a8ObqemK60FwoVYHqLihym4hqwBhTR6UTi_cwJiejG32rAcN94 N1Qtlg5iQ-sjixJ7w> X-ME-Received: <xmr:_ZVoY5F_hmOLeQtIPkXQ_xM0xG9DgF-aUTqFuHAd9c5EG3Sxzs8aDtoyEzBpS74XleJGQSrQJ73qQXBpx2PoN7e9WDekKxubvBwVKGNgUxeZWTZl0o0O3GfCFVtspreuOU-Osw> X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvgedrvdejgdekvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefurghmuhgv lhcujfholhhlrghnugcuoehsrghmuhgvlhesshhhohhllhgrnhgurdhorhhgqeenucggtf frrghtthgvrhhnpedukeetueduhedtleetvefguddvvdejhfefudelgfduveeggeehgfdu feeitdevteenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhroh hmpehsrghmuhgvlhesshhhohhllhgrnhgurdhorhhg X-ME-Proxy: <xmx:_ZVoY-QCcNMH9-u6gJibDQDPl519dktO4AjCK1KHlBf1t9LzU6LhPw> <xmx:_ZVoY2zXvUfRjBGT0qI07B7wkkLQlt5b4rBtO5MJ6cO0iXX1DMs3EQ> <xmx:_ZVoY05d1tvwBR7CdIJsQgoAc34WC4llzkjPq1ZUdyNlXp4x-UyeLw> <xmx:_ZVoY9o-QfZWcx5bkE9KtlE4m5a7R6hNMkIm89ItQCQFNbvMh91N_A> Feedback-ID: i0ad843c9:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 7 Nov 2022 00:22:04 -0500 (EST) From: Samuel Holland <samuel@sholland.org> To: Chen-Yu Tsai <wens@csie.org>, Jernej Skrabec <jernej.skrabec@gmail.com> Cc: linux-arm-kernel@lists.infradead.org, Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>, linux-kernel@vger.kernel.org, linux-sunxi@lists.linux.dev, Samuel Holland <samuel@sholland.org> Subject: [PATCH v2 2/2] bus: sunxi-rsb: Support atomic transfers Date: Sun, 6 Nov 2022 23:22:00 -0600 Message-Id: <20221107052201.65477-3-samuel@sholland.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221107052201.65477-1-samuel@sholland.org> References: <20221107052201.65477-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,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?1748814210311979874?= X-GMAIL-MSGID: =?utf-8?q?1748814210311979874?= |
Series |
bus: sunxi-rsb: Fix poweroff issues
|
|
Commit Message
Samuel Holland
Nov. 7, 2022, 5:22 a.m. UTC
When communicating with a PMIC during system poweroff (pm_power_off()),
IRQs are disabled and we are in a RCU read-side critical section, so we
cannot use wait_for_completion_io_timeout(). Instead, poll the status
register for transfer completion.
Fixes: d787dcdb9c8f ("bus: sunxi-rsb: Add driver for Allwinner Reduced Serial Bus")
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
Changes in v2:
- Add Fixes tag to patch 2
- Only check for specific status bits when polling
drivers/bus/sunxi-rsb.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
Comments
On Sun, 6 Nov 2022 23:22:00 -0600 Samuel Holland <samuel@sholland.org> wrote: Hi, > When communicating with a PMIC during system poweroff (pm_power_off()), > IRQs are disabled and we are in a RCU read-side critical section, so we > cannot use wait_for_completion_io_timeout(). Instead, poll the status > register for transfer completion. > > Fixes: d787dcdb9c8f ("bus: sunxi-rsb: Add driver for Allwinner Reduced Serial Bus") > Signed-off-by: Samuel Holland <samuel@sholland.org> > --- > > Changes in v2: > - Add Fixes tag to patch 2 > - Only check for specific status bits when polling > > drivers/bus/sunxi-rsb.c | 27 ++++++++++++++++++++------- > 1 file changed, 20 insertions(+), 7 deletions(-) > > diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c > index 17343cd75338..012e82f9b7b0 100644 > --- a/drivers/bus/sunxi-rsb.c > +++ b/drivers/bus/sunxi-rsb.c > @@ -267,6 +267,9 @@ EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register); > /* common code that starts a transfer */ > static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) > { > + u32 int_mask, status; > + bool timeout; > + > if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) { > dev_dbg(rsb->dev, "RSB transfer still in progress\n"); > return -EBUSY; > @@ -274,13 +277,23 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) > > reinit_completion(&rsb->complete); > > - writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER, > + int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER; > + writel(int_mask, > rsb->regs + RSB_INTE); > writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, > rsb->regs + RSB_CTRL); > > - if (!wait_for_completion_io_timeout(&rsb->complete, > - msecs_to_jiffies(100))) { > + if (irqs_disabled()) { > + timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, > + status, (status & int_mask), > + 10, 100000); So if I understand correctly, this mimics the operation of sunxi_rsb_irq(), just replacing rsb->status with status. But wouldn't that also mean that we need to clear the interrupt bits in INTS, since we are about to handle them below? It probably doesn't matter in practise, since we call this during power down only, but looks like more robust to do, from a driver's perspective. Cheers, Andre > + } else { > + timeout = !wait_for_completion_io_timeout(&rsb->complete, > + msecs_to_jiffies(100)); > + status = rsb->status; > + } > + > + if (timeout) { > dev_dbg(rsb->dev, "RSB timeout\n"); > > /* abort the transfer */ > @@ -292,18 +305,18 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) > return -ETIMEDOUT; > } > > - if (rsb->status & RSB_INTS_LOAD_BSY) { > + if (status & RSB_INTS_LOAD_BSY) { > dev_dbg(rsb->dev, "RSB busy\n"); > return -EBUSY; > } > > - if (rsb->status & RSB_INTS_TRANS_ERR) { > - if (rsb->status & RSB_INTS_TRANS_ERR_ACK) { > + if (status & RSB_INTS_TRANS_ERR) { > + if (status & RSB_INTS_TRANS_ERR_ACK) { > dev_dbg(rsb->dev, "RSB slave nack\n"); > return -EINVAL; > } > > - if (rsb->status & RSB_INTS_TRANS_ERR_DATA) { > + if (status & RSB_INTS_TRANS_ERR_DATA) { > dev_dbg(rsb->dev, "RSB transfer data error\n"); > return -EIO; > }
Dne ponedeljek, 07. november 2022 ob 12:30:29 CET je Andre Przywara napisal(a): > On Sun, 6 Nov 2022 23:22:00 -0600 > Samuel Holland <samuel@sholland.org> wrote: > > Hi, > > > When communicating with a PMIC during system poweroff (pm_power_off()), > > IRQs are disabled and we are in a RCU read-side critical section, so we > > cannot use wait_for_completion_io_timeout(). Instead, poll the status > > register for transfer completion. > > > > Fixes: d787dcdb9c8f ("bus: sunxi-rsb: Add driver for Allwinner Reduced > > Serial Bus") Signed-off-by: Samuel Holland <samuel@sholland.org> > > --- > > > > Changes in v2: > > - Add Fixes tag to patch 2 > > - Only check for specific status bits when polling > > > > drivers/bus/sunxi-rsb.c | 27 ++++++++++++++++++++------- > > 1 file changed, 20 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c > > index 17343cd75338..012e82f9b7b0 100644 > > --- a/drivers/bus/sunxi-rsb.c > > +++ b/drivers/bus/sunxi-rsb.c > > @@ -267,6 +267,9 @@ EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register); > > > > /* common code that starts a transfer */ > > static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) > > { > > > > + u32 int_mask, status; > > + bool timeout; > > + > > > > if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) { > > > > dev_dbg(rsb->dev, "RSB transfer still in progress\n"); > > return -EBUSY; > > > > @@ -274,13 +277,23 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb > > *rsb) > > > > reinit_completion(&rsb->complete); > > > > - writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER, > > + int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER; > > + writel(int_mask, > > > > rsb->regs + RSB_INTE); > > > > writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, > > > > rsb->regs + RSB_CTRL); > > > > - if (!wait_for_completion_io_timeout(&rsb->complete, > > - msecs_to_jiffies(100))) { > > + if (irqs_disabled()) { > > + timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, > > + status, (status & int_mask), > > + 10, 100000); > > So if I understand correctly, this mimics the operation of > sunxi_rsb_irq(), just replacing rsb->status with status. > But wouldn't that also mean that we need to clear the interrupt bits in > INTS, since we are about to handle them below? Yes, I pointed out that in review of v1. Best regards, Jernej > > It probably doesn't matter in practise, since we call this during power > down only, but looks like more robust to do, from a driver's perspective. > > Cheers, > Andre > > > + } else { > > + timeout = !wait_for_completion_io_timeout(&rsb- >complete, > > + msecs_to_jiffies(100)); > > + status = rsb->status; > > + } > > + > > + if (timeout) { > > > > dev_dbg(rsb->dev, "RSB timeout\n"); > > > > /* abort the transfer */ > > > > @@ -292,18 +305,18 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb > > *rsb) > > > > return -ETIMEDOUT; > > > > } > > > > - if (rsb->status & RSB_INTS_LOAD_BSY) { > > + if (status & RSB_INTS_LOAD_BSY) { > > > > dev_dbg(rsb->dev, "RSB busy\n"); > > return -EBUSY; > > > > } > > > > - if (rsb->status & RSB_INTS_TRANS_ERR) { > > - if (rsb->status & RSB_INTS_TRANS_ERR_ACK) { > > + if (status & RSB_INTS_TRANS_ERR) { > > + if (status & RSB_INTS_TRANS_ERR_ACK) { > > > > dev_dbg(rsb->dev, "RSB slave nack\n"); > > return -EINVAL; > > > > } > > > > - if (rsb->status & RSB_INTS_TRANS_ERR_DATA) { > > + if (status & RSB_INTS_TRANS_ERR_DATA) { > > > > dev_dbg(rsb->dev, "RSB transfer data error\n"); > > return -EIO; > > > > }
diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 17343cd75338..012e82f9b7b0 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -267,6 +267,9 @@ EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register); /* common code that starts a transfer */ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) { + u32 int_mask, status; + bool timeout; + if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) { dev_dbg(rsb->dev, "RSB transfer still in progress\n"); return -EBUSY; @@ -274,13 +277,23 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) reinit_completion(&rsb->complete); - writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER, + int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER; + writel(int_mask, rsb->regs + RSB_INTE); writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, rsb->regs + RSB_CTRL); - if (!wait_for_completion_io_timeout(&rsb->complete, - msecs_to_jiffies(100))) { + if (irqs_disabled()) { + timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, + status, (status & int_mask), + 10, 100000); + } else { + timeout = !wait_for_completion_io_timeout(&rsb->complete, + msecs_to_jiffies(100)); + status = rsb->status; + } + + if (timeout) { dev_dbg(rsb->dev, "RSB timeout\n"); /* abort the transfer */ @@ -292,18 +305,18 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) return -ETIMEDOUT; } - if (rsb->status & RSB_INTS_LOAD_BSY) { + if (status & RSB_INTS_LOAD_BSY) { dev_dbg(rsb->dev, "RSB busy\n"); return -EBUSY; } - if (rsb->status & RSB_INTS_TRANS_ERR) { - if (rsb->status & RSB_INTS_TRANS_ERR_ACK) { + if (status & RSB_INTS_TRANS_ERR) { + if (status & RSB_INTS_TRANS_ERR_ACK) { dev_dbg(rsb->dev, "RSB slave nack\n"); return -EINVAL; } - if (rsb->status & RSB_INTS_TRANS_ERR_DATA) { + if (status & RSB_INTS_TRANS_ERR_DATA) { dev_dbg(rsb->dev, "RSB transfer data error\n"); return -EIO; }