12
12
#include <linux/module.h>
13
13
#include <linux/msi.h>
14
14
#include <linux/irqchip/chained_irq.h>
15
+ #include <linux/irqchip/irq-msi-lib.h>
15
16
#include <linux/pci.h>
16
17
#include <linux/platform_device.h>
17
18
#include <linux/of_pci.h>
@@ -32,7 +33,6 @@ struct xgene_msi_group {
32
33
struct xgene_msi {
33
34
struct device_node * node ;
34
35
struct irq_domain * inner_domain ;
35
- struct irq_domain * msi_domain ;
36
36
u64 msi_addr ;
37
37
void __iomem * msi_regs ;
38
38
unsigned long * bitmap ;
@@ -44,20 +44,6 @@ struct xgene_msi {
44
44
/* Global data */
45
45
static struct xgene_msi xgene_msi_ctrl ;
46
46
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
-
61
47
/*
62
48
* X-Gene v1 has 16 groups of MSI termination registers MSInIRx, where
63
49
* 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,
235
221
irq_domain_free_irqs_parent (domain , virq , nr_irqs );
236
222
}
237
223
238
- static const struct irq_domain_ops msi_domain_ops = {
224
+ static const struct irq_domain_ops xgene_msi_domain_ops = {
239
225
.alloc = xgene_irq_domain_alloc ,
240
226
.free = xgene_irq_domain_free ,
241
227
};
242
228
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
+
243
238
static int xgene_allocate_domains (struct xgene_msi * msi )
244
239
{
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 ;
260
249
}
261
250
262
251
static void xgene_free_domains (struct xgene_msi * msi )
263
252
{
264
- if (msi -> msi_domain )
265
- irq_domain_remove (msi -> msi_domain );
266
253
if (msi -> inner_domain )
267
254
irq_domain_remove (msi -> inner_domain );
268
255
}
0 commit comments