Esempio n. 1
0
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;
}
Esempio n. 6
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);
}
Esempio n. 7
0
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;
}