Commit c2ad8129 authored by Jimmy Assarsson's avatar Jimmy Assarsson Committed by Marc Kleine-Budde
Browse files

can: kvaser_pciefd: Move hardware specific constants and functions into a driver_data struct



Move hardware specific address offsets, interrupt masks and DMA mapping
function, into struct kvaser_pciefd_driver_data, as a step towards adding
new devices based on different hardware.

Co-developed-by: default avatarMartin Jocic <majoc@kvaser.com>
Signed-off-by: default avatarMartin Jocic <majoc@kvaser.com>
Signed-off-by: default avatarJimmy Assarsson <extja@kvaser.com>
Link: https://lore.kernel.org/all/20230622151153.294844-2-extja@kvaser.com


[mkl: mark structs as static]
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 2e12d79f
Loading
Loading
Loading
Loading
+154 −76
Original line number Diff line number Diff line
@@ -33,37 +33,17 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
#define KVASER_PCIEFD_DMA_SIZE (4U * 1024U)

#define KVASER_PCIEFD_VENDOR 0x1a07
/* Altera based devices */
#define KVASER_PCIEFD_4HS_DEVICE_ID 0x000d
#define KVASER_PCIEFD_2HS_V2_DEVICE_ID 0x000e
#define KVASER_PCIEFD_HS_V2_DEVICE_ID 0x000f
#define KVASER_PCIEFD_MINIPCIE_HS_V2_DEVICE_ID 0x0010
#define KVASER_PCIEFD_MINIPCIE_2HS_V2_DEVICE_ID 0x0011

/* PCIe IRQ registers */
#define KVASER_PCIEFD_IRQ_REG 0x40
#define KVASER_PCIEFD_IEN_REG 0x50
/* DMA address translation map register base */
#define KVASER_PCIEFD_DMA_MAP_BASE 0x1000
/* Loopback control register */
#define KVASER_PCIEFD_LOOP_REG 0x1f000
/* System identification and information registers */
#define KVASER_PCIEFD_SYSID_BASE 0x1f020
#define KVASER_PCIEFD_SYSID_VERSION_REG (KVASER_PCIEFD_SYSID_BASE + 0x8)
#define KVASER_PCIEFD_SYSID_CANFREQ_REG (KVASER_PCIEFD_SYSID_BASE + 0xc)
#define KVASER_PCIEFD_SYSID_BUSFREQ_REG (KVASER_PCIEFD_SYSID_BASE + 0x10)
#define KVASER_PCIEFD_SYSID_BUILD_REG (KVASER_PCIEFD_SYSID_BASE + 0x14)
/* Shared receive buffer registers */
#define KVASER_PCIEFD_SRB_BASE 0x1f200
#define KVASER_PCIEFD_SRB_FIFO_LAST_REG (KVASER_PCIEFD_SRB_BASE + 0x1f4)
#define KVASER_PCIEFD_SRB_CMD_REG (KVASER_PCIEFD_SRB_BASE + 0x200)
#define KVASER_PCIEFD_SRB_IEN_REG (KVASER_PCIEFD_SRB_BASE + 0x204)
#define KVASER_PCIEFD_SRB_IRQ_REG (KVASER_PCIEFD_SRB_BASE + 0x20c)
#define KVASER_PCIEFD_SRB_STAT_REG (KVASER_PCIEFD_SRB_BASE + 0x210)
#define KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG (KVASER_PCIEFD_SRB_BASE + 0x214)
#define KVASER_PCIEFD_SRB_CTRL_REG (KVASER_PCIEFD_SRB_BASE + 0x218)
/* Altera SerDes Enable 64-bit DMA address translation */
#define KVASER_PCIEFD_ALTERA_DMA_64BIT BIT(0)

/* Kvaser KCAN CAN controller registers */
#define KVASER_PCIEFD_KCAN0_BASE 0x10000
#define KVASER_PCIEFD_KCAN_BASE_OFFSET 0x1000
#define KVASER_PCIEFD_KCAN_FIFO_REG 0x100
#define KVASER_PCIEFD_KCAN_FIFO_LAST_REG 0x180
#define KVASER_PCIEFD_KCAN_CTRL_REG 0x2c0
@@ -77,13 +57,20 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
#define KVASER_PCIEFD_KCAN_BUS_LOAD_REG 0x424
#define KVASER_PCIEFD_KCAN_BTRD_REG 0x428
#define KVASER_PCIEFD_KCAN_PWM_REG 0x430

