Merge: Changes, which should enable to handle more VME Unican cards under RT-Linux.
authorppisa <pisa@cmp.felk.cvut.cz>
Thu, 3 Feb 2005 15:18:00 +0000 (16:18 +0100)
committerppisa <pisa@cmp.felk.cvut.cz>
Thu, 3 Feb 2005 15:18:00 +0000 (16:18 +0100)
Merge commit 'remotes/sf-ocera-lincan/master'

lincan/include/constants.h
lincan/src/can_devrtl.c
lincan/src/unican.c

index 327e5ef..dc2bb40 100644 (file)
 #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)
index 5bbc2c0..c7ff970 100644 (file)
@@ -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*/
 
                }
index 4efabc8..f72bacc 100644 (file)
@@ -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;
 }