aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2011-03-25 07:12:31 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2011-03-26 19:09:48 -0400
commitd740f4523bb4aea24bece704c726c69094e20d00 (patch)
treeb26bfc2a92c53cf6cf115bf9bf99bc7a51d11983
parent9d8fd10aa5843e018d456644fc1a58896d8eeaf5 (diff)
mfd: twl4030: Cleanup interrupt handling
irq_desc checking in a function which is called with that irq descriptor locked, is pointless. Equally pointless as the irq desc check in the interrupt service routine. The driver sets those lines up, so that cant go away magically. Remove the open coded handler magic and use the proper accessor. No need to fiddle with irq_desc in the type setting function. The original value is in irq_data and the core code stores the new setting when the return value is 0. This driver needs to be converted to threaded interrupts and buslock. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/mfd/twl4030-irq.c46
1 files changed, 8 insertions, 38 deletions
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 63a30e88908f..47e8de0f3366 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
@@ -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 }