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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [m68k/] [kernel/] [ints.c] - Diff between revs 1765 and 1782

Only display areas with differences | Details | Blame | View Log

Rev 1765 Rev 1782
/*
/*
 * ints.c -- 680x0 Linux general interrupt handling code
 * ints.c -- 680x0 Linux general interrupt handling code
 *
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 * for more details.
 *
 *
 * 07/03/96: Timer initialization, and thus mach_sched_init(),
 * 07/03/96: Timer initialization, and thus mach_sched_init(),
 *           removed from request_irq() and moved to init_time().
 *           removed from request_irq() and moved to init_time().
 *           We should therefore consider renaming our add_isr() and
 *           We should therefore consider renaming our add_isr() and
 *           remove_isr() to request_irq() and free_irq()
 *           remove_isr() to request_irq() and free_irq()
 *           respectively, so they are compliant with the other
 *           respectively, so they are compliant with the other
 *           architectures.                                     /Jes
 *           architectures.                                     /Jes
 */
 */
 
 
#include <linux/types.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/kernel_stat.h>
#include <linux/errno.h>
#include <linux/errno.h>
 
 
#include <asm/system.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/irq.h>
#include <asm/traps.h>
#include <asm/traps.h>
#include <asm/page.h>
#include <asm/page.h>
#include <asm/machdep.h>
#include <asm/machdep.h>
 
 
/* list is accessed 0-6 for IRQs 1-7 */
/* list is accessed 0-6 for IRQs 1-7 */
static isr_node_t *isr_list[7];
static isr_node_t *isr_list[7];
 
 
/* The number of spurious interrupts */
/* The number of spurious interrupts */
volatile unsigned long num_spurious;
volatile unsigned long num_spurious;
/*
/*
unsigned long interrupt_stack[PAGE_SIZE/sizeof(long)];
unsigned long interrupt_stack[PAGE_SIZE/sizeof(long)];
*/
*/
 
 
/*
/*
 * void init_IRQ(void)
 * void init_IRQ(void)
 *
 *
 * Parameters:  None
 * Parameters:  None
 *
 *
 * Returns:     Nothing
 * Returns:     Nothing
 *
 *
 * This function should be called during kernel startup to initialize
 * This function should be called during kernel startup to initialize
 * the IRQ handling routines.
 * the IRQ handling routines.
 */
 */
 
 
