Skip to content

Commit 9176bd2

Browse files
axelf4marckleinebudde
authored andcommitted
can: kvaser_pciefd: Force IRQ edge in case of nested IRQ
Avoid the driver missing IRQs by temporarily masking IRQs in the ISR to enforce an edge even if a different IRQ is signalled before handled IRQs are cleared. Fixes: 48f827d ("can: kvaser_pciefd: Move reset of DMA RX buffers to the end of the ISR") Cc: [email protected] Signed-off-by: Axel Forsman <[email protected]> Tested-by: Jimmy Assarsson <[email protected]> Reviewed-by: Jimmy Assarsson <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent 9e89db3 commit 9176bd2

File tree

1 file changed

+38
-43
lines changed

1 file changed

+38
-43
lines changed

drivers/net/can/kvaser_pciefd.c

Lines changed: 38 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,24 +1646,28 @@ static int kvaser_pciefd_read_buffer(struct kvaser_pciefd *pcie, int dma_buf)
16461646
return res;
16471647
}
16481648

1649-
static u32 kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
1649+
static void kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
16501650
{
1651+
void __iomem *srb_cmd_reg = KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG;
16511652
u32 irq = ioread32(KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
16521653

1653-
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0)
1654+
iowrite32(irq, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
1655+
1656+
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0) {
16541657
kvaser_pciefd_read_buffer(pcie, 0);
1658+
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0, srb_cmd_reg); /* Rearm buffer */
1659+
}
16551660

1656-
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1)
1661+
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1) {
16571662
kvaser_pciefd_read_buffer(pcie, 1);
1663+
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1, srb_cmd_reg); /* Rearm buffer */
1664+
}
16581665

16591666
if (unlikely(irq & KVASER_PCIEFD_SRB_IRQ_DOF0 ||
16601667
irq & KVASER_PCIEFD_SRB_IRQ_DOF1 ||
16611668
irq & KVASER_PCIEFD_SRB_IRQ_DUF0 ||
16621669
irq & KVASER_PCIEFD_SRB_IRQ_DUF1))
16631670
dev_err(&pcie->pci->dev, "DMA IRQ error 0x%08X\n", irq);
1664-
1665-
iowrite32(irq, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
1666-
return irq;
16671671
}
16681672

16691673
static void kvaser_pciefd_transmit_irq(struct kvaser_pciefd_can *can)
@@ -1691,29 +1695,22 @@ static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev)
16911695
struct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev;
16921696
const struct kvaser_pciefd_irq_mask *irq_mask = pcie->driver_data->irq_mask;
16931697
u32 pci_irq = ioread32(KVASER_PCIEFD_PCI_IRQ_ADDR(pcie));
1694-
u32 srb_irq = 0;
1695-
u32 srb_release = 0;
16961698
int i;
16971699

16981700
if (!(pci_irq & irq_mask->all))
16991701
return IRQ_NONE;
17001702

1703+
iowrite32(0, KVASER_PCIEFD_PCI_IEN_ADDR(pcie));
1704+
17011705
if (pci_irq & irq_mask->kcan_rx0)
1702-
srb_irq = kvaser_pciefd_receive_irq(pcie);
1706+
kvaser_pciefd_receive_irq(pcie);
17031707

17041708
for (i = 0; i < pcie->nr_channels; i++) {
17051709
if (pci_irq & irq_mask->kcan_tx[i])
17061710
kvaser_pciefd_transmit_irq(pcie->can[i]);
17071711
}
17081712

1709-
if (srb_irq & KVASER_PCIEFD_SRB_IRQ_DPD0)
1710-
srb_release |= KVASER_PCIEFD_SRB_CMD_RDB0;
1711-
1712-
if (srb_irq & KVASER_PCIEFD_SRB_IRQ_DPD1)
1713-
srb_release |= KVASER_PCIEFD_SRB_CMD_RDB1;
1714-
1715-
if (srb_release)
1716-
iowrite32(srb_release, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
1713+
iowrite32(irq_mask->all, KVASER_PCIEFD_PCI_IEN_ADDR(pcie));
17171714

17181715
return IRQ_HANDLED;
17191716
}
@@ -1733,13 +1730,22 @@ static void kvaser_pciefd_teardown_can_ctrls(struct kvaser_pciefd *pcie)
17331730
}
17341731
}
17351732

