Skip to contentSkip to conversation

PINCTRL: Warn if direct IRQ GPIO set to output

PATCH Superseded [email protected] 3 participants 10 messages Jun 2, 2014 – Jul 9, 2014 1 message not in the archive Pin control

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH v2 1/1 PINCTRL: Warn if direct IRQ GPIO set to output

From: Eric Ernst <[email protected]>

For Baytrail, you should never set a GPIO set to direct_irq to output mode. When direct_irq_en is set for a GPIO, it is tied directly to an APIC internally, and making the pad output does not make any sense. Assert a WARN() in the event this happens.

---
 drivers/pinctrl/pinctrl-baytrail.c |   19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/pinctrl/pinctrl-baytrail.c +15 -4
index e59983423991..fde3767df254 100644
@@ -47,6 +47,7 @@
 #define BYT_TRIG_POS		BIT(25)
 #define BYT_TRIG_LVL		BIT(24)
 #define BYT_PIN_MUX		0x07
+#define BYT_DIRECTIRQ		BIT(27)
 
 /* BYT_VAL_REG register bits */
 #define BYT_INPUT_EN		BIT(2)  /* 0: input enabled (active low)*/
@@ -256,19 +257,29 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
 				     unsigned gpio, int value)
 {
 	struct byt_gpio *vg = to_byt_gpio(chip);
-	void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
+	void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG);
+	void __iomem *value_reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
 	unsigned long flags;
 	u32 reg_val;
 
 	spin_lock_irqsave(&vg->lock, flags);
 
-	reg_val = readl(reg) | BYT_DIR_MASK;
+	/*
+	 * Before making any direction modifications, do a check if gpio
+	 * is set for direct IRQ.  On baytrail, setting GPIO to output does
+	 * not make sense, so let's at least warn the caller before they shoot
+	 * themselves in the foot.
+	 */
+	WARN((readl(conf_reg) & BYT_DIRECTIRQ),
+		"Potential Error: Setting GPIO with direct_irq_en to output");
+
+	reg_val = readl(value_reg) | BYT_DIR_MASK;
 	reg_val &= ~BYT_OUTPUT_EN;
 
 	if (value)
-		writel(reg_val | BYT_LEVEL, reg);
+		writel(reg_val | BYT_LEVEL, value_reg);
 	else
-		writel(reg_val & ~BYT_LEVEL, reg);
+		writel(reg_val & ~BYT_LEVEL, value_reg);
 
 	spin_unlock_irqrestore(&vg->lock, flags);
 
Signature · 1 line
1.7.9.5
#2 lore raw
Quoted 6 lines · On Mon, Jun 02, 2014 at 02:12:07PM -0700, [email protected] wrote:

From: Eric Ernst <[email protected]>

For Baytrail, you should never set a GPIO set to direct_irq to output mode. When direct_irq_en is set for a GPIO, it is tied directly to an APIC internally, and making the pad output does not make any sense. Assert a WARN() in the event this happens.

Subject should probably be:

pinctrl: baytrail: Warn if direct IRQ GPIO is set to output

Quoted 10 lines
---
 drivers/pinctrl/pinctrl-baytrail.c |   19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/pinctrl/pinctrl-baytrail.c +0 -0
index e59983423991..fde3767df254 100644

drivers/pinctrl/pinctrl-baytrail.c line 50

Quoted 4 lines
drivers/pinctrl/pinctrl-baytrail.c +1 -0
@@ -47,6 +47,7 @@
 #define BYT_TRIG_POS		BIT(25)
 #define BYT_TRIG_LVL		BIT(24)
 #define BYT_PIN_MUX		0x07
+#define BYT_DIRECTIRQ		BIT(27)

Please move this definition to be first, like:

/* BYT_CONF0_REG register bits */
#define BYT_DIRECT_IRQ_EN BIT(27)
#define BYT_TRIG_NEG BIT(26)
#define BYT_TRIG_POS BIT(25)

and I would call it BYT_DIRECT_IRQ_EN since it's name in datasheet is "direct_irq_en".

drivers/pinctrl/pinctrl-baytrail.c static int byt_gpio_direction_output(struct gpio_chip *chip, · line 261

Quoted 10 lines
drivers/pinctrl/pinctrl-baytrail.c +2 -1
 /* BYT_VAL_REG register bits */
 #define BYT_INPUT_EN		BIT(2)  /* 0: input enabled (active low)*/
@@ -256,19 +257,29 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
 				     unsigned gpio, int value)
 {
 	struct byt_gpio *vg = to_byt_gpio(chip);
-	void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
+	void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG);
+	void __iomem *value_reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);