void init_IRQ(void)
void init_IRQ(void)
{
{
    /* Setup interrupt stack pointer */
    /* Setup interrupt stack pointer */
  /*
  /*
    asm ("movec %0,%/isp"
    asm ("movec %0,%/isp"
         : : "r" (interrupt_stack + sizeof (interrupt_stack) / sizeof (long)));
         : : "r" (interrupt_stack + sizeof (interrupt_stack) / sizeof (long)));
         */
         */
    mach_init_INTS ();
    mach_init_INTS ();
}
}
 
 
void insert_isr (isr_node_t **listp, isr_node_t *node)
void insert_isr (isr_node_t **listp, isr_node_t *node)
{
{
    unsigned long spl;
    unsigned long spl;
    isr_node_t *cur;
    isr_node_t *cur;
 
 
    save_flags(spl);
    save_flags(spl);
    cli();
    cli();
 
 
    cur = *listp;
    cur = *listp;
 
 
    while (cur && cur->pri <= node->pri)
    while (cur && cur->pri <= node->pri)
    {
    {
        listp = &cur->next;
        listp = &cur->next;
        cur = cur->next;
        cur = cur->next;
    }
    }
 
 
    node->next = cur;
    node->next = cur;
    *listp = node;
    *listp = node;
 
 
    restore_flags(spl);
    restore_flags(spl);
}
}
 
 
void delete_isr (isr_node_t **listp, isrfunc isr, void *data)
void delete_isr (isr_node_t **listp, isrfunc isr, void *data)
{
{
    unsigned long flags;
    unsigned long flags;
    isr_node_t *np;
    isr_node_t *np;
 
 
    save_flags(flags);
    save_flags(flags);
    cli();
    cli();
    for (np = *listp; np; listp = &np->next, np = *listp) {
    for (np = *listp; np; listp = &np->next, np = *listp) {
        if (np->isr == isr && np->data == data) {
        if (np->isr == isr && np->data == data) {
            *listp = np->next;
            *listp = np->next;
            /* Mark it as free. */
            /* Mark it as free. */
            np->isr = NULL;
            np->isr = NULL;
            restore_flags(flags);
            restore_flags(flags);
            return;
            return;
        }
        }
    }
    }
    restore_flags(flags);
    restore_flags(flags);
    printk ("delete_isr: isr %p not found on list!\n", isr);
    printk ("delete_isr: isr %p not found on list!\n", isr);
}
}
 
 
#define NUM_ISR_NODES 100
#define NUM_ISR_NODES 100
static isr_node_t nodes[NUM_ISR_NODES];
static isr_node_t nodes[NUM_ISR_NODES];
 
 
isr_node_t *new_isr_node(void)
isr_node_t *new_isr_node(void)
{
{
    isr_node_t *np;
    isr_node_t *np;
 
 
    for (np = nodes; np < &nodes[NUM_ISR_NODES]; np++)
    for (np = nodes; np < &nodes[NUM_ISR_NODES]; np++)
        if (np->isr == NULL)
        if (np->isr == NULL)
            return np;
            return np;
 
 
    printk ("new_isr_node: out of nodes");
    printk ("new_isr_node: out of nodes");
    return NULL;
    return NULL;
}
}
 
 
int add_isr (unsigned long source, isrfunc isr, int pri, void *data,
int add_isr (unsigned long source, isrfunc isr, int pri, void *data,
             char *name)
             char *name)
{
{
    isr_node_t *p;
    isr_node_t *p;
 
 
    if (source & IRQ_MACHSPEC)
    if (source & IRQ_MACHSPEC)
    {
    {
        return mach_add_isr (source, isr, pri, data, name);
        return mach_add_isr (source, isr, pri, data, name);
    }
    }
 
 
    if (source < IRQ1 || source > IRQ7)
    if (source < IRQ1 || source > IRQ7)
        panic ("add_isr: Incorrect IRQ source %ld from %s\n", source, name);
        panic ("add_isr: Incorrect IRQ source %ld from %s\n", source, name);
 
 
    p = new_isr_node();
    p = new_isr_node();
    if (p == NULL)
    if (p == NULL)
        return 0;
        return 0;
    p->isr = isr;
    p->isr = isr;
    p->pri = pri;
    p->pri = pri;
    p->data = data;
    p->data = data;
    p->name = name;
    p->name = name;
    p->next = NULL;
    p->next = NULL;
 
 
    insert_isr (&isr_list[source-1], p);
    insert_isr (&isr_list[source-1], p);
 
 
    return 1;
    return 1;
}
}
 
 
int remove_isr (unsigned long source, isrfunc isr, void *data)
int remove_isr (unsigned long source, isrfunc isr, void *data)
{
{
    if (source & IRQ_MACHSPEC)
    if (source & IRQ_MACHSPEC)
        return mach_remove_isr (source, isr, data);
        return mach_remove_isr (source, isr, data);
 
 
    if (source < IRQ1 || source > IRQ7) {
    if (source < IRQ1 || source > IRQ7) {
        printk ("remove_isr: Incorrect IRQ source %ld\n", source);
        printk ("remove_isr: Incorrect IRQ source %ld\n", source);
        return 0;
        return 0;
    }
    }
 
 
    delete_isr (&isr_list[source - 1], isr, data);
    delete_isr (&isr_list[source - 1], isr, data);
    return 1;
    return 1;
}
}
 
 
void call_isr_list(int irq, isr_node_t *p, struct pt_regs *fp)
void call_isr_list(int irq, isr_node_t *p, struct pt_regs *fp)
{
{
    while (p) {
    while (p) {
        p->isr (irq, fp, p->data);
        p->isr (irq, fp, p->data);
        p = p->next;
        p = p->next;
    }
    }
}
}
 
 
asmlinkage void process_int(int vec, struct pt_regs *regs)
asmlinkage void process_int(int vec, struct pt_regs *regs)
{
{
        int level;
        int level;
 
 
        if (vec >= VECOFF(VEC_INT1) && vec <= VECOFF(VEC_INT7))
        if (vec >= VECOFF(VEC_INT1) && vec <= VECOFF(VEC_INT7))
                level = (vec - VECOFF(VEC_SPUR)) >> 2;
                level = (vec - VECOFF(VEC_SPUR)) >> 2;
        else {
        else {
                if (mach_process_int)
                if (mach_process_int)
                        mach_process_int(vec, regs);
                        mach_process_int(vec, regs);
                else
                else
                        panic("Can't process interrupt vector 0x%03x\n", vec);
                        panic("Can't process interrupt vector 0x%03x\n", vec);
                return;
                return;
        }
        }
 
 
        kstat.interrupts[level]++;
        kstat.interrupts[level]++;
        call_isr_list (level, isr_list[level-1], regs);
        call_isr_list (level, isr_list[level-1], regs);
}
}
 
 
int request_irq(unsigned int irq,
int request_irq(unsigned int irq,
                void (*handler)(int, void *, struct pt_regs *),
                void (*handler)(int, void *, struct pt_regs *),
                unsigned long flags, const char * devname, void *dev_id)
                unsigned long flags, const char * devname, void *dev_id)
{
{
        return -EINVAL;
        return -EINVAL;
}
}
 
 
void free_irq(unsigned int irq, void *dev_id)
void free_irq(unsigned int irq, void *dev_id)
{
{
}
}
 
 
/*
/*
 * Do we need these probe functions on the m68k?
 * Do we need these probe functions on the m68k?
 */
 */
