linux/include/linux/interrupt.h
<<
>>
Prefs
   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 */
  44#define IRQF_DISABLED           0x00000020
  45#define IRQF_SAMPLE_RANDOM      0x00000040
  46#define IRQF_SHARED             0x00000080
  47#define IRQF_PROBE_SHARED       0x00000100
  48#define IRQF_TIMER              0x00000200
  49#define IRQF_PERCPU             0x00000400
  50
  51/*
  52 * Migration helpers. Scheduled for removal in 1/2007
  53 * Do not use for new code !
  54 */
  55#define SA_INTERRUPT            IRQF_DISABLED
  56#define SA_SAMPLE_RANDOM        IRQF_SAMPLE_RANDOM
  57#define SA_SHIRQ                IRQF_SHARED
  58#define SA_PROBEIRQ             IRQF_PROBE_SHARED
  59#define SA_PERCPU               IRQF_PERCPU
  60
  61#define SA_TRIGGER_LOW          IRQF_TRIGGER_LOW
  62#define SA_TRIGGER_HIGH         IRQF_TRIGGER_HIGH
  63#define SA_TRIGGER_FALLING      IRQF_TRIGGER_FALLING
  64#define SA_TRIGGER_RISING       IRQF_TRIGGER_RISING
  65#define SA_TRIGGER_MASK         IRQF_TRIGGER_MASK
  66
  67struct irqaction {
  68        irqreturn_t (*handler)(int, void *, struct pt_regs *);
  69        unsigned long flags;
  70        cpumask_t mask;
  71        const char *name;
  72        void *dev_id;
  73        struct irqaction *next;
  74        int irq;
  75        struct proc_dir_entry *dir;
  76};
  77
  78extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs);
  79extern int request_irq(unsigned int,
  80                       irqreturn_t (*handler)(int, void *, struct pt_regs *),
  81                       unsigned long, const char *, void *);
  82extern void free_irq(unsigned int, void *);
  83
  84/*
  85 * On lockdep we dont want to enable hardirqs in hardirq
  86 * context. Use local_irq_enable_in_hardirq() to annotate
  87 * kernel code that has to do this nevertheless (pretty much
  88 * the only valid case is for old/broken hardware that is
  89 * insanely slow).
  90 *
  91 * NOTE: in theory this might break fragile code that relies
  92 * on hardirq delivery - in practice we dont seem to have such
  93 * places left. So the only effect should be slightly increased
  94 * irqs-off latencies.
  95 */
  96#ifdef CONFIG_LOCKDEP
  97# define local_irq_enable_in_hardirq()  do { } while (0)
  98#else
  99# define local_irq_enable_in_hardirq()  local_irq_enable()
 100#endif
 101
 102#ifdef CONFIG_GENERIC_HARDIRQS
 103extern void disable_irq_nosync(unsigned int irq);
 104extern void disable_irq(unsigned int irq);
 105extern void enable_irq(unsigned int irq);
 106
 107/*
 108 * Special lockdep variants of irq disabling/enabling.
 109 * These should be used for locking constructs that
 110 * know that a particular irq context which is disabled,
 111 * and which is the only irq-context user of a lock,
 112 * that it's safe to take the lock in the irq-disabled
 113 * section without disabling hardirqs.
 114 *
 115 * On !CONFIG_LOCKDEP they are equivalent to the normal
 116 * irq disable/enable methods.
 117 */
 118static inline void disable_irq_nosync_lockdep(unsigned int irq)
 119{
 120        disable_irq_nosync(irq);
 121#ifdef CONFIG_LOCKDEP
 122        local_irq_disable();
 123#endif
 124}
 125
 126static inline void disable_irq_lockdep(unsigned int irq)
 127{
 128        disable_irq(irq);
 129#ifdef CONFIG_LOCKDEP
 130        local_irq_disable();
 131#endif
 132}
 133
 134static inline void enable_irq_lockdep(unsigned int irq)
 135{
 136#ifdef CONFIG_LOCKDEP
 137        local_irq_enable();
 138#endif
 139        enable_irq(irq);
 140}
 141
 142/* IRQ wakeup (PM) control: */
 143extern int set_irq_wake(unsigned int irq, unsigned int on);
 144
 145static inline int enable_irq_wake(unsigned int irq)
 146{
 147        return set_irq_wake(irq, 1);
 148}
 149
 150static inline int disable_irq_wake(unsigned int irq)
 151{
 152        return set_irq_wake(irq, 0);
 153}
 154
 155#else /* !CONFIG_GENERIC_HARDIRQS */
 156/*
 157 * NOTE: non-genirq architectures, if they want to support the lock
 158 * validator need to define the methods below in their asm/irq.h
 159 * files, under an #ifdef CONFIG_LOCKDEP section.
 160 */
 161# ifndef CONFIG_LOCKDEP
 162#  define disable_irq_nosync_lockdep(irq)       disable_irq_nosync(irq)
 163#  define disable_irq_lockdep(irq)              disable_irq(irq)
 164#  define enable_irq_lockdep(irq)               enable_irq(irq)
 165# endif
 166
 167#endif /* CONFIG_GENERIC_HARDIRQS */
 168
 169#ifndef __ARCH_SET_SOFTIRQ_PENDING
 170#define set_softirq_pending(x) (local_softirq_pending() = (x))
 171#define or_softirq_pending(x)  (local_softirq_pending() |= (x))
 172#endif
 173
 174/*
 175 * Temporary defines for UP kernels, until all code gets fixed.
 176 */
 177#ifndef CONFIG_SMP
 178static inline void __deprecated cli(void)
 179{
 180        local_irq_disable();
 181}
 182static inline void __deprecated sti(void)
 183{
 184        local_irq_enable();
 185}
 186static inline void __deprecated save_flags(unsigned long *x)
 187{
 188        local_save_flags(*x);
 189}
 190#define save_flags(x) save_flags(&x)
 191static inline void __deprecated restore_flags(unsigned long x)
 192{
 193        local_irq_restore(x);
 194}
 195
 196static inline void __deprecated save_and_cli(unsigned long *x)
 197{
 198        local_irq_save(*x);
 199}
 200#define save_and_cli(x) save_and_cli(&x)
 201#endif /* CONFIG_SMP */
 202
 203extern void local_bh_disable(void);
 204extern void __local_bh_enable(void);
 205extern void _local_bh_enable(void);
 206extern void local_bh_enable(void);
 207extern void local_bh_enable_ip(unsigned long ip);
 208
 209/* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
 210   frequency threaded job scheduling. For almost all the purposes
 211   tasklets are more than enough. F.e. all serial device BHs et
 212   al. should be converted to tasklets, not to softirqs.
 213 */
 214
 215enum
 216{
 217        HI_SOFTIRQ=0,
 218        TIMER_SOFTIRQ,
 219        NET_TX_SOFTIRQ,
 220        NET_RX_SOFTIRQ,
 221        BLOCK_SOFTIRQ,
 222        TASKLET_SOFTIRQ
 223};
 224
 225/* softirq mask and active fields moved to irq_cpustat_t in
 226 * asm/hardirq.h to get better cache usage.  KAO
 227 */
 228
 229struct softirq_action
 230{
 231        void    (*action)(struct softirq_action *);
 232        void    *data;
 233};
 234
 235asmlinkage void do_softirq(void);
 236extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data);
 237extern void softirq_init(void);
 238#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
 239extern void FASTCALL(raise_softirq_irqoff(unsigned int nr));
 240extern void FASTCALL(raise_softirq(unsigned int nr));
 241
 242
 243/* Tasklets --- multithreaded analogue of BHs.
 244
 245   Main feature differing them of generic softirqs: tasklet
 246   is running only on one CPU simultaneously.
 247
 248   Main feature differing them of BHs: different tasklets
 249   may be run simultaneously on different CPUs.
 250
 251   Properties:
 252   * If tasklet_schedule() is called, then tasklet is guaranteed
 253     to be executed on some cpu at least once after this.
 254   * If the tasklet is already scheduled, but its excecution is still not
 255     started, it will be executed only once.
 256   * If this tasklet is already running on another CPU (or schedule is called
 257     from tasklet itself), it is rescheduled for later.
 258   * Tasklet is strictly serialized wrt itself, but not
 259     wrt another tasklets. If client needs some intertask synchronization,
 260     he makes it with spinlocks.
 261 */
 262
 263struct tasklet_struct
 264{
 265        struct tasklet_struct *next;
 266        unsigned long state;
 267        atomic_t count;
 268        void (*func)(unsigned long);
 269        unsigned long data;
 270};
 271
 272#define DECLARE_TASKLET(name, func, data) \
 273struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }
 274
 275#define DECLARE_TASKLET_DISABLED(name, func, data) \
 276struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data }
 277
 278
 279enum
 280{
 281        TASKLET_STATE_SCHED,    /* Tasklet is scheduled for execution */
 282        TASKLET_STATE_RUN       /* Tasklet is running (SMP only) */
 283};
 284
 285#ifdef CONFIG_SMP
 286static inline int tasklet_trylock(struct tasklet_struct *t)
 287{
 288        return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state);
 289}
 290
 291static inline void tasklet_unlock(struct tasklet_struct *t)
 292{
 293        smp_mb__before_clear_bit(); 
 294        clear_bit(TASKLET_STATE_RUN, &(t)->state);
 295}
 296
 297static inline void tasklet_unlock_wait(struct tasklet_struct *t)
 298{
 299        while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); }
 300}
 301#else
 302#define tasklet_trylock(t) 1
 303#define tasklet_unlock_wait(t) do { } while (0)
 304#define tasklet_unlock(t) do { } while (0)
 305#endif
 306
 307extern void FASTCALL(__tasklet_schedule(struct tasklet_struct *t));
 308
 309static inline void tasklet_schedule(struct tasklet_struct *t)
 310{
 311        if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
 312                __tasklet_schedule(t);
 313}
 314
 315extern void FASTCALL(__tasklet_hi_schedule(struct tasklet_struct *t));
 316
 317static inline void tasklet_hi_schedule(struct tasklet_struct *t)
 318{
 319        if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
 320                __tasklet_hi_schedule(t);
 321}
 322
 323
 324static inline void tasklet_disable_nosync(struct tasklet_struct *t)
 325{
 326        atomic_inc(&t->count);
 327        smp_mb__after_atomic_inc();
 328}
 329
 330static inline void tasklet_disable(struct tasklet_struct *t)
 331{
 332        tasklet_disable_nosync(t);
 333        tasklet_unlock_wait(t);
 334        smp_mb();
 335}
 336
 337static inline void tasklet_enable(struct tasklet_struct *t)
 338{
 339        smp_mb__before_atomic_dec();
 340        atomic_dec(&t->count);
 341}
 342
 343static inline void tasklet_hi_enable(struct tasklet_struct *t)
 344{
 345        smp_mb__before_atomic_dec();
 346        atomic_dec(&t->count);
 347}
 348
 349extern void tasklet_kill(struct tasklet_struct *t);
 350extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu);
 351extern void tasklet_init(struct tasklet_struct *t,
 352                         void (*func)(unsigned long), unsigned long data);
 353
 354/*
 355 * Autoprobing for irqs:
 356 *
 357 * probe_irq_on() and probe_irq_off() provide robust primitives
 358 * for accurate IRQ probing during kernel initialization.  They are
 359 * reasonably simple to use, are not "fooled" by spurious interrupts,
 360 * and, unlike other attempts at IRQ probing, they do not get hung on
 361 * stuck interrupts (such as unused PS2 mouse interfaces on ASUS boards).
 362 *
 363 * For reasonably foolproof probing, use them as follows:
 364 *
 365 * 1. clear and/or mask the device's internal interrupt.
 366 * 2. sti();
 367 * 3. irqs = probe_irq_on();      // "take over" all unassigned idle IRQs
 368 * 4. enable the device and cause it to trigger an interrupt.
 369 * 5. wait for the device to interrupt, using non-intrusive polling or a delay.
 370 * 6. irq = probe_irq_off(irqs);  // get IRQ number, 0=none, negative=multiple
 371 * 7. service the device to clear its pending interrupt.
 372 * 8. loop again if paranoia is required.
 373 *
 374 * probe_irq_on() returns a mask of allocated irq's.
 375 *
 376 * probe_irq_off() takes the mask as a parameter,
 377 * and returns the irq number which occurred,
 378 * or zero if none occurred, or a negative irq number
 379 * if more than one irq occurred.
 380 */
 381
 382#if defined(CONFIG_GENERIC_HARDIRQS) && !defined(CONFIG_GENERIC_IRQ_PROBE) 
 383static inline unsigned long probe_irq_on(void)
 384{
 385        return 0;
 386}
 387static inline int probe_irq_off(unsigned long val)
 388{
 389        return 0;
 390}
 391static inline unsigned int probe_irq_mask(unsigned long val)
 392{
 393        return 0;
 394}
 395#else
 396extern unsigned long probe_irq_on(void);        /* returns 0 on failure */
 397extern int probe_irq_off(unsigned long);        /* returns 0 or negative on failure */
 398extern unsigned int probe_irq_mask(unsigned long);      /* returns mask of ISA interrupts */
 399#endif
 400
 401#endif
 402
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.