1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Intel pinctrl/GPIO core driver. |
4 | * |
5 | * Copyright (C) 2015, Intel Corporation |
6 | * Authors: Mathias Nyman <mathias.nyman@linux.intel.com> |
7 | * Mika Westerberg <mika.westerberg@linux.intel.com> |
8 | */ |
9 | |
10 | #include <linux/acpi.h> |
11 | #include <linux/cleanup.h> |
12 | #include <linux/gpio/driver.h> |
13 | #include <linux/interrupt.h> |
14 | #include <linux/log2.h> |
15 | #include <linux/module.h> |
16 | #include <linux/platform_device.h> |
17 | #include <linux/property.h> |
18 | #include <linux/seq_file.h> |
19 | #include <linux/string_helpers.h> |
20 | #include <linux/time.h> |
21 | |
22 | #include <linux/pinctrl/consumer.h> |
23 | #include <linux/pinctrl/pinconf.h> |
24 | #include <linux/pinctrl/pinconf-generic.h> |
25 | #include <linux/pinctrl/pinctrl.h> |
26 | #include <linux/pinctrl/pinmux.h> |
27 | |
28 | #include <linux/platform_data/x86/pwm-lpss.h> |
29 | |
30 | #include "../core.h" |
31 | #include "pinctrl-intel.h" |
32 | |
33 | /* Offset from regs */ |
34 | #define REVID 0x000 |
35 | #define REVID_SHIFT 16 |
36 | #define REVID_MASK GENMASK(31, 16) |
37 | |
38 | #define CAPLIST 0x004 |
39 | #define CAPLIST_ID_SHIFT 16 |
40 | #define CAPLIST_ID_MASK GENMASK(23, 16) |
41 | #define CAPLIST_ID_GPIO_HW_INFO 1 |
42 | #define CAPLIST_ID_PWM 2 |
43 | #define CAPLIST_ID_BLINK 3 |
44 | #define CAPLIST_ID_EXP 4 |
45 | #define CAPLIST_NEXT_SHIFT 0 |
46 | #define CAPLIST_NEXT_MASK GENMASK(15, 0) |
47 | |
48 | #define PADBAR 0x00c |
49 | |
50 | #define PADOWN_BITS 4 |
51 | #define PADOWN_SHIFT(p) ((p) % 8 * PADOWN_BITS) |
52 | #define PADOWN_MASK(p) (GENMASK(3, 0) << PADOWN_SHIFT(p)) |
53 | #define PADOWN_GPP(p) ((p) / 8) |
54 | |
55 | #define PWMC 0x204 |
56 | |
57 | /* Offset from pad_regs */ |
58 | #define PADCFG0 0x000 |
59 | #define PADCFG0_RXEVCFG_MASK GENMASK(26, 25) |
60 | #define PADCFG0_RXEVCFG_LEVEL (0 << 25) |
61 | #define PADCFG0_RXEVCFG_EDGE (1 << 25) |
62 | #define PADCFG0_RXEVCFG_DISABLED (2 << 25) |
63 | #define PADCFG0_RXEVCFG_EDGE_BOTH (3 << 25) |
64 | #define PADCFG0_PREGFRXSEL BIT(24) |
65 | #define PADCFG0_RXINV BIT(23) |
66 | #define PADCFG0_GPIROUTIOXAPIC BIT(20) |
67 | #define PADCFG0_GPIROUTSCI BIT(19) |
68 | #define PADCFG0_GPIROUTSMI BIT(18) |
69 | #define PADCFG0_GPIROUTNMI BIT(17) |
70 | #define PADCFG0_PMODE_SHIFT 10 |
71 | #define PADCFG0_PMODE_MASK GENMASK(13, 10) |
72 | #define PADCFG0_PMODE_GPIO 0 |
73 | #define PADCFG0_GPIORXDIS BIT(9) |
74 | #define PADCFG0_GPIOTXDIS BIT(8) |
75 | #define PADCFG0_GPIORXSTATE BIT(1) |
76 | #define PADCFG0_GPIOTXSTATE BIT(0) |
77 | |
78 | #define PADCFG1 0x004 |
79 | #define PADCFG1_TERM_UP BIT(13) |
80 | #define PADCFG1_TERM_SHIFT 10 |
81 | #define PADCFG1_TERM_MASK GENMASK(12, 10) |
82 | #define PADCFG1_TERM_20K BIT(2) |
83 | #define PADCFG1_TERM_5K BIT(1) |
84 | #define PADCFG1_TERM_4K (BIT(2) | BIT(1)) |
85 | #define PADCFG1_TERM_1K BIT(0) |
86 | #define PADCFG1_TERM_952 (BIT(2) | BIT(0)) |
87 | #define PADCFG1_TERM_833 (BIT(1) | BIT(0)) |
88 | #define PADCFG1_TERM_800 (BIT(2) | BIT(1) | BIT(0)) |
89 | |
90 | #define PADCFG2 0x008 |
91 | #define PADCFG2_DEBOUNCE_SHIFT 1 |
92 | #define PADCFG2_DEBOUNCE_MASK GENMASK(4, 1) |
93 | #define PADCFG2_DEBEN BIT(0) |
94 | |
95 | #define DEBOUNCE_PERIOD_NSEC 31250 |
96 | |
97 | struct intel_pad_context { |
98 | u32 padcfg0; |
99 | u32 padcfg1; |
100 | u32 padcfg2; |
101 | }; |
102 | |
103 | struct { |
104 | u32 *; |
105 | u32 *; |
106 | }; |
107 | |
108 | #define pin_to_padno(c, p) ((p) - (c)->pin_base) |
109 | #define padgroup_offset(g, p) ((p) - (g)->base) |
110 | |
111 | struct intel_community *(struct intel_pinctrl *pctrl, unsigned int pin) |
112 | { |
113 | struct intel_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 | EXPORT_SYMBOL_NS_GPL(intel_get_community, PINCTRL_INTEL); |
127 | |
128 | static const struct intel_padgroup * |
129 | (const struct intel_community *, |
130 | unsigned int pin) |
131 | { |
132 | int i; |
133 | |
134 | for (i = 0; i < community->ngpps; i++) { |
135 | const struct intel_padgroup *padgrp = &community->gpps[i]; |
136 | |
137 | if (pin >= padgrp->base && pin < padgrp->base + padgrp->size) |
138 | return padgrp; |
139 | } |
140 | |
141 | return NULL; |
142 | } |
143 | |
144 | static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, |
145 | unsigned int pin, unsigned int reg) |
146 | { |
147 | const struct intel_community *; |
148 | unsigned int padno; |
149 | size_t nregs; |
150 | |
151 | community = intel_get_community(pctrl, pin); |
152 | if (!community) |
153 | return NULL; |
154 | |
155 | padno = pin_to_padno(community, pin); |
156 | nregs = (community->features & PINCTRL_FEATURE_DEBOUNCE) ? 4 : 2; |
157 | |
158 | if (reg >= nregs * 4) |
159 | return NULL; |
160 | |
161 | return community->pad_regs + reg + padno * nregs * 4; |
162 | } |
163 | |
164 | static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned int pin) |
165 | { |
166 | const struct intel_community *; |
167 | const struct intel_padgroup *padgrp; |
168 | unsigned int gpp, offset, gpp_offset; |
169 | void __iomem *padown; |
170 | |
171 | community = intel_get_community(pctrl, pin); |
172 | if (!community) |
173 | return false; |
174 | if (!community->padown_offset) |
175 | return true; |
176 | |
177 | padgrp = intel_community_get_padgroup(community, pin); |
178 | if (!padgrp) |
179 | return false; |
180 | |
181 | gpp_offset = padgroup_offset(padgrp, pin); |
182 | gpp = PADOWN_GPP(gpp_offset); |
183 | offset = community->padown_offset + padgrp->padown_num * 4 + gpp * 4; |
184 | padown = community->regs + offset; |
185 | |
186 | return !(readl(addr: padown) & PADOWN_MASK(gpp_offset)); |
187 | } |
188 | |
189 | static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin) |
190 | { |
191 | const struct intel_community *; |
192 | const struct intel_padgroup *padgrp; |
193 | unsigned int offset, gpp_offset; |
194 | void __iomem *hostown; |
195 | |
196 | community = intel_get_community(pctrl, pin); |
197 | if (!community) |
198 | return true; |
199 | if (!community->hostown_offset) |
200 | return false; |
201 | |
202 | padgrp = intel_community_get_padgroup(community, pin); |
203 | if (!padgrp) |
204 | return true; |
205 | |
206 | gpp_offset = padgroup_offset(padgrp, pin); |
207 | offset = community->hostown_offset + padgrp->reg_num * 4; |
208 | hostown = community->regs + offset; |
209 | |
210 | return !(readl(addr: hostown) & BIT(gpp_offset)); |
211 | } |
212 | |
213 | /** |
214 | * enum - Locking variants of the pad configuration |
215 | * |
216 | * @PAD_UNLOCKED: pad is fully controlled by the configuration registers |
217 | * @PAD_LOCKED: pad configuration registers, except TX state, are locked |
218 | * @PAD_LOCKED_TX: pad configuration TX state is locked |
219 | * @PAD_LOCKED_FULL: pad configuration registers are locked completely |
220 | * |
221 | * Locking is considered as read-only mode for corresponding registers and |
222 | * their respective fields. That said, TX state bit is locked separately from |
223 | * the main locking scheme. |
224 | */ |
225 | enum { |
226 | PAD_UNLOCKED = 0, |
227 | PAD_LOCKED = 1, |
228 | PAD_LOCKED_TX = 2, |
229 | PAD_LOCKED_FULL = PAD_LOCKED | PAD_LOCKED_TX, |
230 | }; |
231 | |
232 | static int intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin) |
233 | { |
234 | struct intel_community *; |
235 | const struct intel_padgroup *padgrp; |
236 | unsigned int offset, gpp_offset; |
237 | u32 value; |
238 | int ret = PAD_UNLOCKED; |
239 | |
240 | community = intel_get_community(pctrl, pin); |
241 | if (!community) |
242 | return PAD_LOCKED_FULL; |
243 | if (!community->padcfglock_offset) |
244 | return PAD_UNLOCKED; |
245 | |
246 | padgrp = intel_community_get_padgroup(community, pin); |
247 | if (!padgrp) |
248 | return PAD_LOCKED_FULL; |
249 | |
250 | gpp_offset = padgroup_offset(padgrp, pin); |
251 | |
252 | /* |
253 | * If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad, |
254 | * the pad is considered unlocked. Any other case means that it is |
255 | * either fully or partially locked. |
256 | */ |
257 | offset = community->padcfglock_offset + 0 + padgrp->reg_num * 8; |
258 | value = readl(addr: community->regs + offset); |
259 | if (value & BIT(gpp_offset)) |
260 | ret |= PAD_LOCKED; |
261 | |
262 | offset = community->padcfglock_offset + 4 + padgrp->reg_num * 8; |
263 | value = readl(addr: community->regs + offset); |
264 | if (value & BIT(gpp_offset)) |
265 | ret |= PAD_LOCKED_TX; |
266 | |
267 | return ret; |
268 | } |
269 | |
270 | static bool intel_pad_is_unlocked(struct intel_pinctrl *pctrl, unsigned int pin) |
271 | { |
272 | return (intel_pad_locked(pctrl, pin) & PAD_LOCKED) == PAD_UNLOCKED; |
273 | } |
274 | |
275 | static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned int pin) |
276 | { |
277 | return intel_pad_owned_by_host(pctrl, pin) && intel_pad_is_unlocked(pctrl, pin); |
278 | } |
279 | |
280 | int intel_get_groups_count(struct pinctrl_dev *pctldev) |
281 | { |
282 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
283 | |
284 | return pctrl->soc->ngroups; |
285 | } |
286 | EXPORT_SYMBOL_NS_GPL(intel_get_groups_count, PINCTRL_INTEL); |
287 | |
288 | const char *intel_get_group_name(struct pinctrl_dev *pctldev, unsigned int group) |
289 | { |
290 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
291 | |
292 | return pctrl->soc->groups[group].grp.name; |
293 | } |
294 | EXPORT_SYMBOL_NS_GPL(intel_get_group_name, PINCTRL_INTEL); |
295 | |
296 | int intel_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, |
297 | const unsigned int **pins, unsigned int *npins) |
298 | { |
299 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
300 | |
301 | *pins = pctrl->soc->groups[group].grp.pins; |
302 | *npins = pctrl->soc->groups[group].grp.npins; |
303 | return 0; |
304 | } |
305 | EXPORT_SYMBOL_NS_GPL(intel_get_group_pins, PINCTRL_INTEL); |
306 | |
307 | static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, |
308 | unsigned int pin) |
309 | { |
310 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
311 | void __iomem *padcfg; |
312 | u32 cfg0, cfg1, mode; |
313 | int locked; |
314 | bool acpi; |
315 | |
316 | if (!intel_pad_owned_by_host(pctrl, pin)) { |
317 | seq_puts(m: s, s: "not available" ); |
318 | return; |
319 | } |
320 | |
321 | cfg0 = readl(addr: intel_get_padcfg(pctrl, pin, PADCFG0)); |
322 | cfg1 = readl(addr: intel_get_padcfg(pctrl, pin, PADCFG1)); |
323 | |
324 | mode = (cfg0 & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT; |
325 | if (mode == PADCFG0_PMODE_GPIO) |
326 | seq_puts(m: s, s: "GPIO " ); |
327 | else |
328 | seq_printf(m: s, fmt: "mode %d " , mode); |
329 | |
330 | seq_printf(m: s, fmt: "0x%08x 0x%08x" , cfg0, cfg1); |
331 | |
332 | /* Dump the additional PADCFG registers if available */ |
333 | padcfg = intel_get_padcfg(pctrl, pin, PADCFG2); |
334 | if (padcfg) |
335 | seq_printf(m: s, fmt: " 0x%08x" , readl(addr: padcfg)); |
336 | |
337 | locked = intel_pad_locked(pctrl, pin); |
338 | acpi = intel_pad_acpi_mode(pctrl, pin); |
339 | |
340 | if (locked || acpi) { |
341 | seq_puts(m: s, s: " [" ); |
342 | if (locked) |
343 | seq_puts(m: s, s: "LOCKED" ); |
344 | if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_TX) |
345 | seq_puts(m: s, s: " tx" ); |
346 | else if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_FULL) |
347 | seq_puts(m: s, s: " full" ); |
348 | |
349 | if (locked && acpi) |
350 | seq_puts(m: s, s: ", " ); |
351 | |
352 | if (acpi) |
353 | seq_puts(m: s, s: "ACPI" ); |
354 | seq_puts(m: s, s: "]" ); |
355 | } |
356 | } |
357 | |
358 | static const struct pinctrl_ops intel_pinctrl_ops = { |
359 | .get_groups_count = intel_get_groups_count, |
360 | .get_group_name = intel_get_group_name, |
361 | .get_group_pins = intel_get_group_pins, |
362 | .pin_dbg_show = intel_pin_dbg_show, |
363 | }; |
364 | |
365 | int intel_get_functions_count(struct pinctrl_dev *pctldev) |
366 | { |
367 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
368 | |
369 | return pctrl->soc->nfunctions; |
370 | } |
371 | EXPORT_SYMBOL_NS_GPL(intel_get_functions_count, PINCTRL_INTEL); |
372 | |
373 | const char *intel_get_function_name(struct pinctrl_dev *pctldev, unsigned int function) |
374 | { |
375 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
376 | |
377 | return pctrl->soc->functions[function].func.name; |
378 | } |
379 | EXPORT_SYMBOL_NS_GPL(intel_get_function_name, PINCTRL_INTEL); |
380 | |
381 | int intel_get_function_groups(struct pinctrl_dev *pctldev, unsigned int function, |
382 | const char * const **groups, unsigned int * const ngroups) |
383 | { |
384 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
385 | |
386 | *groups = pctrl->soc->functions[function].func.groups; |
387 | *ngroups = pctrl->soc->functions[function].func.ngroups; |
388 | return 0; |
389 | } |
390 | EXPORT_SYMBOL_NS_GPL(intel_get_function_groups, PINCTRL_INTEL); |
391 | |
392 | static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, |
393 | unsigned int function, unsigned int group) |
394 | { |
395 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
396 | const struct intel_pingroup *grp = &pctrl->soc->groups[group]; |
397 | int i; |
398 | |
399 | guard(raw_spinlock_irqsave)(l: &pctrl->lock); |
400 | |
401 | /* |
402 | * All pins in the groups needs to be accessible and writable |
403 | * before we can enable the mux for this group. |
404 | */ |
405 | for (i = 0; i < grp->grp.npins; i++) { |
406 | if (!intel_pad_usable(pctrl, pin: grp->grp.pins[i])) |
407 | return -EBUSY; |
408 | } |
409 | |
410 | /* Now enable the mux setting for each pin in the group */ |
411 | for (i = 0; i < grp->grp.npins; i++) { |
412 | void __iomem *padcfg0; |
413 | u32 value, pmode; |
414 | |
415 | padcfg0 = intel_get_padcfg(pctrl, pin: grp->grp.pins[i], PADCFG0); |
416 | |
417 | value = readl(addr: padcfg0); |
418 | value &= ~PADCFG0_PMODE_MASK; |
419 | |
420 | if (grp->modes) |
421 | pmode = grp->modes[i]; |
422 | else |
423 | pmode = grp->mode; |
424 | |
425 | value |= pmode << PADCFG0_PMODE_SHIFT; |
426 | writel(val: value, addr: padcfg0); |
427 | } |
428 | |
429 | return 0; |
430 | } |
431 | |
432 | static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input) |
433 | { |
434 | u32 value; |
435 | |
436 | value = readl(addr: padcfg0); |
437 | if (input) { |
438 | value &= ~PADCFG0_GPIORXDIS; |
439 | value |= PADCFG0_GPIOTXDIS; |
440 | } else { |
441 | value &= ~PADCFG0_GPIOTXDIS; |
442 | value |= PADCFG0_GPIORXDIS; |
443 | } |
444 | writel(val: value, addr: padcfg0); |
445 | } |
446 | |
447 | static int __intel_gpio_get_gpio_mode(u32 value) |
448 | { |
449 | return (value & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT; |
450 | } |
451 | |
452 | static int intel_gpio_get_gpio_mode(void __iomem *padcfg0) |
453 | { |
454 | return __intel_gpio_get_gpio_mode(readl(addr: padcfg0)); |
455 | } |
456 | |
457 | static void intel_gpio_set_gpio_mode(void __iomem *padcfg0) |
458 | { |
459 | u32 value; |
460 | |
461 | value = readl(addr: padcfg0); |
462 | |
463 | /* Put the pad into GPIO mode */ |
464 | value &= ~PADCFG0_PMODE_MASK; |
465 | value |= PADCFG0_PMODE_GPIO; |
466 | |
467 | /* Disable TX buffer and enable RX (this will be input) */ |
468 | value &= ~PADCFG0_GPIORXDIS; |
469 | value |= PADCFG0_GPIOTXDIS; |
470 | |
471 | /* Disable SCI/SMI/NMI generation */ |
472 | value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI); |
473 | value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI); |
474 | |
475 | writel(val: value, addr: padcfg0); |
476 | } |
477 | |
478 | static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, |
479 | struct pinctrl_gpio_range *range, |
480 | unsigned int pin) |
481 | { |
482 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
483 | void __iomem *padcfg0; |
484 | |
485 | padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); |
486 | |
487 | guard(raw_spinlock_irqsave)(l: &pctrl->lock); |
488 | |
489 | if (!intel_pad_owned_by_host(pctrl, pin)) |
490 | return -EBUSY; |
491 | |
492 | if (!intel_pad_is_unlocked(pctrl, pin)) |
493 | return 0; |
494 | |
495 | /* |
496 | * If pin is already configured in GPIO mode, we assume that |
497 | * firmware provides correct settings. In such case we avoid |
498 | * potential glitches on the pin. Otherwise, for the pin in |
499 | * alternative mode, consumer has to supply respective flags. |
500 | */ |
501 | if (intel_gpio_get_gpio_mode(padcfg0) == PADCFG0_PMODE_GPIO) |
502 | return 0; |
503 | |
504 | intel_gpio_set_gpio_mode(padcfg0); |
505 | |
506 | return 0; |
507 | } |
508 | |
509 | static int intel_gpio_set_direction(struct pinctrl_dev *pctldev, |
510 | struct pinctrl_gpio_range *range, |
511 | unsigned int pin, bool input) |
512 | { |
513 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
514 | void __iomem *padcfg0; |
515 | |
516 | padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); |
517 | |
518 | guard(raw_spinlock_irqsave)(l: &pctrl->lock); |
519 | |
520 | __intel_gpio_set_direction(padcfg0, input); |
521 | |
522 | return 0; |
523 | } |
524 | |
525 | static const struct pinmux_ops intel_pinmux_ops = { |
526 | .get_functions_count = intel_get_functions_count, |
527 | .get_function_name = intel_get_function_name, |
528 | .get_function_groups = intel_get_function_groups, |
529 | .set_mux = intel_pinmux_set_mux, |
530 | .gpio_request_enable = intel_gpio_request_enable, |
531 | .gpio_set_direction = intel_gpio_set_direction, |
532 | }; |
533 | |
534 | static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin, |
535 | enum pin_config_param param, u32 *arg) |
536 | { |
537 | void __iomem *padcfg1; |
538 | u32 value, term; |
539 | |
540 | padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1); |
541 | |
542 | scoped_guard(raw_spinlock_irqsave, &pctrl->lock) |
543 | value = readl(addr: padcfg1); |
544 | |
545 | term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT; |
546 | |
547 | switch (param) { |
548 | case PIN_CONFIG_BIAS_DISABLE: |
549 | if (term) |
550 | return -EINVAL; |
551 | break; |
552 | |
553 | case PIN_CONFIG_BIAS_PULL_UP: |
554 | if (!term || !(value & PADCFG1_TERM_UP)) |
555 | return -EINVAL; |
556 | |
557 | switch (term) { |
558 | case PADCFG1_TERM_833: |
559 | *arg = 833; |
560 | break; |
561 | case PADCFG1_TERM_1K: |
562 | *arg = 1000; |
563 | break; |
564 | case PADCFG1_TERM_4K: |
565 | *arg = 4000; |
566 | break; |
567 | case PADCFG1_TERM_5K: |
568 | *arg = 5000; |
569 | break; |
570 | case PADCFG1_TERM_20K: |
571 | *arg = 20000; |
572 | break; |
573 | } |
574 | |
575 | break; |
576 | |
577 | case PIN_CONFIG_BIAS_PULL_DOWN: { |
578 | const struct intel_community * = intel_get_community(pctrl, pin); |
579 | |
580 | if (!term || value & PADCFG1_TERM_UP) |
581 | return -EINVAL; |
582 | |
583 | switch (term) { |
584 | case PADCFG1_TERM_833: |
585 | if (!(community->features & PINCTRL_FEATURE_1K_PD)) |
586 | return -EINVAL; |
587 | *arg = 833; |
588 | break; |
589 | case PADCFG1_TERM_1K: |
590 | if (!(community->features & PINCTRL_FEATURE_1K_PD)) |
591 | return -EINVAL; |
592 | *arg = 1000; |
593 | break; |
594 | case PADCFG1_TERM_4K: |
595 | *arg = 4000; |
596 | break; |
597 | case PADCFG1_TERM_5K: |
598 | *arg = 5000; |
599 | break; |
600 | case PADCFG1_TERM_20K: |
601 | *arg = 20000; |
602 | break; |
603 | } |
604 | |
605 | break; |
606 | } |
607 | |
608 | default: |
609 | return -EINVAL; |
610 | } |
611 | |
612 | return 0; |
613 | } |
614 | |
615 | static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int pin, |
616 | enum pin_config_param param, u32 *arg) |
617 | { |
618 | void __iomem *padcfg2; |
619 | unsigned long v; |
620 | u32 value2; |
621 | |
622 | padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2); |
623 | if (!padcfg2) |
624 | return -ENOTSUPP; |
625 | |
626 | scoped_guard(raw_spinlock_irqsave, &pctrl->lock) |
627 | value2 = readl(addr: padcfg2); |
628 | |
629 | if (!(value2 & PADCFG2_DEBEN)) |
630 | return -EINVAL; |
631 | |
632 | v = (value2 & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT; |
633 | *arg = BIT(v) * DEBOUNCE_PERIOD_NSEC / NSEC_PER_USEC; |
634 | |
635 | return 0; |
636 | } |
637 | |
638 | static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, |
639 | unsigned long *config) |
640 | { |
641 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
642 | enum pin_config_param param = pinconf_to_config_param(config: *config); |
643 | u32 arg = 0; |
644 | int ret; |
645 | |
646 | if (!intel_pad_owned_by_host(pctrl, pin)) |
647 | return -ENOTSUPP; |
648 | |
649 | switch (param) { |
650 | case PIN_CONFIG_BIAS_DISABLE: |
651 | case PIN_CONFIG_BIAS_PULL_UP: |
652 | case PIN_CONFIG_BIAS_PULL_DOWN: |
653 | ret = intel_config_get_pull(pctrl, pin, param, arg: &arg); |
654 | if (ret) |
655 | return ret; |
656 | break; |
657 | |
658 | case PIN_CONFIG_INPUT_DEBOUNCE: |
659 | ret = intel_config_get_debounce(pctrl, pin, param, arg: &arg); |
660 | if (ret) |
661 | return ret; |
662 | break; |
663 | |
664 | default: |
665 | return -ENOTSUPP; |
666 | } |
667 | |
668 | *config = pinconf_to_config_packed(param, argument: arg); |
669 | return 0; |
670 | } |
671 | |
672 | static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, |
673 | unsigned long config) |
674 | { |
675 | unsigned int param = pinconf_to_config_param(config); |
676 | unsigned int arg = pinconf_to_config_argument(config); |
677 | u32 term = 0, up = 0, value; |
678 | void __iomem *padcfg1; |
679 | |
680 | switch (param) { |
681 | case PIN_CONFIG_BIAS_DISABLE: |
682 | break; |
683 | |
684 | case PIN_CONFIG_BIAS_PULL_UP: |
685 | switch (arg) { |
686 | case 20000: |
687 | term = PADCFG1_TERM_20K; |
688 | break; |
689 | case 1: /* Set default strength value in case none is given */ |
690 | case 5000: |
691 | term = PADCFG1_TERM_5K; |
692 | break; |
693 | case 4000: |
694 | term = PADCFG1_TERM_4K; |
695 | break; |
696 | case 1000: |
697 | term = PADCFG1_TERM_1K; |
698 | break; |
699 | case 833: |
700 | term = PADCFG1_TERM_833; |
701 | break; |
702 | default: |
703 | return -EINVAL; |
704 | } |
705 | |
706 | up = PADCFG1_TERM_UP; |
707 | break; |
708 | |
709 | case PIN_CONFIG_BIAS_PULL_DOWN: { |
710 | const struct intel_community * = intel_get_community(pctrl, pin); |
711 | |
712 | switch (arg) { |
713 | case 20000: |
714 | term = PADCFG1_TERM_20K; |
715 | break; |
716 | case 1: /* Set default strength value in case none is given */ |
717 | case 5000: |
718 | term = PADCFG1_TERM_5K; |
719 | break; |
720 | case 4000: |
721 | term = PADCFG1_TERM_4K; |
722 | break; |
723 | case 1000: |
724 | if (!(community->features & PINCTRL_FEATURE_1K_PD)) |
725 | return -EINVAL; |
726 | term = PADCFG1_TERM_1K; |
727 | break; |
728 | case 833: |
729 | if (!(community->features & PINCTRL_FEATURE_1K_PD)) |
730 | return -EINVAL; |
731 | term = PADCFG1_TERM_833; |
732 | break; |
733 | default: |
734 | return -EINVAL; |
735 | } |
736 | |
737 | break; |
738 | } |
739 | |
740 | default: |
741 | return -EINVAL; |
742 | } |
743 | |
744 | padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1); |
745 | |
746 | guard(raw_spinlock_irqsave)(l: &pctrl->lock); |
747 | |
748 | value = readl(addr: padcfg1); |
749 | value = (value & ~PADCFG1_TERM_MASK) | (term << PADCFG1_TERM_SHIFT); |
750 | value = (value & ~PADCFG1_TERM_UP) | up; |
751 | writel(val: value, addr: padcfg1); |
752 | |
753 | return 0; |
754 | } |
755 | |
756 | static int intel_config_set_debounce(struct intel_pinctrl *pctrl, |
757 | unsigned int pin, unsigned int debounce) |
758 | { |
759 | void __iomem *padcfg0, *padcfg2; |
760 | u32 value0, value2; |
761 | |
762 | padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2); |
763 | if (!padcfg2) |
764 | return -ENOTSUPP; |
765 | |
766 | padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); |
767 | |
768 | guard(raw_spinlock_irqsave)(l: &pctrl->lock); |
769 | |
770 | value0 = readl(addr: padcfg0); |
771 | value2 = readl(addr: padcfg2); |
772 | |
773 | /* Disable glitch filter and debouncer */ |
774 | value0 &= ~PADCFG0_PREGFRXSEL; |
775 | value2 &= ~(PADCFG2_DEBEN | PADCFG2_DEBOUNCE_MASK); |
776 | |
777 | if (debounce) { |
778 | unsigned long v; |
779 | |
780 | v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC); |
781 | if (v < 3 || v > 15) |
782 | return -EINVAL; |
783 | |
784 | /* Enable glitch filter and debouncer */ |
785 | value0 |= PADCFG0_PREGFRXSEL; |
786 | value2 |= v << PADCFG2_DEBOUNCE_SHIFT; |
787 | value2 |= PADCFG2_DEBEN; |
788 | } |
789 | |
790 | writel(val: value0, addr: padcfg0); |
791 | writel(val: value2, addr: padcfg2); |
792 | |
793 | return 0; |
794 | } |
795 | |
796 | static int intel_config_set(struct pinctrl_dev *pctldev, unsigned int pin, |
797 | unsigned long *configs, unsigned int nconfigs) |
798 | { |
799 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
800 | int i, ret; |
801 | |
802 | if (!intel_pad_usable(pctrl, pin)) |
803 | return -ENOTSUPP; |
804 | |
805 | for (i = 0; i < nconfigs; i++) { |
806 | switch (pinconf_to_config_param(config: configs[i])) { |
807 | case PIN_CONFIG_BIAS_DISABLE: |
808 | case PIN_CONFIG_BIAS_PULL_UP: |
809 | case PIN_CONFIG_BIAS_PULL_DOWN: |
810 | ret = intel_config_set_pull(pctrl, pin, config: configs[i]); |
811 | if (ret) |
812 | return ret; |
813 | break; |
814 | |
815 | case PIN_CONFIG_INPUT_DEBOUNCE: |
816 | ret = intel_config_set_debounce(pctrl, pin, |
817 | debounce: pinconf_to_config_argument(config: configs[i])); |
818 | if (ret) |
819 | return ret; |
820 | break; |
821 | |
822 | default: |
823 | return -ENOTSUPP; |
824 | } |
825 | } |
826 | |
827 | return 0; |
828 | } |
829 | |
830 | static const struct pinconf_ops intel_pinconf_ops = { |
831 | .is_generic = true, |
832 | .pin_config_get = intel_config_get, |
833 | .pin_config_set = intel_config_set, |
834 | }; |
835 | |
836 | static const struct pinctrl_desc intel_pinctrl_desc = { |
837 | .pctlops = &intel_pinctrl_ops, |
838 | .pmxops = &intel_pinmux_ops, |
839 | .confops = &intel_pinconf_ops, |
840 | .owner = THIS_MODULE, |
841 | }; |
842 | |
843 | /** |
844 | * intel_gpio_to_pin() - Translate from GPIO offset to pin number |
845 | * @pctrl: Pinctrl structure |
846 | * @offset: GPIO offset from gpiolib |
847 | * @community: Community is filled here if not %NULL |
848 | * @padgrp: Pad group is filled here if not %NULL |
849 | * |
850 | * When coming through gpiolib irqchip, the GPIO offset is not |
851 | * automatically translated to pinctrl pin number. This function can be |
852 | * used to find out the corresponding pinctrl pin. |
853 | * |
854 | * Return: a pin number and pointers to the community and pad group, which |
855 | * the pin belongs to, or negative error code if translation can't be done. |
856 | */ |
857 | static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset, |
858 | const struct intel_community **, |
859 | const struct intel_padgroup **padgrp) |
860 | { |
861 | int i; |
862 | |
863 | for (i = 0; i < pctrl->ncommunities; i++) { |
864 | const struct intel_community *comm = &pctrl->communities[i]; |
865 | int j; |
866 | |
867 | for (j = 0; j < comm->ngpps; j++) { |
868 | const struct intel_padgroup *pgrp = &comm->gpps[j]; |
869 | |
870 | if (pgrp->gpio_base == INTEL_GPIO_BASE_NOMAP) |
871 | continue; |
872 | |
873 | if (offset >= pgrp->gpio_base && |
874 | offset < pgrp->gpio_base + pgrp->size) { |
875 | int pin; |
876 | |
877 | pin = pgrp->base + offset - pgrp->gpio_base; |
878 | if (community) |
879 | *community = comm; |
880 | if (padgrp) |
881 | *padgrp = pgrp; |
882 | |
883 | return pin; |
884 | } |
885 | } |
886 | } |
887 | |
888 | return -EINVAL; |
889 | } |
890 | |
891 | /** |
892 | * intel_pin_to_gpio() - Translate from pin number to GPIO offset |
893 | * @pctrl: Pinctrl structure |
894 | * @pin: pin number |
895 | * |
896 | * Translate the pin number of pinctrl to GPIO offset |
897 | * |
898 | * Return: a GPIO offset, or negative error code if translation can't be done. |
899 | */ |
900 | static int intel_pin_to_gpio(struct intel_pinctrl *pctrl, int pin) |
901 | { |
902 | const struct intel_community *; |
903 | const struct intel_padgroup *padgrp; |
904 | |
905 | community = intel_get_community(pctrl, pin); |
906 | if (!community) |
907 | return -EINVAL; |
908 | |
909 | padgrp = intel_community_get_padgroup(community, pin); |
910 | if (!padgrp) |
911 | return -EINVAL; |
912 | |
913 | return pin - padgrp->base + padgrp->gpio_base; |
914 | } |
915 | |
916 | static int intel_gpio_get(struct gpio_chip *chip, unsigned int offset) |
917 | { |
918 | struct intel_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
919 | void __iomem *reg; |
920 | u32 padcfg0; |
921 | int pin; |
922 | |
923 | pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL); |
924 | if (pin < 0) |
925 | return -EINVAL; |
926 | |
927 | reg = intel_get_padcfg(pctrl, pin, PADCFG0); |
928 | if (!reg) |
929 | return -EINVAL; |
930 | |
931 | padcfg0 = readl(addr: reg); |
932 | if (!(padcfg0 & PADCFG0_GPIOTXDIS)) |
933 | return !!(padcfg0 & PADCFG0_GPIOTXSTATE); |
934 | |
935 | return !!(padcfg0 & PADCFG0_GPIORXSTATE); |
936 | } |
937 | |
938 | static void intel_gpio_set(struct gpio_chip *chip, unsigned int offset, |
939 | int value) |
940 | { |
941 | struct intel_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
942 | void __iomem *reg; |
943 | u32 padcfg0; |
944 | int pin; |
945 | |
946 | pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL); |
947 | if (pin < 0) |
948 | return; |
949 | |
950 | reg = intel_get_padcfg(pctrl, pin, PADCFG0); |
951 | if (!reg) |
952 | return; |
953 | |
954 | guard(raw_spinlock_irqsave)(l: &pctrl->lock); |
955 | |
956 | padcfg0 = readl(addr: reg); |
957 | if (value) |
958 | padcfg0 |= PADCFG0_GPIOTXSTATE; |
959 | else |
960 | padcfg0 &= ~PADCFG0_GPIOTXSTATE; |
961 | writel(val: padcfg0, addr: reg); |
962 | } |
963 | |
964 | static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) |
965 | { |
966 | struct intel_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
967 | void __iomem *reg; |
968 | u32 padcfg0; |
969 | int pin; |
970 | |
971 | pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL); |
972 | if (pin < 0) |
973 | return -EINVAL; |
974 | |
975 | reg = intel_get_padcfg(pctrl, pin, PADCFG0); |
976 | if (!reg) |
977 | return -EINVAL; |
978 | |
979 | scoped_guard(raw_spinlock_irqsave, &pctrl->lock) |
980 | padcfg0 = readl(addr: reg); |
981 | |
982 | if (padcfg0 & PADCFG0_PMODE_MASK) |
983 | return -EINVAL; |
984 | |
985 | if (padcfg0 & PADCFG0_GPIOTXDIS) |
986 | return GPIO_LINE_DIRECTION_IN; |
987 | |
988 | return GPIO_LINE_DIRECTION_OUT; |
989 | } |
990 | |
991 | static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) |
992 | { |
993 | return pinctrl_gpio_direction_input(gc: chip, offset); |
994 | } |
995 | |
996 | static int intel_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, |
997 | int value) |
998 | { |
999 | intel_gpio_set(chip, offset, value); |
1000 | return pinctrl_gpio_direction_output(gc: chip, offset); |
1001 | } |
1002 | |
1003 | static const struct gpio_chip intel_gpio_chip = { |
1004 | .owner = THIS_MODULE, |
1005 | .request = gpiochip_generic_request, |
1006 | .free = gpiochip_generic_free, |
1007 | .get_direction = intel_gpio_get_direction, |
1008 | .direction_input = intel_gpio_direction_input, |
1009 | .direction_output = intel_gpio_direction_output, |
1010 | .get = intel_gpio_get, |
1011 | .set = intel_gpio_set, |
1012 | .set_config = gpiochip_generic_config, |
1013 | }; |
1014 | |
1015 | static void intel_gpio_irq_ack(struct irq_data *d) |
1016 | { |
1017 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
1018 | struct intel_pinctrl *pctrl = gpiochip_get_data(gc); |
1019 | const struct intel_community *; |
1020 | const struct intel_padgroup *padgrp; |
1021 | int pin; |
1022 | |
1023 | pin = intel_gpio_to_pin(pctrl, offset: irqd_to_hwirq(d), community: &community, padgrp: &padgrp); |
1024 | if (pin >= 0) { |
1025 | unsigned int gpp, gpp_offset; |
1026 | void __iomem *is; |
1027 | |
1028 | gpp = padgrp->reg_num; |
1029 | gpp_offset = padgroup_offset(padgrp, pin); |
1030 | |
1031 | is = community->regs + community->is_offset + gpp * 4; |
1032 | |
1033 | guard(raw_spinlock)(l: &pctrl->lock); |
1034 | |
1035 | writel(BIT(gpp_offset), addr: is); |
1036 | } |
1037 | } |
1038 | |
1039 | static void intel_gpio_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t hwirq, bool mask) |
1040 | { |
1041 | struct intel_pinctrl *pctrl = gpiochip_get_data(gc); |
1042 | const struct intel_community *; |
1043 | const struct intel_padgroup *padgrp; |
1044 | int pin; |
1045 | |
1046 | pin = intel_gpio_to_pin(pctrl, offset: hwirq, community: &community, padgrp: &padgrp); |
1047 | if (pin >= 0) { |
1048 | unsigned int gpp, gpp_offset; |
1049 | void __iomem *reg, *is; |
1050 | u32 value; |
1051 | |
1052 | gpp = padgrp->reg_num; |
1053 | gpp_offset = padgroup_offset(padgrp, pin); |
1054 | |
1055 | reg = community->regs + community->ie_offset + gpp * 4; |
1056 | is = community->regs + community->is_offset + gpp * 4; |
1057 | |
1058 | guard(raw_spinlock_irqsave)(l: &pctrl->lock); |
1059 | |
1060 | /* Clear interrupt status first to avoid unexpected interrupt */ |
1061 | writel(BIT(gpp_offset), addr: is); |
1062 | |
1063 | value = readl(addr: reg); |
1064 | if (mask) |
1065 | value &= ~BIT(gpp_offset); |
1066 | else |
1067 | value |= BIT(gpp_offset); |
1068 | writel(val: value, addr: reg); |
1069 | } |
1070 | } |
1071 | |
1072 | static void intel_gpio_irq_mask(struct irq_data *d) |
1073 | { |
1074 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
1075 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
1076 | |
1077 | intel_gpio_irq_mask_unmask(gc, hwirq, mask: true); |
1078 | gpiochip_disable_irq(gc, offset: hwirq); |
1079 | } |
1080 | |
1081 | static void intel_gpio_irq_unmask(struct irq_data *d) |
1082 | { |
1083 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
1084 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
1085 | |
1086 | gpiochip_enable_irq(gc, offset: hwirq); |
1087 | intel_gpio_irq_mask_unmask(gc, hwirq, mask: false); |
1088 | } |
1089 | |
1090 | static int intel_gpio_irq_type(struct irq_data *d, unsigned int type) |
1091 | { |
1092 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
1093 | struct intel_pinctrl *pctrl = gpiochip_get_data(gc); |
1094 | unsigned int pin = intel_gpio_to_pin(pctrl, offset: irqd_to_hwirq(d), NULL, NULL); |
1095 | u32 rxevcfg, rxinv, value; |
1096 | void __iomem *reg; |
1097 | |
1098 | reg = intel_get_padcfg(pctrl, pin, PADCFG0); |
1099 | if (!reg) |
1100 | return -EINVAL; |
1101 | |
1102 | /* |
1103 | * If the pin is in ACPI mode it is still usable as a GPIO but it |
1104 | * cannot be used as IRQ because GPI_IS status bit will not be |
1105 | * updated by the host controller hardware. |
1106 | */ |
1107 | if (intel_pad_acpi_mode(pctrl, pin)) { |
1108 | dev_warn(pctrl->dev, "pin %u cannot be used as IRQ\n" , pin); |
1109 | return -EPERM; |
1110 | } |
1111 | |
1112 | if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { |
1113 | rxevcfg = PADCFG0_RXEVCFG_EDGE_BOTH; |
1114 | } else if (type & IRQ_TYPE_EDGE_FALLING) { |
1115 | rxevcfg = PADCFG0_RXEVCFG_EDGE; |
1116 | } else if (type & IRQ_TYPE_EDGE_RISING) { |
1117 | rxevcfg = PADCFG0_RXEVCFG_EDGE; |
1118 | } else if (type & IRQ_TYPE_LEVEL_MASK) { |
1119 | rxevcfg = PADCFG0_RXEVCFG_LEVEL; |
1120 | } else { |
1121 | rxevcfg = PADCFG0_RXEVCFG_DISABLED; |
1122 | } |
1123 | |
1124 | if (type == IRQ_TYPE_EDGE_FALLING || type == IRQ_TYPE_LEVEL_LOW) |
1125 | rxinv = PADCFG0_RXINV; |
1126 | else |
1127 | rxinv = 0; |
1128 | |
1129 | guard(raw_spinlock_irqsave)(l: &pctrl->lock); |
1130 | |
1131 | intel_gpio_set_gpio_mode(padcfg0: reg); |
1132 | |
1133 | value = readl(addr: reg); |
1134 | |
1135 | value = (value & ~PADCFG0_RXEVCFG_MASK) | rxevcfg; |
1136 | value = (value & ~PADCFG0_RXINV) | rxinv; |
1137 | |
1138 | writel(val: value, addr: reg); |
1139 | |
1140 | if (type & IRQ_TYPE_EDGE_BOTH) |
1141 | irq_set_handler_locked(data: d, handler: handle_edge_irq); |
1142 | else if (type & IRQ_TYPE_LEVEL_MASK) |
1143 | irq_set_handler_locked(data: d, handler: handle_level_irq); |
1144 | |
1145 | return 0; |
1146 | } |
1147 | |
1148 | static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on) |
1149 | { |
1150 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
1151 | struct intel_pinctrl *pctrl = gpiochip_get_data(gc); |
1152 | unsigned int pin = intel_gpio_to_pin(pctrl, offset: irqd_to_hwirq(d), NULL, NULL); |
1153 | |
1154 | if (on) |
1155 | enable_irq_wake(irq: pctrl->irq); |
1156 | else |
1157 | disable_irq_wake(irq: pctrl->irq); |
1158 | |
1159 | dev_dbg(pctrl->dev, "%s wake for pin %u\n" , str_enable_disable(on), pin); |
1160 | return 0; |
1161 | } |
1162 | |
1163 | static const struct irq_chip intel_gpio_irq_chip = { |
1164 | .name = "intel-gpio" , |
1165 | .irq_ack = intel_gpio_irq_ack, |
1166 | .irq_mask = intel_gpio_irq_mask, |
1167 | .irq_unmask = intel_gpio_irq_unmask, |
1168 | .irq_set_type = intel_gpio_irq_type, |
1169 | .irq_set_wake = intel_gpio_irq_wake, |
1170 | .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE, |
1171 | GPIOCHIP_IRQ_RESOURCE_HELPERS, |
1172 | }; |
1173 | |
1174 | static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, |
1175 | const struct intel_community *) |
1176 | { |
1177 | struct gpio_chip *gc = &pctrl->chip; |
1178 | unsigned int gpp; |
1179 | int ret = 0; |
1180 | |
1181 | for (gpp = 0; gpp < community->ngpps; gpp++) { |
1182 | const struct intel_padgroup *padgrp = &community->gpps[gpp]; |
1183 | unsigned long pending, enabled; |
1184 | unsigned int gpp, gpp_offset; |
1185 | void __iomem *reg, *is; |
1186 | |
1187 | gpp = padgrp->reg_num; |
1188 | |
1189 | reg = community->regs + community->ie_offset + gpp * 4; |
1190 | is = community->regs + community->is_offset + gpp * 4; |
1191 | |
1192 | scoped_guard(raw_spinlock, &pctrl->lock) { |
1193 | pending = readl(addr: is); |
1194 | enabled = readl(addr: reg); |
1195 | } |
1196 | |
1197 | /* Only interrupts that are enabled */ |
1198 | pending &= enabled; |
1199 | |
1200 | for_each_set_bit(gpp_offset, &pending, padgrp->size) |
1201 | generic_handle_domain_irq(domain: gc->irq.domain, hwirq: padgrp->gpio_base + gpp_offset); |
1202 | |
1203 | ret += pending ? 1 : 0; |
1204 | } |
1205 | |
1206 | return ret; |
1207 | } |
1208 | |
1209 | static irqreturn_t intel_gpio_irq(int irq, void *data) |
1210 | { |
1211 | const struct intel_community *; |
1212 | struct intel_pinctrl *pctrl = data; |
1213 | unsigned int i; |
1214 | int ret = 0; |
1215 | |
1216 | /* Need to check all communities for pending interrupts */ |
1217 | for (i = 0; i < pctrl->ncommunities; i++) { |
1218 | community = &pctrl->communities[i]; |
1219 | ret += intel_gpio_community_irq_handler(pctrl, community); |
1220 | } |
1221 | |
1222 | return IRQ_RETVAL(ret); |
1223 | } |
1224 | |
1225 | static void intel_gpio_irq_init(struct intel_pinctrl *pctrl) |
1226 | { |
1227 | int i; |
1228 | |
1229 | for (i = 0; i < pctrl->ncommunities; i++) { |
1230 | const struct intel_community *; |
1231 | void __iomem *reg, *is; |
1232 | unsigned int gpp; |
1233 | |
1234 | community = &pctrl->communities[i]; |
1235 | |
1236 | for (gpp = 0; gpp < community->ngpps; gpp++) { |
1237 | reg = community->regs + community->ie_offset + gpp * 4; |
1238 | is = community->regs + community->is_offset + gpp * 4; |
1239 | |
1240 | /* Mask and clear all interrupts */ |
1241 | writel(val: 0, addr: reg); |
1242 | writel(val: 0xffff, addr: is); |
1243 | } |
1244 | } |
1245 | } |
1246 | |
1247 | static int intel_gpio_irq_init_hw(struct gpio_chip *gc) |
1248 | { |
1249 | struct intel_pinctrl *pctrl = gpiochip_get_data(gc); |
1250 | |
1251 | /* |
1252 | * Make sure the interrupt lines are in a proper state before |
1253 | * further configuration. |
1254 | */ |
1255 | intel_gpio_irq_init(pctrl); |
1256 | |
1257 | return 0; |
1258 | } |
1259 | |
1260 | static int (struct intel_pinctrl *pctrl, |
1261 | const struct intel_community *) |
1262 | { |
1263 | int ret = 0, i; |
1264 | |
1265 | for (i = 0; i < community->ngpps; i++) { |
1266 | const struct intel_padgroup *gpp = &community->gpps[i]; |
1267 | |
1268 | if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP) |
1269 | continue; |
1270 | |
1271 | ret = gpiochip_add_pin_range(gc: &pctrl->chip, pinctl_name: dev_name(dev: pctrl->dev), |
1272 | gpio_offset: gpp->gpio_base, pin_offset: gpp->base, |
1273 | npins: gpp->size); |
1274 | if (ret) |
1275 | return ret; |
1276 | } |
1277 | |
1278 | return ret; |
1279 | } |
1280 | |
1281 | static int intel_gpio_add_pin_ranges(struct gpio_chip *gc) |
1282 | { |
1283 | struct intel_pinctrl *pctrl = gpiochip_get_data(gc); |
1284 | int ret, i; |
1285 | |
1286 | for (i = 0; i < pctrl->ncommunities; i++) { |
1287 | struct intel_community * = &pctrl->communities[i]; |
1288 | |
1289 | ret = intel_gpio_add_community_ranges(pctrl, community); |
1290 | if (ret) { |
1291 | dev_err(pctrl->dev, "failed to add GPIO pin range\n" ); |
1292 | return ret; |
1293 | } |
1294 | } |
1295 | |
1296 | return 0; |
1297 | } |
1298 | |
1299 | static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl) |
1300 | { |
1301 | const struct intel_community *; |
1302 | unsigned int ngpio = 0; |
1303 | int i, j; |
1304 | |
1305 | for (i = 0; i < pctrl->ncommunities; i++) { |
1306 | community = &pctrl->communities[i]; |
1307 | for (j = 0; j < community->ngpps; j++) { |
1308 | const struct intel_padgroup *gpp = &community->gpps[j]; |
1309 | |
1310 | if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP) |
1311 | continue; |
1312 | |
1313 | if (gpp->gpio_base + gpp->size > ngpio) |
1314 | ngpio = gpp->gpio_base + gpp->size; |
1315 | } |
1316 | } |
1317 | |
1318 | return ngpio; |
1319 | } |
1320 | |
1321 | static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) |
1322 | { |
1323 | int ret; |
1324 | struct gpio_irq_chip *girq; |
1325 | |
1326 | pctrl->chip = intel_gpio_chip; |
1327 | |
1328 | /* Setup GPIO chip */ |
1329 | pctrl->chip.ngpio = intel_gpio_ngpio(pctrl); |
1330 | pctrl->chip.label = dev_name(dev: pctrl->dev); |
1331 | pctrl->chip.parent = pctrl->dev; |
1332 | pctrl->chip.base = -1; |
1333 | pctrl->chip.add_pin_ranges = intel_gpio_add_pin_ranges; |
1334 | pctrl->irq = irq; |
1335 | |
1336 | /* |
1337 | * On some platforms several GPIO controllers share the same interrupt |
1338 | * line. |
1339 | */ |
1340 | ret = devm_request_irq(dev: pctrl->dev, irq, handler: intel_gpio_irq, |
1341 | IRQF_SHARED | IRQF_NO_THREAD, |
1342 | devname: dev_name(dev: pctrl->dev), dev_id: pctrl); |
1343 | if (ret) { |
1344 | dev_err(pctrl->dev, "failed to request interrupt\n" ); |
1345 | return ret; |
1346 | } |
1347 | |
1348 | /* Setup IRQ chip */ |
1349 | girq = &pctrl->chip.irq; |
1350 | gpio_irq_chip_set_chip(girq, chip: &intel_gpio_irq_chip); |
1351 | /* This will let us handle the IRQ in the driver */ |
1352 | girq->parent_handler = NULL; |
1353 | girq->num_parents = 0; |
1354 | girq->default_type = IRQ_TYPE_NONE; |
1355 | girq->handler = handle_bad_irq; |
1356 | girq->init_hw = intel_gpio_irq_init_hw; |
1357 | |
1358 | ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl); |
1359 | if (ret) { |
1360 | dev_err(pctrl->dev, "failed to register gpiochip\n" ); |
1361 | return ret; |
1362 | } |
1363 | |
1364 | return 0; |
1365 | } |
1366 | |
1367 | static int intel_pinctrl_add_padgroups_by_gpps(struct intel_pinctrl *pctrl, |
1368 | struct intel_community *) |
1369 | { |
1370 | struct intel_padgroup *gpps; |
1371 | unsigned int padown_num = 0; |
1372 | size_t i, ngpps = community->ngpps; |
1373 | |
1374 | gpps = devm_kcalloc(dev: pctrl->dev, n: ngpps, size: sizeof(*gpps), GFP_KERNEL); |
1375 | if (!gpps) |
1376 | return -ENOMEM; |
1377 | |
1378 | for (i = 0; i < ngpps; i++) { |
1379 | gpps[i] = community->gpps[i]; |
1380 | |
1381 | if (gpps[i].size > INTEL_PINCTRL_MAX_GPP_SIZE) |
1382 | return -EINVAL; |
1383 | |
1384 | /* Special treatment for GPIO base */ |
1385 | switch (gpps[i].gpio_base) { |
1386 | case INTEL_GPIO_BASE_MATCH: |
1387 | gpps[i].gpio_base = gpps[i].base; |
1388 | break; |
1389 | case INTEL_GPIO_BASE_ZERO: |
1390 | gpps[i].gpio_base = 0; |
1391 | break; |
1392 | case INTEL_GPIO_BASE_NOMAP: |
1393 | break; |
1394 | default: |
1395 | break; |
1396 | } |
1397 | |
1398 | gpps[i].padown_num = padown_num; |
1399 | padown_num += DIV_ROUND_UP(gpps[i].size * 4, INTEL_PINCTRL_MAX_GPP_SIZE); |
1400 | } |
1401 | |
1402 | community->gpps = gpps; |
1403 | |
1404 | return 0; |
1405 | } |
1406 | |
1407 | static int intel_pinctrl_add_padgroups_by_size(struct intel_pinctrl *pctrl, |
1408 | struct intel_community *) |
1409 | { |
1410 | struct intel_padgroup *gpps; |
1411 | unsigned int npins = community->npins; |
1412 | unsigned int padown_num = 0; |
1413 | size_t i, ngpps = DIV_ROUND_UP(npins, community->gpp_size); |
1414 | |
1415 | if (community->gpp_size > INTEL_PINCTRL_MAX_GPP_SIZE) |
1416 | return -EINVAL; |
1417 | |
1418 | gpps = devm_kcalloc(dev: pctrl->dev, n: ngpps, size: sizeof(*gpps), GFP_KERNEL); |
1419 | if (!gpps) |
1420 | return -ENOMEM; |
1421 | |
1422 | for (i = 0; i < ngpps; i++) { |
1423 | unsigned int gpp_size = community->gpp_size; |
1424 | |
1425 | gpps[i].reg_num = i; |
1426 | gpps[i].base = community->pin_base + i * gpp_size; |
1427 | gpps[i].size = min(gpp_size, npins); |
1428 | npins -= gpps[i].size; |
1429 | |
1430 | gpps[i].gpio_base = gpps[i].base; |
1431 | gpps[i].padown_num = padown_num; |
1432 | |
1433 | padown_num += community->gpp_num_padown_regs; |
1434 | } |
1435 | |
1436 | community->ngpps = ngpps; |
1437 | community->gpps = gpps; |
1438 | |
1439 | return 0; |
1440 | } |
1441 | |
1442 | static int intel_pinctrl_pm_init(struct intel_pinctrl *pctrl) |
1443 | { |
1444 | #ifdef CONFIG_PM_SLEEP |
1445 | const struct intel_pinctrl_soc_data *soc = pctrl->soc; |
1446 | struct intel_community_context *communities; |
1447 | struct intel_pad_context *pads; |
1448 | int i; |
1449 | |
1450 | pads = devm_kcalloc(dev: pctrl->dev, n: soc->npins, size: sizeof(*pads), GFP_KERNEL); |
1451 | if (!pads) |
1452 | return -ENOMEM; |
1453 | |
1454 | communities = devm_kcalloc(dev: pctrl->dev, n: pctrl->ncommunities, |
1455 | size: sizeof(*communities), GFP_KERNEL); |
1456 | if (!communities) |
1457 | return -ENOMEM; |
1458 | |
1459 | |
1460 | for (i = 0; i < pctrl->ncommunities; i++) { |
1461 | struct intel_community * = &pctrl->communities[i]; |
1462 | u32 *intmask, *hostown; |
1463 | |
1464 | intmask = devm_kcalloc(dev: pctrl->dev, n: community->ngpps, |
1465 | size: sizeof(*intmask), GFP_KERNEL); |
1466 | if (!intmask) |
1467 | return -ENOMEM; |
1468 | |
1469 | communities[i].intmask = intmask; |
1470 | |
1471 | hostown = devm_kcalloc(dev: pctrl->dev, n: community->ngpps, |
1472 | size: sizeof(*hostown), GFP_KERNEL); |
1473 | if (!hostown) |
1474 | return -ENOMEM; |
1475 | |
1476 | communities[i].hostown = hostown; |
1477 | } |
1478 | |
1479 | pctrl->context.pads = pads; |
1480 | pctrl->context.communities = communities; |
1481 | #endif |
1482 | |
1483 | return 0; |
1484 | } |
1485 | |
1486 | static int intel_pinctrl_probe_pwm(struct intel_pinctrl *pctrl, |
1487 | struct intel_community *) |
1488 | { |
1489 | static const struct pwm_lpss_boardinfo info = { |
1490 | .clk_rate = 19200000, |
1491 | .npwm = 1, |
1492 | .base_unit_bits = 22, |
1493 | .bypass = true, |
1494 | }; |
1495 | struct pwm_chip *chip; |
1496 | |
1497 | if (!(community->features & PINCTRL_FEATURE_PWM)) |
1498 | return 0; |
1499 | |
1500 | if (!IS_REACHABLE(CONFIG_PWM_LPSS)) |
1501 | return 0; |
1502 | |
1503 | chip = devm_pwm_lpss_probe(dev: pctrl->dev, base: community->regs + PWMC, info: &info); |
1504 | return PTR_ERR_OR_ZERO(ptr: chip); |
1505 | } |
1506 | |
1507 | int intel_pinctrl_probe(struct platform_device *pdev, |
1508 | const struct intel_pinctrl_soc_data *soc_data) |
1509 | { |
1510 | struct device *dev = &pdev->dev; |
1511 | struct intel_pinctrl *pctrl; |
1512 | int i, ret, irq; |
1513 | |
1514 | pctrl = devm_kzalloc(dev, size: sizeof(*pctrl), GFP_KERNEL); |
1515 | if (!pctrl) |
1516 | return -ENOMEM; |
1517 | |
1518 | pctrl->dev = dev; |
1519 | pctrl->soc = soc_data; |
1520 | raw_spin_lock_init(&pctrl->lock); |
1521 | |
1522 | /* |
1523 | * Make a copy of the communities which we can use to hold pointers |
1524 | * to the registers. |
1525 | */ |
1526 | pctrl->ncommunities = pctrl->soc->ncommunities; |
1527 | pctrl->communities = devm_kcalloc(dev, n: pctrl->ncommunities, |
1528 | size: sizeof(*pctrl->communities), GFP_KERNEL); |
1529 | if (!pctrl->communities) |
1530 | return -ENOMEM; |
1531 | |
1532 | for (i = 0; i < pctrl->ncommunities; i++) { |
1533 | struct intel_community * = &pctrl->communities[i]; |
1534 | void __iomem *regs; |
1535 | u32 offset; |
1536 | u32 value; |
1537 | |
1538 | *community = pctrl->soc->communities[i]; |
1539 | |
1540 | regs = devm_platform_ioremap_resource(pdev, index: community->barno); |
1541 | if (IS_ERR(ptr: regs)) |
1542 | return PTR_ERR(ptr: regs); |
1543 | |
1544 | /* |
1545 | * Determine community features based on the revision. |
1546 | * A value of all ones means the device is not present. |
1547 | */ |
1548 | value = readl(addr: regs + REVID); |
1549 | if (value == ~0u) |
1550 | return -ENODEV; |
1551 | if (((value & REVID_MASK) >> REVID_SHIFT) >= 0x94) { |
1552 | community->features |= PINCTRL_FEATURE_DEBOUNCE; |
1553 | community->features |= PINCTRL_FEATURE_1K_PD; |
1554 | } |
1555 | |
1556 | /* Determine community features based on the capabilities */ |
1557 | offset = CAPLIST; |
1558 | do { |
1559 | value = readl(addr: regs + offset); |
1560 | switch ((value & CAPLIST_ID_MASK) >> CAPLIST_ID_SHIFT) { |
1561 | case CAPLIST_ID_GPIO_HW_INFO: |
1562 | community->features |= PINCTRL_FEATURE_GPIO_HW_INFO; |
1563 | break; |
1564 | case CAPLIST_ID_PWM: |
1565 | community->features |= PINCTRL_FEATURE_PWM; |
1566 | break; |
1567 | case CAPLIST_ID_BLINK: |
1568 | community->features |= PINCTRL_FEATURE_BLINK; |
1569 | break; |
1570 | case CAPLIST_ID_EXP: |
1571 | community->features |= PINCTRL_FEATURE_EXP; |
1572 | break; |
1573 | default: |
1574 | break; |
1575 | } |
1576 | offset = (value & CAPLIST_NEXT_MASK) >> CAPLIST_NEXT_SHIFT; |
1577 | } while (offset); |
1578 | |
1579 | dev_dbg(dev, "Community%d features: %#08x\n" , i, community->features); |
1580 | |
1581 | /* Read offset of the pad configuration registers */ |
1582 | offset = readl(addr: regs + PADBAR); |
1583 | |
1584 | community->regs = regs; |
1585 | community->pad_regs = regs + offset; |
1586 | |
1587 | if (community->gpps) |
1588 | ret = intel_pinctrl_add_padgroups_by_gpps(pctrl, community); |
1589 | else |
1590 | ret = intel_pinctrl_add_padgroups_by_size(pctrl, community); |
1591 | if (ret) |
1592 | return ret; |
1593 | |
1594 | ret = intel_pinctrl_probe_pwm(pctrl, community); |
1595 | if (ret) |
1596 | return ret; |
1597 | } |
1598 | |
1599 | irq = platform_get_irq(pdev, 0); |
1600 | if (irq < 0) |
1601 | return irq; |
1602 | |
1603 | ret = intel_pinctrl_pm_init(pctrl); |
1604 | if (ret) |
1605 | return ret; |
1606 | |
1607 | pctrl->pctldesc = intel_pinctrl_desc; |
1608 | pctrl->pctldesc.name = dev_name(dev); |
1609 | pctrl->pctldesc.pins = pctrl->soc->pins; |
1610 | pctrl->pctldesc.npins = pctrl->soc->npins; |
1611 | |
1612 | pctrl->pctldev = devm_pinctrl_register(dev, pctldesc: &pctrl->pctldesc, driver_data: pctrl); |
1613 | if (IS_ERR(ptr: pctrl->pctldev)) { |
1614 | dev_err(dev, "failed to register pinctrl driver\n" ); |
1615 | return PTR_ERR(ptr: pctrl->pctldev); |
1616 | } |
1617 | |
1618 | ret = intel_gpio_probe(pctrl, irq); |
1619 | if (ret) |
1620 | return ret; |
1621 | |
1622 | platform_set_drvdata(pdev, data: pctrl); |
1623 | |
1624 | return 0; |
1625 | } |
1626 | EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe, PINCTRL_INTEL); |
1627 | |
1628 | int intel_pinctrl_probe_by_hid(struct platform_device *pdev) |
1629 | { |
1630 | const struct intel_pinctrl_soc_data *data; |
1631 | |
1632 | data = device_get_match_data(dev: &pdev->dev); |
1633 | if (!data) |
1634 | return -ENODATA; |
1635 | |
1636 | return intel_pinctrl_probe(pdev, data); |
1637 | } |
1638 | EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe_by_hid, PINCTRL_INTEL); |
1639 | |
1640 | int intel_pinctrl_probe_by_uid(struct platform_device *pdev) |
1641 | { |
1642 | const struct intel_pinctrl_soc_data *data; |
1643 | |
1644 | data = intel_pinctrl_get_soc_data(pdev); |
1645 | if (IS_ERR(ptr: data)) |
1646 | return PTR_ERR(ptr: data); |
1647 | |
1648 | return intel_pinctrl_probe(pdev, data); |
1649 | } |
1650 | EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe_by_uid, PINCTRL_INTEL); |
1651 | |
1652 | const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_device *pdev) |
1653 | { |
1654 | const struct intel_pinctrl_soc_data * const *table; |
1655 | const struct intel_pinctrl_soc_data *data; |
1656 | struct device *dev = &pdev->dev; |
1657 | |
1658 | table = device_get_match_data(dev); |
1659 | if (table) { |
1660 | struct acpi_device *adev = ACPI_COMPANION(dev); |
1661 | unsigned int i; |
1662 | |
1663 | for (i = 0; table[i]; i++) { |
1664 | if (acpi_dev_uid_match(adev, table[i]->uid)) |
1665 | break; |
1666 | } |
1667 | data = table[i]; |
1668 | } else { |
1669 | const struct platform_device_id *id; |
1670 | |
1671 | id = platform_get_device_id(pdev); |
1672 | if (!id) |
1673 | return ERR_PTR(error: -ENODEV); |
1674 | |
1675 | table = (const struct intel_pinctrl_soc_data * const *)id->driver_data; |
1676 | data = table[pdev->id]; |
1677 | } |
1678 | |
1679 | return data ?: ERR_PTR(error: -ENODATA); |
1680 | } |
1681 | EXPORT_SYMBOL_NS_GPL(intel_pinctrl_get_soc_data, PINCTRL_INTEL); |
1682 | |
1683 | static bool __intel_gpio_is_direct_irq(u32 value) |
1684 | { |
1685 | return (value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) && |
1686 | (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO); |
1687 | } |
1688 | |
1689 | static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin) |
1690 | { |
1691 | const struct pin_desc *pd = pin_desc_get(pctldev: pctrl->pctldev, pin); |
1692 | u32 value; |
1693 | |
1694 | if (!pd || !intel_pad_usable(pctrl, pin)) |
1695 | return false; |
1696 | |
1697 | /* |
1698 | * Only restore the pin if it is actually in use by the kernel (or |
1699 | * by userspace). It is possible that some pins are used by the |
1700 | * BIOS during resume and those are not always locked down so leave |
1701 | * them alone. |
1702 | */ |
1703 | if (pd->mux_owner || pd->gpio_owner || |
1704 | gpiochip_line_is_irq(gc: &pctrl->chip, offset: intel_pin_to_gpio(pctrl, pin))) |
1705 | return true; |
1706 | |
1707 | /* |
1708 | * The firmware on some systems may configure GPIO pins to be |
1709 | * an interrupt source in so called "direct IRQ" mode. In such |
1710 | * cases the GPIO controller driver has no idea if those pins |
1711 | * are being used or not. At the same time, there is a known bug |
1712 | * in the firmwares that don't restore the pin settings correctly |
1713 | * after suspend, i.e. by an unknown reason the Rx value becomes |
1714 | * inverted. |
1715 | * |
1716 | * Hence, let's save and restore the pins that are configured |
1717 | * as GPIOs in the input mode with GPIROUTIOXAPIC bit set. |
1718 | * |
1719 | * See https://bugzilla.kernel.org/show_bug.cgi?id=214749. |
1720 | */ |
1721 | value = readl(addr: intel_get_padcfg(pctrl, pin, PADCFG0)); |
1722 | if (__intel_gpio_is_direct_irq(value)) |
1723 | return true; |
1724 | |
1725 | return false; |
1726 | } |
1727 | |
1728 | static int intel_pinctrl_suspend_noirq(struct device *dev) |
1729 | { |
1730 | struct intel_pinctrl *pctrl = dev_get_drvdata(dev); |
1731 | struct intel_community_context *communities; |
1732 | struct intel_pad_context *pads; |
1733 | int i; |
1734 | |
1735 | pads = pctrl->context.pads; |
1736 | for (i = 0; i < pctrl->soc->npins; i++) { |
1737 | const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i]; |
1738 | void __iomem *padcfg; |
1739 | u32 val; |
1740 | |
1741 | if (!intel_pinctrl_should_save(pctrl, pin: desc->number)) |
1742 | continue; |
1743 | |
1744 | val = readl(addr: intel_get_padcfg(pctrl, pin: desc->number, PADCFG0)); |
1745 | pads[i].padcfg0 = val & ~PADCFG0_GPIORXSTATE; |
1746 | val = readl(addr: intel_get_padcfg(pctrl, pin: desc->number, PADCFG1)); |
1747 | pads[i].padcfg1 = val; |
1748 | |
1749 | padcfg = intel_get_padcfg(pctrl, pin: desc->number, PADCFG2); |
1750 | if (padcfg) |
1751 | pads[i].padcfg2 = readl(addr: padcfg); |
1752 | } |
1753 | |
1754 | communities = pctrl->context.communities; |
1755 | for (i = 0; i < pctrl->ncommunities; i++) { |
1756 | struct intel_community * = &pctrl->communities[i]; |
1757 | void __iomem *base; |
1758 | unsigned int gpp; |
1759 | |
1760 | base = community->regs + community->ie_offset; |
1761 | for (gpp = 0; gpp < community->ngpps; gpp++) |
1762 | communities[i].intmask[gpp] = readl(addr: base + gpp * 4); |
1763 | |
1764 | base = community->regs + community->hostown_offset; |
1765 | for (gpp = 0; gpp < community->ngpps; gpp++) |
1766 | communities[i].hostown[gpp] = readl(addr: base + gpp * 4); |
1767 | } |
1768 | |
1769 | return 0; |
1770 | } |
1771 | |
1772 | static bool intel_gpio_update_reg(void __iomem *reg, u32 mask, u32 value) |
1773 | { |
1774 | u32 curr, updated; |
1775 | |
1776 | curr = readl(addr: reg); |
1777 | |
1778 | updated = (curr & ~mask) | (value & mask); |
1779 | if (curr == updated) |
1780 | return false; |
1781 | |
1782 | writel(val: updated, addr: reg); |
1783 | return true; |
1784 | } |
1785 | |
1786 | static void intel_restore_hostown(struct intel_pinctrl *pctrl, unsigned int c, |
1787 | void __iomem *base, unsigned int gpp, u32 saved) |
1788 | { |
1789 | const struct intel_community * = &pctrl->communities[c]; |
1790 | const struct intel_padgroup *padgrp = &community->gpps[gpp]; |
1791 | struct device *dev = pctrl->dev; |
1792 | const char *dummy; |
1793 | u32 requested = 0; |
1794 | unsigned int i; |
1795 | |
1796 | if (padgrp->gpio_base == INTEL_GPIO_BASE_NOMAP) |
1797 | return; |
1798 | |
1799 | for_each_requested_gpio_in_range(&pctrl->chip, i, padgrp->gpio_base, padgrp->size, dummy) |
1800 | requested |= BIT(i); |
1801 | |
1802 | if (!intel_gpio_update_reg(reg: base + gpp * 4, mask: requested, value: saved)) |
1803 | return; |
1804 | |
1805 | dev_dbg(dev, "restored hostown %u/%u %#08x\n" , c, gpp, readl(base + gpp * 4)); |
1806 | } |
1807 | |
1808 | static void intel_restore_intmask(struct intel_pinctrl *pctrl, unsigned int c, |
1809 | void __iomem *base, unsigned int gpp, u32 saved) |
1810 | { |
1811 | struct device *dev = pctrl->dev; |
1812 | |
1813 | if (!intel_gpio_update_reg(reg: base + gpp * 4, mask: ~0U, value: saved)) |
1814 | return; |
1815 | |
1816 | dev_dbg(dev, "restored mask %u/%u %#08x\n" , c, gpp, readl(base + gpp * 4)); |
1817 | } |
1818 | |
1819 | static void intel_restore_padcfg(struct intel_pinctrl *pctrl, unsigned int pin, |
1820 | unsigned int reg, u32 saved) |
1821 | { |
1822 | u32 mask = (reg == PADCFG0) ? PADCFG0_GPIORXSTATE : 0; |
1823 | unsigned int n = reg / sizeof(u32); |
1824 | struct device *dev = pctrl->dev; |
1825 | void __iomem *padcfg; |
1826 | |
1827 | padcfg = intel_get_padcfg(pctrl, pin, reg); |
1828 | if (!padcfg) |
1829 | return; |
1830 | |
1831 | if (!intel_gpio_update_reg(reg: padcfg, mask: ~mask, value: saved)) |
1832 | return; |
1833 | |
1834 | dev_dbg(dev, "restored pin %u padcfg%u %#08x\n" , pin, n, readl(padcfg)); |
1835 | } |
1836 | |
1837 | static int intel_pinctrl_resume_noirq(struct device *dev) |
1838 | { |
1839 | struct intel_pinctrl *pctrl = dev_get_drvdata(dev); |
1840 | const struct intel_community_context *communities; |
1841 | const struct intel_pad_context *pads; |
1842 | int i; |
1843 | |
1844 | /* Mask all interrupts */ |
1845 | intel_gpio_irq_init(pctrl); |
1846 | |
1847 | pads = pctrl->context.pads; |
1848 | for (i = 0; i < pctrl->soc->npins; i++) { |
1849 | const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i]; |
1850 | |
1851 | if (!(intel_pinctrl_should_save(pctrl, pin: desc->number) || |
1852 | /* |
1853 | * If the firmware mangled the register contents too much, |
1854 | * check the saved value for the Direct IRQ mode. |
1855 | */ |
1856 | __intel_gpio_is_direct_irq(value: pads[i].padcfg0))) |
1857 | continue; |
1858 | |
1859 | intel_restore_padcfg(pctrl, pin: desc->number, PADCFG0, saved: pads[i].padcfg0); |
1860 | intel_restore_padcfg(pctrl, pin: desc->number, PADCFG1, saved: pads[i].padcfg1); |
1861 | intel_restore_padcfg(pctrl, pin: desc->number, PADCFG2, saved: pads[i].padcfg2); |
1862 | } |
1863 | |
1864 | communities = pctrl->context.communities; |
1865 | for (i = 0; i < pctrl->ncommunities; i++) { |
1866 | struct intel_community * = &pctrl->communities[i]; |
1867 | void __iomem *base; |
1868 | unsigned int gpp; |
1869 | |
1870 | base = community->regs + community->ie_offset; |
1871 | for (gpp = 0; gpp < community->ngpps; gpp++) |
1872 | intel_restore_intmask(pctrl, c: i, base, gpp, saved: communities[i].intmask[gpp]); |
1873 | |
1874 | base = community->regs + community->hostown_offset; |
1875 | for (gpp = 0; gpp < community->ngpps; gpp++) |
1876 | intel_restore_hostown(pctrl, c: i, base, gpp, saved: communities[i].hostown[gpp]); |
1877 | } |
1878 | |
1879 | return 0; |
1880 | } |
1881 | |
1882 | EXPORT_NS_GPL_DEV_SLEEP_PM_OPS(intel_pinctrl_pm_ops, PINCTRL_INTEL) = { |
1883 | NOIRQ_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend_noirq, intel_pinctrl_resume_noirq) |
1884 | }; |
1885 | |
1886 | MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>" ); |
1887 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>" ); |
1888 | MODULE_DESCRIPTION("Intel pinctrl/GPIO core driver" ); |
1889 | MODULE_LICENSE("GPL v2" ); |
1890 | |