1/*
2 * Marvell MVEBU pinctrl core driver
3 *
4 * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 *          Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/platform_device.h>
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/io.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <linux/of_platform.h>
20#include <linux/err.h>
21#include <linux/gpio.h>
22#include <linux/pinctrl/machine.h>
23#include <linux/pinctrl/pinconf.h>
24#include <linux/pinctrl/pinctrl.h>
25#include <linux/pinctrl/pinmux.h>
26
27#include "pinctrl-mvebu.h"
28
29#define MPPS_PER_REG	8
30#define MPP_BITS	4
31#define MPP_MASK	0xf
32
33struct mvebu_pinctrl_function {
34	const char *name;
35	const char **groups;
36	unsigned num_groups;
37};
38
39struct mvebu_pinctrl_group {
40	const char *name;
41	struct mvebu_mpp_ctrl *ctrl;
42	struct mvebu_mpp_ctrl_setting *settings;
43	unsigned num_settings;
44	unsigned gid;
45	unsigned *pins;
46	unsigned npins;
47};
48
49struct mvebu_pinctrl {
50	struct device *dev;
51	struct pinctrl_dev *pctldev;
52	struct pinctrl_desc desc;
53	struct mvebu_pinctrl_group *groups;
54	unsigned num_groups;
55	struct mvebu_pinctrl_function *functions;
56	unsigned num_functions;
57	u8 variant;
58};
59
60static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_pid(
61	struct mvebu_pinctrl *pctl, unsigned pid)
62{
63	unsigned n;
64	for (n = 0; n < pctl->num_groups; n++) {
65		if (pid >= pctl->groups[n].pins[0] &&
66		    pid < pctl->groups[n].pins[0] +
67			pctl->groups[n].npins)
68			return &pctl->groups[n];
69	}
70	return NULL;
71}
72
73static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_name(
74	struct mvebu_pinctrl *pctl, const char *name)
75{
76	unsigned n;
77	for (n = 0; n < pctl->num_groups; n++) {
78		if (strcmp(name, pctl->groups[n].name) == 0)
79			return &pctl->groups[n];
80	}
81	return NULL;
82}
83
84static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_val(
85	struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
86	unsigned long config)
87{
88	unsigned n;
89	for (n = 0; n < grp->num_settings; n++) {
90		if (config == grp->settings[n].val) {
91			if (!pctl->variant || (pctl->variant &
92					       grp->settings[n].variant))
93				return &grp->settings[n];
94		}
95	}
96	return NULL;
97}
98
99static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_name(
100	struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
101	const char *name)
102{
103	unsigned n;
104	for (n = 0; n < grp->num_settings; n++) {
105		if (strcmp(name, grp->settings[n].name) == 0) {
106			if (!pctl->variant || (pctl->variant &
107					       grp->settings[n].variant))
108				return &grp->settings[n];
109		}
110	}
111	return NULL;
112}
113
114static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_gpio_setting(
115	struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp)
116{
117	unsigned n;
118	for (n = 0; n < grp->num_settings; n++) {
119		if (grp->settings[n].flags &
120			(MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
121			if (!pctl->variant || (pctl->variant &
122						grp->settings[n].variant))
123				return &grp->settings[n];
124		}
125	}
126	return NULL;
127}
128
129static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name(
130	struct mvebu_pinctrl *pctl, const char *name)
131{
132	unsigned n;
133	for (n = 0; n < pctl->num_functions; n++) {
134		if (strcmp(name, pctl->functions[n].name) == 0)
135			return &pctl->functions[n];
136	}
137	return NULL;
138}
139
140static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
141				unsigned gid, unsigned long *config)
142{
143	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
144	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
145
146	if (!grp->ctrl)
147		return -EINVAL;
148
149	return grp->ctrl->mpp_get(grp->pins[0], config);
150}
151
152static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
153				unsigned gid, unsigned long *configs,
154				unsigned num_configs)
155{
156	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
157	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
158	int i, ret;
159
160	if (!grp->ctrl)
161		return -EINVAL;
162
163	for (i = 0; i < num_configs; i++) {
164		ret = grp->ctrl->mpp_set(grp->pins[0], configs[i]);
165		if (ret)
166			return ret;
167	} /* for each config */
168
169	return 0;
170}
171
172static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
173					struct seq_file *s, unsigned gid)
174{
175	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
176	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
177	struct mvebu_mpp_ctrl_setting *curr;
178	unsigned long config;
179	unsigned n;
180
181	if (mvebu_pinconf_group_get(pctldev, gid, &config))
182		return;
183
184	curr = mvebu_pinctrl_find_setting_by_val(pctl, grp, config);
185
186	if (curr) {
187		seq_printf(s, "current: %s", curr->name);
188		if (curr->subname)
189			seq_printf(s, "(%s)", curr->subname);
190		if (curr->flags & (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
191			seq_printf(s, "(");
192			if (curr->flags & MVEBU_SETTING_GPI)
193				seq_printf(s, "i");
194			if (curr->flags & MVEBU_SETTING_GPO)
195				seq_printf(s, "o");
196			seq_printf(s, ")");
197		}
198	} else
199		seq_printf(s, "current: UNKNOWN");
200
201	if (grp->num_settings > 1) {
202		seq_printf(s, ", available = [");
203		for (n = 0; n < grp->num_settings; n++) {
204			if (curr == &grp->settings[n])
205				continue;
206
207			/* skip unsupported settings for this variant */
208			if (pctl->variant &&
209			    !(pctl->variant & grp->settings[n].variant))
210				continue;
211
212			seq_printf(s, " %s", grp->settings[n].name);
213			if (grp->settings[n].subname)
214				seq_printf(s, "(%s)", grp->settings[n].subname);
215			if (grp->settings[n].flags &
216				(MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
217				seq_printf(s, "(");
218				if (grp->settings[n].flags & MVEBU_SETTING_GPI)
219					seq_printf(s, "i");
220				if (grp->settings[n].flags & MVEBU_SETTING_GPO)
221					seq_printf(s, "o");
222				seq_printf(s, ")");
223			}
224		}
225		seq_printf(s, " ]");
226	}
227	return;
228}
229
230static const struct pinconf_ops mvebu_pinconf_ops = {
231	.pin_config_group_get = mvebu_pinconf_group_get,
232	.pin_config_group_set = mvebu_pinconf_group_set,
233	.pin_config_group_dbg_show = mvebu_pinconf_group_dbg_show,
234};
235
236static int mvebu_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
237{
238	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
239
240	return pctl->num_functions;
241}
242
243static const char *mvebu_pinmux_get_func_name(struct pinctrl_dev *pctldev,
244					unsigned fid)
245{
246	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
247
248	return pctl->functions[fid].name;
249}
250
251static int mvebu_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned fid,
252				const char * const **groups,
253				unsigned * const num_groups)
254{
255	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
256
257	*groups = pctl->functions[fid].groups;
258	*num_groups = pctl->functions[fid].num_groups;
259	return 0;
260}
261
262static int mvebu_pinmux_set(struct pinctrl_dev *pctldev, unsigned fid,
263			    unsigned gid)
264{
265	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
266	struct mvebu_pinctrl_function *func = &pctl->functions[fid];
267	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
268	struct mvebu_mpp_ctrl_setting *setting;
269	int ret;
270	unsigned long config;
271
272	setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
273						     func->name);
274	if (!setting) {
275		dev_err(pctl->dev,
276			"unable to find setting %s in group %s\n",
277			func->name, func->groups[gid]);
278		return -EINVAL;
279	}
280
281	config = setting->val;
282	ret = mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
283	if (ret) {
284		dev_err(pctl->dev, "cannot set group %s to %s\n",
285			func->groups[gid], func->name);
286		return ret;
287	}
288
289	return 0;
290}
291
292static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
293			struct pinctrl_gpio_range *range, unsigned offset)
294{
295	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
296	struct mvebu_pinctrl_group *grp;
297	struct mvebu_mpp_ctrl_setting *setting;
298	unsigned long config;
299
300	grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
301	if (!grp)
302		return -EINVAL;
303
304	if (grp->ctrl->mpp_gpio_req)
305		return grp->ctrl->mpp_gpio_req(offset);
306
307	setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
308	if (!setting)
309		return -ENOTSUPP;
310
311	config = setting->val;
312
313	return mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
314}
315
316static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
317	   struct pinctrl_gpio_range *range, unsigned offset, bool input)
318{
319	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
320	struct mvebu_pinctrl_group *grp;
321	struct mvebu_mpp_ctrl_setting *setting;
322
323	grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
324	if (!grp)
325		return -EINVAL;
326
327	if (grp->ctrl->mpp_gpio_dir)
328		return grp->ctrl->mpp_gpio_dir(offset, input);
329
330	setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
331	if (!setting)
332		return -ENOTSUPP;
333
334	if ((input && (setting->flags & MVEBU_SETTING_GPI)) ||
335	    (!input && (setting->flags & MVEBU_SETTING_GPO)))
336		return 0;
337
338	return -ENOTSUPP;
339}
340
341static const struct pinmux_ops mvebu_pinmux_ops = {
342	.get_functions_count = mvebu_pinmux_get_funcs_count,
343	.get_function_name = mvebu_pinmux_get_func_name,
344	.get_function_groups = mvebu_pinmux_get_groups,
345	.gpio_request_enable = mvebu_pinmux_gpio_request_enable,
346	.gpio_set_direction = mvebu_pinmux_gpio_set_direction,
347	.set_mux = mvebu_pinmux_set,
348};
349
350static int mvebu_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
351{
352	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
353	return pctl->num_groups;
354}
355
356static const char *mvebu_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
357						unsigned gid)
358{
359	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
360	return pctl->groups[gid].name;
361}
362
363static int mvebu_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
364					unsigned gid, const unsigned **pins,
365					unsigned *num_pins)
366{
367	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
368	*pins = pctl->groups[gid].pins;
369	*num_pins = pctl->groups[gid].npins;
370	return 0;
371}
372
373static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
374					struct device_node *np,
375					struct pinctrl_map **map,
376					unsigned *num_maps)
377{
378	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
379	struct property *prop;
380	const char *function;
381	const char *group;
382	int ret, nmaps, n;
383
384	*map = NULL;
385	*num_maps = 0;
386
387	ret = of_property_read_string(np, "marvell,function", &function);
388	if (ret) {
389		dev_err(pctl->dev,
390			"missing marvell,function in node %s\n", np->name);
391		return 0;
392	}
393
394	nmaps = of_property_count_strings(np, "marvell,pins");
395	if (nmaps < 0) {
396		dev_err(pctl->dev,
397			"missing marvell,pins in node %s\n", np->name);
398		return 0;
399	}
400
401	*map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL);
402	if (*map == NULL) {
403		dev_err(pctl->dev,
404			"cannot allocate pinctrl_map memory for %s\n",
405			np->name);
406		return -ENOMEM;
407	}
408
409	n = 0;
410	of_property_for_each_string(np, "marvell,pins", prop, group) {
411		struct mvebu_pinctrl_group *grp =
412			mvebu_pinctrl_find_group_by_name(pctl, group);
413
414		if (!grp) {
415			dev_err(pctl->dev, "unknown pin %s", group);
416			continue;
417		}
418
419		if (!mvebu_pinctrl_find_setting_by_name(pctl, grp, function)) {
420			dev_err(pctl->dev, "unsupported function %s on pin %s",
421				function, group);
422			continue;
423		}
424
425		(*map)[n].type = PIN_MAP_TYPE_MUX_GROUP;
426		(*map)[n].data.mux.group = group;
427		(*map)[n].data.mux.function = function;
428		n++;
429	}
430
431	*num_maps = nmaps;
432
433	return 0;
434}
435
436static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
437				struct pinctrl_map *map, unsigned num_maps)
438{
439	kfree(map);
440}
441
442static const struct pinctrl_ops mvebu_pinctrl_ops = {
443	.get_groups_count = mvebu_pinctrl_get_groups_count,
444	.get_group_name = mvebu_pinctrl_get_group_name,
445	.get_group_pins = mvebu_pinctrl_get_group_pins,
446	.dt_node_to_map = mvebu_pinctrl_dt_node_to_map,
447	.dt_free_map = mvebu_pinctrl_dt_free_map,
448};
449
450static int _add_function(struct mvebu_pinctrl_function *funcs, int *funcsize,
451			const char *name)
452{
453	if (*funcsize <= 0)
454		return -EOVERFLOW;
455
456	while (funcs->num_groups) {
457		/* function already there */
458		if (strcmp(funcs->name, name) == 0) {
459			funcs->num_groups++;
460			return -EEXIST;
461		}
462		funcs++;
463	}
464
465	/* append new unique function */
466	funcs->name = name;
467	funcs->num_groups = 1;
468	(*funcsize)--;
469
470	return 0;
471}
472
473static int mvebu_pinctrl_build_functions(struct platform_device *pdev,
474					 struct mvebu_pinctrl *pctl)
475{
476	struct mvebu_pinctrl_function *funcs;
477	int num = 0, funcsize = pctl->desc.npins;
478	int n, s;
479
480	/* we allocate functions for number of pins and hope
481	 * there are fewer unique functions than pins available */
482	funcs = devm_kzalloc(&pdev->dev, funcsize *
483			     sizeof(struct mvebu_pinctrl_function), GFP_KERNEL);
484	if (!funcs)
485		return -ENOMEM;
486
487	for (n = 0; n < pctl->num_groups; n++) {
488		struct mvebu_pinctrl_group *grp = &pctl->groups[n];
489		for (s = 0; s < grp->num_settings; s++) {
490			int ret;
491
492			/* skip unsupported settings on this variant */
493			if (pctl->variant &&
494			    !(pctl->variant & grp->settings[s].variant))
495				continue;
496
497			/* check for unique functions and count groups */
498			ret = _add_function(funcs, &funcsize,
499					    grp->settings[s].name);
500			if (ret == -EOVERFLOW)
501				dev_err(&pdev->dev,
502					"More functions than pins(%d)\n",
503					pctl->desc.npins);
504			if (ret < 0)
505				continue;
506
507			num++;
508		}
509	}
510
511	pctl->num_functions = num;
512	pctl->functions = funcs;
513
514	for (n = 0; n < pctl->num_groups; n++) {
515		struct mvebu_pinctrl_group *grp = &pctl->groups[n];
516		for (s = 0; s < grp->num_settings; s++) {
517			struct mvebu_pinctrl_function *f;
518			const char **groups;
519
520			/* skip unsupported settings on this variant */
521			if (pctl->variant &&
522			    !(pctl->variant & grp->settings[s].variant))
523				continue;
524
525			f = mvebu_pinctrl_find_function_by_name(pctl,
526							grp->settings[s].name);
527
528			/* allocate group name array if not done already */
529			if (!f->groups) {
530				f->groups = devm_kzalloc(&pdev->dev,
531						 f->num_groups * sizeof(char *),
532						 GFP_KERNEL);
533				if (!f->groups)
534					return -ENOMEM;
535			}
536
537			/* find next free group name and assign current name */
538			groups = f->groups;
539			while (*groups)
540				groups++;
541			*groups = grp->name;
542		}
543	}
544
545	return 0;
546}
547
548int mvebu_pinctrl_probe(struct platform_device *pdev)
549{
550	struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
551	struct mvebu_pinctrl *pctl;
552	struct pinctrl_pin_desc *pdesc;
553	unsigned gid, n, k;
554	unsigned size, noname = 0;
555	char *noname_buf;
556	void *p;
557	int ret;
558
559	if (!soc || !soc->controls || !soc->modes) {
560		dev_err(&pdev->dev, "wrong pinctrl soc info\n");
561		return -EINVAL;
562	}
563
564	pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl),
565			GFP_KERNEL);
566	if (!pctl) {
567		dev_err(&pdev->dev, "unable to alloc driver\n");
568		return -ENOMEM;
569	}
570
571	pctl->desc.name = dev_name(&pdev->dev);
572	pctl->desc.owner = THIS_MODULE;
573	pctl->desc.pctlops = &mvebu_pinctrl_ops;
574	pctl->desc.pmxops = &mvebu_pinmux_ops;
575	pctl->desc.confops = &mvebu_pinconf_ops;
576	pctl->variant = soc->variant;
577	pctl->dev = &pdev->dev;
578	platform_set_drvdata(pdev, pctl);
579
580	/* count controls and create names for mvebu generic
581	   register controls; also does sanity checks */
582	pctl->num_groups = 0;
583	pctl->desc.npins = 0;
584	for (n = 0; n < soc->ncontrols; n++) {
585		struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
586
587		pctl->desc.npins += ctrl->npins;
588		/* initialize control's pins[] array */
589		for (k = 0; k < ctrl->npins; k++)
590			ctrl->pins[k] = ctrl->pid + k;
591
592		/*
593		 * We allow to pass controls with NULL name that we treat
594		 * as a range of one-pin groups with generic mvebu register
595		 * controls.
596		 */
597		if (!ctrl->name) {
598			pctl->num_groups += ctrl->npins;
599			noname += ctrl->npins;
600		} else {
601			pctl->num_groups += 1;
602		}
603	}
604
605	pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins *
606			     sizeof(struct pinctrl_pin_desc), GFP_KERNEL);
607	if (!pdesc) {
608		dev_err(&pdev->dev, "failed to alloc pinctrl pins\n");
609		return -ENOMEM;
610	}
611
612	for (n = 0; n < pctl->desc.npins; n++)
613		pdesc[n].number = n;
614	pctl->desc.pins = pdesc;
615
616	/*
617	 * allocate groups and name buffers for unnamed groups.
618	 */
619	size = pctl->num_groups * sizeof(*pctl->groups) + noname * 8;
620	p = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
621	if (!p) {
622		dev_err(&pdev->dev, "failed to alloc group data\n");
623		return -ENOMEM;
624	}
625	pctl->groups = p;
626	noname_buf = p + pctl->num_groups * sizeof(*pctl->groups);
627
628	/* assign mpp controls to groups */
629	gid = 0;
630	for (n = 0; n < soc->ncontrols; n++) {
631		struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
632		pctl->groups[gid].gid = gid;
633		pctl->groups[gid].ctrl = ctrl;
634		pctl->groups[gid].name = ctrl->name;
635		pctl->groups[gid].pins = ctrl->pins;
636		pctl->groups[gid].npins = ctrl->npins;
637
638		/*
639		 * We treat unnamed controls as a range of one-pin groups
640		 * with generic mvebu register controls. Use one group for
641		 * each in this range and assign a default group name.
642		 */
643		if (!ctrl->name) {
644			pctl->groups[gid].name = noname_buf;
645			pctl->groups[gid].npins = 1;
646			sprintf(noname_buf, "mpp%d", ctrl->pid+0);
647			noname_buf += 8;
648
649			for (k = 1; k < ctrl->npins; k++) {
650				gid++;
651				pctl->groups[gid].gid = gid;
652				pctl->groups[gid].ctrl = ctrl;
653				pctl->groups[gid].name = noname_buf;
654				pctl->groups[gid].pins = &ctrl->pins[k];
655				pctl->groups[gid].npins = 1;
656				sprintf(noname_buf, "mpp%d", ctrl->pid+k);
657				noname_buf += 8;
658			}
659		}
660		gid++;
661	}
662
663	/* assign mpp modes to groups */
664	for (n = 0; n < soc->nmodes; n++) {
665		struct mvebu_mpp_mode *mode = &soc->modes[n];
666		struct mvebu_pinctrl_group *grp =
667			mvebu_pinctrl_find_group_by_pid(pctl, mode->pid);
668		unsigned num_settings;
669
670		if (!grp) {
671			dev_warn(&pdev->dev, "unknown pinctrl group %d\n",
672				mode->pid);
673			continue;
674		}
675
676		for (num_settings = 0; ;) {
677			struct mvebu_mpp_ctrl_setting *set =
678				&mode->settings[num_settings];
679
680			if (!set->name)
681				break;
682			num_settings++;
683
684			/* skip unsupported settings for this variant */
685			if (pctl->variant && !(pctl->variant & set->variant))
686				continue;
687
688			/* find gpio/gpo/gpi settings */
689			if (strcmp(set->name, "gpio") == 0)
690				set->flags = MVEBU_SETTING_GPI |
691					MVEBU_SETTING_GPO;
692			else if (strcmp(set->name, "gpo") == 0)
693				set->flags = MVEBU_SETTING_GPO;
694			else if (strcmp(set->name, "gpi") == 0)
695				set->flags = MVEBU_SETTING_GPI;
696		}
697
698		grp->settings = mode->settings;
699		grp->num_settings = num_settings;
700	}
701
702	ret = mvebu_pinctrl_build_functions(pdev, pctl);
703	if (ret) {
704		dev_err(&pdev->dev, "unable to build functions\n");
705		return ret;
706	}
707
708	pctl->pctldev = pinctrl_register(&pctl->desc, &pdev->dev, pctl);
709	if (!pctl->pctldev) {
710		dev_err(&pdev->dev, "unable to register pinctrl driver\n");
711		return -EINVAL;
712	}
713
714	dev_info(&pdev->dev, "registered pinctrl driver\n");
715
716	/* register gpio ranges */
717	for (n = 0; n < soc->ngpioranges; n++)
718		pinctrl_add_gpio_range(pctl->pctldev, &soc->gpioranges[n]);
719
720	return 0;
721}
722
723int mvebu_pinctrl_remove(struct platform_device *pdev)
724{
725	struct mvebu_pinctrl *pctl = platform_get_drvdata(pdev);
726	pinctrl_unregister(pctl->pctldev);
727	return 0;
728}
729