]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
sched: Don't scan all-offline ->cpus_allowed twice if !CONFIG_CPUSETS
[karo-tx-linux.git] / drivers / pinctrl / uniphier / pinctrl-uniphier-core.c
1 /*
2  * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include <linux/export.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/pinctrl/pinconf.h>
18 #include <linux/pinctrl/pinconf-generic.h>
19 #include <linux/pinctrl/pinctrl.h>
20 #include <linux/pinctrl/pinmux.h>
21 #include <linux/platform_device.h>
22 #include <linux/regmap.h>
23
24 #include "../core.h"
25 #include "../pinctrl-utils.h"
26 #include "pinctrl-uniphier.h"
27
28 struct uniphier_pinctrl_priv {
29         struct pinctrl_dev *pctldev;
30         struct regmap *regmap;
31         struct uniphier_pinctrl_socdata *socdata;
32 };
33
34 static int uniphier_pctl_get_groups_count(struct pinctrl_dev *pctldev)
35 {
36         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
37
38         return priv->socdata->groups_count;
39 }
40
41 static const char *uniphier_pctl_get_group_name(struct pinctrl_dev *pctldev,
42                                                 unsigned selector)
43 {
44         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
45
46         return priv->socdata->groups[selector].name;
47 }
48
49 static int uniphier_pctl_get_group_pins(struct pinctrl_dev *pctldev,
50                                         unsigned selector,
51                                         const unsigned **pins,
52                                         unsigned *num_pins)
53 {
54         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
55
56         *pins = priv->socdata->groups[selector].pins;
57         *num_pins = priv->socdata->groups[selector].num_pins;
58
59         return 0;
60 }
61
62 #ifdef CONFIG_DEBUG_FS
63 static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
64                                        struct seq_file *s, unsigned offset)
65 {
66         const struct pinctrl_pin_desc *pin = &pctldev->desc->pins[offset];
67         const char *pull_dir, *drv_str;
68
69         switch (uniphier_pin_get_pull_dir(pin->drv_data)) {
70         case UNIPHIER_PIN_PULL_UP:
71                 pull_dir = "UP";
72                 break;
73         case UNIPHIER_PIN_PULL_DOWN:
74                 pull_dir = "DOWN";
75                 break;
76         case UNIPHIER_PIN_PULL_NONE:
77                 pull_dir = "NONE";
78                 break;
79         default:
80                 BUG();
81         }
82
83         switch (uniphier_pin_get_drv_str(pin->drv_data)) {
84         case UNIPHIER_PIN_DRV_4_8:
85                 drv_str = "4/8(mA)";
86                 break;
87         case UNIPHIER_PIN_DRV_8_12_16_20:
88                 drv_str = "8/12/16/20(mA)";
89                 break;
90         case UNIPHIER_PIN_DRV_FIXED_4:
91                 drv_str = "4(mA)";
92                 break;
93         case UNIPHIER_PIN_DRV_FIXED_5:
94                 drv_str = "5(mA)";
95                 break;
96         case UNIPHIER_PIN_DRV_FIXED_8:
97                 drv_str = "8(mA)";
98                 break;
99         case UNIPHIER_PIN_DRV_NONE:
100                 drv_str = "NONE";
101                 break;
102         default:
103                 BUG();
104         }
105
106         seq_printf(s, " PULL_DIR=%s  DRV_STR=%s", pull_dir, drv_str);
107 }
108 #endif
109
110 static const struct pinctrl_ops uniphier_pctlops = {
111         .get_groups_count = uniphier_pctl_get_groups_count,
112         .get_group_name = uniphier_pctl_get_group_name,
113         .get_group_pins = uniphier_pctl_get_group_pins,
114 #ifdef CONFIG_DEBUG_FS
115         .pin_dbg_show = uniphier_pctl_pin_dbg_show,
116 #endif
117         .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
118         .dt_free_map = pinctrl_utils_dt_free_map,
119 };
120
121 static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev,
122                                       const struct pinctrl_pin_desc *pin,
123                                       enum pin_config_param param)
124 {
125         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
126         enum uniphier_pin_pull_dir pull_dir =
127                                 uniphier_pin_get_pull_dir(pin->drv_data);
128         unsigned int pupdctrl, reg, shift, val;
129         unsigned int expected = 1;
130         int ret;
131
132         switch (param) {
133         case PIN_CONFIG_BIAS_DISABLE:
134                 if (pull_dir == UNIPHIER_PIN_PULL_NONE)
135                         return 0;
136                 if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED ||
137                     pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED)
138                         return -EINVAL;
139                 expected = 0;
140                 break;
141         case PIN_CONFIG_BIAS_PULL_UP:
142                 if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED)
143                         return 0;
144                 if (pull_dir != UNIPHIER_PIN_PULL_UP)
145                         return -EINVAL;
146                 break;
147         case PIN_CONFIG_BIAS_PULL_DOWN:
148                 if (pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED)
149                         return 0;
150                 if (pull_dir != UNIPHIER_PIN_PULL_DOWN)
151                         return -EINVAL;
152                 break;
153         default:
154                 BUG();
155         }
156
157         pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data);
158
159         reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
160         shift = pupdctrl % 32;
161
162         ret = regmap_read(priv->regmap, reg, &val);
163         if (ret)
164                 return ret;
165
166         val = (val >> shift) & 1;
167
168         return (val == expected) ? 0 : -EINVAL;
169 }
170
171 static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev,
172                                        const struct pinctrl_pin_desc *pin,
173                                        u16 *strength)
174 {
175         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
176         enum uniphier_pin_drv_str drv_str =
177                                 uniphier_pin_get_drv_str(pin->drv_data);
178         const unsigned int strength_4_8[] = {4, 8};
179         const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20};
180         const unsigned int *supported_strength;
181         unsigned int drvctrl, reg, shift, mask, width, val;
182         int ret;
183
184         switch (drv_str) {
185         case UNIPHIER_PIN_DRV_4_8:
186                 supported_strength = strength_4_8;
187                 width = 1;
188                 break;
189         case UNIPHIER_PIN_DRV_8_12_16_20:
190                 supported_strength = strength_8_12_16_20;
191                 width = 2;
192                 break;
193         case UNIPHIER_PIN_DRV_FIXED_4:
194                 *strength = 4;
195                 return 0;
196         case UNIPHIER_PIN_DRV_FIXED_5:
197                 *strength = 5;
198                 return 0;
199         case UNIPHIER_PIN_DRV_FIXED_8:
200                 *strength = 8;
201                 return 0;
202         default:
203                 /* drive strength control is not supported for this pin */
204                 return -EINVAL;
205         }
206
207         drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
208         drvctrl *= width;
209
210         reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
211                              UNIPHIER_PINCTRL_DRVCTRL_BASE;
212
213         reg += drvctrl / 32 * 4;
214         shift = drvctrl % 32;
215         mask = (1U << width) - 1;
216
217         ret = regmap_read(priv->regmap, reg, &val);
218         if (ret)
219                 return ret;
220
221         *strength = supported_strength[(val >> shift) & mask];
222
223         return 0;
224 }
225
226 static int uniphier_conf_pin_input_enable_get(struct pinctrl_dev *pctldev,
227                                         const struct pinctrl_pin_desc *pin)
228 {
229         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
230         unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data);
231         unsigned int val;
232         int ret;
233
234         if (iectrl == UNIPHIER_PIN_IECTRL_NONE)
235                 /* This pin is always input-enabled. */
236                 return 0;
237
238         ret = regmap_read(priv->regmap, UNIPHIER_PINCTRL_IECTRL, &val);
239         if (ret)
240                 return ret;
241
242         return val & BIT(iectrl) ? 0 : -EINVAL;
243 }
244
245 static int uniphier_conf_pin_config_get(struct pinctrl_dev *pctldev,
246                                         unsigned pin,
247                                         unsigned long *configs)
248 {
249         const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin];
250         enum pin_config_param param = pinconf_to_config_param(*configs);
251         bool has_arg = false;
252         u16 arg;
253         int ret;
254
255         switch (param) {
256         case PIN_CONFIG_BIAS_DISABLE:
257         case PIN_CONFIG_BIAS_PULL_UP:
258         case PIN_CONFIG_BIAS_PULL_DOWN:
259                 ret = uniphier_conf_pin_bias_get(pctldev, pin_desc, param);
260                 break;
261         case PIN_CONFIG_DRIVE_STRENGTH:
262                 ret = uniphier_conf_pin_drive_get(pctldev, pin_desc, &arg);
263                 has_arg = true;
264                 break;
265         case PIN_CONFIG_INPUT_ENABLE:
266                 ret = uniphier_conf_pin_input_enable_get(pctldev, pin_desc);
267                 break;
268         default:
269                 /* unsupported parameter */
270                 ret = -EINVAL;
271                 break;
272         }
273
274         if (ret == 0 && has_arg)
275                 *configs = pinconf_to_config_packed(param, arg);
276
277         return ret;
278 }
279
280 static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev,
281                                       const struct pinctrl_pin_desc *pin,
282                                       enum pin_config_param param,
283                                       u16 arg)
284 {
285         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
286         enum uniphier_pin_pull_dir pull_dir =
287                                 uniphier_pin_get_pull_dir(pin->drv_data);
288         unsigned int pupdctrl, reg, shift;
289         unsigned int val = 1;
290
291         switch (param) {
292         case PIN_CONFIG_BIAS_DISABLE:
293                 if (pull_dir == UNIPHIER_PIN_PULL_NONE)
294                         return 0;
295                 if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED ||
296                     pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED) {
297                         dev_err(pctldev->dev,
298                                 "can not disable pull register for pin %u (%s)\n",
299                                 pin->number, pin->name);
300                         return -EINVAL;
301                 }
302                 val = 0;
303                 break;
304         case PIN_CONFIG_BIAS_PULL_UP:
305                 if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED && arg != 0)
306                         return 0;
307                 if (pull_dir != UNIPHIER_PIN_PULL_UP) {
308                         dev_err(pctldev->dev,
309                                 "pull-up is unsupported for pin %u (%s)\n",
310                                 pin->number, pin->name);
311                         return -EINVAL;
312                 }
313                 if (arg == 0) {
314                         dev_err(pctldev->dev, "pull-up can not be total\n");
315                         return -EINVAL;
316                 }
317                 break;
318         case PIN_CONFIG_BIAS_PULL_DOWN:
319                 if (pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED && arg != 0)
320                         return 0;
321                 if (pull_dir != UNIPHIER_PIN_PULL_DOWN) {
322                         dev_err(pctldev->dev,
323                                 "pull-down is unsupported for pin %u (%s)\n",
324                                 pin->number, pin->name);
325                         return -EINVAL;
326                 }
327                 if (arg == 0) {
328                         dev_err(pctldev->dev, "pull-down can not be total\n");
329                         return -EINVAL;
330                 }
331                 break;
332         case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
333                 if (pull_dir == UNIPHIER_PIN_PULL_NONE) {
334                         dev_err(pctldev->dev,
335                                 "pull-up/down is unsupported for pin %u (%s)\n",
336                                 pin->number, pin->name);
337                         return -EINVAL;
338                 }
339
340                 if (arg == 0)
341                         return 0; /* configuration ingored */
342                 break;
343         default:
344                 BUG();
345         }
346
347         pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data);
348
349         reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
350         shift = pupdctrl % 32;
351
352         return regmap_update_bits(priv->regmap, reg, 1 << shift, val << shift);
353 }
354
355 static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev,
356                                        const struct pinctrl_pin_desc *pin,
357                                        u16 strength)
358 {
359         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
360         enum uniphier_pin_drv_str drv_str =
361                                 uniphier_pin_get_drv_str(pin->drv_data);
362         const unsigned int strength_4_8[] = {4, 8, -1};
363         const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20, -1};
364         const unsigned int *supported_strength;
365         unsigned int drvctrl, reg, shift, mask, width, val;
366
367         switch (drv_str) {
368         case UNIPHIER_PIN_DRV_4_8:
369                 supported_strength = strength_4_8;
370                 width = 1;
371                 break;
372         case UNIPHIER_PIN_DRV_8_12_16_20:
373                 supported_strength = strength_8_12_16_20;
374                 width = 2;
375                 break;
376         default:
377                 dev_err(pctldev->dev,
378                         "cannot change drive strength for pin %u (%s)\n",
379                         pin->number, pin->name);
380                 return -EINVAL;
381         }
382
383         for (val = 0; supported_strength[val] > 0; val++) {
384                 if (supported_strength[val] > strength)
385                         break;
386         }
387
388         if (val == 0) {
389                 dev_err(pctldev->dev,
390                         "unsupported drive strength %u mA for pin %u (%s)\n",
391                         strength, pin->number, pin->name);
392                 return -EINVAL;
393         }
394
395         val--;
396
397         drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
398         drvctrl *= width;
399
400         reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
401                              UNIPHIER_PINCTRL_DRVCTRL_BASE;
402
403         reg += drvctrl / 32 * 4;
404         shift = drvctrl % 32;
405         mask = (1U << width) - 1;
406
407         return regmap_update_bits(priv->regmap, reg,
408                                   mask << shift, val << shift);
409 }
410
411 static int uniphier_conf_pin_input_enable(struct pinctrl_dev *pctldev,
412                                           const struct pinctrl_pin_desc *pin,
413                                           u16 enable)
414 {
415         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
416         unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data);
417
418         if (enable == 0) {
419                 /*
420                  * Multiple pins share one input enable, so per-pin disabling
421                  * is impossible.
422                  */
423                 dev_err(pctldev->dev, "unable to disable input\n");
424                 return -EINVAL;
425         }
426
427         if (iectrl == UNIPHIER_PIN_IECTRL_NONE)
428                 /* This pin is always input-enabled. nothing to do. */
429                 return 0;
430
431         return regmap_update_bits(priv->regmap, UNIPHIER_PINCTRL_IECTRL,
432                                   BIT(iectrl), BIT(iectrl));
433 }
434
435 static int uniphier_conf_pin_config_set(struct pinctrl_dev *pctldev,
436                                         unsigned pin,
437                                         unsigned long *configs,
438                                         unsigned num_configs)
439 {
440         const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin];
441         int i, ret;
442
443         for (i = 0; i < num_configs; i++) {
444                 enum pin_config_param param =
445                                         pinconf_to_config_param(configs[i]);
446                 u16 arg = pinconf_to_config_argument(configs[i]);
447
448                 switch (param) {
449                 case PIN_CONFIG_BIAS_DISABLE:
450                 case PIN_CONFIG_BIAS_PULL_UP:
451                 case PIN_CONFIG_BIAS_PULL_DOWN:
452                 case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
453                         ret = uniphier_conf_pin_bias_set(pctldev, pin_desc,
454                                                          param, arg);
455                         break;
456                 case PIN_CONFIG_DRIVE_STRENGTH:
457                         ret = uniphier_conf_pin_drive_set(pctldev, pin_desc,
458                                                           arg);
459                         break;
460                 case PIN_CONFIG_INPUT_ENABLE:
461                         ret = uniphier_conf_pin_input_enable(pctldev,
462                                                              pin_desc, arg);
463                         break;
464                 default:
465                         dev_err(pctldev->dev,
466                                 "unsupported configuration parameter %u\n",
467                                 param);
468                         return -EINVAL;
469                 }
470
471                 if (ret)
472                         return ret;
473         }
474
475         return 0;
476 }
477
478 static int uniphier_conf_pin_config_group_set(struct pinctrl_dev *pctldev,
479                                               unsigned selector,
480                                               unsigned long *configs,
481                                               unsigned num_configs)
482 {
483         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
484         const unsigned *pins = priv->socdata->groups[selector].pins;
485         unsigned num_pins = priv->socdata->groups[selector].num_pins;
486         int i, ret;
487
488         for (i = 0; i < num_pins; i++) {
489                 ret = uniphier_conf_pin_config_set(pctldev, pins[i],
490                                                    configs, num_configs);
491                 if (ret)
492                         return ret;
493         }
494
495         return 0;
496 }
497
498 static const struct pinconf_ops uniphier_confops = {
499         .is_generic = true,
500         .pin_config_get = uniphier_conf_pin_config_get,
501         .pin_config_set = uniphier_conf_pin_config_set,
502         .pin_config_group_set = uniphier_conf_pin_config_group_set,
503 };
504
505 static int uniphier_pmx_get_functions_count(struct pinctrl_dev *pctldev)
506 {
507         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
508
509         return priv->socdata->functions_count;
510 }
511
512 static const char *uniphier_pmx_get_function_name(struct pinctrl_dev *pctldev,
513                                                   unsigned selector)
514 {
515         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
516
517         return priv->socdata->functions[selector].name;
518 }
519
520 static int uniphier_pmx_get_function_groups(struct pinctrl_dev *pctldev,
521                                             unsigned selector,
522                                             const char * const **groups,
523                                             unsigned *num_groups)
524 {
525         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
526
527         *groups = priv->socdata->functions[selector].groups;
528         *num_groups = priv->socdata->functions[selector].num_groups;
529
530         return 0;
531 }
532
533 static int uniphier_pmx_set_one_mux(struct pinctrl_dev *pctldev, unsigned pin,
534                                     unsigned muxval)
535 {
536         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
537         unsigned mux_bits = priv->socdata->mux_bits;
538         unsigned reg_stride = priv->socdata->reg_stride;
539         unsigned reg, reg_end, shift, mask;
540         int ret;
541
542         reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
543         reg_end = reg + reg_stride;
544         shift = pin * mux_bits % 32;
545         mask = (1U << mux_bits) - 1;
546
547         /*
548          * If reg_stride is greater than 4, the MSB of each pinsel shall be
549          * stored in the offset+4.
550          */
551         for (; reg < reg_end; reg += 4) {
552                 ret = regmap_update_bits(priv->regmap, reg,
553                                          mask << shift, muxval << shift);
554                 if (ret)
555                         return ret;
556                 muxval >>= mux_bits;
557         }
558
559         if (priv->socdata->load_pinctrl) {
560                 ret = regmap_write(priv->regmap,
561                                    UNIPHIER_PINCTRL_LOAD_PINMUX, 1);
562                 if (ret)
563                         return ret;
564         }
565
566         /* some pins need input-enabling */
567         return uniphier_conf_pin_input_enable(pctldev,
568                                               &pctldev->desc->pins[pin], 1);
569 }
570
571 static int uniphier_pmx_set_mux(struct pinctrl_dev *pctldev,
572                                 unsigned func_selector,
573                                 unsigned group_selector)
574 {
575         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
576         const struct uniphier_pinctrl_group *grp =
577                                         &priv->socdata->groups[group_selector];
578         int i;
579         int ret;
580
581         for (i = 0; i < grp->num_pins; i++) {
582                 ret = uniphier_pmx_set_one_mux(pctldev, grp->pins[i],
583                                                grp->muxvals[i]);
584                 if (ret)
585                         return ret;
586         }
587
588         return 0;
589 }
590
591 static int uniphier_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
592                                             struct pinctrl_gpio_range *range,
593                                             unsigned offset)
594 {
595         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
596         const struct uniphier_pinctrl_group *groups = priv->socdata->groups;
597         int groups_count = priv->socdata->groups_count;
598         enum uniphier_pinmux_gpio_range_type range_type;
599         int i, j;
600
601         if (strstr(range->name, "irq"))
602                 range_type = UNIPHIER_PINMUX_GPIO_RANGE_IRQ;
603         else
604                 range_type = UNIPHIER_PINMUX_GPIO_RANGE_PORT;
605
606         for (i = 0; i < groups_count; i++) {
607                 if (groups[i].range_type != range_type)
608                         continue;
609
610                 for (j = 0; j < groups[i].num_pins; j++)
611                         if (groups[i].pins[j] == offset)
612                                 goto found;
613         }
614
615         dev_err(pctldev->dev, "pin %u does not support GPIO\n", offset);
616         return -EINVAL;
617
618 found:
619         return uniphier_pmx_set_one_mux(pctldev, offset, groups[i].muxvals[j]);
620 }
621
622 static const struct pinmux_ops uniphier_pmxops = {
623         .get_functions_count = uniphier_pmx_get_functions_count,
624         .get_function_name = uniphier_pmx_get_function_name,
625         .get_function_groups = uniphier_pmx_get_function_groups,
626         .set_mux = uniphier_pmx_set_mux,
627         .gpio_request_enable = uniphier_pmx_gpio_request_enable,
628         .strict = true,
629 };
630
631 int uniphier_pinctrl_probe(struct platform_device *pdev,
632                            struct pinctrl_desc *desc,
633                            struct uniphier_pinctrl_socdata *socdata)
634 {
635         struct device *dev = &pdev->dev;
636         struct uniphier_pinctrl_priv *priv;
637
638         if (!socdata ||
639             !socdata->groups ||
640             !socdata->groups_count ||
641             !socdata->functions ||
642             !socdata->functions_count ||
643             !socdata->mux_bits ||
644             !socdata->reg_stride) {
645                 dev_err(dev, "pinctrl socdata lacks necessary members\n");
646                 return -EINVAL;
647         }
648
649         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
650         if (!priv)
651                 return -ENOMEM;
652
653         priv->regmap = syscon_node_to_regmap(dev->of_node);
654         if (IS_ERR(priv->regmap)) {
655                 dev_err(dev, "failed to get regmap\n");
656                 return PTR_ERR(priv->regmap);
657         }
658
659         priv->socdata = socdata;
660         desc->pctlops = &uniphier_pctlops;
661         desc->pmxops = &uniphier_pmxops;
662         desc->confops = &uniphier_confops;
663
664         priv->pctldev = pinctrl_register(desc, dev, priv);
665         if (IS_ERR(priv->pctldev)) {
666                 dev_err(dev, "failed to register UniPhier pinctrl driver\n");
667                 return PTR_ERR(priv->pctldev);
668         }
669
670         platform_set_drvdata(pdev, priv);
671
672         return 0;
673 }
674 EXPORT_SYMBOL_GPL(uniphier_pinctrl_probe);
675
676 int uniphier_pinctrl_remove(struct platform_device *pdev)
677 {
678         struct uniphier_pinctrl_priv *priv = platform_get_drvdata(pdev);
679
680         pinctrl_unregister(priv->pctldev);
681
682         return 0;
683 }
684 EXPORT_SYMBOL_GPL(uniphier_pinctrl_remove);