root/arch/sparc/kernel/sun4c_irq.c

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

DEFINITIONS

This source file includes following definitions.
  1. sun4c_disable_irq
  2. sun4c_enable_irq
  3. sun4c_clear_clock_irq
  4. sun4c_clear_profile_irq
  5. sun4c_load_profile_irq
  6. sun4c_init_timers
  7. sun4c_nop
  8. sun4c_init_IRQ

   1 /*  sun4c_irq.c
   2  *  arch/sparc/kernel/sun4c_irq.c:
   3  *
   4  *  djhr: Hacked out of irq.c into a CPU dependent version.
   5  *
   6  *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
   7  *  Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
   8  *  Copyright (C) 1995 Pete A. Zaitcev (zaitcev@ipmce.su)
   9  *  Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
  10  */
  11 
  12 #include <linux/ptrace.h>
  13 #include <linux/errno.h>
  14 #include <linux/linkage.h>
  15 #include <linux/kernel_stat.h>
  16 #include <linux/signal.h>
  17 #include <linux/sched.h>
  18 #include <linux/interrupt.h>
  19 #include <linux/malloc.h>
  20 
  21 #include <asm/ptrace.h>
  22 #include <asm/processor.h>
  23 #include <asm/system.h>
  24 #include <asm/psr.h>
  25 #include <asm/vaddrs.h>
  26 #include <asm/timer.h>
  27 #include <asm/openprom.h>
  28 #include <asm/oplib.h>
  29 #include <asm/traps.h>
  30 #include <asm/irq.h>
  31 #include <asm/io.h>
  32 
  33 /* Pointer to the interrupt enable byte
  34  *
  35  * Dave Redman (djhr@tadpole.co.uk)
  36  * What you may not be aware of is that entry.S requires this variable.
  37  *
  38  *  --- linux_trap_nmi_sun4c --
  39  *
  40  * so don't go making it static, like I tried. sigh.
  41  */
  42 unsigned char *interrupt_enable = 0;
  43 
  44 static void sun4c_disable_irq(unsigned int irq_nr)
     /* [previous][next][first][last][top][bottom][index][help] */
  45 {
  46         unsigned long flags;
  47         unsigned char current_mask, new_mask;
  48     
  49         save_flags(flags); cli();
  50         irq_nr &= NR_IRQS;
  51         current_mask = *interrupt_enable;
  52         switch(irq_nr) {
  53         case 1:
  54                 new_mask = ((current_mask) & (~(SUN4C_INT_E1)));
  55                 break;
  56         case 8:
  57                 new_mask = ((current_mask) & (~(SUN4C_INT_E8)));
  58                 break;
  59         case 10:
  60                 new_mask = ((current_mask) & (~(SUN4C_INT_E10)));
  61                 break;
  62         case 14:
  63                 new_mask = ((current_mask) & (~(SUN4C_INT_E14)));
  64                 break;
  65         default:
  66                 restore_flags(flags);
  67                 return;
  68         }
  69         *interrupt_enable = new_mask;
  70         restore_flags(flags);
  71 }
  72 
  73 static void sun4c_enable_irq(unsigned int irq_nr)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75         unsigned long flags;
  76         unsigned char current_mask, new_mask;
  77     
  78         save_flags(flags); cli();
  79         irq_nr &= NR_IRQS;
  80         current_mask = *interrupt_enable;
  81         switch(irq_nr) {
  82         case 1:
  83                 new_mask = ((current_mask) | SUN4C_INT_E1);
  84                 break;
  85         case 8:
  86                 new_mask = ((current_mask) | SUN4C_INT_E8);
  87                 break;
  88         case 10:
  89                 new_mask = ((current_mask) | SUN4C_INT_E10);
  90                 break;
  91         case 14:
  92                 new_mask = ((current_mask) | SUN4C_INT_E14);
  93                 break;
  94         default:
  95                 restore_flags(flags);
  96                 return;
  97         }
  98         *interrupt_enable = new_mask;
  99         restore_flags(flags);
 100 }
 101 
 102 #define TIMER_IRQ       10    /* Also at level 14, but we ignore that one. */
 103 #define PROFILE_IRQ     14    /* Level14 ticker.. used by OBP for polling */
 104 
 105 volatile struct sun4c_timer_info *sun4c_timers;
 106 
 107 static void sun4c_clear_clock_irq(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 108 {
 109         volatile unsigned int clear_intr;
 110         clear_intr = sun4c_timers->timer_limit10;
 111 }
 112 
 113 static void sun4c_clear_profile_irq(void )
     /* [previous][next][first][last][top][bottom][index][help] */
 114 {
 115         /* Errm.. not sure how to do this.. */
 116 }
 117 
 118 static void sun4c_load_profile_irq(unsigned int limit)
     /* [previous][next][first][last][top][bottom][index][help] */
 119 {
 120         /* Errm.. not sure how to do this.. */
 121 }
 122 
 123 static void sun4c_init_timers(void (*counter_fn)(int, void *, struct pt_regs *))
     /* [previous][next][first][last][top][bottom][index][help] */
 124 {
 125         int irq;
 126 
 127         /* Map the Timer chip, this is implemented in hardware inside
 128          * the cache chip on the sun4c.
 129          */
 130         sun4c_timers = sparc_alloc_io ((void *) SUN4C_TIMER_PHYSADDR, 0,
 131                                        sizeof(struct sun4c_timer_info),
 132                                        "timer", 0x0, 0x0);
 133     
 134         /* Have the level 10 timer tick at 100HZ.  We don't touch the
 135          * level 14 timer limit since we are letting the prom handle
 136          * them until we have a real console driver so L1-A works.
 137          */
 138         sun4c_timers->timer_limit10 = (((1000000/HZ) + 1) << 10);
 139 
 140         irq = request_irq(TIMER_IRQ,
 141                           counter_fn,
 142                           (SA_INTERRUPT | SA_STATIC_ALLOC),
 143                           "timer", NULL);
 144         if (irq) {
 145                 prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ);
 146                 prom_halt();
 147         }
 148     
 149         claim_ticker14(NULL, PROFILE_IRQ, 0);
 150 }
 151 
 152 static void sun4c_nop(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 153 {
 154 }
 155 
 156 void sun4c_init_IRQ(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 157 {
 158         struct linux_prom_registers int_regs[2];
 159         int ie_node;
 160     
 161         ie_node = prom_searchsiblings (prom_getchild(prom_root_node),
 162                                        "interrupt-enable");
 163         if(ie_node == 0)
 164                 panic("Cannot find /interrupt-enable node");
 165 
 166         /* Depending on the "address" property is bad news... */
 167         prom_getproperty(ie_node, "reg", (char *) int_regs, sizeof(int_regs));
 168         interrupt_enable = (char *) sparc_alloc_io(int_regs[0].phys_addr, 0,
 169                                                    int_regs[0].reg_size,
 170                                                    "sun4c_interrupts",
 171                                                    int_regs[0].which_io, 0x0);
 172         enable_irq = sun4c_enable_irq;
 173         disable_irq = sun4c_disable_irq;
 174         clear_clock_irq = sun4c_clear_clock_irq;
 175         clear_profile_irq = sun4c_clear_profile_irq;
 176         load_profile_irq = sun4c_load_profile_irq;
 177         init_timers = sun4c_init_timers;
 178 #ifdef __SMP__
 179         set_cpu_int = sun4c_nop;
 180         clear_cpu_int = sun4c_nop;
 181         set_irq_udt = sun4c_nop;
 182 #endif
 183         *interrupt_enable = (SUN4C_INT_ENABLE);
 184         sti();
 185 }

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