MIPS: SMTC: Cleanup the hook mess and use irq_data
Signed-off-by: Thomas Gleixner <tglx@linutronix.de> To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2194/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
Родитель
2a2b221298
Коммит
930cd54b3b
|
@ -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);
|
||||||
* 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() & \
|
|
||||||
~(irq_hwmask[irq] & 0x0000ff00)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define __NO_AFFINITY_IRQ_SMTC_HOOK(irq) \
|
if (!ret)
|
||||||
do { \
|
smtc_im_backstop(irq);
|
||||||
if (irq_hwmask[irq] & 0x0000ff00) \
|
return ret;
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче