* @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;
int bank;
u32 rising;
u32 falling;
+ u32 hlevel;
+ u32 llevel;
};
/**
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;
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);
}
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;
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);
}
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;
}