brintos

brintos / linux-shallow public Read only

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