/* PCI interrupt fields */
#define KVASER_PCIEFD_IRQ_SRB BIT(4)
#define KVASER_PCIEFD_IRQ_ALL_MASK GENMASK(4, 0)

/* Enable 64-bit DMA address translation */
#define KVASER_PCIEFD_64BIT_DMA_BIT BIT(0)
/* System identification and information registers */
#define KVASER_PCIEFD_SYSID_VERSION_REG 0x8
#define KVASER_PCIEFD_SYSID_CANFREQ_REG 0xc
#define KVASER_PCIEFD_SYSID_BUSFREQ_REG 0x10
#define KVASER_PCIEFD_SYSID_BUILD_REG 0x14
/* Shared receive buffer FIFO registers */
#define KVASER_PCIEFD_SRB_FIFO_LAST_REG 0x1f4
/* Shared receive buffer registers */
#define KVASER_PCIEFD_SRB_CMD_REG 0x0
#define KVASER_PCIEFD_SRB_IEN_REG 0x04
#define KVASER_PCIEFD_SRB_IRQ_REG 0x0c
#define KVASER_PCIEFD_SRB_STAT_REG 0x10
#define KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG 0x14
#define KVASER_PCIEFD_SRB_CTRL_REG 0x18

/* System build information fields */
#define KVASER_PCIEFD_SYSID_VERSION_NR_CHAN_MASK GENMASK(31, 24)
@@ -253,7 +240,92 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
/* KCAN Error detected packet, second word */
#define KVASER_PCIEFD_EPACK_DIR_TX BIT(0)

/* Macros for calculating addresses of registers */
#define KVASER_PCIEFD_GET_BLOCK_ADDR(pcie, block) \
	((pcie)->reg_base + (pcie)->driver_data->address_offset->block)
#define KVASER_PCIEFD_PCI_IEN_ADDR(pcie) \
	(KVASER_PCIEFD_GET_BLOCK_ADDR((pcie), pci_ien))
#define KVASER_PCIEFD_PCI_IRQ_ADDR(pcie) \
	(KVASER_PCIEFD_GET_BLOCK_ADDR((pcie), pci_irq))
#define KVASER_PCIEFD_SERDES_ADDR(pcie) \
	(KVASER_PCIEFD_GET_BLOCK_ADDR((pcie), serdes))
#define KVASER_PCIEFD_SYSID_ADDR(pcie) \
	(KVASER_PCIEFD_GET_BLOCK_ADDR((pcie), sysid))
#define KVASER_PCIEFD_LOOPBACK_ADDR(pcie) \
	(KVASER_PCIEFD_GET_BLOCK_ADDR((pcie), loopback))
#define KVASER_PCIEFD_SRB_FIFO_ADDR(pcie) \
	(KVASER_PCIEFD_GET_BLOCK_ADDR((pcie), kcan_srb_fifo))
#define KVASER_PCIEFD_SRB_ADDR(pcie) \
	(KVASER_PCIEFD_GET_BLOCK_ADDR((pcie), kcan_srb))
#define KVASER_PCIEFD_KCAN_CH0_ADDR(pcie) \
	(KVASER_PCIEFD_GET_BLOCK_ADDR((pcie), kcan_ch0))
#define KVASER_PCIEFD_KCAN_CH1_ADDR(pcie) \
	(KVASER_PCIEFD_GET_BLOCK_ADDR((pcie), kcan_ch1))
#define KVASER_PCIEFD_KCAN_CHANNEL_SPAN(pcie) \
	(KVASER_PCIEFD_KCAN_CH1_ADDR((pcie)) - KVASER_PCIEFD_KCAN_CH0_ADDR((pcie)))
#define KVASER_PCIEFD_KCAN_CHX_ADDR(pcie, i) \
	(KVASER_PCIEFD_KCAN_CH0_ADDR((pcie)) + (i) * KVASER_PCIEFD_KCAN_CHANNEL_SPAN((pcie)))

