Commit e57a3e28 authored by Marc Zyngier's avatar Marc Zyngier

irqchip/gic-v3-its: Allow doorbell interrupts to be injected/cleared

While the doorbell interrupts are usually driven by the HW itself,
having a way to trigger them independently has proved to be a
really useful debug feature. As it is actually very little code,
let's add it to the VPE irqchip operations.
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent 958b90d1
...@@ -2504,12 +2504,43 @@ static void its_vpe_unmask_irq(struct irq_data *d) ...@@ -2504,12 +2504,43 @@ static void its_vpe_unmask_irq(struct irq_data *d)
its_vpe_send_inv(d); its_vpe_send_inv(d);
} }
static int its_vpe_set_irqchip_state(struct irq_data *d,
enum irqchip_irq_state which,
bool state)
{
struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
if (which != IRQCHIP_STATE_PENDING)
return -EINVAL;
if (gic_rdists->has_direct_lpi) {
void __iomem *rdbase;
rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base;
if (state) {
gic_write_lpir(vpe->vpe_db_lpi, rdbase + GICR_SETLPIR);
} else {
gic_write_lpir(vpe->vpe_db_lpi, rdbase + GICR_CLRLPIR);
while (gic_read_lpir(rdbase + GICR_SYNCR) & 1)
cpu_relax();
}
} else {
if (state)
its_vpe_send_cmd(vpe, its_send_int);
else
its_vpe_send_cmd(vpe, its_send_clear);
}
return 0;
}
static struct irq_chip its_vpe_irq_chip = { static struct irq_chip its_vpe_irq_chip = {
.name = "GICv4-vpe", .name = "GICv4-vpe",
.irq_mask = its_vpe_mask_irq, .irq_mask = its_vpe_mask_irq,
.irq_unmask = its_vpe_unmask_irq, .irq_unmask = its_vpe_unmask_irq,
.irq_eoi = irq_chip_eoi_parent, .irq_eoi = irq_chip_eoi_parent,
.irq_set_affinity = its_vpe_set_affinity, .irq_set_affinity = its_vpe_set_affinity,
.irq_set_irqchip_state = its_vpe_set_irqchip_state,
.irq_set_vcpu_affinity = its_vpe_set_vcpu_affinity, .irq_set_vcpu_affinity = its_vpe_set_vcpu_affinity,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment