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;
}
Beispiel #2
0
static int xgene_gpio_sb_to_irq(struct gpio_chip *gc, u32 gpio)
{
	struct xgene_gpio_sb *priv = gpiochip_get_data(gc);
	struct irq_fwspec fwspec;

	if ((gpio < priv->irq_start) ||
			(gpio > HWIRQ_TO_GPIO(priv, priv->nirq)))
		return -ENXIO;

	if (gc->parent->of_node)
		fwspec.fwnode = of_node_to_fwnode(gc->parent->of_node);
	else
		fwspec.fwnode = gc->parent->fwnode;
	fwspec.param_count = 2;
	fwspec.param[0] = GPIO_TO_HWIRQ(priv, gpio);
	fwspec.param[1] = IRQ_TYPE_NONE;
	return irq_create_fwspec_mapping(&fwspec);
}
static int __init its_pci_of_msi_init(void)
{
	struct device_node *np;

	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;

		if (its_pci_msi_init_one(of_node_to_fwnode(np), np->full_name))
			continue;

		pr_info("PCI/MSI: %pOF domain created\n", np);
	}

	return 0;
}
Beispiel #4
0
static int mvebu_gicp_probe(struct platform_device *pdev)
{
	struct mvebu_gicp *gicp;
	struct irq_domain *inner_domain, *plat_domain, *parent_domain;
	struct device_node *node = pdev->dev.of_node;
	struct device_node *irq_parent_dn;
	int ret, i;

	gicp = devm_kzalloc(&pdev->dev, sizeof(*gicp), GFP_KERNEL);
	if (!gicp)
		return -ENOMEM;

	gicp->dev = &pdev->dev;
	spin_lock_init(&gicp->spi_lock);

	gicp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!gicp->res)
		return -ENODEV;

	ret = of_property_count_u32_elems(node, "marvell,spi-ranges");
	if (ret < 0)
		return ret;

	gicp->spi_ranges_cnt = ret / 2;

	gicp->spi_ranges =
		devm_kzalloc(&pdev->dev,
			     gicp->spi_ranges_cnt *
			     sizeof(struct mvebu_gicp_spi_range),
			     GFP_KERNEL);
	if (!gicp->spi_ranges)
		return -ENOMEM;

	for (i = 0; i < gicp->spi_ranges_cnt; i++) {
		of_property_read_u32_index(node, "marvell,spi-ranges",
					   i * 2,
					   &gicp->spi_ranges[i].start);

		of_property_read_u32_index(node, "marvell,spi-ranges",
					   i * 2 + 1,
					   &gicp->spi_ranges[i].count);

		gicp->spi_cnt += gicp->spi_ranges[i].count;
	}

	gicp->spi_bitmap = devm_kzalloc(&pdev->dev,
				BITS_TO_LONGS(gicp->spi_cnt) * sizeof(long),
				GFP_KERNEL);
	if (!gicp->spi_bitmap)
		return -ENOMEM;

	irq_parent_dn = of_irq_find_parent(node);
	if (!irq_parent_dn) {
		dev_err(&pdev->dev, "failed to find parent IRQ node\n");
		return -ENODEV;
	}

	parent_domain = irq_find_host(irq_parent_dn);
	if (!parent_domain) {
		dev_err(&pdev->dev, "failed to find parent IRQ domain\n");
		return -ENODEV;
	}

	inner_domain = irq_domain_create_hierarchy(parent_domain, 0,
						   gicp->spi_cnt,
						   of_node_to_fwnode(node),
						   &gicp_domain_ops, gicp);
	if (!inner_domain)
		return -ENOMEM;


	plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(node),
						     &gicp_msi_domain_info,
						     inner_domain);
	if (!plat_domain) {
		irq_domain_remove(inner_domain);
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, gicp);

	return 0;
}
Beispiel #5
0
static int xgene_gpio_sb_probe(struct platform_device *pdev)
{
	struct xgene_gpio_sb *priv;
	int ret;
	struct resource *res;
	void __iomem *regs;
	struct irq_domain *parent_domain = NULL;
	struct fwnode_handle *fwnode;
	u32 val32;

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(regs))
		return PTR_ERR(regs);

	priv->regs = regs;

	ret = platform_get_irq(pdev, 0);
	if (ret > 0) {
		priv->parent_irq_base = irq_get_irq_data(ret)->hwirq;
		parent_domain = irq_get_irq_data(ret)->domain;
	}
	if (!parent_domain) {
		dev_err(&pdev->dev, "unable to obtain parent domain\n");
		return -ENODEV;
	}

	ret = bgpio_init(&priv->gc, &pdev->dev, 4,
			regs + MPA_GPIO_IN_ADDR,
			regs + MPA_GPIO_OUT_ADDR, NULL,
			regs + MPA_GPIO_OE_ADDR, NULL, 0);
        if (ret)
                return ret;

	priv->gc.to_irq = xgene_gpio_sb_to_irq;

	/* Retrieve start irq pin, use default if property not found */
	priv->irq_start = XGENE_DFLT_IRQ_START_PIN;
	if (!device_property_read_u32(&pdev->dev,
					XGENE_IRQ_START_PROPERTY, &val32))
		priv->irq_start = val32;

	/* Retrieve number irqs, use default if property not found */
	priv->nirq = XGENE_DFLT_MAX_NIRQ;
	if (!device_property_read_u32(&pdev->dev, XGENE_NIRQ_PROPERTY, &val32))
		priv->nirq = val32;

	/* Retrieve number gpio, use default if property not found */
	priv->gc.ngpio = XGENE_DFLT_MAX_NGPIO;
	if (!device_property_read_u32(&pdev->dev, XGENE_NGPIO_PROPERTY, &val32))
		priv->gc.ngpio = val32;

	dev_info(&pdev->dev, "Support %d gpios, %d irqs start from pin %d\n",
			priv->gc.ngpio, priv->nirq, priv->irq_start);

	platform_set_drvdata(pdev, priv);

	if (pdev->dev.of_node)
		fwnode = of_node_to_fwnode(pdev->dev.of_node);
	else
		fwnode = pdev->dev.fwnode;

	priv->irq_domain = irq_domain_create_hierarchy(parent_domain,
					0, priv->nirq, fwnode,
					&xgene_gpio_sb_domain_ops, priv);
	if (!priv->irq_domain)
		return -ENODEV;

	priv->gc.irqdomain = priv->irq_domain;

	ret = devm_gpiochip_add_data(&pdev->dev, &priv->gc, priv);
	if (ret) {
		dev_err(&pdev->dev,
			"failed to register X-Gene GPIO Standby driver\n");
		irq_domain_remove(priv->irq_domain);
		return ret;
	}

	dev_info(&pdev->dev, "X-Gene GPIO Standby driver registered\n");

	if (priv->nirq > 0) {
		/* Register interrupt handlers for gpio signaled acpi events */
		acpi_gpiochip_request_interrupts(&priv->gc);
	}

	return ret;
}