irqchip/exiu: Preparatory refactor for ACPI support
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 28 May 2019 13:36:45 +0000 (15:36 +0200)
committerMarc Zyngier <marc.zyngier@arm.com>
Tue, 28 May 2019 13:55:02 +0000 (14:55 +0100)
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: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
drivers/irqchip/irq-sni-exiu.c

index 1927b2f36ff6e5e760fce6bd7b5776c51ff9179b..fef7c2437dfb0eca3fdcc1ddb0a0aaf41daac5ce 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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);