aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-21 17:11:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-21 17:11:46 -0400
commit4a60cfa9457749f7987fd4f3c956dbba5a281129 (patch)
tree85f3633276282cde0a3ac558d988704eaa3e68af /include
parent62bea97f54d806218a992b18d1f425cfb5060175 (diff)
parent27afdf2008da0b8878a73e32e4eb12381b84e224 (diff)
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (96 commits) apic, x86: Use BIOS settings for IBS and MCE threshold interrupt LVT offsets apic, x86: Check if EILVT APIC registers are available (AMD only) x86: ioapic: Call free_irte only if interrupt remapping enabled arm: Use ARCH_IRQ_INIT_FLAGS genirq, ARM: Fix boot on ARM platforms genirq: Fix CONFIG_GENIRQ_NO_DEPRECATED=y build x86: Switch sparse_irq allocations to GFP_KERNEL genirq: Switch sparse_irq allocator to GFP_KERNEL genirq: Make sparse_lock a mutex x86: lguest: Use new irq allocator genirq: Remove the now unused sparse irq leftovers genirq: Sanitize dynamic irq handling genirq: Remove arch_init_chip_data() x86: xen: Sanitise sparse_irq handling x86: Use sane enumeration x86: uv: Clean up the direct access to irq_desc x86: Make io_apic.c local functions static genirq: Remove irq_2_iommu x86: Speed up the irq_remapped check in hot pathes intr_remap: Simplify the code further ... Fix up trivial conflicts in arch/x86/Kconfig
Diffstat (limited to 'include')
-rw-r--r--include/linux/dmar.h10
-rw-r--r--include/linux/htirq.h5
-rw-r--r--include/linux/interrupt.h3
-rw-r--r--include/linux/irq.h447
-rw-r--r--include/linux/irqdesc.h159
-rw-r--r--include/linux/irqnr.h5
-rw-r--r--include/linux/lockdep.h8
-rw-r--r--include/linux/msi.h13
8 files changed, 349 insertions, 301 deletions
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index d7cecc90ed34..51651b76d40f 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -106,6 +106,7 @@ struct irte {
106 __u64 high; 106 __u64 high;
107 }; 107 };
108}; 108};
109
109#ifdef CONFIG_INTR_REMAP 110#ifdef CONFIG_INTR_REMAP
110extern int intr_remapping_enabled; 111extern int intr_remapping_enabled;
111extern int intr_remapping_supported(void); 112extern int intr_remapping_supported(void);
@@ -119,11 +120,8 @@ extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count);
119extern int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, 120extern int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index,
120 u16 sub_handle); 121 u16 sub_handle);
121extern int map_irq_to_irte_handle(int irq, u16 *sub_handle); 122extern int map_irq_to_irte_handle(int irq, u16 *sub_handle);
122extern int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index);
123extern int flush_irte(int irq);
124extern int free_irte(int irq); 123extern int free_irte(int irq);
125 124
126extern int irq_remapped(int irq);
127extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev); 125extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev);
128extern struct intel_iommu *map_ioapic_to_ir(int apic); 126extern struct intel_iommu *map_ioapic_to_ir(int apic);
129extern struct intel_iommu *map_hpet_to_ir(u8 id); 127extern struct intel_iommu *map_hpet_to_ir(u8 id);
@@ -177,7 +175,6 @@ static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev)
177 return 0; 175 return 0;
178} 176}
179 177
180#define irq_remapped(irq) (0)
181#define enable_intr_remapping(mode) (-1) 178#define enable_intr_remapping(mode) (-1)
182#define disable_intr_remapping() (0) 179#define disable_intr_remapping() (0)
183#define reenable_intr_remapping(mode) (0) 180#define reenable_intr_remapping(mode) (0)
@@ -187,8 +184,9 @@ static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev)
187/* Can't use the common MSI interrupt functions 184/* Can't use the common MSI interrupt functions
188 * since DMAR is not a pci device 185 * since DMAR is not a pci device
189 */ 186 */
190extern void dmar_msi_unmask(unsigned int irq); 187struct irq_data;
191extern void dmar_msi_mask(unsigned int irq); 188extern void dmar_msi_unmask(struct irq_data *data);
189extern void dmar_msi_mask(struct irq_data *data);
192extern void dmar_msi_read(int irq, struct msi_msg *msg); 190extern void dmar_msi_read(int irq, struct msi_msg *msg);
193extern void dmar_msi_write(int irq, struct msi_msg *msg); 191extern void dmar_msi_write(int irq, struct msi_msg *msg);
194extern int dmar_set_interrupt(struct intel_iommu *iommu); 192extern int dmar_set_interrupt(struct intel_iommu *iommu);
diff --git a/include/linux/htirq.h b/include/linux/htirq.h
index c96ea46737d0..70a1dbbf2093 100644
--- a/include/linux/htirq.h
+++ b/include/linux/htirq.h
@@ -9,8 +9,9 @@ struct ht_irq_msg {
9/* Helper functions.. */ 9/* Helper functions.. */
10void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg); 10void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
11void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg); 11void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
12void mask_ht_irq(unsigned int irq); 12struct irq_data;
13void unmask_ht_irq(unsigned int irq); 13void mask_ht_irq(struct irq_data *data);
14void unmask_ht_irq(struct irq_data *data);
14 15
15/* The arch hook for getting things started */ 16/* The arch hook for getting things started */
16int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev); 17int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev);
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 531495db1708..414328577ced 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -647,11 +647,8 @@ static inline void init_irq_proc(void)
647struct seq_file; 647struct seq_file;
648int show_interrupts(struct seq_file *p, void *v); 648int show_interrupts(struct seq_file *p, void *v);
649 649
650struct irq_desc;
651
652extern int early_irq_init(void); 650extern int early_irq_init(void);
653extern int arch_probe_nr_irqs(void); 651extern int arch_probe_nr_irqs(void);
654extern int arch_early_irq_init(void); 652extern int arch_early_irq_init(void);
655extern int arch_init_chip_data(struct irq_desc *desc, int node);
656 653
657#endif 654#endif
diff --git a/include/linux/irq.h b/include/linux/irq.h
index c03243ad84b4..e9639115dff1 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -72,6 +72,10 @@ typedef void (*irq_flow_handler_t)(unsigned int irq,
72#define IRQ_ONESHOT 0x08000000 /* IRQ is not unmasked after hardirq */ 72#define IRQ_ONESHOT 0x08000000 /* IRQ is not unmasked after hardirq */
73#define IRQ_NESTED_THREAD 0x10000000 /* IRQ is nested into another, no own handler thread */ 73#define IRQ_NESTED_THREAD 0x10000000 /* IRQ is nested into another, no own handler thread */
74 74
75#define IRQF_MODIFY_MASK \
76 (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
77 IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL)
78
75#ifdef CONFIG_IRQ_PER_CPU 79#ifdef CONFIG_IRQ_PER_CPU
76# define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) 80# define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
77# define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) 81# define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING)
@@ -80,36 +84,77 @@ typedef void (*irq_flow_handler_t)(unsigned int irq,
80# define IRQ_NO_BALANCING_MASK IRQ_NO_BALANCING 84# define IRQ_NO_BALANCING_MASK IRQ_NO_BALANCING
81#endif 85#endif
82 86
83struct proc_dir_entry;
84struct msi_desc; 87struct msi_desc;
85 88
86/** 89/**
90 * struct irq_data - per irq and irq chip data passed down to chip functions
91 * @irq: interrupt number
92 * @node: node index useful for balancing
93 * @chip: low level interrupt hardware access
94 * @handler_data: per-IRQ data for the irq_chip methods
95 * @chip_data: platform-specific per-chip private data for the chip
96 * methods, to allow shared chip implementations
97 * @msi_desc: MSI descriptor
98 * @affinity: IRQ affinity on SMP
99 *
100 * The fields here need to overlay the ones in irq_desc until we
101 * cleaned up the direct references and switched everything over to
102 * irq_data.
103 */
104struct irq_data {
105 unsigned int irq;
106 unsigned int node;
107 struct irq_chip *chip;
108 void *handler_data;
109 void *chip_data;
110 struct msi_desc *msi_desc;
111#ifdef CONFIG_SMP
112 cpumask_var_t affinity;
113#endif
114};
115
116/**
87 * struct irq_chip - hardware interrupt chip descriptor 117 * struct irq_chip - hardware interrupt chip descriptor
88 * 118 *
89 * @name: name for /proc/interrupts 119 * @name: name for /proc/interrupts
90 * @startup: start up the interrupt (defaults to ->enable if NULL) 120 * @startup: deprecated, replaced by irq_startup
91 * @shutdown: shut down the interrupt (defaults to ->disable if NULL) 121 * @shutdown: deprecated, replaced by irq_shutdown
92 * @enable: enable the interrupt (defaults to chip->unmask if NULL) 122 * @enable: deprecated, replaced by irq_enable
93 * @disable: disable the interrupt 123 * @disable: deprecated, replaced by irq_disable
94 * @ack: start of a new interrupt 124 * @ack: deprecated, replaced by irq_ack
95 * @mask: mask an interrupt source 125 * @mask: deprecated, replaced by irq_mask
96 * @mask_ack: ack and mask an interrupt source 126 * @mask_ack: deprecated, replaced by irq_mask_ack
97 * @unmask: unmask an interrupt source 127 * @unmask: deprecated, replaced by irq_unmask
98 * @eoi: end of interrupt - chip level 128 * @eoi: deprecated, replaced by irq_eoi
99 * @end: end of interrupt - flow level 129 * @end: deprecated, will go away with __do_IRQ()
100 * @set_affinity: set the CPU affinity on SMP machines 130 * @set_affinity: deprecated, replaced by irq_set_affinity
101 * @retrigger: resend an IRQ to the CPU 131 * @retrigger: deprecated, replaced by irq_retrigger
102 * @set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ 132 * @set_type: deprecated, replaced by irq_set_type
103 * @set_wake: enable/disable power-management wake-on of an IRQ 133 * @set_wake: deprecated, replaced by irq_wake
134 * @bus_lock: deprecated, replaced by irq_bus_lock
135 * @bus_sync_unlock: deprecated, replaced by irq_bus_sync_unlock
104 * 136 *
105 * @bus_lock: function to lock access to slow bus (i2c) chips 137 * @irq_startup: start up the interrupt (defaults to ->enable if NULL)
106 * @bus_sync_unlock: function to sync and unlock slow bus (i2c) chips 138 * @irq_shutdown: shut down the interrupt (defaults to ->disable if NULL)
139 * @irq_enable: enable the interrupt (defaults to chip->unmask if NULL)
140 * @irq_disable: disable the interrupt
141 * @irq_ack: start of a new interrupt
142 * @irq_mask: mask an interrupt source
143 * @irq_mask_ack: ack and mask an interrupt source
144 * @irq_unmask: unmask an interrupt source
145 * @irq_eoi: end of interrupt
146 * @irq_set_affinity: set the CPU affinity on SMP machines
147 * @irq_retrigger: resend an IRQ to the CPU
148 * @irq_set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ
149 * @irq_set_wake: enable/disable power-management wake-on of an IRQ
150 * @irq_bus_lock: function to lock access to slow bus (i2c) chips
151 * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips
107 * 152 *
108 * @release: release function solely used by UML 153 * @release: release function solely used by UML
109 * @typename: obsoleted by name, kept as migration helper
110 */ 154 */
111struct irq_chip { 155struct irq_chip {
112 const char *name; 156 const char *name;
157#ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED
113 unsigned int (*startup)(unsigned int irq); 158 unsigned int (*startup)(unsigned int irq);
114 void (*shutdown)(unsigned int irq); 159 void (*shutdown)(unsigned int irq);
115 void (*enable)(unsigned int irq); 160 void (*enable)(unsigned int irq);
@@ -130,154 +175,66 @@ struct irq_chip {
130 175
131 void (*bus_lock)(unsigned int irq); 176 void (*bus_lock)(unsigned int irq);
132 void (*bus_sync_unlock)(unsigned int irq); 177 void (*bus_sync_unlock)(unsigned int irq);
178#endif
179 unsigned int (*irq_startup)(struct irq_data *data);
180 void (*irq_shutdown)(struct irq_data *data);
181 void (*irq_enable)(struct irq_data *data);
182 void (*irq_disable)(struct irq_data *data);
183
184 void (*irq_ack)(struct irq_data *data);
185 void (*irq_mask)(struct irq_data *data);
186 void (*irq_mask_ack)(struct irq_data *data);
187 void (*irq_unmask)(struct irq_data *data);
188 void (*irq_eoi)(struct irq_data *data);
189
190 int (*irq_set_affinity)(struct irq_data *data, const struct cpumask *dest, bool force);
191 int (*irq_retrigger)(struct irq_data *data);
192 int (*irq_set_type)(struct irq_data *data, unsigned int flow_type);
193 int (*irq_set_wake)(struct irq_data *data, unsigned int on);
194
195 void (*irq_bus_lock)(struct irq_data *data);
196 void (*irq_bus_sync_unlock)(struct irq_data *data);
133 197
134 /* Currently used only by UML, might disappear one day.*/ 198 /* Currently used only by UML, might disappear one day.*/
135#ifdef CONFIG_IRQ_RELEASE_METHOD 199#ifdef CONFIG_IRQ_RELEASE_METHOD
136 void (*release)(unsigned int irq, void *dev_id); 200 void (*release)(unsigned int irq, void *dev_id);
137#endif 201#endif
138 /*
139 * For compatibility, ->typename is copied into ->name.
140 * Will disappear.
141 */
142 const char *typename;
143}; 202};
144 203
145struct timer_rand_state; 204/* This include will go away once we isolated irq_desc usage to core code */
146struct irq_2_iommu; 205#include <linux/irqdesc.h>
147/**
148 * struct irq_desc - interrupt descriptor
149 * @irq: interrupt number for this descriptor
150 * @timer_rand_state: pointer to timer rand state struct
151 * @kstat_irqs: irq stats per cpu
152 * @irq_2_iommu: iommu with this irq
153 * @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()]
154 * @chip: low level interrupt hardware access
155 * @msi_desc: MSI descriptor
156 * @handler_data: per-IRQ data for the irq_chip methods
157 * @chip_data: platform-specific per-chip private data for the chip
158 * methods, to allow shared chip implementations
159 * @action: the irq action chain
160 * @status: status information
161 * @depth: disable-depth, for nested irq_disable() calls
162 * @wake_depth: enable depth, for multiple set_irq_wake() callers
163 * @irq_count: stats field to detect stalled irqs
164 * @last_unhandled: aging timer for unhandled count
165 * @irqs_unhandled: stats field for spurious unhandled interrupts
166 * @lock: locking for SMP
167 * @affinity: IRQ affinity on SMP
168 * @node: node index useful for balancing
169 * @pending_mask: pending rebalanced interrupts
170 * @threads_active: number of irqaction threads currently running
171 * @wait_for_threads: wait queue for sync_irq to wait for threaded handlers
172 * @dir: /proc/irq/ procfs entry
173 * @name: flow handler name for /proc/interrupts output
174 */
175struct irq_desc {
176 unsigned int irq;
177 struct timer_rand_state *timer_rand_state;
178 unsigned int *kstat_irqs;
179#ifdef CONFIG_INTR_REMAP
180 struct irq_2_iommu *irq_2_iommu;
181#endif
182 irq_flow_handler_t handle_irq;
183 struct irq_chip *chip;
184 struct msi_desc *msi_desc;
185 void *handler_data;
186 void *chip_data;
187 struct irqaction *action; /* IRQ action list */
188 unsigned int status; /* IRQ status */
189
190 unsigned int depth; /* nested irq disables */
191 unsigned int wake_depth; /* nested wake enables */
192 unsigned int irq_count; /* For detecting broken IRQs */
193 unsigned long last_unhandled; /* Aging timer for unhandled count */
194 unsigned int irqs_unhandled;
195 raw_spinlock_t lock;
196#ifdef CONFIG_SMP
197 cpumask_var_t affinity;
198 const struct cpumask *affinity_hint;
199 unsigned int node;
200#ifdef CONFIG_GENERIC_PENDING_IRQ
201 cpumask_var_t pending_mask;
202#endif
203#endif
204 atomic_t threads_active;
205 wait_queue_head_t wait_for_threads;
206#ifdef CONFIG_PROC_FS
207 struct proc_dir_entry *dir;
208#endif
209 const char *name;
210} ____cacheline_internodealigned_in_smp;
211 206
212extern void arch_init_copy_chip_data(struct irq_desc *old_desc, 207/*
213 struct irq_desc *desc, int node); 208 * Pick up the arch-dependent methods:
214extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc); 209 */
210#include <asm/hw_irq.h>
215 211
216#ifndef CONFIG_SPARSE_IRQ 212#ifndef NR_IRQS_LEGACY
217extern struct irq_desc irq_desc[NR_IRQS]; 213# define NR_IRQS_LEGACY 0
218#endif 214#endif
219 215
220#ifdef CONFIG_NUMA_IRQ_DESC 216#ifndef ARCH_IRQ_INIT_FLAGS
221extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int node); 217# define ARCH_IRQ_INIT_FLAGS 0
222#else
223static inline struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
224{
225 return desc;
226}
227#endif 218#endif
228 219
229extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node); 220#define IRQ_DEFAULT_INIT_FLAGS (IRQ_DISABLED | ARCH_IRQ_INIT_FLAGS)
230
231/*
232 * Pick up the arch-dependent methods:
233 */
234#include <asm/hw_irq.h>
235 221
222struct irqaction;
236extern int setup_irq(unsigned int irq, struct irqaction *new); 223extern int setup_irq(unsigned int irq, struct irqaction *new);
237extern void remove_irq(unsigned int irq, struct irqaction *act); 224extern void remove_irq(unsigned int irq, struct irqaction *act);
238 225
239#ifdef CONFIG_GENERIC_HARDIRQS 226#ifdef CONFIG_GENERIC_HARDIRQS
240 227
241#ifdef CONFIG_SMP 228#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
242
243#ifdef CONFIG_GENERIC_PENDING_IRQ
244
245void move_native_irq(int irq); 229void move_native_irq(int irq);
246void move_masked_irq(int irq); 230void move_masked_irq(int irq);
247 231#else
248#else /* CONFIG_GENERIC_PENDING_IRQ */ 232static inline void move_native_irq(int irq) { }
249 233static inline void move_masked_irq(int irq) { }
250static inline void move_irq(int irq) 234#endif
251{
252}
253
254static inline void move_native_irq(int irq)
255{
256}
257
258static inline void move_masked_irq(int irq)
259{
260}
261
262#endif /* CONFIG_GENERIC_PENDING_IRQ */
263
264#else /* CONFIG_SMP */
265
266#define move_native_irq(x)
267#define move_masked_irq(x)
268
269#endif /* CONFIG_SMP */
270 235
271extern int no_irq_affinity; 236extern int no_irq_affinity;
272 237
273static inline int irq_balancing_disabled(unsigned int irq)
274{
275 struct irq_desc *desc;
276
277 desc = irq_to_desc(irq);
278 return desc->status & IRQ_NO_BALANCING_MASK;
279}
280
281/* Handle irq action chains: */ 238/* Handle irq action chains: */
282extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action); 239extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action);
283 240
@@ -293,42 +250,10 @@ extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc);
293extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); 250extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc);
294extern void handle_nested_irq(unsigned int irq); 251extern void handle_nested_irq(unsigned int irq);
295 252
296/*
297 * Monolithic do_IRQ implementation.
298 */
299#ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
300extern unsigned int __do_IRQ(unsigned int irq);
301#endif
302
303/*
304 * Architectures call this to let the generic IRQ layer
305 * handle an interrupt. If the descriptor is attached to an
306 * irqchip-style controller then we call the ->handle_irq() handler,
307 * and it calls __do_IRQ() if it's attached to an irqtype-style controller.
308 */
309static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc)
310{
311#ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
312 desc->handle_irq(irq, desc);
313#else
314 if (likely(desc->handle_irq))
315 desc->handle_irq(irq, desc);
316 else
317 __do_IRQ(irq);
318#endif
319}
320
321static inline void generic_handle_irq(unsigned int irq)
322{
323 generic_handle_irq_desc(irq, irq_to_desc(irq));
324}
325
326/* Handling of unhandled and spurious interrupts: */ 253/* Handling of unhandled and spurious interrupts: */
327extern void note_interrupt(unsigned int irq, struct irq_desc *desc, 254extern void note_interrupt(unsigned int irq, struct irq_desc *desc,
328 irqreturn_t action_ret); 255 irqreturn_t action_ret);
329 256
330/* Resending of interrupts :*/
331void check_irq_resend(struct irq_desc *desc, unsigned int irq);
332 257
333/* Enable/disable irq debugging output: */ 258/* Enable/disable irq debugging output: */
334extern int noirqdebug_setup(char *str); 259extern int noirqdebug_setup(char *str);
@@ -351,16 +276,6 @@ extern void
351__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, 276__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
352 const char *name); 277 const char *name);
353 278
354/* caller has locked the irq_desc and both params are valid */
355static inline void __set_irq_handler_unlocked(int irq,
356 irq_flow_handler_t handler)
357{
358 struct irq_desc *desc;
359
360 desc = irq_to_desc(irq);
361 desc->handle_irq = handler;
362}
363
364/* 279/*
365 * Set a highlevel flow handler for a given IRQ: 280 * Set a highlevel flow handler for a given IRQ:
366 */ 281 */
@@ -384,141 +299,121 @@ set_irq_chained_handler(unsigned int irq,
384 299
385extern void set_irq_nested_thread(unsigned int irq, int nest); 300extern void set_irq_nested_thread(unsigned int irq, int nest);
386 301
387extern void set_irq_noprobe(unsigned int irq); 302void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set);
388extern void set_irq_probe(unsigned int irq); 303
304static inline void irq_set_status_flags(unsigned int irq, unsigned long set)
305{
306 irq_modify_status(irq, 0, set);
307}
308
309static inline void irq_clear_status_flags(unsigned int irq, unsigned long clr)
310{
311 irq_modify_status(irq, clr, 0);
312}
313
314static inline void set_irq_noprobe(unsigned int irq)
315{
316 irq_modify_status(irq, 0, IRQ_NOPROBE);
317}
318
319static inline void set_irq_probe(unsigned int irq)
320{
321 irq_modify_status(irq, IRQ_NOPROBE, 0);
322}
389 323
390/* Handle dynamic irq creation and destruction */ 324/* Handle dynamic irq creation and destruction */
391extern unsigned int create_irq_nr(unsigned int irq_want, int node); 325extern unsigned int create_irq_nr(unsigned int irq_want, int node);
392extern int create_irq(void); 326extern int create_irq(void);
393extern void destroy_irq(unsigned int irq); 327extern void destroy_irq(unsigned int irq);
394 328
395/* Test to see if a driver has successfully requested an irq */ 329/*
396static inline int irq_has_action(unsigned int irq) 330 * Dynamic irq helper functions. Obsolete. Use irq_alloc_desc* and
331 * irq_free_desc instead.
332 */
333extern void dynamic_irq_cleanup(unsigned int irq);
334static inline void dynamic_irq_init(unsigned int irq)
397{ 335{
398 struct irq_desc *desc = irq_to_desc(irq); 336 dynamic_irq_cleanup(irq);
399 return desc->action != NULL;
400} 337}
401 338
402/* Dynamic irq helper functions */
403extern void dynamic_irq_init(unsigned int irq);
404void dynamic_irq_init_keep_chip_data(unsigned int irq);
405extern void dynamic_irq_cleanup(unsigned int irq);
406void dynamic_irq_cleanup_keep_chip_data(unsigned int irq);
407
408/* Set/get chip/data for an IRQ: */ 339/* Set/get chip/data for an IRQ: */
409extern int set_irq_chip(unsigned int irq, struct irq_chip *chip); 340extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
410extern int set_irq_data(unsigned int irq, void *data); 341extern int set_irq_data(unsigned int irq, void *data);
411extern int set_irq_chip_data(unsigned int irq, void *data); 342extern int set_irq_chip_data(unsigned int irq, void *data);
412extern int set_irq_type(unsigned int irq, unsigned int type); 343extern int set_irq_type(unsigned int irq, unsigned int type);
413extern int set_irq_msi(unsigned int irq, struct msi_desc *entry); 344extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
345extern struct irq_data *irq_get_irq_data(unsigned int irq);
414 346
415#define get_irq_chip(irq) (irq_to_desc(irq)->chip) 347static inline struct irq_chip *get_irq_chip(unsigned int irq)
416#define get_irq_chip_data(irq) (irq_to_desc(irq)->chip_data)
417#define get_irq_data(irq) (irq_to_desc(irq)->handler_data)
418#define get_irq_msi(irq) (irq_to_desc(irq)->msi_desc)
419
420#define get_irq_desc_chip(desc) ((desc)->chip)
421#define get_irq_desc_chip_data(desc) ((desc)->chip_data)
422#define get_irq_desc_data(desc) ((desc)->handler_data)
423#define get_irq_desc_msi(desc) ((desc)->msi_desc)
424
425#endif /* CONFIG_GENERIC_HARDIRQS */
426
427#endif /* !CONFIG_S390 */
428
429#ifdef CONFIG_SMP
430/**
431 * alloc_desc_masks - allocate cpumasks for irq_desc
432 * @desc: pointer to irq_desc struct
433 * @node: node which will be handling the cpumasks
434 * @boot: true if need bootmem
435 *
436 * Allocates affinity and pending_mask cpumask if required.
437 * Returns true if successful (or not required).
438 */
439static inline bool alloc_desc_masks(struct irq_desc *desc, int node,
440 bool boot)
441{ 348{
442 gfp_t gfp = GFP_ATOMIC; 349 struct irq_data *d = irq_get_irq_data(irq);
443 350 return d ? d->chip : NULL;
444 if (boot) 351}
445 gfp = GFP_NOWAIT;
446
447#ifdef CONFIG_CPUMASK_OFFSTACK
448 if (!alloc_cpumask_var_node(&desc->affinity, gfp, node))
449 return false;
450 352
451#ifdef CONFIG_GENERIC_PENDING_IRQ 353static inline struct irq_chip *irq_data_get_irq_chip(struct irq_data *d)
452 if (!alloc_cpumask_var_node(&desc->pending_mask, gfp, node)) { 354{
453 free_cpumask_var(desc->affinity); 355 return d->chip;
454 return false;
455 }
456#endif
457#endif
458 return true;
459} 356}
460 357
461static inline void init_desc_masks(struct irq_desc *desc) 358static inline void *get_irq_chip_data(unsigned int irq)
462{ 359{
463 cpumask_setall(desc->affinity); 360 struct irq_data *d = irq_get_irq_data(irq);
464#ifdef CONFIG_GENERIC_PENDING_IRQ 361 return d ? d->chip_data : NULL;
465 cpumask_clear(desc->pending_mask);
466#endif
467} 362}
468 363
469/** 364static inline void *irq_data_get_irq_chip_data(struct irq_data *d)
470 * init_copy_desc_masks - copy cpumasks for irq_desc 365{
471 * @old_desc: pointer to old irq_desc struct 366 return d->chip_data;
472 * @new_desc: pointer to new irq_desc struct 367}
473 *
474 * Insures affinity and pending_masks are copied to new irq_desc.
475 * If !CONFIG_CPUMASKS_OFFSTACK the cpumasks are embedded in the
476 * irq_desc struct so the copy is redundant.
477 */
478 368
479static inline void init_copy_desc_masks(struct irq_desc *old_desc, 369static inline void *get_irq_data(unsigned int irq)
480 struct irq_desc *new_desc)
481{ 370{
482#ifdef CONFIG_CPUMASK_OFFSTACK 371 struct irq_data *d = irq_get_irq_data(irq);
483 cpumask_copy(new_desc->affinity, old_desc->affinity); 372 return d ? d->handler_data : NULL;
373}
484 374
485#ifdef CONFIG_GENERIC_PENDING_IRQ 375static inline void *irq_data_get_irq_data(struct irq_data *d)
486 cpumask_copy(new_desc->pending_mask, old_desc->pending_mask); 376{
487#endif 377 return d->handler_data;
488#endif
489} 378}
490 379
491static inline void free_desc_masks(struct irq_desc *old_desc, 380static inline struct msi_desc *get_irq_msi(unsigned int irq)
492 struct irq_desc *new_desc)
493{ 381{
494 free_cpumask_var(old_desc->affinity); 382 struct irq_data *d = irq_get_irq_data(irq);
383 return d ? d->msi_desc : NULL;
384}
495 385
496#ifdef CONFIG_GENERIC_PENDING_IRQ 386static inline struct msi_desc *irq_data_get_msi(struct irq_data *d)
497 free_cpumask_var(old_desc->pending_mask); 387{
498#endif 388 return d->msi_desc;
499} 389}
500 390
501#else /* !CONFIG_SMP */ 391int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node);
392void irq_free_descs(unsigned int irq, unsigned int cnt);
393int irq_reserve_irqs(unsigned int from, unsigned int cnt);
502 394
503static inline bool alloc_desc_masks(struct irq_desc *desc, int node, 395static inline int irq_alloc_desc(int node)
504 bool boot)
505{ 396{
506 return true; 397 return irq_alloc_descs(-1, 0, 1, node);
507} 398}
508 399
509static inline void init_desc_masks(struct irq_desc *desc) 400static inline int irq_alloc_desc_at(unsigned int at, int node)
510{ 401{
402 return irq_alloc_descs(at, at, 1, node);
511} 403}
512 404
513static inline void init_copy_desc_masks(struct irq_desc *old_desc, 405static inline int irq_alloc_desc_from(unsigned int from, int node)
514 struct irq_desc *new_desc)
515{ 406{
407 return irq_alloc_descs(-1, from, 1, node);
516} 408}
517 409
518static inline void free_desc_masks(struct irq_desc *old_desc, 410static inline void irq_free_desc(unsigned int irq)
519 struct irq_desc *new_desc)
520{ 411{
412 irq_free_descs(irq, 1);
521} 413}
522#endif /* CONFIG_SMP */ 414
415#endif /* CONFIG_GENERIC_HARDIRQS */
416
417#endif /* !CONFIG_S390 */
523 418
524#endif /* _LINUX_IRQ_H */ 419#endif /* _LINUX_IRQ_H */
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
new file mode 100644
index 000000000000..979c68cc7458
--- /dev/null
+++ b/include/linux/irqdesc.h
@@ -0,0 +1,159 @@
1#ifndef _LINUX_IRQDESC_H
2#define _LINUX_IRQDESC_H
3
4/*
5 * Core internal functions to deal with irq descriptors
6 *
7 * This include will move to kernel/irq once we cleaned up the tree.
8 * For now it's included from <linux/irq.h>
9 */
10
11struct proc_dir_entry;
12struct timer_rand_state;
13/**
14 * struct irq_desc - interrupt descriptor
15 * @irq_data: per irq and chip data passed down to chip functions
16 * @timer_rand_state: pointer to timer rand state struct
17 * @kstat_irqs: irq stats per cpu
18 * @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()]
19 * @action: the irq action chain
20 * @status: status information
21 * @depth: disable-depth, for nested irq_disable() calls
22 * @wake_depth: enable depth, for multiple set_irq_wake() callers
23 * @irq_count: stats field to detect stalled irqs
24 * @last_unhandled: aging timer for unhandled count
25 * @irqs_unhandled: stats field for spurious unhandled interrupts
26 * @lock: locking for SMP
27 * @pending_mask: pending rebalanced interrupts
28 * @threads_active: number of irqaction threads currently running
29 * @wait_for_threads: wait queue for sync_irq to wait for threaded handlers
30 * @dir: /proc/irq/ procfs entry
31 * @name: flow handler name for /proc/interrupts output
32 */
33struct irq_desc {
34
35#ifdef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED
36 struct irq_data irq_data;
37#else
38 /*
39 * This union will go away, once we fixed the direct access to
40 * irq_desc all over the place. The direct fields are a 1:1
41 * overlay of irq_data.
42 */
43 union {
44 struct irq_data irq_data;
45 struct {
46 unsigned int irq;
47 unsigned int node;
48 struct irq_chip *chip;
49 void *handler_data;
50 void *chip_data;
51 struct msi_desc *msi_desc;
52#ifdef CONFIG_SMP
53 cpumask_var_t affinity;
54#endif
55 };
56 };
57#endif
58
59 struct timer_rand_state *timer_rand_state;
60 unsigned int *kstat_irqs;
61 irq_flow_handler_t handle_irq;
62 struct irqaction *action; /* IRQ action list */
63 unsigned int status; /* IRQ status */
64
65 unsigned int depth; /* nested irq disables */
66 unsigned int wake_depth; /* nested wake enables */
67 unsigned int irq_count; /* For detecting broken IRQs */
68 unsigned long last_unhandled; /* Aging timer for unhandled count */
69 unsigned int irqs_unhandled;
70 raw_spinlock_t lock;
71#ifdef CONFIG_SMP
72 const struct cpumask *affinity_hint;
73#ifdef CONFIG_GENERIC_PENDING_IRQ
74 cpumask_var_t pending_mask;
75#endif
76#endif
77 atomic_t threads_active;
78 wait_queue_head_t wait_for_threads;
79#ifdef CONFIG_PROC_FS
80 struct proc_dir_entry *dir;
81#endif
82 const char *name;
83} ____cacheline_internodealigned_in_smp;
84
85#ifndef CONFIG_SPARSE_IRQ
86extern struct irq_desc irq_desc[NR_IRQS];
87#endif
88
89/* Will be removed once the last users in power and sh are gone */
90extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
91static inline struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
92{
93 return desc;
94}
95
96#ifdef CONFIG_GENERIC_HARDIRQS
97
98#define get_irq_desc_chip(desc) ((desc)->irq_data.chip)
99#define get_irq_desc_chip_data(desc) ((desc)->irq_data.chip_data)
100#define get_irq_desc_data(desc) ((desc)->irq_data.handler_data)
101#define get_irq_desc_msi(desc) ((desc)->irq_data.msi_desc)
102
103/*
104 * Monolithic do_IRQ implementation.
105 */
106#ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
107extern unsigned int __do_IRQ(unsigned int irq);
108#endif
109
110/*
111 * Architectures call this to let the generic IRQ layer
112 * handle an interrupt. If the descriptor is attached to an
113 * irqchip-style controller then we call the ->handle_irq() handler,
114 * and it calls __do_IRQ() if it's attached to an irqtype-style controller.
115 */
116static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc)
117{
118#ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
119 desc->handle_irq(irq, desc);
120#else
121 if (likely(desc->handle_irq))
122 desc->handle_irq(irq, desc);
123 else
124 __do_IRQ(irq);
125#endif
126}
127
128static inline void generic_handle_irq(unsigned int irq)
129{
130 generic_handle_irq_desc(irq, irq_to_desc(irq));
131}
132
133/* Test to see if a driver has successfully requested an irq */
134static inline int irq_has_action(unsigned int irq)
135{
136 struct irq_desc *desc = irq_to_desc(irq);
137 return desc->action != NULL;
138}
139
140static inline int irq_balancing_disabled(unsigned int irq)
141{
142 struct irq_desc *desc;
143
144 desc = irq_to_desc(irq);
145 return desc->status & IRQ_NO_BALANCING_MASK;
146}
147
148/* caller has locked the irq_desc and both params are valid */
149static inline void __set_irq_handler_unlocked(int irq,
150 irq_flow_handler_t handler)
151{
152 struct irq_desc *desc;
153
154 desc = irq_to_desc(irq);
155 desc->handle_irq = handler;
156}
157#endif
158
159#endif
diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h
index 7bf89bc8cbca..05aa8c23483f 100644
--- a/include/linux/irqnr.h
+++ b/include/linux/irqnr.h
@@ -25,6 +25,7 @@
25 25
26extern int nr_irqs; 26extern int nr_irqs;
27extern struct irq_desc *irq_to_desc(unsigned int irq); 27extern struct irq_desc *irq_to_desc(unsigned int irq);
28unsigned int irq_get_next_irq(unsigned int offset);
28 29
29# define for_each_irq_desc(irq, desc) \ 30# define for_each_irq_desc(irq, desc) \
30 for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs; \ 31 for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs; \
@@ -47,6 +48,10 @@ extern struct irq_desc *irq_to_desc(unsigned int irq);
47#define irq_node(irq) 0 48#define irq_node(irq) 0
48#endif 49#endif
49 50
51# define for_each_active_irq(irq) \
52 for (irq = irq_get_next_irq(0); irq < nr_irqs; \
53 irq = irq_get_next_irq(irq + 1))
54
50#endif /* CONFIG_GENERIC_HARDIRQS */ 55#endif /* CONFIG_GENERIC_HARDIRQS */
51 56
52#define for_each_irq_nr(irq) \ 57#define for_each_irq_nr(irq) \
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 2186a64ee4b5..71c09b26c759 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -435,14 +435,6 @@ do { \
435 435
436#endif /* CONFIG_LOCKDEP */ 436#endif /* CONFIG_LOCKDEP */
437 437
438#ifdef CONFIG_GENERIC_HARDIRQS
439extern void early_init_irq_lock_class(void);
440#else
441static inline void early_init_irq_lock_class(void)
442{
443}
444#endif
445
446#ifdef CONFIG_TRACE_IRQFLAGS 438#ifdef CONFIG_TRACE_IRQFLAGS
447extern void early_boot_irqs_off(void); 439extern void early_boot_irqs_off(void);
448extern void early_boot_irqs_on(void); 440extern void early_boot_irqs_on(void);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 91b05c171854..05acced439a3 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -10,12 +10,13 @@ struct msi_msg {
10}; 10};
11 11
12/* Helper functions */ 12/* Helper functions */
13struct irq_desc; 13struct irq_data;
14extern void mask_msi_irq(unsigned int irq); 14struct msi_desc;
15extern void unmask_msi_irq(unsigned int irq); 15extern void mask_msi_irq(struct irq_data *data);
16extern void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); 16extern void unmask_msi_irq(struct irq_data *data);
17extern void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); 17extern void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
18extern void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); 18extern void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
19extern void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
19extern void read_msi_msg(unsigned int irq, struct msi_msg *msg); 20extern void read_msi_msg(unsigned int irq, struct msi_msg *msg);
20extern void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); 21extern void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);
21extern void write_msi_msg(unsigned int irq, struct msi_msg *msg); 22extern void write_msi_msg(unsigned int irq, struct msi_msg *msg);