1212#include <linux/module.h>
1313#include <linux/msi.h>
1414#include <linux/irqchip/chained_irq.h>
15+ #include <linux/irqchip/irq-msi-lib.h>
1516#include <linux/pci.h>
1617#include <linux/platform_device.h>
1718#include <linux/of_pci.h>
@@ -32,7 +33,6 @@ struct xgene_msi_group {
3233struct xgene_msi {
3334 struct device_node * node ;
3435 struct irq_domain * inner_domain ;
35- struct irq_domain * msi_domain ;
3636 u64 msi_addr ;
3737 void __iomem * msi_regs ;
3838 unsigned long * bitmap ;
@@ -44,20 +44,6 @@ struct xgene_msi {
4444/* Global data */
4545static struct xgene_msi xgene_msi_ctrl ;
4646
47- static struct irq_chip xgene_msi_top_irq_chip = {
48- .name = "X-Gene1 MSI" ,
49- .irq_enable = pci_msi_unmask_irq ,
50- .irq_disable = pci_msi_mask_irq ,
51- .irq_mask = pci_msi_mask_irq ,
52- .irq_unmask = pci_msi_unmask_irq ,
53- };
54-
55- static struct msi_domain_info xgene_msi_domain_info = {
56- .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
57- MSI_FLAG_PCI_MSIX ),
58- .chip = & xgene_msi_top_irq_chip ,
59- };
60-
6147/*
6248 * X-Gene v1 has 16 groups of MSI termination registers MSInIRx, where
6349 * n is group number (0..F), x is index of registers in each group (0..7)
@@ -235,34 +221,35 @@ static void xgene_irq_domain_free(struct irq_domain *domain,
235221 irq_domain_free_irqs_parent (domain , virq , nr_irqs );
236222}
237223
238- static const struct irq_domain_ops msi_domain_ops = {
224+ static const struct irq_domain_ops xgene_msi_domain_ops = {
239225 .alloc = xgene_irq_domain_alloc ,
240226 .free = xgene_irq_domain_free ,
241227};
242228
229+ static const struct msi_parent_ops xgene_msi_parent_ops = {
230+ .supported_flags = (MSI_GENERIC_FLAGS_MASK |
231+ MSI_FLAG_PCI_MSIX ),
232+ .required_flags = (MSI_FLAG_USE_DEF_DOM_OPS |
233+ MSI_FLAG_USE_DEF_CHIP_OPS ),
234+ .bus_select_token = DOMAIN_BUS_PCI_MSI ,
235+ .init_dev_msi_info = msi_lib_init_dev_msi_info ,
236+ };
237+
243238static int xgene_allocate_domains (struct xgene_msi * msi )
244239{
245- msi -> inner_domain = irq_domain_add_linear (NULL , NR_MSI_VEC ,
246- & msi_domain_ops , msi );
247- if (!msi -> inner_domain )
248- return - ENOMEM ;
249-
250- msi -> msi_domain = pci_msi_create_irq_domain (of_fwnode_handle (msi -> node ),
251- & xgene_msi_domain_info ,
252- msi -> inner_domain );
253-
254- if (!msi -> msi_domain ) {
255- irq_domain_remove (msi -> inner_domain );
256- return - ENOMEM ;
257- }
258-
259- return 0 ;
240+ struct irq_domain_info info = {
241+ .fwnode = of_fwnode_handle (msi -> node ),
242+ .ops = & xgene_msi_domain_ops ,
243+ .size = NR_MSI_VEC ,
244+ .host_data = msi ,
245+ };
246+
247+ msi -> inner_domain = msi_create_parent_irq_domain (& info , & xgene_msi_parent_ops );
248+ return msi -> inner_domain ? 0 : - ENOMEM ;
260249}
261250
262251static void xgene_free_domains (struct xgene_msi * msi )
263252{
264- if (msi -> msi_domain )
265- irq_domain_remove (msi -> msi_domain );
266253 if (msi -> inner_domain )
267254 irq_domain_remove (msi -> inner_domain );
268255}
0 commit comments