Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : /* interrupt.h */
3 : : #ifndef _LINUX_INTERRUPT_H
4 : : #define _LINUX_INTERRUPT_H
5 : :
6 : : #include <linux/kernel.h>
7 : : #include <linux/bitops.h>
8 : : #include <linux/cpumask.h>
9 : : #include <linux/irqreturn.h>
10 : : #include <linux/irqnr.h>
11 : : #include <linux/hardirq.h>
12 : : #include <linux/irqflags.h>
13 : : #include <linux/hrtimer.h>
14 : : #include <linux/kref.h>
15 : : #include <linux/workqueue.h>
16 : :
17 : : #include <linux/atomic.h>
18 : : #include <asm/ptrace.h>
19 : : #include <asm/irq.h>
20 : : #include <asm/sections.h>
21 : :
22 : : /*
23 : : * These correspond to the IORESOURCE_IRQ_* defines in
24 : : * linux/ioport.h to select the interrupt line behaviour. When
25 : : * requesting an interrupt without specifying a IRQF_TRIGGER, the
26 : : * setting should be assumed to be "as already configured", which
27 : : * may be as per machine or firmware initialisation.
28 : : */
29 : : #define IRQF_TRIGGER_NONE 0x00000000
30 : : #define IRQF_TRIGGER_RISING 0x00000001
31 : : #define IRQF_TRIGGER_FALLING 0x00000002
32 : : #define IRQF_TRIGGER_HIGH 0x00000004
33 : : #define IRQF_TRIGGER_LOW 0x00000008
34 : : #define IRQF_TRIGGER_MASK (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \
35 : : IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
36 : : #define IRQF_TRIGGER_PROBE 0x00000010
37 : :
38 : : /*
39 : : * These flags used only by the kernel as part of the
40 : : * irq handling routines.
41 : : *
42 : : * IRQF_SHARED - allow sharing the irq among several devices
43 : : * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur
44 : : * IRQF_TIMER - Flag to mark this interrupt as timer interrupt
45 : : * IRQF_PERCPU - Interrupt is per cpu
46 : : * IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing
47 : : * IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is
48 : : * registered first in a shared interrupt is considered for
49 : : * performance reasons)
50 : : * IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished.
51 : : * Used by threaded interrupts which need to keep the
52 : : * irq line disabled until the threaded handler has been run.
53 : : * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend. Does not guarantee
54 : : * that this interrupt will wake the system from a suspended
55 : : * state. See Documentation/power/suspend-and-interrupts.rst
56 : : * IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set
57 : : * IRQF_NO_THREAD - Interrupt cannot be threaded
58 : : * IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device
59 : : * resume time.
60 : : * IRQF_COND_SUSPEND - If the IRQ is shared with a NO_SUSPEND user, execute this
61 : : * interrupt handler after suspending interrupts. For system
62 : : * wakeup devices users need to implement wakeup detection in
63 : : * their interrupt handlers.
64 : : */
65 : : #define IRQF_SHARED 0x00000080
66 : : #define IRQF_PROBE_SHARED 0x00000100
67 : : #define __IRQF_TIMER 0x00000200
68 : : #define IRQF_PERCPU 0x00000400
69 : : #define IRQF_NOBALANCING 0x00000800
70 : : #define IRQF_IRQPOLL 0x00001000
71 : : #define IRQF_ONESHOT 0x00002000
72 : : #define IRQF_NO_SUSPEND 0x00004000
73 : : #define IRQF_FORCE_RESUME 0x00008000
74 : : #define IRQF_NO_THREAD 0x00010000
75 : : #define IRQF_EARLY_RESUME 0x00020000
76 : : #define IRQF_COND_SUSPEND 0x00040000
77 : :
78 : : #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
79 : :
80 : : /*
81 : : * These values can be returned by request_any_context_irq() and
82 : : * describe the context the interrupt will be run in.
83 : : *
84 : : * IRQC_IS_HARDIRQ - interrupt runs in hardirq context
85 : : * IRQC_IS_NESTED - interrupt runs in a nested threaded context
86 : : */
87 : : enum {
88 : : IRQC_IS_HARDIRQ = 0,
89 : : IRQC_IS_NESTED,
90 : : };
91 : :
92 : : typedef irqreturn_t (*irq_handler_t)(int, void *);
93 : :
94 : : /**
95 : : * struct irqaction - per interrupt action descriptor
96 : : * @handler: interrupt handler function
97 : : * @name: name of the device
98 : : * @dev_id: cookie to identify the device
99 : : * @percpu_dev_id: cookie to identify the device
100 : : * @next: pointer to the next irqaction for shared interrupts
101 : : * @irq: interrupt number
102 : : * @flags: flags (see IRQF_* above)
103 : : * @thread_fn: interrupt handler function for threaded interrupts
104 : : * @thread: thread pointer for threaded interrupts
105 : : * @secondary: pointer to secondary irqaction (force threading)
106 : : * @thread_flags: flags related to @thread
107 : : * @thread_mask: bitmask for keeping track of @thread activity
108 : : * @dir: pointer to the proc/irq/NN/name entry
109 : : */
110 : : struct irqaction {
111 : : irq_handler_t handler;
112 : : void *dev_id;
113 : : void __percpu *percpu_dev_id;
114 : : struct irqaction *next;
115 : : irq_handler_t thread_fn;
116 : : struct task_struct *thread;
117 : : struct irqaction *secondary;
118 : : unsigned int irq;
119 : : unsigned int flags;
120 : : unsigned long thread_flags;
121 : : unsigned long thread_mask;
122 : : const char *name;
123 : : struct proc_dir_entry *dir;
124 : : } ____cacheline_internodealigned_in_smp;
125 : :
126 : : extern irqreturn_t no_action(int cpl, void *dev_id);
127 : :
128 : : /*
129 : : * If a (PCI) device interrupt is not connected we set dev->irq to
130 : : * IRQ_NOTCONNECTED. This causes request_irq() to fail with -ENOTCONN, so we
131 : : * can distingiush that case from other error returns.
132 : : *
133 : : * 0x80000000 is guaranteed to be outside the available range of interrupts
134 : : * and easy to distinguish from other possible incorrect values.
135 : : */
136 : : #define IRQ_NOTCONNECTED (1U << 31)
137 : :
138 : : extern int __must_check
139 : : request_threaded_irq(unsigned int irq, irq_handler_t handler,
140 : : irq_handler_t thread_fn,
141 : : unsigned long flags, const char *name, void *dev);
142 : :
143 : : /**
144 : : * request_irq - Add a handler for an interrupt line
145 : : * @irq: The interrupt line to allocate
146 : : * @handler: Function to be called when the IRQ occurs.
147 : : * Primary handler for threaded interrupts
148 : : * If NULL, the default primary handler is installed
149 : : * @flags: Handling flags
150 : : * @name: Name of the device generating this interrupt
151 : : * @dev: A cookie passed to the handler function
152 : : *
153 : : * This call allocates an interrupt and establishes a handler; see
154 : : * the documentation for request_threaded_irq() for details.
155 : : */
156 : : static inline int __must_check
157 : 78 : request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
158 : : const char *name, void *dev)
159 : : {
160 : 78 : return request_threaded_irq(irq, handler, NULL, flags, name, dev);
161 : : }
162 : :
163 : : extern int __must_check
164 : : request_any_context_irq(unsigned int irq, irq_handler_t handler,
165 : : unsigned long flags, const char *name, void *dev_id);
166 : :
167 : : extern int __must_check
168 : : __request_percpu_irq(unsigned int irq, irq_handler_t handler,
169 : : unsigned long flags, const char *devname,
170 : : void __percpu *percpu_dev_id);
171 : :
172 : : extern int __must_check
173 : : request_nmi(unsigned int irq, irq_handler_t handler, unsigned long flags,
174 : : const char *name, void *dev);
175 : :
176 : : static inline int __must_check
177 : : request_percpu_irq(unsigned int irq, irq_handler_t handler,
178 : : const char *devname, void __percpu *percpu_dev_id)
179 : : {
180 : : return __request_percpu_irq(irq, handler, 0,
181 : : devname, percpu_dev_id);
182 : : }
183 : :
184 : : extern int __must_check
185 : : request_percpu_nmi(unsigned int irq, irq_handler_t handler,
186 : : const char *devname, void __percpu *dev);
187 : :
188 : : extern const void *free_irq(unsigned int, void *);
189 : : extern void free_percpu_irq(unsigned int, void __percpu *);
190 : :
191 : : extern const void *free_nmi(unsigned int irq, void *dev_id);
192 : : extern void free_percpu_nmi(unsigned int irq, void __percpu *percpu_dev_id);
193 : :
194 : : struct device;
195 : :
196 : : extern int __must_check
197 : : devm_request_threaded_irq(struct device *dev, unsigned int irq,
198 : : irq_handler_t handler, irq_handler_t thread_fn,
199 : : unsigned long irqflags, const char *devname,
200 : : void *dev_id);
201 : :
202 : : static inline int __must_check
203 : 26 : devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
204 : : unsigned long irqflags, const char *devname, void *dev_id)
205 : : {
206 : 26 : return devm_request_threaded_irq(dev, irq, handler, NULL, irqflags,
207 : : devname, dev_id);
208 : : }
209 : :
210 : : extern int __must_check
211 : : devm_request_any_context_irq(struct device *dev, unsigned int irq,
212 : : irq_handler_t handler, unsigned long irqflags,
213 : : const char *devname, void *dev_id);
214 : :
215 : : extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
216 : :
217 : : /*
218 : : * On lockdep we dont want to enable hardirqs in hardirq
219 : : * context. Use local_irq_enable_in_hardirq() to annotate
220 : : * kernel code that has to do this nevertheless (pretty much
221 : : * the only valid case is for old/broken hardware that is
222 : : * insanely slow).
223 : : *
224 : : * NOTE: in theory this might break fragile code that relies
225 : : * on hardirq delivery - in practice we dont seem to have such
226 : : * places left. So the only effect should be slightly increased
227 : : * irqs-off latencies.
228 : : */
229 : : #ifdef CONFIG_LOCKDEP
230 : : # define local_irq_enable_in_hardirq() do { } while (0)
231 : : #else
232 : : # define local_irq_enable_in_hardirq() local_irq_enable()
233 : : #endif
234 : :
235 : : extern void disable_irq_nosync(unsigned int irq);
236 : : extern bool disable_hardirq(unsigned int irq);
237 : : extern void disable_irq(unsigned int irq);
238 : : extern void disable_percpu_irq(unsigned int irq);
239 : : extern void enable_irq(unsigned int irq);
240 : : extern void enable_percpu_irq(unsigned int irq, unsigned int type);
241 : : extern bool irq_percpu_is_enabled(unsigned int irq);
242 : : extern void irq_wake_thread(unsigned int irq, void *dev_id);
243 : :
244 : : extern void disable_nmi_nosync(unsigned int irq);
245 : : extern void disable_percpu_nmi(unsigned int irq);
246 : : extern void enable_nmi(unsigned int irq);
247 : : extern void enable_percpu_nmi(unsigned int irq, unsigned int type);
248 : : extern int prepare_percpu_nmi(unsigned int irq);
249 : : extern void teardown_percpu_nmi(unsigned int irq);
250 : :
251 : : /* The following three functions are for the core kernel use only. */
252 : : extern void suspend_device_irqs(void);
253 : : extern void resume_device_irqs(void);
254 : : extern void rearm_wake_irq(unsigned int irq);
255 : :
256 : : /**
257 : : * struct irq_affinity_notify - context for notification of IRQ affinity changes
258 : : * @irq: Interrupt to which notification applies
259 : : * @kref: Reference count, for internal use
260 : : * @work: Work item, for internal use
261 : : * @notify: Function to be called on change. This will be
262 : : * called in process context.
263 : : * @release: Function to be called on release. This will be
264 : : * called in process context. Once registered, the
265 : : * structure must only be freed when this function is
266 : : * called or later.
267 : : */
268 : : struct irq_affinity_notify {
269 : : unsigned int irq;
270 : : struct kref kref;
271 : : struct work_struct work;
272 : : void (*notify)(struct irq_affinity_notify *, const cpumask_t *mask);
273 : : void (*release)(struct kref *ref);
274 : : };
275 : :
276 : : #define IRQ_AFFINITY_MAX_SETS 4
277 : :
278 : : /**
279 : : * struct irq_affinity - Description for automatic irq affinity assignements
280 : : * @pre_vectors: Don't apply affinity to @pre_vectors at beginning of
281 : : * the MSI(-X) vector space
282 : : * @post_vectors: Don't apply affinity to @post_vectors at end of
283 : : * the MSI(-X) vector space
284 : : * @nr_sets: The number of interrupt sets for which affinity
285 : : * spreading is required
286 : : * @set_size: Array holding the size of each interrupt set
287 : : * @calc_sets: Callback for calculating the number and size
288 : : * of interrupt sets
289 : : * @priv: Private data for usage by @calc_sets, usually a
290 : : * pointer to driver/device specific data.
291 : : */
292 : : struct irq_affinity {
293 : : unsigned int pre_vectors;
294 : : unsigned int post_vectors;
295 : : unsigned int nr_sets;
296 : : unsigned int set_size[IRQ_AFFINITY_MAX_SETS];
297 : : void (*calc_sets)(struct irq_affinity *, unsigned int nvecs);
298 : : void *priv;
299 : : };
300 : :
301 : : /**
302 : : * struct irq_affinity_desc - Interrupt affinity descriptor
303 : : * @mask: cpumask to hold the affinity assignment
304 : : * @is_managed: 1 if the interrupt is managed internally
305 : : */
306 : : struct irq_affinity_desc {
307 : : struct cpumask mask;
308 : : unsigned int is_managed : 1;
309 : : };
310 : :
311 : : #if defined(CONFIG_SMP)
312 : :
313 : : extern cpumask_var_t irq_default_affinity;
314 : :
315 : : /* Internal implementation. Use the helpers below */
316 : : extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask,
317 : : bool force);
318 : :
319 : : /**
320 : : * irq_set_affinity - Set the irq affinity of a given irq
321 : : * @irq: Interrupt to set affinity
322 : : * @cpumask: cpumask
323 : : *
324 : : * Fails if cpumask does not contain an online CPU
325 : : */
326 : : static inline int
327 : 0 : irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
328 : : {
329 : 0 : return __irq_set_affinity(irq, cpumask, false);
330 : : }
331 : :
332 : : /**
333 : : * irq_force_affinity - Force the irq affinity of a given irq
334 : : * @irq: Interrupt to set affinity
335 : : * @cpumask: cpumask
336 : : *
337 : : * Same as irq_set_affinity, but without checking the mask against
338 : : * online cpus.
339 : : *
340 : : * Solely for low level cpu hotplug code, where we need to make per
341 : : * cpu interrupts affine before the cpu becomes online.
342 : : */
343 : : static inline int
344 : : irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
345 : : {
346 : : return __irq_set_affinity(irq, cpumask, true);
347 : : }
348 : :
349 : : extern int irq_can_set_affinity(unsigned int irq);
350 : : extern int irq_select_affinity(unsigned int irq);
351 : :
352 : : extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m);
353 : :
354 : : extern int
355 : : irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify);
356 : :
357 : : struct irq_affinity_desc *
358 : : irq_create_affinity_masks(unsigned int nvec, struct irq_affinity *affd);
359 : :
360 : : unsigned int irq_calc_affinity_vectors(unsigned int minvec, unsigned int maxvec,
361 : : const struct irq_affinity *affd);
362 : :
363 : : #else /* CONFIG_SMP */
364 : :
365 : : static inline int irq_set_affinity(unsigned int irq, const struct cpumask *m)
366 : : {
367 : : return -EINVAL;
368 : : }
369 : :
370 : : static inline int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
371 : : {
372 : : return 0;
373 : : }
374 : :
375 : : static inline int irq_can_set_affinity(unsigned int irq)
376 : : {
377 : : return 0;
378 : : }
379 : :
380 : : static inline int irq_select_affinity(unsigned int irq) { return 0; }
381 : :
382 : : static inline int irq_set_affinity_hint(unsigned int irq,
383 : : const struct cpumask *m)
384 : : {
385 : : return -EINVAL;
386 : : }
387 : :
388 : : static inline int
389 : : irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify)
390 : : {
391 : : return 0;
392 : : }
393 : :
394 : : static inline struct irq_affinity_desc *
395 : : irq_create_affinity_masks(unsigned int nvec, struct irq_affinity *affd)
396 : : {
397 : : return NULL;
398 : : }
399 : :
400 : : static inline unsigned int
401 : : irq_calc_affinity_vectors(unsigned int minvec, unsigned int maxvec,
402 : : const struct irq_affinity *affd)
403 : : {
404 : : return maxvec;
405 : : }
406 : :
407 : : #endif /* CONFIG_SMP */
408 : :
409 : : /*
410 : : * Special lockdep variants of irq disabling/enabling.
411 : : * These should be used for locking constructs that
412 : : * know that a particular irq context which is disabled,
413 : : * and which is the only irq-context user of a lock,
414 : : * that it's safe to take the lock in the irq-disabled
415 : : * section without disabling hardirqs.
416 : : *
417 : : * On !CONFIG_LOCKDEP they are equivalent to the normal
418 : : * irq disable/enable methods.
419 : : */
420 : : static inline void disable_irq_nosync_lockdep(unsigned int irq)
421 : : {
422 : : disable_irq_nosync(irq);
423 : : #ifdef CONFIG_LOCKDEP
424 : : local_irq_disable();
425 : : #endif
426 : : }
427 : :
428 : 0 : static inline void disable_irq_nosync_lockdep_irqsave(unsigned int irq, unsigned long *flags)
429 : : {
430 : 0 : disable_irq_nosync(irq);
431 : : #ifdef CONFIG_LOCKDEP
432 : : local_irq_save(*flags);
433 : : #endif
434 : : }
435 : :
436 : : static inline void disable_irq_lockdep(unsigned int irq)
437 : : {
438 : : disable_irq(irq);
439 : : #ifdef CONFIG_LOCKDEP
440 : : local_irq_disable();
441 : : #endif
442 : : }
443 : :
444 : : static inline void enable_irq_lockdep(unsigned int irq)
445 : : {
446 : : #ifdef CONFIG_LOCKDEP
447 : : local_irq_enable();
448 : : #endif
449 : : enable_irq(irq);
450 : : }
451 : :
452 : 0 : static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long *flags)
453 : : {
454 : : #ifdef CONFIG_LOCKDEP
455 : : local_irq_restore(*flags);
456 : : #endif
457 : 0 : enable_irq(irq);
458 : : }
459 : :
460 : : /* IRQ wakeup (PM) control: */
461 : : extern int irq_set_irq_wake(unsigned int irq, unsigned int on);
462 : :
463 : 0 : static inline int enable_irq_wake(unsigned int irq)
464 : : {
465 : 0 : return irq_set_irq_wake(irq, 1);
466 : : }
467 : :
468 : 0 : static inline int disable_irq_wake(unsigned int irq)
469 : : {
470 : 0 : return irq_set_irq_wake(irq, 0);
471 : : }
472 : :
473 : : /*
474 : : * irq_get_irqchip_state/irq_set_irqchip_state specific flags
475 : : */
476 : : enum irqchip_irq_state {
477 : : IRQCHIP_STATE_PENDING, /* Is interrupt pending? */
478 : : IRQCHIP_STATE_ACTIVE, /* Is interrupt in progress? */
479 : : IRQCHIP_STATE_MASKED, /* Is interrupt masked? */
480 : : IRQCHIP_STATE_LINE_LEVEL, /* Is IRQ line high? */
481 : : };
482 : :
483 : : extern int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
484 : : bool *state);
485 : : extern int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
486 : : bool state);
487 : :
488 : : #ifdef CONFIG_IRQ_FORCED_THREADING
489 : : # ifdef CONFIG_PREEMPT_RT
490 : : # define force_irqthreads (true)
491 : : # else
492 : : extern bool force_irqthreads;
493 : : # endif
494 : : #else
495 : : #define force_irqthreads (0)
496 : : #endif
497 : :
498 : : #ifndef local_softirq_pending
499 : :
500 : : #ifndef local_softirq_pending_ref
501 : : #define local_softirq_pending_ref irq_stat.__softirq_pending
502 : : #endif
503 : :
504 : : #define local_softirq_pending() (__this_cpu_read(local_softirq_pending_ref))
505 : : #define set_softirq_pending(x) (__this_cpu_write(local_softirq_pending_ref, (x)))
506 : : #define or_softirq_pending(x) (__this_cpu_or(local_softirq_pending_ref, (x)))
507 : :
508 : : #endif /* local_softirq_pending */
509 : :
510 : : /* Some architectures might implement lazy enabling/disabling of
511 : : * interrupts. In some cases, such as stop_machine, we might want
512 : : * to ensure that after a local_irq_disable(), interrupts have
513 : : * really been disabled in hardware. Such architectures need to
514 : : * implement the following hook.
515 : : */
516 : : #ifndef hard_irq_disable
517 : : #define hard_irq_disable() do { } while(0)
518 : : #endif
519 : :
520 : : /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
521 : : frequency threaded job scheduling. For almost all the purposes
522 : : tasklets are more than enough. F.e. all serial device BHs et
523 : : al. should be converted to tasklets, not to softirqs.
524 : : */
525 : :
526 : : enum
527 : : {
528 : : HI_SOFTIRQ=0,
529 : : TIMER_SOFTIRQ,
530 : : NET_TX_SOFTIRQ,
531 : : NET_RX_SOFTIRQ,
532 : : BLOCK_SOFTIRQ,
533 : : IRQ_POLL_SOFTIRQ,
534 : : TASKLET_SOFTIRQ,
535 : : SCHED_SOFTIRQ,
536 : : HRTIMER_SOFTIRQ,
537 : : RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
538 : :
539 : : NR_SOFTIRQS
540 : : };
541 : :
542 : : #define SOFTIRQ_STOP_IDLE_MASK (~(1 << RCU_SOFTIRQ))
543 : :
544 : : /* map softirq index to softirq name. update 'softirq_to_name' in
545 : : * kernel/softirq.c when adding a new softirq.
546 : : */
547 : : extern const char * const softirq_to_name[NR_SOFTIRQS];
548 : :
549 : : /* softirq mask and active fields moved to irq_cpustat_t in
550 : : * asm/hardirq.h to get better cache usage. KAO
551 : : */
552 : :
553 : : struct softirq_action
554 : : {
555 : : void (*action)(struct softirq_action *);
556 : : };
557 : :
558 : : asmlinkage void do_softirq(void);
559 : : asmlinkage void __do_softirq(void);
560 : :
561 : : #ifdef __ARCH_HAS_DO_SOFTIRQ
562 : : void do_softirq_own_stack(void);
563 : : #else
564 : : static inline void do_softirq_own_stack(void)
565 : : {
566 : : __do_softirq();
567 : : }
568 : : #endif
569 : :
570 : : extern void open_softirq(int nr, void (*action)(struct softirq_action *));
571 : : extern void softirq_init(void);
572 : : extern void __raise_softirq_irqoff(unsigned int nr);
573 : :
574 : : extern void raise_softirq_irqoff(unsigned int nr);
575 : : extern void raise_softirq(unsigned int nr);
576 : :
577 : : DECLARE_PER_CPU(struct task_struct *, ksoftirqd);
578 : :
579 : 0 : static inline struct task_struct *this_cpu_ksoftirqd(void)
580 : : {
581 [ # # ]: 0 : return this_cpu_read(ksoftirqd);
582 : : }
583 : :
584 : : /* Tasklets --- multithreaded analogue of BHs.
585 : :
586 : : Main feature differing them of generic softirqs: tasklet
587 : : is running only on one CPU simultaneously.
588 : :
589 : : Main feature differing them of BHs: different tasklets
590 : : may be run simultaneously on different CPUs.
591 : :
592 : : Properties:
593 : : * If tasklet_schedule() is called, then tasklet is guaranteed
594 : : to be executed on some cpu at least once after this.
595 : : * If the tasklet is already scheduled, but its execution is still not
596 : : started, it will be executed only once.
597 : : * If this tasklet is already running on another CPU (or schedule is called
598 : : from tasklet itself), it is rescheduled for later.
599 : : * Tasklet is strictly serialized wrt itself, but not
600 : : wrt another tasklets. If client needs some intertask synchronization,
601 : : he makes it with spinlocks.
602 : : */
603 : :
604 : : struct tasklet_struct
605 : : {
606 : : struct tasklet_struct *next;
607 : : unsigned long state;
608 : : atomic_t count;
609 : : void (*func)(unsigned long);
610 : : unsigned long data;
611 : : };
612 : :
613 : : #define DECLARE_TASKLET(name, func, data) \
614 : : struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }
615 : :
616 : : #define DECLARE_TASKLET_DISABLED(name, func, data) \
617 : : struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data }
618 : :
619 : :
620 : : enum
621 : : {
622 : : TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */
623 : : TASKLET_STATE_RUN /* Tasklet is running (SMP only) */
624 : : };
625 : :
626 : : #ifdef CONFIG_SMP
627 : 0 : static inline int tasklet_trylock(struct tasklet_struct *t)
628 : : {
629 [ # # ]: 0 : return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state);
630 : : }
631 : :
632 : 0 : static inline void tasklet_unlock(struct tasklet_struct *t)
633 : : {
634 : 0 : smp_mb__before_atomic();
635 : 0 : clear_bit(TASKLET_STATE_RUN, &(t)->state);
636 : 0 : }
637 : :
638 : : static inline void tasklet_unlock_wait(struct tasklet_struct *t)
639 : : {
640 [ - + ]: 78 : while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); }
641 : : }
642 : : #else
643 : : #define tasklet_trylock(t) 1
644 : : #define tasklet_unlock_wait(t) do { } while (0)
645 : : #define tasklet_unlock(t) do { } while (0)
646 : : #endif
647 : :
648 : : extern void __tasklet_schedule(struct tasklet_struct *t);
649 : :
650 : 13 : static inline void tasklet_schedule(struct tasklet_struct *t)
651 : : {
652 [ + - ]: 13 : if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
653 : 13 : __tasklet_schedule(t);
654 : 13 : }
655 : :
656 : : extern void __tasklet_hi_schedule(struct tasklet_struct *t);
657 : :
658 : 0 : static inline void tasklet_hi_schedule(struct tasklet_struct *t)
659 : : {
660 [ # # ]: 0 : if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
661 : 0 : __tasklet_hi_schedule(t);
662 : 0 : }
663 : :
664 : 65 : static inline void tasklet_disable_nosync(struct tasklet_struct *t)
665 : : {
666 : 65 : atomic_inc(&t->count);
667 : 65 : smp_mb__after_atomic();
668 : 65 : }
669 : :
670 : 65 : static inline void tasklet_disable(struct tasklet_struct *t)
671 : : {
672 : 65 : tasklet_disable_nosync(t);
673 : : tasklet_unlock_wait(t);
674 : 65 : smp_mb();
675 : 65 : }
676 : :
677 : 78 : static inline void tasklet_enable(struct tasklet_struct *t)
678 : : {
679 : 78 : smp_mb__before_atomic();
680 : 78 : atomic_dec(&t->count);
681 : : }
682 : :
683 : : extern void tasklet_kill(struct tasklet_struct *t);
684 : : extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu);
685 : : extern void tasklet_init(struct tasklet_struct *t,
686 : : void (*func)(unsigned long), unsigned long data);
687 : :
688 : : /*
689 : : * Autoprobing for irqs:
690 : : *
691 : : * probe_irq_on() and probe_irq_off() provide robust primitives
692 : : * for accurate IRQ probing during kernel initialization. They are
693 : : * reasonably simple to use, are not "fooled" by spurious interrupts,
694 : : * and, unlike other attempts at IRQ probing, they do not get hung on
695 : : * stuck interrupts (such as unused PS2 mouse interfaces on ASUS boards).
696 : : *
697 : : * For reasonably foolproof probing, use them as follows:
698 : : *
699 : : * 1. clear and/or mask the device's internal interrupt.
700 : : * 2. sti();
701 : : * 3. irqs = probe_irq_on(); // "take over" all unassigned idle IRQs
702 : : * 4. enable the device and cause it to trigger an interrupt.
703 : : * 5. wait for the device to interrupt, using non-intrusive polling or a delay.
704 : : * 6. irq = probe_irq_off(irqs); // get IRQ number, 0=none, negative=multiple
705 : : * 7. service the device to clear its pending interrupt.
706 : : * 8. loop again if paranoia is required.
707 : : *
708 : : * probe_irq_on() returns a mask of allocated irq's.
709 : : *
710 : : * probe_irq_off() takes the mask as a parameter,
711 : : * and returns the irq number which occurred,
712 : : * or zero if none occurred, or a negative irq number
713 : : * if more than one irq occurred.
714 : : */
715 : :
716 : : #if !defined(CONFIG_GENERIC_IRQ_PROBE)
717 : : static inline unsigned long probe_irq_on(void)
718 : : {
719 : : return 0;
720 : : }
721 : : static inline int probe_irq_off(unsigned long val)
722 : : {
723 : : return 0;
724 : : }
725 : : static inline unsigned int probe_irq_mask(unsigned long val)
726 : : {
727 : : return 0;
728 : : }
729 : : #else
730 : : extern unsigned long probe_irq_on(void); /* returns 0 on failure */
731 : : extern int probe_irq_off(unsigned long); /* returns 0 or negative on failure */
732 : : extern unsigned int probe_irq_mask(unsigned long); /* returns mask of ISA interrupts */
733 : : #endif
734 : :
735 : : #ifdef CONFIG_PROC_FS
736 : : /* Initialize /proc/irq/ */
737 : : extern void init_irq_proc(void);
738 : : #else
739 : : static inline void init_irq_proc(void)
740 : : {
741 : : }
742 : : #endif
743 : :
744 : : #ifdef CONFIG_IRQ_TIMINGS
745 : : void irq_timings_enable(void);
746 : : void irq_timings_disable(void);
747 : : u64 irq_timings_next_event(u64 now);
748 : : #endif
749 : :
750 : : struct seq_file;
751 : : int show_interrupts(struct seq_file *p, void *v);
752 : : int arch_show_interrupts(struct seq_file *p, int prec);
753 : :
754 : : extern int early_irq_init(void);
755 : : extern int arch_probe_nr_irqs(void);
756 : : extern int arch_early_irq_init(void);
757 : :
758 : : /*
759 : : * We want to know which function is an entrypoint of a hardirq or a softirq.
760 : : */
761 : : #define __irq_entry __attribute__((__section__(".irqentry.text")))
762 : : #define __softirq_entry \
763 : : __attribute__((__section__(".softirqentry.text")))
764 : :
765 : : #endif
|