root/arch/sparc/kernel/irq.c

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

DEFINITIONS

This source file includes following definitions.
  1. disable_irq
  2. enable_irq
  3. get_irq_list
  4. free_irq
  5. handle_nmi
  6. unexpected_irq
  7. handler_irq
  8. do_IRQ
  9. do_fast_IRQ
  10. request_irq
  11. probe_irq_on
  12. probe_irq_off
  13. init_IRQ

   1 /*  arch/sparc/kernel/irq.c:  Interrupt request handling routines. On the
   2  *                            Sparc the IRQ's are basically 'cast in stone'
   3  *                            and you are supposed to probe the prom's device
   4  *                            node trees to find out who's got which IRQ.
   5  *
   6  *  Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
   7  *
   8  */
   9 
  10 /*
  11  * IRQ's are in fact implemented a bit like signal handlers for the kernel.
  12  * The same sigaction struct is used, and with similar semantics (ie there
  13  * is a SA_INTERRUPT flag etc). Naturally it's not a 1:1 relation, but there
  14  * are similarities.
  15  *
  16  * sa_handler(int irq_NR) is the default function called (0 if no).
  17  * sa_mask is horribly ugly (I won't even mention it)
  18  * sa_flags contains various info: SA_INTERRUPT etc
  19  * sa_restorer is the unused
  20  */
  21 
  22 #include <linux/config.h>
  23 #include <linux/ptrace.h>
  24 #include <linux/errno.h>
  25 #include <linux/linkage.h>
  26 #include <linux/kernel_stat.h>
  27 #include <linux/signal.h>
  28 #include <linux/sched.h>
  29 #include <linux/interrupt.h>
  30 #include <asm/ptrace.h>
  31 #include <asm/system.h>
  32 #include <asm/psr.h>
  33 
  34 void disable_irq(unsigned int irq_nr)
     /* [previous][next][first][last][top][bottom][index][help] */
  35 {
  36   unsigned long flags;
  37   unsigned char *int_reg;
  38   
  39   save_flags(flags);
  40   cli();
  41 
  42   /* We have mapped the irq enable register in head.S and all we
  43    * have to do here is frob the bits.
  44    */
  45 
  46   int_reg = (char *) IRQ_ENA_ADR;
  47 
  48   switch(irq_nr)
  49     {
  50     case 1:
  51       *int_reg = ((*int_reg) & (~(0x02)));
  52       break;
  53     case 4:
  54       *int_reg = ((*int_reg) & (~(0x04)));
  55       break;
  56     case 6:
  57       *int_reg = ((*int_reg) & (~(0x08)));
  58       break;      
  59     case 8:
  60       *int_reg = ((*int_reg) & (~(0x10)));
  61       break;      
  62     case 10:
  63       *int_reg = ((*int_reg) & (~(0x20)));
  64       break;      
  65     case 14:
  66       *int_reg = ((*int_reg) & (~(0x80)));
  67       break;      
  68     default:
  69       printk("AIEEE, Illegal interrupt disable requested irq=%d\n", 
  70              (int) irq_nr);
  71       break;
  72     };
  73   
  74   restore_flags(flags);
  75   return;
  76 }
  77 
  78 void enable_irq(unsigned int irq_nr)
     /* [previous][next][first][last][top][bottom][index][help] */
  79 {
  80   unsigned long flags;
  81   unsigned int *int_reg;
  82   
  83   save_flags(flags);
  84   cli();
  85 
  86   /* We have mapped the irq enable register in head.S and all we
  87    * have to do here is frob the bits.
  88    */
  89 
  90   int_reg = (unsigned int *) IRQ_ENA_ADR;
  91   
  92   switch(irq_nr)
  93     {
  94     case 1:
  95       *int_reg = ((*int_reg) | 0x02);
  96       break;
  97     case 4:
  98       *int_reg = ((*int_reg) | 0x04);
  99       break;
 100     case 6:
 101       *int_reg = ((*int_reg) | 0x08);
 102       break;      
 103     case 8:
 104       *int_reg = ((*int_reg) | 0x10);
 105       break;      
 106     case 10:
 107       *int_reg = ((*int_reg) | 0x20);
 108       break;      
 109     case 14:
 110       *int_reg = ((*int_reg) | 0x80);
 111       break;      
 112     default:
 113       printk("AIEEE, Illegal interrupt enable requested irq=%d\n", 
 114              (int) irq_nr);
 115       break;
 116     };
 117 
 118   restore_flags(flags);
 119   return;
 120 }
 121 
 122 /*
 123  * Initial irq handlers.
 124  */
 125 struct irqaction {
 126   void (*handler)(int, struct pt_regs *);
 127   unsigned long flags;
 128   unsigned long mask;
 129   const char *name;
 130 };
 131 
 132 static struct irqaction irq_action[16] = {
 133   { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
 134   { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
 135   { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
 136   { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
 137   { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
 138   { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
 139   { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
 140   { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
 141 };
 142 
 143 
 144 int get_irq_list(char *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 145 {
 146   int i, len = 0;
 147   struct irqaction * action = irq_action;
 148   
 149   for (i = 0 ; i < 16 ; i++, action++) {
 150     if (!action->handler)
 151       continue;
 152     len += sprintf(buf+len, "%2d: %8d %c %s\n",
 153                    i, kstat.interrupts[i],
 154                    (action->flags & SA_INTERRUPT) ? '+' : ' ',
 155                    action->name);
 156   }
 157   return len;
 158 }
 159 
 160 void free_irq(unsigned int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 161 {
 162         struct irqaction * action = irq + irq_action;
 163         unsigned long flags;
 164 
 165         if (irq > 14) {  /* 14 irq levels on the sparc */
 166                 printk("Trying to free IRQ%d\n", irq);
 167                 return;
 168         }
 169         if (!action->handler) {
 170                 printk("Trying to free free IRQ%d\n", irq);
 171                 return;
 172         }
 173         save_flags(flags);
 174         cli();
 175         disable_irq(irq);
 176         action->handler = NULL;
 177         action->flags = 0;
 178         action->mask = 0;
 179         action->name = NULL;
 180         restore_flags(flags);
 181 }
 182 
 183 #if 0
 184 static void handle_nmi(struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 185 {
 186   printk("NMI, probably due to bus-parity error.\n");
 187   printk("PC=%08lx, SP=%08lx\n", regs->pc, regs->sp);
 188 }
 189 #endif
 190 
 191 static void unexpected_irq(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 192 {
 193         int i;
 194 
 195         printk("IO device interrupt, irq = %d\n", irq);
 196         printk("PC = %08lx NPC = %08lx SP=%08lx\n", regs->pc, 
 197                regs->npc, regs->sp);
 198         printk("Expecting: ");
 199         for (i = 0; i < 16; i++)
 200                 if (irq_action[i].handler)
 201                         printk("[%s:%d] ", irq_action[i].name, i);
 202         printk("AIEEE\n");
 203 }
 204 
 205 static inline void handler_irq(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 206 {
 207   struct irqaction * action = irq + irq_action;
 208 
 209   if (!action->handler) {
 210     unexpected_irq(irq, regs);
 211     return;
 212   }
 213   action->handler(irq, regs);
 214 }
 215 
 216 /*
 217  * do_IRQ handles IRQ's that have been installed without the
 218  * SA_INTERRUPT flag: it uses the full signal-handling return
 219  * and runs with other interrupts enabled. All relatively slow
 220  * IRQ's should use this format: notably the keyboard/timer
 221  * routines.
 222  */
 223 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 224 {
 225   struct irqaction *action = irq + irq_action;
 226 
 227   kstat.interrupts[irq]++;
 228   action->handler(irq, regs);
 229   return;
 230 }
 231 
 232 /*
 233  * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return
 234  * stuff - the handler is also running with interrupts disabled unless
 235  * it explicitly enables them later.
 236  */
 237 asmlinkage void do_fast_IRQ(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 238 {
 239   kstat.interrupts[irq]++;
 240   printk("Got FAST_IRQ number %04lx\n", (long unsigned int) irq);
 241   return;
 242 }
 243 
 244                 
 245 int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
     /* [previous][next][first][last][top][bottom][index][help] */
 246         unsigned long irqflags, const char * devname)
 247 {
 248   struct irqaction *action;
 249   unsigned long flags;
 250 
 251   if(irq > 14)  /* Only levels 1-14 are valid on the Sparc. */
 252     return -EINVAL;
 253 
 254   if(irq == 0)  /* sched_init() requesting the timer IRQ */
 255     irq = 14;
 256 
 257   action = irq + irq_action;
 258 
 259   if(action->handler)
 260     return -EBUSY;
 261 
 262   if(!handler)
 263     return -EINVAL;
 264 
 265   save_flags(flags);
 266   cli();
 267 
 268   action->handler = handler;
 269   action->flags = irqflags;
 270   action->mask = 0;
 271   action->name = devname;
 272 
 273   enable_irq(irq);
 274 
 275   restore_flags(flags);
 276   return 0;
 277 }
 278 
 279 unsigned int probe_irq_on (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 280 {
 281   unsigned int irqs = 0;
 282 
 283   return irqs;
 284 }
 285 
 286 int probe_irq_off (unsigned int irqs)
     /* [previous][next][first][last][top][bottom][index][help] */
 287 {
 288   unsigned int i = 0;
 289 
 290   return i;
 291 }
 292 
 293 void init_IRQ(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 294 {
 295   return;
 296 }

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