staging: mt7621-gpio: implement high level and low level irqs
This chip support high level and low level interrupts. Those have to be implemented also to get a complete and clean driver. Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
fe84f0c9b7
commit
368d97d69d
@ -38,6 +38,8 @@
|
||||
* @bank: gpio bank number for the chip
|
||||
* @rising: mask for rising irqs
|
||||
* @falling: mask for falling irqs
|
||||
* @hlevel: mask for high level irqs
|
||||
* @llevel: mask for low level irqs
|
||||
*/
|
||||
struct mtk_gc {
|
||||
struct gpio_chip chip;
|
||||
@ -45,6 +47,8 @@ struct mtk_gc {
|
||||
int bank;
|
||||
u32 rising;
|
||||
u32 falling;
|
||||
u32 hlevel;
|
||||
u32 llevel;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -184,7 +188,7 @@ mediatek_gpio_irq_unmask(struct irq_data *d)
|
||||
int bank = pin / MTK_BANK_WIDTH;
|
||||
struct mtk_gc *rg = &gpio_data->gc_map[bank];
|
||||
unsigned long flags;
|
||||
u32 rise, fall;
|
||||
u32 rise, fall, high, low;
|
||||
|
||||
if (!rg)
|
||||
return;
|
||||
@ -192,8 +196,12 @@ mediatek_gpio_irq_unmask(struct irq_data *d)
|
||||
spin_lock_irqsave(&rg->lock, flags);
|
||||
rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
|
||||
fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
|
||||
high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
|
||||
low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
|
||||
mtk_gpio_w32(rg, GPIO_REG_REDGE, rise | (PIN_MASK(pin) & rg->rising));
|
||||
mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall | (PIN_MASK(pin) & rg->falling));
|
||||
mtk_gpio_w32(rg, GPIO_REG_HLVL, high | (PIN_MASK(pin) & rg->hlevel));
|
||||
mtk_gpio_w32(rg, GPIO_REG_LLVL, low | (PIN_MASK(pin) & rg->llevel));
|
||||
spin_unlock_irqrestore(&rg->lock, flags);
|
||||
}
|
||||
|
||||
@ -205,7 +213,7 @@ mediatek_gpio_irq_mask(struct irq_data *d)
|
||||
int bank = pin / MTK_BANK_WIDTH;
|
||||
struct mtk_gc *rg = &gpio_data->gc_map[bank];
|
||||
unsigned long flags;
|
||||
u32 rise, fall;
|
||||
u32 rise, fall, high, low;
|
||||
|
||||
if (!rg)
|
||||
return;
|
||||
@ -213,8 +221,12 @@ mediatek_gpio_irq_mask(struct irq_data *d)
|
||||
spin_lock_irqsave(&rg->lock, flags);
|
||||
rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
|
||||
fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
|
||||
high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
|
||||
low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
|
||||
mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall & ~PIN_MASK(pin));
|
||||
mtk_gpio_w32(rg, GPIO_REG_REDGE, rise & ~PIN_MASK(pin));
|
||||
mtk_gpio_w32(rg, GPIO_REG_HLVL, high & ~PIN_MASK(pin));
|
||||
mtk_gpio_w32(rg, GPIO_REG_LLVL, low & ~PIN_MASK(pin));
|
||||
spin_unlock_irqrestore(&rg->lock, flags);
|
||||
}
|
||||
|
||||
@ -231,21 +243,36 @@ mediatek_gpio_irq_type(struct irq_data *d, unsigned int type)
|
||||
return -1;
|
||||
|
||||
if (type == IRQ_TYPE_PROBE) {
|
||||
if ((rg->rising | rg->falling) & mask)
|
||||
if ((rg->rising | rg->falling |
|
||||
rg->hlevel | rg->llevel) & mask)
|
||||
return 0;
|
||||
|
||||
type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
|
||||
}
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
rg->rising |= mask;
|
||||
else
|
||||
rg->rising &= ~mask;
|
||||
rg->rising &= ~mask;
|
||||
rg->falling &= ~mask;
|
||||
rg->hlevel &= ~mask;
|
||||
rg->llevel &= ~mask;
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
switch (type & IRQ_TYPE_SENSE_MASK) {
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
rg->rising |= mask;
|
||||
rg->falling |= mask;
|
||||
else
|
||||
rg->falling &= ~mask;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
rg->rising |= mask;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
rg->falling |= mask;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
rg->hlevel |= mask;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
rg->llevel |= mask;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user