Not sure if it is necessary to rename reg -> value_reg. It just makes the patch bigger than it has to be since you also need to rename stuff below.

Otherwise looks good.

Quoted 29 lines
drivers/pinctrl/pinctrl-baytrail.c +12 -3
 	unsigned long flags;
 	u32 reg_val;
 
 	spin_lock_irqsave(&vg->lock, flags);
 
-	reg_val = readl(reg) | BYT_DIR_MASK;
+	/*
+	 * Before making any direction modifications, do a check if gpio
+	 * is set for direct IRQ.  On baytrail, setting GPIO to output does
+	 * not make sense, so let's at least warn the caller before they shoot
+	 * themselves in the foot.
+	 */
+	WARN((readl(conf_reg) & BYT_DIRECTIRQ),
+		"Potential Error: Setting GPIO with direct_irq_en to output");
+
+	reg_val = readl(value_reg) | BYT_DIR_MASK;
 	reg_val &= ~BYT_OUTPUT_EN;
 
 	if (value)
-		writel(reg_val | BYT_LEVEL, reg);
+		writel(reg_val | BYT_LEVEL, value_reg);
 	else
-		writel(reg_val & ~BYT_LEVEL, reg);
+		writel(reg_val & ~BYT_LEVEL, value_reg);
 
 	spin_unlock_irqrestore(&vg->lock, flags);
 
Signature · 1 line
1.7.9.5
#3 lore raw

PATCH v3 1/1 pinctrl: baytrail: Warn if direct IRQ GPIO set to output

From: Eric Ernst <[email protected]>

For Baytrail, you should never set a GPIO set to direct_irq to output mode. When direct_irq_en is set for a GPIO, it is tied directly to an APIC internally, and making the pad output does not make any sense. Assert a WARN() in the event this happens.

---
 drivers/pinctrl/pinctrl-baytrail.c |   11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/pinctrl/pinctrl-baytrail.c +11 -0
index e59983423991..7f0a2bac7c82 100644
@@ -43,6 +43,7 @@
 #define BYT_INT_STAT_REG	0x800
 
 /* BYT_CONF0_REG register bits */
+#define BYT_DIRECT_IRQ_EN	BIT(27)
 #define BYT_TRIG_NEG		BIT(26)
 #define BYT_TRIG_POS		BIT(25)
 #define BYT_TRIG_LVL		BIT(24)
@@ -256,12 +257,22 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
 				     unsigned gpio, int value)
 {
 	struct byt_gpio *vg = to_byt_gpio(chip);
+	void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG);
 	void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
 	unsigned long flags;
 	u32 reg_val;
 
 	spin_lock_irqsave(&vg->lock, flags);
 
+	/*
+	 * Before making any direction modifications, do a check if gpio
+	 * is set for direct IRQ.  On baytrail, setting GPIO to output does
+	 * not make sense, so let's at least warn the caller before they shoot
+	 * themselves in the foot.
+	 */
+	WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
+		"Potential Error: Setting GPIO with direct_irq_en to output");
+
 	reg_val = readl(reg) | BYT_DIR_MASK;
 	reg_val &= ~BYT_OUTPUT_EN;
 
Signature · 1 line
1.7.9.5
Acked-by on v3 1/1
#4 lore raw

Re: [PATCH v3 1/1] pinctrl: baytrail: Warn if direct IRQ GPIO set to output

Quoted 8 lines · On Tue, Jun 03, 2014 at 03:25:16PM -0700, [email protected] wrote:

From: Eric Ernst <[email protected]>

For Baytrail, you should never set a GPIO set to direct_irq to output mode. When direct_irq_en is set for a GPIO, it is tied directly to an APIC internally, and making the pad output does not make any sense. Assert a WARN() in the event this happens.

Looks good now thanks,

#5 lore raw

Re: [PATCH v3 1/1] pinctrl: baytrail: Warn if direct IRQ GPIO set to output

In reply to [email protected]
Quoted 8 lines · On Wed, Jun 4, 2014 at 12:25 AM, <[email protected]> wrote:

From: Eric Ernst <[email protected]>

For Baytrail, you should never set a GPIO set to direct_irq to output mode. When direct_irq_en is set for a GPIO, it is tied directly to an APIC internally, and making the pad output does not make any sense. Assert a WARN() in the event this happens.

