Commit 0444638c authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Marc Zyngier
Browse files

irqchip/exiu: Preparatory refactor for ACPI support



In preparation of adding support for EXIU controller devices described
via ACPI, split the DT init function in a DT specific and a generic part,
where the latter will be reused for ACPI support later.

Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent 621dc2fd
Loading
Loading
Loading
Loading
+43 −23
Original line number Diff line number Diff line
/*
 * Driver for Socionext External Interrupt Unit (EXIU)
 *
 * Copyright (c) 2017 Linaro, Ltd. <ard.biesheuvel@linaro.org>
 * Copyright (c) 2017-2019 Linaro, Ltd. <ard.biesheuvel@linaro.org>
 *
 * Based on irq-tegra.c:
 *   Copyright (C) 2011 Google, Inc.
@@ -167,35 +167,23 @@ static const struct irq_domain_ops exiu_domain_ops = {
	.free		= irq_domain_free_irqs_common,
};

static int __init exiu_init(struct device_node *node,
			    struct device_node *parent)
static struct exiu_irq_data *exiu_init(const struct fwnode_handle *fwnode,
				       struct resource *res)
{
	struct irq_domain *parent_domain, *domain;
	struct exiu_irq_data *data;
	int err;

	if (!parent) {
		pr_err("%pOF: no parent, giving up\n", node);
		return -ENODEV;
	}

	parent_domain = irq_find_host(parent);
	if (!parent_domain) {
		pr_err("%pOF: unable to obtain parent domain\n", node);
		return -ENXIO;
	}

	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;
		return ERR_PTR(-ENOMEM);

	if (of_property_read_u32(node, "socionext,spi-base", &data->spi_base)) {
		pr_err("%pOF: failed to parse 'spi-base' property\n", node);
	if (fwnode_property_read_u32_array(fwnode, "socionext,spi-base",
					   &data->spi_base, 1)) {
		err = -ENODEV;
		goto out_free;
	}

	data->base = of_iomap(node, 0);
	data->base = ioremap(res->start, resource_size(res));
	if (!data->base) {
		err = -ENODEV;
		goto out_free;
@@ -205,11 +193,44 @@ static int __init exiu_init(struct device_node *node,
	writel_relaxed(0xFFFFFFFF, data->base + EIREQCLR);
	writel_relaxed(0xFFFFFFFF, data->base + EIMASK);

	return data;

out_free:
	kfree(data);
	return ERR_PTR(err);
}

static int __init exiu_dt_init(struct device_node *node,
			       struct device_node *parent)
{
	struct irq_domain *parent_domain, *domain;
	struct exiu_irq_data *data;
	struct resource res;

	if (!parent) {
		pr_err("%pOF: no parent, giving up\n", node);
		return -ENODEV;
	}

	parent_domain = irq_find_host(parent);
	if (!parent_domain) {
		pr_err("%pOF: unable to obtain parent domain\n", node);
		return -ENXIO;
	}

	if (of_address_to_resource(node, 0, &res)) {
		pr_err("%pOF: failed to parse memory resource\n", node);
		return -ENXIO;
	}

	data = exiu_init(of_node_to_fwnode(node), &res);
	if (IS_ERR(data))
		return PTR_ERR(data);

	domain = irq_domain_add_hierarchy(parent_domain, 0, NUM_IRQS, node,
					  &exiu_domain_ops, data);
	if (!domain) {
		pr_err("%pOF: failed to allocate domain\n", node);
		err = -ENOMEM;
		goto out_unmap;
	}

@@ -220,8 +241,7 @@ static int __init exiu_init(struct device_node *node,

out_unmap:
	iounmap(data->base);
out_free:
	kfree(data);
	return err;
	return -ENOMEM;
}
IRQCHIP_DECLARE(exiu, "socionext,synquacer-exiu", exiu_init);
IRQCHIP_DECLARE(exiu, "socionext,synquacer-exiu", exiu_dt_init);