Commit b1026e8a authored by David Lechner's avatar David Lechner Committed by Marc Zyngier
Browse files

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: default avatarSuman Anna <s-anna@ti.com>
Co-developed-by: default avatarGrzegorz Jaszczyk <grzegorz.jaszczyk@linaro.org>
Signed-off-by: default avatarSuman Anna <s-anna@ti.com>
Signed-off-by: default avatarDavid Lechner <david@lechnology.com>
Signed-off-by: default avatarGrzegorz Jaszczyk <grzegorz.jaszczyk@linaro.org>
Reviewed-by: default avatarLee Jones <lee.jones@linaro.org>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 6016f32d
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -12,6 +12,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>
@@ -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,