Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ad9a873 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Bjorn Helgaas
Browse files

Merge branch 'lorenzo/pci/dwc-msi'

* lorenzo/pci/dwc-msi:
  PCI: dwc: Expand maximum number of MSI IRQs from 32 to 256
  PCI: dwc: Remove old MSI IRQs API
  PCI: dwc: Move MSI IRQs allocation to IRQ domains hierarchical API
parents f3c91098 1f319cb0
Loading
Loading
Loading
Loading
+0 −18
Original line number Diff line number Diff line
@@ -294,15 +294,6 @@ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
	return IRQ_HANDLED;
}

static irqreturn_t exynos_pcie_msi_irq_handler(int irq, void *arg)
{
	struct exynos_pcie *ep = arg;
	struct dw_pcie *pci = ep->pci;
	struct pcie_port *pp = &pci->pp;

	return dw_handle_msi_irq(pp);
}

static void exynos_pcie_msi_init(struct exynos_pcie *ep)
{
	struct dw_pcie *pci = ep->pci;
@@ -428,15 +419,6 @@ static int __init exynos_add_pcie_port(struct exynos_pcie *ep,
			dev_err(dev, "failed to get msi irq\n");
			return pp->msi_irq;
		}

		ret = devm_request_irq(dev, pp->msi_irq,
					exynos_pcie_msi_irq_handler,
					IRQF_SHARED | IRQF_NO_THREAD,
					"exynos-pcie", ep);
		if (ret) {
			dev_err(dev, "failed to request msi irq\n");
			return ret;
		}
	}

	pp->root_bus_nr = -1;
+0 −18
Original line number Diff line number Diff line
@@ -542,15 +542,6 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
	return -EINVAL;
}

static irqreturn_t imx6_pcie_msi_handler(int irq, void *arg)
{
	struct imx6_pcie *imx6_pcie = arg;
	struct dw_pcie *pci = imx6_pcie->pci;
	struct pcie_port *pp = &pci->pp;

	return dw_handle_msi_irq(pp);
}

static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
{
	struct dw_pcie *pci = imx6_pcie->pci;
@@ -674,15 +665,6 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
			dev_err(dev, "failed to get MSI irq\n");
			return -ENODEV;
		}

		ret = devm_request_irq(dev, pp->msi_irq,
				       imx6_pcie_msi_handler,
				       IRQF_SHARED | IRQF_NO_THREAD,
				       "mx6-pcie-msi", imx6_pcie);
		if (ret) {
			dev_err(dev, "failed to request MSI irq\n");
			return ret;
		}
	}

	pp->root_bus_nr = -1;
+5 −86
Original line number Diff line number Diff line
@@ -120,20 +120,15 @@ void ks_dw_pcie_handle_msi_irq(struct keystone_pcie *ks_pcie, int offset)
	}
}

static void ks_dw_pcie_msi_irq_ack(struct irq_data *d)
void ks_dw_pcie_msi_irq_ack(int irq, struct pcie_port *pp)
{
	u32 offset, reg_offset, bit_pos;
	u32 reg_offset, bit_pos;
	struct keystone_pcie *ks_pcie;
	struct msi_desc *msi;
	struct pcie_port *pp;
	struct dw_pcie *pci;

	msi = irq_data_get_msi_desc(d);
	pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
	pci = to_dw_pcie_from_pp(pp);
	ks_pcie = to_keystone_pcie(pci);
	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
	update_reg_offset_bit_pos(offset, &reg_offset, &bit_pos);
	update_reg_offset_bit_pos(irq, &reg_offset, &bit_pos);

	ks_dw_app_writel(ks_pcie, MSI0_IRQ_STATUS + (reg_offset << 4),
			 BIT(bit_pos));
@@ -162,85 +157,9 @@ void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq)
			 BIT(bit_pos));
}

