On Thu, 25 Mar 2021 09:00:25 +0000, Kishon Vijay Abraham I <kishon@xxxxxx> wrote: > > Add PCI legacy interrupt support for AM654. AM654 has a single HW > interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD. > The HW interrupt line connected to GIC is a pulse interrupt whereas > the legacy interrupts by definition is level interrupt. In order to > provide level interrupt functionality to edge interrupt line, PCIe > in AM654 has provided IRQ_EOI register. When the SW writes to IRQ_EOI > register after handling the interrupt, the IP checks the state of > legacy interrupt and re-triggers pulse interrupt invoking the handler > again. > > Signed-off-by: Kishon Vijay Abraham I <kishon@xxxxxx> > --- > drivers/pci/controller/dwc/pci-keystone.c | 87 +++++++++++++++++++++-- > 1 file changed, 82 insertions(+), 5 deletions(-) > > diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c > index dfa9a7fcf9b7..84a25207d0d3 100644 > --- a/drivers/pci/controller/dwc/pci-keystone.c > +++ b/drivers/pci/controller/dwc/pci-keystone.c > @@ -118,6 +118,7 @@ struct keystone_pcie { > /* PCI Device ID */ > u32 device_id; > struct device_node *legacy_intc_np; > + struct irq_domain *legacy_irq_domain; > > int msi_host_irq; > int num_lanes; > @@ -289,6 +290,29 @@ static irqreturn_t ks_pcie_handle_error_irq(struct keystone_pcie *ks_pcie) > return IRQ_HANDLED; > } > > +static void ks_pcie_am654_legacy_irq_handler(struct irq_desc *desc) > +{ > + struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc); > + struct irq_chip *chip = irq_desc_get_chip(desc); > + int virq, i; > + u32 reg; > + > + chained_irq_enter(chip, desc); > + > + for (i = 0; i < PCI_NUM_INTX; i++) { > + reg = ks_pcie_app_readl(ks_pcie, IRQ_STATUS(i)); > + if (!(reg & INTx_EN)) > + continue; > + > + virq = irq_linear_revmap(ks_pcie->legacy_irq_domain, i); > + generic_handle_irq(virq); I'm on my way to kill irq_linear_revmap(), so I'd rather you didn't add more instances. Consider using irq_find_mapping() instead. > + ks_pcie_app_writel(ks_pcie, IRQ_STATUS(i), INTx_EN); > + ks_pcie_app_writel(ks_pcie, IRQ_EOI, i); What are these writes for? The first one feels like an Ack, and the second one has EOI written over it. If that's what they are, llease move these to a proper irq_chip structure and use the appropriate flow handler, instead of dummy_irq_chip and handle_simple_irq. Thanks, M. -- Without deviation from the norm, progress is not possible.