}
#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;
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)
{
/* 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 */
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;
}
#define OCR_TX1_PULLUP 0x80
#define OCR_TX1_PUSHPULL 0xc0
+
+/*
+ * Flags for sja1000priv.flags
+ */
+
+#define SJA1000_CUSTOM_IRQ_HANDLER 0x1
+
+
/*
* SJA1000 private data structure
*/
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);
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);