aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl')
-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,