home *** CD-ROM | disk | FTP | other *** search
- /* $Id: lxirq.c,v 1.2 2002/04/26 23:09:23 smilcke Exp $ */
-
- /*
- * irq.c
- * Autor: Stefan Milcke
- * Erstellt am: 10.11.2001
- * Letzte Aenderung am: 19.03.2002
- *
- */
- #define INCL_NOPMAPI
- #define INCL_DOSERRORS // for ERROR_INVALID_FUNCTION
- #include <os2.h>
- #include <ldefos2.h>
- #include "irqos2.h"
-
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/mm.h>
- #include <linux/version.h>
- #include <linux/module.h>
- #include <linux/delay.h>
- #include <linux/types.h>
- #include <linux/timer.h>
- //#include <linux/irq.h>
- #include <linux/signal.h>
-
- struct irq_handler
- {
- char name[32];
- int irq;
- unsigned long flags;
- void *data;
- struct pt_regs *regs;
-
- void (*fn)(int,void *,struct pt_regs*);
- };
-
- #define MAX_IRQ_HANDLERS 20
-
- spinlock_t irqlist_lock=SPIN_LOCK_UNLOCKED;
-
- struct irq_handler irq_handlers[MAX_IRQ_HANDLERS]={0};
-
- void EoiIrq(int irq);
- int RequestIrq(int irq,int flags);
- void FreeIrq(int irq);
-
- extern unsigned long OS2_request_irq(struct lxrm_resource* rm_resource
- ,unsigned int irq,unsigned long flags);
- extern unsigned long OS2_free_irq(struct lxrm_resource* rm_resource
- ,unsigned int irq);
- //-------------------------------- request_irq ---------------------------------
- int request_irq(unsigned int irq
- ,void (*handler)(int, void *, struct pt_regs *regs)
- ,unsigned long flags,const char *name, void *data
- ,struct lxrm_resource* rm_resource)
- {
- int i,ret=0,rc;
- unsigned long f;
- int used=0;
- ret=OS2_request_irq(rm_resource,irq,flags);
- if(ret)
- return ret;
- spin_lock_irqsave(&irqlist_lock,f);
- for(i=0;i<MAX_IRQ_HANDLERS;i++)
- {
- if(0==irq_handlers[i].irq)
- {
- struct irq_handler *p=&(irq_handlers[i]);
- strcpy(p->name,name);
- p->irq=irq;
- p->flags=flags;
- p->data=data;
- p->regs=NULL;
- p->fn=handler;
- break;
- }
- }
- if(i>=MAX_IRQ_HANDLERS)
- ret=-1;
- else
- {
- for(i=0;i<MAX_IRQ_HANDLERS;i++)
- if(irq_handlers[i].irq==irq)
- used++;
- }
- spin_unlock_irqrestore(&irqlist_lock,f);
- if(1==used)
- {
- if(flags&SA_SHIRQ)
- rc=RequestIrq(irq,1);
- else
- rc=RequestIrq(irq,0);
- }
- return ret;
- }
-
- //---------------------------------- free_irq ----------------------------------
- void free_irq(unsigned int irq, void *data
- ,struct lxrm_resource* rm_resource)
- {
- int i;
- unsigned long f;
- int used=0;
- spin_lock_irqsave(&irqlist_lock,f);
- for(i=0;i<MAX_IRQ_HANDLERS;i++)
- {
- if(irq_handlers[i].irq==irq)
- {
- used++;
- if(irq_handlers[i].data==data)
- irq_handlers[i].irq=0;
- }
- }
- if(used>1)
- FreeIrq(irq);
- spin_unlock_irqrestore(&irqlist_lock,f);
- OS2_free_irq(rm_resource,irq);
- }
-
- //---------------------------------- eoi_irq -----------------------------------
- void eoi_irq(unsigned int irq)
- {
- EoiIrq(irq);
- }
-
- extern unsigned long *IRQLevelPtr;
-
- //-------------------------------- irq_handler ---------------------------------
- void __far irq_handler(int irq);
- #pragma aux irq_handler "irq_handler"
- void __far irq_handler(int irq)
- {
- int i;
- for(i=0;i<MAX_IRQ_HANDLERS;i++)
- {
- if(irq_handlers[i].irq==irq)
- {
- struct irq_handler *p=&(irq_handlers[i]);
- p->fn(irq,p->data,p->regs);
- if(0==(p->flags&SA_SHIRQ))
- eoi_irq(irq);
- }
- }
- }
-