]> rtime.felk.cvut.cz Git - socketcan-devel.git/commitdiff
Added support form custom irq handlers.
authorhartkopp <hartkopp@030b6a49-0b11-0410-94ab-b0dab22257f2>
Thu, 19 Jun 2008 10:42:05 +0000 (10:42 +0000)
committerhartkopp <hartkopp@030b6a49-0b11-0410-94ab-b0dab22257f2>
Thu, 19 Jun 2008 10:42:05 +0000 (10:42 +0000)
git-svn-id: svn://svn.berlios.de//socketcan/trunk@783 030b6a49-0b11-0410-94ab-b0dab22257f2

kernel/2.6/drivers/net/can/sja1000/sja1000.c
kernel/2.6/drivers/net/can/sja1000/sja1000.h

index d3712b1418d2b3eb161396e9885287ae2d553136..01d1a72039e410386d833f1b386bd251a5aa6a4d 100644 (file)
@@ -607,10 +607,9 @@ static int sja1000_err(struct net_device *dev,
 }
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-static irqreturn_t sja1000_interrupt(int irq, void *dev_id,
-                                    struct pt_regs *regs)
+irqreturn_t sja1000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #else
-static irqreturn_t sja1000_interrupt(int irq, void *dev_id)
+irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 #endif
 {
        struct net_device *dev = (struct net_device *)dev_id;
@@ -667,8 +666,9 @@ out:
        if (priv->post_irq)
                priv->post_irq(dev);
 
-       return n == 0 ? IRQ_NONE : IRQ_HANDLED;
+       return (n) ? IRQ_HANDLED : IRQ_NONE;
 }
+EXPORT_SYMBOL_GPL(sja1000_interrupt);
 
 static int sja1000_open(struct net_device *dev)
 {
@@ -678,16 +678,18 @@ static int sja1000_open(struct net_device *dev)
        /* set chip into reset mode */
        set_reset_mode(dev);
 
-       /* register interrupt handler */
+       /* register interrupt handler, if not done by the device driver */
+       if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER)) {
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
-       err = request_irq(dev->irq, &sja1000_interrupt, SA_SHIRQ,
-                         dev->name, (void *)dev);
+               err = request_irq(dev->irq, &sja1000_interrupt, SA_SHIRQ,
+                                 dev->name, (void *)dev);
 #else
-       err = request_irq(dev->irq, &sja1000_interrupt, IRQF_SHARED,
-                         dev->name, (void *)dev);
+               err = request_irq(dev->irq, &sja1000_interrupt, IRQF_SHARED,
+                                 dev->name, (void *)dev);
 #endif
-       if (err)
-               return -EAGAIN;
+               if (err)
+                       return -EAGAIN;
+       }
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
        /* clear statistics */
@@ -711,7 +713,9 @@ static int sja1000_close(struct net_device *dev)
        netif_stop_queue(dev);
        priv->open_time = 0;
        can_close_cleanup(dev);
-       free_irq(dev->irq, (void *)dev);
+
+       if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER))
+               free_irq(dev->irq, (void *)dev);
 
        return 0;
 }
index b698a97dece1bb03ea8fe51a9045f56d2ee8efb1..c9d8b32df15f6ccbda4e2d440c60206650e47561 100644 (file)
 #define OCR_TX1_PULLUP    0x80
 #define OCR_TX1_PUSHPULL  0xc0
 
+
+/*
+ * Flags for sja1000priv.flags
+ */
+
+#define SJA1000_CUSTOM_IRQ_HANDLER 0x1
+
+
 /*
  * SJA1000 private data structure
  */
@@ -174,14 +182,18 @@ struct sja1000_priv {
        struct can_priv can;    /* must be the first member! */
        long open_time;
        struct sk_buff *echo_skb;
+
        u8 (*read_reg) (struct net_device *dev, int reg);
        void (*write_reg) (struct net_device *dev, int reg, u8 val);
        void (*pre_irq) (struct net_device *dev);
        void (*post_irq) (struct net_device *dev);
+
        void *priv;             /* for board-specific data */
        struct net_device *dev;
+
        u8 ocr;
        u8 cdr;
+       u32 flags;
 };
 
 struct net_device *alloc_sja1000dev(int sizeof_priv);
@@ -189,6 +201,12 @@ void free_sja1000dev(struct net_device *dev);
 int register_sja1000dev(struct net_device *dev);
 void unregister_sja1000dev(struct net_device *dev);
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+irqreturn_t sja1000_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+#else
+irqreturn_t sja1000_interrupt(int irq, void *dev_id);
+#endif
+
 #if 0
 void can_proc_create(const char *drv_name);
 void can_proc_remove(const char *drv_name);