]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
Merge branch 'ras-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[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         /* some pins need input-enabling */
543         ret = uniphier_conf_pin_input_enable(pctldev,
544                                              &pctldev->desc->pins[pin], 1);
545         if (ret)
546                 return ret;
547
548         reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
549         reg_end = reg + reg_stride;
550         shift = pin * mux_bits % 32;
551         mask = (1U << mux_bits) - 1;
552
553         /*
554          * If reg_stride is greater than 4, the MSB of each pinsel shall be
555          * stored in the offset+4.
556          */
557         for (; reg < reg_end; reg += 4) {
558                 ret = regmap_update_bits(priv->regmap, reg,
559                                          mask << shift, muxval << shift);
560                 if (ret)
561                         return ret;
562                 muxval >>= mux_bits;
563         }
564
565         if (priv->socdata->load_pinctrl) {
566                 ret = regmap_write(priv->regmap,
567                                    UNIPHIER_PINCTRL_LOAD_PINMUX, 1);
568                 if (ret)
569                         return ret;
570         }
571
572         return 0;
573 }
574
575 static int uniphier_pmx_set_mux(struct pinctrl_dev *pctldev,
576                                 unsigned func_selector,
577                                 unsigned group_selector)
578 {
579         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
580         const struct uniphier_pinctrl_group *grp =
581                                         &priv->socdata->groups[group_selector];
582         int i;
583         int ret;
584
585         for (i = 0; i < grp->num_pins; i++) {
586                 ret = uniphier_pmx_set_one_mux(pctldev, grp->pins[i],
587                                                grp->muxvals[i]);
588                 if (ret)
589                         return ret;
590         }
591
592         return 0;
593 }
594
595 static int uniphier_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
596                                             struct pinctrl_gpio_range *range,
597                                             unsigned offset)
598 {
599         struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
600         const struct uniphier_pinctrl_group *groups = priv->socdata->groups;
601         int groups_count = priv->socdata->groups_count;
602         enum uniphier_pinmux_gpio_range_type range_type;
603         int i, j;
604
605         if (strstr(range->name, "irq"))
606                 range_type = UNIPHIER_PINMUX_GPIO_RANGE_IRQ;
607         else
608                 range_type = UNIPHIER_PINMUX_GPIO_RANGE_PORT;
609
610         for (i = 0; i < groups_count; i++) {
611                 if (groups[i].range_type != range_type)
612                         continue;
613
614                 for (j = 0; j < groups[i].num_pins; j++)
615                         if (groups[i].pins[j] == offset)
616                                 goto found;
617         }
618
619         dev_err(pctldev->dev, "pin %u does not support GPIO\n", offset);
620         return -EINVAL;
621
622 found:
623         return uniphier_pmx_set_one_mux(pctldev, offset, groups[i].muxvals[j]);
624 }
625
626 static const struct pinmux_ops uniphier_pmxops = {
627         .get_functions_count = uniphier_pmx_get_functions_count,
628         .get_function_name = uniphier_pmx_get_function_name,
629         .get_function_groups = uniphier_pmx_get_function_groups,
630         .set_mux = uniphier_pmx_set_mux,
631         .gpio_request_enable = uniphier_pmx_gpio_request_enable,
632         .strict = true,
633 };
634
635 int uniphier_pinctrl_probe(struct platform_device *pdev,
636                            struct pinctrl_desc *desc,
637                            struct uniphier_pinctrl_socdata *socdata)
638 {
639         struct device *dev = &pdev->dev;
640         struct uniphier_pinctrl_priv *priv;
641
642         if (!socdata ||
643             !socdata->groups ||
644             !socdata->groups_count ||
645             !socdata->functions ||
646             !socdata->functions_count ||
647             !socdata->mux_bits ||
648             !socdata->reg_stride) {
649                 dev_err(dev, "pinctrl socdata lacks necessary members\n");
650                 return -EINVAL;
651         }
652
653         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
654         if (!priv)
655                 return -ENOMEM;
656
657         priv->regmap = syscon_node_to_regmap(dev->of_node);
658         if (IS_ERR(priv->regmap)) {
659                 dev_err(dev, "failed to get regmap\n");
660                 return PTR_ERR(priv->regmap);
661         }
662
663         priv->socdata = socdata;
664         desc->pctlops = &uniphier_pctlops;
665         desc->pmxops = &uniphier_pmxops;
666         desc->confops = &uniphier_confops;
667
668         priv->pctldev = pinctrl_register(desc, dev, priv);
669         if (IS_ERR(priv->pctldev)) {
670                 dev_err(dev, "failed to register UniPhier pinctrl driver\n");
671                 return PTR_ERR(priv->pctldev);
672         }
673
674         platform_set_drvdata(pdev, priv);
675
676         return 0;
677 }
678 EXPORT_SYMBOL_GPL(uniphier_pinctrl_probe);
679
680 int uniphier_pinctrl_remove(struct platform_device *pdev)
681 {
682         struct uniphier_pinctrl_priv *priv = platform_get_drvdata(pdev);
683
684         pinctrl_unregister(priv->pctldev);
685
686         return 0;
687 }
688 EXPORT_SYMBOL_GPL(uniphier_pinctrl_remove);