[PATCHv3 4/6] irqchip/irq-pruss-intc: Implement irq_{get,set}_irqchip_state ops
Marc Zyngier
maz at kernel.org
Thu Jul 2 13:54:26 EDT 2020
On 2020-07-02 15:17, Grzegorz Jaszczyk wrote:
> From: David Lechner <david at 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 enabling a PRU system event.
"enabling"? That'd be unmasking an interrupt, which isn't what this
does. "injecting", maybe?
>
> Example:
> irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING, true);
Nice example.
What this example does explain is how you are actually going to kick
a PRU via this interface. For that to happen, you'd have to have on
the Linux side an interrupt that is actually routed to a PRU.
And from what I have understood of the previous patches, this can't
be the case. What didi I miss?
>
> Signed-off-by: David Lechner <david at lechnology.com>
> Signed-off-by: Suman Anna <s-anna at ti.com>
> Signed-off-by: Grzegorz Jaszczyk <grzegorz.jaszczyk at linaro.org>
> Reviewed-by: Lee Jones <lee.jones at linaro.org>
> ---
> 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 | 43
> ++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 41 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/irqchip/irq-pruss-intc.c
> b/drivers/irqchip/irq-pruss-intc.c
> index 49c936f..19b3d38 100644
> --- a/drivers/irqchip/irq-pruss-intc.c
> +++ b/drivers/irqchip/irq-pruss-intc.c
> @@ -7,6 +7,7 @@
> * Suman Anna <s-anna at ti.com>
> */
>
> +#include <linux/interrupt.h>
> #include <linux/irq.h>
> #include <linux/irqchip/chained_irq.h>
> #include <linux/irqdomain.h>
> @@ -39,8 +40,7 @@
> #define PRU_INTC_HIEISR 0x0034
> #define PRU_INTC_HIDISR 0x0038
> #define PRU_INTC_GPIR 0x0080
> -#define PRU_INTC_SRSR0 0x0200
> -#define PRU_INTC_SRSR1 0x0204
> +#define PRU_INTC_SRSR(x) (0x0200 + (x) * 4)
> #define PRU_INTC_SECR0 0x0280
> #define PRU_INTC_SECR1 0x0284
> #define PRU_INTC_ESR0 0x0300
> @@ -145,6 +145,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);
I assume the register file scales as more interrupts are added in the
subsequent patch?
> + 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,
> @@ -152,6 +189,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_irq_domain_map(struct irq_domain *d, unsigned
> int virq,
Thanks,
M.
--
Jazz is not dead. It just smells funny...
More information about the linux-arm-kernel
mailing list