*/
#include <linux/kernel.h>
+#include <linux/version.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
-#include <linux/can.h>
-#include <linux/can/dev.h>
+#include <socketcan/can.h>
+#include <socketcan/can/dev.h>
#include <asm/io.h>
#include <pcmcia/cs_types.h>
#define DRV_NAME "ems_pcmcia"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
+#error This driver does not support Kernel versions < 2.6.16
+#endif
+
MODULE_AUTHOR("Sebastian Haas <haas@ems-wuenche.com>");
MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-CARD cards");
MODULE_SUPPORTED_DEVICE("EMS CPC-CARD CAN card");
static void ems_pcmcia_config(struct pcmcia_device *dev);
-static u8 ems_pcmcia_read_reg(struct net_device *dev, int port)
+static u8 ems_pcmcia_read_reg(const struct sja1000_priv *priv, int port)
{
- return readb((void __iomem *)dev->base_addr + port);
+ return readb(priv->reg_base + port);
}
-static void ems_pcmcia_write_reg(struct net_device *dev, int port, u8 val)
+static void ems_pcmcia_write_reg(const struct sja1000_priv *priv,
+ int port, u8 val)
{
- writeb(val, (void __iomem *)dev->base_addr + port);
+ writeb(val, priv->reg_base + port);
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
irqreturn_t retval = IRQ_NONE;
int i, again;
+ /* Card not present */
+ if (readw(card->base_addr) != 0xAA55)
+ return IRQ_HANDLED;
+
do {
again = 0;
* Check if a CAN controller is present at the specified location
* by trying to set 'em into the PeliCAN mode
*/
-static inline int ems_pcmcia_check_chan(struct net_device *dev)
+static inline int ems_pcmcia_check_chan(struct sja1000_priv *priv)
{
unsigned char res;
/* Make sure SJA1000 is in reset mode */
- ems_pcmcia_write_reg(dev, REG_MOD, 1);
+ ems_pcmcia_write_reg(priv, REG_MOD, 1);
- ems_pcmcia_write_reg(dev, REG_CDR, CDR_PELICAN);
+ ems_pcmcia_write_reg(priv, REG_CDR, CDR_PELICAN);
/* read reset-values */
- res = ems_pcmcia_read_reg(dev, REG_CDR);
+ res = ems_pcmcia_read_reg(priv, REG_CDR);
if (res == CDR_PELICAN)
return 1;
priv->priv = card;
SET_NETDEV_DEV(dev, &pdev->dev);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
+ priv->irq_flags = SA_SHIRQ;
+#else
+ priv->irq_flags = IRQF_SHARED;
+#endif
dev->irq = pdev->irq.AssignedIRQ;
- dev->base_addr = (unsigned long)(card->base_addr
+ priv->reg_base = (card->base_addr
+ EMS_PCMCIA_CAN_BASE_OFFSET
+ (i * EMS_PCMCIA_CAN_CTRL_SIZE));
/* Check if channel is present */
- if (ems_pcmcia_check_chan(dev)) {
+ if (ems_pcmcia_check_chan(priv)) {
priv->read_reg = ems_pcmcia_read_reg;
priv->write_reg = ems_pcmcia_write_reg;
- priv->can.bittiming.clock = EMS_PCMCIA_CAN_CLOCK;
+ priv->can.clock.freq = EMS_PCMCIA_CAN_CLOCK;
priv->ocr = EMS_PCMCIA_OCR;
priv->cdr = EMS_PCMCIA_CDR;
priv->flags |= SJA1000_CUSTOM_IRQ_HANDLER;
card->channels++;
printk(KERN_INFO "%s: registered %s on channel "
- "#%d at %lX, irq %d\n", DRV_NAME, dev->name,
- i, dev->base_addr, dev->irq);
+ "#%d at 0x%p, irq %d\n", DRV_NAME, dev->name,
+ i, priv->reg_base, dev->irq);
} else {
free_sja1000dev(dev);
}
/*
* Configure PCMCIA socket
*/
-static void ems_pcmcia_config(struct pcmcia_device *dev)
+static void __devinit ems_pcmcia_config(struct pcmcia_device *dev)
{
win_req_t req;
memreq_t mem;