From b1026e8a95e430e615579f14f0f73c94f9690468 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Wed, 16 Sep 2020 18:36:37 +0200 Subject: [PATCH] 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 Co-developed-by: Grzegorz Jaszczyk Signed-off-by: Suman Anna Signed-off-by: David Lechner Signed-off-by: Grzegorz Jaszczyk Reviewed-by: Lee Jones Signed-off-by: Marc Zyngier --- 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 e7ba35860491..bfe529a9efb8 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -12,6 +12,7 @@ * Copyright (C) 2019 David Lechner */ +#include #include #include #include @@ -323,6 +324,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, @@ -330,6 +368,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,