mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
rockchip: gpio: fix debounce config error
1. Prevent data from crossing boundaries 2. Support GPIO_TYPE_V2_2 debounce config Signed-off-by: Ye Zhang <ye.zhang@rock-chips.com> Change-Id: I57e295806a4f0f4002527daf77fe41f584a7e9e1
This commit is contained in:
@@ -84,7 +84,7 @@ static inline void rockchip_gpio_writel(struct rockchip_pin_bank *bank,
|
||||
{
|
||||
void __iomem *reg = bank->reg_base + offset;
|
||||
|
||||
if (bank->gpio_type == GPIO_TYPE_V2)
|
||||
if (bank->gpio_type >= GPIO_TYPE_V2)
|
||||
gpio_writel_v2(value, reg);
|
||||
else
|
||||
writel(value, reg);
|
||||
@@ -96,7 +96,7 @@ static inline u32 rockchip_gpio_readl(struct rockchip_pin_bank *bank,
|
||||
void __iomem *reg = bank->reg_base + offset;
|
||||
u32 value;
|
||||
|
||||
if (bank->gpio_type == GPIO_TYPE_V2)
|
||||
if (bank->gpio_type >= GPIO_TYPE_V2)
|
||||
value = gpio_readl_v2(reg);
|
||||
else
|
||||
value = readl(reg);
|
||||
@@ -111,7 +111,7 @@ static inline void rockchip_gpio_writel_bit(struct rockchip_pin_bank *bank,
|
||||
void __iomem *reg = bank->reg_base + offset;
|
||||
u32 data;
|
||||
|
||||
if (bank->gpio_type == GPIO_TYPE_V2) {
|
||||
if (bank->gpio_type >= GPIO_TYPE_V2) {
|
||||
if (value)
|
||||
data = BIT(bit % 16) | BIT(bit % 16 + 16);
|
||||
else
|
||||
@@ -132,7 +132,7 @@ static inline u32 rockchip_gpio_readl_bit(struct rockchip_pin_bank *bank,
|
||||
void __iomem *reg = bank->reg_base + offset;
|
||||
u32 data;
|
||||
|
||||
if (bank->gpio_type == GPIO_TYPE_V2) {
|
||||
if (bank->gpio_type >= GPIO_TYPE_V2) {
|
||||
data = readl(bit >= 16 ? reg + 0x4 : reg);
|
||||
data >>= bit % 16;
|
||||
} else {
|
||||
@@ -209,17 +209,24 @@ static int rockchip_gpio_set_debounce(struct gpio_chip *gc,
|
||||
unsigned int cur_div_reg;
|
||||
u64 div;
|
||||
|
||||
if (bank->gpio_type == GPIO_TYPE_V2 && !IS_ERR(bank->db_clk)) {
|
||||
if (bank->gpio_type >= GPIO_TYPE_V2 && !IS_ERR(bank->db_clk)) {
|
||||
div_debounce_support = true;
|
||||
freq = clk_get_rate(bank->db_clk);
|
||||
if (!freq)
|
||||
return -EINVAL;
|
||||
max_debounce = (GENMASK(23, 0) + 1) * 2 * 1000000 / freq;
|
||||
div = (u64)(GENMASK(23, 0) + 1) * 1000000;
|
||||
if (bank->gpio_type == GPIO_TYPE_V2)
|
||||
max_debounce = DIV_ROUND_CLOSEST_ULL(div, freq);
|
||||
else
|
||||
max_debounce = DIV_ROUND_CLOSEST_ULL(div, 2 * freq);
|
||||
if ((unsigned long)debounce > max_debounce)
|
||||
return -EINVAL;
|
||||
|
||||
div = debounce * freq;
|
||||
div_reg = DIV_ROUND_CLOSEST_ULL(div, 2 * USEC_PER_SEC) - 1;
|
||||
div = (u64)debounce * freq;
|
||||
if (bank->gpio_type == GPIO_TYPE_V2)
|
||||
div_reg = DIV_ROUND_CLOSEST_ULL(div, USEC_PER_SEC) - 1;
|
||||
else
|
||||
div_reg = DIV_ROUND_CLOSEST_ULL(div, USEC_PER_SEC / 2) - 1;
|
||||
} else {
|
||||
div_debounce_support = false;
|
||||
}
|
||||
@@ -417,7 +424,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity);
|
||||
|
||||
if (type == IRQ_TYPE_EDGE_BOTH) {
|
||||
if (bank->gpio_type == GPIO_TYPE_V2) {
|
||||
if (bank->gpio_type >= GPIO_TYPE_V2) {
|
||||
rockchip_gpio_writel_bit(bank, d->hwirq, 1,
|
||||
bank->gpio_regs->int_bothedge);
|
||||
goto out;
|
||||
@@ -436,7 +443,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
polarity |= mask;
|
||||
}
|
||||
} else {
|
||||
if (bank->gpio_type == GPIO_TYPE_V2) {
|
||||
if (bank->gpio_type >= GPIO_TYPE_V2) {
|
||||
rockchip_gpio_writel_bit(bank, d->hwirq, 0,
|
||||
bank->gpio_regs->int_bothedge);
|
||||
} else {
|
||||
@@ -544,7 +551,7 @@ static int rockchip_interrupts_register(struct rockchip_pin_bank *bank)
|
||||
}
|
||||
|
||||
gc = irq_get_domain_generic_chip(bank->domain, 0);
|
||||
if (bank->gpio_type == GPIO_TYPE_V2) {
|
||||
if (bank->gpio_type >= GPIO_TYPE_V2) {
|
||||
gc->reg_writel = gpio_writel_v2;
|
||||
gc->reg_readl = gpio_readl_v2;
|
||||
}
|
||||
@@ -633,10 +640,13 @@ static void rockchip_gpio_get_ver(struct rockchip_pin_bank *bank)
|
||||
switch (id) {
|
||||
case GPIO_TYPE_V2:
|
||||
case GPIO_TYPE_V2_1:
|
||||
case GPIO_TYPE_V2_2:
|
||||
bank->gpio_regs = &gpio_regs_v2;
|
||||
bank->gpio_type = GPIO_TYPE_V2;
|
||||
break;
|
||||
case GPIO_TYPE_V2_2:
|
||||
bank->gpio_regs = &gpio_regs_v2;
|
||||
bank->gpio_type = GPIO_TYPE_V2_2;
|
||||
break;
|
||||
default:
|
||||
bank->gpio_regs = &gpio_regs_v1;
|
||||
bank->gpio_type = GPIO_TYPE_V1;
|
||||
|
||||
Reference in New Issue
Block a user