All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Cédric Le Goater" <clg@kaod.org>
To: linuxppc-dev@lists.ozlabs.org
Cc: "Cédric Le Goater" <clg@kaod.org>
Subject: [PATCH v2 12/32] powerpc/powernv/pci: Add MSI domains
Date: Thu,  1 Jul 2021 15:27:30 +0200	[thread overview]
Message-ID: <20210701132750.1475580-13-clg@kaod.org> (raw)
In-Reply-To: <20210701132750.1475580-1-clg@kaod.org>

This is very similar to the MSI domains of the pSeries platform. The
MSI allocator is directly handled under the Linux PHB in the
in-the-middle "PNV-MSI" domain.

Only the XIVE (P9/P10) parent domain is supported for now. Support for
XICS will come later.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 188 ++++++++++++++++++++++
 1 file changed, 188 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 2922674cc934..d2a17fcb6002 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -36,6 +36,7 @@
 #include <asm/firmware.h>
 #include <asm/pnv-pci.h>
 #include <asm/mmzone.h>
+#include <asm/xive.h>
 
 #include <misc/cxl-base.h>
 
@@ -2100,6 +2101,189 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
 	return 0;
 }
 
+/*
+ * The msi_free() op is called before irq_domain_free_irqs_top() when
+ * the handler data is still available. Use that to clear the XIVE
+ * controller.
+ */
+static void pnv_msi_ops_msi_free(struct irq_domain *domain,
+				 struct msi_domain_info *info,
+				 unsigned int irq)
+{
+	if (xive_enabled())
+		xive_irq_free_data(irq);
+}
+
+static struct msi_domain_ops pnv_pci_msi_domain_ops = {
+	.msi_free	= pnv_msi_ops_msi_free,
+};
+
+static void pnv_msi_shutdown(struct irq_data *d)
+{
+	d = d->parent_data;
+	if (d->chip->irq_shutdown)
+		d->chip->irq_shutdown(d);
+}
+
+static void pnv_msi_mask(struct irq_data *d)
+{
+	pci_msi_mask_irq(d);
+	irq_chip_mask_parent(d);
+}
+
+static void pnv_msi_unmask(struct irq_data *d)
+{
+	pci_msi_unmask_irq(d);
+	irq_chip_unmask_parent(d);
+}
+
+static struct irq_chip pnv_pci_msi_irq_chip = {
+	.name		= "PNV-PCI-MSI",
+	.irq_shutdown	= pnv_msi_shutdown,
+	.irq_mask	= pnv_msi_mask,
+	.irq_unmask	= pnv_msi_unmask,
+	.irq_eoi	= irq_chip_eoi_parent,
+};
+
+static struct msi_domain_info pnv_msi_domain_info = {
+	.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+		  MSI_FLAG_MULTI_PCI_MSI  | MSI_FLAG_PCI_MSIX),
+	.ops   = &pnv_pci_msi_domain_ops,
+	.chip  = &pnv_pci_msi_irq_chip,
+};
+
+static void pnv_msi_compose_msg(struct irq_data *d, struct msi_msg *msg)
+{
+	struct msi_desc *entry = irq_data_get_msi_desc(d);
+	struct pci_dev *pdev = msi_desc_to_pci_dev(entry);
+	struct pci_controller *hose = irq_data_get_irq_chip_data(d);
+	struct pnv_phb *phb = hose->private_data;
+	int rc;
+
+	rc = __pnv_pci_ioda_msi_setup(phb, pdev, d->hwirq,
+				      entry->msi_attrib.is_64, msg);
+	if (rc)
+		dev_err(&pdev->dev, "Failed to setup %s-bit MSI #%ld : %d\n",
+			entry->msi_attrib.is_64 ? "64" : "32", d->hwirq, rc);
+}
+
+static struct irq_chip pnv_msi_irq_chip = {
+	.name			= "PNV-MSI",
+	.irq_shutdown		= pnv_msi_shutdown,
+	.irq_mask		= irq_chip_mask_parent,
+	.irq_unmask		= irq_chip_unmask_parent,
+	.irq_eoi		= irq_chip_eoi_parent,
+	.irq_set_affinity	= irq_chip_set_affinity_parent,
+	.irq_compose_msi_msg	= pnv_msi_compose_msg,
+};
+
+static int pnv_irq_parent_domain_alloc(struct irq_domain *domain,
+				       unsigned int virq, int hwirq)
+{
+	struct irq_fwspec parent_fwspec;
+	int ret;
+
+	parent_fwspec.fwnode = domain->parent->fwnode;
+	parent_fwspec.param_count = 2;
+	parent_fwspec.param[0] = hwirq;
+	parent_fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
+
+	ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &parent_fwspec);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int pnv_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				unsigned int nr_irqs, void *arg)
+{
+	struct pci_controller *hose = domain->host_data;
+	struct pnv_phb *phb = hose->private_data;
+	msi_alloc_info_t *info = arg;
+	struct pci_dev *pdev = msi_desc_to_pci_dev(info->desc);
+	int hwirq;
+	int i, ret;
+
+	hwirq = msi_bitmap_alloc_hwirqs(&phb->msi_bmp, nr_irqs);
+	if (hwirq < 0) {
+		dev_warn(&pdev->dev, "failed to find a free MSI\n");
+		return -ENOSPC;
+	}
+
+	dev_dbg(&pdev->dev, "%s bridge %pOF %d/%x #%d\n", __func__,
+		hose->dn, virq, hwirq, nr_irqs);
+
+	for (i = 0; i < nr_irqs; i++) {
+		ret = pnv_irq_parent_domain_alloc(domain, virq + i,
+						  phb->msi_base + hwirq + i);
+		if (ret)
+			goto out;
+
+		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
+					      &pnv_msi_irq_chip, hose);
+	}
+
+	return 0;
+
+out:
+	irq_domain_free_irqs_parent(domain, virq, i - 1);
+	msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq, nr_irqs);
+	return ret;
+}
+
+static void pnv_irq_domain_free(struct irq_domain *domain, unsigned int virq,
+				unsigned int nr_irqs)
+{
+	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+	struct pci_controller *hose = irq_data_get_irq_chip_data(d);
+	struct pnv_phb *phb = hose->private_data;
+
+	pr_debug("%s bridge %pOF %d/%lx #%d\n", __func__, hose->dn,
+		 virq, d->hwirq, nr_irqs);
+
+	msi_bitmap_free_hwirqs(&phb->msi_bmp, d->hwirq, nr_irqs);
+	/* XIVE domain is cleared through ->msi_free() */
+}
+
+static const struct irq_domain_ops pnv_irq_domain_ops = {
+	.alloc  = pnv_irq_domain_alloc,
+	.free   = pnv_irq_domain_free,
+};
+
+static int pnv_msi_allocate_domains(struct pci_controller *hose, unsigned int count)
+{
+	struct pnv_phb *phb = hose->private_data;
+	struct irq_domain *parent = irq_get_default_host();
+
+	hose->fwnode = irq_domain_alloc_named_id_fwnode("PNV-MSI", phb->opal_id);
+	if (!hose->fwnode)
+		return -ENOMEM;
+
+	hose->dev_domain = irq_domain_create_hierarchy(parent, 0, count,
+						       hose->fwnode,
+						       &pnv_irq_domain_ops, hose);
+	if (!hose->dev_domain) {
+		pr_err("PCI: failed to create IRQ domain bridge %pOF (domain %d)\n",
+		       hose->dn, hose->global_number);
+		irq_domain_free_fwnode(hose->fwnode);
+		return -ENOMEM;
+	}
+
+	hose->msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(hose->dn),
+						     &pnv_msi_domain_info,
+						     hose->dev_domain);
+	if (!hose->msi_domain) {
+		pr_err("PCI: failed to create MSI IRQ domain bridge %pOF (domain %d)\n",
+		       hose->dn, hose->global_number);
+		irq_domain_free_fwnode(hose->fwnode);
+		irq_domain_remove(hose->dev_domain);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
 static void pnv_pci_init_ioda_msis(struct pnv_phb *phb)
 {
 	unsigned int count;
@@ -2124,6 +2308,10 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb)
 	phb->msi32_support = 1;
 	pr_info("  Allocated bitmap for %d MSIs (base IRQ 0x%x)\n",
 		count, phb->msi_base);
+
+	/* Only supported by the XIVE driver */
+	if (xive_enabled())
+		pnv_msi_allocate_domains(phb->hose, count);
 }
 
 static void pnv_ioda_setup_pe_res(struct pnv_ioda_pe *pe,
-- 
2.31.1


  parent reply	other threads:[~2021-07-01 13:30 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-01 13:27 [PATCH v2 00/32] powerpc: Add MSI IRQ domains to PCI drivers Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 01/32] powerpc/pseries/pci: Introduce __find_pe_total_msi() Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 02/32] powerpc/pseries/pci: Introduce rtas_prepare_msi_irqs() Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 03/32] powerpc/xive: Add support for IRQ domain hierarchy Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 04/32] powerpc/xive: Ease debugging of xive_irq_set_affinity() Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 05/32] powerpc/pseries/pci: Add MSI domains Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 06/32] powerpc/xive: Drop unmask of MSIs at startup Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 07/32] powerpc/xive: Remove irqd_is_started() check when setting the affinity Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 08/32] powerpc/pseries/pci: Add a domain_free_irqs() handler Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 09/32] powerpc/pseries/pci: Add a msi_free() handler to clear XIVE data Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 10/32] powerpc/pseries/pci: Add support of MSI domains to PHB hotplug Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 11/32] powerpc/powernv/pci: Introduce __pnv_pci_ioda_msi_setup() Cédric Le Goater
2021-07-01 13:27 ` Cédric Le Goater [this message]
2021-07-01 13:27 ` [PATCH v2 13/32] KVM: PPC: Book3S HV: Use the new IRQ chip to detect passthrough interrupts Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 14/32] KVM: PPC: Book3S HV: XIVE: Change interface of passthrough interrupt routines Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 15/32] KVM: PPC: Book3S HV: XIVE: Fix mapping of passthrough interrupts Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 16/32] powerpc/xics: Remove ICS list Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 17/32] powerpc/xics: Rename the map handler in a check handler Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 18/32] powerpc/xics: Give a name to the default XICS IRQ domain Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 19/32] powerpc/xics: Add debug logging to the set_irq_affinity handlers Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 20/32] powerpc/xics: Add support for IRQ domain hierarchy Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 21/32] powerpc/powernv/pci: Customize the MSI EOI handler to support PHB3 Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 22/32] powerpc/pci: Drop XIVE restriction on MSI domains Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 23/32] powerpc/xics: Drop unmask of MSIs at startup Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 24/32] powerpc/pseries/pci: Drop unused MSI code Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 25/32] powerpc/powernv/pci: " Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 26/32] powerpc/powernv/pci: Adapt is_pnv_opal_msi() to detect passthrough interrupt Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 27/32] powerpc/xics: Fix IRQ migration Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 28/32] powerpc/powernv/pci: Set the IRQ chip data for P8/CXL devices Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 29/32] powerpc/powernv/pci: Rework pnv_opal_pci_msi_eoi() Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 30/32] KVM: PPC: Book3S HV: XICS: Fix mapping of passthrough interrupts Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 31/32] powerpc/xive: Use XIVE domain under xmon and debugfs Cédric Le Goater
2021-07-01 13:27 ` [PATCH v2 32/32] genirq: Improve "hwirq" output in /proc and /sys/ Cédric Le Goater
2021-08-18 13:38 ` [PATCH v2 00/32] powerpc: Add MSI IRQ domains to PCI drivers Michael Ellerman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210701132750.1475580-13-clg@kaod.org \
    --to=clg@kaod.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.