blob: e12e5b07f6d751aba9cce63cf49d2acabe50b7ab [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.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/types.h>
26#include <linux/bitops.h>
27#include <linux/interrupt.h>
Mathias Nymana5d811b2013-06-18 14:33:02 +030028#include <linux/gpio.h>
Mathias Nymana5d811b2013-06-18 14:33:02 +030029#include <linux/acpi.h>
Mathias Nymana5d811b2013-06-18 14:33:02 +030030#include <linux/platform_device.h>
31#include <linux/seq_file.h>
32#include <linux/io.h>
33#include <linux/pm_runtime.h>
34#include <linux/pinctrl/pinctrl.h>
35
36/* memory mapped register offsets */
37#define BYT_CONF0_REG 0x000
38#define BYT_CONF1_REG 0x004
39#define BYT_VAL_REG 0x008
40#define BYT_DFT_REG 0x00c
41#define BYT_INT_STAT_REG 0x800
42
43/* BYT_CONF0_REG register bits */
Mika Westerberg3ff95882014-05-16 12:18:29 +030044#define BYT_IODEN BIT(31)
Eric Ernstff998352014-06-12 11:06:20 -070045#define BYT_DIRECT_IRQ_EN BIT(27)
Mathias Nymana5d811b2013-06-18 14:33:02 +030046#define BYT_TRIG_NEG BIT(26)
47#define BYT_TRIG_POS BIT(25)
48#define BYT_TRIG_LVL BIT(24)
Mika Westerberg3ff95882014-05-16 12:18:29 +030049#define BYT_PULL_STR_SHIFT 9
50#define BYT_PULL_STR_MASK (3 << BYT_PULL_STR_SHIFT)
51#define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT)
52#define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT)
53#define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT)
54#define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT)
55#define BYT_PULL_ASSIGN_SHIFT 7
56#define BYT_PULL_ASSIGN_MASK (3 << BYT_PULL_ASSIGN_SHIFT)
57#define BYT_PULL_ASSIGN_UP (1 << BYT_PULL_ASSIGN_SHIFT)
58#define BYT_PULL_ASSIGN_DOWN (2 << BYT_PULL_ASSIGN_SHIFT)
Mathias Nymana5d811b2013-06-18 14:33:02 +030059#define BYT_PIN_MUX 0x07
60
61/* BYT_VAL_REG register bits */
62#define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/
63#define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/
64#define BYT_LEVEL BIT(0)
65
66#define BYT_DIR_MASK (BIT(1) | BIT(2))
67#define BYT_TRIG_MASK (BIT(26) | BIT(25) | BIT(24))
68
69#define BYT_NGPIO_SCORE 102
70#define BYT_NGPIO_NCORE 28
71#define BYT_NGPIO_SUS 44
72
Chew, Kean Ho42bd0072014-03-06 21:59:49 +080073#define BYT_SCORE_ACPI_UID "1"
74#define BYT_NCORE_ACPI_UID "2"
75#define BYT_SUS_ACPI_UID "3"
76
Mathias Nymana5d811b2013-06-18 14:33:02 +030077/*
78 * Baytrail gpio controller consist of three separate sub-controllers called
79 * SCORE, NCORE and SUS. The sub-controllers are identified by their acpi UID.
80 *
81 * GPIO numbering is _not_ ordered meaning that gpio # 0 in ACPI namespace does
82 * _not_ correspond to the first gpio register at controller's gpio base.
83 * There is no logic or pattern in mapping gpio numbers to registers (pads) so
84 * each sub-controller needs to have its own mapping table
85 */
86
87/* score_pins[gpio_nr] = pad_nr */
88
89static unsigned const score_pins[BYT_NGPIO_SCORE] = {
90 85, 89, 93, 96, 99, 102, 98, 101, 34, 37,
91 36, 38, 39, 35, 40, 84, 62, 61, 64, 59,
92 54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
93 52, 49, 48, 43, 46, 41, 45, 42, 58, 44,
94 95, 105, 70, 68, 67, 66, 69, 71, 65, 72,
95 86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
96 80, 82, 13, 12, 15, 14, 17, 18, 19, 16,
97 2, 1, 0, 4, 6, 7, 9, 8, 33, 32,
98 31, 30, 29, 27, 25, 28, 26, 23, 21, 20,
99 24, 22, 5, 3, 10, 11, 106, 87, 91, 104,
100 97, 100,
101};
102
103static unsigned const ncore_pins[BYT_NGPIO_NCORE] = {
104 19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
105 14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
106 3, 6, 10, 13, 2, 5, 9, 7,
107};
108
109static unsigned const sus_pins[BYT_NGPIO_SUS] = {
110 29, 33, 30, 31, 32, 34, 36, 35, 38, 37,
111 18, 7, 11, 20, 17, 1, 8, 10, 19, 12,
112 0, 2, 23, 39, 28, 27, 22, 21, 24, 25,
113 26, 51, 56, 54, 49, 55, 48, 57, 50, 58,
114 52, 53, 59, 40,
115};
116
117static struct pinctrl_gpio_range byt_ranges[] = {
118 {
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800119 .name = BYT_SCORE_ACPI_UID, /* match with acpi _UID in probe */
Mathias Nymana5d811b2013-06-18 14:33:02 +0300120 .npins = BYT_NGPIO_SCORE,
121 .pins = score_pins,
122 },
123 {
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800124 .name = BYT_NCORE_ACPI_UID,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300125 .npins = BYT_NGPIO_NCORE,
126 .pins = ncore_pins,
127 },
128 {
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800129 .name = BYT_SUS_ACPI_UID,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300130 .npins = BYT_NGPIO_SUS,
131 .pins = sus_pins,
132 },
133 {
134 },
135};
136
137struct byt_gpio {
138 struct gpio_chip chip;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300139 struct platform_device *pdev;
140 spinlock_t lock;
141 void __iomem *reg_base;
142 struct pinctrl_gpio_range *range;
143};
144
Andy Shevchenko17e52462013-07-10 14:55:39 +0300145#define to_byt_gpio(c) container_of(c, struct byt_gpio, chip)
146
Mathias Nymana5d811b2013-06-18 14:33:02 +0300147static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset,
148 int reg)
149{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300150 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300151 u32 reg_offset;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300152
153 if (reg == BYT_INT_STAT_REG)
154 reg_offset = (offset / 32) * 4;
155 else
156 reg_offset = vg->range->pins[offset] * 16;
157
Andy Shevchenko9c5b6552013-07-10 14:55:38 +0300158 return vg->reg_base + reg_offset + reg;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300159}
160
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800161static bool is_special_pin(struct byt_gpio *vg, unsigned offset)
162{
163 /* SCORE pin 92-93 */
164 if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) &&
165 offset >= 92 && offset <= 93)
166 return true;
167
168 /* SUS pin 11-21 */
169 if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) &&
170 offset >= 11 && offset <= 21)
171 return true;
172
173 return false;
174}
175
Mathias Nymana5d811b2013-06-18 14:33:02 +0300176static int byt_gpio_request(struct gpio_chip *chip, unsigned offset)
177{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300178 struct byt_gpio *vg = to_byt_gpio(chip);
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800179 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG);
180 u32 value;
181 bool special;
182
183 /*
184 * In most cases, func pin mux 000 means GPIO function.
185 * But, some pins may have func pin mux 001 represents
186 * GPIO function. Only allow user to export pin with
187 * func pin mux preset as GPIO function by BIOS/FW.
188 */
189 value = readl(reg) & BYT_PIN_MUX;
190 special = is_special_pin(vg, offset);
191 if ((special && value != 1) || (!special && value)) {
192 dev_err(&vg->pdev->dev,
193 "pin %u cannot be used as GPIO.\n", offset);
194 return -EINVAL;
195 }
Mathias Nymana5d811b2013-06-18 14:33:02 +0300196
197 pm_runtime_get(&vg->pdev->dev);
198
199 return 0;
200}
201
202static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
203{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300204 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300205 void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
206 u32 value;
207
208 /* clear interrupt triggering */
209 value = readl(reg);
210 value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
211 writel(value, reg);
212
213 pm_runtime_put(&vg->pdev->dev);
214}
215
216static int byt_irq_type(struct irq_data *d, unsigned type)
217{
Mika Westerberge1ee5c52014-07-25 09:54:47 +0300218 struct byt_gpio *vg = to_byt_gpio(irq_data_get_irq_chip_data(d));
Mathias Nymana5d811b2013-06-18 14:33:02 +0300219 u32 offset = irqd_to_hwirq(d);
220 u32 value;
221 unsigned long flags;
222 void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
223
224 if (offset >= vg->chip.ngpio)
225 return -EINVAL;
226
227 spin_lock_irqsave(&vg->lock, flags);
228 value = readl(reg);
229
230 /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
231 * are used to indicate high and low level triggering
232 */
233 value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
234
235 switch (type) {
236 case IRQ_TYPE_LEVEL_HIGH:
237 value |= BYT_TRIG_LVL;
238 case IRQ_TYPE_EDGE_RISING:
239 value |= BYT_TRIG_POS;
240 break;
241 case IRQ_TYPE_LEVEL_LOW:
242 value |= BYT_TRIG_LVL;
243 case IRQ_TYPE_EDGE_FALLING:
244 value |= BYT_TRIG_NEG;
245 break;
246 case IRQ_TYPE_EDGE_BOTH:
247 value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
248 break;
249 }
250 writel(value, reg);
251
252 spin_unlock_irqrestore(&vg->lock, flags);
253
254 return 0;
255}
256
257static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
258{
259 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
260 return readl(reg) & BYT_LEVEL;
261}
262
263static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
264{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300265 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300266 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
267 unsigned long flags;
268 u32 old_val;
269
270 spin_lock_irqsave(&vg->lock, flags);
271
272 old_val = readl(reg);
273
274 if (value)
275 writel(old_val | BYT_LEVEL, reg);
276 else
277 writel(old_val & ~BYT_LEVEL, reg);
278
279 spin_unlock_irqrestore(&vg->lock, flags);
280}
281
282static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
283{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300284 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300285 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
286 unsigned long flags;
287 u32 value;
288
289 spin_lock_irqsave(&vg->lock, flags);
290
291 value = readl(reg) | BYT_DIR_MASK;
Andy Shevchenko496940c2013-07-10 14:55:40 +0300292 value &= ~BYT_INPUT_EN; /* active low */
Mathias Nymana5d811b2013-06-18 14:33:02 +0300293 writel(value, reg);
294
295 spin_unlock_irqrestore(&vg->lock, flags);
296
297 return 0;
298}
299
300static int byt_gpio_direction_output(struct gpio_chip *chip,
301 unsigned gpio, int value)
302{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300303 struct byt_gpio *vg = to_byt_gpio(chip);
Eric Ernstff998352014-06-12 11:06:20 -0700304 void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300305 void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
306 unsigned long flags;
307 u32 reg_val;
308
309 spin_lock_irqsave(&vg->lock, flags);
310
Eric Ernstff998352014-06-12 11:06:20 -0700311 /*
312 * Before making any direction modifications, do a check if gpio
313 * is set for direct IRQ. On baytrail, setting GPIO to output does
314 * not make sense, so let's at least warn the caller before they shoot
315 * themselves in the foot.
316 */
317 WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
318 "Potential Error: Setting GPIO with direct_irq_en to output");
319
Andy Shevchenko496940c2013-07-10 14:55:40 +0300320 reg_val = readl(reg) | BYT_DIR_MASK;
321 reg_val &= ~BYT_OUTPUT_EN;
322
323 if (value)
324 writel(reg_val | BYT_LEVEL, reg);
325 else
326 writel(reg_val & ~BYT_LEVEL, reg);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300327
328 spin_unlock_irqrestore(&vg->lock, flags);
329
330 return 0;
331}
332
333static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
334{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300335 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300336 int i;
337 unsigned long flags;
338 u32 conf0, val, offs;
339
340 spin_lock_irqsave(&vg->lock, flags);
341
342 for (i = 0; i < vg->chip.ngpio; i++) {
Mika Westerberg3ff95882014-05-16 12:18:29 +0300343 const char *pull_str = NULL;
344 const char *pull = NULL;
Mathias Nymana4d8d6d2013-11-22 14:01:23 +0200345 const char *label;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300346 offs = vg->range->pins[i] * 16;
347 conf0 = readl(vg->reg_base + offs + BYT_CONF0_REG);
348 val = readl(vg->reg_base + offs + BYT_VAL_REG);
349
Mathias Nymana4d8d6d2013-11-22 14:01:23 +0200350 label = gpiochip_is_requested(chip, i);
351 if (!label)
352 label = "Unrequested";
353
Mika Westerberg3ff95882014-05-16 12:18:29 +0300354 switch (conf0 & BYT_PULL_ASSIGN_MASK) {
355 case BYT_PULL_ASSIGN_UP:
356 pull = "up";
357 break;
358 case BYT_PULL_ASSIGN_DOWN:
359 pull = "down";
360 break;
361 }
362
363 switch (conf0 & BYT_PULL_STR_MASK) {
364 case BYT_PULL_STR_2K:
365 pull_str = "2k";
366 break;
367 case BYT_PULL_STR_10K:
368 pull_str = "10k";
369 break;
370 case BYT_PULL_STR_20K:
371 pull_str = "20k";
372 break;
373 case BYT_PULL_STR_40K:
374 pull_str = "40k";
375 break;
376 }
377
Mathias Nymana5d811b2013-06-18 14:33:02 +0300378 seq_printf(s,
Mika Westerberg3ff95882014-05-16 12:18:29 +0300379 " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
Mathias Nymana5d811b2013-06-18 14:33:02 +0300380 i,
Mathias Nymana4d8d6d2013-11-22 14:01:23 +0200381 label,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300382 val & BYT_INPUT_EN ? " " : "in",
383 val & BYT_OUTPUT_EN ? " " : "out",
384 val & BYT_LEVEL ? "hi" : "lo",
385 vg->range->pins[i], offs,
386 conf0 & 0x7,
Mika Westerberg3ff95882014-05-16 12:18:29 +0300387 conf0 & BYT_TRIG_NEG ? " fall" : " ",
388 conf0 & BYT_TRIG_POS ? " rise" : " ",
389 conf0 & BYT_TRIG_LVL ? " level" : " ");
390
391 if (pull && pull_str)
392 seq_printf(s, " %-4s %-3s", pull, pull_str);
393 else
394 seq_puts(s, " ");
395
396 if (conf0 & BYT_IODEN)
397 seq_puts(s, " open-drain");
398
399 seq_puts(s, "\n");
Mathias Nymana5d811b2013-06-18 14:33:02 +0300400 }
401 spin_unlock_irqrestore(&vg->lock, flags);
402}
403
Mathias Nymana5d811b2013-06-18 14:33:02 +0300404static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
405{
406 struct irq_data *data = irq_desc_get_irq_data(desc);
Mika Westerberge1ee5c52014-07-25 09:54:47 +0300407 struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc));
Mathias Nymana5d811b2013-06-18 14:33:02 +0300408 struct irq_chip *chip = irq_data_get_irq_chip(data);
409 u32 base, pin, mask;
410 void __iomem *reg;
411 u32 pending;
412 unsigned virq;
413 int looplimit = 0;
414
415 /* check from GPIO controller which pin triggered the interrupt */
416 for (base = 0; base < vg->chip.ngpio; base += 32) {
417
418 reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
419
420 while ((pending = readl(reg))) {
421 pin = __ffs(pending);
422 mask = BIT(pin);
423 /* Clear before handling so we can't lose an edge */
424 writel(mask, reg);
425
Mika Westerberge1ee5c52014-07-25 09:54:47 +0300426 virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300427 generic_handle_irq(virq);
428
429 /* In case bios or user sets triggering incorretly a pin
430 * might remain in "interrupt triggered" state.
431 */
432 if (looplimit++ > 32) {
433 dev_err(&vg->pdev->dev,
434 "Gpio %d interrupt flood, disabling\n",
435 base + pin);
436
437 reg = byt_gpio_reg(&vg->chip, base + pin,
438 BYT_CONF0_REG);
439 mask = readl(reg);
440 mask &= ~(BYT_TRIG_NEG | BYT_TRIG_POS |
441 BYT_TRIG_LVL);
442 writel(mask, reg);
443 mask = readl(reg); /* flush */
444 break;
445 }
446 }
447 }
448 chip->irq_eoi(data);
449}
450
451static void byt_irq_unmask(struct irq_data *d)
452{
453}
454
455static void byt_irq_mask(struct irq_data *d)
456{
457}
458
459static struct irq_chip byt_irqchip = {
460 .name = "BYT-GPIO",
461 .irq_mask = byt_irq_mask,
462 .irq_unmask = byt_irq_unmask,
463 .irq_set_type = byt_irq_type,
Mathias Nyman41939e62014-08-11 16:51:55 +0300464 .flags = IRQCHIP_SKIP_SET_WAKE,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300465};
466
467static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
468{
469 void __iomem *reg;
470 u32 base, value;
471
472 /* clear interrupt status trigger registers */
473 for (base = 0; base < vg->chip.ngpio; base += 32) {
474 reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
475 writel(0xffffffff, reg);
476 /* make sure trigger bits are cleared, if not then a pin
477 might be misconfigured in bios */
478 value = readl(reg);
479 if (value)
480 dev_err(&vg->pdev->dev,
481 "GPIO interrupt error, pins misconfigured\n");
482 }
483}
484
Mathias Nymana5d811b2013-06-18 14:33:02 +0300485static int byt_gpio_probe(struct platform_device *pdev)
486{
487 struct byt_gpio *vg;
488 struct gpio_chip *gc;
489 struct resource *mem_rc, *irq_rc;
490 struct device *dev = &pdev->dev;
491 struct acpi_device *acpi_dev;
492 struct pinctrl_gpio_range *range;
493 acpi_handle handle = ACPI_HANDLE(dev);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300494 int ret;
495
496 if (acpi_bus_get_device(handle, &acpi_dev))
497 return -ENODEV;
498
499 vg = devm_kzalloc(dev, sizeof(struct byt_gpio), GFP_KERNEL);
500 if (!vg) {
501 dev_err(&pdev->dev, "can't allocate byt_gpio chip data\n");
502 return -ENOMEM;
503 }
504
505 for (range = byt_ranges; range->name; range++) {
506 if (!strcmp(acpi_dev->pnp.unique_id, range->name)) {
507 vg->chip.ngpio = range->npins;
508 vg->range = range;
509 break;
510 }
511 }
512
513 if (!vg->chip.ngpio || !vg->range)
514 return -ENODEV;
515
516 vg->pdev = pdev;
517 platform_set_drvdata(pdev, vg);
518
519 mem_rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
520 vg->reg_base = devm_ioremap_resource(dev, mem_rc);
521 if (IS_ERR(vg->reg_base))
522 return PTR_ERR(vg->reg_base);
523
524 spin_lock_init(&vg->lock);
525
526 gc = &vg->chip;
527 gc->label = dev_name(&pdev->dev);
528 gc->owner = THIS_MODULE;
529 gc->request = byt_gpio_request;
530 gc->free = byt_gpio_free;
531 gc->direction_input = byt_gpio_direction_input;
532 gc->direction_output = byt_gpio_direction_output;
533 gc->get = byt_gpio_get;
534 gc->set = byt_gpio_set;
535 gc->dbg_show = byt_gpio_dbg_show;
536 gc->base = -1;
Linus Walleij9fb1f392013-12-04 14:42:46 +0100537 gc->can_sleep = false;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300538 gc->dev = dev;
539
Jin Yao605a7bc2014-05-15 18:28:47 +0300540 ret = gpiochip_add(gc);
541 if (ret) {
542 dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
543 return ret;
544 }
545
Mika Westerberge1ee5c52014-07-25 09:54:47 +0300546 /* set up interrupts */
547 irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
548 if (irq_rc && irq_rc->start) {
549 byt_gpio_irq_init_hw(vg);
550 ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
551 handle_simple_irq, IRQ_TYPE_NONE);
552 if (ret) {
553 dev_err(dev, "failed to add irqchip\n");
554 gpiochip_remove(gc);
555 return ret;
556 }
557
558 gpiochip_set_chained_irqchip(gc, &byt_irqchip,
559 (unsigned)irq_rc->start,
560 byt_gpio_irq_handler);
561 }
562
Mathias Nymana5d811b2013-06-18 14:33:02 +0300563 pm_runtime_enable(dev);
564
565 return 0;
566}
567
568static int byt_gpio_runtime_suspend(struct device *dev)
569{
570 return 0;
571}
572
573static int byt_gpio_runtime_resume(struct device *dev)
574{
575 return 0;
576}
577
578static const struct dev_pm_ops byt_gpio_pm_ops = {
579 .runtime_suspend = byt_gpio_runtime_suspend,
580 .runtime_resume = byt_gpio_runtime_resume,
581};
582
583static const struct acpi_device_id byt_gpio_acpi_match[] = {
584 { "INT33B2", 0 },
Jin Yao20482d32014-05-15 18:28:46 +0300585 { "INT33FC", 0 },
Mathias Nymana5d811b2013-06-18 14:33:02 +0300586 { }
587};
588MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
589
590static int byt_gpio_remove(struct platform_device *pdev)
591{
592 struct byt_gpio *vg = platform_get_drvdata(pdev);
Andy Shevchenkoec243322013-07-10 14:55:36 +0300593
Mathias Nymana5d811b2013-06-18 14:33:02 +0300594 pm_runtime_disable(&pdev->dev);
abdoulaye bertheb4e7c552014-07-12 22:30:13 +0200595 gpiochip_remove(&vg->chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300596
597 return 0;
598}
599
600static struct platform_driver byt_gpio_driver = {
601 .probe = byt_gpio_probe,
602 .remove = byt_gpio_remove,
603 .driver = {
604 .name = "byt_gpio",
605 .owner = THIS_MODULE,
606 .pm = &byt_gpio_pm_ops,
607 .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
608 },
609};
610
611static int __init byt_gpio_init(void)
612{
613 return platform_driver_register(&byt_gpio_driver);
614}
615
616subsys_initcall(byt_gpio_init);