[go: nahoru, domu]

1/*
2 * Driver for the NVIDIA Tegra pinmux
3 *
4 * Copyright (c) 2011-2012, NVIDIA CORPORATION.  All rights reserved.
5 *
6 * Derived from code:
7 * Copyright (C) 2010 Google, Inc.
8 * Copyright (C) 2010 NVIDIA Corporation
9 * Copyright (C) 2009-2011 ST-Ericsson AB
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms and conditions of the GNU General Public License,
13 * version 2, as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18 * more details.
19 */
20
21#include <linux/err.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <linux/module.h>
25#include <linux/of.h>
26#include <linux/platform_device.h>
27#include <linux/pinctrl/machine.h>
28#include <linux/pinctrl/pinctrl.h>
29#include <linux/pinctrl/pinmux.h>
30#include <linux/pinctrl/pinconf.h>
31#include <linux/slab.h>
32
33#include "core.h"
34#include "pinctrl-tegra.h"
35#include "pinctrl-utils.h"
36
37struct tegra_pmx {
38	struct device *dev;
39	struct pinctrl_dev *pctl;
40
41	const struct tegra_pinctrl_soc_data *soc;
42	const char **group_pins;
43
44	int nbanks;
45	void __iomem **regs;
46};
47
48static inline u32 pmx_readl(struct tegra_pmx *pmx, u32 bank, u32 reg)
49{
50	return readl(pmx->regs[bank] + reg);
51}
52
53static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg)
54{
55	writel(val, pmx->regs[bank] + reg);
56}
57
58static int tegra_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
59{
60	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
61
62	return pmx->soc->ngroups;
63}
64
65static const char *tegra_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
66						unsigned group)
67{
68	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
69
70	return pmx->soc->groups[group].name;
71}
72
73static int tegra_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
74					unsigned group,
75					const unsigned **pins,
76					unsigned *num_pins)
77{
78	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
79
80	*pins = pmx->soc->groups[group].pins;
81	*num_pins = pmx->soc->groups[group].npins;
82
83	return 0;
84}
85
86#ifdef CONFIG_DEBUG_FS
87static void tegra_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
88				       struct seq_file *s,
89				       unsigned offset)
90{
91	seq_printf(s, " %s", dev_name(pctldev->dev));
92}
93#endif
94
95static const struct cfg_param {
96	const char *property;
97	enum tegra_pinconf_param param;
98} cfg_params[] = {
99	{"nvidia,pull",			TEGRA_PINCONF_PARAM_PULL},
100	{"nvidia,tristate",		TEGRA_PINCONF_PARAM_TRISTATE},
101	{"nvidia,enable-input",		TEGRA_PINCONF_PARAM_ENABLE_INPUT},
102	{"nvidia,open-drain",		TEGRA_PINCONF_PARAM_OPEN_DRAIN},
103	{"nvidia,lock",			TEGRA_PINCONF_PARAM_LOCK},
104	{"nvidia,io-reset",		TEGRA_PINCONF_PARAM_IORESET},
105	{"nvidia,rcv-sel",		TEGRA_PINCONF_PARAM_RCV_SEL},
106	{"nvidia,high-speed-mode",	TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE},
107	{"nvidia,schmitt",		TEGRA_PINCONF_PARAM_SCHMITT},
108	{"nvidia,low-power-mode",	TEGRA_PINCONF_PARAM_LOW_POWER_MODE},
109	{"nvidia,pull-down-strength",	TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH},
110	{"nvidia,pull-up-strength",	TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH},
111	{"nvidia,slew-rate-falling",	TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING},
112	{"nvidia,slew-rate-rising",	TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
113	{"nvidia,drive-type",		TEGRA_PINCONF_PARAM_DRIVE_TYPE},
114};
115
116static int tegra_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
117					   struct device_node *np,
118					   struct pinctrl_map **map,
119					   unsigned *reserved_maps,
120					   unsigned *num_maps)
121{
122	struct device *dev = pctldev->dev;
123	int ret, i;
124	const char *function;
125	u32 val;
126	unsigned long config;
127	unsigned long *configs = NULL;
128	unsigned num_configs = 0;
129	unsigned reserve;
130	struct property *prop;
131	const char *group;
132
133	ret = of_property_read_string(np, "nvidia,function", &function);
134	if (ret < 0) {
135		/* EINVAL=missing, which is fine since it's optional */
136		if (ret != -EINVAL)
137			dev_err(dev,
138				"could not parse property nvidia,function\n");
139		function = NULL;
140	}
141
142	for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
143		ret = of_property_read_u32(np, cfg_params[i].property, &val);
144		if (!ret) {
145			config = TEGRA_PINCONF_PACK(cfg_params[i].param, val);
146			ret = pinctrl_utils_add_config(pctldev, &configs,
147					&num_configs, config);
148			if (ret < 0)
149				goto exit;
150		/* EINVAL=missing, which is fine since it's optional */
151		} else if (ret != -EINVAL) {
152			dev_err(dev, "could not parse property %s\n",
153				cfg_params[i].property);
154		}
155	}
156
157	reserve = 0;
158	if (function != NULL)
159		reserve++;
160	if (num_configs)
161		reserve++;
162	ret = of_property_count_strings(np, "nvidia,pins");
163	if (ret < 0) {
164		dev_err(dev, "could not parse property nvidia,pins\n");
165		goto exit;
166	}
167	reserve *= ret;
168
169	ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps,
170					num_maps, reserve);
171	if (ret < 0)
172		goto exit;
173
174	of_property_for_each_string(np, "nvidia,pins", prop, group) {
175		if (function) {
176			ret = pinctrl_utils_add_map_mux(pctldev, map,
177					reserved_maps, num_maps, group,
178					function);
179			if (ret < 0)
180				goto exit;
181		}
182
183		if (num_configs) {
184			ret = pinctrl_utils_add_map_configs(pctldev, map,
185					reserved_maps, num_maps, group,
186					configs, num_configs,
187					PIN_MAP_TYPE_CONFIGS_GROUP);
188			if (ret < 0)
189				goto exit;
190		}
191	}
192
193	ret = 0;
194
195exit:
196	kfree(configs);
197	return ret;
198}
199
200static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
201					struct device_node *np_config,
202					struct pinctrl_map **map,
203					unsigned *num_maps)
204{
205	unsigned reserved_maps;
206	struct device_node *np;
207	int ret;
208
209	reserved_maps = 0;
210	*map = NULL;
211	*num_maps = 0;
212
213	for_each_child_of_node(np_config, np) {
214		ret = tegra_pinctrl_dt_subnode_to_map(pctldev, np, map,
215						      &reserved_maps, num_maps);
216		if (ret < 0) {
217			pinctrl_utils_dt_free_map(pctldev, *map,
218				*num_maps);
219			return ret;
220		}
221	}
222
223	return 0;
224}
225
226static const struct pinctrl_ops tegra_pinctrl_ops = {
227	.get_groups_count = tegra_pinctrl_get_groups_count,
228	.get_group_name = tegra_pinctrl_get_group_name,
229	.get_group_pins = tegra_pinctrl_get_group_pins,
230#ifdef CONFIG_DEBUG_FS
231	.pin_dbg_show = tegra_pinctrl_pin_dbg_show,
232#endif
233	.dt_node_to_map = tegra_pinctrl_dt_node_to_map,
234	.dt_free_map = pinctrl_utils_dt_free_map,
235};
236
237static int tegra_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
238{
239	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
240
241	return pmx->soc->nfunctions;
242}
243
244static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
245					       unsigned function)
246{
247	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
248
249	return pmx->soc->functions[function].name;
250}
251
252static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
253					 unsigned function,
254					 const char * const **groups,
255					 unsigned * const num_groups)
256{
257	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
258
259	*groups = pmx->soc->functions[function].groups;
260	*num_groups = pmx->soc->functions[function].ngroups;
261
262	return 0;
263}
264
265static int tegra_pinctrl_set_mux(struct pinctrl_dev *pctldev,
266				 unsigned function,
267				 unsigned group)
268{
269	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
270	const struct tegra_pingroup *g;
271	int i;
272	u32 val;
273
274	g = &pmx->soc->groups[group];
275
276	if (WARN_ON(g->mux_reg < 0))
277		return -EINVAL;
278
279	for (i = 0; i < ARRAY_SIZE(g->funcs); i++) {
280		if (g->funcs[i] == function)
281			break;
282	}
283	if (WARN_ON(i == ARRAY_SIZE(g->funcs)))
284		return -EINVAL;
285
286	val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
287	val &= ~(0x3 << g->mux_bit);
288	val |= i << g->mux_bit;
289	pmx_writel(pmx, val, g->mux_bank, g->mux_reg);
290
291	return 0;
292}
293
294static const struct pinmux_ops tegra_pinmux_ops = {
295	.get_functions_count = tegra_pinctrl_get_funcs_count,
296	.get_function_name = tegra_pinctrl_get_func_name,
297	.get_function_groups = tegra_pinctrl_get_func_groups,
298	.set_mux = tegra_pinctrl_set_mux,
299};
300
301static int tegra_pinconf_reg(struct tegra_pmx *pmx,
302			     const struct tegra_pingroup *g,
303			     enum tegra_pinconf_param param,
304			     bool report_err,
305			     s8 *bank, s16 *reg, s8 *bit, s8 *width)
306{
307	switch (param) {
308	case TEGRA_PINCONF_PARAM_PULL:
309		*bank = g->pupd_bank;
310		*reg = g->pupd_reg;
311		*bit = g->pupd_bit;
312		*width = 2;
313		break;
314	case TEGRA_PINCONF_PARAM_TRISTATE:
315		*bank = g->tri_bank;
316		*reg = g->tri_reg;
317		*bit = g->tri_bit;
318		*width = 1;
319		break;
320	case TEGRA_PINCONF_PARAM_ENABLE_INPUT:
321		*bank = g->mux_bank;
322		*reg = g->mux_reg;
323		*bit = g->einput_bit;
324		*width = 1;
325		break;
326	case TEGRA_PINCONF_PARAM_OPEN_DRAIN:
327		*bank = g->mux_bank;
328		*reg = g->mux_reg;
329		*bit = g->odrain_bit;
330		*width = 1;
331		break;
332	case TEGRA_PINCONF_PARAM_LOCK:
333		*bank = g->mux_bank;
334		*reg = g->mux_reg;
335		*bit = g->lock_bit;
336		*width = 1;
337		break;
338	case TEGRA_PINCONF_PARAM_IORESET:
339		*bank = g->mux_bank;
340		*reg = g->mux_reg;
341		*bit = g->ioreset_bit;
342		*width = 1;
343		break;
344	case TEGRA_PINCONF_PARAM_RCV_SEL:
345		*bank = g->mux_bank;
346		*reg = g->mux_reg;
347		*bit = g->rcv_sel_bit;
348		*width = 1;
349		break;
350	case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE:
351		*bank = g->drv_bank;
352		*reg = g->drv_reg;
353		*bit = g->hsm_bit;
354		*width = 1;
355		break;
356	case TEGRA_PINCONF_PARAM_SCHMITT:
357		*bank = g->drv_bank;
358		*reg = g->drv_reg;
359		*bit = g->schmitt_bit;
360		*width = 1;
361		break;
362	case TEGRA_PINCONF_PARAM_LOW_POWER_MODE:
363		*bank = g->drv_bank;
364		*reg = g->drv_reg;
365		*bit = g->lpmd_bit;
366		*width = 2;
367		break;
368	case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH:
369		*bank = g->drv_bank;
370		*reg = g->drv_reg;
371		*bit = g->drvdn_bit;
372		*width = g->drvdn_width;
373		break;
374	case TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH:
375		*bank = g->drv_bank;
376		*reg = g->drv_reg;
377		*bit = g->drvup_bit;
378		*width = g->drvup_width;
379		break;
380	case TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING:
381		*bank = g->drv_bank;
382		*reg = g->drv_reg;
383		*bit = g->slwf_bit;
384		*width = g->slwf_width;
385		break;
386	case TEGRA_PINCONF_PARAM_SLEW_RATE_RISING:
387		*bank = g->drv_bank;
388		*reg = g->drv_reg;
389		*bit = g->slwr_bit;
390		*width = g->slwr_width;
391		break;
392	case TEGRA_PINCONF_PARAM_DRIVE_TYPE:
393		*bank = g->drv_bank;
394		*reg = g->drv_reg;
395		*bit = g->drvtype_bit;
396		*width = 2;
397		break;
398	default:
399		dev_err(pmx->dev, "Invalid config param %04x\n", param);
400		return -ENOTSUPP;
401	}
402
403	if (*reg < 0 || *bit > 31) {
404		if (report_err) {
405			const char *prop = "unknown";
406			int i;
407
408			for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
409				if (cfg_params[i].param == param) {
410					prop = cfg_params[i].property;
411					break;
412				}
413			}
414
415			dev_err(pmx->dev,
416				"Config param %04x (%s) not supported on group %s\n",
417				param, prop, g->name);
418		}
419		return -ENOTSUPP;
420	}
421
422	return 0;
423}
424
425static int tegra_pinconf_get(struct pinctrl_dev *pctldev,
426			     unsigned pin, unsigned long *config)
427{
428	dev_err(pctldev->dev, "pin_config_get op not supported\n");
429	return -ENOTSUPP;
430}
431
432static int tegra_pinconf_set(struct pinctrl_dev *pctldev,
433			     unsigned pin, unsigned long *configs,
434			     unsigned num_configs)
435{
436	dev_err(pctldev->dev, "pin_config_set op not supported\n");
437	return -ENOTSUPP;
438}
439
440static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev,
441				   unsigned group, unsigned long *config)
442{
443	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
444	enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(*config);
445	u16 arg;
446	const struct tegra_pingroup *g;
447	int ret;
448	s8 bank, bit, width;
449	s16 reg;
450	u32 val, mask;
451
452	g = &pmx->soc->groups[group];
453
454	ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit,
455				&width);
456	if (ret < 0)
457		return ret;
458
459	val = pmx_readl(pmx, bank, reg);
460	mask = (1 << width) - 1;
461	arg = (val >> bit) & mask;
462
463	*config = TEGRA_PINCONF_PACK(param, arg);
464
465	return 0;
466}
467
468static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
469				   unsigned group, unsigned long *configs,
470				   unsigned num_configs)
471{
472	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
473	enum tegra_pinconf_param param;
474	u16 arg;
475	const struct tegra_pingroup *g;
476	int ret, i;
477	s8 bank, bit, width;
478	s16 reg;
479	u32 val, mask;
480
481	g = &pmx->soc->groups[group];
482
483	for (i = 0; i < num_configs; i++) {
484		param = TEGRA_PINCONF_UNPACK_PARAM(configs[i]);
485		arg = TEGRA_PINCONF_UNPACK_ARG(configs[i]);
486
487		ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit,
488					&width);
489		if (ret < 0)
490			return ret;
491
492		val = pmx_readl(pmx, bank, reg);
493
494		/* LOCK can't be cleared */
495		if (param == TEGRA_PINCONF_PARAM_LOCK) {
496			if ((val & BIT(bit)) && !arg) {
497				dev_err(pctldev->dev, "LOCK bit cannot be cleared\n");
498				return -EINVAL;
499			}
500		}
501
502		/* Special-case Boolean values; allow any non-zero as true */
503		if (width == 1)
504			arg = !!arg;
505
506		/* Range-check user-supplied value */
507		mask = (1 << width) - 1;
508		if (arg & ~mask) {
509			dev_err(pctldev->dev,
510				"config %lx: %x too big for %d bit register\n",
511				configs[i], arg, width);
512			return -EINVAL;
513		}
514
515		/* Update register */
516		val &= ~(mask << bit);
517		val |= arg << bit;
518		pmx_writel(pmx, val, bank, reg);
519	} /* for each config */
520
521	return 0;
522}
523
524#ifdef CONFIG_DEBUG_FS
525static void tegra_pinconf_dbg_show(struct pinctrl_dev *pctldev,
526				   struct seq_file *s, unsigned offset)
527{
528}
529
530static const char *strip_prefix(const char *s)
531{
532	const char *comma = strchr(s, ',');
533	if (!comma)
534		return s;
535
536	return comma + 1;
537}
538
539static void tegra_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
540					 struct seq_file *s, unsigned group)
541{
542	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
543	const struct tegra_pingroup *g;
544	int i, ret;
545	s8 bank, bit, width;
546	s16 reg;
547	u32 val;
548
549	g = &pmx->soc->groups[group];
550
551	for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
552		ret = tegra_pinconf_reg(pmx, g, cfg_params[i].param, false,
553					&bank, &reg, &bit, &width);
554		if (ret < 0)
555			continue;
556
557		val = pmx_readl(pmx, bank, reg);
558		val >>= bit;
559		val &= (1 << width) - 1;
560
561		seq_printf(s, "\n\t%s=%u",
562			   strip_prefix(cfg_params[i].property), val);
563	}
564}
565
566static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev,
567					  struct seq_file *s,
568					  unsigned long config)
569{
570	enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config);
571	u16 arg = TEGRA_PINCONF_UNPACK_ARG(config);
572	const char *pname = "unknown";
573	int i;
574
575	for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
576		if (cfg_params[i].param == param) {
577			pname = cfg_params[i].property;
578			break;
579		}
580	}
581
582	seq_printf(s, "%s=%d", strip_prefix(pname), arg);
583}
584#endif
585
586static const struct pinconf_ops tegra_pinconf_ops = {
587	.pin_config_get = tegra_pinconf_get,
588	.pin_config_set = tegra_pinconf_set,
589	.pin_config_group_get = tegra_pinconf_group_get,
590	.pin_config_group_set = tegra_pinconf_group_set,
591#ifdef CONFIG_DEBUG_FS
592	.pin_config_dbg_show = tegra_pinconf_dbg_show,
593	.pin_config_group_dbg_show = tegra_pinconf_group_dbg_show,
594	.pin_config_config_dbg_show = tegra_pinconf_config_dbg_show,
595#endif
596};
597
598static struct pinctrl_gpio_range tegra_pinctrl_gpio_range = {
599	.name = "Tegra GPIOs",
600	.id = 0,
601	.base = 0,
602};
603
604static struct pinctrl_desc tegra_pinctrl_desc = {
605	.pctlops = &tegra_pinctrl_ops,
606	.pmxops = &tegra_pinmux_ops,
607	.confops = &tegra_pinconf_ops,
608	.owner = THIS_MODULE,
609};
610
611int tegra_pinctrl_probe(struct platform_device *pdev,
612			const struct tegra_pinctrl_soc_data *soc_data)
613{
614	struct tegra_pmx *pmx;
615	struct resource *res;
616	int i;
617	const char **group_pins;
618	int fn, gn, gfn;
619
620	pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
621	if (!pmx) {
622		dev_err(&pdev->dev, "Can't alloc tegra_pmx\n");
623		return -ENOMEM;
624	}
625	pmx->dev = &pdev->dev;
626	pmx->soc = soc_data;
627
628	/*
629	 * Each mux group will appear in 4 functions' list of groups.
630	 * This over-allocates slightly, since not all groups are mux groups.
631	 */
632	pmx->group_pins = devm_kzalloc(&pdev->dev,
633		soc_data->ngroups * 4 * sizeof(*pmx->group_pins),
634		GFP_KERNEL);
635	if (!pmx->group_pins)
636		return -ENOMEM;
637
638	group_pins = pmx->group_pins;
639	for (fn = 0; fn < soc_data->nfunctions; fn++) {
640		struct tegra_function *func = &soc_data->functions[fn];
641
642		func->groups = group_pins;
643
644		for (gn = 0; gn < soc_data->ngroups; gn++) {
645			const struct tegra_pingroup *g = &soc_data->groups[gn];
646
647			if (g->mux_reg == -1)
648				continue;
649
650			for (gfn = 0; gfn < 4; gfn++)
651				if (g->funcs[gfn] == fn)
652					break;
653			if (gfn == 4)
654				continue;
655
656			BUG_ON(group_pins - pmx->group_pins >=
657				soc_data->ngroups * 4);
658			*group_pins++ = g->name;
659			func->ngroups++;
660		}
661	}
662
663	tegra_pinctrl_gpio_range.npins = pmx->soc->ngpios;
664	tegra_pinctrl_desc.name = dev_name(&pdev->dev);
665	tegra_pinctrl_desc.pins = pmx->soc->pins;
666	tegra_pinctrl_desc.npins = pmx->soc->npins;
667
668	for (i = 0; ; i++) {
669		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
670		if (!res)
671			break;
672	}
673	pmx->nbanks = i;
674
675	pmx->regs = devm_kzalloc(&pdev->dev, pmx->nbanks * sizeof(*pmx->regs),
676				 GFP_KERNEL);
677	if (!pmx->regs) {
678		dev_err(&pdev->dev, "Can't alloc regs pointer\n");
679		return -ENOMEM;
680	}
681
682	for (i = 0; i < pmx->nbanks; i++) {
683		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
684		pmx->regs[i] = devm_ioremap_resource(&pdev->dev, res);
685		if (IS_ERR(pmx->regs[i]))
686			return PTR_ERR(pmx->regs[i]);
687	}
688
689	pmx->pctl = pinctrl_register(&tegra_pinctrl_desc, &pdev->dev, pmx);
690	if (!pmx->pctl) {
691		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
692		return -ENODEV;
693	}
694
695	pinctrl_add_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range);
696
697	platform_set_drvdata(pdev, pmx);
698
699	dev_dbg(&pdev->dev, "Probed Tegra pinctrl driver\n");
700
701	return 0;
702}
703EXPORT_SYMBOL_GPL(tegra_pinctrl_probe);
704
705int tegra_pinctrl_remove(struct platform_device *pdev)
706{
707	struct tegra_pmx *pmx = platform_get_drvdata(pdev);
708
709	pinctrl_unregister(pmx->pctl);
710
711	return 0;
712}
713EXPORT_SYMBOL_GPL(tegra_pinctrl_remove);
714