1733+
static void kvaser_pciefd_disable_irq_srcs(struct kvaser_pciefd *pcie)
1734+
{
1735+
unsigned int i;
1736+
1737+
/* Masking PCI_IRQ is insufficient as running ISR will unmask it */
1738+
iowrite32(0, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IEN_REG);
1739+
for (i = 0; i < pcie->nr_channels; ++i)
1740+
iowrite32(0, pcie->can[i]->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
1741+
}
1742+
17361743
static int kvaser_pciefd_probe(struct pci_dev *pdev,
17371744
const struct pci_device_id *id)
17381745
{
17391746
int ret;
17401747
struct kvaser_pciefd *pcie;
17411748
const struct kvaser_pciefd_irq_mask *irq_mask;
1742-
void __iomem *irq_en_base;
17431749

17441750
pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
17451751
if (!pcie)
@@ -1805,8 +1811,7 @@ static int kvaser_pciefd_probe(struct pci_dev *pdev,
18051811
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IEN_REG);
18061812

18071813
/* Enable PCI interrupts */
1808-
irq_en_base = KVASER_PCIEFD_PCI_IEN_ADDR(pcie);
1809-
iowrite32(irq_mask->all, irq_en_base);
1814+
iowrite32(irq_mask->all, KVASER_PCIEFD_PCI_IEN_ADDR(pcie));
18101815
/* Ready the DMA buffers */
18111816
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0,
18121817
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
@@ -1820,8 +1825,7 @@ static int kvaser_pciefd_probe(struct pci_dev *pdev,
18201825
return 0;
18211826

18221827
err_free_irq:
1823-
/* Disable PCI interrupts */
1824-
iowrite32(0, irq_en_base);
1828+
kvaser_pciefd_disable_irq_srcs(pcie);
18251829
free_irq(pcie->pci->irq, pcie);
18261830

18271831
err_pci_free_irq_vectors:
@@ -1844,35 +1848,26 @@ static int kvaser_pciefd_probe(struct pci_dev *pdev,
18441848
return ret;
18451849
}
18461850

1847-
static void kvaser_pciefd_remove_all_ctrls(struct kvaser_pciefd *pcie)
1848-
{
1849-
int i;
1850-
1851-
for (i = 0; i < pcie->nr_channels; i++) {
1852-
struct kvaser_pciefd_can *can = pcie->can[i];
1853-
1854-
if (can) {
1855-
iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
1856-
unregister_candev(can->can.dev);
1857-
timer_delete(&can->bec_poll_timer);
1858-
kvaser_pciefd_pwm_stop(can);
1859-
free_candev(can->can.dev);
1860-
}
1861-
}
1862-
}
1863-
18641851
static void kvaser_pciefd_remove(struct pci_dev *pdev)
18651852
{
18661853
struct kvaser_pciefd *pcie = pci_get_drvdata(pdev);
1854+
unsigned int i;
18671855

1868-
kvaser_pciefd_remove_all_ctrls(pcie);
1856+
for (i = 0; i < pcie->nr_channels; ++i) {
1857+
struct kvaser_pciefd_can *can = pcie->can[i];
18691858

1870-
/* Disable interrupts */
1871-
iowrite32(0, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CTRL_REG);
1872-
iowrite32(0, KVASER_PCIEFD_PCI_IEN_ADDR(pcie));
1859+
unregister_candev(can->can.dev);
1860+
timer_delete(&can->bec_poll_timer);
1861+
kvaser_pciefd_pwm_stop(can);
1862+
}
18731863

1864+
kvaser_pciefd_disable_irq_srcs(pcie);
18741865
free_irq(pcie->pci->irq, pcie);
18751866
pci_free_irq_vectors(pcie->pci);
1867+
1868+
for (i = 0; i < pcie->nr_channels; ++i)
1869+
free_candev(pcie->can[i]->can.dev);
1870+
18761871
pci_iounmap(pdev, pcie->reg_base);
18771872
pci_release_regions(pdev);
18781873
pci_disable_device(pdev);

0 commit comments

Comments
 (0)