Skip to content

Commit e5dec38

Browse files
chenhuacaiMarc Zyngier
authored andcommitted
irqchip/loongson-pch-pic: Improve edge triggered interrupt support
Edge-triggered mode and level-triggered mode need different handlers, and edge-triggered mode need a specific ack operation. So improve it. Fixes: ef8c01e ("irqchip: Add Loongson PCH PIC controller") Signed-off-by: Chen Zhu <[email protected]> Signed-off-by: Huacai Chen <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent ff11764 commit e5dec38

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

drivers/irqchip/irq-loongson-pch-pic.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,22 @@ static int pch_pic_set_type(struct irq_data *d, unsigned int type)
9292
case IRQ_TYPE_EDGE_RISING:
9393
pch_pic_bitset(priv, PCH_PIC_EDGE, d->hwirq);
9494
pch_pic_bitclr(priv, PCH_PIC_POL, d->hwirq);
95+
irq_set_handler_locked(d, handle_edge_irq);
9596
break;
9697
case IRQ_TYPE_EDGE_FALLING:
9798
pch_pic_bitset(priv, PCH_PIC_EDGE, d->hwirq);
9899
pch_pic_bitset(priv, PCH_PIC_POL, d->hwirq);
100+
irq_set_handler_locked(d, handle_edge_irq);
99101
break;
100102
case IRQ_TYPE_LEVEL_HIGH:
101103
pch_pic_bitclr(priv, PCH_PIC_EDGE, d->hwirq);
102104
pch_pic_bitclr(priv, PCH_PIC_POL, d->hwirq);
105+
irq_set_handler_locked(d, handle_level_irq);
103106
break;
104107
case IRQ_TYPE_LEVEL_LOW:
105108
pch_pic_bitclr(priv, PCH_PIC_EDGE, d->hwirq);
106109
pch_pic_bitset(priv, PCH_PIC_POL, d->hwirq);
110+
irq_set_handler_locked(d, handle_level_irq);
107111
break;
108112
default:
109113
ret = -EINVAL;
@@ -113,11 +117,24 @@ static int pch_pic_set_type(struct irq_data *d, unsigned int type)
113117
return ret;
114118
}
115119

120+
static void pch_pic_ack_irq(struct irq_data *d)
121+
{
122+
unsigned int reg;
123+
struct pch_pic *priv = irq_data_get_irq_chip_data(d);
124+
125+
reg = readl(priv->base + PCH_PIC_EDGE + PIC_REG_IDX(d->hwirq) * 4);
126+
if (reg & BIT(PIC_REG_BIT(d->hwirq))) {
127+
writel(BIT(PIC_REG_BIT(d->hwirq)),
128+
priv->base + PCH_PIC_CLR + PIC_REG_IDX(d->hwirq) * 4);
129+
}
130+
irq_chip_ack_parent(d);
131+
}
132+
116133
static struct irq_chip pch_pic_irq_chip = {
117134
.name = "PCH PIC",
118135
.irq_mask = pch_pic_mask_irq,
119136
.irq_unmask = pch_pic_unmask_irq,
120-
.irq_ack = irq_chip_ack_parent,
137+
.irq_ack = pch_pic_ack_irq,
121138
.irq_set_affinity = irq_chip_set_affinity_parent,
122139
.irq_set_type = pch_pic_set_type,
123140
};

0 commit comments

Comments
 (0)