unsigned long probe_irq_on (void)
unsigned long probe_irq_on (void)
{
{
  return 0;
  return 0;
}
}
 
 
int probe_irq_off (unsigned long irqs)
int probe_irq_off (unsigned long irqs)
{
{
  return 0;
  return 0;
}
}
 
 
void enable_irq(unsigned int irq_nr)
void enable_irq(unsigned int irq_nr)
{
{
        if ((irq_nr & IRQ_MACHSPEC) && mach_enable_irq)
        if ((irq_nr & IRQ_MACHSPEC) && mach_enable_irq)
                mach_enable_irq(irq_nr);
                mach_enable_irq(irq_nr);
}
}
 
 
void disable_irq(unsigned int irq_nr)
void disable_irq(unsigned int irq_nr)
{
{
        if ((irq_nr & IRQ_MACHSPEC) && mach_disable_irq)
        if ((irq_nr & IRQ_MACHSPEC) && mach_disable_irq)
                mach_disable_irq(irq_nr);
                mach_disable_irq(irq_nr);
}
}
 
 
int get_irq_list(char *buf)
int get_irq_list(char *buf)
{
{
    int i, len = 0;
    int i, len = 0;
    isr_node_t *p;
    isr_node_t *p;
 
 
    /* autovector interrupts */
    /* autovector interrupts */
    for (i = IRQ1; i <= IRQ7; ++i) {
    for (i = IRQ1; i <= IRQ7; ++i) {
        if (!isr_list[i-1])
        if (!isr_list[i-1])
            continue;
            continue;
        len += sprintf(buf+len, "auto %2d: %8d ", i, kstat.interrupts[i]);
        len += sprintf(buf+len, "auto %2d: %8d ", i, kstat.interrupts[i]);
        for (p = isr_list[i-1]; p; p = p->next) {
        for (p = isr_list[i-1]; p; p = p->next) {
            len += sprintf(buf+len, "%s\n", p->name);
            len += sprintf(buf+len, "%s\n", p->name);
            if (p->next)
            if (p->next)
                len += sprintf(buf+len, "                  ");
                len += sprintf(buf+len, "                  ");
        }
        }
    }
    }
 
 
    len = mach_get_irq_list(buf, len);
    len = mach_get_irq_list(buf, len);
    return len;
    return len;
}
}
 
 

powered by: WebSVN 2.1.0

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