diff options
Diffstat (limited to 'drivers/pci/controller/plda/pcie-microchip-host.c')
-rw-r--r-- | drivers/pci/controller/plda/pcie-microchip-host.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/pci/controller/plda/pcie-microchip-host.c b/drivers/pci/controller/plda/pcie-microchip-host.c index e4c58f5133d8b..110a232be8751 100644 --- a/drivers/pci/controller/plda/pcie-microchip-host.c +++ b/drivers/pci/controller/plda/pcie-microchip-host.c @@ -626,6 +626,26 @@ static u32 mc_get_events(struct plda_pcie_rp *port) return events; } +static u32 plda_get_events(struct plda_pcie_rp *port) +{ + u32 events, val, origin; + + origin = readl_relaxed(port->bridge_addr + ISTATUS_LOCAL); + + /* MSI event and sys events */ + val = (origin & SYS_AND_MSI_MASK) >> PM_MSI_INT_MSI_SHIFT; + events = val << (PM_MSI_INT_MSI_SHIFT - PCI_NUM_INTX + 1); + + /* INTx events */ + if (origin & PM_MSI_INT_INTX_MASK) + events |= BIT(PM_MSI_INT_INTX_SHIFT); + + /* remains are same with register */ + events |= origin & GENMASK(P_ATR_EVT_DOORBELL_SHIFT, 0); + + return events; +} + static irqreturn_t mc_event_handler(int irq, void *dev_id) { struct plda_pcie_rp *port = dev_id; @@ -656,7 +676,7 @@ static void plda_handle_event(struct irq_desc *desc) chained_irq_enter(chip, desc); - events = mc_get_events(port); + events = port->event_ops->get_events(port); for_each_set_bit(bit, &events, port->num_events) generic_handle_domain_irq(port->event_domain, bit); @@ -750,6 +770,10 @@ static struct irq_chip mc_event_irq_chip = { .irq_unmask = mc_unmask_event_irq, }; +static const struct plda_event_ops plda_event_ops = { + .get_events = plda_get_events, +}; + static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq) { @@ -815,6 +839,10 @@ static int mc_request_event_irq(struct plda_pcie_rp *plda, int event_irq, 0, event_cause[event].sym, plda); } +static const struct plda_event_ops mc_event_ops = { + .get_events = mc_get_events, +}; + static const struct plda_event mc_event = { .request_event_irq = mc_request_event_irq, .intx_event = EVENT_LOCAL_PM_MSI_INT_INTX, @@ -931,6 +959,9 @@ static int plda_init_interrupts(struct platform_device *pdev, int i, intx_irq, msi_irq, event_irq; int ret; + if (!port->event_ops) + port->event_ops = &plda_event_ops; + ret = plda_pcie_init_irq_domains(port); if (ret) { dev_err(dev, "failed creating IRQ domains\n"); @@ -1006,6 +1037,8 @@ static int mc_platform_init(struct pci_config_window *cfg) if (ret) return ret; + port->plda.event_ops = &mc_event_ops; + /* Address translation is up; safe to enable interrupts */ ret = plda_init_interrupts(pdev, &port->plda, &mc_event); if (ret) |