static void ks_dw_pcie_msi_irq_mask(struct irq_data *d)
{
	struct msi_desc *msi;
	struct pcie_port *pp;
	u32 offset;

	msi = irq_data_get_msi_desc(d);
	pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);

	/* Mask the end point if PVM implemented */
	if (IS_ENABLED(CONFIG_PCI_MSI)) {
		if (msi->msi_attrib.maskbit)
			pci_msi_mask_irq(d);
	}

	ks_dw_pcie_msi_clear_irq(pp, offset);
}

static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d)
{
	struct msi_desc *msi;
	struct pcie_port *pp;
	u32 offset;

	msi = irq_data_get_msi_desc(d);
	pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);

	/* Mask the end point if PVM implemented */
	if (IS_ENABLED(CONFIG_PCI_MSI)) {
		if (msi->msi_attrib.maskbit)
			pci_msi_unmask_irq(d);
	}

	ks_dw_pcie_msi_set_irq(pp, offset);
}

static struct irq_chip ks_dw_pcie_msi_irq_chip = {
	.name = "Keystone-PCIe-MSI-IRQ",
	.irq_ack = ks_dw_pcie_msi_irq_ack,
	.irq_mask = ks_dw_pcie_msi_irq_mask,
	.irq_unmask = ks_dw_pcie_msi_irq_unmask,
};

static int ks_dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
			      irq_hw_number_t hwirq)
int ks_dw_pcie_msi_host_init(struct pcie_port *pp)
{
	irq_set_chip_and_handler(irq, &ks_dw_pcie_msi_irq_chip,
				 handle_level_irq);
	irq_set_chip_data(irq, domain->host_data);

	return 0;
}

static const struct irq_domain_ops ks_dw_pcie_msi_domain_ops = {
	.map = ks_dw_pcie_msi_map,
};

int ks_dw_pcie_msi_host_init(struct pcie_port *pp, struct msi_controller *chip)
{
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct keystone_pcie *ks_pcie = to_keystone_pcie(pci);
	struct device *dev = pci->dev;
	int i;

	pp->irq_domain = irq_domain_add_linear(ks_pcie->msi_intc_np,
					MAX_MSI_IRQS,
					&ks_dw_pcie_msi_domain_ops,
					chip);
	if (!pp->irq_domain) {
		dev_err(dev, "irq domain init failed\n");
		return -ENXIO;
	}

	for (i = 0; i < MAX_MSI_IRQS; i++)
		irq_create_mapping(pp->irq_domain, i);

	return 0;
	return dw_pcie_allocate_domains(pp);
}

void ks_dw_pcie_enable_legacy_irqs(struct keystone_pcie *ks_pcie)
+1 −0
Original line number Diff line number Diff line
@@ -297,6 +297,7 @@ static const struct dw_pcie_host_ops keystone_pcie_host_ops = {
	.msi_clear_irq = ks_dw_pcie_msi_clear_irq,
	.get_msi_addr = ks_dw_pcie_get_msi_addr,
	.msi_host_init = ks_dw_pcie_msi_host_init,
	.msi_irq_ack = ks_dw_pcie_msi_irq_ack,
	.scan_bus = ks_dw_pcie_v3_65_scan_bus,
};

+2 −2
Original line number Diff line number Diff line
@@ -49,9 +49,9 @@ int ks_dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
		unsigned int devfn, int where, int size, u32 *val);
void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie);
void ks_dw_pcie_initiate_link_train(struct keystone_pcie *ks_pcie);
void ks_dw_pcie_msi_irq_ack(int i, struct pcie_port *pp);
void ks_dw_pcie_msi_set_irq(struct pcie_port *pp, int irq);
void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq);
void ks_dw_pcie_v3_65_scan_bus(struct pcie_port *pp);
int ks_dw_pcie_msi_host_init(struct pcie_port *pp,
		struct msi_controller *chip);
int ks_dw_pcie_msi_host_init(struct pcie_port *pp);
int ks_dw_pcie_link_up(struct dw_pcie *pci);
Loading