77#include <linux/crash_dump.h>
88#include <linux/device.h>
99#include <linux/irq.h>
10+ #include <linux/irqchip/irq-msi-lib.h>
1011#include <linux/irqdomain.h>
1112#include <linux/msi.h>
1213#include <linux/seq_file.h>
1516#include <asm/hw_irq.h>
1617#include <asm/ppc-pci.h>
1718#include <asm/machdep.h>
18- #include <asm/xive.h>
1919
2020#include "pseries.h"
2121
@@ -430,25 +430,13 @@ static int rtas_prepare_msi_irqs(struct pci_dev *pdev, int nvec_in, int type,
430430static int pseries_msi_ops_prepare (struct irq_domain * domain , struct device * dev ,
431431 int nvec , msi_alloc_info_t * arg )
432432{
433+ struct msi_domain_info * info = domain -> host_data ;
433434 struct pci_dev * pdev = to_pci_dev (dev );
434- int type = pdev -> msix_enabled ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI ;
435+ int type = ( info -> flags & MSI_FLAG_PCI_MSIX ) ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI ;
435436
436437 return rtas_prepare_msi_irqs (pdev , nvec , type , arg );
437438}
438439
439- /*
440- * ->msi_free() is called before irq_domain_free_irqs_top() when the
441- * handler data is still available. Use that to clear the XIVE
442- * controller data.
443- */
444- static void pseries_msi_ops_msi_free (struct irq_domain * domain ,
445- struct msi_domain_info * info ,
446- unsigned int irq )
447- {
448- if (xive_enabled ())
449- xive_irq_free_data (irq );
450- }
451-
452440/*
453441 * RTAS can not disable one MSI at a time. It's all or nothing. Do it
454442 * at the end after all IRQs have been freed.
@@ -461,31 +449,13 @@ static void pseries_msi_post_free(struct irq_domain *domain, struct device *dev)
461449 rtas_disable_msi (to_pci_dev (dev ));
462450}
463451
464- static struct msi_domain_ops pseries_pci_msi_domain_ops = {
465- .msi_prepare = pseries_msi_ops_prepare ,
466- .msi_free = pseries_msi_ops_msi_free ,
467- .msi_post_free = pseries_msi_post_free ,
468- };
469-
470452static void pseries_msi_shutdown (struct irq_data * d )
471453{
472454 d = d -> parent_data ;
473455 if (d -> chip -> irq_shutdown )
474456 d -> chip -> irq_shutdown (d );
475457}
476458
477- static void pseries_msi_mask (struct irq_data * d )
478- {
479- pci_msi_mask_irq (d );
480- irq_chip_mask_parent (d );
481- }
482-
483- static void pseries_msi_unmask (struct irq_data * d )
484- {
485- pci_msi_unmask_irq (d );
486- irq_chip_unmask_parent (d );
487- }
488-
489459static void pseries_msi_write_msg (struct irq_data * data , struct msi_msg * msg )
490460{
491461 struct msi_desc * entry = irq_data_get_msi_desc (data );
@@ -500,27 +470,39 @@ static void pseries_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
500470 entry -> msg = * msg ;
501471}
502472
503- static struct irq_chip pseries_pci_msi_irq_chip = {
504- .name = "pSeries-PCI-MSI" ,
505- .irq_shutdown = pseries_msi_shutdown ,
506- .irq_mask = pseries_msi_mask ,
507- .irq_unmask = pseries_msi_unmask ,
508- .irq_eoi = irq_chip_eoi_parent ,
509- .irq_write_msi_msg = pseries_msi_write_msg ,
510- };
473+ static bool pseries_init_dev_msi_info (struct device * dev , struct irq_domain * domain ,
474+ struct irq_domain * real_parent , struct msi_domain_info * info )
475+ {
476+ struct irq_chip * chip = info -> chip ;
511477
478+ if (!msi_lib_init_dev_msi_info (dev , domain , real_parent , info ))
479+ return false;
512480
513- /*
514- * Set MSI_FLAG_MSIX_CONTIGUOUS as there is no way to express to
515- * firmware to request a discontiguous or non-zero based range of
516- * MSI-X entries. Core code will reject such setup attempts.
517- */
518- static struct msi_domain_info pseries_msi_domain_info = {
519- .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
520- MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX |
521- MSI_FLAG_MSIX_CONTIGUOUS ),
522- .ops = & pseries_pci_msi_domain_ops ,
523- .chip = & pseries_pci_msi_irq_chip ,
481+ chip -> irq_shutdown = pseries_msi_shutdown ;
482+ chip -> irq_write_msi_msg = pseries_msi_write_msg ;
483+
484+ info -> ops -> msi_prepare = pseries_msi_ops_prepare ;
485+ info -> ops -> msi_post_free = pseries_msi_post_free ;
486+
487+ return true;
488+ }
489+
490+ #define PSERIES_PCI_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
491+ MSI_FLAG_USE_DEF_CHIP_OPS | \
492+ MSI_FLAG_PCI_MSI_MASK_PARENT)
493+ #define PSERIES_PCI_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \
494+ MSI_FLAG_PCI_MSIX | \
495+ MSI_FLAG_MSIX_CONTIGUOUS | \
496+ MSI_FLAG_MULTI_PCI_MSI)
497+
498+ static const struct msi_parent_ops pseries_msi_parent_ops = {
499+ .required_flags = PSERIES_PCI_MSI_FLAGS_REQUIRED ,
500+ .supported_flags = PSERIES_PCI_MSI_FLAGS_SUPPORTED ,
501+ .chip_flags = MSI_CHIP_FLAG_SET_EOI ,
502+ .bus_select_token = DOMAIN_BUS_NEXUS ,
503+ .bus_select_mask = MATCH_PCI_MSI ,
504+ .prefix = "pSeries-" ,
505+ .init_dev_msi_info = pseries_init_dev_msi_info ,
524506};
525507
526508static void pseries_msi_compose_msg (struct irq_data * data , struct msi_msg * msg )
@@ -604,11 +586,11 @@ static void pseries_irq_domain_free(struct irq_domain *domain, unsigned int virq
604586 struct pci_controller * phb = irq_data_get_irq_chip_data (d );
605587
606588 pr_debug ("%s bridge %pOF %d #%d\n" , __func__ , phb -> dn , virq , nr_irqs );
607-
608- /* XIVE domain data is cleared through ->msi_free() */
589+ irq_domain_free_irqs_parent (domain , virq , nr_irqs );
609590}
610591
611592static const struct irq_domain_ops pseries_irq_domain_ops = {
593+ .select = msi_lib_irq_domain_select ,
612594 .alloc = pseries_irq_domain_alloc ,
613595 .free = pseries_irq_domain_free ,
614596};
@@ -617,30 +599,18 @@ static int __pseries_msi_allocate_domains(struct pci_controller *phb,
617599 unsigned int count )
618600{
619601 struct irq_domain * parent = irq_get_default_domain ();
620-
621- phb -> fwnode = irq_domain_alloc_named_id_fwnode ( "pSeries-MSI" ,
622- phb -> global_number );
623- if (! phb -> fwnode )
624- return - ENOMEM ;
625-
626- phb -> dev_domain = irq_domain_create_hierarchy ( parent , 0 , count ,
627- phb -> fwnode ,
628- & pseries_irq_domain_ops , phb );
602+ struct irq_domain_info info = {
603+ . fwnode = of_fwnode_handle ( phb -> dn ) ,
604+ . ops = & pseries_irq_domain_ops ,
605+ . host_data = phb ,
606+ . size = count ,
607+ . parent = parent ,
608+ };
609+
610+ phb -> dev_domain = msi_create_parent_irq_domain ( & info , & pseries_msi_parent_ops );
629611 if (!phb -> dev_domain ) {
630- pr_err ("PCI: failed to create IRQ domain bridge %pOF (domain %d)\n" ,
631- phb -> dn , phb -> global_number );
632- irq_domain_free_fwnode (phb -> fwnode );
633- return - ENOMEM ;
634- }
635-
636- phb -> msi_domain = pci_msi_create_irq_domain (of_fwnode_handle (phb -> dn ),
637- & pseries_msi_domain_info ,
638- phb -> dev_domain );
639- if (!phb -> msi_domain ) {
640612 pr_err ("PCI: failed to create MSI IRQ domain bridge %pOF (domain %d)\n" ,
641613 phb -> dn , phb -> global_number );
642- irq_domain_free_fwnode (phb -> fwnode );
643- irq_domain_remove (phb -> dev_domain );
644614 return - ENOMEM ;
645615 }
646616
@@ -662,12 +632,8 @@ int pseries_msi_allocate_domains(struct pci_controller *phb)
662632
663633void pseries_msi_free_domains (struct pci_controller * phb )
664634{
665- if (phb -> msi_domain )
666- irq_domain_remove (phb -> msi_domain );
667635 if (phb -> dev_domain )
668636 irq_domain_remove (phb -> dev_domain );
669- if (phb -> fwnode )
670- irq_domain_free_fwnode (phb -> fwnode );
671637}
672638
673639static void rtas_msi_pci_irq_fixup (struct pci_dev * pdev )
0 commit comments