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-next>] [day] [month] [year] [list]
Date:   Mon,  4 Jan 2021 12:36:56 -0600
From:   David Lechner <david@...hnology.com>
To:     linux-kernel@...r.kernel.org
Cc:     David Lechner <david@...hnology.com>,
        Thomas Gleixner <tglx@...utronix.de>,
        Marc Zyngier <maz@...nel.org>, Suman Anna <s-anna@...com>,
        Grzegorz Jaszczyk <grzegorz.jaszczyk@...aro.org>,
        Sekhar Nori <nsekhar@...com>,
        Bartosz Golaszewski <bgolaszewski@...libre.com>,
        linux-arm-kernel@...ts.infradead.org
Subject: [PATCH] irqchip/irq-pruss-intc: implement set_type() callback

This implements the irqchip set_type() callback for the TI PRUSS
interrupt controller. This is needed for cases where an event needs
to be active low.

According to the technical reference manual, the polarity should always
be set to high, however in practice, the polarity needs to be set low
for the McASP Tx/Rx system event in conjunction with soft UART PRU
firmware for TI AM18XX SoCs, otherwise it doesn't work.

Signed-off-by: David Lechner <david@...hnology.com>
---
 drivers/irqchip/irq-pruss-intc.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c
index 5409016e6ca0..f882af8a7ded 100644
--- a/drivers/irqchip/irq-pruss-intc.c
+++ b/drivers/irqchip/irq-pruss-intc.c
@@ -334,6 +334,32 @@ static void pruss_intc_irq_unmask(struct irq_data *data)
 	pruss_intc_write_reg(intc, PRU_INTC_EISR, hwirq);
 }
 
+static int pruss_intc_irq_set_type(struct irq_data *data, unsigned int type)
+{
+	struct pruss_intc *intc = irq_data_get_irq_chip_data(data);
+	u32 reg, bit, val;
+
+	if (type & IRQ_TYPE_LEVEL_MASK) {
+		/* polarity register */
+		reg = PRU_INTC_SIPR(data->hwirq / 32);
+		bit = BIT(data->hwirq % 32);
+		val = pruss_intc_read_reg(intc, reg);
+
+		/*
+		 * This check also ensures that IRQ_TYPE_DEFAULT will result
+		 * in setting the level to high.
+		 */
+		if (type & IRQ_TYPE_LEVEL_HIGH)
+			val |= bit;
+		else
+			val &= ~bit;
+
+		pruss_intc_write_reg(intc, reg, val);
+	}
+
+	return 0;
+}
+
 static int pruss_intc_irq_reqres(struct irq_data *data)
 {
 	if (!try_module_get(THIS_MODULE))
@@ -389,6 +415,7 @@ static struct irq_chip pruss_irqchip = {
 	.irq_ack		= pruss_intc_irq_ack,
 	.irq_mask		= pruss_intc_irq_mask,
 	.irq_unmask		= pruss_intc_irq_unmask,
+	.irq_set_type		= pruss_intc_irq_set_type,
 	.irq_request_resources	= pruss_intc_irq_reqres,
 	.irq_release_resources	= pruss_intc_irq_relres,
 	.irq_get_irqchip_state	= pruss_intc_irq_get_irqchip_state,
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