From: ppisa Date: Thu, 3 Feb 2005 15:18:00 +0000 (+0100) Subject: Merge: Changes, which should enable to handle more VME Unican cards under RT-Linux. X-Git-Tag: CLT_COMM_CAN_usb_can1_kriz_bp~75 X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/commitdiff_plain/5988163e5523a21c15882f7a01d293fa0b3736d7?hp=ca4f53cc8f5c5e7b444309afde6d265578be391d Merge: Changes, which should enable to handle more VME Unican cards under RT-Linux. Merge commit 'remotes/sf-ocera-lincan/master' --- diff --git a/lincan/include/constants.h b/lincan/include/constants.h index 327e5ef..dc2bb40 100644 --- a/lincan/include/constants.h +++ b/lincan/include/constants.h @@ -84,9 +84,10 @@ #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) diff --git a/lincan/src/can_devrtl.c b/lincan/src/can_devrtl.c index 5bbc2c0..c7ff970 100644 --- a/lincan/src/can_devrtl.c +++ b/lincan/src/can_devrtl.c @@ -31,6 +31,7 @@ unsigned int can_rtl_isr( unsigned int irq_num, struct pt_regs *r ) 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); @@ -44,6 +45,9 @@ unsigned int can_rtl_isr( unsigned int irq_num, struct pt_regs *r ) 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) @@ -135,9 +139,17 @@ void * can_chip_worker_thread(void *arg) 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*/ } diff --git a/lincan/src/unican.c b/lincan/src/unican.c index 4efabc8..f72bacc 100644 --- a/lincan/src/unican.c +++ b/lincan/src/unican.c @@ -558,10 +558,7 @@ void unican_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj) /** * 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 @@ -582,8 +579,13 @@ int unican_irq_handler(int irq, struct canchip_t *chip) 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); @@ -606,12 +608,31 @@ int unican_irq_handler(int irq, struct canchip_t *chip) 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; @@ -797,7 +818,7 @@ int unican_init_chip_data(struct candevice_t *candev, int chipnr) 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; }