aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2017-06-22 06:34:57 -0400
committerThomas Gleixner <tglx@linutronix.de>2017-06-22 12:28:45 -0400
commit61d0a000b7746665c7cfcff766532f6f2a922a61 (patch)
treef721513ed1aaa59db21e79a8db6af997495ed55c
parent9a0ef98e186d86fb3c1ff3ec267a76f067005f74 (diff)
genirq/irqdomain: Add irq_domain_update_bus_token helper
We can have irq domains that are identified by the same fwnode (because they are serviced by the same HW), and yet have different functionnality (because they serve different busses, for example). This is what we use the bus_token field. Since we don't use this field when generating the domain name, all the aliasing domains will get the same name, and the debugfs file creation fails. Also, bus_token is updated by individual drivers, and the core code is unaware of that update. In order to sort this mess, let's introduce a helper that takes care of updating bus_token, and regenerate the debugfs file. A separate patch will update all the individual users. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--include/linux/irqdomain.h3
-rw-r--r--kernel/irq/irqdomain.c31
2 files changed, 34 insertions, 0 deletions
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 914b0c31d233..222f47af12f4 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -273,6 +273,9 @@ static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode)
273 return fwnode && fwnode->type == FWNODE_IRQCHIP; 273 return fwnode && fwnode->type == FWNODE_IRQCHIP;
274} 274}
275 275
276extern void irq_domain_update_bus_token(struct irq_domain *domain,
277 enum irq_domain_bus_token bus_token);
278
276static inline 279static inline
277struct irq_domain *irq_find_matching_fwnode(struct fwnode_handle *fwnode, 280struct irq_domain *irq_find_matching_fwnode(struct fwnode_handle *fwnode,
278 enum irq_domain_bus_token bus_token) 281 enum irq_domain_bus_token bus_token)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 75e1f0851c33..f6adeaeb4c16 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -245,6 +245,37 @@ void irq_domain_remove(struct irq_domain *domain)
245} 245}
246EXPORT_SYMBOL_GPL(irq_domain_remove); 246EXPORT_SYMBOL_GPL(irq_domain_remove);
247 247
248void irq_domain_update_bus_token(struct irq_domain *domain,
249 enum irq_domain_bus_token bus_token)
250{
251 char *name;
252
253 if (domain->bus_token == bus_token)
254 return;
255
256 mutex_lock(&irq_domain_mutex);
257
258 domain->bus_token = bus_token;
259
260 name = kasprintf(GFP_KERNEL, "%s-%d", domain->name, bus_token);
261 if (!name) {
262 mutex_unlock(&irq_domain_mutex);
263 return;
264 }
265
266 debugfs_remove_domain_dir(domain);
267
268 if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED)
269 kfree(domain->name);
270 else
271 domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
272
273 domain->name = name;
274 debugfs_add_domain_dir(domain);
275
276 mutex_unlock(&irq_domain_mutex);
277}
278
248/** 279/**
249 * irq_domain_add_simple() - Register an irq_domain and optionally map a range of irqs 280 * irq_domain_add_simple() - Register an irq_domain and optionally map a range of irqs
250 * @of_node: pointer to interrupt controller's device tree node. 281 * @of_node: pointer to interrupt controller's device tree node.