On Thu, 26 May 2022 at 21:42, Rob Herring <robh@xxxxxxxxxx> wrote: > > On Mon, May 23, 2022 at 09:18:34PM +0300, Dmitry Baryshkov wrote: > > If the PCIe DWC controller uses split MSI IRQs for reporting MSI > > vectors, it is possible to detect, which group triggered the interrupt. > > Provide an optimized version of MSI ISR handler that will handle just a > > single MSI group instead of handling all of them. > > A lot more complexity to save 7 register reads... Thus it is a separate patch. It can be dropped w/o any issues. > > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx> > > --- > > .../pci/controller/dwc/pcie-designware-host.c | 86 ++++++++++++++----- > > 1 file changed, 65 insertions(+), 21 deletions(-) > > > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c > > index 98a57249ecaf..2b2de517301a 100644 > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c > > @@ -52,34 +52,42 @@ static struct msi_domain_info dw_pcie_msi_domain_info = { > > .chip = &dw_pcie_msi_irq_chip, > > }; > > > > +static inline irqreturn_t dw_handle_single_msi_group(struct pcie_port *pp, int i) > > +{ > > + int pos; > > + unsigned long val; > > + u32 status; > > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); > > + > > + status = dw_pcie_readl_dbi(pci, PCIE_MSI_INTR0_STATUS + > > + (i * MSI_REG_CTRL_BLOCK_SIZE)); > > + if (!status) > > + return IRQ_NONE; > > + > > + val = status; > > + pos = 0; > > + while ((pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, > > + pos)) != MAX_MSI_IRQS_PER_CTRL) { > > for_each_set_bit() doesn't work here? Good question, I just moved the existing DWC code. > > > + generic_handle_domain_irq(pp->irq_domain, > > + (i * MAX_MSI_IRQS_PER_CTRL) + > > + pos); > > + pos++; > > + } > > + > > + return IRQ_HANDLED; > > +} > > + > > /* MSI int handler */ > > irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) > > { > > - int i, pos; > > - unsigned long val; > > - u32 status, num_ctrls; > > + int i; > > + u32 num_ctrls; > > irqreturn_t ret = IRQ_NONE; > > - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); > > > > num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; > > > > - for (i = 0; i < num_ctrls; i++) { > > - status = dw_pcie_readl_dbi(pci, PCIE_MSI_INTR0_STATUS + > > - (i * MSI_REG_CTRL_BLOCK_SIZE)); > > - if (!status) > > - continue; > > - > > - ret = IRQ_HANDLED; > > - val = status; > > - pos = 0; > > - while ((pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, > > - pos)) != MAX_MSI_IRQS_PER_CTRL) { > > - generic_handle_domain_irq(pp->irq_domain, > > - (i * MAX_MSI_IRQS_PER_CTRL) + > > - pos); > > - pos++; > > - } > > - } > > + for (i = 0; i < num_ctrls; i++) > > + ret |= dw_handle_single_msi_group(pp, i); > > > > return ret; > > } -- With best wishes Dmitry