[PATCH v5 4/5] irqchip/irq-pruss-intc: Implement irq_{get, set}_irqchip_state ops
From: Grzegorz Jaszczyk <hidden>
Date: 2020-08-17 13:42:33
Also in:
linux-devicetree, linux-omap, lkml
Subsystem:
irqchip drivers, the rest · Maintainers:
Thomas Gleixner, Linus Torvalds
From: David Lechner <david@lechnology.com>
This implements the irq_get_irqchip_state and irq_set_irqchip_state
callbacks for the TI PRUSS INTC driver. The set callback can be used
by drivers to "kick" a PRU by injecting a PRU system event.
Example:
irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING, true);
Signed-off-by: David Lechner <david@lechnology.com>
Signed-off-by: Suman Anna <redacted>
Signed-off-by: Grzegorz Jaszczyk <redacted>
Reviewed-by: Lee Jones <redacted>
---
v4->v5:
- No change.
v3->v4:
- Update commit message
v2->v3:
- Get rid of unnecessary pruss_intc_check_write() and use
pruss_intc_write_reg directly.
v1->v2:
- https://patchwork.kernel.org/patch/11069769/
---
drivers/irqchip/irq-pruss-intc.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c
index 1a72591..15f0407 100644
--- a/drivers/irqchip/irq-pruss-intc.c
+++ b/drivers/irqchip/irq-pruss-intc.c@@ -9,6 +9,7 @@ * Copyright (C) 2019 David Lechner <david@lechnology.com> */ +#include <linux/interrupt.h> #include <linux/irq.h> #include <linux/irqchip/chained_irq.h> #include <linux/irqdomain.h>
@@ -319,6 +320,43 @@ static void pruss_intc_irq_relres(struct irq_data *data) module_put(THIS_MODULE); } +static int pruss_intc_irq_get_irqchip_state(struct irq_data *data, + enum irqchip_irq_state which, + bool *state) +{ + struct pruss_intc *intc = irq_data_get_irq_chip_data(data); + u32 reg, mask, srsr; + + if (which != IRQCHIP_STATE_PENDING) + return -EINVAL; + + reg = PRU_INTC_SRSR(data->hwirq / 32); + mask = BIT(data->hwirq % 32); + + srsr = pruss_intc_read_reg(intc, reg); + + *state = !!(srsr & mask); + + return 0; +} + +static int pruss_intc_irq_set_irqchip_state(struct irq_data *data, + enum irqchip_irq_state which, + bool state) +{ + struct pruss_intc *intc = irq_data_get_irq_chip_data(data); + + if (which != IRQCHIP_STATE_PENDING) + return -EINVAL; + + if (state) + pruss_intc_write_reg(intc, PRU_INTC_SISR, data->hwirq); + else + pruss_intc_write_reg(intc, PRU_INTC_SICR, data->hwirq); + + return 0; +} + static struct irq_chip pruss_irqchip = { .name = "pruss-intc", .irq_ack = pruss_intc_irq_ack,
@@ -326,6 +364,8 @@ static struct irq_chip pruss_irqchip = { .irq_unmask = pruss_intc_irq_unmask, .irq_request_resources = pruss_intc_irq_reqres, .irq_release_resources = pruss_intc_irq_relres, + .irq_get_irqchip_state = pruss_intc_irq_get_irqchip_state, + .irq_set_irqchip_state = pruss_intc_irq_set_irqchip_state, }; static int pruss_intc_validate_mapping(struct pruss_intc *intc, int event,
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel