root/arch/m68k/kernel/ints.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. init_IRQ
  2. insert_isr
  3. delete_isr
  4. new_isr_node
  5. add_isr
  6. remove_isr
  7. call_isr_list
  8. process_int
  9. request_irq
  10. free_irq
  11. probe_irq_on
  12. probe_irq_off
  13. enable_irq
  14. disable_irq
  15. get_irq_list

   1 /*
   2  * ints.c -- 680x0 Linux general interrupt handling code
   3  *
   4  * This file is subject to the terms and conditions of the GNU General Public
   5  * License.  See the file README.legal in the main directory of this archive
   6  * for more details.
   7  *
   8  * 07/03/96: Timer initialization, and thus mach_sched_init(),
   9  *           removed from request_irq() and moved to init_time().
  10  *           We should therefore consider renaming our add_isr() and
  11  *           remove_isr() to request_irq() and free_irq()
  12  *           respectively, so they are compliant with the other
  13  *           architectures.                                     /Jes
  14  */
  15 
  16 #include <linux/types.h>
  17 #include <linux/sched.h>
  18 #include <linux/kernel_stat.h>
  19 #include <linux/errno.h>
  20 
  21 #include <asm/system.h>
  22 #include <asm/irq.h>
  23 #include <asm/traps.h>
  24 #include <asm/page.h>
  25 #include <asm/machdep.h>
  26 
  27 /* list is accessed 0-6 for IRQs 1-7 */
  28 static isr_node_t *isr_list[7];
  29 
  30 /* The number of spurious interrupts */
  31 volatile unsigned long num_spurious;
  32 /*
  33 unsigned long interrupt_stack[PAGE_SIZE/sizeof(long)];
  34 */
  35 
  36 /*
  37  * void init_IRQ(void)
  38  *
  39  * Parameters:  None
  40  *
  41  * Returns:     Nothing
  42  *
  43  * This function should be called during kernel startup to initialize
  44  * the IRQ handling routines.
  45  */
  46 
  47 void init_IRQ(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49     /* Setup interrupt stack pointer */
  50   /*
  51     asm ("movec %0,%/isp"
  52          : : "r" (interrupt_stack + sizeof (interrupt_stack) / sizeof (long)));
  53          */
  54     mach_init_INTS ();
  55 }
  56 
  57 void insert_isr (isr_node_t **listp, isr_node_t *node)
     /* [previous][next][first][last][top][bottom][index][help] */
  58 {
  59     unsigned long spl;
  60     isr_node_t *cur;
  61 
  62     save_flags(spl);
  63     cli();
  64 
  65     cur = *listp;
  66 
  67     while (cur && cur->pri <= node->pri)
  68     {
  69         listp = &cur->next;
  70         cur = cur->next;
  71     }
  72 
  73     node->next = cur;
  74     *listp = node;
  75 
  76     restore_flags(spl);
  77 }
  78 
  79 void delete_isr (isr_node_t **listp, isrfunc isr)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81     unsigned long flags;
  82     isr_node_t *np;
  83 
  84     save_flags(flags);
  85     cli();
  86     for (np = *listp; np; listp = &np->next, np = *listp) {
  87         if (np->isr == isr) {
  88             *listp = np->next;
  89             /* Mark it as free. */
  90             np->isr = NULL;
  91             restore_flags(flags);
  92             return;
  93         }
  94     }
  95     restore_flags(flags);
  96     printk ("delete_isr: isr %p not found on list!\n", isr);
  97 }
  98 
  99 #define NUM_ISR_NODES 100
 100 static isr_node_t nodes[NUM_ISR_NODES];
 101 
 102 isr_node_t *new_isr_node(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104     isr_node_t *np;
 105 
 106     for (np = nodes; np < &nodes[NUM_ISR_NODES]; np++)
 107         if (np->isr == NULL)
 108             return np;
 109 
 110     printk ("new_isr_node: out of nodes");
 111     return NULL;
 112 }
 113 
 114 int add_isr (unsigned long source, isrfunc isr, int pri, void *data,
     /* [previous][next][first][last][top][bottom][index][help] */
 115              char *name)
 116 {
 117     isr_node_t *p;
 118 
 119     if (source & IRQ_MACHSPEC)
 120     {
 121         return mach_add_isr (source, isr, pri, data, name);
 122     }
 123 
 124     if (source < IRQ1 || source > IRQ7)
 125         panic ("add_isr: Incorrect IRQ source %ld from %s\n", source, name);
 126 
 127     p = new_isr_node();
 128     if (p == NULL)
 129         return 0;
 130     p->isr = isr;
 131     p->pri = pri;
 132     p->data = data;
 133     p->name = name;
 134     p->next = NULL;
 135 
 136     insert_isr (&isr_list[source-1], p);
 137 
 138     return 1;
 139 }
 140 
 141 int remove_isr (unsigned long source, isrfunc isr)
     /* [previous][next][first][last][top][bottom][index][help] */
 142 {
 143     if (source & IRQ_MACHSPEC)
 144         return mach_remove_isr (source, isr);
 145 
 146     if (source < IRQ1 || source > IRQ7) {
 147         printk ("remove_isr: Incorrect IRQ source %ld\n", source);
 148         return 0;
 149     }
 150 
 151     delete_isr (&isr_list[source - 1], isr);
 152     return 1;
 153 }
 154 
 155 void call_isr_list(int irq, isr_node_t *p, struct pt_regs *fp)
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157     while (p) {
 158         p->isr (irq, fp, p->data);
 159         p = p->next;
 160     }
 161 }
 162 
 163 asmlinkage void process_int(int vec, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 164 {
 165         int level;
 166 
 167         if (vec >= VECOFF(VEC_INT1) && vec <= VECOFF(VEC_INT7))
 168                 level = (vec - VECOFF(VEC_SPUR)) >> 2;
 169         else {
 170                 if (mach_process_int)
 171                         mach_process_int(vec, regs);
 172                 else
 173                         panic("Can't process interrupt vector 0x%03x\n", vec);
 174                 return;
 175         }
 176 
 177         kstat.interrupts[level]++;      
 178         call_isr_list (level, isr_list[level-1], regs);
 179 }
 180 
 181 int request_irq(unsigned int irq,
     /* [previous][next][first][last][top][bottom][index][help] */
 182                 void (*handler)(int, void *, struct pt_regs *),
 183                 unsigned long flags, const char * devname, void *dev_id)
 184 {
 185         return -EINVAL;
 186 }
 187 
 188 void free_irq(unsigned int irq, void *dev_id)
     /* [previous][next][first][last][top][bottom][index][help] */
 189 {
 190 }
 191 
 192 /*
 193  * Do we need these probe functions on the m68k?
 194  */
 195 unsigned long probe_irq_on (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 196 {
 197   return 0;
 198 }
 199 
 200 int probe_irq_off (unsigned long irqs)
     /* [previous][next][first][last][top][bottom][index][help] */
 201 {
 202   return 0;
 203 }
 204 
 205 void enable_irq(unsigned int irq_nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 206 {
 207         if ((irq_nr & IRQ_MACHSPEC) && mach_enable_irq)
 208                 mach_enable_irq(irq_nr);
 209 }
 210 
 211 void disable_irq(unsigned int irq_nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 212 {
 213         if ((irq_nr & IRQ_MACHSPEC) && mach_disable_irq)
 214                 mach_disable_irq(irq_nr);
 215 }
 216 
 217 int get_irq_list(char *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 218 {
 219     int i, len = 0;
 220     isr_node_t *p;
 221     
 222     /* autovector interrupts */
 223     for (i = IRQ1; i <= IRQ7; ++i) {
 224         if (!isr_list[i-1])
 225             continue;
 226         len += sprintf(buf+len, "auto %2d: %8d ", i, kstat.interrupts[i]);
 227         for (p = isr_list[i-1]; p; p = p->next) {
 228             len += sprintf(buf+len, "%s\n", p->name);
 229             if (p->next)
 230                 len += sprintf(buf+len, "                  ");
 231         }
 232     }
 233 
 234     len = mach_get_irq_list(buf, len);
 235     return len;
 236 }

/* [previous][next][first][last][top][bottom][index][help] */