This does not apply to my devel branch or Torvald's HEAD. Please rebase and repost, and include Mika's ACK.

Yours,
Linus Walleij

#6 lore raw

PATCH v4 1/1 pinctrl: baytrail: Warn if direct IRQ GPIO set to output

From: Eric Ernst <[email protected]>

For Baytrail, you should never set a GPIO set to direct_irq to output mode. When direct_irq_en is set for a GPIO, it is tied directly to an APIC internally, and making the pad output does not make any sense. Assert a WARN() in the event this happens.

---
 drivers/pinctrl/pinctrl-baytrail.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/pinctrl/pinctrl-baytrail.c +10 -0
index 975572e2f260..c34add934216 100644
@@ -303,12 +303,22 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
 				     unsigned gpio, int value)
 {
 	struct byt_gpio *vg = to_byt_gpio(chip);
+	void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG);
 	void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
 	unsigned long flags;
 	u32 reg_val;
 
 	spin_lock_irqsave(&vg->lock, flags);
 
+	/*
+	 * Before making any direction modifications, do a check if gpio
+	 * is set for direct IRQ.  On baytrail, setting GPIO to output does
+	 * not make sense, so let's at least warn the caller before they shoot
+	 * themselves in the foot.
+	 */
+	WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
+		"Potential Error: Setting GPIO with direct_irq_en to output");
+
 	reg_val = readl(reg) | BYT_DIR_MASK;
 	reg_val &= ~BYT_OUTPUT_EN;
 
Signature · 1 line
1.7.9.5
#7 lore raw

Re: [PATCH v4 1/1] pinctrl: baytrail: Warn if direct IRQ GPIO set to output

Quoted 9 lines · On Thu, Jun 12, 2014 at 8:06 PM, <[email protected]> wrote:

From: Eric Ernst <[email protected]>

For Baytrail, you should never set a GPIO set to direct_irq to output mode. When direct_irq_en is set for a GPIO, it is tied directly to an APIC internally, and making the pad output does not make any sense. Assert a WARN() in the event this happens.

Patch applied.

Sorry for the delay.

Yours,
Linus Walleij

#8 lore raw

Re: [PATCH v4 1/1] pinctrl: baytrail: Warn if direct IRQ GPIO set to output

In reply to [email protected]

drivers/pinctrl/pinctrl-baytrail.c static int byt_gpio_direction_output(struct gpio_chip *chip, · line 320

Quoted 2 lines · On Thu, Jun 12, 2014 at 8:06 PM, <[email protected]> wrote:
drivers/pinctrl/pinctrl-baytrail.c +2 -0
+       WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
+               "Potential Error: Setting GPIO with direct_irq_en to output");

Hm in the v4 version you somehow managed to drop the definition of BYT_DIRECT_IRQ_EN...

I patched it back in. Let's hope it compiles now.

Yours,
Linus Walleij

author
#9 lore raw

Re: [PATCH v4 1/1] pinctrl: baytrail: Warn if direct IRQ GPIO set to output

Mea culpa - thanks Linus. I saw a note from kbuild test robot indicating an issue, but given your response, I am assuming it was from your first build attempt. Thanks.

Quoted 11 lines · Linus Walleij

drivers/pinctrl/pinctrl-baytrail.c static int byt_gpio_direction_output(struct gpio_chip *chip, · line 320

Quoted 2 lines · On Thu, Jun 12, 2014 at 8:06 PM, <[email protected]> wrote:
drivers/pinctrl/pinctrl-baytrail.c +2 -0
+       WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
+               "Potential Error: Setting GPIO with direct_irq_en to output");

Hm in the v4 version you somehow managed to drop the definition of BYT_DIRECT_IRQ_EN...

I patched it back in. Let's hope it compiles now.

Yours,
Linus Walleij

#10 lore raw
In reply to [email protected]

drivers/pinctrl/pinctrl-baytrail.c static int byt_gpio_direction_output(struct gpio_chip *chip, · line 274

Quoted 2 lines · On Mon, Jun 02, 2014 at 02:12:07PM -0700, [email protected] wrote:
drivers/pinctrl/pinctrl-baytrail.c +2 -0
+	WARN((readl(conf_reg) & BYT_DIRECTIRQ),
+		"Potential Error: Setting GPIO with direct_irq_en to output");

Also you don't need parentheses here.