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:
Ye Zhang
2024-08-07 17:14:03 +08:00
committed by Tao Huang
parent e8c26e3dfa
commit 62dec0a878

View File

@@ -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;