blob: bf2b3f65546986ac3a9c7b787549d16fc0fcc5b9 [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>
28#include <linux/irq.h>
29#include <linux/gpio.h>
30#include <linux/irqdomain.h>
31#include <linux/acpi.h>
Mathias Nymana5d811b2013-06-18 14:33:02 +030032#include <linux/platform_device.h>
33#include <linux/seq_file.h>
34#include <linux/io.h>
35#include <linux/pm_runtime.h>
36#include <linux/pinctrl/pinctrl.h>
37
38/* memory mapped register offsets */
39#define BYT_CONF0_REG 0x000
40#define BYT_CONF1_REG 0x004
41#define BYT_VAL_REG 0x008
42#define BYT_DFT_REG 0x00c
43#define BYT_INT_STAT_REG 0x800
44
45/* BYT_CONF0_REG register bits */
46#define BYT_TRIG_NEG BIT(26)
47#define BYT_TRIG_POS BIT(25)
48#define BYT_TRIG_LVL BIT(24)
49#define BYT_PIN_MUX 0x07
50
51/* BYT_VAL_REG register bits */
52#define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/
53#define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/
54#define BYT_LEVEL BIT(0)
55
56#define BYT_DIR_MASK (BIT(1) | BIT(2))
57#define BYT_TRIG_MASK (BIT(26) | BIT(25) | BIT(24))
58
59#define BYT_NGPIO_SCORE 102
60#define BYT_NGPIO_NCORE 28
61#define BYT_NGPIO_SUS 44
62
Chew, Kean Ho42bd0072014-03-06 21:59:49 +080063#define BYT_SCORE_ACPI_UID "1"
64#define BYT_NCORE_ACPI_UID "2"
65#define BYT_SUS_ACPI_UID "3"
66
Mathias Nymana5d811b2013-06-18 14:33:02 +030067/*
68 * Baytrail gpio controller consist of three separate sub-controllers called
69 * SCORE, NCORE and SUS. The sub-controllers are identified by their acpi UID.
70 *
71 * GPIO numbering is _not_ ordered meaning that gpio # 0 in ACPI namespace does
72 * _not_ correspond to the first gpio register at controller's gpio base.
73 * There is no logic or pattern in mapping gpio numbers to registers (pads) so
74 * each sub-controller needs to have its own mapping table
75 */
76
77/* score_pins[gpio_nr] = pad_nr */
78
79static unsigned const score_pins[BYT_NGPIO_SCORE] = {
80 85, 89, 93, 96, 99, 102, 98, 101, 34, 37,
81 36, 38, 39, 35, 40, 84, 62, 61, 64, 59,
82 54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
83 52, 49, 48, 43, 46, 41, 45, 42, 58, 44,
84 95, 105, 70, 68, 67, 66, 69, 71, 65, 72,
85 86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
86 80, 82, 13, 12, 15, 14, 17, 18, 19, 16,
87 2, 1, 0, 4, 6, 7, 9, 8, 33, 32,
88 31, 30, 29, 27, 25, 28, 26, 23, 21, 20,
89 24, 22, 5, 3, 10, 11, 106, 87, 91, 104,
90 97, 100,
91};
92
93static unsigned const ncore_pins[BYT_NGPIO_NCORE] = {
94 19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
95 14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
96 3, 6, 10, 13, 2, 5, 9, 7,
97};
98
99static unsigned const sus_pins[BYT_NGPIO_SUS] = {
100 29, 33, 30, 31, 32, 34, 36, 35, 38, 37,
101 18, 7, 11, 20, 17, 1, 8, 10, 19, 12,
102 0, 2, 23, 39, 28, 27, 22, 21, 24, 25,
103 26, 51, 56, 54, 49, 55, 48, 57, 50, 58,
104 52, 53, 59, 40,
105};
106
107static struct pinctrl_gpio_range byt_ranges[] = {
108 {
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800109 .name = BYT_SCORE_ACPI_UID, /* match with acpi _UID in probe */
Mathias Nymana5d811b2013-06-18 14:33:02 +0300110 .npins = BYT_NGPIO_SCORE,
111 .pins = score_pins,
112 },
113 {
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800114 .name = BYT_NCORE_ACPI_UID,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300115 .npins = BYT_NGPIO_NCORE,
116 .pins = ncore_pins,
117 },
118 {
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800119 .name = BYT_SUS_ACPI_UID,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300120 .npins = BYT_NGPIO_SUS,
121 .pins = sus_pins,
122 },
123 {
124 },
125};
126
127struct byt_gpio {
128 struct gpio_chip chip;
129 struct irq_domain *domain;
130 struct platform_device *pdev;
131 spinlock_t lock;
132 void __iomem *reg_base;
133 struct pinctrl_gpio_range *range;
134};
135
Andy Shevchenko17e52462013-07-10 14:55:39 +0300136#define to_byt_gpio(c) container_of(c, struct byt_gpio, chip)
137
Mathias Nymana5d811b2013-06-18 14:33:02 +0300138static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset,
139 int reg)
140{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300141 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300142 u32 reg_offset;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300143
144 if (reg == BYT_INT_STAT_REG)
145 reg_offset = (offset / 32) * 4;
146 else
147 reg_offset = vg->range->pins[offset] * 16;
148
Andy Shevchenko9c5b6552013-07-10 14:55:38 +0300149 return vg->reg_base + reg_offset + reg;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300150}
151
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800152static bool is_special_pin(struct byt_gpio *vg, unsigned offset)
153{
154 /* SCORE pin 92-93 */
155 if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) &&
156 offset >= 92 && offset <= 93)
157 return true;
158
159 /* SUS pin 11-21 */
160 if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) &&
161 offset >= 11 && offset <= 21)
162 return true;
163
164 return false;
165}
166
Mathias Nymana5d811b2013-06-18 14:33:02 +0300167static int byt_gpio_request(struct gpio_chip *chip, unsigned offset)
168{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300169 struct byt_gpio *vg = to_byt_gpio(chip);
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800170 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG);
171 u32 value;
172 bool special;
173
174 /*
175 * In most cases, func pin mux 000 means GPIO function.
176 * But, some pins may have func pin mux 001 represents
177 * GPIO function. Only allow user to export pin with
178 * func pin mux preset as GPIO function by BIOS/FW.
179 */
180 value = readl(reg) & BYT_PIN_MUX;
181 special = is_special_pin(vg, offset);
182 if ((special && value != 1) || (!special && value)) {
183 dev_err(&vg->pdev->dev,
184 "pin %u cannot be used as GPIO.\n", offset);
185 return -EINVAL;
186 }
Mathias Nymana5d811b2013-06-18 14:33:02 +0300187
188 pm_runtime_get(&vg->pdev->dev);
189
190 return 0;
191}
192
193static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
194{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300195 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300196 void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
197 u32 value;
198
199 /* clear interrupt triggering */
200 value = readl(reg);
201 value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
202 writel(value, reg);
203
204 pm_runtime_put(&vg->pdev->dev);
205}
206
207static int byt_irq_type(struct irq_data *d, unsigned type)
208{
209 struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
210 u32 offset = irqd_to_hwirq(d);
211 u32 value;
212 unsigned long flags;
213 void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
214
215 if (offset >= vg->chip.ngpio)
216 return -EINVAL;
217
218 spin_lock_irqsave(&vg->lock, flags);
219 value = readl(reg);
220
221 /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
222 * are used to indicate high and low level triggering
223 */
224 value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
225
226 switch (type) {
227 case IRQ_TYPE_LEVEL_HIGH:
228 value |= BYT_TRIG_LVL;
229 case IRQ_TYPE_EDGE_RISING:
230 value |= BYT_TRIG_POS;
231 break;
232 case IRQ_TYPE_LEVEL_LOW:
233 value |= BYT_TRIG_LVL;
234 case IRQ_TYPE_EDGE_FALLING:
235 value |= BYT_TRIG_NEG;
236 break;
237 case IRQ_TYPE_EDGE_BOTH:
238 value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
239 break;
240 }
241 writel(value, reg);
242
243 spin_unlock_irqrestore(&vg->lock, flags);
244
245 return 0;
246}
247
248static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
249{
250 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
251 return readl(reg) & BYT_LEVEL;
252}
253
254static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
255{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300256 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300257 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
258 unsigned long flags;
259 u32 old_val;
260
261 spin_lock_irqsave(&vg->lock, flags);
262
263 old_val = readl(reg);
264
265 if (value)
266 writel(old_val | BYT_LEVEL, reg);
267 else
268 writel(old_val & ~BYT_LEVEL, reg);
269
270 spin_unlock_irqrestore(&vg->lock, flags);
271}
272
273static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
274{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300275 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300276 void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
277 unsigned long flags;
278 u32 value;
279
280 spin_lock_irqsave(&vg->lock, flags);
281
282 value = readl(reg) | BYT_DIR_MASK;
Andy Shevchenko496940c2013-07-10 14:55:40 +0300283 value &= ~BYT_INPUT_EN; /* active low */
Mathias Nymana5d811b2013-06-18 14:33:02 +0300284 writel(value, reg);
285
286 spin_unlock_irqrestore(&vg->lock, flags);
287
288 return 0;
289}
290
291static int byt_gpio_direction_output(struct gpio_chip *chip,
292 unsigned gpio, int value)
293{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300294 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300295 void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
296 unsigned long flags;
297 u32 reg_val;
298
299 spin_lock_irqsave(&vg->lock, flags);
300
Andy Shevchenko496940c2013-07-10 14:55:40 +0300301 reg_val = readl(reg) | BYT_DIR_MASK;
302 reg_val &= ~BYT_OUTPUT_EN;
303
304 if (value)
305 writel(reg_val | BYT_LEVEL, reg);
306 else
307 writel(reg_val & ~BYT_LEVEL, reg);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300308
309 spin_unlock_irqrestore(&vg->lock, flags);
310
311 return 0;
312}
313
314static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
315{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300316 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300317 int i;
318 unsigned long flags;
319 u32 conf0, val, offs;
320
321 spin_lock_irqsave(&vg->lock, flags);
322
323 for (i = 0; i < vg->chip.ngpio; i++) {
Mathias Nymana4d8d6d2013-11-22 14:01:23 +0200324 const char *label;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300325 offs = vg->range->pins[i] * 16;
326 conf0 = readl(vg->reg_base + offs + BYT_CONF0_REG);
327 val = readl(vg->reg_base + offs + BYT_VAL_REG);
328
Mathias Nymana4d8d6d2013-11-22 14:01:23 +0200329 label = gpiochip_is_requested(chip, i);
330 if (!label)
331 label = "Unrequested";
332
Mathias Nymana5d811b2013-06-18 14:33:02 +0300333 seq_printf(s,
Mathias Nymana4d8d6d2013-11-22 14:01:23 +0200334 " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s\n",
Mathias Nymana5d811b2013-06-18 14:33:02 +0300335 i,
Mathias Nymana4d8d6d2013-11-22 14:01:23 +0200336 label,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300337 val & BYT_INPUT_EN ? " " : "in",
338 val & BYT_OUTPUT_EN ? " " : "out",
339 val & BYT_LEVEL ? "hi" : "lo",
340 vg->range->pins[i], offs,
341 conf0 & 0x7,
Andy Shevchenko15834492013-07-10 16:42:14 +0300342 conf0 & BYT_TRIG_NEG ? " fall" : "",
343 conf0 & BYT_TRIG_POS ? " rise" : "",
344 conf0 & BYT_TRIG_LVL ? " level" : "");
Mathias Nymana5d811b2013-06-18 14:33:02 +0300345 }
346 spin_unlock_irqrestore(&vg->lock, flags);
347}
348
349static int byt_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
350{
Andy Shevchenko17e52462013-07-10 14:55:39 +0300351 struct byt_gpio *vg = to_byt_gpio(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300352 return irq_create_mapping(vg->domain, offset);
353}
354
355static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
356{
357 struct irq_data *data = irq_desc_get_irq_data(desc);
358 struct byt_gpio *vg = irq_data_get_irq_handler_data(data);
359 struct irq_chip *chip = irq_data_get_irq_chip(data);
360 u32 base, pin, mask;
361 void __iomem *reg;
362 u32 pending;
363 unsigned virq;
364 int looplimit = 0;
365
366 /* check from GPIO controller which pin triggered the interrupt */
367 for (base = 0; base < vg->chip.ngpio; base += 32) {
368
369 reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
370
371 while ((pending = readl(reg))) {
372 pin = __ffs(pending);
373 mask = BIT(pin);
374 /* Clear before handling so we can't lose an edge */
375 writel(mask, reg);
376
377 virq = irq_find_mapping(vg->domain, base + pin);
378 generic_handle_irq(virq);
379
380 /* In case bios or user sets triggering incorretly a pin
381 * might remain in "interrupt triggered" state.
382 */
383 if (looplimit++ > 32) {
384 dev_err(&vg->pdev->dev,
385 "Gpio %d interrupt flood, disabling\n",
386 base + pin);
387
388 reg = byt_gpio_reg(&vg->chip, base + pin,
389 BYT_CONF0_REG);
390 mask = readl(reg);
391 mask &= ~(BYT_TRIG_NEG | BYT_TRIG_POS |
392 BYT_TRIG_LVL);
393 writel(mask, reg);
394 mask = readl(reg); /* flush */
395 break;
396 }
397 }
398 }
399 chip->irq_eoi(data);
400}
401
402static void byt_irq_unmask(struct irq_data *d)
403{
404}
405
406static void byt_irq_mask(struct irq_data *d)
407{
408}
409
Linus Walleij1d2d8ce2013-12-03 15:20:34 +0100410static unsigned int byt_irq_startup(struct irq_data *d)
411{
412 struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
413
414 if (gpio_lock_as_irq(&vg->chip, irqd_to_hwirq(d)))
415 dev_err(vg->chip.dev,
416 "unable to lock HW IRQ %lu for IRQ\n",
417 irqd_to_hwirq(d));
418 byt_irq_unmask(d);
419 return 0;
420}
421
422static void byt_irq_shutdown(struct irq_data *d)
423{
424 struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
425
426 byt_irq_mask(d);
427 gpio_unlock_as_irq(&vg->chip, irqd_to_hwirq(d));
428}
429
Mathias Nymana5d811b2013-06-18 14:33:02 +0300430static struct irq_chip byt_irqchip = {
431 .name = "BYT-GPIO",
432 .irq_mask = byt_irq_mask,
433 .irq_unmask = byt_irq_unmask,
434 .irq_set_type = byt_irq_type,
Linus Walleij1d2d8ce2013-12-03 15:20:34 +0100435 .irq_startup = byt_irq_startup,
436 .irq_shutdown = byt_irq_shutdown,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300437};
438
439static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
440{
441 void __iomem *reg;
442 u32 base, value;
443
444 /* clear interrupt status trigger registers */
445 for (base = 0; base < vg->chip.ngpio; base += 32) {
446 reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
447 writel(0xffffffff, reg);
448 /* make sure trigger bits are cleared, if not then a pin
449 might be misconfigured in bios */
450 value = readl(reg);
451 if (value)
452 dev_err(&vg->pdev->dev,
453 "GPIO interrupt error, pins misconfigured\n");
454 }
455}
456
457static int byt_gpio_irq_map(struct irq_domain *d, unsigned int virq,
458 irq_hw_number_t hw)
459{
460 struct byt_gpio *vg = d->host_data;
461
462 irq_set_chip_and_handler_name(virq, &byt_irqchip, handle_simple_irq,
463 "demux");
464 irq_set_chip_data(virq, vg);
465 irq_set_irq_type(virq, IRQ_TYPE_NONE);
466
467 return 0;
468}
469
470static const struct irq_domain_ops byt_gpio_irq_ops = {
471 .map = byt_gpio_irq_map,
472};
473
474static int byt_gpio_probe(struct platform_device *pdev)
475{
476 struct byt_gpio *vg;
477 struct gpio_chip *gc;
478 struct resource *mem_rc, *irq_rc;
479 struct device *dev = &pdev->dev;
480 struct acpi_device *acpi_dev;
481 struct pinctrl_gpio_range *range;
482 acpi_handle handle = ACPI_HANDLE(dev);
483 unsigned hwirq;
484 int ret;
485
486 if (acpi_bus_get_device(handle, &acpi_dev))
487 return -ENODEV;
488
489 vg = devm_kzalloc(dev, sizeof(struct byt_gpio), GFP_KERNEL);
490 if (!vg) {
491 dev_err(&pdev->dev, "can't allocate byt_gpio chip data\n");
492 return -ENOMEM;
493 }
494
495 for (range = byt_ranges; range->name; range++) {
496 if (!strcmp(acpi_dev->pnp.unique_id, range->name)) {
497 vg->chip.ngpio = range->npins;
498 vg->range = range;
499 break;
500 }
501 }
502
503 if (!vg->chip.ngpio || !vg->range)
504 return -ENODEV;
505
506 vg->pdev = pdev;
507 platform_set_drvdata(pdev, vg);
508
509 mem_rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
510 vg->reg_base = devm_ioremap_resource(dev, mem_rc);
511 if (IS_ERR(vg->reg_base))
512 return PTR_ERR(vg->reg_base);
513
514 spin_lock_init(&vg->lock);
515
516 gc = &vg->chip;
517 gc->label = dev_name(&pdev->dev);
518 gc->owner = THIS_MODULE;
519 gc->request = byt_gpio_request;
520 gc->free = byt_gpio_free;
521 gc->direction_input = byt_gpio_direction_input;
522 gc->direction_output = byt_gpio_direction_output;
523 gc->get = byt_gpio_get;
524 gc->set = byt_gpio_set;
525 gc->dbg_show = byt_gpio_dbg_show;
526 gc->base = -1;
Linus Walleij9fb1f392013-12-04 14:42:46 +0100527 gc->can_sleep = false;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300528 gc->dev = dev;
529
530 ret = gpiochip_add(gc);
531 if (ret) {
532 dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
533 return ret;
534 }
535
536 /* set up interrupts */
537 irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
538 if (irq_rc && irq_rc->start) {
539 hwirq = irq_rc->start;
540 gc->to_irq = byt_gpio_to_irq;
541
542 vg->domain = irq_domain_add_linear(NULL, gc->ngpio,
543 &byt_gpio_irq_ops, vg);
544 if (!vg->domain)
545 return -ENXIO;
546
547 byt_gpio_irq_init_hw(vg);
548
549 irq_set_handler_data(hwirq, vg);
550 irq_set_chained_handler(hwirq, byt_gpio_irq_handler);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300551 }
552
553 pm_runtime_enable(dev);
554
555 return 0;
556}
557
558static int byt_gpio_runtime_suspend(struct device *dev)
559{
560 return 0;
561}
562
563static int byt_gpio_runtime_resume(struct device *dev)
564{
565 return 0;
566}
567
568static const struct dev_pm_ops byt_gpio_pm_ops = {
569 .runtime_suspend = byt_gpio_runtime_suspend,
570 .runtime_resume = byt_gpio_runtime_resume,
571};
572
573static const struct acpi_device_id byt_gpio_acpi_match[] = {
574 { "INT33B2", 0 },
575 { }
576};
577MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
578
579static int byt_gpio_remove(struct platform_device *pdev)
580{
581 struct byt_gpio *vg = platform_get_drvdata(pdev);
582 int err;
Andy Shevchenkoec243322013-07-10 14:55:36 +0300583
Mathias Nymana5d811b2013-06-18 14:33:02 +0300584 pm_runtime_disable(&pdev->dev);
585 err = gpiochip_remove(&vg->chip);
586 if (err)
587 dev_warn(&pdev->dev, "failed to remove gpio_chip.\n");
588
589 return 0;
590}
591
592static struct platform_driver byt_gpio_driver = {
593 .probe = byt_gpio_probe,
594 .remove = byt_gpio_remove,
595 .driver = {
596 .name = "byt_gpio",
597 .owner = THIS_MODULE,
598 .pm = &byt_gpio_pm_ops,
599 .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
600 },
601};
602
603static int __init byt_gpio_init(void)
604{
605 return platform_driver_register(&byt_gpio_driver);
606}
607
608subsys_initcall(byt_gpio_init);