1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * OWL SoC's Pinctrl driver |
4 | * |
5 | * Copyright (c) 2014 Actions Semi Inc. |
6 | * Author: David Liu <liuwei@actions-semi.com> |
7 | * |
8 | * Copyright (c) 2018 Linaro Ltd. |
9 | * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
10 | */ |
11 | |
12 | #include <linux/clk.h> |
13 | #include <linux/err.h> |
14 | #include <linux/gpio/driver.h> |
15 | #include <linux/io.h> |
16 | #include <linux/irq.h> |
17 | #include <linux/module.h> |
18 | #include <linux/of.h> |
19 | #include <linux/platform_device.h> |
20 | #include <linux/seq_file.h> |
21 | #include <linux/slab.h> |
22 | #include <linux/spinlock.h> |
23 | |
24 | #include <linux/pinctrl/machine.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 "../core.h" |
31 | #include "../pinctrl-utils.h" |
32 | #include "pinctrl-owl.h" |
33 | |
34 | /** |
35 | * struct owl_pinctrl - pinctrl state of the device |
36 | * @dev: device handle |
37 | * @pctrldev: pinctrl handle |
38 | * @chip: gpio chip |
39 | * @lock: spinlock to protect registers |
40 | * @clk: clock control |
41 | * @soc: reference to soc_data |
42 | * @base: pinctrl register base address |
43 | * @num_irq: number of possible interrupts |
44 | * @irq: interrupt numbers |
45 | */ |
46 | struct owl_pinctrl { |
47 | struct device *dev; |
48 | struct pinctrl_dev *pctrldev; |
49 | struct gpio_chip chip; |
50 | raw_spinlock_t lock; |
51 | struct clk *clk; |
52 | const struct owl_pinctrl_soc_data *soc; |
53 | void __iomem *base; |
54 | unsigned int num_irq; |
55 | unsigned int *irq; |
56 | }; |
57 | |
58 | static void owl_update_bits(void __iomem *base, u32 mask, u32 val) |
59 | { |
60 | u32 reg_val; |
61 | |
62 | reg_val = readl_relaxed(base); |
63 | |
64 | reg_val = (reg_val & ~mask) | (val & mask); |
65 | |
66 | writel_relaxed(reg_val, base); |
67 | } |
68 | |
69 | static u32 owl_read_field(struct owl_pinctrl *pctrl, u32 reg, |
70 | u32 bit, u32 width) |
71 | { |
72 | u32 tmp, mask; |
73 | |
74 | tmp = readl_relaxed(pctrl->base + reg); |
75 | mask = (1 << width) - 1; |
76 | |
77 | return (tmp >> bit) & mask; |
78 | } |
79 | |
80 | static void owl_write_field(struct owl_pinctrl *pctrl, u32 reg, u32 arg, |
81 | u32 bit, u32 width) |
82 | { |
83 | u32 mask; |
84 | |
85 | mask = (1 << width) - 1; |
86 | mask = mask << bit; |
87 | |
88 | owl_update_bits(base: pctrl->base + reg, mask, val: (arg << bit)); |
89 | } |
90 | |
91 | static int owl_get_groups_count(struct pinctrl_dev *pctrldev) |
92 | { |
93 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
94 | |
95 | return pctrl->soc->ngroups; |
96 | } |
97 | |
98 | static const char *owl_get_group_name(struct pinctrl_dev *pctrldev, |
99 | unsigned int group) |
100 | { |
101 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
102 | |
103 | return pctrl->soc->groups[group].name; |
104 | } |
105 | |
106 | static int owl_get_group_pins(struct pinctrl_dev *pctrldev, |
107 | unsigned int group, |
108 | const unsigned int **pins, |
109 | unsigned int *num_pins) |
110 | { |
111 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
112 | |
113 | *pins = pctrl->soc->groups[group].pads; |
114 | *num_pins = pctrl->soc->groups[group].npads; |
115 | |
116 | return 0; |
117 | } |
118 | |
119 | static void owl_pin_dbg_show(struct pinctrl_dev *pctrldev, |
120 | struct seq_file *s, |
121 | unsigned int offset) |
122 | { |
123 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
124 | |
125 | seq_printf(m: s, fmt: "%s" , dev_name(dev: pctrl->dev)); |
126 | } |
127 | |
128 | static const struct pinctrl_ops owl_pinctrl_ops = { |
129 | .get_groups_count = owl_get_groups_count, |
130 | .get_group_name = owl_get_group_name, |
131 | .get_group_pins = owl_get_group_pins, |
132 | .pin_dbg_show = owl_pin_dbg_show, |
133 | .dt_node_to_map = pinconf_generic_dt_node_to_map_all, |
134 | .dt_free_map = pinctrl_utils_free_map, |
135 | }; |
136 | |
137 | static int owl_get_funcs_count(struct pinctrl_dev *pctrldev) |
138 | { |
139 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
140 | |
141 | return pctrl->soc->nfunctions; |
142 | } |
143 | |
144 | static const char *owl_get_func_name(struct pinctrl_dev *pctrldev, |
145 | unsigned int function) |
146 | { |
147 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
148 | |
149 | return pctrl->soc->functions[function].name; |
150 | } |
151 | |
152 | static int owl_get_func_groups(struct pinctrl_dev *pctrldev, |
153 | unsigned int function, |
154 | const char * const **groups, |
155 | unsigned int * const num_groups) |
156 | { |
157 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
158 | |
159 | *groups = pctrl->soc->functions[function].groups; |
160 | *num_groups = pctrl->soc->functions[function].ngroups; |
161 | |
162 | return 0; |
163 | } |
164 | |
165 | static inline int get_group_mfp_mask_val(const struct owl_pingroup *g, |
166 | int function, |
167 | u32 *mask, |
168 | u32 *val) |
169 | { |
170 | int id; |
171 | u32 option_num; |
172 | u32 option_mask; |
173 | |
174 | for (id = 0; id < g->nfuncs; id++) { |
175 | if (g->funcs[id] == function) |
176 | break; |
177 | } |
178 | if (WARN_ON(id == g->nfuncs)) |
179 | return -EINVAL; |
180 | |
181 | option_num = (1 << g->mfpctl_width); |
182 | if (id > option_num) |
183 | id -= option_num; |
184 | |
185 | option_mask = option_num - 1; |
186 | *mask = (option_mask << g->mfpctl_shift); |
187 | *val = (id << g->mfpctl_shift); |
188 | |
189 | return 0; |
190 | } |
191 | |
192 | static int owl_set_mux(struct pinctrl_dev *pctrldev, |
193 | unsigned int function, |
194 | unsigned int group) |
195 | { |
196 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
197 | const struct owl_pingroup *g; |
198 | unsigned long flags; |
199 | u32 val, mask; |
200 | |
201 | g = &pctrl->soc->groups[group]; |
202 | |
203 | if (get_group_mfp_mask_val(g, function, mask: &mask, val: &val)) |
204 | return -EINVAL; |
205 | |
206 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
207 | |
208 | owl_update_bits(base: pctrl->base + g->mfpctl_reg, mask, val); |
209 | |
210 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
211 | |
212 | return 0; |
213 | } |
214 | |
215 | static const struct pinmux_ops owl_pinmux_ops = { |
216 | .get_functions_count = owl_get_funcs_count, |
217 | .get_function_name = owl_get_func_name, |
218 | .get_function_groups = owl_get_func_groups, |
219 | .set_mux = owl_set_mux, |
220 | }; |
221 | |
222 | static int owl_pad_pinconf_reg(const struct owl_padinfo *info, |
223 | unsigned int param, |
224 | u32 *reg, |
225 | u32 *bit, |
226 | u32 *width) |
227 | { |
228 | switch (param) { |
229 | case PIN_CONFIG_BIAS_BUS_HOLD: |
230 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: |
231 | case PIN_CONFIG_BIAS_PULL_DOWN: |
232 | case PIN_CONFIG_BIAS_PULL_UP: |
233 | if (!info->pullctl) |
234 | return -EINVAL; |
235 | *reg = info->pullctl->reg; |
236 | *bit = info->pullctl->shift; |
237 | *width = info->pullctl->width; |
238 | break; |
239 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: |
240 | if (!info->st) |
241 | return -EINVAL; |
242 | *reg = info->st->reg; |
243 | *bit = info->st->shift; |
244 | *width = info->st->width; |
245 | break; |
246 | default: |
247 | return -ENOTSUPP; |
248 | } |
249 | |
250 | return 0; |
251 | } |
252 | |
253 | static int owl_pin_config_get(struct pinctrl_dev *pctrldev, |
254 | unsigned int pin, |
255 | unsigned long *config) |
256 | { |
257 | int ret = 0; |
258 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
259 | const struct owl_padinfo *info; |
260 | unsigned int param = pinconf_to_config_param(config: *config); |
261 | u32 reg, bit, width, arg; |
262 | |
263 | info = &pctrl->soc->padinfo[pin]; |
264 | |
265 | ret = owl_pad_pinconf_reg(info, param, reg: ®, bit: &bit, width: &width); |
266 | if (ret) |
267 | return ret; |
268 | |
269 | arg = owl_read_field(pctrl, reg, bit, width); |
270 | |
271 | if (!pctrl->soc->padctl_val2arg) |
272 | return -ENOTSUPP; |
273 | |
274 | ret = pctrl->soc->padctl_val2arg(info, param, &arg); |
275 | if (ret) |
276 | return ret; |
277 | |
278 | *config = pinconf_to_config_packed(param, argument: arg); |
279 | |
280 | return ret; |
281 | } |
282 | |
283 | static int owl_pin_config_set(struct pinctrl_dev *pctrldev, |
284 | unsigned int pin, |
285 | unsigned long *configs, |
286 | unsigned int num_configs) |
287 | { |
288 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
289 | const struct owl_padinfo *info; |
290 | unsigned long flags; |
291 | unsigned int param; |
292 | u32 reg, bit, width, arg; |
293 | int ret = 0, i; |
294 | |
295 | info = &pctrl->soc->padinfo[pin]; |
296 | |
297 | for (i = 0; i < num_configs; i++) { |
298 | param = pinconf_to_config_param(config: configs[i]); |
299 | arg = pinconf_to_config_argument(config: configs[i]); |
300 | |
301 | ret = owl_pad_pinconf_reg(info, param, reg: ®, bit: &bit, width: &width); |
302 | if (ret) |
303 | return ret; |
304 | |
305 | if (!pctrl->soc->padctl_arg2val) |
306 | return -ENOTSUPP; |
307 | |
308 | ret = pctrl->soc->padctl_arg2val(info, param, &arg); |
309 | if (ret) |
310 | return ret; |
311 | |
312 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
313 | |
314 | owl_write_field(pctrl, reg, arg, bit, width); |
315 | |
316 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
317 | } |
318 | |
319 | return ret; |
320 | } |
321 | |
322 | static int owl_group_pinconf_reg(const struct owl_pingroup *g, |
323 | unsigned int param, |
324 | u32 *reg, |
325 | u32 *bit, |
326 | u32 *width) |
327 | { |
328 | switch (param) { |
329 | case PIN_CONFIG_DRIVE_STRENGTH: |
330 | if (g->drv_reg < 0) |
331 | return -EINVAL; |
332 | *reg = g->drv_reg; |
333 | *bit = g->drv_shift; |
334 | *width = g->drv_width; |
335 | break; |
336 | case PIN_CONFIG_SLEW_RATE: |
337 | if (g->sr_reg < 0) |
338 | return -EINVAL; |
339 | *reg = g->sr_reg; |
340 | *bit = g->sr_shift; |
341 | *width = g->sr_width; |
342 | break; |
343 | default: |
344 | return -ENOTSUPP; |
345 | } |
346 | |
347 | return 0; |
348 | } |
349 | |
350 | static int owl_group_pinconf_arg2val(const struct owl_pingroup *g, |
351 | unsigned int param, |
352 | u32 *arg) |
353 | { |
354 | switch (param) { |
355 | case PIN_CONFIG_DRIVE_STRENGTH: |
356 | switch (*arg) { |
357 | case 2: |
358 | *arg = OWL_PINCONF_DRV_2MA; |
359 | break; |
360 | case 4: |
361 | *arg = OWL_PINCONF_DRV_4MA; |
362 | break; |
363 | case 8: |
364 | *arg = OWL_PINCONF_DRV_8MA; |
365 | break; |
366 | case 12: |
367 | *arg = OWL_PINCONF_DRV_12MA; |
368 | break; |
369 | default: |
370 | return -EINVAL; |
371 | } |
372 | break; |
373 | case PIN_CONFIG_SLEW_RATE: |
374 | if (*arg) |
375 | *arg = OWL_PINCONF_SLEW_FAST; |
376 | else |
377 | *arg = OWL_PINCONF_SLEW_SLOW; |
378 | break; |
379 | default: |
380 | return -ENOTSUPP; |
381 | } |
382 | |
383 | return 0; |
384 | } |
385 | |
386 | static int owl_group_pinconf_val2arg(const struct owl_pingroup *g, |
387 | unsigned int param, |
388 | u32 *arg) |
389 | { |
390 | switch (param) { |
391 | case PIN_CONFIG_DRIVE_STRENGTH: |
392 | switch (*arg) { |
393 | case OWL_PINCONF_DRV_2MA: |
394 | *arg = 2; |
395 | break; |
396 | case OWL_PINCONF_DRV_4MA: |
397 | *arg = 4; |
398 | break; |
399 | case OWL_PINCONF_DRV_8MA: |
400 | *arg = 8; |
401 | break; |
402 | case OWL_PINCONF_DRV_12MA: |
403 | *arg = 12; |
404 | break; |
405 | default: |
406 | return -EINVAL; |
407 | } |
408 | break; |
409 | case PIN_CONFIG_SLEW_RATE: |
410 | if (*arg) |
411 | *arg = 1; |
412 | else |
413 | *arg = 0; |
414 | break; |
415 | default: |
416 | return -ENOTSUPP; |
417 | } |
418 | |
419 | return 0; |
420 | } |
421 | |
422 | static int owl_group_config_get(struct pinctrl_dev *pctrldev, |
423 | unsigned int group, |
424 | unsigned long *config) |
425 | { |
426 | const struct owl_pingroup *g; |
427 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
428 | unsigned int param = pinconf_to_config_param(config: *config); |
429 | u32 reg, bit, width, arg; |
430 | int ret; |
431 | |
432 | g = &pctrl->soc->groups[group]; |
433 | |
434 | ret = owl_group_pinconf_reg(g, param, reg: ®, bit: &bit, width: &width); |
435 | if (ret) |
436 | return ret; |
437 | |
438 | arg = owl_read_field(pctrl, reg, bit, width); |
439 | |
440 | ret = owl_group_pinconf_val2arg(g, param, arg: &arg); |
441 | if (ret) |
442 | return ret; |
443 | |
444 | *config = pinconf_to_config_packed(param, argument: arg); |
445 | |
446 | return ret; |
447 | } |
448 | |
449 | static int owl_group_config_set(struct pinctrl_dev *pctrldev, |
450 | unsigned int group, |
451 | unsigned long *configs, |
452 | unsigned int num_configs) |
453 | { |
454 | const struct owl_pingroup *g; |
455 | struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
456 | unsigned long flags; |
457 | unsigned int param; |
458 | u32 reg, bit, width, arg; |
459 | int ret, i; |
460 | |
461 | g = &pctrl->soc->groups[group]; |
462 | |
463 | for (i = 0; i < num_configs; i++) { |
464 | param = pinconf_to_config_param(config: configs[i]); |
465 | arg = pinconf_to_config_argument(config: configs[i]); |
466 | |
467 | ret = owl_group_pinconf_reg(g, param, reg: ®, bit: &bit, width: &width); |
468 | if (ret) |
469 | return ret; |
470 | |
471 | ret = owl_group_pinconf_arg2val(g, param, arg: &arg); |
472 | if (ret) |
473 | return ret; |
474 | |
475 | /* Update register */ |
476 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
477 | |
478 | owl_write_field(pctrl, reg, arg, bit, width); |
479 | |
480 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
481 | } |
482 | |
483 | return 0; |
484 | } |
485 | |
486 | static const struct pinconf_ops owl_pinconf_ops = { |
487 | .is_generic = true, |
488 | .pin_config_get = owl_pin_config_get, |
489 | .pin_config_set = owl_pin_config_set, |
490 | .pin_config_group_get = owl_group_config_get, |
491 | .pin_config_group_set = owl_group_config_set, |
492 | }; |
493 | |
494 | static struct pinctrl_desc owl_pinctrl_desc = { |
495 | .pctlops = &owl_pinctrl_ops, |
496 | .pmxops = &owl_pinmux_ops, |
497 | .confops = &owl_pinconf_ops, |
498 | .owner = THIS_MODULE, |
499 | }; |
500 | |
501 | static const struct owl_gpio_port * |
502 | owl_gpio_get_port(struct owl_pinctrl *pctrl, unsigned int *pin) |
503 | { |
504 | unsigned int start = 0, i; |
505 | |
506 | for (i = 0; i < pctrl->soc->nports; i++) { |
507 | const struct owl_gpio_port *port = &pctrl->soc->ports[i]; |
508 | |
509 | if (*pin >= start && *pin < start + port->pins) { |
510 | *pin -= start; |
511 | return port; |
512 | } |
513 | |
514 | start += port->pins; |
515 | } |
516 | |
517 | return NULL; |
518 | } |
519 | |
520 | static void owl_gpio_update_reg(void __iomem *base, unsigned int pin, int flag) |
521 | { |
522 | u32 val; |
523 | |
524 | val = readl_relaxed(base); |
525 | |
526 | if (flag) |
527 | val |= BIT(pin); |
528 | else |
529 | val &= ~BIT(pin); |
530 | |
531 | writel_relaxed(val, base); |
532 | } |
533 | |
534 | static int owl_gpio_request(struct gpio_chip *chip, unsigned int offset) |
535 | { |
536 | struct owl_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
537 | const struct owl_gpio_port *port; |
538 | void __iomem *gpio_base; |
539 | unsigned long flags; |
540 | |
541 | port = owl_gpio_get_port(pctrl, pin: &offset); |
542 | if (WARN_ON(port == NULL)) |
543 | return -ENODEV; |
544 | |
545 | gpio_base = pctrl->base + port->offset; |
546 | |
547 | /* |
548 | * GPIOs have higher priority over other modules, so either setting |
549 | * them as OUT or IN is sufficient |
550 | */ |
551 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
552 | owl_gpio_update_reg(base: gpio_base + port->outen, pin: offset, flag: true); |
553 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
554 | |
555 | return 0; |
556 | } |
557 | |
558 | static void owl_gpio_free(struct gpio_chip *chip, unsigned int offset) |
559 | { |
560 | struct owl_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
561 | const struct owl_gpio_port *port; |
562 | void __iomem *gpio_base; |
563 | unsigned long flags; |
564 | |
565 | port = owl_gpio_get_port(pctrl, pin: &offset); |
566 | if (WARN_ON(port == NULL)) |
567 | return; |
568 | |
569 | gpio_base = pctrl->base + port->offset; |
570 | |
571 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
572 | /* disable gpio output */ |
573 | owl_gpio_update_reg(base: gpio_base + port->outen, pin: offset, flag: false); |
574 | |
575 | /* disable gpio input */ |
576 | owl_gpio_update_reg(base: gpio_base + port->inen, pin: offset, flag: false); |
577 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
578 | } |
579 | |
580 | static int owl_gpio_get(struct gpio_chip *chip, unsigned int offset) |
581 | { |
582 | struct owl_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
583 | const struct owl_gpio_port *port; |
584 | void __iomem *gpio_base; |
585 | unsigned long flags; |
586 | u32 val; |
587 | |
588 | port = owl_gpio_get_port(pctrl, pin: &offset); |
589 | if (WARN_ON(port == NULL)) |
590 | return -ENODEV; |
591 | |
592 | gpio_base = pctrl->base + port->offset; |
593 | |
594 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
595 | val = readl_relaxed(gpio_base + port->dat); |
596 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
597 | |
598 | return !!(val & BIT(offset)); |
599 | } |
600 | |
601 | static void owl_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) |
602 | { |
603 | struct owl_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
604 | const struct owl_gpio_port *port; |
605 | void __iomem *gpio_base; |
606 | unsigned long flags; |
607 | |
608 | port = owl_gpio_get_port(pctrl, pin: &offset); |
609 | if (WARN_ON(port == NULL)) |
610 | return; |
611 | |
612 | gpio_base = pctrl->base + port->offset; |
613 | |
614 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
615 | owl_gpio_update_reg(base: gpio_base + port->dat, pin: offset, flag: value); |
616 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
617 | } |
618 | |
619 | static int owl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) |
620 | { |
621 | struct owl_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
622 | const struct owl_gpio_port *port; |
623 | void __iomem *gpio_base; |
624 | unsigned long flags; |
625 | |
626 | port = owl_gpio_get_port(pctrl, pin: &offset); |
627 | if (WARN_ON(port == NULL)) |
628 | return -ENODEV; |
629 | |
630 | gpio_base = pctrl->base + port->offset; |
631 | |
632 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
633 | owl_gpio_update_reg(base: gpio_base + port->outen, pin: offset, flag: false); |
634 | owl_gpio_update_reg(base: gpio_base + port->inen, pin: offset, flag: true); |
635 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
636 | |
637 | return 0; |
638 | } |
639 | |
640 | static int owl_gpio_direction_output(struct gpio_chip *chip, |
641 | unsigned int offset, int value) |
642 | { |
643 | struct owl_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
644 | const struct owl_gpio_port *port; |
645 | void __iomem *gpio_base; |
646 | unsigned long flags; |
647 | |
648 | port = owl_gpio_get_port(pctrl, pin: &offset); |
649 | if (WARN_ON(port == NULL)) |
650 | return -ENODEV; |
651 | |
652 | gpio_base = pctrl->base + port->offset; |
653 | |
654 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
655 | owl_gpio_update_reg(base: gpio_base + port->inen, pin: offset, flag: false); |
656 | owl_gpio_update_reg(base: gpio_base + port->outen, pin: offset, flag: true); |
657 | owl_gpio_update_reg(base: gpio_base + port->dat, pin: offset, flag: value); |
658 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
659 | |
660 | return 0; |
661 | } |
662 | |
663 | static void irq_set_type(struct owl_pinctrl *pctrl, int gpio, unsigned int type) |
664 | { |
665 | const struct owl_gpio_port *port; |
666 | void __iomem *gpio_base; |
667 | unsigned long flags; |
668 | unsigned int offset, value, irq_type = 0; |
669 | |
670 | switch (type) { |
671 | case IRQ_TYPE_EDGE_BOTH: |
672 | /* |
673 | * Since the hardware doesn't support interrupts on both edges, |
674 | * emulate it in the software by setting the single edge |
675 | * interrupt and switching to the opposite edge while ACKing |
676 | * the interrupt |
677 | */ |
678 | if (owl_gpio_get(chip: &pctrl->chip, offset: gpio)) |
679 | irq_type = OWL_GPIO_INT_EDGE_FALLING; |
680 | else |
681 | irq_type = OWL_GPIO_INT_EDGE_RISING; |
682 | break; |
683 | |
684 | case IRQ_TYPE_EDGE_RISING: |
685 | irq_type = OWL_GPIO_INT_EDGE_RISING; |
686 | break; |
687 | |
688 | case IRQ_TYPE_EDGE_FALLING: |
689 | irq_type = OWL_GPIO_INT_EDGE_FALLING; |
690 | break; |
691 | |
692 | case IRQ_TYPE_LEVEL_HIGH: |
693 | irq_type = OWL_GPIO_INT_LEVEL_HIGH; |
694 | break; |
695 | |
696 | case IRQ_TYPE_LEVEL_LOW: |
697 | irq_type = OWL_GPIO_INT_LEVEL_LOW; |
698 | break; |
699 | |
700 | default: |
701 | break; |
702 | } |
703 | |
704 | port = owl_gpio_get_port(pctrl, pin: &gpio); |
705 | if (WARN_ON(port == NULL)) |
706 | return; |
707 | |
708 | gpio_base = pctrl->base + port->offset; |
709 | |
710 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
711 | |
712 | offset = (gpio < 16) ? 4 : 0; |
713 | value = readl_relaxed(gpio_base + port->intc_type + offset); |
714 | value &= ~(OWL_GPIO_INT_MASK << ((gpio % 16) * 2)); |
715 | value |= irq_type << ((gpio % 16) * 2); |
716 | writel_relaxed(value, gpio_base + port->intc_type + offset); |
717 | |
718 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
719 | } |
720 | |
721 | static void owl_gpio_irq_mask(struct irq_data *data) |
722 | { |
723 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d: data); |
724 | struct owl_pinctrl *pctrl = gpiochip_get_data(gc); |
725 | irq_hw_number_t hwirq = irqd_to_hwirq(d: data); |
726 | const struct owl_gpio_port *port; |
727 | unsigned int gpio = hwirq; |
728 | void __iomem *gpio_base; |
729 | unsigned long flags; |
730 | u32 val; |
731 | |
732 | port = owl_gpio_get_port(pctrl, pin: &gpio); |
733 | if (WARN_ON(port == NULL)) |
734 | return; |
735 | |
736 | gpio_base = pctrl->base + port->offset; |
737 | |
738 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
739 | |
740 | owl_gpio_update_reg(base: gpio_base + port->intc_msk, pin: gpio, flag: false); |
741 | |
742 | /* disable port interrupt if no interrupt pending bit is active */ |
743 | val = readl_relaxed(gpio_base + port->intc_msk); |
744 | if (val == 0) |
745 | owl_gpio_update_reg(base: gpio_base + port->intc_ctl, |
746 | OWL_GPIO_CTLR_ENABLE + port->shared_ctl_offset * 5, flag: false); |
747 | |
748 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
749 | |
750 | gpiochip_disable_irq(gc, offset: hwirq); |
751 | } |
752 | |
753 | static void owl_gpio_irq_unmask(struct irq_data *data) |
754 | { |
755 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d: data); |
756 | struct owl_pinctrl *pctrl = gpiochip_get_data(gc); |
757 | irq_hw_number_t hwirq = irqd_to_hwirq(d: data); |
758 | const struct owl_gpio_port *port; |
759 | unsigned int gpio = hwirq; |
760 | void __iomem *gpio_base; |
761 | unsigned long flags; |
762 | u32 value; |
763 | |
764 | port = owl_gpio_get_port(pctrl, pin: &gpio); |
765 | if (WARN_ON(port == NULL)) |
766 | return; |
767 | |
768 | gpiochip_enable_irq(gc, offset: hwirq); |
769 | |
770 | gpio_base = pctrl->base + port->offset; |
771 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
772 | |
773 | /* enable port interrupt */ |
774 | value = readl_relaxed(gpio_base + port->intc_ctl); |
775 | value |= ((BIT(OWL_GPIO_CTLR_ENABLE) | BIT(OWL_GPIO_CTLR_SAMPLE_CLK_24M)) |
776 | << port->shared_ctl_offset * 5); |
777 | writel_relaxed(value, gpio_base + port->intc_ctl); |
778 | |
779 | /* enable GPIO interrupt */ |
780 | owl_gpio_update_reg(base: gpio_base + port->intc_msk, pin: gpio, flag: true); |
781 | |
782 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
783 | } |
784 | |
785 | static void owl_gpio_irq_ack(struct irq_data *data) |
786 | { |
787 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d: data); |
788 | struct owl_pinctrl *pctrl = gpiochip_get_data(gc); |
789 | irq_hw_number_t hwirq = irqd_to_hwirq(d: data); |
790 | const struct owl_gpio_port *port; |
791 | unsigned int gpio = hwirq; |
792 | void __iomem *gpio_base; |
793 | unsigned long flags; |
794 | |
795 | /* |
796 | * Switch the interrupt edge to the opposite edge of the interrupt |
797 | * which got triggered for the case of emulating both edges |
798 | */ |
799 | if (irqd_get_trigger_type(d: data) == IRQ_TYPE_EDGE_BOTH) { |
800 | if (owl_gpio_get(chip: gc, offset: hwirq)) |
801 | irq_set_type(pctrl, gpio: hwirq, type: IRQ_TYPE_EDGE_FALLING); |
802 | else |
803 | irq_set_type(pctrl, gpio: hwirq, type: IRQ_TYPE_EDGE_RISING); |
804 | } |
805 | |
806 | port = owl_gpio_get_port(pctrl, pin: &gpio); |
807 | if (WARN_ON(port == NULL)) |
808 | return; |
809 | |
810 | gpio_base = pctrl->base + port->offset; |
811 | |
812 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
813 | |
814 | owl_gpio_update_reg(base: gpio_base + port->intc_ctl, |
815 | OWL_GPIO_CTLR_PENDING + port->shared_ctl_offset * 5, flag: true); |
816 | |
817 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
818 | } |
819 | |
820 | static int owl_gpio_irq_set_type(struct irq_data *data, unsigned int type) |
821 | { |
822 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d: data); |
823 | struct owl_pinctrl *pctrl = gpiochip_get_data(gc); |
824 | |
825 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
826 | irq_set_handler_locked(data, handler: handle_level_irq); |
827 | else |
828 | irq_set_handler_locked(data, handler: handle_edge_irq); |
829 | |
830 | irq_set_type(pctrl, gpio: data->hwirq, type); |
831 | |
832 | return 0; |
833 | } |
834 | |
835 | static const struct irq_chip owl_gpio_irqchip = { |
836 | .name = "owl-irq" , |
837 | .irq_ack = owl_gpio_irq_ack, |
838 | .irq_mask = owl_gpio_irq_mask, |
839 | .irq_unmask = owl_gpio_irq_unmask, |
840 | .irq_set_type = owl_gpio_irq_set_type, |
841 | .flags = IRQCHIP_IMMUTABLE, |
842 | GPIOCHIP_IRQ_RESOURCE_HELPERS, |
843 | }; |
844 | |
845 | static void owl_gpio_irq_handler(struct irq_desc *desc) |
846 | { |
847 | struct owl_pinctrl *pctrl = irq_desc_get_handler_data(desc); |
848 | struct irq_chip *chip = irq_desc_get_chip(desc); |
849 | struct irq_domain *domain = pctrl->chip.irq.domain; |
850 | unsigned int parent = irq_desc_get_irq(desc); |
851 | const struct owl_gpio_port *port; |
852 | void __iomem *base; |
853 | unsigned int pin, offset = 0, i; |
854 | unsigned long pending_irq; |
855 | |
856 | chained_irq_enter(chip, desc); |
857 | |
858 | for (i = 0; i < pctrl->soc->nports; i++) { |
859 | port = &pctrl->soc->ports[i]; |
860 | base = pctrl->base + port->offset; |
861 | |
862 | /* skip ports that are not associated with this irq */ |
863 | if (parent != pctrl->irq[i]) |
864 | goto skip; |
865 | |
866 | pending_irq = readl_relaxed(base + port->intc_pd); |
867 | |
868 | for_each_set_bit(pin, &pending_irq, port->pins) { |
869 | generic_handle_domain_irq(domain, hwirq: offset + pin); |
870 | |
871 | /* clear pending interrupt */ |
872 | owl_gpio_update_reg(base: base + port->intc_pd, pin, flag: true); |
873 | } |
874 | |
875 | skip: |
876 | offset += port->pins; |
877 | } |
878 | |
879 | chained_irq_exit(chip, desc); |
880 | } |
881 | |
882 | static int owl_gpio_init(struct owl_pinctrl *pctrl) |
883 | { |
884 | struct gpio_chip *chip; |
885 | struct gpio_irq_chip *gpio_irq; |
886 | int ret, i, j, offset; |
887 | |
888 | chip = &pctrl->chip; |
889 | chip->base = -1; |
890 | chip->ngpio = pctrl->soc->ngpios; |
891 | chip->label = dev_name(dev: pctrl->dev); |
892 | chip->parent = pctrl->dev; |
893 | chip->owner = THIS_MODULE; |
894 | |
895 | gpio_irq = &chip->irq; |
896 | gpio_irq_chip_set_chip(girq: gpio_irq, chip: &owl_gpio_irqchip); |
897 | gpio_irq->handler = handle_simple_irq; |
898 | gpio_irq->default_type = IRQ_TYPE_NONE; |
899 | gpio_irq->parent_handler = owl_gpio_irq_handler; |
900 | gpio_irq->parent_handler_data = pctrl; |
901 | gpio_irq->num_parents = pctrl->num_irq; |
902 | gpio_irq->parents = pctrl->irq; |
903 | |
904 | gpio_irq->map = devm_kcalloc(dev: pctrl->dev, n: chip->ngpio, |
905 | size: sizeof(*gpio_irq->map), GFP_KERNEL); |
906 | if (!gpio_irq->map) |
907 | return -ENOMEM; |
908 | |
909 | for (i = 0, offset = 0; i < pctrl->soc->nports; i++) { |
910 | const struct owl_gpio_port *port = &pctrl->soc->ports[i]; |
911 | |
912 | for (j = 0; j < port->pins; j++) |
913 | gpio_irq->map[offset + j] = gpio_irq->parents[i]; |
914 | |
915 | offset += port->pins; |
916 | } |
917 | |
918 | ret = gpiochip_add_data(&pctrl->chip, pctrl); |
919 | if (ret) { |
920 | dev_err(pctrl->dev, "failed to register gpiochip\n" ); |
921 | return ret; |
922 | } |
923 | |
924 | return 0; |
925 | } |
926 | |
927 | int owl_pinctrl_probe(struct platform_device *pdev, |
928 | struct owl_pinctrl_soc_data *soc_data) |
929 | { |
930 | struct owl_pinctrl *pctrl; |
931 | int ret, i; |
932 | |
933 | pctrl = devm_kzalloc(dev: &pdev->dev, size: sizeof(*pctrl), GFP_KERNEL); |
934 | if (!pctrl) |
935 | return -ENOMEM; |
936 | |
937 | pctrl->base = devm_platform_ioremap_resource(pdev, index: 0); |
938 | if (IS_ERR(ptr: pctrl->base)) |
939 | return PTR_ERR(ptr: pctrl->base); |
940 | |
941 | /* enable GPIO/MFP clock */ |
942 | pctrl->clk = devm_clk_get(dev: &pdev->dev, NULL); |
943 | if (IS_ERR(ptr: pctrl->clk)) { |
944 | dev_err(&pdev->dev, "no clock defined\n" ); |
945 | return PTR_ERR(ptr: pctrl->clk); |
946 | } |
947 | |
948 | ret = clk_prepare_enable(clk: pctrl->clk); |
949 | if (ret) { |
950 | dev_err(&pdev->dev, "clk enable failed\n" ); |
951 | return ret; |
952 | } |
953 | |
954 | raw_spin_lock_init(&pctrl->lock); |
955 | |
956 | owl_pinctrl_desc.name = dev_name(dev: &pdev->dev); |
957 | owl_pinctrl_desc.pins = soc_data->pins; |
958 | owl_pinctrl_desc.npins = soc_data->npins; |
959 | |
960 | pctrl->chip.direction_input = owl_gpio_direction_input; |
961 | pctrl->chip.direction_output = owl_gpio_direction_output; |
962 | pctrl->chip.get = owl_gpio_get; |
963 | pctrl->chip.set = owl_gpio_set; |
964 | pctrl->chip.request = owl_gpio_request; |
965 | pctrl->chip.free = owl_gpio_free; |
966 | |
967 | pctrl->soc = soc_data; |
968 | pctrl->dev = &pdev->dev; |
969 | |
970 | pctrl->pctrldev = devm_pinctrl_register(dev: &pdev->dev, |
971 | pctldesc: &owl_pinctrl_desc, driver_data: pctrl); |
972 | if (IS_ERR(ptr: pctrl->pctrldev)) { |
973 | dev_err(&pdev->dev, "could not register Actions OWL pinmux driver\n" ); |
974 | ret = PTR_ERR(ptr: pctrl->pctrldev); |
975 | goto err_exit; |
976 | } |
977 | |
978 | ret = platform_irq_count(pdev); |
979 | if (ret < 0) |
980 | goto err_exit; |
981 | |
982 | pctrl->num_irq = ret; |
983 | |
984 | pctrl->irq = devm_kcalloc(dev: &pdev->dev, n: pctrl->num_irq, |
985 | size: sizeof(*pctrl->irq), GFP_KERNEL); |
986 | if (!pctrl->irq) { |
987 | ret = -ENOMEM; |
988 | goto err_exit; |
989 | } |
990 | |
991 | for (i = 0; i < pctrl->num_irq ; i++) { |
992 | ret = platform_get_irq(pdev, i); |
993 | if (ret < 0) |
994 | goto err_exit; |
995 | pctrl->irq[i] = ret; |
996 | } |
997 | |
998 | ret = owl_gpio_init(pctrl); |
999 | if (ret) |
1000 | goto err_exit; |
1001 | |
1002 | platform_set_drvdata(pdev, data: pctrl); |
1003 | |
1004 | return 0; |
1005 | |
1006 | err_exit: |
1007 | clk_disable_unprepare(clk: pctrl->clk); |
1008 | |
1009 | return ret; |
1010 | } |
1011 | |