aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/twl4030-irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/twl4030-irq.c')
-rw-r--r--drivers/mfd/twl4030-irq.c66
1 files changed, 18 insertions, 48 deletions
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 63a30e88908f..8a7ee3139b86 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -320,24 +320,8 @@ static int twl4030_irq_thread(void *data)
320 for (module_irq = twl4030_irq_base; 320 for (module_irq = twl4030_irq_base;
321 pih_isr; 321 pih_isr;
322 pih_isr >>= 1, module_irq++) { 322 pih_isr >>= 1, module_irq++) {
323 if (pih_isr & 0x1) { 323 if (pih_isr & 0x1)
324 struct irq_desc *d = irq_to_desc(module_irq); 324 generic_handle_irq(module_irq);
325
326 if (!d) {
327 pr_err("twl4030: Invalid SIH IRQ: %d\n",
328 module_irq);
329 return -EINVAL;
330 }
331
332 /* These can't be masked ... always warn
333 * if we get any surprises.
334 */
335 if (d->status & IRQ_DISABLED)
336 note_interrupt(module_irq, d,
337 IRQ_NONE);
338 else
339 d->handle_irq(module_irq, d);
340 }
341 } 325 }
342 local_irq_enable(); 326 local_irq_enable();
343 327
@@ -470,7 +454,7 @@ static inline void activate_irq(int irq)
470 set_irq_flags(irq, IRQF_VALID); 454 set_irq_flags(irq, IRQF_VALID);
471#else 455#else
472 /* same effect on other architectures */ 456 /* same effect on other architectures */
473 set_irq_noprobe(irq); 457 irq_set_noprobe(irq);
474#endif 458#endif
475} 459}
476 460
@@ -560,24 +544,18 @@ static void twl4030_sih_do_edge(struct work_struct *work)
560 /* Modify only the bits we know must change */ 544 /* Modify only the bits we know must change */
561 while (edge_change) { 545 while (edge_change) {
562 int i = fls(edge_change) - 1; 546 int i = fls(edge_change) - 1;
563 struct irq_desc *d = irq_to_desc(i + agent->irq_base); 547 struct irq_data *idata = irq_get_irq_data(i + agent->irq_base);
564 int byte = 1 + (i >> 2); 548 int byte = 1 + (i >> 2);
565 int off = (i & 0x3) * 2; 549 int off = (i & 0x3) * 2;
566 550 unsigned int type;
567 if (!d) {
568 pr_err("twl4030: Invalid IRQ: %d\n",
569 i + agent->irq_base);
570 return;
571 }
572 551
573 bytes[byte] &= ~(0x03 << off); 552 bytes[byte] &= ~(0x03 << off);
574 553
575 raw_spin_lock_irq(&d->lock); 554 type = irqd_get_trigger_type(idata);
576 if (d->status & IRQ_TYPE_EDGE_RISING) 555 if (type & IRQ_TYPE_EDGE_RISING)
577 bytes[byte] |= BIT(off + 1); 556 bytes[byte] |= BIT(off + 1);
578 if (d->status & IRQ_TYPE_EDGE_FALLING) 557 if (type & IRQ_TYPE_EDGE_FALLING)
579 bytes[byte] |= BIT(off + 0); 558 bytes[byte] |= BIT(off + 0);
580 raw_spin_unlock_irq(&d->lock);
581 559
582 edge_change &= ~BIT(i); 560 edge_change &= ~BIT(i);
583 } 561 }
@@ -626,21 +604,13 @@ static void twl4030_sih_unmask(struct irq_data *data)
626static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) 604static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger)
627{ 605{
628 struct sih_agent *sih = irq_data_get_irq_chip_data(data); 606 struct sih_agent *sih = irq_data_get_irq_chip_data(data);
629 struct irq_desc *desc = irq_to_desc(data->irq);
630 unsigned long flags; 607 unsigned long flags;
631 608
632 if (!desc) {
633 pr_err("twl4030: Invalid IRQ: %d\n", data->irq);
634 return -EINVAL;
635 }
636
637 if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) 609 if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
638 return -EINVAL; 610 return -EINVAL;
639 611
640 spin_lock_irqsave(&sih_agent_lock, flags); 612 spin_lock_irqsave(&sih_agent_lock, flags);
641 if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) { 613 if (irqd_get_trigger_type(data) != trigger) {
642 desc->status &= ~IRQ_TYPE_SENSE_MASK;
643 desc->status |= trigger;
644 sih->edge_change |= BIT(data->irq - sih->irq_base); 614 sih->edge_change |= BIT(data->irq - sih->irq_base);
645 queue_work(wq, &sih->edge_work); 615 queue_work(wq, &sih->edge_work);
646 } 616 }
@@ -680,7 +650,7 @@ static inline int sih_read_isr(const struct sih *sih)
680 */ 650 */
681static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) 651static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc)
682{ 652{
683 struct sih_agent *agent = get_irq_data(irq); 653 struct sih_agent *agent = irq_get_handler_data(irq);
684 const struct sih *sih = agent->sih; 654 const struct sih *sih = agent->sih;
685 int isr; 655 int isr;
686 656
@@ -754,9 +724,9 @@ int twl4030_sih_setup(int module)
754 for (i = 0; i < sih->bits; i++) { 724 for (i = 0; i < sih->bits; i++) {
755 irq = irq_base + i; 725 irq = irq_base + i;
756 726
757 set_irq_chip_and_handler(irq, &twl4030_sih_irq_chip, 727 irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip,
758 handle_edge_irq); 728 handle_edge_irq);
759 set_irq_chip_data(irq, agent); 729 irq_set_chip_data(irq, agent);
760 activate_irq(irq); 730 activate_irq(irq);
761 } 731 }
762 732
@@ -765,8 +735,8 @@ int twl4030_sih_setup(int module)
765 735
766 /* replace generic PIH handler (handle_simple_irq) */ 736 /* replace generic PIH handler (handle_simple_irq) */
767 irq = sih_mod + twl4030_irq_base; 737 irq = sih_mod + twl4030_irq_base;
768 set_irq_data(irq, agent); 738 irq_set_handler_data(irq, agent);
769 set_irq_chained_handler(irq, handle_twl4030_sih); 739 irq_set_chained_handler(irq, handle_twl4030_sih);
770 740
771 pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name, 741 pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name,
772 irq, irq_base, twl4030_irq_next - 1); 742 irq, irq_base, twl4030_irq_next - 1);
@@ -815,8 +785,8 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
815 twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; 785 twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack;
816 786
817 for (i = irq_base; i < irq_end; i++) { 787 for (i = irq_base; i < irq_end; i++) {
818 set_irq_chip_and_handler(i, &twl4030_irq_chip, 788 irq_set_chip_and_handler(i, &twl4030_irq_chip,
819 handle_simple_irq); 789 handle_simple_irq);
820 activate_irq(i); 790 activate_irq(i);
821 } 791 }
822 twl4030_irq_next = i; 792 twl4030_irq_next = i;
@@ -856,7 +826,7 @@ fail_rqirq:
856 /* clean up twl4030_sih_setup */ 826 /* clean up twl4030_sih_setup */
857fail: 827fail:
858 for (i = irq_base; i < irq_end; i++) 828 for (i = irq_base; i < irq_end; i++)
859 set_irq_chip_and_handler(i, NULL, NULL); 829 irq_set_chip_and_handler(i, NULL, NULL);
860 destroy_workqueue(wq); 830 destroy_workqueue(wq);
861 wq = NULL; 831 wq = NULL;
862 return status; 832 return status;