* [PATCH 01/23] irqdomain: Introduce irq_domain_free()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 02/23] irqdomain: Introduce irq_domain_instantiate() Herve Codina
` (22 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
In preparation of the introduction of the irq domain instantiation,
introduce irq_domain_free() to avoid code duplication on later
modifications.
This new function is an extraction of the current operations performed
to free the irq domain. No functional changes are introduced.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
kernel/irq/irqdomain.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 86f8b91b0d3a..95eda206367f 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -241,6 +241,15 @@ static void __irq_domain_publish(struct irq_domain *domain)
pr_debug("Added domain %s\n", domain->name);
}
+static void irq_domain_free(struct irq_domain *domain)
+{
+ fwnode_dev_initialized(domain->fwnode, false);
+ fwnode_handle_put(domain->fwnode);
+ if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED)
+ kfree(domain->name);
+ kfree(domain);
+}
+
/**
* __irq_domain_add() - Allocate a new irq_domain data structure
* @fwnode: firmware node for the interrupt controller
@@ -296,12 +305,7 @@ void irq_domain_remove(struct irq_domain *domain)
mutex_unlock(&irq_domain_mutex);
pr_debug("Removed domain %s\n", domain->name);
-
- fwnode_dev_initialized(domain->fwnode, false);
- fwnode_handle_put(domain->fwnode);
- if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED)
- kfree(domain->name);
- kfree(domain);
+ irq_domain_free(domain);
}
EXPORT_SYMBOL_GPL(irq_domain_remove);
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Introduce irq_domain_free()
2024-06-14 17:32 ` [PATCH 01/23] irqdomain: Introduce irq_domain_free() Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Thomas Gleixner, Herve Codina, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 89b37541ca38954f8ac01c2ca25405b140cfc8eb
Gitweb: https://git.kernel.org/tip/89b37541ca38954f8ac01c2ca25405b140cfc8eb
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:02 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:12 +02:00
irqdomain: Introduce irq_domain_free()
In preparation of the introduction of the irq domain instantiation,
introduce irq_domain_free() to avoid code duplication on later
modifications.
This new function is an extraction of the current operations performed
to free the irq domain. No functional change intended.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-2-herve.codina@bootlin.com
---
kernel/irq/irqdomain.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 7b4d580..40b631b 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -238,6 +238,15 @@ static void __irq_domain_publish(struct irq_domain *domain)
pr_debug("Added domain %s\n", domain->name);
}
+static void irq_domain_free(struct irq_domain *domain)
+{
+ fwnode_dev_initialized(domain->fwnode, false);
+ fwnode_handle_put(domain->fwnode);
+ if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED)
+ kfree(domain->name);
+ kfree(domain);
+}
+
/**
* __irq_domain_add() - Allocate a new irq_domain data structure
* @fwnode: firmware node for the interrupt controller
@@ -293,12 +302,7 @@ void irq_domain_remove(struct irq_domain *domain)
mutex_unlock(&irq_domain_mutex);
pr_debug("Removed domain %s\n", domain->name);
-
- fwnode_dev_initialized(domain->fwnode, false);
- fwnode_handle_put(domain->fwnode);
- if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED)
- kfree(domain->name);
- kfree(domain);
+ irq_domain_free(domain);
}
EXPORT_SYMBOL_GPL(irq_domain_remove);
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 02/23] irqdomain: Introduce irq_domain_instantiate()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
2024-06-14 17:32 ` [PATCH 01/23] irqdomain: Introduce irq_domain_free() Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 03/23] irqdomain: Fixed unbalanced fwnode get and put Herve Codina
` (21 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
The existing irq_domain_add_*() functions used to instantiate an IRQ
domain are wrappers built on top of __irq_domain_add() and describes the
domain properties using a bunch of parameters.
Adding more parameters and wrappers to hide new parameters in the
existing code lead to more and more code without any relevant values and
without any flexibility.
Introduce irq_domain_instantiate() where the IRQ domain properties are
given using the irq_domain_info structure instead of the bunch of
parameters to allow flexibility and easy evolution.
This new irq_domain_instantiate() perform the same operation as the one
done by __irq_domain_add(). For compatibility reason with existing code,
keep __irq_domain_add() but convert it to irq_domain_instantiate().
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irqdomain.h | 21 +++++++++++++++++++++
kernel/irq/irqdomain.c | 39 ++++++++++++++++++++++++++++++++-------
2 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 21ecf582a0fe..ab8939c8724d 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -257,6 +257,27 @@ static inline struct fwnode_handle *irq_domain_alloc_fwnode(phys_addr_t *pa)
}
void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
+/**
+ * struct irq_domain_info - Domain information structure
+ * @fwnode: firmware node for the interrupt controller
+ * @size: Size of linear map; 0 for radix mapping only
+ * @hwirq_max: Maximum number of interrupts supported by controller
+ * @direct_max: Maximum value of direct maps;
+ * Use ~0 for no limit; 0 for no direct mapping
+ * @ops: Domain operation callbacks
+ * @host_data: Controller private data pointer
+ */
+struct irq_domain_info {
+ struct fwnode_handle *fwnode;
+ unsigned int size;
+ irq_hw_number_t hwirq_max;
+ int direct_max;
+ const struct irq_domain_ops *ops;
+ void *host_data;
+};
+
+struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
+
struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
irq_hw_number_t hwirq_max, int direct_max,
const struct irq_domain_ops *ops,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 95eda206367f..012ada09b419 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -250,6 +250,27 @@ static void irq_domain_free(struct irq_domain *domain)
kfree(domain);
}
+/**
+ * irq_domain_instantiate() - Instantiate a new irq domain data structure
+ * @info: Domain information pointer pointing to the information for this domain
+ *
+ * Return: A pointer to the instantiated irq domain or an ERR_PTR value.
+ */
+struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
+{
+ struct irq_domain *domain;
+
+ domain = __irq_domain_create(info->fwnode, info->size, info->hwirq_max,
+ info->direct_max, info->ops, info->host_data);
+ if (!domain)
+ return ERR_PTR(-ENOMEM);
+
+ __irq_domain_publish(domain);
+
+ return domain;
+}
+EXPORT_SYMBOL_GPL(irq_domain_instantiate);
+
/**
* __irq_domain_add() - Allocate a new irq_domain data structure
* @fwnode: firmware node for the interrupt controller
@@ -268,14 +289,18 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int s
const struct irq_domain_ops *ops,
void *host_data)
{
- struct irq_domain *domain;
-
- domain = __irq_domain_create(fwnode, size, hwirq_max, direct_max,
- ops, host_data);
- if (domain)
- __irq_domain_publish(domain);
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .size = size,
+ .hwirq_max = hwirq_max,
+ .direct_max = direct_max,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
- return domain;
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
EXPORT_SYMBOL_GPL(__irq_domain_add);
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Introduce irq_domain_instantiate()
2024-06-14 17:32 ` [PATCH 02/23] irqdomain: Introduce irq_domain_instantiate() Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Thomas Gleixner, Herve Codina, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 299d623f5c9ab48e53255cf6b510627f1ef26dfe
Gitweb: https://git.kernel.org/tip/299d623f5c9ab48e53255cf6b510627f1ef26dfe
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:03 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:13 +02:00
irqdomain: Introduce irq_domain_instantiate()
The existing irq_domain_add_*() functions used to instantiate an IRQ
domain are wrappers built on top of __irq_domain_add() and describe the
domain properties using a bunch of parameters.
Adding more parameters and wrappers to hide new parameters in the
existing code lead to more and more code without any relevant value and
without any flexibility.
Introduce irq_domain_instantiate() where the interrupt domain properties
are given using a irq_domain_info structure instead of the bunch of
parameters to allow flexibility and easy evolution.
irq_domain_instantiate() performs the same operation as the one done by
__irq_domain_add(). For compatibility reason with existing code, keep
__irq_domain_add() but convert it to irq_domain_instantiate().
[ tglx: Fixed up struct initializer coding style ]
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-3-herve.codina@bootlin.com
---
include/linux/irqdomain.h | 21 ++++++++++++++++++++-
kernel/irq/irqdomain.c | 39 +++++++++++++++++++++++++++++++-------
2 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 21ecf58..ab8939c 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -257,6 +257,27 @@ static inline struct fwnode_handle *irq_domain_alloc_fwnode(phys_addr_t *pa)
}
void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
+/**
+ * struct irq_domain_info - Domain information structure
+ * @fwnode: firmware node for the interrupt controller
+ * @size: Size of linear map; 0 for radix mapping only
+ * @hwirq_max: Maximum number of interrupts supported by controller
+ * @direct_max: Maximum value of direct maps;
+ * Use ~0 for no limit; 0 for no direct mapping
+ * @ops: Domain operation callbacks
+ * @host_data: Controller private data pointer
+ */
+struct irq_domain_info {
+ struct fwnode_handle *fwnode;
+ unsigned int size;
+ irq_hw_number_t hwirq_max;
+ int direct_max;
+ const struct irq_domain_ops *ops;
+ void *host_data;
+};
+
+struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
+
struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
irq_hw_number_t hwirq_max, int direct_max,
const struct irq_domain_ops *ops,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 40b631b..111052f 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -248,6 +248,27 @@ static void irq_domain_free(struct irq_domain *domain)
}
/**
+ * irq_domain_instantiate() - Instantiate a new irq domain data structure
+ * @info: Domain information pointer pointing to the information for this domain
+ *
+ * Return: A pointer to the instantiated irq domain or an ERR_PTR value.
+ */
+struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
+{
+ struct irq_domain *domain;
+
+ domain = __irq_domain_create(info->fwnode, info->size, info->hwirq_max,
+ info->direct_max, info->ops, info->host_data);
+ if (!domain)
+ return ERR_PTR(-ENOMEM);
+
+ __irq_domain_publish(domain);
+
+ return domain;
+}
+EXPORT_SYMBOL_GPL(irq_domain_instantiate);
+
+/**
* __irq_domain_add() - Allocate a new irq_domain data structure
* @fwnode: firmware node for the interrupt controller
* @size: Size of linear map; 0 for radix mapping only
@@ -265,14 +286,18 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int s
const struct irq_domain_ops *ops,
void *host_data)
{
- struct irq_domain *domain;
-
- domain = __irq_domain_create(fwnode, size, hwirq_max, direct_max,
- ops, host_data);
- if (domain)
- __irq_domain_publish(domain);
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .size = size,
+ .hwirq_max = hwirq_max,
+ .direct_max = direct_max,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
- return domain;
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
EXPORT_SYMBOL_GPL(__irq_domain_add);
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 03/23] irqdomain: Fixed unbalanced fwnode get and put
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
2024-06-14 17:32 ` [PATCH 01/23] irqdomain: Introduce irq_domain_free() Herve Codina
2024-06-14 17:32 ` [PATCH 02/23] irqdomain: Introduce irq_domain_instantiate() Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 04/23] irqdomain: Constify parameter in is_fwnode_irqchip() Herve Codina
` (20 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni, stable
fwnode_handle_get(fwnode) is called when a domain is created with fwnode
passed as a function parameter. fwnode_handle_put(domain->fwnode) is
called when the domain is destroyed but during the creation a path
exists that does not set domain->fwnode.
If this path is taken, the fwnode get will never be put.
To avoid the unbalanced get and put, set domain->fwnode unconditionally.
Fixes: d59f6617eef0 ("genirq: Allow fwnode to carry name information only")
Cc: stable@vger.kernel.org
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
kernel/irq/irqdomain.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 012ada09b419..31277488ed42 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -156,7 +156,6 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
switch (fwid->type) {
case IRQCHIP_FWNODE_NAMED:
case IRQCHIP_FWNODE_NAMED_ID:
- domain->fwnode = fwnode;
domain->name = kstrdup(fwid->name, GFP_KERNEL);
if (!domain->name) {
kfree(domain);
@@ -165,7 +164,6 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
break;
default:
- domain->fwnode = fwnode;
domain->name = fwid->name;
break;
}
@@ -185,7 +183,6 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
}
domain->name = strreplace(name, '/', ':');
- domain->fwnode = fwnode;
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
}
@@ -201,8 +198,8 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
}
- fwnode_handle_get(fwnode);
- fwnode_dev_initialized(fwnode, true);
+ domain->fwnode = fwnode_handle_get(fwnode);
+ fwnode_dev_initialized(domain->fwnode, true);
/* Fill structure */
INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL);
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Fixed unbalanced fwnode get and put
2024-06-14 17:32 ` [PATCH 03/23] irqdomain: Fixed unbalanced fwnode get and put Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits
Cc: Herve Codina, Thomas Gleixner, stable, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 6ce3e98184b625d2870991880bf9586ded7ea7f9
Gitweb: https://git.kernel.org/tip/6ce3e98184b625d2870991880bf9586ded7ea7f9
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:04 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:12 +02:00
irqdomain: Fixed unbalanced fwnode get and put
fwnode_handle_get(fwnode) is called when a domain is created with fwnode
passed as a function parameter. fwnode_handle_put(domain->fwnode) is called
when the domain is destroyed but during the creation a path exists that
does not set domain->fwnode.
If this path is taken, the fwnode get will never be put.
To avoid the unbalanced get and put, set domain->fwnode unconditionally.
Fixes: d59f6617eef0 ("genirq: Allow fwnode to carry name information only")
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20240614173232.1184015-4-herve.codina@bootlin.com
---
kernel/irq/irqdomain.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 28709c1..7b4d580 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -156,7 +156,6 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
switch (fwid->type) {
case IRQCHIP_FWNODE_NAMED:
case IRQCHIP_FWNODE_NAMED_ID:
- domain->fwnode = fwnode;
domain->name = kstrdup(fwid->name, GFP_KERNEL);
if (!domain->name) {
kfree(domain);
@@ -165,7 +164,6 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
break;
default:
- domain->fwnode = fwnode;
domain->name = fwid->name;
break;
}
@@ -185,7 +183,6 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
}
domain->name = strreplace(name, '/', ':');
- domain->fwnode = fwnode;
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
}
@@ -201,8 +198,8 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
}
- fwnode_handle_get(fwnode);
- fwnode_dev_initialized(fwnode, true);
+ domain->fwnode = fwnode_handle_get(fwnode);
+ fwnode_dev_initialized(domain->fwnode, true);
/* Fill structure */
INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL);
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 04/23] irqdomain: Constify parameter in is_fwnode_irqchip()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (2 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 03/23] irqdomain: Fixed unbalanced fwnode get and put Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 05/23] irqdomain: Use a dedicated function to set the domain name Herve Codina
` (19 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
The fwnode parameter has no reason to be pointer to an un-const struct
fwnode_handle. Indeed, struct fwnode_handle is not modified by the
function.
Be consistent with other function performing the same kind
of operation such as is_of_node(), is_acpi_device_node() or
is_software_node(): constify the fwnode parameter.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irqdomain.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index ab8939c8724d..a3b43e357009 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -314,7 +314,7 @@ static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
extern const struct fwnode_operations irqchip_fwnode_ops;
-static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode)
+static inline bool is_fwnode_irqchip(const struct fwnode_handle *fwnode)
{
return fwnode && fwnode->ops == &irqchip_fwnode_ops;
}
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Constify parameter in is_fwnode_irqchip()
2024-06-14 17:32 ` [PATCH 04/23] irqdomain: Constify parameter in is_fwnode_irqchip() Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 922ac2cf9fe444c4aff165b9f7e158a9b651647d
Gitweb: https://git.kernel.org/tip/922ac2cf9fe444c4aff165b9f7e158a9b651647d
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:05 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:13 +02:00
irqdomain: Constify parameter in is_fwnode_irqchip()
The fwnode parameter has no reason to be a pointer to an un-const struct
fwnode_handle. Indeed, struct fwnode_handle is not supposed to be modified
by the function.
Be consistent with other function performing the same kind of operation
such as is_of_node(), is_acpi_device_node() or is_software_node(): constify
the fwnode parameter.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-5-herve.codina@bootlin.com
---
include/linux/irqdomain.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index ab8939c..a3b43e3 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -314,7 +314,7 @@ static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
extern const struct fwnode_operations irqchip_fwnode_ops;
-static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode)
+static inline bool is_fwnode_irqchip(const struct fwnode_handle *fwnode)
{
return fwnode && fwnode->ops == &irqchip_fwnode_ops;
}
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 05/23] irqdomain: Use a dedicated function to set the domain name
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (3 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 04/23] irqdomain: Constify parameter in is_fwnode_irqchip() Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 06/23] irqdomain: Convert __irq_domain_create() to use struct irq_domain_info Herve Codina
` (18 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
The irq domain name computation and setting is directly done in
__irq_domain_create(). This leads to a quite long __irq_domain_create()
function.
In order to simplify __irq_domain_create() and isolate the domain name
computation and setting, move the related operations to a dedicated
function.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
kernel/irq/irqdomain.c | 69 +++++++++++++++++++++++-------------------
1 file changed, 38 insertions(+), 31 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 31277488ed42..0b152061e63a 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -128,27 +128,11 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
}
EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
-static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
- unsigned int size,
- irq_hw_number_t hwirq_max,
- int direct_max,
- const struct irq_domain_ops *ops,
- void *host_data)
+static int irq_domain_set_name(struct irq_domain *domain,
+ const struct fwnode_handle *fwnode)
{
- struct irqchip_fwid *fwid;
- struct irq_domain *domain;
-
static atomic_t unknown_domains;
-
- if (WARN_ON((size && direct_max) ||
- (!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && direct_max) ||
- (direct_max && (direct_max != hwirq_max))))
- return NULL;
-
- domain = kzalloc_node(struct_size(domain, revmap, size),
- GFP_KERNEL, of_node_to_nid(to_of_node(fwnode)));
- if (!domain)
- return NULL;
+ struct irqchip_fwid *fwid;
if (is_fwnode_irqchip(fwnode)) {
fwid = container_of(fwnode, struct irqchip_fwid, fwnode);
@@ -157,10 +141,8 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
case IRQCHIP_FWNODE_NAMED:
case IRQCHIP_FWNODE_NAMED_ID:
domain->name = kstrdup(fwid->name, GFP_KERNEL);
- if (!domain->name) {
- kfree(domain);
- return NULL;
- }
+ if (!domain->name)
+ return -ENOMEM;
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
break;
default:
@@ -177,10 +159,8 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
* the trick and is not as offensive as '\'...
*/
name = kasprintf(GFP_KERNEL, "%pfw", fwnode);
- if (!name) {
- kfree(domain);
- return NULL;
- }
+ if (!name)
+ return -ENOMEM;
domain->name = strreplace(name, '/', ':');
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
@@ -191,13 +171,40 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
pr_err("Invalid fwnode type for irqdomain\n");
domain->name = kasprintf(GFP_KERNEL, "unknown-%d",
atomic_inc_return(&unknown_domains));
- if (!domain->name) {
- kfree(domain);
- return NULL;
- }
+ if (!domain->name)
+ return -ENOMEM;
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
}
+ return 0;
+}
+
+static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
+ unsigned int size,
+ irq_hw_number_t hwirq_max,
+ int direct_max,
+ const struct irq_domain_ops *ops,
+ void *host_data)
+{
+ struct irq_domain *domain;
+ int err;
+
+ if (WARN_ON((size && direct_max) ||
+ (!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && direct_max) ||
+ (direct_max && direct_max != hwirq_max)))
+ return NULL;
+
+ domain = kzalloc_node(struct_size(domain, revmap, size),
+ GFP_KERNEL, of_node_to_nid(to_of_node(fwnode)));
+ if (!domain)
+ return NULL;
+
+ err = irq_domain_set_name(domain, fwnode);
+ if (err) {
+ kfree(domain);
+ return NULL;
+ }
+
domain->fwnode = fwnode_handle_get(fwnode);
fwnode_dev_initialized(domain->fwnode, true);
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Use a dedicated function to set the domain name
2024-06-14 17:32 ` [PATCH 05/23] irqdomain: Use a dedicated function to set the domain name Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: dbd56abffc6a43eb361e8033dce7a7d176f8e867
Gitweb: https://git.kernel.org/tip/dbd56abffc6a43eb361e8033dce7a7d176f8e867
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:06 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:13 +02:00
irqdomain: Use a dedicated function to set the domain name
The interrupt domain name computation and setting is directly done in
__irq_domain_create(). This leads to a quite long __irq_domain_create()
function.
In order to simplify __irq_domain_create() and isolate the domain name
computation and setting, move the related operations to a dedicated
function.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-6-herve.codina@bootlin.com
---
kernel/irq/irqdomain.c | 69 ++++++++++++++++++++++-------------------
1 file changed, 38 insertions(+), 31 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 111052f..a7be776 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -128,27 +128,11 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
}
EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
-static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
- unsigned int size,
- irq_hw_number_t hwirq_max,
- int direct_max,
- const struct irq_domain_ops *ops,
- void *host_data)
+static int irq_domain_set_name(struct irq_domain *domain,
+ const struct fwnode_handle *fwnode)
{
- struct irqchip_fwid *fwid;
- struct irq_domain *domain;
-
static atomic_t unknown_domains;
-
- if (WARN_ON((size && direct_max) ||
- (!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && direct_max) ||
- (direct_max && (direct_max != hwirq_max))))
- return NULL;
-
- domain = kzalloc_node(struct_size(domain, revmap, size),
- GFP_KERNEL, of_node_to_nid(to_of_node(fwnode)));
- if (!domain)
- return NULL;
+ struct irqchip_fwid *fwid;
if (is_fwnode_irqchip(fwnode)) {
fwid = container_of(fwnode, struct irqchip_fwid, fwnode);
@@ -157,10 +141,8 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
case IRQCHIP_FWNODE_NAMED:
case IRQCHIP_FWNODE_NAMED_ID:
domain->name = kstrdup(fwid->name, GFP_KERNEL);
- if (!domain->name) {
- kfree(domain);
- return NULL;
- }
+ if (!domain->name)
+ return -ENOMEM;
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
break;
default:
@@ -177,10 +159,8 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
* the trick and is not as offensive as '\'...
*/
name = kasprintf(GFP_KERNEL, "%pfw", fwnode);
- if (!name) {
- kfree(domain);
- return NULL;
- }
+ if (!name)
+ return -ENOMEM;
domain->name = strreplace(name, '/', ':');
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
@@ -191,13 +171,40 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
pr_err("Invalid fwnode type for irqdomain\n");
domain->name = kasprintf(GFP_KERNEL, "unknown-%d",
atomic_inc_return(&unknown_domains));
- if (!domain->name) {
- kfree(domain);
- return NULL;
- }
+ if (!domain->name)
+ return -ENOMEM;
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
}
+ return 0;
+}
+
+static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
+ unsigned int size,
+ irq_hw_number_t hwirq_max,
+ int direct_max,
+ const struct irq_domain_ops *ops,
+ void *host_data)
+{
+ struct irq_domain *domain;
+ int err;
+
+ if (WARN_ON((size && direct_max) ||
+ (!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && direct_max) ||
+ (direct_max && direct_max != hwirq_max)))
+ return NULL;
+
+ domain = kzalloc_node(struct_size(domain, revmap, size),
+ GFP_KERNEL, of_node_to_nid(to_of_node(fwnode)));
+ if (!domain)
+ return NULL;
+
+ err = irq_domain_set_name(domain, fwnode);
+ if (err) {
+ kfree(domain);
+ return NULL;
+ }
+
domain->fwnode = fwnode_handle_get(fwnode);
fwnode_dev_initialized(domain->fwnode, true);
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 06/23] irqdomain: Convert __irq_domain_create() to use struct irq_domain_info
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (4 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 05/23] irqdomain: Use a dedicated function to set the domain name Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 07/23] irqdomain: Handle additional domain flags in irq_domain_instantiate() Herve Codina
` (17 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
The existing __irq_domain_create() use a bunch of parameters to create
an irq domain.
With the introduction of irq_domain_info structure, these parameters are
available in the information structure itself.
Using directly this information structure allows future flexibility to
add other parameters in a simple way without the need to change the
__irq_domain_create() prototype.
Convert __irq_domain_create() to use the information structure.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
kernel/irq/irqdomain.c | 48 +++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 0b152061e63a..28a463e25d99 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -179,45 +179,40 @@ static int irq_domain_set_name(struct irq_domain *domain,
return 0;
}
-static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
- unsigned int size,
- irq_hw_number_t hwirq_max,
- int direct_max,
- const struct irq_domain_ops *ops,
- void *host_data)
+static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info)
{
struct irq_domain *domain;
int err;
- if (WARN_ON((size && direct_max) ||
- (!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && direct_max) ||
- (direct_max && direct_max != hwirq_max)))
+ if (WARN_ON((info->size && info->direct_max) ||
+ (!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && info->direct_max) ||
+ (info->direct_max && info->direct_max != info->hwirq_max)))
return NULL;
- domain = kzalloc_node(struct_size(domain, revmap, size),
- GFP_KERNEL, of_node_to_nid(to_of_node(fwnode)));
+ domain = kzalloc_node(struct_size(domain, revmap, info->size),
+ GFP_KERNEL, of_node_to_nid(to_of_node(info->fwnode)));
if (!domain)
return NULL;
- err = irq_domain_set_name(domain, fwnode);
+ err = irq_domain_set_name(domain, info->fwnode);
if (err) {
kfree(domain);
return NULL;
}
- domain->fwnode = fwnode_handle_get(fwnode);
+ domain->fwnode = fwnode_handle_get(info->fwnode);
fwnode_dev_initialized(domain->fwnode, true);
/* Fill structure */
INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL);
- domain->ops = ops;
- domain->host_data = host_data;
- domain->hwirq_max = hwirq_max;
+ domain->ops = info->ops;
+ domain->host_data = info->host_data;
+ domain->hwirq_max = info->hwirq_max;
- if (direct_max)
+ if (info->direct_max)
domain->flags |= IRQ_DOMAIN_FLAG_NO_MAP;
- domain->revmap_size = size;
+ domain->revmap_size = info->size;
/*
* Hierarchical domains use the domain lock of the root domain
@@ -264,8 +259,7 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
{
struct irq_domain *domain;
- domain = __irq_domain_create(info->fwnode, info->size, info->hwirq_max,
- info->direct_max, info->ops, info->host_data);
+ domain = __irq_domain_create(info);
if (!domain)
return ERR_PTR(-ENOMEM);
@@ -1204,13 +1198,19 @@ struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
const struct irq_domain_ops *ops,
void *host_data)
{
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .size = size,
+ .hwirq_max = size,
+ .ops = ops,
+ .host_data = host_data,
+ };
struct irq_domain *domain;
- if (size)
- domain = __irq_domain_create(fwnode, size, size, 0, ops, host_data);
- else
- domain = __irq_domain_create(fwnode, 0, ~0, 0, ops, host_data);
+ if (!info.size)
+ info.hwirq_max = ~0U;
+ domain = __irq_domain_create(&info);
if (domain) {
if (parent)
domain->root = parent->root;
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Convert __irq_domain_create() to use struct irq_domain_info
2024-06-14 17:32 ` [PATCH 06/23] irqdomain: Convert __irq_domain_create() to use struct irq_domain_info Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Thomas Gleixner, Herve Codina, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 24a4f4e48557dddf2bb722df7b01184efc92a6a7
Gitweb: https://git.kernel.org/tip/24a4f4e48557dddf2bb722df7b01184efc92a6a7
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:07 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:13 +02:00
irqdomain: Convert __irq_domain_create() to use struct irq_domain_info
The existing __irq_domain_create() use a bunch of parameters to create
an irq domain.
With the introduction of irq_domain_info structure, these parameters are
available in the information structure itself.
Using directly this information structure allows future flexibility to
add other parameters in a simple way without the need to change the
__irq_domain_create() prototype.
Convert __irq_domain_create() to use the information structure.
[ tglx: Fixup struct initializer ]
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-7-herve.codina@bootlin.com
---
kernel/irq/irqdomain.c | 48 ++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index a7be776..0eda48f 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -179,45 +179,40 @@ static int irq_domain_set_name(struct irq_domain *domain,
return 0;
}
-static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
- unsigned int size,
- irq_hw_number_t hwirq_max,
- int direct_max,
- const struct irq_domain_ops *ops,
- void *host_data)
+static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info)
{
struct irq_domain *domain;
int err;
- if (WARN_ON((size && direct_max) ||
- (!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && direct_max) ||
- (direct_max && direct_max != hwirq_max)))
+ if (WARN_ON((info->size && info->direct_max) ||
+ (!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && info->direct_max) ||
+ (info->direct_max && info->direct_max != info->hwirq_max)))
return NULL;
- domain = kzalloc_node(struct_size(domain, revmap, size),
- GFP_KERNEL, of_node_to_nid(to_of_node(fwnode)));
+ domain = kzalloc_node(struct_size(domain, revmap, info->size),
+ GFP_KERNEL, of_node_to_nid(to_of_node(info->fwnode)));
if (!domain)
return NULL;
- err = irq_domain_set_name(domain, fwnode);
+ err = irq_domain_set_name(domain, info->fwnode);
if (err) {
kfree(domain);
return NULL;
}
- domain->fwnode = fwnode_handle_get(fwnode);
+ domain->fwnode = fwnode_handle_get(info->fwnode);
fwnode_dev_initialized(domain->fwnode, true);
/* Fill structure */
INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL);
- domain->ops = ops;
- domain->host_data = host_data;
- domain->hwirq_max = hwirq_max;
+ domain->ops = info->ops;
+ domain->host_data = info->host_data;
+ domain->hwirq_max = info->hwirq_max;
- if (direct_max)
+ if (info->direct_max)
domain->flags |= IRQ_DOMAIN_FLAG_NO_MAP;
- domain->revmap_size = size;
+ domain->revmap_size = info->size;
/*
* Hierarchical domains use the domain lock of the root domain
@@ -264,8 +259,7 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
{
struct irq_domain *domain;
- domain = __irq_domain_create(info->fwnode, info->size, info->hwirq_max,
- info->direct_max, info->ops, info->host_data);
+ domain = __irq_domain_create(info);
if (!domain)
return ERR_PTR(-ENOMEM);
@@ -1204,13 +1198,19 @@ struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
const struct irq_domain_ops *ops,
void *host_data)
{
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .size = size,
+ .hwirq_max = size,
+ .ops = ops,
+ .host_data = host_data,
+ };
struct irq_domain *domain;
- if (size)
- domain = __irq_domain_create(fwnode, size, size, 0, ops, host_data);
- else
- domain = __irq_domain_create(fwnode, 0, ~0, 0, ops, host_data);
+ if (!info.size)
+ info.hwirq_max = ~0U;
+ domain = __irq_domain_create(&info);
if (domain) {
if (parent)
domain->root = parent->root;
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 07/23] irqdomain: Handle additional domain flags in irq_domain_instantiate()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (5 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 06/23] irqdomain: Convert __irq_domain_create() to use struct irq_domain_info Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 08/23] irqdomain: Handle domain hierarchy parent " Herve Codina
` (16 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
In order to use irq_domain_instantiate() from several places such as
irq_domain_create_hierarchy(), irq_domain_instantiate() needs to handle
additional domain flags.
Handle these additional flags.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irqdomain.h | 2 ++
kernel/irq/irqdomain.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index a3b43e357009..4683b66eded9 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -260,6 +260,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
/**
* struct irq_domain_info - Domain information structure
* @fwnode: firmware node for the interrupt controller
+ * @domain_flags: Additional flags to add to the domain flags
* @size: Size of linear map; 0 for radix mapping only
* @hwirq_max: Maximum number of interrupts supported by controller
* @direct_max: Maximum value of direct maps;
@@ -269,6 +270,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
*/
struct irq_domain_info {
struct fwnode_handle *fwnode;
+ unsigned int domain_flags;
unsigned int size;
irq_hw_number_t hwirq_max;
int direct_max;
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 28a463e25d99..34acc2ccfee7 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -263,6 +263,8 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
if (!domain)
return ERR_PTR(-ENOMEM);
+ domain->flags |= info->domain_flags;
+
__irq_domain_publish(domain);
return domain;
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Handle additional domain flags in irq_domain_instantiate()
2024-06-14 17:32 ` [PATCH 07/23] irqdomain: Handle additional domain flags in irq_domain_instantiate() Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Thomas Gleixner, Herve Codina, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 757398541c30a5e898169763b43f08dab71ea3bd
Gitweb: https://git.kernel.org/tip/757398541c30a5e898169763b43f08dab71ea3bd
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:08 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:13 +02:00
irqdomain: Handle additional domain flags in irq_domain_instantiate()
In order to use irq_domain_instantiate() from several places such as
irq_domain_create_hierarchy(), irq_domain_instantiate() needs to handle
additional domain flags.
Add the required infrastructure.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-8-herve.codina@bootlin.com
---
include/linux/irqdomain.h | 2 ++
kernel/irq/irqdomain.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index a3b43e3..4683b66 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -260,6 +260,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
/**
* struct irq_domain_info - Domain information structure
* @fwnode: firmware node for the interrupt controller
+ * @domain_flags: Additional flags to add to the domain flags
* @size: Size of linear map; 0 for radix mapping only
* @hwirq_max: Maximum number of interrupts supported by controller
* @direct_max: Maximum value of direct maps;
@@ -269,6 +270,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
*/
struct irq_domain_info {
struct fwnode_handle *fwnode;
+ unsigned int domain_flags;
unsigned int size;
irq_hw_number_t hwirq_max;
int direct_max;
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 0eda48f..26ad1ea 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -263,6 +263,8 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
if (!domain)
return ERR_PTR(-ENOMEM);
+ domain->flags |= info->domain_flags;
+
__irq_domain_publish(domain);
return domain;
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 08/23] irqdomain: Handle domain hierarchy parent in irq_domain_instantiate()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (6 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 07/23] irqdomain: Handle additional domain flags in irq_domain_instantiate() Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 09/23] irqdomain: Use irq_domain_instantiate() for hierarchy domain creation Herve Codina
` (15 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
To use irq_domain_instantiate() from irq_domain_create_hierarchy(),
irq_domain_instantiate() needs to handle the domain hierarchy parent.
Handle this parent.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irqdomain.h | 6 ++++++
kernel/irq/irqdomain.c | 7 +++++++
2 files changed, 13 insertions(+)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 4683b66eded9..e52fd5e5494c 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -276,6 +276,12 @@ struct irq_domain_info {
int direct_max;
const struct irq_domain_ops *ops;
void *host_data;
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+ /**
+ * @parent: Pointer to the parent irq domain used in a hierarchy domain
+ */
+ struct irq_domain *parent;
+#endif
};
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 34acc2ccfee7..7e4a1da63549 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -265,6 +265,13 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
domain->flags |= info->domain_flags;
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+ if (info->parent) {
+ domain->root = info->parent->root;
+ domain->parent = info->parent;
+ }
+#endif
+
__irq_domain_publish(domain);
return domain;
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Handle domain hierarchy parent in irq_domain_instantiate()
2024-06-14 17:32 ` [PATCH 08/23] irqdomain: Handle domain hierarchy parent " Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 419e3778ff295c00aa158d9f2854a70b47ba1136
Gitweb: https://git.kernel.org/tip/419e3778ff295c00aa158d9f2854a70b47ba1136
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:09 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:13 +02:00
irqdomain: Handle domain hierarchy parent in irq_domain_instantiate()
To use irq_domain_instantiate() from irq_domain_create_hierarchy(),
irq_domain_instantiate() needs to handle the domain hierarchy parent.
Add the required functionality.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-9-herve.codina@bootlin.com
---
include/linux/irqdomain.h | 6 ++++++
kernel/irq/irqdomain.c | 7 +++++++
2 files changed, 13 insertions(+)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 4683b66..e52fd5e 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -276,6 +276,12 @@ struct irq_domain_info {
int direct_max;
const struct irq_domain_ops *ops;
void *host_data;
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+ /**
+ * @parent: Pointer to the parent irq domain used in a hierarchy domain
+ */
+ struct irq_domain *parent;
+#endif
};
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 26ad1ea..1269a81 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -265,6 +265,13 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
domain->flags |= info->domain_flags;
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+ if (info->parent) {
+ domain->root = info->parent->root;
+ domain->parent = info->parent;
+ }
+#endif
+
__irq_domain_publish(domain);
return domain;
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 09/23] irqdomain: Use irq_domain_instantiate() for hierarchy domain creation
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (7 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 08/23] irqdomain: Handle domain hierarchy parent " Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 10/23] irqdomain: Make __irq_domain_create() return an error code Herve Codina
` (14 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
irq_domain_instantiate() handles all needs to be used in
irq_domain_create_hierarchy()
Avoid code duplication and use directly irq_domain_instantiate() for
hierarchy domain creation.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
kernel/irq/irqdomain.c | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 7e4a1da63549..edfd386be985 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1213,23 +1213,16 @@ struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
.hwirq_max = size,
.ops = ops,
.host_data = host_data,
+ .domain_flags = flags,
+ .parent = parent,
};
- struct irq_domain *domain;
+ struct irq_domain *d;
if (!info.size)
info.hwirq_max = ~0U;
- domain = __irq_domain_create(&info);
- if (domain) {
- if (parent)
- domain->root = parent->root;
- domain->parent = parent;
- domain->flags |= flags;
-
- __irq_domain_publish(domain);
- }
-
- return domain;
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
EXPORT_SYMBOL_GPL(irq_domain_create_hierarchy);
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Use irq_domain_instantiate() for hierarchy domain creation
2024-06-14 17:32 ` [PATCH 09/23] irqdomain: Use irq_domain_instantiate() for hierarchy domain creation Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: b986055dd04141efd6d5dcdacd48d6b38cf320c8
Gitweb: https://git.kernel.org/tip/b986055dd04141efd6d5dcdacd48d6b38cf320c8
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:10 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:13 +02:00
irqdomain: Use irq_domain_instantiate() for hierarchy domain creation
irq_domain_instantiate() handles all needs to be used in
irq_domain_create_hierarchy()
Avoid code duplication and use directly irq_domain_instantiate() for
hierarchy domain creation.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-10-herve.codina@bootlin.com
---
kernel/irq/irqdomain.c | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 1269a81..8dc0007 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1213,23 +1213,16 @@ struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
.hwirq_max = size,
.ops = ops,
.host_data = host_data,
+ .domain_flags = flags,
+ .parent = parent,
};
- struct irq_domain *domain;
+ struct irq_domain *d;
if (!info.size)
info.hwirq_max = ~0U;
- domain = __irq_domain_create(&info);
- if (domain) {
- if (parent)
- domain->root = parent->root;
- domain->parent = parent;
- domain->flags |= flags;
-
- __irq_domain_publish(domain);
- }
-
- return domain;
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
EXPORT_SYMBOL_GPL(irq_domain_create_hierarchy);
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 10/23] irqdomain: Make __irq_domain_create() return an error code
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (8 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 09/23] irqdomain: Use irq_domain_instantiate() for hierarchy domain creation Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 11/23] irqdomain: Handle domain bus token in irq_domain_create() Herve Codina
` (13 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
__irq_domain_create() can fail for several reasons. When it fails it
returns a NULL pointer and so filters out the exact failure reason.
The only user of __irq_domain_create() is irq_domain_instantiate() which
can return a PTR_ERR value. On __irq_domain_create() failure, it uses an
arbitrary error code.
Rather than using this arbitrary error value, make __irq_domain_create()
return is own error code and use that one.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
kernel/irq/irqdomain.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index edfd386be985..5090b1c572c6 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -187,17 +187,17 @@ static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info
if (WARN_ON((info->size && info->direct_max) ||
(!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && info->direct_max) ||
(info->direct_max && info->direct_max != info->hwirq_max)))
- return NULL;
+ return ERR_PTR(-EINVAL);
domain = kzalloc_node(struct_size(domain, revmap, info->size),
GFP_KERNEL, of_node_to_nid(to_of_node(info->fwnode)));
if (!domain)
- return NULL;
+ return ERR_PTR(-ENOMEM);
err = irq_domain_set_name(domain, info->fwnode);
if (err) {
kfree(domain);
- return NULL;
+ return ERR_PTR(err);
}
domain->fwnode = fwnode_handle_get(info->fwnode);
@@ -260,8 +260,8 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
struct irq_domain *domain;
domain = __irq_domain_create(info);
- if (!domain)
- return ERR_PTR(-ENOMEM);
+ if (IS_ERR(domain))
+ return ERR_CAST(domain);
domain->flags |= info->domain_flags;
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Make __irq_domain_create() return an error code
2024-06-14 17:32 ` [PATCH 10/23] irqdomain: Make __irq_domain_create() return an error code Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 80f6abe0d39bc6ccf353290067ff589653ff922c
Gitweb: https://git.kernel.org/tip/80f6abe0d39bc6ccf353290067ff589653ff922c
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:11 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:13 +02:00
irqdomain: Make __irq_domain_create() return an error code
__irq_domain_create() can fail for several reasons. When it fails it
returns a NULL pointer and so filters out the exact failure reason.
The only user of __irq_domain_create() is irq_domain_instantiate() which
can return a PTR_ERR value. On __irq_domain_create() failure, it uses an
arbitrary error code.
Rather than using this arbitrary error value, make __irq_domain_create()
return is own error code and use that one.
[ tglx: Remove the pointless ERR_CAST. domain is a valid return pointer ]
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-11-herve.codina@bootlin.com
---
kernel/irq/irqdomain.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 8dc0007..fe7bba6 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -187,17 +187,17 @@ static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info
if (WARN_ON((info->size && info->direct_max) ||
(!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && info->direct_max) ||
(info->direct_max && info->direct_max != info->hwirq_max)))
- return NULL;
+ return ERR_PTR(-EINVAL);
domain = kzalloc_node(struct_size(domain, revmap, info->size),
GFP_KERNEL, of_node_to_nid(to_of_node(info->fwnode)));
if (!domain)
- return NULL;
+ return ERR_PTR(-ENOMEM);
err = irq_domain_set_name(domain, info->fwnode);
if (err) {
kfree(domain);
- return NULL;
+ return ERR_PTR(err);
}
domain->fwnode = fwnode_handle_get(info->fwnode);
@@ -260,8 +260,8 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
struct irq_domain *domain;
domain = __irq_domain_create(info);
- if (!domain)
- return ERR_PTR(-ENOMEM);
+ if (IS_ERR(domain))
+ return domain;
domain->flags |= info->domain_flags;
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 11/23] irqdomain: Handle domain bus token in irq_domain_create()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (9 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 10/23] irqdomain: Make __irq_domain_create() return an error code Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 12/23] irqdomain: Introduce init() and exit() hooks Herve Codina
` (12 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
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 into account
the domain bus token during the domain creation.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irqdomain.h | 2 ++
kernel/irq/irqdomain.c | 30 ++++++++++++++++++++++++------
2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index e52fd5e5494c..52bed23e5c61 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -265,6 +265,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
* @hwirq_max: Maximum number of interrupts supported by controller
* @direct_max: Maximum value of direct maps;
* Use ~0 for no limit; 0 for no direct mapping
+ * @bus_token: Domain bus token
* @ops: Domain operation callbacks
* @host_data: Controller private data pointer
*/
@@ -274,6 +275,7 @@ struct irq_domain_info {
unsigned int size;
irq_hw_number_t hwirq_max;
int direct_max;
+ enum irq_domain_bus_token bus_token;
const struct irq_domain_ops *ops;
void *host_data;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 5090b1c572c6..d05aeb9c0a67 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -129,7 +129,8 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
static int irq_domain_set_name(struct irq_domain *domain,
- const struct fwnode_handle *fwnode)
+ const struct fwnode_handle *fwnode,
+ enum irq_domain_bus_token bus_token)
{
static atomic_t unknown_domains;
struct irqchip_fwid *fwid;
@@ -140,13 +141,23 @@ static int irq_domain_set_name(struct irq_domain *domain,
switch (fwid->type) {
case IRQCHIP_FWNODE_NAMED:
case IRQCHIP_FWNODE_NAMED_ID:
- domain->name = kstrdup(fwid->name, GFP_KERNEL);
+ domain->name = bus_token ?
+ kasprintf(GFP_KERNEL, "%s-%d",
+ fwid->name, bus_token) :
+ kstrdup(fwid->name, GFP_KERNEL);
if (!domain->name)
return -ENOMEM;
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
break;
default:
domain->name = fwid->name;
+ if (bus_token) {
+ domain->name = kasprintf(GFP_KERNEL, "%s-%d",
+ fwid->name, bus_token);
+ if (!domain->name)
+ return -ENOMEM;
+ domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
+ }
break;
}
} 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,
* unhappy about. Replace them with ':', which does
* the trick and is not as offensive as '\'...
*/
- name = kasprintf(GFP_KERNEL, "%pfw", fwnode);
+ name = bus_token ?
+ kasprintf(GFP_KERNEL, "%pfw-%d", fwnode, bus_token) :
+ kasprintf(GFP_KERNEL, "%pfw", fwnode);
if (!name)
return -ENOMEM;
@@ -169,8 +182,12 @@ static int irq_domain_set_name(struct irq_domain *domain,
if (!domain->name) {
if (fwnode)
pr_err("Invalid fwnode type for irqdomain\n");
- domain->name = kasprintf(GFP_KERNEL, "unknown-%d",
- atomic_inc_return(&unknown_domains));
+ domain->name = bus_token ?
+ kasprintf(GFP_KERNEL, "unknown-%d-%d",
+ atomic_inc_return(&unknown_domains),
+ bus_token) :
+ kasprintf(GFP_KERNEL, "unknown-%d",
+ atomic_inc_return(&unknown_domains));
if (!domain->name)
return -ENOMEM;
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
@@ -194,7 +211,7 @@ static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info
if (!domain)
return ERR_PTR(-ENOMEM);
- err = irq_domain_set_name(domain, info->fwnode);
+ err = irq_domain_set_name(domain, info->fwnode, info->bus_token);
if (err) {
kfree(domain);
return ERR_PTR(err);
@@ -207,6 +224,7 @@ static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info
INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL);
domain->ops = info->ops;
domain->host_data = info->host_data;
+ domain->bus_token = info->bus_token;
domain->hwirq_max = info->hwirq_max;
if (info->direct_max)
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Handle domain bus token in irq_domain_create()
2024-06-14 17:32 ` [PATCH 11/23] irqdomain: Handle domain bus token in irq_domain_create() Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Thomas Gleixner, Herve Codina, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 0b21add71bd9cfa2bd6677a0300e15fd4c4b84ed
Gitweb: https://git.kernel.org/tip/0b21add71bd9cfa2bd6677a0300e15fd4c4b84ed
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:12 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:14 +02:00
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 <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-12-herve.codina@bootlin.com
---
include/linux/irqdomain.h | 2 ++
kernel/irq/irqdomain.c | 30 ++++++++++++++++++++++++------
2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index e52fd5e..52bed23 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -265,6 +265,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
* @hwirq_max: Maximum number of interrupts supported by controller
* @direct_max: Maximum value of direct maps;
* Use ~0 for no limit; 0 for no direct mapping
+ * @bus_token: Domain bus token
* @ops: Domain operation callbacks
* @host_data: Controller private data pointer
*/
@@ -274,6 +275,7 @@ struct irq_domain_info {
unsigned int size;
irq_hw_number_t hwirq_max;
int direct_max;
+ enum irq_domain_bus_token bus_token;
const struct irq_domain_ops *ops;
void *host_data;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index fe7bba6..a21648c 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -129,7 +129,8 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
static int irq_domain_set_name(struct irq_domain *domain,
- const struct fwnode_handle *fwnode)
+ const struct fwnode_handle *fwnode,
+ enum irq_domain_bus_token bus_token)
{
static atomic_t unknown_domains;
struct irqchip_fwid *fwid;
@@ -140,13 +141,23 @@ static int irq_domain_set_name(struct irq_domain *domain,
switch (fwid->type) {
case IRQCHIP_FWNODE_NAMED:
case IRQCHIP_FWNODE_NAMED_ID:
- domain->name = kstrdup(fwid->name, GFP_KERNEL);
+ domain->name = bus_token ?
+ kasprintf(GFP_KERNEL, "%s-%d",
+ fwid->name, bus_token) :
+ kstrdup(fwid->name, GFP_KERNEL);
if (!domain->name)
return -ENOMEM;
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
break;
default:
domain->name = fwid->name;
+ if (bus_token) {
+ domain->name = kasprintf(GFP_KERNEL, "%s-%d",
+ fwid->name, bus_token);
+ if (!domain->name)
+ return -ENOMEM;
+ domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
+ }
break;
}
} 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,
* unhappy about. Replace them with ':', which does
* the trick and is not as offensive as '\'...
*/
- name = kasprintf(GFP_KERNEL, "%pfw", fwnode);
+ name = bus_token ?
+ kasprintf(GFP_KERNEL, "%pfw-%d", fwnode, bus_token) :
+ kasprintf(GFP_KERNEL, "%pfw", fwnode);
if (!name)
return -ENOMEM;
@@ -169,8 +182,12 @@ static int irq_domain_set_name(struct irq_domain *domain,
if (!domain->name) {
if (fwnode)
pr_err("Invalid fwnode type for irqdomain\n");
- domain->name = kasprintf(GFP_KERNEL, "unknown-%d",
- atomic_inc_return(&unknown_domains));
+ domain->name = bus_token ?
+ kasprintf(GFP_KERNEL, "unknown-%d-%d",
+ atomic_inc_return(&unknown_domains),
+ bus_token) :
+ kasprintf(GFP_KERNEL, "unknown-%d",
+ atomic_inc_return(&unknown_domains));
if (!domain->name)
return -ENOMEM;
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
@@ -194,7 +211,7 @@ static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info
if (!domain)
return ERR_PTR(-ENOMEM);
- err = irq_domain_set_name(domain, info->fwnode);
+ err = irq_domain_set_name(domain, info->fwnode, info->bus_token);
if (err) {
kfree(domain);
return ERR_PTR(err);
@@ -207,6 +224,7 @@ static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info
INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL);
domain->ops = info->ops;
domain->host_data = info->host_data;
+ domain->bus_token = info->bus_token;
domain->hwirq_max = info->hwirq_max;
if (info->direct_max)
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 12/23] irqdomain: Introduce init() and exit() hooks
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (10 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 11/23] irqdomain: Handle domain bus token in irq_domain_create() Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 13/23] genirq/generic_chip: Introduce irq_domain_{alloc,remove}_generic_chips() Herve Codina
` (11 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
The current API does not allow additional initialization before the
domain is published. This can lead to a race condition between consumers
and supplier as a domain can be available for consumers before being
fully ready.
Introduce the init() hook to allow additional initialization before
plublishing the domain. Also introduce the exit() hook to revert
operations done in init() on domain removal.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irqdomain.h | 8 ++++++++
kernel/irq/irqdomain.c | 15 +++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 52bed23e5c61..2c927edc4d43 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -141,6 +141,7 @@ struct irq_domain_chip_generic;
* purposes related to the irq domain.
* @parent: Pointer to parent irq_domain to support hierarchy irq_domains
* @msi_parent_ops: Pointer to MSI parent domain methods for per device domain init
+ * @exit: Function called when the domain is destroyed
*
* Revmap data, used internally by the irq domain code:
* @revmap_size: Size of the linear map table @revmap[]
@@ -169,6 +170,7 @@ struct irq_domain {
#ifdef CONFIG_GENERIC_MSI_IRQ
const struct msi_parent_ops *msi_parent_ops;
#endif
+ void (*exit)(struct irq_domain *d);
/* reverse map data. The linear map gets appended to the irq_domain */
irq_hw_number_t hwirq_max;
@@ -268,6 +270,10 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
* @bus_token: Domain bus token
* @ops: Domain operation callbacks
* @host_data: Controller private data pointer
+ * @init: Function called when the domain is created.
+ * Allow to do some additional domain initialisation.
+ * @exit: Function called when the domain is destroyed.
+ * Allow to do some additional cleanup operation.
*/
struct irq_domain_info {
struct fwnode_handle *fwnode;
@@ -284,6 +290,8 @@ struct irq_domain_info {
*/
struct irq_domain *parent;
#endif
+ int (*init)(struct irq_domain *d);
+ void (*exit)(struct irq_domain *d);
};
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index d05aeb9c0a67..9efc9f180308 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -276,12 +276,14 @@ static void irq_domain_free(struct irq_domain *domain)
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
{
struct irq_domain *domain;
+ int err;
domain = __irq_domain_create(info);
if (IS_ERR(domain))
return ERR_CAST(domain);
domain->flags |= info->domain_flags;
+ domain->exit = info->exit;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
if (info->parent) {
@@ -290,9 +292,19 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
}
#endif
+ if (info->init) {
+ err = info->init(domain);
+ if (err)
+ goto err_domain_free;
+ }
+
__irq_domain_publish(domain);
return domain;
+
+err_domain_free:
+ irq_domain_free(domain);
+ return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(irq_domain_instantiate);
@@ -339,6 +351,9 @@ EXPORT_SYMBOL_GPL(__irq_domain_add);
*/
void irq_domain_remove(struct irq_domain *domain)
{
+ if (domain->exit)
+ domain->exit(domain);
+
mutex_lock(&irq_domain_mutex);
debugfs_remove_domain_dir(domain);
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Introduce init() and exit() hooks
2024-06-14 17:32 ` [PATCH 12/23] irqdomain: Introduce init() and exit() hooks Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Thomas Gleixner, Herve Codina, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 44b68de9b8e3dfde12308e8567548799d7ded0de
Gitweb: https://git.kernel.org/tip/44b68de9b8e3dfde12308e8567548799d7ded0de
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:13 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:14 +02:00
irqdomain: Introduce init() and exit() hooks
The current API does not allow additional initialization before the
domain is published. This can lead to a race condition between consumers
and supplier as a domain can be available for consumers before being
fully ready.
Introduce the init() hook to allow additional initialization before
plublishing the domain. Also introduce the exit() hook to revert
operations done in init() on domain removal.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-13-herve.codina@bootlin.com
---
include/linux/irqdomain.h | 8 ++++++++
kernel/irq/irqdomain.c | 15 +++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 52bed23..2c927ed 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -141,6 +141,7 @@ struct irq_domain_chip_generic;
* purposes related to the irq domain.
* @parent: Pointer to parent irq_domain to support hierarchy irq_domains
* @msi_parent_ops: Pointer to MSI parent domain methods for per device domain init
+ * @exit: Function called when the domain is destroyed
*
* Revmap data, used internally by the irq domain code:
* @revmap_size: Size of the linear map table @revmap[]
@@ -169,6 +170,7 @@ struct irq_domain {
#ifdef CONFIG_GENERIC_MSI_IRQ
const struct msi_parent_ops *msi_parent_ops;
#endif
+ void (*exit)(struct irq_domain *d);
/* reverse map data. The linear map gets appended to the irq_domain */
irq_hw_number_t hwirq_max;
@@ -268,6 +270,10 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
* @bus_token: Domain bus token
* @ops: Domain operation callbacks
* @host_data: Controller private data pointer
+ * @init: Function called when the domain is created.
+ * Allow to do some additional domain initialisation.
+ * @exit: Function called when the domain is destroyed.
+ * Allow to do some additional cleanup operation.
*/
struct irq_domain_info {
struct fwnode_handle *fwnode;
@@ -284,6 +290,8 @@ struct irq_domain_info {
*/
struct irq_domain *parent;
#endif
+ int (*init)(struct irq_domain *d);
+ void (*exit)(struct irq_domain *d);
};
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index a21648c..a0324d8 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -276,12 +276,14 @@ static void irq_domain_free(struct irq_domain *domain)
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
{
struct irq_domain *domain;
+ int err;
domain = __irq_domain_create(info);
if (IS_ERR(domain))
return domain;
domain->flags |= info->domain_flags;
+ domain->exit = info->exit;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
if (info->parent) {
@@ -290,9 +292,19 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
}
#endif
+ if (info->init) {
+ err = info->init(domain);
+ if (err)
+ goto err_domain_free;
+ }
+
__irq_domain_publish(domain);
return domain;
+
+err_domain_free:
+ irq_domain_free(domain);
+ return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(irq_domain_instantiate);
@@ -339,6 +351,9 @@ EXPORT_SYMBOL_GPL(__irq_domain_add);
*/
void irq_domain_remove(struct irq_domain *domain)
{
+ if (domain->exit)
+ domain->exit(domain);
+
mutex_lock(&irq_domain_mutex);
debugfs_remove_domain_dir(domain);
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 13/23] genirq/generic_chip: Introduce irq_domain_{alloc,remove}_generic_chips()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (11 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 12/23] irqdomain: Introduce init() and exit() hooks Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 14/23] genirq/generic_chip: Introduce init() and exit() hooks Herve Codina
` (10 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
The existing __irq_alloc_domain_generic_chips() use a bunch of
parameters to describe the generic chips that need to be allocated.
Adding more parameters and wrappers to hide new parameters in the
existing code lead to more and more code without any relevant values and
without any flexibility.
Introduce irq_domain_alloc_generic_chips() where the generic chips
description is done using the irq_domain_chip_generic_info structure
instead of the bunch of parameters to allow flexibility and easy
evolution.
Also introduce irq_domain_remove_generic_chips() to revert the
operations done by irq_domain_alloc_generic_chips().
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irq.h | 25 +++++++++++
kernel/irq/generic-chip.c | 91 +++++++++++++++++++++++++++++----------
2 files changed, 93 insertions(+), 23 deletions(-)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index a217e1029c1d..58264b236cbf 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -1117,6 +1117,27 @@ struct irq_domain_chip_generic {
struct irq_chip_generic *gc[];
};
+/**
+ * struct irq_domain_chip_generic_info - Generic chip information structure
+ * @name: Name of the generic interrupt chip
+ * @handler: Interrupt handler used by the generic interrupt chip
+ * @irqs_per_chip: Number of interrupts each chip handles (max 32)
+ * @num_ct: Number of irq_chip_type instances associated with each
+ * chip
+ * @irq_flags_to_clear: IRQ_* bits to clear in the mapping function
+ * @irq_flags_to_set: IRQ_* bits to set in the mapping function
+ * @gc_flags: Generic chip specific setup flags
+ */
+struct irq_domain_chip_generic_info {
+ const char *name;
+ irq_flow_handler_t handler;
+ unsigned int irqs_per_chip;
+ unsigned int num_ct;
+ unsigned int irq_flags_to_clear;
+ unsigned int irq_flags_to_set;
+ enum irq_gc_flags gc_flags;
+};
+
/* Generic chip callback functions */
void irq_gc_noop(struct irq_data *d);
void irq_gc_mask_disable_reg(struct irq_data *d);
@@ -1153,6 +1174,10 @@ int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc,
struct irq_chip_generic *irq_get_domain_generic_chip(struct irq_domain *d, unsigned int hw_irq);
+int irq_domain_alloc_generic_chips(struct irq_domain *d,
+ const struct irq_domain_chip_generic_info *info);
+void irq_domain_remove_generic_chips(struct irq_domain *d);
+
int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
int num_ct, const char *name,
irq_flow_handler_t handler,
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c
index d39a40bc542b..d9696f5dcc38 100644
--- a/kernel/irq/generic-chip.c
+++ b/kernel/irq/generic-chip.c
@@ -276,21 +276,14 @@ irq_gc_init_mask_cache(struct irq_chip_generic *gc, enum irq_gc_flags flags)
}
/**
- * __irq_alloc_domain_generic_chips - Allocate generic chips for an irq domain
- * @d: irq domain for which to allocate chips
- * @irqs_per_chip: Number of interrupts each chip handles (max 32)
- * @num_ct: Number of irq_chip_type instances associated with this
- * @name: Name of the irq chip
- * @handler: Default flow handler associated with these chips
- * @clr: IRQ_* bits to clear in the mapping function
- * @set: IRQ_* bits to set in the mapping function
- * @gcflags: Generic chip specific setup flags
+ * irq_domain_alloc_generic_chips - Allocate generic chips for an irq domain
+ * @d: irq domain for which to allocate chips
+ * @info: Generic chip information
+ *
+ * Return: 0 on success, negative error code on failure
*/
-int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
- int num_ct, const char *name,
- irq_flow_handler_t handler,
- unsigned int clr, unsigned int set,
- enum irq_gc_flags gcflags)
+int irq_domain_alloc_generic_chips(struct irq_domain *d,
+ const struct irq_domain_chip_generic_info *info)
{
struct irq_domain_chip_generic *dgc;
struct irq_chip_generic *gc;
@@ -304,23 +297,23 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
if (d->gc)
return -EBUSY;
- numchips = DIV_ROUND_UP(d->revmap_size, irqs_per_chip);
+ numchips = DIV_ROUND_UP(d->revmap_size, info->irqs_per_chip);
if (!numchips)
return -EINVAL;
/* Allocate a pointer, generic chip and chiptypes for each chip */
- gc_sz = struct_size(gc, chip_types, num_ct);
+ gc_sz = struct_size(gc, chip_types, info->num_ct);
dgc_sz = struct_size(dgc, gc, numchips);
sz = dgc_sz + numchips * gc_sz;
tmp = dgc = kzalloc(sz, GFP_KERNEL);
if (!dgc)
return -ENOMEM;
- dgc->irqs_per_chip = irqs_per_chip;
+ dgc->irqs_per_chip = info->irqs_per_chip;
dgc->num_chips = numchips;
- dgc->irq_flags_to_set = set;
- dgc->irq_flags_to_clear = clr;
- dgc->gc_flags = gcflags;
+ dgc->irq_flags_to_set = info->irq_flags_to_set;
+ dgc->irq_flags_to_clear = info->irq_flags_to_clear;
+ dgc->gc_flags = info->gc_flags;
d->gc = dgc;
/* Calc pointer to the first generic chip */
@@ -328,11 +321,12 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
for (i = 0; i < numchips; i++) {
/* Store the pointer to the generic chip */
dgc->gc[i] = gc = tmp;
- irq_init_generic_chip(gc, name, num_ct, i * irqs_per_chip,
- NULL, handler);
+ irq_init_generic_chip(gc, info->name, info->num_ct,
+ i * dgc->irqs_per_chip, NULL,
+ info->handler);
gc->domain = d;
- if (gcflags & IRQ_GC_BE_IO) {
+ if (dgc->gc_flags & IRQ_GC_BE_IO) {
gc->reg_readl = &irq_readl_be;
gc->reg_writel = &irq_writel_be;
}
@@ -345,6 +339,57 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
}
return 0;
}
+EXPORT_SYMBOL_GPL(irq_domain_alloc_generic_chips);
+
+/**
+ * irq_domain_remove_generic_chips - Remove generic chips from an irq domain
+ * @d: irq domain for which generic chips are to be removed
+ */
+void irq_domain_remove_generic_chips(struct irq_domain *d)
+{
+ struct irq_domain_chip_generic *dgc = d->gc;
+ unsigned int i;
+
+ if (!dgc)
+ return;
+
+ for (i = 0; i < dgc->num_chips; i++)
+ irq_remove_generic_chip(dgc->gc[i], ~0U, 0, 0);
+
+ d->gc = NULL;
+ kfree(dgc);
+}
+EXPORT_SYMBOL_GPL(irq_domain_remove_generic_chips);
+
+/**
+ * __irq_alloc_domain_generic_chips - Allocate generic chips for an irq domain
+ * @d: irq domain for which to allocate chips
+ * @irqs_per_chip: Number of interrupts each chip handles (max 32)
+ * @num_ct: Number of irq_chip_type instances associated with this
+ * @name: Name of the irq chip
+ * @handler: Default flow handler associated with these chips
+ * @clr: IRQ_* bits to clear in the mapping function
+ * @set: IRQ_* bits to set in the mapping function
+ * @gcflags: Generic chip specific setup flags
+ */
+int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
+ int num_ct, const char *name,
+ irq_flow_handler_t handler,
+ unsigned int clr, unsigned int set,
+ enum irq_gc_flags gcflags)
+{
+ struct irq_domain_chip_generic_info info = {
+ .irqs_per_chip = irqs_per_chip,
+ .num_ct = num_ct,
+ .name = name,
+ .handler = handler,
+ .irq_flags_to_clear = clr,
+ .irq_flags_to_set = set,
+ .gc_flags = gcflags,
+ };
+
+ return irq_domain_alloc_generic_chips(d, &info);
+}
EXPORT_SYMBOL_GPL(__irq_alloc_domain_generic_chips);
static struct irq_chip_generic *
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] genirq/generic_chip: Introduce irq_domain_{alloc,remove}_generic_chips()
2024-06-14 17:32 ` [PATCH 13/23] genirq/generic_chip: Introduce irq_domain_{alloc,remove}_generic_chips() Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Thomas Gleixner, Herve Codina, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: e25f553a92973eaf59ff3a00fe7f61ab01b2877f
Gitweb: https://git.kernel.org/tip/e25f553a92973eaf59ff3a00fe7f61ab01b2877f
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:14 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:14 +02:00
genirq/generic_chip: Introduce irq_domain_{alloc,remove}_generic_chips()
The existing __irq_alloc_domain_generic_chips() uses a bunch of parameters
to describe the generic chips that need to be allocated.
Adding more parameters and wrappers to hide new parameters in the existing
code leads to more and more code without any relevant values and without
any flexibility.
Introduce irq_domain_alloc_generic_chips() where the generic chips
description is done using the irq_domain_chip_generic_info structure
instead of the bunch of parameters to allow flexibility and easy evolution.
Also introduce irq_domain_remove_generic_chips() to revert the operations
done by irq_domain_alloc_generic_chips().
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-14-herve.codina@bootlin.com
---
include/linux/irq.h | 25 ++++++++++-
kernel/irq/generic-chip.c | 91 ++++++++++++++++++++++++++++----------
2 files changed, 93 insertions(+), 23 deletions(-)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index a217e10..58264b2 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -1117,6 +1117,27 @@ struct irq_domain_chip_generic {
struct irq_chip_generic *gc[];
};
+/**
+ * struct irq_domain_chip_generic_info - Generic chip information structure
+ * @name: Name of the generic interrupt chip
+ * @handler: Interrupt handler used by the generic interrupt chip
+ * @irqs_per_chip: Number of interrupts each chip handles (max 32)
+ * @num_ct: Number of irq_chip_type instances associated with each
+ * chip
+ * @irq_flags_to_clear: IRQ_* bits to clear in the mapping function
+ * @irq_flags_to_set: IRQ_* bits to set in the mapping function
+ * @gc_flags: Generic chip specific setup flags
+ */
+struct irq_domain_chip_generic_info {
+ const char *name;
+ irq_flow_handler_t handler;
+ unsigned int irqs_per_chip;
+ unsigned int num_ct;
+ unsigned int irq_flags_to_clear;
+ unsigned int irq_flags_to_set;
+ enum irq_gc_flags gc_flags;
+};
+
/* Generic chip callback functions */
void irq_gc_noop(struct irq_data *d);
void irq_gc_mask_disable_reg(struct irq_data *d);
@@ -1153,6 +1174,10 @@ int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc,
struct irq_chip_generic *irq_get_domain_generic_chip(struct irq_domain *d, unsigned int hw_irq);
+int irq_domain_alloc_generic_chips(struct irq_domain *d,
+ const struct irq_domain_chip_generic_info *info);
+void irq_domain_remove_generic_chips(struct irq_domain *d);
+
int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
int num_ct, const char *name,
irq_flow_handler_t handler,
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c
index d39a40b..d9696f5 100644
--- a/kernel/irq/generic-chip.c
+++ b/kernel/irq/generic-chip.c
@@ -276,21 +276,14 @@ irq_gc_init_mask_cache(struct irq_chip_generic *gc, enum irq_gc_flags flags)
}
/**
- * __irq_alloc_domain_generic_chips - Allocate generic chips for an irq domain
- * @d: irq domain for which to allocate chips
- * @irqs_per_chip: Number of interrupts each chip handles (max 32)
- * @num_ct: Number of irq_chip_type instances associated with this
- * @name: Name of the irq chip
- * @handler: Default flow handler associated with these chips
- * @clr: IRQ_* bits to clear in the mapping function
- * @set: IRQ_* bits to set in the mapping function
- * @gcflags: Generic chip specific setup flags
+ * irq_domain_alloc_generic_chips - Allocate generic chips for an irq domain
+ * @d: irq domain for which to allocate chips
+ * @info: Generic chip information
+ *
+ * Return: 0 on success, negative error code on failure
*/
-int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
- int num_ct, const char *name,
- irq_flow_handler_t handler,
- unsigned int clr, unsigned int set,
- enum irq_gc_flags gcflags)
+int irq_domain_alloc_generic_chips(struct irq_domain *d,
+ const struct irq_domain_chip_generic_info *info)
{
struct irq_domain_chip_generic *dgc;
struct irq_chip_generic *gc;
@@ -304,23 +297,23 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
if (d->gc)
return -EBUSY;
- numchips = DIV_ROUND_UP(d->revmap_size, irqs_per_chip);
+ numchips = DIV_ROUND_UP(d->revmap_size, info->irqs_per_chip);
if (!numchips)
return -EINVAL;
/* Allocate a pointer, generic chip and chiptypes for each chip */
- gc_sz = struct_size(gc, chip_types, num_ct);
+ gc_sz = struct_size(gc, chip_types, info->num_ct);
dgc_sz = struct_size(dgc, gc, numchips);
sz = dgc_sz + numchips * gc_sz;
tmp = dgc = kzalloc(sz, GFP_KERNEL);
if (!dgc)
return -ENOMEM;
- dgc->irqs_per_chip = irqs_per_chip;
+ dgc->irqs_per_chip = info->irqs_per_chip;
dgc->num_chips = numchips;
- dgc->irq_flags_to_set = set;
- dgc->irq_flags_to_clear = clr;
- dgc->gc_flags = gcflags;
+ dgc->irq_flags_to_set = info->irq_flags_to_set;
+ dgc->irq_flags_to_clear = info->irq_flags_to_clear;
+ dgc->gc_flags = info->gc_flags;
d->gc = dgc;
/* Calc pointer to the first generic chip */
@@ -328,11 +321,12 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
for (i = 0; i < numchips; i++) {
/* Store the pointer to the generic chip */
dgc->gc[i] = gc = tmp;
- irq_init_generic_chip(gc, name, num_ct, i * irqs_per_chip,
- NULL, handler);
+ irq_init_generic_chip(gc, info->name, info->num_ct,
+ i * dgc->irqs_per_chip, NULL,
+ info->handler);
gc->domain = d;
- if (gcflags & IRQ_GC_BE_IO) {
+ if (dgc->gc_flags & IRQ_GC_BE_IO) {
gc->reg_readl = &irq_readl_be;
gc->reg_writel = &irq_writel_be;
}
@@ -345,6 +339,57 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
}
return 0;
}
+EXPORT_SYMBOL_GPL(irq_domain_alloc_generic_chips);
+
+/**
+ * irq_domain_remove_generic_chips - Remove generic chips from an irq domain
+ * @d: irq domain for which generic chips are to be removed
+ */
+void irq_domain_remove_generic_chips(struct irq_domain *d)
+{
+ struct irq_domain_chip_generic *dgc = d->gc;
+ unsigned int i;
+
+ if (!dgc)
+ return;
+
+ for (i = 0; i < dgc->num_chips; i++)
+ irq_remove_generic_chip(dgc->gc[i], ~0U, 0, 0);
+
+ d->gc = NULL;
+ kfree(dgc);
+}
+EXPORT_SYMBOL_GPL(irq_domain_remove_generic_chips);
+
+/**
+ * __irq_alloc_domain_generic_chips - Allocate generic chips for an irq domain
+ * @d: irq domain for which to allocate chips
+ * @irqs_per_chip: Number of interrupts each chip handles (max 32)
+ * @num_ct: Number of irq_chip_type instances associated with this
+ * @name: Name of the irq chip
+ * @handler: Default flow handler associated with these chips
+ * @clr: IRQ_* bits to clear in the mapping function
+ * @set: IRQ_* bits to set in the mapping function
+ * @gcflags: Generic chip specific setup flags
+ */
+int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
+ int num_ct, const char *name,
+ irq_flow_handler_t handler,
+ unsigned int clr, unsigned int set,
+ enum irq_gc_flags gcflags)
+{
+ struct irq_domain_chip_generic_info info = {
+ .irqs_per_chip = irqs_per_chip,
+ .num_ct = num_ct,
+ .name = name,
+ .handler = handler,
+ .irq_flags_to_clear = clr,
+ .irq_flags_to_set = set,
+ .gc_flags = gcflags,
+ };
+
+ return irq_domain_alloc_generic_chips(d, &info);
+}
EXPORT_SYMBOL_GPL(__irq_alloc_domain_generic_chips);
static struct irq_chip_generic *
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 14/23] genirq/generic_chip: Introduce init() and exit() hooks
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (12 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 13/23] genirq/generic_chip: Introduce irq_domain_{alloc,remove}_generic_chips() Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 15/23] irqdomain: Add support for generic irq chips creation before publishing a domain Herve Codina
` (9 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
Most of generic chip drivers need to perform some more additional
initializations on the generic chips allocated before they can be fully
ready.
These additional initializations need to be performed before the IRQ
domain is published to avoid a race condition between IRQ consumers and
suppliers.
Introduce the init() hook to perform these initializations at the right
place just after the generic chip creation. Also introduce the exit()
hook to allow reververting operations done by the init() hook just
before the generic chip is destroyed.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irq.h | 8 ++++++++
kernel/irq/generic-chip.c | 24 ++++++++++++++++++++++--
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 58264b236cbf..712bcee56efc 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -1106,6 +1106,7 @@ enum irq_gc_flags {
* @irq_flags_to_set: IRQ* flags to set on irq setup
* @irq_flags_to_clear: IRQ* flags to clear on irq setup
* @gc_flags: Generic chip specific setup flags
+ * @exit: Function called on each chip when they are destroyed.
* @gc: Array of pointers to generic interrupt chips
*/
struct irq_domain_chip_generic {
@@ -1114,6 +1115,7 @@ struct irq_domain_chip_generic {
unsigned int irq_flags_to_clear;
unsigned int irq_flags_to_set;
enum irq_gc_flags gc_flags;
+ void (*exit)(struct irq_chip_generic *gc);
struct irq_chip_generic *gc[];
};
@@ -1127,6 +1129,10 @@ struct irq_domain_chip_generic {
* @irq_flags_to_clear: IRQ_* bits to clear in the mapping function
* @irq_flags_to_set: IRQ_* bits to set in the mapping function
* @gc_flags: Generic chip specific setup flags
+ * @init: Function called on each chip when they are created.
+ * Allow to do some additional chip initialisation.
+ * @exit: Function called on each chip when they are destroyed.
+ * Allow to do some chip cleanup operation.
*/
struct irq_domain_chip_generic_info {
const char *name;
@@ -1136,6 +1142,8 @@ struct irq_domain_chip_generic_info {
unsigned int irq_flags_to_clear;
unsigned int irq_flags_to_set;
enum irq_gc_flags gc_flags;
+ int (*init)(struct irq_chip_generic *gc);
+ void (*exit)(struct irq_chip_generic *gc);
};
/* Generic chip callback functions */
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c
index d9696f5dcc38..32ffcbb87fa1 100644
--- a/kernel/irq/generic-chip.c
+++ b/kernel/irq/generic-chip.c
@@ -293,6 +293,7 @@ int irq_domain_alloc_generic_chips(struct irq_domain *d,
size_t gc_sz;
size_t sz;
void *tmp;
+ int ret;
if (d->gc)
return -EBUSY;
@@ -314,6 +315,7 @@ int irq_domain_alloc_generic_chips(struct irq_domain *d,
dgc->irq_flags_to_set = info->irq_flags_to_set;
dgc->irq_flags_to_clear = info->irq_flags_to_clear;
dgc->gc_flags = info->gc_flags;
+ dgc->exit = info->exit;
d->gc = dgc;
/* Calc pointer to the first generic chip */
@@ -331,6 +333,12 @@ int irq_domain_alloc_generic_chips(struct irq_domain *d,
gc->reg_writel = &irq_writel_be;
}
+ if (info->init) {
+ ret = info->init(gc);
+ if (ret)
+ goto err;
+ }
+
raw_spin_lock_irqsave(&gc_lock, flags);
list_add_tail(&gc->list, &gc_list);
raw_spin_unlock_irqrestore(&gc_lock, flags);
@@ -338,6 +346,16 @@ int irq_domain_alloc_generic_chips(struct irq_domain *d,
tmp += gc_sz;
}
return 0;
+
+err:
+ while (i--) {
+ if (dgc->exit)
+ dgc->exit(dgc->gc[i]);
+ irq_remove_generic_chip(dgc->gc[i], ~0U, 0, 0);
+ }
+ d->gc = NULL;
+ kfree(dgc);
+ return ret;
}
EXPORT_SYMBOL_GPL(irq_domain_alloc_generic_chips);
@@ -353,9 +371,11 @@ void irq_domain_remove_generic_chips(struct irq_domain *d)
if (!dgc)
return;
- for (i = 0; i < dgc->num_chips; i++)
+ for (i = 0; i < dgc->num_chips; i++) {
+ if (dgc->exit)
+ dgc->exit(dgc->gc[i]);
irq_remove_generic_chip(dgc->gc[i], ~0U, 0, 0);
-
+ }
d->gc = NULL;
kfree(dgc);
}
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] genirq/generic_chip: Introduce init() and exit() hooks
2024-06-14 17:32 ` [PATCH 14/23] genirq/generic_chip: Introduce init() and exit() hooks Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Thomas Gleixner, Herve Codina, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: fea922ee9f8ffd3c2a8e8dfbc68de42905a3982a
Gitweb: https://git.kernel.org/tip/fea922ee9f8ffd3c2a8e8dfbc68de42905a3982a
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:15 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:14 +02:00
genirq/generic_chip: Introduce init() and exit() hooks
Most of generic chip drivers need to perform some more additional
initializations on the generic chips allocated before they can be fully
ready.
These additional initializations need to be performed before the IRQ
domain is published to avoid a race condition between IRQ consumers and
suppliers.
Introduce the init() hook to perform these initializations at the right
place just after the generic chip creation. Also introduce the exit() hook
to allow reverting operations done by the init() hook just before the
generic chip is destroyed.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-15-herve.codina@bootlin.com
---
include/linux/irq.h | 8 ++++++++
kernel/irq/generic-chip.c | 24 ++++++++++++++++++++++--
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 58264b2..712bcee 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -1106,6 +1106,7 @@ enum irq_gc_flags {
* @irq_flags_to_set: IRQ* flags to set on irq setup
* @irq_flags_to_clear: IRQ* flags to clear on irq setup
* @gc_flags: Generic chip specific setup flags
+ * @exit: Function called on each chip when they are destroyed.
* @gc: Array of pointers to generic interrupt chips
*/
struct irq_domain_chip_generic {
@@ -1114,6 +1115,7 @@ struct irq_domain_chip_generic {
unsigned int irq_flags_to_clear;
unsigned int irq_flags_to_set;
enum irq_gc_flags gc_flags;
+ void (*exit)(struct irq_chip_generic *gc);
struct irq_chip_generic *gc[];
};
@@ -1127,6 +1129,10 @@ struct irq_domain_chip_generic {
* @irq_flags_to_clear: IRQ_* bits to clear in the mapping function
* @irq_flags_to_set: IRQ_* bits to set in the mapping function
* @gc_flags: Generic chip specific setup flags
+ * @init: Function called on each chip when they are created.
+ * Allow to do some additional chip initialisation.
+ * @exit: Function called on each chip when they are destroyed.
+ * Allow to do some chip cleanup operation.
*/
struct irq_domain_chip_generic_info {
const char *name;
@@ -1136,6 +1142,8 @@ struct irq_domain_chip_generic_info {
unsigned int irq_flags_to_clear;
unsigned int irq_flags_to_set;
enum irq_gc_flags gc_flags;
+ int (*init)(struct irq_chip_generic *gc);
+ void (*exit)(struct irq_chip_generic *gc);
};
/* Generic chip callback functions */
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c
index d9696f5..32ffcbb 100644
--- a/kernel/irq/generic-chip.c
+++ b/kernel/irq/generic-chip.c
@@ -293,6 +293,7 @@ int irq_domain_alloc_generic_chips(struct irq_domain *d,
size_t gc_sz;
size_t sz;
void *tmp;
+ int ret;
if (d->gc)
return -EBUSY;
@@ -314,6 +315,7 @@ int irq_domain_alloc_generic_chips(struct irq_domain *d,
dgc->irq_flags_to_set = info->irq_flags_to_set;
dgc->irq_flags_to_clear = info->irq_flags_to_clear;
dgc->gc_flags = info->gc_flags;
+ dgc->exit = info->exit;
d->gc = dgc;
/* Calc pointer to the first generic chip */
@@ -331,6 +333,12 @@ int irq_domain_alloc_generic_chips(struct irq_domain *d,
gc->reg_writel = &irq_writel_be;
}
+ if (info->init) {
+ ret = info->init(gc);
+ if (ret)
+ goto err;
+ }
+
raw_spin_lock_irqsave(&gc_lock, flags);
list_add_tail(&gc->list, &gc_list);
raw_spin_unlock_irqrestore(&gc_lock, flags);
@@ -338,6 +346,16 @@ int irq_domain_alloc_generic_chips(struct irq_domain *d,
tmp += gc_sz;
}
return 0;
+
+err:
+ while (i--) {
+ if (dgc->exit)
+ dgc->exit(dgc->gc[i]);
+ irq_remove_generic_chip(dgc->gc[i], ~0U, 0, 0);
+ }
+ d->gc = NULL;
+ kfree(dgc);
+ return ret;
}
EXPORT_SYMBOL_GPL(irq_domain_alloc_generic_chips);
@@ -353,9 +371,11 @@ void irq_domain_remove_generic_chips(struct irq_domain *d)
if (!dgc)
return;
- for (i = 0; i < dgc->num_chips; i++)
+ for (i = 0; i < dgc->num_chips; i++) {
+ if (dgc->exit)
+ dgc->exit(dgc->gc[i]);
irq_remove_generic_chip(dgc->gc[i], ~0U, 0, 0);
-
+ }
d->gc = NULL;
kfree(dgc);
}
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 15/23] irqdomain: Add support for generic irq chips creation before publishing a domain
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (13 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 14/23] genirq/generic_chip: Introduce init() and exit() hooks Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 16/23] irqdomain: Add a resource managed version of irq_domain_instantiate() Herve Codina
` (8 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
The current API functions create an irq_domain and also publish this
newly created to domain. Once an irq_domain is published, consumers can
request IRQ in order to use them.
Some interrupt controller drivers have to perform some more operations
with the created irq_domain in order to have it ready to be used.
For instance:
- Allocate generic irq chips with irq_alloc_domain_generic_chips()
- Retrieve the generic irq chips with irq_get_domain_generic_chip()
- Initialize retrieved chips: set register base address and offsets,
set several hooks such as irq_mask, irq_unmask, ...
With the newly introduced irq_domain_alloc_generic_chips(), an interrupt
controller driver can use the irq_domain_chip_generic_info structure and
set the init() hook to perform its generic chips initialization.
In order to avoid a window where the domain is published but not yet
ready to be used, handle the generic chip creation (i.e the
irq_domain_alloc_generic_chips() call) before the domain is published.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irqdomain.h | 9 +++++++++
kernel/irq/irqdomain.c | 14 +++++++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 2c927edc4d43..5540b22a755c 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -210,6 +210,9 @@ enum {
/* Irq domain is a MSI device domain */
IRQ_DOMAIN_FLAG_MSI_DEVICE = (1 << 9),
+ /* Irq domain must destroy generic chips when removed */
+ IRQ_DOMAIN_FLAG_DESTROY_GC = (1 << 10),
+
/*
* Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
* for implementation specific purposes and ignored by the
@@ -259,6 +262,9 @@ static inline struct fwnode_handle *irq_domain_alloc_fwnode(phys_addr_t *pa)
}
void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
+
+struct irq_domain_chip_generic_info;
+
/**
* struct irq_domain_info - Domain information structure
* @fwnode: firmware node for the interrupt controller
@@ -270,6 +276,8 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
* @bus_token: Domain bus token
* @ops: Domain operation callbacks
* @host_data: Controller private data pointer
+ * @dgc_info: Geneneric chip information structure pointer used to
+ * create generic chips for the domain if not NULL.
* @init: Function called when the domain is created.
* Allow to do some additional domain initialisation.
* @exit: Function called when the domain is destroyed.
@@ -290,6 +298,7 @@ struct irq_domain_info {
*/
struct irq_domain *parent;
#endif
+ struct irq_domain_chip_generic_info *dgc_info;
int (*init)(struct irq_domain *d);
void (*exit)(struct irq_domain *d);
};
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 9efc9f180308..d95ca575a108 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -292,16 +292,25 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
}
#endif
+ if (info->dgc_info) {
+ err = irq_domain_alloc_generic_chips(domain, info->dgc_info);
+ if (err)
+ goto err_domain_free;
+ }
+
if (info->init) {
err = info->init(domain);
if (err)
- goto err_domain_free;
+ goto err_domain_gc_remove;
}
__irq_domain_publish(domain);
return domain;
+err_domain_gc_remove:
+ if (info->dgc_info)
+ irq_domain_remove_generic_chips(domain);
err_domain_free:
irq_domain_free(domain);
return ERR_PTR(err);
@@ -369,6 +378,9 @@ void irq_domain_remove(struct irq_domain *domain)
mutex_unlock(&irq_domain_mutex);
+ if (domain->flags & IRQ_DOMAIN_FLAG_DESTROY_GC)
+ irq_domain_remove_generic_chips(domain);
+
pr_debug("Removed domain %s\n", domain->name);
irq_domain_free(domain);
}
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Add support for generic irq chips creation before publishing a domain
2024-06-14 17:32 ` [PATCH 15/23] irqdomain: Add support for generic irq chips creation before publishing a domain Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Thomas Gleixner, Herve Codina, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: e6f67ce32e8e6dcbadf42dc435fbc9002cabf1f9
Gitweb: https://git.kernel.org/tip/e6f67ce32e8e6dcbadf42dc435fbc9002cabf1f9
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:16 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:14 +02:00
irqdomain: Add support for generic irq chips creation before publishing a domain
The current API functions create an irq_domain and also publish this
newly created to domain. Once an irq_domain is published, consumers can
request IRQ in order to use them.
Some interrupt controller drivers have to perform some more operations
with the created irq_domain in order to have it ready to be used.
For instance:
- Allocate generic irq chips with irq_alloc_domain_generic_chips()
- Retrieve the generic irq chips with irq_get_domain_generic_chip()
- Initialize retrieved chips: set register base address and offsets,
set several hooks such as irq_mask, irq_unmask, ...
With the newly introduced irq_domain_alloc_generic_chips(), an interrupt
controller driver can use the irq_domain_chip_generic_info structure and
set the init() hook to perform its generic chips initialization.
In order to avoid a window where the domain is published but not yet
ready to be used, handle the generic chip creation (i.e the
irq_domain_alloc_generic_chips() call) before the domain is published.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-16-herve.codina@bootlin.com
---
include/linux/irqdomain.h | 9 +++++++++
kernel/irq/irqdomain.c | 14 +++++++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 2c927ed..5540b22 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -210,6 +210,9 @@ enum {
/* Irq domain is a MSI device domain */
IRQ_DOMAIN_FLAG_MSI_DEVICE = (1 << 9),
+ /* Irq domain must destroy generic chips when removed */
+ IRQ_DOMAIN_FLAG_DESTROY_GC = (1 << 10),
+
/*
* Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
* for implementation specific purposes and ignored by the
@@ -259,6 +262,9 @@ static inline struct fwnode_handle *irq_domain_alloc_fwnode(phys_addr_t *pa)
}
void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
+
+struct irq_domain_chip_generic_info;
+
/**
* struct irq_domain_info - Domain information structure
* @fwnode: firmware node for the interrupt controller
@@ -270,6 +276,8 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
* @bus_token: Domain bus token
* @ops: Domain operation callbacks
* @host_data: Controller private data pointer
+ * @dgc_info: Geneneric chip information structure pointer used to
+ * create generic chips for the domain if not NULL.
* @init: Function called when the domain is created.
* Allow to do some additional domain initialisation.
* @exit: Function called when the domain is destroyed.
@@ -290,6 +298,7 @@ struct irq_domain_info {
*/
struct irq_domain *parent;
#endif
+ struct irq_domain_chip_generic_info *dgc_info;
int (*init)(struct irq_domain *d);
void (*exit)(struct irq_domain *d);
};
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index a0324d8..4d2a403 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -292,16 +292,25 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
}
#endif
+ if (info->dgc_info) {
+ err = irq_domain_alloc_generic_chips(domain, info->dgc_info);
+ if (err)
+ goto err_domain_free;
+ }
+
if (info->init) {
err = info->init(domain);
if (err)
- goto err_domain_free;
+ goto err_domain_gc_remove;
}
__irq_domain_publish(domain);
return domain;
+err_domain_gc_remove:
+ if (info->dgc_info)
+ irq_domain_remove_generic_chips(domain);
err_domain_free:
irq_domain_free(domain);
return ERR_PTR(err);
@@ -369,6 +378,9 @@ void irq_domain_remove(struct irq_domain *domain)
mutex_unlock(&irq_domain_mutex);
+ if (domain->flags & IRQ_DOMAIN_FLAG_DESTROY_GC)
+ irq_domain_remove_generic_chips(domain);
+
pr_debug("Removed domain %s\n", domain->name);
irq_domain_free(domain);
}
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 16/23] irqdomain: Add a resource managed version of irq_domain_instantiate()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (14 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 15/23] irqdomain: Add support for generic irq chips creation before publishing a domain Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 17/23] irqdomain: Convert __irq_domain_add() wrappers to irq_domain_instantiate() Herve Codina
` (7 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
Add a devres version of irq_domain_instantiate().
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irqdomain.h | 2 ++
kernel/irq/devres.c | 41 +++++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 5540b22a755c..8820317582c4 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -304,6 +304,8 @@ struct irq_domain_info {
};
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
+struct irq_domain *devm_irq_domain_instantiate(struct device *dev,
+ const struct irq_domain_info *info);
struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
irq_hw_number_t hwirq_max, int direct_max,
diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
index f6e5515ee077..b3e98668f4dd 100644
--- a/kernel/irq/devres.c
+++ b/kernel/irq/devres.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
#include <linux/device.h>
#include <linux/gfp.h>
#include <linux/irq.h>
@@ -282,3 +283,43 @@ int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc,
}
EXPORT_SYMBOL_GPL(devm_irq_setup_generic_chip);
#endif /* CONFIG_GENERIC_IRQ_CHIP */
+
+#ifdef CONFIG_IRQ_DOMAIN
+static void devm_irq_domain_remove(struct device *dev, void *res)
+{
+ struct irq_domain **domain = res;
+
+ irq_domain_remove(*domain);
+}
+
+/**
+ * devm_irq_domain_instantiate() - Instantiate a new irq domain data for a
+ * managed device.
+ * @dev: Device to instantiate the domain for
+ * @info: Domain information pointer pointing to the information for this
+ * domain
+ *
+ * Return: A pointer to the instantiated irq domain or an ERR_PTR value.
+ */
+struct irq_domain *devm_irq_domain_instantiate(struct device *dev,
+ const struct irq_domain_info *info)
+{
+ struct irq_domain *domain;
+ struct irq_domain **dr;
+
+ dr = devres_alloc(devm_irq_domain_remove, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return ERR_PTR(-ENOMEM);
+
+ domain = irq_domain_instantiate(info);
+ if (!IS_ERR(domain)) {
+ *dr = domain;
+ devres_add(dev, dr);
+ } else {
+ devres_free(dr);
+ }
+
+ return domain;
+}
+EXPORT_SYMBOL_GPL(devm_irq_domain_instantiate);
+#endif /* CONFIG_IRQ_DOMAIN */
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Add a resource managed version of irq_domain_instantiate()
2024-06-14 17:32 ` [PATCH 16/23] irqdomain: Add a resource managed version of irq_domain_instantiate() Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 0c5b29a6dc7b463b6072da8cef43800008728ff3
Gitweb: https://git.kernel.org/tip/0c5b29a6dc7b463b6072da8cef43800008728ff3
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:17 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:14 +02:00
irqdomain: Add a resource managed version of irq_domain_instantiate()
Add a devres version of irq_domain_instantiate().
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-17-herve.codina@bootlin.com
---
include/linux/irqdomain.h | 2 ++-
kernel/irq/devres.c | 41 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 43 insertions(+)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 5540b22..8820317 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -304,6 +304,8 @@ struct irq_domain_info {
};
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
+struct irq_domain *devm_irq_domain_instantiate(struct device *dev,
+ const struct irq_domain_info *info);
struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
irq_hw_number_t hwirq_max, int direct_max,
diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
index f6e5515..b3e9866 100644
--- a/kernel/irq/devres.c
+++ b/kernel/irq/devres.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
#include <linux/device.h>
#include <linux/gfp.h>
#include <linux/irq.h>
@@ -282,3 +283,43 @@ int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc,
}
EXPORT_SYMBOL_GPL(devm_irq_setup_generic_chip);
#endif /* CONFIG_GENERIC_IRQ_CHIP */
+
+#ifdef CONFIG_IRQ_DOMAIN
+static void devm_irq_domain_remove(struct device *dev, void *res)
+{
+ struct irq_domain **domain = res;
+
+ irq_domain_remove(*domain);
+}
+
+/**
+ * devm_irq_domain_instantiate() - Instantiate a new irq domain data for a
+ * managed device.
+ * @dev: Device to instantiate the domain for
+ * @info: Domain information pointer pointing to the information for this
+ * domain
+ *
+ * Return: A pointer to the instantiated irq domain or an ERR_PTR value.
+ */
+struct irq_domain *devm_irq_domain_instantiate(struct device *dev,
+ const struct irq_domain_info *info)
+{
+ struct irq_domain *domain;
+ struct irq_domain **dr;
+
+ dr = devres_alloc(devm_irq_domain_remove, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return ERR_PTR(-ENOMEM);
+
+ domain = irq_domain_instantiate(info);
+ if (!IS_ERR(domain)) {
+ *dr = domain;
+ devres_add(dev, dr);
+ } else {
+ devres_free(dr);
+ }
+
+ return domain;
+}
+EXPORT_SYMBOL_GPL(devm_irq_domain_instantiate);
+#endif /* CONFIG_IRQ_DOMAIN */
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 17/23] irqdomain: Convert __irq_domain_add() wrappers to irq_domain_instantiate()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (15 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 16/23] irqdomain: Add a resource managed version of irq_domain_instantiate() Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 18/23] irqdomain: Convert domain creation functions " Herve Codina
` (6 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
__irq_domain_add() wrappers use directly __irq_domain_add(). With the
introduction of irq_domain_instantiate(), __irq_domain_add() becomes
obsolete.
In order to fully remove __irq_domain_add(), convert wrappers to
irq_domain_instantiate()
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irqdomain.h | 58 +++++++++++++++++++++++++++++++++++----
1 file changed, 53 insertions(+), 5 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 8820317582c4..1cd1cbf57736 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -400,7 +400,17 @@ static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_no
const struct irq_domain_ops *ops,
void *host_data)
{
- return __irq_domain_add(of_node_to_fwnode(of_node), size, size, 0, ops, host_data);
+ struct irq_domain_info info = {
+ .fwnode = of_node_to_fwnode(of_node),
+ .size = size,
+ .hwirq_max = size,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
+
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
#ifdef CONFIG_IRQ_DOMAIN_NOMAP
@@ -409,7 +419,17 @@ static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_nod
const struct irq_domain_ops *ops,
void *host_data)
{
- return __irq_domain_add(of_node_to_fwnode(of_node), 0, max_irq, max_irq, ops, host_data);
+ struct irq_domain_info info = {
+ .fwnode = of_node_to_fwnode(of_node),
+ .hwirq_max = max_irq,
+ .direct_max = max_irq,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
+
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
@@ -419,7 +439,16 @@ static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node
const struct irq_domain_ops *ops,
void *host_data)
{
- return __irq_domain_add(of_node_to_fwnode(of_node), 0, ~0, 0, ops, host_data);
+ struct irq_domain_info info = {
+ .fwnode = of_node_to_fwnode(of_node),
+ .hwirq_max = ~0U,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
+
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle *fwnode,
@@ -427,14 +456,33 @@ static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle *
const struct irq_domain_ops *ops,
void *host_data)
{
- return __irq_domain_add(fwnode, size, size, 0, ops, host_data);
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .size = size,
+ .hwirq_max = size,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
+
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
static inline struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fwnode,
const struct irq_domain_ops *ops,
void *host_data)
{
- return __irq_domain_add(fwnode, 0, ~0, 0, ops, host_data);
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .hwirq_max = ~0,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
+
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
extern void irq_domain_remove(struct irq_domain *host);
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Convert __irq_domain_add() wrappers to irq_domain_instantiate()
2024-06-14 17:32 ` [PATCH 17/23] irqdomain: Convert __irq_domain_add() wrappers to irq_domain_instantiate() Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 7c53626cd11820a11f9cb2c54c02d47fc062a265
Gitweb: https://git.kernel.org/tip/7c53626cd11820a11f9cb2c54c02d47fc062a265
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:18 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:14 +02:00
irqdomain: Convert __irq_domain_add() wrappers to irq_domain_instantiate()
__irq_domain_add() wrappers use directly __irq_domain_add(). With the
introduction of irq_domain_instantiate(), __irq_domain_add() becomes
obsolete.
In order to fully remove __irq_domain_add(), convert wrappers to
irq_domain_instantiate()
[ tglx: Fixup struct initializers ]
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-18-herve.codina@bootlin.com
---
include/linux/irqdomain.h | 58 ++++++++++++++++++++++++++++++++++----
1 file changed, 53 insertions(+), 5 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 8820317..33a968f 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -400,7 +400,17 @@ static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_no
const struct irq_domain_ops *ops,
void *host_data)
{
- return __irq_domain_add(of_node_to_fwnode(of_node), size, size, 0, ops, host_data);
+ struct irq_domain_info info = {
+ .fwnode = of_node_to_fwnode(of_node),
+ .size = size,
+ .hwirq_max = size,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
+
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
#ifdef CONFIG_IRQ_DOMAIN_NOMAP
@@ -409,7 +419,17 @@ static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_nod
const struct irq_domain_ops *ops,
void *host_data)
{
- return __irq_domain_add(of_node_to_fwnode(of_node), 0, max_irq, max_irq, ops, host_data);
+ struct irq_domain_info info = {
+ .fwnode = of_node_to_fwnode(of_node),
+ .hwirq_max = max_irq,
+ .direct_max = max_irq,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
+
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
@@ -419,7 +439,16 @@ static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node
const struct irq_domain_ops *ops,
void *host_data)
{
- return __irq_domain_add(of_node_to_fwnode(of_node), 0, ~0, 0, ops, host_data);
+ struct irq_domain_info info = {
+ .fwnode = of_node_to_fwnode(of_node),
+ .hwirq_max = ~0U,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
+
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle *fwnode,
@@ -427,14 +456,33 @@ static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle *
const struct irq_domain_ops *ops,
void *host_data)
{
- return __irq_domain_add(fwnode, size, size, 0, ops, host_data);
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .size = size,
+ .hwirq_max = size,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
+
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
static inline struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fwnode,
const struct irq_domain_ops *ops,
void *host_data)
{
- return __irq_domain_add(fwnode, 0, ~0, 0, ops, host_data);
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .hwirq_max = ~0,
+ .ops = ops,
+ .host_data = host_data,
+ };
+ struct irq_domain *d;
+
+ d = irq_domain_instantiate(&info);
+ return IS_ERR(d) ? NULL : d;
}
extern void irq_domain_remove(struct irq_domain *host);
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 18/23] irqdomain: Convert domain creation functions to irq_domain_instantiate()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (16 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 17/23] irqdomain: Convert __irq_domain_add() wrappers to irq_domain_instantiate() Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 19/23] um: virt-pci: Use irq_domain_instantiate() Herve Codina
` (5 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
Domain creation functions use __irq_domain_add(). With the introduction
of irq_domain_instantiate(), __irq_domain_add() becomes obsolete.
In order to fully remove __irq_domain_add(), convert domain
creation function to irq_domain_instantiate()
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
kernel/irq/irqdomain.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index d95ca575a108..e1ceb2ba2699 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -442,10 +442,17 @@ struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode,
const struct irq_domain_ops *ops,
void *host_data)
{
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .size = size,
+ .hwirq_max = size,
+ .ops = ops,
+ .host_data = host_data,
+ };
struct irq_domain *domain;
- domain = __irq_domain_add(fwnode, size, size, 0, ops, host_data);
- if (!domain)
+ domain = irq_domain_instantiate(&info);
+ if (IS_ERR(domain))
return NULL;
if (first_irq > 0) {
@@ -498,11 +505,20 @@ struct irq_domain *irq_domain_create_legacy(struct fwnode_handle *fwnode,
const struct irq_domain_ops *ops,
void *host_data)
{
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .size = first_hwirq + size,
+ .hwirq_max = first_hwirq + size,
+ .ops = ops,
+ .host_data = host_data,
+ };
struct irq_domain *domain;
- domain = __irq_domain_add(fwnode, first_hwirq + size, first_hwirq + size, 0, ops, host_data);
- if (domain)
- irq_domain_associate_many(domain, first_irq, first_hwirq, size);
+ domain = irq_domain_instantiate(&info);
+ if (IS_ERR(domain))
+ return NULL;
+
+ irq_domain_associate_many(domain, first_irq, first_hwirq, size);
return domain;
}
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Convert domain creation functions to irq_domain_instantiate()
2024-06-14 17:32 ` [PATCH 18/23] irqdomain: Convert domain creation functions " Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 2ada5ed6ecac06e32defe39b15b33e9a6b004413
Gitweb: https://git.kernel.org/tip/2ada5ed6ecac06e32defe39b15b33e9a6b004413
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:19 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:15 +02:00
irqdomain: Convert domain creation functions to irq_domain_instantiate()
Domain creation functions use __irq_domain_add(). With the introduction
of irq_domain_instantiate(), __irq_domain_add() becomes obsolete.
In order to fully remove __irq_domain_add(), convert domain
creation function to irq_domain_instantiate()
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-19-herve.codina@bootlin.com
---
kernel/irq/irqdomain.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 4d2a403..c9b076c 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -442,10 +442,17 @@ struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode,
const struct irq_domain_ops *ops,
void *host_data)
{
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .size = size,
+ .hwirq_max = size,
+ .ops = ops,
+ .host_data = host_data,
+ };
struct irq_domain *domain;
- domain = __irq_domain_add(fwnode, size, size, 0, ops, host_data);
- if (!domain)
+ domain = irq_domain_instantiate(&info);
+ if (IS_ERR(domain))
return NULL;
if (first_irq > 0) {
@@ -498,11 +505,20 @@ struct irq_domain *irq_domain_create_legacy(struct fwnode_handle *fwnode,
const struct irq_domain_ops *ops,
void *host_data)
{
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .size = first_hwirq + size,
+ .hwirq_max = first_hwirq + size,
+ .ops = ops,
+ .host_data = host_data,
+ };
struct irq_domain *domain;
- domain = __irq_domain_add(fwnode, first_hwirq + size, first_hwirq + size, 0, ops, host_data);
- if (domain)
- irq_domain_associate_many(domain, first_irq, first_hwirq, size);
+ domain = irq_domain_instantiate(&info);
+ if (IS_ERR(domain))
+ return NULL;
+
+ irq_domain_associate_many(domain, first_irq, first_hwirq, size);
return domain;
}
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 19/23] um: virt-pci: Use irq_domain_instantiate()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (17 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 18/23] irqdomain: Convert domain creation functions " Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] _PATCH_19_23_um_virt_pci_Use_irq_domain_instantiate_ tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 20/23] irqdomain: Remove __irq_domain_add() Herve Codina
` (4 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
um_pci_init() uses __irq_domain_add(). With the introduction of
irq_domain_instantiate(), __irq_domain_add() becomes obsolete.
In order to fully remove __irq_domain_add(), use directly
irq_domain_instantiate().
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
arch/um/drivers/virt-pci.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
index 7cb503469bbd..597d89338693 100644
--- a/arch/um/drivers/virt-pci.c
+++ b/arch/um/drivers/virt-pci.c
@@ -986,6 +986,11 @@ static struct resource virt_platform_resource = {
static int __init um_pci_init(void)
{
+ struct irq_domain_info inner_domain_info = {
+ .size = MAX_MSI_VECTORS,
+ .hwirq_max = MAX_MSI_VECTORS,
+ .ops = &um_pci_inner_domain_ops,
+ };
int err, i;
WARN_ON(logic_iomem_add_region(&virt_cfgspace_resource,
@@ -1015,11 +1020,10 @@ static int __init um_pci_init(void)
goto free;
}
- um_pci_inner_domain = __irq_domain_add(um_pci_fwnode, MAX_MSI_VECTORS,
- MAX_MSI_VECTORS, 0,
- &um_pci_inner_domain_ops, NULL);
- if (!um_pci_inner_domain) {
- err = -ENOMEM;
+ inner_domain_info.fwnode = um_pci_fwnode;
+ um_pci_inner_domain = irq_domain_instantiate(&inner_domain_info);
+ if (IS_ERR(um_pci_inner_domain)) {
+ err = PTR_ERR(um_pci_inner_domain);
goto free;
}
@@ -1056,7 +1060,7 @@ static int __init um_pci_init(void)
goto free;
return 0;
free:
- if (um_pci_inner_domain)
+ if (!IS_ERR_OR_NULL(um_pci_inner_domain))
irq_domain_remove(um_pci_inner_domain);
if (um_pci_fwnode)
irq_domain_free_fwnode(um_pci_fwnode);
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] _PATCH_19_23_um_virt_pci_Use_irq_domain_instantiate_
2024-06-14 17:32 ` [PATCH 19/23] um: virt-pci: Use irq_domain_instantiate() Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: a701f8e93b8355a0817a3b60974e8211797e0733
Gitweb: https://git.kernel.org/tip/a701f8e93b8355a0817a3b60974e8211797e0733
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:20 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:15 +02:00
_PATCH_19_23_um_virt_pci_Use_irq_domain_instantiate_
um_pci_init() uses __irq_domain_add(). With the introduction of
irq_domain_instantiate(), __irq_domain_add() becomes obsolete.
In order to fully remove __irq_domain_add(), use directly
irq_domain_instantiate().
[ tglx: Fixup struct initializer ]
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-20-herve.codina@bootlin.com
---
arch/um/drivers/virt-pci.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
index 7cb5034..a0883d5 100644
--- a/arch/um/drivers/virt-pci.c
+++ b/arch/um/drivers/virt-pci.c
@@ -986,6 +986,11 @@ static struct resource virt_platform_resource = {
static int __init um_pci_init(void)
{
+ struct irq_domain_info inner_domain_info = {
+ .size = MAX_MSI_VECTORS,
+ .hwirq_max = MAX_MSI_VECTORS,
+ .ops = &um_pci_inner_domain_ops,
+ };
int err, i;
WARN_ON(logic_iomem_add_region(&virt_cfgspace_resource,
@@ -1015,11 +1020,10 @@ static int __init um_pci_init(void)
goto free;
}
- um_pci_inner_domain = __irq_domain_add(um_pci_fwnode, MAX_MSI_VECTORS,
- MAX_MSI_VECTORS, 0,
- &um_pci_inner_domain_ops, NULL);
- if (!um_pci_inner_domain) {
- err = -ENOMEM;
+ inner_domain_info.fwnode = um_pci_fwnode;
+ um_pci_inner_domain = irq_domain_instantiate(&inner_domain_info);
+ if (IS_ERR(um_pci_inner_domain)) {
+ err = PTR_ERR(um_pci_inner_domain);
goto free;
}
@@ -1056,7 +1060,7 @@ static int __init um_pci_init(void)
goto free;
return 0;
free:
- if (um_pci_inner_domain)
+ if (!IS_ERR_OR_NULL(um_pci_inner_domain))
irq_domain_remove(um_pci_inner_domain);
if (um_pci_fwnode)
irq_domain_free_fwnode(um_pci_fwnode);
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 20/23] irqdomain: Remove __irq_domain_add()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (18 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 19/23] um: virt-pci: Use irq_domain_instantiate() Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 21/23] dt-bindings: interrupt-controller: Add support for Microchip LAN966x OIC Herve Codina
` (3 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
__irq_domain_add() has been replaced by irq_domain_instanciate() and so,
it is no more used.
Simply remove it.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
include/linux/irqdomain.h | 6 +-----
kernel/irq/irqdomain.c | 33 ---------------------------------
2 files changed, 1 insertion(+), 38 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 1cd1cbf57736..401dca796633 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -184,7 +184,7 @@ enum {
/* Irq domain is hierarchical */
IRQ_DOMAIN_FLAG_HIERARCHY = (1 << 0),
- /* Irq domain name was allocated in __irq_domain_add() */
+ /* Irq domain name was allocated internally */
IRQ_DOMAIN_NAME_ALLOCATED = (1 << 1),
/* Irq domain is an IPI domain with virq per cpu */
@@ -307,10 +307,6 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
struct irq_domain *devm_irq_domain_instantiate(struct device *dev,
const struct irq_domain_info *info);
-struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
- irq_hw_number_t hwirq_max, int direct_max,
- const struct irq_domain_ops *ops,
- void *host_data);
struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode,
unsigned int size,
unsigned int first_irq,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index e1ceb2ba2699..53c38f951348 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -317,39 +317,6 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
}
EXPORT_SYMBOL_GPL(irq_domain_instantiate);
-/**
- * __irq_domain_add() - Allocate a new irq_domain data structure
- * @fwnode: firmware node for the interrupt controller
- * @size: Size of linear map; 0 for radix mapping only
- * @hwirq_max: Maximum number of interrupts supported by controller
- * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no
- * direct mapping
- * @ops: domain callbacks
- * @host_data: Controller private data pointer
- *
- * Allocates and initializes an irq_domain structure.
- * Returns pointer to IRQ domain, or NULL on failure.
- */
-struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
- irq_hw_number_t hwirq_max, int direct_max,
- const struct irq_domain_ops *ops,
- void *host_data)
-{
- struct irq_domain_info info = {
- .fwnode = fwnode,
- .size = size,
- .hwirq_max = hwirq_max,
- .direct_max = direct_max,
- .ops = ops,
- .host_data = host_data,
- };
- struct irq_domain *d;
-
- d = irq_domain_instantiate(&info);
- return IS_ERR(d) ? NULL : d;
-}
-EXPORT_SYMBOL_GPL(__irq_domain_add);
-
/**
* irq_domain_remove() - Remove an irq domain.
* @domain: domain to remove
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqdomain: Remove __irq_domain_add()
2024-06-14 17:32 ` [PATCH 20/23] irqdomain: Remove __irq_domain_add() Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 0b4b172b760efabf8a77ea17644d333fbb444d39
Gitweb: https://git.kernel.org/tip/0b4b172b760efabf8a77ea17644d333fbb444d39
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:21 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:15 +02:00
irqdomain: Remove __irq_domain_add()
__irq_domain_add() has been replaced by irq_domain_instanciate() and so,
it is no more used.
Simply remove it.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-21-herve.codina@bootlin.com
---
include/linux/irqdomain.h | 6 +-----
kernel/irq/irqdomain.c | 33 ---------------------------------
2 files changed, 1 insertion(+), 38 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 33a968f..02cd486 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -184,7 +184,7 @@ enum {
/* Irq domain is hierarchical */
IRQ_DOMAIN_FLAG_HIERARCHY = (1 << 0),
- /* Irq domain name was allocated in __irq_domain_add() */
+ /* Irq domain name was allocated internally */
IRQ_DOMAIN_NAME_ALLOCATED = (1 << 1),
/* Irq domain is an IPI domain with virq per cpu */
@@ -307,10 +307,6 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);
struct irq_domain *devm_irq_domain_instantiate(struct device *dev,
const struct irq_domain_info *info);
-struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
- irq_hw_number_t hwirq_max, int direct_max,
- const struct irq_domain_ops *ops,
- void *host_data);
struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode,
unsigned int size,
unsigned int first_irq,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index c9b076c..91eaf6b 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -318,39 +318,6 @@ err_domain_free:
EXPORT_SYMBOL_GPL(irq_domain_instantiate);
/**
- * __irq_domain_add() - Allocate a new irq_domain data structure
- * @fwnode: firmware node for the interrupt controller
- * @size: Size of linear map; 0 for radix mapping only
- * @hwirq_max: Maximum number of interrupts supported by controller
- * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no
- * direct mapping
- * @ops: domain callbacks
- * @host_data: Controller private data pointer
- *
- * Allocates and initializes an irq_domain structure.
- * Returns pointer to IRQ domain, or NULL on failure.
- */
-struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
- irq_hw_number_t hwirq_max, int direct_max,
- const struct irq_domain_ops *ops,
- void *host_data)
-{
- struct irq_domain_info info = {
- .fwnode = fwnode,
- .size = size,
- .hwirq_max = hwirq_max,
- .direct_max = direct_max,
- .ops = ops,
- .host_data = host_data,
- };
- struct irq_domain *d;
-
- d = irq_domain_instantiate(&info);
- return IS_ERR(d) ? NULL : d;
-}
-EXPORT_SYMBOL_GPL(__irq_domain_add);
-
-/**
* irq_domain_remove() - Remove an irq domain.
* @domain: domain to remove
*
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 21/23] dt-bindings: interrupt-controller: Add support for Microchip LAN966x OIC
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (19 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 20/23] irqdomain: Remove __irq_domain_add() Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 22/23] irqchip: Add support for " Herve Codina
` (2 subsequent siblings)
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
The Microchip LAN966x outband interrupt controller (OIC) maps the
internal interrupt sources of the LAN966x device to an external
interrupt.
When the LAN966x device is used as a PCI device, the external interrupt
is routed to the PCI interrupt.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
---
.../microchip,lan966x-oic.yaml | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml
diff --git a/Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml b/Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml
new file mode 100644
index 000000000000..b2adc7174177
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/microchip,lan966x-oic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip LAN966x outband interrupt controller
+
+maintainers:
+ - Herve Codina <herve.codina@bootlin.com>
+
+allOf:
+ - $ref: /schemas/interrupt-controller.yaml#
+
+description: |
+ The Microchip LAN966x outband interrupt controller (OIC) maps the internal
+ interrupt sources of the LAN966x device to an external interrupt.
+ When the LAN966x device is used as a PCI device, the external interrupt is
+ routed to the PCI interrupt.
+
+properties:
+ compatible:
+ const: microchip,lan966x-oic
+
+ '#interrupt-cells':
+ const: 2
+
+ interrupt-controller: true
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+required:
+ - compatible
+ - '#interrupt-cells'
+ - interrupt-controller
+ - interrupts
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ interrupt-controller@e00c0120 {
+ compatible = "microchip,lan966x-oic";
+ reg = <0xe00c0120 0x190>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ interrupts = <0>;
+ interrupt-parent = <&intc>;
+ };
+...
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] dt-bindings: interrupt-controller: Add support for Microchip LAN966x OIC
2024-06-14 17:32 ` [PATCH 21/23] dt-bindings: interrupt-controller: Add support for Microchip LAN966x OIC Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits
Cc: Herve Codina, Thomas Gleixner, Rob Herring (Arm), x86,
linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 17972a5f1ba85ad8c4f32dfd00ff620a85e98416
Gitweb: https://git.kernel.org/tip/17972a5f1ba85ad8c4f32dfd00ff620a85e98416
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:22 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:15 +02:00
dt-bindings: interrupt-controller: Add support for Microchip LAN966x OIC
The Microchip LAN966x outband interrupt controller (OIC) maps the
internal interrupt sources of the LAN966x device to an external
interrupt.
When the LAN966x device is used as a PCI device, the external interrupt
is routed to the PCI interrupt.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Link: https://lore.kernel.org/r/20240614173232.1184015-22-herve.codina@bootlin.com
---
Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml
diff --git a/Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml b/Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml
new file mode 100644
index 0000000..b2adc71
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/microchip,lan966x-oic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip LAN966x outband interrupt controller
+
+maintainers:
+ - Herve Codina <herve.codina@bootlin.com>
+
+allOf:
+ - $ref: /schemas/interrupt-controller.yaml#
+
+description: |
+ The Microchip LAN966x outband interrupt controller (OIC) maps the internal
+ interrupt sources of the LAN966x device to an external interrupt.
+ When the LAN966x device is used as a PCI device, the external interrupt is
+ routed to the PCI interrupt.
+
+properties:
+ compatible:
+ const: microchip,lan966x-oic
+
+ '#interrupt-cells':
+ const: 2
+
+ interrupt-controller: true
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+required:
+ - compatible
+ - '#interrupt-cells'
+ - interrupt-controller
+ - interrupts
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ interrupt-controller@e00c0120 {
+ compatible = "microchip,lan966x-oic";
+ reg = <0xe00c0120 0x190>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ interrupts = <0>;
+ interrupt-parent = <&intc>;
+ };
+...
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 22/23] irqchip: Add support for LAN966x OIC
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (20 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 21/23] dt-bindings: interrupt-controller: Add support for Microchip LAN966x OIC Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-14 17:32 ` [PATCH 23/23] MAINTAINERS: Add the Microchip LAN966x OIC driver entry Herve Codina
2024-06-17 13:57 ` [PATCH 00/23] Introduce irq_domain_instanciate() Thomas Gleixner
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
The Microchip LAN966x outband interrupt controller (OIC) maps the
internal interrupt sources of the LAN966x device to an external
interrupt.
When the LAN966x device is used as a PCI device, the external interrupt
is routed to the PCI interrupt.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
drivers/irqchip/Kconfig | 12 ++
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-lan966x-oic.c | 278 ++++++++++++++++++++++++++++++
3 files changed, 291 insertions(+)
create mode 100644 drivers/irqchip/irq-lan966x-oic.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 14464716bacb..348f34525d23 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -169,6 +169,18 @@ config IXP4XX_IRQ
select IRQ_DOMAIN
select SPARSE_IRQ
+config LAN966X_OIC
+ tristate "Microchip LAN966x OIC Support"
+ select GENERIC_IRQ_CHIP
+ select IRQ_DOMAIN
+ help
+ Enable support for the LAN966x Outbound Interrupt Controller.
+ This controller is present on the Microchip LAN966x PCI device and
+ maps the internal interrupts sources to PCIe interrupt.
+
+ To compile this driver as a module, choose M here: the module
+ will be called irq-lan966x-oic.
+
config MADERA_IRQ
tristate
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index d9dc3d99aaa8..9f6f88274bec 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o
obj-$(CONFIG_IMX_INTMUX) += irq-imx-intmux.o
obj-$(CONFIG_IMX_MU_MSI) += irq-imx-mu-msi.o
obj-$(CONFIG_MADERA_IRQ) += irq-madera.o
+obj-$(CONFIG_LAN966X_OIC) += irq-lan966x-oic.o
obj-$(CONFIG_LS1X_IRQ) += irq-ls1x.o
obj-$(CONFIG_TI_SCI_INTR_IRQCHIP) += irq-ti-sci-intr.o
obj-$(CONFIG_TI_SCI_INTA_IRQCHIP) += irq-ti-sci-inta.o
diff --git a/drivers/irqchip/irq-lan966x-oic.c b/drivers/irqchip/irq-lan966x-oic.c
new file mode 100644
index 000000000000..34a10f7615d5
--- /dev/null
+++ b/drivers/irqchip/irq-lan966x-oic.c
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the Microchip LAN966x outbound interrupt controller
+ *
+ * Copyright (c) 2024 Technology Inc. and its subsidiaries.
+ *
+ * Authors:
+ * Horatiu Vultur <horatiu.vultur@microchip.com>
+ * Clément Léger <clement.leger@bootlin.com>
+ * Herve Codina <herve.codina@bootlin.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip.h>
+#include <linux/irq.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct lan966x_oic_chip_regs {
+ int reg_off_ena_set;
+ int reg_off_ena_clr;
+ int reg_off_sticky;
+ int reg_off_ident;
+ int reg_off_map;
+};
+
+struct lan966x_oic_data {
+ void __iomem *regs;
+ int irq;
+};
+
+#define LAN966X_OIC_NR_IRQ 86
+
+/* Interrupt sticky status */
+#define LAN966X_OIC_INTR_STICKY 0x30
+#define LAN966X_OIC_INTR_STICKY1 0x34
+#define LAN966X_OIC_INTR_STICKY2 0x38
+
+/* Interrupt enable */
+#define LAN966X_OIC_INTR_ENA 0x48
+#define LAN966X_OIC_INTR_ENA1 0x4c
+#define LAN966X_OIC_INTR_ENA2 0x50
+
+/* Atomic clear of interrupt enable */
+#define LAN966X_OIC_INTR_ENA_CLR 0x54
+#define LAN966X_OIC_INTR_ENA_CLR1 0x58
+#define LAN966X_OIC_INTR_ENA_CLR2 0x5c
+
+/* Atomic set of interrupt */
+#define LAN966X_OIC_INTR_ENA_SET 0x60
+#define LAN966X_OIC_INTR_ENA_SET1 0x64
+#define LAN966X_OIC_INTR_ENA_SET2 0x68
+
+/* Mapping of source to destination interrupts (_n = 0..8) */
+#define LAN966X_OIC_DST_INTR_MAP(_n) (0x78 + (_n) * 4)
+#define LAN966X_OIC_DST_INTR_MAP1(_n) (0x9c + (_n) * 4)
+#define LAN966X_OIC_DST_INTR_MAP2(_n) (0xc0 + (_n) * 4)
+
+/* Currently active interrupt sources per destination (_n = 0..8) */
+#define LAN966X_OIC_DST_INTR_IDENT(_n) (0xe4 + (_n) * 4)
+#define LAN966X_OIC_DST_INTR_IDENT1(_n) (0x108 + (_n) * 4)
+#define LAN966X_OIC_DST_INTR_IDENT2(_n) (0x12c + (_n) * 4)
+
+static unsigned int lan966x_oic_irq_startup(struct irq_data *data)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+ struct irq_chip_type *ct = irq_data_get_chip_type(data);
+ struct lan966x_oic_chip_regs *chip_regs = gc->private;
+ u32 map;
+
+ irq_gc_lock(gc);
+
+ /* Map the source interrupt to the destination */
+ map = irq_reg_readl(gc, chip_regs->reg_off_map);
+ map |= data->mask;
+ irq_reg_writel(gc, map, chip_regs->reg_off_map);
+
+ irq_gc_unlock(gc);
+
+ ct->chip.irq_ack(data);
+ ct->chip.irq_unmask(data);
+
+ return 0;
+}
+
+static void lan966x_oic_irq_shutdown(struct irq_data *data)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+ struct irq_chip_type *ct = irq_data_get_chip_type(data);
+ struct lan966x_oic_chip_regs *chip_regs = gc->private;
+ u32 map;
+
+ ct->chip.irq_mask(data);
+
+ irq_gc_lock(gc);
+
+ /* Unmap the interrupt */
+ map = irq_reg_readl(gc, chip_regs->reg_off_map);
+ map &= ~data->mask;
+ irq_reg_writel(gc, map, chip_regs->reg_off_map);
+
+ irq_gc_unlock(gc);
+}
+
+static int lan966x_oic_irq_set_type(struct irq_data *data,
+ unsigned int flow_type)
+{
+ if (flow_type != IRQ_TYPE_LEVEL_HIGH) {
+ pr_err("lan966x oic doesn't support flow type %d\n", flow_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void lan966x_oic_irq_handler_domain(struct irq_domain *d, u32 first_irq)
+{
+ struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, first_irq);
+ struct lan966x_oic_chip_regs *chip_regs = gc->private;
+ unsigned long ident;
+ unsigned int hwirq;
+
+ ident = irq_reg_readl(gc, chip_regs->reg_off_ident);
+ if (!ident)
+ return;
+
+ for_each_set_bit(hwirq, &ident, 32)
+ generic_handle_domain_irq(d, hwirq + first_irq);
+}
+
+static void lan966x_oic_irq_handler(struct irq_desc *desc)
+{
+ struct irq_domain *d = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+
+ chained_irq_enter(chip, desc);
+ lan966x_oic_irq_handler_domain(d, 0);
+ lan966x_oic_irq_handler_domain(d, 32);
+ lan966x_oic_irq_handler_domain(d, 64);
+ chained_irq_exit(chip, desc);
+}
+
+static struct lan966x_oic_chip_regs lan966x_oic_chip_regs[3] = {
+ {
+ .reg_off_ena_set = LAN966X_OIC_INTR_ENA_SET,
+ .reg_off_ena_clr = LAN966X_OIC_INTR_ENA_CLR,
+ .reg_off_sticky = LAN966X_OIC_INTR_STICKY,
+ .reg_off_ident = LAN966X_OIC_DST_INTR_IDENT(0),
+ .reg_off_map = LAN966X_OIC_DST_INTR_MAP(0),
+ }, {
+ .reg_off_ena_set = LAN966X_OIC_INTR_ENA_SET1,
+ .reg_off_ena_clr = LAN966X_OIC_INTR_ENA_CLR1,
+ .reg_off_sticky = LAN966X_OIC_INTR_STICKY1,
+ .reg_off_ident = LAN966X_OIC_DST_INTR_IDENT1(0),
+ .reg_off_map = LAN966X_OIC_DST_INTR_MAP1(0),
+ }, {
+ .reg_off_ena_set = LAN966X_OIC_INTR_ENA_SET2,
+ .reg_off_ena_clr = LAN966X_OIC_INTR_ENA_CLR2,
+ .reg_off_sticky = LAN966X_OIC_INTR_STICKY2,
+ .reg_off_ident = LAN966X_OIC_DST_INTR_IDENT2(0),
+ .reg_off_map = LAN966X_OIC_DST_INTR_MAP2(0),
+ }
+};
+
+static int lan966x_oic_chip_init(struct irq_chip_generic *gc)
+{
+ struct lan966x_oic_data *lan966x_oic = gc->domain->host_data;
+ struct lan966x_oic_chip_regs *chip_regs;
+
+ chip_regs = &lan966x_oic_chip_regs[gc->irq_base / 32];
+
+ gc->reg_base = lan966x_oic->regs;
+ gc->chip_types[0].regs.enable = chip_regs->reg_off_ena_set;
+ gc->chip_types[0].regs.disable = chip_regs->reg_off_ena_clr;
+ gc->chip_types[0].regs.ack = chip_regs->reg_off_sticky;
+ gc->chip_types[0].chip.irq_startup = lan966x_oic_irq_startup;
+ gc->chip_types[0].chip.irq_shutdown = lan966x_oic_irq_shutdown;
+ gc->chip_types[0].chip.irq_set_type = lan966x_oic_irq_set_type;
+ gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg;
+ gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg;
+ gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+ gc->private = chip_regs;
+
+ /* Disable all interrupts handled by this chip */
+ irq_reg_writel(gc, ~0U, chip_regs->reg_off_ena_clr);
+
+ return 0;
+}
+
+static void lan966x_oic_chip_exit(struct irq_chip_generic *gc)
+{
+ /* Disable and ack all interrupts handled by this chip */
+ irq_reg_writel(gc, ~0U, gc->chip_types[0].regs.disable);
+ irq_reg_writel(gc, ~0U, gc->chip_types[0].regs.ack);
+}
+
+static int lan966x_oic_domain_init(struct irq_domain *d)
+{
+ struct lan966x_oic_data *lan966x_oic = d->host_data;
+
+ irq_set_chained_handler_and_data(lan966x_oic->irq, lan966x_oic_irq_handler, d);
+
+ return 0;
+}
+
+static void lan966x_oic_domain_exit(struct irq_domain *d)
+{
+ struct lan966x_oic_data *lan966x_oic = d->host_data;
+
+ irq_set_chained_handler_and_data(lan966x_oic->irq, NULL, NULL);
+}
+
+static int lan966x_oic_probe(struct platform_device *pdev)
+{
+ struct irq_domain_chip_generic_info dgc_info = {
+ .name = "lan966x-oic",
+ .handler = handle_level_irq,
+ .irqs_per_chip = 32,
+ .num_ct = 1,
+ .init = lan966x_oic_chip_init,
+ .exit = lan966x_oic_chip_exit,
+ };
+ struct irq_domain_info d_info = {
+ .fwnode = of_node_to_fwnode(pdev->dev.of_node),
+ .domain_flags = IRQ_DOMAIN_FLAG_DESTROY_GC,
+ .size = LAN966X_OIC_NR_IRQ,
+ .hwirq_max = LAN966X_OIC_NR_IRQ,
+ .ops = &irq_generic_chip_ops,
+ .dgc_info = &dgc_info,
+ .init = lan966x_oic_domain_init,
+ .exit = lan966x_oic_domain_exit,
+ };
+ struct lan966x_oic_data *lan966x_oic;
+ struct device *dev = &pdev->dev;
+ struct irq_domain *domain;
+
+ lan966x_oic = devm_kmalloc(dev, sizeof(*lan966x_oic), GFP_KERNEL);
+ if (!lan966x_oic)
+ return -ENOMEM;
+
+ lan966x_oic->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(lan966x_oic->regs))
+ return dev_err_probe(dev, PTR_ERR(lan966x_oic->regs),
+ "failed to map resource\n");
+
+ lan966x_oic->irq = platform_get_irq(pdev, 0);
+ if (lan966x_oic->irq < 0)
+ return dev_err_probe(dev, lan966x_oic->irq, "failed to get the IRQ\n");
+
+ d_info.host_data = lan966x_oic;
+ domain = devm_irq_domain_instantiate(dev, &d_info);
+ if (IS_ERR(domain))
+ return dev_err_probe(dev, PTR_ERR(domain),
+ "failed to instantiate the IRQ domain\n");
+ return 0;
+}
+
+static const struct of_device_id lan966x_oic_of_match[] = {
+ { .compatible = "microchip,lan966x-oic" },
+ {} /* sentinel */
+};
+MODULE_DEVICE_TABLE(of, lan966x_oic_of_match);
+
+static struct platform_driver lan966x_oic_driver = {
+ .probe = lan966x_oic_probe,
+ .driver = {
+ .name = "lan966x-oic",
+ .of_match_table = lan966x_oic_of_match,
+ },
+};
+module_platform_driver(lan966x_oic_driver);
+
+MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
+MODULE_DESCRIPTION("Microchip LAN966x OIC driver");
+MODULE_LICENSE("GPL");
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] irqchip: Add support for LAN966x OIC
2024-06-14 17:32 ` [PATCH 22/23] irqchip: Add support for " Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 3e3a7b35332924c8ade696c4b24735561ee6aea3
Gitweb: https://git.kernel.org/tip/3e3a7b35332924c8ade696c4b24735561ee6aea3
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:23 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:15 +02:00
irqchip: Add support for LAN966x OIC
The Microchip LAN966x outband interrupt controller (OIC) maps the
internal interrupt sources of the LAN966x device to an external
interrupt.
When the LAN966x device is used as a PCI device, the external interrupt
is routed to the PCI interrupt.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-23-herve.codina@bootlin.com
---
drivers/irqchip/Kconfig | 12 +-
drivers/irqchip/Makefile | 1 +-
drivers/irqchip/irq-lan966x-oic.c | 278 +++++++++++++++++++++++++++++-
3 files changed, 291 insertions(+)
create mode 100644 drivers/irqchip/irq-lan966x-oic.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 1446471..348f345 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -169,6 +169,18 @@ config IXP4XX_IRQ
select IRQ_DOMAIN
select SPARSE_IRQ
+config LAN966X_OIC
+ tristate "Microchip LAN966x OIC Support"
+ select GENERIC_IRQ_CHIP
+ select IRQ_DOMAIN
+ help
+ Enable support for the LAN966x Outbound Interrupt Controller.
+ This controller is present on the Microchip LAN966x PCI device and
+ maps the internal interrupts sources to PCIe interrupt.
+
+ To compile this driver as a module, choose M here: the module
+ will be called irq-lan966x-oic.
+
config MADERA_IRQ
tristate
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index d9dc3d9..9f6f882 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o
obj-$(CONFIG_IMX_INTMUX) += irq-imx-intmux.o
obj-$(CONFIG_IMX_MU_MSI) += irq-imx-mu-msi.o
obj-$(CONFIG_MADERA_IRQ) += irq-madera.o
+obj-$(CONFIG_LAN966X_OIC) += irq-lan966x-oic.o
obj-$(CONFIG_LS1X_IRQ) += irq-ls1x.o
obj-$(CONFIG_TI_SCI_INTR_IRQCHIP) += irq-ti-sci-intr.o
obj-$(CONFIG_TI_SCI_INTA_IRQCHIP) += irq-ti-sci-inta.o
diff --git a/drivers/irqchip/irq-lan966x-oic.c b/drivers/irqchip/irq-lan966x-oic.c
new file mode 100644
index 0000000..41ac880
--- /dev/null
+++ b/drivers/irqchip/irq-lan966x-oic.c
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the Microchip LAN966x outbound interrupt controller
+ *
+ * Copyright (c) 2024 Technology Inc. and its subsidiaries.
+ *
+ * Authors:
+ * Horatiu Vultur <horatiu.vultur@microchip.com>
+ * Clément Léger <clement.leger@bootlin.com>
+ * Herve Codina <herve.codina@bootlin.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip.h>
+#include <linux/irq.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct lan966x_oic_chip_regs {
+ int reg_off_ena_set;
+ int reg_off_ena_clr;
+ int reg_off_sticky;
+ int reg_off_ident;
+ int reg_off_map;
+};
+
+struct lan966x_oic_data {
+ void __iomem *regs;
+ int irq;
+};
+
+#define LAN966X_OIC_NR_IRQ 86
+
+/* Interrupt sticky status */
+#define LAN966X_OIC_INTR_STICKY 0x30
+#define LAN966X_OIC_INTR_STICKY1 0x34
+#define LAN966X_OIC_INTR_STICKY2 0x38
+
+/* Interrupt enable */
+#define LAN966X_OIC_INTR_ENA 0x48
+#define LAN966X_OIC_INTR_ENA1 0x4c
+#define LAN966X_OIC_INTR_ENA2 0x50
+
+/* Atomic clear of interrupt enable */
+#define LAN966X_OIC_INTR_ENA_CLR 0x54
+#define LAN966X_OIC_INTR_ENA_CLR1 0x58
+#define LAN966X_OIC_INTR_ENA_CLR2 0x5c
+
+/* Atomic set of interrupt */
+#define LAN966X_OIC_INTR_ENA_SET 0x60
+#define LAN966X_OIC_INTR_ENA_SET1 0x64
+#define LAN966X_OIC_INTR_ENA_SET2 0x68
+
+/* Mapping of source to destination interrupts (_n = 0..8) */
+#define LAN966X_OIC_DST_INTR_MAP(_n) (0x78 + (_n) * 4)
+#define LAN966X_OIC_DST_INTR_MAP1(_n) (0x9c + (_n) * 4)
+#define LAN966X_OIC_DST_INTR_MAP2(_n) (0xc0 + (_n) * 4)
+
+/* Currently active interrupt sources per destination (_n = 0..8) */
+#define LAN966X_OIC_DST_INTR_IDENT(_n) (0xe4 + (_n) * 4)
+#define LAN966X_OIC_DST_INTR_IDENT1(_n) (0x108 + (_n) * 4)
+#define LAN966X_OIC_DST_INTR_IDENT2(_n) (0x12c + (_n) * 4)
+
+static unsigned int lan966x_oic_irq_startup(struct irq_data *data)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+ struct irq_chip_type *ct = irq_data_get_chip_type(data);
+ struct lan966x_oic_chip_regs *chip_regs = gc->private;
+ u32 map;
+
+ irq_gc_lock(gc);
+
+ /* Map the source interrupt to the destination */
+ map = irq_reg_readl(gc, chip_regs->reg_off_map);
+ map |= data->mask;
+ irq_reg_writel(gc, map, chip_regs->reg_off_map);
+
+ irq_gc_unlock(gc);
+
+ ct->chip.irq_ack(data);
+ ct->chip.irq_unmask(data);
+
+ return 0;
+}
+
+static void lan966x_oic_irq_shutdown(struct irq_data *data)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+ struct irq_chip_type *ct = irq_data_get_chip_type(data);
+ struct lan966x_oic_chip_regs *chip_regs = gc->private;
+ u32 map;
+
+ ct->chip.irq_mask(data);
+
+ irq_gc_lock(gc);
+
+ /* Unmap the interrupt */
+ map = irq_reg_readl(gc, chip_regs->reg_off_map);
+ map &= ~data->mask;
+ irq_reg_writel(gc, map, chip_regs->reg_off_map);
+
+ irq_gc_unlock(gc);
+}
+
+static int lan966x_oic_irq_set_type(struct irq_data *data,
+ unsigned int flow_type)
+{
+ if (flow_type != IRQ_TYPE_LEVEL_HIGH) {
+ pr_err("lan966x oic doesn't support flow type %d\n", flow_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void lan966x_oic_irq_handler_domain(struct irq_domain *d, u32 first_irq)
+{
+ struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, first_irq);
+ struct lan966x_oic_chip_regs *chip_regs = gc->private;
+ unsigned long ident;
+ unsigned int hwirq;
+
+ ident = irq_reg_readl(gc, chip_regs->reg_off_ident);
+ if (!ident)
+ return;
+
+ for_each_set_bit(hwirq, &ident, 32)
+ generic_handle_domain_irq(d, hwirq + first_irq);
+}
+
+static void lan966x_oic_irq_handler(struct irq_desc *desc)
+{
+ struct irq_domain *d = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+
+ chained_irq_enter(chip, desc);
+ lan966x_oic_irq_handler_domain(d, 0);
+ lan966x_oic_irq_handler_domain(d, 32);
+ lan966x_oic_irq_handler_domain(d, 64);
+ chained_irq_exit(chip, desc);
+}
+
+static struct lan966x_oic_chip_regs lan966x_oic_chip_regs[3] = {
+ {
+ .reg_off_ena_set = LAN966X_OIC_INTR_ENA_SET,
+ .reg_off_ena_clr = LAN966X_OIC_INTR_ENA_CLR,
+ .reg_off_sticky = LAN966X_OIC_INTR_STICKY,
+ .reg_off_ident = LAN966X_OIC_DST_INTR_IDENT(0),
+ .reg_off_map = LAN966X_OIC_DST_INTR_MAP(0),
+ }, {
+ .reg_off_ena_set = LAN966X_OIC_INTR_ENA_SET1,
+ .reg_off_ena_clr = LAN966X_OIC_INTR_ENA_CLR1,
+ .reg_off_sticky = LAN966X_OIC_INTR_STICKY1,
+ .reg_off_ident = LAN966X_OIC_DST_INTR_IDENT1(0),
+ .reg_off_map = LAN966X_OIC_DST_INTR_MAP1(0),
+ }, {
+ .reg_off_ena_set = LAN966X_OIC_INTR_ENA_SET2,
+ .reg_off_ena_clr = LAN966X_OIC_INTR_ENA_CLR2,
+ .reg_off_sticky = LAN966X_OIC_INTR_STICKY2,
+ .reg_off_ident = LAN966X_OIC_DST_INTR_IDENT2(0),
+ .reg_off_map = LAN966X_OIC_DST_INTR_MAP2(0),
+ }
+};
+
+static int lan966x_oic_chip_init(struct irq_chip_generic *gc)
+{
+ struct lan966x_oic_data *lan966x_oic = gc->domain->host_data;
+ struct lan966x_oic_chip_regs *chip_regs;
+
+ chip_regs = &lan966x_oic_chip_regs[gc->irq_base / 32];
+
+ gc->reg_base = lan966x_oic->regs;
+ gc->chip_types[0].regs.enable = chip_regs->reg_off_ena_set;
+ gc->chip_types[0].regs.disable = chip_regs->reg_off_ena_clr;
+ gc->chip_types[0].regs.ack = chip_regs->reg_off_sticky;
+ gc->chip_types[0].chip.irq_startup = lan966x_oic_irq_startup;
+ gc->chip_types[0].chip.irq_shutdown = lan966x_oic_irq_shutdown;
+ gc->chip_types[0].chip.irq_set_type = lan966x_oic_irq_set_type;
+ gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg;
+ gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg;
+ gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+ gc->private = chip_regs;
+
+ /* Disable all interrupts handled by this chip */
+ irq_reg_writel(gc, ~0U, chip_regs->reg_off_ena_clr);
+
+ return 0;
+}
+
+static void lan966x_oic_chip_exit(struct irq_chip_generic *gc)
+{
+ /* Disable and ack all interrupts handled by this chip */
+ irq_reg_writel(gc, ~0U, gc->chip_types[0].regs.disable);
+ irq_reg_writel(gc, ~0U, gc->chip_types[0].regs.ack);
+}
+
+static int lan966x_oic_domain_init(struct irq_domain *d)
+{
+ struct lan966x_oic_data *lan966x_oic = d->host_data;
+
+ irq_set_chained_handler_and_data(lan966x_oic->irq, lan966x_oic_irq_handler, d);
+
+ return 0;
+}
+
+static void lan966x_oic_domain_exit(struct irq_domain *d)
+{
+ struct lan966x_oic_data *lan966x_oic = d->host_data;
+
+ irq_set_chained_handler_and_data(lan966x_oic->irq, NULL, NULL);
+}
+
+static int lan966x_oic_probe(struct platform_device *pdev)
+{
+ struct irq_domain_chip_generic_info dgc_info = {
+ .name = "lan966x-oic",
+ .handler = handle_level_irq,
+ .irqs_per_chip = 32,
+ .num_ct = 1,
+ .init = lan966x_oic_chip_init,
+ .exit = lan966x_oic_chip_exit,
+ };
+ struct irq_domain_info d_info = {
+ .fwnode = of_node_to_fwnode(pdev->dev.of_node),
+ .domain_flags = IRQ_DOMAIN_FLAG_DESTROY_GC,
+ .size = LAN966X_OIC_NR_IRQ,
+ .hwirq_max = LAN966X_OIC_NR_IRQ,
+ .ops = &irq_generic_chip_ops,
+ .dgc_info = &dgc_info,
+ .init = lan966x_oic_domain_init,
+ .exit = lan966x_oic_domain_exit,
+ };
+ struct lan966x_oic_data *lan966x_oic;
+ struct device *dev = &pdev->dev;
+ struct irq_domain *domain;
+
+ lan966x_oic = devm_kmalloc(dev, sizeof(*lan966x_oic), GFP_KERNEL);
+ if (!lan966x_oic)
+ return -ENOMEM;
+
+ lan966x_oic->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(lan966x_oic->regs))
+ return dev_err_probe(dev, PTR_ERR(lan966x_oic->regs),
+ "failed to map resource\n");
+
+ lan966x_oic->irq = platform_get_irq(pdev, 0);
+ if (lan966x_oic->irq < 0)
+ return dev_err_probe(dev, lan966x_oic->irq, "failed to get the IRQ\n");
+
+ d_info.host_data = lan966x_oic;
+ domain = devm_irq_domain_instantiate(dev, &d_info);
+ if (IS_ERR(domain))
+ return dev_err_probe(dev, PTR_ERR(domain),
+ "failed to instantiate the IRQ domain\n");
+ return 0;
+}
+
+static const struct of_device_id lan966x_oic_of_match[] = {
+ { .compatible = "microchip,lan966x-oic" },
+ {} /* sentinel */
+};
+MODULE_DEVICE_TABLE(of, lan966x_oic_of_match);
+
+static struct platform_driver lan966x_oic_driver = {
+ .probe = lan966x_oic_probe,
+ .driver = {
+ .name = "lan966x-oic",
+ .of_match_table = lan966x_oic_of_match,
+ },
+};
+module_platform_driver(lan966x_oic_driver);
+
+MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
+MODULE_DESCRIPTION("Microchip LAN966x OIC driver");
+MODULE_LICENSE("GPL");
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 23/23] MAINTAINERS: Add the Microchip LAN966x OIC driver entry
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (21 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 22/23] irqchip: Add support for " Herve Codina
@ 2024-06-14 17:32 ` Herve Codina
2024-06-17 13:51 ` [tip: irq/core] " tip-bot2 for Herve Codina
2024-06-17 13:57 ` [PATCH 00/23] Introduce irq_domain_instanciate() Thomas Gleixner
23 siblings, 1 reply; 49+ messages in thread
From: Herve Codina @ 2024-06-14 17:32 UTC (permalink / raw)
To: Matti Vaittinen, Herve Codina, Thomas Gleixner, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
After contributing the driver, add myself as the maintainer for the
Microchip LAN966x OIC driver.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
MAINTAINERS | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index d6c90161c7bf..baeb307344cd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14727,6 +14727,12 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/microchip/lan966x/*
+MICROCHIP LAN966X OIC DRIVER
+M: Herve Codina <herve.codina@bootlin.com>
+S: Maintained
+F: Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml
+F: drivers/irqchip/irq-lan966x-oic.c
+
MICROCHIP LCDFB DRIVER
M: Nicolas Ferre <nicolas.ferre@microchip.com>
L: linux-fbdev@vger.kernel.org
--
2.45.0
^ permalink raw reply related [flat|nested] 49+ messages in thread* [tip: irq/core] MAINTAINERS: Add the Microchip LAN966x OIC driver entry
2024-06-14 17:32 ` [PATCH 23/23] MAINTAINERS: Add the Microchip LAN966x OIC driver entry Herve Codina
@ 2024-06-17 13:51 ` tip-bot2 for Herve Codina
0 siblings, 0 replies; 49+ messages in thread
From: tip-bot2 for Herve Codina @ 2024-06-17 13:51 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Herve Codina, Thomas Gleixner, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 92584deade41ac8dda3f9b79ab545f50ba0e95db
Gitweb: https://git.kernel.org/tip/92584deade41ac8dda3f9b79ab545f50ba0e95db
Author: Herve Codina <herve.codina@bootlin.com>
AuthorDate: Fri, 14 Jun 2024 19:32:24 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 17 Jun 2024 15:48:15 +02:00
MAINTAINERS: Add the Microchip LAN966x OIC driver entry
After contributing the driver, add myself as the maintainer for the
Microchip LAN966x OIC driver.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-24-herve.codina@bootlin.com
---
MAINTAINERS | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 8754ac2..c47d8b9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14727,6 +14727,12 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/microchip/lan966x/*
+MICROCHIP LAN966X OIC DRIVER
+M: Herve Codina <herve.codina@bootlin.com>
+S: Maintained
+F: Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml
+F: drivers/irqchip/irq-lan966x-oic.c
+
MICROCHIP LCDFB DRIVER
M: Nicolas Ferre <nicolas.ferre@microchip.com>
L: linux-fbdev@vger.kernel.org
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH 00/23] Introduce irq_domain_instanciate()
2024-06-14 17:32 [PATCH 00/23] Introduce irq_domain_instanciate() Herve Codina
` (22 preceding siblings ...)
2024-06-14 17:32 ` [PATCH 23/23] MAINTAINERS: Add the Microchip LAN966x OIC driver entry Herve Codina
@ 2024-06-17 13:57 ` Thomas Gleixner
2024-06-18 13:05 ` Matti Vaittinen
23 siblings, 1 reply; 49+ messages in thread
From: Thomas Gleixner @ 2024-06-17 13:57 UTC (permalink / raw)
To: Herve Codina, Matti Vaittinen, Herve Codina, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Richard Weinberger,
Anton Ivanov, Johannes Berg, Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
Herve!
On Fri, Jun 14 2024 at 19:32, Herve Codina wrote:
> During the review, it was asked to rework the irq domain modification in
> order to avoid more wrappers and a new irq_domain_instanciate() function
> was proposed [2].
>
> Also a patch [3] sent by Maitti Vaittinen can benefit of this new
> irq_domain_instanciate() function. Even if Maitti's use case is not
> handle yet in this series, it should not be a big deal add support for
> it on top of this current series.
>
> So, this current series introduces this new irq_domain_instanciate()
> function and migrate existing wrappers and functions to this new
> function (patches 1 to 20).
>
> It then introduces the first driver that uses directly this new function
> with the init()/exit() hooks set: the Microchip LAN966x OIC driver
> (patches 21 to 23).
>
> Existing irqchip drivers are not converted yet to use this new API
> function in the same way as the LAN966x OIC driver does.
> I prefer to have this series accepted first to avoid doing and re-doing
> several times the same modifications on existing drivers depending on
> changes requested on this current series review.
I'm truly impressed by the quality of this patch set.
The only nitpicks I found was the formatting of the struct
initializers. I fixed them up for you this time. Keep up the good work!
The result can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
Matti, can you please build your extensions on top of that?
Thanks,
tglx
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH 00/23] Introduce irq_domain_instanciate()
2024-06-17 13:57 ` [PATCH 00/23] Introduce irq_domain_instanciate() Thomas Gleixner
@ 2024-06-18 13:05 ` Matti Vaittinen
0 siblings, 0 replies; 49+ messages in thread
From: Matti Vaittinen @ 2024-06-18 13:05 UTC (permalink / raw)
To: Thomas Gleixner, Herve Codina, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Weinberger, Anton Ivanov, Johannes Berg,
Marc Zyngier
Cc: linux-kernel, devicetree, linux-um, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
On 6/17/24 16:57, Thomas Gleixner wrote:
>
> The result can be found at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
>
> Matti, can you please build your extensions on top of that?
Will do, but it takes me a while as I'm on a vacation. I'll try to cook
it up when the next rainy day hits us ;) Thanks!
Yours,
-- Matti
--
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland
~~ When things go utterly wrong vim users can always type :help! ~~
^ permalink raw reply [flat|nested] 49+ messages in thread