15fae8b86SMika Westerberg /*
25fae8b86SMika Westerberg  * Pinctrl GPIO driver for Intel Baytrail
35fae8b86SMika Westerberg  * Copyright (c) 2012-2013, Intel Corporation.
45fae8b86SMika Westerberg  *
55fae8b86SMika Westerberg  * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
65fae8b86SMika Westerberg  *
75fae8b86SMika Westerberg  * This program is free software; you can redistribute it and/or modify it
85fae8b86SMika Westerberg  * under the terms and conditions of the GNU General Public License,
95fae8b86SMika Westerberg  * version 2, as published by the Free Software Foundation.
105fae8b86SMika Westerberg  *
115fae8b86SMika Westerberg  * This program is distributed in the hope it will be useful, but WITHOUT
125fae8b86SMika Westerberg  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
135fae8b86SMika Westerberg  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
145fae8b86SMika Westerberg  * more details.
155fae8b86SMika Westerberg  */
165fae8b86SMika Westerberg 
175fae8b86SMika Westerberg #include <linux/kernel.h>
185fae8b86SMika Westerberg #include <linux/init.h>
195fae8b86SMika Westerberg #include <linux/types.h>
205fae8b86SMika Westerberg #include <linux/bitops.h>
215fae8b86SMika Westerberg #include <linux/interrupt.h>
2286e3ef81SCristina Ciocan #include <linux/gpio.h>
23bf9a5c96SLinus Walleij #include <linux/gpio/driver.h>
245fae8b86SMika Westerberg #include <linux/acpi.h>
255fae8b86SMika Westerberg #include <linux/platform_device.h>
265fae8b86SMika Westerberg #include <linux/seq_file.h>
275fae8b86SMika Westerberg #include <linux/io.h>
285fae8b86SMika Westerberg #include <linux/pm_runtime.h>
295fae8b86SMika Westerberg #include <linux/pinctrl/pinctrl.h>
30c501d0b1SCristina Ciocan #include <linux/pinctrl/pinmux.h>
31c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf.h>
32c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf-generic.h>
335fae8b86SMika Westerberg 
345fae8b86SMika Westerberg /* memory mapped register offsets */
355fae8b86SMika Westerberg #define BYT_CONF0_REG		0x000
365fae8b86SMika Westerberg #define BYT_CONF1_REG		0x004
375fae8b86SMika Westerberg #define BYT_VAL_REG		0x008
385fae8b86SMika Westerberg #define BYT_DFT_REG		0x00c
395fae8b86SMika Westerberg #define BYT_INT_STAT_REG	0x800
40658b476cSCristina Ciocan #define BYT_DEBOUNCE_REG	0x9d0
415fae8b86SMika Westerberg 
425fae8b86SMika Westerberg /* BYT_CONF0_REG register bits */
435fae8b86SMika Westerberg #define BYT_IODEN		BIT(31)
445fae8b86SMika Westerberg #define BYT_DIRECT_IRQ_EN	BIT(27)
455fae8b86SMika Westerberg #define BYT_TRIG_NEG		BIT(26)
465fae8b86SMika Westerberg #define BYT_TRIG_POS		BIT(25)
475fae8b86SMika Westerberg #define BYT_TRIG_LVL		BIT(24)
48658b476cSCristina Ciocan #define BYT_DEBOUNCE_EN		BIT(20)
495fae8b86SMika Westerberg #define BYT_PULL_STR_SHIFT	9
505fae8b86SMika Westerberg #define BYT_PULL_STR_MASK	(3 << BYT_PULL_STR_SHIFT)
515fae8b86SMika Westerberg #define BYT_PULL_STR_2K		(0 << BYT_PULL_STR_SHIFT)
525fae8b86SMika Westerberg #define BYT_PULL_STR_10K	(1 << BYT_PULL_STR_SHIFT)
535fae8b86SMika Westerberg #define BYT_PULL_STR_20K	(2 << BYT_PULL_STR_SHIFT)
545fae8b86SMika Westerberg #define BYT_PULL_STR_40K	(3 << BYT_PULL_STR_SHIFT)
555fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_SHIFT	7
565fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_MASK	(3 << BYT_PULL_ASSIGN_SHIFT)
575fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_UP	(1 << BYT_PULL_ASSIGN_SHIFT)
585fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_DOWN	(2 << BYT_PULL_ASSIGN_SHIFT)
595fae8b86SMika Westerberg #define BYT_PIN_MUX		0x07
605fae8b86SMika Westerberg 
615fae8b86SMika Westerberg /* BYT_VAL_REG register bits */
625fae8b86SMika Westerberg #define BYT_INPUT_EN		BIT(2)  /* 0: input enabled (active low)*/
635fae8b86SMika Westerberg #define BYT_OUTPUT_EN		BIT(1)  /* 0: output enabled (active low)*/
645fae8b86SMika Westerberg #define BYT_LEVEL		BIT(0)
655fae8b86SMika Westerberg 
665fae8b86SMika Westerberg #define BYT_DIR_MASK		(BIT(1) | BIT(2))
675fae8b86SMika Westerberg #define BYT_TRIG_MASK		(BIT(26) | BIT(25) | BIT(24))
685fae8b86SMika Westerberg 
69fcc18debSMika Westerberg #define BYT_CONF0_RESTORE_MASK	(BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | \
70fcc18debSMika Westerberg 				 BYT_PIN_MUX)
71fcc18debSMika Westerberg #define BYT_VAL_RESTORE_MASK	(BYT_DIR_MASK | BYT_LEVEL)
72fcc18debSMika Westerberg 
73658b476cSCristina Ciocan /* BYT_DEBOUNCE_REG bits */
74658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_MASK		0x7
75658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_375US	1
76658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_750US	2
77658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_1500US	3
78658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_3MS		4
79658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_6MS		5
80658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_12MS		6
81658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_24MS		7
82658b476cSCristina Ciocan 
835fae8b86SMika Westerberg #define BYT_NGPIO_SCORE		102
845fae8b86SMika Westerberg #define BYT_NGPIO_NCORE		28
855fae8b86SMika Westerberg #define BYT_NGPIO_SUS		44
865fae8b86SMika Westerberg 
875fae8b86SMika Westerberg #define BYT_SCORE_ACPI_UID	"1"
885fae8b86SMika Westerberg #define BYT_NCORE_ACPI_UID	"2"
895fae8b86SMika Westerberg #define BYT_SUS_ACPI_UID	"3"
905fae8b86SMika Westerberg 
91c501d0b1SCristina Ciocan /*
92c501d0b1SCristina Ciocan  * This is the function value most pins have for GPIO muxing. If the value
93c501d0b1SCristina Ciocan  * differs from the default one, it must be explicitly mentioned. Otherwise, the
94c501d0b1SCristina Ciocan  * pin control implementation will set the muxing value to default GPIO if it
95c501d0b1SCristina Ciocan  * does not find a match for the requested function.
96c501d0b1SCristina Ciocan  */
97c501d0b1SCristina Ciocan #define BYT_DEFAULT_GPIO_MUX	0
98c501d0b1SCristina Ciocan 
99c8f5c4c7SCristina Ciocan struct byt_gpio_pin_context {
100c8f5c4c7SCristina Ciocan 	u32 conf0;
101c8f5c4c7SCristina Ciocan 	u32 val;
102c8f5c4c7SCristina Ciocan };
1035fae8b86SMika Westerberg 
104c8f5c4c7SCristina Ciocan struct byt_simple_func_mux {
105c8f5c4c7SCristina Ciocan 	const char *name;
106c8f5c4c7SCristina Ciocan 	unsigned short func;
107c8f5c4c7SCristina Ciocan };
108c8f5c4c7SCristina Ciocan 
109c8f5c4c7SCristina Ciocan struct byt_mixed_func_mux {
110c8f5c4c7SCristina Ciocan 	const char *name;
111c8f5c4c7SCristina Ciocan 	const unsigned short *func_values;
112c8f5c4c7SCristina Ciocan };
113c8f5c4c7SCristina Ciocan 
114c8f5c4c7SCristina Ciocan struct byt_pingroup {
115c8f5c4c7SCristina Ciocan 	const char *name;
116c8f5c4c7SCristina Ciocan 	const unsigned int *pins;
117c8f5c4c7SCristina Ciocan 	size_t npins;
118c8f5c4c7SCristina Ciocan 	unsigned short has_simple_funcs;
119c8f5c4c7SCristina Ciocan 	union {
120c8f5c4c7SCristina Ciocan 		const struct byt_simple_func_mux *simple_funcs;
121c8f5c4c7SCristina Ciocan 		const struct byt_mixed_func_mux *mixed_funcs;
122c8f5c4c7SCristina Ciocan 	};
123c8f5c4c7SCristina Ciocan 	size_t nfuncs;
124c8f5c4c7SCristina Ciocan };
125c8f5c4c7SCristina Ciocan 
126c8f5c4c7SCristina Ciocan struct byt_function {
127c8f5c4c7SCristina Ciocan 	const char *name;
128c8f5c4c7SCristina Ciocan 	const char * const *groups;
129c8f5c4c7SCristina Ciocan 	size_t ngroups;
130c8f5c4c7SCristina Ciocan };
131c8f5c4c7SCristina Ciocan 
132c8f5c4c7SCristina Ciocan struct byt_community {
133c8f5c4c7SCristina Ciocan 	unsigned int pin_base;
134c8f5c4c7SCristina Ciocan 	size_t npins;
135c8f5c4c7SCristina Ciocan 	const unsigned int *pad_map;
136c8f5c4c7SCristina Ciocan 	void __iomem *reg_base;
137c8f5c4c7SCristina Ciocan };
138c8f5c4c7SCristina Ciocan 
139c8f5c4c7SCristina Ciocan #define SIMPLE_FUNC(n, f)	\
140c8f5c4c7SCristina Ciocan 	{			\
141c8f5c4c7SCristina Ciocan 		.name	= (n),	\
142c8f5c4c7SCristina Ciocan 		.func	= (f),	\
143c8f5c4c7SCristina Ciocan 	}
144c8f5c4c7SCristina Ciocan #define MIXED_FUNC(n, f)		\
145c8f5c4c7SCristina Ciocan 	{				\
146c8f5c4c7SCristina Ciocan 		.name		= (n),	\
147c8f5c4c7SCristina Ciocan 		.func_values	= (f),	\
148c8f5c4c7SCristina Ciocan 	}
149c8f5c4c7SCristina Ciocan 
150c8f5c4c7SCristina Ciocan #define PIN_GROUP_SIMPLE(n, p, f)				\
151c8f5c4c7SCristina Ciocan 	{							\
152c8f5c4c7SCristina Ciocan 		.name			= (n),			\
153c8f5c4c7SCristina Ciocan 		.pins			= (p),			\
154c8f5c4c7SCristina Ciocan 		.npins			= ARRAY_SIZE((p)),	\
155c8f5c4c7SCristina Ciocan 		.has_simple_funcs	= 1,			\
156bbccb9c7SAndrew Morton 		{						\
157c8f5c4c7SCristina Ciocan 			.simple_funcs		= (f),		\
158bbccb9c7SAndrew Morton 		},						\
159c8f5c4c7SCristina Ciocan 		.nfuncs			= ARRAY_SIZE((f)),	\
160c8f5c4c7SCristina Ciocan 	}
161c8f5c4c7SCristina Ciocan #define PIN_GROUP_MIXED(n, p, f)				\
162c8f5c4c7SCristina Ciocan 	{							\
163c8f5c4c7SCristina Ciocan 		.name			= (n),			\
164c8f5c4c7SCristina Ciocan 		.pins			= (p),			\
165c8f5c4c7SCristina Ciocan 		.npins			= ARRAY_SIZE((p)),	\
166c8f5c4c7SCristina Ciocan 		.has_simple_funcs	= 0,			\
167bbccb9c7SAndrew Morton 		{						\
168c8f5c4c7SCristina Ciocan 			.mixed_funcs		= (f),		\
169bbccb9c7SAndrew Morton 		},						\
170c8f5c4c7SCristina Ciocan 		.nfuncs			= ARRAY_SIZE((f)),	\
171c8f5c4c7SCristina Ciocan 	}
172c8f5c4c7SCristina Ciocan 
173c8f5c4c7SCristina Ciocan #define FUNCTION(n, g)					\
174c8f5c4c7SCristina Ciocan 	{						\
175c8f5c4c7SCristina Ciocan 		.name		= (n),			\
176c8f5c4c7SCristina Ciocan 		.groups		= (g),			\
177c8f5c4c7SCristina Ciocan 		.ngroups	= ARRAY_SIZE((g)),	\
178c8f5c4c7SCristina Ciocan 	}
179c8f5c4c7SCristina Ciocan 
180c8f5c4c7SCristina Ciocan #define COMMUNITY(p, n, map)		\
181c8f5c4c7SCristina Ciocan 	{				\
182c8f5c4c7SCristina Ciocan 		.pin_base	= (p),	\
183c8f5c4c7SCristina Ciocan 		.npins		= (n),	\
184c8f5c4c7SCristina Ciocan 		.pad_map	= (map),\
185c8f5c4c7SCristina Ciocan 	}
186c8f5c4c7SCristina Ciocan 
187c8f5c4c7SCristina Ciocan struct byt_pinctrl_soc_data {
188c8f5c4c7SCristina Ciocan 	const char *uid;
189c8f5c4c7SCristina Ciocan 	const struct pinctrl_pin_desc *pins;
190c8f5c4c7SCristina Ciocan 	size_t npins;
191c8f5c4c7SCristina Ciocan 	const struct byt_pingroup *groups;
192c8f5c4c7SCristina Ciocan 	size_t ngroups;
193c8f5c4c7SCristina Ciocan 	const struct byt_function *functions;
194c8f5c4c7SCristina Ciocan 	size_t nfunctions;
195c8f5c4c7SCristina Ciocan 	const struct byt_community *communities;
196c8f5c4c7SCristina Ciocan 	size_t ncommunities;
197c8f5c4c7SCristina Ciocan };
198c8f5c4c7SCristina Ciocan 
19971e6ca61SCristina Ciocan struct byt_gpio {
20071e6ca61SCristina Ciocan 	struct gpio_chip chip;
20171e6ca61SCristina Ciocan 	struct platform_device *pdev;
20271e6ca61SCristina Ciocan 	struct pinctrl_dev *pctl_dev;
20371e6ca61SCristina Ciocan 	struct pinctrl_desc pctl_desc;
20471e6ca61SCristina Ciocan 	raw_spinlock_t lock;
20571e6ca61SCristina Ciocan 	const struct byt_pinctrl_soc_data *soc_data;
20671e6ca61SCristina Ciocan 	struct byt_community *communities_copy;
20771e6ca61SCristina Ciocan 	struct byt_gpio_pin_context *saved_context;
20871e6ca61SCristina Ciocan };
20971e6ca61SCristina Ciocan 
210c8f5c4c7SCristina Ciocan /* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */
211c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_score_pins[] = {
212c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(0, "SATA_GP0"),
213c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(1, "SATA_GP1"),
214c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(2, "SATA_LED#"),
215c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(3, "PCIE_CLKREQ0"),
216c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(4, "PCIE_CLKREQ1"),
217c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(5, "PCIE_CLKREQ2"),
218c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(6, "PCIE_CLKREQ3"),
219c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(7, "SD3_WP"),
220c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(8, "HDA_RST"),
221c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(9, "HDA_SYNC"),
222c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(10, "HDA_CLK"),
223c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(11, "HDA_SDO"),
224c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(12, "HDA_SDI0"),
225c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(13, "HDA_SDI1"),
226c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(14, "GPIO_S0_SC14"),
227c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(15, "GPIO_S0_SC15"),
228c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(16, "MMC1_CLK"),
229c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(17, "MMC1_D0"),
230c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(18, "MMC1_D1"),
231c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(19, "MMC1_D2"),
232c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(20, "MMC1_D3"),
233c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(21, "MMC1_D4"),
234c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(22, "MMC1_D5"),
235c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(23, "MMC1_D6"),
236c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(24, "MMC1_D7"),
237c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(25, "MMC1_CMD"),
238c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(26, "MMC1_RST"),
239c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(27, "SD2_CLK"),
240c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(28, "SD2_D0"),
241c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(29, "SD2_D1"),
242c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(30, "SD2_D2"),
243c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(31, "SD2_D3_CD"),
244c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(32, "SD2_CMD"),
245c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(33, "SD3_CLK"),
246c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(34, "SD3_D0"),
247c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(35, "SD3_D1"),
248c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(36, "SD3_D2"),
249c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(37, "SD3_D3"),
250c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(38, "SD3_CD"),
251c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(39, "SD3_CMD"),
252c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(40, "SD3_1P8EN"),
253c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(41, "SD3_PWREN#"),
254c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(42, "ILB_LPC_AD0"),
255c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(43, "ILB_LPC_AD1"),
256c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(44, "ILB_LPC_AD2"),
257c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(45, "ILB_LPC_AD3"),
258c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(46, "ILB_LPC_FRAME"),
259c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(47, "ILB_LPC_CLK0"),
260c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(48, "ILB_LPC_CLK1"),
261c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(49, "ILB_LPC_CLKRUN"),
262c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(50, "ILB_LPC_SERIRQ"),
263c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(51, "PCU_SMB_DATA"),
264c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(52, "PCU_SMB_CLK"),
265c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(53, "PCU_SMB_ALERT"),
266c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(54, "ILB_8254_SPKR"),
267c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(55, "GPIO_S0_SC55"),
268c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(56, "GPIO_S0_SC56"),
269c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(57, "GPIO_S0_SC57"),
270c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(58, "GPIO_S0_SC58"),
271c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(59, "GPIO_S0_SC59"),
272c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(60, "GPIO_S0_SC60"),
273c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(61, "GPIO_S0_SC61"),
274c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(62, "LPE_I2S2_CLK"),
275c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(63, "LPE_I2S2_FRM"),
276c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(64, "LPE_I2S2_DATAIN"),
277c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"),
278c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(66, "SIO_SPI_CS"),
279c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(67, "SIO_SPI_MISO"),
280c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(68, "SIO_SPI_MOSI"),
281c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(69, "SIO_SPI_CLK"),
282c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(70, "SIO_UART1_RXD"),
283c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(71, "SIO_UART1_TXD"),
284c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(72, "SIO_UART1_RTS"),
285c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(73, "SIO_UART1_CTS"),
286c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(74, "SIO_UART2_RXD"),
287c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(75, "SIO_UART2_TXD"),
288c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(76, "SIO_UART2_RTS"),
289c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(77, "SIO_UART2_CTS"),
290c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(78, "SIO_I2C0_DATA"),
291c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(79, "SIO_I2C0_CLK"),
292c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(80, "SIO_I2C1_DATA"),
293c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(81, "SIO_I2C1_CLK"),
294c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(82, "SIO_I2C2_DATA"),
295c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(83, "SIO_I2C2_CLK"),
296c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(84, "SIO_I2C3_DATA"),
297c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(85, "SIO_I2C3_CLK"),
298c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(86, "SIO_I2C4_DATA"),
299c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(87, "SIO_I2C4_CLK"),
300c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(88, "SIO_I2C5_DATA"),
301c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(89, "SIO_I2C5_CLK"),
302c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(90, "SIO_I2C6_DATA"),
303c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(91, "SIO_I2C6_CLK"),
304c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(92, "GPIO_S0_SC92"),
305c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(93, "GPIO_S0_SC93"),
306c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(94, "SIO_PWM0"),
307c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(95, "SIO_PWM1"),
308c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(96, "PMC_PLT_CLK0"),
309c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(97, "PMC_PLT_CLK1"),
310c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(98, "PMC_PLT_CLK2"),
311c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(99, "PMC_PLT_CLK3"),
312c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(100, "PMC_PLT_CLK4"),
313c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(101, "PMC_PLT_CLK5"),
314c8f5c4c7SCristina Ciocan };
3155fae8b86SMika Westerberg 
316c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = {
317c8f5c4c7SCristina Ciocan 	85, 89, 93, 96, 99, 102, 98, 101, 34, 37,
318c8f5c4c7SCristina Ciocan 	36, 38, 39, 35, 40, 84, 62, 61, 64, 59,
319c8f5c4c7SCristina Ciocan 	54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
320c8f5c4c7SCristina Ciocan 	52, 49, 48, 43, 46, 41, 45, 42, 58, 44,
321c8f5c4c7SCristina Ciocan 	95, 105, 70, 68, 67, 66, 69, 71, 65, 72,
322c8f5c4c7SCristina Ciocan 	86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
323c8f5c4c7SCristina Ciocan 	80, 82, 13, 12, 15, 14, 17, 18, 19, 16,
324c8f5c4c7SCristina Ciocan 	2, 1, 0, 4, 6, 7, 9, 8, 33, 32,
325c8f5c4c7SCristina Ciocan 	31, 30, 29, 27, 25, 28, 26, 23, 21, 20,
326c8f5c4c7SCristina Ciocan 	24, 22, 5, 3, 10, 11, 106, 87, 91, 104,
327c8f5c4c7SCristina Ciocan 	97, 100,
3285fae8b86SMika Westerberg };
3295fae8b86SMika Westerberg 
330c8f5c4c7SCristina Ciocan /* SCORE groups */
331c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 };
332c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 };
333c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_uart_mux[] = {
334c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("uart", 1),
335c8f5c4c7SCristina Ciocan };
336c8f5c4c7SCristina Ciocan 
337c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm0_pins[] = { 94 };
338c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm1_pins[] = { 95 };
339c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_pwm_mux[] = {
340c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("pwm", 1),
341c8f5c4c7SCristina Ciocan };
342c8f5c4c7SCristina Ciocan 
343c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 };
344c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_spi_mux[] = {
345c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("spi", 1),
346c8f5c4c7SCristina Ciocan };
347c8f5c4c7SCristina Ciocan 
348c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c5_pins[] = { 88, 89 };
349c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c6_pins[] = { 90, 91 };
350c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c4_pins[] = { 86, 87 };
351c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c3_pins[] = { 84, 85 };
352c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c2_pins[] = { 82, 83 };
353c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c1_pins[] = { 80, 81 };
354c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c0_pins[] = { 78, 79 };
355c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_i2c_mux[] = {
356c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("i2c", 1),
357c8f5c4c7SCristina Ciocan };
358c8f5c4c7SCristina Ciocan 
359c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 };
360c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 };
361c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 };
362c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_ssp_mux[] = {
363c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("ssp", 1),
364c8f5c4c7SCristina Ciocan };
365c8f5c4c7SCristina Ciocan 
366c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdcard_pins[] = {
367c8f5c4c7SCristina Ciocan 	7, 33, 34, 35, 36, 37, 38, 39, 40, 41,
368c8f5c4c7SCristina Ciocan };
369c8f5c4c7SCristina Ciocan static const unsigned short byt_score_sdcard_mux_values[] = {
370c8f5c4c7SCristina Ciocan 	2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
371c8f5c4c7SCristina Ciocan };
372c8f5c4c7SCristina Ciocan static const struct byt_mixed_func_mux byt_score_sdcard_mux[] = {
373c8f5c4c7SCristina Ciocan 	MIXED_FUNC("sdcard", byt_score_sdcard_mux_values),
374c8f5c4c7SCristina Ciocan };
375c8f5c4c7SCristina Ciocan 
376c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 };
377c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_sdio_mux[] = {
378c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("sdio", 1),
379c8f5c4c7SCristina Ciocan };
380c8f5c4c7SCristina Ciocan 
381c8f5c4c7SCristina Ciocan static const unsigned int byt_score_emmc_pins[] = {
382c8f5c4c7SCristina Ciocan 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
383c8f5c4c7SCristina Ciocan };
384c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_emmc_mux[] = {
385c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("emmc", 1),
386c8f5c4c7SCristina Ciocan };
387c8f5c4c7SCristina Ciocan 
388c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ilb_lpc_pins[] = {
389c8f5c4c7SCristina Ciocan 	42, 43, 44, 45, 46, 47, 48, 49, 50,
390c8f5c4c7SCristina Ciocan };
391c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_lpc_mux[] = {
392c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("lpc", 1),
393c8f5c4c7SCristina Ciocan };
394c8f5c4c7SCristina Ciocan 
395c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 };
396c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_sata_mux[] = {
397c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("sata", 1),
398c8f5c4c7SCristina Ciocan };
399c8f5c4c7SCristina Ciocan 
400c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk0_pins[] = { 96 };
401c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk1_pins[] = { 97 };
402c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk2_pins[] = { 98 };
403b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk3_pins[] = { 99 };
404b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk4_pins[] = { 100 };
405b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk5_pins[] = { 101 };
406c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_plt_clk_mux[] = {
407c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("plt_clk", 1),
408c8f5c4c7SCristina Ciocan };
409c8f5c4c7SCristina Ciocan 
410c8f5c4c7SCristina Ciocan static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 };
411c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_smbus_mux[] = {
412c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("smbus", 1),
413c8f5c4c7SCristina Ciocan };
414c8f5c4c7SCristina Ciocan 
415c8f5c4c7SCristina Ciocan static const struct byt_pingroup byt_score_groups[] = {
416c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("uart1_grp",
417c8f5c4c7SCristina Ciocan 			 byt_score_uart1_pins, byt_score_uart_mux),
418c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("uart2_grp",
419c8f5c4c7SCristina Ciocan 			 byt_score_uart2_pins, byt_score_uart_mux),
420c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("pwm0_grp",
421c8f5c4c7SCristina Ciocan 			 byt_score_pwm0_pins, byt_score_pwm_mux),
422c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("pwm1_grp",
423c8f5c4c7SCristina Ciocan 			 byt_score_pwm1_pins, byt_score_pwm_mux),
424c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("ssp2_grp",
425c8f5c4c7SCristina Ciocan 			 byt_score_ssp2_pins, byt_score_pwm_mux),
426c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("sio_spi_grp",
427c8f5c4c7SCristina Ciocan 			 byt_score_sio_spi_pins, byt_score_spi_mux),
428c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("i2c5_grp",
429c8f5c4c7SCristina Ciocan 			 byt_score_i2c5_pins, byt_score_i2c_mux),
430c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("i2c6_grp",
431c8f5c4c7SCristina Ciocan 			 byt_score_i2c6_pins, byt_score_i2c_mux),
432c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("i2c4_grp",
433c8f5c4c7SCristina Ciocan 			 byt_score_i2c4_pins, byt_score_i2c_mux),
434c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("i2c3_grp",
435c8f5c4c7SCristina Ciocan 			 byt_score_i2c3_pins, byt_score_i2c_mux),
436c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("i2c2_grp",
437c8f5c4c7SCristina Ciocan 			 byt_score_i2c2_pins, byt_score_i2c_mux),
438c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("i2c1_grp",
439c8f5c4c7SCristina Ciocan 			 byt_score_i2c1_pins, byt_score_i2c_mux),
440c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("i2c0_grp",
441c8f5c4c7SCristina Ciocan 			 byt_score_i2c0_pins, byt_score_i2c_mux),
442c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("ssp0_grp",
443c8f5c4c7SCristina Ciocan 			 byt_score_ssp0_pins, byt_score_ssp_mux),
444c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("ssp1_grp",
445c8f5c4c7SCristina Ciocan 			 byt_score_ssp1_pins, byt_score_ssp_mux),
446c8f5c4c7SCristina Ciocan 	PIN_GROUP_MIXED("sdcard_grp",
447c8f5c4c7SCristina Ciocan 			byt_score_sdcard_pins, byt_score_sdcard_mux),
448c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("sdio_grp",
449c8f5c4c7SCristina Ciocan 			 byt_score_sdio_pins, byt_score_sdio_mux),
450c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("emmc_grp",
451c8f5c4c7SCristina Ciocan 			 byt_score_emmc_pins, byt_score_emmc_mux),
452c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("lpc_grp",
453c8f5c4c7SCristina Ciocan 			 byt_score_ilb_lpc_pins, byt_score_lpc_mux),
454c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("sata_grp",
455c8f5c4c7SCristina Ciocan 			 byt_score_sata_pins, byt_score_sata_mux),
456c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("plt_clk0_grp",
457c8f5c4c7SCristina Ciocan 			 byt_score_plt_clk0_pins, byt_score_plt_clk_mux),
458c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("plt_clk1_grp",
459c8f5c4c7SCristina Ciocan 			 byt_score_plt_clk1_pins, byt_score_plt_clk_mux),
460c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("plt_clk2_grp",
461c8f5c4c7SCristina Ciocan 			 byt_score_plt_clk2_pins, byt_score_plt_clk_mux),
462c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("plt_clk3_grp",
463c8f5c4c7SCristina Ciocan 			 byt_score_plt_clk3_pins, byt_score_plt_clk_mux),
464c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("plt_clk4_grp",
465c8f5c4c7SCristina Ciocan 			 byt_score_plt_clk4_pins, byt_score_plt_clk_mux),
466c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("plt_clk5_grp",
467c8f5c4c7SCristina Ciocan 			 byt_score_plt_clk5_pins, byt_score_plt_clk_mux),
468c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("smbus_grp",
469c8f5c4c7SCristina Ciocan 			 byt_score_smbus_pins, byt_score_smbus_mux),
470c8f5c4c7SCristina Ciocan };
471c8f5c4c7SCristina Ciocan 
472c8f5c4c7SCristina Ciocan static const char * const byt_score_uart_groups[] = {
473c8f5c4c7SCristina Ciocan 	"uart1_grp", "uart2_grp",
474c8f5c4c7SCristina Ciocan };
475c8f5c4c7SCristina Ciocan static const char * const byt_score_pwm_groups[] = {
476c8f5c4c7SCristina Ciocan 	"pwm0_grp", "pwm1_grp",
477c8f5c4c7SCristina Ciocan };
478c8f5c4c7SCristina Ciocan static const char * const byt_score_ssp_groups[] = {
479c8f5c4c7SCristina Ciocan 	"ssp0_grp", "ssp1_grp", "ssp2_grp",
480c8f5c4c7SCristina Ciocan };
481c8f5c4c7SCristina Ciocan static const char * const byt_score_spi_groups[] = { "sio_spi_grp" };
482c8f5c4c7SCristina Ciocan static const char * const byt_score_i2c_groups[] = {
483c8f5c4c7SCristina Ciocan 	"i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp",
484c8f5c4c7SCristina Ciocan 	"i2c6_grp",
485c8f5c4c7SCristina Ciocan };
486c8f5c4c7SCristina Ciocan static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" };
487c8f5c4c7SCristina Ciocan static const char * const byt_score_sdio_groups[] = { "sdio_grp" };
488c8f5c4c7SCristina Ciocan static const char * const byt_score_emmc_groups[] = { "emmc_grp" };
489c8f5c4c7SCristina Ciocan static const char * const byt_score_lpc_groups[] = { "lpc_grp" };
490c8f5c4c7SCristina Ciocan static const char * const byt_score_sata_groups[] = { "sata_grp" };
491c8f5c4c7SCristina Ciocan static const char * const byt_score_plt_clk_groups[] = {
492c8f5c4c7SCristina Ciocan 	"plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
493c8f5c4c7SCristina Ciocan 	"plt_clk4_grp", "plt_clk5_grp",
494c8f5c4c7SCristina Ciocan };
495c8f5c4c7SCristina Ciocan static const char * const byt_score_smbus_groups[] = { "smbus_grp" };
496c8f5c4c7SCristina Ciocan static const char * const byt_score_gpio_groups[] = {
497c8f5c4c7SCristina Ciocan 	"uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp",
498c8f5c4c7SCristina Ciocan 	"ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp",
499c8f5c4c7SCristina Ciocan 	"i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp",
500c8f5c4c7SCristina Ciocan 	"sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp",
501c8f5c4c7SCristina Ciocan 	"plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
502c8f5c4c7SCristina Ciocan 	"plt_clk4_grp", "plt_clk5_grp", "smbus_grp",
503c8f5c4c7SCristina Ciocan 
504c8f5c4c7SCristina Ciocan };
505c8f5c4c7SCristina Ciocan 
506c8f5c4c7SCristina Ciocan static const struct byt_function byt_score_functions[] = {
507c8f5c4c7SCristina Ciocan 	FUNCTION("uart", byt_score_uart_groups),
508c8f5c4c7SCristina Ciocan 	FUNCTION("pwm", byt_score_pwm_groups),
509c8f5c4c7SCristina Ciocan 	FUNCTION("ssp", byt_score_ssp_groups),
510c8f5c4c7SCristina Ciocan 	FUNCTION("spi", byt_score_spi_groups),
511c8f5c4c7SCristina Ciocan 	FUNCTION("i2c", byt_score_i2c_groups),
512c8f5c4c7SCristina Ciocan 	FUNCTION("sdcard", byt_score_sdcard_groups),
513c8f5c4c7SCristina Ciocan 	FUNCTION("sdio", byt_score_sdio_groups),
514c8f5c4c7SCristina Ciocan 	FUNCTION("emmc", byt_score_emmc_groups),
515c8f5c4c7SCristina Ciocan 	FUNCTION("lpc", byt_score_lpc_groups),
516c8f5c4c7SCristina Ciocan 	FUNCTION("sata", byt_score_sata_groups),
517c8f5c4c7SCristina Ciocan 	FUNCTION("plt_clk", byt_score_plt_clk_groups),
518c8f5c4c7SCristina Ciocan 	FUNCTION("smbus", byt_score_smbus_groups),
519c8f5c4c7SCristina Ciocan 	FUNCTION("gpio", byt_score_gpio_groups),
520c8f5c4c7SCristina Ciocan };
521c8f5c4c7SCristina Ciocan 
522c8f5c4c7SCristina Ciocan static const struct byt_community byt_score_communities[] = {
523c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
524c8f5c4c7SCristina Ciocan };
525c8f5c4c7SCristina Ciocan 
526c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_score_soc_data = {
527c8f5c4c7SCristina Ciocan 	.uid		= BYT_SCORE_ACPI_UID,
528c8f5c4c7SCristina Ciocan 	.pins		= byt_score_pins,
529c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_score_pins),
530c8f5c4c7SCristina Ciocan 	.groups		= byt_score_groups,
531c8f5c4c7SCristina Ciocan 	.ngroups	= ARRAY_SIZE(byt_score_groups),
532c8f5c4c7SCristina Ciocan 	.functions	= byt_score_functions,
533c8f5c4c7SCristina Ciocan 	.nfunctions	= ARRAY_SIZE(byt_score_functions),
534c8f5c4c7SCristina Ciocan 	.communities	= byt_score_communities,
535c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_score_communities),
536c8f5c4c7SCristina Ciocan };
537c8f5c4c7SCristina Ciocan 
538c8f5c4c7SCristina Ciocan /* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>]  */
539c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_sus_pins[] = {
540c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(0, "GPIO_S50"),
541c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(1, "GPIO_S51"),
542c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(2, "GPIO_S52"),
543c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(3, "GPIO_S53"),
544c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(4, "GPIO_S54"),
545c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(5, "GPIO_S55"),
546c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(6, "GPIO_S56"),
547c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(7, "GPIO_S57"),
548c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(8, "GPIO_S58"),
549c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(9, "GPIO_S59"),
550c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(10, "GPIO_S510"),
551c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(11, "PMC_SUSPWRDNACK"),
552c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(12, "PMC_SUSCLK0"),
553c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(13, "GPIO_S513"),
554c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(14, "USB_ULPI_RST"),
555c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"),
556c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(16, "PMC_PWRBTN"),
557c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(17, "GPIO_S517"),
558c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(18, "PMC_SUS_STAT"),
559c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(19, "USB_OC0"),
560c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(20, "USB_OC1"),
561c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(21, "PCU_SPI_CS1"),
562c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(22, "GPIO_S522"),
563c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(23, "GPIO_S523"),
564c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(24, "GPIO_S524"),
565c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(25, "GPIO_S525"),
566c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(26, "GPIO_S526"),
567c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(27, "GPIO_S527"),
568c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(28, "GPIO_S528"),
569c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(29, "GPIO_S529"),
570c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(30, "GPIO_S530"),
571c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(31, "USB_ULPI_CLK"),
572c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(32, "USB_ULPI_DATA0"),
573c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(33, "USB_ULPI_DATA1"),
574c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(34, "USB_ULPI_DATA2"),
575c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(35, "USB_ULPI_DATA3"),
576c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(36, "USB_ULPI_DATA4"),
577c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(37, "USB_ULPI_DATA5"),
578c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(38, "USB_ULPI_DATA6"),
579c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(39, "USB_ULPI_DATA7"),
580c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(40, "USB_ULPI_DIR"),
581c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(41, "USB_ULPI_NXT"),
582c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(42, "USB_ULPI_STP"),
583c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(43, "USB_ULPI_REFCLK"),
584c8f5c4c7SCristina Ciocan };
585c8f5c4c7SCristina Ciocan 
586c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = {
587c8f5c4c7SCristina Ciocan 	29, 33, 30, 31, 32, 34, 36, 35, 38, 37,
588c8f5c4c7SCristina Ciocan 	18, 7, 11, 20, 17, 1, 8, 10, 19, 12,
589c8f5c4c7SCristina Ciocan 	0, 2, 23, 39, 28, 27, 22, 21, 24, 25,
590c8f5c4c7SCristina Ciocan 	26, 51, 56, 54, 49, 55, 48, 57, 50, 58,
591c8f5c4c7SCristina Ciocan 	52, 53, 59, 40,
592c8f5c4c7SCristina Ciocan };
593c8f5c4c7SCristina Ciocan 
594c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 };
595c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_sus_usb_oc_mux[] = {
596c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("usb", 0),
597c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("gpio", 1),
598c8f5c4c7SCristina Ciocan };
599c8f5c4c7SCristina Ciocan 
600c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_ulpi_pins[] = {
601c8f5c4c7SCristina Ciocan 	14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
602c8f5c4c7SCristina Ciocan };
603c8f5c4c7SCristina Ciocan static const unsigned short byt_sus_usb_ulpi_mode_values[] = {
604c8f5c4c7SCristina Ciocan 	2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
605c8f5c4c7SCristina Ciocan };
606c8f5c4c7SCristina Ciocan static const unsigned short byt_sus_usb_ulpi_gpio_mode_values[] = {
607c8f5c4c7SCristina Ciocan 	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
608c8f5c4c7SCristina Ciocan };
609c8f5c4c7SCristina Ciocan static const struct byt_mixed_func_mux byt_sus_usb_ulpi_mux[] = {
610c8f5c4c7SCristina Ciocan 	MIXED_FUNC("usb", byt_sus_usb_ulpi_mode_values),
611c8f5c4c7SCristina Ciocan 	MIXED_FUNC("gpio", byt_sus_usb_ulpi_gpio_mode_values),
612c8f5c4c7SCristina Ciocan };
613c8f5c4c7SCristina Ciocan 
614c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pcu_spi_pins[] = { 21 };
615c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_sus_pcu_spi_mux[] = {
616c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("spi", 0),
617c8f5c4c7SCristina Ciocan 	SIMPLE_FUNC("gpio", 1),
618c8f5c4c7SCristina Ciocan };
619c8f5c4c7SCristina Ciocan 
620c8f5c4c7SCristina Ciocan static const struct byt_pingroup byt_sus_groups[] = {
621c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("usb_oc_grp",
622c8f5c4c7SCristina Ciocan 			byt_sus_usb_over_current_pins, byt_sus_usb_oc_mux),
623c8f5c4c7SCristina Ciocan 	PIN_GROUP_MIXED("usb_ulpi_grp",
624c8f5c4c7SCristina Ciocan 			byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mux),
625c8f5c4c7SCristina Ciocan 	PIN_GROUP_SIMPLE("pcu_spi_grp",
626c8f5c4c7SCristina Ciocan 			byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mux),
627c8f5c4c7SCristina Ciocan };
628c8f5c4c7SCristina Ciocan 
629c8f5c4c7SCristina Ciocan static const char * const byt_sus_usb_groups[] = {
630c8f5c4c7SCristina Ciocan 	"usb_oc_grp", "usb_ulpi_grp",
631c8f5c4c7SCristina Ciocan };
632c8f5c4c7SCristina Ciocan static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" };
633c8f5c4c7SCristina Ciocan static const char * const byt_sus_gpio_groups[] = {
634c8f5c4c7SCristina Ciocan 	"usb_oc_grp", "usb_ulpi_grp", "pcu_spi_grp",
635c8f5c4c7SCristina Ciocan };
636c8f5c4c7SCristina Ciocan 
637c8f5c4c7SCristina Ciocan static const struct byt_function byt_sus_functions[] = {
638c8f5c4c7SCristina Ciocan 	FUNCTION("usb", byt_sus_usb_groups),
639c8f5c4c7SCristina Ciocan 	FUNCTION("spi", byt_sus_spi_groups),
640c8f5c4c7SCristina Ciocan 	FUNCTION("gpio", byt_sus_gpio_groups),
641c8f5c4c7SCristina Ciocan };
642c8f5c4c7SCristina Ciocan 
643c8f5c4c7SCristina Ciocan static const struct byt_community byt_sus_communities[] = {
644c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
645c8f5c4c7SCristina Ciocan };
646c8f5c4c7SCristina Ciocan 
647c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_sus_soc_data = {
648c8f5c4c7SCristina Ciocan 	.uid		= BYT_SUS_ACPI_UID,
649c8f5c4c7SCristina Ciocan 	.pins		= byt_sus_pins,
650c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_sus_pins),
651c8f5c4c7SCristina Ciocan 	.groups		= byt_sus_groups,
652c8f5c4c7SCristina Ciocan 	.ngroups	= ARRAY_SIZE(byt_sus_groups),
653c8f5c4c7SCristina Ciocan 	.functions	= byt_sus_functions,
654c8f5c4c7SCristina Ciocan 	.nfunctions	= ARRAY_SIZE(byt_sus_functions),
655c8f5c4c7SCristina Ciocan 	.communities	= byt_sus_communities,
656c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_sus_communities),
657c8f5c4c7SCristina Ciocan };
658c8f5c4c7SCristina Ciocan 
659c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_ncore_pins[] = {
660c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(0, "GPIO_NCORE0"),
661c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(1, "GPIO_NCORE1"),
662c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(2, "GPIO_NCORE2"),
663c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(3, "GPIO_NCORE3"),
664c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(4, "GPIO_NCORE4"),
665c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(5, "GPIO_NCORE5"),
666c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(6, "GPIO_NCORE6"),
667c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(7, "GPIO_NCORE7"),
668c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(8, "GPIO_NCORE8"),
669c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(9, "GPIO_NCORE9"),
670c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(10, "GPIO_NCORE10"),
671c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(11, "GPIO_NCORE11"),
672c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(12, "GPIO_NCORE12"),
673c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(13, "GPIO_NCORE13"),
674c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(14, "GPIO_NCORE14"),
675c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(15, "GPIO_NCORE15"),
676c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(16, "GPIO_NCORE16"),
677c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(17, "GPIO_NCORE17"),
678c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(18, "GPIO_NCORE18"),
679c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(19, "GPIO_NCORE19"),
680c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(20, "GPIO_NCORE20"),
681c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(21, "GPIO_NCORE21"),
682c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(22, "GPIO_NCORE22"),
683c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(23, "GPIO_NCORE23"),
684c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(24, "GPIO_NCORE24"),
685c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(25, "GPIO_NCORE25"),
686c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(26, "GPIO_NCORE26"),
687c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(27, "GPIO_NCORE27"),
688c8f5c4c7SCristina Ciocan };
689c8f5c4c7SCristina Ciocan 
690c8f5c4c7SCristina Ciocan static unsigned const byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
691c8f5c4c7SCristina Ciocan 	19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
692c8f5c4c7SCristina Ciocan 	14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
693c8f5c4c7SCristina Ciocan 	3, 6, 10, 13, 2, 5, 9, 7,
694c8f5c4c7SCristina Ciocan };
695c8f5c4c7SCristina Ciocan 
696c8f5c4c7SCristina Ciocan static const struct byt_community byt_ncore_communities[] = {
697c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
698c8f5c4c7SCristina Ciocan };
699c8f5c4c7SCristina Ciocan 
700c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_ncore_soc_data = {
701c8f5c4c7SCristina Ciocan 	.uid		= BYT_NCORE_ACPI_UID,
702c8f5c4c7SCristina Ciocan 	.pins		= byt_ncore_pins,
703c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_ncore_pins),
704c8f5c4c7SCristina Ciocan 	.communities	= byt_ncore_communities,
705c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_ncore_communities),
706c8f5c4c7SCristina Ciocan };
707c8f5c4c7SCristina Ciocan 
708c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data *byt_soc_data[] = {
709c8f5c4c7SCristina Ciocan 	&byt_score_soc_data,
710c8f5c4c7SCristina Ciocan 	&byt_sus_soc_data,
711c8f5c4c7SCristina Ciocan 	&byt_ncore_soc_data,
712c8f5c4c7SCristina Ciocan 	NULL,
713c8f5c4c7SCristina Ciocan };
714c8f5c4c7SCristina Ciocan 
715c501d0b1SCristina Ciocan static struct byt_community *byt_get_community(struct byt_gpio *vg,
716c501d0b1SCristina Ciocan 					       unsigned int pin)
717c501d0b1SCristina Ciocan {
718c501d0b1SCristina Ciocan 	struct byt_community *comm;
719c501d0b1SCristina Ciocan 	int i;
720c501d0b1SCristina Ciocan 
721c501d0b1SCristina Ciocan 	for (i = 0; i < vg->soc_data->ncommunities; i++) {
722c501d0b1SCristina Ciocan 		comm = vg->communities_copy + i;
723c501d0b1SCristina Ciocan 		if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base)
724c501d0b1SCristina Ciocan 			return comm;
725c501d0b1SCristina Ciocan 	}
726c501d0b1SCristina Ciocan 
727c501d0b1SCristina Ciocan 	return NULL;
728c501d0b1SCristina Ciocan }
729c501d0b1SCristina Ciocan 
730c501d0b1SCristina Ciocan static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
7315fae8b86SMika Westerberg 				  int reg)
7325fae8b86SMika Westerberg {
733c501d0b1SCristina Ciocan 	struct byt_community *comm = byt_get_community(vg, offset);
7341b89970dSAndy Shevchenko 	u32 reg_offset;
7355fae8b86SMika Westerberg 
736c501d0b1SCristina Ciocan 	if (!comm)
737c501d0b1SCristina Ciocan 		return NULL;
738c501d0b1SCristina Ciocan 
739c501d0b1SCristina Ciocan 	offset -= comm->pin_base;
7401b89970dSAndy Shevchenko 	switch (reg) {
7411b89970dSAndy Shevchenko 	case BYT_INT_STAT_REG:
7425fae8b86SMika Westerberg 		reg_offset = (offset / 32) * 4;
7431b89970dSAndy Shevchenko 		break;
7441b89970dSAndy Shevchenko 	case BYT_DEBOUNCE_REG:
7451b89970dSAndy Shevchenko 		reg_offset = 0;
7461b89970dSAndy Shevchenko 		break;
7471b89970dSAndy Shevchenko 	default:
748c501d0b1SCristina Ciocan 		reg_offset = comm->pad_map[offset] * 16;
7491b89970dSAndy Shevchenko 		break;
7501b89970dSAndy Shevchenko 	}
7515fae8b86SMika Westerberg 
752c501d0b1SCristina Ciocan 	return comm->reg_base + reg_offset + reg;
7535fae8b86SMika Westerberg }
7545fae8b86SMika Westerberg 
755c501d0b1SCristina Ciocan static int byt_get_groups_count(struct pinctrl_dev *pctldev)
75695f0972cSMika Westerberg {
757c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
758c501d0b1SCristina Ciocan 
759c501d0b1SCristina Ciocan 	return vg->soc_data->ngroups;
760c501d0b1SCristina Ciocan }
761c501d0b1SCristina Ciocan 
762c501d0b1SCristina Ciocan static const char *byt_get_group_name(struct pinctrl_dev *pctldev,
763c501d0b1SCristina Ciocan 				      unsigned int selector)
764c501d0b1SCristina Ciocan {
765c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
766c501d0b1SCristina Ciocan 
767c501d0b1SCristina Ciocan 	return vg->soc_data->groups[selector].name;
768c501d0b1SCristina Ciocan }
769c501d0b1SCristina Ciocan 
770c501d0b1SCristina Ciocan static int byt_get_group_pins(struct pinctrl_dev *pctldev,
771c501d0b1SCristina Ciocan 			      unsigned int selector,
772c501d0b1SCristina Ciocan 			      const unsigned int **pins,
773c501d0b1SCristina Ciocan 			      unsigned int *num_pins)
774c501d0b1SCristina Ciocan {
775c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
776c501d0b1SCristina Ciocan 
777c501d0b1SCristina Ciocan 	*pins		= vg->soc_data->groups[selector].pins;
778c501d0b1SCristina Ciocan 	*num_pins	= vg->soc_data->groups[selector].npins;
779c501d0b1SCristina Ciocan 
780c501d0b1SCristina Ciocan 	return 0;
781c501d0b1SCristina Ciocan }
782c501d0b1SCristina Ciocan 
783c501d0b1SCristina Ciocan static const struct pinctrl_ops byt_pinctrl_ops = {
784c501d0b1SCristina Ciocan 	.get_groups_count	= byt_get_groups_count,
785c501d0b1SCristina Ciocan 	.get_group_name		= byt_get_group_name,
786c501d0b1SCristina Ciocan 	.get_group_pins		= byt_get_group_pins,
787c501d0b1SCristina Ciocan };
788c501d0b1SCristina Ciocan 
789c501d0b1SCristina Ciocan static int byt_get_functions_count(struct pinctrl_dev *pctldev)
790c501d0b1SCristina Ciocan {
791c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
792c501d0b1SCristina Ciocan 
793c501d0b1SCristina Ciocan 	return vg->soc_data->nfunctions;
794c501d0b1SCristina Ciocan }
795c501d0b1SCristina Ciocan 
796c501d0b1SCristina Ciocan static const char *byt_get_function_name(struct pinctrl_dev *pctldev,
797c501d0b1SCristina Ciocan 					 unsigned int selector)
798c501d0b1SCristina Ciocan {
799c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
800c501d0b1SCristina Ciocan 
801c501d0b1SCristina Ciocan 	return vg->soc_data->functions[selector].name;
802c501d0b1SCristina Ciocan }
803c501d0b1SCristina Ciocan 
804c501d0b1SCristina Ciocan static int byt_get_function_groups(struct pinctrl_dev *pctldev,
805c501d0b1SCristina Ciocan 				   unsigned int selector,
806c501d0b1SCristina Ciocan 				   const char * const **groups,
807c501d0b1SCristina Ciocan 				   unsigned int *num_groups)
808c501d0b1SCristina Ciocan {
809c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
810c501d0b1SCristina Ciocan 
811c501d0b1SCristina Ciocan 	*groups		= vg->soc_data->functions[selector].groups;
812c501d0b1SCristina Ciocan 	*num_groups	= vg->soc_data->functions[selector].ngroups;
813c501d0b1SCristina Ciocan 
814c501d0b1SCristina Ciocan 	return 0;
815c501d0b1SCristina Ciocan }
816c501d0b1SCristina Ciocan 
817c501d0b1SCristina Ciocan static int byt_get_group_simple_mux(const struct byt_pingroup group,
818c501d0b1SCristina Ciocan 				    const char *func_name,
819c501d0b1SCristina Ciocan 				    unsigned short *func)
820c501d0b1SCristina Ciocan {
821c501d0b1SCristina Ciocan 	int i;
822c501d0b1SCristina Ciocan 
823c501d0b1SCristina Ciocan 	for (i = 0; i < group.nfuncs; i++) {
824c501d0b1SCristina Ciocan 		if (!strcmp(group.simple_funcs[i].name, func_name)) {
825c501d0b1SCristina Ciocan 			*func = group.simple_funcs[i].func;
826c501d0b1SCristina Ciocan 			return 0;
827c501d0b1SCristina Ciocan 		}
828c501d0b1SCristina Ciocan 	}
829c501d0b1SCristina Ciocan 
830c501d0b1SCristina Ciocan 	return 1;
831c501d0b1SCristina Ciocan }
832c501d0b1SCristina Ciocan 
833c501d0b1SCristina Ciocan static int byt_get_group_mixed_mux(const struct byt_pingroup group,
834c501d0b1SCristina Ciocan 				   const char *func_name,
835c501d0b1SCristina Ciocan 				   const unsigned short **func)
836c501d0b1SCristina Ciocan {
837c501d0b1SCristina Ciocan 	int i;
838c501d0b1SCristina Ciocan 
839c501d0b1SCristina Ciocan 	for (i = 0; i < group.nfuncs; i++) {
840c501d0b1SCristina Ciocan 		if (!strcmp(group.mixed_funcs[i].name, func_name)) {
841c501d0b1SCristina Ciocan 			*func = group.mixed_funcs[i].func_values;
842c501d0b1SCristina Ciocan 			return 0;
843c501d0b1SCristina Ciocan 		}
844c501d0b1SCristina Ciocan 	}
845c501d0b1SCristina Ciocan 
846c501d0b1SCristina Ciocan 	return 1;
847c501d0b1SCristina Ciocan }
848c501d0b1SCristina Ciocan 
849c501d0b1SCristina Ciocan static void byt_set_group_simple_mux(struct byt_gpio *vg,
850c501d0b1SCristina Ciocan 				     const struct byt_pingroup group,
851c501d0b1SCristina Ciocan 				     unsigned short func)
852c501d0b1SCristina Ciocan {
853c501d0b1SCristina Ciocan 	unsigned long flags;
854c501d0b1SCristina Ciocan 	int i;
855c501d0b1SCristina Ciocan 
856c501d0b1SCristina Ciocan 	raw_spin_lock_irqsave(&vg->lock, flags);
857c501d0b1SCristina Ciocan 
858c501d0b1SCristina Ciocan 	for (i = 0; i < group.npins; i++) {
859c501d0b1SCristina Ciocan 		void __iomem *padcfg0;
860c501d0b1SCristina Ciocan 		u32 value;
861c501d0b1SCristina Ciocan 
862c501d0b1SCristina Ciocan 		padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
863c501d0b1SCristina Ciocan 		if (!padcfg0) {
864c501d0b1SCristina Ciocan 			dev_warn(&vg->pdev->dev,
865c501d0b1SCristina Ciocan 				 "Group %s, pin %i not muxed (no padcfg0)\n",
866c501d0b1SCristina Ciocan 				 group.name, i);
867c501d0b1SCristina Ciocan 			continue;
868c501d0b1SCristina Ciocan 		}
869c501d0b1SCristina Ciocan 
870c501d0b1SCristina Ciocan 		value = readl(padcfg0);
871c501d0b1SCristina Ciocan 		value &= ~BYT_PIN_MUX;
872c501d0b1SCristina Ciocan 		value |= func;
873c501d0b1SCristina Ciocan 		writel(value, padcfg0);
874c501d0b1SCristina Ciocan 	}
875c501d0b1SCristina Ciocan 
876c501d0b1SCristina Ciocan 	raw_spin_unlock_irqrestore(&vg->lock, flags);
877c501d0b1SCristina Ciocan }
878c501d0b1SCristina Ciocan 
879c501d0b1SCristina Ciocan static void byt_set_group_mixed_mux(struct byt_gpio *vg,
880c501d0b1SCristina Ciocan 				    const struct byt_pingroup group,
881c501d0b1SCristina Ciocan 				    const unsigned short *func)
882c501d0b1SCristina Ciocan {
883c501d0b1SCristina Ciocan 	unsigned long flags;
884c501d0b1SCristina Ciocan 	int i;
885c501d0b1SCristina Ciocan 
886c501d0b1SCristina Ciocan 	raw_spin_lock_irqsave(&vg->lock, flags);
887c501d0b1SCristina Ciocan 
888c501d0b1SCristina Ciocan 	for (i = 0; i < group.npins; i++) {
889c501d0b1SCristina Ciocan 		void __iomem *padcfg0;
890c501d0b1SCristina Ciocan 		u32 value;
891c501d0b1SCristina Ciocan 
892c501d0b1SCristina Ciocan 		padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
893c501d0b1SCristina Ciocan 		if (!padcfg0) {
894c501d0b1SCristina Ciocan 			dev_warn(&vg->pdev->dev,
895c501d0b1SCristina Ciocan 				 "Group %s, pin %i not muxed (no padcfg0)\n",
896c501d0b1SCristina Ciocan 				 group.name, i);
897c501d0b1SCristina Ciocan 			continue;
898c501d0b1SCristina Ciocan 		}
899c501d0b1SCristina Ciocan 
900c501d0b1SCristina Ciocan 		value = readl(padcfg0);
901c501d0b1SCristina Ciocan 		value &= ~BYT_PIN_MUX;
902c501d0b1SCristina Ciocan 		value |= func[i];
903c501d0b1SCristina Ciocan 		writel(value, padcfg0);
904c501d0b1SCristina Ciocan 	}
905c501d0b1SCristina Ciocan 
906c501d0b1SCristina Ciocan 	raw_spin_unlock_irqrestore(&vg->lock, flags);
907c501d0b1SCristina Ciocan }
908c501d0b1SCristina Ciocan 
909c501d0b1SCristina Ciocan static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
910c501d0b1SCristina Ciocan 		       unsigned int group_selector)
911c501d0b1SCristina Ciocan {
912c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
913c501d0b1SCristina Ciocan 	const struct byt_function func = vg->soc_data->functions[func_selector];
914c501d0b1SCristina Ciocan 	const struct byt_pingroup group = vg->soc_data->groups[group_selector];
915c501d0b1SCristina Ciocan 	const unsigned short *mixed_func;
916c501d0b1SCristina Ciocan 	unsigned short simple_func;
917c501d0b1SCristina Ciocan 	int ret = 1;
918c501d0b1SCristina Ciocan 
919c501d0b1SCristina Ciocan 	if (group.has_simple_funcs)
920c501d0b1SCristina Ciocan 		ret = byt_get_group_simple_mux(group, func.name, &simple_func);
921c501d0b1SCristina Ciocan 	else
922c501d0b1SCristina Ciocan 		ret = byt_get_group_mixed_mux(group, func.name, &mixed_func);
923c501d0b1SCristina Ciocan 
924c501d0b1SCristina Ciocan 	if (ret)
925c501d0b1SCristina Ciocan 		byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX);
926c501d0b1SCristina Ciocan 	else if (group.has_simple_funcs)
927c501d0b1SCristina Ciocan 		byt_set_group_simple_mux(vg, group, simple_func);
928c501d0b1SCristina Ciocan 	else
929c501d0b1SCristina Ciocan 		byt_set_group_mixed_mux(vg, group, mixed_func);
930c501d0b1SCristina Ciocan 
931c501d0b1SCristina Ciocan 	return 0;
932c501d0b1SCristina Ciocan }
933c501d0b1SCristina Ciocan 
934c501d0b1SCristina Ciocan static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset)
935c501d0b1SCristina Ciocan {
936c501d0b1SCristina Ciocan 	/* SCORE pin 92-93 */
937c501d0b1SCristina Ciocan 	if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) &&
938c501d0b1SCristina Ciocan 	    offset >= 92 && offset <= 93)
939c501d0b1SCristina Ciocan 		return 1;
940c501d0b1SCristina Ciocan 
941c501d0b1SCristina Ciocan 	/* SUS pin 11-21 */
942c501d0b1SCristina Ciocan 	if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) &&
943c501d0b1SCristina Ciocan 	    offset >= 11 && offset <= 21)
944c501d0b1SCristina Ciocan 		return 1;
945c501d0b1SCristina Ciocan 
946c501d0b1SCristina Ciocan 	return 0;
947c501d0b1SCristina Ciocan }
948c501d0b1SCristina Ciocan 
949c501d0b1SCristina Ciocan static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset)
950c501d0b1SCristina Ciocan {
951c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
95295f0972cSMika Westerberg 	unsigned long flags;
95395f0972cSMika Westerberg 	u32 value;
95495f0972cSMika Westerberg 
95578e1c896SMika Westerberg 	raw_spin_lock_irqsave(&vg->lock, flags);
95695f0972cSMika Westerberg 	value = readl(reg);
95795f0972cSMika Westerberg 	value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
95895f0972cSMika Westerberg 	writel(value, reg);
95978e1c896SMika Westerberg 	raw_spin_unlock_irqrestore(&vg->lock, flags);
96095f0972cSMika Westerberg }
96195f0972cSMika Westerberg 
962c501d0b1SCristina Ciocan static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
963c501d0b1SCristina Ciocan 				   struct pinctrl_gpio_range *range,
964c501d0b1SCristina Ciocan 				   unsigned int offset)
9655fae8b86SMika Westerberg {
966c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
967c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
968f8323b6bSMika Westerberg 	u32 value, gpio_mux;
96939ce8150SMika Westerberg 	unsigned long flags;
97039ce8150SMika Westerberg 
97178e1c896SMika Westerberg 	raw_spin_lock_irqsave(&vg->lock, flags);
9725fae8b86SMika Westerberg 
9735fae8b86SMika Westerberg 	/*
9745fae8b86SMika Westerberg 	 * In most cases, func pin mux 000 means GPIO function.
9755fae8b86SMika Westerberg 	 * But, some pins may have func pin mux 001 represents
976f8323b6bSMika Westerberg 	 * GPIO function.
977f8323b6bSMika Westerberg 	 *
978f8323b6bSMika Westerberg 	 * Because there are devices out there where some pins were not
979f8323b6bSMika Westerberg 	 * configured correctly we allow changing the mux value from
980f8323b6bSMika Westerberg 	 * request (but print out warning about that).
9815fae8b86SMika Westerberg 	 */
9825fae8b86SMika Westerberg 	value = readl(reg) & BYT_PIN_MUX;
983f8323b6bSMika Westerberg 	gpio_mux = byt_get_gpio_mux(vg, offset);
984b5894d12SHans de Goede 	if (gpio_mux != value) {
985f8323b6bSMika Westerberg 		value = readl(reg) & ~BYT_PIN_MUX;
986f8323b6bSMika Westerberg 		value |= gpio_mux;
987f8323b6bSMika Westerberg 		writel(value, reg);
988f8323b6bSMika Westerberg 
989b5894d12SHans de Goede 		dev_warn(&vg->pdev->dev, FW_BUG
990f8323b6bSMika Westerberg 			 "pin %u forcibly re-configured as GPIO\n", offset);
9915fae8b86SMika Westerberg 	}
9925fae8b86SMika Westerberg 
99378e1c896SMika Westerberg 	raw_spin_unlock_irqrestore(&vg->lock, flags);
99439ce8150SMika Westerberg 
9955fae8b86SMika Westerberg 	pm_runtime_get(&vg->pdev->dev);
9965fae8b86SMika Westerberg 
9975fae8b86SMika Westerberg 	return 0;
9985fae8b86SMika Westerberg }
9995fae8b86SMika Westerberg 
1000c501d0b1SCristina Ciocan static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
1001c501d0b1SCristina Ciocan 				  struct pinctrl_gpio_range *range,
1002c501d0b1SCristina Ciocan 				  unsigned int offset)
1003c501d0b1SCristina Ciocan {
1004c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
1005c501d0b1SCristina Ciocan 
1006c501d0b1SCristina Ciocan 	byt_gpio_clear_triggering(vg, offset);
1007c501d0b1SCristina Ciocan 	pm_runtime_put(&vg->pdev->dev);
1008c501d0b1SCristina Ciocan }
1009c501d0b1SCristina Ciocan 
1010c501d0b1SCristina Ciocan static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
1011c501d0b1SCristina Ciocan 				  struct pinctrl_gpio_range *range,
1012c501d0b1SCristina Ciocan 				  unsigned int offset,
1013c501d0b1SCristina Ciocan 				  bool input)
1014c501d0b1SCristina Ciocan {
1015c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
1016c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
1017c501d0b1SCristina Ciocan 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
1018c501d0b1SCristina Ciocan 	unsigned long flags;
1019c501d0b1SCristina Ciocan 	u32 value;
1020c501d0b1SCristina Ciocan 
1021c501d0b1SCristina Ciocan 	raw_spin_lock_irqsave(&vg->lock, flags);
1022c501d0b1SCristina Ciocan 
1023c501d0b1SCristina Ciocan 	value = readl(val_reg);
1024c501d0b1SCristina Ciocan 	value &= ~BYT_DIR_MASK;
1025c501d0b1SCristina Ciocan 	if (input)
1026c501d0b1SCristina Ciocan 		value |= BYT_OUTPUT_EN;
1027c501d0b1SCristina Ciocan 	else
1028c501d0b1SCristina Ciocan 		/*
1029c501d0b1SCristina Ciocan 		 * Before making any direction modifications, do a check if gpio
1030c501d0b1SCristina Ciocan 		 * is set for direct IRQ.  On baytrail, setting GPIO to output
1031c501d0b1SCristina Ciocan 		 * does not make sense, so let's at least warn the caller before
1032c501d0b1SCristina Ciocan 		 * they shoot themselves in the foot.
1033c501d0b1SCristina Ciocan 		 */
1034c501d0b1SCristina Ciocan 		WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
1035c501d0b1SCristina Ciocan 		     "Potential Error: Setting GPIO with direct_irq_en to output");
1036c501d0b1SCristina Ciocan 	writel(value, val_reg);
1037c501d0b1SCristina Ciocan 
1038c501d0b1SCristina Ciocan 	raw_spin_unlock_irqrestore(&vg->lock, flags);
1039c501d0b1SCristina Ciocan 
1040c501d0b1SCristina Ciocan 	return 0;
1041c501d0b1SCristina Ciocan }
1042c501d0b1SCristina Ciocan 
1043c501d0b1SCristina Ciocan static const struct pinmux_ops byt_pinmux_ops = {
1044c501d0b1SCristina Ciocan 	.get_functions_count	= byt_get_functions_count,
1045c501d0b1SCristina Ciocan 	.get_function_name	= byt_get_function_name,
1046c501d0b1SCristina Ciocan 	.get_function_groups	= byt_get_function_groups,
1047c501d0b1SCristina Ciocan 	.set_mux		= byt_set_mux,
1048c501d0b1SCristina Ciocan 	.gpio_request_enable	= byt_gpio_request_enable,
1049c501d0b1SCristina Ciocan 	.gpio_disable_free	= byt_gpio_disable_free,
1050c501d0b1SCristina Ciocan 	.gpio_set_direction	= byt_gpio_set_direction,
1051c501d0b1SCristina Ciocan };
1052c501d0b1SCristina Ciocan 
1053c501d0b1SCristina Ciocan static void byt_get_pull_strength(u32 reg, u16 *strength)
1054c501d0b1SCristina Ciocan {
1055c501d0b1SCristina Ciocan 	switch (reg & BYT_PULL_STR_MASK) {
1056c501d0b1SCristina Ciocan 	case BYT_PULL_STR_2K:
1057c501d0b1SCristina Ciocan 		*strength = 2000;
1058c501d0b1SCristina Ciocan 		break;
1059c501d0b1SCristina Ciocan 	case BYT_PULL_STR_10K:
1060c501d0b1SCristina Ciocan 		*strength = 10000;
1061c501d0b1SCristina Ciocan 		break;
1062c501d0b1SCristina Ciocan 	case BYT_PULL_STR_20K:
1063c501d0b1SCristina Ciocan 		*strength = 20000;
1064c501d0b1SCristina Ciocan 		break;
1065c501d0b1SCristina Ciocan 	case BYT_PULL_STR_40K:
1066c501d0b1SCristina Ciocan 		*strength = 40000;
1067c501d0b1SCristina Ciocan 		break;
1068c501d0b1SCristina Ciocan 	}
1069c501d0b1SCristina Ciocan }
1070c501d0b1SCristina Ciocan 
1071c501d0b1SCristina Ciocan static int byt_set_pull_strength(u32 *reg, u16 strength)
1072c501d0b1SCristina Ciocan {
1073c501d0b1SCristina Ciocan 	*reg &= ~BYT_PULL_STR_MASK;
1074c501d0b1SCristina Ciocan 
1075c501d0b1SCristina Ciocan 	switch (strength) {
1076c501d0b1SCristina Ciocan 	case 2000:
1077c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_2K;
1078c501d0b1SCristina Ciocan 		break;
1079c501d0b1SCristina Ciocan 	case 10000:
1080c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_10K;
1081c501d0b1SCristina Ciocan 		break;
1082c501d0b1SCristina Ciocan 	case 20000:
1083c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_20K;
1084c501d0b1SCristina Ciocan 		break;
1085c501d0b1SCristina Ciocan 	case 40000:
1086c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_40K;
1087c501d0b1SCristina Ciocan 		break;
1088c501d0b1SCristina Ciocan 	default:
1089c501d0b1SCristina Ciocan 		return -EINVAL;
1090c501d0b1SCristina Ciocan 	}
1091c501d0b1SCristina Ciocan 
1092c501d0b1SCristina Ciocan 	return 0;
1093c501d0b1SCristina Ciocan }
1094c501d0b1SCristina Ciocan 
1095c501d0b1SCristina Ciocan static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
1096c501d0b1SCristina Ciocan 			      unsigned long *config)
1097c501d0b1SCristina Ciocan {
1098c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
1099c501d0b1SCristina Ciocan 	enum pin_config_param param = pinconf_to_config_param(*config);
1100c501d0b1SCristina Ciocan 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
1101c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
110204ff5a09SAndy Shevchenko 	void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
1103c501d0b1SCristina Ciocan 	unsigned long flags;
1104658b476cSCristina Ciocan 	u32 conf, pull, val, debounce;
1105c501d0b1SCristina Ciocan 	u16 arg = 0;
1106c501d0b1SCristina Ciocan 
1107c501d0b1SCristina Ciocan 	raw_spin_lock_irqsave(&vg->lock, flags);
1108c501d0b1SCristina Ciocan 	conf = readl(conf_reg);
1109c501d0b1SCristina Ciocan 	pull = conf & BYT_PULL_ASSIGN_MASK;
1110c501d0b1SCristina Ciocan 	val = readl(val_reg);
1111c501d0b1SCristina Ciocan 	raw_spin_unlock_irqrestore(&vg->lock, flags);
1112c501d0b1SCristina Ciocan 
1113c501d0b1SCristina Ciocan 	switch (param) {
1114c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_DISABLE:
1115c501d0b1SCristina Ciocan 		if (pull)
1116c501d0b1SCristina Ciocan 			return -EINVAL;
1117c501d0b1SCristina Ciocan 		break;
1118c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_PULL_DOWN:
1119c501d0b1SCristina Ciocan 		/* Pull assignment is only applicable in input mode */
1120c501d0b1SCristina Ciocan 		if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN)
1121c501d0b1SCristina Ciocan 			return -EINVAL;
1122c501d0b1SCristina Ciocan 
1123c501d0b1SCristina Ciocan 		byt_get_pull_strength(conf, &arg);
1124c501d0b1SCristina Ciocan 
1125c501d0b1SCristina Ciocan 		break;
1126c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_PULL_UP:
1127c501d0b1SCristina Ciocan 		/* Pull assignment is only applicable in input mode */
1128c501d0b1SCristina Ciocan 		if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP)
1129c501d0b1SCristina Ciocan 			return -EINVAL;
1130c501d0b1SCristina Ciocan 
1131c501d0b1SCristina Ciocan 		byt_get_pull_strength(conf, &arg);
1132c501d0b1SCristina Ciocan 
1133c501d0b1SCristina Ciocan 		break;
1134658b476cSCristina Ciocan 	case PIN_CONFIG_INPUT_DEBOUNCE:
1135658b476cSCristina Ciocan 		if (!(conf & BYT_DEBOUNCE_EN))
1136658b476cSCristina Ciocan 			return -EINVAL;
1137658b476cSCristina Ciocan 
1138658b476cSCristina Ciocan 		raw_spin_lock_irqsave(&vg->lock, flags);
113904ff5a09SAndy Shevchenko 		debounce = readl(db_reg);
1140658b476cSCristina Ciocan 		raw_spin_unlock_irqrestore(&vg->lock, flags);
1141658b476cSCristina Ciocan 
1142658b476cSCristina Ciocan 		switch (debounce & BYT_DEBOUNCE_PULSE_MASK) {
1143658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_375US:
1144658b476cSCristina Ciocan 			arg = 375;
1145658b476cSCristina Ciocan 			break;
1146658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_750US:
1147658b476cSCristina Ciocan 			arg = 750;
1148658b476cSCristina Ciocan 			break;
1149658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_1500US:
1150658b476cSCristina Ciocan 			arg = 1500;
1151658b476cSCristina Ciocan 			break;
1152658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_3MS:
1153658b476cSCristina Ciocan 			arg = 3000;
1154658b476cSCristina Ciocan 			break;
1155658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_6MS:
1156658b476cSCristina Ciocan 			arg = 6000;
1157658b476cSCristina Ciocan 			break;
1158658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_12MS:
1159658b476cSCristina Ciocan 			arg = 12000;
1160658b476cSCristina Ciocan 			break;
1161658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_24MS:
1162658b476cSCristina Ciocan 			arg = 24000;
1163658b476cSCristina Ciocan 			break;
1164658b476cSCristina Ciocan 		default:
1165658b476cSCristina Ciocan 			return -EINVAL;
1166658b476cSCristina Ciocan 		}
1167658b476cSCristina Ciocan 
1168658b476cSCristina Ciocan 		break;
1169c501d0b1SCristina Ciocan 	default:
1170c501d0b1SCristina Ciocan 		return -ENOTSUPP;
1171c501d0b1SCristina Ciocan 	}
1172c501d0b1SCristina Ciocan 
1173c501d0b1SCristina Ciocan 	*config = pinconf_to_config_packed(param, arg);
1174c501d0b1SCristina Ciocan 
1175c501d0b1SCristina Ciocan 	return 0;
1176c501d0b1SCristina Ciocan }
1177c501d0b1SCristina Ciocan 
1178c501d0b1SCristina Ciocan static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
1179c501d0b1SCristina Ciocan 			      unsigned int offset,
1180c501d0b1SCristina Ciocan 			      unsigned long *configs,
1181c501d0b1SCristina Ciocan 			      unsigned int num_configs)
1182c501d0b1SCristina Ciocan {
1183c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
1184c501d0b1SCristina Ciocan 	unsigned int param, arg;
1185c501d0b1SCristina Ciocan 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
1186c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
118704ff5a09SAndy Shevchenko 	void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
1188c501d0b1SCristina Ciocan 	unsigned long flags;
1189658b476cSCristina Ciocan 	u32 conf, val, debounce;
1190c501d0b1SCristina Ciocan 	int i, ret = 0;
1191c501d0b1SCristina Ciocan 
1192c501d0b1SCristina Ciocan 	raw_spin_lock_irqsave(&vg->lock, flags);
1193c501d0b1SCristina Ciocan 
1194c501d0b1SCristina Ciocan 	conf = readl(conf_reg);
1195c501d0b1SCristina Ciocan 	val = readl(val_reg);
1196c501d0b1SCristina Ciocan 
1197c501d0b1SCristina Ciocan 	for (i = 0; i < num_configs; i++) {
1198c501d0b1SCristina Ciocan 		param = pinconf_to_config_param(configs[i]);
1199c501d0b1SCristina Ciocan 		arg = pinconf_to_config_argument(configs[i]);
1200c501d0b1SCristina Ciocan 
1201c501d0b1SCristina Ciocan 		switch (param) {
1202c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_DISABLE:
1203c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
1204c501d0b1SCristina Ciocan 			break;
1205c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_PULL_DOWN:
1206c501d0b1SCristina Ciocan 			/* Set default strength value in case none is given */
1207c501d0b1SCristina Ciocan 			if (arg == 1)
1208c501d0b1SCristina Ciocan 				arg = 2000;
1209c501d0b1SCristina Ciocan 
1210c501d0b1SCristina Ciocan 			/*
1211c501d0b1SCristina Ciocan 			 * Pull assignment is only applicable in input mode. If
1212c501d0b1SCristina Ciocan 			 * chip is not in input mode, set it and warn about it.
1213c501d0b1SCristina Ciocan 			 */
1214c501d0b1SCristina Ciocan 			if (val & BYT_INPUT_EN) {
1215c501d0b1SCristina Ciocan 				val &= ~BYT_INPUT_EN;
1216c501d0b1SCristina Ciocan 				writel(val, val_reg);
1217c501d0b1SCristina Ciocan 				dev_warn(&vg->pdev->dev,
1218c501d0b1SCristina Ciocan 					 "pin %u forcibly set to input mode\n",
1219c501d0b1SCristina Ciocan 					 offset);
1220c501d0b1SCristina Ciocan 			}
1221c501d0b1SCristina Ciocan 
1222c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
1223c501d0b1SCristina Ciocan 			conf |= BYT_PULL_ASSIGN_DOWN;
1224c501d0b1SCristina Ciocan 			ret = byt_set_pull_strength(&conf, arg);
1225c501d0b1SCristina Ciocan 
1226c501d0b1SCristina Ciocan 			break;
1227c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_PULL_UP:
1228c501d0b1SCristina Ciocan 			/* Set default strength value in case none is given */
1229c501d0b1SCristina Ciocan 			if (arg == 1)
1230c501d0b1SCristina Ciocan 				arg = 2000;
1231c501d0b1SCristina Ciocan 
1232c501d0b1SCristina Ciocan 			/*
1233c501d0b1SCristina Ciocan 			 * Pull assignment is only applicable in input mode. If
1234c501d0b1SCristina Ciocan 			 * chip is not in input mode, set it and warn about it.
1235c501d0b1SCristina Ciocan 			 */
1236c501d0b1SCristina Ciocan 			if (val & BYT_INPUT_EN) {
1237c501d0b1SCristina Ciocan 				val &= ~BYT_INPUT_EN;
1238c501d0b1SCristina Ciocan 				writel(val, val_reg);
1239c501d0b1SCristina Ciocan 				dev_warn(&vg->pdev->dev,
1240c501d0b1SCristina Ciocan 					 "pin %u forcibly set to input mode\n",
1241c501d0b1SCristina Ciocan 					 offset);
1242c501d0b1SCristina Ciocan 			}
1243c501d0b1SCristina Ciocan 
1244c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
1245c501d0b1SCristina Ciocan 			conf |= BYT_PULL_ASSIGN_UP;
1246c501d0b1SCristina Ciocan 			ret = byt_set_pull_strength(&conf, arg);
1247c501d0b1SCristina Ciocan 
1248c501d0b1SCristina Ciocan 			break;
1249658b476cSCristina Ciocan 		case PIN_CONFIG_INPUT_DEBOUNCE:
125004ff5a09SAndy Shevchenko 			debounce = readl(db_reg);
125104ff5a09SAndy Shevchenko 			debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
1252658b476cSCristina Ciocan 
1253827e1579SAndy Shevchenko 			if (arg)
1254827e1579SAndy Shevchenko 				conf |= BYT_DEBOUNCE_EN;
1255827e1579SAndy Shevchenko 			else
1256827e1579SAndy Shevchenko 				conf &= ~BYT_DEBOUNCE_EN;
1257827e1579SAndy Shevchenko 
1258658b476cSCristina Ciocan 			switch (arg) {
1259658b476cSCristina Ciocan 			case 375:
126004ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_375US;
1261658b476cSCristina Ciocan 				break;
1262658b476cSCristina Ciocan 			case 750:
126304ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_750US;
1264658b476cSCristina Ciocan 				break;
1265658b476cSCristina Ciocan 			case 1500:
126604ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_1500US;
1267658b476cSCristina Ciocan 				break;
1268658b476cSCristina Ciocan 			case 3000:
126904ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_3MS;
1270658b476cSCristina Ciocan 				break;
1271658b476cSCristina Ciocan 			case 6000:
127204ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_6MS;
1273658b476cSCristina Ciocan 				break;
1274658b476cSCristina Ciocan 			case 12000:
127504ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_12MS;
1276658b476cSCristina Ciocan 				break;
1277658b476cSCristina Ciocan 			case 24000:
127804ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_24MS;
1279658b476cSCristina Ciocan 				break;
1280658b476cSCristina Ciocan 			default:
1281827e1579SAndy Shevchenko 				if (arg)
1282658b476cSCristina Ciocan 					ret = -EINVAL;
1283827e1579SAndy Shevchenko 				break;
1284658b476cSCristina Ciocan 			}
1285658b476cSCristina Ciocan 
128604ff5a09SAndy Shevchenko 			if (!ret)
128704ff5a09SAndy Shevchenko 				writel(debounce, db_reg);
1288658b476cSCristina Ciocan 			break;
1289c501d0b1SCristina Ciocan 		default:
1290c501d0b1SCristina Ciocan 			ret = -ENOTSUPP;
1291c501d0b1SCristina Ciocan 		}
1292c501d0b1SCristina Ciocan 
1293c501d0b1SCristina Ciocan 		if (ret)
1294c501d0b1SCristina Ciocan 			break;
1295c501d0b1SCristina Ciocan 	}
1296c501d0b1SCristina Ciocan 
1297c501d0b1SCristina Ciocan 	if (!ret)
1298c501d0b1SCristina Ciocan 		writel(conf, conf_reg);
1299c501d0b1SCristina Ciocan 
1300c501d0b1SCristina Ciocan 	raw_spin_unlock_irqrestore(&vg->lock, flags);
1301c501d0b1SCristina Ciocan 
1302c501d0b1SCristina Ciocan 	return ret;
1303c501d0b1SCristina Ciocan }
1304c501d0b1SCristina Ciocan 
1305c501d0b1SCristina Ciocan static const struct pinconf_ops byt_pinconf_ops = {
1306c501d0b1SCristina Ciocan 	.is_generic	= true,
1307c501d0b1SCristina Ciocan 	.pin_config_get	= byt_pin_config_get,
1308c501d0b1SCristina Ciocan 	.pin_config_set	= byt_pin_config_set,
1309c501d0b1SCristina Ciocan };
1310c501d0b1SCristina Ciocan 
1311c501d0b1SCristina Ciocan static const struct pinctrl_desc byt_pinctrl_desc = {
1312c501d0b1SCristina Ciocan 	.pctlops	= &byt_pinctrl_ops,
1313c501d0b1SCristina Ciocan 	.pmxops		= &byt_pinmux_ops,
1314c501d0b1SCristina Ciocan 	.confops	= &byt_pinconf_ops,
1315c501d0b1SCristina Ciocan 	.owner		= THIS_MODULE,
1316c501d0b1SCristina Ciocan };
1317c501d0b1SCristina Ciocan 
13185fae8b86SMika Westerberg static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
13195fae8b86SMika Westerberg {
1320bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(chip);
1321c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
132239ce8150SMika Westerberg 	unsigned long flags;
132339ce8150SMika Westerberg 	u32 val;
132439ce8150SMika Westerberg 
132578e1c896SMika Westerberg 	raw_spin_lock_irqsave(&vg->lock, flags);
132639ce8150SMika Westerberg 	val = readl(reg);
132778e1c896SMika Westerberg 	raw_spin_unlock_irqrestore(&vg->lock, flags);
132839ce8150SMika Westerberg 
13293bde8771SLinus Walleij 	return !!(val & BYT_LEVEL);
13305fae8b86SMika Westerberg }
13315fae8b86SMika Westerberg 
13325fae8b86SMika Westerberg static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
13335fae8b86SMika Westerberg {
1334bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(chip);
1335c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
13365fae8b86SMika Westerberg 	unsigned long flags;
13375fae8b86SMika Westerberg 	u32 old_val;
13385fae8b86SMika Westerberg 
133986e3ef81SCristina Ciocan 	if (!reg)
134086e3ef81SCristina Ciocan 		return;
134186e3ef81SCristina Ciocan 
134278e1c896SMika Westerberg 	raw_spin_lock_irqsave(&vg->lock, flags);
13435fae8b86SMika Westerberg 	old_val = readl(reg);
13445fae8b86SMika Westerberg 	if (value)
13455fae8b86SMika Westerberg 		writel(old_val | BYT_LEVEL, reg);
13465fae8b86SMika Westerberg 	else
13475fae8b86SMika Westerberg 		writel(old_val & ~BYT_LEVEL, reg);
134878e1c896SMika Westerberg 	raw_spin_unlock_irqrestore(&vg->lock, flags);
13495fae8b86SMika Westerberg }
13505fae8b86SMika Westerberg 
135186e3ef81SCristina Ciocan static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
13525fae8b86SMika Westerberg {
1353bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(chip);
1354c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
13555fae8b86SMika Westerberg 	unsigned long flags;
13565fae8b86SMika Westerberg 	u32 value;
13575fae8b86SMika Westerberg 
135886e3ef81SCristina Ciocan 	if (!reg)
135986e3ef81SCristina Ciocan 		return -EINVAL;
136086e3ef81SCristina Ciocan 
136178e1c896SMika Westerberg 	raw_spin_lock_irqsave(&vg->lock, flags);
136286e3ef81SCristina Ciocan 	value = readl(reg);
136378e1c896SMika Westerberg 	raw_spin_unlock_irqrestore(&vg->lock, flags);
13645fae8b86SMika Westerberg 
136586e3ef81SCristina Ciocan 	if (!(value & BYT_OUTPUT_EN))
136686e3ef81SCristina Ciocan 		return GPIOF_DIR_OUT;
136786e3ef81SCristina Ciocan 	if (!(value & BYT_INPUT_EN))
136886e3ef81SCristina Ciocan 		return GPIOF_DIR_IN;
136986e3ef81SCristina Ciocan 
137086e3ef81SCristina Ciocan 	return -EINVAL;
13715fae8b86SMika Westerberg }
13725fae8b86SMika Westerberg 
137386e3ef81SCristina Ciocan static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
13745fae8b86SMika Westerberg {
137586e3ef81SCristina Ciocan 	return pinctrl_gpio_direction_input(chip->base + offset);
137686e3ef81SCristina Ciocan }
13775fae8b86SMika Westerberg 
137886e3ef81SCristina Ciocan static int byt_gpio_direction_output(struct gpio_chip *chip,
137986e3ef81SCristina Ciocan 				     unsigned int offset, int value)
138086e3ef81SCristina Ciocan {
138186e3ef81SCristina Ciocan 	int ret = pinctrl_gpio_direction_output(chip->base + offset);
13825fae8b86SMika Westerberg 
138386e3ef81SCristina Ciocan 	if (ret)
138486e3ef81SCristina Ciocan 		return ret;
138586e3ef81SCristina Ciocan 
138686e3ef81SCristina Ciocan 	byt_gpio_set(chip, offset, value);
13875fae8b86SMika Westerberg 
13885fae8b86SMika Westerberg 	return 0;
13895fae8b86SMika Westerberg }
13905fae8b86SMika Westerberg 
13915fae8b86SMika Westerberg static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
13925fae8b86SMika Westerberg {
1393bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(chip);
13945fae8b86SMika Westerberg 	int i;
139586e3ef81SCristina Ciocan 	u32 conf0, val;
13965fae8b86SMika Westerberg 
139786e3ef81SCristina Ciocan 	for (i = 0; i < vg->soc_data->npins; i++) {
139886e3ef81SCristina Ciocan 		const struct byt_community *comm;
13995fae8b86SMika Westerberg 		const char *pull_str = NULL;
14005fae8b86SMika Westerberg 		const char *pull = NULL;
140186e3ef81SCristina Ciocan 		void __iomem *reg;
140278e1c896SMika Westerberg 		unsigned long flags;
14035fae8b86SMika Westerberg 		const char *label;
140486e3ef81SCristina Ciocan 		unsigned int pin;
140578e1c896SMika Westerberg 
140678e1c896SMika Westerberg 		raw_spin_lock_irqsave(&vg->lock, flags);
140786e3ef81SCristina Ciocan 		pin = vg->soc_data->pins[i].number;
140886e3ef81SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
140986e3ef81SCristina Ciocan 		if (!reg) {
141086e3ef81SCristina Ciocan 			seq_printf(s,
141186e3ef81SCristina Ciocan 				   "Could not retrieve pin %i conf0 reg\n",
141286e3ef81SCristina Ciocan 				   pin);
141322bbd21bSDan Carpenter 			raw_spin_unlock_irqrestore(&vg->lock, flags);
141486e3ef81SCristina Ciocan 			continue;
141586e3ef81SCristina Ciocan 		}
141686e3ef81SCristina Ciocan 		conf0 = readl(reg);
141786e3ef81SCristina Ciocan 
141886e3ef81SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
141986e3ef81SCristina Ciocan 		if (!reg) {
142086e3ef81SCristina Ciocan 			seq_printf(s,
142186e3ef81SCristina Ciocan 				   "Could not retrieve pin %i val reg\n", pin);
142222bbd21bSDan Carpenter 			raw_spin_unlock_irqrestore(&vg->lock, flags);
142322bbd21bSDan Carpenter 			continue;
142486e3ef81SCristina Ciocan 		}
142586e3ef81SCristina Ciocan 		val = readl(reg);
142678e1c896SMika Westerberg 		raw_spin_unlock_irqrestore(&vg->lock, flags);
14275fae8b86SMika Westerberg 
142886e3ef81SCristina Ciocan 		comm = byt_get_community(vg, pin);
142986e3ef81SCristina Ciocan 		if (!comm) {
143086e3ef81SCristina Ciocan 			seq_printf(s,
143186e3ef81SCristina Ciocan 				   "Could not get community for pin %i\n", pin);
143286e3ef81SCristina Ciocan 			continue;
143386e3ef81SCristina Ciocan 		}
14345fae8b86SMika Westerberg 		label = gpiochip_is_requested(chip, i);
14355fae8b86SMika Westerberg 		if (!label)
14365fae8b86SMika Westerberg 			label = "Unrequested";
14375fae8b86SMika Westerberg 
14385fae8b86SMika Westerberg 		switch (conf0 & BYT_PULL_ASSIGN_MASK) {
14395fae8b86SMika Westerberg 		case BYT_PULL_ASSIGN_UP:
14405fae8b86SMika Westerberg 			pull = "up";
14415fae8b86SMika Westerberg 			break;
14425fae8b86SMika Westerberg 		case BYT_PULL_ASSIGN_DOWN:
14435fae8b86SMika Westerberg 			pull = "down";
14445fae8b86SMika Westerberg 			break;
14455fae8b86SMika Westerberg 		}
14465fae8b86SMika Westerberg 
14475fae8b86SMika Westerberg 		switch (conf0 & BYT_PULL_STR_MASK) {
14485fae8b86SMika Westerberg 		case BYT_PULL_STR_2K:
14495fae8b86SMika Westerberg 			pull_str = "2k";
14505fae8b86SMika Westerberg 			break;
14515fae8b86SMika Westerberg 		case BYT_PULL_STR_10K:
14525fae8b86SMika Westerberg 			pull_str = "10k";
14535fae8b86SMika Westerberg 			break;
14545fae8b86SMika Westerberg 		case BYT_PULL_STR_20K:
14555fae8b86SMika Westerberg 			pull_str = "20k";
14565fae8b86SMika Westerberg 			break;
14575fae8b86SMika Westerberg 		case BYT_PULL_STR_40K:
14585fae8b86SMika Westerberg 			pull_str = "40k";
14595fae8b86SMika Westerberg 			break;
14605fae8b86SMika Westerberg 		}
14615fae8b86SMika Westerberg 
14625fae8b86SMika Westerberg 		seq_printf(s,
14635fae8b86SMika Westerberg 			   " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
146486e3ef81SCristina Ciocan 			   pin,
14655fae8b86SMika Westerberg 			   label,
14665fae8b86SMika Westerberg 			   val & BYT_INPUT_EN ? "  " : "in",
14675fae8b86SMika Westerberg 			   val & BYT_OUTPUT_EN ? "   " : "out",
14685fae8b86SMika Westerberg 			   val & BYT_LEVEL ? "hi" : "lo",
14693655a1caSAlexander Stein 			   comm->pad_map[i], comm->pad_map[i] * 16,
14705fae8b86SMika Westerberg 			   conf0 & 0x7,
14715fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_NEG ? " fall" : "     ",
14725fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_POS ? " rise" : "     ",
14735fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_LVL ? " level" : "      ");
14745fae8b86SMika Westerberg 
14755fae8b86SMika Westerberg 		if (pull && pull_str)
14765fae8b86SMika Westerberg 			seq_printf(s, " %-4s %-3s", pull, pull_str);
14775fae8b86SMika Westerberg 		else
14785fae8b86SMika Westerberg 			seq_puts(s, "          ");
14795fae8b86SMika Westerberg 
14805fae8b86SMika Westerberg 		if (conf0 & BYT_IODEN)
14815fae8b86SMika Westerberg 			seq_puts(s, " open-drain");
14825fae8b86SMika Westerberg 
14835fae8b86SMika Westerberg 		seq_puts(s, "\n");
14845fae8b86SMika Westerberg 	}
14855fae8b86SMika Westerberg }
14865fae8b86SMika Westerberg 
148786e3ef81SCristina Ciocan static const struct gpio_chip byt_gpio_chip = {
148886e3ef81SCristina Ciocan 	.owner			= THIS_MODULE,
148986e3ef81SCristina Ciocan 	.request		= gpiochip_generic_request,
149086e3ef81SCristina Ciocan 	.free			= gpiochip_generic_free,
149186e3ef81SCristina Ciocan 	.get_direction		= byt_gpio_get_direction,
149286e3ef81SCristina Ciocan 	.direction_input	= byt_gpio_direction_input,
149386e3ef81SCristina Ciocan 	.direction_output	= byt_gpio_direction_output,
149486e3ef81SCristina Ciocan 	.get			= byt_gpio_get,
149586e3ef81SCristina Ciocan 	.set			= byt_gpio_set,
149686e3ef81SCristina Ciocan 	.dbg_show		= byt_gpio_dbg_show,
149786e3ef81SCristina Ciocan };
149886e3ef81SCristina Ciocan 
149931e4329fSMika Westerberg static void byt_irq_ack(struct irq_data *d)
150031e4329fSMika Westerberg {
150131e4329fSMika Westerberg 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
1502bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(gc);
150331e4329fSMika Westerberg 	unsigned offset = irqd_to_hwirq(d);
150431e4329fSMika Westerberg 	void __iomem *reg;
150531e4329fSMika Westerberg 
1506c501d0b1SCristina Ciocan 	reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG);
15079f573b98SCristina Ciocan 	if (!reg)
15089f573b98SCristina Ciocan 		return;
15099f573b98SCristina Ciocan 
15109f573b98SCristina Ciocan 	raw_spin_lock(&vg->lock);
151131e4329fSMika Westerberg 	writel(BIT(offset % 32), reg);
151278e1c896SMika Westerberg 	raw_spin_unlock(&vg->lock);
151331e4329fSMika Westerberg }
151431e4329fSMika Westerberg 
15159f573b98SCristina Ciocan static void byt_irq_mask(struct irq_data *d)
15169f573b98SCristina Ciocan {
15179f573b98SCristina Ciocan 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
15189f573b98SCristina Ciocan 	struct byt_gpio *vg = gpiochip_get_data(gc);
15199f573b98SCristina Ciocan 
15209f573b98SCristina Ciocan 	byt_gpio_clear_triggering(vg, irqd_to_hwirq(d));
15219f573b98SCristina Ciocan }
15229f573b98SCristina Ciocan 
15235fae8b86SMika Westerberg static void byt_irq_unmask(struct irq_data *d)
15245fae8b86SMika Westerberg {
152531e4329fSMika Westerberg 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
1526bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(gc);
152731e4329fSMika Westerberg 	unsigned offset = irqd_to_hwirq(d);
152831e4329fSMika Westerberg 	unsigned long flags;
152931e4329fSMika Westerberg 	void __iomem *reg;
153031e4329fSMika Westerberg 	u32 value;
153131e4329fSMika Westerberg 
1532c501d0b1SCristina Ciocan 	reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
15339f573b98SCristina Ciocan 	if (!reg)
15349f573b98SCristina Ciocan 		return;
153578e1c896SMika Westerberg 
153678e1c896SMika Westerberg 	raw_spin_lock_irqsave(&vg->lock, flags);
153731e4329fSMika Westerberg 	value = readl(reg);
153831e4329fSMika Westerberg 
153931e4329fSMika Westerberg 	switch (irqd_get_trigger_type(d)) {
154031e4329fSMika Westerberg 	case IRQ_TYPE_LEVEL_HIGH:
154131e4329fSMika Westerberg 		value |= BYT_TRIG_LVL;
154231e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_RISING:
154331e4329fSMika Westerberg 		value |= BYT_TRIG_POS;
154431e4329fSMika Westerberg 		break;
154531e4329fSMika Westerberg 	case IRQ_TYPE_LEVEL_LOW:
154631e4329fSMika Westerberg 		value |= BYT_TRIG_LVL;
154731e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_FALLING:
154831e4329fSMika Westerberg 		value |= BYT_TRIG_NEG;
154931e4329fSMika Westerberg 		break;
155031e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_BOTH:
155131e4329fSMika Westerberg 		value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
155231e4329fSMika Westerberg 		break;
155331e4329fSMika Westerberg 	}
155431e4329fSMika Westerberg 
155531e4329fSMika Westerberg 	writel(value, reg);
155631e4329fSMika Westerberg 
155778e1c896SMika Westerberg 	raw_spin_unlock_irqrestore(&vg->lock, flags);
15585fae8b86SMika Westerberg }
15595fae8b86SMika Westerberg 
15609f573b98SCristina Ciocan static int byt_irq_type(struct irq_data *d, unsigned int type)
15615fae8b86SMika Westerberg {
15629f573b98SCristina Ciocan 	struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
15639f573b98SCristina Ciocan 	u32 offset = irqd_to_hwirq(d);
15649f573b98SCristina Ciocan 	u32 value;
15659f573b98SCristina Ciocan 	unsigned long flags;
15669f573b98SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
156731e4329fSMika Westerberg 
15689f573b98SCristina Ciocan 	if (!reg || offset >= vg->chip.ngpio)
15699f573b98SCristina Ciocan 		return -EINVAL;
15709f573b98SCristina Ciocan 
15719f573b98SCristina Ciocan 	raw_spin_lock_irqsave(&vg->lock, flags);
15729f573b98SCristina Ciocan 	value = readl(reg);
15739f573b98SCristina Ciocan 
15749f573b98SCristina Ciocan 	WARN(value & BYT_DIRECT_IRQ_EN,
15759f573b98SCristina Ciocan 	     "Bad pad config for io mode, force direct_irq_en bit clearing");
15769f573b98SCristina Ciocan 
15779f573b98SCristina Ciocan 	/* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
15789f573b98SCristina Ciocan 	 * are used to indicate high and low level triggering
15799f573b98SCristina Ciocan 	 */
15809f573b98SCristina Ciocan 	value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
15819f573b98SCristina Ciocan 		   BYT_TRIG_LVL);
15829f573b98SCristina Ciocan 
15839f573b98SCristina Ciocan 	writel(value, reg);
15849f573b98SCristina Ciocan 
15859f573b98SCristina Ciocan 	if (type & IRQ_TYPE_EDGE_BOTH)
15869f573b98SCristina Ciocan 		irq_set_handler_locked(d, handle_edge_irq);
15879f573b98SCristina Ciocan 	else if (type & IRQ_TYPE_LEVEL_MASK)
15889f573b98SCristina Ciocan 		irq_set_handler_locked(d, handle_level_irq);
15899f573b98SCristina Ciocan 
15909f573b98SCristina Ciocan 	raw_spin_unlock_irqrestore(&vg->lock, flags);
15919f573b98SCristina Ciocan 
15929f573b98SCristina Ciocan 	return 0;
15935fae8b86SMika Westerberg }
15945fae8b86SMika Westerberg 
15955fae8b86SMika Westerberg static struct irq_chip byt_irqchip = {
15965fae8b86SMika Westerberg 	.name		= "BYT-GPIO",
159731e4329fSMika Westerberg 	.irq_ack	= byt_irq_ack,
15985fae8b86SMika Westerberg 	.irq_mask	= byt_irq_mask,
15995fae8b86SMika Westerberg 	.irq_unmask	= byt_irq_unmask,
16005fae8b86SMika Westerberg 	.irq_set_type	= byt_irq_type,
16015fae8b86SMika Westerberg 	.flags		= IRQCHIP_SKIP_SET_WAKE,
16025fae8b86SMika Westerberg };
16035fae8b86SMika Westerberg 
160471e6ca61SCristina Ciocan static void byt_gpio_irq_handler(struct irq_desc *desc)
160571e6ca61SCristina Ciocan {
160671e6ca61SCristina Ciocan 	struct irq_data *data = irq_desc_get_irq_data(desc);
160771e6ca61SCristina Ciocan 	struct byt_gpio *vg = gpiochip_get_data(
160871e6ca61SCristina Ciocan 				irq_desc_get_handler_data(desc));
160971e6ca61SCristina Ciocan 	struct irq_chip *chip = irq_data_get_irq_chip(data);
161071e6ca61SCristina Ciocan 	u32 base, pin;
161171e6ca61SCristina Ciocan 	void __iomem *reg;
161271e6ca61SCristina Ciocan 	unsigned long pending;
161371e6ca61SCristina Ciocan 	unsigned int virq;
161471e6ca61SCristina Ciocan 
161571e6ca61SCristina Ciocan 	/* check from GPIO controller which pin triggered the interrupt */
161671e6ca61SCristina Ciocan 	for (base = 0; base < vg->chip.ngpio; base += 32) {
161771e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
161871e6ca61SCristina Ciocan 
161971e6ca61SCristina Ciocan 		if (!reg) {
162071e6ca61SCristina Ciocan 			dev_warn(&vg->pdev->dev,
162171e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve interrupt status register\n",
162271e6ca61SCristina Ciocan 				 base);
162371e6ca61SCristina Ciocan 			continue;
162471e6ca61SCristina Ciocan 		}
162571e6ca61SCristina Ciocan 
1626cdca06e4SAlexander Stein 		raw_spin_lock(&vg->lock);
162771e6ca61SCristina Ciocan 		pending = readl(reg);
1628cdca06e4SAlexander Stein 		raw_spin_unlock(&vg->lock);
162971e6ca61SCristina Ciocan 		for_each_set_bit(pin, &pending, 32) {
1630f0fbe7bcSThierry Reding 			virq = irq_find_mapping(vg->chip.irq.domain, base + pin);
163171e6ca61SCristina Ciocan 			generic_handle_irq(virq);
163271e6ca61SCristina Ciocan 		}
163371e6ca61SCristina Ciocan 	}
163471e6ca61SCristina Ciocan 	chip->irq_eoi(data);
163571e6ca61SCristina Ciocan }
163671e6ca61SCristina Ciocan 
16375fae8b86SMika Westerberg static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
16385fae8b86SMika Westerberg {
163949c03096SAndy Shevchenko 	struct gpio_chip *gc = &vg->chip;
164049c03096SAndy Shevchenko 	struct device *dev = &vg->pdev->dev;
16415fae8b86SMika Westerberg 	void __iomem *reg;
16425fae8b86SMika Westerberg 	u32 base, value;
164395f0972cSMika Westerberg 	int i;
164495f0972cSMika Westerberg 
164595f0972cSMika Westerberg 	/*
164695f0972cSMika Westerberg 	 * Clear interrupt triggers for all pins that are GPIOs and
164795f0972cSMika Westerberg 	 * do not use direct IRQ mode. This will prevent spurious
164895f0972cSMika Westerberg 	 * interrupts from misconfigured pins.
164995f0972cSMika Westerberg 	 */
165071e6ca61SCristina Ciocan 	for (i = 0; i < vg->soc_data->npins; i++) {
165171e6ca61SCristina Ciocan 		unsigned int pin = vg->soc_data->pins[i].number;
165271e6ca61SCristina Ciocan 
165371e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
165471e6ca61SCristina Ciocan 		if (!reg) {
165571e6ca61SCristina Ciocan 			dev_warn(&vg->pdev->dev,
165671e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve conf0 register\n",
165771e6ca61SCristina Ciocan 				 i);
165871e6ca61SCristina Ciocan 			continue;
165971e6ca61SCristina Ciocan 		}
166071e6ca61SCristina Ciocan 
166171e6ca61SCristina Ciocan 		value = readl(reg);
166249c03096SAndy Shevchenko 		if (value & BYT_DIRECT_IRQ_EN) {
1663dc7b0387SThierry Reding 			clear_bit(i, gc->irq.valid_mask);
166449c03096SAndy Shevchenko 			dev_dbg(dev, "excluding GPIO %d from IRQ domain\n", i);
166549c03096SAndy Shevchenko 		} else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) {
166695f0972cSMika Westerberg 			byt_gpio_clear_triggering(vg, i);
166749c03096SAndy Shevchenko 			dev_dbg(dev, "disabling GPIO %d\n", i);
166895f0972cSMika Westerberg 		}
166995f0972cSMika Westerberg 	}
16705fae8b86SMika Westerberg 
16715fae8b86SMika Westerberg 	/* clear interrupt status trigger registers */
167271e6ca61SCristina Ciocan 	for (base = 0; base < vg->soc_data->npins; base += 32) {
1673c501d0b1SCristina Ciocan 		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
167471e6ca61SCristina Ciocan 
167571e6ca61SCristina Ciocan 		if (!reg) {
167671e6ca61SCristina Ciocan 			dev_warn(&vg->pdev->dev,
167771e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve irq status reg\n",
167871e6ca61SCristina Ciocan 				 base);
167971e6ca61SCristina Ciocan 			continue;
168071e6ca61SCristina Ciocan 		}
168171e6ca61SCristina Ciocan 
16825fae8b86SMika Westerberg 		writel(0xffffffff, reg);
16835fae8b86SMika Westerberg 		/* make sure trigger bits are cleared, if not then a pin
16845fae8b86SMika Westerberg 		   might be misconfigured in bios */
16855fae8b86SMika Westerberg 		value = readl(reg);
16865fae8b86SMika Westerberg 		if (value)
16875fae8b86SMika Westerberg 			dev_err(&vg->pdev->dev,
16885fae8b86SMika Westerberg 				"GPIO interrupt error, pins misconfigured\n");
16895fae8b86SMika Westerberg 	}
16905fae8b86SMika Westerberg }
16915fae8b86SMika Westerberg 
169271e6ca61SCristina Ciocan static int byt_gpio_probe(struct byt_gpio *vg)
16935fae8b86SMika Westerberg {
16945fae8b86SMika Westerberg 	struct gpio_chip *gc;
169571e6ca61SCristina Ciocan 	struct resource *irq_rc;
16965fae8b86SMika Westerberg 	int ret;
16975fae8b86SMika Westerberg 
169871e6ca61SCristina Ciocan 	/* Set up gpio chip */
169971e6ca61SCristina Ciocan 	vg->chip	= byt_gpio_chip;
17005fae8b86SMika Westerberg 	gc		= &vg->chip;
170171e6ca61SCristina Ciocan 	gc->label	= dev_name(&vg->pdev->dev);
17025fae8b86SMika Westerberg 	gc->base	= -1;
17035fae8b86SMika Westerberg 	gc->can_sleep	= false;
170471e6ca61SCristina Ciocan 	gc->parent	= &vg->pdev->dev;
170571e6ca61SCristina Ciocan 	gc->ngpio	= vg->soc_data->npins;
1706dc7b0387SThierry Reding 	gc->irq.need_valid_mask	= true;
17075fae8b86SMika Westerberg 
1708fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP
170971e6ca61SCristina Ciocan 	vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio,
1710fcc18debSMika Westerberg 				       sizeof(*vg->saved_context), GFP_KERNEL);
1711fcc18debSMika Westerberg #endif
17120612413fSAndy Shevchenko 	ret = devm_gpiochip_add_data(&vg->pdev->dev, gc, vg);
17135fae8b86SMika Westerberg 	if (ret) {
171471e6ca61SCristina Ciocan 		dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n");
17155fae8b86SMika Westerberg 		return ret;
17165fae8b86SMika Westerberg 	}
17175fae8b86SMika Westerberg 
171871e6ca61SCristina Ciocan 	ret = gpiochip_add_pin_range(&vg->chip, dev_name(&vg->pdev->dev),
171971e6ca61SCristina Ciocan 				     0, 0, vg->soc_data->npins);
172071e6ca61SCristina Ciocan 	if (ret) {
172171e6ca61SCristina Ciocan 		dev_err(&vg->pdev->dev, "failed to add GPIO pin range\n");
17220612413fSAndy Shevchenko 		return ret;
172371e6ca61SCristina Ciocan 	}
172471e6ca61SCristina Ciocan 
17255fae8b86SMika Westerberg 	/* set up interrupts  */
172671e6ca61SCristina Ciocan 	irq_rc = platform_get_resource(vg->pdev, IORESOURCE_IRQ, 0);
17275fae8b86SMika Westerberg 	if (irq_rc && irq_rc->start) {
17285fae8b86SMika Westerberg 		byt_gpio_irq_init_hw(vg);
17295fae8b86SMika Westerberg 		ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
17303ae02c14SAndy Shevchenko 					   handle_bad_irq, IRQ_TYPE_NONE);
17315fae8b86SMika Westerberg 		if (ret) {
173271e6ca61SCristina Ciocan 			dev_err(&vg->pdev->dev, "failed to add irqchip\n");
17330612413fSAndy Shevchenko 			return ret;
17345fae8b86SMika Westerberg 		}
17355fae8b86SMika Westerberg 
17365fae8b86SMika Westerberg 		gpiochip_set_chained_irqchip(gc, &byt_irqchip,
17375fae8b86SMika Westerberg 					     (unsigned)irq_rc->start,
17385fae8b86SMika Westerberg 					     byt_gpio_irq_handler);
17395fae8b86SMika Westerberg 	}
17405fae8b86SMika Westerberg 
174171e6ca61SCristina Ciocan 	return ret;
174271e6ca61SCristina Ciocan }
174371e6ca61SCristina Ciocan 
174471e6ca61SCristina Ciocan static int byt_set_soc_data(struct byt_gpio *vg,
174571e6ca61SCristina Ciocan 			    const struct byt_pinctrl_soc_data *soc_data)
174671e6ca61SCristina Ciocan {
174771e6ca61SCristina Ciocan 	int i;
174871e6ca61SCristina Ciocan 
174971e6ca61SCristina Ciocan 	vg->soc_data = soc_data;
175071e6ca61SCristina Ciocan 	vg->communities_copy = devm_kcalloc(&vg->pdev->dev,
175171e6ca61SCristina Ciocan 					    soc_data->ncommunities,
175271e6ca61SCristina Ciocan 					    sizeof(*vg->communities_copy),
175371e6ca61SCristina Ciocan 					    GFP_KERNEL);
175471e6ca61SCristina Ciocan 	if (!vg->communities_copy)
175571e6ca61SCristina Ciocan 		return -ENOMEM;
175671e6ca61SCristina Ciocan 
175771e6ca61SCristina Ciocan 	for (i = 0; i < soc_data->ncommunities; i++) {
175871e6ca61SCristina Ciocan 		struct byt_community *comm = vg->communities_copy + i;
175971e6ca61SCristina Ciocan 		struct resource *mem_rc;
176071e6ca61SCristina Ciocan 
176171e6ca61SCristina Ciocan 		*comm = vg->soc_data->communities[i];
176271e6ca61SCristina Ciocan 
176371e6ca61SCristina Ciocan 		mem_rc = platform_get_resource(vg->pdev, IORESOURCE_MEM, 0);
176471e6ca61SCristina Ciocan 		comm->reg_base = devm_ioremap_resource(&vg->pdev->dev, mem_rc);
176571e6ca61SCristina Ciocan 		if (IS_ERR(comm->reg_base))
176671e6ca61SCristina Ciocan 			return PTR_ERR(comm->reg_base);
176771e6ca61SCristina Ciocan 	}
176871e6ca61SCristina Ciocan 
176971e6ca61SCristina Ciocan 	return 0;
177071e6ca61SCristina Ciocan }
177171e6ca61SCristina Ciocan 
177271e6ca61SCristina Ciocan static const struct acpi_device_id byt_gpio_acpi_match[] = {
177371e6ca61SCristina Ciocan 	{ "INT33B2", (kernel_ulong_t)byt_soc_data },
177471e6ca61SCristina Ciocan 	{ "INT33FC", (kernel_ulong_t)byt_soc_data },
177571e6ca61SCristina Ciocan 	{ }
177671e6ca61SCristina Ciocan };
177771e6ca61SCristina Ciocan MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
177871e6ca61SCristina Ciocan 
177971e6ca61SCristina Ciocan static int byt_pinctrl_probe(struct platform_device *pdev)
178071e6ca61SCristina Ciocan {
178171e6ca61SCristina Ciocan 	const struct byt_pinctrl_soc_data *soc_data = NULL;
178271e6ca61SCristina Ciocan 	const struct byt_pinctrl_soc_data **soc_table;
178371e6ca61SCristina Ciocan 	const struct acpi_device_id *acpi_id;
178471e6ca61SCristina Ciocan 	struct acpi_device *acpi_dev;
178571e6ca61SCristina Ciocan 	struct byt_gpio *vg;
178671e6ca61SCristina Ciocan 	int i, ret;
178771e6ca61SCristina Ciocan 
178871e6ca61SCristina Ciocan 	acpi_dev = ACPI_COMPANION(&pdev->dev);
178971e6ca61SCristina Ciocan 	if (!acpi_dev)
179071e6ca61SCristina Ciocan 		return -ENODEV;
179171e6ca61SCristina Ciocan 
179271e6ca61SCristina Ciocan 	acpi_id = acpi_match_device(byt_gpio_acpi_match, &pdev->dev);
179371e6ca61SCristina Ciocan 	if (!acpi_id)
179471e6ca61SCristina Ciocan 		return -ENODEV;
179571e6ca61SCristina Ciocan 
179671e6ca61SCristina Ciocan 	soc_table = (const struct byt_pinctrl_soc_data **)acpi_id->driver_data;
179771e6ca61SCristina Ciocan 
179871e6ca61SCristina Ciocan 	for (i = 0; soc_table[i]; i++) {
179971e6ca61SCristina Ciocan 		if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) {
180071e6ca61SCristina Ciocan 			soc_data = soc_table[i];
180171e6ca61SCristina Ciocan 			break;
180271e6ca61SCristina Ciocan 		}
180371e6ca61SCristina Ciocan 	}
180471e6ca61SCristina Ciocan 
180571e6ca61SCristina Ciocan 	if (!soc_data)
180671e6ca61SCristina Ciocan 		return -ENODEV;
180771e6ca61SCristina Ciocan 
180871e6ca61SCristina Ciocan 	vg = devm_kzalloc(&pdev->dev, sizeof(*vg), GFP_KERNEL);
180971e6ca61SCristina Ciocan 	if (!vg)
181071e6ca61SCristina Ciocan 		return -ENOMEM;
181171e6ca61SCristina Ciocan 
181271e6ca61SCristina Ciocan 	vg->pdev = pdev;
181371e6ca61SCristina Ciocan 	ret = byt_set_soc_data(vg, soc_data);
181471e6ca61SCristina Ciocan 	if (ret) {
181571e6ca61SCristina Ciocan 		dev_err(&pdev->dev, "failed to set soc data\n");
181671e6ca61SCristina Ciocan 		return ret;
181771e6ca61SCristina Ciocan 	}
181871e6ca61SCristina Ciocan 
181971e6ca61SCristina Ciocan 	vg->pctl_desc		= byt_pinctrl_desc;
182071e6ca61SCristina Ciocan 	vg->pctl_desc.name	= dev_name(&pdev->dev);
182171e6ca61SCristina Ciocan 	vg->pctl_desc.pins	= vg->soc_data->pins;
182271e6ca61SCristina Ciocan 	vg->pctl_desc.npins	= vg->soc_data->npins;
182371e6ca61SCristina Ciocan 
18240612413fSAndy Shevchenko 	vg->pctl_dev = devm_pinctrl_register(&pdev->dev, &vg->pctl_desc, vg);
182571e6ca61SCristina Ciocan 	if (IS_ERR(vg->pctl_dev)) {
182671e6ca61SCristina Ciocan 		dev_err(&pdev->dev, "failed to register pinctrl driver\n");
182771e6ca61SCristina Ciocan 		return PTR_ERR(vg->pctl_dev);
182871e6ca61SCristina Ciocan 	}
182971e6ca61SCristina Ciocan 
1830a171bc51SVille Syrjälä 	raw_spin_lock_init(&vg->lock);
1831a171bc51SVille Syrjälä 
183271e6ca61SCristina Ciocan 	ret = byt_gpio_probe(vg);
18330612413fSAndy Shevchenko 	if (ret)
183471e6ca61SCristina Ciocan 		return ret;
183571e6ca61SCristina Ciocan 
183671e6ca61SCristina Ciocan 	platform_set_drvdata(pdev, vg);
183771e6ca61SCristina Ciocan 	pm_runtime_enable(&pdev->dev);
183871e6ca61SCristina Ciocan 
183971e6ca61SCristina Ciocan 	return 0;
184071e6ca61SCristina Ciocan }
184171e6ca61SCristina Ciocan 
1842fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP
1843fcc18debSMika Westerberg static int byt_gpio_suspend(struct device *dev)
1844fcc18debSMika Westerberg {
1845fcc18debSMika Westerberg 	struct platform_device *pdev = to_platform_device(dev);
1846fcc18debSMika Westerberg 	struct byt_gpio *vg = platform_get_drvdata(pdev);
1847fcc18debSMika Westerberg 	int i;
1848fcc18debSMika Westerberg 
184971e6ca61SCristina Ciocan 	for (i = 0; i < vg->soc_data->npins; i++) {
1850fcc18debSMika Westerberg 		void __iomem *reg;
1851fcc18debSMika Westerberg 		u32 value;
185271e6ca61SCristina Ciocan 		unsigned int pin = vg->soc_data->pins[i].number;
1853fcc18debSMika Westerberg 
185471e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
185571e6ca61SCristina Ciocan 		if (!reg) {
185671e6ca61SCristina Ciocan 			dev_warn(&vg->pdev->dev,
185771e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve conf0 register\n",
185871e6ca61SCristina Ciocan 				 i);
185971e6ca61SCristina Ciocan 			continue;
186071e6ca61SCristina Ciocan 		}
1861fcc18debSMika Westerberg 		value = readl(reg) & BYT_CONF0_RESTORE_MASK;
1862fcc18debSMika Westerberg 		vg->saved_context[i].conf0 = value;
1863fcc18debSMika Westerberg 
186471e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
1865fcc18debSMika Westerberg 		value = readl(reg) & BYT_VAL_RESTORE_MASK;
1866fcc18debSMika Westerberg 		vg->saved_context[i].val = value;
1867fcc18debSMika Westerberg 	}
1868fcc18debSMika Westerberg 
1869fcc18debSMika Westerberg 	return 0;
1870fcc18debSMika Westerberg }
1871fcc18debSMika Westerberg 
1872fcc18debSMika Westerberg static int byt_gpio_resume(struct device *dev)
1873fcc18debSMika Westerberg {
1874fcc18debSMika Westerberg 	struct platform_device *pdev = to_platform_device(dev);
1875fcc18debSMika Westerberg 	struct byt_gpio *vg = platform_get_drvdata(pdev);
1876fcc18debSMika Westerberg 	int i;
1877fcc18debSMika Westerberg 
187871e6ca61SCristina Ciocan 	for (i = 0; i < vg->soc_data->npins; i++) {
1879fcc18debSMika Westerberg 		void __iomem *reg;
1880fcc18debSMika Westerberg 		u32 value;
188171e6ca61SCristina Ciocan 		unsigned int pin = vg->soc_data->pins[i].number;
1882fcc18debSMika Westerberg 
188371e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
188471e6ca61SCristina Ciocan 		if (!reg) {
188571e6ca61SCristina Ciocan 			dev_warn(&vg->pdev->dev,
188671e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve conf0 register\n",
188771e6ca61SCristina Ciocan 				 i);
188871e6ca61SCristina Ciocan 			continue;
188971e6ca61SCristina Ciocan 		}
1890fcc18debSMika Westerberg 		value = readl(reg);
1891fcc18debSMika Westerberg 		if ((value & BYT_CONF0_RESTORE_MASK) !=
1892fcc18debSMika Westerberg 		     vg->saved_context[i].conf0) {
1893fcc18debSMika Westerberg 			value &= ~BYT_CONF0_RESTORE_MASK;
1894fcc18debSMika Westerberg 			value |= vg->saved_context[i].conf0;
1895fcc18debSMika Westerberg 			writel(value, reg);
1896fcc18debSMika Westerberg 			dev_info(dev, "restored pin %d conf0 %#08x", i, value);
1897fcc18debSMika Westerberg 		}
1898fcc18debSMika Westerberg 
189971e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
1900fcc18debSMika Westerberg 		value = readl(reg);
1901fcc18debSMika Westerberg 		if ((value & BYT_VAL_RESTORE_MASK) !=
1902fcc18debSMika Westerberg 		     vg->saved_context[i].val) {
1903fcc18debSMika Westerberg 			u32 v;
1904fcc18debSMika Westerberg 
1905fcc18debSMika Westerberg 			v = value & ~BYT_VAL_RESTORE_MASK;
1906fcc18debSMika Westerberg 			v |= vg->saved_context[i].val;
1907fcc18debSMika Westerberg 			if (v != value) {
1908fcc18debSMika Westerberg 				writel(v, reg);
1909fcc18debSMika Westerberg 				dev_dbg(dev, "restored pin %d val %#08x\n",
1910fcc18debSMika Westerberg 					i, v);
1911fcc18debSMika Westerberg 			}
1912fcc18debSMika Westerberg 		}
1913fcc18debSMika Westerberg 	}
1914fcc18debSMika Westerberg 
1915fcc18debSMika Westerberg 	return 0;
1916fcc18debSMika Westerberg }
1917fcc18debSMika Westerberg #endif
1918fcc18debSMika Westerberg 
1919ec879f12SMika Westerberg #ifdef CONFIG_PM
19205fae8b86SMika Westerberg static int byt_gpio_runtime_suspend(struct device *dev)
19215fae8b86SMika Westerberg {
19225fae8b86SMika Westerberg 	return 0;
19235fae8b86SMika Westerberg }
19245fae8b86SMika Westerberg 
19255fae8b86SMika Westerberg static int byt_gpio_runtime_resume(struct device *dev)
19265fae8b86SMika Westerberg {
19275fae8b86SMika Westerberg 	return 0;
19285fae8b86SMika Westerberg }
1929ec879f12SMika Westerberg #endif
19305fae8b86SMika Westerberg 
19315fae8b86SMika Westerberg static const struct dev_pm_ops byt_gpio_pm_ops = {
1932fcc18debSMika Westerberg 	SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume)
1933fcc18debSMika Westerberg 	SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume,
1934fcc18debSMika Westerberg 			   NULL)
19355fae8b86SMika Westerberg };
19365fae8b86SMika Westerberg 
19375fae8b86SMika Westerberg static struct platform_driver byt_gpio_driver = {
193871e6ca61SCristina Ciocan 	.probe          = byt_pinctrl_probe,
19395fae8b86SMika Westerberg 	.driver         = {
19405fae8b86SMika Westerberg 		.name			= "byt_gpio",
19415fae8b86SMika Westerberg 		.pm			= &byt_gpio_pm_ops,
1942360943a8SPaul Gortmaker 		.suppress_bind_attrs	= true,
1943360943a8SPaul Gortmaker 
19445fae8b86SMika Westerberg 		.acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
19455fae8b86SMika Westerberg 	},
19465fae8b86SMika Westerberg };
19475fae8b86SMika Westerberg 
19485fae8b86SMika Westerberg static int __init byt_gpio_init(void)
19495fae8b86SMika Westerberg {
19505fae8b86SMika Westerberg 	return platform_driver_register(&byt_gpio_driver);
19515fae8b86SMika Westerberg }
19525fae8b86SMika Westerberg subsys_initcall(byt_gpio_init);
1953