static int __init its_pci_msi_init(void) { struct device_node *np; struct irq_domain *parent; for (np = of_find_matching_node(NULL, its_device_id); np; np = of_find_matching_node(np, its_device_id)) { if (!of_property_read_bool(np, "msi-controller")) continue; parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS); if (!parent || !msi_get_domain_info(parent)) { pr_err("%s: unable to locate ITS domain\n", np->full_name); continue; } if (!pci_msi_create_irq_domain(np, &its_pci_msi_domain_info, parent)) { pr_err("%s: unable to create PCI domain\n", np->full_name); continue; } pr_info("PCI/MSI: %s domain created\n", np->full_name); } return 0; }
static int __init its_fsl_mc_msi_init(void) { struct device_node *np; struct irq_domain *parent; struct irq_domain *mc_msi_domain; for (np = of_find_matching_node(NULL, its_device_id); np; np = of_find_matching_node(np, its_device_id)) { if (!of_device_is_available(np)) continue; if (!of_property_read_bool(np, "msi-controller")) continue; parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS); if (!parent || !msi_get_domain_info(parent)) { pr_err("%pOF: unable to locate ITS domain\n", np); continue; } mc_msi_domain = fsl_mc_msi_create_irq_domain( of_node_to_fwnode(np), &its_fsl_mc_msi_domain_info, parent); if (!mc_msi_domain) { pr_err("%pOF: unable to create fsl-mc domain\n", np); continue; } pr_info("fsl-mc MSI: %pOF domain created\n", np); } return 0; }
static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain, struct device *dev, int nvec, msi_alloc_info_t *info) { struct fsl_mc_device *mc_bus_dev; struct msi_domain_info *msi_info; if (!dev_is_fsl_mc(dev)) return -EINVAL; mc_bus_dev = to_fsl_mc_device(dev); if (!(mc_bus_dev->flags & FSL_MC_IS_DPRC)) return -EINVAL; /* * Set the device Id to be passed to the GIC-ITS: * * NOTE: This device id corresponds to the IOMMU stream ID * associated with the DPRC object (ICID). */ #ifdef GENERIC_MSI_DOMAIN_OPS info->scratchpad[0].ul = mc_bus_dev->icid; #endif msi_info = msi_get_domain_info(msi_domain->parent); return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info); }
static int its_pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec, msi_alloc_info_t *info) { struct pci_dev *pdev, *alias_dev; struct msi_domain_info *msi_info; int alias_count = 0; if (!dev_is_pci(dev)) return -EINVAL; msi_info = msi_get_domain_info(domain->parent); pdev = to_pci_dev(dev); /* * If pdev is downstream of any aliasing bridges, take an upper * bound of how many other vectors could map to the same DevID. */ pci_for_each_dma_alias(pdev, its_get_pci_alias, &alias_dev); if (alias_dev != pdev && alias_dev->subordinate) pci_walk_bus(alias_dev->subordinate, its_pci_msi_vec_count, &alias_count); /* ITS specific DeviceID, as the core ITS ignores dev. */ info->scratchpad[0].ul = pci_msi_domain_get_msi_rid(domain, pdev); return msi_info->ops->msi_prepare(domain->parent, dev, max(nvec, alias_count), info); }
static int __init its_pci_msi_init_one(struct fwnode_handle *handle, const char *name) { struct irq_domain *parent; parent = irq_find_matching_fwnode(handle, DOMAIN_BUS_NEXUS); if (!parent || !msi_get_domain_info(parent)) { pr_err("%s: Unable to locate ITS domain\n", name); return -ENXIO; } if (!pci_msi_create_irq_domain(handle, &its_pci_msi_domain_info, parent)) { pr_err("%s: Unable to create PCI domain\n", name); return -ENOMEM; } return 0; }
static int its_pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec, msi_alloc_info_t *info) { struct pci_dev *pdev; struct its_pci_alias dev_alias; struct msi_domain_info *msi_info; if (!dev_is_pci(dev)) return -EINVAL; msi_info = msi_get_domain_info(domain->parent); pdev = to_pci_dev(dev); dev_alias.pdev = pdev; dev_alias.count = nvec; pci_for_each_dma_alias(pdev, its_get_pci_alias, &dev_alias); /* ITS specific DeviceID, as the core ITS ignores dev. */ info->scratchpad[0].ul = dev_alias.dev_id; return msi_info->ops->msi_prepare(domain->parent, dev, dev_alias.count, info); }
static inline int hpet_dev_id(struct irq_domain *domain) { struct msi_domain_info *info = msi_get_domain_info(domain); return (int)(long)info->data; }