hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/gpio/gpio-tc3589x.c
....@@ -1,7 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) ST-Ericsson SA 2010
34 *
4
- * License Terms: GNU General Public License, version 2
55 * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson
66 * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
77 */
....@@ -19,9 +19,9 @@
1919 * These registers are modified under the irq bus lock and cached to avoid
2020 * unnecessary writes in bus_sync_unlock.
2121 */
22
-enum { REG_IBE, REG_IEV, REG_IS, REG_IE };
22
+enum { REG_IBE, REG_IEV, REG_IS, REG_IE, REG_DIRECT };
2323
24
-#define CACHE_NR_REGS 4
24
+#define CACHE_NR_REGS 5
2525 #define CACHE_NR_BANKS 3
2626
2727 struct tc3589x_gpio {
....@@ -97,7 +97,10 @@
9797 if (ret < 0)
9898 return ret;
9999
100
- return !(ret & BIT(pos));
100
+ if (ret & BIT(pos))
101
+ return GPIO_LINE_DIRECTION_OUT;
102
+
103
+ return GPIO_LINE_DIRECTION_IN;
101104 }
102105
103106 static int tc3589x_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
....@@ -197,6 +200,7 @@
197200 [REG_IEV] = TC3589x_GPIOIEV0,
198201 [REG_IS] = TC3589x_GPIOIS0,
199202 [REG_IE] = TC3589x_GPIOIE0,
203
+ [REG_DIRECT] = TC3589x_DIRECT0,
200204 };
201205 int i, j;
202206
....@@ -225,6 +229,7 @@
225229 int mask = BIT(offset % 8);
226230
227231 tc3589x_gpio->regs[REG_IE][regoffset] &= ~mask;
232
+ tc3589x_gpio->regs[REG_DIRECT][regoffset] |= mask;
228233 }
229234
230235 static void tc3589x_gpio_irq_unmask(struct irq_data *d)
....@@ -236,6 +241,7 @@
236241 int mask = BIT(offset % 8);
237242
238243 tc3589x_gpio->regs[REG_IE][regoffset] |= mask;
244
+ tc3589x_gpio->regs[REG_DIRECT][regoffset] &= ~mask;
239245 }
240246
241247 static struct irq_chip tc3589x_gpio_irq_chip = {
....@@ -286,6 +292,7 @@
286292 struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent);
287293 struct device_node *np = pdev->dev.of_node;
288294 struct tc3589x_gpio *tc3589x_gpio;
295
+ struct gpio_irq_chip *girq;
289296 int ret;
290297 int irq;
291298
....@@ -314,9 +321,30 @@
314321 tc3589x_gpio->chip.base = -1;
315322 tc3589x_gpio->chip.of_node = np;
316323
324
+ girq = &tc3589x_gpio->chip.irq;
325
+ girq->chip = &tc3589x_gpio_irq_chip;
326
+ /* This will let us handle the parent IRQ in the driver */
327
+ girq->parent_handler = NULL;
328
+ girq->num_parents = 0;
329
+ girq->parents = NULL;
330
+ girq->default_type = IRQ_TYPE_NONE;
331
+ girq->handler = handle_simple_irq;
332
+ girq->threaded = true;
333
+
317334 /* Bring the GPIO module out of reset */
318335 ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL,
319336 TC3589x_RSTCTRL_GPIRST, 0);
337
+ if (ret < 0)
338
+ return ret;
339
+
340
+ /* For tc35894, have to disable Direct KBD interrupts,
341
+ * else IRQST will always be 0x20, IRQN low level, can't
342
+ * clear the irq status.
343
+ * TODO: need more test on other tc3589x chip.
344
+ *
345
+ */
346
+ ret = tc3589x_reg_write(tc3589x, TC3589x_DKBDMSK,
347
+ TC3589x_DKBDMSK_ELINT | TC3589x_DKBDMSK_EINT);
320348 if (ret < 0)
321349 return ret;
322350
....@@ -335,21 +363,6 @@
335363 dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret);
336364 return ret;
337365 }
338
-
339
- ret = gpiochip_irqchip_add_nested(&tc3589x_gpio->chip,
340
- &tc3589x_gpio_irq_chip,
341
- 0,
342
- handle_simple_irq,
343
- IRQ_TYPE_NONE);
344
- if (ret) {
345
- dev_err(&pdev->dev,
346
- "could not connect irqchip to gpiochip\n");
347
- return ret;
348
- }
349
-
350
- gpiochip_set_nested_irqchip(&tc3589x_gpio->chip,
351
- &tc3589x_gpio_irq_chip,
352
- irq);
353366
354367 platform_set_drvdata(pdev, tc3589x_gpio);
355368