irqchip/irq-pruss-intc: Implement irq_{get, set}_irqchip_state ops

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.

Co-developed-by: Suman Anna <s-anna@ti.com>
Co-developed-by: Grzegorz Jaszczyk <grzegorz.jaszczyk@linaro.org>
Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: David Lechner <david@lechnology.com>
Signed-off-by: Grzegorz Jaszczyk <grzegorz.jaszczyk@linaro.org>
Reviewed-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
David Lechner 2020-09-16 18:36:37 +02:00 committed by Marc Zyngier
parent 6016f32d1d
commit b1026e8a95

View File

@ -12,6 +12,7 @@
* Copyright (C) 2019 David Lechner <david@lechnology.com> * Copyright (C) 2019 David Lechner <david@lechnology.com>
*/ */
#include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqchip/chained_irq.h> #include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
@ -323,6 +324,43 @@ static void pruss_intc_irq_relres(struct irq_data *data)
module_put(THIS_MODULE); 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 = { static struct irq_chip pruss_irqchip = {
.name = "pruss-intc", .name = "pruss-intc",
.irq_ack = pruss_intc_irq_ack, .irq_ack = pruss_intc_irq_ack,
@ -330,6 +368,8 @@ static struct irq_chip pruss_irqchip = {
.irq_unmask = pruss_intc_irq_unmask, .irq_unmask = pruss_intc_irq_unmask,
.irq_request_resources = pruss_intc_irq_reqres, .irq_request_resources = pruss_intc_irq_reqres,
.irq_release_resources = pruss_intc_irq_relres, .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, static int pruss_intc_validate_mapping(struct pruss_intc *intc, int event,