- if ((irq_register & IR_RI) != 0) {
- sja1000p_read(chip,fifo);
- chip->msgobj[0]->ret = 0;
- if (waitqueue_active(&fifo->readq))
- wake_up_interruptible(&fifo->readq);
- }
- if ((irq_register & IR_TI) != 0) {
- chip->msgobj[0]->ret = 0;
- sja1000p_irq_write_handler(chip,fifo);
- }
- if ((irq_register & (IR_EI|IR_BEI|IR_EPI|IR_DOI)) != 0) {
- // Some error happened
- status=can_read_reg(chip,SJASR);
- error_code=can_read_reg(chip,SJAECC);
- CANMSG("Error: status register: 0x%x irq_register: 0x%02x error: 0x%02x\n",
- status, irq_register, error_code);
+ status=can_read_reg(chip,SJASR);
+
+ do {
+
+ if(!loop_cnt--) {
+ CANMSG("sja1000p_irq_handler IRQ %d stuck\n",irq);
+ return CANCHIP_IRQ_STUCK;
+ }
+
+ /* (irq_register & sjaIR_RI) */
+ /* old variant using SJAIR, collides with intended use with irq_accept */
+ if (status & sjaSR_RBS) {
+ DEBUGMSG("sja1000_irq_handler: RI or RBS\n");
+ sja1000p_read(chip,obj);
+ obj->ret = 0;
+ }
+
+ /* (irq_register & sjaIR_TI) */
+ /* old variant using SJAIR, collides with intended use with irq_accept */
+ if (((status & sjaSR_TBS) && can_msgobj_test_fl(obj,TX_PENDING))||
+ (can_msgobj_test_fl(obj,TX_REQUEST))) {
+ DEBUGMSG("sja1000_irq_handler: TI or TX_PENDING and TBS\n");
+ obj->ret = 0;
+ can_msgobj_set_fl(obj,TX_REQUEST);
+ while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+ can_msgobj_clear_fl(obj,TX_REQUEST);
+
+ if (can_read_reg(chip, SJASR) & sjaSR_TBS)
+ sja1000p_irq_write_handler(chip, obj);
+
+ can_msgobj_clear_fl(obj,TX_LOCK);
+ if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
+ DEBUGMSG("TX looping in sja1000_irq_handler\n");
+ }
+ }
+ if ((irq_register & (sjaIR_EI|sjaIR_BEI|sjaIR_EPI|sjaIR_DOI)) != 0) {
+ // Some error happened
+ error_code=can_read_reg(chip,SJAECC);
+ sja1000_report_error(chip, status, irq_register, error_code);