mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-07 09:55:19 +02:00
can: kvaser_pciefd: Move reset of DMA RX buffers to the end of the ISR
[ Upstream commit48f827d4f4
] A new interrupt is triggered by resetting the DMA RX buffers. Since MSI interrupts are faster than legacy interrupts, the reset of the DMA buffers must be moved to the very end of the ISR, otherwise a new MSI interrupt will be masked by the current one. Signed-off-by: Martin Jocic <martin.jocic@kvaser.com> Link: https://lore.kernel.org/all/20240620181320.235465-2-martin.jocic@kvaser.com Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Stable-dep-of:dd885d90c0
("can: kvaser_pciefd: Use a single write when releasing RX buffers") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
00e4c69422
commit
6587b387cd
|
@ -1580,23 +1580,15 @@ static int kvaser_pciefd_read_buffer(struct kvaser_pciefd *pcie, int dma_buf)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
|
static u32 kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
|
||||||
{
|
{
|
||||||
u32 irq = ioread32(KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
|
u32 irq = ioread32(KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
|
||||||
|
|
||||||
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0) {
|
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0)
|
||||||
kvaser_pciefd_read_buffer(pcie, 0);
|
kvaser_pciefd_read_buffer(pcie, 0);
|
||||||
/* Reset DMA buffer 0 */
|
|
||||||
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0,
|
|
||||||
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1) {
|
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1)
|
||||||
kvaser_pciefd_read_buffer(pcie, 1);
|
kvaser_pciefd_read_buffer(pcie, 1);
|
||||||
/* Reset DMA buffer 1 */
|
|
||||||
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1,
|
|
||||||
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (irq & KVASER_PCIEFD_SRB_IRQ_DOF0 ||
|
if (irq & KVASER_PCIEFD_SRB_IRQ_DOF0 ||
|
||||||
irq & KVASER_PCIEFD_SRB_IRQ_DOF1 ||
|
irq & KVASER_PCIEFD_SRB_IRQ_DOF1 ||
|
||||||
|
@ -1605,6 +1597,7 @@ static void kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
|
||||||
dev_err(&pcie->pci->dev, "DMA IRQ error 0x%08X\n", irq);
|
dev_err(&pcie->pci->dev, "DMA IRQ error 0x%08X\n", irq);
|
||||||
|
|
||||||
iowrite32(irq, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
|
iowrite32(irq, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
|
||||||
|
return irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvaser_pciefd_transmit_irq(struct kvaser_pciefd_can *can)
|
static void kvaser_pciefd_transmit_irq(struct kvaser_pciefd_can *can)
|
||||||
|
@ -1632,19 +1625,32 @@ static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev)
|
||||||
struct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev;
|
struct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev;
|
||||||
const struct kvaser_pciefd_irq_mask *irq_mask = pcie->driver_data->irq_mask;
|
const struct kvaser_pciefd_irq_mask *irq_mask = pcie->driver_data->irq_mask;
|
||||||
u32 pci_irq = ioread32(KVASER_PCIEFD_PCI_IRQ_ADDR(pcie));
|
u32 pci_irq = ioread32(KVASER_PCIEFD_PCI_IRQ_ADDR(pcie));
|
||||||
|
u32 srb_irq = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!(pci_irq & irq_mask->all))
|
if (!(pci_irq & irq_mask->all))
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
|
|
||||||
if (pci_irq & irq_mask->kcan_rx0)
|
if (pci_irq & irq_mask->kcan_rx0)
|
||||||
kvaser_pciefd_receive_irq(pcie);
|
srb_irq = kvaser_pciefd_receive_irq(pcie);
|
||||||
|
|
||||||
for (i = 0; i < pcie->nr_channels; i++) {
|
for (i = 0; i < pcie->nr_channels; i++) {
|
||||||
if (pci_irq & irq_mask->kcan_tx[i])
|
if (pci_irq & irq_mask->kcan_tx[i])
|
||||||
kvaser_pciefd_transmit_irq(pcie->can[i]);
|
kvaser_pciefd_transmit_irq(pcie->can[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srb_irq & KVASER_PCIEFD_SRB_IRQ_DPD0) {
|
||||||
|
/* Reset DMA buffer 0, may trigger new interrupt */
|
||||||
|
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0,
|
||||||
|
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srb_irq & KVASER_PCIEFD_SRB_IRQ_DPD1) {
|
||||||
|
/* Reset DMA buffer 1, may trigger new interrupt */
|
||||||
|
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1,
|
||||||
|
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
|
||||||
|
}
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user