mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-26 05:30:53 +07:00
mfd: ab8500: actually handle the AB8500 GPIO IRQs correctly
The patch: "mfd: ab8500: prepare to handle AB8500 GPIO's IRQs correctly" altered the AB8500 IRQ mask/unmask functions such that they would handle masking on/off the falling edge IRQ if this was requested by the consumer. However the bit mask for hwirqs 43 and 44 was shifting the bit mask incorrectly, resulting in the wrong IRQ being mased/unmasked. Further while the patch would mask/unmask the correct line, when the interrupt actually came in, it would still be treated as a valid hwirq. The offsetting applied when masking/unmasking was not applied when handling the IRQ, i.e. the falling edge lines were not routed back to the rising edge lines. This fixes both cases. The end result has been tested with the SIM detect IRQ, GPIO12, hwirq 46 and 62. Cc: Samuel Ortiz <sameo@linux.intel.com> Cc: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
This commit is contained in:
parent
9c677b9b74
commit
e2ddf46ab4
@ -375,7 +375,8 @@ static void ab8500_irq_mask(struct irq_data *data)
|
||||
if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R)
|
||||
ab8500->mask[index + 1] |= mask;
|
||||
if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R)
|
||||
ab8500->mask[index] |= (mask >> 1);
|
||||
/* Here the falling IRQ is one bit lower */
|
||||
ab8500->mask[index] |= (mask << 1);
|
||||
}
|
||||
|
||||
static void ab8500_irq_unmask(struct irq_data *data)
|
||||
@ -396,12 +397,14 @@ static void ab8500_irq_unmask(struct irq_data *data)
|
||||
else if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R)
|
||||
ab8500->mask[index + 1] &= ~mask;
|
||||
else if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R)
|
||||
ab8500->mask[index] &= ~(mask >> 1);
|
||||
/* Here the falling IRQ is one bit lower */
|
||||
ab8500->mask[index] &= ~(mask << 1);
|
||||
else
|
||||
ab8500->mask[index] &= ~mask;
|
||||
} else
|
||||
} else {
|
||||
/* Satisfies the case where type is not set. */
|
||||
ab8500->mask[index] &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
static struct irq_chip ab8500_irq_chip = {
|
||||
@ -435,6 +438,19 @@ static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500,
|
||||
line = (i << 3) + int_bit;
|
||||
latch_val &= ~(1 << int_bit);
|
||||
|
||||
/*
|
||||
* This handles the falling edge hwirqs from the GPIO
|
||||
* lines. Route them back to the line registered for the
|
||||
* rising IRQ, as this is merely a flag for the same IRQ
|
||||
* in linux terms.
|
||||
*/
|
||||
if (line >= AB8500_INT_GPIO6F && line <= AB8500_INT_GPIO41F)
|
||||
line -= 16;
|
||||
if (line >= AB9540_INT_GPIO50F && line <= AB9540_INT_GPIO54F)
|
||||
line -= 8;
|
||||
if (line == AB8540_INT_GPIO43F || line == AB8540_INT_GPIO44F)
|
||||
line += 1;
|
||||
|
||||
handle_nested_irq(ab8500->irq_base + line);
|
||||
} while (latch_val);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user