mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
IRQCHIP: mips-gic: Don't nest calls to do_IRQ()
The GIC chained handlers use do_IRQ() to call the subhandlers. This means that irq_enter() calls get nested, which leads to preempt count looking like we're in nested interrupts, which in turn leads to all system time being accounted as IRQ time in account_system_time(). Fix it by using generic_handle_irq(). Since these same functions are used in some systems (if cpu_has_veic) from a low-level vectored interrupt handler which does not go throught do_IRQ(), we need to do it conditionally. Signed-off-by: Rabin Vincent <[email protected]> Reviewed-by: Andrew Bresticker <[email protected]> Acked-by: Thomas Gleixner <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Patchwork: https://patchwork.linux-mips.org/patch/10545/ Signed-off-by: Ralf Baechle <[email protected]>
This commit is contained in:
parent
9cc719ab3f
commit
1b3ed367ce
1 changed files with 14 additions and 7 deletions
|
|
@ -271,7 +271,7 @@ int gic_get_c0_fdc_int(void)
|
|||
GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC));
|
||||
}
|
||||
|
||||
static void gic_handle_shared_int(void)
|
||||
static void gic_handle_shared_int(bool chained)
|
||||
{
|
||||
unsigned int i, intr, virq;
|
||||
unsigned long *pcpu_mask;
|
||||
|
|
@ -299,7 +299,10 @@ static void gic_handle_shared_int(void)
|
|||
while (intr != gic_shared_intrs) {
|
||||
virq = irq_linear_revmap(gic_irq_domain,
|
||||
GIC_SHARED_TO_HWIRQ(intr));
|
||||
do_IRQ(virq);
|
||||
if (chained)
|
||||
generic_handle_irq(virq);
|
||||
else
|
||||
do_IRQ(virq);
|
||||
|
||||
/* go to next pending bit */
|
||||
bitmap_clear(pending, intr, 1);
|
||||
|
|
@ -431,7 +434,7 @@ static struct irq_chip gic_edge_irq_controller = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static void gic_handle_local_int(void)
|
||||
static void gic_handle_local_int(bool chained)
|
||||
{
|
||||
unsigned long pending, masked;
|
||||
unsigned int intr, virq;
|
||||
|
|
@ -445,7 +448,10 @@ static void gic_handle_local_int(void)
|
|||
while (intr != GIC_NUM_LOCAL_INTRS) {
|
||||
virq = irq_linear_revmap(gic_irq_domain,
|
||||
GIC_LOCAL_TO_HWIRQ(intr));
|
||||
do_IRQ(virq);
|
||||
if (chained)
|
||||
generic_handle_irq(virq);
|
||||
else
|
||||
do_IRQ(virq);
|
||||
|
||||
/* go to next pending bit */
|
||||
bitmap_clear(&pending, intr, 1);
|
||||
|
|
@ -509,13 +515,14 @@ static struct irq_chip gic_all_vpes_local_irq_controller = {
|
|||
|
||||
static void __gic_irq_dispatch(void)
|
||||
{
|
||||
gic_handle_local_int();
|
||||
gic_handle_shared_int();
|
||||
gic_handle_local_int(false);
|
||||
gic_handle_shared_int(false);
|
||||
}
|
||||
|
||||
static void gic_irq_dispatch(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
__gic_irq_dispatch();
|
||||
gic_handle_local_int(true);
|
||||
gic_handle_shared_int(true);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MIPS_GIC_IPI
|
||||
|
|
|
|||
Loading…
Reference in a new issue