hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpio/gpio-wcove.c
....@@ -1,34 +1,26 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Intel Whiskey Cove PMIC GPIO Driver
34 *
45 * This driver is written based on gpio-crystalcove.c
56 *
67 * Copyright (C) 2016 Intel Corporation. All rights reserved.
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License version
10
- * 2 as published by the Free Software Foundation.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
168 */
179
1810 #include <linux/bitops.h>
19
-#include <linux/module.h>
20
-#include <linux/interrupt.h>
2111 #include <linux/gpio/driver.h>
12
+#include <linux/interrupt.h>
2213 #include <linux/mfd/intel_soc_pmic.h>
14
+#include <linux/module.h>
2315 #include <linux/platform_device.h>
2416 #include <linux/regmap.h>
2517 #include <linux/seq_file.h>
2618
2719 /*
2820 * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks:
29
- * Bank 0: Pin 0 - 6
30
- * Bank 1: Pin 7 - 10
31
- * Bank 2: Pin 11 -12
21
+ * Bank 0: Pin 0 - 6
22
+ * Bank 1: Pin 7 - 10
23
+ * Bank 2: Pin 11 - 12
3224 * Each pin has one output control register and one input control register.
3325 */
3426 #define BANK0_NR_PINS 7
....@@ -75,8 +67,8 @@
7567 #define CTLO_RVAL_50KDOWN (2 << 1)
7668 #define CTLO_RVAL_50KUP (3 << 1)
7769
78
-#define CTLO_INPUT_SET (CTLO_DRV_CMOS | CTLO_DRV_REN | CTLO_RVAL_2KUP)
79
-#define CTLO_OUTPUT_SET (CTLO_DIR_OUT | CTLO_INPUT_SET)
70
+#define CTLO_INPUT_SET (CTLO_DRV_CMOS | CTLO_DRV_REN | CTLO_RVAL_2KUP)
71
+#define CTLO_OUTPUT_SET (CTLO_DIR_OUT | CTLO_INPUT_SET)
8072
8173 enum ctrl_register {
8274 CTRL_IN,
....@@ -105,7 +97,7 @@
10597 bool set_irq_mask;
10698 };
10799
108
-static inline unsigned int to_reg(int gpio, enum ctrl_register reg_type)
100
+static inline int to_reg(int gpio, enum ctrl_register reg_type)
109101 {
110102 unsigned int reg;
111103
....@@ -178,13 +170,16 @@
178170 int ret, reg = to_reg(gpio, CTRL_OUT);
179171
180172 if (reg < 0)
181
- return 0;
173
+ return GPIO_LINE_DIRECTION_OUT;
182174
183175 ret = regmap_read(wg->regmap, reg, &val);
184176 if (ret)
185177 return ret;
186178
187
- return !(val & CTLO_DIR_OUT);
179
+ if (val & CTLO_DIR_OUT)
180
+ return GPIO_LINE_DIRECTION_OUT;
181
+
182
+ return GPIO_LINE_DIRECTION_IN;
188183 }
189184
190185 static int wcove_gpio_get(struct gpio_chip *chip, unsigned int gpio)
....@@ -203,8 +198,7 @@
203198 return val & 0x1;
204199 }
205200
206
-static void wcove_gpio_set(struct gpio_chip *chip,
207
- unsigned int gpio, int value)
201
+static void wcove_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
208202 {
209203 struct wcove_gpio *wg = gpiochip_get_data(chip);
210204 int reg = to_reg(gpio, CTRL_OUT);
....@@ -406,6 +400,7 @@
406400 struct wcove_gpio *wg;
407401 int virq, ret, irq;
408402 struct device *dev;
403
+ struct gpio_irq_chip *girq;
409404
410405 /*
411406 * This gpio platform device is created by a mfd device (see
....@@ -448,33 +443,34 @@
448443 wg->dev = dev;
449444 wg->regmap = pmic->regmap;
450445
451
- ret = devm_gpiochip_add_data(dev, &wg->chip, wg);
452
- if (ret) {
453
- dev_err(dev, "Failed to add gpiochip: %d\n", ret);
454
- return ret;
455
- }
456
-
457
- ret = gpiochip_irqchip_add_nested(&wg->chip, &wcove_irqchip, 0,
458
- handle_simple_irq, IRQ_TYPE_NONE);
459
- if (ret) {
460
- dev_err(dev, "Failed to add irqchip: %d\n", ret);
461
- return ret;
462
- }
463
-
464446 virq = regmap_irq_get_virq(wg->regmap_irq_chip, irq);
465447 if (virq < 0) {
466448 dev_err(dev, "Failed to get virq by irq %d\n", irq);
467449 return virq;
468450 }
469451
470
- ret = devm_request_threaded_irq(dev, virq, NULL,
471
- wcove_gpio_irq_handler, IRQF_ONESHOT, pdev->name, wg);
452
+ girq = &wg->chip.irq;
453
+ girq->chip = &wcove_irqchip;
454
+ /* This will let us handle the parent IRQ in the driver */
455
+ girq->parent_handler = NULL;
456
+ girq->num_parents = 0;
457
+ girq->parents = NULL;
458
+ girq->default_type = IRQ_TYPE_NONE;
459
+ girq->handler = handle_simple_irq;
460
+ girq->threaded = true;
461
+
462
+ ret = devm_request_threaded_irq(dev, virq, NULL, wcove_gpio_irq_handler,
463
+ IRQF_ONESHOT, pdev->name, wg);
472464 if (ret) {
473465 dev_err(dev, "Failed to request irq %d\n", virq);
474466 return ret;
475467 }
476468
477
- gpiochip_set_nested_irqchip(&wg->chip, &wcove_irqchip, virq);
469
+ ret = devm_gpiochip_add_data(dev, &wg->chip, wg);
470
+ if (ret) {
471
+ dev_err(dev, "Failed to add gpiochip: %d\n", ret);
472
+ return ret;
473
+ }
478474
479475 /* Enable GPIO0 interrupts */
480476 ret = regmap_update_bits(wg->regmap, IRQ_MASK_BASE, GPIO_IRQ0_MASK,