/* 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>
-
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))
-#include <asm/spinlock.h>
-#else
-#include <linux/spinlock.h>
-#endif
-
+#include "../include/can.h"
+#include "../include/can_sysdep.h"
#include "../include/main.h"
#include "../include/irq.h"
-#include "../include/i82527.h"
-#include "../include/sja1000.h"
-
-void i82527_irq_rtr_handler(void);
-void sja1000_irq_read_handler(void);
-void sja1000_irq_write_handler(void);
-
-void (*put_reg)(unsigned char data, unsigned long address);
-unsigned (*get_reg)(unsigned long address);
-
-struct chip_t *chip=NULL;
-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(void)
-{
- put_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)) {
- chip->msgobj[object]->ret = 0;
- wake_up_interruptible(&fifo->writeq);
- }
- return;
- }
- if (chip->chipspecops->pre_write_config(chip, chip->msgobj[object],
- fifo->tx_readp)) {
- if (waitqueue_active(&fifo->writeq)) {
- chip->msgobj[object]->ret = -1;
- wake_up_interruptible(&fifo->writeq);
- return;
- }
- }
- if (chip->chipspecops->send_msg(chip, chip->msgobj[object],
- fifo->tx_readp)) {
- if (waitqueue_active(&fifo->writeq)) {
- chip->msgobj[object]->ret = -1;
- wake_up_interruptible(&fifo->writeq);
- return;
- }
- }
-}
-
-inline void i82527_irq_read_handler(void)
-{
- int i=0, tmp=1 ;
-
- while (tmp) {
- put_reg((RMPD_RES|TXRQ_RES|MLST_RES|NEWD_RES), msgbase +
- iMSGCTL1);
- put_reg((MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES), msgbase +
- iMSGCTL0);
-
- fifo->rx_writep->length =(get_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] = get_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=get_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;
-
- chip=(struct chip_t *)dev_id;
- device=(struct candevice_t *)chip->hostdevice;
-
- put_reg=device->hwspecops->write_register;
- get_reg=device->hwspecops->read_register;
-
- if ( (chip->flags & SEGMENTED) != 0)
- irq_register = get_reg(chip->chip_base_addr+iIRQ+SPACING);
- else
- irq_register = get_reg(chip->chip_base_addr+iIRQ);
-
- while (irq_register) {
-
- if (irq_register == 0x01) {
- DEBUGMSG("Status register: 0x%x\n",get_reg(chip->chip_base_addr+iSTAT));
- return;
- }
-
- if (irq_register == 0x02)
- object = 14;
- else
- object = irq_register-3;
- fifo=chip->msgobj[object]->fifo;
- msgbase=chip->msgobj[object]->obj_base_addr;
-
- if (get_reg(msgbase+iMSGCFG) & MCFG_DIR) {
- i82527_irq_write_handler();
- }
- else {
-
- if (extended) {
- id0=get_reg(msgbase+iMSGID3);
- id1=get_reg(msgbase+iMSGID2)<<8;
- id2=get_reg(msgbase+iMSGID1)<<16;
- id3=get_reg(msgbase+iMSGID0)<<24;
- message_id=(id0|id1|id2|id3)>>3;
- }
- else {
- id0=get_reg(msgbase+iMSGID1);
- id1=get_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();
- else
- i82527_irq_read_handler();
- }
-
- if ( (chip->flags & SEGMENTED) != 0)
- irq_register=get_reg(chip->chip_base_addr+iIRQ+SPACING);
- else
- irq_register=get_reg(chip->chip_base_addr+iIRQ);
- }
-
-}
-
-void i82527_irq_rtr_handler(void)
-{
- short int i=0;
-
- put_reg((MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),msgbase + iMSGCTL0);
- put_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=(get_reg(msgbase + iMSGCFG) & 0xf0)>>4;
- for (i=0; i<rtr_search->rtr_message->length; i++)
- rtr_search->rtr_message->data[i]=get_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)
-{
- chip=(struct chip_t *)dev_id;
- device=(struct candevice_t *)chip->hostdevice;
-
- put_reg=device->hwspecops->write_register;
- get_reg=device->hwspecops->read_register;
-
- irq_register=get_reg(chip->chip_base_addr+SJAIR);
-// DEBUGMSG("sja1000_irq_handler: SJAIR:%02x\n",irq_register);
-// DEBUGMSG("sja1000_irq_handler: SJASR:%02x\n",
-// get_reg(chip->chip_base_addr+SJASR));
-
- if ((irq_register & (IR_WUI|IR_DOI|IR_EI|IR_TI|IR_RI)) == 0)
- return;
-
- fifo=chip->msgobj[0]->fifo;
- msgbase=chip->msgobj[0]->obj_base_addr;
-
- if ((irq_register & IR_RI) != 0)
- sja1000_irq_read_handler();
- if ((irq_register & IR_TI) != 0)
- sja1000_irq_write_handler();
- 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",
- get_reg(chip->chip_base_addr+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(void)
-{
- int i=0, id=0, tmp=1;
-
- while (tmp) {
- id = get_reg(msgbase+SJARXID0) | (get_reg(msgbase+SJARXID1)<<8);
- fifo->buf_rx_entry[fifo->head].length = id & 0x0f;
- fifo->buf_rx_entry[fifo->head].flags = id&ID0_RTR ? MSG_RTR : 0;
- fifo->buf_rx_entry[fifo->head].timestamp = 0;
- fifo->buf_rx_entry[fifo->head].cob = 0;
- fifo->buf_rx_entry[fifo->head].id = id>>5;
-
- for (i=0; i<fifo->buf_rx_entry[fifo->head].length; i++)
- fifo->buf_rx_entry[fifo->head].data[i]=get_reg(msgbase +
- SJARXDAT0 + i);
-
- put_reg(CMR_RRB,msgbase+SJACMR);
-
- fifo->head++;
- if (fifo->head >= MAX_BUF_LENGTH-1)
- fifo->head=0;
-
- tmp=(get_reg(msgbase+SJASR) & SR_RBS);
- }
- if (waitqueue_active(&fifo->readq))
- wake_up_interruptible(&fifo->readq);
-}
-void sja1000_irq_write_handler(void)
-{
- 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)) {
- chip->msgobj[object]->ret = 0;
- wake_up_interruptible(&fifo->writeq);
- }
- return;
- }
- if (chip->chipspecops->pre_write_config(chip, chip->msgobj[object],
- fifo->tx_readp)) {
- if (waitqueue_active(&fifo->writeq)) {
- chip->msgobj[object]->ret = -1;
- wake_up_interruptible(&fifo->writeq);
- return;
- }
- }
- if (chip->chipspecops->send_msg(chip, chip->msgobj[object],
- fifo->tx_readp)) {
- if (waitqueue_active(&fifo->writeq)) {
- chip->msgobj[object]->ret = -1;
- wake_up_interruptible(&fifo->writeq);
- return;
- }
- }
+can_irqreturn_t dummy_irq_handler(int irq, void *dev_id, struct pt_regs *regs) {
+ CANMSG("dummy_irq_handler called irq %d \n", irq);
+ return CAN_IRQ_NONE;
}