lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sat, 09 Sep 2017 22:47:14 +0100
From:   Ben Hutchings <ben@...adent.org.uk>
To:     linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC:     akpm@...ux-foundation.org,
        "Linus Walleij" <linus.walleij@...aro.org>,
        "Uwe Kleine-König" 
        <u.kleine-koenig@...gutronix.de>, "Shawn Guo" <shawnguo@...nel.org>
Subject: [PATCH 3.16 081/233] pinctrl: mxs: atomically switch mux and
 drive strength config

3.16.48-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Uwe Kleine-König <u.kleine-koenig@...gutronix.de>

commit da6c2addf66d7ff7d0b090d6267d4292f951e4e6 upstream.

To set the mux mode of a pin two bits must be set. Up to now this is
implemented using the following idiom:

	writel(mask, reg + CLR);
	writel(value, reg + SET);

. This however results in the mux mode being 0 between the two writes.

On my machine there is an IC's reset pin connected to LCD_D20. The
bootloader configures this pin as GPIO output-high (i.e. not holding the
IC in reset). When Linux reconfigures the pin to GPIO the short time
LCD_D20 is muxed as LCD_D20 instead of GPIO_1_20 is enough to confuse
the connected IC.

The same problem is present for the pin's drive strength setting which is
reset to low drive strength before using the right value.

So instead of relying on the hardware to modify the register setting
using two writes implement the bit toggling using read-modify-write.

Fixes: 17723111e64f ("pinctrl: add pinctrl-mxs support")
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@...gutronix.de>
Acked-by: Shawn Guo <shawnguo@...nel.org>
Signed-off-by: Linus Walleij <linus.walleij@...aro.org>
[bwh: Backported to 3.16: adjust filename, context]
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
 drivers/pinctrl/pinctrl-mxs.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

--- a/drivers/pinctrl/pinctrl-mxs.c
+++ b/drivers/pinctrl/pinctrl-mxs.c
@@ -195,6 +195,16 @@ static int mxs_pinctrl_get_func_groups(s
 	return 0;
 }
 
+static void mxs_pinctrl_rmwl(u32 value, u32 mask, u8 shift, void __iomem *reg)
+{
+	u32 tmp;
+
+	tmp = readl(reg);
+	tmp &= ~(mask << shift);
+	tmp |= value << shift;
+	writel(tmp, reg);
+}
+
 static int mxs_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned selector,
 			      unsigned group)
 {
@@ -212,8 +222,7 @@ static int mxs_pinctrl_enable(struct pin
 		reg += bank * 0x20 + pin / 16 * 0x10;
 		shift = pin % 16 * 2;
 
-		writel(0x3 << shift, reg + CLR);
-		writel(g->muxsel[i] << shift, reg + SET);
+		mxs_pinctrl_rmwl(g->muxsel[i], 0x3, shift, reg);
 	}
 
 	return 0;
@@ -280,8 +289,7 @@ static int mxs_pinconf_group_set(struct
 			/* mA */
 			if (config & MA_PRESENT) {
 				shift = pin % 8 * 4;
-				writel(0x3 << shift, reg + CLR);
-				writel(ma << shift, reg + SET);
+				mxs_pinctrl_rmwl(ma, 0x3, shift, reg);
 			}
 
 			/* vol */

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