1/*
2 * Marvell Dove pinctrl driver based on mvebu pinctrl core
3 *
4 * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/err.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/module.h>
16#include <linux/bitops.h>
17#include <linux/platform_device.h>
18#include <linux/clk.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
21#include <linux/mfd/syscon.h>
22#include <linux/pinctrl/pinctrl.h>
23#include <linux/regmap.h>
24
25#include "pinctrl-mvebu.h"
26
27/* Internal registers can be configured at any 1 MiB aligned address */
28#define INT_REGS_MASK		~(SZ_1M - 1)
29#define MPP4_REGS_OFFS		0xd0440
30#define PMU_REGS_OFFS		0xd802c
31#define GC_REGS_OFFS		0xe802c
32
33/* MPP Base registers */
34#define PMU_MPP_GENERAL_CTRL	0x10
35#define  AU0_AC97_SEL		BIT(16)
36
37/* MPP Control 4 register */
38#define SPI_GPIO_SEL		BIT(5)
39#define UART1_GPIO_SEL		BIT(4)
40#define AU1_GPIO_SEL		BIT(3)
41#define CAM_GPIO_SEL		BIT(2)
42#define SD1_GPIO_SEL		BIT(1)
43#define SD0_GPIO_SEL		BIT(0)
44
45/* PMU Signal Select registers */
46#define PMU_SIGNAL_SELECT_0	0x00
47#define PMU_SIGNAL_SELECT_1	0x04
48
49/* Global Config regmap registers */
50#define GLOBAL_CONFIG_1		0x00
51#define  TWSI_ENABLE_OPTION1	BIT(7)
52#define GLOBAL_CONFIG_2		0x04
53#define  TWSI_ENABLE_OPTION2	BIT(20)
54#define  TWSI_ENABLE_OPTION3	BIT(21)
55#define  TWSI_OPTION3_GPIO	BIT(22)
56#define SSP_CTRL_STATUS_1	0x08
57#define  SSP_ON_AU1		BIT(0)
58#define MPP_GENERAL_CONFIG	0x10
59#define  AU1_SPDIFO_GPIO_EN	BIT(1)
60#define  NAND_GPIO_EN		BIT(0)
61
62#define CONFIG_PMU	BIT(4)
63
64static void __iomem *mpp_base;
65static void __iomem *mpp4_base;
66static void __iomem *pmu_base;
67static struct regmap *gconfmap;
68
69static int dove_mpp_ctrl_get(unsigned pid, unsigned long *config)
70{
71	return default_mpp_ctrl_get(mpp_base, pid, config);
72}
73
74static int dove_mpp_ctrl_set(unsigned pid, unsigned long config)
75{
76	return default_mpp_ctrl_set(mpp_base, pid, config);
77}
78
79static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config)
80{
81	unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
82	unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
83	unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
84	unsigned long func;
85
86	if ((pmu & BIT(pid)) == 0)
87		return default_mpp_ctrl_get(mpp_base, pid, config);
88
89	func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);
90	*config = (func >> shift) & MVEBU_MPP_MASK;
91	*config |= CONFIG_PMU;
92
93	return 0;
94}
95
96static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config)
97{
98	unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
99	unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
100	unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
101	unsigned long func;
102
103	if ((config & CONFIG_PMU) == 0) {
104		writel(pmu & ~BIT(pid), mpp_base + PMU_MPP_GENERAL_CTRL);
105		return default_mpp_ctrl_set(mpp_base, pid, config);
106	}
107
108	writel(pmu | BIT(pid), mpp_base + PMU_MPP_GENERAL_CTRL);
109	func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);
110	func &= ~(MVEBU_MPP_MASK << shift);
111	func |= (config & MVEBU_MPP_MASK) << shift;
112	writel(func, pmu_base + PMU_SIGNAL_SELECT_0 + off);
113
114	return 0;
115}
116
117static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config)
118{
119	unsigned long mpp4 = readl(mpp4_base);
120	unsigned long mask;
121
122	switch (pid) {
123	case 24: /* mpp_camera */
124		mask = CAM_GPIO_SEL;
125		break;
126	case 40: /* mpp_sdio0 */
127		mask = SD0_GPIO_SEL;
128		break;
129	case 46: /* mpp_sdio1 */
130		mask = SD1_GPIO_SEL;
131		break;
132	case 58: /* mpp_spi0 */
133		mask = SPI_GPIO_SEL;
134		break;
135	case 62: /* mpp_uart1 */
136		mask = UART1_GPIO_SEL;
137		break;
138	default:
139		return -EINVAL;
140	}
141
142	*config = ((mpp4 & mask) != 0);
143
144	return 0;
145}
146
147static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config)
148{
149	unsigned long mpp4 = readl(mpp4_base);
150	unsigned long mask;
151
152	switch (pid) {
153	case 24: /* mpp_camera */
154		mask = CAM_GPIO_SEL;
155		break;
156	case 40: /* mpp_sdio0 */
157		mask = SD0_GPIO_SEL;
158		break;
159	case 46: /* mpp_sdio1 */
160		mask = SD1_GPIO_SEL;
161		break;
162	case 58: /* mpp_spi0 */
163		mask = SPI_GPIO_SEL;
164		break;
165	case 62: /* mpp_uart1 */
166		mask = UART1_GPIO_SEL;
167		break;
168	default:
169		return -EINVAL;
170	}
171
172	mpp4 &= ~mask;
173	if (config)
174		mpp4 |= mask;
175
176	writel(mpp4, mpp4_base);
177
178	return 0;
179}
180
181static int dove_nand_ctrl_get(unsigned pid, unsigned long *config)
182{
183	unsigned int gmpp;
184
185	regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);
186	*config = ((gmpp & NAND_GPIO_EN) != 0);
187
188	return 0;
189}
190
191static int dove_nand_ctrl_set(unsigned pid, unsigned long config)
192{
193	regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
194			   NAND_GPIO_EN,
195			   (config) ? NAND_GPIO_EN : 0);
196	return 0;
197}
198
199static int dove_audio0_ctrl_get(unsigned pid, unsigned long *config)
200{
201	unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
202
203	*config = ((pmu & AU0_AC97_SEL) != 0);
204
205	return 0;
206}
207
208static int dove_audio0_ctrl_set(unsigned pid, unsigned long config)
209{
210	unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
211
212	pmu &= ~AU0_AC97_SEL;
213	if (config)
214		pmu |= AU0_AC97_SEL;
215	writel(pmu, mpp_base + PMU_MPP_GENERAL_CTRL);
216
217	return 0;
218}
219
220static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config)
221{
222	unsigned int mpp4 = readl(mpp4_base);
223	unsigned int sspc1;
224	unsigned int gmpp;
225	unsigned int gcfg2;
226
227	regmap_read(gconfmap, SSP_CTRL_STATUS_1, &sspc1);
228	regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);
229	regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);
230
231	*config = 0;
232	if (mpp4 & AU1_GPIO_SEL)
233		*config |= BIT(3);
234	if (sspc1 & SSP_ON_AU1)
235		*config |= BIT(2);
236	if (gmpp & AU1_SPDIFO_GPIO_EN)
237		*config |= BIT(1);
238	if (gcfg2 & TWSI_OPTION3_GPIO)
239		*config |= BIT(0);
240
241	/* SSP/TWSI only if I2S1 not set*/
242	if ((*config & BIT(3)) == 0)
243		*config &= ~(BIT(2) | BIT(0));
244	/* TWSI only if SPDIFO not set*/
245	if ((*config & BIT(1)) == 0)
246		*config &= ~BIT(0);
247	return 0;
248}
249
250static int dove_audio1_ctrl_set(unsigned pid, unsigned long config)
251{
252	unsigned int mpp4 = readl(mpp4_base);
253
254	mpp4 &= ~AU1_GPIO_SEL;
255	if (config & BIT(3))
256		mpp4 |= AU1_GPIO_SEL;
257	writel(mpp4, mpp4_base);
258
259	regmap_update_bits(gconfmap, SSP_CTRL_STATUS_1,
260			   SSP_ON_AU1,
261			   (config & BIT(2)) ? SSP_ON_AU1 : 0);
262	regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
263			   AU1_SPDIFO_GPIO_EN,
264			   (config & BIT(1)) ? AU1_SPDIFO_GPIO_EN : 0);
265	regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,
266			   TWSI_OPTION3_GPIO,
267			   (config & BIT(0)) ? TWSI_OPTION3_GPIO : 0);
268
269	return 0;
270}
271
272/* mpp[52:57] gpio pins depend heavily on current config;
273 * gpio_req does not try to mux in gpio capabilities to not
274 * break other functions. If you require all mpps as gpio
275 * enforce gpio setting by pinctrl mapping.
276 */
277static int dove_audio1_ctrl_gpio_req(unsigned pid)
278{
279	unsigned long config;
280
281	dove_audio1_ctrl_get(pid, &config);
282
283	switch (config) {
284	case 0x02: /* i2s1 : gpio[56:57] */
285	case 0x0e: /* ssp  : gpio[56:57] */
286		if (pid >= 56)
287			return 0;
288		return -ENOTSUPP;
289	case 0x08: /* spdifo : gpio[52:55] */
290	case 0x0b: /* twsi   : gpio[52:55] */
291		if (pid <= 55)
292			return 0;
293		return -ENOTSUPP;
294	case 0x0a: /* all gpio */
295		return 0;
296	/* 0x00 : i2s1/spdifo : no gpio */
297	/* 0x0c : ssp/spdifo  : no gpio */
298	/* 0x0f : ssp/twsi    : no gpio */
299	}
300	return -ENOTSUPP;
301}
302
303/* mpp[52:57] has gpio pins capable of in and out */
304static int dove_audio1_ctrl_gpio_dir(unsigned pid, bool input)
305{
306	if (pid < 52 || pid > 57)
307		return -ENOTSUPP;
308	return 0;
309}
310
311static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config)
312{
313	unsigned int gcfg1;
314	unsigned int gcfg2;
315
316	regmap_read(gconfmap, GLOBAL_CONFIG_1, &gcfg1);
317	regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);
318
319	*config = 0;
320	if (gcfg1 & TWSI_ENABLE_OPTION1)
321		*config = 1;
322	else if (gcfg2 & TWSI_ENABLE_OPTION2)
323		*config = 2;
324	else if (gcfg2 & TWSI_ENABLE_OPTION3)
325		*config = 3;
326
327	return 0;
328}
329
330static int dove_twsi_ctrl_set(unsigned pid, unsigned long config)
331{
332	unsigned int gcfg1 = 0;
333	unsigned int gcfg2 = 0;
334
335	switch (config) {
336	case 1:
337		gcfg1 = TWSI_ENABLE_OPTION1;
338		break;
339	case 2:
340		gcfg2 = TWSI_ENABLE_OPTION2;
341		break;
342	case 3:
343		gcfg2 = TWSI_ENABLE_OPTION3;
344		break;
345	}
346
347	regmap_update_bits(gconfmap, GLOBAL_CONFIG_1,
348			   TWSI_ENABLE_OPTION1,
349			   gcfg1);
350	regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,
351			   TWSI_ENABLE_OPTION2 | TWSI_ENABLE_OPTION3,
352			   gcfg2);
353
354	return 0;
355}
356
357static struct mvebu_mpp_ctrl dove_mpp_controls[] = {
358	MPP_FUNC_CTRL(0, 15, NULL, dove_pmu_mpp_ctrl),
359	MPP_FUNC_CTRL(16, 23, NULL, dove_mpp_ctrl),
360	MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl),
361	MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl),
362	MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl),
363	MPP_FUNC_GPIO_CTRL(52, 57, "mpp_audio1", dove_audio1_ctrl),
364	MPP_FUNC_CTRL(58, 61, "mpp_spi0", dove_mpp4_ctrl),
365	MPP_FUNC_CTRL(62, 63, "mpp_uart1", dove_mpp4_ctrl),
366	MPP_FUNC_CTRL(64, 71, "mpp_nand", dove_nand_ctrl),
367	MPP_FUNC_CTRL(72, 72, "audio0", dove_audio0_ctrl),
368	MPP_FUNC_CTRL(73, 73, "twsi", dove_twsi_ctrl),
369};
370
371static struct mvebu_mpp_mode dove_mpp_modes[] = {
372	MPP_MODE(0,
373		MPP_FUNCTION(0x00, "gpio", NULL),
374		MPP_FUNCTION(0x02, "uart2", "rts"),
375		MPP_FUNCTION(0x03, "sdio0", "cd"),
376		MPP_FUNCTION(0x0f, "lcd0", "pwm"),
377		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
378		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
379		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
380		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
381		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
382		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
383		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
384		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
385		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
386		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
387		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
388		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
389	MPP_MODE(1,
390		MPP_FUNCTION(0x00, "gpio", NULL),
391		MPP_FUNCTION(0x02, "uart2", "cts"),
392		MPP_FUNCTION(0x03, "sdio0", "wp"),
393		MPP_FUNCTION(0x0f, "lcd1", "pwm"),
394		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
395		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
396		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
397		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
398		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
399		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
400		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
401		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
402		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
403		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
404		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
405		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
406	MPP_MODE(2,
407		MPP_FUNCTION(0x00, "gpio", NULL),
408		MPP_FUNCTION(0x01, "sata", "prsnt"),
409		MPP_FUNCTION(0x02, "uart2", "txd"),
410		MPP_FUNCTION(0x03, "sdio0", "buspwr"),
411		MPP_FUNCTION(0x04, "uart1", "rts"),
412		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
413		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
414		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
415		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
416		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
417		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
418		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
419		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
420		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
421		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
422		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
423		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
424	MPP_MODE(3,
425		MPP_FUNCTION(0x00, "gpio", NULL),
426		MPP_FUNCTION(0x01, "sata", "act"),
427		MPP_FUNCTION(0x02, "uart2", "rxd"),
428		MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
429		MPP_FUNCTION(0x04, "uart1", "cts"),
430		MPP_FUNCTION(0x0f, "lcd-spi", "cs1"),
431		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
432		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
433		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
434		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
435		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
436		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
437		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
438		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
439		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
440		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
441		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
442		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
443	MPP_MODE(4,
444		MPP_FUNCTION(0x00, "gpio", NULL),
445		MPP_FUNCTION(0x02, "uart3", "rts"),
446		MPP_FUNCTION(0x03, "sdio1", "cd"),
447		MPP_FUNCTION(0x04, "spi1", "miso"),
448		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
449		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
450		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
451		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
452		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
453		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
454		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
455		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
456		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
457		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
458		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
459		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
460	MPP_MODE(5,
461		MPP_FUNCTION(0x00, "gpio", NULL),
462		MPP_FUNCTION(0x02, "uart3", "cts"),
463		MPP_FUNCTION(0x03, "sdio1", "wp"),
464		MPP_FUNCTION(0x04, "spi1", "cs"),
465		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
466		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
467		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
468		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
469		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
470		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
471		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
472		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
473		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
474		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
475		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
476		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
477	MPP_MODE(6,
478		MPP_FUNCTION(0x00, "gpio", NULL),
479		MPP_FUNCTION(0x02, "uart3", "txd"),
480		MPP_FUNCTION(0x03, "sdio1", "buspwr"),
481		MPP_FUNCTION(0x04, "spi1", "mosi"),
482		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
483		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
484		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
485		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
486		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
487		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
488		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
489		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
490		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
491		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
492		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
493		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
494	MPP_MODE(7,
495		MPP_FUNCTION(0x00, "gpio", NULL),
496		MPP_FUNCTION(0x02, "uart3", "rxd"),
497		MPP_FUNCTION(0x03, "sdio1", "ledctrl"),
498		MPP_FUNCTION(0x04, "spi1", "sck"),
499		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
500		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
501		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
502		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
503		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
504		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
505		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
506		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
507		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
508		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
509		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
510		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
511	MPP_MODE(8,
512		MPP_FUNCTION(0x00, "gpio", NULL),
513		MPP_FUNCTION(0x01, "watchdog", "rstout"),
514		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
515		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
516		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
517		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
518		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
519		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
520		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
521		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
522		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
523		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
524		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
525		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
526	MPP_MODE(9,
527		MPP_FUNCTION(0x00, "gpio", NULL),
528		MPP_FUNCTION(0x05, "pex1", "clkreq"),
529		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
530		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
531		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
532		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
533		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
534		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
535		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
536		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
537		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
538		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
539		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
540		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
541	MPP_MODE(10,
542		MPP_FUNCTION(0x00, "gpio", NULL),
543		MPP_FUNCTION(0x05, "ssp", "sclk"),
544		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
545		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
546		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
547		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
548		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
549		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
550		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
551		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
552		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
553		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
554		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
555		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
556	MPP_MODE(11,
557		MPP_FUNCTION(0x00, "gpio", NULL),
558		MPP_FUNCTION(0x01, "sata", "prsnt"),
559		MPP_FUNCTION(0x02, "sata-1", "act"),
560		MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
561		MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
562		MPP_FUNCTION(0x05, "pex0", "clkreq"),
563		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
564		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
565		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
566		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
567		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
568		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
569		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
570		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
571		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
572		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
573		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
574		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
575	MPP_MODE(12,
576		MPP_FUNCTION(0x00, "gpio", NULL),
577		MPP_FUNCTION(0x01, "sata", "act"),
578		MPP_FUNCTION(0x02, "uart2", "rts"),
579		MPP_FUNCTION(0x03, "audio0", "extclk"),
580		MPP_FUNCTION(0x04, "sdio1", "cd"),
581		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
582		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
583		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
584		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
585		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
586		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
587		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
588		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
589		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
590		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
591		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
592		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
593	MPP_MODE(13,
594		MPP_FUNCTION(0x00, "gpio", NULL),
595		MPP_FUNCTION(0x02, "uart2", "cts"),
596		MPP_FUNCTION(0x03, "audio1", "extclk"),
597		MPP_FUNCTION(0x04, "sdio1", "wp"),
598		MPP_FUNCTION(0x05, "ssp", "extclk"),
599		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
600		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
601		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
602		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
603		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
604		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
605		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
606		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
607		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
608		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
609		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
610		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
611	MPP_MODE(14,
612		MPP_FUNCTION(0x00, "gpio", NULL),
613		MPP_FUNCTION(0x02, "uart2", "txd"),
614		MPP_FUNCTION(0x04, "sdio1", "buspwr"),
615		MPP_FUNCTION(0x05, "ssp", "rxd"),
616		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
617		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
618		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
619		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
620		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
621		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
622		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
623		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
624		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
625		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
626		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
627		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
628	MPP_MODE(15,
629		MPP_FUNCTION(0x00, "gpio", NULL),
630		MPP_FUNCTION(0x02, "uart2", "rxd"),
631		MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
632		MPP_FUNCTION(0x05, "ssp", "sfrm"),
633		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
634		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
635		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
636		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
637		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
638		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
639		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
640		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
641		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
642		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
643		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
644		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
645	MPP_MODE(16,
646		MPP_FUNCTION(0x00, "gpio", NULL),
647		MPP_FUNCTION(0x02, "uart3", "rts"),
648		MPP_FUNCTION(0x03, "sdio0", "cd"),
649		MPP_FUNCTION(0x04, "lcd-spi", "cs1"),
650		MPP_FUNCTION(0x05, "ac97", "sdi1")),
651	MPP_MODE(17,
652		MPP_FUNCTION(0x00, "gpio", NULL),
653		MPP_FUNCTION(0x01, "ac97-1", "sysclko"),
654		MPP_FUNCTION(0x02, "uart3", "cts"),
655		MPP_FUNCTION(0x03, "sdio0", "wp"),
656		MPP_FUNCTION(0x04, "twsi", "sda"),
657		MPP_FUNCTION(0x05, "ac97", "sdi2")),
658	MPP_MODE(18,
659		MPP_FUNCTION(0x00, "gpio", NULL),
660		MPP_FUNCTION(0x02, "uart3", "txd"),
661		MPP_FUNCTION(0x03, "sdio0", "buspwr"),
662		MPP_FUNCTION(0x04, "lcd0", "pwm"),
663		MPP_FUNCTION(0x05, "ac97", "sdi3")),
664	MPP_MODE(19,
665		MPP_FUNCTION(0x00, "gpio", NULL),
666		MPP_FUNCTION(0x02, "uart3", "rxd"),
667		MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
668		MPP_FUNCTION(0x04, "twsi", "sck")),
669	MPP_MODE(20,
670		MPP_FUNCTION(0x00, "gpio", NULL),
671		MPP_FUNCTION(0x01, "ac97", "sysclko"),
672		MPP_FUNCTION(0x02, "lcd-spi", "miso"),
673		MPP_FUNCTION(0x03, "sdio1", "cd"),
674		MPP_FUNCTION(0x05, "sdio0", "cd"),
675		MPP_FUNCTION(0x06, "spi1", "miso")),
676	MPP_MODE(21,
677		MPP_FUNCTION(0x00, "gpio", NULL),
678		MPP_FUNCTION(0x01, "uart1", "rts"),
679		MPP_FUNCTION(0x02, "lcd-spi", "cs0"),
680		MPP_FUNCTION(0x03, "sdio1", "wp"),
681		MPP_FUNCTION(0x04, "ssp", "sfrm"),
682		MPP_FUNCTION(0x05, "sdio0", "wp"),
683		MPP_FUNCTION(0x06, "spi1", "cs")),
684	MPP_MODE(22,
685		MPP_FUNCTION(0x00, "gpio", NULL),
686		MPP_FUNCTION(0x01, "uart1", "cts"),
687		MPP_FUNCTION(0x02, "lcd-spi", "mosi"),
688		MPP_FUNCTION(0x03, "sdio1", "buspwr"),
689		MPP_FUNCTION(0x04, "ssp", "txd"),
690		MPP_FUNCTION(0x05, "sdio0", "buspwr"),
691		MPP_FUNCTION(0x06, "spi1", "mosi")),
692	MPP_MODE(23,
693		MPP_FUNCTION(0x00, "gpio", NULL),
694		MPP_FUNCTION(0x02, "lcd-spi", "sck"),
695		MPP_FUNCTION(0x03, "sdio1", "ledctrl"),
696		MPP_FUNCTION(0x04, "ssp", "sclk"),
697		MPP_FUNCTION(0x05, "sdio0", "ledctrl"),
698		MPP_FUNCTION(0x06, "spi1", "sck")),
699	MPP_MODE(24,
700		MPP_FUNCTION(0x00, "camera", NULL),
701		MPP_FUNCTION(0x01, "gpio", NULL)),
702	MPP_MODE(40,
703		MPP_FUNCTION(0x00, "sdio0", NULL),
704		MPP_FUNCTION(0x01, "gpio", NULL)),
705	MPP_MODE(46,
706		MPP_FUNCTION(0x00, "sdio1", NULL),
707		MPP_FUNCTION(0x01, "gpio", NULL)),
708	MPP_MODE(52,
709		MPP_FUNCTION(0x00, "i2s1/spdifo", NULL),
710		MPP_FUNCTION(0x02, "i2s1", NULL),
711		MPP_FUNCTION(0x08, "spdifo", NULL),
712		MPP_FUNCTION(0x0a, "gpio", NULL),
713		MPP_FUNCTION(0x0b, "twsi", NULL),
714		MPP_FUNCTION(0x0c, "ssp/spdifo", NULL),
715		MPP_FUNCTION(0x0e, "ssp", NULL),
716		MPP_FUNCTION(0x0f, "ssp/twsi", NULL)),
717	MPP_MODE(58,
718		MPP_FUNCTION(0x00, "spi0", NULL),
719		MPP_FUNCTION(0x01, "gpio", NULL)),
720	MPP_MODE(62,
721		MPP_FUNCTION(0x00, "uart1", NULL),
722		MPP_FUNCTION(0x01, "gpio", NULL)),
723	MPP_MODE(64,
724		MPP_FUNCTION(0x00, "nand", NULL),
725		MPP_FUNCTION(0x01, "gpo", NULL)),
726	MPP_MODE(72,
727		MPP_FUNCTION(0x00, "i2s", NULL),
728		MPP_FUNCTION(0x01, "ac97", NULL)),
729	MPP_MODE(73,
730		MPP_FUNCTION(0x00, "twsi-none", NULL),
731		MPP_FUNCTION(0x01, "twsi-opt1", NULL),
732		MPP_FUNCTION(0x02, "twsi-opt2", NULL),
733		MPP_FUNCTION(0x03, "twsi-opt3", NULL)),
734};
735
736static struct pinctrl_gpio_range dove_mpp_gpio_ranges[] = {
737	MPP_GPIO_RANGE(0,  0,  0, 32),
738	MPP_GPIO_RANGE(1, 32, 32, 32),
739	MPP_GPIO_RANGE(2, 64, 64,  8),
740};
741
742static struct mvebu_pinctrl_soc_info dove_pinctrl_info = {
743	.controls = dove_mpp_controls,
744	.ncontrols = ARRAY_SIZE(dove_mpp_controls),
745	.modes = dove_mpp_modes,
746	.nmodes = ARRAY_SIZE(dove_mpp_modes),
747	.gpioranges = dove_mpp_gpio_ranges,
748	.ngpioranges = ARRAY_SIZE(dove_mpp_gpio_ranges),
749	.variant = 0,
750};
751
752static struct clk *clk;
753
754static const struct of_device_id dove_pinctrl_of_match[] = {
755	{ .compatible = "marvell,dove-pinctrl", .data = &dove_pinctrl_info },
756	{ }
757};
758
759static const struct regmap_config gc_regmap_config = {
760	.reg_bits = 32,
761	.val_bits = 32,
762	.reg_stride = 4,
763	.max_register = 5,
764};
765
766static int dove_pinctrl_probe(struct platform_device *pdev)
767{
768	struct resource *res, *mpp_res;
769	struct resource fb_res;
770	const struct of_device_id *match =
771		of_match_device(dove_pinctrl_of_match, &pdev->dev);
772	pdev->dev.platform_data = (void *)match->data;
773
774	/*
775	 * General MPP Configuration Register is part of pdma registers.
776	 * grab clk to make sure it is ticking.
777	 */
778	clk = devm_clk_get(&pdev->dev, NULL);
779	if (IS_ERR(clk)) {
780		dev_err(&pdev->dev, "Unable to get pdma clock");
781		return PTR_ERR(clk);
782	}
783	clk_prepare_enable(clk);
784
785	mpp_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
786	mpp_base = devm_ioremap_resource(&pdev->dev, mpp_res);
787	if (IS_ERR(mpp_base))
788		return PTR_ERR(mpp_base);
789
790	/* prepare fallback resource */
791	memcpy(&fb_res, mpp_res, sizeof(struct resource));
792	fb_res.start = 0;
793
794	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
795	if (!res) {
796		dev_warn(&pdev->dev, "falling back to hardcoded MPP4 resource\n");
797		adjust_resource(&fb_res,
798			(mpp_res->start & INT_REGS_MASK) + MPP4_REGS_OFFS, 0x4);
799		res = &fb_res;
800	}
801
802	mpp4_base = devm_ioremap_resource(&pdev->dev, res);
803	if (IS_ERR(mpp4_base))
804		return PTR_ERR(mpp4_base);
805
806	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
807	if (!res) {
808		dev_warn(&pdev->dev, "falling back to hardcoded PMU resource\n");
809		adjust_resource(&fb_res,
810			(mpp_res->start & INT_REGS_MASK) + PMU_REGS_OFFS, 0x8);
811		res = &fb_res;
812	}
813
814	pmu_base = devm_ioremap_resource(&pdev->dev, res);
815	if (IS_ERR(pmu_base))
816		return PTR_ERR(pmu_base);
817
818	gconfmap = syscon_regmap_lookup_by_compatible("marvell,dove-global-config");
819	if (IS_ERR(gconfmap)) {
820		void __iomem *gc_base;
821
822		dev_warn(&pdev->dev, "falling back to hardcoded global registers\n");
823		adjust_resource(&fb_res,
824			(mpp_res->start & INT_REGS_MASK) + GC_REGS_OFFS, 0x14);
825		gc_base = devm_ioremap_resource(&pdev->dev, &fb_res);
826		if (IS_ERR(gc_base))
827			return PTR_ERR(gc_base);
828		gconfmap = devm_regmap_init_mmio(&pdev->dev,
829						 gc_base, &gc_regmap_config);
830		if (IS_ERR(gconfmap))
831			return PTR_ERR(gconfmap);
832	}
833
834	/* Warn on any missing DT resource */
835	if (fb_res.start)
836		dev_warn(&pdev->dev, FW_BUG "Missing pinctrl regs in DTB. Please update your firmware.\n");
837
838	return mvebu_pinctrl_probe(pdev);
839}
840
841static int dove_pinctrl_remove(struct platform_device *pdev)
842{
843	int ret;
844
845	ret = mvebu_pinctrl_remove(pdev);
846	if (!IS_ERR(clk))
847		clk_disable_unprepare(clk);
848	return ret;
849}
850
851static struct platform_driver dove_pinctrl_driver = {
852	.driver = {
853		.name = "dove-pinctrl",
854		.of_match_table = dove_pinctrl_of_match,
855	},
856	.probe = dove_pinctrl_probe,
857	.remove = dove_pinctrl_remove,
858};
859
860module_platform_driver(dove_pinctrl_driver);
861
862MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>");
863MODULE_DESCRIPTION("Marvell Dove pinctrl driver");
864MODULE_LICENSE("GPL v2");
865