Commit 830920e0 authored by Marc Zyngier's avatar Marc Zyngier Committed by Lorenzo Pieralisi

PCI: dwc: Use interrupt masking instead of disabling

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: 7c5925af ("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: default avatarNiklas Cassel <niklas.cassel@linaro.org>
Tested-by: default avatarGustavo Pimentel <gustavo.pimentel@synopsys.com>
Tested-by: default avatarStanimir Varbanov <svarbanov@mm-sol.com>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
[lorenzo.pieralisi@arm.com: updated commit log]
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: stable@vger.kernel.org
parent 65102238
...@@ -168,8 +168,8 @@ static void dw_pci_bottom_mask(struct irq_data *data) ...@@ -168,8 +168,8 @@ static void dw_pci_bottom_mask(struct irq_data *data)
bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL;
pp->irq_status[ctrl] &= ~(1 << bit); pp->irq_status[ctrl] &= ~(1 << bit);
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4,
pp->irq_status[ctrl]); ~pp->irq_status[ctrl]);
} }
raw_spin_unlock_irqrestore(&pp->lock, flags); raw_spin_unlock_irqrestore(&pp->lock, flags);
...@@ -191,8 +191,8 @@ static void dw_pci_bottom_unmask(struct irq_data *data) ...@@ -191,8 +191,8 @@ static void dw_pci_bottom_unmask(struct irq_data *data)
bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL;
pp->irq_status[ctrl] |= 1 << bit; pp->irq_status[ctrl] |= 1 << bit;
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4,
pp->irq_status[ctrl]); ~pp->irq_status[ctrl]);
} }
raw_spin_unlock_irqrestore(&pp->lock, flags); raw_spin_unlock_irqrestore(&pp->lock, flags);
...@@ -658,10 +658,15 @@ void dw_pcie_setup_rc(struct pcie_port *pp) ...@@ -658,10 +658,15 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL;
/* Initialize IRQ Status array */ /* Initialize IRQ Status array */
for (ctrl = 0; ctrl < num_ctrls; ctrl++) for (ctrl = 0; ctrl < num_ctrls; ctrl++) {
dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK +
(ctrl * MSI_REG_CTRL_BLOCK_SIZE), (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 */ /* Setup RC BARs */
dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004); dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment