[PATCH v2 02/14] PCI/MSI: Allow an msi_chip to be associated to an irq domain

From: Marc Zyngier
Date: Wed Nov 12 2014 - 05:32:46 EST


The new MSI stacked domain has the interesting effect that it is
quite hard to use if the architecture doesn't provide its own
arch_setup_msi_irqs() function to override the default.

This inhibates the msi_chip infrastructure introduced in
0cbdcfcf427b (PCI: Introduce new MSI chip infrastructure), as it is
not possible to use it as an indirection between the core MSI code
and the MSI driver (useful when having multiple MSI controllers that
do not share the same requirements). The setup_irq and teardown_irq
are rendered useless, as their role is now taken over by the alloc/free
functions in the irq domain code.

This patch introduces two optionnal fields to the msi_chip structure:
- a pointer to an irq domain, describing the MSI domain associated
with this msi_chip. To be populated with msi_create_irq_domain.
- a domain_alloc_irqs() callback that has the same purpose as
arch_setup_msi_irqs(), with the above domain as an additional
parameter.

If both of these fields are non-NULL, then domain_alloc_irqs() is
called, bypassing the setup_irq callback. This allows the MSI driver
to use the domain stacking feature without mandating core support in
the architecture.

Tested on arm64 with the GICv3 ITS.

Signed-off-by: Marc Zyngier <marc.zyngier@xxxxxxx>
---
drivers/pci/msi.c | 9 ++++++++-
include/linux/msi.h | 5 +++++
2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 6c38306..baefc21 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -63,8 +63,15 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)

/*
* If an architecture wants to support multiple MSI, it needs to
- * override arch_setup_msi_irqs()
+ * override arch_setup_msi_irqs(), or provide a way out on a per
+ * domain basis.
*/
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+ struct msi_chip *chip = dev->bus->msi;
+
+ if (chip->domain && chip->domain_alloc_irqs)
+ return chip->domain_alloc_irqs(chip->domain, dev, nvec, type);
+#endif
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;

diff --git a/include/linux/msi.h b/include/linux/msi.h
index 0789a4d..7170eea 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -110,7 +110,12 @@ struct msi_chip {
struct device *dev;
struct device_node *of_node;
struct list_head list;
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+ struct irq_domain *domain;

+ int (*domain_alloc_irqs)(struct irq_domain *domain,
+ struct pci_dev *pdev, int nvec, int type);
+#endif
int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
struct msi_desc *desc);
void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
--
2.0.4

Thoughts? I'll post the full patch series later today.

Thanks,

M.
--
Jazz is not dead. It just smells funny...

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/