aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2015-03-30 10:31:49 -0400
committerLinus Walleij <linus.walleij@linaro.org>2015-04-07 09:15:23 -0400
commit7981c0015af26323281c937c8983dfeabc3395fe (patch)
treedf17a64dda5a262ff3f663c2e9a6d1e481d229ba
parent16837f9588819c06469e635c04a8135f98ab9ae6 (diff)
pinctrl: intel: Add Intel Sunrisepoint pin controller and GPIO support
This driver supports pinctrl/GPIO hardware found on Intel Sunrisepoint (a Skylake PCH) providing users a pinctrl and GPIO interfaces (including GPIO interrupts). The driver is split into core and platform parts so that the same core driver can be reused in other drivers for other Intel GPIO hardware that is based on the same host controller design. Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/intel/Kconfig17
-rw-r--r--drivers/pinctrl/intel/Makefile2
-rw-r--r--drivers/pinctrl/intel/pinctrl-intel.c1149
-rw-r--r--drivers/pinctrl/intel/pinctrl-intel.h128
-rw-r--r--drivers/pinctrl/intel/pinctrl-sunrisepoint.c336
5 files changed, 1632 insertions, 0 deletions
diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig
index b801d869e91c..fe5e07db0a95 100644
--- a/drivers/pinctrl/intel/Kconfig
+++ b/drivers/pinctrl/intel/Kconfig
@@ -25,3 +25,20 @@ config PINCTRL_CHERRYVIEW
25 help 25 help
26 Cherryview/Braswell pinctrl driver provides an interface that 26 Cherryview/Braswell pinctrl driver provides an interface that
27 allows configuring of SoC pins and using them as GPIOs. 27 allows configuring of SoC pins and using them as GPIOs.
28
29config PINCTRL_INTEL
30 tristate
31 select PINMUX
32 select PINCONF
33 select GENERIC_PINCONF
34 select GPIOLIB
35 select GPIOLIB_IRQCHIP
36
37config PINCTRL_SUNRISEPOINT
38 tristate "Intel Sunrisepoint pinctrl and GPIO driver"
39 depends on ACPI
40 select PINCTRL_INTEL
41 help
42 Sunrisepoint is the PCH of Intel Skylake. This pinctrl driver
43 provides an interface that allows configuring of PCH pins and
44 using them as GPIOs.
diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile
index 4c210e4139e2..fee756e1255b 100644
--- a/drivers/pinctrl/intel/Makefile
+++ b/drivers/pinctrl/intel/Makefile
@@ -2,3 +2,5 @@
2 2
3obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o 3obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
4obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o 4obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o
5obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o
6obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
new file mode 100644
index 000000000000..00768e53deec
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -0,0 +1,1149 @@
1/*
2 * Intel pinctrl/GPIO core driver.
3 *
4 * Copyright (C) 2015, Intel Corporation
5 * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
6 * Mika Westerberg <mika.westerberg@linux.intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/acpi.h>
16#include <linux/gpio.h>
17#include <linux/gpio/driver.h>
18#include <linux/platform_device.h>
19#include <linux/pm.h>
20#include <linux/pinctrl/pinctrl.h>
21#include <linux/pinctrl/pinmux.h>
22#include <linux/pinctrl/pinconf.h>
23#include <linux/pinctrl/pinconf-generic.h>
24
25#include "pinctrl-intel.h"
26
27/* Maximum number of pads in each group */
28#define NPADS_IN_GPP 24
29
30/* Offset from regs */
31#define PADBAR 0x00c
32#define GPI_IS 0x100
33#define GPI_GPE_STS 0x140
34#define GPI_GPE_EN 0x160
35
36#define PADOWN_BITS 4
37#define PADOWN_SHIFT(p) ((p) % 8 * PADOWN_BITS)
38#define PADOWN_MASK(p) (0xf << PADOWN_SHIFT(p))
39
40/* Offset from pad_regs */
41#define PADCFG0 0x000
42#define PADCFG0_RXEVCFG_SHIFT 25
43#define PADCFG0_RXEVCFG_MASK (3 << PADCFG0_RXEVCFG_SHIFT)
44#define PADCFG0_RXEVCFG_LEVEL 0
45#define PADCFG0_RXEVCFG_EDGE 1
46#define PADCFG0_RXEVCFG_DISABLED 2
47#define PADCFG0_RXEVCFG_EDGE_BOTH 3
48#define PADCFG0_RXINV BIT(23)
49#define PADCFG0_GPIROUTIOXAPIC BIT(20)
50#define PADCFG0_GPIROUTSCI BIT(19)
51#define PADCFG0_GPIROUTSMI BIT(18)
52#define PADCFG0_GPIROUTNMI BIT(17)
53#define PADCFG0_PMODE_SHIFT 10
54#define PADCFG0_PMODE_MASK (0xf << PADCFG0_PMODE_SHIFT)
55#define PADCFG0_GPIORXDIS BIT(9)
56#define PADCFG0_GPIOTXDIS BIT(8)
57#define PADCFG0_GPIORXSTATE BIT(1)
58#define PADCFG0_GPIOTXSTATE BIT(0)
59
60#define PADCFG1 0x004
61#define PADCFG1_TERM_UP BIT(13)
62#define PADCFG1_TERM_SHIFT 10
63#define PADCFG1_TERM_MASK (7 << PADCFG1_TERM_SHIFT)
64#define PADCFG1_TERM_20K 4
65#define PADCFG1_TERM_2K 3
66#define PADCFG1_TERM_5K 2
67#define PADCFG1_TERM_1K 1
68
69struct intel_pad_context {
70 u32 padcfg0;
71 u32 padcfg1;
72};
73
74struct intel_community_context {
75 u32 *intmask;
76};
77
78struct intel_pinctrl_context {
79 struct intel_pad_context *pads;
80 struct intel_community_context *communities;
81};
82
83/**
84 * struct intel_pinctrl - Intel pinctrl private structure
85 * @dev: Pointer to the device structure
86 * @lock: Lock to serialize register access
87 * @pctldesc: Pin controller description
88 * @pctldev: Pointer to the pin controller device
89 * @chip: GPIO chip in this pin controller
90 * @soc: SoC/PCH specific pin configuration data
91 * @communities: All communities in this pin controller
92 * @ncommunities: Number of communities in this pin controller
93 * @context: Configuration saved over system sleep
94 */
95struct intel_pinctrl {
96 struct device *dev;
97 spinlock_t lock;
98 struct pinctrl_desc pctldesc;
99 struct pinctrl_dev *pctldev;
100 struct gpio_chip chip;
101 const struct intel_pinctrl_soc_data *soc;
102 struct intel_community *communities;
103 size_t ncommunities;
104 struct intel_pinctrl_context context;
105};
106
107#define gpiochip_to_pinctrl(c) container_of(c, struct intel_pinctrl, chip)
108#define pin_to_padno(c, p) ((p) - (c)->pin_base)
109
110static struct intel_community *intel_get_community(struct intel_pinctrl *pctrl,
111 unsigned pin)
112{
113 struct intel_community *community;
114 int i;
115
116 for (i = 0; i < pctrl->ncommunities; i++) {
117 community = &pctrl->communities[i];
118 if (pin >= community->pin_base &&
119 pin < community->pin_base + community->npins)
120 return community;
121 }
122
123 dev_warn(pctrl->dev, "failed to find community for pin %u\n", pin);
124 return NULL;
125}
126
127static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, unsigned pin,
128 unsigned reg)
129{
130 const struct intel_community *community;
131 unsigned padno;
132
133 community = intel_get_community(pctrl, pin);
134 if (!community)
135 return NULL;
136
137 padno = pin_to_padno(community, pin);
138 return community->pad_regs + reg + padno * 8;
139}
140
141static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned pin)
142{
143 const struct intel_community *community;
144 unsigned padno, gpp, gpp_offset, offset;
145 void __iomem *padown;
146
147 community = intel_get_community(pctrl, pin);
148 if (!community)
149 return false;
150 if (!community->padown_offset)
151 return true;
152
153 padno = pin_to_padno(community, pin);
154 gpp = padno / NPADS_IN_GPP;
155 gpp_offset = padno % NPADS_IN_GPP;
156 offset = community->padown_offset + gpp * 16 + (gpp_offset / 8) * 4;
157 padown = community->regs + offset;
158
159 return !(readl(padown) & PADOWN_MASK(padno));
160}
161
162static bool intel_pad_reserved_for_acpi(struct intel_pinctrl *pctrl,
163 unsigned pin)
164{
165 const struct intel_community *community;
166 unsigned padno, gpp, offset;
167 void __iomem *hostown;
168
169 community = intel_get_community(pctrl, pin);
170 if (!community)
171 return true;
172 if (!community->hostown_offset)
173 return false;
174
175 padno = pin_to_padno(community, pin);
176 gpp = padno / NPADS_IN_GPP;
177 offset = community->hostown_offset + gpp * 4;
178 hostown = community->regs + offset;
179
180 return !(readl(hostown) & BIT(padno % NPADS_IN_GPP));
181}
182
183static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
184{
185 struct intel_community *community;
186 unsigned padno, gpp, offset;
187 u32 value;
188
189 community = intel_get_community(pctrl, pin);
190 if (!community)
191 return true;
192 if (!community->padcfglock_offset)
193 return false;
194
195 padno = pin_to_padno(community, pin);
196 gpp = padno / NPADS_IN_GPP;
197
198 /*
199 * If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad,
200 * the pad is considered unlocked. Any other case means that it is
201 * either fully or partially locked and we don't touch it.
202 */
203 offset = community->padcfglock_offset + gpp * 8;
204 value = readl(community->regs + offset);
205 if (value & BIT(pin % NPADS_IN_GPP))
206 return true;
207
208 offset = community->padcfglock_offset + 4 + gpp * 8;
209 value = readl(community->regs + offset);
210 if (value & BIT(pin % NPADS_IN_GPP))
211 return true;
212
213 return false;
214}
215
216static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned pin)
217{
218 return intel_pad_owned_by_host(pctrl, pin) &&
219 !intel_pad_reserved_for_acpi(pctrl, pin) &&
220 !intel_pad_locked(pctrl, pin);
221}
222
223static int intel_get_groups_count(struct pinctrl_dev *pctldev)
224{
225 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
226
227 return pctrl->soc->ngroups;
228}
229
230static const char *intel_get_group_name(struct pinctrl_dev *pctldev,
231 unsigned group)
232{
233 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
234
235 return pctrl->soc->groups[group].name;
236}
237
238static int intel_get_group_pins(struct pinctrl_dev *pctldev, unsigned group,
239 const unsigned **pins, unsigned *npins)
240{
241 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
242
243 *pins = pctrl->soc->groups[group].pins;
244 *npins = pctrl->soc->groups[group].npins;
245 return 0;
246}
247
248static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
249 unsigned pin)
250{
251 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
252 u32 cfg0, cfg1, mode;
253 bool locked, acpi;
254
255 if (!intel_pad_owned_by_host(pctrl, pin)) {
256 seq_puts(s, "not available");
257 return;
258 }
259
260 cfg0 = readl(intel_get_padcfg(pctrl, pin, PADCFG0));
261 cfg1 = readl(intel_get_padcfg(pctrl, pin, PADCFG1));
262
263 mode = (cfg0 & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
264 if (!mode)
265 seq_puts(s, "GPIO ");
266 else
267 seq_printf(s, "mode %d ", mode);
268
269 seq_printf(s, "0x%08x 0x%08x", cfg0, cfg1);
270
271 locked = intel_pad_locked(pctrl, pin);
272 acpi = intel_pad_reserved_for_acpi(pctrl, pin);
273
274 if (locked || acpi) {
275 seq_puts(s, " [");
276 if (locked) {
277 seq_puts(s, "LOCKED");
278 if (acpi)
279 seq_puts(s, ", ");
280 }
281 if (acpi)
282 seq_puts(s, "ACPI");
283 seq_puts(s, "]");
284 }
285}
286
287static const struct pinctrl_ops intel_pinctrl_ops = {
288 .get_groups_count = intel_get_groups_count,
289 .get_group_name = intel_get_group_name,
290 .get_group_pins = intel_get_group_pins,
291 .pin_dbg_show = intel_pin_dbg_show,
292};
293
294static int intel_get_functions_count(struct pinctrl_dev *pctldev)
295{
296 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
297
298 return pctrl->soc->nfunctions;
299}
300
301static const char *intel_get_function_name(struct pinctrl_dev *pctldev,
302 unsigned function)
303{
304 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
305
306 return pctrl->soc->functions[function].name;
307}
308
309static int intel_get_function_groups(struct pinctrl_dev *pctldev,
310 unsigned function,
311 const char * const **groups,
312 unsigned * const ngroups)
313{
314 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
315
316 *groups = pctrl->soc->functions[function].groups;
317 *ngroups = pctrl->soc->functions[function].ngroups;
318 return 0;
319}
320
321static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
322 unsigned group)
323{
324 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
325 const struct intel_pingroup *grp = &pctrl->soc->groups[group];
326 unsigned long flags;
327 int i;
328
329 spin_lock_irqsave(&pctrl->lock, flags);
330
331 /*
332 * All pins in the groups needs to be accessible and writable
333 * before we can enable the mux for this group.
334 */
335 for (i = 0; i < grp->npins; i++) {
336 if (!intel_pad_usable(pctrl, grp->pins[i])) {
337 spin_unlock_irqrestore(&pctrl->lock, flags);
338 return -EBUSY;
339 }
340 }
341
342 /* Now enable the mux setting for each pin in the group */
343 for (i = 0; i < grp->npins; i++) {
344 void __iomem *padcfg0;
345 u32 value;
346
347 padcfg0 = intel_get_padcfg(pctrl, grp->pins[i], PADCFG0);
348 value = readl(padcfg0);
349
350 value &= ~PADCFG0_PMODE_MASK;
351 value |= grp->mode << PADCFG0_PMODE_SHIFT;
352
353 writel(value, padcfg0);
354 }
355
356 spin_unlock_irqrestore(&pctrl->lock, flags);
357
358 return 0;
359}
360
361static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
362 struct pinctrl_gpio_range *range,
363 unsigned pin)
364{
365 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
366 void __iomem *padcfg0;
367 unsigned long flags;
368 u32 value;
369
370 spin_lock_irqsave(&pctrl->lock, flags);
371
372 if (!intel_pad_usable(pctrl, pin)) {
373 spin_unlock_irqrestore(&pctrl->lock, flags);
374 return -EBUSY;
375 }
376
377 padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
378 /* Put the pad into GPIO mode */
379 value = readl(padcfg0) & ~PADCFG0_PMODE_MASK;
380 /* Disable SCI/SMI/NMI generation */
381 value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI);
382 value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI);
383 /* Disable TX buffer and enable RX (this will be input) */
384 value &= ~PADCFG0_GPIORXDIS;
385 value |= PADCFG0_GPIOTXDIS;
386 writel(value, padcfg0);
387
388 spin_unlock_irqrestore(&pctrl->lock, flags);
389
390 return 0;
391}
392
393static int intel_gpio_set_direction(struct pinctrl_dev *pctldev,
394 struct pinctrl_gpio_range *range,
395 unsigned pin, bool input)
396{
397 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
398 void __iomem *padcfg0;
399 unsigned long flags;
400 u32 value;
401
402 spin_lock_irqsave(&pctrl->lock, flags);
403
404 padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
405
406 value = readl(padcfg0);
407 if (input)
408 value |= PADCFG0_GPIOTXDIS;
409 else
410 value &= ~PADCFG0_GPIOTXDIS;
411 writel(value, padcfg0);
412
413 spin_unlock_irqrestore(&pctrl->lock, flags);
414
415 return 0;
416}
417
418static const struct pinmux_ops intel_pinmux_ops = {
419 .get_functions_count = intel_get_functions_count,
420 .get_function_name = intel_get_function_name,
421 .get_function_groups = intel_get_function_groups,
422 .set_mux = intel_pinmux_set_mux,
423 .gpio_request_enable = intel_gpio_request_enable,
424 .gpio_set_direction = intel_gpio_set_direction,
425};
426
427static int intel_config_get(struct pinctrl_dev *pctldev, unsigned pin,
428 unsigned long *config)
429{
430 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
431 enum pin_config_param param = pinconf_to_config_param(*config);
432 u32 value, term;
433 u16 arg = 0;
434
435 if (!intel_pad_owned_by_host(pctrl, pin))
436 return -ENOTSUPP;
437
438 value = readl(intel_get_padcfg(pctrl, pin, PADCFG1));
439 term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT;
440
441 switch (param) {
442 case PIN_CONFIG_BIAS_DISABLE:
443 if (term)
444 return -EINVAL;
445 break;
446
447 case PIN_CONFIG_BIAS_PULL_UP:
448 if (!term || !(value & PADCFG1_TERM_UP))
449 return -EINVAL;
450
451 switch (term) {
452 case PADCFG1_TERM_1K:
453 arg = 1000;
454 break;
455 case PADCFG1_TERM_2K:
456 arg = 2000;
457 break;
458 case PADCFG1_TERM_5K:
459 arg = 5000;
460 break;
461 case PADCFG1_TERM_20K:
462 arg = 20000;
463 break;
464 }
465
466 break;
467
468 case PIN_CONFIG_BIAS_PULL_DOWN:
469 if (!term || value & PADCFG1_TERM_UP)
470 return -EINVAL;
471
472 switch (term) {
473 case PADCFG1_TERM_5K:
474 arg = 5000;
475 break;
476 case PADCFG1_TERM_20K:
477 arg = 20000;
478 break;
479 }
480
481 break;
482
483 default:
484 return -ENOTSUPP;
485 }
486
487 *config = pinconf_to_config_packed(param, arg);
488 return 0;
489}
490
491static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned pin,
492 unsigned long config)
493{
494 unsigned param = pinconf_to_config_param(config);
495 unsigned arg = pinconf_to_config_argument(config);
496 void __iomem *padcfg1;
497 unsigned long flags;
498 int ret = 0;
499 u32 value;
500
501 spin_lock_irqsave(&pctrl->lock, flags);
502
503 padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
504 value = readl(padcfg1);
505
506 switch (param) {
507 case PIN_CONFIG_BIAS_DISABLE:
508 value &= ~(PADCFG1_TERM_MASK | PADCFG1_TERM_UP);
509 break;
510
511 case PIN_CONFIG_BIAS_PULL_UP:
512 value &= ~PADCFG1_TERM_MASK;
513
514 value |= PADCFG1_TERM_UP;
515
516 switch (arg) {
517 case 20000:
518 value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT;
519 break;
520 case 5000:
521 value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT;
522 break;
523 case 2000:
524 value |= PADCFG1_TERM_2K << PADCFG1_TERM_SHIFT;
525 break;
526 case 1000:
527 value |= PADCFG1_TERM_1K << PADCFG1_TERM_SHIFT;
528 break;
529 default:
530 ret = -EINVAL;
531 }
532
533 break;
534
535 case PIN_CONFIG_BIAS_PULL_DOWN:
536 value &= ~(PADCFG1_TERM_UP | PADCFG1_TERM_MASK);
537
538 switch (arg) {
539 case 20000:
540 value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT;
541 break;
542 case 5000:
543 value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT;
544 break;
545 default:
546 ret = -EINVAL;
547 }
548
549 break;
550 }
551
552 if (!ret)
553 writel(value, padcfg1);
554
555 spin_unlock_irqrestore(&pctrl->lock, flags);
556
557 return ret;
558}
559
560static int intel_config_set(struct pinctrl_dev *pctldev, unsigned pin,
561 unsigned long *configs, unsigned nconfigs)
562{
563 struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
564 int i, ret;
565
566 if (!intel_pad_usable(pctrl, pin))
567 return -ENOTSUPP;
568
569 for (i = 0; i < nconfigs; i++) {
570 switch (pinconf_to_config_param(configs[i])) {
571 case PIN_CONFIG_BIAS_DISABLE:
572 case PIN_CONFIG_BIAS_PULL_UP:
573 case PIN_CONFIG_BIAS_PULL_DOWN:
574 ret = intel_config_set_pull(pctrl, pin, configs[i]);
575 if (ret)
576 return ret;
577 break;
578
579 default:
580 return -ENOTSUPP;
581 }
582 }
583
584 return 0;
585}
586
587static const struct pinconf_ops intel_pinconf_ops = {
588 .is_generic = true,
589 .pin_config_get = intel_config_get,
590 .pin_config_set = intel_config_set,
591};
592
593static const struct pinctrl_desc intel_pinctrl_desc = {
594 .pctlops = &intel_pinctrl_ops,
595 .pmxops = &intel_pinmux_ops,
596 .confops = &intel_pinconf_ops,
597 .owner = THIS_MODULE,
598};
599
600static int intel_gpio_request(struct gpio_chip *chip, unsigned offset)
601{
602 return pinctrl_request_gpio(chip->base + offset);
603}
604
605static void intel_gpio_free(struct gpio_chip *chip, unsigned offset)
606{
607 pinctrl_free_gpio(chip->base + offset);
608}
609
610static int intel_gpio_get(struct gpio_chip *chip, unsigned offset)
611{
612 struct intel_pinctrl *pctrl = gpiochip_to_pinctrl(chip);
613 void __iomem *reg;
614
615 reg = intel_get_padcfg(pctrl, offset, PADCFG0);
616 if (!reg)
617 return -EINVAL;
618
619 return !!(readl(reg) & PADCFG0_GPIORXSTATE);
620}
621
622static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
623{
624 struct intel_pinctrl *pctrl = gpiochip_to_pinctrl(chip);
625 void __iomem *reg;
626
627 reg = intel_get_padcfg(pctrl, offset, PADCFG0);
628 if (reg) {
629 unsigned long flags;
630 u32 padcfg0;
631
632 spin_lock_irqsave(&pctrl->lock, flags);
633 padcfg0 = readl(reg);
634 if (value)
635 padcfg0 |= PADCFG0_GPIOTXSTATE;
636 else
637 padcfg0 &= ~PADCFG0_GPIOTXSTATE;
638 writel(padcfg0, reg);
639 spin_unlock_irqrestore(&pctrl->lock, flags);
640 }
641}
642
643static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
644{
645 return pinctrl_gpio_direction_input(chip->base + offset);
646}
647
648static int intel_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
649 int value)
650{
651 intel_gpio_set(chip, offset, value);
652 return pinctrl_gpio_direction_output(chip->base + offset);
653}
654
655static const struct gpio_chip intel_gpio_chip = {
656 .owner = THIS_MODULE,
657 .request = intel_gpio_request,
658 .free = intel_gpio_free,
659 .direction_input = intel_gpio_direction_input,
660 .direction_output = intel_gpio_direction_output,
661 .get = intel_gpio_get,
662 .set = intel_gpio_set,
663};
664
665static void intel_gpio_irq_ack(struct irq_data *d)
666{
667 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
668 struct intel_pinctrl *pctrl = gpiochip_to_pinctrl(gc);
669 const struct intel_community *community;
670 unsigned pin = irqd_to_hwirq(d);
671
672 spin_lock(&pctrl->lock);
673
674 community = intel_get_community(pctrl, pin);
675 if (community) {
676 unsigned padno = pin_to_padno(community, pin);
677 unsigned gpp_offset = padno % NPADS_IN_GPP;
678 unsigned gpp = padno / NPADS_IN_GPP;
679
680 writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
681 }
682
683 spin_unlock(&pctrl->lock);
684}
685
686static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
687{
688 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
689 struct intel_pinctrl *pctrl = gpiochip_to_pinctrl(gc);
690 const struct intel_community *community;
691 unsigned pin = irqd_to_hwirq(d);
692 unsigned long flags;
693
694 spin_lock_irqsave(&pctrl->lock, flags);
695
696 community = intel_get_community(pctrl, pin);
697 if (community) {
698 unsigned padno = pin_to_padno(community, pin);
699 unsigned gpp_offset = padno % NPADS_IN_GPP;
700 unsigned gpp = padno / NPADS_IN_GPP;
701 void __iomem *reg;
702 u32 value;
703
704 reg = community->regs + community->ie_offset + gpp * 4;
705 value = readl(reg);
706 if (mask)
707 value &= ~BIT(gpp_offset);
708 else
709 value |= BIT(gpp_offset);
710 writel(value, reg);
711 }
712
713 spin_unlock_irqrestore(&pctrl->lock, flags);
714}
715
716static void intel_gpio_irq_mask(struct irq_data *d)
717{
718 intel_gpio_irq_mask_unmask(d, true);
719}
720
721static void intel_gpio_irq_unmask(struct irq_data *d)
722{
723 intel_gpio_irq_mask_unmask(d, false);
724}
725
726static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
727{
728 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
729 struct intel_pinctrl *pctrl = gpiochip_to_pinctrl(gc);
730 unsigned pin = irqd_to_hwirq(d);
731 unsigned long flags;
732 void __iomem *reg;
733 u32 value;
734
735 reg = intel_get_padcfg(pctrl, pin, PADCFG0);
736 if (!reg)
737 return -EINVAL;
738
739 spin_lock_irqsave(&pctrl->lock, flags);
740
741 value = readl(reg);
742
743 value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV);
744
745 if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
746 value |= PADCFG0_RXEVCFG_EDGE_BOTH << PADCFG0_RXEVCFG_SHIFT;
747 } else if (type & IRQ_TYPE_EDGE_FALLING) {
748 value |= PADCFG0_RXEVCFG_EDGE << PADCFG0_RXEVCFG_SHIFT;
749 value |= PADCFG0_RXINV;
750 } else if (type & IRQ_TYPE_EDGE_RISING) {
751 value |= PADCFG0_RXEVCFG_EDGE << PADCFG0_RXEVCFG_SHIFT;
752 } else if (type & IRQ_TYPE_LEVEL_LOW) {
753 value |= PADCFG0_RXINV;
754 } else {
755 value |= PADCFG0_RXEVCFG_DISABLED << PADCFG0_RXEVCFG_SHIFT;
756 }
757
758 writel(value, reg);
759
760 if (type & IRQ_TYPE_EDGE_BOTH)
761 __irq_set_handler_locked(d->irq, handle_edge_irq);
762 else if (type & IRQ_TYPE_LEVEL_MASK)
763 __irq_set_handler_locked(d->irq, handle_level_irq);
764
765 spin_unlock_irqrestore(&pctrl->lock, flags);
766
767 return 0;
768}
769
770static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
771{
772 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
773 struct intel_pinctrl *pctrl = gpiochip_to_pinctrl(gc);
774 const struct intel_community *community;
775 unsigned pin = irqd_to_hwirq(d);
776 unsigned padno, gpp, gpp_offset;
777 u32 gpe_en;
778
779 community = intel_get_community(pctrl, pin);
780 if (!community)
781 return -EINVAL;
782
783 padno = pin_to_padno(community, pin);
784 gpp = padno / NPADS_IN_GPP;
785 gpp_offset = padno % NPADS_IN_GPP;
786
787 /* Clear the existing wake status */
788 writel(BIT(gpp_offset), community->regs + GPI_GPE_STS + gpp * 4);
789
790 /*
791 * The controller will generate wake when GPE of the corresponding
792 * pad is enabled and it is not routed to SCI (GPIROUTSCI is not
793 * set).
794 */
795 gpe_en = readl(community->regs + GPI_GPE_EN + gpp * 4);
796 if (on)
797 gpe_en |= BIT(gpp_offset);
798 else
799 gpe_en &= ~BIT(gpp_offset);
800 writel(gpe_en, community->regs + GPI_GPE_EN + gpp * 4);
801
802 dev_dbg(pctrl->dev, "%sable wake for pin %u\n", on ? "en" : "dis", pin);
803 return 0;
804}
805
806static void intel_gpio_community_irq_handler(struct gpio_chip *gc,
807 const struct intel_community *community)
808{
809 int gpp;
810
811 for (gpp = 0; gpp < community->ngpps; gpp++) {
812 unsigned long pending, enabled, gpp_offset;
813
814 pending = readl(community->regs + GPI_IS + gpp * 4);
815 enabled = readl(community->regs + community->ie_offset +
816 gpp * 4);
817
818 /* Only interrupts that are enabled */
819 pending &= enabled;
820
821 for_each_set_bit(gpp_offset, &pending, NPADS_IN_GPP) {
822 unsigned padno, irq;
823
824 /*
825 * The last group in community can have less pins
826 * than NPADS_IN_GPP.
827 */
828 padno = gpp_offset + gpp * NPADS_IN_GPP;
829 if (padno >= community->npins)
830 break;
831
832 irq = irq_find_mapping(gc->irqdomain,
833 community->pin_base + padno);
834 generic_handle_irq(irq);
835 }
836 }
837}
838
839static void intel_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
840{
841 struct gpio_chip *gc = irq_desc_get_handler_data(desc);
842 struct intel_pinctrl *pctrl = gpiochip_to_pinctrl(gc);
843 struct irq_chip *chip = irq_get_chip(irq);
844 int i;
845
846 chained_irq_enter(chip, desc);
847
848 /* Need to check all communities for pending interrupts */
849 for (i = 0; i < pctrl->ncommunities; i++)
850 intel_gpio_community_irq_handler(gc, &pctrl->communities[i]);
851
852 chained_irq_exit(chip, desc);
853}
854
855static struct irq_chip intel_gpio_irqchip = {
856 .name = "intel-gpio",
857 .irq_ack = intel_gpio_irq_ack,
858 .irq_mask = intel_gpio_irq_mask,
859 .irq_unmask = intel_gpio_irq_unmask,
860 .irq_set_type = intel_gpio_irq_type,
861 .irq_set_wake = intel_gpio_irq_wake,
862};
863
864static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
865{
866 size_t i;
867
868 for (i = 0; i < pctrl->ncommunities; i++) {
869 const struct intel_community *community;
870 void __iomem *base;
871 unsigned gpp;
872
873 community = &pctrl->communities[i];
874 base = community->regs;
875
876 for (gpp = 0; gpp < community->ngpps; gpp++) {
877 /* Mask and clear all interrupts */
878 writel(0, base + community->ie_offset + gpp * 4);
879 writel(0xffff, base + GPI_IS + gpp * 4);
880 }
881 }
882}
883
884static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
885{
886 int ret;
887
888 pctrl->chip = intel_gpio_chip;
889
890 pctrl->chip.ngpio = pctrl->soc->npins;
891 pctrl->chip.label = dev_name(pctrl->dev);
892 pctrl->chip.dev = pctrl->dev;
893 pctrl->chip.base = -1;
894
895 ret = gpiochip_add(&pctrl->chip);
896 if (ret) {
897 dev_err(pctrl->dev, "failed to register gpiochip\n");
898 return ret;
899 }
900
901 ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
902 0, 0, pctrl->soc->npins);
903 if (ret) {
904 dev_err(pctrl->dev, "failed to add GPIO pin range\n");
905 gpiochip_remove(&pctrl->chip);
906 return ret;
907 }
908
909 ret = gpiochip_irqchip_add(&pctrl->chip, &intel_gpio_irqchip, 0,
910 handle_simple_irq, IRQ_TYPE_NONE);
911 if (ret) {
912 dev_err(pctrl->dev, "failed to add irqchip\n");
913 gpiochip_remove(&pctrl->chip);
914 return ret;
915 }
916
917 gpiochip_set_chained_irqchip(&pctrl->chip, &intel_gpio_irqchip, irq,
918 intel_gpio_irq_handler);
919 return 0;
920}
921
922static int intel_pinctrl_pm_init(struct intel_pinctrl *pctrl)
923{
924#ifdef CONFIG_PM_SLEEP
925 const struct intel_pinctrl_soc_data *soc = pctrl->soc;
926 struct intel_community_context *communities;
927 struct intel_pad_context *pads;
928 int i;
929
930 pads = devm_kcalloc(pctrl->dev, soc->npins, sizeof(*pads), GFP_KERNEL);
931 if (!pads)
932 return -ENOMEM;
933
934 communities = devm_kcalloc(pctrl->dev, pctrl->ncommunities,
935 sizeof(*communities), GFP_KERNEL);
936 if (!communities)
937 return -ENOMEM;
938
939
940 for (i = 0; i < pctrl->ncommunities; i++) {
941 struct intel_community *community = &pctrl->communities[i];
942 u32 *intmask;
943
944 intmask = devm_kcalloc(pctrl->dev, community->ngpps,
945 sizeof(*intmask), GFP_KERNEL);
946 if (!intmask)
947 return -ENOMEM;
948
949 communities[i].intmask = intmask;
950 }
951
952 pctrl->context.pads = pads;
953 pctrl->context.communities = communities;
954#endif
955
956 return 0;
957}
958
959int intel_pinctrl_probe(struct platform_device *pdev,
960 const struct intel_pinctrl_soc_data *soc_data)
961{
962 struct intel_pinctrl *pctrl;
963 int i, ret, irq;
964
965 if (!soc_data)
966 return -EINVAL;
967
968 pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
969 if (!pctrl)
970 return -ENOMEM;
971
972 pctrl->dev = &pdev->dev;
973 pctrl->soc = soc_data;
974 spin_lock_init(&pctrl->lock);
975
976 /*
977 * Make a copy of the communities which we can use to hold pointers
978 * to the registers.
979 */
980 pctrl->ncommunities = pctrl->soc->ncommunities;
981 pctrl->communities = devm_kcalloc(&pdev->dev, pctrl->ncommunities,
982 sizeof(*pctrl->communities), GFP_KERNEL);
983 if (!pctrl->communities)
984 return -ENOMEM;
985
986 for (i = 0; i < pctrl->ncommunities; i++) {
987 struct intel_community *community = &pctrl->communities[i];
988 struct resource *res;
989 void __iomem *regs;
990 u32 padbar;
991
992 *community = pctrl->soc->communities[i];
993
994 res = platform_get_resource(pdev, IORESOURCE_MEM,
995 community->barno);
996 regs = devm_ioremap_resource(&pdev->dev, res);
997 if (IS_ERR(regs))
998 return PTR_ERR(regs);
999
1000 /* Read offset of the pad configuration registers */
1001 padbar = readl(regs + PADBAR);
1002
1003 community->regs = regs;
1004 community->pad_regs = regs + padbar;
1005 community->ngpps = DIV_ROUND_UP(community->npins, NPADS_IN_GPP);
1006 }
1007
1008 irq = platform_get_irq(pdev, 0);
1009 if (irq < 0) {
1010 dev_err(&pdev->dev, "failed to get interrupt number\n");
1011 return irq;
1012 }
1013
1014 ret = intel_pinctrl_pm_init(pctrl);
1015 if (ret)
1016 return ret;
1017
1018 pctrl->pctldesc = intel_pinctrl_desc;
1019 pctrl->pctldesc.name = dev_name(&pdev->dev);
1020 pctrl->pctldesc.pins = pctrl->soc->pins;
1021 pctrl->pctldesc.npins = pctrl->soc->npins;
1022
1023 pctrl->pctldev = pinctrl_register(&pctrl->pctldesc, &pdev->dev, pctrl);
1024 if (!pctrl->pctldev) {
1025 dev_err(&pdev->dev, "failed to register pinctrl driver\n");
1026 return -ENODEV;
1027 }
1028
1029 ret = intel_gpio_probe(pctrl, irq);
1030 if (ret) {
1031 pinctrl_unregister(pctrl->pctldev);
1032 return ret;
1033 }
1034
1035 platform_set_drvdata(pdev, pctrl);
1036
1037 return 0;
1038}
1039EXPORT_SYMBOL_GPL(intel_pinctrl_probe);
1040
1041int intel_pinctrl_remove(struct platform_device *pdev)
1042{
1043 struct intel_pinctrl *pctrl = platform_get_drvdata(pdev);
1044
1045 gpiochip_remove(&pctrl->chip);
1046 pinctrl_unregister(pctrl->pctldev);
1047
1048 return 0;
1049}
1050EXPORT_SYMBOL_GPL(intel_pinctrl_remove);
1051
1052#ifdef CONFIG_PM_SLEEP
1053int intel_pinctrl_suspend(struct device *dev)
1054{
1055 struct platform_device *pdev = to_platform_device(dev);
1056 struct intel_pinctrl *pctrl = platform_get_drvdata(pdev);
1057 struct intel_community_context *communities;
1058 struct intel_pad_context *pads;
1059 int i;
1060
1061 pads = pctrl->context.pads;
1062 for (i = 0; i < pctrl->soc->npins; i++) {
1063 const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i];
1064 u32 val;
1065
1066 if (!intel_pad_usable(pctrl, desc->number))
1067 continue;
1068
1069 val = readl(intel_get_padcfg(pctrl, desc->number, PADCFG0));
1070 pads[i].padcfg0 = val & ~PADCFG0_GPIORXSTATE;
1071 val = readl(intel_get_padcfg(pctrl, desc->number, PADCFG1));
1072 pads[i].padcfg1 = val;
1073 }
1074
1075 communities = pctrl->context.communities;
1076 for (i = 0; i < pctrl->ncommunities; i++) {
1077 struct intel_community *community = &pctrl->communities[i];
1078 void __iomem *base;
1079 unsigned gpp;
1080
1081 base = community->regs + community->ie_offset;
1082 for (gpp = 0; gpp < community->ngpps; gpp++)
1083 communities[i].intmask[gpp] = readl(base + gpp * 4);
1084 }
1085
1086 return 0;
1087}
1088EXPORT_SYMBOL_GPL(intel_pinctrl_suspend);
1089
1090int intel_pinctrl_resume(struct device *dev)
1091{
1092 struct platform_device *pdev = to_platform_device(dev);
1093 struct intel_pinctrl *pctrl = platform_get_drvdata(pdev);
1094 const struct intel_community_context *communities;
1095 const struct intel_pad_context *pads;
1096 int i;
1097
1098 /* Mask all interrupts */
1099 intel_gpio_irq_init(pctrl);
1100
1101 pads = pctrl->context.pads;
1102 for (i = 0; i < pctrl->soc->npins; i++) {
1103 const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i];
1104 void __iomem *padcfg;
1105 u32 val;
1106
1107 if (!intel_pad_usable(pctrl, desc->number))
1108 continue;
1109
1110 padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG0);
1111 val = readl(padcfg) & ~PADCFG0_GPIORXSTATE;
1112 if (val != pads[i].padcfg0) {
1113 writel(pads[i].padcfg0, padcfg);
1114 dev_dbg(dev, "restored pin %u padcfg0 %#08x\n",
1115 desc->number, readl(padcfg));
1116 }
1117
1118 padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG1);
1119 val = readl(padcfg);
1120 if (val != pads[i].padcfg1) {
1121 writel(pads[i].padcfg1, padcfg);
1122 dev_dbg(dev, "restored pin %u padcfg1 %#08x\n",
1123 desc->number, readl(padcfg));
1124 }
1125 }
1126
1127 communities = pctrl->context.communities;
1128 for (i = 0; i < pctrl->ncommunities; i++) {
1129 struct intel_community *community = &pctrl->communities[i];
1130 void __iomem *base;
1131 unsigned gpp;
1132
1133 base = community->regs + community->ie_offset;
1134 for (gpp = 0; gpp < community->ngpps; gpp++) {
1135 writel(communities[i].intmask[gpp], base + gpp * 4);
1136 dev_dbg(dev, "restored mask %d/%u %#08x\n", i, gpp,
1137 readl(base + gpp * 4));
1138 }
1139 }
1140
1141 return 0;
1142}
1143EXPORT_SYMBOL_GPL(intel_pinctrl_resume);
1144#endif
1145
1146MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>");
1147MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
1148MODULE_DESCRIPTION("Intel pinctrl/GPIO core driver");
1149MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h
new file mode 100644
index 000000000000..4ec8b572a288
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-intel.h
@@ -0,0 +1,128 @@
1/*
2 * Core pinctrl/GPIO driver for Intel GPIO controllers
3 *
4 * Copyright (C) 2015, Intel Corporation
5 * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
6 * Mika Westerberg <mika.westerberg@linux.intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef PINCTRL_INTEL_H
14#define PINCTRL_INTEL_H
15
16struct pinctrl_pin_desc;
17struct platform_device;
18struct device;
19
20/**
21 * struct intel_pingroup - Description about group of pins
22 * @name: Name of the groups
23 * @pins: All pins in this group
24 * @npins: Number of pins in this groups
25 * @mode: Native mode in which the group is muxed out @pins
26 */
27struct intel_pingroup {
28 const char *name;
29 const unsigned *pins;
30 size_t npins;
31 unsigned short mode;
32};
33
34/**
35 * struct intel_function - Description about a function
36 * @name: Name of the function
37 * @groups: An array of groups for this function
38 * @ngroups: Number of groups in @groups
39 */
40struct intel_function {
41 const char *name;
42 const char * const *groups;
43 size_t ngroups;
44};
45
46/**
47 * struct intel_community - Intel pin community description
48 * @barno: MMIO BAR number where registers for this community reside
49 * @padown_offset: Register offset of PAD_OWN register from @regs. If %0
50 * then there is no support for owner.
51 * @padcfglock_offset: Register offset of PADCFGLOCK from @regs. If %0 then
52 * locking is not supported.
53 * @hostown_offset: Register offset of HOSTSW_OWN from @regs. If %0 then it
54 * is assumed that the host owns the pin (rather than
55 * ACPI).
56 * @ie_offset: Register offset of GPI_IE from @regs.
57 * @pin_base: Starting pin of pins in this community
58 * @npins: Number of pins in this community
59 * @regs: Community specific common registers (reserved for core driver)
60 * @pad_regs: Community specific pad registers (reserved for core driver)
61 * @ngpps: Number of groups (hw groups) in this community (reserved for
62 * core driver)
63 */
64struct intel_community {
65 unsigned barno;
66 unsigned padown_offset;
67 unsigned padcfglock_offset;
68 unsigned hostown_offset;
69 unsigned ie_offset;
70 unsigned pin_base;
71 size_t npins;
72 void __iomem *regs;
73 void __iomem *pad_regs;
74 size_t ngpps;
75};
76
77#define PIN_GROUP(n, p, m) \
78 { \
79 .name = (n), \
80 .pins = (p), \
81 .npins = ARRAY_SIZE((p)), \
82 .mode = (m), \
83 }
84
85#define FUNCTION(n, g) \
86 { \
87 .name = (n), \
88 .groups = (g), \
89 .ngroups = ARRAY_SIZE((g)), \
90 }
91
92/**
93 * struct intel_pinctrl_soc_data - Intel pin controller per-SoC configuration
94 * @uid: ACPI _UID for the probe driver use if needed
95 * @pins: Array if pins this pinctrl controls
96 * @npins: Number of pins in the array
97 * @groups: Array of pin groups
98 * @ngroups: Number of groups in the array
99 * @functions: Array of functions
100 * @nfunctions: Number of functions in the array
101 * @communities: Array of communities this pinctrl handles
102 * @ncommunities: Number of communities in the array
103 *
104 * The @communities is used as a template by the core driver. It will make
105 * copy of all communities and fill in rest of the information.
106 */
107struct intel_pinctrl_soc_data {
108 const char *uid;
109 const struct pinctrl_pin_desc *pins;
110 size_t npins;
111 const struct intel_pingroup *groups;
112 size_t ngroups;
113 const struct intel_function *functions;
114 size_t nfunctions;
115 const struct intel_community *communities;
116 size_t ncommunities;
117};
118
119int intel_pinctrl_probe(struct platform_device *pdev,
120 const struct intel_pinctrl_soc_data *soc_data);
121int intel_pinctrl_remove(struct platform_device *pdev);
122
123#ifdef CONFIG_PM_SLEEP
124int intel_pinctrl_suspend(struct device *dev);
125int intel_pinctrl_resume(struct device *dev);
126#endif
127
128#endif /* PINCTRL_INTEL_H */
diff --git a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c
new file mode 100644
index 000000000000..55d025dc89e8
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c
@@ -0,0 +1,336 @@
1/*
2 * Intel Sunrisepoint PCH pinctrl/GPIO driver
3 *
4 * Copyright (C) 2015, Intel Corporation
5 * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
6 * Mika Westerberg <mika.westerberg@linux.intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/acpi.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/pm.h>
17#include <linux/pinctrl/pinctrl.h>
18
19#include "pinctrl-intel.h"
20
21#define SPT_PAD_OWN 0x020
22#define SPT_PADCFGLOCK 0x0a0
23#define SPT_HOSTSW_OWN 0x0d0
24#define SPT_GPI_IE 0x120
25
26#define SPT_COMMUNITY(b, s, e) \
27 { \
28 .barno = (b), \
29 .padown_offset = SPT_PAD_OWN, \
30 .padcfglock_offset = SPT_PADCFGLOCK, \
31 .hostown_offset = SPT_HOSTSW_OWN, \
32 .ie_offset = SPT_GPI_IE, \
33 .pin_base = (s), \
34 .npins = ((e) - (s) + 1), \
35 }
36
37/* Sunrisepoint-LP */
38static const struct pinctrl_pin_desc sptlp_pins[] = {
39 /* GPP_A */
40 PINCTRL_PIN(0, "RCINB"),
41 PINCTRL_PIN(1, "LAD_0"),
42 PINCTRL_PIN(2, "LAD_1"),
43 PINCTRL_PIN(3, "LAD_2"),
44 PINCTRL_PIN(4, "LAD_3"),
45 PINCTRL_PIN(5, "LFRAMEB"),
46 PINCTRL_PIN(6, "SERIQ"),
47 PINCTRL_PIN(7, "PIRQAB"),
48 PINCTRL_PIN(8, "CLKRUNB"),
49 PINCTRL_PIN(9, "CLKOUT_LPC_0"),
50 PINCTRL_PIN(10, "CLKOUT_LPC_1"),
51 PINCTRL_PIN(11, "PMEB"),
52 PINCTRL_PIN(12, "BM_BUSYB"),
53 PINCTRL_PIN(13, "SUSWARNB_SUS_PWRDNACK"),
54 PINCTRL_PIN(14, "SUS_STATB"),
55 PINCTRL_PIN(15, "SUSACKB"),
56 PINCTRL_PIN(16, "SD_1P8_SEL"),
57 PINCTRL_PIN(17, "SD_PWR_EN_B"),
58 PINCTRL_PIN(18, "ISH_GP_0"),
59 PINCTRL_PIN(19, "ISH_GP_1"),
60 PINCTRL_PIN(20, "ISH_GP_2"),
61 PINCTRL_PIN(21, "ISH_GP_3"),
62 PINCTRL_PIN(22, "ISH_GP_4"),
63 PINCTRL_PIN(23, "ISH_GP_5"),
64 /* GPP_B */
65 PINCTRL_PIN(24, "CORE_VID_0"),
66 PINCTRL_PIN(25, "CORE_VID_1"),
67 PINCTRL_PIN(26, "VRALERTB"),
68 PINCTRL_PIN(27, "CPU_GP_2"),
69 PINCTRL_PIN(28, "CPU_GP_3"),
70 PINCTRL_PIN(29, "SRCCLKREQB_0"),
71 PINCTRL_PIN(30, "SRCCLKREQB_1"),
72 PINCTRL_PIN(31, "SRCCLKREQB_2"),
73 PINCTRL_PIN(32, "SRCCLKREQB_3"),
74 PINCTRL_PIN(33, "SRCCLKREQB_4"),
75 PINCTRL_PIN(34, "SRCCLKREQB_5"),
76 PINCTRL_PIN(35, "EXT_PWR_GATEB"),
77 PINCTRL_PIN(36, "SLP_S0B"),
78 PINCTRL_PIN(37, "PLTRSTB"),
79 PINCTRL_PIN(38, "SPKR"),
80 PINCTRL_PIN(39, "GSPI0_CSB"),
81 PINCTRL_PIN(40, "GSPI0_CLK"),
82 PINCTRL_PIN(41, "GSPI0_MISO"),
83 PINCTRL_PIN(42, "GSPI0_MOSI"),
84 PINCTRL_PIN(43, "GSPI1_CSB"),
85 PINCTRL_PIN(44, "GSPI1_CLK"),
86 PINCTRL_PIN(45, "GSPI1_MISO"),
87 PINCTRL_PIN(46, "GSPI1_MOSI"),
88 PINCTRL_PIN(47, "SML1ALERTB"),
89 /* GPP_C */
90 PINCTRL_PIN(48, "SMBCLK"),
91 PINCTRL_PIN(49, "SMBDATA"),
92 PINCTRL_PIN(50, "SMBALERTB"),
93 PINCTRL_PIN(51, "SML0CLK"),
94 PINCTRL_PIN(52, "SML0DATA"),
95 PINCTRL_PIN(53, "SML0ALERTB"),
96 PINCTRL_PIN(54, "SML1CLK"),
97 PINCTRL_PIN(55, "SML1DATA"),
98 PINCTRL_PIN(56, "UART0_RXD"),
99 PINCTRL_PIN(57, "UART0_TXD"),
100 PINCTRL_PIN(58, "UART0_RTSB"),
101 PINCTRL_PIN(59, "UART0_CTSB"),
102 PINCTRL_PIN(60, "UART1_RXD"),
103 PINCTRL_PIN(61, "UART1_TXD"),
104 PINCTRL_PIN(62, "UART1_RTSB"),
105 PINCTRL_PIN(63, "UART1_CTSB"),
106 PINCTRL_PIN(64, "I2C0_SDA"),
107 PINCTRL_PIN(65, "I2C0_SCL"),
108 PINCTRL_PIN(66, "I2C1_SDA"),
109 PINCTRL_PIN(67, "I2C1_SCL"),
110 PINCTRL_PIN(68, "UART2_RXD"),
111 PINCTRL_PIN(69, "UART2_TXD"),
112 PINCTRL_PIN(70, "UART2_RTSB"),
113 PINCTRL_PIN(71, "UART2_CTSB"),
114 /* GPP_D */
115 PINCTRL_PIN(72, "SPI1_CSB"),
116 PINCTRL_PIN(73, "SPI1_CLK"),
117 PINCTRL_PIN(74, "SPI1_MISO_IO_1"),
118 PINCTRL_PIN(75, "SPI1_MOSI_IO_0"),
119 PINCTRL_PIN(76, "FLASHTRIG"),
120 PINCTRL_PIN(77, "ISH_I2C0_SDA"),
121 PINCTRL_PIN(78, "ISH_I2C0_SCL"),
122 PINCTRL_PIN(79, "ISH_I2C1_SDA"),
123 PINCTRL_PIN(80, "ISH_I2C1_SCL"),
124 PINCTRL_PIN(81, "ISH_SPI_CSB"),
125 PINCTRL_PIN(82, "ISH_SPI_CLK"),
126 PINCTRL_PIN(83, "ISH_SPI_MISO"),
127 PINCTRL_PIN(84, "ISH_SPI_MOSI"),
128 PINCTRL_PIN(85, "ISH_UART0_RXD"),
129 PINCTRL_PIN(86, "ISH_UART0_TXD"),
130 PINCTRL_PIN(87, "ISH_UART0_RTSB"),
131 PINCTRL_PIN(88, "ISH_UART0_CTSB"),
132 PINCTRL_PIN(89, "DMIC_CLK_1"),
133 PINCTRL_PIN(90, "DMIC_DATA_1"),
134 PINCTRL_PIN(91, "DMIC_CLK_0"),
135 PINCTRL_PIN(92, "DMIC_DATA_0"),
136 PINCTRL_PIN(93, "SPI1_IO_2"),
137 PINCTRL_PIN(94, "SPI1_IO_3"),
138 PINCTRL_PIN(95, "SSP_MCLK"),
139 /* GPP_E */
140 PINCTRL_PIN(96, "SATAXPCIE_0"),
141 PINCTRL_PIN(97, "SATAXPCIE_1"),
142 PINCTRL_PIN(98, "SATAXPCIE_2"),
143 PINCTRL_PIN(99, "CPU_GP_0"),
144 PINCTRL_PIN(100, "SATA_DEVSLP_0"),
145 PINCTRL_PIN(101, "SATA_DEVSLP_1"),
146 PINCTRL_PIN(102, "SATA_DEVSLP_2"),
147 PINCTRL_PIN(103, "CPU_GP_1"),
148 PINCTRL_PIN(104, "SATA_LEDB"),
149 PINCTRL_PIN(105, "USB2_OCB_0"),
150 PINCTRL_PIN(106, "USB2_OCB_1"),
151 PINCTRL_PIN(107, "USB2_OCB_2"),
152 PINCTRL_PIN(108, "USB2_OCB_3"),
153 PINCTRL_PIN(109, "DDSP_HPD_0"),
154 PINCTRL_PIN(110, "DDSP_HPD_1"),
155 PINCTRL_PIN(111, "DDSP_HPD_2"),
156 PINCTRL_PIN(112, "DDSP_HPD_3"),
157 PINCTRL_PIN(113, "EDP_HPD"),
158 PINCTRL_PIN(114, "DDPB_CTRLCLK"),
159 PINCTRL_PIN(115, "DDPB_CTRLDATA"),
160 PINCTRL_PIN(116, "DDPC_CTRLCLK"),
161 PINCTRL_PIN(117, "DDPC_CTRLDATA"),
162 PINCTRL_PIN(118, "DDPD_CTRLCLK"),
163 PINCTRL_PIN(119, "DDPD_CTRLDATA"),
164 /* GPP_F */
165 PINCTRL_PIN(120, "SSP2_SCLK"),
166 PINCTRL_PIN(121, "SSP2_SFRM"),
167 PINCTRL_PIN(122, "SSP2_TXD"),
168 PINCTRL_PIN(123, "SSP2_RXD"),
169 PINCTRL_PIN(124, "I2C2_SDA"),
170 PINCTRL_PIN(125, "I2C2_SCL"),
171 PINCTRL_PIN(126, "I2C3_SDA"),
172 PINCTRL_PIN(127, "I2C3_SCL"),
173 PINCTRL_PIN(128, "I2C4_SDA"),
174 PINCTRL_PIN(129, "I2C4_SCL"),
175 PINCTRL_PIN(130, "I2C5_SDA"),
176 PINCTRL_PIN(131, "I2C5_SCL"),
177 PINCTRL_PIN(132, "EMMC_CMD"),
178 PINCTRL_PIN(133, "EMMC_DATA_0"),
179 PINCTRL_PIN(134, "EMMC_DATA_1"),
180 PINCTRL_PIN(135, "EMMC_DATA_2"),
181 PINCTRL_PIN(136, "EMMC_DATA_3"),
182 PINCTRL_PIN(137, "EMMC_DATA_4"),
183 PINCTRL_PIN(138, "EMMC_DATA_5"),
184 PINCTRL_PIN(139, "EMMC_DATA_6"),
185 PINCTRL_PIN(140, "EMMC_DATA_7"),
186 PINCTRL_PIN(141, "EMMC_RCLK"),
187 PINCTRL_PIN(142, "EMMC_CLK"),
188 PINCTRL_PIN(143, "GPP_F_23"),
189 /* GPP_G */
190 PINCTRL_PIN(144, "SD_CMD"),
191 PINCTRL_PIN(145, "SD_DATA_0"),
192 PINCTRL_PIN(146, "SD_DATA_1"),
193 PINCTRL_PIN(147, "SD_DATA_2"),
194 PINCTRL_PIN(148, "SD_DATA_3"),
195 PINCTRL_PIN(149, "SD_CDB"),
196 PINCTRL_PIN(150, "SD_CLK"),
197 PINCTRL_PIN(151, "SD_WP"),
198};
199
200static const unsigned sptlp_spi0_pins[] = { 39, 40, 41, 42 };
201static const unsigned sptlp_spi1_pins[] = { 43, 44, 45, 46 };
202static const unsigned sptlp_uart0_pins[] = { 56, 57, 58, 59 };
203static const unsigned sptlp_uart1_pins[] = { 60, 61, 62, 63 };
204static const unsigned sptlp_uart2_pins[] = { 68, 69, 71, 71 };
205static const unsigned sptlp_i2c0_pins[] = { 64, 65 };
206static const unsigned sptlp_i2c1_pins[] = { 66, 67 };
207static const unsigned sptlp_i2c2_pins[] = { 124, 125 };
208static const unsigned sptlp_i2c3_pins[] = { 126, 127 };
209static const unsigned sptlp_i2c4_pins[] = { 128, 129 };
210static const unsigned sptlp_i2c4b_pins[] = { 85, 86 };
211static const unsigned sptlp_i2c5_pins[] = { 130, 131 };
212static const unsigned sptlp_ssp2_pins[] = { 120, 121, 122, 123 };
213static const unsigned sptlp_emmc_pins[] = {
214 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
215};
216static const unsigned sptlp_sd_pins[] = {
217 144, 145, 146, 147, 148, 149, 150, 151,
218};
219
220static const struct intel_pingroup sptlp_groups[] = {
221 PIN_GROUP("spi0_grp", sptlp_spi0_pins, 1),
222 PIN_GROUP("spi1_grp", sptlp_spi1_pins, 1),
223 PIN_GROUP("uart0_grp", sptlp_uart0_pins, 1),
224 PIN_GROUP("uart1_grp", sptlp_uart1_pins, 1),
225 PIN_GROUP("uart2_grp", sptlp_uart2_pins, 1),
226 PIN_GROUP("i2c0_grp", sptlp_i2c0_pins, 1),
227 PIN_GROUP("i2c1_grp", sptlp_i2c1_pins, 1),
228 PIN_GROUP("i2c2_grp", sptlp_i2c2_pins, 1),
229 PIN_GROUP("i2c3_grp", sptlp_i2c3_pins, 1),
230 PIN_GROUP("i2c4_grp", sptlp_i2c4_pins, 1),
231 PIN_GROUP("i2c4b_grp", sptlp_i2c4b_pins, 3),
232 PIN_GROUP("i2c5_grp", sptlp_i2c5_pins, 1),
233 PIN_GROUP("ssp2_grp", sptlp_ssp2_pins, 1),
234 PIN_GROUP("emmc_grp", sptlp_emmc_pins, 1),
235 PIN_GROUP("sd_grp", sptlp_sd_pins, 1),
236};
237
238static const char * const sptlp_spi0_groups[] = { "spi0_grp" };
239static const char * const sptlp_spi1_groups[] = { "spi0_grp" };
240static const char * const sptlp_uart0_groups[] = { "uart0_grp" };
241static const char * const sptlp_uart1_groups[] = { "uart1_grp" };
242static const char * const sptlp_uart2_groups[] = { "uart2_grp" };
243static const char * const sptlp_i2c0_groups[] = { "i2c0_grp" };
244static const char * const sptlp_i2c1_groups[] = { "i2c1_grp" };
245static const char * const sptlp_i2c2_groups[] = { "i2c2_grp" };
246static const char * const sptlp_i2c3_groups[] = { "i2c3_grp" };
247static const char * const sptlp_i2c4_groups[] = { "i2c4_grp", "i2c4b_grp" };
248static const char * const sptlp_i2c5_groups[] = { "i2c5_grp" };
249static const char * const sptlp_ssp2_groups[] = { "ssp2_grp" };
250static const char * const sptlp_emmc_groups[] = { "emmc_grp" };
251static const char * const sptlp_sd_groups[] = { "sd_grp" };
252
253static const struct intel_function sptlp_functions[] = {
254 FUNCTION("spi0", sptlp_spi0_groups),
255 FUNCTION("spi1", sptlp_spi1_groups),
256 FUNCTION("uart0", sptlp_uart0_groups),
257 FUNCTION("uart1", sptlp_uart1_groups),
258 FUNCTION("uart2", sptlp_uart2_groups),
259 FUNCTION("i2c0", sptlp_i2c0_groups),
260 FUNCTION("i2c1", sptlp_i2c1_groups),
261 FUNCTION("i2c2", sptlp_i2c2_groups),
262 FUNCTION("i2c3", sptlp_i2c3_groups),
263 FUNCTION("i2c4", sptlp_i2c4_groups),
264 FUNCTION("i2c5", sptlp_i2c5_groups),
265 FUNCTION("ssp2", sptlp_ssp2_groups),
266 FUNCTION("emmc", sptlp_emmc_groups),
267 FUNCTION("sd", sptlp_sd_groups),
268};
269
270static const struct intel_community sptlp_communities[] = {
271 SPT_COMMUNITY(0, 0, 47),
272 SPT_COMMUNITY(1, 48, 119),
273 SPT_COMMUNITY(2, 120, 151),
274};
275
276static const struct intel_pinctrl_soc_data sptlp_soc_data = {
277 .pins = sptlp_pins,
278 .npins = ARRAY_SIZE(sptlp_pins),
279 .groups = sptlp_groups,
280 .ngroups = ARRAY_SIZE(sptlp_groups),
281 .functions = sptlp_functions,
282 .nfunctions = ARRAY_SIZE(sptlp_functions),
283 .communities = sptlp_communities,
284 .ncommunities = ARRAY_SIZE(sptlp_communities),
285};
286
287static const struct acpi_device_id spt_pinctrl_acpi_match[] = {
288 { "INT344B", (kernel_ulong_t)&sptlp_soc_data },
289 { }
290};
291MODULE_DEVICE_TABLE(acpi, spt_pinctrl_acpi_match);
292
293static int spt_pinctrl_probe(struct platform_device *pdev)
294{
295 const struct intel_pinctrl_soc_data *soc_data;
296 const struct acpi_device_id *id;
297
298 id = acpi_match_device(spt_pinctrl_acpi_match, &pdev->dev);
299 if (!id || !id->driver_data)
300 return -ENODEV;
301
302 soc_data = (const struct intel_pinctrl_soc_data *)id->driver_data;
303 return intel_pinctrl_probe(pdev, soc_data);
304}
305
306static const struct dev_pm_ops spt_pinctrl_pm_ops = {
307 SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
308 intel_pinctrl_resume)
309};
310
311static struct platform_driver spt_pinctrl_driver = {
312 .probe = spt_pinctrl_probe,
313 .remove = intel_pinctrl_remove,
314 .driver = {
315 .name = "sunrisepoint-pinctrl",
316 .acpi_match_table = spt_pinctrl_acpi_match,
317 .pm = &spt_pinctrl_pm_ops,
318 },
319};
320
321static int __init spt_pinctrl_init(void)
322{
323 return platform_driver_register(&spt_pinctrl_driver);
324}
325subsys_initcall(spt_pinctrl_init);
326
327static void __exit spt_pinctrl_exit(void)
328{
329 platform_driver_unregister(&spt_pinctrl_driver);
330}
331module_exit(spt_pinctrl_exit);
332
333MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>");
334MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
335MODULE_DESCRIPTION("Intel Sunrisepoint PCH pinctrl/GPIO driver");
336MODULE_LICENSE("GPL v2");