struct kvaser_pciefd;
static void kvaser_pciefd_write_dma_map_altera(struct kvaser_pciefd *pcie,
					       dma_addr_t addr, int index);

struct kvaser_pciefd_address_offset {
	u32 serdes;
	u32 pci_ien;
	u32 pci_irq;
	u32 sysid;
	u32 loopback;
	u32 kcan_srb_fifo;
	u32 kcan_srb;
	u32 kcan_ch0;
	u32 kcan_ch1;
};

struct kvaser_pciefd_dev_ops {
	void (*kvaser_pciefd_write_dma_map)(struct kvaser_pciefd *pcie,
					    dma_addr_t addr, int index);
};

struct kvaser_pciefd_irq_mask {
	u32 kcan_rx0;
	u32 kcan_tx[KVASER_PCIEFD_MAX_CAN_CHANNELS];
	u32 all;
};

struct kvaser_pciefd_driver_data {
	const struct kvaser_pciefd_address_offset *address_offset;
	const struct kvaser_pciefd_irq_mask *irq_mask;
	const struct kvaser_pciefd_dev_ops *ops;
};

static const struct kvaser_pciefd_address_offset kvaser_pciefd_altera_address_offset = {
	.serdes = 0x1000,
	.pci_ien = 0x50,
	.pci_irq = 0x40,
	.sysid = 0x1f020,
	.loopback = 0x1f000,
	.kcan_srb_fifo = 0x1f200,
	.kcan_srb = 0x1f400,
	.kcan_ch0 = 0x10000,
	.kcan_ch1 = 0x11000,
};

static const struct kvaser_pciefd_irq_mask kvaser_pciefd_altera_irq_mask = {
	.kcan_rx0 = BIT(4),
	.kcan_tx = { BIT(0), BIT(1), BIT(2), BIT(3) },
	.all = GENMASK(4, 0),
};

static const struct kvaser_pciefd_dev_ops kvaser_pciefd_altera_dev_ops = {
	.kvaser_pciefd_write_dma_map = kvaser_pciefd_write_dma_map_altera,
};

static const struct kvaser_pciefd_driver_data kvaser_pciefd_altera_driver_data = {
	.address_offset = &kvaser_pciefd_altera_address_offset,
	.irq_mask = &kvaser_pciefd_altera_irq_mask,
	.ops = &kvaser_pciefd_altera_dev_ops,
};

struct kvaser_pciefd_can {
	struct can_priv can;
@@ -273,6 +345,7 @@ struct kvaser_pciefd {
	struct pci_dev *pci;
	void __iomem *reg_base;
	struct kvaser_pciefd_can *can[KVASER_PCIEFD_MAX_CAN_CHANNELS];
	const struct kvaser_pciefd_driver_data *driver_data;
	void *dma_data[KVASER_PCIEFD_DMA_COUNT];
	u8 nr_channels;
	u32 bus_freq;
@@ -305,18 +378,23 @@ static const struct can_bittiming_const kvaser_pciefd_bittiming_const = {
static struct pci_device_id kvaser_pciefd_id_table[] = {
	{
		PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_4HS_DEVICE_ID),
		.driver_data = (kernel_ulong_t)&kvaser_pciefd_altera_driver_data,
	},
	{
		PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_2HS_V2_DEVICE_ID),
		.driver_data = (kernel_ulong_t)&kvaser_pciefd_altera_driver_data,
	},
	{
		PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_HS_V2_DEVICE_ID),
		.driver_data = (kernel_ulong_t)&kvaser_pciefd_altera_driver_data,
	},
	{
		PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_MINIPCIE_HS_V2_DEVICE_ID),
		.driver_data = (kernel_ulong_t)&kvaser_pciefd_altera_driver_data,
	},
	{
		PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_MINIPCIE_2HS_V2_DEVICE_ID),
		.driver_data = (kernel_ulong_t)&kvaser_pciefd_altera_driver_data,
	},
	{
		0,
@@ -783,8 +861,7 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
		can = netdev_priv(netdev);
		netdev->netdev_ops = &kvaser_pciefd_netdev_ops;
		netdev->ethtool_ops = &kvaser_pciefd_ethtool_ops;
		can->reg_base = pcie->reg_base + KVASER_PCIEFD_KCAN0_BASE +
				i * KVASER_PCIEFD_KCAN_BASE_OFFSET;
		can->reg_base = KVASER_PCIEFD_KCAN_CHX_ADDR(pcie, i);
		can->kv_pcie = pcie;
		can->cmd_seq = 0;
		can->err_rep_cnt = 0;
@@ -865,20 +942,22 @@ static int kvaser_pciefd_reg_candev(struct kvaser_pciefd *pcie)
	return 0;
}

