[v1] pinctrl: intel: Avoid potential glitches if pin is in GPIO mode
diff mbox series

Message ID 20191014095104.77689-1-andriy.shevchenko@linux.intel.com
State New
Headers show
Series
  • [v1] pinctrl: intel: Avoid potential glitches if pin is in GPIO mode
Related show

Commit Message

andriy.shevchenko@linux.intel.com Oct. 14, 2019, 9:51 a.m. UTC
When consumer requests a pin, in order to be on the safest side,
we switch it first to GPIO mode followed by immediate transition
to the input state. Due to posted writes it's luckily to be a single
I/O transaction.

However, if firmware or boot loader already configures the pin
to the GPIO mode, user expects no glitches for the requested pin.
We may check if the pin is pre-configured and leave it as is
till the actual consumer toggles its state to avoid glitches.

Fixes: 7981c0015af2 ("pinctrl: intel: Add Intel Sunrisepoint pin controller and GPIO support")
Depends-on: f5a26acf0162 ("pinctrl: intel: Initialize GPIO properly when used through irqchip")
Cc: fei.yang@intel.com
Reported-by: Oliver Barta <oliver.barta@aptiv.com>
Reported-by: Malin Jonsson <malin.jonsson@ericsson.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-intel.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

Comments

Linus Walleij Oct. 16, 2019, 12:58 p.m. UTC | #1
On Mon, Oct 14, 2019 at 11:51 AM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:

> When consumer requests a pin, in order to be on the safest side,
> we switch it first to GPIO mode followed by immediate transition
> to the input state. Due to posted writes it's luckily to be a single
> I/O transaction.
>
> However, if firmware or boot loader already configures the pin
> to the GPIO mode, user expects no glitches for the requested pin.
> We may check if the pin is pre-configured and leave it as is
> till the actual consumer toggles its state to avoid glitches.
>
> Fixes: 7981c0015af2 ("pinctrl: intel: Add Intel Sunrisepoint pin controller and GPIO support")
> Depends-on: f5a26acf0162 ("pinctrl: intel: Initialize GPIO properly when used through irqchip")
> Cc: fei.yang@intel.com
> Reported-by: Oliver Barta <oliver.barta@aptiv.com>
> Reported-by: Malin Jonsson <malin.jonsson@ericsson.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

You surely know this best, should it also be tagged for stable?

Yours,
Linus Walleij
Mika Westerberg Oct. 21, 2019, 12:44 p.m. UTC | #2
On Mon, Oct 14, 2019 at 12:51:04PM +0300, Andy Shevchenko wrote:
> When consumer requests a pin, in order to be on the safest side,
> we switch it first to GPIO mode followed by immediate transition
> to the input state. Due to posted writes it's luckily to be a single
> I/O transaction.
> 
> However, if firmware or boot loader already configures the pin
> to the GPIO mode, user expects no glitches for the requested pin.
> We may check if the pin is pre-configured and leave it as is
> till the actual consumer toggles its state to avoid glitches.
> 
> Fixes: 7981c0015af2 ("pinctrl: intel: Add Intel Sunrisepoint pin controller and GPIO support")
> Depends-on: f5a26acf0162 ("pinctrl: intel: Initialize GPIO properly when used through irqchip")
> Cc: fei.yang@intel.com
> Reported-by: Oliver Barta <oliver.barta@aptiv.com>
> Reported-by: Malin Jonsson <malin.jonsson@ericsson.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Tagged for stable and applied to intel.git/fixes, thanks!

Patch
diff mbox series

diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
index b9df243e19cf..df8ca7cdefcb 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -52,6 +52,7 @@ 
 #define PADCFG0_GPIROUTNMI		BIT(17)
 #define PADCFG0_PMODE_SHIFT		10
 #define PADCFG0_PMODE_MASK		GENMASK(13, 10)
+#define PADCFG0_PMODE_GPIO		0
 #define PADCFG0_GPIORXDIS		BIT(9)
 #define PADCFG0_GPIOTXDIS		BIT(8)
 #define PADCFG0_GPIORXSTATE		BIT(1)
@@ -332,7 +333,7 @@  static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
 	cfg1 = readl(intel_get_padcfg(pctrl, pin, PADCFG1));
 
 	mode = (cfg0 & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
-	if (!mode)
+	if (mode == PADCFG0_PMODE_GPIO)
 		seq_puts(s, "GPIO ");
 	else
 		seq_printf(s, "mode %d ", mode);
@@ -458,6 +459,11 @@  static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input)
 	writel(value, padcfg0);
 }
 
+static int intel_gpio_get_gpio_mode(void __iomem *padcfg0)
+{
+	return (readl(padcfg0) & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
+}
+
 static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
 {
 	u32 value;
@@ -491,7 +497,20 @@  static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
 	}
 
 	padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
+
+	/*
+	 * If pin is already configured in GPIO mode, we assume that
+	 * firmware provides correct settings. In such case we avoid
+	 * potential glitches on the pin. Otherwise, for the pin in
+	 * alternative mode, consumer has to supply respective flags.
+	 */
+	if (intel_gpio_get_gpio_mode(padcfg0) == PADCFG0_PMODE_GPIO) {
+		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+		return 0;
+	}
+
 	intel_gpio_set_gpio_mode(padcfg0);
+
 	/* Disable TX buffer and enable RX (this will be input) */
 	__intel_gpio_set_direction(padcfg0, true);