OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [lib/] [irqs-trio.c] - Diff between revs 1622 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 1622 Rev 1765
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
 
 
#include <asm/io.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/hardware.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/irq.h>
#include <asm/arch/irq.h>
#include <asm/arch/irq.h>
 
 
 
 
 
 
/* The trio AIC need to recive EOI command at the end of interrupt handler,
/* The trio AIC need to recive EOI command at the end of interrupt handler,
   These command is compossed from previous IRQ nr and previous IRQ priority.
   These command is compossed from previous IRQ nr and previous IRQ priority.
   So we maintain this value in the trio_irq_prority variable.
   So we maintain this value in the trio_irq_prority variable.
 
 
   The trio_irq_prtable contains the priority<<5 for each IRQ
   The trio_irq_prtable contains the priority<<5 for each IRQ
*/
*/
 
 
volatile unsigned char trio_irq_priority = 0; /* Current IRQ number and priority */
volatile unsigned char trio_irq_priority = 0; /* Current IRQ number and priority */
unsigned char trio_irq_prtable[16] = {
unsigned char trio_irq_prtable[16] = {
        7,  /* FIQ */
        7,  /* FIQ */
        0,  /* WDIRQ */
        0,  /* WDIRQ */
        0,  /* SWIRQ */
        0,  /* SWIRQ */
        2, /* UAIRQ */
        2, /* UAIRQ */
        0,               /* TC0 (Timer 0 used for DRAM refresh */
        0,               /* TC0 (Timer 0 used for DRAM refresh */
        1, /* TC1IRQ */
        1, /* TC1IRQ */
        0,               /* TC2IRQ */
        0,               /* TC2IRQ */
        0,  /* PIOAIRQ */
        0,  /* PIOAIRQ */
        0,  /* LCDIRQ not used */
        0,  /* LCDIRQ not used */
        5, /* SPIIRQ */
        5, /* SPIIRQ */
        4, /* IRQ0, (ETHERNET? )*/
        4, /* IRQ0, (ETHERNET? )*/
        0,  /* IRQ1 */
        0,  /* IRQ1 */
        6,  /* OAKAIRQ */
        6,  /* OAKAIRQ */
        6,  /* OAKBIRQ */
        6,  /* OAKBIRQ */
        3, /* UBIRQ */
        3, /* UBIRQ */
        5 /* PIOBIRQ */
        5 /* PIOBIRQ */
 
 
};
};
 
 
void do_IRQ(int irq, struct pt_regs * regs);
void do_IRQ(int irq, struct pt_regs * regs);
 
 
 
 
inline void irq_ack(int priority)
inline void irq_ack(int priority)
{
{
        outl(priority, AIC_EOICR);
        outl(priority, AIC_EOICR);
}
}
 
 
asmlinkage int probe_IRQ_interrupt(int irq, struct pt_regs * regs)
asmlinkage int probe_IRQ_interrupt(int irq, struct pt_regs * regs)
{
{
        mask_irq(irq);
        mask_irq(irq);
        irq_ack(trio_irq_priority);
        irq_ack(trio_irq_priority);
        return 0;
        return 0;
}
}
 
 
asmlinkage int bad_IRQ_interrupt(int irqn, struct pt_regs * regs)
asmlinkage int bad_IRQ_interrupt(int irqn, struct pt_regs * regs)
{
{
        printk("bad interrupt %d recieved!\n", irqn);
        printk("bad interrupt %d recieved!\n", irqn);
        irq_ack(trio_irq_priority);
        irq_ack(trio_irq_priority);
        return 0;
        return 0;
}
}
 
 
asmlinkage int IRQ_interrupt(int irq, struct pt_regs * regs)
asmlinkage int IRQ_interrupt(int irq, struct pt_regs * regs)
{
{
        register unsigned long flags;
        register unsigned long flags;
        register unsigned long saved_count;
        register unsigned long saved_count;
        register unsigned char spr = trio_irq_priority;
        register unsigned char spr = trio_irq_priority;
 
 
        trio_irq_priority = ((unsigned char)irq) | trio_irq_prtable[irq];
        trio_irq_priority = ((unsigned char)irq) | trio_irq_prtable[irq];
 
 
 
 
        saved_count = intr_count;
        saved_count = intr_count;
        intr_count = saved_count + 1;
        intr_count = saved_count + 1;
 
 
        save_flags(flags);
        save_flags(flags);
        sti();
        sti();
        do_IRQ(irq, regs);
        do_IRQ(irq, regs);
        restore_flags(flags);
        restore_flags(flags);
        intr_count = saved_count;
        intr_count = saved_count;
        trio_irq_priority = spr;
        trio_irq_priority = spr;
        irq_ack(spr);
        irq_ack(spr);
        return 0;
        return 0;
}
}
 
 
 
 
asmlinkage int timer_IRQ_interrupt(int irq, struct pt_regs * regs)
asmlinkage int timer_IRQ_interrupt(int irq, struct pt_regs * regs)
{
{
        register unsigned long flags;
        register unsigned long flags;
        register unsigned long saved_count;
        register unsigned long saved_count;
        register unsigned char spr = trio_irq_priority;
        register unsigned char spr = trio_irq_priority;
 
 
        trio_irq_priority = ((unsigned char)irq) | trio_irq_prtable[irq];
        trio_irq_priority = ((unsigned char)irq) | trio_irq_prtable[irq];
 
 
 
 
 
 
        saved_count = intr_count;
        saved_count = intr_count;
        intr_count = saved_count + 1;
        intr_count = saved_count + 1;
 
 
        save_flags(flags);
        save_flags(flags);
        do_IRQ(irq, regs);
        do_IRQ(irq, regs);
        restore_flags(flags);
        restore_flags(flags);
        intr_count = saved_count;
        intr_count = saved_count;
        trio_irq_priority = spr;
        trio_irq_priority = spr;
        irq_ack(spr);
        irq_ack(spr);
        return 0;
        return 0;
}
}
 
 
 
 
asmlinkage int fast_IRQ_interrupt(int irq, struct pt_regs * regs)
asmlinkage int fast_IRQ_interrupt(int irq, struct pt_regs * regs)
{
{
        register unsigned long saved_count;
        register unsigned long saved_count;
 
 
        saved_count = intr_count;
        saved_count = intr_count;
        intr_count = saved_count + 1;
        intr_count = saved_count + 1;
 
 
        do_IRQ(irq, regs);
        do_IRQ(irq, regs);
        cli();
        cli();
        intr_count = saved_count;
        intr_count = saved_count;
        inl(AIC_FVR);
        inl(AIC_FVR);
        return 1;
        return 1;
}
}
 
 
void trio_init_aic()
void trio_init_aic()
{
{
        int irqno;
        int irqno;
 
 
        // Disable all interrupts
        // Disable all interrupts
        outl(0xFFFFFFFF, AIC_IDCR);
        outl(0xFFFFFFFF, AIC_IDCR);
 
 
        // Clear all interrupts
        // Clear all interrupts
        outl(0xFFFFFFFF, AIC_ICCR);
        outl(0xFFFFFFFF, AIC_ICCR);
 
 
        for ( irqno = 0 ; irqno < 8 ; irqno++ )
        for ( irqno = 0 ; irqno < 8 ; irqno++ )
        {
        {
                outl(irqno, AIC_EOICR);
                outl(irqno, AIC_EOICR);
        }
        }
 
 
 
 
 
 
        for ( irqno = 0 ; irqno < 16 ; irqno++ )
        for ( irqno = 0 ; irqno < 16 ; irqno++ )
        {
        {
                outl(trio_irq_prtable[irqno]  |  (1 << 5), AIC_SMR(irqno));
                outl(trio_irq_prtable[irqno]  |  (1 << 5), AIC_SMR(irqno));
        }
        }
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.