lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250205160119.136639-2-c-vankar@ti.com>
Date: Wed, 5 Feb 2025 21:31:18 +0530
From: Chintan Vankar <c-vankar@...com>
To: Jason Reeder <jreeder@...com>, <vigneshr@...com>, <nm@...com>,
        "Chintan
 Vankar" <c-vankar@...com>, Paolo Abeni <pabeni@...hat.com>,
        Jakub Kicinski
	<kuba@...nel.org>, Eric Dumazet <edumazet@...gle.com>,
        "David S. Miller"
	<davem@...emloft.net>,
        Andrew Lunn <andrew+netdev@...n.ch>,
        Thomas Gleixner
	<tglx@...utronix.de>
CC: <netdev@...r.kernel.org>, <linux-kernel@...r.kernel.org>, <srk@...com>,
        <s-vadapalli@...com>, <danishanwar@...com>, <m-malladi@...com>
Subject: [RFC PATCH 1/2] irqchip: ti-tsir: Add support for Timesync Interrupt Router

Timesync Interrupt Router is an instantiation of generic interrupt router
module. It provides a mechanism to mux M interrupt inputs to N interrupt
outputs, where all M inputs are selectable to be driven as per N output.
Timesync Interrupt Router's inputs are either from peripherals or from
Device sync Events.

Add support for Timesync Interrupt Router driver to map input received
from peripherals with the corresponding output.

Signed-off-by: Chintan Vankar <c-vankar@...com>
---
 drivers/irqchip/Kconfig            |   9 +++
 drivers/irqchip/Makefile           |   1 +
 drivers/irqchip/ti-timesync-intr.c | 109 +++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+)
 create mode 100644 drivers/irqchip/ti-timesync-intr.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index c11b9965c4ad..48b9d907be0f 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -557,6 +557,15 @@ config TI_SCI_INTA_IRQCHIP
 	  If you wish to use interrupt aggregator irq resources managed by the
 	  TI System Controller, say Y here. Otherwise, say N.
 
+config TI_TS_INTR
+	bool
+	select IRQ_DOMAIN_HIERARCHY
+	help
+	  This enables the irqchip driver support for K3 Timesync Interrupt
+	  router available on TI's SoCs.
+	  To enable Timesync Interrupt Router's mapping, say Y here. Otherwise
+	  say N.
+
 config TI_PRUSS_INTC
 	tristate
 	depends on TI_PRUSS
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 25e9ad29b8c4..00c49f6d492a 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -129,3 +129,4 @@ obj-$(CONFIG_IRQ_IDT3243X)		+= irq-idt3243x.o
 obj-$(CONFIG_APPLE_AIC)			+= irq-apple-aic.o
 obj-$(CONFIG_MCHP_EIC)			+= irq-mchp-eic.o
 obj-$(CONFIG_SUNPLUS_SP7021_INTC)	+= irq-sp7021-intc.o
+obj-$(CONFIG_TS_INTR)			+= ti-timesync-intr.o
diff --git a/drivers/irqchip/ti-timesync-intr.c b/drivers/irqchip/ti-timesync-intr.c
new file mode 100644
index 000000000000..11f26ca649d2
--- /dev/null
+++ b/drivers/irqchip/ti-timesync-intr.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL
+/*
+ * Texas Instruments K3 Timesync Interrupt Router driver
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ *	Chintan Vankar <c-vankar@...com>
+ */
+
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/list.h>
+
+#define DRIVER_NAME	"ti-tsir"
+
+#define TIMESYNC_INTRTR_ENABLE			GENMASK(5, 0)
+#define TIMESYNC_INTRTR_INT_ENABLE		BIT(16)
+#define TIMESYNC_INTRTR_MAX_OUTPUT_LINES	48
+
+struct tsr_chip_data {
+	void __iomem		*tsr_base;
+	struct irq_domain	*domain;
+	u64			flags;
+};
+
+static struct irq_chip ts_intr_irq_chip = {
+	.name			= "TIMESYNC_INTRTR",
+};
+
+static u32 output_line_to_virq[TIMESYNC_INTRTR_MAX_OUTPUT_LINES];
+static struct tsr_chip_data tsr_data;
+
+static int ts_intr_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				    unsigned int nr_irqs, void *arg)
+{
+	unsigned int output_line, input_line, output_line_offset;
+	struct irq_fwspec *fwspec = (struct irq_fwspec *)arg;
+	int ret;
+
+	irq_domain_set_hwirq_and_chip(domain, virq, output_line,
+				      &ts_intr_irq_chip,
+				      NULL);
+
+	/* Check for two input parameters: output line and corresponding input line */
+	if (fwspec->param_count != 2)
+		return -EINVAL;
+
+	output_line = fwspec->param[0];
+
+	/* Timesync Interrupt Router's mux-controller register starts at offset 4 from base
+	 * address and each output line are at offset in multiple of 4s in Timesync INTR's
+	 * register space, calculate the register offset from provided output line.
+	 */
+	output_line_offset = 4 * output_line + 0x4;
+	output_line_to_virq[output_line] = virq;
+	input_line = fwspec->param[1] & TIMESYNC_INTRTR_ENABLE;
+
+	/* Map output line corresponding to input line */
+	writel(input_line, tsr_data.tsr_base + output_line_offset);
+
+	/* When interrupt enable bit is set for Timesync Interrupt Router it maps the output
+	 * line with the existing input line, hence enable interrupt line after we set bits for
+	 * output line.
+	 */
+	input_line |= TIMESYNC_INTRTR_INT_ENABLE;
+	writel(input_line, tsr_data.tsr_base + output_line_offset);
+
+	return 0;
+}
+
+static void ts_intr_irq_domain_free(struct irq_domain *domain, unsigned int virq,
+				    unsigned int nr_irqs)
+{
+	struct output_line_to_virq *node, *n;
+	unsigned int output_line_offset;
+	int i;
+
+	for (i = 0; i < TIMESYNC_INTRTR_MAX_OUTPUT_LINES; i++) {
+		if (output_line_to_virq[i] == virq) {
+			/* Calculate the register offset value from provided output line */
+			output_line_offset = 4 * i + 0x4;
+			writel(~TIMESYNC_INTRTR_INT_ENABLE, tsr_data.tsr_base + output_line_offset);
+		}
+	}
+}
+
+static const struct irq_domain_ops ts_intr_irq_domain_ops = {
+	.alloc		= ts_intr_irq_domain_alloc,
+	.free		= ts_intr_irq_domain_free,
+};
+
+static int tsr_init(struct device_node *node)
+{
+	tsr_data.tsr_base = of_iomap(node, 0);
+	if (IS_ERR(tsr_data.tsr_base)) {
+		pr_err("Unable to get reg\n");
+		return PTR_ERR(tsr_data.tsr_base);
+	}
+
+	tsr_data.domain = irq_domain_create_tree(&node->fwnode, &ts_intr_irq_domain_ops, &tsr_data);
+
+	return 0;
+}
+
+IRQCHIP_DECLARE(ts_intr, "ti,ts-intr", tsr_init);
+
+MODULE_AUTHOR("Chintan Vankar <c-vankar@...com>");
+MODULE_DESCRIPTION("Driver to configure Timesync Interrupt Router");
+MODULE_LICENSE("GPL");
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