mirror of
https://github.com/torvalds/linux.git
synced 2024-12-04 10:01:41 +00:00
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:
parent
6016f32d1d
commit
b1026e8a95
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user