]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/irq.c
CAN driver infrastructure redesign to LinCAN-0.2 version
[lincan.git] / lincan / src / irq.c
index caf0ac6ebda7eec416401f8c68f1b8756a3d4514..1623ce8ea38617209d69a1206778cd3df6a34452 100644 (file)
@@ -1,18 +1,13 @@
 /* irq.c
  * Linux CAN-bus device driver.
  * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
+ * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
+ * email:pisa@cmp.felk.cvut.cz
  * This software is released under the GPL-License.
- * Version 0.7  6 Aug 2001
+ * Version lincan-0.2  9 Jul 2003
  */
 
 #include <linux/autoconf.h>
-#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS)
-#define MODVERSIONS
-#endif
-
-#if defined (MODVERSIONS)
-#include <linux/modversions.h>
-#endif 
 
 #include <linux/sched.h>
 #include <linux/version.h>
 
 #include "../include/main.h"
 #include "../include/irq.h"
-#include "../include/i82527.h"
-#include "../include/sja1000.h"
-
-void i82527_irq_rtr_handler(struct chip_t *chip, struct msgobj_t *msgobj, 
-                           struct rtr_id *rtr_search, unsigned long message_id);
-void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *msgobj);
-void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *msgobj);
-
-/*struct candevice_t *device=NULL;
-unsigned object=0,irq_register=0;
-unsigned long msgbase=0;
-struct canfifo_t *fifo=NULL;
-unsigned long message_id=0;
-struct rtr_id *rtr_search;
-*/
-
-inline void i82527_irq_write_handler(struct chip_t *chip, struct msgobj_t *msgobj)
-{
-       struct canfifo_t *fifo=msgobj->fifo;
-       unsigned long msgbase=msgobj->obj_base_addr;
-       void (*write_reg)(unsigned char data, unsigned long address);
-       unsigned (*read_reg)(unsigned long address);
-       write_reg=chip->hostdevice->hwspecops->write_register;
-       read_reg=chip->hostdevice->hwspecops->read_register;
-
-       (*write_reg)((MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),msgbase+iMSGCTL0);
-
-       fifo->tx_readp++;
-       if (fifo->tx_readp >= fifo->buf_tx_entry + MAX_BUF_LENGTH)
-               fifo->tx_readp = fifo->buf_tx_entry;
-       if (fifo->tx_readp == fifo->tx_writep) { // Output buffer is empty
-               fifo->tx_in_progress = 0;
-               if (waitqueue_active(&fifo->writeq)) {
-                       msgobj->ret = 0;
-                       wake_up_interruptible(&fifo->writeq);
-               }
-               return;
-       }
-       if (chip->chipspecops->pre_write_config(chip, msgobj, fifo->tx_readp)) {
-               if (waitqueue_active(&fifo->writeq)) {
-                       msgobj->ret = -1;
-                       wake_up_interruptible(&fifo->writeq);
-                       return;
-               }
-       }
-       if (chip->chipspecops->send_msg(chip, msgobj, fifo->tx_readp)) {
-               if (waitqueue_active(&fifo->writeq)) {
-                       msgobj->ret = -1;
-                       wake_up_interruptible(&fifo->writeq);
-                       return;
-               }
-       } 
-}
-
-inline void i82527_irq_read_handler(struct chip_t *chip, struct msgobj_t *msgobj,
-                                   unsigned long message_id)
-{
-       int i=0, tmp=1 ;
-       struct canfifo_t *fifo=msgobj->fifo;
-       unsigned long msgbase=msgobj->obj_base_addr;
-       void (*write_reg)(unsigned char data, unsigned long address);
-       unsigned (*read_reg)(unsigned long address);
-       write_reg=chip->hostdevice->hwspecops->write_register;
-       read_reg=chip->hostdevice->hwspecops->read_register;
-       
-       while (tmp) {
-               (*write_reg)((RMPD_RES|TXRQ_RES|MLST_RES|NEWD_RES), msgbase +
-                                                               iMSGCTL1);
-               (*write_reg)((MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES), msgbase +
-                                                               iMSGCTL0);
-
-               fifo->rx_writep->length =((*read_reg)(msgbase+iMSGCFG) & 0xf0) >> 4;
-               fifo->rx_writep->id = message_id;
-               for (i=0; i < fifo->rx_writep->length; i++)
-                       fifo->rx_writep->data[i] = (*read_reg)(msgbase+iMSGDAT0+i);
-
-//FIXME: Add buffer overflow check, currently it's silently over written!
-
-               fifo->rx_writep++;
-               if (fifo->rx_writep >= fifo->buf_rx_entry + MAX_BUF_LENGTH)
-                       fifo->rx_writep = fifo->buf_rx_entry;
-
-               if (!((tmp=(*read_reg)(msgbase + iMSGCTL1)) & NEWD_SET)) {
-                       break;
-               }
-
-               if (tmp & MLST_SET)
-                       CANMSG("Message lost!\n");
-
-       }
-       if (waitqueue_active(&fifo->readq)) {
-               wake_up_interruptible(&fifo->readq);
-       }
-}
-
-void i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-       int id0=0, id1=0, id2=0, id3=0;
-
-       unsigned irq_register;
-       unsigned object;
-       struct chip_t *chip=(struct chip_t *)dev_id;
-       struct msgobj_t *msgobj;
-       unsigned long msgbase;
-       unsigned long message_id;
-       struct rtr_id *rtr_search;
-       void (*write_reg)(unsigned char data, unsigned long address);
-       unsigned (*read_reg)(unsigned long address);
-       write_reg=chip->hostdevice->hwspecops->write_register;
-       read_reg=chip->hostdevice->hwspecops->read_register;
-
-       /*put_reg=device->hwspecops->write_register;*/
-       /*get_reg=device->hwspecops->read_register;*/
-
-       if ( (chip->flags & SEGMENTED) != 0)
-               irq_register = can_read_reg(chip, iIRQ+SPACING);
-       else 
-               irq_register = can_read_reg(chip, iIRQ);
-
-       while (irq_register) {
-
-               if (irq_register == 0x01) {
-                       DEBUGMSG("Status register: 0x%x\n",can_read_reg(chip, iSTAT));
-                       return;
-               }
-               
-               if (irq_register == 0x02)
-                       object = 14;
-               else
-                       object = irq_register-3;
-
-               msgobj=chip->msgobj[object];
-               msgbase=msgobj->obj_base_addr;
-
-               if ((*read_reg)(msgbase+iMSGCFG) & MCFG_DIR) {
-                       i82527_irq_write_handler(chip, msgobj); 
-               }
-               else { 
-
-                       if (extended) {
-                               id0=(*read_reg)(msgbase+iMSGID3);
-                               id1=(*read_reg)(msgbase+iMSGID2)<<8;
-                               id2=(*read_reg)(msgbase+iMSGID1)<<16;
-                               id3=(*read_reg)(msgbase+iMSGID0)<<24;
-                               message_id=(id0|id1|id2|id3)>>3;
-                       }
-                       else {
-                               id0=(*read_reg)(msgbase+iMSGID1);
-                               id1=(*read_reg)(msgbase+iMSGID0)<<8;
-                               message_id=(id0|id1)>>5;
-                       }
 
-                       spin_lock(&hardware_p->rtr_lock);
-                       rtr_search=hardware_p->rtr_queue;
-                       while (rtr_search != NULL) {
-                               if (rtr_search->id == message_id)
-                                       break;
-                               rtr_search=rtr_search->next;
-                       }
-                       spin_unlock(&hardware_p->rtr_lock);
-                       if ((rtr_search!=NULL) && (rtr_search->id==message_id))
-                               i82527_irq_rtr_handler(chip, msgobj, rtr_search, message_id);
-                       else
-                               i82527_irq_read_handler(chip, msgobj, message_id); 
-               }
-
-               if ( (chip->flags & SEGMENTED) != 0)
-                       irq_register=can_read_reg(chip, iIRQ+SPACING);
-               else
-                       irq_register=can_read_reg(chip, iIRQ);
-       }
-       
-}
-
-void i82527_irq_rtr_handler(struct chip_t *chip, struct msgobj_t *msgobj,
-                           struct rtr_id *rtr_search, unsigned long message_id)
-{
-       short int i=0;
-       unsigned long msgbase=msgobj->obj_base_addr;
-       void (*write_reg)(unsigned char data, unsigned long address);
-       unsigned (*read_reg)(unsigned long address);
-       write_reg=chip->hostdevice->hwspecops->write_register;
-       read_reg=chip->hostdevice->hwspecops->read_register;
-
-       (*write_reg)((MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),msgbase + iMSGCTL0);
-       (*write_reg)((RMPD_RES|TXRQ_RES|MLST_RES|NEWD_RES),msgbase + iMSGCTL1);
-       
-       spin_lock(&hardware_p->rtr_lock);
-
-       rtr_search->rtr_message->id=message_id;
-       rtr_search->rtr_message->length=((*read_reg)(msgbase + iMSGCFG) & 0xf0)>>4;
-       for (i=0; i<rtr_search->rtr_message->length; i++)
-               rtr_search->rtr_message->data[i]=(*read_reg)(msgbase+iMSGDAT0+i);
-       
-       spin_unlock(&hardware_p->rtr_lock);
-
-       if (waitqueue_active(&rtr_search->rtr_wq))
-               wake_up_interruptible(&rtr_search->rtr_wq);
-}
-
-void sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-       unsigned irq_register;
-       struct chip_t *chip=(struct chip_t *)dev_id;
-       struct msgobj_t *msgobj;
-       struct canfifo_t *fifo;
-
-       irq_register=can_read_reg(chip, SJAIR);
-//     DEBUGMSG("sja1000_irq_handler: SJAIR:%02x\n",irq_register);
-//     DEBUGMSG("sja1000_irq_handler: SJASR:%02x\n",
-//                                     can_read_reg(chip, SJASR));
-
-       if ((irq_register & (IR_WUI|IR_DOI|IR_EI|IR_TI|IR_RI)) == 0)
-               return;
-
-       msgobj=chip->msgobj[0];
-       fifo=msgobj->fifo;
-
-       if ((irq_register & IR_RI) != 0) 
-               sja1000_irq_read_handler(chip, msgobj);
-       if ((irq_register & IR_TI) != 0) 
-               sja1000_irq_write_handler(chip, msgobj);
-       if ((irq_register & (IR_EI|IR_DOI)) != 0) { 
-               // Some error happened
-// FIXME: chip should be brought to usable state. Transmission cancelled if in progress.
-// Reset flag set to 0 if chip is already off the bus. Full state report
-               CANMSG("Error: status register: 0x%x irq_register: 0x%02x\n",
-                       can_read_reg(chip, SJASR), irq_register);
-               chip->msgobj[0]->ret=-1;
-               if (waitqueue_active(&fifo->writeq))
-                       wake_up_interruptible(&fifo->writeq);
-               if (waitqueue_active(&fifo->readq))
-                       wake_up_interruptible(&fifo->readq);
-       }
-
-       return;
-}
-
-void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *msgobj)
-{
-       int i=0, id=0;
-       struct canfifo_t *fifo=msgobj->fifo;
-
-       do {
-               id = can_read_reg(chip, SJARXID0) | (can_read_reg(chip, SJARXID1)<<8);
-               fifo->rx_writep->length = id & 0x0f;
-               fifo->rx_writep->flags = id&ID0_RTR ? MSG_RTR : 0;
-               fifo->rx_writep->timestamp = 0;
-               fifo->rx_writep->cob = 0;
-               fifo->rx_writep->id = id>>5;
-
-               for (i=0; i<fifo->rx_writep->length; i++)
-                       fifo->rx_writep->data[i]=can_read_reg(chip, SJARXDAT0 + i);
-
-               can_write_reg(chip, CMR_RRB, SJACMR);
-
-               fifo->rx_writep++;
-               if (fifo->rx_writep >= fifo->buf_rx_entry + MAX_BUF_LENGTH)
-                       fifo->rx_writep = fifo->buf_rx_entry;
-
-       } while(can_read_reg(chip, SJASR) & SR_RBS);
-
-       if (waitqueue_active(&fifo->readq))
-               wake_up_interruptible(&fifo->readq);
-}
-
-void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *msgobj)
-{
-       struct canfifo_t *fifo=msgobj->fifo;
-
-       fifo->tx_readp++;
-       if (fifo->tx_readp >= fifo->buf_tx_entry + MAX_BUF_LENGTH)
-               fifo->tx_readp = fifo->buf_tx_entry;
-       if (fifo->tx_readp == fifo->tx_writep) { // Output buffer is empty
-               fifo->tx_in_progress = 0;
-               if (waitqueue_active(&fifo->writeq)) {
-                       msgobj->ret = 0;
-                       wake_up_interruptible(&fifo->writeq);
-               }
-               return;
-       }
-       if (chip->chipspecops->pre_write_config(chip, msgobj, fifo->tx_readp)) {
-               if (waitqueue_active(&fifo->writeq)) {
-                       msgobj->ret = -1;
-                       wake_up_interruptible(&fifo->writeq);
-                       return;
-               }
-       }
-       if (chip->chipspecops->send_msg(chip, msgobj, fifo->tx_readp)) {
-               if (waitqueue_active(&fifo->writeq)) {
-                       msgobj->ret = -1;
-                       wake_up_interruptible(&fifo->writeq);
-                       return;
-               }
-       }
-}
 
-void dummy_irq_handler(int irq, void *dev_id, struct pt_regs *regs) {
+irqreturn_t dummy_irq_handler(int irq, void *dev_id, struct pt_regs *regs) {
        CANMSG("dummy_irq_handler called irq %d \n", irq);
+       return IRQ_NONE;
 }