[BACK]Return to tairqc.c CVS log [TXT][DIR] Up to [local] / funnyos / arch / testarm / dev

Diff for /funnyos/arch/testarm/dev/tairqc.c between version 1.1 and 1.7

version 1.1, 2007/10/29 20:12:18 version 1.7, 2007/11/05 20:11:25
Line 4 
Line 4 
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/device.h>  #include <sys/device.h>
 #include <sys/bus.h>  #include <sys/bus.h>
   #include <sys/kern_irq.h>
   
   #include <dev/cpuvar.h>
   
 #include <arch/testarm/dev/tairqcvar.h>  #include <arch/testarm/dev/tairqcvar.h>
 #include <arch/testarm/dev/tairqcreg.h>  #include <arch/testarm/dev/tairqcreg.h>
   #include <libkern/printf.h>
   
   /* #define TAIRQC_DEBUG */
   
   #ifdef TAIRQC_DEBUG
   #define DPRINTF(x...)   do { printf(x); } while (0)
   #else
   #define DPRINTF(x...)   { }
   #endif
   
 /*  /*
  * testarm Interrupt Controller Unit support.   * testarm Interrupt Controller Unit support.
  */   */
 int     tairqc_attach(struct device *self, uint32_t loc, uint8_t flags);  int     tairqc_attach(struct device *self, uint32_t loc, uint8_t flags);
   void    tairqc_mask_intr(uint8_t intrno);
   void    tairqc_unmask_intr(uint8_t intrno);
   uint32_t tairqc_intrstatus(void);
 void    tairqc_irq(void);  void    tairqc_irq(void);
   
   extern void (*irq_trampoline_func)(void);
   struct tairqc_dd *irqcdd;                       /* current irq device */
   
 struct driver tairqc_dr = {  struct driver tairqc_dr = {
         sizeof(struct tairqc_dd),          sizeof(struct tairqc_dd),
         tairqc_attach,          tairqc_attach,
           NULL,
         NULL          NULL
 };  };
   
Line 26 
Line 44 
 tairqc_attach(struct device *self, uint32_t loc, uint8_t flags)  tairqc_attach(struct device *self, uint32_t loc, uint8_t flags)
 {  {
         struct tairqc_dd *ddp = self->dv_devdata;          struct tairqc_dd *ddp = self->dv_devdata;
           uint8_t intrno;
   
         /* leap to parent's bus_handle */          /* leap to parent's bus_handle */
         ddp->td_bushandlep = self->dv_parent->dv_aux;          ddp->td_bushandlep = self->dv_parent->dv_aux;
   
           /* save locator */
           ddp->td_ioaddr = loc ? loc : TAIRQC_REG_BASE;
   
           irqcdd = ddp;
   
           printf("testarm IRQ Controller (2=cons, 3=ether, 4=rtc, 6=mp)\n");
   
           /* override trampoline so core irq jumps to us */
           irq_trampoline_func = tairqc_irq;
   
           /* mask all interrupts */
           for (intrno = 0; intrno < 32; intrno++)
                   tairqc_mask_intr(intrno);
   
           /* XXX unmask rtc intr */
           tairqc_unmask_intr(4);
   
           __cpu_enable_irq();
   
           return(0);
 }  }
   
   
 void  void
   tairqc_mask_intr(uint8_t intrno)
   {
           bus_write_1(irqcdd->td_bushandlep, irqcdd->td_ioaddr + TAIRQC_OFF_IRQMASK, intrno);
           DPRINTF("tairqc_mask_intr: masked interrupt no. %d (status=0x%x)\n", intrno, tairqc_intrstatus());
   }
   
   
   void
   tairqc_unmask_intr(uint8_t intrno)
   {
           bus_write_1(irqcdd->td_bushandlep, irqcdd->td_ioaddr + TAIRQC_OFF_IRQUNMASK, intrno);
           DPRINTF("tairqc_unmask_intr: unmasked interrupt no. %d (status=0x%x)\n", intrno, tairqc_intrstatus());
   }
   
   
   uint32_t
   tairqc_intrstatus(void)
   {
           bus_read_4(irqcdd->td_bushandlep, irqcdd->td_ioaddr + TAIRQC_OFF_IRQSTATUS);
   }
   
   
   void
 tairqc_irq(void)  tairqc_irq(void)
 {  {
         /*          /*
          * Process an IRQ           * Process an IRQ.
            * Check interrupt status of the irqc and execute corresponding intr handlers
            * for every asserted interrupt source (could be 0...31 on tairqc)
          */           */
           uint32_t irqstatus;
           uint8_t intrno;
   
           /* read intr status; one bit per intr source */
           irqstatus = tairqc_intrstatus();
   
           DPRINTF("tairqc_irq: got interrupt (status=0x%x)\n", irqstatus);
   
           /* exit if no interrupts; should not happen */
           if (irqstatus == 0)
                   return;
   
           /* let kern_irq throw us to the right place */
           for (intrno = 0; intrno < 32; intrno++)
                   if (irqstatus & (1 << intrno)) {
                           /* interrupt line is active */
                           intr_execute(intrno);
                   }
   
 }  }
   

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.7

CVSweb