at v2.6.27 13 kB view raw
1/* interrupt.h */ 2#ifndef _LINUX_INTERRUPT_H 3#define _LINUX_INTERRUPT_H 4 5#include <linux/kernel.h> 6#include <linux/linkage.h> 7#include <linux/bitops.h> 8#include <linux/preempt.h> 9#include <linux/cpumask.h> 10#include <linux/irqreturn.h> 11#include <linux/hardirq.h> 12#include <linux/sched.h> 13#include <linux/irqflags.h> 14#include <asm/atomic.h> 15#include <asm/ptrace.h> 16#include <asm/system.h> 17 18/* 19 * These correspond to the IORESOURCE_IRQ_* defines in 20 * linux/ioport.h to select the interrupt line behaviour. When 21 * requesting an interrupt without specifying a IRQF_TRIGGER, the 22 * setting should be assumed to be "as already configured", which 23 * may be as per machine or firmware initialisation. 24 */ 25#define IRQF_TRIGGER_NONE 0x00000000 26#define IRQF_TRIGGER_RISING 0x00000001 27#define IRQF_TRIGGER_FALLING 0x00000002 28#define IRQF_TRIGGER_HIGH 0x00000004 29#define IRQF_TRIGGER_LOW 0x00000008 30#define IRQF_TRIGGER_MASK (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \ 31 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING) 32#define IRQF_TRIGGER_PROBE 0x00000010 33 34/* 35 * These flags used only by the kernel as part of the 36 * irq handling routines. 37 * 38 * IRQF_DISABLED - keep irqs disabled when calling the action handler 39 * IRQF_SAMPLE_RANDOM - irq is used to feed the random generator 40 * IRQF_SHARED - allow sharing the irq among several devices 41 * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur 42 * IRQF_TIMER - Flag to mark this interrupt as timer interrupt 43 * IRQF_PERCPU - Interrupt is per cpu 44 * IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing 45 * IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is 46 * registered first in an shared interrupt is considered for 47 * performance reasons) 48 */ 49#define IRQF_DISABLED 0x00000020 50#define IRQF_SAMPLE_RANDOM 0x00000040 51#define IRQF_SHARED 0x00000080 52#define IRQF_PROBE_SHARED 0x00000100 53#define IRQF_TIMER 0x00000200 54#define IRQF_PERCPU 0x00000400 55#define IRQF_NOBALANCING 0x00000800 56#define IRQF_IRQPOLL 0x00001000 57 58typedef irqreturn_t (*irq_handler_t)(int, void *); 59 60struct irqaction { 61 irq_handler_t handler; 62 unsigned long flags; 63 cpumask_t mask; 64 const char *name; 65 void *dev_id; 66 struct irqaction *next; 67 int irq; 68 struct proc_dir_entry *dir; 69}; 70 71extern irqreturn_t no_action(int cpl, void *dev_id); 72extern int __must_check request_irq(unsigned int, irq_handler_t handler, 73 unsigned long, const char *, void *); 74extern void free_irq(unsigned int, void *); 75 76struct device; 77 78extern int __must_check devm_request_irq(struct device *dev, unsigned int irq, 79 irq_handler_t handler, unsigned long irqflags, 80 const char *devname, void *dev_id); 81extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id); 82 83/* 84 * On lockdep we dont want to enable hardirqs in hardirq 85 * context. Use local_irq_enable_in_hardirq() to annotate 86 * kernel code that has to do this nevertheless (pretty much 87 * the only valid case is for old/broken hardware that is 88 * insanely slow). 89 * 90 * NOTE: in theory this might break fragile code that relies 91 * on hardirq delivery - in practice we dont seem to have such 92 * places left. So the only effect should be slightly increased 93 * irqs-off latencies. 94 */ 95#ifdef CONFIG_LOCKDEP 96# define local_irq_enable_in_hardirq() do { } while (0) 97#else 98# define local_irq_enable_in_hardirq() local_irq_enable() 99#endif 100 101extern void disable_irq_nosync(unsigned int irq); 102extern void disable_irq(unsigned int irq); 103extern void enable_irq(unsigned int irq); 104 105#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS) 106 107extern cpumask_t irq_default_affinity; 108 109extern int irq_set_affinity(unsigned int irq, cpumask_t cpumask); 110extern int irq_can_set_affinity(unsigned int irq); 111extern int irq_select_affinity(unsigned int irq); 112 113#else /* CONFIG_SMP */ 114 115static inline int irq_set_affinity(unsigned int irq, cpumask_t cpumask) 116{ 117 return -EINVAL; 118} 119 120static inline int irq_can_set_affinity(unsigned int irq) 121{ 122 return 0; 123} 124 125static inline int irq_select_affinity(unsigned int irq) { return 0; } 126 127#endif /* CONFIG_SMP && CONFIG_GENERIC_HARDIRQS */ 128 129#ifdef CONFIG_GENERIC_HARDIRQS 130/* 131 * Special lockdep variants of irq disabling/enabling. 132 * These should be used for locking constructs that 133 * know that a particular irq context which is disabled, 134 * and which is the only irq-context user of a lock, 135 * that it's safe to take the lock in the irq-disabled 136 * section without disabling hardirqs. 137 * 138 * On !CONFIG_LOCKDEP they are equivalent to the normal 139 * irq disable/enable methods. 140 */ 141static inline void disable_irq_nosync_lockdep(unsigned int irq) 142{ 143 disable_irq_nosync(irq); 144#ifdef CONFIG_LOCKDEP 145 local_irq_disable(); 146#endif 147} 148 149static inline void disable_irq_nosync_lockdep_irqsave(unsigned int irq, unsigned long *flags) 150{ 151 disable_irq_nosync(irq); 152#ifdef CONFIG_LOCKDEP 153 local_irq_save(*flags); 154#endif 155} 156 157static inline void disable_irq_lockdep(unsigned int irq) 158{ 159 disable_irq(irq); 160#ifdef CONFIG_LOCKDEP 161 local_irq_disable(); 162#endif 163} 164 165static inline void enable_irq_lockdep(unsigned int irq) 166{ 167#ifdef CONFIG_LOCKDEP 168 local_irq_enable(); 169#endif 170 enable_irq(irq); 171} 172 173static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long *flags) 174{ 175#ifdef CONFIG_LOCKDEP 176 local_irq_restore(*flags); 177#endif 178 enable_irq(irq); 179} 180 181/* IRQ wakeup (PM) control: */ 182extern int set_irq_wake(unsigned int irq, unsigned int on); 183 184static inline int enable_irq_wake(unsigned int irq) 185{ 186 return set_irq_wake(irq, 1); 187} 188 189static inline int disable_irq_wake(unsigned int irq) 190{ 191 return set_irq_wake(irq, 0); 192} 193 194#else /* !CONFIG_GENERIC_HARDIRQS */ 195/* 196 * NOTE: non-genirq architectures, if they want to support the lock 197 * validator need to define the methods below in their asm/irq.h 198 * files, under an #ifdef CONFIG_LOCKDEP section. 199 */ 200#ifndef CONFIG_LOCKDEP 201# define disable_irq_nosync_lockdep(irq) disable_irq_nosync(irq) 202# define disable_irq_nosync_lockdep_irqsave(irq, flags) \ 203 disable_irq_nosync(irq) 204# define disable_irq_lockdep(irq) disable_irq(irq) 205# define enable_irq_lockdep(irq) enable_irq(irq) 206# define enable_irq_lockdep_irqrestore(irq, flags) \ 207 enable_irq(irq) 208# endif 209 210static inline int enable_irq_wake(unsigned int irq) 211{ 212 return 0; 213} 214 215static inline int disable_irq_wake(unsigned int irq) 216{ 217 return 0; 218} 219#endif /* CONFIG_GENERIC_HARDIRQS */ 220 221#ifndef __ARCH_SET_SOFTIRQ_PENDING 222#define set_softirq_pending(x) (local_softirq_pending() = (x)) 223#define or_softirq_pending(x) (local_softirq_pending() |= (x)) 224#endif 225 226/* Some architectures might implement lazy enabling/disabling of 227 * interrupts. In some cases, such as stop_machine, we might want 228 * to ensure that after a local_irq_disable(), interrupts have 229 * really been disabled in hardware. Such architectures need to 230 * implement the following hook. 231 */ 232#ifndef hard_irq_disable 233#define hard_irq_disable() do { } while(0) 234#endif 235 236/* PLEASE, avoid to allocate new softirqs, if you need not _really_ high 237 frequency threaded job scheduling. For almost all the purposes 238 tasklets are more than enough. F.e. all serial device BHs et 239 al. should be converted to tasklets, not to softirqs. 240 */ 241 242enum 243{ 244 HI_SOFTIRQ=0, 245 TIMER_SOFTIRQ, 246 NET_TX_SOFTIRQ, 247 NET_RX_SOFTIRQ, 248 BLOCK_SOFTIRQ, 249 TASKLET_SOFTIRQ, 250 SCHED_SOFTIRQ, 251#ifdef CONFIG_HIGH_RES_TIMERS 252 HRTIMER_SOFTIRQ, 253#endif 254 RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ 255}; 256 257/* softirq mask and active fields moved to irq_cpustat_t in 258 * asm/hardirq.h to get better cache usage. KAO 259 */ 260 261struct softirq_action 262{ 263 void (*action)(struct softirq_action *); 264}; 265 266asmlinkage void do_softirq(void); 267asmlinkage void __do_softirq(void); 268extern void open_softirq(int nr, void (*action)(struct softirq_action *)); 269extern void softirq_init(void); 270#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0) 271extern void raise_softirq_irqoff(unsigned int nr); 272extern void raise_softirq(unsigned int nr); 273 274 275/* Tasklets --- multithreaded analogue of BHs. 276 277 Main feature differing them of generic softirqs: tasklet 278 is running only on one CPU simultaneously. 279 280 Main feature differing them of BHs: different tasklets 281 may be run simultaneously on different CPUs. 282 283 Properties: 284 * If tasklet_schedule() is called, then tasklet is guaranteed 285 to be executed on some cpu at least once after this. 286 * If the tasklet is already scheduled, but its excecution is still not 287 started, it will be executed only once. 288 * If this tasklet is already running on another CPU (or schedule is called 289 from tasklet itself), it is rescheduled for later. 290 * Tasklet is strictly serialized wrt itself, but not 291 wrt another tasklets. If client needs some intertask synchronization, 292 he makes it with spinlocks. 293 */ 294 295struct tasklet_struct 296{ 297 struct tasklet_struct *next; 298 unsigned long state; 299 atomic_t count; 300 void (*func)(unsigned long); 301 unsigned long data; 302}; 303 304#define DECLARE_TASKLET(name, func, data) \ 305struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data } 306 307#define DECLARE_TASKLET_DISABLED(name, func, data) \ 308struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data } 309 310 311enum 312{ 313 TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */ 314 TASKLET_STATE_RUN /* Tasklet is running (SMP only) */ 315}; 316 317#ifdef CONFIG_SMP 318static inline int tasklet_trylock(struct tasklet_struct *t) 319{ 320 return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state); 321} 322 323static inline void tasklet_unlock(struct tasklet_struct *t) 324{ 325 smp_mb__before_clear_bit(); 326 clear_bit(TASKLET_STATE_RUN, &(t)->state); 327} 328 329static inline void tasklet_unlock_wait(struct tasklet_struct *t) 330{ 331 while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); } 332} 333#else 334#define tasklet_trylock(t) 1 335#define tasklet_unlock_wait(t) do { } while (0) 336#define tasklet_unlock(t) do { } while (0) 337#endif 338 339extern void __tasklet_schedule(struct tasklet_struct *t); 340 341static inline void tasklet_schedule(struct tasklet_struct *t) 342{ 343 if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) 344 __tasklet_schedule(t); 345} 346 347extern void __tasklet_hi_schedule(struct tasklet_struct *t); 348 349static inline void tasklet_hi_schedule(struct tasklet_struct *t) 350{ 351 if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) 352 __tasklet_hi_schedule(t); 353} 354 355 356static inline void tasklet_disable_nosync(struct tasklet_struct *t) 357{ 358 atomic_inc(&t->count); 359 smp_mb__after_atomic_inc(); 360} 361 362static inline void tasklet_disable(struct tasklet_struct *t) 363{ 364 tasklet_disable_nosync(t); 365 tasklet_unlock_wait(t); 366 smp_mb(); 367} 368 369static inline void tasklet_enable(struct tasklet_struct *t) 370{ 371 smp_mb__before_atomic_dec(); 372 atomic_dec(&t->count); 373} 374 375static inline void tasklet_hi_enable(struct tasklet_struct *t) 376{ 377 smp_mb__before_atomic_dec(); 378 atomic_dec(&t->count); 379} 380 381extern void tasklet_kill(struct tasklet_struct *t); 382extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu); 383extern void tasklet_init(struct tasklet_struct *t, 384 void (*func)(unsigned long), unsigned long data); 385 386/* 387 * Autoprobing for irqs: 388 * 389 * probe_irq_on() and probe_irq_off() provide robust primitives 390 * for accurate IRQ probing during kernel initialization. They are 391 * reasonably simple to use, are not "fooled" by spurious interrupts, 392 * and, unlike other attempts at IRQ probing, they do not get hung on 393 * stuck interrupts (such as unused PS2 mouse interfaces on ASUS boards). 394 * 395 * For reasonably foolproof probing, use them as follows: 396 * 397 * 1. clear and/or mask the device's internal interrupt. 398 * 2. sti(); 399 * 3. irqs = probe_irq_on(); // "take over" all unassigned idle IRQs 400 * 4. enable the device and cause it to trigger an interrupt. 401 * 5. wait for the device to interrupt, using non-intrusive polling or a delay. 402 * 6. irq = probe_irq_off(irqs); // get IRQ number, 0=none, negative=multiple 403 * 7. service the device to clear its pending interrupt. 404 * 8. loop again if paranoia is required. 405 * 406 * probe_irq_on() returns a mask of allocated irq's. 407 * 408 * probe_irq_off() takes the mask as a parameter, 409 * and returns the irq number which occurred, 410 * or zero if none occurred, or a negative irq number 411 * if more than one irq occurred. 412 */ 413 414#if defined(CONFIG_GENERIC_HARDIRQS) && !defined(CONFIG_GENERIC_IRQ_PROBE) 415static inline unsigned long probe_irq_on(void) 416{ 417 return 0; 418} 419static inline int probe_irq_off(unsigned long val) 420{ 421 return 0; 422} 423static inline unsigned int probe_irq_mask(unsigned long val) 424{ 425 return 0; 426} 427#else 428extern unsigned long probe_irq_on(void); /* returns 0 on failure */ 429extern int probe_irq_off(unsigned long); /* returns 0 or negative on failure */ 430extern unsigned int probe_irq_mask(unsigned long); /* returns mask of ISA interrupts */ 431#endif 432 433#ifdef CONFIG_PROC_FS 434/* Initialize /proc/irq/ */ 435extern void init_irq_proc(void); 436#else 437static inline void init_irq_proc(void) 438{ 439} 440#endif 441 442int show_interrupts(struct seq_file *p, void *v); 443 444#endif