Skip to content

Commit

Permalink
mfd: htc-i2cpld: Cleanup interrupt handling
Browse files Browse the repository at this point in the history
Remove the pointless irq_desc check in set_type. This function is
called with that irq descriptor locked. Also remove the write back of
the flow type as the core code does this already when the return value
is 0.

Also store the flow type in the chip data structure, so there is no
need to fiddle in the irq descriptor.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
  • Loading branch information
Thomas Gleixner authored and Samuel Ortiz committed Mar 26, 2011
1 parent 77eda96 commit 9eaee99
Showing 1 changed file with 7 additions and 18 deletions.
25 changes: 7 additions & 18 deletions drivers/mfd/htc-i2cpld.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct htcpld_chip {
uint irq_start;
int nirqs;

unsigned int flow_type;
/*
* Work structure to allow for setting values outside of any
* possible interrupt context
Expand Down Expand Up @@ -97,12 +98,7 @@ static void htcpld_unmask(struct irq_data *data)

static int htcpld_set_type(struct irq_data *data, unsigned int flags)
{
struct irq_desc *d = irq_to_desc(data->irq);

if (!d) {
pr_err("HTCPLD invalid IRQ: %d\n", data->irq);
return -EINVAL;
}
struct htcpld_chip *chip = irq_data_get_irq_chip_data(data);

if (flags & ~IRQ_TYPE_SENSE_MASK)
return -EINVAL;
Expand All @@ -111,9 +107,7 @@ static int htcpld_set_type(struct irq_data *data, unsigned int flags)
if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))
return -EINVAL;

d->status &= ~IRQ_TYPE_SENSE_MASK;
d->status |= flags;

chip->flow_type = flags;
return 0;
}

Expand All @@ -135,7 +129,6 @@ static irqreturn_t htcpld_handler(int irq, void *dev)
unsigned int i;
unsigned long flags;
int irqpin;
struct irq_desc *desc;

if (!htcpld) {
pr_debug("htcpld is null in ISR\n");
Expand Down Expand Up @@ -195,23 +188,19 @@ static irqreturn_t htcpld_handler(int irq, void *dev)
* associated interrupts.
*/
for (irqpin = 0; irqpin < chip->nirqs; irqpin++) {
unsigned oldb, newb;
int flags;
unsigned oldb, newb, type = chip->flow_type;

irq = chip->irq_start + irqpin;
desc = irq_to_desc(irq);
flags = desc->status;

/* Run the IRQ handler, but only if the bit value
* changed, and the proper flags are set */
oldb = (old_val >> irqpin) & 1;
newb = (uval >> irqpin) & 1;

if ((!oldb && newb && (flags & IRQ_TYPE_EDGE_RISING)) ||
(oldb && !newb &&
(flags & IRQ_TYPE_EDGE_FALLING))) {
if ((!oldb && newb && (type & IRQ_TYPE_EDGE_RISING)) ||
(oldb && !newb && (type & IRQ_TYPE_EDGE_FALLING))) {
pr_debug("fire IRQ %d\n", irqpin);
desc->handle_irq(irq, desc);
generic_handle_irq(irq);
}
}
}
Expand Down

0 comments on commit 9eaee99

Please sign in to comment.