#define CHIP_MAX_IRQLOOP 1000
/* System independent defines of IRQ handled state */
-#define CANCHIP_IRQ_NONE 0
-#define CANCHIP_IRQ_HANDLED 1
-#define CANCHIP_IRQ_STUCK 2
+#define CANCHIP_IRQ_NONE 0
+#define CANCHIP_IRQ_HANDLED 1
+#define CANCHIP_IRQ_ACCEPTED 2
+#define CANCHIP_IRQ_STUCK 3
/* These flags can be used for the candevices_t structure flags data entry */
#define CANDEV_PROGRAMMABLE_IRQ (1<<0)
int board_nr;
int chip_nr;
int irq2linux=0;
+ int ret;
pthread_t thread=NULL;
DEBUGMSG("can_rtl_isr invoked for irq %d\n",irq_num);
continue;
if(chip->chip_irq!=irq_num) continue;
+ if(chip->chipspecops->irq_accept)
+ ret=chip->chipspecops->irq_accept(chip->chip_irq,chip);
+
set_bit(MSGOBJ_IRQ_REQUEST_b,&chip->pend_flags);
set_bit(MSGOBJ_WORKER_WAKE_b,&chip->pend_flags);
if(chip->flags & CHIP_IRQ_PCI)
if(chip->chip_irq>=0) {
if ((chip->flags & CHIP_IRQ_VME) == 0) can_enable_irq(chip->chip_irq);
#ifdef CAN_ENABLE_VME_SUPPORT
- else tundra_rtl_enable_pci_irq();
+ #if 0
+ else tundra_rtl_enable_pci_irq();
+ #endif
/* FIXME: Bad practice. Doesn't work with more
- * than one card. */
+ * than one card.
+ *
+ * irq_accept added to the LinCAN driver now,
+ * and above workaround should not be required.
+ * Enable rtl_hard_enable_irq() at line
+ * ca91c042.c:1045
+ */
#endif /*CAN_ENABLE_VME_SUPPORT*/
}
/**
* unican_irq_handler: - interrupt service routine
* @irq: interrupt vector number, this value is system specific
- * @dev_id: driver private pointer registered at time of request_irq() call.
- * The CAN driver uses this pointer to store relationship of interrupt
- * to chip state structure - @struct canchip_t
- * @regs: system dependent value pointing to registers stored in exception frame
+ * @chip: pointer to chip state structure
*
* Interrupt handler is activated when state of CAN controller chip changes,
* there is message to be read or there is more space for new messages or
return CANCHIP_IRQ_NONE;
}
- if (cl2_get_status(chipext, &status) == CL2_NO_REQUEST)
+ if (cl2_get_status(chipext, &status) == CL2_NO_REQUEST) {
+ /* Reenable interrupts generation, this has to be even there,
+ * because irq_accept disables interrupts
+ */
+ cl2_gen_interrupt(chipext);
return CANCHIP_IRQ_NONE;
+ }
cl2_clear_interrupt(chipext);
unican_read(chip, obj);
}
+ /* Reenable interrupts generation */
cl2_gen_interrupt(chipext);
return CANCHIP_IRQ_HANDLED;
}
+/**
+ * unican_irq_accept: - fast irq accept routine, blocks further interrupts
+ * @irq: interrupt vector number, this value is system specific
+ * @chip: pointer to chip state structure
+ *
+ * This routine only accepts interrupt reception and stops further
+ * incoming interrupts, but does not handle situation causing interrupt.
+ * File: src/unican.c
+ */
+int unican_irq_accept(int irq, struct canchip_t *chip)
+{
+ sCAN_CARD *chipext = (sCAN_CARD *)chip->chip_data;
+
+ cl2_clear_interrupt(chipext);
+
+ return CANCHIP_IRQ_ACCEPTED;
+}
+
/*void unican_do_tx_timeout(unsigned long data)
{
struct msgobj_t *obj=(struct msgobj_t *)data;
chip->chipspecops->start_chip=unican_start_chip;
chip->chipspecops->stop_chip=unican_stop_chip;
chip->chipspecops->irq_handler=unican_irq_handler;
- chip->chipspecops->irq_accept=NULL;
+ chip->chipspecops->irq_accept=unican_irq_accept;
return 0;
}