1 | // SPDX-License-Identifier: GPL-2.0 |
---|---|
2 | /* |
3 | * Intel Lynxpoint PCH pinctrl/GPIO driver |
4 | * |
5 | * Copyright (c) 2012, 2019, Intel Corporation |
6 | * Authors: Mathias Nyman <mathias.nyman@linux.intel.com> |
7 | * Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
8 | */ |
9 | |
10 | #include <linux/acpi.h> |
11 | #include <linux/array_size.h> |
12 | #include <linux/bitops.h> |
13 | #include <linux/cleanup.h> |
14 | #include <linux/gpio/driver.h> |
15 | #include <linux/interrupt.h> |
16 | #include <linux/io.h> |
17 | #include <linux/module.h> |
18 | #include <linux/platform_device.h> |
19 | #include <linux/pm.h> |
20 | #include <linux/seq_file.h> |
21 | #include <linux/slab.h> |
22 | #include <linux/types.h> |
23 | |
24 | #include <linux/pinctrl/consumer.h> |
25 | #include <linux/pinctrl/pinconf-generic.h> |
26 | #include <linux/pinctrl/pinconf.h> |
27 | #include <linux/pinctrl/pinctrl.h> |
28 | #include <linux/pinctrl/pinmux.h> |
29 | |
30 | #include "pinctrl-intel.h" |
31 | |
32 | #define COMMUNITY(p, n) \ |
33 | { \ |
34 | .pin_base = (p), \ |
35 | .npins = (n), \ |
36 | } |
37 | |
38 | static const struct pinctrl_pin_desc lptlp_pins[] = { |
39 | PINCTRL_PIN(0, "GP0_UART1_RXD"), |
40 | PINCTRL_PIN(1, "GP1_UART1_TXD"), |
41 | PINCTRL_PIN(2, "GP2_UART1_RTSB"), |
42 | PINCTRL_PIN(3, "GP3_UART1_CTSB"), |
43 | PINCTRL_PIN(4, "GP4_I2C0_SDA"), |
44 | PINCTRL_PIN(5, "GP5_I2C0_SCL"), |
45 | PINCTRL_PIN(6, "GP6_I2C1_SDA"), |
46 | PINCTRL_PIN(7, "GP7_I2C1_SCL"), |
47 | PINCTRL_PIN(8, "GP8"), |
48 | PINCTRL_PIN(9, "GP9"), |
49 | PINCTRL_PIN(10, "GP10"), |
50 | PINCTRL_PIN(11, "GP11_SMBALERTB"), |
51 | PINCTRL_PIN(12, "GP12_LANPHYPC"), |
52 | PINCTRL_PIN(13, "GP13"), |
53 | PINCTRL_PIN(14, "GP14"), |
54 | PINCTRL_PIN(15, "GP15"), |
55 | PINCTRL_PIN(16, "GP16_MGPIO9"), |
56 | PINCTRL_PIN(17, "GP17_MGPIO10"), |
57 | PINCTRL_PIN(18, "GP18_SRC0CLKRQB"), |
58 | PINCTRL_PIN(19, "GP19_SRC1CLKRQB"), |
59 | PINCTRL_PIN(20, "GP20_SRC2CLKRQB"), |
60 | PINCTRL_PIN(21, "GP21_SRC3CLKRQB"), |
61 | PINCTRL_PIN(22, "GP22_SRC4CLKRQB_TRST2"), |
62 | PINCTRL_PIN(23, "GP23_SRC5CLKRQB_TDI2"), |
63 | PINCTRL_PIN(24, "GP24_MGPIO0"), |
64 | PINCTRL_PIN(25, "GP25_USBWAKEOUTB"), |
65 | PINCTRL_PIN(26, "GP26_MGPIO5"), |
66 | PINCTRL_PIN(27, "GP27_MGPIO6"), |
67 | PINCTRL_PIN(28, "GP28_MGPIO7"), |
68 | PINCTRL_PIN(29, "GP29_SLP_WLANB_MGPIO3"), |
69 | PINCTRL_PIN(30, "GP30_SUSWARNB_SUSPWRDNACK_MGPIO1"), |
70 | PINCTRL_PIN(31, "GP31_ACPRESENT_MGPIO2"), |
71 | PINCTRL_PIN(32, "GP32_CLKRUNB"), |
72 | PINCTRL_PIN(33, "GP33_DEVSLP0"), |
73 | PINCTRL_PIN(34, "GP34_SATA0XPCIE6L3B_SATA0GP"), |
74 | PINCTRL_PIN(35, "GP35_SATA1XPCIE6L2B_SATA1GP"), |
75 | PINCTRL_PIN(36, "GP36_SATA2XPCIE6L1B_SATA2GP"), |
76 | PINCTRL_PIN(37, "GP37_SATA3XPCIE6L0B_SATA3GP"), |
77 | PINCTRL_PIN(38, "GP38_DEVSLP1"), |
78 | PINCTRL_PIN(39, "GP39_DEVSLP2"), |
79 | PINCTRL_PIN(40, "GP40_OC0B"), |
80 | PINCTRL_PIN(41, "GP41_OC1B"), |
81 | PINCTRL_PIN(42, "GP42_OC2B"), |
82 | PINCTRL_PIN(43, "GP43_OC3B"), |
83 | PINCTRL_PIN(44, "GP44"), |
84 | PINCTRL_PIN(45, "GP45_TMS2"), |
85 | PINCTRL_PIN(46, "GP46_TDO2"), |
86 | PINCTRL_PIN(47, "GP47"), |
87 | PINCTRL_PIN(48, "GP48"), |
88 | PINCTRL_PIN(49, "GP49"), |
89 | PINCTRL_PIN(50, "GP50"), |
90 | PINCTRL_PIN(51, "GP51_GSXDOUT"), |
91 | PINCTRL_PIN(52, "GP52_GSXSLOAD"), |
92 | PINCTRL_PIN(53, "GP53_GSXDIN"), |
93 | PINCTRL_PIN(54, "GP54_GSXSRESETB"), |
94 | PINCTRL_PIN(55, "GP55_GSXCLK"), |
95 | PINCTRL_PIN(56, "GP56"), |
96 | PINCTRL_PIN(57, "GP57"), |
97 | PINCTRL_PIN(58, "GP58"), |
98 | PINCTRL_PIN(59, "GP59"), |
99 | PINCTRL_PIN(60, "GP60_SML0ALERTB_MGPIO4"), |
100 | PINCTRL_PIN(61, "GP61_SUS_STATB"), |
101 | PINCTRL_PIN(62, "GP62_SUSCLK"), |
102 | PINCTRL_PIN(63, "GP63_SLP_S5B"), |
103 | PINCTRL_PIN(64, "GP64_SDIO_CLK"), |
104 | PINCTRL_PIN(65, "GP65_SDIO_CMD"), |
105 | PINCTRL_PIN(66, "GP66_SDIO_D0"), |
106 | PINCTRL_PIN(67, "GP67_SDIO_D1"), |
107 | PINCTRL_PIN(68, "GP68_SDIO_D2"), |
108 | PINCTRL_PIN(69, "GP69_SDIO_D3"), |
109 | PINCTRL_PIN(70, "GP70_SDIO_POWER_EN"), |
110 | PINCTRL_PIN(71, "GP71_MPHYPC"), |
111 | PINCTRL_PIN(72, "GP72_BATLOWB"), |
112 | PINCTRL_PIN(73, "GP73_SML1ALERTB_PCHHOTB_MGPIO8"), |
113 | PINCTRL_PIN(74, "GP74_SML1DATA_MGPIO12"), |
114 | PINCTRL_PIN(75, "GP75_SML1CLK_MGPIO11"), |
115 | PINCTRL_PIN(76, "GP76_BMBUSYB"), |
116 | PINCTRL_PIN(77, "GP77_PIRQAB"), |
117 | PINCTRL_PIN(78, "GP78_PIRQBB"), |
118 | PINCTRL_PIN(79, "GP79_PIRQCB"), |
119 | PINCTRL_PIN(80, "GP80_PIRQDB"), |
120 | PINCTRL_PIN(81, "GP81_SPKR"), |
121 | PINCTRL_PIN(82, "GP82_RCINB"), |
122 | PINCTRL_PIN(83, "GP83_GSPI0_CSB"), |
123 | PINCTRL_PIN(84, "GP84_GSPI0_CLK"), |
124 | PINCTRL_PIN(85, "GP85_GSPI0_MISO"), |
125 | PINCTRL_PIN(86, "GP86_GSPI0_MOSI"), |
126 | PINCTRL_PIN(87, "GP87_GSPI1_CSB"), |
127 | PINCTRL_PIN(88, "GP88_GSPI1_CLK"), |
128 | PINCTRL_PIN(89, "GP89_GSPI1_MISO"), |
129 | PINCTRL_PIN(90, "GP90_GSPI1_MOSI"), |
130 | PINCTRL_PIN(91, "GP91_UART0_RXD"), |
131 | PINCTRL_PIN(92, "GP92_UART0_TXD"), |
132 | PINCTRL_PIN(93, "GP93_UART0_RTSB"), |
133 | PINCTRL_PIN(94, "GP94_UART0_CTSB"), |
134 | }; |
135 | |
136 | static const struct intel_community lptlp_communities[] = { |
137 | COMMUNITY(0, 95), |
138 | }; |
139 | |
140 | static const struct intel_pinctrl_soc_data lptlp_soc_data = { |
141 | .pins = lptlp_pins, |
142 | .npins = ARRAY_SIZE(lptlp_pins), |
143 | .communities = lptlp_communities, |
144 | .ncommunities = ARRAY_SIZE(lptlp_communities), |
145 | }; |
146 | |
147 | /* LynxPoint chipset has support for 95 GPIO pins */ |
148 | |
149 | #define LP_NUM_GPIO 95 |
150 | |
151 | /* Bitmapped register offsets */ |
152 | #define LP_ACPI_OWNED 0x00 /* Bitmap, set by bios, 0: pin reserved for ACPI */ |
153 | #define LP_IRQ2IOXAPIC 0x10 /* Bitmap, set by bios, 1: pin routed to IOxAPIC */ |
154 | #define LP_GC 0x7C /* set APIC IRQ to IRQ14 or IRQ15 for all pins */ |
155 | #define LP_INT_STAT 0x80 |
156 | #define LP_INT_ENABLE 0x90 |
157 | |
158 | /* Each pin has two 32 bit config registers, starting at 0x100 */ |
159 | #define LP_CONFIG1 0x100 |
160 | #define LP_CONFIG2 0x104 |
161 | |
162 | /* LP_CONFIG1 reg bits */ |
163 | #define OUT_LVL_BIT BIT(31) |
164 | #define IN_LVL_BIT BIT(30) |
165 | #define TRIG_SEL_BIT BIT(4) /* 0: Edge, 1: Level */ |
166 | #define INT_INV_BIT BIT(3) /* Invert interrupt triggering */ |
167 | #define DIR_BIT BIT(2) /* 0: Output, 1: Input */ |
168 | #define USE_SEL_MASK GENMASK(1, 0) /* 0: Native, 1: GPIO, ... */ |
169 | #define USE_SEL_NATIVE (0 << 0) |
170 | #define USE_SEL_GPIO (1 << 0) |
171 | |
172 | /* LP_CONFIG2 reg bits */ |
173 | #define GPINDIS_BIT BIT(2) /* disable input sensing */ |
174 | #define GPIWP_MASK GENMASK(1, 0) /* weak pull options */ |
175 | #define GPIWP_NONE 0 /* none */ |
176 | #define GPIWP_DOWN 1 /* weak pull down */ |
177 | #define GPIWP_UP 2 /* weak pull up */ |
178 | |
179 | /* |
180 | * Lynxpoint gpios are controlled through both bitmapped registers and |
181 | * per gpio specific registers. The bitmapped registers are in chunks of |
182 | * 3 x 32bit registers to cover all 95 GPIOs |
183 | * |
184 | * per gpio specific registers consist of two 32bit registers per gpio |
185 | * (LP_CONFIG1 and LP_CONFIG2), with 95 GPIOs there's a total of |
186 | * 190 config registers. |
187 | * |
188 | * A simplified view of the register layout look like this: |
189 | * |
190 | * LP_ACPI_OWNED[31:0] gpio ownerships for gpios 0-31 (bitmapped registers) |
191 | * LP_ACPI_OWNED[63:32] gpio ownerships for gpios 32-63 |
192 | * LP_ACPI_OWNED[94:64] gpio ownerships for gpios 63-94 |
193 | * ... |
194 | * LP_INT_ENABLE[31:0] ... |
195 | * LP_INT_ENABLE[63:32] ... |
196 | * LP_INT_ENABLE[94:64] ... |
197 | * LP0_CONFIG1 (gpio 0) config1 reg for gpio 0 (per gpio registers) |
198 | * LP0_CONFIG2 (gpio 0) config2 reg for gpio 0 |
199 | * LP1_CONFIG1 (gpio 1) config1 reg for gpio 1 |
200 | * LP1_CONFIG2 (gpio 1) config2 reg for gpio 1 |
201 | * LP2_CONFIG1 (gpio 2) ... |
202 | * LP2_CONFIG2 (gpio 2) ... |
203 | * ... |
204 | * LP94_CONFIG1 (gpio 94) ... |
205 | * LP94_CONFIG2 (gpio 94) ... |
206 | * |
207 | * IOxAPIC redirection map applies only for gpio 8-10, 13-14, 45-55. |
208 | */ |
209 | |
210 | static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset, |
211 | int reg) |
212 | { |
213 | struct intel_pinctrl *lg = gpiochip_get_data(gc: chip); |
214 | const struct intel_community *comm; |
215 | int reg_offset; |
216 | |
217 | comm = intel_get_community(pctrl: lg, pin: offset); |
218 | if (!comm) |
219 | return NULL; |
220 | |
221 | offset -= comm->pin_base; |
222 | |
223 | if (reg == LP_CONFIG1 || reg == LP_CONFIG2) |
224 | /* per gpio specific config registers */ |
225 | reg_offset = offset * 8; |
226 | else |
227 | /* bitmapped registers */ |
228 | reg_offset = (offset / 32) * 4; |
229 | |
230 | return comm->regs + reg_offset + reg; |
231 | } |
232 | |
233 | static bool lp_gpio_acpi_use(struct intel_pinctrl *lg, unsigned int pin) |
234 | { |
235 | void __iomem *acpi_use; |
236 | |
237 | acpi_use = lp_gpio_reg(chip: &lg->chip, offset: pin, LP_ACPI_OWNED); |
238 | if (!acpi_use) |
239 | return true; |
240 | |
241 | return !(ioread32(acpi_use) & BIT(pin % 32)); |
242 | } |
243 | |
244 | static bool lp_gpio_ioxapic_use(struct gpio_chip *chip, unsigned int offset) |
245 | { |
246 | void __iomem *ioxapic_use = lp_gpio_reg(chip, offset, LP_IRQ2IOXAPIC); |
247 | u32 value; |
248 | |
249 | value = ioread32(ioxapic_use); |
250 | |
251 | if (offset >= 8 && offset <= 10) |
252 | return !!(value & BIT(offset - 8 + 0)); |
253 | if (offset >= 13 && offset <= 14) |
254 | return !!(value & BIT(offset - 13 + 3)); |
255 | if (offset >= 45 && offset <= 55) |
256 | return !!(value & BIT(offset - 45 + 5)); |
257 | |
258 | return false; |
259 | } |
260 | |
261 | static void lp_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, |
262 | unsigned int pin) |
263 | { |
264 | struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); |
265 | void __iomem *reg = lp_gpio_reg(chip: &lg->chip, offset: pin, LP_CONFIG1); |
266 | void __iomem *conf2 = lp_gpio_reg(chip: &lg->chip, offset: pin, LP_CONFIG2); |
267 | u32 value, mode; |
268 | |
269 | value = ioread32(reg); |
270 | |
271 | mode = value & USE_SEL_MASK; |
272 | if (mode == USE_SEL_GPIO) |
273 | seq_puts(m: s, s: "GPIO "); |
274 | else |
275 | seq_printf(m: s, fmt: "mode %d ", mode); |
276 | |
277 | seq_printf(m: s, fmt: "0x%08x 0x%08x", value, ioread32(conf2)); |
278 | |
279 | if (lp_gpio_acpi_use(lg, pin)) |
280 | seq_puts(m: s, s: " [ACPI]"); |
281 | } |
282 | |
283 | static const struct pinctrl_ops lptlp_pinctrl_ops = { |
284 | .get_groups_count = intel_get_groups_count, |
285 | .get_group_name = intel_get_group_name, |
286 | .get_group_pins = intel_get_group_pins, |
287 | .pin_dbg_show = lp_pin_dbg_show, |
288 | }; |
289 | |
290 | static int lp_pinmux_set_mux(struct pinctrl_dev *pctldev, |
291 | unsigned int function, unsigned int group) |
292 | { |
293 | struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); |
294 | const struct intel_pingroup *grp = &lg->soc->groups[group]; |
295 | int i; |
296 | |
297 | guard(raw_spinlock_irqsave)(l: &lg->lock); |
298 | |
299 | /* Now enable the mux setting for each pin in the group */ |
300 | for (i = 0; i < grp->grp.npins; i++) { |
301 | void __iomem *reg = lp_gpio_reg(chip: &lg->chip, offset: grp->grp.pins[i], LP_CONFIG1); |
302 | u32 value; |
303 | |
304 | value = ioread32(reg); |
305 | |
306 | value &= ~USE_SEL_MASK; |
307 | if (grp->modes) |
308 | value |= grp->modes[i]; |
309 | else |
310 | value |= grp->mode; |
311 | |
312 | iowrite32(value, reg); |
313 | } |
314 | |
315 | return 0; |
316 | } |
317 | |
318 | static void lp_gpio_enable_input(void __iomem *reg) |
319 | { |
320 | iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg); |
321 | } |
322 | |
323 | static void lp_gpio_disable_input(void __iomem *reg) |
324 | { |
325 | iowrite32(ioread32(reg) | GPINDIS_BIT, reg); |
326 | } |
327 | |
328 | static int lp_gpio_request_enable(struct pinctrl_dev *pctldev, |
329 | struct pinctrl_gpio_range *range, |
330 | unsigned int pin) |
331 | { |
332 | struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); |
333 | void __iomem *reg = lp_gpio_reg(chip: &lg->chip, offset: pin, LP_CONFIG1); |
334 | void __iomem *conf2 = lp_gpio_reg(chip: &lg->chip, offset: pin, LP_CONFIG2); |
335 | u32 value; |
336 | |
337 | guard(raw_spinlock_irqsave)(l: &lg->lock); |
338 | |
339 | /* |
340 | * Reconfigure pin to GPIO mode if needed and issue a warning, |
341 | * since we expect firmware to configure it properly. |
342 | */ |
343 | value = ioread32(reg); |
344 | if ((value & USE_SEL_MASK) != USE_SEL_GPIO) { |
345 | iowrite32((value & USE_SEL_MASK) | USE_SEL_GPIO, reg); |
346 | dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", pin); |
347 | } |
348 | |
349 | /* Enable input sensing */ |
350 | lp_gpio_enable_input(reg: conf2); |
351 | |
352 | return 0; |
353 | } |
354 | |
355 | static void lp_gpio_disable_free(struct pinctrl_dev *pctldev, |
356 | struct pinctrl_gpio_range *range, |
357 | unsigned int pin) |
358 | { |
359 | struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); |
360 | void __iomem *conf2 = lp_gpio_reg(chip: &lg->chip, offset: pin, LP_CONFIG2); |
361 | |
362 | guard(raw_spinlock_irqsave)(l: &lg->lock); |
363 | |
364 | /* Disable input sensing */ |
365 | lp_gpio_disable_input(reg: conf2); |
366 | } |
367 | |
368 | static int lp_gpio_set_direction(struct pinctrl_dev *pctldev, |
369 | struct pinctrl_gpio_range *range, |
370 | unsigned int pin, bool input) |
371 | { |
372 | struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); |
373 | void __iomem *reg = lp_gpio_reg(chip: &lg->chip, offset: pin, LP_CONFIG1); |
374 | u32 value; |
375 | |
376 | guard(raw_spinlock_irqsave)(l: &lg->lock); |
377 | |
378 | value = ioread32(reg); |
379 | value &= ~DIR_BIT; |
380 | if (input) { |
381 | value |= DIR_BIT; |
382 | } else { |
383 | /* |
384 | * Before making any direction modifications, do a check if GPIO |
385 | * is set for direct IRQ. On Lynxpoint, setting GPIO to output |
386 | * does not make sense, so let's at least warn the caller before |
387 | * they shoot themselves in the foot. |
388 | */ |
389 | WARN(lp_gpio_ioxapic_use(&lg->chip, pin), |
390 | "Potential Error: Setting GPIO to output with IOxAPIC redirection"); |
391 | } |
392 | iowrite32(value, reg); |
393 | |
394 | return 0; |
395 | } |
396 | |
397 | static const struct pinmux_ops lptlp_pinmux_ops = { |
398 | .get_functions_count = intel_get_functions_count, |
399 | .get_function_name = intel_get_function_name, |
400 | .get_function_groups = intel_get_function_groups, |
401 | .set_mux = lp_pinmux_set_mux, |
402 | .gpio_request_enable = lp_gpio_request_enable, |
403 | .gpio_disable_free = lp_gpio_disable_free, |
404 | .gpio_set_direction = lp_gpio_set_direction, |
405 | }; |
406 | |
407 | static int lp_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin, |
408 | unsigned long *config) |
409 | { |
410 | struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); |
411 | void __iomem *conf2 = lp_gpio_reg(chip: &lg->chip, offset: pin, LP_CONFIG2); |
412 | enum pin_config_param param = pinconf_to_config_param(config: *config); |
413 | u32 value, pull; |
414 | u16 arg; |
415 | |
416 | scoped_guard(raw_spinlock_irqsave, &lg->lock) |
417 | value = ioread32(conf2); |
418 | |
419 | pull = value & GPIWP_MASK; |
420 | |
421 | switch (param) { |
422 | case PIN_CONFIG_BIAS_DISABLE: |
423 | if (pull != GPIWP_NONE) |
424 | return -EINVAL; |
425 | arg = 0; |
426 | break; |
427 | case PIN_CONFIG_BIAS_PULL_DOWN: |
428 | if (pull != GPIWP_DOWN) |
429 | return -EINVAL; |
430 | |
431 | arg = 1; |
432 | break; |
433 | case PIN_CONFIG_BIAS_PULL_UP: |
434 | if (pull != GPIWP_UP) |
435 | return -EINVAL; |
436 | |
437 | arg = 1; |
438 | break; |
439 | default: |
440 | return -ENOTSUPP; |
441 | } |
442 | |
443 | *config = pinconf_to_config_packed(param, argument: arg); |
444 | |
445 | return 0; |
446 | } |
447 | |
448 | static int lp_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin, |
449 | unsigned long *configs, unsigned int num_configs) |
450 | { |
451 | struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); |
452 | void __iomem *conf2 = lp_gpio_reg(chip: &lg->chip, offset: pin, LP_CONFIG2); |
453 | enum pin_config_param param; |
454 | unsigned int i; |
455 | u32 value; |
456 | |
457 | guard(raw_spinlock_irqsave)(l: &lg->lock); |
458 | |
459 | value = ioread32(conf2); |
460 | |
461 | for (i = 0; i < num_configs; i++) { |
462 | param = pinconf_to_config_param(config: configs[i]); |
463 | |
464 | switch (param) { |
465 | case PIN_CONFIG_BIAS_DISABLE: |
466 | value &= ~GPIWP_MASK; |
467 | value |= GPIWP_NONE; |
468 | break; |
469 | case PIN_CONFIG_BIAS_PULL_DOWN: |
470 | value &= ~GPIWP_MASK; |
471 | value |= GPIWP_DOWN; |
472 | break; |
473 | case PIN_CONFIG_BIAS_PULL_UP: |
474 | value &= ~GPIWP_MASK; |
475 | value |= GPIWP_UP; |
476 | break; |
477 | default: |
478 | return -ENOTSUPP; |
479 | } |
480 | } |
481 | |
482 | iowrite32(value, conf2); |
483 | |
484 | return 0; |
485 | } |
486 | |
487 | static const struct pinconf_ops lptlp_pinconf_ops = { |
488 | .is_generic = true, |
489 | .pin_config_get = lp_pin_config_get, |
490 | .pin_config_set = lp_pin_config_set, |
491 | }; |
492 | |
493 | static const struct pinctrl_desc lptlp_pinctrl_desc = { |
494 | .pctlops = &lptlp_pinctrl_ops, |
495 | .pmxops = &lptlp_pinmux_ops, |
496 | .confops = &lptlp_pinconf_ops, |
497 | .owner = THIS_MODULE, |
498 | }; |
499 | |
500 | static int lp_gpio_get(struct gpio_chip *chip, unsigned int offset) |
501 | { |
502 | void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); |
503 | return !!(ioread32(reg) & IN_LVL_BIT); |
504 | } |
505 | |
506 | static void lp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) |
507 | { |
508 | struct intel_pinctrl *lg = gpiochip_get_data(gc: chip); |
509 | void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); |
510 | |
511 | guard(raw_spinlock_irqsave)(l: &lg->lock); |
512 | |
513 | if (value) |
514 | iowrite32(ioread32(reg) | OUT_LVL_BIT, reg); |
515 | else |
516 | iowrite32(ioread32(reg) & ~OUT_LVL_BIT, reg); |
517 | } |
518 | |
519 | static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) |
520 | { |
521 | return pinctrl_gpio_direction_input(gc: chip, offset); |
522 | } |
523 | |
524 | static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, |
525 | int value) |
526 | { |
527 | lp_gpio_set(chip, offset, value); |
528 | |
529 | return pinctrl_gpio_direction_output(gc: chip, offset); |
530 | } |
531 | |
532 | static int lp_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) |
533 | { |
534 | void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); |
535 | |
536 | if (ioread32(reg) & DIR_BIT) |
537 | return GPIO_LINE_DIRECTION_IN; |
538 | |
539 | return GPIO_LINE_DIRECTION_OUT; |
540 | } |
541 | |
542 | static void lp_gpio_irq_handler(struct irq_desc *desc) |
543 | { |
544 | struct irq_data *data = irq_desc_get_irq_data(desc); |
545 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); |
546 | struct intel_pinctrl *lg = gpiochip_get_data(gc); |
547 | struct irq_chip *chip = irq_data_get_irq_chip(d: data); |
548 | void __iomem *reg, *ena; |
549 | unsigned long pending; |
550 | u32 base, pin; |
551 | |
552 | chained_irq_enter(chip, desc); |
553 | |
554 | /* check from GPIO controller which pin triggered the interrupt */ |
555 | for (base = 0; base < lg->chip.ngpio; base += 32) { |
556 | reg = lp_gpio_reg(chip: &lg->chip, offset: base, LP_INT_STAT); |
557 | ena = lp_gpio_reg(chip: &lg->chip, offset: base, LP_INT_ENABLE); |
558 | |
559 | /* Only interrupts that are enabled */ |
560 | pending = ioread32(reg) & ioread32(ena); |
561 | |
562 | for_each_set_bit(pin, &pending, 32) |
563 | generic_handle_domain_irq(domain: lg->chip.irq.domain, hwirq: base + pin); |
564 | } |
565 | |
566 | chained_irq_exit(chip, desc); |
567 | } |
568 | |
569 | static void lp_irq_ack(struct irq_data *d) |
570 | { |
571 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
572 | struct intel_pinctrl *lg = gpiochip_get_data(gc); |
573 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
574 | void __iomem *reg = lp_gpio_reg(chip: &lg->chip, offset: hwirq, LP_INT_STAT); |
575 | |
576 | guard(raw_spinlock_irqsave)(l: &lg->lock); |
577 | |
578 | iowrite32(BIT(hwirq % 32), reg); |
579 | } |
580 | |
581 | static void lp_irq_unmask(struct irq_data *d) |
582 | { |
583 | } |
584 | |
585 | static void lp_irq_mask(struct irq_data *d) |
586 | { |
587 | } |
588 | |
589 | static void lp_irq_enable(struct irq_data *d) |
590 | { |
591 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
592 | struct intel_pinctrl *lg = gpiochip_get_data(gc); |
593 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
594 | void __iomem *reg = lp_gpio_reg(chip: &lg->chip, offset: hwirq, LP_INT_ENABLE); |
595 | |
596 | gpiochip_enable_irq(gc, offset: hwirq); |
597 | |
598 | scoped_guard(raw_spinlock_irqsave, &lg->lock) |
599 | iowrite32(ioread32(reg) | BIT(hwirq % 32), reg); |
600 | } |
601 | |
602 | static void lp_irq_disable(struct irq_data *d) |
603 | { |
604 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
605 | struct intel_pinctrl *lg = gpiochip_get_data(gc); |
606 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
607 | void __iomem *reg = lp_gpio_reg(chip: &lg->chip, offset: hwirq, LP_INT_ENABLE); |
608 | |
609 | scoped_guard(raw_spinlock_irqsave, &lg->lock) |
610 | iowrite32(ioread32(reg) & ~BIT(hwirq % 32), reg); |
611 | |
612 | gpiochip_disable_irq(gc, offset: hwirq); |
613 | } |
614 | |
615 | static int lp_irq_set_type(struct irq_data *d, unsigned int type) |
616 | { |
617 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
618 | struct intel_pinctrl *lg = gpiochip_get_data(gc); |
619 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
620 | void __iomem *reg; |
621 | u32 value; |
622 | |
623 | reg = lp_gpio_reg(chip: &lg->chip, offset: hwirq, LP_CONFIG1); |
624 | if (!reg) |
625 | return -EINVAL; |
626 | |
627 | /* Fail if BIOS reserved pin for ACPI use */ |
628 | if (lp_gpio_acpi_use(lg, pin: hwirq)) { |
629 | dev_err(lg->dev, "pin %lu can't be used as IRQ\n", hwirq); |
630 | return -EBUSY; |
631 | } |
632 | |
633 | guard(raw_spinlock_irqsave)(l: &lg->lock); |
634 | |
635 | value = ioread32(reg); |
636 | |
637 | /* set both TRIG_SEL and INV bits to 0 for rising edge */ |
638 | if (type & IRQ_TYPE_EDGE_RISING) |
639 | value &= ~(TRIG_SEL_BIT | INT_INV_BIT); |
640 | |
641 | /* TRIG_SEL bit 0, INV bit 1 for falling edge */ |
642 | if (type & IRQ_TYPE_EDGE_FALLING) |
643 | value = (value | INT_INV_BIT) & ~TRIG_SEL_BIT; |
644 | |
645 | /* TRIG_SEL bit 1, INV bit 0 for level low */ |
646 | if (type & IRQ_TYPE_LEVEL_LOW) |
647 | value = (value | TRIG_SEL_BIT) & ~INT_INV_BIT; |
648 | |
649 | /* TRIG_SEL bit 1, INV bit 1 for level high */ |
650 | if (type & IRQ_TYPE_LEVEL_HIGH) |
651 | value |= TRIG_SEL_BIT | INT_INV_BIT; |
652 | |
653 | iowrite32(value, reg); |
654 | |
655 | if (type & IRQ_TYPE_EDGE_BOTH) |
656 | irq_set_handler_locked(data: d, handler: handle_edge_irq); |
657 | else if (type & IRQ_TYPE_LEVEL_MASK) |
658 | irq_set_handler_locked(data: d, handler: handle_level_irq); |
659 | |
660 | return 0; |
661 | } |
662 | |
663 | static const struct irq_chip lp_irqchip = { |
664 | .name = "LP-GPIO", |
665 | .irq_ack = lp_irq_ack, |
666 | .irq_mask = lp_irq_mask, |
667 | .irq_unmask = lp_irq_unmask, |
668 | .irq_enable = lp_irq_enable, |
669 | .irq_disable = lp_irq_disable, |
670 | .irq_set_type = lp_irq_set_type, |
671 | .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE, |
672 | GPIOCHIP_IRQ_RESOURCE_HELPERS, |
673 | }; |
674 | |
675 | static int lp_gpio_irq_init_hw(struct gpio_chip *chip) |
676 | { |
677 | struct intel_pinctrl *lg = gpiochip_get_data(gc: chip); |
678 | void __iomem *reg; |
679 | unsigned int base; |
680 | |
681 | for (base = 0; base < lg->chip.ngpio; base += 32) { |
682 | /* disable gpio pin interrupts */ |
683 | reg = lp_gpio_reg(chip: &lg->chip, offset: base, LP_INT_ENABLE); |
684 | iowrite32(0, reg); |
685 | /* Clear interrupt status register */ |
686 | reg = lp_gpio_reg(chip: &lg->chip, offset: base, LP_INT_STAT); |
687 | iowrite32(0xffffffff, reg); |
688 | } |
689 | |
690 | return 0; |
691 | } |
692 | |
693 | static int lp_gpio_add_pin_ranges(struct gpio_chip *chip) |
694 | { |
695 | struct intel_pinctrl *lg = gpiochip_get_data(gc: chip); |
696 | struct device *dev = lg->dev; |
697 | int ret; |
698 | |
699 | ret = gpiochip_add_pin_range(gc: chip, pinctl_name: dev_name(dev), gpio_offset: 0, pin_offset: 0, npins: lg->soc->npins); |
700 | if (ret) |
701 | dev_err(dev, "failed to add GPIO pin range\n"); |
702 | |
703 | return ret; |
704 | } |
705 | |
706 | static int lp_gpio_probe(struct platform_device *pdev) |
707 | { |
708 | const struct intel_pinctrl_soc_data *soc; |
709 | struct intel_pinctrl *lg; |
710 | struct gpio_chip *gc; |
711 | struct device *dev = &pdev->dev; |
712 | struct resource *io_rc; |
713 | void __iomem *regs; |
714 | unsigned int i; |
715 | int irq, ret; |
716 | |
717 | soc = (const struct intel_pinctrl_soc_data *)device_get_match_data(dev); |
718 | if (!soc) |
719 | return -ENODEV; |
720 | |
721 | lg = devm_kzalloc(dev, size: sizeof(*lg), GFP_KERNEL); |
722 | if (!lg) |
723 | return -ENOMEM; |
724 | |
725 | lg->dev = dev; |
726 | lg->soc = soc; |
727 | |
728 | lg->ncommunities = lg->soc->ncommunities; |
729 | lg->communities = devm_kcalloc(dev, n: lg->ncommunities, |
730 | size: sizeof(*lg->communities), GFP_KERNEL); |
731 | if (!lg->communities) |
732 | return -ENOMEM; |
733 | |
734 | lg->pctldesc = lptlp_pinctrl_desc; |
735 | lg->pctldesc.name = dev_name(dev); |
736 | lg->pctldesc.pins = lg->soc->pins; |
737 | lg->pctldesc.npins = lg->soc->npins; |
738 | |
739 | lg->pctldev = devm_pinctrl_register(dev, pctldesc: &lg->pctldesc, driver_data: lg); |
740 | if (IS_ERR(ptr: lg->pctldev)) { |
741 | dev_err(dev, "failed to register pinctrl driver\n"); |
742 | return PTR_ERR(ptr: lg->pctldev); |
743 | } |
744 | |
745 | platform_set_drvdata(pdev, data: lg); |
746 | |
747 | io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0); |
748 | if (!io_rc) { |
749 | dev_err(dev, "missing IO resources\n"); |
750 | return -EINVAL; |
751 | } |
752 | |
753 | regs = devm_ioport_map(dev, port: io_rc->start, nr: resource_size(res: io_rc)); |
754 | if (!regs) { |
755 | dev_err(dev, "failed mapping IO region %pR\n", &io_rc); |
756 | return -EBUSY; |
757 | } |
758 | |
759 | for (i = 0; i < lg->soc->ncommunities; i++) { |
760 | struct intel_community *comm = &lg->communities[i]; |
761 | |
762 | *comm = lg->soc->communities[i]; |
763 | |
764 | comm->regs = regs; |
765 | comm->pad_regs = regs + 0x100; |
766 | } |
767 | |
768 | raw_spin_lock_init(&lg->lock); |
769 | |
770 | gc = &lg->chip; |
771 | gc->label = dev_name(dev); |
772 | gc->owner = THIS_MODULE; |
773 | gc->request = gpiochip_generic_request; |
774 | gc->free = gpiochip_generic_free; |
775 | gc->direction_input = lp_gpio_direction_input; |
776 | gc->direction_output = lp_gpio_direction_output; |
777 | gc->get = lp_gpio_get; |
778 | gc->set = lp_gpio_set; |
779 | gc->set_config = gpiochip_generic_config; |
780 | gc->get_direction = lp_gpio_get_direction; |
781 | gc->base = -1; |
782 | gc->ngpio = LP_NUM_GPIO; |
783 | gc->can_sleep = false; |
784 | gc->add_pin_ranges = lp_gpio_add_pin_ranges; |
785 | gc->parent = dev; |
786 | |
787 | /* set up interrupts */ |
788 | irq = platform_get_irq_optional(pdev, 0); |
789 | if (irq > 0) { |
790 | struct gpio_irq_chip *girq; |
791 | |
792 | girq = &gc->irq; |
793 | gpio_irq_chip_set_chip(girq, chip: &lp_irqchip); |
794 | girq->init_hw = lp_gpio_irq_init_hw; |
795 | girq->parent_handler = lp_gpio_irq_handler; |
796 | girq->num_parents = 1; |
797 | girq->parents = devm_kcalloc(dev, n: girq->num_parents, |
798 | size: sizeof(*girq->parents), |
799 | GFP_KERNEL); |
800 | if (!girq->parents) |
801 | return -ENOMEM; |
802 | girq->parents[0] = irq; |
803 | girq->default_type = IRQ_TYPE_NONE; |
804 | girq->handler = handle_bad_irq; |
805 | } |
806 | |
807 | ret = devm_gpiochip_add_data(dev, gc, lg); |
808 | if (ret) { |
809 | dev_err(dev, "failed adding lp-gpio chip\n"); |
810 | return ret; |
811 | } |
812 | |
813 | return 0; |
814 | } |
815 | |
816 | static int lp_gpio_resume(struct device *dev) |
817 | { |
818 | struct intel_pinctrl *lg = dev_get_drvdata(dev); |
819 | struct gpio_chip *chip = &lg->chip; |
820 | const char *dummy; |
821 | int i; |
822 | |
823 | /* on some hardware suspend clears input sensing, re-enable it here */ |
824 | for_each_requested_gpio(chip, i, dummy) |
825 | lp_gpio_enable_input(reg: lp_gpio_reg(chip, offset: i, LP_CONFIG2)); |
826 | |
827 | return 0; |
828 | } |
829 | |
830 | static DEFINE_SIMPLE_DEV_PM_OPS(lp_gpio_pm_ops, NULL, lp_gpio_resume); |
831 | |
832 | static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = { |
833 | { "INT33C7", (kernel_ulong_t)&lptlp_soc_data }, |
834 | { "INT3437", (kernel_ulong_t)&lptlp_soc_data }, |
835 | { } |
836 | }; |
837 | MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match); |
838 | |
839 | static struct platform_driver lp_gpio_driver = { |
840 | .probe = lp_gpio_probe, |
841 | .driver = { |
842 | .name = "lp_gpio", |
843 | .pm = pm_sleep_ptr(&lp_gpio_pm_ops), |
844 | .acpi_match_table = lynxpoint_gpio_acpi_match, |
845 | }, |
846 | }; |
847 | |
848 | static int __init lp_gpio_init(void) |
849 | { |
850 | return platform_driver_register(&lp_gpio_driver); |
851 | } |
852 | subsys_initcall(lp_gpio_init); |
853 | |
854 | static void __exit lp_gpio_exit(void) |
855 | { |
856 | platform_driver_unregister(&lp_gpio_driver); |
857 | } |
858 | module_exit(lp_gpio_exit); |
859 | |
860 | MODULE_AUTHOR("Mathias Nyman (Intel)"); |
861 | MODULE_AUTHOR("Andy Shevchenko (Intel)"); |
862 | MODULE_DESCRIPTION("Intel Lynxpoint pinctrl driver"); |
863 | MODULE_LICENSE("GPL v2"); |
864 | MODULE_ALIAS("platform:lp_gpio"); |
865 | MODULE_IMPORT_NS("PINCTRL_INTEL"); |
866 |
Definitions
- lptlp_pins
- lptlp_communities
- lptlp_soc_data
- lp_gpio_reg
- lp_gpio_acpi_use
- lp_gpio_ioxapic_use
- lp_pin_dbg_show
- lptlp_pinctrl_ops
- lp_pinmux_set_mux
- lp_gpio_enable_input
- lp_gpio_disable_input
- lp_gpio_request_enable
- lp_gpio_disable_free
- lp_gpio_set_direction
- lptlp_pinmux_ops
- lp_pin_config_get
- lp_pin_config_set
- lptlp_pinconf_ops
- lptlp_pinctrl_desc
- lp_gpio_get
- lp_gpio_set
- lp_gpio_direction_input
- lp_gpio_direction_output
- lp_gpio_get_direction
- lp_gpio_irq_handler
- lp_irq_ack
- lp_irq_unmask
- lp_irq_mask
- lp_irq_enable
- lp_irq_disable
- lp_irq_set_type
- lp_irqchip
- lp_gpio_irq_init_hw
- lp_gpio_add_pin_ranges
- lp_gpio_probe
- lp_gpio_resume
- lp_gpio_pm_ops
- lynxpoint_gpio_acpi_match
- lp_gpio_driver
- lp_gpio_init
Improve your Profiling and Debugging skills
Find out more