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.h62
1 files changed, 59 insertions, 3 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 3dddfa703ebd..98564dc64476 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -129,9 +129,14 @@ struct irq_chip {
129 const char *typename; 129 const char *typename;
130}; 130};
131 131
132struct timer_rand_state;
133struct irq_2_iommu;
132/** 134/**
133 * struct irq_desc - interrupt descriptor 135 * struct irq_desc - interrupt descriptor
134 * @irq: interrupt number for this descriptor 136 * @irq: interrupt number for this descriptor
137 * @timer_rand_state: pointer to timer rand state struct
138 * @kstat_irqs: irq stats per cpu
139 * @irq_2_iommu: iommu with this irq
135 * @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()] 140 * @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()]
136 * @chip: low level interrupt hardware access 141 * @chip: low level interrupt hardware access
137 * @msi_desc: MSI descriptor 142 * @msi_desc: MSI descriptor
@@ -143,8 +148,8 @@ struct irq_chip {
143 * @depth: disable-depth, for nested irq_disable() calls 148 * @depth: disable-depth, for nested irq_disable() calls
144 * @wake_depth: enable depth, for multiple set_irq_wake() callers 149 * @wake_depth: enable depth, for multiple set_irq_wake() callers
145 * @irq_count: stats field to detect stalled irqs 150 * @irq_count: stats field to detect stalled irqs
146 * @irqs_unhandled: stats field for spurious unhandled interrupts
147 * @last_unhandled: aging timer for unhandled count 151 * @last_unhandled: aging timer for unhandled count
152 * @irqs_unhandled: stats field for spurious unhandled interrupts
148 * @lock: locking for SMP 153 * @lock: locking for SMP
149 * @affinity: IRQ affinity on SMP 154 * @affinity: IRQ affinity on SMP
150 * @cpu: cpu index useful for balancing 155 * @cpu: cpu index useful for balancing
@@ -154,6 +159,13 @@ struct irq_chip {
154 */ 159 */
155struct irq_desc { 160struct irq_desc {
156 unsigned int irq; 161 unsigned int irq;
162#ifdef CONFIG_SPARSE_IRQ
163 struct timer_rand_state *timer_rand_state;
164 unsigned int *kstat_irqs;
165# ifdef CONFIG_INTR_REMAP
166 struct irq_2_iommu *irq_2_iommu;
167# endif
168#endif
157 irq_flow_handler_t handle_irq; 169 irq_flow_handler_t handle_irq;
158 struct irq_chip *chip; 170 struct irq_chip *chip;
159 struct msi_desc *msi_desc; 171 struct msi_desc *msi_desc;
@@ -165,8 +177,8 @@ struct irq_desc {
165 unsigned int depth; /* nested irq disables */ 177 unsigned int depth; /* nested irq disables */
166 unsigned int wake_depth; /* nested wake enables */ 178 unsigned int wake_depth; /* nested wake enables */
167 unsigned int irq_count; /* For detecting broken IRQs */ 179 unsigned int irq_count; /* For detecting broken IRQs */
168 unsigned int irqs_unhandled;
169 unsigned long last_unhandled; /* Aging timer for unhandled count */ 180 unsigned long last_unhandled; /* Aging timer for unhandled count */
181 unsigned int irqs_unhandled;
170 spinlock_t lock; 182 spinlock_t lock;
171#ifdef CONFIG_SMP 183#ifdef CONFIG_SMP
172 cpumask_t affinity; 184 cpumask_t affinity;
@@ -181,12 +193,51 @@ struct irq_desc {
181 const char *name; 193 const char *name;
182} ____cacheline_internodealigned_in_smp; 194} ____cacheline_internodealigned_in_smp;
183 195
196extern void early_irq_init(void);
197extern void arch_early_irq_init(void);
198extern void arch_init_chip_data(struct irq_desc *desc, int cpu);
199extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
200 struct irq_desc *desc, int cpu);
201extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
184 202
203#ifndef CONFIG_SPARSE_IRQ
185extern struct irq_desc irq_desc[NR_IRQS]; 204extern struct irq_desc irq_desc[NR_IRQS];
186 205
187static inline struct irq_desc *irq_to_desc(unsigned int irq) 206static inline struct irq_desc *irq_to_desc(unsigned int irq)
188{ 207{
189 return (irq < nr_irqs) ? irq_desc + irq : NULL; 208 return (irq < NR_IRQS) ? irq_desc + irq : NULL;
209}
210static inline struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
211{
212 return irq_to_desc(irq);
213}
214
215#else
216
217extern struct irq_desc *irq_to_desc(unsigned int irq);
218extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu);
219extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu);
220
221# define for_each_irq_desc(irq, desc) \
222 for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs; irq++, desc = irq_to_desc(irq))
223# define for_each_irq_desc_reverse(irq, desc) \
224 for (irq = nr_irqs - 1, desc = irq_to_desc(irq); irq >= 0; irq--, desc = irq_to_desc(irq))
225
226#define kstat_irqs_this_cpu(DESC) \
227 ((DESC)->kstat_irqs[smp_processor_id()])
228#define kstat_incr_irqs_this_cpu(irqno, DESC) \
229 ((DESC)->kstat_irqs[smp_processor_id()]++)
230
231#endif
232
233static inline struct irq_desc *
234irq_remap_to_desc(unsigned int irq, struct irq_desc *desc)
235{
236#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
237 return irq_to_desc(irq);
238#else
239 return desc;
240#endif
190} 241}
191 242
192/* 243/*
@@ -380,6 +431,11 @@ extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
380#define get_irq_data(irq) (irq_to_desc(irq)->handler_data) 431#define get_irq_data(irq) (irq_to_desc(irq)->handler_data)
381#define get_irq_msi(irq) (irq_to_desc(irq)->msi_desc) 432#define get_irq_msi(irq) (irq_to_desc(irq)->msi_desc)
382 433
434#define get_irq_desc_chip(desc) ((desc)->chip)
435#define get_irq_desc_chip_data(desc) ((desc)->chip_data)
436#define get_irq_desc_data(desc) ((desc)->handler_data)
437#define get_irq_desc_msi(desc) ((desc)->msi_desc)
438
383#endif /* CONFIG_GENERIC_HARDIRQS */ 439#endif /* CONFIG_GENERIC_HARDIRQS */
384 440
385#endif /* !CONFIG_S390 */ 441#endif /* !CONFIG_S390 */