From c179c9b978b90bdf9cb39f5b5716dede157f1eaf Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Thu, 9 Jul 2015 16:00:36 +0800 Subject: PCI: Add helper function msi_desc_to_pci_sysdata() Add helper function msi_desc_to_pci_sysdata() to retrieve sysdata from an MSI descriptor. To avoid pulling include/linux/pci.h into include/linux/msi.h, msi_desc_to_pci_sysdata() is implemented as a normal function instead of an inline function. Signed-off-by: Jiang Liu Reviewed-by: Yijing Wang Acked-by: Bjorn Helgaas Cc: Tony Luck Cc: linux-arm-kernel@lists.infradead.org Cc: Grant Likely Cc: Marc Zyngier Cc: Stuart Yoder Cc: Borislav Petkov Cc: Alexander Gordeev Link: http://lkml.kernel.org/r/1436428847-8886-2-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner --- include/linux/msi.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux/msi.h') diff --git a/include/linux/msi.h b/include/linux/msi.h index 8ac4a68ffae2..cfbd2afeaf64 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -60,6 +60,13 @@ static inline struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc) { return desc->dev; } + +void *msi_desc_to_pci_sysdata(struct msi_desc *desc); +#else /* CONFIG_PCI_MSI */ +static inline void *msi_desc_to_pci_sysdata(struct msi_desc *desc) +{ + return NULL; +} #endif /* CONFIG_PCI_MSI */ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg); -- cgit v1.2.3 From 4a7cc831670550e6b48ef5760e7213f89935ff0d Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Thu, 9 Jul 2015 16:00:44 +0800 Subject: genirq/MSI: Move msi_list from struct pci_dev to struct device Move msi_list from struct pci_dev into struct device, so we can support non-PCI-device based generic MSI interrupts. msi_list is now conditional under CONFIG_GENERIC_MSI_IRQ, which is selected from CONFIG_PCI_MSI, so no functional change for PCI MSI users. Signed-off-by: Jiang Liu Reviewed-by: Yijing Wang Acked-by: Bjorn Helgaas Cc: Tony Luck Cc: linux-arm-kernel@lists.infradead.org Cc: Grant Likely Cc: Marc Zyngier Cc: Stuart Yoder Cc: Borislav Petkov Cc: Greg Kroah-Hartman Cc: Joe Perches Cc: Dmitry Torokhov Cc: Paul Gortmaker Cc: Luis R. Rodriguez Cc: Rafael J. Wysocki Cc: Joerg Roedel Cc: Alexander Gordeev Link: http://lkml.kernel.org/r/1436428847-8886-10-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner --- include/linux/msi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/msi.h') diff --git a/include/linux/msi.h b/include/linux/msi.h index cfbd2afeaf64..57fe766a14bf 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -45,7 +45,7 @@ struct msi_desc { /* Helpers to hide struct msi_desc implementation details */ #define msi_desc_to_dev(desc) (&(desc)->dev.dev) -#define dev_to_msi_list(dev) (&to_pci_dev((dev))->msi_list) +#define dev_to_msi_list(dev) (&(dev)->msi_list) #define first_msi_entry(dev) \ list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list) #define for_each_msi_entry(desc, dev) \ -- cgit v1.2.3 From 25a98bd4ff9355a218d2e7aa4d6e3c9bc2c27d6f Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Thu, 9 Jul 2015 16:00:45 +0800 Subject: genirq/MSI: Store 'struct device' instead of 'struct pci_dev' in struct msi_desc Store 'struct device *' instead of 'struct pci_dev *' in struct msi_desc, so struct msi_desc can be reused by non PCI based MSI drivers. Signed-off-by: Jiang Liu Reviewed-by: Yijing Wang Reviewed-by: Marc Zyngier Cc: Tony Luck Cc: linux-arm-kernel@lists.infradead.org Cc: Bjorn Helgaas Cc: Grant Likely Cc: Stuart Yoder Cc: Borislav Petkov Cc: Alexander Gordeev Link: http://lkml.kernel.org/r/1436428847-8886-11-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner --- include/linux/msi.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'include/linux/msi.h') diff --git a/include/linux/msi.h b/include/linux/msi.h index 57fe766a14bf..5f77e231f515 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -14,6 +14,7 @@ extern int pci_msi_ignore_mask; /* Helper functions */ struct irq_data; struct msi_desc; +struct pci_dev; 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); @@ -37,14 +38,14 @@ struct msi_desc { void __iomem *mask_base; u8 mask_pos; }; - struct pci_dev *dev; + struct device *dev; /* Last set MSI message */ struct msi_msg msg; }; /* Helpers to hide struct msi_desc implementation details */ -#define msi_desc_to_dev(desc) (&(desc)->dev.dev) +#define msi_desc_to_dev(desc) ((desc)->dev) #define dev_to_msi_list(dev) (&(dev)->msi_list) #define first_msi_entry(dev) \ list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list) @@ -56,11 +57,7 @@ struct msi_desc { #define for_each_pci_msi_entry(desc, pdev) \ for_each_msi_entry((desc), &(pdev)->dev) -static inline struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc) -{ - return desc->dev; -} - +struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc); void *msi_desc_to_pci_sysdata(struct msi_desc *desc); #else /* CONFIG_PCI_MSI */ static inline void *msi_desc_to_pci_sysdata(struct msi_desc *desc) -- cgit v1.2.3 From fc88419cfac50b05c7c1ea218b08e70c31d1b71f Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Thu, 9 Jul 2015 16:00:46 +0800 Subject: genirq/MSI: Reorginize struct msi_desc to prepare for support of generic MSI Reorganize struct msi_desc so it could be reused by other MSI drivers. We have the following layout now: struct msi_desc { /* Shared device/bus independent data */ ... union { /* PCI specific data */ struct { ... }; }; }; We need to have anonymous union and a anonymous structure for the PCI fields, otherwise we would have to change all instances using these fields. For non PCI devices we will enforce a proper namespace and a non anonymous structure. [ tglx: Added proper comments to the structure and massaged changelog ] Signed-off-by: Jiang Liu Reviewed-by: Yijing Wang Reviewed-by: Marc Zyngier Cc: Tony Luck Cc: linux-arm-kernel@lists.infradead.org Cc: Bjorn Helgaas Cc: Grant Likely Cc: Stuart Yoder Cc: Borislav Petkov Cc: Alexander Gordeev Link: http://lkml.kernel.org/r/1436428847-8886-12-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner --- include/linux/msi.h | 70 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 20 deletions(-) (limited to 'include/linux/msi.h') diff --git a/include/linux/msi.h b/include/linux/msi.h index 5f77e231f515..518e8c4a4064 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -18,30 +18,60 @@ struct pci_dev; 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); +/** + * struct msi_desc - Descriptor structure for MSI based interrupts + * @list: List head for management + * @irq: The base interrupt number + * @nvec_used: The number of vectors used + * @dev: Pointer to the device which uses this descriptor + * @msg: The last set MSI message cached for reuse + * + * @masked: [PCI MSI/X] Mask bits + * @is_msix: [PCI MSI/X] True if MSI-X + * @multiple: [PCI MSI/X] log2 num of messages allocated + * @multi_cap: [PCI MSI/X] log2 num of messages supported + * @maskbit: [PCI MSI/X] Mask-Pending bit supported? + * @is_64: [PCI MSI/X] Address size: 0=32bit 1=64bit + * @entry_nr: [PCI MSI/X] Entry which is described by this descriptor + * @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 + */ struct msi_desc { - struct { - __u8 is_msix : 1; - __u8 multiple: 3; /* log2 num of messages allocated */ - __u8 multi_cap : 3; /* log2 num of messages supported */ - __u8 maskbit : 1; /* mask-pending bit supported ? */ - __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ - __u16 entry_nr; /* specific enabled entry */ - unsigned default_irq; /* default pre-assigned irq */ - } msi_attrib; - - u32 masked; /* mask bits */ - unsigned int irq; - unsigned int nvec_used; /* number of messages */ - struct list_head list; + /* Shared device/bus type independent data */ + struct list_head list; + unsigned int irq; + unsigned int nvec_used; + struct device *dev; + struct msi_msg msg; union { - void __iomem *mask_base; - u8 mask_pos; - }; - struct device *dev; + /* PCI MSI/X specific data */ + struct { + u32 masked; + struct { + __u8 is_msix : 1; + __u8 multiple : 3; + __u8 multi_cap : 3; + __u8 maskbit : 1; + __u8 is_64 : 1; + __u16 entry_nr; + unsigned default_irq; + } msi_attrib; + union { + u8 mask_pos; + void __iomem *mask_base; + }; + }; - /* Last set MSI message */ - struct msi_msg msg; + /* + * Non PCI variants add their data structure here. New + * entries need to use a named structure. We want + * proper name spaces for this. The PCI part is + * anonymous for now as it would require an immediate + * tree wide cleanup. + */ + }; }; /* Helpers to hide struct msi_desc implementation details */ -- cgit v1.2.3 From aa48b6f708868ab9c22ca737f27a0da832bf7f08 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Thu, 9 Jul 2015 16:00:47 +0800 Subject: genirq/MSI: Move alloc_msi_entry() from PCI into generic MSI code Move alloc_msi_entry() from PCI MSI code into generic MSI code, so it can be reused by other generic MSI drivers. Also introduce free_msi_entry() for completeness. Suggested-by: Stuart Yoder . Signed-off-by: Jiang Liu Reviewed-by: Marc Zyngier Reviewed-by: Yijing Wang Acked-by: Bjorn Helgaas Cc: Tony Luck Cc: linux-arm-kernel@lists.infradead.org Cc: Grant Likely Cc: Borislav Petkov Cc: Alexander Gordeev Link: http://lkml.kernel.org/r/1436428847-8886-13-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner --- include/linux/msi.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/msi.h') diff --git a/include/linux/msi.h b/include/linux/msi.h index 518e8c4a4064..f83c87e447bc 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -96,6 +96,8 @@ static inline void *msi_desc_to_pci_sysdata(struct msi_desc *desc) } #endif /* CONFIG_PCI_MSI */ +struct msi_desc *alloc_msi_entry(struct device *dev); +void free_msi_entry(struct msi_desc *entry); void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg); void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg); void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg); -- cgit v1.2.3 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 v1.2.3 From f075915ac0b11847fcfc8c4d55526a317e71c4d1 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 28 Jul 2015 14:46:26 +0100 Subject: PCI/MSI: Drop domain field from msi_controller The only three users of that field are not using the msi_controller structure anymore, so drop it altogether. Acked-by: Bjorn Helgaas Signed-off-by: Marc Zyngier Cc: Cc: Yijing Wang Cc: Ma Jun Cc: Lorenzo Pieralisi Cc: Duc Dang Cc: Hanjun Guo Cc: Jiang Liu Cc: Jason Cooper Link: http://lkml.kernel.org/r/1438091186-10244-20-git-send-email-marc.zyngier@arm.com Signed-off-by: Thomas Gleixner --- include/linux/msi.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux/msi.h') diff --git a/include/linux/msi.h b/include/linux/msi.h index 809b749f9300..ad939d0ba816 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -160,9 +160,6 @@ struct msi_controller { struct device *dev; struct device_node *of_node; struct list_head list; -#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN - struct irq_domain *domain; -#endif int (*setup_irq)(struct msi_controller *chip, struct pci_dev *dev, struct msi_desc *desc); -- cgit v1.2.3