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>
2161db6c9dSAndy Shevchenko 
225fae8b86SMika Westerberg #include <linux/pinctrl/pinctrl.h>
23c501d0b1SCristina Ciocan #include <linux/pinctrl/pinmux.h>
24c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf.h>
25c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf-generic.h>
265fae8b86SMika Westerberg 
274f010b93SAndy Shevchenko #include "pinctrl-intel.h"
284f010b93SAndy Shevchenko 
295fae8b86SMika Westerberg /* memory mapped register offsets */
305fae8b86SMika Westerberg #define BYT_CONF0_REG		0x000
315fae8b86SMika Westerberg #define BYT_CONF1_REG		0x004
325fae8b86SMika Westerberg #define BYT_VAL_REG		0x008
335fae8b86SMika Westerberg #define BYT_DFT_REG		0x00c
345fae8b86SMika Westerberg #define BYT_INT_STAT_REG	0x800
35689e0088SHans de Goede #define BYT_DIRECT_IRQ_REG	0x980
36658b476cSCristina Ciocan #define BYT_DEBOUNCE_REG	0x9d0
375fae8b86SMika Westerberg 
385fae8b86SMika Westerberg /* BYT_CONF0_REG register bits */
395fae8b86SMika Westerberg #define BYT_IODEN		BIT(31)
405fae8b86SMika Westerberg #define BYT_DIRECT_IRQ_EN	BIT(27)
41eb0a2daaSAndy Shevchenko #define BYT_TRIG_MASK		GENMASK(26, 24)
425fae8b86SMika Westerberg #define BYT_TRIG_NEG		BIT(26)
435fae8b86SMika Westerberg #define BYT_TRIG_POS		BIT(25)
445fae8b86SMika Westerberg #define BYT_TRIG_LVL		BIT(24)
45658b476cSCristina Ciocan #define BYT_DEBOUNCE_EN		BIT(20)
469291c65bSHans de Goede #define BYT_GLITCH_FILTER_EN	BIT(19)
479291c65bSHans de Goede #define BYT_GLITCH_F_SLOW_CLK	BIT(17)
489291c65bSHans de Goede #define BYT_GLITCH_F_FAST_CLK	BIT(16)
495fae8b86SMika Westerberg #define BYT_PULL_STR_SHIFT	9
50eb0a2daaSAndy Shevchenko #define BYT_PULL_STR_MASK	GENMASK(10, 9)
515fae8b86SMika Westerberg #define BYT_PULL_STR_2K		(0 << BYT_PULL_STR_SHIFT)
525fae8b86SMika Westerberg #define BYT_PULL_STR_10K	(1 << BYT_PULL_STR_SHIFT)
535fae8b86SMika Westerberg #define BYT_PULL_STR_20K	(2 << BYT_PULL_STR_SHIFT)
545fae8b86SMika Westerberg #define BYT_PULL_STR_40K	(3 << BYT_PULL_STR_SHIFT)
555fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_SHIFT	7
56eb0a2daaSAndy Shevchenko #define BYT_PULL_ASSIGN_MASK	GENMASK(8, 7)
575fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_UP	(1 << BYT_PULL_ASSIGN_SHIFT)
585fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_DOWN	(2 << BYT_PULL_ASSIGN_SHIFT)
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 
606*770f53d4SAndy 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 
616*770f53d4SAndy Shevchenko 	*pins		= vg->soc->groups[selector].grp.pins;
617*770f53d4SAndy 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 
6405d33e0ebSAndy Shevchenko 	return vg->soc->functions[selector].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,
646c501d0b1SCristina Ciocan 				   unsigned int *num_groups)
647c501d0b1SCristina Ciocan {
6485d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
649c501d0b1SCristina Ciocan 
6505d33e0ebSAndy Shevchenko 	*groups		= vg->soc->functions[selector].groups;
6515d33e0ebSAndy Shevchenko 	*num_groups	= vg->soc->functions[selector].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 
665*770f53d4SAndy Shevchenko 	for (i = 0; i < group.grp.npins; i++) {
666c501d0b1SCristina Ciocan 		void __iomem *padcfg0;
667c501d0b1SCristina Ciocan 		u32 value;
668c501d0b1SCristina Ciocan 
669*770f53d4SAndy Shevchenko 		padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG);
670c501d0b1SCristina Ciocan 		if (!padcfg0) {
671990ec243SAndy Shevchenko 			dev_warn(vg->dev,
672c501d0b1SCristina Ciocan 				 "Group %s, pin %i not muxed (no padcfg0)\n",
673*770f53d4SAndy Shevchenko 				 group.grp.name, i);
674c501d0b1SCristina Ciocan 			continue;
675c501d0b1SCristina Ciocan 		}
676c501d0b1SCristina Ciocan 
677c501d0b1SCristina Ciocan 		value = readl(padcfg0);
678c501d0b1SCristina Ciocan 		value &= ~BYT_PIN_MUX;
679c501d0b1SCristina Ciocan 		value |= func;
680c501d0b1SCristina Ciocan 		writel(value, padcfg0);
681c501d0b1SCristina Ciocan 	}
682c501d0b1SCristina Ciocan 
68340ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
684c501d0b1SCristina Ciocan }
685c501d0b1SCristina Ciocan 
6865d33e0ebSAndy Shevchenko static void byt_set_group_mixed_mux(struct intel_pinctrl *vg,
6874f010b93SAndy Shevchenko 				    const struct intel_pingroup group,
6884f010b93SAndy Shevchenko 				    const unsigned int *func)
689c501d0b1SCristina Ciocan {
690c501d0b1SCristina Ciocan 	unsigned long flags;
691c501d0b1SCristina Ciocan 	int i;
692c501d0b1SCristina Ciocan 
69340ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
694c501d0b1SCristina Ciocan 
695*770f53d4SAndy Shevchenko 	for (i = 0; i < group.grp.npins; i++) {
696c501d0b1SCristina Ciocan 		void __iomem *padcfg0;
697c501d0b1SCristina Ciocan 		u32 value;
698c501d0b1SCristina Ciocan 
699*770f53d4SAndy Shevchenko 		padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG);
700c501d0b1SCristina Ciocan 		if (!padcfg0) {
701990ec243SAndy Shevchenko 			dev_warn(vg->dev,
702c501d0b1SCristina Ciocan 				 "Group %s, pin %i not muxed (no padcfg0)\n",
703*770f53d4SAndy Shevchenko 				 group.grp.name, i);
704c501d0b1SCristina Ciocan 			continue;
705c501d0b1SCristina Ciocan 		}
706c501d0b1SCristina Ciocan 
707c501d0b1SCristina Ciocan 		value = readl(padcfg0);
708c501d0b1SCristina Ciocan 		value &= ~BYT_PIN_MUX;
709c501d0b1SCristina Ciocan 		value |= func[i];
710c501d0b1SCristina Ciocan 		writel(value, padcfg0);
711c501d0b1SCristina Ciocan 	}
712c501d0b1SCristina Ciocan 
71340ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
714c501d0b1SCristina Ciocan }
715c501d0b1SCristina Ciocan 
716c501d0b1SCristina Ciocan static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
717c501d0b1SCristina Ciocan 		       unsigned int group_selector)
718c501d0b1SCristina Ciocan {
7195d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
7205d33e0ebSAndy Shevchenko 	const struct intel_function func = vg->soc->functions[func_selector];
7215d33e0ebSAndy Shevchenko 	const struct intel_pingroup group = vg->soc->groups[group_selector];
722c501d0b1SCristina Ciocan 
7234f010b93SAndy Shevchenko 	if (group.modes)
7244f010b93SAndy Shevchenko 		byt_set_group_mixed_mux(vg, group, group.modes);
7254f010b93SAndy Shevchenko 	else if (!strcmp(func.name, "gpio"))
726c501d0b1SCristina Ciocan 		byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX);
727c501d0b1SCristina Ciocan 	else
7284f010b93SAndy Shevchenko 		byt_set_group_simple_mux(vg, group, group.mode);
729c501d0b1SCristina Ciocan 
730c501d0b1SCristina Ciocan 	return 0;
731c501d0b1SCristina Ciocan }
732c501d0b1SCristina Ciocan 
7335d33e0ebSAndy Shevchenko static u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset)
734c501d0b1SCristina Ciocan {
735c501d0b1SCristina Ciocan 	/* SCORE pin 92-93 */
7365d33e0ebSAndy Shevchenko 	if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) &&
737c501d0b1SCristina Ciocan 	    offset >= 92 && offset <= 93)
738a705f9c1SAndy Shevchenko 		return BYT_ALTER_GPIO_MUX;
739c501d0b1SCristina Ciocan 
740c501d0b1SCristina Ciocan 	/* SUS pin 11-21 */
7415d33e0ebSAndy Shevchenko 	if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) &&
742c501d0b1SCristina Ciocan 	    offset >= 11 && offset <= 21)
743a705f9c1SAndy Shevchenko 		return BYT_ALTER_GPIO_MUX;
744c501d0b1SCristina Ciocan 
745a705f9c1SAndy Shevchenko 	return BYT_DEFAULT_GPIO_MUX;
746c501d0b1SCristina Ciocan }
747c501d0b1SCristina Ciocan 
7485d33e0ebSAndy Shevchenko static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset)
749c501d0b1SCristina Ciocan {
750c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
75195f0972cSMika Westerberg 	unsigned long flags;
75295f0972cSMika Westerberg 	u32 value;
75395f0972cSMika Westerberg 
75440ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
75595f0972cSMika Westerberg 	value = readl(reg);
756a2368059SHans de Goede 
757a2368059SHans de Goede 	/* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */
758a2368059SHans de Goede 	if (value & BYT_DIRECT_IRQ_EN)
759a2368059SHans de Goede 		/* nothing to do */ ;
760a2368059SHans de Goede 	else
76195f0972cSMika Westerberg 		value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
762a2368059SHans de Goede 
76395f0972cSMika Westerberg 	writel(value, reg);
76440ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
76595f0972cSMika Westerberg }
76695f0972cSMika Westerberg 
767c501d0b1SCristina Ciocan static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
768c501d0b1SCristina Ciocan 				   struct pinctrl_gpio_range *range,
769c501d0b1SCristina Ciocan 				   unsigned int offset)
7705fae8b86SMika Westerberg {
7715d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
772c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
773f8323b6bSMika Westerberg 	u32 value, gpio_mux;
77439ce8150SMika Westerberg 	unsigned long flags;
77539ce8150SMika Westerberg 
77640ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
7775fae8b86SMika Westerberg 
7785fae8b86SMika Westerberg 	/*
7795fae8b86SMika Westerberg 	 * In most cases, func pin mux 000 means GPIO function.
7805fae8b86SMika Westerberg 	 * But, some pins may have func pin mux 001 represents
781f8323b6bSMika Westerberg 	 * GPIO function.
782f8323b6bSMika Westerberg 	 *
783f8323b6bSMika Westerberg 	 * Because there are devices out there where some pins were not
784f8323b6bSMika Westerberg 	 * configured correctly we allow changing the mux value from
785f8323b6bSMika Westerberg 	 * request (but print out warning about that).
7865fae8b86SMika Westerberg 	 */
7875fae8b86SMika Westerberg 	value = readl(reg) & BYT_PIN_MUX;
788f8323b6bSMika Westerberg 	gpio_mux = byt_get_gpio_mux(vg, offset);
789b5894d12SHans de Goede 	if (gpio_mux != value) {
790f8323b6bSMika Westerberg 		value = readl(reg) & ~BYT_PIN_MUX;
791f8323b6bSMika Westerberg 		value |= gpio_mux;
792f8323b6bSMika Westerberg 		writel(value, reg);
793f8323b6bSMika Westerberg 
794990ec243SAndy Shevchenko 		dev_warn(vg->dev, FW_BUG "pin %u forcibly re-configured as GPIO\n", offset);
7955fae8b86SMika Westerberg 	}
7965fae8b86SMika Westerberg 
79740ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
79839ce8150SMika Westerberg 
799990ec243SAndy Shevchenko 	pm_runtime_get(vg->dev);
8005fae8b86SMika Westerberg 
8015fae8b86SMika Westerberg 	return 0;
8025fae8b86SMika Westerberg }
8035fae8b86SMika Westerberg 
804c501d0b1SCristina Ciocan static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
805c501d0b1SCristina Ciocan 				  struct pinctrl_gpio_range *range,
806c501d0b1SCristina Ciocan 				  unsigned int offset)
807c501d0b1SCristina Ciocan {
8085d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
809c501d0b1SCristina Ciocan 
810c501d0b1SCristina Ciocan 	byt_gpio_clear_triggering(vg, offset);
811990ec243SAndy Shevchenko 	pm_runtime_put(vg->dev);
812c501d0b1SCristina Ciocan }
813c501d0b1SCristina Ciocan 
814156abe29SHans de Goede static void byt_gpio_direct_irq_check(struct intel_pinctrl *vg,
815156abe29SHans de Goede 				      unsigned int offset)
816156abe29SHans de Goede {
817156abe29SHans de Goede 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
818156abe29SHans de Goede 
819156abe29SHans de Goede 	/*
820156abe29SHans de Goede 	 * Before making any direction modifications, do a check if gpio is set
821156abe29SHans de Goede 	 * for direct IRQ. On Bay Trail, setting GPIO to output does not make
822156abe29SHans de Goede 	 * sense, so let's at least inform the caller before they shoot
823156abe29SHans de Goede 	 * themselves in the foot.
824156abe29SHans de Goede 	 */
825156abe29SHans de Goede 	if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
826156abe29SHans de Goede 		dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output");
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);
1029990ec243SAndy Shevchenko 				dev_warn(vg->dev,
1030c501d0b1SCristina Ciocan 					 "pin %u forcibly set to input mode\n",
1031c501d0b1SCristina Ciocan 					 offset);
1032c501d0b1SCristina Ciocan 			}
1033c501d0b1SCristina Ciocan 
1034c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
1035c501d0b1SCristina Ciocan 			conf |= BYT_PULL_ASSIGN_DOWN;
1036c501d0b1SCristina Ciocan 			ret = byt_set_pull_strength(&conf, arg);
1037c501d0b1SCristina Ciocan 
1038c501d0b1SCristina Ciocan 			break;
1039c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_PULL_UP:
1040c501d0b1SCristina Ciocan 			/* Set default strength value in case none is given */
1041c501d0b1SCristina Ciocan 			if (arg == 1)
1042c501d0b1SCristina Ciocan 				arg = 2000;
1043c501d0b1SCristina Ciocan 
1044c501d0b1SCristina Ciocan 			/*
1045c501d0b1SCristina Ciocan 			 * Pull assignment is only applicable in input mode. If
1046c501d0b1SCristina Ciocan 			 * chip is not in input mode, set it and warn about it.
1047c501d0b1SCristina Ciocan 			 */
1048c501d0b1SCristina Ciocan 			if (val & BYT_INPUT_EN) {
1049c501d0b1SCristina Ciocan 				val &= ~BYT_INPUT_EN;
1050c501d0b1SCristina Ciocan 				writel(val, val_reg);
1051990ec243SAndy Shevchenko 				dev_warn(vg->dev,
1052c501d0b1SCristina Ciocan 					 "pin %u forcibly set to input mode\n",
1053c501d0b1SCristina Ciocan 					 offset);
1054c501d0b1SCristina Ciocan 			}
1055c501d0b1SCristina Ciocan 
1056c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
1057c501d0b1SCristina Ciocan 			conf |= BYT_PULL_ASSIGN_UP;
1058c501d0b1SCristina Ciocan 			ret = byt_set_pull_strength(&conf, arg);
1059c501d0b1SCristina Ciocan 
1060c501d0b1SCristina Ciocan 			break;
1061658b476cSCristina Ciocan 		case PIN_CONFIG_INPUT_DEBOUNCE:
106204ff5a09SAndy Shevchenko 			debounce = readl(db_reg);
1063658b476cSCristina Ciocan 
1064827e1579SAndy Shevchenko 			if (arg)
1065827e1579SAndy Shevchenko 				conf |= BYT_DEBOUNCE_EN;
1066827e1579SAndy Shevchenko 			else
1067827e1579SAndy Shevchenko 				conf &= ~BYT_DEBOUNCE_EN;
1068827e1579SAndy Shevchenko 
1069658b476cSCristina Ciocan 			switch (arg) {
1070658b476cSCristina Ciocan 			case 375:
10715f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
107204ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_375US;
1073658b476cSCristina Ciocan 				break;
1074658b476cSCristina Ciocan 			case 750:
10755f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
107604ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_750US;
1077658b476cSCristina Ciocan 				break;
1078658b476cSCristina Ciocan 			case 1500:
10795f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
108004ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_1500US;
1081658b476cSCristina Ciocan 				break;
1082658b476cSCristina Ciocan 			case 3000:
10835f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
108404ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_3MS;
1085658b476cSCristina Ciocan 				break;
1086658b476cSCristina Ciocan 			case 6000:
10875f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
108804ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_6MS;
1089658b476cSCristina Ciocan 				break;
1090658b476cSCristina Ciocan 			case 12000:
10915f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
109204ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_12MS;
1093658b476cSCristina Ciocan 				break;
1094658b476cSCristina Ciocan 			case 24000:
10955f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
109604ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_24MS;
1097658b476cSCristina Ciocan 				break;
1098658b476cSCristina Ciocan 			default:
1099827e1579SAndy Shevchenko 				if (arg)
1100658b476cSCristina Ciocan 					ret = -EINVAL;
1101827e1579SAndy Shevchenko 				break;
1102658b476cSCristina Ciocan 			}
1103658b476cSCristina Ciocan 
110404ff5a09SAndy Shevchenko 			if (!ret)
110504ff5a09SAndy Shevchenko 				writel(debounce, db_reg);
1106658b476cSCristina Ciocan 			break;
1107c501d0b1SCristina Ciocan 		default:
1108c501d0b1SCristina Ciocan 			ret = -ENOTSUPP;
1109c501d0b1SCristina Ciocan 		}
1110c501d0b1SCristina Ciocan 
1111c501d0b1SCristina Ciocan 		if (ret)
1112c501d0b1SCristina Ciocan 			break;
1113c501d0b1SCristina Ciocan 	}
1114c501d0b1SCristina Ciocan 
1115c501d0b1SCristina Ciocan 	if (!ret)
1116c501d0b1SCristina Ciocan 		writel(conf, conf_reg);
1117c501d0b1SCristina Ciocan 
111840ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1119c501d0b1SCristina Ciocan 
1120c501d0b1SCristina Ciocan 	return ret;
1121c501d0b1SCristina Ciocan }
1122c501d0b1SCristina Ciocan 
1123c501d0b1SCristina Ciocan static const struct pinconf_ops byt_pinconf_ops = {
1124c501d0b1SCristina Ciocan 	.is_generic	= true,
1125c501d0b1SCristina Ciocan 	.pin_config_get	= byt_pin_config_get,
1126c501d0b1SCristina Ciocan 	.pin_config_set	= byt_pin_config_set,
1127c501d0b1SCristina Ciocan };
1128c501d0b1SCristina Ciocan 
1129c501d0b1SCristina Ciocan static const struct pinctrl_desc byt_pinctrl_desc = {
1130c501d0b1SCristina Ciocan 	.pctlops	= &byt_pinctrl_ops,
1131c501d0b1SCristina Ciocan 	.pmxops		= &byt_pinmux_ops,
1132c501d0b1SCristina Ciocan 	.confops	= &byt_pinconf_ops,
1133c501d0b1SCristina Ciocan 	.owner		= THIS_MODULE,
1134c501d0b1SCristina Ciocan };
1135c501d0b1SCristina Ciocan 
1136939330d7SAndy Shevchenko static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset)
11375fae8b86SMika Westerberg {
11385d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1139c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
114039ce8150SMika Westerberg 	unsigned long flags;
114139ce8150SMika Westerberg 	u32 val;
114239ce8150SMika Westerberg 
114340ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
114439ce8150SMika Westerberg 	val = readl(reg);
114540ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
114639ce8150SMika Westerberg 
11473bde8771SLinus Walleij 	return !!(val & BYT_LEVEL);
11485fae8b86SMika Westerberg }
11495fae8b86SMika Westerberg 
1150939330d7SAndy Shevchenko static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
11515fae8b86SMika Westerberg {
11525d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1153c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
11545fae8b86SMika Westerberg 	unsigned long flags;
11555fae8b86SMika Westerberg 	u32 old_val;
11565fae8b86SMika Westerberg 
115786e3ef81SCristina Ciocan 	if (!reg)
115886e3ef81SCristina Ciocan 		return;
115986e3ef81SCristina Ciocan 
116040ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
11615fae8b86SMika Westerberg 	old_val = readl(reg);
11625fae8b86SMika Westerberg 	if (value)
11635fae8b86SMika Westerberg 		writel(old_val | BYT_LEVEL, reg);
11645fae8b86SMika Westerberg 	else
11655fae8b86SMika Westerberg 		writel(old_val & ~BYT_LEVEL, reg);
116640ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
11675fae8b86SMika Westerberg }
11685fae8b86SMika Westerberg 
116986e3ef81SCristina Ciocan static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
11705fae8b86SMika Westerberg {
11715d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1172c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
11735fae8b86SMika Westerberg 	unsigned long flags;
11745fae8b86SMika Westerberg 	u32 value;
11755fae8b86SMika Westerberg 
117686e3ef81SCristina Ciocan 	if (!reg)
117786e3ef81SCristina Ciocan 		return -EINVAL;
117886e3ef81SCristina Ciocan 
117940ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
118086e3ef81SCristina Ciocan 	value = readl(reg);
118140ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
11825fae8b86SMika Westerberg 
118386e3ef81SCristina Ciocan 	if (!(value & BYT_OUTPUT_EN))
1184faf86c0cSMatti Vaittinen 		return GPIO_LINE_DIRECTION_OUT;
118586e3ef81SCristina Ciocan 	if (!(value & BYT_INPUT_EN))
1186faf86c0cSMatti Vaittinen 		return GPIO_LINE_DIRECTION_IN;
118786e3ef81SCristina Ciocan 
118886e3ef81SCristina Ciocan 	return -EINVAL;
11895fae8b86SMika Westerberg }
11905fae8b86SMika Westerberg 
119186e3ef81SCristina Ciocan static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
11925fae8b86SMika Westerberg {
1193156abe29SHans de Goede 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1194156abe29SHans de Goede 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
1195156abe29SHans de Goede 	unsigned long flags;
1196156abe29SHans de Goede 	u32 reg;
1197156abe29SHans de Goede 
1198156abe29SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
1199156abe29SHans de Goede 
1200156abe29SHans de Goede 	reg = readl(val_reg);
1201156abe29SHans de Goede 	reg &= ~BYT_DIR_MASK;
1202156abe29SHans de Goede 	reg |= BYT_OUTPUT_EN;
1203156abe29SHans de Goede 	writel(reg, val_reg);
1204156abe29SHans de Goede 
1205156abe29SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1206156abe29SHans de Goede 	return 0;
120786e3ef81SCristina Ciocan }
12085fae8b86SMika Westerberg 
1209156abe29SHans de Goede /*
1210156abe29SHans de Goede  * Note despite the temptation this MUST NOT be converted into a call to
1211156abe29SHans de Goede  * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this
1212156abe29SHans de Goede  * MUST be done as a single BYT_VAL_REG register write.
1213156abe29SHans de Goede  * See the commit message of the commit adding this comment for details.
1214156abe29SHans de Goede  */
121586e3ef81SCristina Ciocan static int byt_gpio_direction_output(struct gpio_chip *chip,
121686e3ef81SCristina Ciocan 				     unsigned int offset, int value)
121786e3ef81SCristina Ciocan {
1218156abe29SHans de Goede 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1219156abe29SHans de Goede 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
1220156abe29SHans de Goede 	unsigned long flags;
1221156abe29SHans de Goede 	u32 reg;
12225fae8b86SMika Westerberg 
1223156abe29SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
122486e3ef81SCristina Ciocan 
1225156abe29SHans de Goede 	byt_gpio_direct_irq_check(vg, offset);
12265fae8b86SMika Westerberg 
1227156abe29SHans de Goede 	reg = readl(val_reg);
1228156abe29SHans de Goede 	reg &= ~BYT_DIR_MASK;
1229156abe29SHans de Goede 	if (value)
1230156abe29SHans de Goede 		reg |= BYT_LEVEL;
1231156abe29SHans de Goede 	else
1232156abe29SHans de Goede 		reg &= ~BYT_LEVEL;
1233156abe29SHans de Goede 
1234156abe29SHans de Goede 	writel(reg, val_reg);
1235156abe29SHans de Goede 
1236156abe29SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
12375fae8b86SMika Westerberg 	return 0;
12385fae8b86SMika Westerberg }
12395fae8b86SMika Westerberg 
12405fae8b86SMika Westerberg static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
12415fae8b86SMika Westerberg {
12425d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
12435fae8b86SMika Westerberg 	int i;
124486e3ef81SCristina Ciocan 	u32 conf0, val;
12455fae8b86SMika Westerberg 
12465d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
124734e65670SAndy Shevchenko 		const struct intel_community *comm;
12485fae8b86SMika Westerberg 		const char *pull_str = NULL;
12495fae8b86SMika Westerberg 		const char *pull = NULL;
125086e3ef81SCristina Ciocan 		void __iomem *reg;
125178e1c896SMika Westerberg 		unsigned long flags;
12525fae8b86SMika Westerberg 		const char *label;
125386e3ef81SCristina Ciocan 		unsigned int pin;
125478e1c896SMika Westerberg 
125540ecab55SHans de Goede 		raw_spin_lock_irqsave(&byt_lock, flags);
12565d33e0ebSAndy Shevchenko 		pin = vg->soc->pins[i].number;
125786e3ef81SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
125886e3ef81SCristina Ciocan 		if (!reg) {
125986e3ef81SCristina Ciocan 			seq_printf(s,
126086e3ef81SCristina Ciocan 				   "Could not retrieve pin %i conf0 reg\n",
126186e3ef81SCristina Ciocan 				   pin);
126240ecab55SHans de Goede 			raw_spin_unlock_irqrestore(&byt_lock, flags);
126386e3ef81SCristina Ciocan 			continue;
126486e3ef81SCristina Ciocan 		}
126586e3ef81SCristina Ciocan 		conf0 = readl(reg);
126686e3ef81SCristina Ciocan 
126786e3ef81SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
126886e3ef81SCristina Ciocan 		if (!reg) {
126986e3ef81SCristina Ciocan 			seq_printf(s,
127086e3ef81SCristina Ciocan 				   "Could not retrieve pin %i val reg\n", pin);
127140ecab55SHans de Goede 			raw_spin_unlock_irqrestore(&byt_lock, flags);
127222bbd21bSDan Carpenter 			continue;
127386e3ef81SCristina Ciocan 		}
127486e3ef81SCristina Ciocan 		val = readl(reg);
127540ecab55SHans de Goede 		raw_spin_unlock_irqrestore(&byt_lock, flags);
12765fae8b86SMika Westerberg 
127786e3ef81SCristina Ciocan 		comm = byt_get_community(vg, pin);
127886e3ef81SCristina Ciocan 		if (!comm) {
127986e3ef81SCristina Ciocan 			seq_printf(s,
128086e3ef81SCristina Ciocan 				   "Could not get community for pin %i\n", pin);
128186e3ef81SCristina Ciocan 			continue;
128286e3ef81SCristina Ciocan 		}
12835fae8b86SMika Westerberg 		label = gpiochip_is_requested(chip, i);
12845fae8b86SMika Westerberg 		if (!label)
12855fae8b86SMika Westerberg 			label = "Unrequested";
12865fae8b86SMika Westerberg 
12875fae8b86SMika Westerberg 		switch (conf0 & BYT_PULL_ASSIGN_MASK) {
12885fae8b86SMika Westerberg 		case BYT_PULL_ASSIGN_UP:
12895fae8b86SMika Westerberg 			pull = "up";
12905fae8b86SMika Westerberg 			break;
12915fae8b86SMika Westerberg 		case BYT_PULL_ASSIGN_DOWN:
12925fae8b86SMika Westerberg 			pull = "down";
12935fae8b86SMika Westerberg 			break;
12945fae8b86SMika Westerberg 		}
12955fae8b86SMika Westerberg 
12965fae8b86SMika Westerberg 		switch (conf0 & BYT_PULL_STR_MASK) {
12975fae8b86SMika Westerberg 		case BYT_PULL_STR_2K:
12985fae8b86SMika Westerberg 			pull_str = "2k";
12995fae8b86SMika Westerberg 			break;
13005fae8b86SMika Westerberg 		case BYT_PULL_STR_10K:
13015fae8b86SMika Westerberg 			pull_str = "10k";
13025fae8b86SMika Westerberg 			break;
13035fae8b86SMika Westerberg 		case BYT_PULL_STR_20K:
13045fae8b86SMika Westerberg 			pull_str = "20k";
13055fae8b86SMika Westerberg 			break;
13065fae8b86SMika Westerberg 		case BYT_PULL_STR_40K:
13075fae8b86SMika Westerberg 			pull_str = "40k";
13085fae8b86SMika Westerberg 			break;
13095fae8b86SMika Westerberg 		}
13105fae8b86SMika Westerberg 
13115fae8b86SMika Westerberg 		seq_printf(s,
13125fae8b86SMika Westerberg 			   " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
131386e3ef81SCristina Ciocan 			   pin,
13145fae8b86SMika Westerberg 			   label,
13155fae8b86SMika Westerberg 			   val & BYT_INPUT_EN ? "  " : "in",
13165fae8b86SMika Westerberg 			   val & BYT_OUTPUT_EN ? "   " : "out",
13175fae8b86SMika Westerberg 			   val & BYT_LEVEL ? "hi" : "lo",
13183655a1caSAlexander Stein 			   comm->pad_map[i], comm->pad_map[i] * 16,
13195fae8b86SMika Westerberg 			   conf0 & 0x7,
13205fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_NEG ? " fall" : "     ",
13215fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_POS ? " rise" : "     ",
13225fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_LVL ? " level" : "      ");
13235fae8b86SMika Westerberg 
13245fae8b86SMika Westerberg 		if (pull && pull_str)
13255fae8b86SMika Westerberg 			seq_printf(s, " %-4s %-3s", pull, pull_str);
13265fae8b86SMika Westerberg 		else
13275fae8b86SMika Westerberg 			seq_puts(s, "          ");
13285fae8b86SMika Westerberg 
13295fae8b86SMika Westerberg 		if (conf0 & BYT_IODEN)
13305fae8b86SMika Westerberg 			seq_puts(s, " open-drain");
13315fae8b86SMika Westerberg 
13325fae8b86SMika Westerberg 		seq_puts(s, "\n");
13335fae8b86SMika Westerberg 	}
13345fae8b86SMika Westerberg }
13355fae8b86SMika Westerberg 
133686e3ef81SCristina Ciocan static const struct gpio_chip byt_gpio_chip = {
133786e3ef81SCristina Ciocan 	.owner			= THIS_MODULE,
133886e3ef81SCristina Ciocan 	.request		= gpiochip_generic_request,
133986e3ef81SCristina Ciocan 	.free			= gpiochip_generic_free,
134086e3ef81SCristina Ciocan 	.get_direction		= byt_gpio_get_direction,
134186e3ef81SCristina Ciocan 	.direction_input	= byt_gpio_direction_input,
134286e3ef81SCristina Ciocan 	.direction_output	= byt_gpio_direction_output,
134386e3ef81SCristina Ciocan 	.get			= byt_gpio_get,
134486e3ef81SCristina Ciocan 	.set			= byt_gpio_set,
1345ccd025eaSAndy Shevchenko 	.set_config		= gpiochip_generic_config,
134686e3ef81SCristina Ciocan 	.dbg_show		= byt_gpio_dbg_show,
134786e3ef81SCristina Ciocan };
134886e3ef81SCristina Ciocan 
134931e4329fSMika Westerberg static void byt_irq_ack(struct irq_data *d)
135031e4329fSMika Westerberg {
135131e4329fSMika Westerberg 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
13525d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(gc);
13536d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
135431e4329fSMika Westerberg 	void __iomem *reg;
135531e4329fSMika Westerberg 
13566d209b42SAndy Shevchenko 	reg = byt_gpio_reg(vg, hwirq, BYT_INT_STAT_REG);
13579f573b98SCristina Ciocan 	if (!reg)
13589f573b98SCristina Ciocan 		return;
13599f573b98SCristina Ciocan 
136040ecab55SHans de Goede 	raw_spin_lock(&byt_lock);
13616d209b42SAndy Shevchenko 	writel(BIT(hwirq % 32), reg);
136240ecab55SHans de Goede 	raw_spin_unlock(&byt_lock);
136331e4329fSMika Westerberg }
136431e4329fSMika Westerberg 
13659f573b98SCristina Ciocan static void byt_irq_mask(struct irq_data *d)
13669f573b98SCristina Ciocan {
13679f573b98SCristina Ciocan 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
13685d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(gc);
13696d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
13709f573b98SCristina Ciocan 
13716d209b42SAndy Shevchenko 	byt_gpio_clear_triggering(vg, hwirq);
13726d209b42SAndy Shevchenko 	gpiochip_disable_irq(gc, hwirq);
13739f573b98SCristina Ciocan }
13749f573b98SCristina Ciocan 
13755fae8b86SMika Westerberg static void byt_irq_unmask(struct irq_data *d)
13765fae8b86SMika Westerberg {
137731e4329fSMika Westerberg 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
13785d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(gc);
13796d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
138031e4329fSMika Westerberg 	unsigned long flags;
138131e4329fSMika Westerberg 	void __iomem *reg;
138231e4329fSMika Westerberg 	u32 value;
138331e4329fSMika Westerberg 
13846d209b42SAndy Shevchenko 	gpiochip_enable_irq(gc, hwirq);
13856d209b42SAndy Shevchenko 
13866d209b42SAndy Shevchenko 	reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG);
13879f573b98SCristina Ciocan 	if (!reg)
13889f573b98SCristina Ciocan 		return;
138978e1c896SMika Westerberg 
139040ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
139131e4329fSMika Westerberg 	value = readl(reg);
139231e4329fSMika Westerberg 
139331e4329fSMika Westerberg 	switch (irqd_get_trigger_type(d)) {
139431e4329fSMika Westerberg 	case IRQ_TYPE_LEVEL_HIGH:
139531e4329fSMika Westerberg 		value |= BYT_TRIG_LVL;
13960a093020SGustavo A. R. Silva 		fallthrough;
139731e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_RISING:
139831e4329fSMika Westerberg 		value |= BYT_TRIG_POS;
139931e4329fSMika Westerberg 		break;
140031e4329fSMika Westerberg 	case IRQ_TYPE_LEVEL_LOW:
140131e4329fSMika Westerberg 		value |= BYT_TRIG_LVL;
14020a093020SGustavo A. R. Silva 		fallthrough;
140331e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_FALLING:
140431e4329fSMika Westerberg 		value |= BYT_TRIG_NEG;
140531e4329fSMika Westerberg 		break;
140631e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_BOTH:
140731e4329fSMika Westerberg 		value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
140831e4329fSMika Westerberg 		break;
140931e4329fSMika Westerberg 	}
141031e4329fSMika Westerberg 
141131e4329fSMika Westerberg 	writel(value, reg);
141231e4329fSMika Westerberg 
141340ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
14145fae8b86SMika Westerberg }
14155fae8b86SMika Westerberg 
14169f573b98SCristina Ciocan static int byt_irq_type(struct irq_data *d, unsigned int type)
14175fae8b86SMika Westerberg {
14185d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
14196d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
14209f573b98SCristina Ciocan 	u32 value;
14219f573b98SCristina Ciocan 	unsigned long flags;
14226d209b42SAndy Shevchenko 	void __iomem *reg;
142331e4329fSMika Westerberg 
14246d209b42SAndy Shevchenko 	reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG);
14256d209b42SAndy Shevchenko 	if (!reg)
14269f573b98SCristina Ciocan 		return -EINVAL;
14279f573b98SCristina Ciocan 
142840ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
14299f573b98SCristina Ciocan 	value = readl(reg);
14309f573b98SCristina Ciocan 
14319f573b98SCristina Ciocan 	WARN(value & BYT_DIRECT_IRQ_EN,
14329f573b98SCristina Ciocan 	     "Bad pad config for io mode, force direct_irq_en bit clearing");
14339f573b98SCristina Ciocan 
14349f573b98SCristina Ciocan 	/* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
14359f573b98SCristina Ciocan 	 * are used to indicate high and low level triggering
14369f573b98SCristina Ciocan 	 */
14379f573b98SCristina Ciocan 	value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
14389f573b98SCristina Ciocan 		   BYT_TRIG_LVL);
14399291c65bSHans de Goede 	/* Enable glitch filtering */
14409291c65bSHans de Goede 	value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK |
14419291c65bSHans de Goede 		 BYT_GLITCH_F_FAST_CLK;
14429f573b98SCristina Ciocan 
14439f573b98SCristina Ciocan 	writel(value, reg);
14449f573b98SCristina Ciocan 
14459f573b98SCristina Ciocan 	if (type & IRQ_TYPE_EDGE_BOTH)
14469f573b98SCristina Ciocan 		irq_set_handler_locked(d, handle_edge_irq);
14479f573b98SCristina Ciocan 	else if (type & IRQ_TYPE_LEVEL_MASK)
14489f573b98SCristina Ciocan 		irq_set_handler_locked(d, handle_level_irq);
14499f573b98SCristina Ciocan 
145040ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
14519f573b98SCristina Ciocan 
14529f573b98SCristina Ciocan 	return 0;
14535fae8b86SMika Westerberg }
14545fae8b86SMika Westerberg 
14556d209b42SAndy Shevchenko static const struct irq_chip byt_gpio_irq_chip = {
14566d209b42SAndy Shevchenko 	.name		= "BYT-GPIO",
14576d209b42SAndy Shevchenko 	.irq_ack	= byt_irq_ack,
14586d209b42SAndy Shevchenko 	.irq_mask	= byt_irq_mask,
14596d209b42SAndy Shevchenko 	.irq_unmask	= byt_irq_unmask,
14606d209b42SAndy Shevchenko 	.irq_set_type	= byt_irq_type,
14616d209b42SAndy Shevchenko 	.flags		= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED | IRQCHIP_IMMUTABLE,
14626d209b42SAndy Shevchenko 	GPIOCHIP_IRQ_RESOURCE_HELPERS,
14636d209b42SAndy Shevchenko };
14646d209b42SAndy Shevchenko 
146571e6ca61SCristina Ciocan static void byt_gpio_irq_handler(struct irq_desc *desc)
146671e6ca61SCristina Ciocan {
146771e6ca61SCristina Ciocan 	struct irq_data *data = irq_desc_get_irq_data(desc);
14685d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(irq_desc_get_handler_data(desc));
146971e6ca61SCristina Ciocan 	struct irq_chip *chip = irq_data_get_irq_chip(data);
147071e6ca61SCristina Ciocan 	u32 base, pin;
147171e6ca61SCristina Ciocan 	void __iomem *reg;
147271e6ca61SCristina Ciocan 	unsigned long pending;
147371e6ca61SCristina Ciocan 
147471e6ca61SCristina Ciocan 	/* check from GPIO controller which pin triggered the interrupt */
147571e6ca61SCristina Ciocan 	for (base = 0; base < vg->chip.ngpio; base += 32) {
147671e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
147771e6ca61SCristina Ciocan 
147871e6ca61SCristina Ciocan 		if (!reg) {
1479990ec243SAndy Shevchenko 			dev_warn(vg->dev,
148071e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve interrupt status register\n",
148171e6ca61SCristina Ciocan 				 base);
148271e6ca61SCristina Ciocan 			continue;
148371e6ca61SCristina Ciocan 		}
148471e6ca61SCristina Ciocan 
148540ecab55SHans de Goede 		raw_spin_lock(&byt_lock);
148671e6ca61SCristina Ciocan 		pending = readl(reg);
148740ecab55SHans de Goede 		raw_spin_unlock(&byt_lock);
1488a9cb09b7SMarc Zyngier 		for_each_set_bit(pin, &pending, 32)
1489a9cb09b7SMarc Zyngier 			generic_handle_domain_irq(vg->chip.irq.domain, base + pin);
149071e6ca61SCristina Ciocan 	}
149171e6ca61SCristina Ciocan 	chip->irq_eoi(data);
149271e6ca61SCristina Ciocan }
149371e6ca61SCristina Ciocan 
1494689e0088SHans de Goede static bool byt_direct_irq_sanity_check(struct intel_pinctrl *vg, int pin, u32 conf0)
1495689e0088SHans de Goede {
1496689e0088SHans de Goede 	int direct_irq, ioapic_direct_irq_base;
1497689e0088SHans de Goede 	u8 *match, direct_irq_mux[16];
1498689e0088SHans de Goede 	u32 trig;
1499689e0088SHans de Goede 
1500689e0088SHans de Goede 	memcpy_fromio(direct_irq_mux, vg->communities->pad_regs + BYT_DIRECT_IRQ_REG,
1501689e0088SHans de Goede 		      sizeof(direct_irq_mux));
1502689e0088SHans de Goede 	match = memchr(direct_irq_mux, pin, sizeof(direct_irq_mux));
1503689e0088SHans de Goede 	if (!match) {
1504689e0088SHans de Goede 		dev_warn(vg->dev, FW_BUG "pin %i: direct_irq_en set but no IRQ assigned, clearing\n", pin);
1505689e0088SHans de Goede 		return false;
1506689e0088SHans de Goede 	}
1507689e0088SHans de Goede 
1508689e0088SHans de Goede 	direct_irq = match - direct_irq_mux;
1509689e0088SHans de Goede 	/* Base IO-APIC pin numbers come from atom-e3800-family-datasheet.pdf */
1510689e0088SHans de Goede 	ioapic_direct_irq_base = (vg->communities->npins == BYT_NGPIO_SCORE) ? 51 : 67;
1511689e0088SHans de Goede 	dev_dbg(vg->dev, "Pin %i: uses direct IRQ %d (IO-APIC %d)\n", pin,
1512689e0088SHans de Goede 		direct_irq, direct_irq + ioapic_direct_irq_base);
1513689e0088SHans de Goede 
1514689e0088SHans de Goede 	/*
1515689e0088SHans de Goede 	 * Testing has shown that the way direct IRQs work is that the combination of the
1516689e0088SHans de Goede 	 * direct-irq-en flag and the direct IRQ mux connect the output of the GPIO's IRQ
1517689e0088SHans de Goede 	 * trigger block, which normally sets the status flag in the IRQ status reg at
1518689e0088SHans de Goede 	 * 0x800, to one of the IO-APIC pins according to the mux registers.
1519689e0088SHans de Goede 	 *
1520689e0088SHans de Goede 	 * This means that:
1521689e0088SHans de Goede 	 * 1. The TRIG_MASK bits must be set to configure the GPIO's IRQ trigger block
1522689e0088SHans de Goede 	 * 2. The TRIG_LVL bit *must* be set, so that the GPIO's input value is directly
1523689e0088SHans de Goede 	 *    passed (1:1 or inverted) to the IO-APIC pin, if TRIG_LVL is not set,
1524689e0088SHans de Goede 	 *    selecting edge mode operation then on the first edge the IO-APIC pin goes
1525689e0088SHans de Goede 	 *    high, but since no write-to-clear write will be done to the IRQ status reg
1526689e0088SHans de Goede 	 *    at 0x800, the detected edge condition will never get cleared.
1527689e0088SHans de Goede 	 */
1528689e0088SHans de Goede 	trig = conf0 & BYT_TRIG_MASK;
1529689e0088SHans de Goede 	if (trig != (BYT_TRIG_POS | BYT_TRIG_LVL) &&
1530689e0088SHans de Goede 	    trig != (BYT_TRIG_NEG | BYT_TRIG_LVL)) {
1531689e0088SHans de Goede 		dev_warn(vg->dev, FW_BUG "pin %i: direct_irq_en set without trigger (conf0: %xh), clearing\n",
1532689e0088SHans de Goede 			 pin, conf0);
1533689e0088SHans de Goede 		return false;
1534689e0088SHans de Goede 	}
1535689e0088SHans de Goede 
1536689e0088SHans de Goede 	return true;
1537689e0088SHans de Goede }
1538689e0088SHans de Goede 
15395fbe5b58SLinus Walleij static void byt_init_irq_valid_mask(struct gpio_chip *chip,
15405fbe5b58SLinus Walleij 				    unsigned long *valid_mask,
15415fbe5b58SLinus Walleij 				    unsigned int ngpios)
15425fbe5b58SLinus Walleij {
15435d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
15445fae8b86SMika Westerberg 	void __iomem *reg;
1545e70982b3SAndy Shevchenko 	u32 value;
154695f0972cSMika Westerberg 	int i;
154795f0972cSMika Westerberg 
154895f0972cSMika Westerberg 	/*
154995f0972cSMika Westerberg 	 * Clear interrupt triggers for all pins that are GPIOs and
155095f0972cSMika Westerberg 	 * do not use direct IRQ mode. This will prevent spurious
155195f0972cSMika Westerberg 	 * interrupts from misconfigured pins.
155295f0972cSMika Westerberg 	 */
15535d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
15545d33e0ebSAndy Shevchenko 		unsigned int pin = vg->soc->pins[i].number;
155571e6ca61SCristina Ciocan 
155671e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
155771e6ca61SCristina Ciocan 		if (!reg) {
1558990ec243SAndy Shevchenko 			dev_warn(vg->dev,
155971e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve conf0 register\n",
156071e6ca61SCristina Ciocan 				 i);
156171e6ca61SCristina Ciocan 			continue;
156271e6ca61SCristina Ciocan 		}
156371e6ca61SCristina Ciocan 
156471e6ca61SCristina Ciocan 		value = readl(reg);
156549c03096SAndy Shevchenko 		if (value & BYT_DIRECT_IRQ_EN) {
1566689e0088SHans de Goede 			if (byt_direct_irq_sanity_check(vg, i, value)) {
1567e70982b3SAndy Shevchenko 				clear_bit(i, valid_mask);
1568689e0088SHans de Goede 			} else {
1569689e0088SHans de Goede 				value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS |
1570689e0088SHans de Goede 					   BYT_TRIG_NEG | BYT_TRIG_LVL);
1571689e0088SHans de Goede 				writel(value, reg);
1572689e0088SHans de Goede 			}
157349c03096SAndy Shevchenko 		} else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) {
157495f0972cSMika Westerberg 			byt_gpio_clear_triggering(vg, i);
1575990ec243SAndy Shevchenko 			dev_dbg(vg->dev, "disabling GPIO %d\n", i);
157695f0972cSMika Westerberg 		}
157795f0972cSMika Westerberg 	}
1578e70982b3SAndy Shevchenko }
1579e70982b3SAndy Shevchenko 
1580e70982b3SAndy Shevchenko static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
1581e70982b3SAndy Shevchenko {
15825d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1583e70982b3SAndy Shevchenko 	void __iomem *reg;
1584e70982b3SAndy Shevchenko 	u32 base, value;
15855fae8b86SMika Westerberg 
15865fae8b86SMika Westerberg 	/* clear interrupt status trigger registers */
15875d33e0ebSAndy Shevchenko 	for (base = 0; base < vg->soc->npins; base += 32) {
1588c501d0b1SCristina Ciocan 		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
158971e6ca61SCristina Ciocan 
159071e6ca61SCristina Ciocan 		if (!reg) {
1591990ec243SAndy Shevchenko 			dev_warn(vg->dev,
159271e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve irq status reg\n",
159371e6ca61SCristina Ciocan 				 base);
159471e6ca61SCristina Ciocan 			continue;
159571e6ca61SCristina Ciocan 		}
159671e6ca61SCristina Ciocan 
15975fae8b86SMika Westerberg 		writel(0xffffffff, reg);
15985fae8b86SMika Westerberg 		/* make sure trigger bits are cleared, if not then a pin
15995fae8b86SMika Westerberg 		   might be misconfigured in bios */
16005fae8b86SMika Westerberg 		value = readl(reg);
16015fae8b86SMika Westerberg 		if (value)
1602990ec243SAndy Shevchenko 			dev_err(vg->dev,
1603973232e2SAlexander Stein 				"GPIO interrupt error, pins misconfigured. INT_STAT%u: 0x%08x\n",
1604973232e2SAlexander Stein 				base / 32, value);
16055fae8b86SMika Westerberg 	}
1606ca8a958eSAndy Shevchenko 
1607ca8a958eSAndy Shevchenko 	return 0;
16085fae8b86SMika Westerberg }
16095fae8b86SMika Westerberg 
1610ed3c1564SAndy Shevchenko static int byt_gpio_add_pin_ranges(struct gpio_chip *chip)
1611ed3c1564SAndy Shevchenko {
16125d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1613990ec243SAndy Shevchenko 	struct device *dev = vg->dev;
1614ed3c1564SAndy Shevchenko 	int ret;
1615ed3c1564SAndy Shevchenko 
16165d33e0ebSAndy Shevchenko 	ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins);
1617ed3c1564SAndy Shevchenko 	if (ret)
1618ed3c1564SAndy Shevchenko 		dev_err(dev, "failed to add GPIO pin range\n");
1619ed3c1564SAndy Shevchenko 
1620ed3c1564SAndy Shevchenko 	return ret;
1621ed3c1564SAndy Shevchenko }
1622ed3c1564SAndy Shevchenko 
16235d33e0ebSAndy Shevchenko static int byt_gpio_probe(struct intel_pinctrl *vg)
16245fae8b86SMika Westerberg {
1625990ec243SAndy Shevchenko 	struct platform_device *pdev = to_platform_device(vg->dev);
16265fae8b86SMika Westerberg 	struct gpio_chip *gc;
1627f86a1bb5SAndy Shevchenko 	int irq, ret;
16285fae8b86SMika Westerberg 
162971e6ca61SCristina Ciocan 	/* Set up gpio chip */
163071e6ca61SCristina Ciocan 	vg->chip	= byt_gpio_chip;
16315fae8b86SMika Westerberg 	gc		= &vg->chip;
1632990ec243SAndy Shevchenko 	gc->label	= dev_name(vg->dev);
16335fae8b86SMika Westerberg 	gc->base	= -1;
16345fae8b86SMika Westerberg 	gc->can_sleep	= false;
1635ed3c1564SAndy Shevchenko 	gc->add_pin_ranges = byt_gpio_add_pin_ranges;
1636990ec243SAndy Shevchenko 	gc->parent	= vg->dev;
16375d33e0ebSAndy Shevchenko 	gc->ngpio	= vg->soc->npins;
16385fae8b86SMika Westerberg 
1639fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP
16405d33e0ebSAndy Shevchenko 	vg->context.pads = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->context.pads),
16415d33e0ebSAndy Shevchenko 					GFP_KERNEL);
16425d33e0ebSAndy Shevchenko 	if (!vg->context.pads)
1643d6cb7722SAditya Pakki 		return -ENOMEM;
1644fcc18debSMika Westerberg #endif
16455fae8b86SMika Westerberg 
16465fae8b86SMika Westerberg 	/* set up interrupts  */
1647f86a1bb5SAndy Shevchenko 	irq = platform_get_irq_optional(pdev, 0);
1648f86a1bb5SAndy Shevchenko 	if (irq > 0) {
1649ca8a958eSAndy Shevchenko 		struct gpio_irq_chip *girq;
1650ca8a958eSAndy Shevchenko 
1651ca8a958eSAndy Shevchenko 		girq = &gc->irq;
16526d209b42SAndy Shevchenko 		gpio_irq_chip_set_chip(girq, &byt_gpio_irq_chip);
1653ca8a958eSAndy Shevchenko 		girq->init_hw = byt_gpio_irq_init_hw;
1654ab68b220SAndy Shevchenko 		girq->init_valid_mask = byt_init_irq_valid_mask;
1655ca8a958eSAndy Shevchenko 		girq->parent_handler = byt_gpio_irq_handler;
1656ca8a958eSAndy Shevchenko 		girq->num_parents = 1;
1657990ec243SAndy Shevchenko 		girq->parents = devm_kcalloc(vg->dev, girq->num_parents,
1658ca8a958eSAndy Shevchenko 					     sizeof(*girq->parents), GFP_KERNEL);
1659ca8a958eSAndy Shevchenko 		if (!girq->parents)
1660ca8a958eSAndy Shevchenko 			return -ENOMEM;
1661f86a1bb5SAndy Shevchenko 		girq->parents[0] = irq;
1662ca8a958eSAndy Shevchenko 		girq->default_type = IRQ_TYPE_NONE;
1663ca8a958eSAndy Shevchenko 		girq->handler = handle_bad_irq;
16645fae8b86SMika Westerberg 	}
16655fae8b86SMika Westerberg 
1666990ec243SAndy Shevchenko 	ret = devm_gpiochip_add_data(vg->dev, gc, vg);
1667ca8a958eSAndy Shevchenko 	if (ret) {
1668990ec243SAndy Shevchenko 		dev_err(vg->dev, "failed adding byt-gpio chip\n");
1669ca8a958eSAndy Shevchenko 		return ret;
16705fae8b86SMika Westerberg 	}
16715fae8b86SMika Westerberg 
167271e6ca61SCristina Ciocan 	return ret;
167371e6ca61SCristina Ciocan }
167471e6ca61SCristina Ciocan 
16755d33e0ebSAndy Shevchenko static int byt_set_soc_data(struct intel_pinctrl *vg,
16765d33e0ebSAndy Shevchenko 			    const struct intel_pinctrl_soc_data *soc)
167771e6ca61SCristina Ciocan {
1678990ec243SAndy Shevchenko 	struct platform_device *pdev = to_platform_device(vg->dev);
167971e6ca61SCristina Ciocan 	int i;
168071e6ca61SCristina Ciocan 
16815d33e0ebSAndy Shevchenko 	vg->soc = soc;
16825d33e0ebSAndy Shevchenko 
16835d33e0ebSAndy Shevchenko 	vg->ncommunities = vg->soc->ncommunities;
16845d33e0ebSAndy Shevchenko 	vg->communities = devm_kcalloc(vg->dev, vg->ncommunities,
16855d33e0ebSAndy Shevchenko 				       sizeof(*vg->communities), GFP_KERNEL);
16865d33e0ebSAndy Shevchenko 	if (!vg->communities)
168771e6ca61SCristina Ciocan 		return -ENOMEM;
168871e6ca61SCristina Ciocan 
16895d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->ncommunities; i++) {
16905d33e0ebSAndy Shevchenko 		struct intel_community *comm = vg->communities + i;
169171e6ca61SCristina Ciocan 
16925d33e0ebSAndy Shevchenko 		*comm = vg->soc->communities[i];
169371e6ca61SCristina Ciocan 
1694990ec243SAndy Shevchenko 		comm->pad_regs = devm_platform_ioremap_resource(pdev, 0);
169534e65670SAndy Shevchenko 		if (IS_ERR(comm->pad_regs))
169634e65670SAndy Shevchenko 			return PTR_ERR(comm->pad_regs);
169771e6ca61SCristina Ciocan 	}
169871e6ca61SCristina Ciocan 
169971e6ca61SCristina Ciocan 	return 0;
170071e6ca61SCristina Ciocan }
170171e6ca61SCristina Ciocan 
170271e6ca61SCristina Ciocan static const struct acpi_device_id byt_gpio_acpi_match[] = {
170371e6ca61SCristina Ciocan 	{ "INT33B2", (kernel_ulong_t)byt_soc_data },
170471e6ca61SCristina Ciocan 	{ "INT33FC", (kernel_ulong_t)byt_soc_data },
170571e6ca61SCristina Ciocan 	{ }
170671e6ca61SCristina Ciocan };
170771e6ca61SCristina Ciocan 
170871e6ca61SCristina Ciocan static int byt_pinctrl_probe(struct platform_device *pdev)
170971e6ca61SCristina Ciocan {
1710ce7793e9SAndy Shevchenko 	const struct intel_pinctrl_soc_data *soc_data;
17112c02af70SAndy Shevchenko 	struct device *dev = &pdev->dev;
17125d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg;
1713ce7793e9SAndy Shevchenko 	int ret;
171471e6ca61SCristina Ciocan 
1715ce7793e9SAndy Shevchenko 	soc_data = intel_pinctrl_get_soc_data(pdev);
1716ce7793e9SAndy Shevchenko 	if (IS_ERR(soc_data))
1717ce7793e9SAndy Shevchenko 		return PTR_ERR(soc_data);
171871e6ca61SCristina Ciocan 
17192c02af70SAndy Shevchenko 	vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL);
172071e6ca61SCristina Ciocan 	if (!vg)
172171e6ca61SCristina Ciocan 		return -ENOMEM;
172271e6ca61SCristina Ciocan 
17232c02af70SAndy Shevchenko 	vg->dev = dev;
172471e6ca61SCristina Ciocan 	ret = byt_set_soc_data(vg, soc_data);
172571e6ca61SCristina Ciocan 	if (ret) {
17262c02af70SAndy Shevchenko 		dev_err(dev, "failed to set soc data\n");
172771e6ca61SCristina Ciocan 		return ret;
172871e6ca61SCristina Ciocan 	}
172971e6ca61SCristina Ciocan 
17305d33e0ebSAndy Shevchenko 	vg->pctldesc		= byt_pinctrl_desc;
17315d33e0ebSAndy Shevchenko 	vg->pctldesc.name	= dev_name(dev);
17325d33e0ebSAndy Shevchenko 	vg->pctldesc.pins	= vg->soc->pins;
17335d33e0ebSAndy Shevchenko 	vg->pctldesc.npins	= vg->soc->npins;
173471e6ca61SCristina Ciocan 
17355d33e0ebSAndy Shevchenko 	vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg);
17365d33e0ebSAndy Shevchenko 	if (IS_ERR(vg->pctldev)) {
17372c02af70SAndy Shevchenko 		dev_err(dev, "failed to register pinctrl driver\n");
17385d33e0ebSAndy Shevchenko 		return PTR_ERR(vg->pctldev);
173971e6ca61SCristina Ciocan 	}
174071e6ca61SCristina Ciocan 
174171e6ca61SCristina Ciocan 	ret = byt_gpio_probe(vg);
17420612413fSAndy Shevchenko 	if (ret)
174371e6ca61SCristina Ciocan 		return ret;
174471e6ca61SCristina Ciocan 
174571e6ca61SCristina Ciocan 	platform_set_drvdata(pdev, vg);
17462c02af70SAndy Shevchenko 	pm_runtime_enable(dev);
174771e6ca61SCristina Ciocan 
174871e6ca61SCristina Ciocan 	return 0;
174971e6ca61SCristina Ciocan }
175071e6ca61SCristina Ciocan 
1751fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP
1752fcc18debSMika Westerberg static int byt_gpio_suspend(struct device *dev)
1753fcc18debSMika Westerberg {
17545d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = dev_get_drvdata(dev);
175540ecab55SHans de Goede 	unsigned long flags;
1756fcc18debSMika Westerberg 	int i;
1757fcc18debSMika Westerberg 
175840ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
175940ecab55SHans de Goede 
17605d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
1761fcc18debSMika Westerberg 		void __iomem *reg;
1762fcc18debSMika Westerberg 		u32 value;
17635d33e0ebSAndy Shevchenko 		unsigned int pin = vg->soc->pins[i].number;
1764fcc18debSMika Westerberg 
176571e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
176671e6ca61SCristina Ciocan 		if (!reg) {
1767990ec243SAndy Shevchenko 			dev_warn(vg->dev,
176871e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve conf0 register\n",
176971e6ca61SCristina Ciocan 				 i);
177071e6ca61SCristina Ciocan 			continue;
177171e6ca61SCristina Ciocan 		}
1772fcc18debSMika Westerberg 		value = readl(reg) & BYT_CONF0_RESTORE_MASK;
17735d33e0ebSAndy Shevchenko 		vg->context.pads[i].conf0 = value;
1774fcc18debSMika Westerberg 
177571e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
1776fcc18debSMika Westerberg 		value = readl(reg) & BYT_VAL_RESTORE_MASK;
17775d33e0ebSAndy Shevchenko 		vg->context.pads[i].val = value;
1778fcc18debSMika Westerberg 	}
1779fcc18debSMika Westerberg 
178040ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1781fcc18debSMika Westerberg 	return 0;
1782fcc18debSMika Westerberg }
1783fcc18debSMika Westerberg 
1784fcc18debSMika Westerberg static int byt_gpio_resume(struct device *dev)
1785fcc18debSMika Westerberg {
17865d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = dev_get_drvdata(dev);
178740ecab55SHans de Goede 	unsigned long flags;
1788fcc18debSMika Westerberg 	int i;
1789fcc18debSMika Westerberg 
179040ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
179140ecab55SHans de Goede 
17925d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
1793fcc18debSMika Westerberg 		void __iomem *reg;
1794fcc18debSMika Westerberg 		u32 value;
17955d33e0ebSAndy Shevchenko 		unsigned int pin = vg->soc->pins[i].number;
1796fcc18debSMika Westerberg 
179771e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
179871e6ca61SCristina Ciocan 		if (!reg) {
1799990ec243SAndy Shevchenko 			dev_warn(vg->dev,
180071e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve conf0 register\n",
180171e6ca61SCristina Ciocan 				 i);
180271e6ca61SCristina Ciocan 			continue;
180371e6ca61SCristina Ciocan 		}
1804fcc18debSMika Westerberg 		value = readl(reg);
1805fcc18debSMika Westerberg 		if ((value & BYT_CONF0_RESTORE_MASK) !=
18065d33e0ebSAndy Shevchenko 		     vg->context.pads[i].conf0) {
1807fcc18debSMika Westerberg 			value &= ~BYT_CONF0_RESTORE_MASK;
18085d33e0ebSAndy Shevchenko 			value |= vg->context.pads[i].conf0;
1809fcc18debSMika Westerberg 			writel(value, reg);
1810fcc18debSMika Westerberg 			dev_info(dev, "restored pin %d conf0 %#08x", i, value);
1811fcc18debSMika Westerberg 		}
1812fcc18debSMika Westerberg 
181371e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
1814fcc18debSMika Westerberg 		value = readl(reg);
1815fcc18debSMika Westerberg 		if ((value & BYT_VAL_RESTORE_MASK) !=
18165d33e0ebSAndy Shevchenko 		     vg->context.pads[i].val) {
1817fcc18debSMika Westerberg 			u32 v;
1818fcc18debSMika Westerberg 
1819fcc18debSMika Westerberg 			v = value & ~BYT_VAL_RESTORE_MASK;
18205d33e0ebSAndy Shevchenko 			v |= vg->context.pads[i].val;
1821fcc18debSMika Westerberg 			if (v != value) {
1822fcc18debSMika Westerberg 				writel(v, reg);
1823fcc18debSMika Westerberg 				dev_dbg(dev, "restored pin %d val %#08x\n",
1824fcc18debSMika Westerberg 					i, v);
1825fcc18debSMika Westerberg 			}
1826fcc18debSMika Westerberg 		}
1827fcc18debSMika Westerberg 	}
1828fcc18debSMika Westerberg 
182940ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1830fcc18debSMika Westerberg 	return 0;
1831fcc18debSMika Westerberg }
1832fcc18debSMika Westerberg #endif
1833fcc18debSMika Westerberg 
1834ec879f12SMika Westerberg #ifdef CONFIG_PM
18355fae8b86SMika Westerberg static int byt_gpio_runtime_suspend(struct device *dev)
18365fae8b86SMika Westerberg {
18375fae8b86SMika Westerberg 	return 0;
18385fae8b86SMika Westerberg }
18395fae8b86SMika Westerberg 
18405fae8b86SMika Westerberg static int byt_gpio_runtime_resume(struct device *dev)
18415fae8b86SMika Westerberg {
18425fae8b86SMika Westerberg 	return 0;
18435fae8b86SMika Westerberg }
1844ec879f12SMika Westerberg #endif
18455fae8b86SMika Westerberg 
18465fae8b86SMika Westerberg static const struct dev_pm_ops byt_gpio_pm_ops = {
1847fcc18debSMika Westerberg 	SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume)
1848fcc18debSMika Westerberg 	SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume,
1849fcc18debSMika Westerberg 			   NULL)
18505fae8b86SMika Westerberg };
18515fae8b86SMika Westerberg 
18525fae8b86SMika Westerberg static struct platform_driver byt_gpio_driver = {
185371e6ca61SCristina Ciocan 	.probe          = byt_pinctrl_probe,
18545fae8b86SMika Westerberg 	.driver         = {
18555fae8b86SMika Westerberg 		.name			= "byt_gpio",
18565fae8b86SMika Westerberg 		.pm			= &byt_gpio_pm_ops,
1857e87daf0bSAndy Shevchenko 		.acpi_match_table	= byt_gpio_acpi_match,
1858360943a8SPaul Gortmaker 		.suppress_bind_attrs	= true,
18595fae8b86SMika Westerberg 	},
18605fae8b86SMika Westerberg };
18615fae8b86SMika Westerberg 
18625fae8b86SMika Westerberg static int __init byt_gpio_init(void)
18635fae8b86SMika Westerberg {
18645fae8b86SMika Westerberg 	return platform_driver_register(&byt_gpio_driver);
18655fae8b86SMika Westerberg }
18665fae8b86SMika Westerberg subsys_initcall(byt_gpio_init);
1867