aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2015-02-23 07:53:12 -0500
committerLinus Walleij <linus.walleij@linaro.org>2015-03-06 06:22:41 -0500
commit31e4329f99062a06dca5a493bb4495a63b2dc6ba (patch)
treea0df5223e51622480ddad730d6ed093e0fa8388d
parent95f0972c7e4cbf3fc68160131c5ac2f033481d00 (diff)
pinctrl: baytrail: Rework interrupt handling
Instead of handling everything in the driver's first level interrupt handler, we can take advantage of already existing flow handlers that are provided by the IRQ core. This changes the functionality a bit also. Previously the driver looped over pending interrupts in a single loop, restarting the loop if some interrupt changed state. This caused problem with Lenovo Thinkpad 10 digitizer that it was not able to deassert the interrupt before the driver disabled the interrupt for good (looplimit was exhausted). Rework the interrupt handling logic a bit so that we provide proper mask, ack and unmask operations in terms of Baytrail GPIO hardware and loop over pending interrupts only once. If the interrupt remains asserted the first level handler will be re-triggered automatically. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/intel/pinctrl-baytrail.c100
1 files changed, 56 insertions, 44 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index d264b099182d..2318057a309b 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -252,23 +252,13 @@ static int byt_irq_type(struct irq_data *d, unsigned type)
252 value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | 252 value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
253 BYT_TRIG_LVL); 253 BYT_TRIG_LVL);
254 254
255 switch (type) {
256 case IRQ_TYPE_LEVEL_HIGH:
257 value |= BYT_TRIG_LVL;
258 case IRQ_TYPE_EDGE_RISING:
259 value |= BYT_TRIG_POS;
260 break;
261 case IRQ_TYPE_LEVEL_LOW:
262 value |= BYT_TRIG_LVL;
263 case IRQ_TYPE_EDGE_FALLING:
264 value |= BYT_TRIG_NEG;
265 break;
266 case IRQ_TYPE_EDGE_BOTH:
267 value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
268 break;
269 }
270 writel(value, reg); 255 writel(value, reg);
271 256
257 if (type & IRQ_TYPE_EDGE_BOTH)
258 __irq_set_handler_locked(d->irq, handle_edge_irq);
259 else if (type & IRQ_TYPE_LEVEL_MASK)
260 __irq_set_handler_locked(d->irq, handle_level_irq);
261
272 spin_unlock_irqrestore(&vg->lock, flags); 262 spin_unlock_irqrestore(&vg->lock, flags);
273 263
274 return 0; 264 return 0;
@@ -426,58 +416,80 @@ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
426 struct irq_data *data = irq_desc_get_irq_data(desc); 416 struct irq_data *data = irq_desc_get_irq_data(desc);
427 struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc)); 417 struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc));
428 struct irq_chip *chip = irq_data_get_irq_chip(data); 418 struct irq_chip *chip = irq_data_get_irq_chip(data);
429 u32 base, pin, mask; 419 u32 base, pin;
430 void __iomem *reg; 420 void __iomem *reg;
431 u32 pending; 421 unsigned long pending;
432 unsigned virq; 422 unsigned virq;
433 int looplimit = 0;
434 423
435 /* check from GPIO controller which pin triggered the interrupt */ 424 /* check from GPIO controller which pin triggered the interrupt */
436 for (base = 0; base < vg->chip.ngpio; base += 32) { 425 for (base = 0; base < vg->chip.ngpio; base += 32) {
437
438 reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG); 426 reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
439 427 pending = readl(reg);
440 while ((pending = readl(reg))) { 428 for_each_set_bit(pin, &pending, 32) {
441 pin = __ffs(pending);
442 mask = BIT(pin);
443 /* Clear before handling so we can't lose an edge */
444 writel(mask, reg);
445
446 virq = irq_find_mapping(vg->chip.irqdomain, base + pin); 429 virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
447 generic_handle_irq(virq); 430 generic_handle_irq(virq);
448
449 /* In case bios or user sets triggering incorretly a pin
450 * might remain in "interrupt triggered" state.
451 */
452 if (looplimit++ > 32) {
453 dev_err(&vg->pdev->dev,
454 "Gpio %d interrupt flood, disabling\n",
455 base + pin);
456
457 reg = byt_gpio_reg(&vg->chip, base + pin,
458 BYT_CONF0_REG);
459 mask = readl(reg);
460 mask &= ~(BYT_TRIG_NEG | BYT_TRIG_POS |
461 BYT_TRIG_LVL);
462 writel(mask, reg);
463 mask = readl(reg); /* flush */
464 break;
465 }
466 } 431 }
467 } 432 }
468 chip->irq_eoi(data); 433 chip->irq_eoi(data);
469} 434}
470 435
436static void byt_irq_ack(struct irq_data *d)
437{
438 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
439 struct byt_gpio *vg = to_byt_gpio(gc);
440 unsigned offset = irqd_to_hwirq(d);
441 void __iomem *reg;
442
443 reg = byt_gpio_reg(&vg->chip, offset, BYT_INT_STAT_REG);
444 writel(BIT(offset % 32), reg);
445}
446
471static void byt_irq_unmask(struct irq_data *d) 447static void byt_irq_unmask(struct irq_data *d)
472{ 448{
449 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
450 struct byt_gpio *vg = to_byt_gpio(gc);
451 unsigned offset = irqd_to_hwirq(d);
452 unsigned long flags;
453 void __iomem *reg;
454 u32 value;
455
456 spin_lock_irqsave(&vg->lock, flags);
457
458 reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
459 value = readl(reg);
460
461 switch (irqd_get_trigger_type(d)) {
462 case IRQ_TYPE_LEVEL_HIGH:
463 value |= BYT_TRIG_LVL;
464 case IRQ_TYPE_EDGE_RISING:
465 value |= BYT_TRIG_POS;
466 break;
467 case IRQ_TYPE_LEVEL_LOW:
468 value |= BYT_TRIG_LVL;
469 case IRQ_TYPE_EDGE_FALLING:
470 value |= BYT_TRIG_NEG;
471 break;
472 case IRQ_TYPE_EDGE_BOTH:
473 value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
474 break;
475 }
476
477 writel(value, reg);
478
479 spin_unlock_irqrestore(&vg->lock, flags);
473} 480}
474 481
475static void byt_irq_mask(struct irq_data *d) 482static void byt_irq_mask(struct irq_data *d)
476{ 483{
484 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
485 struct byt_gpio *vg = to_byt_gpio(gc);
486
487 byt_gpio_clear_triggering(vg, irqd_to_hwirq(d));
477} 488}
478 489
479static struct irq_chip byt_irqchip = { 490static struct irq_chip byt_irqchip = {
480 .name = "BYT-GPIO", 491 .name = "BYT-GPIO",
492 .irq_ack = byt_irq_ack,
481 .irq_mask = byt_irq_mask, 493 .irq_mask = byt_irq_mask,
482 .irq_unmask = byt_irq_unmask, 494 .irq_unmask = byt_irq_unmask,
483 .irq_set_type = byt_irq_type, 495 .irq_set_type = byt_irq_type,