static void kvaser_pciefd_write_dma_map(struct kvaser_pciefd *pcie,
					dma_addr_t addr, int offset)
static void kvaser_pciefd_write_dma_map_altera(struct kvaser_pciefd *pcie,
					       dma_addr_t addr, int index)
{
	void __iomem *serdes_base;
	u32 word1, word2;

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	word1 = addr | KVASER_PCIEFD_64BIT_DMA_BIT;
	word1 = addr | KVASER_PCIEFD_ALTERA_DMA_64BIT;
	word2 = addr >> 32;
#else
	word1 = addr;
	word2 = 0;
#endif
	iowrite32(word1, pcie->reg_base + offset);
	iowrite32(word2, pcie->reg_base + offset + 4);
	serdes_base = KVASER_PCIEFD_SERDES_ADDR(pcie) + 0x8 * index;
	iowrite32(word1, serdes_base);
	iowrite32(word2, serdes_base + 0x4);
}

static int kvaser_pciefd_setup_dma(struct kvaser_pciefd *pcie)
@@ -889,10 +968,8 @@ static int kvaser_pciefd_setup_dma(struct kvaser_pciefd *pcie)
	dma_addr_t dma_addr[KVASER_PCIEFD_DMA_COUNT];

	/* Disable the DMA */
	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG);
	iowrite32(0, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CTRL_REG);
	for (i = 0; i < KVASER_PCIEFD_DMA_COUNT; i++) {
		unsigned int offset = KVASER_PCIEFD_DMA_MAP_BASE + 8 * i;

		pcie->dma_data[i] = dmam_alloc_coherent(&pcie->pci->dev,
							KVASER_PCIEFD_DMA_SIZE,
							&dma_addr[i],
@@ -903,24 +980,25 @@ static int kvaser_pciefd_setup_dma(struct kvaser_pciefd *pcie)
				KVASER_PCIEFD_DMA_SIZE);
			return -ENOMEM;
		}
		kvaser_pciefd_write_dma_map(pcie, dma_addr[i], offset);
		pcie->driver_data->ops->kvaser_pciefd_write_dma_map(pcie, dma_addr[i], i);
	}

	/* Reset Rx FIFO, and both DMA buffers */
	iowrite32(KVASER_PCIEFD_SRB_CMD_FOR | KVASER_PCIEFD_SRB_CMD_RDB0 |
		  KVASER_PCIEFD_SRB_CMD_RDB1,
		  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
		  KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
	/* Empty Rx FIFO */
	srb_packet_count =
		FIELD_GET(KVASER_PCIEFD_SRB_RX_NR_PACKETS_MASK,
			  ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG));
			  ioread32(KVASER_PCIEFD_SRB_ADDR(pcie) +
				   KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG));
	while (srb_packet_count) {
		/* Drop current packet in FIFO */
		ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_FIFO_LAST_REG);
		ioread32(KVASER_PCIEFD_SRB_FIFO_ADDR(pcie) + KVASER_PCIEFD_SRB_FIFO_LAST_REG);
		srb_packet_count--;
	}

	srb_status = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_STAT_REG);
	srb_status = ioread32(KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_STAT_REG);
	if (!(srb_status & KVASER_PCIEFD_SRB_STAT_DI)) {
		dev_err(&pcie->pci->dev, "DMA not idle before enabling\n");
		return -EIO;
@@ -928,7 +1006,7 @@ static int kvaser_pciefd_setup_dma(struct kvaser_pciefd *pcie)

	/* Enable the DMA */
	iowrite32(KVASER_PCIEFD_SRB_CTRL_DMA_ENABLE,
		  pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG);
		  KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CTRL_REG);

	return 0;
}
@@ -937,30 +1015,29 @@ static int kvaser_pciefd_setup_board(struct kvaser_pciefd *pcie)
{
	u32 version, srb_status, build;

	version = ioread32(pcie->reg_base + KVASER_PCIEFD_SYSID_VERSION_REG);
	version = ioread32(KVASER_PCIEFD_SYSID_ADDR(pcie) + KVASER_PCIEFD_SYSID_VERSION_REG);
	pcie->nr_channels = min(KVASER_PCIEFD_MAX_CAN_CHANNELS,
				FIELD_GET(KVASER_PCIEFD_SYSID_VERSION_NR_CHAN_MASK, version));

	build = ioread32(pcie->reg_base + KVASER_PCIEFD_SYSID_BUILD_REG);
	build = ioread32(KVASER_PCIEFD_SYSID_ADDR(pcie) + KVASER_PCIEFD_SYSID_BUILD_REG);
	dev_dbg(&pcie->pci->dev, "Version %lu.%lu.%lu\n",
		FIELD_GET(KVASER_PCIEFD_SYSID_VERSION_MAJOR_MASK, version),
		FIELD_GET(KVASER_PCIEFD_SYSID_VERSION_MINOR_MASK, version),
		FIELD_GET(KVASER_PCIEFD_SYSID_BUILD_SEQ_MASK, build));

	srb_status = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_STAT_REG);
	srb_status = ioread32(KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_STAT_REG);
	if (!(srb_status & KVASER_PCIEFD_SRB_STAT_DMA)) {
		dev_err(&pcie->pci->dev, "Hardware without DMA is not supported\n");
		return -ENODEV;
	}

	pcie->bus_freq = ioread32(pcie->reg_base +
				  KVASER_PCIEFD_SYSID_BUSFREQ_REG);
	pcie->freq = ioread32(pcie->reg_base + KVASER_PCIEFD_SYSID_CANFREQ_REG);
	pcie->bus_freq = ioread32(KVASER_PCIEFD_SYSID_ADDR(pcie) + KVASER_PCIEFD_SYSID_BUSFREQ_REG);
	pcie->freq = ioread32(KVASER_PCIEFD_SYSID_ADDR(pcie) + KVASER_PCIEFD_SYSID_CANFREQ_REG);
	pcie->freq_to_ticks_div = pcie->freq / 1000000;
	if (pcie->freq_to_ticks_div == 0)
		pcie->freq_to_ticks_div = 1;
	/* Turn off all loopback functionality */
	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_LOOP_REG);
	iowrite32(0, KVASER_PCIEFD_LOOPBACK_ADDR(pcie));

	return 0;
}
@@ -1430,21 +1507,20 @@ static int kvaser_pciefd_read_buffer(struct kvaser_pciefd *pcie, int dma_buf)

