Skip to content

Commit 29c2c6a

Browse files
andy-shevwesteri
authored andcommitted
pinctrl: intel: Avoid potential glitches if pin is in GPIO mode
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: 7981c00 ("pinctrl: intel: Add Intel Sunrisepoint pin controller and GPIO support") Depends-on: f5a26ac ("pinctrl: intel: Initialize GPIO properly when used through irqchip") Cc: [email protected] Cc: [email protected] Reported-by: Oliver Barta <[email protected]> Reported-by: Malin Jonsson <[email protected]> Signed-off-by: Andy Shevchenko <[email protected]> Signed-off-by: Mika Westerberg <[email protected]>
1 parent 260996c commit 29c2c6a

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

drivers/pinctrl/intel/pinctrl-intel.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#define PADCFG0_GPIROUTNMI BIT(17)
5353
#define PADCFG0_PMODE_SHIFT 10
5454
#define PADCFG0_PMODE_MASK GENMASK(13, 10)
55+
#define PADCFG0_PMODE_GPIO 0
5556
#define PADCFG0_GPIORXDIS BIT(9)
5657
#define PADCFG0_GPIOTXDIS BIT(8)
5758
#define PADCFG0_GPIORXSTATE BIT(1)
@@ -332,7 +333,7 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
332333
cfg1 = readl(intel_get_padcfg(pctrl, pin, PADCFG1));
333334

334335
mode = (cfg0 & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
335-
if (!mode)
336+
if (mode == PADCFG0_PMODE_GPIO)
336337
seq_puts(s, "GPIO ");
337338
else
338339
seq_printf(s, "mode %d ", mode);
@@ -458,6 +459,11 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input)
458459
writel(value, padcfg0);
459460
}
460461

462+
static int intel_gpio_get_gpio_mode(void __iomem *padcfg0)
463+
{
464+
return (readl(padcfg0) & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
465+
}
466+
461467
static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
462468
{
463469
u32 value;
@@ -491,7 +497,20 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
491497
}
492498

493499
padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
500+
501+
/*
502+
* If pin is already configured in GPIO mode, we assume that
503+
* firmware provides correct settings. In such case we avoid
504+
* potential glitches on the pin. Otherwise, for the pin in
505+
* alternative mode, consumer has to supply respective flags.
506+
*/
507+
if (intel_gpio_get_gpio_mode(padcfg0) == PADCFG0_PMODE_GPIO) {
508+
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
509+
return 0;
510+
}
511+
494512
intel_gpio_set_gpio_mode(padcfg0);
513+
495514
/* Disable TX buffer and enable RX (this will be input) */
496515
__intel_gpio_set_direction(padcfg0, true);
497516

0 commit comments

Comments
 (0)