aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/irq.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/irq.h')
-rw-r--r--include/linux/irq.h130
1 files changed, 129 insertions, 1 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 069d3b84d311..69681c3b1f05 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -32,7 +32,12 @@
32#define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */ 32#define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */
33#define IRQ_LEVEL 64 /* IRQ level triggered */ 33#define IRQ_LEVEL 64 /* IRQ level triggered */
34#define IRQ_MASKED 128 /* IRQ masked - shouldn't be seen again */ 34#define IRQ_MASKED 128 /* IRQ masked - shouldn't be seen again */
35#define IRQ_PER_CPU 256 /* IRQ is per CPU */ 35#if defined(ARCH_HAS_IRQ_PER_CPU)
36# define IRQ_PER_CPU 256 /* IRQ is per CPU */
37# define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
38#else
39# define CHECK_IRQ_PER_CPU(var) 0
40#endif
36 41
37/* 42/*
38 * Interrupt controller descriptor. This is all we need 43 * Interrupt controller descriptor. This is all we need
@@ -71,16 +76,139 @@ typedef struct irq_desc {
71 unsigned int irq_count; /* For detecting broken interrupts */ 76 unsigned int irq_count; /* For detecting broken interrupts */
72 unsigned int irqs_unhandled; 77 unsigned int irqs_unhandled;
73 spinlock_t lock; 78 spinlock_t lock;
79#if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE)
80 unsigned int move_irq; /* Flag need to re-target intr dest*/
81#endif
74} ____cacheline_aligned irq_desc_t; 82} ____cacheline_aligned irq_desc_t;
75 83
76extern irq_desc_t irq_desc [NR_IRQS]; 84extern irq_desc_t irq_desc [NR_IRQS];
77 85
86/* Return a pointer to the irq descriptor for IRQ. */
87static inline irq_desc_t *
88irq_descp (int irq)
89{
90 return irq_desc + irq;
91}
92
78#include <asm/hw_irq.h> /* the arch dependent stuff */ 93#include <asm/hw_irq.h> /* the arch dependent stuff */
79 94
80extern int setup_irq(unsigned int irq, struct irqaction * new); 95extern int setup_irq(unsigned int irq, struct irqaction * new);
81 96
82#ifdef CONFIG_GENERIC_HARDIRQS 97#ifdef CONFIG_GENERIC_HARDIRQS
83extern cpumask_t irq_affinity[NR_IRQS]; 98extern cpumask_t irq_affinity[NR_IRQS];
99
100#ifdef CONFIG_SMP
101static inline void set_native_irq_info(int irq, cpumask_t mask)
102{
103 irq_affinity[irq] = mask;
104}
105#else
106static inline void set_native_irq_info(int irq, cpumask_t mask)
107{
108}
109#endif
110
111#ifdef CONFIG_SMP
112
113#if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE)
114extern cpumask_t pending_irq_cpumask[NR_IRQS];
115
116static inline void set_pending_irq(unsigned int irq, cpumask_t mask)
117{
118 irq_desc_t *desc = irq_desc + irq;
119 unsigned long flags;
120
121 spin_lock_irqsave(&desc->lock, flags);
122 desc->move_irq = 1;
123 pending_irq_cpumask[irq] = mask;
124 spin_unlock_irqrestore(&desc->lock, flags);
125}
126
127static inline void
128move_native_irq(int irq)
129{
130 cpumask_t tmp;
131 irq_desc_t *desc = irq_descp(irq);
132
133 if (likely (!desc->move_irq))
134 return;
135
136 desc->move_irq = 0;
137
138 if (likely(cpus_empty(pending_irq_cpumask[irq])))
139 return;
140
141 if (!desc->handler->set_affinity)
142 return;
143
144 /* note - we hold the desc->lock */
145 cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map);
146
147 /*
148 * If there was a valid mask to work with, please
149 * do the disable, re-program, enable sequence.
150 * This is *not* particularly important for level triggered
151 * but in a edge trigger case, we might be setting rte
152 * when an active trigger is comming in. This could
153 * cause some ioapics to mal-function.
154 * Being paranoid i guess!
155 */
156 if (unlikely(!cpus_empty(tmp))) {
157 desc->handler->disable(irq);
158 desc->handler->set_affinity(irq,tmp);
159 desc->handler->enable(irq);
160 }
161 cpus_clear(pending_irq_cpumask[irq]);
162}
163
164#ifdef CONFIG_PCI_MSI
165/*
166 * Wonder why these are dummies?
167 * For e.g the set_ioapic_affinity_vector() calls the set_ioapic_affinity_irq()
168 * counter part after translating the vector to irq info. We need to perform
169 * this operation on the real irq, when we dont use vector, i.e when
170 * pci_use_vector() is false.
171 */
172static inline void move_irq(int irq)
173{
174}
175
176static inline void set_irq_info(int irq, cpumask_t mask)
177{
178}
179
180#else // CONFIG_PCI_MSI
181
182static inline void move_irq(int irq)
183{
184 move_native_irq(irq);
185}
186
187static inline void set_irq_info(int irq, cpumask_t mask)
188{
189 set_native_irq_info(irq, mask);
190}
191#endif // CONFIG_PCI_MSI
192
193#else // CONFIG_GENERIC_PENDING_IRQ || CONFIG_IRQBALANCE
194
195#define move_irq(x)
196#define move_native_irq(x)
197#define set_pending_irq(x,y)
198static inline void set_irq_info(int irq, cpumask_t mask)
199{
200 set_native_irq_info(irq, mask);
201}
202
203#endif // CONFIG_GENERIC_PENDING_IRQ
204
205#else // CONFIG_SMP
206
207#define move_irq(x)
208#define move_native_irq(x)
209
210#endif // CONFIG_SMP
211
84extern int no_irq_affinity; 212extern int no_irq_affinity;
85extern int noirqdebug_setup(char *str); 213extern int noirqdebug_setup(char *str);
86 214