2020#include <linux/interrupt.h>
2121#include <linux/irqchip.h>
2222#include <linux/irqchip/chained_irq.h>
23+ #include <linux/irqchip/irq-msi-lib.h>
2324#include <linux/cpu.h>
2425#include <linux/io.h>
2526#include <linux/of_address.h>
156157 * @parent_irq: parent IRQ if MPIC is not top-level interrupt controller
157158 * @domain: MPIC main interrupt domain
158159 * @ipi_domain: IPI domain
159- * @msi_domain: MSI domain
160160 * @msi_inner_domain: MSI inner domain
161161 * @msi_used: bitmap of used MSI numbers
162162 * @msi_lock: mutex serializing access to @msi_used
@@ -176,7 +176,6 @@ struct mpic {
176176 struct irq_domain * ipi_domain ;
177177#endif
178178#ifdef CONFIG_PCI_MSI
179- struct irq_domain * msi_domain ;
180179 struct irq_domain * msi_inner_domain ;
181180 DECLARE_BITMAP (msi_used , PCI_MSI_FULL_DOORBELL_NR );
182181 struct mutex msi_lock ;
@@ -234,18 +233,6 @@ static void mpic_irq_unmask(struct irq_data *d)
234233
235234#ifdef CONFIG_PCI_MSI
236235
237- static struct irq_chip mpic_msi_irq_chip = {
238- .name = "MPIC MSI" ,
239- .irq_mask = pci_msi_mask_irq ,
240- .irq_unmask = pci_msi_unmask_irq ,
241- };
242-
243- static struct msi_domain_info mpic_msi_domain_info = {
244- .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
245- MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX ),
246- .chip = & mpic_msi_irq_chip ,
247- };
248-
249236static void mpic_compose_msi_msg (struct irq_data * d , struct msi_msg * msg )
250237{
251238 unsigned int cpu = cpumask_first (irq_data_get_effective_affinity_mask (d ));
@@ -314,6 +301,7 @@ static void mpic_msi_free(struct irq_domain *domain, unsigned int virq, unsigned
314301}
315302
316303static const struct irq_domain_ops mpic_msi_domain_ops = {
304+ .select = msi_lib_irq_domain_select ,
317305 .alloc = mpic_msi_alloc ,
318306 .free = mpic_msi_free ,
319307};
@@ -331,6 +319,21 @@ static void mpic_msi_reenable_percpu(struct mpic *mpic)
331319 writel (1 , mpic -> per_cpu + MPIC_INT_CLEAR_MASK );
332320}
333321
322+ #define MPIC_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
323+ MSI_FLAG_USE_DEF_CHIP_OPS)
324+ #define MPIC_MSI_FLAGS_SUPPORTED (MSI_FLAG_MULTI_PCI_MSI | \
325+ MSI_FLAG_PCI_MSIX | \
326+ MSI_GENERIC_FLAGS_MASK)
327+
328+ static const struct msi_parent_ops mpic_msi_parent_ops = {
329+ .required_flags = MPIC_MSI_FLAGS_REQUIRED ,
330+ .supported_flags = MPIC_MSI_FLAGS_SUPPORTED ,
331+ .bus_select_token = DOMAIN_BUS_NEXUS ,
332+ .bus_select_mask = MATCH_PCI_MSI ,
333+ .prefix = "MPIC-" ,
334+ .init_dev_msi_info = msi_lib_init_dev_msi_info ,
335+ };
336+
334337static int __init mpic_msi_init (struct mpic * mpic , struct device_node * node ,
335338 phys_addr_t main_int_phys_base )
336339{
@@ -348,17 +351,16 @@ static int __init mpic_msi_init(struct mpic *mpic, struct device_node *node,
348351 mpic -> msi_doorbell_mask = PCI_MSI_FULL_DOORBELL_MASK ;
349352 }
350353
351- mpic -> msi_inner_domain = irq_domain_create_linear (NULL , mpic -> msi_doorbell_size ,
352- & mpic_msi_domain_ops , mpic );
353- if (!mpic -> msi_inner_domain )
354- return - ENOMEM ;
354+ struct irq_domain_info info = {
355+ .fwnode = of_fwnode_handle (node ),
356+ .ops = & mpic_msi_domain_ops ,
357+ .host_data = mpic ,
358+ .size = mpic -> msi_doorbell_size ,
359+ };
355360
356- mpic -> msi_domain = pci_msi_create_irq_domain (of_fwnode_handle (node ), & mpic_msi_domain_info ,
357- mpic -> msi_inner_domain );
358- if (!mpic -> msi_domain ) {
359- irq_domain_remove (mpic -> msi_inner_domain );
361+ mpic -> msi_inner_domain = msi_create_parent_irq_domain (& info , & mpic_msi_parent_ops );
362+ if (!mpic -> msi_inner_domain )
360363 return - ENOMEM ;
361- }
362364
363365 mpic_msi_reenable_percpu (mpic );
364366
0 commit comments