Skip to content

Commit 0b21add

Browse files
hcodinaKAGA-KOKO
authored andcommitted
irqdomain: Handle domain bus token in irq_domain_create()
irq_domain_update_bus_token() is the only way to set the domain bus token. This is sub-optimal as irq_domain_update_bus_token() can be called only once the domain is created and needs to revert some operations, change the domain name and redo the operations. In order to avoid this revert/change/redo sequence, take the domain bus into account token during the domain creation. Suggested-by: Thomas Gleixner <[email protected]> Signed-off-by: Herve Codina <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 80f6abe commit 0b21add

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

include/linux/irqdomain.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
265265
* @hwirq_max: Maximum number of interrupts supported by controller
266266
* @direct_max: Maximum value of direct maps;
267267
* Use ~0 for no limit; 0 for no direct mapping
268+
* @bus_token: Domain bus token
268269
* @ops: Domain operation callbacks
269270
* @host_data: Controller private data pointer
270271
*/
@@ -274,6 +275,7 @@ struct irq_domain_info {
274275
unsigned int size;
275276
irq_hw_number_t hwirq_max;
276277
int direct_max;
278+
enum irq_domain_bus_token bus_token;
277279
const struct irq_domain_ops *ops;
278280
void *host_data;
279281
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY

kernel/irq/irqdomain.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
129129
EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
130130

131131
static int irq_domain_set_name(struct irq_domain *domain,
132-
const struct fwnode_handle *fwnode)
132+
const struct fwnode_handle *fwnode,
133+
enum irq_domain_bus_token bus_token)
133134
{
134135
static atomic_t unknown_domains;
135136
struct irqchip_fwid *fwid;
@@ -140,13 +141,23 @@ static int irq_domain_set_name(struct irq_domain *domain,
140141
switch (fwid->type) {
141142
case IRQCHIP_FWNODE_NAMED:
142143
case IRQCHIP_FWNODE_NAMED_ID:
143-
domain->name = kstrdup(fwid->name, GFP_KERNEL);
144+
domain->name = bus_token ?
145+
kasprintf(GFP_KERNEL, "%s-%d",
146+
fwid->name, bus_token) :
147+
kstrdup(fwid->name, GFP_KERNEL);
144148
if (!domain->name)
145149
return -ENOMEM;
146150
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
147151
break;
148152
default:
149153
domain->name = fwid->name;
154+
if (bus_token) {
155+
domain->name = kasprintf(GFP_KERNEL, "%s-%d",
156+
fwid->name, bus_token);
157+
if (!domain->name)
158+
return -ENOMEM;
159+
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
160+
}
150161
break;
151162
}
152163
} else if (is_of_node(fwnode) || is_acpi_device_node(fwnode) ||
@@ -158,7 +169,9 @@ static int irq_domain_set_name(struct irq_domain *domain,
158169
* unhappy about. Replace them with ':', which does
159170
* the trick and is not as offensive as '\'...
160171
*/
161-
name = kasprintf(GFP_KERNEL, "%pfw", fwnode);
172+
name = bus_token ?
173+
kasprintf(GFP_KERNEL, "%pfw-%d", fwnode, bus_token) :
174+
kasprintf(GFP_KERNEL, "%pfw", fwnode);
162175
if (!name)
163176
return -ENOMEM;
164177

@@ -169,8 +182,12 @@ static int irq_domain_set_name(struct irq_domain *domain,
169182
if (!domain->name) {
170183
if (fwnode)
171184
pr_err("Invalid fwnode type for irqdomain\n");
172-
domain->name = kasprintf(GFP_KERNEL, "unknown-%d",
173-
atomic_inc_return(&unknown_domains));
185+
domain->name = bus_token ?
186+
kasprintf(GFP_KERNEL, "unknown-%d-%d",
187+
atomic_inc_return(&unknown_domains),
188+
bus_token) :
189+
kasprintf(GFP_KERNEL, "unknown-%d",
190+
atomic_inc_return(&unknown_domains));
174191
if (!domain->name)
175192
return -ENOMEM;
176193
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
@@ -194,7 +211,7 @@ static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info
194211
if (!domain)
195212
return ERR_PTR(-ENOMEM);
196213

197-
err = irq_domain_set_name(domain, info->fwnode);
214+
err = irq_domain_set_name(domain, info->fwnode, info->bus_token);
198215
if (err) {
199216
kfree(domain);
200217
return ERR_PTR(err);
@@ -207,6 +224,7 @@ static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info
207224
INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL);
208225
domain->ops = info->ops;
209226
domain->host_data = info->host_data;
227+
domain->bus_token = info->bus_token;
210228
domain->hwirq_max = info->hwirq_max;
211229

212230
if (info->direct_max)

0 commit comments

Comments
 (0)