From 9f0831682519a50071fe3c74ab65d73c8282b307 Mon Sep 17 00:00:00 2001 From: Alison Montag Date: Thu, 13 Aug 2026 11:04:54 -0500 Subject: [PATCH] Add NI_IRQ_RESOLVER Adds a resolver that translates hwirqs to virq for use by NI proprietary drivers. In previous kernels, they were equivalent, but in 6.18, they are no longer guaranteed. Required on zynq targets. Signed-off-by: Alison Montag --- MAINTAINERS | 6 +++ arch/arm/configs/nati_bluefin_defconfig | 1 + arch/arm/configs/nati_slsc_defconfig | 1 + arch/arm/configs/nati_zynq_defconfig | 1 + drivers/misc/Kconfig | 10 +++++ drivers/misc/Makefile | 1 + drivers/misc/niirqresolver.c | 56 +++++++++++++++++++++++++ include/linux/niirqresolver.h | 23 ++++++++++ 8 files changed, 99 insertions(+) create mode 100644 drivers/misc/niirqresolver.c create mode 100644 include/linux/niirqresolver.h diff --git a/MAINTAINERS b/MAINTAINERS index 6161a4507e4ec..b1a81b684f504 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17699,6 +17699,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next F: drivers/mtd/nand/ F: include/linux/mtd/*nand*.h +NATIONAL INSTRUMENTS DEVICETREE IRQ RESOLVER +M: Alison Montag +S: Maintained +F: drivers/misc/niirqresolver.c +F: include/linux/niirqresolver.h + NATIONAL INSTRUMENTS SERIAL DRIVER M: Chaitanya Vadrevu L: linux-serial@vger.kernel.org diff --git a/arch/arm/configs/nati_bluefin_defconfig b/arch/arm/configs/nati_bluefin_defconfig index 5cb1e0e1b40d4..d93765d777db9 100644 --- a/arch/arm/configs/nati_bluefin_defconfig +++ b/arch/arm/configs/nati_bluefin_defconfig @@ -82,6 +82,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_SRAM=y +CONFIG_NI_IRQ_RESOLVER=y CONFIG_EEPROM_AT24=y CONFIG_EEPROM_AT25=y CONFIG_SCSI=y diff --git a/arch/arm/configs/nati_slsc_defconfig b/arch/arm/configs/nati_slsc_defconfig index 4546c323117d8..1aa2a20e48601 100644 --- a/arch/arm/configs/nati_slsc_defconfig +++ b/arch/arm/configs/nati_slsc_defconfig @@ -71,6 +71,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_SRAM=y +CONFIG_NI_IRQ_RESOLVER=y CONFIG_EEPROM_AT24=y CONFIG_EEPROM_AT25=y CONFIG_EEPROM_93CX6=m diff --git a/arch/arm/configs/nati_zynq_defconfig b/arch/arm/configs/nati_zynq_defconfig index 8b849b1760254..eafc0445dc284 100644 --- a/arch/arm/configs/nati_zynq_defconfig +++ b/arch/arm/configs/nati_zynq_defconfig @@ -179,6 +179,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_FPGA_PERIPHERAL=y CONFIG_NIZYNQ_CPLD=y CONFIG_SRAM=y +CONFIG_NI_IRQ_RESOLVER=y CONFIG_EEPROM_AT24=y CONFIG_EEPROM_AT25=y CONFIG_SCSI=y diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 7f369157c4609..b25f99b0e82dc 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -694,6 +694,16 @@ config NI_WATCHDOG If unsure, say N (but it's safe to say "Y"). +config NI_IRQ_RESOLVER + bool "NI interrupt resolver" + depends on ARCH_ZYNQ + help + Resolves the Linux virtual IRQ for the HW interrupts. + Required for NI-RIO Zynq HW on kernels where the + GIC allocates virtual IRQs dynamically. + + If unsure, say Y on NI-RIO Zynq targets. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 0ca142eee19bf..f93bfc2dc288f 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -79,3 +79,4 @@ obj-$(CONFIG_MISC_RP1) += rp1/ obj-$(CONFIG_NI_RT_FEATURES) += nirtfeatures.o obj-$(CONFIG_NI_WATCHDOG) += niwatchdog.o obj-$(CONFIG_FPGA_PERIPHERAL) += fpgaperipheral.o +obj-$(CONFIG_NI_IRQ_RESOLVER) += niirqresolver.o diff --git a/drivers/misc/niirqresolver.c b/drivers/misc/niirqresolver.c new file mode 100644 index 0000000000000..f1d2b6704af9b --- /dev/null +++ b/drivers/misc/niirqresolver.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Generic devicetree interrupt specifier -> Linux virq resolver. + * + * This file has no knowledge of any specific device, board, or interrupt + * controller: the caller supplies the controller's devicetree "compatible" + * string and its raw, controller-specific interrupt specifier cells (for + * example for an ARM GIC). + */ + +#include +#include +#include +#include +#include + +/** + * ni_of_resolve_irq - resolve a Linux virq from a devicetree interrupt specifier + * @compatible: devicetree "compatible" string of the interrupt controller node + * @args: raw interrupt specifier cells, controller-specific + * @args_count: number of valid entries in @args (must not exceed MAX_PHANDLE_ARGS) + * + * Finds the first devicetree node matching @compatible and asks its + * irqdomain to map @args to a Linux virq. Repeated calls with the same + * arguments return the same virq. + * + * Return: the Linux virtual IRQ number, or 0 if it could not be resolved + * (no matching node, args_count out of range, or the domain couldn't map it). + */ +unsigned int ni_of_resolve_irq(const char *compatible, const unsigned int *args, + unsigned int args_count) +{ + struct device_node *node; + struct of_phandle_args irq_spec; + unsigned int virq; + unsigned int i; + + if (args_count > MAX_PHANDLE_ARGS) + return 0; + + node = of_find_compatible_node(NULL, NULL, compatible); + if (!node) + return 0; + + irq_spec.np = node; + irq_spec.args_count = args_count; + for (i = 0; i < args_count; i++) + irq_spec.args[i] = args[i]; + + virq = irq_create_of_mapping(&irq_spec); + + of_node_put(node); + + return virq; +} +EXPORT_SYMBOL(ni_of_resolve_irq); diff --git a/include/linux/niirqresolver.h b/include/linux/niirqresolver.h new file mode 100644 index 0000000000000..cd2dee268a7a3 --- /dev/null +++ b/include/linux/niirqresolver.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Generic devicetree interrupt specifier -> Linux virq resolver. + * + * Public declaration for the NI IRQ resolver implemented in + * drivers/misc/niirqresolver.c. + */ + +#ifndef _LINUX_NIIRQRESOLVER_H_ +#define _LINUX_NIIRQRESOLVER_H_ + +/** + * ni_of_resolve_irq - resolve a Linux virq from a devicetree interrupt specifier + * @compatible: devicetree "compatible" string of the interrupt controller node + * @args: raw interrupt specifier cells, controller-specific + * @args_count: number of valid entries in @args (must not exceed MAX_PHANDLE_ARGS) + * + * Return: the Linux virtual IRQ number, or 0 if it could not be resolved. + */ +unsigned int ni_of_resolve_irq(const char *compatible, const unsigned int *args, + unsigned int args_count); + +#endif /* _LINUX_NIIRQRESOLVER_H_ */