mirror of
https://github.com/merbanan/airoha_ml.git
synced 2025-11-10 17:46:10 +00:00
69 lines
2.0 KiB
Plaintext
69 lines
2.0 KiB
Plaintext
From 4da48477d2fcc165b0d4e692488b65ada571c884 Mon Sep 17 00:00:00 2001
|
|
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
|
Date: Fri, 23 Dec 2022 19:18:03 +0300
|
|
Subject: gpio: en7523: fix direction set/query
|
|
|
|
GPIO Control Register uses 2 bit to specify gpio pin function. This
|
|
results in 4 possible values:
|
|
0: GPIO input mode.
|
|
1: GPIO output mode.
|
|
2: Reserved
|
|
3: Reserved
|
|
|
|
It may be noted, that only low bit is used to specify pin function.
|
|
High bit is reserved and should be zero.
|
|
|
|
It was noted that some gpio have non-zero reserved bit. Current GPIO
|
|
driver does not touch reserved bit. As result it was not possible to
|
|
configure as input/output pins with non-zero reserved bit.
|
|
|
|
Fix an issue by always zero reserved bit.
|
|
|
|
diff --git a/drivers/gpio/gpio-en7523.c b/drivers/gpio/gpio-en7523.c
|
|
index be669ec17..29ab63f97 100755
|
|
--- a/drivers/gpio/gpio-en7523.c
|
|
+++ b/drivers/gpio/gpio-en7523.c
|
|
@@ -86,16 +86,15 @@ static int airoha_dir_set(struct gpio_chip *gc, unsigned int gpio,
|
|
int val, int out)
|
|
{
|
|
struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc);
|
|
- u32 dir = ioread32(ctrl->dir[gpio / 16]);
|
|
u32 output = ioread32(ctrl->output);
|
|
- u32 mask = BIT((gpio % 16) * 2);
|
|
+ u32 dir = ioread32(ctrl->dir[gpio / 16]);
|
|
+ u32 shift = (gpio % 16) * 2;
|
|
|
|
+ dir &= ~(0x3 << shift);
|
|
+ output &= ~BIT(gpio);
|
|
if (out) {
|
|
- dir |= mask;
|
|
+ dir |= (0x1 << shift);
|
|
output |= BIT(gpio);
|
|
- } else {
|
|
- dir &= ~mask;
|
|
- output &= ~BIT(gpio);
|
|
}
|
|
|
|
iowrite32(dir, ctrl->dir[gpio / 16]);
|
|
@@ -123,9 +122,18 @@ static int airoha_get_dir(struct gpio_chip *gc, unsigned int gpio)
|
|
{
|
|
struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc);
|
|
u32 dir = ioread32(ctrl->dir[gpio / 16]);
|
|
- u32 mask = BIT((gpio % 16) * 2);
|
|
+ u32 shift = (gpio % 16) * 2;
|
|
+
|
|
+ switch ((dir >> shift) & 0x03) {
|
|
+ case 0:
|
|
+ return GPIO_LINE_DIRECTION_IN;
|
|
+ case 1:
|
|
+ return GPIO_LINE_DIRECTION_OUT;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
|
|
- return (dir & mask) ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
static irqreturn_t airoha_gpio_irq_handler(int irq, void *data)
|