From c09fcc4b2b48d58d769a8cff5041533535ece449 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 28 Jul 2015 14:46:16 +0100 Subject: drivers/base: Add MSI domain support for non-PCI devices With the msi_list and the msi_domain properties now being at the generic device level, it is starting to be relatively easy to offer a generic way of providing non-PCI MSIs. The two major hurdles with this idea are: - Lack of global ID that identifies a device: this is worked around by having a global ID allocator for each device that gets enrolled in the platform MSI subsystem - Lack of standard way to write the message in the generating device. This is solved by mandating driver code to provide a write_msg callback, so that everyone can have their own square wheel Apart from that, the API is fairly straightforward: - platform_msi_create_irq_domain creates an MSI domain that gets tagged with DOMAIN_BUS_PLATFORM_MSI - platform_msi_domain_alloc_irqs allocate MSIs for a given device, populating the msi_list - platform_msi_domain_free_irqs does what is written on the tin [ tglx: Created a seperate struct platform_msi_desc and added kerneldoc entries ] Signed-off-by: Marc Zyngier Cc: Cc: Yijing Wang Cc: Ma Jun Cc: Lorenzo Pieralisi Cc: Duc Dang Cc: Hanjun Guo Cc: Bjorn Helgaas Cc: Jiang Liu Cc: Jason Cooper Link: http://lkml.kernel.org/r/1438091186-10244-10-git-send-email-marc.zyngier@arm.com Signed-off-by: Thomas Gleixner --- include/linux/msi.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'include/linux/msi.h') diff --git a/include/linux/msi.h b/include/linux/msi.h index f83c87e447bc..809b749f9300 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -15,9 +15,23 @@ extern int pci_msi_ignore_mask; struct irq_data; struct msi_desc; struct pci_dev; +struct platform_msi_priv_data; void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg); void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); +typedef void (*irq_write_msi_msg_t)(struct msi_desc *desc, + struct msi_msg *msg); + +/** + * platform_msi_desc - Platform device specific msi descriptor data + * @msi_priv_data: Pointer to platform private data + * @msi_index: The index of the MSI descriptor for multi MSI + */ +struct platform_msi_desc { + struct platform_msi_priv_data *msi_priv_data; + u16 msi_index; +}; + /** * struct msi_desc - Descriptor structure for MSI based interrupts * @list: List head for management @@ -36,6 +50,7 @@ void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); * @default_irq:[PCI MSI/X] The default pre-assigned non-MSI irq * @mask_pos: [PCI MSI] Mask register position * @mask_base: [PCI MSI-X] Mask register base address + * @platform: [platform] Platform device specific msi descriptor data */ struct msi_desc { /* Shared device/bus type independent data */ @@ -71,6 +86,7 @@ struct msi_desc { * anonymous for now as it would require an immediate * tree wide cleanup. */ + struct platform_msi_desc platform; }; }; @@ -257,6 +273,12 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev); struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain); +struct irq_domain *platform_msi_create_irq_domain(struct device_node *np, + struct msi_domain_info *info, + struct irq_domain *parent); +int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec, + irq_write_msi_msg_t write_msi_msg); +void platform_msi_domain_free_irqs(struct device *dev); #endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */ #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN -- cgit