blob: 016b4019d2a5652b07099a1848bab1c400b72be9 [file] [log] [blame]
Mathias Nymana5d811b2013-06-18 14:33:02 +03001/*
2 * Pinctrl GPIO driver for Intel Baytrail
3 * Copyright (c) 2012-2013, Intel Corporation.
4 *
5 * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
Mathias Nymana5d811b2013-06-18 14:33:02 +030015 */
16
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/types.h>
21#include <linux/bitops.h>
22#include <linux/interrupt.h>
Mathias Nymana5d811b2013-06-18 14:33:02 +030023#include <linux/gpio.h>
Mathias Nymana5d811b2013-06-18 14:33:02 +030024#include <linux/acpi.h>
Mathias Nymana5d811b2013-06-18 14:33:02 +030025#include <linux/platform_device.h>
26#include <linux/seq_file.h>
27#include <linux/io.h>
28#include <linux/pm_runtime.h>
29#include <linux/pinctrl/pinctrl.h>
30
31/* memory mapped register offsets */
32#define BYT_CONF0_REG 0x000
33#define BYT_CONF1_REG 0x004
34#define BYT_VAL_REG 0x008
35#define BYT_DFT_REG 0x00c
36#define BYT_INT_STAT_REG 0x800
37
38/* BYT_CONF0_REG register bits */
Mika Westerberg3ff95882014-05-16 12:18:29 +030039#define BYT_IODEN BIT(31)
Eric Ernstff998352014-06-12 11:06:20 -070040#define BYT_DIRECT_IRQ_EN BIT(27)
Mathias Nymana5d811b2013-06-18 14:33:02 +030041#define BYT_TRIG_NEG BIT(26)
42#define BYT_TRIG_POS BIT(25)
43#define BYT_TRIG_LVL BIT(24)
Mika Westerberg3ff95882014-05-16 12:18:29 +030044#define BYT_PULL_STR_SHIFT 9
45#define BYT_PULL_STR_MASK (3 << BYT_PULL_STR_SHIFT)
46#define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT)
47#define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT)
48#define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT)
49#define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT)
50#define BYT_PULL_ASSIGN_SHIFT 7
51#define BYT_PULL_ASSIGN_MASK (3 << BYT_PULL_ASSIGN_SHIFT)
52#define BYT_PULL_ASSIGN_UP (1 << BYT_PULL_ASSIGN_SHIFT)
53#define BYT_PULL_ASSIGN_DOWN (2 << BYT_PULL_ASSIGN_SHIFT)
Mathias Nymana5d811b2013-06-18 14:33:02 +030054#define BYT_PIN_MUX 0x07
55
56/* BYT_VAL_REG register bits */
57#define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/
58#define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/
59#define BYT_LEVEL BIT(0)
60
61#define BYT_DIR_MASK (BIT(1) | BIT(2))
62#define BYT_TRIG_MASK (BIT(26) | BIT(25) | BIT(24))
63
Mika Westerbergfcc18de2015-02-23 14:53:13 +020064#define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | \
65 BYT_PIN_MUX)
66#define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL)
67
Mathias Nymana5d811b2013-06-18 14:33:02 +030068#define BYT_NGPIO_SCORE 102
69#define BYT_NGPIO_NCORE 28
70#define BYT_NGPIO_SUS 44
71
Chew, Kean Ho42bd0072014-03-06 21:59:49 +080072#define BYT_SCORE_ACPI_UID "1"
73#define BYT_NCORE_ACPI_UID "2"
74#define BYT_SUS_ACPI_UID "3"
75
Mathias Nymana5d811b2013-06-18 14:33:02 +030076/*
77 * Baytrail gpio controller consist of three separate sub-controllers called
78 * SCORE, NCORE and SUS. The sub-controllers are identified by their acpi UID.
79 *
80 * GPIO numbering is _not_ ordered meaning that gpio # 0 in ACPI namespace does
81 * _not_ correspond to the first gpio register at controller's gpio base.
82 * There is no logic or pattern in mapping gpio numbers to registers (pads) so
83 * each sub-controller needs to have its own mapping table
84 */
85
86/* score_pins[gpio_nr] = pad_nr */
87
88static unsigned const score_pins[BYT_NGPIO_SCORE] = {
89 85, 89, 93, 96, 99, 102, 98, 101, 34, 37,
90 36, 38, 39, 35, 40, 84, 62, 61, 64, 59,
91 54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
92 52, 49, 48, 43, 46, 41, 45, 42, 58, 44,
93 95, 105, 70, 68, 67, 66, 69, 71, 65, 72,
94 86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
95 80, 82, 13, 12, 15, 14, 17, 18, 19, 16,
96 2, 1, 0, 4, 6, 7, 9, 8, 33, 32,
97 31, 30, 29, 27, 25, 28, 26, 23, 21, 20,
98 24, 22, 5, 3, 10, 11, 106, 87, 91, 104,
99 97, 100,
100};
101
102static unsigned const ncore_pins[BYT_NGPIO_NCORE] = {
103 19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
104 14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
105 3, 6, 10, 13, 2, 5, 9, 7,
106};
107
108static unsigned const sus_pins[BYT_NGPIO_SUS] = {
109 29, 33, 30, 31, 32, 34, 36, 35, 38, 37,
110 18, 7, 11, 20, 17, 1, 8, 10, 19, 12,
111 0, 2, 23, 39, 28, 27, 22, 21, 24, 25,
112 26, 51, 56, 54, 49, 55, 48, 57, 50, 58,
113 52, 53, 59, 40,
114};
115
116static struct pinctrl_gpio_range byt_ranges[] = {
117 {
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800118 .name = BYT_SCORE_ACPI_UID, /* match with acpi _UID in probe */
Mathias Nymana5d811b2013-06-18 14:33:02 +0300119 .npins = BYT_NGPIO_SCORE,
120 .pins = score_pins,
121 },
122 {
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800123 .name = BYT_NCORE_ACPI_UID,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300124 .npins = BYT_NGPIO_NCORE,
125 .pins = ncore_pins,
126 },
127 {
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800128 .name = BYT_SUS_ACPI_UID,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300129 .npins = BYT_NGPIO_SUS,
130 .pins = sus_pins,
131 },
132 {
133 },
134};
135
Mika Westerbergfcc18de2015-02-23 14:53:13 +0200136struct byt_gpio_pin_context {
137 u32 conf0;
138 u32 val;
139};
140
Mathias Nymana5d811b2013-06-18 14:33:02 +0300141struct byt_gpio {
142 struct gpio_chip chip;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300143 struct platform_device *pdev;
144 spinlock_t lock;
145 void __iomem *reg_base;
146 struct pinctrl_gpio_range *range;
Mika Westerbergfcc18de2015-02-23 14:53:13 +0200147 struct byt_gpio_pin_context *saved_context;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300148};
149
Andy Shevchenko17e52462013-07-10 14:55:39 +0300150#define to_byt_gpio(c) container_of(c, struct byt_gpio, chip)
151
Mathias Nymana5d811b2013-06-18 14:33:02 +0300152static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset,
153 int reg)
154{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300155 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300156 u32 reg_offset;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300157
158 if (reg == BYT_INT_STAT_REG)
159 reg_offset = (offset / 32) * 4;
160 else
161 reg_offset = vg->range->pins[offset] * 16;
162
Andy Shevchenko9c5b6552013-07-10 14:55:38 +0300163 return vg->reg_base + reg_offset + reg;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300164}
165
Mika Westerberg95f09722015-02-23 14:53:11 +0200166static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned offset)
167{
168 void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
169 unsigned long flags;
170 u32 value;
171
172 spin_lock_irqsave(&vg->lock, flags);
173 value = readl(reg);
174 value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
175 writel(value, reg);
176 spin_unlock_irqrestore(&vg->lock, flags);
177}
178
Mika Westerbergf8323b62015-02-23 14:53:10 +0200179static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset)
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800180{
181 /* SCORE pin 92-93 */
182 if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) &&
183 offset >= 92 && offset <= 93)
Mika Westerbergf8323b62015-02-23 14:53:10 +0200184 return 1;
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800185
186 /* SUS pin 11-21 */
187 if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) &&
188 offset >= 11 && offset <= 21)
Mika Westerbergf8323b62015-02-23 14:53:10 +0200189 return 1;
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800190
Mika Westerbergf8323b62015-02-23 14:53:10 +0200191 return 0;
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800192}
193
Mathias Nymana5d811b2013-06-18 14:33:02 +0300194static int byt_gpio_request(struct gpio_chip *chip, unsigned offset)
195{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300196 struct byt_gpio *vg = to_byt_gpio(chip);
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800197 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG);
Mika Westerbergf8323b62015-02-23 14:53:10 +0200198 u32 value, gpio_mux;
Mika Westerberg39ce8152015-08-04 15:03:14 +0300199 unsigned long flags;
200
201 spin_lock_irqsave(&vg->lock, flags);
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800202
203 /*
204 * In most cases, func pin mux 000 means GPIO function.
205 * But, some pins may have func pin mux 001 represents
Mika Westerbergf8323b62015-02-23 14:53:10 +0200206 * GPIO function.
207 *
208 * Because there are devices out there where some pins were not
209 * configured correctly we allow changing the mux value from
210 * request (but print out warning about that).
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800211 */
212 value = readl(reg) & BYT_PIN_MUX;
Mika Westerbergf8323b62015-02-23 14:53:10 +0200213 gpio_mux = byt_get_gpio_mux(vg, offset);
214 if (WARN_ON(gpio_mux != value)) {
Mika Westerbergf8323b62015-02-23 14:53:10 +0200215 value = readl(reg) & ~BYT_PIN_MUX;
216 value |= gpio_mux;
217 writel(value, reg);
Mika Westerbergf8323b62015-02-23 14:53:10 +0200218
219 dev_warn(&vg->pdev->dev,
220 "pin %u forcibly re-configured as GPIO\n", offset);
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800221 }
Mathias Nymana5d811b2013-06-18 14:33:02 +0300222
Mika Westerberg39ce8152015-08-04 15:03:14 +0300223 spin_unlock_irqrestore(&vg->lock, flags);
224
Mathias Nymana5d811b2013-06-18 14:33:02 +0300225 pm_runtime_get(&vg->pdev->dev);
226
227 return 0;
228}
229
230static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
231{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300232 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300233
Mika Westerberg95f09722015-02-23 14:53:11 +0200234 byt_gpio_clear_triggering(vg, offset);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300235 pm_runtime_put(&vg->pdev->dev);
236}
237
238static int byt_irq_type(struct irq_data *d, unsigned type)
239{
Mika Westerberge1ee5c52014-07-25 09:54:47 +0300240 struct byt_gpio *vg = to_byt_gpio(irq_data_get_irq_chip_data(d));
Mathias Nymana5d811b2013-06-18 14:33:02 +0300241 u32 offset = irqd_to_hwirq(d);
242 u32 value;
243 unsigned long flags;
244 void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
245
246 if (offset >= vg->chip.ngpio)
247 return -EINVAL;
248
249 spin_lock_irqsave(&vg->lock, flags);
250 value = readl(reg);
251
Loic Poulain3a71c052014-09-26 16:14:51 +0200252 WARN(value & BYT_DIRECT_IRQ_EN,
253 "Bad pad config for io mode, force direct_irq_en bit clearing");
254
Mathias Nymana5d811b2013-06-18 14:33:02 +0300255 /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
256 * are used to indicate high and low level triggering
257 */
Loic Poulain3a71c052014-09-26 16:14:51 +0200258 value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
259 BYT_TRIG_LVL);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300260
Mathias Nymana5d811b2013-06-18 14:33:02 +0300261 writel(value, reg);
262
Mika Westerberg31e43292015-02-23 14:53:12 +0200263 if (type & IRQ_TYPE_EDGE_BOTH)
Thomas Gleixnerf3a085b2015-06-23 15:52:44 +0200264 irq_set_handler_locked(d, handle_edge_irq);
Mika Westerberg31e43292015-02-23 14:53:12 +0200265 else if (type & IRQ_TYPE_LEVEL_MASK)
Thomas Gleixnerf3a085b2015-06-23 15:52:44 +0200266 irq_set_handler_locked(d, handle_level_irq);
Mika Westerberg31e43292015-02-23 14:53:12 +0200267
Mathias Nymana5d811b2013-06-18 14:33:02 +0300268 spin_unlock_irqrestore(&vg->lock, flags);
269
270 return 0;
271}
272
273static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
274{
275 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
Mika Westerberg39ce8152015-08-04 15:03:14 +0300276 struct byt_gpio *vg = to_byt_gpio(chip);
277 unsigned long flags;
278 u32 val;
279
280 spin_lock_irqsave(&vg->lock, flags);
281 val = readl(reg);
282 spin_unlock_irqrestore(&vg->lock, flags);
283
284 return val & BYT_LEVEL;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300285}
286
287static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
288{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300289 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300290 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
291 unsigned long flags;
292 u32 old_val;
293
294 spin_lock_irqsave(&vg->lock, flags);
295
296 old_val = readl(reg);
297
298 if (value)
299 writel(old_val | BYT_LEVEL, reg);
300 else
301 writel(old_val & ~BYT_LEVEL, reg);
302
303 spin_unlock_irqrestore(&vg->lock, flags);
304}
305
306static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
307{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300308 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300309 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
310 unsigned long flags;
311 u32 value;
312
313 spin_lock_irqsave(&vg->lock, flags);
314
315 value = readl(reg) | BYT_DIR_MASK;
Andy Shevchenko496940c2013-07-10 14:55:40 +0300316 value &= ~BYT_INPUT_EN; /* active low */
Mathias Nymana5d811b2013-06-18 14:33:02 +0300317 writel(value, reg);
318
319 spin_unlock_irqrestore(&vg->lock, flags);
320
321 return 0;
322}
323
324static int byt_gpio_direction_output(struct gpio_chip *chip,
325 unsigned gpio, int value)
326{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300327 struct byt_gpio *vg = to_byt_gpio(chip);
Eric Ernstff998352014-06-12 11:06:20 -0700328 void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300329 void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
330 unsigned long flags;
331 u32 reg_val;
332
333 spin_lock_irqsave(&vg->lock, flags);
334
Eric Ernstff998352014-06-12 11:06:20 -0700335 /*
336 * Before making any direction modifications, do a check if gpio
337 * is set for direct IRQ. On baytrail, setting GPIO to output does
338 * not make sense, so let's at least warn the caller before they shoot
339 * themselves in the foot.
340 */
341 WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
342 "Potential Error: Setting GPIO with direct_irq_en to output");
343
Andy Shevchenko496940c2013-07-10 14:55:40 +0300344 reg_val = readl(reg) | BYT_DIR_MASK;
David Cohend90c3382014-10-14 10:54:37 -0700345 reg_val &= ~(BYT_OUTPUT_EN | BYT_INPUT_EN);
Andy Shevchenko496940c2013-07-10 14:55:40 +0300346
347 if (value)
348 writel(reg_val | BYT_LEVEL, reg);
349 else
350 writel(reg_val & ~BYT_LEVEL, reg);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300351
352 spin_unlock_irqrestore(&vg->lock, flags);
353
354 return 0;
355}
356
357static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
358{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300359 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300360 int i;
361 unsigned long flags;
362 u32 conf0, val, offs;
363
364 spin_lock_irqsave(&vg->lock, flags);
365
366 for (i = 0; i < vg->chip.ngpio; i++) {
Mika Westerberg3ff95882014-05-16 12:18:29 +0300367 const char *pull_str = NULL;
368 const char *pull = NULL;
Mathias Nymana4d8d6d2013-11-22 14:01:23 +0200369 const char *label;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300370 offs = vg->range->pins[i] * 16;
371 conf0 = readl(vg->reg_base + offs + BYT_CONF0_REG);
372 val = readl(vg->reg_base + offs + BYT_VAL_REG);
373
Mathias Nymana4d8d6d2013-11-22 14:01:23 +0200374 label = gpiochip_is_requested(chip, i);
375 if (!label)
376 label = "Unrequested";
377
Mika Westerberg3ff95882014-05-16 12:18:29 +0300378 switch (conf0 & BYT_PULL_ASSIGN_MASK) {
379 case BYT_PULL_ASSIGN_UP:
380 pull = "up";
381 break;
382 case BYT_PULL_ASSIGN_DOWN:
383 pull = "down";
384 break;
385 }
386
387 switch (conf0 & BYT_PULL_STR_MASK) {
388 case BYT_PULL_STR_2K:
389 pull_str = "2k";
390 break;
391 case BYT_PULL_STR_10K:
392 pull_str = "10k";
393 break;
394 case BYT_PULL_STR_20K:
395 pull_str = "20k";
396 break;
397 case BYT_PULL_STR_40K:
398 pull_str = "40k";
399 break;
400 }
401
Mathias Nymana5d811b2013-06-18 14:33:02 +0300402 seq_printf(s,
Mika Westerberg3ff95882014-05-16 12:18:29 +0300403 " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
Mathias Nymana5d811b2013-06-18 14:33:02 +0300404 i,
Mathias Nymana4d8d6d2013-11-22 14:01:23 +0200405 label,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300406 val & BYT_INPUT_EN ? " " : "in",
407 val & BYT_OUTPUT_EN ? " " : "out",
408 val & BYT_LEVEL ? "hi" : "lo",
409 vg->range->pins[i], offs,
410 conf0 & 0x7,
Mika Westerberg3ff95882014-05-16 12:18:29 +0300411 conf0 & BYT_TRIG_NEG ? " fall" : " ",
412 conf0 & BYT_TRIG_POS ? " rise" : " ",
413 conf0 & BYT_TRIG_LVL ? " level" : " ");
414
415 if (pull && pull_str)
416 seq_printf(s, " %-4s %-3s", pull, pull_str);
417 else
418 seq_puts(s, " ");
419
420 if (conf0 & BYT_IODEN)
421 seq_puts(s, " open-drain");
422
423 seq_puts(s, "\n");
Mathias Nymana5d811b2013-06-18 14:33:02 +0300424 }
425 spin_unlock_irqrestore(&vg->lock, flags);
426}
427
Mathias Nymana5d811b2013-06-18 14:33:02 +0300428static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
429{
430 struct irq_data *data = irq_desc_get_irq_data(desc);
Mika Westerberge1ee5c52014-07-25 09:54:47 +0300431 struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc));
Mathias Nymana5d811b2013-06-18 14:33:02 +0300432 struct irq_chip *chip = irq_data_get_irq_chip(data);
Mika Westerberg31e43292015-02-23 14:53:12 +0200433 u32 base, pin;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300434 void __iomem *reg;
Mika Westerberg31e43292015-02-23 14:53:12 +0200435 unsigned long pending;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300436 unsigned virq;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300437
438 /* check from GPIO controller which pin triggered the interrupt */
439 for (base = 0; base < vg->chip.ngpio; base += 32) {
Mathias Nymana5d811b2013-06-18 14:33:02 +0300440 reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
Mika Westerberg31e43292015-02-23 14:53:12 +0200441 pending = readl(reg);
442 for_each_set_bit(pin, &pending, 32) {
Mika Westerberge1ee5c52014-07-25 09:54:47 +0300443 virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300444 generic_handle_irq(virq);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300445 }
446 }
447 chip->irq_eoi(data);
448}
449
Mika Westerberg31e43292015-02-23 14:53:12 +0200450static void byt_irq_ack(struct irq_data *d)
451{
452 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
453 struct byt_gpio *vg = to_byt_gpio(gc);
454 unsigned offset = irqd_to_hwirq(d);
455 void __iomem *reg;
456
Mika Westerberg39ce8152015-08-04 15:03:14 +0300457 spin_lock(&vg->lock);
Mika Westerberg31e43292015-02-23 14:53:12 +0200458 reg = byt_gpio_reg(&vg->chip, offset, BYT_INT_STAT_REG);
459 writel(BIT(offset % 32), reg);
Mika Westerberg39ce8152015-08-04 15:03:14 +0300460 spin_unlock(&vg->lock);
Mika Westerberg31e43292015-02-23 14:53:12 +0200461}
462
Mathias Nymana5d811b2013-06-18 14:33:02 +0300463static void byt_irq_unmask(struct irq_data *d)
464{
Mika Westerberg31e43292015-02-23 14:53:12 +0200465 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
466 struct byt_gpio *vg = to_byt_gpio(gc);
467 unsigned offset = irqd_to_hwirq(d);
468 unsigned long flags;
469 void __iomem *reg;
470 u32 value;
471
472 spin_lock_irqsave(&vg->lock, flags);
473
474 reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
475 value = readl(reg);
476
477 switch (irqd_get_trigger_type(d)) {
478 case IRQ_TYPE_LEVEL_HIGH:
479 value |= BYT_TRIG_LVL;
480 case IRQ_TYPE_EDGE_RISING:
481 value |= BYT_TRIG_POS;
482 break;
483 case IRQ_TYPE_LEVEL_LOW:
484 value |= BYT_TRIG_LVL;
485 case IRQ_TYPE_EDGE_FALLING:
486 value |= BYT_TRIG_NEG;
487 break;
488 case IRQ_TYPE_EDGE_BOTH:
489 value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
490 break;
491 }
492
493 writel(value, reg);
494
495 spin_unlock_irqrestore(&vg->lock, flags);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300496}
497
498static void byt_irq_mask(struct irq_data *d)
499{
Mika Westerberg31e43292015-02-23 14:53:12 +0200500 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
501 struct byt_gpio *vg = to_byt_gpio(gc);
502
503 byt_gpio_clear_triggering(vg, irqd_to_hwirq(d));
Mathias Nymana5d811b2013-06-18 14:33:02 +0300504}
505
506static struct irq_chip byt_irqchip = {
507 .name = "BYT-GPIO",
Mika Westerberg31e43292015-02-23 14:53:12 +0200508 .irq_ack = byt_irq_ack,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300509 .irq_mask = byt_irq_mask,
510 .irq_unmask = byt_irq_unmask,
511 .irq_set_type = byt_irq_type,
Mathias Nyman41939e62014-08-11 16:51:55 +0300512 .flags = IRQCHIP_SKIP_SET_WAKE,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300513};
514
515static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
516{
517 void __iomem *reg;
518 u32 base, value;
Mika Westerberg95f09722015-02-23 14:53:11 +0200519 int i;
520
521 /*
522 * Clear interrupt triggers for all pins that are GPIOs and
523 * do not use direct IRQ mode. This will prevent spurious
524 * interrupts from misconfigured pins.
525 */
526 for (i = 0; i < vg->chip.ngpio; i++) {
527 value = readl(byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG));
528 if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i) &&
529 !(value & BYT_DIRECT_IRQ_EN)) {
530 byt_gpio_clear_triggering(vg, i);
531 dev_dbg(&vg->pdev->dev, "disabling GPIO %d\n", i);
532 }
533 }
Mathias Nymana5d811b2013-06-18 14:33:02 +0300534
535 /* clear interrupt status trigger registers */
536 for (base = 0; base < vg->chip.ngpio; base += 32) {
537 reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
538 writel(0xffffffff, reg);
539 /* make sure trigger bits are cleared, if not then a pin
540 might be misconfigured in bios */
541 value = readl(reg);
542 if (value)
543 dev_err(&vg->pdev->dev,
544 "GPIO interrupt error, pins misconfigured\n");
545 }
546}
547
Mathias Nymana5d811b2013-06-18 14:33:02 +0300548static int byt_gpio_probe(struct platform_device *pdev)
549{
550 struct byt_gpio *vg;
551 struct gpio_chip *gc;
552 struct resource *mem_rc, *irq_rc;
553 struct device *dev = &pdev->dev;
554 struct acpi_device *acpi_dev;
555 struct pinctrl_gpio_range *range;
556 acpi_handle handle = ACPI_HANDLE(dev);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300557 int ret;
558
559 if (acpi_bus_get_device(handle, &acpi_dev))
560 return -ENODEV;
561
562 vg = devm_kzalloc(dev, sizeof(struct byt_gpio), GFP_KERNEL);
563 if (!vg) {
564 dev_err(&pdev->dev, "can't allocate byt_gpio chip data\n");
565 return -ENOMEM;
566 }
567
568 for (range = byt_ranges; range->name; range++) {
569 if (!strcmp(acpi_dev->pnp.unique_id, range->name)) {
570 vg->chip.ngpio = range->npins;
571 vg->range = range;
572 break;
573 }
574 }
575
576 if (!vg->chip.ngpio || !vg->range)
577 return -ENODEV;
578
579 vg->pdev = pdev;
580 platform_set_drvdata(pdev, vg);
581
582 mem_rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
583 vg->reg_base = devm_ioremap_resource(dev, mem_rc);
584 if (IS_ERR(vg->reg_base))
585 return PTR_ERR(vg->reg_base);
586
587 spin_lock_init(&vg->lock);
588
589 gc = &vg->chip;
590 gc->label = dev_name(&pdev->dev);
591 gc->owner = THIS_MODULE;
592 gc->request = byt_gpio_request;
593 gc->free = byt_gpio_free;
594 gc->direction_input = byt_gpio_direction_input;
595 gc->direction_output = byt_gpio_direction_output;
596 gc->get = byt_gpio_get;
597 gc->set = byt_gpio_set;
598 gc->dbg_show = byt_gpio_dbg_show;
599 gc->base = -1;
Linus Walleij9fb1f392013-12-04 14:42:46 +0100600 gc->can_sleep = false;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300601 gc->dev = dev;
602
Mika Westerbergfcc18de2015-02-23 14:53:13 +0200603#ifdef CONFIG_PM_SLEEP
604 vg->saved_context = devm_kcalloc(&pdev->dev, gc->ngpio,
605 sizeof(*vg->saved_context), GFP_KERNEL);
606#endif
607
Jin Yao605a7bc2014-05-15 18:28:47 +0300608 ret = gpiochip_add(gc);
609 if (ret) {
610 dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
611 return ret;
612 }
613
Mika Westerberge1ee5c52014-07-25 09:54:47 +0300614 /* set up interrupts */
615 irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
616 if (irq_rc && irq_rc->start) {
617 byt_gpio_irq_init_hw(vg);
618 ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
619 handle_simple_irq, IRQ_TYPE_NONE);
620 if (ret) {
621 dev_err(dev, "failed to add irqchip\n");
622 gpiochip_remove(gc);
623 return ret;
624 }
625
626 gpiochip_set_chained_irqchip(gc, &byt_irqchip,
627 (unsigned)irq_rc->start,
628 byt_gpio_irq_handler);
629 }
630
Mathias Nymana5d811b2013-06-18 14:33:02 +0300631 pm_runtime_enable(dev);
632
633 return 0;
634}
635
Mika Westerbergfcc18de2015-02-23 14:53:13 +0200636#ifdef CONFIG_PM_SLEEP
637static int byt_gpio_suspend(struct device *dev)
638{
639 struct platform_device *pdev = to_platform_device(dev);
640 struct byt_gpio *vg = platform_get_drvdata(pdev);
641 int i;
642
643 for (i = 0; i < vg->chip.ngpio; i++) {
644 void __iomem *reg;
645 u32 value;
646
647 reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG);
648 value = readl(reg) & BYT_CONF0_RESTORE_MASK;
649 vg->saved_context[i].conf0 = value;
650
651 reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG);
652 value = readl(reg) & BYT_VAL_RESTORE_MASK;
653 vg->saved_context[i].val = value;
654 }
655
656 return 0;
657}
658
659static int byt_gpio_resume(struct device *dev)
660{
661 struct platform_device *pdev = to_platform_device(dev);
662 struct byt_gpio *vg = platform_get_drvdata(pdev);
663 int i;
664
665 for (i = 0; i < vg->chip.ngpio; i++) {
666 void __iomem *reg;
667 u32 value;
668
669 reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG);
670 value = readl(reg);
671 if ((value & BYT_CONF0_RESTORE_MASK) !=
672 vg->saved_context[i].conf0) {
673 value &= ~BYT_CONF0_RESTORE_MASK;
674 value |= vg->saved_context[i].conf0;
675 writel(value, reg);
676 dev_info(dev, "restored pin %d conf0 %#08x", i, value);
677 }
678
679 reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG);
680 value = readl(reg);
681 if ((value & BYT_VAL_RESTORE_MASK) !=
682 vg->saved_context[i].val) {
683 u32 v;
684
685 v = value & ~BYT_VAL_RESTORE_MASK;
686 v |= vg->saved_context[i].val;
687 if (v != value) {
688 writel(v, reg);
689 dev_dbg(dev, "restored pin %d val %#08x\n",
690 i, v);
691 }
692 }
693 }
694
695 return 0;
696}
697#endif
698
Mathias Nymana5d811b2013-06-18 14:33:02 +0300699static int byt_gpio_runtime_suspend(struct device *dev)
700{
701 return 0;
702}
703
704static int byt_gpio_runtime_resume(struct device *dev)
705{
706 return 0;
707}
708
709static const struct dev_pm_ops byt_gpio_pm_ops = {
Mika Westerbergfcc18de2015-02-23 14:53:13 +0200710 SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume)
711 SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume,
712 NULL)
Mathias Nymana5d811b2013-06-18 14:33:02 +0300713};
714
715static const struct acpi_device_id byt_gpio_acpi_match[] = {
716 { "INT33B2", 0 },
Jin Yao20482d32014-05-15 18:28:46 +0300717 { "INT33FC", 0 },
Mathias Nymana5d811b2013-06-18 14:33:02 +0300718 { }
719};
720MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
721
722static int byt_gpio_remove(struct platform_device *pdev)
723{
724 struct byt_gpio *vg = platform_get_drvdata(pdev);
Andy Shevchenkoec243322013-07-10 14:55:36 +0300725
Mathias Nymana5d811b2013-06-18 14:33:02 +0300726 pm_runtime_disable(&pdev->dev);
abdoulaye bertheb4e7c552014-07-12 22:30:13 +0200727 gpiochip_remove(&vg->chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300728
729 return 0;
730}
731
732static struct platform_driver byt_gpio_driver = {
733 .probe = byt_gpio_probe,
734 .remove = byt_gpio_remove,
735 .driver = {
736 .name = "byt_gpio",
Mathias Nymana5d811b2013-06-18 14:33:02 +0300737 .pm = &byt_gpio_pm_ops,
738 .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
739 },
740};
741
742static int __init byt_gpio_init(void)
743{
744 return platform_driver_register(&byt_gpio_driver);
745}
Mathias Nymana5d811b2013-06-18 14:33:02 +0300746subsys_initcall(byt_gpio_init);
Felipe Balbi9067bbe2014-10-13 15:50:08 -0500747
748static void __exit byt_gpio_exit(void)
749{
750 platform_driver_unregister(&byt_gpio_driver);
751}
752module_exit(byt_gpio_exit);