提交 c0ad90a3 编写于 作者: I Ingo Molnar 提交者: Linus Torvalds

[PATCH] genirq: add ->retrigger() irq op to consolidate hw_irq_resend()

Add ->retrigger() irq op to consolidate hw_irq_resend() implementations.
(Most architectures had it defined to NOP anyway.)

NOTE: ia64 needs testing. i386 and x86_64 tested.
Signed-off-by: NIngo Molnar <mingo@elte.hu>
Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 096c8131
...@@ -2071,6 +2071,13 @@ static void set_ioapic_affinity_vector (unsigned int vector, ...@@ -2071,6 +2071,13 @@ static void set_ioapic_affinity_vector (unsigned int vector,
#endif #endif
#endif #endif
static int ioapic_retrigger(unsigned int irq)
{
send_IPI_self(IO_APIC_VECTOR(irq));
return 1;
}
/* /*
* Level and edge triggered IO-APIC interrupts need different handling, * Level and edge triggered IO-APIC interrupts need different handling,
* so we use two separate IRQ descriptors. Edge triggered IRQs can be * so we use two separate IRQ descriptors. Edge triggered IRQs can be
...@@ -2090,6 +2097,7 @@ static struct hw_interrupt_type ioapic_edge_type __read_mostly = { ...@@ -2090,6 +2097,7 @@ static struct hw_interrupt_type ioapic_edge_type __read_mostly = {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.set_affinity = set_ioapic_affinity, .set_affinity = set_ioapic_affinity,
#endif #endif
.retrigger = ioapic_retrigger,
}; };
static struct hw_interrupt_type ioapic_level_type __read_mostly = { static struct hw_interrupt_type ioapic_level_type __read_mostly = {
...@@ -2103,6 +2111,7 @@ static struct hw_interrupt_type ioapic_level_type __read_mostly = { ...@@ -2103,6 +2111,7 @@ static struct hw_interrupt_type ioapic_level_type __read_mostly = {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.set_affinity = set_ioapic_affinity, .set_affinity = set_ioapic_affinity,
#endif #endif
.retrigger = ioapic_retrigger,
}; };
static inline void init_IO_APIC_traps(void) static inline void init_IO_APIC_traps(void)
......
...@@ -26,6 +26,13 @@ lsapic_noop (unsigned int irq) ...@@ -26,6 +26,13 @@ lsapic_noop (unsigned int irq)
/* nuthing to do... */ /* nuthing to do... */
} }
static int lsapic_retrigger(unsigned int irq)
{
ia64_resend_irq(irq);
return 1;
}
struct hw_interrupt_type irq_type_ia64_lsapic = { struct hw_interrupt_type irq_type_ia64_lsapic = {
.typename = "LSAPIC", .typename = "LSAPIC",
.startup = lsapic_noop_startup, .startup = lsapic_noop_startup,
...@@ -33,5 +40,6 @@ struct hw_interrupt_type irq_type_ia64_lsapic = { ...@@ -33,5 +40,6 @@ struct hw_interrupt_type irq_type_ia64_lsapic = {
.enable = lsapic_noop, .enable = lsapic_noop,
.disable = lsapic_noop, .disable = lsapic_noop,
.ack = lsapic_noop, .ack = lsapic_noop,
.end = lsapic_noop .end = lsapic_noop,
.retrigger = lsapic_retrigger,
}; };
...@@ -6165,7 +6165,7 @@ pfm_load_regs (struct task_struct *task) ...@@ -6165,7 +6165,7 @@ pfm_load_regs (struct task_struct *task)
/* /*
* will replay the PMU interrupt * will replay the PMU interrupt
*/ */
if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR);
pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++;
} }
...@@ -6305,7 +6305,7 @@ pfm_load_regs (struct task_struct *task) ...@@ -6305,7 +6305,7 @@ pfm_load_regs (struct task_struct *task)
/* /*
* will replay the PMU interrupt * will replay the PMU interrupt
*/ */
if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR);
pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++;
} }
......
...@@ -125,6 +125,10 @@ static struct hw_interrupt_type cpu_interrupt_type = { ...@@ -125,6 +125,10 @@ static struct hw_interrupt_type cpu_interrupt_type = {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.set_affinity = cpu_set_affinity_irq, .set_affinity = cpu_set_affinity_irq,
#endif #endif
/* XXX: Needs to be written. We managed without it so far, but
* we really ought to write it.
*/
.retrigger = NULL,
}; };
int show_interrupts(struct seq_file *p, void *v) int show_interrupts(struct seq_file *p, void *v)
...@@ -404,13 +408,6 @@ void __init init_IRQ(void) ...@@ -404,13 +408,6 @@ void __init init_IRQ(void)
} }
void hw_resend_irq(struct hw_interrupt_type *type, unsigned int irq)
{
/* XXX: Needs to be written. We managed without it so far, but
* we really ought to write it.
*/
}
void ack_bad_irq(unsigned int irq) void ack_bad_irq(unsigned int irq)
{ {
printk("unexpected IRQ %d\n", irq); printk("unexpected IRQ %d\n", irq);
......
...@@ -1618,6 +1618,13 @@ static void set_ioapic_affinity_vector (unsigned int vector, ...@@ -1618,6 +1618,13 @@ static void set_ioapic_affinity_vector (unsigned int vector,
#endif // CONFIG_SMP #endif // CONFIG_SMP
#endif // CONFIG_PCI_MSI #endif // CONFIG_PCI_MSI
static int ioapic_retrigger(unsigned int irq)
{
send_IPI_self(IO_APIC_VECTOR(irq));
return 1;
}
/* /*
* Level and edge triggered IO-APIC interrupts need different handling, * Level and edge triggered IO-APIC interrupts need different handling,
* so we use two separate IRQ descriptors. Edge triggered IRQs can be * so we use two separate IRQ descriptors. Edge triggered IRQs can be
...@@ -1638,6 +1645,7 @@ static struct hw_interrupt_type ioapic_edge_type __read_mostly = { ...@@ -1638,6 +1645,7 @@ static struct hw_interrupt_type ioapic_edge_type __read_mostly = {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.set_affinity = set_ioapic_affinity, .set_affinity = set_ioapic_affinity,
#endif #endif
.retrigger = ioapic_retrigger,
}; };
static struct hw_interrupt_type ioapic_level_type __read_mostly = { static struct hw_interrupt_type ioapic_level_type __read_mostly = {
...@@ -1651,6 +1659,7 @@ static struct hw_interrupt_type ioapic_level_type __read_mostly = { ...@@ -1651,6 +1659,7 @@ static struct hw_interrupt_type ioapic_level_type __read_mostly = {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.set_affinity = set_ioapic_affinity, .set_affinity = set_ioapic_affinity,
#endif #endif
.retrigger = ioapic_retrigger,
}; };
static inline void init_IO_APIC_traps(void) static inline void init_IO_APIC_traps(void)
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
#define _ALPHA_HW_IRQ_H #define _ALPHA_HW_IRQ_H
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
extern volatile unsigned long irq_err_count; extern volatile unsigned long irq_err_count;
#ifdef CONFIG_ALPHA_GENERIC #ifdef CONFIG_ALPHA_GENERIC
......
#ifndef _ASM_HW_IRQ_H #ifndef _ASM_HW_IRQ_H
#define _ASM_HW_IRQ_H #define _ASM_HW_IRQ_H
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
#endif #endif
...@@ -69,14 +69,4 @@ extern atomic_t irq_mis_count; ...@@ -69,14 +69,4 @@ extern atomic_t irq_mis_count;
#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs)) #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
#if defined(CONFIG_X86_IO_APIC)
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
{
if (IO_APIC_IRQ(i))
send_IPI_self(IO_APIC_VECTOR(i));
}
#else
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
#endif
#endif /* _ASM_HW_IRQ_H */ #endif /* _ASM_HW_IRQ_H */
...@@ -97,8 +97,7 @@ extern int reserve_irq_vector (int vector); ...@@ -97,8 +97,7 @@ extern int reserve_irq_vector (int vector);
extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
static inline void static inline void ia64_resend_irq(unsigned int vector)
hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector)
{ {
platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0); platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
} }
......
#ifndef _ASM_M32R_HW_IRQ_H #ifndef _ASM_M32R_HW_IRQ_H
#define _ASM_M32R_HW_IRQ_H #define _ASM_M32R_HW_IRQ_H
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
{
/* Nothing to do */
}
#endif /* _ASM_M32R_HW_IRQ_H */ #endif /* _ASM_M32R_HW_IRQ_H */
...@@ -19,9 +19,9 @@ extern void init_8259A(int aeoi); ...@@ -19,9 +19,9 @@ extern void init_8259A(int aeoi);
extern atomic_t irq_err_count; extern atomic_t irq_err_count;
/* This may not be apropriate for all machines, we'll see ... */ /*
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) * interrupt-retrigger: NOP for now. This may not be apropriate for all
{ * machines, we'll see ...
} */
#endif /* __ASM_HW_IRQ_H */ #endif /* __ASM_HW_IRQ_H */
...@@ -3,15 +3,6 @@ ...@@ -3,15 +3,6 @@
/* /*
* linux/include/asm/hw_irq.h * linux/include/asm/hw_irq.h
*
* (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
*
* moved some of the old arch/i386/kernel/irq.h to here. VY
*
* IRQ/IPI changes taken from work by Thomas Radke
* <tomsoft@informatik.tu-chemnitz.de>
*/ */
extern void hw_resend_irq(struct hw_interrupt_type *, unsigned int);
#endif #endif
...@@ -102,11 +102,11 @@ static inline void local_irq_save_ptr(unsigned long *flags) ...@@ -102,11 +102,11 @@ static inline void local_irq_save_ptr(unsigned long *flags)
desc->chip->ack(irq); \ desc->chip->ack(irq); \
}) })
/* Should we handle this via lost interrupts and IPIs or should we don't care like /*
* we do now ? --BenH. * interrupt-retrigger: should we handle this via lost interrupts and IPIs
* or should we not care like we do now ? --BenH.
*/ */
struct hw_interrupt_type; struct hw_interrupt_type;
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_HW_IRQ_H */ #endif /* _ASM_POWERPC_HW_IRQ_H */
#ifndef __ASM_SH_HW_IRQ_H #ifndef __ASM_SH_HW_IRQ_H
#define __ASM_SH_HW_IRQ_H #define __ASM_SH_HW_IRQ_H
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
{
/* Nothing to do */
}
#endif /* __ASM_SH_HW_IRQ_H */ #endif /* __ASM_SH_HW_IRQ_H */
...@@ -11,6 +11,5 @@ ...@@ -11,6 +11,5 @@
* Copyright (C) 2000, 2001 Paolo Alberelli * Copyright (C) 2000, 2001 Paolo Alberelli
* *
*/ */
static __inline__ void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { /* Nothing to do */ }
#endif /* __ASM_SH64_HW_IRQ_H */ #endif /* __ASM_SH64_HW_IRQ_H */
...@@ -4,7 +4,4 @@ ...@@ -4,7 +4,4 @@
#include "asm/irq.h" #include "asm/irq.h"
#include "asm/archparam.h" #include "asm/archparam.h"
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
{}
#endif #endif
#ifndef __V850_HW_IRQ_H__ #ifndef __V850_HW_IRQ_H__
#define __V850_HW_IRQ_H__ #define __V850_HW_IRQ_H__
static inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
{
}
#endif /* __V850_HW_IRQ_H__ */ #endif /* __V850_HW_IRQ_H__ */
...@@ -127,15 +127,6 @@ __asm__( \ ...@@ -127,15 +127,6 @@ __asm__( \
"push $~(" #nr ") ; " \ "push $~(" #nr ") ; " \
"jmp common_interrupt"); "jmp common_interrupt");
#if defined(CONFIG_X86_IO_APIC)
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
if (IO_APIC_IRQ(i))
send_IPI_self(IO_APIC_VECTOR(i));
}
#else
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
#endif
#define platform_legacy_irq(irq) ((irq) < 16) #define platform_legacy_irq(irq) ((irq) < 16)
#endif #endif
......
...@@ -11,8 +11,4 @@ ...@@ -11,8 +11,4 @@
#ifndef _XTENSA_HW_IRQ_H #ifndef _XTENSA_HW_IRQ_H
#define _XTENSA_HW_IRQ_H #define _XTENSA_HW_IRQ_H
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
{
}
#endif #endif
...@@ -53,6 +53,8 @@ struct hw_interrupt_type { ...@@ -53,6 +53,8 @@ struct hw_interrupt_type {
void (*ack)(unsigned int irq); void (*ack)(unsigned int irq);
void (*end)(unsigned int irq); void (*end)(unsigned int irq);
void (*set_affinity)(unsigned int irq, cpumask_t dest); void (*set_affinity)(unsigned int irq, cpumask_t dest);
int (*retrigger)(unsigned int irq);
/* Currently used only by UML, might disappear one day.*/ /* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD #ifdef CONFIG_IRQ_RELEASE_METHOD
void (*release)(unsigned int irq, void *dev_id); void (*release)(unsigned int irq, void *dev_id);
......
...@@ -123,7 +123,8 @@ void enable_irq(unsigned int irq) ...@@ -123,7 +123,8 @@ void enable_irq(unsigned int irq)
desc->status = status; desc->status = status;
if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
desc->status = status | IRQ_REPLAY; desc->status = status | IRQ_REPLAY;
hw_resend_irq(desc->chip,irq); if (desc->chip && desc->chip->retrigger)
desc->chip->retrigger(irq);
} }
desc->chip->enable(irq); desc->chip->enable(irq);
/* fall-through */ /* fall-through */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册