aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2015-02-23 07:53:11 -0500
committerLinus Walleij <linus.walleij@linaro.org>2015-03-06 06:21:09 -0500
commit95f0972c7e4cbf3fc68160131c5ac2f033481d00 (patch)
tree5fe75c4fe7e8700ebd68523a61af3d179ef5ef3c /drivers
parentf8323b6bb2cc7d26941d4838dd4375952980a88a (diff)
pinctrl: baytrail: Clear interrupt triggering from pins that are in GPIO mode
If the pin is already configured as GPIO and it has any of the triggering flags set, we may get spurious interrupts depending on the state of the pin. Prevent this by clearing the triggering flags on such pins. However, if the pin is also configured as "direct IRQ" we leave the flags as is. Otherwise it will prevent interrupts that are routed directly to IO-APIC. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pinctrl/intel/pinctrl-baytrail.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index e44f2fd6753f..d264b099182d 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -158,6 +158,19 @@ static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset,
158 return vg->reg_base + reg_offset + reg; 158 return vg->reg_base + reg_offset + reg;
159} 159}
160 160
161static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned offset)
162{
163 void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
164 unsigned long flags;
165 u32 value;
166
167 spin_lock_irqsave(&vg->lock, flags);
168 value = readl(reg);
169 value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
170 writel(value, reg);
171 spin_unlock_irqrestore(&vg->lock, flags);
172}
173
161static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset) 174static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset)
162{ 175{
163 /* SCORE pin 92-93 */ 176 /* SCORE pin 92-93 */
@@ -211,14 +224,8 @@ static int byt_gpio_request(struct gpio_chip *chip, unsigned offset)
211static void byt_gpio_free(struct gpio_chip *chip, unsigned offset) 224static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
212{ 225{
213 struct byt_gpio *vg = to_byt_gpio(chip); 226 struct byt_gpio *vg = to_byt_gpio(chip);
214 void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
215 u32 value;
216
217 /* clear interrupt triggering */
218 value = readl(reg);
219 value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
220 writel(value, reg);
221 227
228 byt_gpio_clear_triggering(vg, offset);
222 pm_runtime_put(&vg->pdev->dev); 229 pm_runtime_put(&vg->pdev->dev);
223} 230}
224 231
@@ -481,6 +488,21 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
481{ 488{
482 void __iomem *reg; 489 void __iomem *reg;
483 u32 base, value; 490 u32 base, value;
491 int i;
492
493 /*
494 * Clear interrupt triggers for all pins that are GPIOs and
495 * do not use direct IRQ mode. This will prevent spurious
496 * interrupts from misconfigured pins.
497 */
498 for (i = 0; i < vg->chip.ngpio; i++) {
499 value = readl(byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG));
500 if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i) &&
501 !(value & BYT_DIRECT_IRQ_EN)) {
502 byt_gpio_clear_triggering(vg, i);
503 dev_dbg(&vg->pdev->dev, "disabling GPIO %d\n", i);
504 }
505 }
484 506
485 /* clear interrupt status trigger registers */ 507 /* clear interrupt status trigger registers */
486 for (base = 0; base < vg->chip.ngpio; base += 32) { 508 for (base = 0; base < vg->chip.ngpio; base += 32) {