1875a92b3SAndy Shevchenko // SPDX-License-Identifier: GPL-2.0
25fae8b86SMika Westerberg /*
35fae8b86SMika Westerberg  * Pinctrl GPIO driver for Intel Baytrail
45fae8b86SMika Westerberg  *
5875a92b3SAndy Shevchenko  * Copyright (c) 2012-2013, Intel Corporation
65fae8b86SMika Westerberg  * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
75fae8b86SMika Westerberg  */
85fae8b86SMika Westerberg 
95fae8b86SMika Westerberg #include <linux/acpi.h>
10e0da3842SAndy Shevchenko #include <linux/bitops.h>
11e0da3842SAndy Shevchenko #include <linux/gpio/driver.h>
12e0da3842SAndy Shevchenko #include <linux/init.h>
13e0da3842SAndy Shevchenko #include <linux/interrupt.h>
145fae8b86SMika Westerberg #include <linux/io.h>
15e0da3842SAndy Shevchenko #include <linux/kernel.h>
16e0da3842SAndy Shevchenko #include <linux/types.h>
17e0da3842SAndy Shevchenko #include <linux/platform_device.h>
185fae8b86SMika Westerberg #include <linux/pm_runtime.h>
1961db6c9dSAndy Shevchenko #include <linux/property.h>
20e0da3842SAndy Shevchenko #include <linux/seq_file.h>
21c518d31bSAndy Shevchenko #include <linux/string_helpers.h>
2261db6c9dSAndy Shevchenko 
235fae8b86SMika Westerberg #include <linux/pinctrl/pinctrl.h>
24c501d0b1SCristina Ciocan #include <linux/pinctrl/pinmux.h>
25c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf.h>
26c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf-generic.h>
275fae8b86SMika Westerberg 
284f010b93SAndy Shevchenko #include "pinctrl-intel.h"
294f010b93SAndy Shevchenko 
305fae8b86SMika Westerberg /* memory mapped register offsets */
315fae8b86SMika Westerberg #define BYT_CONF0_REG		0x000
325fae8b86SMika Westerberg #define BYT_CONF1_REG		0x004
335fae8b86SMika Westerberg #define BYT_VAL_REG		0x008
345fae8b86SMika Westerberg #define BYT_DFT_REG		0x00c
355fae8b86SMika Westerberg #define BYT_INT_STAT_REG	0x800
36689e0088SHans de Goede #define BYT_DIRECT_IRQ_REG	0x980
37658b476cSCristina Ciocan #define BYT_DEBOUNCE_REG	0x9d0
385fae8b86SMika Westerberg 
395fae8b86SMika Westerberg /* BYT_CONF0_REG register bits */
405fae8b86SMika Westerberg #define BYT_IODEN		BIT(31)
415fae8b86SMika Westerberg #define BYT_DIRECT_IRQ_EN	BIT(27)
42eb0a2daaSAndy Shevchenko #define BYT_TRIG_MASK		GENMASK(26, 24)
435fae8b86SMika Westerberg #define BYT_TRIG_NEG		BIT(26)
445fae8b86SMika Westerberg #define BYT_TRIG_POS		BIT(25)
455fae8b86SMika Westerberg #define BYT_TRIG_LVL		BIT(24)
46658b476cSCristina Ciocan #define BYT_DEBOUNCE_EN		BIT(20)
479291c65bSHans de Goede #define BYT_GLITCH_FILTER_EN	BIT(19)
489291c65bSHans de Goede #define BYT_GLITCH_F_SLOW_CLK	BIT(17)
499291c65bSHans de Goede #define BYT_GLITCH_F_FAST_CLK	BIT(16)
505fae8b86SMika Westerberg #define BYT_PULL_STR_SHIFT	9
51eb0a2daaSAndy Shevchenko #define BYT_PULL_STR_MASK	GENMASK(10, 9)
525fae8b86SMika Westerberg #define BYT_PULL_STR_2K		(0 << BYT_PULL_STR_SHIFT)
535fae8b86SMika Westerberg #define BYT_PULL_STR_10K	(1 << BYT_PULL_STR_SHIFT)
545fae8b86SMika Westerberg #define BYT_PULL_STR_20K	(2 << BYT_PULL_STR_SHIFT)
555fae8b86SMika Westerberg #define BYT_PULL_STR_40K	(3 << BYT_PULL_STR_SHIFT)
56eb0a2daaSAndy Shevchenko #define BYT_PULL_ASSIGN_MASK	GENMASK(8, 7)
579d712086SAndy Shevchenko #define BYT_PULL_ASSIGN_DOWN	BIT(8)
589d712086SAndy Shevchenko #define BYT_PULL_ASSIGN_UP	BIT(7)
59eb0a2daaSAndy Shevchenko #define BYT_PIN_MUX		GENMASK(2, 0)
605fae8b86SMika Westerberg 
615fae8b86SMika Westerberg /* BYT_VAL_REG register bits */
62eb0a2daaSAndy Shevchenko #define BYT_DIR_MASK		GENMASK(2, 1)
635fae8b86SMika Westerberg #define BYT_INPUT_EN		BIT(2)  /* 0: input enabled (active low)*/
645fae8b86SMika Westerberg #define BYT_OUTPUT_EN		BIT(1)  /* 0: output enabled (active low)*/
655fae8b86SMika Westerberg #define BYT_LEVEL		BIT(0)
665fae8b86SMika Westerberg 
67eb0a2daaSAndy Shevchenko #define BYT_CONF0_RESTORE_MASK	(BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | BYT_PIN_MUX)
68fcc18debSMika Westerberg #define BYT_VAL_RESTORE_MASK	(BYT_DIR_MASK | BYT_LEVEL)
69fcc18debSMika Westerberg 
70658b476cSCristina Ciocan /* BYT_DEBOUNCE_REG bits */
71eb0a2daaSAndy Shevchenko #define BYT_DEBOUNCE_PULSE_MASK		GENMASK(2, 0)
72658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_375US	1
73658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_750US	2
74658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_1500US	3
75658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_3MS		4
76658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_6MS		5
77658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_12MS		6
78658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_24MS		7
79658b476cSCristina Ciocan 
805fae8b86SMika Westerberg #define BYT_NGPIO_SCORE		102
815fae8b86SMika Westerberg #define BYT_NGPIO_NCORE		28
825fae8b86SMika Westerberg #define BYT_NGPIO_SUS		44
835fae8b86SMika Westerberg 
845fae8b86SMika Westerberg #define BYT_SCORE_ACPI_UID	"1"
855fae8b86SMika Westerberg #define BYT_NCORE_ACPI_UID	"2"
865fae8b86SMika Westerberg #define BYT_SUS_ACPI_UID	"3"
875fae8b86SMika Westerberg 
88c501d0b1SCristina Ciocan /*
89c501d0b1SCristina Ciocan  * This is the function value most pins have for GPIO muxing. If the value
90c501d0b1SCristina Ciocan  * differs from the default one, it must be explicitly mentioned. Otherwise, the
91c501d0b1SCristina Ciocan  * pin control implementation will set the muxing value to default GPIO if it
92c501d0b1SCristina Ciocan  * does not find a match for the requested function.
93c501d0b1SCristina Ciocan  */
94c501d0b1SCristina Ciocan #define BYT_DEFAULT_GPIO_MUX	0
95a705f9c1SAndy Shevchenko #define BYT_ALTER_GPIO_MUX	1
96c501d0b1SCristina Ciocan 
975d33e0ebSAndy Shevchenko struct intel_pad_context {
98c8f5c4c7SCristina Ciocan 	u32 conf0;
99c8f5c4c7SCristina Ciocan 	u32 val;
100c8f5c4c7SCristina Ciocan };
1015fae8b86SMika Westerberg 
102c8f5c4c7SCristina Ciocan #define COMMUNITY(p, n, map)		\
103c8f5c4c7SCristina Ciocan 	{				\
104c8f5c4c7SCristina Ciocan 		.pin_base	= (p),	\
105c8f5c4c7SCristina Ciocan 		.npins		= (n),	\
106c8f5c4c7SCristina Ciocan 		.pad_map	= (map),\
107c8f5c4c7SCristina Ciocan 	}
108c8f5c4c7SCristina Ciocan 
109c8f5c4c7SCristina Ciocan /* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */
110c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_score_pins[] = {
111c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(0, "SATA_GP0"),
112c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(1, "SATA_GP1"),
113c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(2, "SATA_LED#"),
114c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(3, "PCIE_CLKREQ0"),
115c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(4, "PCIE_CLKREQ1"),
116c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(5, "PCIE_CLKREQ2"),
117c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(6, "PCIE_CLKREQ3"),
118c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(7, "SD3_WP"),
119c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(8, "HDA_RST"),
120c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(9, "HDA_SYNC"),
121c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(10, "HDA_CLK"),
122c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(11, "HDA_SDO"),
123c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(12, "HDA_SDI0"),
124c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(13, "HDA_SDI1"),
125c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(14, "GPIO_S0_SC14"),
126c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(15, "GPIO_S0_SC15"),
127c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(16, "MMC1_CLK"),
128c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(17, "MMC1_D0"),
129c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(18, "MMC1_D1"),
130c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(19, "MMC1_D2"),
131c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(20, "MMC1_D3"),
132c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(21, "MMC1_D4"),
133c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(22, "MMC1_D5"),
134c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(23, "MMC1_D6"),
135c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(24, "MMC1_D7"),
136c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(25, "MMC1_CMD"),
137c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(26, "MMC1_RST"),
138c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(27, "SD2_CLK"),
139c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(28, "SD2_D0"),
140c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(29, "SD2_D1"),
141c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(30, "SD2_D2"),
142c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(31, "SD2_D3_CD"),
143c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(32, "SD2_CMD"),
144c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(33, "SD3_CLK"),
145c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(34, "SD3_D0"),
146c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(35, "SD3_D1"),
147c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(36, "SD3_D2"),
148c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(37, "SD3_D3"),
149c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(38, "SD3_CD"),
150c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(39, "SD3_CMD"),
151c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(40, "SD3_1P8EN"),
152c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(41, "SD3_PWREN#"),
153c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(42, "ILB_LPC_AD0"),
154c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(43, "ILB_LPC_AD1"),
155c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(44, "ILB_LPC_AD2"),
156c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(45, "ILB_LPC_AD3"),
157c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(46, "ILB_LPC_FRAME"),
158c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(47, "ILB_LPC_CLK0"),
159c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(48, "ILB_LPC_CLK1"),
160c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(49, "ILB_LPC_CLKRUN"),
161c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(50, "ILB_LPC_SERIRQ"),
162c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(51, "PCU_SMB_DATA"),
163c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(52, "PCU_SMB_CLK"),
164c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(53, "PCU_SMB_ALERT"),
165c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(54, "ILB_8254_SPKR"),
166c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(55, "GPIO_S0_SC55"),
167c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(56, "GPIO_S0_SC56"),
168c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(57, "GPIO_S0_SC57"),
169c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(58, "GPIO_S0_SC58"),
170c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(59, "GPIO_S0_SC59"),
171c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(60, "GPIO_S0_SC60"),
172c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(61, "GPIO_S0_SC61"),
173c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(62, "LPE_I2S2_CLK"),
174c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(63, "LPE_I2S2_FRM"),
175c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(64, "LPE_I2S2_DATAIN"),
176c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"),
177c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(66, "SIO_SPI_CS"),
178c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(67, "SIO_SPI_MISO"),
179c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(68, "SIO_SPI_MOSI"),
180c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(69, "SIO_SPI_CLK"),
181c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(70, "SIO_UART1_RXD"),
182c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(71, "SIO_UART1_TXD"),
183c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(72, "SIO_UART1_RTS"),
184c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(73, "SIO_UART1_CTS"),
185c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(74, "SIO_UART2_RXD"),
186c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(75, "SIO_UART2_TXD"),
187c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(76, "SIO_UART2_RTS"),
188c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(77, "SIO_UART2_CTS"),
189c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(78, "SIO_I2C0_DATA"),
190c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(79, "SIO_I2C0_CLK"),
191c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(80, "SIO_I2C1_DATA"),
192c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(81, "SIO_I2C1_CLK"),
193c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(82, "SIO_I2C2_DATA"),
194c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(83, "SIO_I2C2_CLK"),
195c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(84, "SIO_I2C3_DATA"),
196c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(85, "SIO_I2C3_CLK"),
197c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(86, "SIO_I2C4_DATA"),
198c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(87, "SIO_I2C4_CLK"),
199c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(88, "SIO_I2C5_DATA"),
200c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(89, "SIO_I2C5_CLK"),
201c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(90, "SIO_I2C6_DATA"),
202c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(91, "SIO_I2C6_CLK"),
203c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(92, "GPIO_S0_SC92"),
204c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(93, "GPIO_S0_SC93"),
205c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(94, "SIO_PWM0"),
206c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(95, "SIO_PWM1"),
207c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(96, "PMC_PLT_CLK0"),
208c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(97, "PMC_PLT_CLK1"),
209c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(98, "PMC_PLT_CLK2"),
210c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(99, "PMC_PLT_CLK3"),
211c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(100, "PMC_PLT_CLK4"),
212c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(101, "PMC_PLT_CLK5"),
213c8f5c4c7SCristina Ciocan };
2145fae8b86SMika Westerberg 
215c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = {
216c8f5c4c7SCristina Ciocan 	85, 89, 93, 96, 99, 102, 98, 101, 34, 37,
217c8f5c4c7SCristina Ciocan 	36, 38, 39, 35, 40, 84, 62, 61, 64, 59,
218c8f5c4c7SCristina Ciocan 	54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
219c8f5c4c7SCristina Ciocan 	52, 49, 48, 43, 46, 41, 45, 42, 58, 44,
220c8f5c4c7SCristina Ciocan 	95, 105, 70, 68, 67, 66, 69, 71, 65, 72,
221c8f5c4c7SCristina Ciocan 	86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
222c8f5c4c7SCristina Ciocan 	80, 82, 13, 12, 15, 14, 17, 18, 19, 16,
223c8f5c4c7SCristina Ciocan 	2, 1, 0, 4, 6, 7, 9, 8, 33, 32,
224c8f5c4c7SCristina Ciocan 	31, 30, 29, 27, 25, 28, 26, 23, 21, 20,
225c8f5c4c7SCristina Ciocan 	24, 22, 5, 3, 10, 11, 106, 87, 91, 104,
226c8f5c4c7SCristina Ciocan 	97, 100,
2275fae8b86SMika Westerberg };
2285fae8b86SMika Westerberg 
229c8f5c4c7SCristina Ciocan /* SCORE groups */
230c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 };
231c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 };
232c8f5c4c7SCristina Ciocan 
233c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm0_pins[] = { 94 };
234c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm1_pins[] = { 95 };
235c8f5c4c7SCristina Ciocan 
236c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 };
237c8f5c4c7SCristina Ciocan 
238c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c5_pins[] = { 88, 89 };
239c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c6_pins[] = { 90, 91 };
240c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c4_pins[] = { 86, 87 };
241c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c3_pins[] = { 84, 85 };
242c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c2_pins[] = { 82, 83 };
243c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c1_pins[] = { 80, 81 };
244c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c0_pins[] = { 78, 79 };
245c8f5c4c7SCristina Ciocan 
246c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 };
247c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 };
248c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 };
249c8f5c4c7SCristina Ciocan 
250c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdcard_pins[] = {
251c8f5c4c7SCristina Ciocan 	7, 33, 34, 35, 36, 37, 38, 39, 40, 41,
252c8f5c4c7SCristina Ciocan };
2534f010b93SAndy Shevchenko static const unsigned int byt_score_sdcard_mux_values[] = {
254c8f5c4c7SCristina Ciocan 	2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
255c8f5c4c7SCristina Ciocan };
256c8f5c4c7SCristina Ciocan 
257c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 };
258c8f5c4c7SCristina Ciocan 
259c8f5c4c7SCristina Ciocan static const unsigned int byt_score_emmc_pins[] = {
260c8f5c4c7SCristina Ciocan 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
261c8f5c4c7SCristina Ciocan };
262c8f5c4c7SCristina Ciocan 
263c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ilb_lpc_pins[] = {
264c8f5c4c7SCristina Ciocan 	42, 43, 44, 45, 46, 47, 48, 49, 50,
265c8f5c4c7SCristina Ciocan };
266c8f5c4c7SCristina Ciocan 
267c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 };
268c8f5c4c7SCristina Ciocan 
269c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk0_pins[] = { 96 };
270c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk1_pins[] = { 97 };
271c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk2_pins[] = { 98 };
272b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk3_pins[] = { 99 };
273b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk4_pins[] = { 100 };
274b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk5_pins[] = { 101 };
275c8f5c4c7SCristina Ciocan 
276c8f5c4c7SCristina Ciocan static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 };
277c8f5c4c7SCristina Ciocan 
2784f010b93SAndy Shevchenko static const struct intel_pingroup byt_score_groups[] = {
2794f010b93SAndy Shevchenko 	PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1),
2804f010b93SAndy Shevchenko 	PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1),
2814f010b93SAndy Shevchenko 	PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1),
2824f010b93SAndy Shevchenko 	PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1),
2834f010b93SAndy Shevchenko 	PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1),
2844f010b93SAndy Shevchenko 	PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1),
2854f010b93SAndy Shevchenko 	PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1),
2864f010b93SAndy Shevchenko 	PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1),
2874f010b93SAndy Shevchenko 	PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1),
2884f010b93SAndy Shevchenko 	PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1),
2894f010b93SAndy Shevchenko 	PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1),
2904f010b93SAndy Shevchenko 	PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1),
2914f010b93SAndy Shevchenko 	PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1),
2924f010b93SAndy Shevchenko 	PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1),
2934f010b93SAndy Shevchenko 	PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1),
2944f010b93SAndy Shevchenko 	PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values),
2954f010b93SAndy Shevchenko 	PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1),
2964f010b93SAndy Shevchenko 	PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1),
2974f010b93SAndy Shevchenko 	PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1),
2984f010b93SAndy Shevchenko 	PIN_GROUP("sata_grp", byt_score_sata_pins, 1),
2994f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1),
3004f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1),
3014f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1),
3024f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1),
3034f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1),
3044f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1),
3054f010b93SAndy Shevchenko 	PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1),
306c8f5c4c7SCristina Ciocan };
307c8f5c4c7SCristina Ciocan 
308c8f5c4c7SCristina Ciocan static const char * const byt_score_uart_groups[] = {
309c8f5c4c7SCristina Ciocan 	"uart1_grp", "uart2_grp",
310c8f5c4c7SCristina Ciocan };
311c8f5c4c7SCristina Ciocan static const char * const byt_score_pwm_groups[] = {
312c8f5c4c7SCristina Ciocan 	"pwm0_grp", "pwm1_grp",
313c8f5c4c7SCristina Ciocan };
314c8f5c4c7SCristina Ciocan static const char * const byt_score_ssp_groups[] = {
315c8f5c4c7SCristina Ciocan 	"ssp0_grp", "ssp1_grp", "ssp2_grp",
316c8f5c4c7SCristina Ciocan };
317c8f5c4c7SCristina Ciocan static const char * const byt_score_spi_groups[] = { "sio_spi_grp" };
318c8f5c4c7SCristina Ciocan static const char * const byt_score_i2c_groups[] = {
319c8f5c4c7SCristina Ciocan 	"i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp",
320c8f5c4c7SCristina Ciocan 	"i2c6_grp",
321c8f5c4c7SCristina Ciocan };
322c8f5c4c7SCristina Ciocan static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" };
323c8f5c4c7SCristina Ciocan static const char * const byt_score_sdio_groups[] = { "sdio_grp" };
324c8f5c4c7SCristina Ciocan static const char * const byt_score_emmc_groups[] = { "emmc_grp" };
325c8f5c4c7SCristina Ciocan static const char * const byt_score_lpc_groups[] = { "lpc_grp" };
326c8f5c4c7SCristina Ciocan static const char * const byt_score_sata_groups[] = { "sata_grp" };
327c8f5c4c7SCristina Ciocan static const char * const byt_score_plt_clk_groups[] = {
328c8f5c4c7SCristina Ciocan 	"plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
329c8f5c4c7SCristina Ciocan 	"plt_clk4_grp", "plt_clk5_grp",
330c8f5c4c7SCristina Ciocan };
331c8f5c4c7SCristina Ciocan static const char * const byt_score_smbus_groups[] = { "smbus_grp" };
332c8f5c4c7SCristina Ciocan static const char * const byt_score_gpio_groups[] = {
333c8f5c4c7SCristina Ciocan 	"uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp",
334c8f5c4c7SCristina Ciocan 	"ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp",
335c8f5c4c7SCristina Ciocan 	"i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp",
336c8f5c4c7SCristina Ciocan 	"sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp",
337c8f5c4c7SCristina Ciocan 	"plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
338c8f5c4c7SCristina Ciocan 	"plt_clk4_grp", "plt_clk5_grp", "smbus_grp",
339c8f5c4c7SCristina Ciocan };
340c8f5c4c7SCristina Ciocan 
3414f010b93SAndy Shevchenko static const struct intel_function byt_score_functions[] = {
342c8f5c4c7SCristina Ciocan 	FUNCTION("uart", byt_score_uart_groups),
343c8f5c4c7SCristina Ciocan 	FUNCTION("pwm", byt_score_pwm_groups),
344c8f5c4c7SCristina Ciocan 	FUNCTION("ssp", byt_score_ssp_groups),
345c8f5c4c7SCristina Ciocan 	FUNCTION("spi", byt_score_spi_groups),
346c8f5c4c7SCristina Ciocan 	FUNCTION("i2c", byt_score_i2c_groups),
347c8f5c4c7SCristina Ciocan 	FUNCTION("sdcard", byt_score_sdcard_groups),
348c8f5c4c7SCristina Ciocan 	FUNCTION("sdio", byt_score_sdio_groups),
349c8f5c4c7SCristina Ciocan 	FUNCTION("emmc", byt_score_emmc_groups),
350c8f5c4c7SCristina Ciocan 	FUNCTION("lpc", byt_score_lpc_groups),
351c8f5c4c7SCristina Ciocan 	FUNCTION("sata", byt_score_sata_groups),
352c8f5c4c7SCristina Ciocan 	FUNCTION("plt_clk", byt_score_plt_clk_groups),
353c8f5c4c7SCristina Ciocan 	FUNCTION("smbus", byt_score_smbus_groups),
354c8f5c4c7SCristina Ciocan 	FUNCTION("gpio", byt_score_gpio_groups),
355c8f5c4c7SCristina Ciocan };
356c8f5c4c7SCristina Ciocan 
35734e65670SAndy Shevchenko static const struct intel_community byt_score_communities[] = {
358c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
359c8f5c4c7SCristina Ciocan };
360c8f5c4c7SCristina Ciocan 
36134e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_score_soc_data = {
362c8f5c4c7SCristina Ciocan 	.uid		= BYT_SCORE_ACPI_UID,
363c8f5c4c7SCristina Ciocan 	.pins		= byt_score_pins,
364c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_score_pins),
365c8f5c4c7SCristina Ciocan 	.groups		= byt_score_groups,
366c8f5c4c7SCristina Ciocan 	.ngroups	= ARRAY_SIZE(byt_score_groups),
367c8f5c4c7SCristina Ciocan 	.functions	= byt_score_functions,
368c8f5c4c7SCristina Ciocan 	.nfunctions	= ARRAY_SIZE(byt_score_functions),
369c8f5c4c7SCristina Ciocan 	.communities	= byt_score_communities,
370c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_score_communities),
371c8f5c4c7SCristina Ciocan };
372c8f5c4c7SCristina Ciocan 
373c8f5c4c7SCristina Ciocan /* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>]  */
374c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_sus_pins[] = {
375c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(0, "GPIO_S50"),
376c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(1, "GPIO_S51"),
377c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(2, "GPIO_S52"),
378c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(3, "GPIO_S53"),
379c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(4, "GPIO_S54"),
380c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(5, "GPIO_S55"),
381c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(6, "GPIO_S56"),
382c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(7, "GPIO_S57"),
383c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(8, "GPIO_S58"),
384c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(9, "GPIO_S59"),
385c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(10, "GPIO_S510"),
386c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(11, "PMC_SUSPWRDNACK"),
387c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(12, "PMC_SUSCLK0"),
388c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(13, "GPIO_S513"),
389c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(14, "USB_ULPI_RST"),
390c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"),
391c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(16, "PMC_PWRBTN"),
392c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(17, "GPIO_S517"),
393c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(18, "PMC_SUS_STAT"),
394c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(19, "USB_OC0"),
395c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(20, "USB_OC1"),
396c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(21, "PCU_SPI_CS1"),
397c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(22, "GPIO_S522"),
398c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(23, "GPIO_S523"),
399c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(24, "GPIO_S524"),
400c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(25, "GPIO_S525"),
401c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(26, "GPIO_S526"),
402c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(27, "GPIO_S527"),
403c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(28, "GPIO_S528"),
404c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(29, "GPIO_S529"),
405c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(30, "GPIO_S530"),
406c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(31, "USB_ULPI_CLK"),
407c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(32, "USB_ULPI_DATA0"),
408c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(33, "USB_ULPI_DATA1"),
409c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(34, "USB_ULPI_DATA2"),
410c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(35, "USB_ULPI_DATA3"),
411c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(36, "USB_ULPI_DATA4"),
412c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(37, "USB_ULPI_DATA5"),
413c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(38, "USB_ULPI_DATA6"),
414c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(39, "USB_ULPI_DATA7"),
415c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(40, "USB_ULPI_DIR"),
416c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(41, "USB_ULPI_NXT"),
417c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(42, "USB_ULPI_STP"),
418c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(43, "USB_ULPI_REFCLK"),
419c8f5c4c7SCristina Ciocan };
420c8f5c4c7SCristina Ciocan 
421c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = {
422c8f5c4c7SCristina Ciocan 	29, 33, 30, 31, 32, 34, 36, 35, 38, 37,
423c8f5c4c7SCristina Ciocan 	18, 7, 11, 20, 17, 1, 8, 10, 19, 12,
424c8f5c4c7SCristina Ciocan 	0, 2, 23, 39, 28, 27, 22, 21, 24, 25,
425c8f5c4c7SCristina Ciocan 	26, 51, 56, 54, 49, 55, 48, 57, 50, 58,
426c8f5c4c7SCristina Ciocan 	52, 53, 59, 40,
427c8f5c4c7SCristina Ciocan };
428c8f5c4c7SCristina Ciocan 
429c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 };
4304f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_mode_values[] = { 0, 0 };
4314f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_gpio_mode_values[] = { 1, 1 };
432c8f5c4c7SCristina Ciocan 
433c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_ulpi_pins[] = {
434c8f5c4c7SCristina Ciocan 	14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
435c8f5c4c7SCristina Ciocan };
4364f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_mode_values[] = {
437c8f5c4c7SCristina Ciocan 	2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
438c8f5c4c7SCristina Ciocan };
4394f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_gpio_mode_values[] = {
4404f010b93SAndy Shevchenko 	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
441c8f5c4c7SCristina Ciocan };
442c8f5c4c7SCristina Ciocan 
443c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pcu_spi_pins[] = { 21 };
4444f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_mode_values[] = { 0 };
4454f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_gpio_mode_values[] = { 1 };
446c8f5c4c7SCristina Ciocan 
4472f46d7f7SHans de Goede static const unsigned int byt_sus_pmu_clk1_pins[] = { 5 };
4482f46d7f7SHans de Goede static const unsigned int byt_sus_pmu_clk2_pins[] = { 6 };
4492f46d7f7SHans de Goede 
4504f010b93SAndy Shevchenko static const struct intel_pingroup byt_sus_groups[] = {
4514f010b93SAndy Shevchenko 	PIN_GROUP("usb_oc_grp", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_mode_values),
4524f010b93SAndy Shevchenko 	PIN_GROUP("usb_ulpi_grp", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mode_values),
4534f010b93SAndy Shevchenko 	PIN_GROUP("pcu_spi_grp", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mode_values),
4544f010b93SAndy Shevchenko 	PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values),
4554f010b93SAndy Shevchenko 	PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values),
4564f010b93SAndy Shevchenko 	PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values),
4572f46d7f7SHans de Goede 	PIN_GROUP("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1),
4582f46d7f7SHans de Goede 	PIN_GROUP("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1),
459c8f5c4c7SCristina Ciocan };
460c8f5c4c7SCristina Ciocan 
461c8f5c4c7SCristina Ciocan static const char * const byt_sus_usb_groups[] = {
462c8f5c4c7SCristina Ciocan 	"usb_oc_grp", "usb_ulpi_grp",
463c8f5c4c7SCristina Ciocan };
464c8f5c4c7SCristina Ciocan static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" };
4652f46d7f7SHans de Goede static const char * const byt_sus_pmu_clk_groups[] = {
4662f46d7f7SHans de Goede 	"pmu_clk1_grp", "pmu_clk2_grp",
4672f46d7f7SHans de Goede };
468c8f5c4c7SCristina Ciocan static const char * const byt_sus_gpio_groups[] = {
4694f010b93SAndy Shevchenko 	"usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio",
4702f46d7f7SHans de Goede 	"pmu_clk1_grp", "pmu_clk2_grp",
471c8f5c4c7SCristina Ciocan };
472c8f5c4c7SCristina Ciocan 
4734f010b93SAndy Shevchenko static const struct intel_function byt_sus_functions[] = {
474c8f5c4c7SCristina Ciocan 	FUNCTION("usb", byt_sus_usb_groups),
475c8f5c4c7SCristina Ciocan 	FUNCTION("spi", byt_sus_spi_groups),
476c8f5c4c7SCristina Ciocan 	FUNCTION("gpio", byt_sus_gpio_groups),
4772f46d7f7SHans de Goede 	FUNCTION("pmu_clk", byt_sus_pmu_clk_groups),
478c8f5c4c7SCristina Ciocan };
479c8f5c4c7SCristina Ciocan 
48034e65670SAndy Shevchenko static const struct intel_community byt_sus_communities[] = {
481c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
482c8f5c4c7SCristina Ciocan };
483c8f5c4c7SCristina Ciocan 
48434e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_sus_soc_data = {
485c8f5c4c7SCristina Ciocan 	.uid		= BYT_SUS_ACPI_UID,
486c8f5c4c7SCristina Ciocan 	.pins		= byt_sus_pins,
487c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_sus_pins),
488c8f5c4c7SCristina Ciocan 	.groups		= byt_sus_groups,
489c8f5c4c7SCristina Ciocan 	.ngroups	= ARRAY_SIZE(byt_sus_groups),
490c8f5c4c7SCristina Ciocan 	.functions	= byt_sus_functions,
491c8f5c4c7SCristina Ciocan 	.nfunctions	= ARRAY_SIZE(byt_sus_functions),
492c8f5c4c7SCristina Ciocan 	.communities	= byt_sus_communities,
493c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_sus_communities),
494c8f5c4c7SCristina Ciocan };
495c8f5c4c7SCristina Ciocan 
496c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_ncore_pins[] = {
497b30b736aSAndy Shevchenko 	PINCTRL_PIN(0, "HV_DDI0_HPD"),
498b30b736aSAndy Shevchenko 	PINCTRL_PIN(1, "HV_DDI0_DDC_SDA"),
499b30b736aSAndy Shevchenko 	PINCTRL_PIN(2, "HV_DDI0_DDC_SCL"),
500b30b736aSAndy Shevchenko 	PINCTRL_PIN(3, "PANEL0_VDDEN"),
501b30b736aSAndy Shevchenko 	PINCTRL_PIN(4, "PANEL0_BKLTEN"),
502b30b736aSAndy Shevchenko 	PINCTRL_PIN(5, "PANEL0_BKLTCTL"),
503b30b736aSAndy Shevchenko 	PINCTRL_PIN(6, "HV_DDI1_HPD"),
504b30b736aSAndy Shevchenko 	PINCTRL_PIN(7, "HV_DDI1_DDC_SDA"),
505b30b736aSAndy Shevchenko 	PINCTRL_PIN(8, "HV_DDI1_DDC_SCL"),
506b30b736aSAndy Shevchenko 	PINCTRL_PIN(9, "PANEL1_VDDEN"),
507b30b736aSAndy Shevchenko 	PINCTRL_PIN(10, "PANEL1_BKLTEN"),
508b30b736aSAndy Shevchenko 	PINCTRL_PIN(11, "PANEL1_BKLTCTL"),
509b30b736aSAndy Shevchenko 	PINCTRL_PIN(12, "GP_INTD_DSI_TE1"),
510b30b736aSAndy Shevchenko 	PINCTRL_PIN(13, "HV_DDI2_DDC_SDA"),
511b30b736aSAndy Shevchenko 	PINCTRL_PIN(14, "HV_DDI2_DDC_SCL"),
512b30b736aSAndy Shevchenko 	PINCTRL_PIN(15, "GP_CAMERASB00"),
513b30b736aSAndy Shevchenko 	PINCTRL_PIN(16, "GP_CAMERASB01"),
514b30b736aSAndy Shevchenko 	PINCTRL_PIN(17, "GP_CAMERASB02"),
515b30b736aSAndy Shevchenko 	PINCTRL_PIN(18, "GP_CAMERASB03"),
516b30b736aSAndy Shevchenko 	PINCTRL_PIN(19, "GP_CAMERASB04"),
517b30b736aSAndy Shevchenko 	PINCTRL_PIN(20, "GP_CAMERASB05"),
518b30b736aSAndy Shevchenko 	PINCTRL_PIN(21, "GP_CAMERASB06"),
519b30b736aSAndy Shevchenko 	PINCTRL_PIN(22, "GP_CAMERASB07"),
520b30b736aSAndy Shevchenko 	PINCTRL_PIN(23, "GP_CAMERASB08"),
521b30b736aSAndy Shevchenko 	PINCTRL_PIN(24, "GP_CAMERASB09"),
522b30b736aSAndy Shevchenko 	PINCTRL_PIN(25, "GP_CAMERASB10"),
523b30b736aSAndy Shevchenko 	PINCTRL_PIN(26, "GP_CAMERASB11"),
524b30b736aSAndy Shevchenko 	PINCTRL_PIN(27, "GP_INTD_DSI_TE2"),
525c8f5c4c7SCristina Ciocan };
526c8f5c4c7SCristina Ciocan 
527939330d7SAndy Shevchenko static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
528c8f5c4c7SCristina Ciocan 	19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
529c8f5c4c7SCristina Ciocan 	14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
530c8f5c4c7SCristina Ciocan 	3, 6, 10, 13, 2, 5, 9, 7,
531c8f5c4c7SCristina Ciocan };
532c8f5c4c7SCristina Ciocan 
53334e65670SAndy Shevchenko static const struct intel_community byt_ncore_communities[] = {
534c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
535c8f5c4c7SCristina Ciocan };
536c8f5c4c7SCristina Ciocan 
53734e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_ncore_soc_data = {
538c8f5c4c7SCristina Ciocan 	.uid		= BYT_NCORE_ACPI_UID,
539c8f5c4c7SCristina Ciocan 	.pins		= byt_ncore_pins,
540c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_ncore_pins),
541c8f5c4c7SCristina Ciocan 	.communities	= byt_ncore_communities,
542c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_ncore_communities),
543c8f5c4c7SCristina Ciocan };
544c8f5c4c7SCristina Ciocan 
54534e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data *byt_soc_data[] = {
546c8f5c4c7SCristina Ciocan 	&byt_score_soc_data,
547c8f5c4c7SCristina Ciocan 	&byt_sus_soc_data,
548c8f5c4c7SCristina Ciocan 	&byt_ncore_soc_data,
549166d6e2aSAndy Shevchenko 	NULL
550c8f5c4c7SCristina Ciocan };
551c8f5c4c7SCristina Ciocan 
55240ecab55SHans de Goede static DEFINE_RAW_SPINLOCK(byt_lock);
55340ecab55SHans de Goede 
5545d33e0ebSAndy Shevchenko static struct intel_community *byt_get_community(struct intel_pinctrl *vg,
555c501d0b1SCristina Ciocan 						 unsigned int pin)
556c501d0b1SCristina Ciocan {
55734e65670SAndy Shevchenko 	struct intel_community *comm;
558c501d0b1SCristina Ciocan 	int i;
559c501d0b1SCristina Ciocan 
5605d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->ncommunities; i++) {
5615d33e0ebSAndy Shevchenko 		comm = vg->communities + i;
562c501d0b1SCristina Ciocan 		if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base)
563c501d0b1SCristina Ciocan 			return comm;
564c501d0b1SCristina Ciocan 	}
565c501d0b1SCristina Ciocan 
566c501d0b1SCristina Ciocan 	return NULL;
567c501d0b1SCristina Ciocan }
568c501d0b1SCristina Ciocan 
5695d33e0ebSAndy Shevchenko static void __iomem *byt_gpio_reg(struct intel_pinctrl *vg, unsigned int offset,
5705fae8b86SMika Westerberg 				  int reg)
5715fae8b86SMika Westerberg {
57234e65670SAndy Shevchenko 	struct intel_community *comm = byt_get_community(vg, offset);
5731b89970dSAndy Shevchenko 	u32 reg_offset;
5745fae8b86SMika Westerberg 
575c501d0b1SCristina Ciocan 	if (!comm)
576c501d0b1SCristina Ciocan 		return NULL;
577c501d0b1SCristina Ciocan 
578c501d0b1SCristina Ciocan 	offset -= comm->pin_base;
5791b89970dSAndy Shevchenko 	switch (reg) {
5801b89970dSAndy Shevchenko 	case BYT_INT_STAT_REG:
5815fae8b86SMika Westerberg 		reg_offset = (offset / 32) * 4;
5821b89970dSAndy Shevchenko 		break;
5831b89970dSAndy Shevchenko 	case BYT_DEBOUNCE_REG:
5841b89970dSAndy Shevchenko 		reg_offset = 0;
5851b89970dSAndy Shevchenko 		break;
5861b89970dSAndy Shevchenko 	default:
587c501d0b1SCristina Ciocan 		reg_offset = comm->pad_map[offset] * 16;
5881b89970dSAndy Shevchenko 		break;
5891b89970dSAndy Shevchenko 	}
5905fae8b86SMika Westerberg 
59134e65670SAndy Shevchenko 	return comm->pad_regs + reg_offset + reg;
5925fae8b86SMika Westerberg }
5935fae8b86SMika Westerberg 
594c501d0b1SCristina Ciocan static int byt_get_groups_count(struct pinctrl_dev *pctldev)
59595f0972cSMika Westerberg {
5965d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
597c501d0b1SCristina Ciocan 
5985d33e0ebSAndy Shevchenko 	return vg->soc->ngroups;
599c501d0b1SCristina Ciocan }
600c501d0b1SCristina Ciocan 
601c501d0b1SCristina Ciocan static const char *byt_get_group_name(struct pinctrl_dev *pctldev,
602c501d0b1SCristina Ciocan 				      unsigned int selector)
603c501d0b1SCristina Ciocan {
6045d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
605c501d0b1SCristina Ciocan 
606770f53d4SAndy Shevchenko 	return vg->soc->groups[selector].grp.name;
607c501d0b1SCristina Ciocan }
608c501d0b1SCristina Ciocan 
609c501d0b1SCristina Ciocan static int byt_get_group_pins(struct pinctrl_dev *pctldev,
610c501d0b1SCristina Ciocan 			      unsigned int selector,
611c501d0b1SCristina Ciocan 			      const unsigned int **pins,
612c501d0b1SCristina Ciocan 			      unsigned int *num_pins)
613c501d0b1SCristina Ciocan {
6145d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
615c501d0b1SCristina Ciocan 
616770f53d4SAndy Shevchenko 	*pins		= vg->soc->groups[selector].grp.pins;
617770f53d4SAndy Shevchenko 	*num_pins	= vg->soc->groups[selector].grp.npins;
618c501d0b1SCristina Ciocan 
619c501d0b1SCristina Ciocan 	return 0;
620c501d0b1SCristina Ciocan }
621c501d0b1SCristina Ciocan 
622c501d0b1SCristina Ciocan static const struct pinctrl_ops byt_pinctrl_ops = {
623c501d0b1SCristina Ciocan 	.get_groups_count	= byt_get_groups_count,
624c501d0b1SCristina Ciocan 	.get_group_name		= byt_get_group_name,
625c501d0b1SCristina Ciocan 	.get_group_pins		= byt_get_group_pins,
626c501d0b1SCristina Ciocan };
627c501d0b1SCristina Ciocan 
628c501d0b1SCristina Ciocan static int byt_get_functions_count(struct pinctrl_dev *pctldev)
629c501d0b1SCristina Ciocan {
6305d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
631c501d0b1SCristina Ciocan 
6325d33e0ebSAndy Shevchenko 	return vg->soc->nfunctions;
633c501d0b1SCristina Ciocan }
634c501d0b1SCristina Ciocan 
635c501d0b1SCristina Ciocan static const char *byt_get_function_name(struct pinctrl_dev *pctldev,
636c501d0b1SCristina Ciocan 					 unsigned int selector)
637c501d0b1SCristina Ciocan {
6385d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
639c501d0b1SCristina Ciocan 
640988ac1a4SAndy Shevchenko 	return vg->soc->functions[selector].func.name;
641c501d0b1SCristina Ciocan }
642c501d0b1SCristina Ciocan 
643c501d0b1SCristina Ciocan static int byt_get_function_groups(struct pinctrl_dev *pctldev,
644c501d0b1SCristina Ciocan 				   unsigned int selector,
645c501d0b1SCristina Ciocan 				   const char * const **groups,
646988ac1a4SAndy Shevchenko 				   unsigned int *ngroups)
647c501d0b1SCristina Ciocan {
6485d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
649c501d0b1SCristina Ciocan 
650988ac1a4SAndy Shevchenko 	*groups		= vg->soc->functions[selector].func.groups;
651988ac1a4SAndy Shevchenko 	*ngroups	= vg->soc->functions[selector].func.ngroups;
652c501d0b1SCristina Ciocan 
653c501d0b1SCristina Ciocan 	return 0;
654c501d0b1SCristina Ciocan }
655c501d0b1SCristina Ciocan 
6565d33e0ebSAndy Shevchenko static void byt_set_group_simple_mux(struct intel_pinctrl *vg,
6574f010b93SAndy Shevchenko 				     const struct intel_pingroup group,
6584f010b93SAndy Shevchenko 				     unsigned int func)
659c501d0b1SCristina Ciocan {
660c501d0b1SCristina Ciocan 	unsigned long flags;
661c501d0b1SCristina Ciocan 	int i;
662c501d0b1SCristina Ciocan 
66340ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
664c501d0b1SCristina Ciocan 
665770f53d4SAndy Shevchenko 	for (i = 0; i < group.grp.npins; i++) {
666c501d0b1SCristina Ciocan 		void __iomem *padcfg0;
667c501d0b1SCristina Ciocan 		u32 value;
668c501d0b1SCristina Ciocan 
669770f53d4SAndy Shevchenko 		padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG);
670c501d0b1SCristina Ciocan 		if (!padcfg0) {
671b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Group %s, pin %i not muxed (can't retrieve CONF0)\n",
672770f53d4SAndy Shevchenko 				 group.grp.name, i);
673c501d0b1SCristina Ciocan 			continue;
674c501d0b1SCristina Ciocan 		}
675c501d0b1SCristina Ciocan 
676c501d0b1SCristina Ciocan 		value = readl(padcfg0);
677c501d0b1SCristina Ciocan 		value &= ~BYT_PIN_MUX;
678c501d0b1SCristina Ciocan 		value |= func;
679c501d0b1SCristina Ciocan 		writel(value, padcfg0);
680c501d0b1SCristina Ciocan 	}
681c501d0b1SCristina Ciocan 
68240ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
683c501d0b1SCristina Ciocan }
684c501d0b1SCristina Ciocan 
6855d33e0ebSAndy Shevchenko static void byt_set_group_mixed_mux(struct intel_pinctrl *vg,
6864f010b93SAndy Shevchenko 				    const struct intel_pingroup group,
6874f010b93SAndy Shevchenko 				    const unsigned int *func)
688c501d0b1SCristina Ciocan {
689c501d0b1SCristina Ciocan 	unsigned long flags;
690c501d0b1SCristina Ciocan 	int i;
691c501d0b1SCristina Ciocan 
69240ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
693c501d0b1SCristina Ciocan 
694770f53d4SAndy Shevchenko 	for (i = 0; i < group.grp.npins; i++) {
695c501d0b1SCristina Ciocan 		void __iomem *padcfg0;
696c501d0b1SCristina Ciocan 		u32 value;
697c501d0b1SCristina Ciocan 
698770f53d4SAndy Shevchenko 		padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG);
699c501d0b1SCristina Ciocan 		if (!padcfg0) {
700b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Group %s, pin %i not muxed (can't retrieve CONF0)\n",
701770f53d4SAndy Shevchenko 				 group.grp.name, i);
702c501d0b1SCristina Ciocan 			continue;
703c501d0b1SCristina Ciocan 		}
704c501d0b1SCristina Ciocan 
705c501d0b1SCristina Ciocan 		value = readl(padcfg0);
706c501d0b1SCristina Ciocan 		value &= ~BYT_PIN_MUX;
707c501d0b1SCristina Ciocan 		value |= func[i];
708c501d0b1SCristina Ciocan 		writel(value, padcfg0);
709c501d0b1SCristina Ciocan 	}
710c501d0b1SCristina Ciocan 
71140ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
712c501d0b1SCristina Ciocan }
713c501d0b1SCristina Ciocan 
714c501d0b1SCristina Ciocan static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
715c501d0b1SCristina Ciocan 		       unsigned int group_selector)
716c501d0b1SCristina Ciocan {
7175d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
7185d33e0ebSAndy Shevchenko 	const struct intel_function func = vg->soc->functions[func_selector];
7195d33e0ebSAndy Shevchenko 	const struct intel_pingroup group = vg->soc->groups[group_selector];
720c501d0b1SCristina Ciocan 
7214f010b93SAndy Shevchenko 	if (group.modes)
7224f010b93SAndy Shevchenko 		byt_set_group_mixed_mux(vg, group, group.modes);
723988ac1a4SAndy Shevchenko 	else if (!strcmp(func.func.name, "gpio"))
724c501d0b1SCristina Ciocan 		byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX);
725c501d0b1SCristina Ciocan 	else
7264f010b93SAndy Shevchenko 		byt_set_group_simple_mux(vg, group, group.mode);
727c501d0b1SCristina Ciocan 
728c501d0b1SCristina Ciocan 	return 0;
729c501d0b1SCristina Ciocan }
730c501d0b1SCristina Ciocan 
7315d33e0ebSAndy Shevchenko static u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset)
732c501d0b1SCristina Ciocan {
733c501d0b1SCristina Ciocan 	/* SCORE pin 92-93 */
7345d33e0ebSAndy Shevchenko 	if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) &&
735c501d0b1SCristina Ciocan 	    offset >= 92 && offset <= 93)
736a705f9c1SAndy Shevchenko 		return BYT_ALTER_GPIO_MUX;
737c501d0b1SCristina Ciocan 
738c501d0b1SCristina Ciocan 	/* SUS pin 11-21 */
7395d33e0ebSAndy Shevchenko 	if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) &&
740c501d0b1SCristina Ciocan 	    offset >= 11 && offset <= 21)
741a705f9c1SAndy Shevchenko 		return BYT_ALTER_GPIO_MUX;
742c501d0b1SCristina Ciocan 
743a705f9c1SAndy Shevchenko 	return BYT_DEFAULT_GPIO_MUX;
744c501d0b1SCristina Ciocan }
745c501d0b1SCristina Ciocan 
7465d33e0ebSAndy Shevchenko static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset)
747c501d0b1SCristina Ciocan {
748c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
74995f0972cSMika Westerberg 	unsigned long flags;
75095f0972cSMika Westerberg 	u32 value;
75195f0972cSMika Westerberg 
75240ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
75395f0972cSMika Westerberg 	value = readl(reg);
754a2368059SHans de Goede 
755a2368059SHans de Goede 	/* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */
756a2368059SHans de Goede 	if (value & BYT_DIRECT_IRQ_EN)
757a2368059SHans de Goede 		/* nothing to do */ ;
758a2368059SHans de Goede 	else
75995f0972cSMika Westerberg 		value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
760a2368059SHans de Goede 
76195f0972cSMika Westerberg 	writel(value, reg);
76240ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
76395f0972cSMika Westerberg }
76495f0972cSMika Westerberg 
765c501d0b1SCristina Ciocan static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
766c501d0b1SCristina Ciocan 				   struct pinctrl_gpio_range *range,
767c501d0b1SCristina Ciocan 				   unsigned int offset)
7685fae8b86SMika Westerberg {
7695d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
770c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
771f8323b6bSMika Westerberg 	u32 value, gpio_mux;
77239ce8150SMika Westerberg 	unsigned long flags;
77339ce8150SMika Westerberg 
77440ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
7755fae8b86SMika Westerberg 
7765fae8b86SMika Westerberg 	/*
7775fae8b86SMika Westerberg 	 * In most cases, func pin mux 000 means GPIO function.
7785fae8b86SMika Westerberg 	 * But, some pins may have func pin mux 001 represents
779f8323b6bSMika Westerberg 	 * GPIO function.
780f8323b6bSMika Westerberg 	 *
781f8323b6bSMika Westerberg 	 * Because there are devices out there where some pins were not
782f8323b6bSMika Westerberg 	 * configured correctly we allow changing the mux value from
783f8323b6bSMika Westerberg 	 * request (but print out warning about that).
7845fae8b86SMika Westerberg 	 */
7855fae8b86SMika Westerberg 	value = readl(reg) & BYT_PIN_MUX;
786f8323b6bSMika Westerberg 	gpio_mux = byt_get_gpio_mux(vg, offset);
787b5894d12SHans de Goede 	if (gpio_mux != value) {
788f8323b6bSMika Westerberg 		value = readl(reg) & ~BYT_PIN_MUX;
789f8323b6bSMika Westerberg 		value |= gpio_mux;
790f8323b6bSMika Westerberg 		writel(value, reg);
791f8323b6bSMika Westerberg 
792b9e18434SAndy Shevchenko 		dev_warn(vg->dev, FW_BUG "Pin %i: forcibly re-configured as GPIO\n", offset);
7935fae8b86SMika Westerberg 	}
7945fae8b86SMika Westerberg 
79540ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
79639ce8150SMika Westerberg 
797990ec243SAndy Shevchenko 	pm_runtime_get(vg->dev);
7985fae8b86SMika Westerberg 
7995fae8b86SMika Westerberg 	return 0;
8005fae8b86SMika Westerberg }
8015fae8b86SMika Westerberg 
802c501d0b1SCristina Ciocan static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
803c501d0b1SCristina Ciocan 				  struct pinctrl_gpio_range *range,
804c501d0b1SCristina Ciocan 				  unsigned int offset)
805c501d0b1SCristina Ciocan {
8065d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
807c501d0b1SCristina Ciocan 
808c501d0b1SCristina Ciocan 	byt_gpio_clear_triggering(vg, offset);
809990ec243SAndy Shevchenko 	pm_runtime_put(vg->dev);
810c501d0b1SCristina Ciocan }
811c501d0b1SCristina Ciocan 
812156abe29SHans de Goede static void byt_gpio_direct_irq_check(struct intel_pinctrl *vg,
813156abe29SHans de Goede 				      unsigned int offset)
814156abe29SHans de Goede {
815156abe29SHans de Goede 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
816156abe29SHans de Goede 
817156abe29SHans de Goede 	/*
818156abe29SHans de Goede 	 * Before making any direction modifications, do a check if gpio is set
819156abe29SHans de Goede 	 * for direct IRQ. On Bay Trail, setting GPIO to output does not make
820156abe29SHans de Goede 	 * sense, so let's at least inform the caller before they shoot
821156abe29SHans de Goede 	 * themselves in the foot.
822156abe29SHans de Goede 	 */
823156abe29SHans de Goede 	if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
824b9e18434SAndy Shevchenko 		dev_info_once(vg->dev,
825b9e18434SAndy Shevchenko 			      "Potential Error: Pin %i: forcibly set GPIO with DIRECT_IRQ_EN to output\n",
826b9e18434SAndy Shevchenko 			      offset);
827156abe29SHans de Goede }
828156abe29SHans de Goede 
829c501d0b1SCristina Ciocan static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
830c501d0b1SCristina Ciocan 				  struct pinctrl_gpio_range *range,
831c501d0b1SCristina Ciocan 				  unsigned int offset,
832c501d0b1SCristina Ciocan 				  bool input)
833c501d0b1SCristina Ciocan {
8345d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
835c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
836c501d0b1SCristina Ciocan 	unsigned long flags;
837c501d0b1SCristina Ciocan 	u32 value;
838c501d0b1SCristina Ciocan 
83940ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
840c501d0b1SCristina Ciocan 
841c501d0b1SCristina Ciocan 	value = readl(val_reg);
842c501d0b1SCristina Ciocan 	value &= ~BYT_DIR_MASK;
843c501d0b1SCristina Ciocan 	if (input)
844c501d0b1SCristina Ciocan 		value |= BYT_OUTPUT_EN;
845156abe29SHans de Goede 	else
846156abe29SHans de Goede 		byt_gpio_direct_irq_check(vg, offset);
847e2b74419SHans de Goede 
848c501d0b1SCristina Ciocan 	writel(value, val_reg);
849c501d0b1SCristina Ciocan 
85040ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
851c501d0b1SCristina Ciocan 
852c501d0b1SCristina Ciocan 	return 0;
853c501d0b1SCristina Ciocan }
854c501d0b1SCristina Ciocan 
855c501d0b1SCristina Ciocan static const struct pinmux_ops byt_pinmux_ops = {
856c501d0b1SCristina Ciocan 	.get_functions_count	= byt_get_functions_count,
857c501d0b1SCristina Ciocan 	.get_function_name	= byt_get_function_name,
858c501d0b1SCristina Ciocan 	.get_function_groups	= byt_get_function_groups,
859c501d0b1SCristina Ciocan 	.set_mux		= byt_set_mux,
860c501d0b1SCristina Ciocan 	.gpio_request_enable	= byt_gpio_request_enable,
861c501d0b1SCristina Ciocan 	.gpio_disable_free	= byt_gpio_disable_free,
862c501d0b1SCristina Ciocan 	.gpio_set_direction	= byt_gpio_set_direction,
863c501d0b1SCristina Ciocan };
864c501d0b1SCristina Ciocan 
865c501d0b1SCristina Ciocan static void byt_get_pull_strength(u32 reg, u16 *strength)
866c501d0b1SCristina Ciocan {
867c501d0b1SCristina Ciocan 	switch (reg & BYT_PULL_STR_MASK) {
868c501d0b1SCristina Ciocan 	case BYT_PULL_STR_2K:
869c501d0b1SCristina Ciocan 		*strength = 2000;
870c501d0b1SCristina Ciocan 		break;
871c501d0b1SCristina Ciocan 	case BYT_PULL_STR_10K:
872c501d0b1SCristina Ciocan 		*strength = 10000;
873c501d0b1SCristina Ciocan 		break;
874c501d0b1SCristina Ciocan 	case BYT_PULL_STR_20K:
875c501d0b1SCristina Ciocan 		*strength = 20000;
876c501d0b1SCristina Ciocan 		break;
877c501d0b1SCristina Ciocan 	case BYT_PULL_STR_40K:
878c501d0b1SCristina Ciocan 		*strength = 40000;
879c501d0b1SCristina Ciocan 		break;
880c501d0b1SCristina Ciocan 	}
881c501d0b1SCristina Ciocan }
882c501d0b1SCristina Ciocan 
883c501d0b1SCristina Ciocan static int byt_set_pull_strength(u32 *reg, u16 strength)
884c501d0b1SCristina Ciocan {
885c501d0b1SCristina Ciocan 	*reg &= ~BYT_PULL_STR_MASK;
886c501d0b1SCristina Ciocan 
887c501d0b1SCristina Ciocan 	switch (strength) {
888c501d0b1SCristina Ciocan 	case 2000:
889c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_2K;
890c501d0b1SCristina Ciocan 		break;
891c501d0b1SCristina Ciocan 	case 10000:
892c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_10K;
893c501d0b1SCristina Ciocan 		break;
894c501d0b1SCristina Ciocan 	case 20000:
895c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_20K;
896c501d0b1SCristina Ciocan 		break;
897c501d0b1SCristina Ciocan 	case 40000:
898c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_40K;
899c501d0b1SCristina Ciocan 		break;
900c501d0b1SCristina Ciocan 	default:
901c501d0b1SCristina Ciocan 		return -EINVAL;
902c501d0b1SCristina Ciocan 	}
903c501d0b1SCristina Ciocan 
904c501d0b1SCristina Ciocan 	return 0;
905c501d0b1SCristina Ciocan }
906c501d0b1SCristina Ciocan 
907c501d0b1SCristina Ciocan static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
908c501d0b1SCristina Ciocan 			      unsigned long *config)
909c501d0b1SCristina Ciocan {
9105d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
911c501d0b1SCristina Ciocan 	enum pin_config_param param = pinconf_to_config_param(*config);
912c501d0b1SCristina Ciocan 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
913c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
91404ff5a09SAndy Shevchenko 	void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
915c501d0b1SCristina Ciocan 	unsigned long flags;
916658b476cSCristina Ciocan 	u32 conf, pull, val, debounce;
917c501d0b1SCristina Ciocan 	u16 arg = 0;
918c501d0b1SCristina Ciocan 
91940ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
920c501d0b1SCristina Ciocan 	conf = readl(conf_reg);
921c501d0b1SCristina Ciocan 	pull = conf & BYT_PULL_ASSIGN_MASK;
922c501d0b1SCristina Ciocan 	val = readl(val_reg);
92340ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
924c501d0b1SCristina Ciocan 
925c501d0b1SCristina Ciocan 	switch (param) {
926c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_DISABLE:
927c501d0b1SCristina Ciocan 		if (pull)
928c501d0b1SCristina Ciocan 			return -EINVAL;
929c501d0b1SCristina Ciocan 		break;
930c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_PULL_DOWN:
931c501d0b1SCristina Ciocan 		/* Pull assignment is only applicable in input mode */
932c501d0b1SCristina Ciocan 		if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN)
933c501d0b1SCristina Ciocan 			return -EINVAL;
934c501d0b1SCristina Ciocan 
935c501d0b1SCristina Ciocan 		byt_get_pull_strength(conf, &arg);
936c501d0b1SCristina Ciocan 
937c501d0b1SCristina Ciocan 		break;
938c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_PULL_UP:
939c501d0b1SCristina Ciocan 		/* Pull assignment is only applicable in input mode */
940c501d0b1SCristina Ciocan 		if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP)
941c501d0b1SCristina Ciocan 			return -EINVAL;
942c501d0b1SCristina Ciocan 
943c501d0b1SCristina Ciocan 		byt_get_pull_strength(conf, &arg);
944c501d0b1SCristina Ciocan 
945c501d0b1SCristina Ciocan 		break;
946658b476cSCristina Ciocan 	case PIN_CONFIG_INPUT_DEBOUNCE:
947658b476cSCristina Ciocan 		if (!(conf & BYT_DEBOUNCE_EN))
948658b476cSCristina Ciocan 			return -EINVAL;
949658b476cSCristina Ciocan 
95040ecab55SHans de Goede 		raw_spin_lock_irqsave(&byt_lock, flags);
95104ff5a09SAndy Shevchenko 		debounce = readl(db_reg);
95240ecab55SHans de Goede 		raw_spin_unlock_irqrestore(&byt_lock, flags);
953658b476cSCristina Ciocan 
954658b476cSCristina Ciocan 		switch (debounce & BYT_DEBOUNCE_PULSE_MASK) {
955658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_375US:
956658b476cSCristina Ciocan 			arg = 375;
957658b476cSCristina Ciocan 			break;
958658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_750US:
959658b476cSCristina Ciocan 			arg = 750;
960658b476cSCristina Ciocan 			break;
961658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_1500US:
962658b476cSCristina Ciocan 			arg = 1500;
963658b476cSCristina Ciocan 			break;
964658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_3MS:
965658b476cSCristina Ciocan 			arg = 3000;
966658b476cSCristina Ciocan 			break;
967658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_6MS:
968658b476cSCristina Ciocan 			arg = 6000;
969658b476cSCristina Ciocan 			break;
970658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_12MS:
971658b476cSCristina Ciocan 			arg = 12000;
972658b476cSCristina Ciocan 			break;
973658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_24MS:
974658b476cSCristina Ciocan 			arg = 24000;
975658b476cSCristina Ciocan 			break;
976658b476cSCristina Ciocan 		default:
977658b476cSCristina Ciocan 			return -EINVAL;
978658b476cSCristina Ciocan 		}
979658b476cSCristina Ciocan 
980658b476cSCristina Ciocan 		break;
981c501d0b1SCristina Ciocan 	default:
982c501d0b1SCristina Ciocan 		return -ENOTSUPP;
983c501d0b1SCristina Ciocan 	}
984c501d0b1SCristina Ciocan 
985c501d0b1SCristina Ciocan 	*config = pinconf_to_config_packed(param, arg);
986c501d0b1SCristina Ciocan 
987c501d0b1SCristina Ciocan 	return 0;
988c501d0b1SCristina Ciocan }
989c501d0b1SCristina Ciocan 
990c501d0b1SCristina Ciocan static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
991c501d0b1SCristina Ciocan 			      unsigned int offset,
992c501d0b1SCristina Ciocan 			      unsigned long *configs,
993c501d0b1SCristina Ciocan 			      unsigned int num_configs)
994c501d0b1SCristina Ciocan {
9955d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
996c501d0b1SCristina Ciocan 	unsigned int param, arg;
997c501d0b1SCristina Ciocan 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
998c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
99904ff5a09SAndy Shevchenko 	void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
1000c501d0b1SCristina Ciocan 	unsigned long flags;
1001658b476cSCristina Ciocan 	u32 conf, val, debounce;
1002c501d0b1SCristina Ciocan 	int i, ret = 0;
1003c501d0b1SCristina Ciocan 
100440ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
1005c501d0b1SCristina Ciocan 
1006c501d0b1SCristina Ciocan 	conf = readl(conf_reg);
1007c501d0b1SCristina Ciocan 	val = readl(val_reg);
1008c501d0b1SCristina Ciocan 
1009c501d0b1SCristina Ciocan 	for (i = 0; i < num_configs; i++) {
1010c501d0b1SCristina Ciocan 		param = pinconf_to_config_param(configs[i]);
1011c501d0b1SCristina Ciocan 		arg = pinconf_to_config_argument(configs[i]);
1012c501d0b1SCristina Ciocan 
1013c501d0b1SCristina Ciocan 		switch (param) {
1014c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_DISABLE:
1015c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
1016c501d0b1SCristina Ciocan 			break;
1017c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_PULL_DOWN:
1018c501d0b1SCristina Ciocan 			/* Set default strength value in case none is given */
1019c501d0b1SCristina Ciocan 			if (arg == 1)
1020c501d0b1SCristina Ciocan 				arg = 2000;
1021c501d0b1SCristina Ciocan 
1022c501d0b1SCristina Ciocan 			/*
1023c501d0b1SCristina Ciocan 			 * Pull assignment is only applicable in input mode. If
1024c501d0b1SCristina Ciocan 			 * chip is not in input mode, set it and warn about it.
1025c501d0b1SCristina Ciocan 			 */
1026c501d0b1SCristina Ciocan 			if (val & BYT_INPUT_EN) {
1027c501d0b1SCristina Ciocan 				val &= ~BYT_INPUT_EN;
1028c501d0b1SCristina Ciocan 				writel(val, val_reg);
1029b9e18434SAndy Shevchenko 				dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset);
1030c501d0b1SCristina Ciocan 			}
1031c501d0b1SCristina Ciocan 
1032c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
1033c501d0b1SCristina Ciocan 			conf |= BYT_PULL_ASSIGN_DOWN;
1034c501d0b1SCristina Ciocan 			ret = byt_set_pull_strength(&conf, arg);
1035c501d0b1SCristina Ciocan 
1036c501d0b1SCristina Ciocan 			break;
1037c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_PULL_UP:
1038c501d0b1SCristina Ciocan 			/* Set default strength value in case none is given */
1039c501d0b1SCristina Ciocan 			if (arg == 1)
1040c501d0b1SCristina Ciocan 				arg = 2000;
1041c501d0b1SCristina Ciocan 
1042c501d0b1SCristina Ciocan 			/*
1043c501d0b1SCristina Ciocan 			 * Pull assignment is only applicable in input mode. If
1044c501d0b1SCristina Ciocan 			 * chip is not in input mode, set it and warn about it.
1045c501d0b1SCristina Ciocan 			 */
1046c501d0b1SCristina Ciocan 			if (val & BYT_INPUT_EN) {
1047c501d0b1SCristina Ciocan 				val &= ~BYT_INPUT_EN;
1048c501d0b1SCristina Ciocan 				writel(val, val_reg);
1049b9e18434SAndy Shevchenko 				dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset);
1050c501d0b1SCristina Ciocan 			}
1051c501d0b1SCristina Ciocan 
1052c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
1053c501d0b1SCristina Ciocan 			conf |= BYT_PULL_ASSIGN_UP;
1054c501d0b1SCristina Ciocan 			ret = byt_set_pull_strength(&conf, arg);
1055c501d0b1SCristina Ciocan 
1056c501d0b1SCristina Ciocan 			break;
1057658b476cSCristina Ciocan 		case PIN_CONFIG_INPUT_DEBOUNCE:
105804ff5a09SAndy Shevchenko 			debounce = readl(db_reg);
1059658b476cSCristina Ciocan 
1060827e1579SAndy Shevchenko 			if (arg)
1061827e1579SAndy Shevchenko 				conf |= BYT_DEBOUNCE_EN;
1062827e1579SAndy Shevchenko 			else
1063827e1579SAndy Shevchenko 				conf &= ~BYT_DEBOUNCE_EN;
1064827e1579SAndy Shevchenko 
1065658b476cSCristina Ciocan 			switch (arg) {
1066658b476cSCristina Ciocan 			case 375:
10675f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
106804ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_375US;
1069658b476cSCristina Ciocan 				break;
1070658b476cSCristina Ciocan 			case 750:
10715f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
107204ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_750US;
1073658b476cSCristina Ciocan 				break;
1074658b476cSCristina Ciocan 			case 1500:
10755f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
107604ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_1500US;
1077658b476cSCristina Ciocan 				break;
1078658b476cSCristina Ciocan 			case 3000:
10795f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
108004ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_3MS;
1081658b476cSCristina Ciocan 				break;
1082658b476cSCristina Ciocan 			case 6000:
10835f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
108404ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_6MS;
1085658b476cSCristina Ciocan 				break;
1086658b476cSCristina Ciocan 			case 12000:
10875f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
108804ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_12MS;
1089658b476cSCristina Ciocan 				break;
1090658b476cSCristina Ciocan 			case 24000:
10915f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
109204ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_24MS;
1093658b476cSCristina Ciocan 				break;
1094658b476cSCristina Ciocan 			default:
1095827e1579SAndy Shevchenko 				if (arg)
1096658b476cSCristina Ciocan 					ret = -EINVAL;
1097827e1579SAndy Shevchenko 				break;
1098658b476cSCristina Ciocan 			}
1099658b476cSCristina Ciocan 
110004ff5a09SAndy Shevchenko 			if (!ret)
110104ff5a09SAndy Shevchenko 				writel(debounce, db_reg);
1102658b476cSCristina Ciocan 			break;
1103c501d0b1SCristina Ciocan 		default:
1104c501d0b1SCristina Ciocan 			ret = -ENOTSUPP;
1105c501d0b1SCristina Ciocan 		}
1106c501d0b1SCristina Ciocan 
1107c501d0b1SCristina Ciocan 		if (ret)
1108c501d0b1SCristina Ciocan 			break;
1109c501d0b1SCristina Ciocan 	}
1110c501d0b1SCristina Ciocan 
1111c501d0b1SCristina Ciocan 	if (!ret)
1112c501d0b1SCristina Ciocan 		writel(conf, conf_reg);
1113c501d0b1SCristina Ciocan 
111440ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1115c501d0b1SCristina Ciocan 
1116c501d0b1SCristina Ciocan 	return ret;
1117c501d0b1SCristina Ciocan }
1118c501d0b1SCristina Ciocan 
1119c501d0b1SCristina Ciocan static const struct pinconf_ops byt_pinconf_ops = {
1120c501d0b1SCristina Ciocan 	.is_generic	= true,
1121c501d0b1SCristina Ciocan 	.pin_config_get	= byt_pin_config_get,
1122c501d0b1SCristina Ciocan 	.pin_config_set	= byt_pin_config_set,
1123c501d0b1SCristina Ciocan };
1124c501d0b1SCristina Ciocan 
1125c501d0b1SCristina Ciocan static const struct pinctrl_desc byt_pinctrl_desc = {
1126c501d0b1SCristina Ciocan 	.pctlops	= &byt_pinctrl_ops,
1127c501d0b1SCristina Ciocan 	.pmxops		= &byt_pinmux_ops,
1128c501d0b1SCristina Ciocan 	.confops	= &byt_pinconf_ops,
1129c501d0b1SCristina Ciocan 	.owner		= THIS_MODULE,
1130c501d0b1SCristina Ciocan };
1131c501d0b1SCristina Ciocan 
1132939330d7SAndy Shevchenko static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset)
11335fae8b86SMika Westerberg {
11345d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1135c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
113639ce8150SMika Westerberg 	unsigned long flags;
113739ce8150SMika Westerberg 	u32 val;
113839ce8150SMika Westerberg 
113940ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
114039ce8150SMika Westerberg 	val = readl(reg);
114140ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
114239ce8150SMika Westerberg 
11433bde8771SLinus Walleij 	return !!(val & BYT_LEVEL);
11445fae8b86SMika Westerberg }
11455fae8b86SMika Westerberg 
1146939330d7SAndy Shevchenko static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
11475fae8b86SMika Westerberg {
11485d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1149c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
11505fae8b86SMika Westerberg 	unsigned long flags;
11515fae8b86SMika Westerberg 	u32 old_val;
11525fae8b86SMika Westerberg 
115386e3ef81SCristina Ciocan 	if (!reg)
115486e3ef81SCristina Ciocan 		return;
115586e3ef81SCristina Ciocan 
115640ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
11575fae8b86SMika Westerberg 	old_val = readl(reg);
11585fae8b86SMika Westerberg 	if (value)
11595fae8b86SMika Westerberg 		writel(old_val | BYT_LEVEL, reg);
11605fae8b86SMika Westerberg 	else
11615fae8b86SMika Westerberg 		writel(old_val & ~BYT_LEVEL, reg);
116240ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
11635fae8b86SMika Westerberg }
11645fae8b86SMika Westerberg 
116586e3ef81SCristina Ciocan static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
11665fae8b86SMika Westerberg {
11675d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1168c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
11695fae8b86SMika Westerberg 	unsigned long flags;
11705fae8b86SMika Westerberg 	u32 value;
11715fae8b86SMika Westerberg 
117286e3ef81SCristina Ciocan 	if (!reg)
117386e3ef81SCristina Ciocan 		return -EINVAL;
117486e3ef81SCristina Ciocan 
117540ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
117686e3ef81SCristina Ciocan 	value = readl(reg);
117740ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
11785fae8b86SMika Westerberg 
117986e3ef81SCristina Ciocan 	if (!(value & BYT_OUTPUT_EN))
1180faf86c0cSMatti Vaittinen 		return GPIO_LINE_DIRECTION_OUT;
118186e3ef81SCristina Ciocan 	if (!(value & BYT_INPUT_EN))
1182faf86c0cSMatti Vaittinen 		return GPIO_LINE_DIRECTION_IN;
118386e3ef81SCristina Ciocan 
118486e3ef81SCristina Ciocan 	return -EINVAL;
11855fae8b86SMika Westerberg }
11865fae8b86SMika Westerberg 
118786e3ef81SCristina Ciocan static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
11885fae8b86SMika Westerberg {
1189156abe29SHans de Goede 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1190156abe29SHans de Goede 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
1191156abe29SHans de Goede 	unsigned long flags;
1192156abe29SHans de Goede 	u32 reg;
1193156abe29SHans de Goede 
1194156abe29SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
1195156abe29SHans de Goede 
1196156abe29SHans de Goede 	reg = readl(val_reg);
1197156abe29SHans de Goede 	reg &= ~BYT_DIR_MASK;
1198156abe29SHans de Goede 	reg |= BYT_OUTPUT_EN;
1199156abe29SHans de Goede 	writel(reg, val_reg);
1200156abe29SHans de Goede 
1201156abe29SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1202156abe29SHans de Goede 	return 0;
120386e3ef81SCristina Ciocan }
12045fae8b86SMika Westerberg 
1205156abe29SHans de Goede /*
1206156abe29SHans de Goede  * Note despite the temptation this MUST NOT be converted into a call to
1207156abe29SHans de Goede  * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this
1208156abe29SHans de Goede  * MUST be done as a single BYT_VAL_REG register write.
1209156abe29SHans de Goede  * See the commit message of the commit adding this comment for details.
1210156abe29SHans de Goede  */
121186e3ef81SCristina Ciocan static int byt_gpio_direction_output(struct gpio_chip *chip,
121286e3ef81SCristina Ciocan 				     unsigned int offset, int value)
121386e3ef81SCristina Ciocan {
1214156abe29SHans de Goede 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1215156abe29SHans de Goede 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
1216156abe29SHans de Goede 	unsigned long flags;
1217156abe29SHans de Goede 	u32 reg;
12185fae8b86SMika Westerberg 
1219156abe29SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
122086e3ef81SCristina Ciocan 
1221156abe29SHans de Goede 	byt_gpio_direct_irq_check(vg, offset);
12225fae8b86SMika Westerberg 
1223156abe29SHans de Goede 	reg = readl(val_reg);
1224156abe29SHans de Goede 	reg &= ~BYT_DIR_MASK;
1225156abe29SHans de Goede 	if (value)
1226156abe29SHans de Goede 		reg |= BYT_LEVEL;
1227156abe29SHans de Goede 	else
1228156abe29SHans de Goede 		reg &= ~BYT_LEVEL;
1229156abe29SHans de Goede 
1230156abe29SHans de Goede 	writel(reg, val_reg);
1231156abe29SHans de Goede 
1232156abe29SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
12335fae8b86SMika Westerberg 	return 0;
12345fae8b86SMika Westerberg }
12355fae8b86SMika Westerberg 
12365fae8b86SMika Westerberg static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
12375fae8b86SMika Westerberg {
12385d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
12395fae8b86SMika Westerberg 	int i;
124086e3ef81SCristina Ciocan 	u32 conf0, val;
12415fae8b86SMika Westerberg 
12425d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
124334e65670SAndy Shevchenko 		const struct intel_community *comm;
12445a9fa4c2SRaag Jadav 		void __iomem *conf_reg, *val_reg;
12455fae8b86SMika Westerberg 		const char *pull_str = NULL;
12465fae8b86SMika Westerberg 		const char *pull = NULL;
124778e1c896SMika Westerberg 		unsigned long flags;
12485fae8b86SMika Westerberg 		const char *label;
124986e3ef81SCristina Ciocan 		unsigned int pin;
125078e1c896SMika Westerberg 
12515d33e0ebSAndy Shevchenko 		pin = vg->soc->pins[i].number;
125286e3ef81SCristina Ciocan 
12535a9fa4c2SRaag Jadav 		conf_reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
12545a9fa4c2SRaag Jadav 		if (!conf_reg) {
12555a9fa4c2SRaag Jadav 			seq_printf(s, "Pin %i: can't retrieve CONF0\n", pin);
125622bbd21bSDan Carpenter 			continue;
125786e3ef81SCristina Ciocan 		}
12585a9fa4c2SRaag Jadav 
12595a9fa4c2SRaag Jadav 		val_reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
12605a9fa4c2SRaag Jadav 		if (!val_reg) {
12615a9fa4c2SRaag Jadav 			seq_printf(s, "Pin %i: can't retrieve VAL\n", pin);
12625a9fa4c2SRaag Jadav 			continue;
12635a9fa4c2SRaag Jadav 		}
12645a9fa4c2SRaag Jadav 
12655a9fa4c2SRaag Jadav 		raw_spin_lock_irqsave(&byt_lock, flags);
12665a9fa4c2SRaag Jadav 		conf0 = readl(conf_reg);
12675a9fa4c2SRaag Jadav 		val = readl(val_reg);
126840ecab55SHans de Goede 		raw_spin_unlock_irqrestore(&byt_lock, flags);
12695fae8b86SMika Westerberg 
127086e3ef81SCristina Ciocan 		comm = byt_get_community(vg, pin);
127186e3ef81SCristina Ciocan 		if (!comm) {
1272b9e18434SAndy Shevchenko 			seq_printf(s, "Pin %i: can't retrieve community\n", pin);
127386e3ef81SCristina Ciocan 			continue;
127486e3ef81SCristina Ciocan 		}
12755fae8b86SMika Westerberg 		label = gpiochip_is_requested(chip, i);
12765fae8b86SMika Westerberg 		if (!label)
12775fae8b86SMika Westerberg 			label = "Unrequested";
12785fae8b86SMika Westerberg 
12795fae8b86SMika Westerberg 		switch (conf0 & BYT_PULL_ASSIGN_MASK) {
12805fae8b86SMika Westerberg 		case BYT_PULL_ASSIGN_UP:
12815fae8b86SMika Westerberg 			pull = "up";
12825fae8b86SMika Westerberg 			break;
12835fae8b86SMika Westerberg 		case BYT_PULL_ASSIGN_DOWN:
12845fae8b86SMika Westerberg 			pull = "down";
12855fae8b86SMika Westerberg 			break;
12865fae8b86SMika Westerberg 		}
12875fae8b86SMika Westerberg 
12885fae8b86SMika Westerberg 		switch (conf0 & BYT_PULL_STR_MASK) {
12895fae8b86SMika Westerberg 		case BYT_PULL_STR_2K:
12905fae8b86SMika Westerberg 			pull_str = "2k";
12915fae8b86SMika Westerberg 			break;
12925fae8b86SMika Westerberg 		case BYT_PULL_STR_10K:
12935fae8b86SMika Westerberg 			pull_str = "10k";
12945fae8b86SMika Westerberg 			break;
12955fae8b86SMika Westerberg 		case BYT_PULL_STR_20K:
12965fae8b86SMika Westerberg 			pull_str = "20k";
12975fae8b86SMika Westerberg 			break;
12985fae8b86SMika Westerberg 		case BYT_PULL_STR_40K:
12995fae8b86SMika Westerberg 			pull_str = "40k";
13005fae8b86SMika Westerberg 			break;
13015fae8b86SMika Westerberg 		}
13025fae8b86SMika Westerberg 
13035fae8b86SMika Westerberg 		seq_printf(s,
13045fae8b86SMika Westerberg 			   " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
130586e3ef81SCristina Ciocan 			   pin,
13065fae8b86SMika Westerberg 			   label,
13075fae8b86SMika Westerberg 			   val & BYT_INPUT_EN ? "  " : "in",
13085fae8b86SMika Westerberg 			   val & BYT_OUTPUT_EN ? "   " : "out",
1309c518d31bSAndy Shevchenko 			   str_hi_lo(val & BYT_LEVEL),
13103655a1caSAlexander Stein 			   comm->pad_map[i], comm->pad_map[i] * 16,
13115fae8b86SMika Westerberg 			   conf0 & 0x7,
13125fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_NEG ? " fall" : "     ",
13135fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_POS ? " rise" : "     ",
13145fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_LVL ? " level" : "      ");
13155fae8b86SMika Westerberg 
13165fae8b86SMika Westerberg 		if (pull && pull_str)
13175fae8b86SMika Westerberg 			seq_printf(s, " %-4s %-3s", pull, pull_str);
13185fae8b86SMika Westerberg 		else
13195fae8b86SMika Westerberg 			seq_puts(s, "          ");
13205fae8b86SMika Westerberg 
13215fae8b86SMika Westerberg 		if (conf0 & BYT_IODEN)
13225fae8b86SMika Westerberg 			seq_puts(s, " open-drain");
13235fae8b86SMika Westerberg 
13245fae8b86SMika Westerberg 		seq_puts(s, "\n");
13255fae8b86SMika Westerberg 	}
13265fae8b86SMika Westerberg }
13275fae8b86SMika Westerberg 
132886e3ef81SCristina Ciocan static const struct gpio_chip byt_gpio_chip = {
132986e3ef81SCristina Ciocan 	.owner			= THIS_MODULE,
133086e3ef81SCristina Ciocan 	.request		= gpiochip_generic_request,
133186e3ef81SCristina Ciocan 	.free			= gpiochip_generic_free,
133286e3ef81SCristina Ciocan 	.get_direction		= byt_gpio_get_direction,
133386e3ef81SCristina Ciocan 	.direction_input	= byt_gpio_direction_input,
133486e3ef81SCristina Ciocan 	.direction_output	= byt_gpio_direction_output,
133586e3ef81SCristina Ciocan 	.get			= byt_gpio_get,
133686e3ef81SCristina Ciocan 	.set			= byt_gpio_set,
1337ccd025eaSAndy Shevchenko 	.set_config		= gpiochip_generic_config,
133886e3ef81SCristina Ciocan 	.dbg_show		= byt_gpio_dbg_show,
133986e3ef81SCristina Ciocan };
134086e3ef81SCristina Ciocan 
134131e4329fSMika Westerberg static void byt_irq_ack(struct irq_data *d)
134231e4329fSMika Westerberg {
134331e4329fSMika Westerberg 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
13445d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(gc);
13456d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
134631e4329fSMika Westerberg 	void __iomem *reg;
134731e4329fSMika Westerberg 
13486d209b42SAndy Shevchenko 	reg = byt_gpio_reg(vg, hwirq, BYT_INT_STAT_REG);
13499f573b98SCristina Ciocan 	if (!reg)
13509f573b98SCristina Ciocan 		return;
13519f573b98SCristina Ciocan 
135240ecab55SHans de Goede 	raw_spin_lock(&byt_lock);
13536d209b42SAndy Shevchenko 	writel(BIT(hwirq % 32), reg);
135440ecab55SHans de Goede 	raw_spin_unlock(&byt_lock);
135531e4329fSMika Westerberg }
135631e4329fSMika Westerberg 
13579f573b98SCristina Ciocan static void byt_irq_mask(struct irq_data *d)
13589f573b98SCristina Ciocan {
13599f573b98SCristina Ciocan 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
13605d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(gc);
13616d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
13629f573b98SCristina Ciocan 
13636d209b42SAndy Shevchenko 	byt_gpio_clear_triggering(vg, hwirq);
13646d209b42SAndy Shevchenko 	gpiochip_disable_irq(gc, hwirq);
13659f573b98SCristina Ciocan }
13669f573b98SCristina Ciocan 
13675fae8b86SMika Westerberg static void byt_irq_unmask(struct irq_data *d)
13685fae8b86SMika Westerberg {
136931e4329fSMika Westerberg 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
13705d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(gc);
13716d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
137231e4329fSMika Westerberg 	unsigned long flags;
137331e4329fSMika Westerberg 	void __iomem *reg;
137431e4329fSMika Westerberg 	u32 value;
137531e4329fSMika Westerberg 
13766d209b42SAndy Shevchenko 	gpiochip_enable_irq(gc, hwirq);
13776d209b42SAndy Shevchenko 
13786d209b42SAndy Shevchenko 	reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG);
13799f573b98SCristina Ciocan 	if (!reg)
13809f573b98SCristina Ciocan 		return;
138178e1c896SMika Westerberg 
138240ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
138331e4329fSMika Westerberg 	value = readl(reg);
138431e4329fSMika Westerberg 
138531e4329fSMika Westerberg 	switch (irqd_get_trigger_type(d)) {
138631e4329fSMika Westerberg 	case IRQ_TYPE_LEVEL_HIGH:
138731e4329fSMika Westerberg 		value |= BYT_TRIG_LVL;
13880a093020SGustavo A. R. Silva 		fallthrough;
138931e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_RISING:
139031e4329fSMika Westerberg 		value |= BYT_TRIG_POS;
139131e4329fSMika Westerberg 		break;
139231e4329fSMika Westerberg 	case IRQ_TYPE_LEVEL_LOW:
139331e4329fSMika Westerberg 		value |= BYT_TRIG_LVL;
13940a093020SGustavo A. R. Silva 		fallthrough;
139531e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_FALLING:
139631e4329fSMika Westerberg 		value |= BYT_TRIG_NEG;
139731e4329fSMika Westerberg 		break;
139831e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_BOTH:
139931e4329fSMika Westerberg 		value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
140031e4329fSMika Westerberg 		break;
140131e4329fSMika Westerberg 	}
140231e4329fSMika Westerberg 
140331e4329fSMika Westerberg 	writel(value, reg);
140431e4329fSMika Westerberg 
140540ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
14065fae8b86SMika Westerberg }
14075fae8b86SMika Westerberg 
14089f573b98SCristina Ciocan static int byt_irq_type(struct irq_data *d, unsigned int type)
14095fae8b86SMika Westerberg {
14105d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
14116d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
14129f573b98SCristina Ciocan 	u32 value;
14139f573b98SCristina Ciocan 	unsigned long flags;
14146d209b42SAndy Shevchenko 	void __iomem *reg;
141531e4329fSMika Westerberg 
14166d209b42SAndy Shevchenko 	reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG);
14176d209b42SAndy Shevchenko 	if (!reg)
14189f573b98SCristina Ciocan 		return -EINVAL;
14199f573b98SCristina Ciocan 
142040ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
14219f573b98SCristina Ciocan 	value = readl(reg);
14229f573b98SCristina Ciocan 
14239f573b98SCristina Ciocan 	WARN(value & BYT_DIRECT_IRQ_EN,
1424b9e18434SAndy Shevchenko 	     "Bad pad config for IO mode, force DIRECT_IRQ_EN bit clearing");
14259f573b98SCristina Ciocan 
14269f573b98SCristina Ciocan 	/* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
14279f573b98SCristina Ciocan 	 * are used to indicate high and low level triggering
14289f573b98SCristina Ciocan 	 */
14299f573b98SCristina Ciocan 	value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
14309f573b98SCristina Ciocan 		   BYT_TRIG_LVL);
14319291c65bSHans de Goede 	/* Enable glitch filtering */
14329291c65bSHans de Goede 	value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK |
14339291c65bSHans de Goede 		 BYT_GLITCH_F_FAST_CLK;
14349f573b98SCristina Ciocan 
14359f573b98SCristina Ciocan 	writel(value, reg);
14369f573b98SCristina Ciocan 
14379f573b98SCristina Ciocan 	if (type & IRQ_TYPE_EDGE_BOTH)
14389f573b98SCristina Ciocan 		irq_set_handler_locked(d, handle_edge_irq);
14399f573b98SCristina Ciocan 	else if (type & IRQ_TYPE_LEVEL_MASK)
14409f573b98SCristina Ciocan 		irq_set_handler_locked(d, handle_level_irq);
14419f573b98SCristina Ciocan 
144240ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
14439f573b98SCristina Ciocan 
14449f573b98SCristina Ciocan 	return 0;
14455fae8b86SMika Westerberg }
14465fae8b86SMika Westerberg 
14476d209b42SAndy Shevchenko static const struct irq_chip byt_gpio_irq_chip = {
14486d209b42SAndy Shevchenko 	.name		= "BYT-GPIO",
14496d209b42SAndy Shevchenko 	.irq_ack	= byt_irq_ack,
14506d209b42SAndy Shevchenko 	.irq_mask	= byt_irq_mask,
14516d209b42SAndy Shevchenko 	.irq_unmask	= byt_irq_unmask,
14526d209b42SAndy Shevchenko 	.irq_set_type	= byt_irq_type,
14536d209b42SAndy Shevchenko 	.flags		= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED | IRQCHIP_IMMUTABLE,
14546d209b42SAndy Shevchenko 	GPIOCHIP_IRQ_RESOURCE_HELPERS,
14556d209b42SAndy Shevchenko };
14566d209b42SAndy Shevchenko 
145771e6ca61SCristina Ciocan static void byt_gpio_irq_handler(struct irq_desc *desc)
145871e6ca61SCristina Ciocan {
145971e6ca61SCristina Ciocan 	struct irq_data *data = irq_desc_get_irq_data(desc);
14605d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(irq_desc_get_handler_data(desc));
146171e6ca61SCristina Ciocan 	struct irq_chip *chip = irq_data_get_irq_chip(data);
146271e6ca61SCristina Ciocan 	u32 base, pin;
146371e6ca61SCristina Ciocan 	void __iomem *reg;
146471e6ca61SCristina Ciocan 	unsigned long pending;
146571e6ca61SCristina Ciocan 
146671e6ca61SCristina Ciocan 	/* check from GPIO controller which pin triggered the interrupt */
146771e6ca61SCristina Ciocan 	for (base = 0; base < vg->chip.ngpio; base += 32) {
146871e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
146971e6ca61SCristina Ciocan 
147071e6ca61SCristina Ciocan 		if (!reg) {
1471b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Pin %i: can't retrieve INT_STAT%u\n", base / 32, base);
147271e6ca61SCristina Ciocan 			continue;
147371e6ca61SCristina Ciocan 		}
147471e6ca61SCristina Ciocan 
147540ecab55SHans de Goede 		raw_spin_lock(&byt_lock);
147671e6ca61SCristina Ciocan 		pending = readl(reg);
147740ecab55SHans de Goede 		raw_spin_unlock(&byt_lock);
1478a9cb09b7SMarc Zyngier 		for_each_set_bit(pin, &pending, 32)
1479a9cb09b7SMarc Zyngier 			generic_handle_domain_irq(vg->chip.irq.domain, base + pin);
148071e6ca61SCristina Ciocan 	}
148171e6ca61SCristina Ciocan 	chip->irq_eoi(data);
148271e6ca61SCristina Ciocan }
148371e6ca61SCristina Ciocan 
1484689e0088SHans de Goede static bool byt_direct_irq_sanity_check(struct intel_pinctrl *vg, int pin, u32 conf0)
1485689e0088SHans de Goede {
1486689e0088SHans de Goede 	int direct_irq, ioapic_direct_irq_base;
1487689e0088SHans de Goede 	u8 *match, direct_irq_mux[16];
1488689e0088SHans de Goede 	u32 trig;
1489689e0088SHans de Goede 
1490689e0088SHans de Goede 	memcpy_fromio(direct_irq_mux, vg->communities->pad_regs + BYT_DIRECT_IRQ_REG,
1491689e0088SHans de Goede 		      sizeof(direct_irq_mux));
1492689e0088SHans de Goede 	match = memchr(direct_irq_mux, pin, sizeof(direct_irq_mux));
1493689e0088SHans de Goede 	if (!match) {
1494b9e18434SAndy Shevchenko 		dev_warn(vg->dev, FW_BUG "Pin %i: DIRECT_IRQ_EN set but no IRQ assigned, clearing\n", pin);
1495689e0088SHans de Goede 		return false;
1496689e0088SHans de Goede 	}
1497689e0088SHans de Goede 
1498689e0088SHans de Goede 	direct_irq = match - direct_irq_mux;
1499689e0088SHans de Goede 	/* Base IO-APIC pin numbers come from atom-e3800-family-datasheet.pdf */
1500689e0088SHans de Goede 	ioapic_direct_irq_base = (vg->communities->npins == BYT_NGPIO_SCORE) ? 51 : 67;
1501689e0088SHans de Goede 	dev_dbg(vg->dev, "Pin %i: uses direct IRQ %d (IO-APIC %d)\n", pin,
1502689e0088SHans de Goede 		direct_irq, direct_irq + ioapic_direct_irq_base);
1503689e0088SHans de Goede 
1504689e0088SHans de Goede 	/*
1505689e0088SHans de Goede 	 * Testing has shown that the way direct IRQs work is that the combination of the
1506689e0088SHans de Goede 	 * direct-irq-en flag and the direct IRQ mux connect the output of the GPIO's IRQ
1507689e0088SHans de Goede 	 * trigger block, which normally sets the status flag in the IRQ status reg at
1508689e0088SHans de Goede 	 * 0x800, to one of the IO-APIC pins according to the mux registers.
1509689e0088SHans de Goede 	 *
1510689e0088SHans de Goede 	 * This means that:
1511689e0088SHans de Goede 	 * 1. The TRIG_MASK bits must be set to configure the GPIO's IRQ trigger block
1512689e0088SHans de Goede 	 * 2. The TRIG_LVL bit *must* be set, so that the GPIO's input value is directly
1513689e0088SHans de Goede 	 *    passed (1:1 or inverted) to the IO-APIC pin, if TRIG_LVL is not set,
1514689e0088SHans de Goede 	 *    selecting edge mode operation then on the first edge the IO-APIC pin goes
1515689e0088SHans de Goede 	 *    high, but since no write-to-clear write will be done to the IRQ status reg
1516689e0088SHans de Goede 	 *    at 0x800, the detected edge condition will never get cleared.
1517689e0088SHans de Goede 	 */
1518689e0088SHans de Goede 	trig = conf0 & BYT_TRIG_MASK;
1519689e0088SHans de Goede 	if (trig != (BYT_TRIG_POS | BYT_TRIG_LVL) &&
1520689e0088SHans de Goede 	    trig != (BYT_TRIG_NEG | BYT_TRIG_LVL)) {
1521b9e18434SAndy Shevchenko 		dev_warn(vg->dev,
1522b9e18434SAndy Shevchenko 			 FW_BUG "Pin %i: DIRECT_IRQ_EN set without trigger (CONF0: %#08x), clearing\n",
1523689e0088SHans de Goede 			 pin, conf0);
1524689e0088SHans de Goede 		return false;
1525689e0088SHans de Goede 	}
1526689e0088SHans de Goede 
1527689e0088SHans de Goede 	return true;
1528689e0088SHans de Goede }
1529689e0088SHans de Goede 
15305fbe5b58SLinus Walleij static void byt_init_irq_valid_mask(struct gpio_chip *chip,
15315fbe5b58SLinus Walleij 				    unsigned long *valid_mask,
15325fbe5b58SLinus Walleij 				    unsigned int ngpios)
15335fbe5b58SLinus Walleij {
15345d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
15355fae8b86SMika Westerberg 	void __iomem *reg;
1536e70982b3SAndy Shevchenko 	u32 value;
153795f0972cSMika Westerberg 	int i;
153895f0972cSMika Westerberg 
153995f0972cSMika Westerberg 	/*
154095f0972cSMika Westerberg 	 * Clear interrupt triggers for all pins that are GPIOs and
154195f0972cSMika Westerberg 	 * do not use direct IRQ mode. This will prevent spurious
154295f0972cSMika Westerberg 	 * interrupts from misconfigured pins.
154395f0972cSMika Westerberg 	 */
15445d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
15455d33e0ebSAndy Shevchenko 		unsigned int pin = vg->soc->pins[i].number;
154671e6ca61SCristina Ciocan 
154771e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
154871e6ca61SCristina Ciocan 		if (!reg) {
1549b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Pin %i: could not retrieve CONF0\n", i);
155071e6ca61SCristina Ciocan 			continue;
155171e6ca61SCristina Ciocan 		}
155271e6ca61SCristina Ciocan 
155371e6ca61SCristina Ciocan 		value = readl(reg);
155449c03096SAndy Shevchenko 		if (value & BYT_DIRECT_IRQ_EN) {
1555689e0088SHans de Goede 			if (byt_direct_irq_sanity_check(vg, i, value)) {
1556e70982b3SAndy Shevchenko 				clear_bit(i, valid_mask);
1557689e0088SHans de Goede 			} else {
1558689e0088SHans de Goede 				value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS |
1559689e0088SHans de Goede 					   BYT_TRIG_NEG | BYT_TRIG_LVL);
1560689e0088SHans de Goede 				writel(value, reg);
1561689e0088SHans de Goede 			}
156249c03096SAndy Shevchenko 		} else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) {
156395f0972cSMika Westerberg 			byt_gpio_clear_triggering(vg, i);
1564990ec243SAndy Shevchenko 			dev_dbg(vg->dev, "disabling GPIO %d\n", i);
156595f0972cSMika Westerberg 		}
156695f0972cSMika Westerberg 	}
1567e70982b3SAndy Shevchenko }
1568e70982b3SAndy Shevchenko 
1569e70982b3SAndy Shevchenko static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
1570e70982b3SAndy Shevchenko {
15715d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1572e70982b3SAndy Shevchenko 	void __iomem *reg;
1573e70982b3SAndy Shevchenko 	u32 base, value;
15745fae8b86SMika Westerberg 
15755fae8b86SMika Westerberg 	/* clear interrupt status trigger registers */
15765d33e0ebSAndy Shevchenko 	for (base = 0; base < vg->soc->npins; base += 32) {
1577c501d0b1SCristina Ciocan 		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
157871e6ca61SCristina Ciocan 
157971e6ca61SCristina Ciocan 		if (!reg) {
1580b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Pin %i: can't retrieve INT_STAT%u\n", base / 32, base);
158171e6ca61SCristina Ciocan 			continue;
158271e6ca61SCristina Ciocan 		}
158371e6ca61SCristina Ciocan 
15845fae8b86SMika Westerberg 		writel(0xffffffff, reg);
15855fae8b86SMika Westerberg 		/* make sure trigger bits are cleared, if not then a pin
15865fae8b86SMika Westerberg 		   might be misconfigured in bios */
15875fae8b86SMika Westerberg 		value = readl(reg);
15885fae8b86SMika Westerberg 		if (value)
1589990ec243SAndy Shevchenko 			dev_err(vg->dev,
1590b9e18434SAndy Shevchenko 				"GPIO interrupt error, pins misconfigured. INT_STAT%u: %#08x\n",
1591973232e2SAlexander Stein 				base / 32, value);
15925fae8b86SMika Westerberg 	}
1593ca8a958eSAndy Shevchenko 
1594ca8a958eSAndy Shevchenko 	return 0;
15955fae8b86SMika Westerberg }
15965fae8b86SMika Westerberg 
1597ed3c1564SAndy Shevchenko static int byt_gpio_add_pin_ranges(struct gpio_chip *chip)
1598ed3c1564SAndy Shevchenko {
15995d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1600990ec243SAndy Shevchenko 	struct device *dev = vg->dev;
1601ed3c1564SAndy Shevchenko 	int ret;
1602ed3c1564SAndy Shevchenko 
16035d33e0ebSAndy Shevchenko 	ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins);
1604ed3c1564SAndy Shevchenko 	if (ret)
1605ed3c1564SAndy Shevchenko 		dev_err(dev, "failed to add GPIO pin range\n");
1606ed3c1564SAndy Shevchenko 
1607ed3c1564SAndy Shevchenko 	return ret;
1608ed3c1564SAndy Shevchenko }
1609ed3c1564SAndy Shevchenko 
16105d33e0ebSAndy Shevchenko static int byt_gpio_probe(struct intel_pinctrl *vg)
16115fae8b86SMika Westerberg {
1612990ec243SAndy Shevchenko 	struct platform_device *pdev = to_platform_device(vg->dev);
16135fae8b86SMika Westerberg 	struct gpio_chip *gc;
1614f86a1bb5SAndy Shevchenko 	int irq, ret;
16155fae8b86SMika Westerberg 
161671e6ca61SCristina Ciocan 	/* Set up gpio chip */
161771e6ca61SCristina Ciocan 	vg->chip	= byt_gpio_chip;
16185fae8b86SMika Westerberg 	gc		= &vg->chip;
1619990ec243SAndy Shevchenko 	gc->label	= dev_name(vg->dev);
16205fae8b86SMika Westerberg 	gc->base	= -1;
16215fae8b86SMika Westerberg 	gc->can_sleep	= false;
1622ed3c1564SAndy Shevchenko 	gc->add_pin_ranges = byt_gpio_add_pin_ranges;
1623990ec243SAndy Shevchenko 	gc->parent	= vg->dev;
16245d33e0ebSAndy Shevchenko 	gc->ngpio	= vg->soc->npins;
16255fae8b86SMika Westerberg 
1626fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP
16275d33e0ebSAndy Shevchenko 	vg->context.pads = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->context.pads),
16285d33e0ebSAndy Shevchenko 					GFP_KERNEL);
16295d33e0ebSAndy Shevchenko 	if (!vg->context.pads)
1630d6cb7722SAditya Pakki 		return -ENOMEM;
1631fcc18debSMika Westerberg #endif
16325fae8b86SMika Westerberg 
16335fae8b86SMika Westerberg 	/* set up interrupts  */
1634f86a1bb5SAndy Shevchenko 	irq = platform_get_irq_optional(pdev, 0);
1635f86a1bb5SAndy Shevchenko 	if (irq > 0) {
1636ca8a958eSAndy Shevchenko 		struct gpio_irq_chip *girq;
1637ca8a958eSAndy Shevchenko 
1638ca8a958eSAndy Shevchenko 		girq = &gc->irq;
16396d209b42SAndy Shevchenko 		gpio_irq_chip_set_chip(girq, &byt_gpio_irq_chip);
1640ca8a958eSAndy Shevchenko 		girq->init_hw = byt_gpio_irq_init_hw;
1641ab68b220SAndy Shevchenko 		girq->init_valid_mask = byt_init_irq_valid_mask;
1642ca8a958eSAndy Shevchenko 		girq->parent_handler = byt_gpio_irq_handler;
1643ca8a958eSAndy Shevchenko 		girq->num_parents = 1;
1644990ec243SAndy Shevchenko 		girq->parents = devm_kcalloc(vg->dev, girq->num_parents,
1645ca8a958eSAndy Shevchenko 					     sizeof(*girq->parents), GFP_KERNEL);
1646ca8a958eSAndy Shevchenko 		if (!girq->parents)
1647ca8a958eSAndy Shevchenko 			return -ENOMEM;
1648f86a1bb5SAndy Shevchenko 		girq->parents[0] = irq;
1649ca8a958eSAndy Shevchenko 		girq->default_type = IRQ_TYPE_NONE;
1650ca8a958eSAndy Shevchenko 		girq->handler = handle_bad_irq;
16515fae8b86SMika Westerberg 	}
16525fae8b86SMika Westerberg 
1653990ec243SAndy Shevchenko 	ret = devm_gpiochip_add_data(vg->dev, gc, vg);
1654ca8a958eSAndy Shevchenko 	if (ret) {
1655990ec243SAndy Shevchenko 		dev_err(vg->dev, "failed adding byt-gpio chip\n");
1656ca8a958eSAndy Shevchenko 		return ret;
16575fae8b86SMika Westerberg 	}
16585fae8b86SMika Westerberg 
165971e6ca61SCristina Ciocan 	return ret;
166071e6ca61SCristina Ciocan }
166171e6ca61SCristina Ciocan 
16625d33e0ebSAndy Shevchenko static int byt_set_soc_data(struct intel_pinctrl *vg,
16635d33e0ebSAndy Shevchenko 			    const struct intel_pinctrl_soc_data *soc)
166471e6ca61SCristina Ciocan {
1665990ec243SAndy Shevchenko 	struct platform_device *pdev = to_platform_device(vg->dev);
166671e6ca61SCristina Ciocan 	int i;
166771e6ca61SCristina Ciocan 
16685d33e0ebSAndy Shevchenko 	vg->soc = soc;
16695d33e0ebSAndy Shevchenko 
16705d33e0ebSAndy Shevchenko 	vg->ncommunities = vg->soc->ncommunities;
16715d33e0ebSAndy Shevchenko 	vg->communities = devm_kcalloc(vg->dev, vg->ncommunities,
16725d33e0ebSAndy Shevchenko 				       sizeof(*vg->communities), GFP_KERNEL);
16735d33e0ebSAndy Shevchenko 	if (!vg->communities)
167471e6ca61SCristina Ciocan 		return -ENOMEM;
167571e6ca61SCristina Ciocan 
16765d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->ncommunities; i++) {
16775d33e0ebSAndy Shevchenko 		struct intel_community *comm = vg->communities + i;
167871e6ca61SCristina Ciocan 
16795d33e0ebSAndy Shevchenko 		*comm = vg->soc->communities[i];
168071e6ca61SCristina Ciocan 
1681990ec243SAndy Shevchenko 		comm->pad_regs = devm_platform_ioremap_resource(pdev, 0);
168234e65670SAndy Shevchenko 		if (IS_ERR(comm->pad_regs))
168334e65670SAndy Shevchenko 			return PTR_ERR(comm->pad_regs);
168471e6ca61SCristina Ciocan 	}
168571e6ca61SCristina Ciocan 
168671e6ca61SCristina Ciocan 	return 0;
168771e6ca61SCristina Ciocan }
168871e6ca61SCristina Ciocan 
168971e6ca61SCristina Ciocan static const struct acpi_device_id byt_gpio_acpi_match[] = {
169071e6ca61SCristina Ciocan 	{ "INT33B2", (kernel_ulong_t)byt_soc_data },
169171e6ca61SCristina Ciocan 	{ "INT33FC", (kernel_ulong_t)byt_soc_data },
169271e6ca61SCristina Ciocan 	{ }
169371e6ca61SCristina Ciocan };
169471e6ca61SCristina Ciocan 
169571e6ca61SCristina Ciocan static int byt_pinctrl_probe(struct platform_device *pdev)
169671e6ca61SCristina Ciocan {
1697ce7793e9SAndy Shevchenko 	const struct intel_pinctrl_soc_data *soc_data;
16982c02af70SAndy Shevchenko 	struct device *dev = &pdev->dev;
16995d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg;
1700ce7793e9SAndy Shevchenko 	int ret;
170171e6ca61SCristina Ciocan 
1702ce7793e9SAndy Shevchenko 	soc_data = intel_pinctrl_get_soc_data(pdev);
1703ce7793e9SAndy Shevchenko 	if (IS_ERR(soc_data))
1704ce7793e9SAndy Shevchenko 		return PTR_ERR(soc_data);
170571e6ca61SCristina Ciocan 
17062c02af70SAndy Shevchenko 	vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL);
170771e6ca61SCristina Ciocan 	if (!vg)
170871e6ca61SCristina Ciocan 		return -ENOMEM;
170971e6ca61SCristina Ciocan 
17102c02af70SAndy Shevchenko 	vg->dev = dev;
171171e6ca61SCristina Ciocan 	ret = byt_set_soc_data(vg, soc_data);
171271e6ca61SCristina Ciocan 	if (ret) {
17132c02af70SAndy Shevchenko 		dev_err(dev, "failed to set soc data\n");
171471e6ca61SCristina Ciocan 		return ret;
171571e6ca61SCristina Ciocan 	}
171671e6ca61SCristina Ciocan 
17175d33e0ebSAndy Shevchenko 	vg->pctldesc		= byt_pinctrl_desc;
17185d33e0ebSAndy Shevchenko 	vg->pctldesc.name	= dev_name(dev);
17195d33e0ebSAndy Shevchenko 	vg->pctldesc.pins	= vg->soc->pins;
17205d33e0ebSAndy Shevchenko 	vg->pctldesc.npins	= vg->soc->npins;
172171e6ca61SCristina Ciocan 
17225d33e0ebSAndy Shevchenko 	vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg);
17235d33e0ebSAndy Shevchenko 	if (IS_ERR(vg->pctldev)) {
17242c02af70SAndy Shevchenko 		dev_err(dev, "failed to register pinctrl driver\n");
17255d33e0ebSAndy Shevchenko 		return PTR_ERR(vg->pctldev);
172671e6ca61SCristina Ciocan 	}
172771e6ca61SCristina Ciocan 
172871e6ca61SCristina Ciocan 	ret = byt_gpio_probe(vg);
17290612413fSAndy Shevchenko 	if (ret)
173071e6ca61SCristina Ciocan 		return ret;
173171e6ca61SCristina Ciocan 
173271e6ca61SCristina Ciocan 	platform_set_drvdata(pdev, vg);
17332c02af70SAndy Shevchenko 	pm_runtime_enable(dev);
173471e6ca61SCristina Ciocan 
173571e6ca61SCristina Ciocan 	return 0;
173671e6ca61SCristina Ciocan }
173771e6ca61SCristina Ciocan 
1738fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP
1739fcc18debSMika Westerberg static int byt_gpio_suspend(struct device *dev)
1740fcc18debSMika Westerberg {
17415d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = dev_get_drvdata(dev);
174240ecab55SHans de Goede 	unsigned long flags;
1743fcc18debSMika Westerberg 	int i;
1744fcc18debSMika Westerberg 
174540ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
174640ecab55SHans de Goede 
17475d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
1748fcc18debSMika Westerberg 		void __iomem *reg;
1749fcc18debSMika Westerberg 		u32 value;
17505d33e0ebSAndy Shevchenko 		unsigned int pin = vg->soc->pins[i].number;
1751fcc18debSMika Westerberg 
175271e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
175371e6ca61SCristina Ciocan 		if (!reg) {
1754b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Pin %i: can't retrieve CONF0\n", i);
175571e6ca61SCristina Ciocan 			continue;
175671e6ca61SCristina Ciocan 		}
1757fcc18debSMika Westerberg 		value = readl(reg) & BYT_CONF0_RESTORE_MASK;
17585d33e0ebSAndy Shevchenko 		vg->context.pads[i].conf0 = value;
1759fcc18debSMika Westerberg 
176071e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
1761*9d49882eSRaag Jadav 		if (!reg) {
1762*9d49882eSRaag Jadav 			dev_warn(vg->dev, "Pin %i: can't retrieve VAL\n", i);
1763*9d49882eSRaag Jadav 			continue;
1764*9d49882eSRaag Jadav 		}
1765fcc18debSMika Westerberg 		value = readl(reg) & BYT_VAL_RESTORE_MASK;
17665d33e0ebSAndy Shevchenko 		vg->context.pads[i].val = value;
1767fcc18debSMika Westerberg 	}
1768fcc18debSMika Westerberg 
176940ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1770fcc18debSMika Westerberg 	return 0;
1771fcc18debSMika Westerberg }
1772fcc18debSMika Westerberg 
1773fcc18debSMika Westerberg static int byt_gpio_resume(struct device *dev)
1774fcc18debSMika Westerberg {
17755d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = dev_get_drvdata(dev);
177640ecab55SHans de Goede 	unsigned long flags;
1777fcc18debSMika Westerberg 	int i;
1778fcc18debSMika Westerberg 
177940ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
178040ecab55SHans de Goede 
17815d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
1782fcc18debSMika Westerberg 		void __iomem *reg;
1783fcc18debSMika Westerberg 		u32 value;
17845d33e0ebSAndy Shevchenko 		unsigned int pin = vg->soc->pins[i].number;
1785fcc18debSMika Westerberg 
178671e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
178771e6ca61SCristina Ciocan 		if (!reg) {
1788b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Pin %i: can't retrieve CONF0\n", i);
178971e6ca61SCristina Ciocan 			continue;
179071e6ca61SCristina Ciocan 		}
1791fcc18debSMika Westerberg 		value = readl(reg);
1792fcc18debSMika Westerberg 		if ((value & BYT_CONF0_RESTORE_MASK) !=
17935d33e0ebSAndy Shevchenko 		     vg->context.pads[i].conf0) {
1794fcc18debSMika Westerberg 			value &= ~BYT_CONF0_RESTORE_MASK;
17955d33e0ebSAndy Shevchenko 			value |= vg->context.pads[i].conf0;
1796fcc18debSMika Westerberg 			writel(value, reg);
1797b9e18434SAndy Shevchenko 			dev_info(dev, "restored pin %d CONF0 %#08x", i, value);
1798fcc18debSMika Westerberg 		}
1799fcc18debSMika Westerberg 
180071e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
1801*9d49882eSRaag Jadav 		if (!reg) {
1802*9d49882eSRaag Jadav 			dev_warn(vg->dev, "Pin %i: can't retrieve VAL\n", i);
1803*9d49882eSRaag Jadav 			continue;
1804*9d49882eSRaag Jadav 		}
1805fcc18debSMika Westerberg 		value = readl(reg);
1806fcc18debSMika Westerberg 		if ((value & BYT_VAL_RESTORE_MASK) !=
18075d33e0ebSAndy Shevchenko 		     vg->context.pads[i].val) {
1808fcc18debSMika Westerberg 			u32 v;
1809fcc18debSMika Westerberg 
1810fcc18debSMika Westerberg 			v = value & ~BYT_VAL_RESTORE_MASK;
18115d33e0ebSAndy Shevchenko 			v |= vg->context.pads[i].val;
1812fcc18debSMika Westerberg 			if (v != value) {
1813fcc18debSMika Westerberg 				writel(v, reg);
1814b9e18434SAndy Shevchenko 				dev_dbg(dev, "restored pin %d VAL %#08x\n", i, v);
1815fcc18debSMika Westerberg 			}
1816fcc18debSMika Westerberg 		}
1817fcc18debSMika Westerberg 	}
1818fcc18debSMika Westerberg 
181940ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1820fcc18debSMika Westerberg 	return 0;
1821fcc18debSMika Westerberg }
1822fcc18debSMika Westerberg #endif
1823fcc18debSMika Westerberg 
1824ec879f12SMika Westerberg #ifdef CONFIG_PM
18255fae8b86SMika Westerberg static int byt_gpio_runtime_suspend(struct device *dev)
18265fae8b86SMika Westerberg {
18275fae8b86SMika Westerberg 	return 0;
18285fae8b86SMika Westerberg }
18295fae8b86SMika Westerberg 
18305fae8b86SMika Westerberg static int byt_gpio_runtime_resume(struct device *dev)
18315fae8b86SMika Westerberg {
18325fae8b86SMika Westerberg 	return 0;
18335fae8b86SMika Westerberg }
1834ec879f12SMika Westerberg #endif
18355fae8b86SMika Westerberg 
18365fae8b86SMika Westerberg static const struct dev_pm_ops byt_gpio_pm_ops = {
1837fcc18debSMika Westerberg 	SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume)
1838fcc18debSMika Westerberg 	SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume,
1839fcc18debSMika Westerberg 			   NULL)
18405fae8b86SMika Westerberg };
18415fae8b86SMika Westerberg 
18425fae8b86SMika Westerberg static struct platform_driver byt_gpio_driver = {
184371e6ca61SCristina Ciocan 	.probe          = byt_pinctrl_probe,
18445fae8b86SMika Westerberg 	.driver         = {
18455fae8b86SMika Westerberg 		.name			= "byt_gpio",
18465fae8b86SMika Westerberg 		.pm			= &byt_gpio_pm_ops,
1847e87daf0bSAndy Shevchenko 		.acpi_match_table	= byt_gpio_acpi_match,
1848360943a8SPaul Gortmaker 		.suppress_bind_attrs	= true,
18495fae8b86SMika Westerberg 	},
18505fae8b86SMika Westerberg };
18515fae8b86SMika Westerberg 
18525fae8b86SMika Westerberg static int __init byt_gpio_init(void)
18535fae8b86SMika Westerberg {
18545fae8b86SMika Westerberg 	return platform_driver_register(&byt_gpio_driver);
18555fae8b86SMika Westerberg }
18565fae8b86SMika Westerberg subsys_initcall(byt_gpio_init);
1857