static void kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
{
	u32 irq;
	u32 irq = ioread32(KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);

	irq = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_IRQ_REG);
	if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0) {
		kvaser_pciefd_read_buffer(pcie, 0);
		/* Reset DMA buffer 0 */
		iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0,
			  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
			  KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
	}

	if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1) {
		kvaser_pciefd_read_buffer(pcie, 1);
		/* Reset DMA buffer 1 */
		iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1,
			  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
			  KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
	}

	if (irq & KVASER_PCIEFD_SRB_IRQ_DOF0 ||
@@ -1453,7 +1529,7 @@ static void kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
	    irq & KVASER_PCIEFD_SRB_IRQ_DUF1)
		dev_err(&pcie->pci->dev, "DMA IRQ error 0x%08X\n", irq);

	iowrite32(irq, pcie->reg_base + KVASER_PCIEFD_SRB_IRQ_REG);
	iowrite32(irq, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
}

static void kvaser_pciefd_transmit_irq(struct kvaser_pciefd_can *can)
@@ -1479,15 +1555,14 @@ static void kvaser_pciefd_transmit_irq(struct kvaser_pciefd_can *can)
static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev)
{
	struct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev;
	u32 board_irq;
	const struct kvaser_pciefd_irq_mask *irq_mask = pcie->driver_data->irq_mask;
	u32 board_irq = ioread32(KVASER_PCIEFD_PCI_IRQ_ADDR(pcie));
	int i;

	board_irq = ioread32(pcie->reg_base + KVASER_PCIEFD_IRQ_REG);

	if (!(board_irq & KVASER_PCIEFD_IRQ_ALL_MASK))
	if (!(board_irq & irq_mask->all))
		return IRQ_NONE;

	if (board_irq & KVASER_PCIEFD_IRQ_SRB)
	if (board_irq & irq_mask->kcan_rx0)
		kvaser_pciefd_receive_irq(pcie);

	for (i = 0; i < pcie->nr_channels; i++) {
@@ -1498,7 +1573,7 @@ static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev)
		}

		/* Check that mask matches channel (i) IRQ mask */
		if (board_irq & (1 << i))
		if (board_irq & irq_mask->kcan_tx[i])
			kvaser_pciefd_transmit_irq(pcie->can[i]);
	}

