Commit d72683e6 authored by Gilles Chanteperdrix's avatar Gilles Chanteperdrix Committed by Dmitriy Cherkasov

irqchip: gic-v3: ipipe: enable pipelined interrupts

parent f1e05ac8
......@@ -200,7 +200,12 @@ static void gic_poke_irq(struct irq_data *d, u32 offset)
static void gic_mask_irq(struct irq_data *d)
{
unsigned long flags;
flags = hard_cond_local_irq_save();
ipipe_lock_irq(d->irq);
gic_poke_irq(d, GICD_ICENABLER);
hard_cond_local_irq_restore(flags);
}
static void gic_eoimode1_mask_irq(struct irq_data *d)
......@@ -220,7 +225,12 @@ static void gic_eoimode1_mask_irq(struct irq_data *d)
static void gic_unmask_irq(struct irq_data *d)
{
unsigned long flags;
flags = hard_cond_local_irq_save();
gic_poke_irq(d, GICD_ISENABLER);
ipipe_unlock_irq(d->irq);
hard_cond_local_irq_restore(flags);
}
static int gic_irq_set_irqchip_state(struct irq_data *d,
......@@ -294,6 +304,27 @@ static void gic_eoimode1_eoi_irq(struct irq_data *d)
gic_write_dir(gic_irq(d));
}
#ifdef CONFIG_IPIPE
static void gic_hold_irq(struct irq_data *d)
{
struct irq_chip *chip = irq_data_get_irq_chip(d);
gic_poke_irq(d, GICD_ICENABLER);
if (chip->irq_eoi == gic_eoimode1_eoi_irq) {
if (irqd_is_forwarded_to_vcpu(d))
gic_poke_irq(d, GICD_ICACTIVER);
gic_eoimode1_eoi_irq(d);
} else
gic_eoi_irq(d);
}
static void gic_release_irq(struct irq_data *d)
{
gic_poke_irq(d, GICD_ISENABLER);
}
#endif /* CONFIG_IPIPE */
static int gic_set_type(struct irq_data *d, unsigned int type)
{
unsigned int irq = gic_irq(d);
......@@ -356,7 +387,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
else
isb();
err = handle_domain_irq(gic_data.domain, irqnr, regs);
err = ipipe_handle_domain_irq(gic_data.domain, irqnr, regs);
if (err) {
WARN_ONCE(true, "Unexpected interrupt received!\n");
if (static_key_true(&supports_deactivate)) {
......@@ -380,7 +411,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
* that any shared data read by handle_IPI will
* be read after the ACK.
*/
handle_IPI(irqnr, regs);
ipipe_handle_multi_ipi(irqnr, regs);
#else
WARN_ONCE(true, "Unexpected SGI received!\n");
#endif
......@@ -769,10 +800,14 @@ static struct irq_chip gic_chip = {
.irq_unmask = gic_unmask_irq,
.irq_eoi = gic_eoi_irq,
.irq_set_type = gic_set_type,
#ifdef CONFIG_IPIPE
.irq_hold = gic_hold_irq,
.irq_release = gic_release_irq,
#endif
.irq_set_affinity = gic_set_affinity,
.irq_get_irqchip_state = gic_irq_get_irqchip_state,
.irq_set_irqchip_state = gic_irq_set_irqchip_state,
.flags = IRQCHIP_SET_TYPE_MASKED,
.flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_PIPELINE_SAFE,
};
static struct irq_chip gic_eoimode1_chip = {
......@@ -781,11 +816,15 @@ static struct irq_chip gic_eoimode1_chip = {
.irq_unmask = gic_unmask_irq,
.irq_eoi = gic_eoimode1_eoi_irq,
.irq_set_type = gic_set_type,
#ifdef CONFIG_IPIPE
.irq_hold = gic_hold_irq,
.irq_release = gic_release_irq,
#endif
.irq_set_affinity = gic_set_affinity,
.irq_get_irqchip_state = gic_irq_get_irqchip_state,
.irq_set_irqchip_state = gic_irq_set_irqchip_state,
.irq_set_vcpu_affinity = gic_irq_set_vcpu_affinity,
.flags = IRQCHIP_SET_TYPE_MASKED,
.flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_PIPELINE_SAFE,
};
#define GIC_ID_NR (1U << gic_data.rdists.id_bits)
......
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