Commit 930cd54b authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Ralf Baechle

MIPS: SMTC: Cleanup the hook mess and use irq_data

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
To: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/2194/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 2a2b2212
...@@ -57,7 +57,7 @@ static inline void smtc_im_ack_irq(unsigned int irq) ...@@ -57,7 +57,7 @@ static inline void smtc_im_ack_irq(unsigned int irq)
extern int plat_set_irq_affinity(struct irq_data *d, extern int plat_set_irq_affinity(struct irq_data *d,
const struct cpumask *affinity, bool force); const struct cpumask *affinity, bool force);
extern void smtc_forward_irq(unsigned int irq); extern void smtc_forward_irq(struct irq_data *d);
/* /*
* IRQ affinity hook invoked at the beginning of interrupt dispatch * IRQ affinity hook invoked at the beginning of interrupt dispatch
...@@ -70,51 +70,53 @@ extern void smtc_forward_irq(unsigned int irq); ...@@ -70,51 +70,53 @@ extern void smtc_forward_irq(unsigned int irq);
* cpumask implementations, this version is optimistically assuming * cpumask implementations, this version is optimistically assuming
* that cpumask.h macro overhead is reasonable during interrupt dispatch. * that cpumask.h macro overhead is reasonable during interrupt dispatch.
*/ */
#define IRQ_AFFINITY_HOOK(irq) \ static inline int handle_on_other_cpu(unsigned int irq)
do { \ {
if (!cpumask_test_cpu(smp_processor_id(), irq_desc[irq].affinity)) {\ struct irq_data *d = irq_get_irq_data(irq);
smtc_forward_irq(irq); \
irq_exit(); \ if (cpumask_test_cpu(smp_processor_id(), d->affinity))
return; \ return 0;
} \ smtc_forward_irq(d);
} while (0) return 1;
}
#else /* Not doing SMTC affinity */ #else /* Not doing SMTC affinity */
#define IRQ_AFFINITY_HOOK(irq) do { } while (0) static inline int handle_on_other_cpu(unsigned int irq) { return 0; }
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
static inline void smtc_im_backstop(unsigned int irq)
{
if (irq_hwmask[irq] & 0x0000ff00)
write_c0_tccontext(read_c0_tccontext() &
~(irq_hwmask[irq] & 0x0000ff00));
}
/* /*
* Clear interrupt mask handling "backstop" if irq_hwmask * Clear interrupt mask handling "backstop" if irq_hwmask
* entry so indicates. This implies that the ack() or end() * entry so indicates. This implies that the ack() or end()
* functions will take over re-enabling the low-level mask. * functions will take over re-enabling the low-level mask.
* Otherwise it will be done on return from exception. * Otherwise it will be done on return from exception.
*/ */
#define __DO_IRQ_SMTC_HOOK(irq) \ static inline int smtc_handle_on_other_cpu(unsigned int irq)
do { \ {
IRQ_AFFINITY_HOOK(irq); \ int ret = handle_on_other_cpu(irq);
if (irq_hwmask[irq] & 0x0000ff00) \
write_c0_tccontext(read_c0_tccontext() & \ if (!ret)
~(irq_hwmask[irq] & 0x0000ff00)); \ smtc_im_backstop(irq);
} while (0) return ret;
}
#define __NO_AFFINITY_IRQ_SMTC_HOOK(irq) \
do { \
if (irq_hwmask[irq] & 0x0000ff00) \
write_c0_tccontext(read_c0_tccontext() & \
~(irq_hwmask[irq] & 0x0000ff00)); \
} while (0)
#else #else
#define __DO_IRQ_SMTC_HOOK(irq) \ static inline void smtc_im_backstop(unsigned int irq) { }
do { \ static inline int smtc_handle_on_other_cpu(unsigned int irq)
IRQ_AFFINITY_HOOK(irq); \ {
} while (0) return handle_on_other_cpu(irq);
#define __NO_AFFINITY_IRQ_SMTC_HOOK(irq) do { } while (0) }
#endif #endif
......
...@@ -183,8 +183,8 @@ void __irq_entry do_IRQ(unsigned int irq) ...@@ -183,8 +183,8 @@ void __irq_entry do_IRQ(unsigned int irq)
{ {
irq_enter(); irq_enter();
check_stack_overflow(); check_stack_overflow();
__DO_IRQ_SMTC_HOOK(irq); if (!smtc_handle_on_other_cpu(irq))
generic_handle_irq(irq); generic_handle_irq(irq);
irq_exit(); irq_exit();
} }
...@@ -197,7 +197,7 @@ void __irq_entry do_IRQ(unsigned int irq) ...@@ -197,7 +197,7 @@ void __irq_entry do_IRQ(unsigned int irq)
void __irq_entry do_IRQ_no_affinity(unsigned int irq) void __irq_entry do_IRQ_no_affinity(unsigned int irq)
{ {
irq_enter(); irq_enter();
__NO_AFFINITY_IRQ_SMTC_HOOK(irq); smtc_im_backstop(irq);
generic_handle_irq(irq); generic_handle_irq(irq);
irq_exit(); irq_exit();
} }
......
...@@ -677,9 +677,9 @@ void smtc_set_irq_affinity(unsigned int irq, cpumask_t affinity) ...@@ -677,9 +677,9 @@ void smtc_set_irq_affinity(unsigned int irq, cpumask_t affinity)
*/ */
} }
void smtc_forward_irq(unsigned int irq) void smtc_forward_irq(struct irq_data *d)
{ {
struct irq_data *d = irq_get_irq_data(irq); unsigned int irq = d->irq;
int target; int target;
/* /*
...@@ -708,12 +708,10 @@ void smtc_forward_irq(unsigned int irq) ...@@ -708,12 +708,10 @@ void smtc_forward_irq(unsigned int irq)
*/ */
/* If no one is eligible, service locally */ /* If no one is eligible, service locally */
if (target >= NR_CPUS) { if (target >= NR_CPUS)
do_IRQ_no_affinity(irq); do_IRQ_no_affinity(irq);
return; else
} smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq);
smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq);
} }
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment