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