From 42b8b16fe56c206fde7fbae0116769d0addef4b7 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:33 +0100 Subject: [PATCH 01/16] irqdomain: Drop irq_domain_add_*() functions Most irq_domain_add_*() functions are unused now, so drop them. The remaining ones are moved to the deprecated section and will be removed during the merge window after the patches in various trees have been merged. Note: The Chinese docs are touched but unfinished. I cannot parse those. [ tglx: Remove the leftover in irq-domain.rst and handle merge logistics ] Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-41-jirislaby@kernel.org --- Documentation/core-api/irq/irq-domain.rst | 41 ++----- .../zh_CN/core-api/irq/irq-domain.rst | 4 - include/linux/irqdomain.h | 102 ++++++------------ kernel/irq/irqdomain.c | 27 ----- 4 files changed, 44 insertions(+), 130 deletions(-) diff --git a/Documentation/core-api/irq/irq-domain.rst b/Documentation/core-api/irq/irq-domain.rst index 44f4ba5480df..7624607a171b 100644 --- a/Documentation/core-api/irq/irq-domain.rst +++ b/Documentation/core-api/irq/irq-domain.rst @@ -42,10 +42,9 @@ irq_domain usage ================ An interrupt controller driver creates and registers an irq_domain by -calling one of the irq_domain_add_*() or irq_domain_create_*() functions -(each mapping method has a different allocator function, more on that later). -The function will return a pointer to the irq_domain on success. The caller -must provide the allocator function with an irq_domain_ops structure. +calling one of the irq_domain_create_*() functions. The function will +return a pointer to the irq_domain on success. The caller must provide the +allocator function with an irq_domain_ops structure. In most cases, the irq_domain will begin empty without any mappings between hwirq and IRQ numbers. Mappings are added to the irq_domain @@ -92,7 +91,6 @@ Linear :: - irq_domain_add_linear() irq_domain_create_linear() The linear reverse map maintains a fixed size table indexed by the @@ -105,11 +103,6 @@ map are fixed time lookup for IRQ numbers, and irq_descs are only allocated for in-use IRQs. The disadvantage is that the table must be as large as the largest possible hwirq number. -irq_domain_add_linear() and irq_domain_create_linear() are functionally -equivalent, except for the first argument is different - the former -accepts an Open Firmware specific 'struct device_node', while the latter -accepts a more general abstraction 'struct fwnode_handle'. - The majority of drivers should use the linear map. Tree @@ -117,7 +110,6 @@ Tree :: - irq_domain_add_tree() irq_domain_create_tree() The irq_domain maintains a radix tree map from hwirq numbers to Linux @@ -129,11 +121,6 @@ since it doesn't need to allocate a table as large as the largest hwirq number. The disadvantage is that hwirq to IRQ number lookup is dependent on how many entries are in the table. -irq_domain_add_tree() and irq_domain_create_tree() are functionally -equivalent, except for the first argument is different - the former -accepts an Open Firmware specific 'struct device_node', while the latter -accepts a more general abstraction 'struct fwnode_handle'. - Very few drivers should need this mapping. No Map @@ -159,8 +146,6 @@ Legacy :: - irq_domain_add_simple() - irq_domain_add_legacy() irq_domain_create_simple() irq_domain_create_legacy() @@ -189,13 +174,13 @@ supported. For example, ISA controllers would use the legacy map for mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ numbers. -Most users of legacy mappings should use irq_domain_add_simple() or -irq_domain_create_simple() which will use a legacy domain only if an IRQ range -is supplied by the system and will otherwise use a linear domain mapping. -The semantics of this call are such that if an IRQ range is specified then -descriptors will be allocated on-the-fly for it, and if no range is -specified it will fall through to irq_domain_add_linear() or -irq_domain_create_linear() which means *no* irq descriptors will be allocated. +Most users of legacy mappings should use irq_domain_create_simple() +which will use a legacy domain only if an IRQ range is supplied by the +system and will otherwise use a linear domain mapping. The semantics of +this call are such that if an IRQ range is specified then descriptors +will be allocated on-the-fly for it, and if no range is specified it +will fall through to irq_domain_create_linear() which means *no* irq +descriptors will be allocated. A typical use case for simple domains is where an irqchip provider is supporting both dynamic and static IRQ assignments. @@ -206,12 +191,6 @@ that the driver using the simple domain call irq_create_mapping() before any irq_find_mapping() since the latter will actually work for the static IRQ assignment case. -irq_domain_add_simple() and irq_domain_create_simple() as well as -irq_domain_add_legacy() and irq_domain_create_legacy() are functionally -equivalent, except for the first argument is different - the former -accepts an Open Firmware specific 'struct device_node', while the latter -accepts a more general abstraction 'struct fwnode_handle'. - Hierarchy IRQ domain -------------------- diff --git a/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst b/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst index ecb23cfbc9fc..913c3eda3f74 100644 --- a/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst +++ b/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst @@ -83,7 +83,6 @@ irq_domain映射的类型 :: - irq_domain_add_linear() irq_domain_create_linear() 线性反向映射维护了一个固定大小的表,该表以hwirq号为索引。 当一个hwirq被映射 @@ -104,7 +103,6 @@ irq_domain_add_linear()和irq_domain_create_linear()在功能上是等价的, :: - irq_domain_add_tree() irq_domain_create_tree() irq_domain维护着从hwirq号到Linux IRQ的radix的树状映射。 当一个hwirq被映射时, @@ -138,8 +136,6 @@ Linux IRQ号编入硬件本身,这样就不需要映射了。 调用irq_create :: - irq_domain_add_simple() - irq_domain_add_legacy() irq_domain_create_simple() irq_domain_create_legacy() diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index f3c79f908a28..712c662de981 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -338,12 +338,6 @@ struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode, unsigned int first_irq, const struct irq_domain_ops *ops, void *host_data); -struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, - unsigned int size, - unsigned int first_irq, - irq_hw_number_t first_hwirq, - const struct irq_domain_ops *ops, - void *host_data); struct irq_domain *irq_domain_create_legacy(struct fwnode_handle *fwnode, unsigned int size, unsigned int first_irq, @@ -396,40 +390,6 @@ static inline struct irq_domain *irq_find_host(struct device_node *node) return d; } -static inline struct irq_domain *irq_domain_add_simple(struct device_node *of_node, - unsigned int size, - unsigned int first_irq, - const struct irq_domain_ops *ops, - void *host_data) -{ - return irq_domain_create_simple(of_fwnode_handle(of_node), size, first_irq, ops, host_data); -} - -/** - * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain. - * @of_node: pointer to interrupt controller's device tree node. - * @size: Number of interrupts in the domain. - * @ops: map/unmap domain callbacks - * @host_data: Controller private data pointer - */ -static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_node, - unsigned int size, - const struct irq_domain_ops *ops, - void *host_data) -{ - struct irq_domain_info info = { - .fwnode = of_fwnode_handle(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 static inline struct irq_domain *irq_domain_create_nomap(struct fwnode_handle *fwnode, unsigned int max_irq, @@ -452,22 +412,6 @@ static inline struct irq_domain *irq_domain_create_nomap(struct fwnode_handle *f unsigned int irq_create_direct_mapping(struct irq_domain *domain); #endif -static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node, - const struct irq_domain_ops *ops, - void *host_data) -{ - struct irq_domain_info info = { - .fwnode = of_fwnode_handle(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, unsigned int size, const struct irq_domain_ops *ops, @@ -631,18 +575,6 @@ static inline struct irq_domain *irq_domain_create_hierarchy(struct irq_domain * return IS_ERR(d) ? NULL : d; } -static inline struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent, - unsigned int flags, - unsigned int size, - struct device_node *node, - const struct irq_domain_ops *ops, - void *host_data) -{ - return irq_domain_create_hierarchy(parent, flags, size, - of_fwnode_handle(node), - ops, host_data); -} - int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, unsigned int nr_irqs, int node, void *arg, bool realloc, @@ -789,6 +721,40 @@ static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node) return node ? &node->fwnode : NULL; } +static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node, + const struct irq_domain_ops *ops, + void *host_data) +{ + struct irq_domain_info info = { + .fwnode = of_fwnode_handle(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_add_linear(struct device_node *of_node, + unsigned int size, + const struct irq_domain_ops *ops, + void *host_data) +{ + struct irq_domain_info info = { + .fwnode = of_fwnode_handle(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; +} + #else /* CONFIG_IRQ_DOMAIN */ static inline void irq_dispose_mapping(unsigned int virq) { } static inline struct irq_domain *irq_find_matching_fwnode( diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 74ad4a8fb4f7..57098c79750f 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -480,33 +480,6 @@ struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode, } EXPORT_SYMBOL_GPL(irq_domain_create_simple); -/** - * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain. - * @of_node: pointer to interrupt controller's device tree node. - * @size: total number of irqs in legacy mapping - * @first_irq: first number of irq block assigned to the domain - * @first_hwirq: first hwirq number to use for the translation. Should normally - * be '0', but a positive integer can be used if the effective - * hwirqs numbering does not begin at zero. - * @ops: map/unmap domain callbacks - * @host_data: Controller private data pointer - * - * Note: the map() callback will be called before this function returns - * for all legacy interrupts except 0 (which is always the invalid irq for - * a legacy controller). - */ -struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, - unsigned int size, - unsigned int first_irq, - irq_hw_number_t first_hwirq, - const struct irq_domain_ops *ops, - void *host_data) -{ - return irq_domain_create_legacy(of_fwnode_handle(of_node), size, - first_irq, first_hwirq, ops, host_data); -} -EXPORT_SYMBOL_GPL(irq_domain_add_legacy); - struct irq_domain *irq_domain_create_legacy(struct fwnode_handle *fwnode, unsigned int size, unsigned int first_irq, -- 2.51.0 From 8035d9f2665e2de138007e2341d8b6d0e46c5606 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:34 +0100 Subject: [PATCH 02/16] powerpc: Switch to irq_find_mapping() irq_linear_revmap() is deprecated, so remove all its uses and supersede them by an identical call to irq_find_mapping(). [ tglx: Fix up subject prefix ] Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Acked-by: Christophe Leroy # for 8xx Link: https://lore.kernel.org/all/20250319092951.37667-42-jirislaby@kernel.org --- arch/powerpc/platforms/44x/uic.c | 2 +- arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 2 +- arch/powerpc/platforms/52xx/mpc52xx_pic.c | 2 +- arch/powerpc/platforms/85xx/socrates_fpga_pic.c | 2 +- arch/powerpc/platforms/8xx/cpm1-ic.c | 2 +- arch/powerpc/platforms/8xx/pic.c | 2 +- arch/powerpc/platforms/embedded6xx/flipper-pic.c | 2 +- arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 2 +- arch/powerpc/platforms/powermac/pic.c | 2 +- arch/powerpc/sysdev/cpm2_pic.c | 2 +- arch/powerpc/sysdev/ehv_pic.c | 2 +- arch/powerpc/sysdev/ge/ge_pic.c | 2 +- arch/powerpc/sysdev/ipic.c | 2 +- arch/powerpc/sysdev/mpic.c | 4 ++-- 14 files changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/platforms/44x/uic.c b/arch/powerpc/platforms/44x/uic.c index 481ec25ce78f..85daf841fd3f 100644 --- a/arch/powerpc/platforms/44x/uic.c +++ b/arch/powerpc/platforms/44x/uic.c @@ -328,5 +328,5 @@ unsigned int uic_get_irq(void) msr = mfdcr(primary_uic->dcrbase + UIC_MSR); src = 32 - ffs(msr); - return irq_linear_revmap(primary_uic->irqhost, src); + return irq_find_mapping(primary_uic->irqhost, src); } diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index f042b21b2b73..3dbe5a5e5d1f 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -369,7 +369,7 @@ struct mpc52xx_gpt_priv *mpc52xx_gpt_from_irq(int irq) mutex_lock(&mpc52xx_gpt_list_mutex); list_for_each(pos, &mpc52xx_gpt_list) { gpt = container_of(pos, struct mpc52xx_gpt_priv, list); - if (gpt->irqhost && irq == irq_linear_revmap(gpt->irqhost, 0)) { + if (gpt->irqhost && irq == irq_find_mapping(gpt->irqhost, 0)) { mutex_unlock(&mpc52xx_gpt_list_mutex); return gpt; } diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 7ec56d3788a9..eb6a4e745c08 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -515,5 +515,5 @@ unsigned int mpc52xx_get_irq(void) return 0; } - return irq_linear_revmap(mpc52xx_irqhost, irq); + return irq_find_mapping(mpc52xx_irqhost, irq); } diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c index b4f6360830b1..4b69fb321a68 100644 --- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c +++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c @@ -83,7 +83,7 @@ static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq) if (cause >> (i + 16)) break; } - return irq_linear_revmap(socrates_fpga_pic_irq_host, + return irq_find_mapping(socrates_fpga_pic_irq_host, (irq_hw_number_t)i); } diff --git a/arch/powerpc/platforms/8xx/cpm1-ic.c b/arch/powerpc/platforms/8xx/cpm1-ic.c index 1549f6cd29f4..a49d4a9ab3bc 100644 --- a/arch/powerpc/platforms/8xx/cpm1-ic.c +++ b/arch/powerpc/platforms/8xx/cpm1-ic.c @@ -59,7 +59,7 @@ static int cpm_get_irq(struct irq_desc *desc) cpm_vec = in_be16(&data->reg->cpic_civr); cpm_vec >>= 11; - return irq_linear_revmap(data->host, cpm_vec); + return irq_find_mapping(data->host, cpm_vec); } static void cpm_cascade(struct irq_desc *desc) diff --git a/arch/powerpc/platforms/8xx/pic.c b/arch/powerpc/platforms/8xx/pic.c index 7639f28172be..933d6ab7f512 100644 --- a/arch/powerpc/platforms/8xx/pic.c +++ b/arch/powerpc/platforms/8xx/pic.c @@ -80,7 +80,7 @@ unsigned int mpc8xx_get_irq(void) if (irq == PIC_VEC_SPURRIOUS) return 0; - return irq_linear_revmap(mpc8xx_pic_host, irq); + return irq_find_mapping(mpc8xx_pic_host, irq); } diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c index a41649bf0cb8..91a8f0a7086e 100644 --- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c @@ -173,7 +173,7 @@ unsigned int flipper_pic_get_irq(void) return 0; /* no more IRQs pending */ irq = __ffs(irq_status); - return irq_linear_revmap(flipper_irq_host, irq); + return irq_find_mapping(flipper_irq_host, irq); } /* diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c index 9abb3da36ba5..b57e87b0b3ce 100644 --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -190,7 +190,7 @@ static struct irq_domain *__init hlwd_pic_init(struct device_node *np) unsigned int hlwd_pic_get_irq(void) { unsigned int hwirq = __hlwd_pic_get_irq(hlwd_irq_host); - return hwirq ? irq_linear_revmap(hlwd_irq_host, hwirq) : 0; + return hwirq ? irq_find_mapping(hlwd_irq_host, hwirq) : 0; } /* diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 2eddc8bff7ab..c37783a03d25 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -250,7 +250,7 @@ static unsigned int pmac_pic_get_irq(void) raw_spin_unlock_irqrestore(&pmac_pic_lock, flags); if (unlikely(irq < 0)) return 0; - return irq_linear_revmap(pmac_pic_host, irq); + return irq_find_mapping(pmac_pic_host, irq); } static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node, diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index c63d72f17a3e..4a59ed1d62ce 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c @@ -207,7 +207,7 @@ unsigned int cpm2_get_irq(void) if (irq == 0) return(-1); - return irq_linear_revmap(cpm2_pic_host, irq); + return irq_find_mapping(cpm2_pic_host, irq); } static int cpm2_pic_host_map(struct irq_domain *h, unsigned int virq, diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c index 4ee8d36ca647..b6f9774038e1 100644 --- a/arch/powerpc/sysdev/ehv_pic.c +++ b/arch/powerpc/sysdev/ehv_pic.c @@ -175,7 +175,7 @@ unsigned int ehv_pic_get_irq(void) * this will also setup revmap[] in the slow path for the first * time, next calls will always use fast path by indexing revmap */ - return irq_linear_revmap(global_ehv_pic->irqhost, irq); + return irq_find_mapping(global_ehv_pic->irqhost, irq); } static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node, diff --git a/arch/powerpc/sysdev/ge/ge_pic.c b/arch/powerpc/sysdev/ge/ge_pic.c index 5b1f8dc3c960..0bc3f0b36528 100644 --- a/arch/powerpc/sysdev/ge/ge_pic.c +++ b/arch/powerpc/sysdev/ge/ge_pic.c @@ -245,7 +245,7 @@ unsigned int gef_pic_get_irq(void) if (active & (0x1 << hwirq)) break; } - virq = irq_linear_revmap(gef_pic_irq_host, + virq = irq_find_mapping(gef_pic_irq_host, (irq_hw_number_t)hwirq); } diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index f7b415ebb71c..70be2105865d 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -801,7 +801,7 @@ unsigned int ipic_get_irq(void) if (irq == 0) /* 0 --> no irq is pending */ return 0; - return irq_linear_revmap(primary_ipic->irqhost, irq); + return irq_find_mapping(primary_ipic->irqhost, irq); } #ifdef CONFIG_SUSPEND diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 3de090159a1b..787a88efdb35 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1785,7 +1785,7 @@ static unsigned int _mpic_get_one_irq(struct mpic *mpic, int reg) return 0; } - return irq_linear_revmap(mpic->irqhost, src); + return irq_find_mapping(mpic->irqhost, src); } unsigned int mpic_get_one_irq(struct mpic *mpic) @@ -1823,7 +1823,7 @@ unsigned int mpic_get_coreint_irq(void) return 0; } - return irq_linear_revmap(mpic->irqhost, src); + return irq_find_mapping(mpic->irqhost, src); #else return 0; #endif -- 2.51.0 From f569ac9cabfd983d3d3904dbc9d7dbbf13368f4b Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:35 +0100 Subject: [PATCH 03/16] sh: Switch to irq_find_mapping() irq_linear_revmap() is deprecated, so remove all its uses and supersede them by an identical call to irq_find_mapping(). [ tglx: Fix up subject prefix ] Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-43-jirislaby@kernel.org --- arch/sh/boards/mach-se/7343/irq.c | 2 +- arch/sh/boards/mach-se/7722/irq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c index 8241bdedcc82..730c01b225bd 100644 --- a/arch/sh/boards/mach-se/7343/irq.c +++ b/arch/sh/boards/mach-se/7343/irq.c @@ -71,7 +71,7 @@ static void __init se7343_gc_init(void) struct irq_chip_type *ct; unsigned int irq_base; - irq_base = irq_linear_revmap(se7343_irq_domain, 0); + irq_base = irq_find_mapping(se7343_irq_domain, 0); gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7343_irq_regs, handle_level_irq); diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c index 9a460a81907f..49aa3a2b1b8f 100644 --- a/arch/sh/boards/mach-se/7722/irq.c +++ b/arch/sh/boards/mach-se/7722/irq.c @@ -69,7 +69,7 @@ static void __init se7722_gc_init(void) struct irq_chip_type *ct; unsigned int irq_base; - irq_base = irq_linear_revmap(se7722_irq_domain, 0); + irq_base = irq_find_mapping(se7722_irq_domain, 0); gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7722_irq_regs, handle_level_irq); -- 2.51.0 From 30b6692ceda0dae971e9471479285b6b2b914aee Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:36 +0100 Subject: [PATCH 04/16] gpio: idt3243x: Switch to irq_find_mapping() irq_linear_revmap() is deprecated, so remove all its uses and supersede them by an identical call to irq_find_mapping(). [ tglx: Fix up subject prefix ] Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Reviewed-by: Linus Walleij Link: https://lore.kernel.org/all/20250319092951.37667-44-jirislaby@kernel.org --- drivers/gpio/gpio-idt3243x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-idt3243x.c b/drivers/gpio/gpio-idt3243x.c index 00f547d26254..535f25514455 100644 --- a/drivers/gpio/gpio-idt3243x.c +++ b/drivers/gpio/gpio-idt3243x.c @@ -37,7 +37,7 @@ static void idt_gpio_dispatch(struct irq_desc *desc) pending = readl(ctrl->pic + IDT_PIC_IRQ_PEND); pending &= ~ctrl->mask_cache; for_each_set_bit(bit, &pending, gc->ngpio) { - virq = irq_linear_revmap(gc->irq.domain, bit); + virq = irq_find_mapping(gc->irq.domain, bit); if (virq) generic_handle_irq(virq); } -- 2.51.0 From e68664c08e3980f394d0bf22c64ce3cd2a3929e2 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:37 +0100 Subject: [PATCH 05/16] gpu: ipu-v3: Switch to irq_find_mapping() irq_linear_revmap() is deprecated, so remove all its uses and supersede them by an identical call to irq_find_mapping(). [ tglx: Fix up subject prefix ] Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-45-jirislaby@kernel.org --- drivers/gpu/ipu-v3/ipu-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 223e6d563a6b..333f36e0a715 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -1008,7 +1008,7 @@ int ipu_map_irq(struct ipu_soc *ipu, int irq) { int virq; - virq = irq_linear_revmap(ipu->domain, irq); + virq = irq_find_mapping(ipu->domain, irq); if (!virq) virq = irq_create_mapping(ipu->domain, irq); @@ -1219,7 +1219,7 @@ static void ipu_irq_exit(struct ipu_soc *ipu) /* TODO: remove irq_domain_generic_chips */ for (i = 0; i < IPU_NUM_IRQS; i++) { - irq = irq_linear_revmap(ipu->domain, i); + irq = irq_find_mapping(ipu->domain, i); if (irq) irq_dispose_mapping(irq); } -- 2.51.0 From 31b3ad400245b5ddf8081394330ba460f8b431e7 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:39 +0100 Subject: [PATCH 06/16] irqchip/armada-370-xp: Switch to irq_find_mapping() irq_linear_revmap() is deprecated, so remove all its uses and supersede them by an identical call to irq_find_mapping(). [ tglx: Fix up subject prefix ] Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-47-jirislaby@kernel.org --- drivers/irqchip/irq-armada-370-xp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index e51612992735..67b672a78862 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -546,7 +546,7 @@ static void mpic_reenable_percpu(struct mpic *mpic) { /* Re-enable per-CPU interrupts that were enabled before suspend */ for (irq_hw_number_t i = 0; i < MPIC_PER_CPU_IRQS_NR; i++) { - unsigned int virq = irq_linear_revmap(mpic->domain, i); + unsigned int virq = irq_find_mapping(mpic->domain, i); struct irq_data *d; if (!virq || !irq_percpu_is_enabled(virq)) @@ -740,7 +740,7 @@ static void mpic_resume(void) /* Re-enable interrupts */ for (irq_hw_number_t i = 0; i < mpic->domain->hwirq_max; i++) { - unsigned int virq = irq_linear_revmap(mpic->domain, i); + unsigned int virq = irq_find_mapping(mpic->domain, i); struct irq_data *d; if (!virq) -- 2.51.0 From 609f900ad6093af6f97a313c4bacf4ca3757db4a Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:40 +0100 Subject: [PATCH 07/16] pinctrl: keembay: Switch to irq_find_mapping() irq_linear_revmap() is deprecated, so remove all its uses and supersede them by an identical call to irq_find_mapping(). [ tglx: Fix up subject prefix ] Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Reviewed-by: Linus Walleij Link: https://lore.kernel.org/all/20250319092951.37667-48-jirislaby@kernel.org --- drivers/pinctrl/pinctrl-keembay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-keembay.c b/drivers/pinctrl/pinctrl-keembay.c index b693f4787044..0d7cc8280ea2 100644 --- a/drivers/pinctrl/pinctrl-keembay.c +++ b/drivers/pinctrl/pinctrl-keembay.c @@ -1268,7 +1268,7 @@ static void keembay_gpio_irq_handler(struct irq_desc *desc) for_each_set_clump8(bit, clump, ®, BITS_PER_TYPE(typeof(reg))) { pin = clump & ~KEEMBAY_GPIO_IRQ_ENABLE; val = keembay_read_pin(kpc->base0 + KEEMBAY_GPIO_DATA_IN, pin); - kmb_irq = irq_linear_revmap(gc->irq.domain, pin); + kmb_irq = irq_find_mapping(gc->irq.domain, pin); /* Checks if the interrupt is enabled */ if (val && (clump & KEEMBAY_GPIO_IRQ_ENABLE)) -- 2.51.0 From 14ebb11ba895c9223d9a453a17df2fd81410c96c Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:42 +0100 Subject: [PATCH 08/16] irqdomain: Drop irq_linear_revmap() irq_linear_revmap() is deprecated and unused now. So remove it. Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-50-jirislaby@kernel.org --- Documentation/core-api/irq/irq-domain.rst | 2 -- .../translations/zh_CN/core-api/irq/irq-domain.rst | 2 -- include/linux/irqdomain.h | 6 ------ 3 files changed, 10 deletions(-) diff --git a/Documentation/core-api/irq/irq-domain.rst b/Documentation/core-api/irq/irq-domain.rst index 7624607a171b..c365c3ed4eba 100644 --- a/Documentation/core-api/irq/irq-domain.rst +++ b/Documentation/core-api/irq/irq-domain.rst @@ -62,8 +62,6 @@ variety of methods: mapping. - irq_find_mapping() returns a Linux IRQ number for a given domain and hwirq number, and 0 if there was no mapping -- irq_linear_revmap() is now identical to irq_find_mapping(), and is - deprecated - generic_handle_domain_irq() handles an interrupt described by a domain and a hwirq number diff --git a/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst b/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst index 913c3eda3f74..4a2d3b27aa4d 100644 --- a/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst +++ b/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst @@ -60,8 +60,6 @@ irq_domain和一个hwirq号作为参数。 如果hwirq的映射还不存在, - irq_find_mapping()返回给定域和hwirq的Linux IRQ号,如果没有映射则返回0。 -- irq_linear_revmap()现与irq_find_mapping()相同,已被废弃。 - - generic_handle_domain_irq()处理一个由域和hwirq号描述的中断。 请注意,irq域的查找必须发生在与RCU读临界区兼容的上下文中。 diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 712c662de981..c8e55cd1e352 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -492,12 +492,6 @@ static inline unsigned int irq_find_mapping(struct irq_domain *domain, return 0; } -static inline unsigned int irq_linear_revmap(struct irq_domain *domain, - irq_hw_number_t hwirq) -{ - return irq_find_mapping(domain, hwirq); -} - extern const struct irq_domain_ops irq_domain_simple_ops; /* stock xlate functions */ -- 2.51.0 From 18e743e911020eb74cc4eaf549c18ed12a5acb9a Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:43 +0100 Subject: [PATCH 09/16] irqdomain: Use irq_domain_instantiate()'s return value as initializers This makes the code more compact. Note that irq_domain_create_hierarchy()'s handling of size is now part of info's initializer (using the ternary operator). That makes more sense while reading it. Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-51-jirislaby@kernel.org --- include/linux/irqdomain.h | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index c8e55cd1e352..1e3858438e69 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -403,9 +403,8 @@ static inline struct irq_domain *irq_domain_create_nomap(struct fwnode_handle *f .ops = ops, .host_data = host_data, }; - struct irq_domain *d; + struct irq_domain *d = irq_domain_instantiate(&info); - d = irq_domain_instantiate(&info); return IS_ERR(d) ? NULL : d; } @@ -424,9 +423,8 @@ static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle * .ops = ops, .host_data = host_data, }; - struct irq_domain *d; + struct irq_domain *d = irq_domain_instantiate(&info); - d = irq_domain_instantiate(&info); return IS_ERR(d) ? NULL : d; } @@ -440,9 +438,8 @@ static inline struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fw .ops = ops, .host_data = host_data, }; - struct irq_domain *d; + struct irq_domain *d = irq_domain_instantiate(&info); - d = irq_domain_instantiate(&info); return IS_ERR(d) ? NULL : d; } @@ -554,18 +551,14 @@ static inline struct irq_domain *irq_domain_create_hierarchy(struct irq_domain * struct irq_domain_info info = { .fwnode = fwnode, .size = size, - .hwirq_max = size, + .hwirq_max = size ? : ~0U, .ops = ops, .host_data = host_data, .domain_flags = flags, .parent = parent, }; - struct irq_domain *d; + struct irq_domain *d = irq_domain_instantiate(&info); - if (!info.size) - info.hwirq_max = ~0U; - - d = irq_domain_instantiate(&info); return IS_ERR(d) ? NULL : d; } -- 2.51.0 From 66cbf17fe67156608421e717975c415a85c08466 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:44 +0100 Subject: [PATCH 10/16] irqdomain: Make struct irq_domain_info variables const This is just expressing it explicitly as irq_domain_instantiate() takes const already. No functional change. Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-52-jirislaby@kernel.org --- include/linux/irqdomain.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 1e3858438e69..66a26dfd254b 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -396,7 +396,7 @@ static inline struct irq_domain *irq_domain_create_nomap(struct fwnode_handle *f const struct irq_domain_ops *ops, void *host_data) { - struct irq_domain_info info = { + const struct irq_domain_info info = { .fwnode = fwnode, .hwirq_max = max_irq, .direct_max = max_irq, @@ -416,7 +416,7 @@ static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle * const struct irq_domain_ops *ops, void *host_data) { - struct irq_domain_info info = { + const struct irq_domain_info info = { .fwnode = fwnode, .size = size, .hwirq_max = size, @@ -432,7 +432,7 @@ static inline struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fw const struct irq_domain_ops *ops, void *host_data) { - struct irq_domain_info info = { + const struct irq_domain_info info = { .fwnode = fwnode, .hwirq_max = ~0, .ops = ops, @@ -548,7 +548,7 @@ static inline struct irq_domain *irq_domain_create_hierarchy(struct irq_domain * const struct irq_domain_ops *ops, void *host_data) { - struct irq_domain_info info = { + const struct irq_domain_info info = { .fwnode = fwnode, .size = size, .hwirq_max = size ? : ~0U, -- 2.51.0 From 2272a78b3f4a7a1621f00ac6e9c9232d12b7ff01 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:45 +0100 Subject: [PATCH 11/16] irqdomain: Improve kernel-docs of functions Many of irqdomain.h's functions are referenced in Documentation/ but are not properly documented. Therefore, document these. And use "Returns:" tag consistently, so that it is properly generated in the resulting docs. Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-53-jirislaby@kernel.org --- include/linux/irqdomain.h | 42 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 66a26dfd254b..a70e2ba0b91f 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -411,6 +411,15 @@ static inline struct irq_domain *irq_domain_create_nomap(struct fwnode_handle *f unsigned int irq_create_direct_mapping(struct irq_domain *domain); #endif +/** + * irq_domain_create_linear - Allocate and register a linear revmap irq_domain. + * @fwnode: pointer to interrupt controller's FW node. + * @size: Number of interrupts in the domain. + * @ops: map/unmap domain callbacks + * @host_data: Controller private data pointer + * + * Returns: Newly created irq_domain + */ static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle *fwnode, unsigned int size, const struct irq_domain_ops *ops, @@ -457,6 +466,18 @@ unsigned int irq_create_mapping_affinity(struct irq_domain *domain, unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec); void irq_dispose_mapping(unsigned int virq); +/** + * irq_create_mapping - Map a hardware interrupt into linux irq space + * @domain: domain owning this hardware interrupt or NULL for default domain + * @hwirq: hardware irq number in that domain space + * + * Only one mapping per hardware interrupt is permitted. + * + * If the sense/trigger is to be specified, set_irq_type() should be called + * on the number returned from that call. + * + * Returns: Linux irq number or 0 on error + */ static inline unsigned int irq_create_mapping(struct irq_domain *domain, irq_hw_number_t hwirq) { @@ -467,6 +488,13 @@ struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain, irq_hw_number_t hwirq, unsigned int *irq); +/** + * irq_resolve_mapping - Find a linux irq from a hw irq number. + * @domain: domain owning this hardware interrupt + * @hwirq: hardware irq number in that domain space + * + * Returns: Interrupt descriptor + */ static inline struct irq_desc *irq_resolve_mapping(struct irq_domain *domain, irq_hw_number_t hwirq) { @@ -477,6 +505,8 @@ static inline struct irq_desc *irq_resolve_mapping(struct irq_domain *domain, * irq_find_mapping() - Find a linux irq from a hw irq number. * @domain: domain owning this hardware interrupt * @hwirq: hardware irq number in that domain space + * + * Returns: Linux irq number or 0 if not found */ static inline unsigned int irq_find_mapping(struct irq_domain *domain, irq_hw_number_t hwirq) @@ -539,7 +569,8 @@ void irq_domain_reset_irq_data(struct irq_data *irq_data); * * If successful the parent is associated to the new domain and the * domain flags are set. - * Returns pointer to IRQ domain, or NULL on failure. + * + * Returns: A pointer to IRQ domain, or %NULL on failure. */ static inline struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent, unsigned int flags, @@ -570,6 +601,15 @@ void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs); int irq_domain_activate_irq(struct irq_data *irq_data, bool early); void irq_domain_deactivate_irq(struct irq_data *irq_data); +/** + * irq_domain_alloc_irqs - Allocate IRQs from domain + * @domain: domain to allocate from + * @nr_irqs: number of IRQs to allocate + * @node: NUMA node id for memory allocation + * @arg: domain specific argument + * + * See __irq_domain_alloc_irqs()' documentation. + */ static inline int irq_domain_alloc_irqs(struct irq_domain *domain, unsigned int nr_irqs, int node, void *arg) { -- 2.51.0 From 2f7bd3293e4512323fd5334ef13cf2826de27666 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:46 +0100 Subject: [PATCH 12/16] Documentation: irq/concepts: Add commas and reflow For easier reading, it is always desired to add commas at some places in text. Like before adverbs or after fronted sentences. [ tglx: Fix up subject prefix ] Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-54-jirislaby@kernel.org --- Documentation/core-api/irq/concepts.rst | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Documentation/core-api/irq/concepts.rst b/Documentation/core-api/irq/concepts.rst index 4273806a606b..f166006a81f6 100644 --- a/Documentation/core-api/irq/concepts.rst +++ b/Documentation/core-api/irq/concepts.rst @@ -2,23 +2,22 @@ What is an IRQ? =============== -An IRQ is an interrupt request from a device. -Currently they can come in over a pin, or over a packet. -Several devices may be connected to the same pin thus -sharing an IRQ. +An IRQ is an interrupt request from a device. Currently, they can come +in over a pin, or over a packet. Several devices may be connected to +the same pin thus sharing an IRQ. An IRQ number is a kernel identifier used to talk about a hardware -interrupt source. Typically this is an index into the global irq_desc -array, but except for what linux/interrupt.h implements the details +interrupt source. Typically, this is an index into the global irq_desc +array, but except for what linux/interrupt.h implements, the details are architecture specific. An IRQ number is an enumeration of the possible interrupt sources on a -machine. Typically what is enumerated is the number of input pins on -all of the interrupt controller in the system. In the case of ISA +machine. Typically, what is enumerated is the number of input pins on +all of the interrupt controllers in the system. In the case of ISA, what is enumerated are the 16 input pins on the two i8259 interrupt controllers. Architectures can assign additional meaning to the IRQ numbers, and -are encouraged to in the case where there is any manual configuration -of the hardware involved. The ISA IRQs are a classic example of +are encouraged to in the case where there is any manual configuration +of the hardware involved. The ISA IRQs are a classic example of assigning this kind of additional meaning. -- 2.51.0 From 225942f06e93dc4c24ce50df92e0eb5bcd2afbac Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:47 +0100 Subject: [PATCH 13/16] Documentation: irq/concepts: Minor improvements Just note in the docs: 1) A PCI device as an example for shared interrupts 2) A sparse tree can be used for interrupts too 3) i8259s which have 8 pins [ tglx: Fix up subject prefix ] Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-55-jirislaby@kernel.org --- Documentation/core-api/irq/concepts.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Documentation/core-api/irq/concepts.rst b/Documentation/core-api/irq/concepts.rst index f166006a81f6..7c4564f3cbdf 100644 --- a/Documentation/core-api/irq/concepts.rst +++ b/Documentation/core-api/irq/concepts.rst @@ -4,18 +4,20 @@ What is an IRQ? An IRQ is an interrupt request from a device. Currently, they can come in over a pin, or over a packet. Several devices may be connected to -the same pin thus sharing an IRQ. +the same pin thus sharing an IRQ. Such as on legacy PCI bus: All devices +typically share 4 lanes/pins. Note that each device can request an +interrupt on each of the lanes. An IRQ number is a kernel identifier used to talk about a hardware interrupt source. Typically, this is an index into the global irq_desc -array, but except for what linux/interrupt.h implements, the details -are architecture specific. +array or sparse_irqs tree. But except for what linux/interrupt.h +implements, the details are architecture specific. An IRQ number is an enumeration of the possible interrupt sources on a machine. Typically, what is enumerated is the number of input pins on all of the interrupt controllers in the system. In the case of ISA, -what is enumerated are the 16 input pins on the two i8259 interrupt -controllers. +what is enumerated are the 8 input pins on each of the two i8259 +interrupt controllers. Architectures can assign additional meaning to the IRQ numbers, and are encouraged to in the case where there is any manual configuration -- 2.51.0 From 95cfac1b2f85ed883b1748d7955e00f0980c1bb3 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:48 +0100 Subject: [PATCH 14/16] Documentation: irq-domain.rst: Simple improvements The improvements include: * Capitals in headlines. * Add commas: for easier reading, it is always desired to add commas at some places in text. Like before adverbs or after fronted sentences. * 3rd person -> add 's' to verbs. * End some sentences with period and start a new one. Avoid thus heavy sentences. [ tglx: Fix up subject prefix ] Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-56-jirislaby@kernel.org --- Documentation/core-api/irq/irq-domain.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Documentation/core-api/irq/irq-domain.rst b/Documentation/core-api/irq/irq-domain.rst index c365c3ed4eba..cb25649d0bb7 100644 --- a/Documentation/core-api/irq/irq-domain.rst +++ b/Documentation/core-api/irq/irq-domain.rst @@ -1,19 +1,19 @@ =============================================== -The irq_domain interrupt number mapping library +The irq_domain Interrupt Number Mapping Library =============================================== The current design of the Linux kernel uses a single large number space where each separate IRQ source is assigned a different number. This is simple when there is only one interrupt controller, but in -systems with multiple interrupt controllers the kernel must ensure +systems with multiple interrupt controllers, the kernel must ensure that each one gets assigned non-overlapping allocations of Linux IRQ numbers. The number of interrupt controllers registered as unique irqchips -show a rising tendency: for example subdrivers of different kinds +shows a rising tendency. For example, subdrivers of different kinds such as GPIO controllers avoid reimplementing identical callback mechanisms as the IRQ core system by modelling their interrupt -handlers as irqchips, i.e. in effect cascading interrupt controllers. +handlers as irqchips. I.e. in effect cascading interrupt controllers. Here the interrupt number loose all kind of correspondence to hardware interrupt numbers: whereas in the past, IRQ numbers could @@ -21,15 +21,15 @@ be chosen so they matched the hardware IRQ line into the root interrupt controller (i.e. the component actually fireing the interrupt line to the CPU) nowadays this number is just a number. -For this reason we need a mechanism to separate controller-local -interrupt numbers, called hardware irq's, from Linux IRQ numbers. +For this reason, we need a mechanism to separate controller-local +interrupt numbers, called hardware IRQs, from Linux IRQ numbers. The irq_alloc_desc*() and irq_free_desc*() APIs provide allocation of irq numbers, but they don't provide any support for reverse mapping of the controller-local IRQ (hwirq) number into the Linux IRQ number space. -The irq_domain library adds mapping between hwirq and IRQ numbers on +The irq_domain library adds a mapping between hwirq and IRQ numbers on top of the irq_alloc_desc*() API. An irq_domain to manage mapping is preferred over interrupt controller drivers open coding their own reverse mapping scheme. @@ -38,7 +38,7 @@ irq_domain also implements translation from an abstract irq_fwspec structure to hwirq numbers (Device Tree and ACPI GSI so far), and can be easily extended to support other IRQ topology data sources. -irq_domain usage +irq_domain Usage ================ An interrupt controller driver creates and registers an irq_domain by @@ -76,7 +76,7 @@ If the driver has the Linux IRQ number or the irq_data pointer, and needs to know the associated hwirq number (such as in the irq_chip callbacks) then it can be directly obtained from irq_data->hwirq. -Types of irq_domain mappings +Types of irq_domain Mappings ============================ There are several mechanisms available for reverse mapping from hwirq @@ -101,7 +101,7 @@ map are fixed time lookup for IRQ numbers, and irq_descs are only allocated for in-use IRQs. The disadvantage is that the table must be as large as the largest possible hwirq number. -The majority of drivers should use the linear map. +The majority of drivers should use the Linear map. Tree ---- @@ -189,7 +189,7 @@ that the driver using the simple domain call irq_create_mapping() before any irq_find_mapping() since the latter will actually work for the static IRQ assignment case. -Hierarchy IRQ domain +Hierarchy IRQ Domain -------------------- On some architectures, there may be multiple interrupt controllers -- 2.51.0 From a4efe303e50e3222591ab6ec5eb0ea92b7260d96 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:49 +0100 Subject: [PATCH 15/16] Documentation: irqdomain: Update it The irqdomain documentaion became obsolete over time. Update and extend it a bit with respect to the current code and HW. Most notably the doubled documentation of irq_domain (from .rst and .h) was unified and let only in .rst. A reference link was added to .h. Furthermore: * Add some 'struct' keywords, so that the respective structs are hyperlinked * :c:member: use where appropriate to mark a member of a struct * Rephrase some wording to improve readability/understanding Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-57-jirislaby@kernel.org --- Documentation/core-api/irq/irq-domain.rst | 122 +++++++++++++--------- include/linux/irqdomain.h | 26 +---- 2 files changed, 76 insertions(+), 72 deletions(-) diff --git a/Documentation/core-api/irq/irq-domain.rst b/Documentation/core-api/irq/irq-domain.rst index cb25649d0bb7..67d45b3405cb 100644 --- a/Documentation/core-api/irq/irq-domain.rst +++ b/Documentation/core-api/irq/irq-domain.rst @@ -3,8 +3,8 @@ The irq_domain Interrupt Number Mapping Library =============================================== The current design of the Linux kernel uses a single large number -space where each separate IRQ source is assigned a different number. -This is simple when there is only one interrupt controller, but in +space where each separate IRQ source is assigned a unique number. +This is simple when there is only one interrupt controller. But in systems with multiple interrupt controllers, the kernel must ensure that each one gets assigned non-overlapping allocations of Linux IRQ numbers. @@ -15,44 +15,63 @@ such as GPIO controllers avoid reimplementing identical callback mechanisms as the IRQ core system by modelling their interrupt handlers as irqchips. I.e. in effect cascading interrupt controllers. -Here the interrupt number loose all kind of correspondence to -hardware interrupt numbers: whereas in the past, IRQ numbers could -be chosen so they matched the hardware IRQ line into the root -interrupt controller (i.e. the component actually fireing the -interrupt line to the CPU) nowadays this number is just a number. +So in the past, IRQ numbers could be chosen so that they match the +hardware IRQ line into the root interrupt controller (i.e. the +component actually firing the interrupt line to the CPU). Nowadays, +this number is just a number and the number loose all kind of +correspondence to hardware interrupt numbers. For this reason, we need a mechanism to separate controller-local interrupt numbers, called hardware IRQs, from Linux IRQ numbers. The irq_alloc_desc*() and irq_free_desc*() APIs provide allocation of -irq numbers, but they don't provide any support for reverse mapping of +IRQ numbers, but they don't provide any support for reverse mapping of the controller-local IRQ (hwirq) number into the Linux IRQ number space. The irq_domain library adds a mapping between hwirq and IRQ numbers on -top of the irq_alloc_desc*() API. An irq_domain to manage mapping is -preferred over interrupt controller drivers open coding their own +top of the irq_alloc_desc*() API. An irq_domain to manage the mapping +is preferred over interrupt controller drivers open coding their own reverse mapping scheme. -irq_domain also implements translation from an abstract irq_fwspec -structure to hwirq numbers (Device Tree and ACPI GSI so far), and can -be easily extended to support other IRQ topology data sources. +irq_domain also implements a translation from an abstract struct +irq_fwspec to hwirq numbers (Device Tree, non-DT firmware node, ACPI +GSI, and software node so far), and can be easily extended to support +other IRQ topology data sources. The implementation is performed +without any extra platform support code. irq_domain Usage ================ - -An interrupt controller driver creates and registers an irq_domain by -calling one of the irq_domain_create_*() functions. The function will -return a pointer to the irq_domain on success. The caller must provide the -allocator function with an irq_domain_ops structure. +struct irq_domain could be defined as an irq domain controller. That +is, it handles the mapping between hardware and virtual interrupt +numbers for a given interrupt domain. The domain structure is +generally created by the PIC code for a given PIC instance (though a +domain can cover more than one PIC if they have a flat number model). +It is the domain callbacks that are responsible for setting the +irq_chip on a given irq_desc after it has been mapped. + +The host code and data structures use a fwnode_handle pointer to +identify the domain. In some cases, and in order to preserve source +code compatibility, this fwnode pointer is "upgraded" to a DT +device_node. For those firmware infrastructures that do not provide a +unique identifier for an interrupt controller, the irq_domain code +offers a fwnode allocator. + +An interrupt controller driver creates and registers a struct irq_domain +by calling one of the irq_domain_create_*() functions (each mapping +method has a different allocator function, more on that later). The +function will return a pointer to the struct irq_domain on success. The +caller must provide the allocator function with a struct irq_domain_ops +pointer. In most cases, the irq_domain will begin empty without any mappings between hwirq and IRQ numbers. Mappings are added to the irq_domain by calling irq_create_mapping() which accepts the irq_domain and a -hwirq number as arguments. If a mapping for the hwirq doesn't already -exist then it will allocate a new Linux irq_desc, associate it with -the hwirq, and call the .map() callback so the driver can perform any -required hardware setup. +hwirq number as arguments. If a mapping for the hwirq doesn't already +exist, irq_create_mapping() allocates a new Linux irq_desc, associates +it with the hwirq, and calls the :c:member:`irq_domain_ops.map()` +callback. In there, the driver can perform any required hardware +setup. Once a mapping has been established, it can be retrieved or used via a variety of methods: @@ -74,7 +93,8 @@ be allocated. If the driver has the Linux IRQ number or the irq_data pointer, and needs to know the associated hwirq number (such as in the irq_chip -callbacks) then it can be directly obtained from irq_data->hwirq. +callbacks) then it can be directly obtained from +:c:member:`irq_data.hwirq`. Types of irq_domain Mappings ============================ @@ -230,20 +250,40 @@ There are four major interfaces to use hierarchy irq_domain: 4) irq_domain_deactivate_irq(): deactivate interrupt controller hardware to stop delivering the interrupt. -Following changes are needed to support hierarchy irq_domain: +The following is needed to support hierarchy irq_domain: -1) a new field 'parent' is added to struct irq_domain; it's used to +1) The :c:member:`parent` field in struct irq_domain is used to maintain irq_domain hierarchy information. -2) a new field 'parent_data' is added to struct irq_data; it's used to - build hierarchy irq_data to match hierarchy irq_domains. The irq_data - is used to store irq_domain pointer and hardware irq number. -3) new callbacks are added to struct irq_domain_ops to support hierarchy - irq_domain operations. - -With support of hierarchy irq_domain and hierarchy irq_data ready, an -irq_domain structure is built for each interrupt controller, and an +2) The :c:member:`parent_data` field in struct irq_data is used to + build hierarchy irq_data to match hierarchy irq_domains. The + irq_data is used to store irq_domain pointer and hardware irq + number. +3) The :c:member:`alloc()`, :c:member:`free()`, and other callbacks in + struct irq_domain_ops to support hierarchy irq_domain operations. + +With the support of hierarchy irq_domain and hierarchy irq_data ready, +an irq_domain structure is built for each interrupt controller, and an irq_data structure is allocated for each irq_domain associated with an -IRQ. Now we could go one step further to support stacked(hierarchy) +IRQ. + +For an interrupt controller driver to support hierarchy irq_domain, it +needs to: + +1) Implement irq_domain_ops.alloc() and irq_domain_ops.free() +2) Optionally, implement irq_domain_ops.activate() and + irq_domain_ops.deactivate(). +3) Optionally, implement an irq_chip to manage the interrupt controller + hardware. +4) There is no need to implement irq_domain_ops.map() and + irq_domain_ops.unmap(). They are unused with hierarchy irq_domain. + +Note the hierarchy irq_domain is in no way x86-specific, and is +heavily used to support other architectures, such as ARM, ARM64 etc. + +Stacked irq_chip +~~~~~~~~~~~~~~~~ + +Now, we could go one step further to support stacked (hierarchy) irq_chip. That is, an irq_chip is associated with each irq_data along the hierarchy. A child irq_chip may implement a required action by itself or by cooperating with its parent irq_chip. @@ -253,20 +293,6 @@ with the hardware managed by itself and may ask for services from its parent irq_chip when needed. So we could achieve a much cleaner software architecture. -For an interrupt controller driver to support hierarchy irq_domain, it -needs to: - -1) Implement irq_domain_ops.alloc and irq_domain_ops.free -2) Optionally implement irq_domain_ops.activate and - irq_domain_ops.deactivate. -3) Optionally implement an irq_chip to manage the interrupt controller - hardware. -4) No need to implement irq_domain_ops.map and irq_domain_ops.unmap, - they are unused with hierarchy irq_domain. - -Hierarchy irq_domain is in no way x86 specific, and is heavily used to -support other architectures, such as ARM, ARM64 etc. - Debugging ========= diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index a70e2ba0b91f..1a1786dc19d2 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -1,30 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * irq_domain - IRQ translation domains + * irq_domain - IRQ Translation Domains * - * Translation infrastructure between hw and linux irq numbers. This is - * helpful for interrupt controllers to implement mapping between hardware - * irq numbers and the Linux irq number space. - * - * irq_domains also have hooks for translating device tree or other - * firmware interrupt representations into a hardware irq number that - * can be mapped back to a Linux irq number without any extra platform - * support code. - * - * Interrupt controller "domain" data structure. This could be defined as a - * irq domain controller. That is, it handles the mapping between hardware - * and virtual interrupt numbers for a given interrupt domain. The domain - * structure is generally created by the PIC code for a given PIC instance - * (though a domain can cover more than one PIC if they have a flat number - * model). It's the domain callbacks that are responsible for setting the - * irq_chip on a given irq_desc after it's been mapped. - * - * The host code and data structures use a fwnode_handle pointer to - * identify the domain. In some cases, and in order to preserve source - * code compatibility, this fwnode pointer is "upgraded" to a DT - * device_node. For those firmware infrastructures that do not provide - * a unique identifier for an interrupt controller, the irq_domain - * code offers a fwnode allocator. + * See Documentation/core-api/irq/irq-domain.rst for the details. */ #ifndef _LINUX_IRQDOMAIN_H -- 2.51.0 From a10024e671d12c8125a8f31d08c67245f6dee16d Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:50 +0100 Subject: [PATCH 16/16] irqdomain: Fix kernel-doc and add it to Documentation irqdomain.c's kernel-doc exists, but is not plugged into Documentation/ yet. Before plugging it in, fix it first: irq_domain_get_irq_data() and irq_domain_set_info() were documented twice. Identically, by both definitions for CONFIG_IRQ_DOMAIN_HIERARCHY and !CONFIG_IRQ_DOMAIN_HIERARCHY. Therefore, switch the second kernel-doc into an ordinary comment -- change "/**" to simple "/*". This avoids sphinx's: WARNING: Duplicate C declaration Next, in commit b7b377332b96 ("irqdomain: Fix the kernel-doc and plug it into Documentation"), irqdomain.h's (header) kernel-doc was added into core-api/genericirq.rst. But given the amount of irqdomain functions and structures, move all these to core-api/irq/irq-domain.rst now. Finally, add these newly fixed irqdomain.c's (source) docs there as well. Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250319092951.37667-58-jirislaby@kernel.org --- Documentation/core-api/genericirq.rst | 2 -- Documentation/core-api/irq/irq-domain.rst | 20 ++++++++++++++++++++ kernel/irq/irqdomain.c | 4 ++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Documentation/core-api/genericirq.rst b/Documentation/core-api/genericirq.rst index 25f94dfd66fa..582bde9bf5a9 100644 --- a/Documentation/core-api/genericirq.rst +++ b/Documentation/core-api/genericirq.rst @@ -410,8 +410,6 @@ which are used in the generic IRQ layer. .. kernel-doc:: include/linux/interrupt.h :internal: -.. kernel-doc:: include/linux/irqdomain.h - Public Functions Provided ========================= diff --git a/Documentation/core-api/irq/irq-domain.rst b/Documentation/core-api/irq/irq-domain.rst index 67d45b3405cb..a01c6ead1bc0 100644 --- a/Documentation/core-api/irq/irq-domain.rst +++ b/Documentation/core-api/irq/irq-domain.rst @@ -298,3 +298,23 @@ Debugging Most of the internals of the IRQ subsystem are exposed in debugfs by turning CONFIG_GENERIC_IRQ_DEBUGFS on. + +Structures and Public Functions Provided +======================================== + +This chapter contains the autogenerated documentation of the structures +and exported kernel API functions which are used for IRQ domains. + +.. kernel-doc:: include/linux/irqdomain.h + +.. kernel-doc:: kernel/irq/irqdomain.c + :export: + +Internal Functions Provided +=========================== + +This chapter contains the autogenerated documentation of the internal +functions. + +.. kernel-doc:: kernel/irq/irqdomain.c + :internal: diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 57098c79750f..c8b6de09047b 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1996,7 +1996,7 @@ static void irq_domain_check_hierarchy(struct irq_domain *domain) domain->flags |= IRQ_DOMAIN_FLAG_HIERARCHY; } #else /* CONFIG_IRQ_DOMAIN_HIERARCHY */ -/** +/* * irq_domain_get_irq_data - Get irq_data associated with @virq and @domain * @domain: domain to match * @virq: IRQ number to get irq_data @@ -2010,7 +2010,7 @@ struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, } EXPORT_SYMBOL_GPL(irq_domain_get_irq_data); -/** +/* * irq_domain_set_info - Set the complete data for a @virq in @domain * @domain: Interrupt domain to match * @virq: IRQ number -- 2.51.0