summaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2019-05-28 09:36:45 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2019-05-28 09:55:02 -0400
commit0444638c0f0641c5239197f0c00a4293949d071e (patch)
treecbb88e43c713b2ab235c7d6d2ec81a303a7f7d88 /drivers/irqchip
parent621dc2fdcea1496ddd472c297d42e8d6642b05bc (diff)
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: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/irq-sni-exiu.c66
1 files changed, 43 insertions, 23 deletions
diff --git a/drivers/irqchip/irq-sni-exiu.c b/drivers/irqchip/irq-sni-exiu.c
index 1927b2f36ff6..fef7c2437dfb 100644
--- a/drivers/irqchip/irq-sni-exiu.c
+++ b/drivers/irqchip/irq-sni-exiu.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for Socionext External Interrupt Unit (EXIU) 2 * Driver for Socionext External Interrupt Unit (EXIU)
3 * 3 *
4 * Copyright (c) 2017 Linaro, Ltd. <ard.biesheuvel@linaro.org> 4 * Copyright (c) 2017-2019 Linaro, Ltd. <ard.biesheuvel@linaro.org>
5 * 5 *
6 * Based on irq-tegra.c: 6 * Based on irq-tegra.c:
7 * Copyright (C) 2011 Google, Inc. 7 * Copyright (C) 2011 Google, Inc.
@@ -167,35 +167,23 @@ static const struct irq_domain_ops exiu_domain_ops = {
167 .free = irq_domain_free_irqs_common, 167 .free = irq_domain_free_irqs_common,
168}; 168};
169 169
170static int __init exiu_init(struct device_node *node, 170static struct exiu_irq_data *exiu_init(const struct fwnode_handle *fwnode,
171 struct device_node *parent) 171 struct resource *res)
172{ 172{
173 struct irq_domain *parent_domain, *domain;
174 struct exiu_irq_data *data; 173 struct exiu_irq_data *data;
175 int err; 174 int err;
176 175
177 if (!parent) {
178 pr_err("%pOF: no parent, giving up\n", node);
179 return -ENODEV;
180 }
181
182 parent_domain = irq_find_host(parent);
183 if (!parent_domain) {
184 pr_err("%pOF: unable to obtain parent domain\n", node);
185 return -ENXIO;
186 }
187
188 data = kzalloc(sizeof(*data), GFP_KERNEL); 176 data = kzalloc(sizeof(*data), GFP_KERNEL);
189 if (!data) 177 if (!data)
190 return -ENOMEM; 178 return ERR_PTR(-ENOMEM);
191 179
192 if (of_property_read_u32(node, "socionext,spi-base", &data->spi_base)) { 180 if (fwnode_property_read_u32_array(fwnode, "socionext,spi-base",
193 pr_err("%pOF: failed to parse 'spi-base' property\n", node); 181 &data->spi_base, 1)) {
194 err = -ENODEV; 182 err = -ENODEV;
195 goto out_free; 183 goto out_free;
196 } 184 }
197 185
198 data->base = of_iomap(node, 0); 186 data->base = ioremap(res->start, resource_size(res));
199 if (!data->base) { 187 if (!data->base) {
200 err = -ENODEV; 188 err = -ENODEV;
201 goto out_free; 189 goto out_free;
@@ -205,11 +193,44 @@ static int __init exiu_init(struct device_node *node,
205 writel_relaxed(0xFFFFFFFF, data->base + EIREQCLR); 193 writel_relaxed(0xFFFFFFFF, data->base + EIREQCLR);
206 writel_relaxed(0xFFFFFFFF, data->base + EIMASK); 194 writel_relaxed(0xFFFFFFFF, data->base + EIMASK);
207 195
196 return data;
197
198out_free:
199 kfree(data);
200 return ERR_PTR(err);
201}
202
203static int __init exiu_dt_init(struct device_node *node,
204 struct device_node *parent)
205{
206 struct irq_domain *parent_domain, *domain;
207 struct exiu_irq_data *data;
208 struct resource res;
209
210 if (!parent) {
211 pr_err("%pOF: no parent, giving up\n", node);
212 return -ENODEV;
213 }
214
215 parent_domain = irq_find_host(parent);
216 if (!parent_domain) {
217 pr_err("%pOF: unable to obtain parent domain\n", node);
218 return -ENXIO;
219 }
220
221 if (of_address_to_resource(node, 0, &res)) {
222 pr_err("%pOF: failed to parse memory resource\n", node);
223 return -ENXIO;
224 }
225
226 data = exiu_init(of_node_to_fwnode(node), &res);
227 if (IS_ERR(data))
228 return PTR_ERR(data);
229
208 domain = irq_domain_add_hierarchy(parent_domain, 0, NUM_IRQS, node, 230 domain = irq_domain_add_hierarchy(parent_domain, 0, NUM_IRQS, node,
209 &exiu_domain_ops, data); 231 &exiu_domain_ops, data);
210 if (!domain) { 232 if (!domain) {
211 pr_err("%pOF: failed to allocate domain\n", node); 233 pr_err("%pOF: failed to allocate domain\n", node);
212 err = -ENOMEM;
213 goto out_unmap; 234 goto out_unmap;
214 } 235 }
215 236
@@ -220,8 +241,7 @@ static int __init exiu_init(struct device_node *node,
220 241
221out_unmap: 242out_unmap:
222 iounmap(data->base); 243 iounmap(data->base);
223out_free:
224 kfree(data); 244 kfree(data);
225 return err; 245 return -ENOMEM;
226} 246}
227IRQCHIP_DECLARE(exiu, "socionext,synquacer-exiu", exiu_init); 247IRQCHIP_DECLARE(exiu, "socionext,synquacer-exiu", exiu_dt_init);