Skip to content

Commit

Permalink
PCI: dwc: Use interrupt masking instead of disabling
Browse files Browse the repository at this point in the history
The dwc driver is showing an interesting level of brokeness, as it
insists on using the enable/disable set of registers to mask/unmask
MSIs, meaning that an MSIs being generated while the interrupt is in
that "disabled" state will simply be lost.

Let's move to the mask/unmask set of registers, which offers the
expected semantics.

Fixes: 7c5925a ("PCI: dwc: Move MSI IRQs allocation to IRQ domains
hierarchical API")
Link: https://lore.kernel.org/linux-pci/20181113225734.8026-1-marc.zyngier@arm.com/
Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Tested-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Tested-by: Stanimir Varbanov <svarbanov@mm-sol.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
[lorenzo.pieralisi@arm.com: updated commit log]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: stable@vger.kernel.org
  • Loading branch information
Marc Zyngier authored and Lorenzo Pieralisi committed Dec 11, 2018
1 parent 6510223 commit 830920e
Showing 1 changed file with 12 additions and 7 deletions.
19 changes: 12 additions & 7 deletions drivers/pci/controller/dwc/pcie-designware-host.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ static void dw_pci_bottom_mask(struct irq_data *data)
bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL;

pp->irq_status[ctrl] &= ~(1 << bit);
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4,
pp->irq_status[ctrl]);
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4,
~pp->irq_status[ctrl]);
}

raw_spin_unlock_irqrestore(&pp->lock, flags);
Expand All @@ -191,8 +191,8 @@ static void dw_pci_bottom_unmask(struct irq_data *data)
bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL;

pp->irq_status[ctrl] |= 1 << bit;
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4,
pp->irq_status[ctrl]);
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4,
~pp->irq_status[ctrl]);
}

raw_spin_unlock_irqrestore(&pp->lock, flags);
Expand Down Expand Up @@ -658,10 +658,15 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL;

/* Initialize IRQ Status array */
for (ctrl = 0; ctrl < num_ctrls; ctrl++)
dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE +
for (ctrl = 0; ctrl < num_ctrls; ctrl++) {
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK +
(ctrl * MSI_REG_CTRL_BLOCK_SIZE),
4, &pp->irq_status[ctrl]);
4, ~0);
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE +
(ctrl * MSI_REG_CTRL_BLOCK_SIZE),
4, ~0);
pp->irq_status[ctrl] = 0;
}

/* Setup RC BARs */
dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004);
Expand Down

0 comments on commit 830920e

Please sign in to comment.