@@ -1525,6 +1600,8 @@ static int kvaser_pciefd_probe(struct pci_dev *pdev,
{
	int err;
	struct kvaser_pciefd *pcie;
	const struct kvaser_pciefd_irq_mask *irq_mask;
	void __iomem *irq_en_base;

	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
	if (!pcie)
@@ -1532,6 +1609,8 @@ static int kvaser_pciefd_probe(struct pci_dev *pdev,

	pci_set_drvdata(pdev, pcie);
	pcie->pci = pdev;
	pcie->driver_data = (const struct kvaser_pciefd_driver_data *)id->driver_data;
	irq_mask = pcie->driver_data->irq_mask;

	err = pci_enable_device(pdev);
	if (err)
@@ -1567,22 +1646,21 @@ static int kvaser_pciefd_probe(struct pci_dev *pdev,
		goto err_teardown_can_ctrls;

	iowrite32(KVASER_PCIEFD_SRB_IRQ_DPD0 | KVASER_PCIEFD_SRB_IRQ_DPD1,
		  pcie->reg_base + KVASER_PCIEFD_SRB_IRQ_REG);
		  KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);

	iowrite32(KVASER_PCIEFD_SRB_IRQ_DPD0 | KVASER_PCIEFD_SRB_IRQ_DPD1 |
		  KVASER_PCIEFD_SRB_IRQ_DOF0 | KVASER_PCIEFD_SRB_IRQ_DOF1 |
		  KVASER_PCIEFD_SRB_IRQ_DUF0 | KVASER_PCIEFD_SRB_IRQ_DUF1,
		  pcie->reg_base + KVASER_PCIEFD_SRB_IEN_REG);
		  KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IEN_REG);

	/* Enable PCI interrupts */
	iowrite32(KVASER_PCIEFD_IRQ_ALL_MASK,
		  pcie->reg_base + KVASER_PCIEFD_IEN_REG);

	irq_en_base = KVASER_PCIEFD_PCI_IEN_ADDR(pcie);
	iowrite32(irq_mask->all, irq_en_base);
	/* Ready the DMA buffers */
	iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0,
		  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
		  KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
	iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1,
		  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
		  KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);

	err = kvaser_pciefd_reg_candev(pcie);
	if (err)
@@ -1592,12 +1670,12 @@ static int kvaser_pciefd_probe(struct pci_dev *pdev,

err_free_irq:
	/* Disable PCI interrupts */
	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_IEN_REG);
	iowrite32(0, irq_en_base);
	free_irq(pcie->pci->irq, pcie);

err_teardown_can_ctrls:
	kvaser_pciefd_teardown_can_ctrls(pcie);
	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG);
	iowrite32(0, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CTRL_REG);
	pci_clear_master(pdev);

err_pci_iounmap:
@@ -1636,8 +1714,8 @@ static void kvaser_pciefd_remove(struct pci_dev *pdev)
	kvaser_pciefd_remove_all_ctrls(pcie);

	/* Disable interrupts */
	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG);
	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_IEN_REG);
	iowrite32(0, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CTRL_REG);
	iowrite32(0, KVASER_PCIEFD_PCI_IEN_ADDR(pcie));

	free_irq(pcie->pci->irq, pcie);