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>
This commit is contained in:
parent
9d8fd10aa5
commit
d740f4523b
1 changed files with 8 additions and 38 deletions
|
@ -320,24 +320,8 @@ static int twl4030_irq_thread(void *data)
|
||||||
for (module_irq = twl4030_irq_base;
|
for (module_irq = twl4030_irq_base;
|
||||||
pih_isr;
|
pih_isr;
|
||||||
pih_isr >>= 1, module_irq++) {
|
pih_isr >>= 1, module_irq++) {
|
||||||
if (pih_isr & 0x1) {
|
if (pih_isr & 0x1)
|
||||||
struct irq_desc *d = irq_to_desc(module_irq);
|
generic_handle_irq(module_irq);
|
||||||
|
|
||||||
if (!d) {
|
|
||||||
pr_err("twl4030: Invalid SIH IRQ: %d\n",
|
|
||||||
module_irq);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* These can't be masked ... always warn
|
|
||||||
* if we get any surprises.
|
|
||||||
*/
|
|
||||||
if (d->status & IRQ_DISABLED)
|
|
||||||
note_interrupt(module_irq, d,
|
|
||||||
IRQ_NONE);
|
|
||||||
else
|
|
||||||
d->handle_irq(module_irq, d);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
|
||||||
|
@ -560,24 +544,18 @@ static void twl4030_sih_do_edge(struct work_struct *work)
|
||||||
/* Modify only the bits we know must change */
|
/* Modify only the bits we know must change */
|
||||||
while (edge_change) {
|
while (edge_change) {
|
||||||
int i = fls(edge_change) - 1;
|
int i = fls(edge_change) - 1;
|
||||||
struct irq_desc *d = irq_to_desc(i + agent->irq_base);
|
struct irq_data *idata = irq_get_irq_data(i + agent->irq_base);
|
||||||
int byte = 1 + (i >> 2);
|
int byte = 1 + (i >> 2);
|
||||||
int off = (i & 0x3) * 2;
|
int off = (i & 0x3) * 2;
|
||||||
|
unsigned int type;
|
||||||
if (!d) {
|
|
||||||
pr_err("twl4030: Invalid IRQ: %d\n",
|
|
||||||
i + agent->irq_base);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes[byte] &= ~(0x03 << off);
|
bytes[byte] &= ~(0x03 << off);
|
||||||
|
|
||||||
raw_spin_lock_irq(&d->lock);
|
type = irqd_get_trigger_type(idata);
|
||||||
if (d->status & IRQ_TYPE_EDGE_RISING)
|
if (type & IRQ_TYPE_EDGE_RISING)
|
||||||
bytes[byte] |= BIT(off + 1);
|
bytes[byte] |= BIT(off + 1);
|
||||||
if (d->status & IRQ_TYPE_EDGE_FALLING)
|
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||||
bytes[byte] |= BIT(off + 0);
|
bytes[byte] |= BIT(off + 0);
|
||||||
raw_spin_unlock_irq(&d->lock);
|
|
||||||
|
|
||||||
edge_change &= ~BIT(i);
|
edge_change &= ~BIT(i);
|
||||||
}
|
}
|
||||||
|
@ -626,21 +604,13 @@ static void twl4030_sih_unmask(struct irq_data *data)
|
||||||
static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger)
|
static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger)
|
||||||
{
|
{
|
||||||
struct sih_agent *sih = irq_data_get_irq_chip_data(data);
|
struct sih_agent *sih = irq_data_get_irq_chip_data(data);
|
||||||
struct irq_desc *desc = irq_to_desc(data->irq);
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!desc) {
|
|
||||||
pr_err("twl4030: Invalid IRQ: %d\n", data->irq);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
|
if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
spin_lock_irqsave(&sih_agent_lock, flags);
|
spin_lock_irqsave(&sih_agent_lock, flags);
|
||||||
if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) {
|
if (irqd_get_trigger_type(data) != trigger) {
|
||||||
desc->status &= ~IRQ_TYPE_SENSE_MASK;
|
|
||||||
desc->status |= trigger;
|
|
||||||
sih->edge_change |= BIT(data->irq - sih->irq_base);
|
sih->edge_change |= BIT(data->irq - sih->irq_base);
|
||||||
queue_work(wq, &sih->edge_work);
|
queue_work(wq, &sih->edge_work);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue