Message ID | 546364FA.7010806@arm.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Bjorn Helgaas |
Headers | show |
On Wed, 12 Nov 2014, Marc Zyngier wrote: > 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. I'd rather have the callback in the irqdomain itself. Along with a callback to free the interrupts. AFAICT is msi_chip more or less a wrapper around the actual MSI irq domain. So we rather move towards assigning irqdomain to the pci bus and get rid of msi_chip instead of adding another level of obscure indirection through msi_chip. Thanks, tglx -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 2014/11/12 22:46, Thomas Gleixner wrote: > On Wed, 12 Nov 2014, Marc Zyngier wrote: >> 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. > > I'd rather have the callback in the irqdomain itself. Along with a > callback to free the interrupts. > > AFAICT is msi_chip more or less a wrapper around the actual MSI irq > domain. So we rather move towards assigning irqdomain to the pci bus > and get rid of msi_chip instead of adding another level of obscure > indirection through msi_chip. Hi Thomas and Marc, I'm trying to replace all weak functions , such as arch_setup_msi_irqs()/arch_setup_msi_irq(), in drivers/pci/msi.c. The framework core changes are almost ready, but it does take time to convert current arch_setup_msi_irqs() implementations to new irqdomain interfaces. Not sure whether it's the right direction to go:( Regards! Gerry > > Thanks, > > tglx > -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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);