⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ints.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
字号:
/* *  linux/arch/m68k/hp300/ints.c * *  Copyright (C) 1998 Philip Blundell <philb@gnu.org> * *  This file contains the HP300-specific interrupt handling. *  We only use the autovector interrupts, and therefore we need to *  maintain lists of devices sharing each ipl. *  [ipl list code added by Peter Maydell <pmaydell@chiark.greenend.org.uk> 06/1998] */#include <linux/kernel.h>#include <linux/types.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/kernel_stat.h>#include <linux/interrupt.h>#include <linux/spinlock.h>#include <asm/machdep.h>#include <asm/irq.h>#include <asm/io.h>#include <asm/system.h>#include <asm/traps.h>#include <asm/ptrace.h>#include "ints.h"/* Each ipl has a linked list of interrupt service routines. * Service routines are added via hp300_request_irq() and removed * via hp300_free_irq(). The device driver should set IRQ_FLG_FAST * if it needs to be serviced early (eg FIFOless UARTs); this will * cause it to be added at the front of the queue rather than  * the back. * Currently IRQ_FLG_SLOW and flags=0 are treated identically; if * we needed three levels of priority we could distinguish them * but this strikes me as mildly ugly... *//* we start with no entries in any list */static irq_node_t *hp300_irq_list[HP300_NUM_IRQS] = { [0 ... HP300_NUM_IRQS-1] = NULL };static spinlock_t irqlist_lock;/* This handler receives all interrupts, dispatching them to the registered handlers */static void hp300_int_handler(int irq, void *dev_id, struct pt_regs *fp){        irq_node_t *t;        /* We just give every handler on the chain an opportunity to handle         * the interrupt, in priority order.         */        for(t = hp300_irq_list[irq]; t; t=t->next)                t->handler(irq, t->dev_id, fp);        /* We could put in some accounting routines, checks for stray interrupts,         * etc, in here. Note that currently we can't tell whether or not         * a handler handles the interrupt, though.          */}void (*hp300_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {	hp300_int_handler, hp300_int_handler, hp300_int_handler, hp300_int_handler,	hp300_int_handler, hp300_int_handler, hp300_int_handler, NULL};/* dev_id had better be unique to each handler because it's the only way we have * to distinguish handlers when removing them... * * It would be pretty easy to support IRQ_FLG_LOCK (handler is not replacable) * and IRQ_FLG_REPLACE (handler replaces existing one with this dev_id) * if we wanted to. IRQ_FLG_FAST is needed for devices where interrupt latency * matters (eg the dreaded FIFOless UART...) */int hp300_request_irq(unsigned int irq,                      void (*handler) (int, void *, struct pt_regs *),                      unsigned long flags, const char *devname, void *dev_id){        irq_node_t *t, *n = new_irq_node();                if (!n)                                   /* oops, no free nodes */                return -ENOMEM;	spin_lock_irqsave(&irqlist_lock, flags);        if (!hp300_irq_list[irq]) {                /* no list yet */                hp300_irq_list[irq] = n;                n->next = NULL;        } else if (flags & IRQ_FLG_FAST) {                /* insert at head of list */                n->next = hp300_irq_list[irq];                hp300_irq_list[irq] = n;        } else {                /* insert at end of list */                for(t = hp300_irq_list[irq]; t->next; t = t->next)                        /* do nothing */;                n->next = NULL;                t->next = n;        }        /* Fill in n appropriately */        n->handler = handler;        n->flags = flags;        n->dev_id = dev_id;        n->devname = devname;	spin_unlock_irqrestore(&irqlist_lock, flags);	return 0;}void hp300_free_irq(unsigned int irq, void *dev_id){        irq_node_t *t;        unsigned long flags;        spin_lock_irqsave(&irqlist_lock, flags);                t = hp300_irq_list[irq];        if (!t)                                   /* no handlers at all for that IRQ */        {                printk(KERN_ERR "hp300_free_irq: attempt to remove nonexistent handler for IRQ %d\n", irq);                spin_unlock_irqrestore(&irqlist_lock, flags);		return;        }                if (t->dev_id == dev_id)        {                                         /* removing first handler on chain */                t->flags = IRQ_FLG_STD;           /* we probably don't really need these */                t->dev_id = NULL;                t->devname = NULL;                t->handler = NULL;                /* frees this irq_node_t */                hp300_irq_list[irq] = t->next;		spin_unlock_irqrestore(&irqlist_lock, flags);		return;        }                /* OK, must be removing from middle of the chain */                for (t = hp300_irq_list[irq]; t->next && t->next->dev_id != dev_id; t = t->next)                /* do nothing */;        if (!t->next)        {                printk(KERN_ERR "hp300_free_irq: attempt to remove nonexistent handler for IRQ %d\n", irq);		spin_unlock_irqrestore(&irqlist_lock, flags);		return;        }        /* remove the entry after t: */        t->next->flags = IRQ_FLG_STD;        t->next->dev_id = t->next->devname = t->next->handler = NULL;        t->next = t->next->next;        	spin_unlock_irqrestore(&irqlist_lock, flags);}int hp300_get_irq_list(char *buf){	return 0;}void __init hp300_init_IRQ(void){	spin_lock_init(&irqlist_lock);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -