From: M. R. B. <mr...@us...> - 2001-03-01 10:54:20
|
Update of /cvsroot/linuxdc/linux/arch/sh/kernel In directory usw-pr-cvs1:/tmp/cvs-serv8952/arch/sh/kernel Modified Files: setup_powervr2dc.c Log Message: IRQ offset and NMI fixes Index: setup_powervr2dc.c =================================================================== RCS file: /cvsroot/linuxdc/linux/arch/sh/kernel/setup_powervr2dc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** setup_powervr2dc.c 2001/02/21 15:22:11 1.1 --- setup_powervr2dc.c 2001/03/01 10:55:42 1.2 *************** *** 83,92 **** static inline void disable_powervr2dc_irq(unsigned int irq) { ! clear_bit(irq, (volatile unsigned long *)PVR2DC_REG_IMRA); } static inline void enable_powervr2dc_irq(unsigned int irq) { ! set_bit(irq, (volatile unsigned long *)PVR2DC_REG_IMRA); } --- 83,92 ---- static inline void disable_powervr2dc_irq(unsigned int irq) { ! clear_bit(irq - PVR2DC_IRQ_BASE, (volatile unsigned long *)PVR2DC_REG_IMRA); } static inline void enable_powervr2dc_irq(unsigned int irq) { ! set_bit(irq - PVR2DC_IRQ_BASE, (volatile unsigned long *)PVR2DC_REG_IMRA); } *************** *** 98,102 **** static void ack_powervr2dc_irq(unsigned int irq) { ! set_bit(irq, (volatile unsigned long *)PVR2DC_REG_IPRA); } --- 98,103 ---- static void ack_powervr2dc_irq(unsigned int irq) { ! test_and_set_bit(irq - PVR2DC_IRQ_BASE, ! (volatile unsigned long *)PVR2DC_REG_IPRA); } *************** *** 104,108 **** static void end_powervr2dc_irq(unsigned int irq) { ! enable_powervr2dc_irq(irq); } --- 105,109 ---- static void end_powervr2dc_irq(unsigned int irq) { ! /*enable_powervr2dc_irq(irq);*/ } *************** *** 129,133 **** }; - /* Just to satisfy my own curiosities :) */ static void powervr2dc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { --- 130,133 ---- *************** *** 144,171 **** /* ! * That handy bitfield again. To demux IRQ9, just find the first non-zero bit ! * to use as the source. There's only one problem: if you get multiple interrupt ! * sources per IRQ, how do you demux those? */ - /* XXX: Need to make sure all int. sources are being handled per IRQ! Is this - * handled in irq.c:handle_IRQ_event()/do_IRQ() ? */ int powervr2dc_irq_demux(int irq) { if (irq == PVR2DC_IRQ) { ! u32 i = 0, bit; ! u32 ipr, req; ! ! /* Brute force scan each int. pending register. ! * This also needs fixing. */ ! for (ipr = PVR2DC_REG_IPRA ; ipr <= PVR2DC_REG_IPRC ; ipr += 4) { ! req = ctrl_inl(ipr); ! for (bit = 1 ; i < PVR2DC_IRQ_NUM ; bit <<= 1, i++) ! if (req & bit) ! goto found; } found: ! if (i < PVR2DC_IRQ_NUM) irq = PVR2DC_IRQ_BASE + i; } --- 144,175 ---- /* ! * There initially was a problem with pvr2dc NMI's (namely the scanline triggers) ! * occurring faster than what we could handle. Right now this is fixed a) because ! * nothing uses the scanline ints yet; and b) I should've known to remask the IPR ! * just in case this happened :). */ int powervr2dc_irq_demux(int irq) { if (irq == PVR2DC_IRQ) { ! u32 i = 0, j, bit; ! u32 ipr, reg; ! /* ! * Scan through each IPR and return the first found interrupt ! * (make sure we mask out those we don't want). ! */ ! for (ipr = PVR2DC_REG_IPRA ; ipr <= PVR2DC_REG_IPRC ; ipr += 4) { ! reg = ctrl_inl(ipr); ! /* Only because the IPR/IMR are parallel does this work */ ! reg &= ctrl_inl(ipr + 0x30); ! ! for (bit = 1, j = 0 ; j < 32 ; bit <<= 1, i++) ! if (reg & bit) ! goto found; } found: ! if (i < PVR2DC_IRQ_NUM) { irq = PVR2DC_IRQ_BASE + i; + } } *************** *** 183,189 **** } - for (i = PVR2DC_IRQ_BASE; i < PVR2DC_IRQ_BASE + PVR2DC_IRQ_NUM; i++) - irq_desc[i].handler = &powervr2dc_int; - ver_major = (ctrl_inl(PVR2DC_REG_VERSION) >> 4) & 0x0f; ver_minor = ctrl_inl(PVR2DC_REG_VERSION) & 0x0f; --- 187,190 ---- *************** *** 193,198 **** ver_major, ver_minor, PVR2DC_BASE, PVR2DC_IRQ, PVR2DC_IRQ_NUM); - setup_irq(PVR2DC_IRQ, &irq9); - /* Mask all interrupts. */ ctrl_outl(0, PVR2DC_REG_IMRA); --- 194,197 ---- *************** *** 207,210 **** --- 206,214 ---- ctrl_inl(PVR2DC_REG_IPRC); ctrl_outl(0xffffffff, PVR2DC_REG_IPRC); + + for (i = PVR2DC_IRQ_BASE; i < PVR2DC_IRQ_BASE + PVR2DC_IRQ_NUM; i++) + irq_desc[i].handler = &powervr2dc_int; + + setup_irq(PVR2DC_IRQ, &irq9); return 0; |