v4.19.13 snapshot.
diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig
new file mode 100644
index 0000000..452a14f
--- /dev/null
+++ b/drivers/pinctrl/intel/Kconfig
@@ -0,0 +1,118 @@
+# SPDX-License-Identifier: GPL-2.0
+# Intel pin control drivers
+
+if (X86 || COMPILE_TEST)
+
+config PINCTRL_BAYTRAIL
+	bool "Intel Baytrail GPIO pin control"
+	depends on ACPI
+	select GPIOLIB
+	select GPIOLIB_IRQCHIP
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+	help
+	  driver for memory mapped GPIO functionality on Intel Baytrail
+	  platforms. Supports 3 banks with 102, 28 and 44 gpios.
+	  Most pins are usually muxed to some other functionality by firmware,
+	  so only a small amount is available for gpio use.
+
+	  Requires ACPI device enumeration code to set up a platform device.
+
+config PINCTRL_CHERRYVIEW
+	tristate "Intel Cherryview/Braswell pinctrl and GPIO driver"
+	depends on ACPI
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+	select GPIOLIB
+	select GPIOLIB_IRQCHIP
+	help
+	  Cherryview/Braswell pinctrl driver provides an interface that
+	  allows configuring of SoC pins and using them as GPIOs.
+
+config PINCTRL_MERRIFIELD
+	tristate "Intel Merrifield pinctrl driver"
+	depends on X86_INTEL_MID
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+	help
+	  Merrifield Family-Level Interface Shim (FLIS) driver provides an
+	  interface that allows configuring of SoC pins and using them as
+	  GPIOs.
+
+config PINCTRL_INTEL
+	tristate
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+	select GPIOLIB
+	select GPIOLIB_IRQCHIP
+
+config PINCTRL_BROXTON
+	tristate "Intel Broxton pinctrl and GPIO driver"
+	depends on ACPI
+	select PINCTRL_INTEL
+	help
+	  Broxton pinctrl driver provides an interface that allows
+	  configuring of SoC pins and using them as GPIOs.
+
+config PINCTRL_CANNONLAKE
+	tristate "Intel Cannon Lake PCH pinctrl and GPIO driver"
+	depends on ACPI
+	select PINCTRL_INTEL
+	help
+	  This pinctrl driver provides an interface that allows configuring
+	  of Intel Cannon Lake PCH pins and using them as GPIOs.
+
+config PINCTRL_CEDARFORK
+	tristate "Intel Cedar Fork pinctrl and GPIO driver"
+	depends on ACPI
+	select PINCTRL_INTEL
+	help
+	  This pinctrl driver provides an interface that allows configuring
+	  of Intel Cedar Fork PCH pins and using them as GPIOs.
+
+config PINCTRL_DENVERTON
+	tristate "Intel Denverton pinctrl and GPIO driver"
+	depends on ACPI
+	select PINCTRL_INTEL
+	help
+	  This pinctrl driver provides an interface that allows configuring
+	  of Intel Denverton SoC pins and using them as GPIOs.
+
+config PINCTRL_GEMINILAKE
+	tristate "Intel Gemini Lake SoC pinctrl and GPIO driver"
+	depends on ACPI
+	select PINCTRL_INTEL
+	help
+	  This pinctrl driver provides an interface that allows configuring
+	  of Intel Gemini Lake SoC pins and using them as GPIOs.
+
+config PINCTRL_ICELAKE
+	tristate "Intel Ice Lake PCH pinctrl and GPIO driver"
+	depends on ACPI
+	select PINCTRL_INTEL
+	help
+	  This pinctrl driver provides an interface that allows configuring
+	  of Intel Ice Lake PCH pins and using them as GPIOs.
+
+config PINCTRL_LEWISBURG
+	tristate "Intel Lewisburg pinctrl and GPIO driver"
+	depends on ACPI
+	select PINCTRL_INTEL
+	help
+	  This pinctrl driver provides an interface that allows configuring
+	  of Intel Lewisburg pins and using them as GPIOs.
+
+config PINCTRL_SUNRISEPOINT
+	tristate "Intel Sunrisepoint pinctrl and GPIO driver"
+	depends on ACPI
+	select PINCTRL_INTEL
+	help
+	  Sunrisepoint is the PCH of Intel Skylake. This pinctrl driver
+	  provides an interface that allows configuring of PCH pins and
+	  using them as GPIOs.
+
+endif
diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile
new file mode 100644
index 0000000..cb491e6
--- /dev/null
+++ b/drivers/pinctrl/intel/Makefile
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0
+# Intel pin control drivers
+
+obj-$(CONFIG_PINCTRL_BAYTRAIL)		+= pinctrl-baytrail.o
+obj-$(CONFIG_PINCTRL_CHERRYVIEW)	+= pinctrl-cherryview.o
+obj-$(CONFIG_PINCTRL_MERRIFIELD)	+= pinctrl-merrifield.o
+obj-$(CONFIG_PINCTRL_INTEL)		+= pinctrl-intel.o
+obj-$(CONFIG_PINCTRL_BROXTON)		+= pinctrl-broxton.o
+obj-$(CONFIG_PINCTRL_CANNONLAKE)	+= pinctrl-cannonlake.o
+obj-$(CONFIG_PINCTRL_CEDARFORK)		+= pinctrl-cedarfork.o
+obj-$(CONFIG_PINCTRL_DENVERTON)		+= pinctrl-denverton.o
+obj-$(CONFIG_PINCTRL_GEMINILAKE)	+= pinctrl-geminilake.o
+obj-$(CONFIG_PINCTRL_ICELAKE)		+= pinctrl-icelake.o
+obj-$(CONFIG_PINCTRL_LEWISBURG)		+= pinctrl-lewisburg.o
+obj-$(CONFIG_PINCTRL_SUNRISEPOINT)	+= pinctrl-sunrisepoint.o
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
new file mode 100644
index 0000000..f38d596
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -0,0 +1,1953 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Pinctrl GPIO driver for Intel Baytrail
+ *
+ * Copyright (c) 2012-2013, Intel Corporation
+ * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
+#include <linux/acpi.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+
+/* memory mapped register offsets */
+#define BYT_CONF0_REG		0x000
+#define BYT_CONF1_REG		0x004
+#define BYT_VAL_REG		0x008
+#define BYT_DFT_REG		0x00c
+#define BYT_INT_STAT_REG	0x800
+#define BYT_DEBOUNCE_REG	0x9d0
+
+/* BYT_CONF0_REG register bits */
+#define BYT_IODEN		BIT(31)
+#define BYT_DIRECT_IRQ_EN	BIT(27)
+#define BYT_TRIG_NEG		BIT(26)
+#define BYT_TRIG_POS		BIT(25)
+#define BYT_TRIG_LVL		BIT(24)
+#define BYT_DEBOUNCE_EN		BIT(20)
+#define BYT_GLITCH_FILTER_EN	BIT(19)
+#define BYT_GLITCH_F_SLOW_CLK	BIT(17)
+#define BYT_GLITCH_F_FAST_CLK	BIT(16)
+#define BYT_PULL_STR_SHIFT	9
+#define BYT_PULL_STR_MASK	(3 << BYT_PULL_STR_SHIFT)
+#define BYT_PULL_STR_2K		(0 << BYT_PULL_STR_SHIFT)
+#define BYT_PULL_STR_10K	(1 << BYT_PULL_STR_SHIFT)
+#define BYT_PULL_STR_20K	(2 << BYT_PULL_STR_SHIFT)
+#define BYT_PULL_STR_40K	(3 << BYT_PULL_STR_SHIFT)
+#define BYT_PULL_ASSIGN_SHIFT	7
+#define BYT_PULL_ASSIGN_MASK	(3 << BYT_PULL_ASSIGN_SHIFT)
+#define BYT_PULL_ASSIGN_UP	(1 << BYT_PULL_ASSIGN_SHIFT)
+#define BYT_PULL_ASSIGN_DOWN	(2 << BYT_PULL_ASSIGN_SHIFT)
+#define BYT_PIN_MUX		0x07
+
+/* BYT_VAL_REG register bits */
+#define BYT_INPUT_EN		BIT(2)  /* 0: input enabled (active low)*/
+#define BYT_OUTPUT_EN		BIT(1)  /* 0: output enabled (active low)*/
+#define BYT_LEVEL		BIT(0)
+
+#define BYT_DIR_MASK		(BIT(1) | BIT(2))
+#define BYT_TRIG_MASK		(BIT(26) | BIT(25) | BIT(24))
+
+#define BYT_CONF0_RESTORE_MASK	(BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | \
+				 BYT_PIN_MUX)
+#define BYT_VAL_RESTORE_MASK	(BYT_DIR_MASK | BYT_LEVEL)
+
+/* BYT_DEBOUNCE_REG bits */
+#define BYT_DEBOUNCE_PULSE_MASK		0x7
+#define BYT_DEBOUNCE_PULSE_375US	1
+#define BYT_DEBOUNCE_PULSE_750US	2
+#define BYT_DEBOUNCE_PULSE_1500US	3
+#define BYT_DEBOUNCE_PULSE_3MS		4
+#define BYT_DEBOUNCE_PULSE_6MS		5
+#define BYT_DEBOUNCE_PULSE_12MS		6
+#define BYT_DEBOUNCE_PULSE_24MS		7
+
+#define BYT_NGPIO_SCORE		102
+#define BYT_NGPIO_NCORE		28
+#define BYT_NGPIO_SUS		44
+
+#define BYT_SCORE_ACPI_UID	"1"
+#define BYT_NCORE_ACPI_UID	"2"
+#define BYT_SUS_ACPI_UID	"3"
+
+/*
+ * This is the function value most pins have for GPIO muxing. If the value
+ * differs from the default one, it must be explicitly mentioned. Otherwise, the
+ * pin control implementation will set the muxing value to default GPIO if it
+ * does not find a match for the requested function.
+ */
+#define BYT_DEFAULT_GPIO_MUX	0
+
+struct byt_gpio_pin_context {
+	u32 conf0;
+	u32 val;
+};
+
+struct byt_simple_func_mux {
+	const char *name;
+	unsigned short func;
+};
+
+struct byt_mixed_func_mux {
+	const char *name;
+	const unsigned short *func_values;
+};
+
+struct byt_pingroup {
+	const char *name;
+	const unsigned int *pins;
+	size_t npins;
+	unsigned short has_simple_funcs;
+	union {
+		const struct byt_simple_func_mux *simple_funcs;
+		const struct byt_mixed_func_mux *mixed_funcs;
+	};
+	size_t nfuncs;
+};
+
+struct byt_function {
+	const char *name;
+	const char * const *groups;
+	size_t ngroups;
+};
+
+struct byt_community {
+	unsigned int pin_base;
+	size_t npins;
+	const unsigned int *pad_map;
+	void __iomem *reg_base;
+};
+
+#define SIMPLE_FUNC(n, f)	\
+	{			\
+		.name	= (n),	\
+		.func	= (f),	\
+	}
+#define MIXED_FUNC(n, f)		\
+	{				\
+		.name		= (n),	\
+		.func_values	= (f),	\
+	}
+
+#define PIN_GROUP_SIMPLE(n, p, f)				\
+	{							\
+		.name			= (n),			\
+		.pins			= (p),			\
+		.npins			= ARRAY_SIZE((p)),	\
+		.has_simple_funcs	= 1,			\
+		{						\
+			.simple_funcs		= (f),		\
+		},						\
+		.nfuncs			= ARRAY_SIZE((f)),	\
+	}
+#define PIN_GROUP_MIXED(n, p, f)				\
+	{							\
+		.name			= (n),			\
+		.pins			= (p),			\
+		.npins			= ARRAY_SIZE((p)),	\
+		.has_simple_funcs	= 0,			\
+		{						\
+			.mixed_funcs		= (f),		\
+		},						\
+		.nfuncs			= ARRAY_SIZE((f)),	\
+	}
+
+#define FUNCTION(n, g)					\
+	{						\
+		.name		= (n),			\
+		.groups		= (g),			\
+		.ngroups	= ARRAY_SIZE((g)),	\
+	}
+
+#define COMMUNITY(p, n, map)		\
+	{				\
+		.pin_base	= (p),	\
+		.npins		= (n),	\
+		.pad_map	= (map),\
+	}
+
+struct byt_pinctrl_soc_data {
+	const char *uid;
+	const struct pinctrl_pin_desc *pins;
+	size_t npins;
+	const struct byt_pingroup *groups;
+	size_t ngroups;
+	const struct byt_function *functions;
+	size_t nfunctions;
+	const struct byt_community *communities;
+	size_t ncommunities;
+};
+
+struct byt_gpio {
+	struct gpio_chip chip;
+	struct platform_device *pdev;
+	struct pinctrl_dev *pctl_dev;
+	struct pinctrl_desc pctl_desc;
+	raw_spinlock_t lock;
+	const struct byt_pinctrl_soc_data *soc_data;
+	struct byt_community *communities_copy;
+	struct byt_gpio_pin_context *saved_context;
+};
+
+/* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */
+static const struct pinctrl_pin_desc byt_score_pins[] = {
+	PINCTRL_PIN(0, "SATA_GP0"),
+	PINCTRL_PIN(1, "SATA_GP1"),
+	PINCTRL_PIN(2, "SATA_LED#"),
+	PINCTRL_PIN(3, "PCIE_CLKREQ0"),
+	PINCTRL_PIN(4, "PCIE_CLKREQ1"),
+	PINCTRL_PIN(5, "PCIE_CLKREQ2"),
+	PINCTRL_PIN(6, "PCIE_CLKREQ3"),
+	PINCTRL_PIN(7, "SD3_WP"),
+	PINCTRL_PIN(8, "HDA_RST"),
+	PINCTRL_PIN(9, "HDA_SYNC"),
+	PINCTRL_PIN(10, "HDA_CLK"),
+	PINCTRL_PIN(11, "HDA_SDO"),
+	PINCTRL_PIN(12, "HDA_SDI0"),
+	PINCTRL_PIN(13, "HDA_SDI1"),
+	PINCTRL_PIN(14, "GPIO_S0_SC14"),
+	PINCTRL_PIN(15, "GPIO_S0_SC15"),
+	PINCTRL_PIN(16, "MMC1_CLK"),
+	PINCTRL_PIN(17, "MMC1_D0"),
+	PINCTRL_PIN(18, "MMC1_D1"),
+	PINCTRL_PIN(19, "MMC1_D2"),
+	PINCTRL_PIN(20, "MMC1_D3"),
+	PINCTRL_PIN(21, "MMC1_D4"),
+	PINCTRL_PIN(22, "MMC1_D5"),
+	PINCTRL_PIN(23, "MMC1_D6"),
+	PINCTRL_PIN(24, "MMC1_D7"),
+	PINCTRL_PIN(25, "MMC1_CMD"),
+	PINCTRL_PIN(26, "MMC1_RST"),
+	PINCTRL_PIN(27, "SD2_CLK"),
+	PINCTRL_PIN(28, "SD2_D0"),
+	PINCTRL_PIN(29, "SD2_D1"),
+	PINCTRL_PIN(30, "SD2_D2"),
+	PINCTRL_PIN(31, "SD2_D3_CD"),
+	PINCTRL_PIN(32, "SD2_CMD"),
+	PINCTRL_PIN(33, "SD3_CLK"),
+	PINCTRL_PIN(34, "SD3_D0"),
+	PINCTRL_PIN(35, "SD3_D1"),
+	PINCTRL_PIN(36, "SD3_D2"),
+	PINCTRL_PIN(37, "SD3_D3"),
+	PINCTRL_PIN(38, "SD3_CD"),
+	PINCTRL_PIN(39, "SD3_CMD"),
+	PINCTRL_PIN(40, "SD3_1P8EN"),
+	PINCTRL_PIN(41, "SD3_PWREN#"),
+	PINCTRL_PIN(42, "ILB_LPC_AD0"),
+	PINCTRL_PIN(43, "ILB_LPC_AD1"),
+	PINCTRL_PIN(44, "ILB_LPC_AD2"),
+	PINCTRL_PIN(45, "ILB_LPC_AD3"),
+	PINCTRL_PIN(46, "ILB_LPC_FRAME"),
+	PINCTRL_PIN(47, "ILB_LPC_CLK0"),
+	PINCTRL_PIN(48, "ILB_LPC_CLK1"),
+	PINCTRL_PIN(49, "ILB_LPC_CLKRUN"),
+	PINCTRL_PIN(50, "ILB_LPC_SERIRQ"),
+	PINCTRL_PIN(51, "PCU_SMB_DATA"),
+	PINCTRL_PIN(52, "PCU_SMB_CLK"),
+	PINCTRL_PIN(53, "PCU_SMB_ALERT"),
+	PINCTRL_PIN(54, "ILB_8254_SPKR"),
+	PINCTRL_PIN(55, "GPIO_S0_SC55"),
+	PINCTRL_PIN(56, "GPIO_S0_SC56"),
+	PINCTRL_PIN(57, "GPIO_S0_SC57"),
+	PINCTRL_PIN(58, "GPIO_S0_SC58"),
+	PINCTRL_PIN(59, "GPIO_S0_SC59"),
+	PINCTRL_PIN(60, "GPIO_S0_SC60"),
+	PINCTRL_PIN(61, "GPIO_S0_SC61"),
+	PINCTRL_PIN(62, "LPE_I2S2_CLK"),
+	PINCTRL_PIN(63, "LPE_I2S2_FRM"),
+	PINCTRL_PIN(64, "LPE_I2S2_DATAIN"),
+	PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"),
+	PINCTRL_PIN(66, "SIO_SPI_CS"),
+	PINCTRL_PIN(67, "SIO_SPI_MISO"),
+	PINCTRL_PIN(68, "SIO_SPI_MOSI"),
+	PINCTRL_PIN(69, "SIO_SPI_CLK"),
+	PINCTRL_PIN(70, "SIO_UART1_RXD"),
+	PINCTRL_PIN(71, "SIO_UART1_TXD"),
+	PINCTRL_PIN(72, "SIO_UART1_RTS"),
+	PINCTRL_PIN(73, "SIO_UART1_CTS"),
+	PINCTRL_PIN(74, "SIO_UART2_RXD"),
+	PINCTRL_PIN(75, "SIO_UART2_TXD"),
+	PINCTRL_PIN(76, "SIO_UART2_RTS"),
+	PINCTRL_PIN(77, "SIO_UART2_CTS"),
+	PINCTRL_PIN(78, "SIO_I2C0_DATA"),
+	PINCTRL_PIN(79, "SIO_I2C0_CLK"),
+	PINCTRL_PIN(80, "SIO_I2C1_DATA"),
+	PINCTRL_PIN(81, "SIO_I2C1_CLK"),
+	PINCTRL_PIN(82, "SIO_I2C2_DATA"),
+	PINCTRL_PIN(83, "SIO_I2C2_CLK"),
+	PINCTRL_PIN(84, "SIO_I2C3_DATA"),
+	PINCTRL_PIN(85, "SIO_I2C3_CLK"),
+	PINCTRL_PIN(86, "SIO_I2C4_DATA"),
+	PINCTRL_PIN(87, "SIO_I2C4_CLK"),
+	PINCTRL_PIN(88, "SIO_I2C5_DATA"),
+	PINCTRL_PIN(89, "SIO_I2C5_CLK"),
+	PINCTRL_PIN(90, "SIO_I2C6_DATA"),
+	PINCTRL_PIN(91, "SIO_I2C6_CLK"),
+	PINCTRL_PIN(92, "GPIO_S0_SC92"),
+	PINCTRL_PIN(93, "GPIO_S0_SC93"),
+	PINCTRL_PIN(94, "SIO_PWM0"),
+	PINCTRL_PIN(95, "SIO_PWM1"),
+	PINCTRL_PIN(96, "PMC_PLT_CLK0"),
+	PINCTRL_PIN(97, "PMC_PLT_CLK1"),
+	PINCTRL_PIN(98, "PMC_PLT_CLK2"),
+	PINCTRL_PIN(99, "PMC_PLT_CLK3"),
+	PINCTRL_PIN(100, "PMC_PLT_CLK4"),
+	PINCTRL_PIN(101, "PMC_PLT_CLK5"),
+};
+
+static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = {
+	85, 89, 93, 96, 99, 102, 98, 101, 34, 37,
+	36, 38, 39, 35, 40, 84, 62, 61, 64, 59,
+	54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
+	52, 49, 48, 43, 46, 41, 45, 42, 58, 44,
+	95, 105, 70, 68, 67, 66, 69, 71, 65, 72,
+	86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
+	80, 82, 13, 12, 15, 14, 17, 18, 19, 16,
+	2, 1, 0, 4, 6, 7, 9, 8, 33, 32,
+	31, 30, 29, 27, 25, 28, 26, 23, 21, 20,
+	24, 22, 5, 3, 10, 11, 106, 87, 91, 104,
+	97, 100,
+};
+
+/* SCORE groups */
+static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 };
+static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 };
+static const struct byt_simple_func_mux byt_score_uart_mux[] = {
+	SIMPLE_FUNC("uart", 1),
+};
+
+static const unsigned int byt_score_pwm0_pins[] = { 94 };
+static const unsigned int byt_score_pwm1_pins[] = { 95 };
+static const struct byt_simple_func_mux byt_score_pwm_mux[] = {
+	SIMPLE_FUNC("pwm", 1),
+};
+
+static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 };
+static const struct byt_simple_func_mux byt_score_spi_mux[] = {
+	SIMPLE_FUNC("spi", 1),
+};
+
+static const unsigned int byt_score_i2c5_pins[] = { 88, 89 };
+static const unsigned int byt_score_i2c6_pins[] = { 90, 91 };
+static const unsigned int byt_score_i2c4_pins[] = { 86, 87 };
+static const unsigned int byt_score_i2c3_pins[] = { 84, 85 };
+static const unsigned int byt_score_i2c2_pins[] = { 82, 83 };
+static const unsigned int byt_score_i2c1_pins[] = { 80, 81 };
+static const unsigned int byt_score_i2c0_pins[] = { 78, 79 };
+static const struct byt_simple_func_mux byt_score_i2c_mux[] = {
+	SIMPLE_FUNC("i2c", 1),
+};
+
+static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 };
+static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 };
+static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 };
+static const struct byt_simple_func_mux byt_score_ssp_mux[] = {
+	SIMPLE_FUNC("ssp", 1),
+};
+
+static const unsigned int byt_score_sdcard_pins[] = {
+	7, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+};
+static const unsigned short byt_score_sdcard_mux_values[] = {
+	2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+};
+static const struct byt_mixed_func_mux byt_score_sdcard_mux[] = {
+	MIXED_FUNC("sdcard", byt_score_sdcard_mux_values),
+};
+
+static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 };
+static const struct byt_simple_func_mux byt_score_sdio_mux[] = {
+	SIMPLE_FUNC("sdio", 1),
+};
+
+static const unsigned int byt_score_emmc_pins[] = {
+	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+};
+static const struct byt_simple_func_mux byt_score_emmc_mux[] = {
+	SIMPLE_FUNC("emmc", 1),
+};
+
+static const unsigned int byt_score_ilb_lpc_pins[] = {
+	42, 43, 44, 45, 46, 47, 48, 49, 50,
+};
+static const struct byt_simple_func_mux byt_score_lpc_mux[] = {
+	SIMPLE_FUNC("lpc", 1),
+};
+
+static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 };
+static const struct byt_simple_func_mux byt_score_sata_mux[] = {
+	SIMPLE_FUNC("sata", 1),
+};
+
+static const unsigned int byt_score_plt_clk0_pins[] = { 96 };
+static const unsigned int byt_score_plt_clk1_pins[] = { 97 };
+static const unsigned int byt_score_plt_clk2_pins[] = { 98 };
+static const unsigned int byt_score_plt_clk3_pins[] = { 99 };
+static const unsigned int byt_score_plt_clk4_pins[] = { 100 };
+static const unsigned int byt_score_plt_clk5_pins[] = { 101 };
+static const struct byt_simple_func_mux byt_score_plt_clk_mux[] = {
+	SIMPLE_FUNC("plt_clk", 1),
+};
+
+static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 };
+static const struct byt_simple_func_mux byt_score_smbus_mux[] = {
+	SIMPLE_FUNC("smbus", 1),
+};
+
+static const struct byt_pingroup byt_score_groups[] = {
+	PIN_GROUP_SIMPLE("uart1_grp",
+			 byt_score_uart1_pins, byt_score_uart_mux),
+	PIN_GROUP_SIMPLE("uart2_grp",
+			 byt_score_uart2_pins, byt_score_uart_mux),
+	PIN_GROUP_SIMPLE("pwm0_grp",
+			 byt_score_pwm0_pins, byt_score_pwm_mux),
+	PIN_GROUP_SIMPLE("pwm1_grp",
+			 byt_score_pwm1_pins, byt_score_pwm_mux),
+	PIN_GROUP_SIMPLE("ssp2_grp",
+			 byt_score_ssp2_pins, byt_score_pwm_mux),
+	PIN_GROUP_SIMPLE("sio_spi_grp",
+			 byt_score_sio_spi_pins, byt_score_spi_mux),
+	PIN_GROUP_SIMPLE("i2c5_grp",
+			 byt_score_i2c5_pins, byt_score_i2c_mux),
+	PIN_GROUP_SIMPLE("i2c6_grp",
+			 byt_score_i2c6_pins, byt_score_i2c_mux),
+	PIN_GROUP_SIMPLE("i2c4_grp",
+			 byt_score_i2c4_pins, byt_score_i2c_mux),
+	PIN_GROUP_SIMPLE("i2c3_grp",
+			 byt_score_i2c3_pins, byt_score_i2c_mux),
+	PIN_GROUP_SIMPLE("i2c2_grp",
+			 byt_score_i2c2_pins, byt_score_i2c_mux),
+	PIN_GROUP_SIMPLE("i2c1_grp",
+			 byt_score_i2c1_pins, byt_score_i2c_mux),
+	PIN_GROUP_SIMPLE("i2c0_grp",
+			 byt_score_i2c0_pins, byt_score_i2c_mux),
+	PIN_GROUP_SIMPLE("ssp0_grp",
+			 byt_score_ssp0_pins, byt_score_ssp_mux),
+	PIN_GROUP_SIMPLE("ssp1_grp",
+			 byt_score_ssp1_pins, byt_score_ssp_mux),
+	PIN_GROUP_MIXED("sdcard_grp",
+			byt_score_sdcard_pins, byt_score_sdcard_mux),
+	PIN_GROUP_SIMPLE("sdio_grp",
+			 byt_score_sdio_pins, byt_score_sdio_mux),
+	PIN_GROUP_SIMPLE("emmc_grp",
+			 byt_score_emmc_pins, byt_score_emmc_mux),
+	PIN_GROUP_SIMPLE("lpc_grp",
+			 byt_score_ilb_lpc_pins, byt_score_lpc_mux),
+	PIN_GROUP_SIMPLE("sata_grp",
+			 byt_score_sata_pins, byt_score_sata_mux),
+	PIN_GROUP_SIMPLE("plt_clk0_grp",
+			 byt_score_plt_clk0_pins, byt_score_plt_clk_mux),
+	PIN_GROUP_SIMPLE("plt_clk1_grp",
+			 byt_score_plt_clk1_pins, byt_score_plt_clk_mux),
+	PIN_GROUP_SIMPLE("plt_clk2_grp",
+			 byt_score_plt_clk2_pins, byt_score_plt_clk_mux),
+	PIN_GROUP_SIMPLE("plt_clk3_grp",
+			 byt_score_plt_clk3_pins, byt_score_plt_clk_mux),
+	PIN_GROUP_SIMPLE("plt_clk4_grp",
+			 byt_score_plt_clk4_pins, byt_score_plt_clk_mux),
+	PIN_GROUP_SIMPLE("plt_clk5_grp",
+			 byt_score_plt_clk5_pins, byt_score_plt_clk_mux),
+	PIN_GROUP_SIMPLE("smbus_grp",
+			 byt_score_smbus_pins, byt_score_smbus_mux),
+};
+
+static const char * const byt_score_uart_groups[] = {
+	"uart1_grp", "uart2_grp",
+};
+static const char * const byt_score_pwm_groups[] = {
+	"pwm0_grp", "pwm1_grp",
+};
+static const char * const byt_score_ssp_groups[] = {
+	"ssp0_grp", "ssp1_grp", "ssp2_grp",
+};
+static const char * const byt_score_spi_groups[] = { "sio_spi_grp" };
+static const char * const byt_score_i2c_groups[] = {
+	"i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp",
+	"i2c6_grp",
+};
+static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" };
+static const char * const byt_score_sdio_groups[] = { "sdio_grp" };
+static const char * const byt_score_emmc_groups[] = { "emmc_grp" };
+static const char * const byt_score_lpc_groups[] = { "lpc_grp" };
+static const char * const byt_score_sata_groups[] = { "sata_grp" };
+static const char * const byt_score_plt_clk_groups[] = {
+	"plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
+	"plt_clk4_grp", "plt_clk5_grp",
+};
+static const char * const byt_score_smbus_groups[] = { "smbus_grp" };
+static const char * const byt_score_gpio_groups[] = {
+	"uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp",
+	"ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp",
+	"i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp",
+	"sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp",
+	"plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
+	"plt_clk4_grp", "plt_clk5_grp", "smbus_grp",
+
+};
+
+static const struct byt_function byt_score_functions[] = {
+	FUNCTION("uart", byt_score_uart_groups),
+	FUNCTION("pwm", byt_score_pwm_groups),
+	FUNCTION("ssp", byt_score_ssp_groups),
+	FUNCTION("spi", byt_score_spi_groups),
+	FUNCTION("i2c", byt_score_i2c_groups),
+	FUNCTION("sdcard", byt_score_sdcard_groups),
+	FUNCTION("sdio", byt_score_sdio_groups),
+	FUNCTION("emmc", byt_score_emmc_groups),
+	FUNCTION("lpc", byt_score_lpc_groups),
+	FUNCTION("sata", byt_score_sata_groups),
+	FUNCTION("plt_clk", byt_score_plt_clk_groups),
+	FUNCTION("smbus", byt_score_smbus_groups),
+	FUNCTION("gpio", byt_score_gpio_groups),
+};
+
+static const struct byt_community byt_score_communities[] = {
+	COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
+};
+
+static const struct byt_pinctrl_soc_data byt_score_soc_data = {
+	.uid		= BYT_SCORE_ACPI_UID,
+	.pins		= byt_score_pins,
+	.npins		= ARRAY_SIZE(byt_score_pins),
+	.groups		= byt_score_groups,
+	.ngroups	= ARRAY_SIZE(byt_score_groups),
+	.functions	= byt_score_functions,
+	.nfunctions	= ARRAY_SIZE(byt_score_functions),
+	.communities	= byt_score_communities,
+	.ncommunities	= ARRAY_SIZE(byt_score_communities),
+};
+
+/* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>]  */
+static const struct pinctrl_pin_desc byt_sus_pins[] = {
+	PINCTRL_PIN(0, "GPIO_S50"),
+	PINCTRL_PIN(1, "GPIO_S51"),
+	PINCTRL_PIN(2, "GPIO_S52"),
+	PINCTRL_PIN(3, "GPIO_S53"),
+	PINCTRL_PIN(4, "GPIO_S54"),
+	PINCTRL_PIN(5, "GPIO_S55"),
+	PINCTRL_PIN(6, "GPIO_S56"),
+	PINCTRL_PIN(7, "GPIO_S57"),
+	PINCTRL_PIN(8, "GPIO_S58"),
+	PINCTRL_PIN(9, "GPIO_S59"),
+	PINCTRL_PIN(10, "GPIO_S510"),
+	PINCTRL_PIN(11, "PMC_SUSPWRDNACK"),
+	PINCTRL_PIN(12, "PMC_SUSCLK0"),
+	PINCTRL_PIN(13, "GPIO_S513"),
+	PINCTRL_PIN(14, "USB_ULPI_RST"),
+	PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"),
+	PINCTRL_PIN(16, "PMC_PWRBTN"),
+	PINCTRL_PIN(17, "GPIO_S517"),
+	PINCTRL_PIN(18, "PMC_SUS_STAT"),
+	PINCTRL_PIN(19, "USB_OC0"),
+	PINCTRL_PIN(20, "USB_OC1"),
+	PINCTRL_PIN(21, "PCU_SPI_CS1"),
+	PINCTRL_PIN(22, "GPIO_S522"),
+	PINCTRL_PIN(23, "GPIO_S523"),
+	PINCTRL_PIN(24, "GPIO_S524"),
+	PINCTRL_PIN(25, "GPIO_S525"),
+	PINCTRL_PIN(26, "GPIO_S526"),
+	PINCTRL_PIN(27, "GPIO_S527"),
+	PINCTRL_PIN(28, "GPIO_S528"),
+	PINCTRL_PIN(29, "GPIO_S529"),
+	PINCTRL_PIN(30, "GPIO_S530"),
+	PINCTRL_PIN(31, "USB_ULPI_CLK"),
+	PINCTRL_PIN(32, "USB_ULPI_DATA0"),
+	PINCTRL_PIN(33, "USB_ULPI_DATA1"),
+	PINCTRL_PIN(34, "USB_ULPI_DATA2"),
+	PINCTRL_PIN(35, "USB_ULPI_DATA3"),
+	PINCTRL_PIN(36, "USB_ULPI_DATA4"),
+	PINCTRL_PIN(37, "USB_ULPI_DATA5"),
+	PINCTRL_PIN(38, "USB_ULPI_DATA6"),
+	PINCTRL_PIN(39, "USB_ULPI_DATA7"),
+	PINCTRL_PIN(40, "USB_ULPI_DIR"),
+	PINCTRL_PIN(41, "USB_ULPI_NXT"),
+	PINCTRL_PIN(42, "USB_ULPI_STP"),
+	PINCTRL_PIN(43, "USB_ULPI_REFCLK"),
+};
+
+static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = {
+	29, 33, 30, 31, 32, 34, 36, 35, 38, 37,
+	18, 7, 11, 20, 17, 1, 8, 10, 19, 12,
+	0, 2, 23, 39, 28, 27, 22, 21, 24, 25,
+	26, 51, 56, 54, 49, 55, 48, 57, 50, 58,
+	52, 53, 59, 40,
+};
+
+static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 };
+static const struct byt_simple_func_mux byt_sus_usb_oc_mux[] = {
+	SIMPLE_FUNC("usb", 0),
+	SIMPLE_FUNC("gpio", 1),
+};
+
+static const unsigned int byt_sus_usb_ulpi_pins[] = {
+	14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+};
+static const unsigned short byt_sus_usb_ulpi_mode_values[] = {
+	2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+};
+static const unsigned short byt_sus_usb_ulpi_gpio_mode_values[] = {
+	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+static const struct byt_mixed_func_mux byt_sus_usb_ulpi_mux[] = {
+	MIXED_FUNC("usb", byt_sus_usb_ulpi_mode_values),
+	MIXED_FUNC("gpio", byt_sus_usb_ulpi_gpio_mode_values),
+};
+
+static const unsigned int byt_sus_pcu_spi_pins[] = { 21 };
+static const struct byt_simple_func_mux byt_sus_pcu_spi_mux[] = {
+	SIMPLE_FUNC("spi", 0),
+	SIMPLE_FUNC("gpio", 1),
+};
+
+static const struct byt_pingroup byt_sus_groups[] = {
+	PIN_GROUP_SIMPLE("usb_oc_grp",
+			byt_sus_usb_over_current_pins, byt_sus_usb_oc_mux),
+	PIN_GROUP_MIXED("usb_ulpi_grp",
+			byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mux),
+	PIN_GROUP_SIMPLE("pcu_spi_grp",
+			byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mux),
+};
+
+static const char * const byt_sus_usb_groups[] = {
+	"usb_oc_grp", "usb_ulpi_grp",
+};
+static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" };
+static const char * const byt_sus_gpio_groups[] = {
+	"usb_oc_grp", "usb_ulpi_grp", "pcu_spi_grp",
+};
+
+static const struct byt_function byt_sus_functions[] = {
+	FUNCTION("usb", byt_sus_usb_groups),
+	FUNCTION("spi", byt_sus_spi_groups),
+	FUNCTION("gpio", byt_sus_gpio_groups),
+};
+
+static const struct byt_community byt_sus_communities[] = {
+	COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
+};
+
+static const struct byt_pinctrl_soc_data byt_sus_soc_data = {
+	.uid		= BYT_SUS_ACPI_UID,
+	.pins		= byt_sus_pins,
+	.npins		= ARRAY_SIZE(byt_sus_pins),
+	.groups		= byt_sus_groups,
+	.ngroups	= ARRAY_SIZE(byt_sus_groups),
+	.functions	= byt_sus_functions,
+	.nfunctions	= ARRAY_SIZE(byt_sus_functions),
+	.communities	= byt_sus_communities,
+	.ncommunities	= ARRAY_SIZE(byt_sus_communities),
+};
+
+static const struct pinctrl_pin_desc byt_ncore_pins[] = {
+	PINCTRL_PIN(0, "GPIO_NCORE0"),
+	PINCTRL_PIN(1, "GPIO_NCORE1"),
+	PINCTRL_PIN(2, "GPIO_NCORE2"),
+	PINCTRL_PIN(3, "GPIO_NCORE3"),
+	PINCTRL_PIN(4, "GPIO_NCORE4"),
+	PINCTRL_PIN(5, "GPIO_NCORE5"),
+	PINCTRL_PIN(6, "GPIO_NCORE6"),
+	PINCTRL_PIN(7, "GPIO_NCORE7"),
+	PINCTRL_PIN(8, "GPIO_NCORE8"),
+	PINCTRL_PIN(9, "GPIO_NCORE9"),
+	PINCTRL_PIN(10, "GPIO_NCORE10"),
+	PINCTRL_PIN(11, "GPIO_NCORE11"),
+	PINCTRL_PIN(12, "GPIO_NCORE12"),
+	PINCTRL_PIN(13, "GPIO_NCORE13"),
+	PINCTRL_PIN(14, "GPIO_NCORE14"),
+	PINCTRL_PIN(15, "GPIO_NCORE15"),
+	PINCTRL_PIN(16, "GPIO_NCORE16"),
+	PINCTRL_PIN(17, "GPIO_NCORE17"),
+	PINCTRL_PIN(18, "GPIO_NCORE18"),
+	PINCTRL_PIN(19, "GPIO_NCORE19"),
+	PINCTRL_PIN(20, "GPIO_NCORE20"),
+	PINCTRL_PIN(21, "GPIO_NCORE21"),
+	PINCTRL_PIN(22, "GPIO_NCORE22"),
+	PINCTRL_PIN(23, "GPIO_NCORE23"),
+	PINCTRL_PIN(24, "GPIO_NCORE24"),
+	PINCTRL_PIN(25, "GPIO_NCORE25"),
+	PINCTRL_PIN(26, "GPIO_NCORE26"),
+	PINCTRL_PIN(27, "GPIO_NCORE27"),
+};
+
+static unsigned const byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
+	19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
+	14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
+	3, 6, 10, 13, 2, 5, 9, 7,
+};
+
+static const struct byt_community byt_ncore_communities[] = {
+	COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
+};
+
+static const struct byt_pinctrl_soc_data byt_ncore_soc_data = {
+	.uid		= BYT_NCORE_ACPI_UID,
+	.pins		= byt_ncore_pins,
+	.npins		= ARRAY_SIZE(byt_ncore_pins),
+	.communities	= byt_ncore_communities,
+	.ncommunities	= ARRAY_SIZE(byt_ncore_communities),
+};
+
+static const struct byt_pinctrl_soc_data *byt_soc_data[] = {
+	&byt_score_soc_data,
+	&byt_sus_soc_data,
+	&byt_ncore_soc_data,
+	NULL,
+};
+
+static struct byt_community *byt_get_community(struct byt_gpio *vg,
+					       unsigned int pin)
+{
+	struct byt_community *comm;
+	int i;
+
+	for (i = 0; i < vg->soc_data->ncommunities; i++) {
+		comm = vg->communities_copy + i;
+		if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base)
+			return comm;
+	}
+
+	return NULL;
+}
+
+static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
+				  int reg)
+{
+	struct byt_community *comm = byt_get_community(vg, offset);
+	u32 reg_offset;
+
+	if (!comm)
+		return NULL;
+
+	offset -= comm->pin_base;
+	switch (reg) {
+	case BYT_INT_STAT_REG:
+		reg_offset = (offset / 32) * 4;
+		break;
+	case BYT_DEBOUNCE_REG:
+		reg_offset = 0;
+		break;
+	default:
+		reg_offset = comm->pad_map[offset] * 16;
+		break;
+	}
+
+	return comm->reg_base + reg_offset + reg;
+}
+
+static int byt_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
+
+	return vg->soc_data->ngroups;
+}
+
+static const char *byt_get_group_name(struct pinctrl_dev *pctldev,
+				      unsigned int selector)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
+
+	return vg->soc_data->groups[selector].name;
+}
+
+static int byt_get_group_pins(struct pinctrl_dev *pctldev,
+			      unsigned int selector,
+			      const unsigned int **pins,
+			      unsigned int *num_pins)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
+
+	*pins		= vg->soc_data->groups[selector].pins;
+	*num_pins	= vg->soc_data->groups[selector].npins;
+
+	return 0;
+}
+
+static const struct pinctrl_ops byt_pinctrl_ops = {
+	.get_groups_count	= byt_get_groups_count,
+	.get_group_name		= byt_get_group_name,
+	.get_group_pins		= byt_get_group_pins,
+};
+
+static int byt_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
+
+	return vg->soc_data->nfunctions;
+}
+
+static const char *byt_get_function_name(struct pinctrl_dev *pctldev,
+					 unsigned int selector)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
+
+	return vg->soc_data->functions[selector].name;
+}
+
+static int byt_get_function_groups(struct pinctrl_dev *pctldev,
+				   unsigned int selector,
+				   const char * const **groups,
+				   unsigned int *num_groups)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups		= vg->soc_data->functions[selector].groups;
+	*num_groups	= vg->soc_data->functions[selector].ngroups;
+
+	return 0;
+}
+
+static int byt_get_group_simple_mux(const struct byt_pingroup group,
+				    const char *func_name,
+				    unsigned short *func)
+{
+	int i;
+
+	for (i = 0; i < group.nfuncs; i++) {
+		if (!strcmp(group.simple_funcs[i].name, func_name)) {
+			*func = group.simple_funcs[i].func;
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+static int byt_get_group_mixed_mux(const struct byt_pingroup group,
+				   const char *func_name,
+				   const unsigned short **func)
+{
+	int i;
+
+	for (i = 0; i < group.nfuncs; i++) {
+		if (!strcmp(group.mixed_funcs[i].name, func_name)) {
+			*func = group.mixed_funcs[i].func_values;
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+static void byt_set_group_simple_mux(struct byt_gpio *vg,
+				     const struct byt_pingroup group,
+				     unsigned short func)
+{
+	unsigned long flags;
+	int i;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+
+	for (i = 0; i < group.npins; i++) {
+		void __iomem *padcfg0;
+		u32 value;
+
+		padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
+		if (!padcfg0) {
+			dev_warn(&vg->pdev->dev,
+				 "Group %s, pin %i not muxed (no padcfg0)\n",
+				 group.name, i);
+			continue;
+		}
+
+		value = readl(padcfg0);
+		value &= ~BYT_PIN_MUX;
+		value |= func;
+		writel(value, padcfg0);
+	}
+
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+}
+
+static void byt_set_group_mixed_mux(struct byt_gpio *vg,
+				    const struct byt_pingroup group,
+				    const unsigned short *func)
+{
+	unsigned long flags;
+	int i;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+
+	for (i = 0; i < group.npins; i++) {
+		void __iomem *padcfg0;
+		u32 value;
+
+		padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
+		if (!padcfg0) {
+			dev_warn(&vg->pdev->dev,
+				 "Group %s, pin %i not muxed (no padcfg0)\n",
+				 group.name, i);
+			continue;
+		}
+
+		value = readl(padcfg0);
+		value &= ~BYT_PIN_MUX;
+		value |= func[i];
+		writel(value, padcfg0);
+	}
+
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+}
+
+static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
+		       unsigned int group_selector)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
+	const struct byt_function func = vg->soc_data->functions[func_selector];
+	const struct byt_pingroup group = vg->soc_data->groups[group_selector];
+	const unsigned short *mixed_func;
+	unsigned short simple_func;
+	int ret = 1;
+
+	if (group.has_simple_funcs)
+		ret = byt_get_group_simple_mux(group, func.name, &simple_func);
+	else
+		ret = byt_get_group_mixed_mux(group, func.name, &mixed_func);
+
+	if (ret)
+		byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX);
+	else if (group.has_simple_funcs)
+		byt_set_group_simple_mux(vg, group, simple_func);
+	else
+		byt_set_group_mixed_mux(vg, group, mixed_func);
+
+	return 0;
+}
+
+static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset)
+{
+	/* SCORE pin 92-93 */
+	if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) &&
+	    offset >= 92 && offset <= 93)
+		return 1;
+
+	/* SUS pin 11-21 */
+	if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) &&
+	    offset >= 11 && offset <= 21)
+		return 1;
+
+	return 0;
+}
+
+static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset)
+{
+	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
+	unsigned long flags;
+	u32 value;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+	value = readl(reg);
+	value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
+	writel(value, reg);
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+}
+
+static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
+				   struct pinctrl_gpio_range *range,
+				   unsigned int offset)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
+	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
+	u32 value, gpio_mux;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+
+	/*
+	 * In most cases, func pin mux 000 means GPIO function.
+	 * But, some pins may have func pin mux 001 represents
+	 * GPIO function.
+	 *
+	 * Because there are devices out there where some pins were not
+	 * configured correctly we allow changing the mux value from
+	 * request (but print out warning about that).
+	 */
+	value = readl(reg) & BYT_PIN_MUX;
+	gpio_mux = byt_get_gpio_mux(vg, offset);
+	if (gpio_mux != value) {
+		value = readl(reg) & ~BYT_PIN_MUX;
+		value |= gpio_mux;
+		writel(value, reg);
+
+		dev_warn(&vg->pdev->dev, FW_BUG
+			 "pin %u forcibly re-configured as GPIO\n", offset);
+	}
+
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+
+	pm_runtime_get(&vg->pdev->dev);
+
+	return 0;
+}
+
+static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
+				  struct pinctrl_gpio_range *range,
+				  unsigned int offset)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
+
+	byt_gpio_clear_triggering(vg, offset);
+	pm_runtime_put(&vg->pdev->dev);
+}
+
+static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
+				  struct pinctrl_gpio_range *range,
+				  unsigned int offset,
+				  bool input)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
+	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
+	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
+	unsigned long flags;
+	u32 value;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+
+	value = readl(val_reg);
+	value &= ~BYT_DIR_MASK;
+	if (input)
+		value |= BYT_OUTPUT_EN;
+	else
+		/*
+		 * Before making any direction modifications, do a check if gpio
+		 * is set for direct IRQ.  On baytrail, setting GPIO to output
+		 * does not make sense, so let's at least warn the caller before
+		 * they shoot themselves in the foot.
+		 */
+		WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
+		     "Potential Error: Setting GPIO with direct_irq_en to output");
+	writel(value, val_reg);
+
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+
+	return 0;
+}
+
+static const struct pinmux_ops byt_pinmux_ops = {
+	.get_functions_count	= byt_get_functions_count,
+	.get_function_name	= byt_get_function_name,
+	.get_function_groups	= byt_get_function_groups,
+	.set_mux		= byt_set_mux,
+	.gpio_request_enable	= byt_gpio_request_enable,
+	.gpio_disable_free	= byt_gpio_disable_free,
+	.gpio_set_direction	= byt_gpio_set_direction,
+};
+
+static void byt_get_pull_strength(u32 reg, u16 *strength)
+{
+	switch (reg & BYT_PULL_STR_MASK) {
+	case BYT_PULL_STR_2K:
+		*strength = 2000;
+		break;
+	case BYT_PULL_STR_10K:
+		*strength = 10000;
+		break;
+	case BYT_PULL_STR_20K:
+		*strength = 20000;
+		break;
+	case BYT_PULL_STR_40K:
+		*strength = 40000;
+		break;
+	}
+}
+
+static int byt_set_pull_strength(u32 *reg, u16 strength)
+{
+	*reg &= ~BYT_PULL_STR_MASK;
+
+	switch (strength) {
+	case 2000:
+		*reg |= BYT_PULL_STR_2K;
+		break;
+	case 10000:
+		*reg |= BYT_PULL_STR_10K;
+		break;
+	case 20000:
+		*reg |= BYT_PULL_STR_20K;
+		break;
+	case 40000:
+		*reg |= BYT_PULL_STR_40K;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
+			      unsigned long *config)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
+	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
+	void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
+	unsigned long flags;
+	u32 conf, pull, val, debounce;
+	u16 arg = 0;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+	conf = readl(conf_reg);
+	pull = conf & BYT_PULL_ASSIGN_MASK;
+	val = readl(val_reg);
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pull)
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		/* Pull assignment is only applicable in input mode */
+		if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN)
+			return -EINVAL;
+
+		byt_get_pull_strength(conf, &arg);
+
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		/* Pull assignment is only applicable in input mode */
+		if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP)
+			return -EINVAL;
+
+		byt_get_pull_strength(conf, &arg);
+
+		break;
+	case PIN_CONFIG_INPUT_DEBOUNCE:
+		if (!(conf & BYT_DEBOUNCE_EN))
+			return -EINVAL;
+
+		raw_spin_lock_irqsave(&vg->lock, flags);
+		debounce = readl(db_reg);
+		raw_spin_unlock_irqrestore(&vg->lock, flags);
+
+		switch (debounce & BYT_DEBOUNCE_PULSE_MASK) {
+		case BYT_DEBOUNCE_PULSE_375US:
+			arg = 375;
+			break;
+		case BYT_DEBOUNCE_PULSE_750US:
+			arg = 750;
+			break;
+		case BYT_DEBOUNCE_PULSE_1500US:
+			arg = 1500;
+			break;
+		case BYT_DEBOUNCE_PULSE_3MS:
+			arg = 3000;
+			break;
+		case BYT_DEBOUNCE_PULSE_6MS:
+			arg = 6000;
+			break;
+		case BYT_DEBOUNCE_PULSE_12MS:
+			arg = 12000;
+			break;
+		case BYT_DEBOUNCE_PULSE_24MS:
+			arg = 24000;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, arg);
+
+	return 0;
+}
+
+static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
+			      unsigned int offset,
+			      unsigned long *configs,
+			      unsigned int num_configs)
+{
+	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
+	unsigned int param, arg;
+	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
+	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
+	void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
+	unsigned long flags;
+	u32 conf, val, debounce;
+	int i, ret = 0;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+
+	conf = readl(conf_reg);
+	val = readl(val_reg);
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_DISABLE:
+			conf &= ~BYT_PULL_ASSIGN_MASK;
+			break;
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			/* Set default strength value in case none is given */
+			if (arg == 1)
+				arg = 2000;
+
+			/*
+			 * Pull assignment is only applicable in input mode. If
+			 * chip is not in input mode, set it and warn about it.
+			 */
+			if (val & BYT_INPUT_EN) {
+				val &= ~BYT_INPUT_EN;
+				writel(val, val_reg);
+				dev_warn(&vg->pdev->dev,
+					 "pin %u forcibly set to input mode\n",
+					 offset);
+			}
+
+			conf &= ~BYT_PULL_ASSIGN_MASK;
+			conf |= BYT_PULL_ASSIGN_DOWN;
+			ret = byt_set_pull_strength(&conf, arg);
+
+			break;
+		case PIN_CONFIG_BIAS_PULL_UP:
+			/* Set default strength value in case none is given */
+			if (arg == 1)
+				arg = 2000;
+
+			/*
+			 * Pull assignment is only applicable in input mode. If
+			 * chip is not in input mode, set it and warn about it.
+			 */
+			if (val & BYT_INPUT_EN) {
+				val &= ~BYT_INPUT_EN;
+				writel(val, val_reg);
+				dev_warn(&vg->pdev->dev,
+					 "pin %u forcibly set to input mode\n",
+					 offset);
+			}
+
+			conf &= ~BYT_PULL_ASSIGN_MASK;
+			conf |= BYT_PULL_ASSIGN_UP;
+			ret = byt_set_pull_strength(&conf, arg);
+
+			break;
+		case PIN_CONFIG_INPUT_DEBOUNCE:
+			debounce = readl(db_reg);
+			debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
+
+			if (arg)
+				conf |= BYT_DEBOUNCE_EN;
+			else
+				conf &= ~BYT_DEBOUNCE_EN;
+
+			switch (arg) {
+			case 375:
+				debounce |= BYT_DEBOUNCE_PULSE_375US;
+				break;
+			case 750:
+				debounce |= BYT_DEBOUNCE_PULSE_750US;
+				break;
+			case 1500:
+				debounce |= BYT_DEBOUNCE_PULSE_1500US;
+				break;
+			case 3000:
+				debounce |= BYT_DEBOUNCE_PULSE_3MS;
+				break;
+			case 6000:
+				debounce |= BYT_DEBOUNCE_PULSE_6MS;
+				break;
+			case 12000:
+				debounce |= BYT_DEBOUNCE_PULSE_12MS;
+				break;
+			case 24000:
+				debounce |= BYT_DEBOUNCE_PULSE_24MS;
+				break;
+			default:
+				if (arg)
+					ret = -EINVAL;
+				break;
+			}
+
+			if (!ret)
+				writel(debounce, db_reg);
+			break;
+		default:
+			ret = -ENOTSUPP;
+		}
+
+		if (ret)
+			break;
+	}
+
+	if (!ret)
+		writel(conf, conf_reg);
+
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+
+	return ret;
+}
+
+static const struct pinconf_ops byt_pinconf_ops = {
+	.is_generic	= true,
+	.pin_config_get	= byt_pin_config_get,
+	.pin_config_set	= byt_pin_config_set,
+};
+
+static const struct pinctrl_desc byt_pinctrl_desc = {
+	.pctlops	= &byt_pinctrl_ops,
+	.pmxops		= &byt_pinmux_ops,
+	.confops	= &byt_pinconf_ops,
+	.owner		= THIS_MODULE,
+};
+
+static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct byt_gpio *vg = gpiochip_get_data(chip);
+	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
+	unsigned long flags;
+	u32 val;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+	val = readl(reg);
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+
+	return !!(val & BYT_LEVEL);
+}
+
+static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct byt_gpio *vg = gpiochip_get_data(chip);
+	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
+	unsigned long flags;
+	u32 old_val;
+
+	if (!reg)
+		return;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+	old_val = readl(reg);
+	if (value)
+		writel(old_val | BYT_LEVEL, reg);
+	else
+		writel(old_val & ~BYT_LEVEL, reg);
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+}
+
+static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+	struct byt_gpio *vg = gpiochip_get_data(chip);
+	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
+	unsigned long flags;
+	u32 value;
+
+	if (!reg)
+		return -EINVAL;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+	value = readl(reg);
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+
+	if (!(value & BYT_OUTPUT_EN))
+		return GPIOF_DIR_OUT;
+	if (!(value & BYT_INPUT_EN))
+		return GPIOF_DIR_IN;
+
+	return -EINVAL;
+}
+
+static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int byt_gpio_direction_output(struct gpio_chip *chip,
+				     unsigned int offset, int value)
+{
+	int ret = pinctrl_gpio_direction_output(chip->base + offset);
+
+	if (ret)
+		return ret;
+
+	byt_gpio_set(chip, offset, value);
+
+	return 0;
+}
+
+static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+	struct byt_gpio *vg = gpiochip_get_data(chip);
+	int i;
+	u32 conf0, val;
+
+	for (i = 0; i < vg->soc_data->npins; i++) {
+		const struct byt_community *comm;
+		const char *pull_str = NULL;
+		const char *pull = NULL;
+		void __iomem *reg;
+		unsigned long flags;
+		const char *label;
+		unsigned int pin;
+
+		raw_spin_lock_irqsave(&vg->lock, flags);
+		pin = vg->soc_data->pins[i].number;
+		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
+		if (!reg) {
+			seq_printf(s,
+				   "Could not retrieve pin %i conf0 reg\n",
+				   pin);
+			raw_spin_unlock_irqrestore(&vg->lock, flags);
+			continue;
+		}
+		conf0 = readl(reg);
+
+		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
+		if (!reg) {
+			seq_printf(s,
+				   "Could not retrieve pin %i val reg\n", pin);
+			raw_spin_unlock_irqrestore(&vg->lock, flags);
+			continue;
+		}
+		val = readl(reg);
+		raw_spin_unlock_irqrestore(&vg->lock, flags);
+
+		comm = byt_get_community(vg, pin);
+		if (!comm) {
+			seq_printf(s,
+				   "Could not get community for pin %i\n", pin);
+			continue;
+		}
+		label = gpiochip_is_requested(chip, i);
+		if (!label)
+			label = "Unrequested";
+
+		switch (conf0 & BYT_PULL_ASSIGN_MASK) {
+		case BYT_PULL_ASSIGN_UP:
+			pull = "up";
+			break;
+		case BYT_PULL_ASSIGN_DOWN:
+			pull = "down";
+			break;
+		}
+
+		switch (conf0 & BYT_PULL_STR_MASK) {
+		case BYT_PULL_STR_2K:
+			pull_str = "2k";
+			break;
+		case BYT_PULL_STR_10K:
+			pull_str = "10k";
+			break;
+		case BYT_PULL_STR_20K:
+			pull_str = "20k";
+			break;
+		case BYT_PULL_STR_40K:
+			pull_str = "40k";
+			break;
+		}
+
+		seq_printf(s,
+			   " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
+			   pin,
+			   label,
+			   val & BYT_INPUT_EN ? "  " : "in",
+			   val & BYT_OUTPUT_EN ? "   " : "out",
+			   val & BYT_LEVEL ? "hi" : "lo",
+			   comm->pad_map[i], comm->pad_map[i] * 16,
+			   conf0 & 0x7,
+			   conf0 & BYT_TRIG_NEG ? " fall" : "     ",
+			   conf0 & BYT_TRIG_POS ? " rise" : "     ",
+			   conf0 & BYT_TRIG_LVL ? " level" : "      ");
+
+		if (pull && pull_str)
+			seq_printf(s, " %-4s %-3s", pull, pull_str);
+		else
+			seq_puts(s, "          ");
+
+		if (conf0 & BYT_IODEN)
+			seq_puts(s, " open-drain");
+
+		seq_puts(s, "\n");
+	}
+}
+
+static const struct gpio_chip byt_gpio_chip = {
+	.owner			= THIS_MODULE,
+	.request		= gpiochip_generic_request,
+	.free			= gpiochip_generic_free,
+	.get_direction		= byt_gpio_get_direction,
+	.direction_input	= byt_gpio_direction_input,
+	.direction_output	= byt_gpio_direction_output,
+	.get			= byt_gpio_get,
+	.set			= byt_gpio_set,
+	.dbg_show		= byt_gpio_dbg_show,
+};
+
+static void byt_irq_ack(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct byt_gpio *vg = gpiochip_get_data(gc);
+	unsigned offset = irqd_to_hwirq(d);
+	void __iomem *reg;
+
+	reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG);
+	if (!reg)
+		return;
+
+	raw_spin_lock(&vg->lock);
+	writel(BIT(offset % 32), reg);
+	raw_spin_unlock(&vg->lock);
+}
+
+static void byt_irq_mask(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct byt_gpio *vg = gpiochip_get_data(gc);
+
+	byt_gpio_clear_triggering(vg, irqd_to_hwirq(d));
+}
+
+static void byt_irq_unmask(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct byt_gpio *vg = gpiochip_get_data(gc);
+	unsigned offset = irqd_to_hwirq(d);
+	unsigned long flags;
+	void __iomem *reg;
+	u32 value;
+
+	reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
+	if (!reg)
+		return;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+	value = readl(reg);
+
+	switch (irqd_get_trigger_type(d)) {
+	case IRQ_TYPE_LEVEL_HIGH:
+		value |= BYT_TRIG_LVL;
+		/* fall through */
+	case IRQ_TYPE_EDGE_RISING:
+		value |= BYT_TRIG_POS;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		value |= BYT_TRIG_LVL;
+		/* fall through */
+	case IRQ_TYPE_EDGE_FALLING:
+		value |= BYT_TRIG_NEG;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
+		break;
+	}
+
+	writel(value, reg);
+
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+}
+
+static int byt_irq_type(struct irq_data *d, unsigned int type)
+{
+	struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
+	u32 offset = irqd_to_hwirq(d);
+	u32 value;
+	unsigned long flags;
+	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
+
+	if (!reg || offset >= vg->chip.ngpio)
+		return -EINVAL;
+
+	raw_spin_lock_irqsave(&vg->lock, flags);
+	value = readl(reg);
+
+	WARN(value & BYT_DIRECT_IRQ_EN,
+	     "Bad pad config for io mode, force direct_irq_en bit clearing");
+
+	/* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
+	 * are used to indicate high and low level triggering
+	 */
+	value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
+		   BYT_TRIG_LVL);
+	/* Enable glitch filtering */
+	value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK |
+		 BYT_GLITCH_F_FAST_CLK;
+
+	writel(value, reg);
+
+	if (type & IRQ_TYPE_EDGE_BOTH)
+		irq_set_handler_locked(d, handle_edge_irq);
+	else if (type & IRQ_TYPE_LEVEL_MASK)
+		irq_set_handler_locked(d, handle_level_irq);
+
+	raw_spin_unlock_irqrestore(&vg->lock, flags);
+
+	return 0;
+}
+
+static struct irq_chip byt_irqchip = {
+	.name		= "BYT-GPIO",
+	.irq_ack	= byt_irq_ack,
+	.irq_mask	= byt_irq_mask,
+	.irq_unmask	= byt_irq_unmask,
+	.irq_set_type	= byt_irq_type,
+	.flags		= IRQCHIP_SKIP_SET_WAKE,
+};
+
+static void byt_gpio_irq_handler(struct irq_desc *desc)
+{
+	struct irq_data *data = irq_desc_get_irq_data(desc);
+	struct byt_gpio *vg = gpiochip_get_data(
+				irq_desc_get_handler_data(desc));
+	struct irq_chip *chip = irq_data_get_irq_chip(data);
+	u32 base, pin;
+	void __iomem *reg;
+	unsigned long pending;
+	unsigned int virq;
+
+	/* check from GPIO controller which pin triggered the interrupt */
+	for (base = 0; base < vg->chip.ngpio; base += 32) {
+		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
+
+		if (!reg) {
+			dev_warn(&vg->pdev->dev,
+				 "Pin %i: could not retrieve interrupt status register\n",
+				 base);
+			continue;
+		}
+
+		raw_spin_lock(&vg->lock);
+		pending = readl(reg);
+		raw_spin_unlock(&vg->lock);
+		for_each_set_bit(pin, &pending, 32) {
+			virq = irq_find_mapping(vg->chip.irq.domain, base + pin);
+			generic_handle_irq(virq);
+		}
+	}
+	chip->irq_eoi(data);
+}
+
+static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
+{
+	struct gpio_chip *gc = &vg->chip;
+	struct device *dev = &vg->pdev->dev;
+	void __iomem *reg;
+	u32 base, value;
+	int i;
+
+	/*
+	 * Clear interrupt triggers for all pins that are GPIOs and
+	 * do not use direct IRQ mode. This will prevent spurious
+	 * interrupts from misconfigured pins.
+	 */
+	for (i = 0; i < vg->soc_data->npins; i++) {
+		unsigned int pin = vg->soc_data->pins[i].number;
+
+		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
+		if (!reg) {
+			dev_warn(&vg->pdev->dev,
+				 "Pin %i: could not retrieve conf0 register\n",
+				 i);
+			continue;
+		}
+
+		value = readl(reg);
+		if (value & BYT_DIRECT_IRQ_EN) {
+			clear_bit(i, gc->irq.valid_mask);
+			dev_dbg(dev, "excluding GPIO %d from IRQ domain\n", i);
+		} else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) {
+			byt_gpio_clear_triggering(vg, i);
+			dev_dbg(dev, "disabling GPIO %d\n", i);
+		}
+	}
+
+	/* clear interrupt status trigger registers */
+	for (base = 0; base < vg->soc_data->npins; base += 32) {
+		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
+
+		if (!reg) {
+			dev_warn(&vg->pdev->dev,
+				 "Pin %i: could not retrieve irq status reg\n",
+				 base);
+			continue;
+		}
+
+		writel(0xffffffff, reg);
+		/* make sure trigger bits are cleared, if not then a pin
+		   might be misconfigured in bios */
+		value = readl(reg);
+		if (value)
+			dev_err(&vg->pdev->dev,
+				"GPIO interrupt error, pins misconfigured. INT_STAT%u: 0x%08x\n",
+				base / 32, value);
+	}
+}
+
+static int byt_gpio_probe(struct byt_gpio *vg)
+{
+	struct gpio_chip *gc;
+	struct resource *irq_rc;
+	int ret;
+
+	/* Set up gpio chip */
+	vg->chip	= byt_gpio_chip;
+	gc		= &vg->chip;
+	gc->label	= dev_name(&vg->pdev->dev);
+	gc->base	= -1;
+	gc->can_sleep	= false;
+	gc->parent	= &vg->pdev->dev;
+	gc->ngpio	= vg->soc_data->npins;
+	gc->irq.need_valid_mask	= true;
+
+#ifdef CONFIG_PM_SLEEP
+	vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio,
+				       sizeof(*vg->saved_context), GFP_KERNEL);
+#endif
+	ret = devm_gpiochip_add_data(&vg->pdev->dev, gc, vg);
+	if (ret) {
+		dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n");
+		return ret;
+	}
+
+	ret = gpiochip_add_pin_range(&vg->chip, dev_name(&vg->pdev->dev),
+				     0, 0, vg->soc_data->npins);
+	if (ret) {
+		dev_err(&vg->pdev->dev, "failed to add GPIO pin range\n");
+		return ret;
+	}
+
+	/* set up interrupts  */
+	irq_rc = platform_get_resource(vg->pdev, IORESOURCE_IRQ, 0);
+	if (irq_rc && irq_rc->start) {
+		byt_gpio_irq_init_hw(vg);
+		ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
+					   handle_bad_irq, IRQ_TYPE_NONE);
+		if (ret) {
+			dev_err(&vg->pdev->dev, "failed to add irqchip\n");
+			return ret;
+		}
+
+		gpiochip_set_chained_irqchip(gc, &byt_irqchip,
+					     (unsigned)irq_rc->start,
+					     byt_gpio_irq_handler);
+	}
+
+	return ret;
+}
+
+static int byt_set_soc_data(struct byt_gpio *vg,
+			    const struct byt_pinctrl_soc_data *soc_data)
+{
+	int i;
+
+	vg->soc_data = soc_data;
+	vg->communities_copy = devm_kcalloc(&vg->pdev->dev,
+					    soc_data->ncommunities,
+					    sizeof(*vg->communities_copy),
+					    GFP_KERNEL);
+	if (!vg->communities_copy)
+		return -ENOMEM;
+
+	for (i = 0; i < soc_data->ncommunities; i++) {
+		struct byt_community *comm = vg->communities_copy + i;
+		struct resource *mem_rc;
+
+		*comm = vg->soc_data->communities[i];
+
+		mem_rc = platform_get_resource(vg->pdev, IORESOURCE_MEM, 0);
+		comm->reg_base = devm_ioremap_resource(&vg->pdev->dev, mem_rc);
+		if (IS_ERR(comm->reg_base))
+			return PTR_ERR(comm->reg_base);
+	}
+
+	return 0;
+}
+
+static const struct acpi_device_id byt_gpio_acpi_match[] = {
+	{ "INT33B2", (kernel_ulong_t)byt_soc_data },
+	{ "INT33FC", (kernel_ulong_t)byt_soc_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
+
+static int byt_pinctrl_probe(struct platform_device *pdev)
+{
+	const struct byt_pinctrl_soc_data *soc_data = NULL;
+	const struct byt_pinctrl_soc_data **soc_table;
+	const struct acpi_device_id *acpi_id;
+	struct acpi_device *acpi_dev;
+	struct byt_gpio *vg;
+	int i, ret;
+
+	acpi_dev = ACPI_COMPANION(&pdev->dev);
+	if (!acpi_dev)
+		return -ENODEV;
+
+	acpi_id = acpi_match_device(byt_gpio_acpi_match, &pdev->dev);
+	if (!acpi_id)
+		return -ENODEV;
+
+	soc_table = (const struct byt_pinctrl_soc_data **)acpi_id->driver_data;
+
+	for (i = 0; soc_table[i]; i++) {
+		if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) {
+			soc_data = soc_table[i];
+			break;
+		}
+	}
+
+	if (!soc_data)
+		return -ENODEV;
+
+	vg = devm_kzalloc(&pdev->dev, sizeof(*vg), GFP_KERNEL);
+	if (!vg)
+		return -ENOMEM;
+
+	vg->pdev = pdev;
+	ret = byt_set_soc_data(vg, soc_data);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to set soc data\n");
+		return ret;
+	}
+
+	vg->pctl_desc		= byt_pinctrl_desc;
+	vg->pctl_desc.name	= dev_name(&pdev->dev);
+	vg->pctl_desc.pins	= vg->soc_data->pins;
+	vg->pctl_desc.npins	= vg->soc_data->npins;
+
+	vg->pctl_dev = devm_pinctrl_register(&pdev->dev, &vg->pctl_desc, vg);
+	if (IS_ERR(vg->pctl_dev)) {
+		dev_err(&pdev->dev, "failed to register pinctrl driver\n");
+		return PTR_ERR(vg->pctl_dev);
+	}
+
+	raw_spin_lock_init(&vg->lock);
+
+	ret = byt_gpio_probe(vg);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, vg);
+	pm_runtime_enable(&pdev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int byt_gpio_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct byt_gpio *vg = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < vg->soc_data->npins; i++) {
+		void __iomem *reg;
+		u32 value;
+		unsigned int pin = vg->soc_data->pins[i].number;
+
+		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
+		if (!reg) {
+			dev_warn(&vg->pdev->dev,
+				 "Pin %i: could not retrieve conf0 register\n",
+				 i);
+			continue;
+		}
+		value = readl(reg) & BYT_CONF0_RESTORE_MASK;
+		vg->saved_context[i].conf0 = value;
+
+		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
+		value = readl(reg) & BYT_VAL_RESTORE_MASK;
+		vg->saved_context[i].val = value;
+	}
+
+	return 0;
+}
+
+static int byt_gpio_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct byt_gpio *vg = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < vg->soc_data->npins; i++) {
+		void __iomem *reg;
+		u32 value;
+		unsigned int pin = vg->soc_data->pins[i].number;
+
+		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
+		if (!reg) {
+			dev_warn(&vg->pdev->dev,
+				 "Pin %i: could not retrieve conf0 register\n",
+				 i);
+			continue;
+		}
+		value = readl(reg);
+		if ((value & BYT_CONF0_RESTORE_MASK) !=
+		     vg->saved_context[i].conf0) {
+			value &= ~BYT_CONF0_RESTORE_MASK;
+			value |= vg->saved_context[i].conf0;
+			writel(value, reg);
+			dev_info(dev, "restored pin %d conf0 %#08x", i, value);
+		}
+
+		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
+		value = readl(reg);
+		if ((value & BYT_VAL_RESTORE_MASK) !=
+		     vg->saved_context[i].val) {
+			u32 v;
+
+			v = value & ~BYT_VAL_RESTORE_MASK;
+			v |= vg->saved_context[i].val;
+			if (v != value) {
+				writel(v, reg);
+				dev_dbg(dev, "restored pin %d val %#08x\n",
+					i, v);
+			}
+		}
+	}
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int byt_gpio_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int byt_gpio_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops byt_gpio_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume)
+	SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume,
+			   NULL)
+};
+
+static struct platform_driver byt_gpio_driver = {
+	.probe          = byt_pinctrl_probe,
+	.driver         = {
+		.name			= "byt_gpio",
+		.pm			= &byt_gpio_pm_ops,
+		.suppress_bind_attrs	= true,
+
+		.acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
+	},
+};
+
+static int __init byt_gpio_init(void)
+{
+	return platform_driver_register(&byt_gpio_driver);
+}
+subsys_initcall(byt_gpio_init);
diff --git a/drivers/pinctrl/intel/pinctrl-broxton.c b/drivers/pinctrl/intel/pinctrl-broxton.c
new file mode 100644
index 0000000..8b1c7b5
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-broxton.c
@@ -0,0 +1,1081 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Broxton SoC pinctrl/GPIO driver
+ *
+ * Copyright (C) 2015, 2016 Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-intel.h"
+
+#define BXT_PAD_OWN	0x020
+#define BXT_HOSTSW_OWN	0x080
+#define BXT_PADCFGLOCK	0x060
+#define BXT_GPI_IE	0x110
+
+#define BXT_COMMUNITY(s, e)				\
+	{						\
+		.padown_offset = BXT_PAD_OWN,		\
+		.padcfglock_offset = BXT_PADCFGLOCK,	\
+		.hostown_offset = BXT_HOSTSW_OWN,	\
+		.ie_offset = BXT_GPI_IE,		\
+		.gpp_size = 32,                         \
+		.pin_base = (s),			\
+		.npins = ((e) - (s) + 1),		\
+	}
+
+/* BXT */
+static const struct pinctrl_pin_desc bxt_north_pins[] = {
+	PINCTRL_PIN(0, "GPIO_0"),
+	PINCTRL_PIN(1, "GPIO_1"),
+	PINCTRL_PIN(2, "GPIO_2"),
+	PINCTRL_PIN(3, "GPIO_3"),
+	PINCTRL_PIN(4, "GPIO_4"),
+	PINCTRL_PIN(5, "GPIO_5"),
+	PINCTRL_PIN(6, "GPIO_6"),
+	PINCTRL_PIN(7, "GPIO_7"),
+	PINCTRL_PIN(8, "GPIO_8"),
+	PINCTRL_PIN(9, "GPIO_9"),
+	PINCTRL_PIN(10, "GPIO_10"),
+	PINCTRL_PIN(11, "GPIO_11"),
+	PINCTRL_PIN(12, "GPIO_12"),
+	PINCTRL_PIN(13, "GPIO_13"),
+	PINCTRL_PIN(14, "GPIO_14"),
+	PINCTRL_PIN(15, "GPIO_15"),
+	PINCTRL_PIN(16, "GPIO_16"),
+	PINCTRL_PIN(17, "GPIO_17"),
+	PINCTRL_PIN(18, "GPIO_18"),
+	PINCTRL_PIN(19, "GPIO_19"),
+	PINCTRL_PIN(20, "GPIO_20"),
+	PINCTRL_PIN(21, "GPIO_21"),
+	PINCTRL_PIN(22, "GPIO_22"),
+	PINCTRL_PIN(23, "GPIO_23"),
+	PINCTRL_PIN(24, "GPIO_24"),
+	PINCTRL_PIN(25, "GPIO_25"),
+	PINCTRL_PIN(26, "GPIO_26"),
+	PINCTRL_PIN(27, "GPIO_27"),
+	PINCTRL_PIN(28, "GPIO_28"),
+	PINCTRL_PIN(29, "GPIO_29"),
+	PINCTRL_PIN(30, "GPIO_30"),
+	PINCTRL_PIN(31, "GPIO_31"),
+	PINCTRL_PIN(32, "GPIO_32"),
+	PINCTRL_PIN(33, "GPIO_33"),
+	PINCTRL_PIN(34, "PWM0"),
+	PINCTRL_PIN(35, "PWM1"),
+	PINCTRL_PIN(36, "PWM2"),
+	PINCTRL_PIN(37, "PWM3"),
+	PINCTRL_PIN(38, "LPSS_UART0_RXD"),
+	PINCTRL_PIN(39, "LPSS_UART0_TXD"),
+	PINCTRL_PIN(40, "LPSS_UART0_RTS_B"),
+	PINCTRL_PIN(41, "LPSS_UART0_CTS_B"),
+	PINCTRL_PIN(42, "LPSS_UART1_RXD"),
+	PINCTRL_PIN(43, "LPSS_UART1_TXD"),
+	PINCTRL_PIN(44, "LPSS_UART1_RTS_B"),
+	PINCTRL_PIN(45, "LPSS_UART1_CTS_B"),
+	PINCTRL_PIN(46, "LPSS_UART2_RXD"),
+	PINCTRL_PIN(47, "LPSS_UART2_TXD"),
+	PINCTRL_PIN(48, "LPSS_UART2_RTS_B"),
+	PINCTRL_PIN(49, "LPSS_UART2_CTS_B"),
+	PINCTRL_PIN(50, "ISH_UART0_RXD"),
+	PINCTRL_PIN(51, "ISH_UART0_TXT"),
+	PINCTRL_PIN(52, "ISH_UART0_RTS_B"),
+	PINCTRL_PIN(53, "ISH_UART0_CTS_B"),
+	PINCTRL_PIN(54, "ISH_UART1_RXD"),
+	PINCTRL_PIN(55, "ISH_UART1_TXT"),
+	PINCTRL_PIN(56, "ISH_UART1_RTS_B"),
+	PINCTRL_PIN(57, "ISH_UART1_CTS_B"),
+	PINCTRL_PIN(58, "ISH_UART2_RXD"),
+	PINCTRL_PIN(59, "ISH_UART2_TXD"),
+	PINCTRL_PIN(60, "ISH_UART2_RTS_B"),
+	PINCTRL_PIN(61, "ISH_UART2_CTS_B"),
+	PINCTRL_PIN(62, "GP_CAMERASB00"),
+	PINCTRL_PIN(63, "GP_CAMERASB01"),
+	PINCTRL_PIN(64, "GP_CAMERASB02"),
+	PINCTRL_PIN(65, "GP_CAMERASB03"),
+	PINCTRL_PIN(66, "GP_CAMERASB04"),
+	PINCTRL_PIN(67, "GP_CAMERASB05"),
+	PINCTRL_PIN(68, "GP_CAMERASB06"),
+	PINCTRL_PIN(69, "GP_CAMERASB07"),
+	PINCTRL_PIN(70, "GP_CAMERASB08"),
+	PINCTRL_PIN(71, "GP_CAMERASB09"),
+	PINCTRL_PIN(72, "GP_CAMERASB10"),
+	PINCTRL_PIN(73, "GP_CAMERASB11"),
+	PINCTRL_PIN(74, "TCK"),
+	PINCTRL_PIN(75, "TRST_B"),
+	PINCTRL_PIN(76, "TMS"),
+	PINCTRL_PIN(77, "TDI"),
+	PINCTRL_PIN(78, "CX_PMODE"),
+	PINCTRL_PIN(79, "CX_PREQ_B"),
+	PINCTRL_PIN(80, "JTAGX"),
+	PINCTRL_PIN(81, "CX_PRDY_B"),
+	PINCTRL_PIN(82, "TDO"),
+};
+
+static const unsigned bxt_north_pwm0_pins[] = { 34 };
+static const unsigned bxt_north_pwm1_pins[] = { 35 };
+static const unsigned bxt_north_pwm2_pins[] = { 36 };
+static const unsigned bxt_north_pwm3_pins[] = { 37 };
+static const unsigned bxt_north_uart0_pins[] = { 38, 39, 40, 41 };
+static const unsigned bxt_north_uart1_pins[] = { 42, 43, 44, 45 };
+static const unsigned bxt_north_uart2_pins[] = { 46, 47, 48, 49 };
+static const unsigned bxt_north_uart0b_pins[] = { 50, 51, 52, 53 };
+static const unsigned bxt_north_uart1b_pins[] = { 54, 55, 56, 57 };
+static const unsigned bxt_north_uart2b_pins[] = { 58, 59, 60, 61 };
+static const unsigned bxt_north_uart3_pins[] = { 58, 59, 60, 61 };
+
+static const struct intel_pingroup bxt_north_groups[] = {
+	PIN_GROUP("pwm0_grp", bxt_north_pwm0_pins, 1),
+	PIN_GROUP("pwm1_grp", bxt_north_pwm1_pins, 1),
+	PIN_GROUP("pwm2_grp", bxt_north_pwm2_pins, 1),
+	PIN_GROUP("pwm3_grp", bxt_north_pwm3_pins, 1),
+	PIN_GROUP("uart0_grp", bxt_north_uart0_pins, 1),
+	PIN_GROUP("uart1_grp", bxt_north_uart1_pins, 1),
+	PIN_GROUP("uart2_grp", bxt_north_uart2_pins, 1),
+	PIN_GROUP("uart0b_grp", bxt_north_uart0b_pins, 2),
+	PIN_GROUP("uart1b_grp", bxt_north_uart1b_pins, 2),
+	PIN_GROUP("uart2b_grp", bxt_north_uart2b_pins, 2),
+	PIN_GROUP("uart3_grp", bxt_north_uart3_pins, 3),
+};
+
+static const char * const bxt_north_pwm0_groups[] = { "pwm0_grp" };
+static const char * const bxt_north_pwm1_groups[] = { "pwm1_grp" };
+static const char * const bxt_north_pwm2_groups[] = { "pwm2_grp" };
+static const char * const bxt_north_pwm3_groups[] = { "pwm3_grp" };
+static const char * const bxt_north_uart0_groups[] = {
+	"uart0_grp", "uart0b_grp",
+};
+static const char * const bxt_north_uart1_groups[] = {
+	"uart1_grp", "uart1b_grp",
+};
+static const char * const bxt_north_uart2_groups[] = {
+	"uart2_grp", "uart2b_grp",
+};
+static const char * const bxt_north_uart3_groups[] = { "uart3_grp" };
+
+static const struct intel_function bxt_north_functions[] = {
+	FUNCTION("pwm0", bxt_north_pwm0_groups),
+	FUNCTION("pwm1", bxt_north_pwm1_groups),
+	FUNCTION("pwm2", bxt_north_pwm2_groups),
+	FUNCTION("pwm3", bxt_north_pwm3_groups),
+	FUNCTION("uart0", bxt_north_uart0_groups),
+	FUNCTION("uart1", bxt_north_uart1_groups),
+	FUNCTION("uart2", bxt_north_uart2_groups),
+	FUNCTION("uart3", bxt_north_uart3_groups),
+};
+
+static const struct intel_community bxt_north_communities[] = {
+	BXT_COMMUNITY(0, 82),
+};
+
+static const struct intel_pinctrl_soc_data bxt_north_soc_data = {
+	.uid = "1",
+	.pins = bxt_north_pins,
+	.npins = ARRAY_SIZE(bxt_north_pins),
+	.groups = bxt_north_groups,
+	.ngroups = ARRAY_SIZE(bxt_north_groups),
+	.functions = bxt_north_functions,
+	.nfunctions = ARRAY_SIZE(bxt_north_functions),
+	.communities = bxt_north_communities,
+	.ncommunities = ARRAY_SIZE(bxt_north_communities),
+};
+
+static const struct pinctrl_pin_desc bxt_northwest_pins[] = {
+	PINCTRL_PIN(0, "PMC_SPI_FS0"),
+	PINCTRL_PIN(1, "PMC_SPI_FS1"),
+	PINCTRL_PIN(2, "PMC_SPI_FS2"),
+	PINCTRL_PIN(3, "PMC_SPI_RXD"),
+	PINCTRL_PIN(4, "PMC_SPI_TXD"),
+	PINCTRL_PIN(5, "PMC_SPI_CLK"),
+	PINCTRL_PIN(6, "PMC_UART_RXD"),
+	PINCTRL_PIN(7, "PMC_UART_TXD"),
+	PINCTRL_PIN(8, "PMIC_PWRGOOD"),
+	PINCTRL_PIN(9, "PMIC_RESET_B"),
+	PINCTRL_PIN(10, "RTC_CLK"),
+	PINCTRL_PIN(11, "PMIC_SDWN_B"),
+	PINCTRL_PIN(12, "PMIC_BCUDISW2"),
+	PINCTRL_PIN(13, "PMIC_BCUDISCRIT"),
+	PINCTRL_PIN(14, "PMIC_THERMTRIP_B"),
+	PINCTRL_PIN(15, "PMIC_STDBY"),
+	PINCTRL_PIN(16, "SVID0_ALERT_B"),
+	PINCTRL_PIN(17, "SVID0_DATA"),
+	PINCTRL_PIN(18, "SVID0_CLK"),
+	PINCTRL_PIN(19, "PMIC_I2C_SCL"),
+	PINCTRL_PIN(20, "PMIC_I2C_SDA"),
+	PINCTRL_PIN(21, "AVS_I2S1_MCLK"),
+	PINCTRL_PIN(22, "AVS_I2S1_BCLK"),
+	PINCTRL_PIN(23, "AVS_I2S1_WS_SYNC"),
+	PINCTRL_PIN(24, "AVS_I2S1_SDI"),
+	PINCTRL_PIN(25, "AVS_I2S1_SDO"),
+	PINCTRL_PIN(26, "AVS_M_CLK_A1"),
+	PINCTRL_PIN(27, "AVS_M_CLK_B1"),
+	PINCTRL_PIN(28, "AVS_M_DATA_1"),
+	PINCTRL_PIN(29, "AVS_M_CLK_AB2"),
+	PINCTRL_PIN(30, "AVS_M_DATA_2"),
+	PINCTRL_PIN(31, "AVS_I2S2_MCLK"),
+	PINCTRL_PIN(32, "AVS_I2S2_BCLK"),
+	PINCTRL_PIN(33, "AVS_I2S2_WS_SYNC"),
+	PINCTRL_PIN(34, "AVS_I2S2_SDI"),
+	PINCTRL_PIN(35, "AVS_I2S2_SDOK"),
+	PINCTRL_PIN(36, "AVS_I2S3_BCLK"),
+	PINCTRL_PIN(37, "AVS_I2S3_WS_SYNC"),
+	PINCTRL_PIN(38, "AVS_I2S3_SDI"),
+	PINCTRL_PIN(39, "AVS_I2S3_SDO"),
+	PINCTRL_PIN(40, "AVS_I2S4_BCLK"),
+	PINCTRL_PIN(41, "AVS_I2S4_WS_SYNC"),
+	PINCTRL_PIN(42, "AVS_I2S4_SDI"),
+	PINCTRL_PIN(43, "AVS_I2S4_SDO"),
+	PINCTRL_PIN(44, "PROCHOT_B"),
+	PINCTRL_PIN(45, "FST_SPI_CS0_B"),
+	PINCTRL_PIN(46, "FST_SPI_CS1_B"),
+	PINCTRL_PIN(47, "FST_SPI_MOSI_IO0"),
+	PINCTRL_PIN(48, "FST_SPI_MISO_IO1"),
+	PINCTRL_PIN(49, "FST_SPI_IO2"),
+	PINCTRL_PIN(50, "FST_SPI_IO3"),
+	PINCTRL_PIN(51, "FST_SPI_CLK"),
+	PINCTRL_PIN(52, "FST_SPI_CLK_FB"),
+	PINCTRL_PIN(53, "GP_SSP_0_CLK"),
+	PINCTRL_PIN(54, "GP_SSP_0_FS0"),
+	PINCTRL_PIN(55, "GP_SSP_0_FS1"),
+	PINCTRL_PIN(56, "GP_SSP_0_FS2"),
+	PINCTRL_PIN(57, "GP_SSP_0_RXD"),
+	PINCTRL_PIN(58, "GP_SSP_0_TXD"),
+	PINCTRL_PIN(59, "GP_SSP_1_CLK"),
+	PINCTRL_PIN(60, "GP_SSP_1_FS0"),
+	PINCTRL_PIN(61, "GP_SSP_1_FS1"),
+	PINCTRL_PIN(62, "GP_SSP_1_FS2"),
+	PINCTRL_PIN(63, "GP_SSP_1_FS3"),
+	PINCTRL_PIN(64, "GP_SSP_1_RXD"),
+	PINCTRL_PIN(65, "GP_SSP_1_TXD"),
+	PINCTRL_PIN(66, "GP_SSP_2_CLK"),
+	PINCTRL_PIN(67, "GP_SSP_2_FS0"),
+	PINCTRL_PIN(68, "GP_SSP_2_FS1"),
+	PINCTRL_PIN(69, "GP_SSP_2_FS2"),
+	PINCTRL_PIN(70, "GP_SSP_2_RXD"),
+	PINCTRL_PIN(71, "GP_SSP_2_TXD"),
+};
+
+static const unsigned bxt_northwest_ssp0_pins[] = { 53, 54, 55, 56, 57, 58 };
+static const unsigned bxt_northwest_ssp1_pins[] = {
+	59, 60, 61, 62, 63, 64, 65
+};
+static const unsigned bxt_northwest_ssp2_pins[] = { 66, 67, 68, 69, 70, 71 };
+static const unsigned bxt_northwest_uart3_pins[] = { 67, 68, 69, 70 };
+
+static const struct intel_pingroup bxt_northwest_groups[] = {
+	PIN_GROUP("ssp0_grp", bxt_northwest_ssp0_pins, 1),
+	PIN_GROUP("ssp1_grp", bxt_northwest_ssp1_pins, 1),
+	PIN_GROUP("ssp2_grp", bxt_northwest_ssp2_pins, 1),
+	PIN_GROUP("uart3_grp", bxt_northwest_uart3_pins, 2),
+};
+
+static const char * const bxt_northwest_ssp0_groups[] = { "ssp0_grp" };
+static const char * const bxt_northwest_ssp1_groups[] = { "ssp1_grp" };
+static const char * const bxt_northwest_ssp2_groups[] = { "ssp2_grp" };
+static const char * const bxt_northwest_uart3_groups[] = { "uart3_grp" };
+
+static const struct intel_function bxt_northwest_functions[] = {
+	FUNCTION("ssp0", bxt_northwest_ssp0_groups),
+	FUNCTION("ssp1", bxt_northwest_ssp1_groups),
+	FUNCTION("ssp2", bxt_northwest_ssp2_groups),
+	FUNCTION("uart3", bxt_northwest_uart3_groups),
+};
+
+static const struct intel_community bxt_northwest_communities[] = {
+	BXT_COMMUNITY(0, 71),
+};
+
+static const struct intel_pinctrl_soc_data bxt_northwest_soc_data = {
+	.uid = "2",
+	.pins = bxt_northwest_pins,
+	.npins = ARRAY_SIZE(bxt_northwest_pins),
+	.groups = bxt_northwest_groups,
+	.ngroups = ARRAY_SIZE(bxt_northwest_groups),
+	.functions = bxt_northwest_functions,
+	.nfunctions = ARRAY_SIZE(bxt_northwest_functions),
+	.communities = bxt_northwest_communities,
+	.ncommunities = ARRAY_SIZE(bxt_northwest_communities),
+};
+
+static const struct pinctrl_pin_desc bxt_west_pins[] = {
+	PINCTRL_PIN(0, "LPSS_I2C0_SDA"),
+	PINCTRL_PIN(1, "LPSS_I2C0_SCL"),
+	PINCTRL_PIN(2, "LPSS_I2C1_SDA"),
+	PINCTRL_PIN(3, "LPSS_I2C1_SCL"),
+	PINCTRL_PIN(4, "LPSS_I2C2_SDA"),
+	PINCTRL_PIN(5, "LPSS_I2C2_SCL"),
+	PINCTRL_PIN(6, "LPSS_I2C3_SDA"),
+	PINCTRL_PIN(7, "LPSS_I2C3_SCL"),
+	PINCTRL_PIN(8, "LPSS_I2C4_SDA"),
+	PINCTRL_PIN(9, "LPSS_I2C4_SCL"),
+	PINCTRL_PIN(10, "LPSS_I2C5_SDA"),
+	PINCTRL_PIN(11, "LPSS_I2C5_SCL"),
+	PINCTRL_PIN(12, "LPSS_I2C6_SDA"),
+	PINCTRL_PIN(13, "LPSS_I2C6_SCL"),
+	PINCTRL_PIN(14, "LPSS_I2C7_SDA"),
+	PINCTRL_PIN(15, "LPSS_I2C7_SCL"),
+	PINCTRL_PIN(16, "ISH_I2C0_SDA"),
+	PINCTRL_PIN(17, "ISH_I2C0_SCL"),
+	PINCTRL_PIN(18, "ISH_I2C1_SDA"),
+	PINCTRL_PIN(19, "ISH_I2C1_SCL"),
+	PINCTRL_PIN(20, "ISH_I2C2_SDA"),
+	PINCTRL_PIN(21, "ISH_I2C2_SCL"),
+	PINCTRL_PIN(22, "ISH_GPIO_0"),
+	PINCTRL_PIN(23, "ISH_GPIO_1"),
+	PINCTRL_PIN(24, "ISH_GPIO_2"),
+	PINCTRL_PIN(25, "ISH_GPIO_3"),
+	PINCTRL_PIN(26, "ISH_GPIO_4"),
+	PINCTRL_PIN(27, "ISH_GPIO_5"),
+	PINCTRL_PIN(28, "ISH_GPIO_6"),
+	PINCTRL_PIN(29, "ISH_GPIO_7"),
+	PINCTRL_PIN(30, "ISH_GPIO_8"),
+	PINCTRL_PIN(31, "ISH_GPIO_9"),
+	PINCTRL_PIN(32, "MODEM_CLKREQ"),
+	PINCTRL_PIN(33, "DGCLKDBG_PMC_0"),
+	PINCTRL_PIN(34, "DGCLKDBG_PMC_1"),
+	PINCTRL_PIN(35, "DGCLKDBG_PMC_2"),
+	PINCTRL_PIN(36, "DGCLKDBG_ICLK_0"),
+	PINCTRL_PIN(37, "DGCLKDBG_ICLK_1"),
+	PINCTRL_PIN(38, "OSC_CLK_OUT_0"),
+	PINCTRL_PIN(39, "OSC_CLK_OUT_1"),
+	PINCTRL_PIN(40, "OSC_CLK_OUT_2"),
+	PINCTRL_PIN(41, "OSC_CLK_OUT_3"),
+};
+
+static const unsigned bxt_west_i2c0_pins[] = { 0, 1 };
+static const unsigned bxt_west_i2c1_pins[] = { 2, 3 };
+static const unsigned bxt_west_i2c2_pins[] = { 4, 5 };
+static const unsigned bxt_west_i2c3_pins[] = { 6, 7 };
+static const unsigned bxt_west_i2c4_pins[] = { 8, 9 };
+static const unsigned bxt_west_i2c5_pins[] = { 10, 11 };
+static const unsigned bxt_west_i2c6_pins[] = { 12, 13 };
+static const unsigned bxt_west_i2c7_pins[] = { 14, 15 };
+static const unsigned bxt_west_i2c5b_pins[] = { 16, 17 };
+static const unsigned bxt_west_i2c6b_pins[] = { 18, 19 };
+static const unsigned bxt_west_i2c7b_pins[] = { 20, 21 };
+
+static const struct intel_pingroup bxt_west_groups[] = {
+	PIN_GROUP("i2c0_grp", bxt_west_i2c0_pins, 1),
+	PIN_GROUP("i2c1_grp", bxt_west_i2c1_pins, 1),
+	PIN_GROUP("i2c2_grp", bxt_west_i2c2_pins, 1),
+	PIN_GROUP("i2c3_grp", bxt_west_i2c3_pins, 1),
+	PIN_GROUP("i2c4_grp", bxt_west_i2c4_pins, 1),
+	PIN_GROUP("i2c5_grp", bxt_west_i2c5_pins, 1),
+	PIN_GROUP("i2c6_grp", bxt_west_i2c6_pins, 1),
+	PIN_GROUP("i2c7_grp", bxt_west_i2c7_pins, 1),
+	PIN_GROUP("i2c5b_grp", bxt_west_i2c5b_pins, 2),
+	PIN_GROUP("i2c6b_grp", bxt_west_i2c6b_pins, 2),
+	PIN_GROUP("i2c7b_grp", bxt_west_i2c7b_pins, 2),
+};
+
+static const char * const bxt_west_i2c0_groups[] = { "i2c0_grp" };
+static const char * const bxt_west_i2c1_groups[] = { "i2c1_grp" };
+static const char * const bxt_west_i2c2_groups[] = { "i2c2_grp" };
+static const char * const bxt_west_i2c3_groups[] = { "i2c3_grp" };
+static const char * const bxt_west_i2c4_groups[] = { "i2c4_grp" };
+static const char * const bxt_west_i2c5_groups[] = { "i2c5_grp", "i2c5b_grp" };
+static const char * const bxt_west_i2c6_groups[] = { "i2c6_grp", "i2c6b_grp" };
+static const char * const bxt_west_i2c7_groups[] = { "i2c7_grp", "i2c7b_grp" };
+
+static const struct intel_function bxt_west_functions[] = {
+	FUNCTION("i2c0", bxt_west_i2c0_groups),
+	FUNCTION("i2c1", bxt_west_i2c1_groups),
+	FUNCTION("i2c2", bxt_west_i2c2_groups),
+	FUNCTION("i2c3", bxt_west_i2c3_groups),
+	FUNCTION("i2c4", bxt_west_i2c4_groups),
+	FUNCTION("i2c5", bxt_west_i2c5_groups),
+	FUNCTION("i2c6", bxt_west_i2c6_groups),
+	FUNCTION("i2c7", bxt_west_i2c7_groups),
+};
+
+static const struct intel_community bxt_west_communities[] = {
+	BXT_COMMUNITY(0, 41),
+};
+
+static const struct intel_pinctrl_soc_data bxt_west_soc_data = {
+	.uid = "3",
+	.pins = bxt_west_pins,
+	.npins = ARRAY_SIZE(bxt_west_pins),
+	.groups = bxt_west_groups,
+	.ngroups = ARRAY_SIZE(bxt_west_groups),
+	.functions = bxt_west_functions,
+	.nfunctions = ARRAY_SIZE(bxt_west_functions),
+	.communities = bxt_west_communities,
+	.ncommunities = ARRAY_SIZE(bxt_west_communities),
+};
+
+static const struct pinctrl_pin_desc bxt_southwest_pins[] = {
+	PINCTRL_PIN(0, "EMMC0_CLK"),
+	PINCTRL_PIN(1, "EMMC0_D0"),
+	PINCTRL_PIN(2, "EMMC0_D1"),
+	PINCTRL_PIN(3, "EMMC0_D2"),
+	PINCTRL_PIN(4, "EMMC0_D3"),
+	PINCTRL_PIN(5, "EMMC0_D4"),
+	PINCTRL_PIN(6, "EMMC0_D5"),
+	PINCTRL_PIN(7, "EMMC0_D6"),
+	PINCTRL_PIN(8, "EMMC0_D7"),
+	PINCTRL_PIN(9, "EMMC0_CMD"),
+	PINCTRL_PIN(10, "SDIO_CLK"),
+	PINCTRL_PIN(11, "SDIO_D0"),
+	PINCTRL_PIN(12, "SDIO_D1"),
+	PINCTRL_PIN(13, "SDIO_D2"),
+	PINCTRL_PIN(14, "SDIO_D3"),
+	PINCTRL_PIN(15, "SDIO_CMD"),
+	PINCTRL_PIN(16, "SDCARD_CLK"),
+	PINCTRL_PIN(17, "SDCARD_D0"),
+	PINCTRL_PIN(18, "SDCARD_D1"),
+	PINCTRL_PIN(19, "SDCARD_D2"),
+	PINCTRL_PIN(20, "SDCARD_D3"),
+	PINCTRL_PIN(21, "SDCARD_CD_B"),
+	PINCTRL_PIN(22, "SDCARD_CMD"),
+	PINCTRL_PIN(23, "SDCARD_LVL_CLK_FB"),
+	PINCTRL_PIN(24, "SDCARD_LVL_CMD_DIR"),
+	PINCTRL_PIN(25, "SDCARD_LVL_DAT_DIR"),
+	PINCTRL_PIN(26, "EMMC0_STROBE"),
+	PINCTRL_PIN(27, "SDIO_PWR_DOWN_B"),
+	PINCTRL_PIN(28, "SDCARD_PWR_DOWN_B"),
+	PINCTRL_PIN(29, "SDCARD_LVL_SEL"),
+	PINCTRL_PIN(30, "SDCARD_LVL_WP"),
+};
+
+static const unsigned bxt_southwest_emmc0_pins[] = {
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 26,
+};
+static const unsigned bxt_southwest_sdio_pins[] = {
+	10, 11, 12, 13, 14, 15, 27,
+};
+static const unsigned bxt_southwest_sdcard_pins[] = {
+	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30,
+};
+
+static const struct intel_pingroup bxt_southwest_groups[] = {
+	PIN_GROUP("emmc0_grp", bxt_southwest_emmc0_pins, 1),
+	PIN_GROUP("sdio_grp", bxt_southwest_sdio_pins, 1),
+	PIN_GROUP("sdcard_grp", bxt_southwest_sdcard_pins, 1),
+};
+
+static const char * const bxt_southwest_emmc0_groups[] = { "emmc0_grp" };
+static const char * const bxt_southwest_sdio_groups[] = { "sdio_grp" };
+static const char * const bxt_southwest_sdcard_groups[] = { "sdcard_grp" };
+
+static const struct intel_function bxt_southwest_functions[] = {
+	FUNCTION("emmc0", bxt_southwest_emmc0_groups),
+	FUNCTION("sdio", bxt_southwest_sdio_groups),
+	FUNCTION("sdcard", bxt_southwest_sdcard_groups),
+};
+
+static const struct intel_community bxt_southwest_communities[] = {
+	BXT_COMMUNITY(0, 30),
+};
+
+static const struct intel_pinctrl_soc_data bxt_southwest_soc_data = {
+	.uid = "4",
+	.pins = bxt_southwest_pins,
+	.npins = ARRAY_SIZE(bxt_southwest_pins),
+	.groups = bxt_southwest_groups,
+	.ngroups = ARRAY_SIZE(bxt_southwest_groups),
+	.functions = bxt_southwest_functions,
+	.nfunctions = ARRAY_SIZE(bxt_southwest_functions),
+	.communities = bxt_southwest_communities,
+	.ncommunities = ARRAY_SIZE(bxt_southwest_communities),
+};
+
+static const struct pinctrl_pin_desc bxt_south_pins[] = {
+	PINCTRL_PIN(0, "HV_DDI0_DDC_SDA"),
+	PINCTRL_PIN(1, "HV_DDI0_DDC_SCL"),
+	PINCTRL_PIN(2, "HV_DDI1_DDC_SDA"),
+	PINCTRL_PIN(3, "HV_DDI1_DDC_SCL"),
+	PINCTRL_PIN(4, "DBI_SDA"),
+	PINCTRL_PIN(5, "DBI_SCL"),
+	PINCTRL_PIN(6, "PANEL0_VDDEN"),
+	PINCTRL_PIN(7, "PANEL0_BKLTEN"),
+	PINCTRL_PIN(8, "PANEL0_BKLTCTL"),
+	PINCTRL_PIN(9, "PANEL1_VDDEN"),
+	PINCTRL_PIN(10, "PANEL1_BKLTEN"),
+	PINCTRL_PIN(11, "PANEL1_BKLTCTL"),
+	PINCTRL_PIN(12, "DBI_CSX"),
+	PINCTRL_PIN(13, "DBI_RESX"),
+	PINCTRL_PIN(14, "GP_INTD_DSI_TE1"),
+	PINCTRL_PIN(15, "GP_INTD_DSI_TE2"),
+	PINCTRL_PIN(16, "USB_OC0_B"),
+	PINCTRL_PIN(17, "USB_OC1_B"),
+	PINCTRL_PIN(18, "MEX_WAKE0_B"),
+	PINCTRL_PIN(19, "MEX_WAKE1_B"),
+};
+
+static const struct intel_community bxt_south_communities[] = {
+	BXT_COMMUNITY(0, 19),
+};
+
+static const struct intel_pinctrl_soc_data bxt_south_soc_data = {
+	.uid = "5",
+	.pins = bxt_south_pins,
+	.npins = ARRAY_SIZE(bxt_south_pins),
+	.communities = bxt_south_communities,
+	.ncommunities = ARRAY_SIZE(bxt_south_communities),
+};
+
+static const struct intel_pinctrl_soc_data *bxt_pinctrl_soc_data[] = {
+	&bxt_north_soc_data,
+	&bxt_northwest_soc_data,
+	&bxt_west_soc_data,
+	&bxt_southwest_soc_data,
+	&bxt_south_soc_data,
+	NULL,
+};
+
+/* APL */
+static const struct pinctrl_pin_desc apl_north_pins[] = {
+	PINCTRL_PIN(0, "GPIO_0"),
+	PINCTRL_PIN(1, "GPIO_1"),
+	PINCTRL_PIN(2, "GPIO_2"),
+	PINCTRL_PIN(3, "GPIO_3"),
+	PINCTRL_PIN(4, "GPIO_4"),
+	PINCTRL_PIN(5, "GPIO_5"),
+	PINCTRL_PIN(6, "GPIO_6"),
+	PINCTRL_PIN(7, "GPIO_7"),
+	PINCTRL_PIN(8, "GPIO_8"),
+	PINCTRL_PIN(9, "GPIO_9"),
+	PINCTRL_PIN(10, "GPIO_10"),
+	PINCTRL_PIN(11, "GPIO_11"),
+	PINCTRL_PIN(12, "GPIO_12"),
+	PINCTRL_PIN(13, "GPIO_13"),
+	PINCTRL_PIN(14, "GPIO_14"),
+	PINCTRL_PIN(15, "GPIO_15"),
+	PINCTRL_PIN(16, "GPIO_16"),
+	PINCTRL_PIN(17, "GPIO_17"),
+	PINCTRL_PIN(18, "GPIO_18"),
+	PINCTRL_PIN(19, "GPIO_19"),
+	PINCTRL_PIN(20, "GPIO_20"),
+	PINCTRL_PIN(21, "GPIO_21"),
+	PINCTRL_PIN(22, "GPIO_22"),
+	PINCTRL_PIN(23, "GPIO_23"),
+	PINCTRL_PIN(24, "GPIO_24"),
+	PINCTRL_PIN(25, "GPIO_25"),
+	PINCTRL_PIN(26, "GPIO_26"),
+	PINCTRL_PIN(27, "GPIO_27"),
+	PINCTRL_PIN(28, "GPIO_28"),
+	PINCTRL_PIN(29, "GPIO_29"),
+	PINCTRL_PIN(30, "GPIO_30"),
+	PINCTRL_PIN(31, "GPIO_31"),
+	PINCTRL_PIN(32, "GPIO_32"),
+	PINCTRL_PIN(33, "GPIO_33"),
+	PINCTRL_PIN(34, "PWM0"),
+	PINCTRL_PIN(35, "PWM1"),
+	PINCTRL_PIN(36, "PWM2"),
+	PINCTRL_PIN(37, "PWM3"),
+	PINCTRL_PIN(38, "LPSS_UART0_RXD"),
+	PINCTRL_PIN(39, "LPSS_UART0_TXD"),
+	PINCTRL_PIN(40, "LPSS_UART0_RTS_B"),
+	PINCTRL_PIN(41, "LPSS_UART0_CTS_B"),
+	PINCTRL_PIN(42, "LPSS_UART1_RXD"),
+	PINCTRL_PIN(43, "LPSS_UART1_TXD"),
+	PINCTRL_PIN(44, "LPSS_UART1_RTS_B"),
+	PINCTRL_PIN(45, "LPSS_UART1_CTS_B"),
+	PINCTRL_PIN(46, "LPSS_UART2_RXD"),
+	PINCTRL_PIN(47, "LPSS_UART2_TXD"),
+	PINCTRL_PIN(48, "LPSS_UART2_RTS_B"),
+	PINCTRL_PIN(49, "LPSS_UART2_CTS_B"),
+	PINCTRL_PIN(50, "GP_CAMERASB00"),
+	PINCTRL_PIN(51, "GP_CAMERASB01"),
+	PINCTRL_PIN(52, "GP_CAMERASB02"),
+	PINCTRL_PIN(53, "GP_CAMERASB03"),
+	PINCTRL_PIN(54, "GP_CAMERASB04"),
+	PINCTRL_PIN(55, "GP_CAMERASB05"),
+	PINCTRL_PIN(56, "GP_CAMERASB06"),
+	PINCTRL_PIN(57, "GP_CAMERASB07"),
+	PINCTRL_PIN(58, "GP_CAMERASB08"),
+	PINCTRL_PIN(59, "GP_CAMERASB09"),
+	PINCTRL_PIN(60, "GP_CAMERASB10"),
+	PINCTRL_PIN(61, "GP_CAMERASB11"),
+	PINCTRL_PIN(62, "TCK"),
+	PINCTRL_PIN(63, "TRST_B"),
+	PINCTRL_PIN(64, "TMS"),
+	PINCTRL_PIN(65, "TDI"),
+	PINCTRL_PIN(66, "CX_PMODE"),
+	PINCTRL_PIN(67, "CX_PREQ_B"),
+	PINCTRL_PIN(68, "JTAGX"),
+	PINCTRL_PIN(69, "CX_PRDY_B"),
+	PINCTRL_PIN(70, "TDO"),
+	PINCTRL_PIN(71, "CNV_BRI_DT"),
+	PINCTRL_PIN(72, "CNV_BRI_RSP"),
+	PINCTRL_PIN(73, "CNV_RGI_DT"),
+	PINCTRL_PIN(74, "CNV_RGI_RSP"),
+	PINCTRL_PIN(75, "SVID0_ALERT_B"),
+	PINCTRL_PIN(76, "SVID0_DATA"),
+	PINCTRL_PIN(77, "SVID0_CLK"),
+};
+
+static const unsigned apl_north_pwm0_pins[] = { 34 };
+static const unsigned apl_north_pwm1_pins[] = { 35 };
+static const unsigned apl_north_pwm2_pins[] = { 36 };
+static const unsigned apl_north_pwm3_pins[] = { 37 };
+static const unsigned apl_north_uart0_pins[] = { 38, 39, 40, 41 };
+static const unsigned apl_north_uart1_pins[] = { 42, 43, 44, 45 };
+static const unsigned apl_north_uart2_pins[] = { 46, 47, 48, 49 };
+
+static const struct intel_pingroup apl_north_groups[] = {
+	PIN_GROUP("pwm0_grp", apl_north_pwm0_pins, 1),
+	PIN_GROUP("pwm1_grp", apl_north_pwm1_pins, 1),
+	PIN_GROUP("pwm2_grp", apl_north_pwm2_pins, 1),
+	PIN_GROUP("pwm3_grp", apl_north_pwm3_pins, 1),
+	PIN_GROUP("uart0_grp", apl_north_uart0_pins, 1),
+	PIN_GROUP("uart1_grp", apl_north_uart1_pins, 1),
+	PIN_GROUP("uart2_grp", apl_north_uart2_pins, 1),
+};
+
+static const char * const apl_north_pwm0_groups[] = { "pwm0_grp" };
+static const char * const apl_north_pwm1_groups[] = { "pwm1_grp" };
+static const char * const apl_north_pwm2_groups[] = { "pwm2_grp" };
+static const char * const apl_north_pwm3_groups[] = { "pwm3_grp" };
+static const char * const apl_north_uart0_groups[] = { "uart0_grp" };
+static const char * const apl_north_uart1_groups[] = { "uart1_grp" };
+static const char * const apl_north_uart2_groups[] = { "uart2_grp" };
+
+static const struct intel_function apl_north_functions[] = {
+	FUNCTION("pwm0", apl_north_pwm0_groups),
+	FUNCTION("pwm1", apl_north_pwm1_groups),
+	FUNCTION("pwm2", apl_north_pwm2_groups),
+	FUNCTION("pwm3", apl_north_pwm3_groups),
+	FUNCTION("uart0", apl_north_uart0_groups),
+	FUNCTION("uart1", apl_north_uart1_groups),
+	FUNCTION("uart2", apl_north_uart2_groups),
+};
+
+static const struct intel_community apl_north_communities[] = {
+	BXT_COMMUNITY(0, 77),
+};
+
+static const struct intel_pinctrl_soc_data apl_north_soc_data = {
+	.uid = "1",
+	.pins = apl_north_pins,
+	.npins = ARRAY_SIZE(apl_north_pins),
+	.groups = apl_north_groups,
+	.ngroups = ARRAY_SIZE(apl_north_groups),
+	.functions = apl_north_functions,
+	.nfunctions = ARRAY_SIZE(apl_north_functions),
+	.communities = apl_north_communities,
+	.ncommunities = ARRAY_SIZE(apl_north_communities),
+};
+
+static const struct pinctrl_pin_desc apl_northwest_pins[] = {
+	PINCTRL_PIN(0, "HV_DDI0_DDC_SDA"),
+	PINCTRL_PIN(1, "HV_DDI0_DDC_SCL"),
+	PINCTRL_PIN(2, "HV_DDI1_DDC_SDA"),
+	PINCTRL_PIN(3, "HV_DDI1_DDC_SCL"),
+	PINCTRL_PIN(4, "DBI_SDA"),
+	PINCTRL_PIN(5, "DBI_SCL"),
+	PINCTRL_PIN(6, "PANEL0_VDDEN"),
+	PINCTRL_PIN(7, "PANEL0_BKLTEN"),
+	PINCTRL_PIN(8, "PANEL0_BKLTCTL"),
+	PINCTRL_PIN(9, "PANEL1_VDDEN"),
+	PINCTRL_PIN(10, "PANEL1_BKLTEN"),
+	PINCTRL_PIN(11, "PANEL1_BKLTCTL"),
+	PINCTRL_PIN(12, "DBI_CSX"),
+	PINCTRL_PIN(13, "DBI_RESX"),
+	PINCTRL_PIN(14, "GP_INTD_DSI_TE1"),
+	PINCTRL_PIN(15, "GP_INTD_DSI_TE2"),
+	PINCTRL_PIN(16, "USB_OC0_B"),
+	PINCTRL_PIN(17, "USB_OC1_B"),
+	PINCTRL_PIN(18, "PMC_SPI_FS0"),
+	PINCTRL_PIN(19, "PMC_SPI_FS1"),
+	PINCTRL_PIN(20, "PMC_SPI_FS2"),
+	PINCTRL_PIN(21, "PMC_SPI_RXD"),
+	PINCTRL_PIN(22, "PMC_SPI_TXD"),
+	PINCTRL_PIN(23, "PMC_SPI_CLK"),
+	PINCTRL_PIN(24, "PMIC_PWRGOOD"),
+	PINCTRL_PIN(25, "PMIC_RESET_B"),
+	PINCTRL_PIN(26, "PMIC_SDWN_B"),
+	PINCTRL_PIN(27, "PMIC_BCUDISW2"),
+	PINCTRL_PIN(28, "PMIC_BCUDISCRIT"),
+	PINCTRL_PIN(29, "PMIC_THERMTRIP_B"),
+	PINCTRL_PIN(30, "PMIC_STDBY"),
+	PINCTRL_PIN(31, "PROCHOT_B"),
+	PINCTRL_PIN(32, "PMIC_I2C_SCL"),
+	PINCTRL_PIN(33, "PMIC_I2C_SDA"),
+	PINCTRL_PIN(34, "AVS_I2S1_MCLK"),
+	PINCTRL_PIN(35, "AVS_I2S1_BCLK"),
+	PINCTRL_PIN(36, "AVS_I2S1_WS_SYNC"),
+	PINCTRL_PIN(37, "AVS_I2S1_SDI"),
+	PINCTRL_PIN(38, "AVS_I2S1_SDO"),
+	PINCTRL_PIN(39, "AVS_M_CLK_A1"),
+	PINCTRL_PIN(40, "AVS_M_CLK_B1"),
+	PINCTRL_PIN(41, "AVS_M_DATA_1"),
+	PINCTRL_PIN(42, "AVS_M_CLK_AB2"),
+	PINCTRL_PIN(43, "AVS_M_DATA_2"),
+	PINCTRL_PIN(44, "AVS_I2S2_MCLK"),
+	PINCTRL_PIN(45, "AVS_I2S2_BCLK"),
+	PINCTRL_PIN(46, "AVS_I2S2_WS_SYNC"),
+	PINCTRL_PIN(47, "AVS_I2S2_SDI"),
+	PINCTRL_PIN(48, "AVS_I2S2_SDO"),
+	PINCTRL_PIN(49, "AVS_I2S3_BCLK"),
+	PINCTRL_PIN(50, "AVS_I2S3_WS_SYNC"),
+	PINCTRL_PIN(51, "AVS_I2S3_SDI"),
+	PINCTRL_PIN(52, "AVS_I2S3_SDO"),
+	PINCTRL_PIN(53, "FST_SPI_CS0_B"),
+	PINCTRL_PIN(54, "FST_SPI_CS1_B"),
+	PINCTRL_PIN(55, "FST_SPI_MOSI_IO0"),
+	PINCTRL_PIN(56, "FST_SPI_MISO_IO1"),
+	PINCTRL_PIN(57, "FST_SPI_IO2"),
+	PINCTRL_PIN(58, "FST_SPI_IO3"),
+	PINCTRL_PIN(59, "FST_SPI_CLK"),
+	PINCTRL_PIN(60, "FST_SPI_CLK_FB"),
+	PINCTRL_PIN(61, "GP_SSP_0_CLK"),
+	PINCTRL_PIN(62, "GP_SSP_0_FS0"),
+	PINCTRL_PIN(63, "GP_SSP_0_FS1"),
+	PINCTRL_PIN(64, "GP_SSP_0_RXD"),
+	PINCTRL_PIN(65, "GP_SSP_0_TXD"),
+	PINCTRL_PIN(66, "GP_SSP_1_CLK"),
+	PINCTRL_PIN(67, "GP_SSP_1_FS0"),
+	PINCTRL_PIN(68, "GP_SSP_1_FS1"),
+	PINCTRL_PIN(69, "GP_SSP_1_RXD"),
+	PINCTRL_PIN(70, "GP_SSP_1_TXD"),
+	PINCTRL_PIN(71, "GP_SSP_2_CLK"),
+	PINCTRL_PIN(72, "GP_SSP_2_FS0"),
+	PINCTRL_PIN(73, "GP_SSP_2_FS1"),
+	PINCTRL_PIN(74, "GP_SSP_2_FS2"),
+	PINCTRL_PIN(75, "GP_SSP_2_RXD"),
+	PINCTRL_PIN(76, "GP_SSP_2_TXD"),
+};
+
+static const unsigned apl_northwest_ssp0_pins[] = { 61, 62, 63, 64, 65 };
+static const unsigned apl_northwest_ssp1_pins[] = { 66, 67, 68, 69, 70 };
+static const unsigned apl_northwest_ssp2_pins[] = { 71, 72, 73, 74, 75, 76 };
+static const unsigned apl_northwest_uart3_pins[] = { 67, 68, 69, 70 };
+
+static const struct intel_pingroup apl_northwest_groups[] = {
+	PIN_GROUP("ssp0_grp", apl_northwest_ssp0_pins, 1),
+	PIN_GROUP("ssp1_grp", apl_northwest_ssp1_pins, 1),
+	PIN_GROUP("ssp2_grp", apl_northwest_ssp2_pins, 1),
+	PIN_GROUP("uart3_grp", apl_northwest_uart3_pins, 2),
+};
+
+static const char * const apl_northwest_ssp0_groups[] = { "ssp0_grp" };
+static const char * const apl_northwest_ssp1_groups[] = { "ssp1_grp" };
+static const char * const apl_northwest_ssp2_groups[] = { "ssp2_grp" };
+static const char * const apl_northwest_uart3_groups[] = { "uart3_grp" };
+
+static const struct intel_function apl_northwest_functions[] = {
+	FUNCTION("ssp0", apl_northwest_ssp0_groups),
+	FUNCTION("ssp1", apl_northwest_ssp1_groups),
+	FUNCTION("ssp2", apl_northwest_ssp2_groups),
+	FUNCTION("uart3", apl_northwest_uart3_groups),
+};
+
+static const struct intel_community apl_northwest_communities[] = {
+	BXT_COMMUNITY(0, 76),
+};
+
+static const struct intel_pinctrl_soc_data apl_northwest_soc_data = {
+	.uid = "2",
+	.pins = apl_northwest_pins,
+	.npins = ARRAY_SIZE(apl_northwest_pins),
+	.groups = apl_northwest_groups,
+	.ngroups = ARRAY_SIZE(apl_northwest_groups),
+	.functions = apl_northwest_functions,
+	.nfunctions = ARRAY_SIZE(apl_northwest_functions),
+	.communities = apl_northwest_communities,
+	.ncommunities = ARRAY_SIZE(apl_northwest_communities),
+};
+
+static const struct pinctrl_pin_desc apl_west_pins[] = {
+	PINCTRL_PIN(0, "LPSS_I2C0_SDA"),
+	PINCTRL_PIN(1, "LPSS_I2C0_SCL"),
+	PINCTRL_PIN(2, "LPSS_I2C1_SDA"),
+	PINCTRL_PIN(3, "LPSS_I2C1_SCL"),
+	PINCTRL_PIN(4, "LPSS_I2C2_SDA"),
+	PINCTRL_PIN(5, "LPSS_I2C2_SCL"),
+	PINCTRL_PIN(6, "LPSS_I2C3_SDA"),
+	PINCTRL_PIN(7, "LPSS_I2C3_SCL"),
+	PINCTRL_PIN(8, "LPSS_I2C4_SDA"),
+	PINCTRL_PIN(9, "LPSS_I2C4_SCL"),
+	PINCTRL_PIN(10, "LPSS_I2C5_SDA"),
+	PINCTRL_PIN(11, "LPSS_I2C5_SCL"),
+	PINCTRL_PIN(12, "LPSS_I2C6_SDA"),
+	PINCTRL_PIN(13, "LPSS_I2C6_SCL"),
+	PINCTRL_PIN(14, "LPSS_I2C7_SDA"),
+	PINCTRL_PIN(15, "LPSS_I2C7_SCL"),
+	PINCTRL_PIN(16, "ISH_GPIO_0"),
+	PINCTRL_PIN(17, "ISH_GPIO_1"),
+	PINCTRL_PIN(18, "ISH_GPIO_2"),
+	PINCTRL_PIN(19, "ISH_GPIO_3"),
+	PINCTRL_PIN(20, "ISH_GPIO_4"),
+	PINCTRL_PIN(21, "ISH_GPIO_5"),
+	PINCTRL_PIN(22, "ISH_GPIO_6"),
+	PINCTRL_PIN(23, "ISH_GPIO_7"),
+	PINCTRL_PIN(24, "ISH_GPIO_8"),
+	PINCTRL_PIN(25, "ISH_GPIO_9"),
+	PINCTRL_PIN(26, "PCIE_CLKREQ0_B"),
+	PINCTRL_PIN(27, "PCIE_CLKREQ1_B"),
+	PINCTRL_PIN(28, "PCIE_CLKREQ2_B"),
+	PINCTRL_PIN(29, "PCIE_CLKREQ3_B"),
+	PINCTRL_PIN(30, "OSC_CLK_OUT_0"),
+	PINCTRL_PIN(31, "OSC_CLK_OUT_1"),
+	PINCTRL_PIN(32, "OSC_CLK_OUT_2"),
+	PINCTRL_PIN(33, "OSC_CLK_OUT_3"),
+	PINCTRL_PIN(34, "OSC_CLK_OUT_4"),
+	PINCTRL_PIN(35, "PMU_AC_PRESENT"),
+	PINCTRL_PIN(36, "PMU_BATLOW_B"),
+	PINCTRL_PIN(37, "PMU_PLTRST_B"),
+	PINCTRL_PIN(38, "PMU_PWRBTN_B"),
+	PINCTRL_PIN(39, "PMU_RESETBUTTON_B"),
+	PINCTRL_PIN(40, "PMU_SLP_S0_B"),
+	PINCTRL_PIN(41, "PMU_SLP_S3_B"),
+	PINCTRL_PIN(42, "PMU_SLP_S4_B"),
+	PINCTRL_PIN(43, "PMU_SUSCLK"),
+	PINCTRL_PIN(44, "PMU_WAKE_B"),
+	PINCTRL_PIN(45, "SUS_STAT_B"),
+	PINCTRL_PIN(46, "SUSPWRDNACK"),
+};
+
+static const unsigned apl_west_i2c0_pins[] = { 0, 1 };
+static const unsigned apl_west_i2c1_pins[] = { 2, 3 };
+static const unsigned apl_west_i2c2_pins[] = { 4, 5 };
+static const unsigned apl_west_i2c3_pins[] = { 6, 7 };
+static const unsigned apl_west_i2c4_pins[] = { 8, 9 };
+static const unsigned apl_west_i2c5_pins[] = { 10, 11 };
+static const unsigned apl_west_i2c6_pins[] = { 12, 13 };
+static const unsigned apl_west_i2c7_pins[] = { 14, 15 };
+static const unsigned apl_west_uart2_pins[] = { 20, 21, 22, 34 };
+
+static const struct intel_pingroup apl_west_groups[] = {
+	PIN_GROUP("i2c0_grp", apl_west_i2c0_pins, 1),
+	PIN_GROUP("i2c1_grp", apl_west_i2c1_pins, 1),
+	PIN_GROUP("i2c2_grp", apl_west_i2c2_pins, 1),
+	PIN_GROUP("i2c3_grp", apl_west_i2c3_pins, 1),
+	PIN_GROUP("i2c4_grp", apl_west_i2c4_pins, 1),
+	PIN_GROUP("i2c5_grp", apl_west_i2c5_pins, 1),
+	PIN_GROUP("i2c6_grp", apl_west_i2c6_pins, 1),
+	PIN_GROUP("i2c7_grp", apl_west_i2c7_pins, 1),
+	PIN_GROUP("uart2_grp", apl_west_uart2_pins, 3),
+};
+
+static const char * const apl_west_i2c0_groups[] = { "i2c0_grp" };
+static const char * const apl_west_i2c1_groups[] = { "i2c1_grp" };
+static const char * const apl_west_i2c2_groups[] = { "i2c2_grp" };
+static const char * const apl_west_i2c3_groups[] = { "i2c3_grp" };
+static const char * const apl_west_i2c4_groups[] = { "i2c4_grp" };
+static const char * const apl_west_i2c5_groups[] = { "i2c5_grp" };
+static const char * const apl_west_i2c6_groups[] = { "i2c6_grp" };
+static const char * const apl_west_i2c7_groups[] = { "i2c7_grp" };
+static const char * const apl_west_uart2_groups[] = { "uart2_grp" };
+
+static const struct intel_function apl_west_functions[] = {
+	FUNCTION("i2c0", apl_west_i2c0_groups),
+	FUNCTION("i2c1", apl_west_i2c1_groups),
+	FUNCTION("i2c2", apl_west_i2c2_groups),
+	FUNCTION("i2c3", apl_west_i2c3_groups),
+	FUNCTION("i2c4", apl_west_i2c4_groups),
+	FUNCTION("i2c5", apl_west_i2c5_groups),
+	FUNCTION("i2c6", apl_west_i2c6_groups),
+	FUNCTION("i2c7", apl_west_i2c7_groups),
+	FUNCTION("uart2", apl_west_uart2_groups),
+};
+
+static const struct intel_community apl_west_communities[] = {
+	BXT_COMMUNITY(0, 46),
+};
+
+static const struct intel_pinctrl_soc_data apl_west_soc_data = {
+	.uid = "3",
+	.pins = apl_west_pins,
+	.npins = ARRAY_SIZE(apl_west_pins),
+	.groups = apl_west_groups,
+	.ngroups = ARRAY_SIZE(apl_west_groups),
+	.functions = apl_west_functions,
+	.nfunctions = ARRAY_SIZE(apl_west_functions),
+	.communities = apl_west_communities,
+	.ncommunities = ARRAY_SIZE(apl_west_communities),
+};
+
+static const struct pinctrl_pin_desc apl_southwest_pins[] = {
+	PINCTRL_PIN(0, "PCIE_WAKE0_B"),
+	PINCTRL_PIN(1, "PCIE_WAKE1_B"),
+	PINCTRL_PIN(2, "PCIE_WAKE2_B"),
+	PINCTRL_PIN(3, "PCIE_WAKE3_B"),
+	PINCTRL_PIN(4, "EMMC0_CLK"),
+	PINCTRL_PIN(5, "EMMC0_D0"),
+	PINCTRL_PIN(6, "EMMC0_D1"),
+	PINCTRL_PIN(7, "EMMC0_D2"),
+	PINCTRL_PIN(8, "EMMC0_D3"),
+	PINCTRL_PIN(9, "EMMC0_D4"),
+	PINCTRL_PIN(10, "EMMC0_D5"),
+	PINCTRL_PIN(11, "EMMC0_D6"),
+	PINCTRL_PIN(12, "EMMC0_D7"),
+	PINCTRL_PIN(13, "EMMC0_CMD"),
+	PINCTRL_PIN(14, "SDIO_CLK"),
+	PINCTRL_PIN(15, "SDIO_D0"),
+	PINCTRL_PIN(16, "SDIO_D1"),
+	PINCTRL_PIN(17, "SDIO_D2"),
+	PINCTRL_PIN(18, "SDIO_D3"),
+	PINCTRL_PIN(19, "SDIO_CMD"),
+	PINCTRL_PIN(20, "SDCARD_CLK"),
+	PINCTRL_PIN(21, "SDCARD_CLK_FB"),
+	PINCTRL_PIN(22, "SDCARD_D0"),
+	PINCTRL_PIN(23, "SDCARD_D1"),
+	PINCTRL_PIN(24, "SDCARD_D2"),
+	PINCTRL_PIN(25, "SDCARD_D3"),
+	PINCTRL_PIN(26, "SDCARD_CD_B"),
+	PINCTRL_PIN(27, "SDCARD_CMD"),
+	PINCTRL_PIN(28, "SDCARD_LVL_WP"),
+	PINCTRL_PIN(29, "EMMC0_STROBE"),
+	PINCTRL_PIN(30, "SDIO_PWR_DOWN_B"),
+	PINCTRL_PIN(31, "SMB_ALERTB"),
+	PINCTRL_PIN(32, "SMB_CLK"),
+	PINCTRL_PIN(33, "SMB_DATA"),
+	PINCTRL_PIN(34, "LPC_ILB_SERIRQ"),
+	PINCTRL_PIN(35, "LPC_CLKOUT0"),
+	PINCTRL_PIN(36, "LPC_CLKOUT1"),
+	PINCTRL_PIN(37, "LPC_AD0"),
+	PINCTRL_PIN(38, "LPC_AD1"),
+	PINCTRL_PIN(39, "LPC_AD2"),
+	PINCTRL_PIN(40, "LPC_AD3"),
+	PINCTRL_PIN(41, "LPC_CLKRUNB"),
+	PINCTRL_PIN(42, "LPC_FRAMEB"),
+};
+
+static const unsigned apl_southwest_emmc0_pins[] = {
+	4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 29,
+};
+static const unsigned apl_southwest_sdio_pins[] = {
+	14, 15, 16, 17, 18, 19, 30,
+};
+static const unsigned apl_southwest_sdcard_pins[] = {
+	20, 21, 22, 23, 24, 25, 26, 27, 28,
+};
+static const unsigned apl_southwest_i2c7_pins[] = { 32, 33 };
+
+static const struct intel_pingroup apl_southwest_groups[] = {
+	PIN_GROUP("emmc0_grp", apl_southwest_emmc0_pins, 1),
+	PIN_GROUP("sdio_grp", apl_southwest_sdio_pins, 1),
+	PIN_GROUP("sdcard_grp", apl_southwest_sdcard_pins, 1),
+	PIN_GROUP("i2c7_grp", apl_southwest_i2c7_pins, 2),
+};
+
+static const char * const apl_southwest_emmc0_groups[] = { "emmc0_grp" };
+static const char * const apl_southwest_sdio_groups[] = { "sdio_grp" };
+static const char * const apl_southwest_sdcard_groups[] = { "sdcard_grp" };
+static const char * const apl_southwest_i2c7_groups[] = { "i2c7_grp" };
+
+static const struct intel_function apl_southwest_functions[] = {
+	FUNCTION("emmc0", apl_southwest_emmc0_groups),
+	FUNCTION("sdio", apl_southwest_sdio_groups),
+	FUNCTION("sdcard", apl_southwest_sdcard_groups),
+	FUNCTION("i2c7", apl_southwest_i2c7_groups),
+};
+
+static const struct intel_community apl_southwest_communities[] = {
+	BXT_COMMUNITY(0, 42),
+};
+
+static const struct intel_pinctrl_soc_data apl_southwest_soc_data = {
+	.uid = "4",
+	.pins = apl_southwest_pins,
+	.npins = ARRAY_SIZE(apl_southwest_pins),
+	.groups = apl_southwest_groups,
+	.ngroups = ARRAY_SIZE(apl_southwest_groups),
+	.functions = apl_southwest_functions,
+	.nfunctions = ARRAY_SIZE(apl_southwest_functions),
+	.communities = apl_southwest_communities,
+	.ncommunities = ARRAY_SIZE(apl_southwest_communities),
+};
+
+static const struct intel_pinctrl_soc_data *apl_pinctrl_soc_data[] = {
+	&apl_north_soc_data,
+	&apl_northwest_soc_data,
+	&apl_west_soc_data,
+	&apl_southwest_soc_data,
+	NULL,
+};
+
+static const struct acpi_device_id bxt_pinctrl_acpi_match[] = {
+	{ "INT3452", (kernel_ulong_t)apl_pinctrl_soc_data },
+	{ "INT34D1", (kernel_ulong_t)bxt_pinctrl_soc_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, bxt_pinctrl_acpi_match);
+
+static const struct platform_device_id bxt_pinctrl_platform_ids[] = {
+	{ "apollolake-pinctrl", (kernel_ulong_t)apl_pinctrl_soc_data },
+	{ "broxton-pinctrl", (kernel_ulong_t)bxt_pinctrl_soc_data },
+	{ },
+};
+
+static int bxt_pinctrl_probe(struct platform_device *pdev)
+{
+	const struct intel_pinctrl_soc_data *soc_data = NULL;
+	const struct intel_pinctrl_soc_data **soc_table;
+	struct acpi_device *adev;
+	int i;
+
+	adev = ACPI_COMPANION(&pdev->dev);
+	if (adev) {
+		const struct acpi_device_id *id;
+
+		id = acpi_match_device(bxt_pinctrl_acpi_match, &pdev->dev);
+		if (!id)
+			return -ENODEV;
+
+		soc_table = (const struct intel_pinctrl_soc_data **)
+			id->driver_data;
+
+		for (i = 0; soc_table[i]; i++) {
+			if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) {
+				soc_data = soc_table[i];
+				break;
+			}
+		}
+	} else {
+		const struct platform_device_id *pid;
+
+		pid = platform_get_device_id(pdev);
+		if (!pid)
+			return -ENODEV;
+
+		soc_table = (const struct intel_pinctrl_soc_data **)
+			pid->driver_data;
+		soc_data = soc_table[pdev->id];
+	}
+
+	if (!soc_data)
+		return -ENODEV;
+
+	return intel_pinctrl_probe(pdev, soc_data);
+}
+
+static const struct dev_pm_ops bxt_pinctrl_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
+				     intel_pinctrl_resume)
+};
+
+static struct platform_driver bxt_pinctrl_driver = {
+	.probe = bxt_pinctrl_probe,
+	.driver = {
+		.name = "broxton-pinctrl",
+		.acpi_match_table = bxt_pinctrl_acpi_match,
+		.pm = &bxt_pinctrl_pm_ops,
+	},
+	.id_table = bxt_pinctrl_platform_ids,
+};
+
+static int __init bxt_pinctrl_init(void)
+{
+	return platform_driver_register(&bxt_pinctrl_driver);
+}
+subsys_initcall(bxt_pinctrl_init);
+
+static void __exit bxt_pinctrl_exit(void)
+{
+	platform_driver_unregister(&bxt_pinctrl_driver);
+}
+module_exit(bxt_pinctrl_exit);
+
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+MODULE_DESCRIPTION("Intel Broxton SoC pinctrl/GPIO driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:broxton-pinctrl");
diff --git a/drivers/pinctrl/intel/pinctrl-cannonlake.c b/drivers/pinctrl/intel/pinctrl-cannonlake.c
new file mode 100644
index 0000000..e7f45d9
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-cannonlake.c
@@ -0,0 +1,867 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Cannon Lake PCH pinctrl/GPIO driver
+ *
+ * Copyright (C) 2017, Intel Corporation
+ * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+ *          Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-intel.h"
+
+#define CNL_PAD_OWN		0x020
+#define CNL_PADCFGLOCK		0x080
+#define CNL_LP_HOSTSW_OWN	0x0b0
+#define CNL_H_HOSTSW_OWN	0x0c0
+#define CNL_GPI_IE		0x120
+
+#define CNL_GPP(r, s, e, g)				\
+	{						\
+		.reg_num = (r),				\
+		.base = (s),				\
+		.size = ((e) - (s) + 1),		\
+		.gpio_base = (g),			\
+	}
+
+#define CNL_NO_GPIO	-1
+
+#define CNL_COMMUNITY(b, s, e, o, g)			\
+	{						\
+		.barno = (b),				\
+		.padown_offset = CNL_PAD_OWN,		\
+		.padcfglock_offset = CNL_PADCFGLOCK,	\
+		.hostown_offset = (o),			\
+		.ie_offset = CNL_GPI_IE,		\
+		.pin_base = (s),			\
+		.npins = ((e) - (s) + 1),		\
+		.gpps = (g),				\
+		.ngpps = ARRAY_SIZE(g),			\
+	}
+
+#define CNLLP_COMMUNITY(b, s, e, g)			\
+	CNL_COMMUNITY(b, s, e, CNL_LP_HOSTSW_OWN, g)
+
+#define CNLH_COMMUNITY(b, s, e, g)			\
+	CNL_COMMUNITY(b, s, e, CNL_H_HOSTSW_OWN, g)
+
+/* Cannon Lake-H */
+static const struct pinctrl_pin_desc cnlh_pins[] = {
+	/* GPP_A */
+	PINCTRL_PIN(0, "RCINB"),
+	PINCTRL_PIN(1, "LAD_0"),
+	PINCTRL_PIN(2, "LAD_1"),
+	PINCTRL_PIN(3, "LAD_2"),
+	PINCTRL_PIN(4, "LAD_3"),
+	PINCTRL_PIN(5, "LFRAMEB"),
+	PINCTRL_PIN(6, "SERIRQ"),
+	PINCTRL_PIN(7, "PIRQAB"),
+	PINCTRL_PIN(8, "CLKRUNB"),
+	PINCTRL_PIN(9, "CLKOUT_LPC_0"),
+	PINCTRL_PIN(10, "CLKOUT_LPC_1"),
+	PINCTRL_PIN(11, "PMEB"),
+	PINCTRL_PIN(12, "BM_BUSYB"),
+	PINCTRL_PIN(13, "SUSWARNB_SUSPWRDNACK"),
+	PINCTRL_PIN(14, "SUS_STATB"),
+	PINCTRL_PIN(15, "SUSACKB"),
+	PINCTRL_PIN(16, "CLKOUT_48"),
+	PINCTRL_PIN(17, "SD_VDD1_PWR_EN_B"),
+	PINCTRL_PIN(18, "ISH_GP_0"),
+	PINCTRL_PIN(19, "ISH_GP_1"),
+	PINCTRL_PIN(20, "ISH_GP_2"),
+	PINCTRL_PIN(21, "ISH_GP_3"),
+	PINCTRL_PIN(22, "ISH_GP_4"),
+	PINCTRL_PIN(23, "ISH_GP_5"),
+	PINCTRL_PIN(24, "ESPI_CLK_LOOPBK"),
+	/* GPP_B */
+	PINCTRL_PIN(25, "GSPI0_CS1B"),
+	PINCTRL_PIN(26, "GSPI1_CS1B"),
+	PINCTRL_PIN(27, "VRALERTB"),
+	PINCTRL_PIN(28, "CPU_GP_2"),
+	PINCTRL_PIN(29, "CPU_GP_3"),
+	PINCTRL_PIN(30, "SRCCLKREQB_0"),
+	PINCTRL_PIN(31, "SRCCLKREQB_1"),
+	PINCTRL_PIN(32, "SRCCLKREQB_2"),
+	PINCTRL_PIN(33, "SRCCLKREQB_3"),
+	PINCTRL_PIN(34, "SRCCLKREQB_4"),
+	PINCTRL_PIN(35, "SRCCLKREQB_5"),
+	PINCTRL_PIN(36, "SSP_MCLK"),
+	PINCTRL_PIN(37, "SLP_S0B"),
+	PINCTRL_PIN(38, "PLTRSTB"),
+	PINCTRL_PIN(39, "SPKR"),
+	PINCTRL_PIN(40, "GSPI0_CS0B"),
+	PINCTRL_PIN(41, "GSPI0_CLK"),
+	PINCTRL_PIN(42, "GSPI0_MISO"),
+	PINCTRL_PIN(43, "GSPI0_MOSI"),
+	PINCTRL_PIN(44, "GSPI1_CS0B"),
+	PINCTRL_PIN(45, "GSPI1_CLK"),
+	PINCTRL_PIN(46, "GSPI1_MISO"),
+	PINCTRL_PIN(47, "GSPI1_MOSI"),
+	PINCTRL_PIN(48, "SML1ALERTB"),
+	PINCTRL_PIN(49, "GSPI0_CLK_LOOPBK"),
+	PINCTRL_PIN(50, "GSPI1_CLK_LOOPBK"),
+	/* GPP_C */
+	PINCTRL_PIN(51, "SMBCLK"),
+	PINCTRL_PIN(52, "SMBDATA"),
+	PINCTRL_PIN(53, "SMBALERTB"),
+	PINCTRL_PIN(54, "SML0CLK"),
+	PINCTRL_PIN(55, "SML0DATA"),
+	PINCTRL_PIN(56, "SML0ALERTB"),
+	PINCTRL_PIN(57, "SML1CLK"),
+	PINCTRL_PIN(58, "SML1DATA"),
+	PINCTRL_PIN(59, "UART0_RXD"),
+	PINCTRL_PIN(60, "UART0_TXD"),
+	PINCTRL_PIN(61, "UART0_RTSB"),
+	PINCTRL_PIN(62, "UART0_CTSB"),
+	PINCTRL_PIN(63, "UART1_RXD"),
+	PINCTRL_PIN(64, "UART1_TXD"),
+	PINCTRL_PIN(65, "UART1_RTSB"),
+	PINCTRL_PIN(66, "UART1_CTSB"),
+	PINCTRL_PIN(67, "I2C0_SDA"),
+	PINCTRL_PIN(68, "I2C0_SCL"),
+	PINCTRL_PIN(69, "I2C1_SDA"),
+	PINCTRL_PIN(70, "I2C1_SCL"),
+	PINCTRL_PIN(71, "UART2_RXD"),
+	PINCTRL_PIN(72, "UART2_TXD"),
+	PINCTRL_PIN(73, "UART2_RTSB"),
+	PINCTRL_PIN(74, "UART2_CTSB"),
+	/* GPP_D */
+	PINCTRL_PIN(75, "SPI1_CSB"),
+	PINCTRL_PIN(76, "SPI1_CLK"),
+	PINCTRL_PIN(77, "SPI1_MISO_IO_1"),
+	PINCTRL_PIN(78, "SPI1_MOSI_IO_0"),
+	PINCTRL_PIN(79, "ISH_I2C2_SDA"),
+	PINCTRL_PIN(80, "SSP2_SFRM"),
+	PINCTRL_PIN(81, "SSP2_TXD"),
+	PINCTRL_PIN(82, "SSP2_RXD"),
+	PINCTRL_PIN(83, "SSP2_SCLK"),
+	PINCTRL_PIN(84, "ISH_SPI_CSB"),
+	PINCTRL_PIN(85, "ISH_SPI_CLK"),
+	PINCTRL_PIN(86, "ISH_SPI_MISO"),
+	PINCTRL_PIN(87, "ISH_SPI_MOSI"),
+	PINCTRL_PIN(88, "ISH_UART0_RXD"),
+	PINCTRL_PIN(89, "ISH_UART0_TXD"),
+	PINCTRL_PIN(90, "ISH_UART0_RTSB"),
+	PINCTRL_PIN(91, "ISH_UART0_CTSB"),
+	PINCTRL_PIN(92, "DMIC_CLK_1"),
+	PINCTRL_PIN(93, "DMIC_DATA_1"),
+	PINCTRL_PIN(94, "DMIC_CLK_0"),
+	PINCTRL_PIN(95, "DMIC_DATA_0"),
+	PINCTRL_PIN(96, "SPI1_IO_2"),
+	PINCTRL_PIN(97, "SPI1_IO_3"),
+	PINCTRL_PIN(98, "ISH_I2C2_SCL"),
+	/* GPP_G */
+	PINCTRL_PIN(99, "SD3_CMD"),
+	PINCTRL_PIN(100, "SD3_D0"),
+	PINCTRL_PIN(101, "SD3_D1"),
+	PINCTRL_PIN(102, "SD3_D2"),
+	PINCTRL_PIN(103, "SD3_D3"),
+	PINCTRL_PIN(104, "SD3_CDB"),
+	PINCTRL_PIN(105, "SD3_CLK"),
+	PINCTRL_PIN(106, "SD3_WP"),
+	/* AZA */
+	PINCTRL_PIN(107, "HDA_BCLK"),
+	PINCTRL_PIN(108, "HDA_RSTB"),
+	PINCTRL_PIN(109, "HDA_SYNC"),
+	PINCTRL_PIN(110, "HDA_SDO"),
+	PINCTRL_PIN(111, "HDA_SDI_0"),
+	PINCTRL_PIN(112, "HDA_SDI_1"),
+	PINCTRL_PIN(113, "SSP1_SFRM"),
+	PINCTRL_PIN(114, "SSP1_TXD"),
+	/* vGPIO */
+	PINCTRL_PIN(115, "CNV_BTEN"),
+	PINCTRL_PIN(116, "CNV_GNEN"),
+	PINCTRL_PIN(117, "CNV_WFEN"),
+	PINCTRL_PIN(118, "CNV_WCEN"),
+	PINCTRL_PIN(119, "CNV_BT_HOST_WAKEB"),
+	PINCTRL_PIN(120, "vCNV_GNSS_HOST_WAKEB"),
+	PINCTRL_PIN(121, "vSD3_CD_B"),
+	PINCTRL_PIN(122, "CNV_BT_IF_SELECT"),
+	PINCTRL_PIN(123, "vCNV_BT_UART_TXD"),
+	PINCTRL_PIN(124, "vCNV_BT_UART_RXD"),
+	PINCTRL_PIN(125, "vCNV_BT_UART_CTS_B"),
+	PINCTRL_PIN(126, "vCNV_BT_UART_RTS_B"),
+	PINCTRL_PIN(127, "vCNV_MFUART1_TXD"),
+	PINCTRL_PIN(128, "vCNV_MFUART1_RXD"),
+	PINCTRL_PIN(129, "vCNV_MFUART1_CTS_B"),
+	PINCTRL_PIN(130, "vCNV_MFUART1_RTS_B"),
+	PINCTRL_PIN(131, "vCNV_GNSS_UART_TXD"),
+	PINCTRL_PIN(132, "vCNV_GNSS_UART_RXD"),
+	PINCTRL_PIN(133, "vCNV_GNSS_UART_CTS_B"),
+	PINCTRL_PIN(134, "vCNV_GNSS_UART_RTS_B"),
+	PINCTRL_PIN(135, "vUART0_TXD"),
+	PINCTRL_PIN(136, "vUART0_RXD"),
+	PINCTRL_PIN(137, "vUART0_CTS_B"),
+	PINCTRL_PIN(138, "vUART0_RTSB"),
+	PINCTRL_PIN(139, "vISH_UART0_TXD"),
+	PINCTRL_PIN(140, "vISH_UART0_RXD"),
+	PINCTRL_PIN(141, "vISH_UART0_CTS_B"),
+	PINCTRL_PIN(142, "vISH_UART0_RTSB"),
+	PINCTRL_PIN(143, "vISH_UART1_TXD"),
+	PINCTRL_PIN(144, "vISH_UART1_RXD"),
+	PINCTRL_PIN(145, "vISH_UART1_CTS_B"),
+	PINCTRL_PIN(146, "vISH_UART1_RTS_B"),
+	PINCTRL_PIN(147, "vCNV_BT_I2S_BCLK"),
+	PINCTRL_PIN(148, "vCNV_BT_I2S_WS_SYNC"),
+	PINCTRL_PIN(149, "vCNV_BT_I2S_SDO"),
+	PINCTRL_PIN(150, "vCNV_BT_I2S_SDI"),
+	PINCTRL_PIN(151, "vSSP2_SCLK"),
+	PINCTRL_PIN(152, "vSSP2_SFRM"),
+	PINCTRL_PIN(153, "vSSP2_TXD"),
+	PINCTRL_PIN(154, "vSSP2_RXD"),
+	/* GPP_K */
+	PINCTRL_PIN(155, "FAN_TACH_0"),
+	PINCTRL_PIN(156, "FAN_TACH_1"),
+	PINCTRL_PIN(157, "FAN_TACH_2"),
+	PINCTRL_PIN(158, "FAN_TACH_3"),
+	PINCTRL_PIN(159, "FAN_TACH_4"),
+	PINCTRL_PIN(160, "FAN_TACH_5"),
+	PINCTRL_PIN(161, "FAN_TACH_6"),
+	PINCTRL_PIN(162, "FAN_TACH_7"),
+	PINCTRL_PIN(163, "FAN_PWM_0"),
+	PINCTRL_PIN(164, "FAN_PWM_1"),
+	PINCTRL_PIN(165, "FAN_PWM_2"),
+	PINCTRL_PIN(166, "FAN_PWM_3"),
+	PINCTRL_PIN(167, "GSXDOUT"),
+	PINCTRL_PIN(168, "GSXSLOAD"),
+	PINCTRL_PIN(169, "GSXDIN"),
+	PINCTRL_PIN(170, "GSXSRESETB"),
+	PINCTRL_PIN(171, "GSXCLK"),
+	PINCTRL_PIN(172, "ADR_COMPLETE"),
+	PINCTRL_PIN(173, "NMIB"),
+	PINCTRL_PIN(174, "SMIB"),
+	PINCTRL_PIN(175, "CORE_VID_0"),
+	PINCTRL_PIN(176, "CORE_VID_1"),
+	PINCTRL_PIN(177, "IMGCLKOUT_0"),
+	PINCTRL_PIN(178, "IMGCLKOUT_1"),
+	/* GPP_H */
+	PINCTRL_PIN(179, "SRCCLKREQB_6"),
+	PINCTRL_PIN(180, "SRCCLKREQB_7"),
+	PINCTRL_PIN(181, "SRCCLKREQB_8"),
+	PINCTRL_PIN(182, "SRCCLKREQB_9"),
+	PINCTRL_PIN(183, "SRCCLKREQB_10"),
+	PINCTRL_PIN(184, "SRCCLKREQB_11"),
+	PINCTRL_PIN(185, "SRCCLKREQB_12"),
+	PINCTRL_PIN(186, "SRCCLKREQB_13"),
+	PINCTRL_PIN(187, "SRCCLKREQB_14"),
+	PINCTRL_PIN(188, "SRCCLKREQB_15"),
+	PINCTRL_PIN(189, "SML2CLK"),
+	PINCTRL_PIN(190, "SML2DATA"),
+	PINCTRL_PIN(191, "SML2ALERTB"),
+	PINCTRL_PIN(192, "SML3CLK"),
+	PINCTRL_PIN(193, "SML3DATA"),
+	PINCTRL_PIN(194, "SML3ALERTB"),
+	PINCTRL_PIN(195, "SML4CLK"),
+	PINCTRL_PIN(196, "SML4DATA"),
+	PINCTRL_PIN(197, "SML4ALERTB"),
+	PINCTRL_PIN(198, "ISH_I2C0_SDA"),
+	PINCTRL_PIN(199, "ISH_I2C0_SCL"),
+	PINCTRL_PIN(200, "ISH_I2C1_SDA"),
+	PINCTRL_PIN(201, "ISH_I2C1_SCL"),
+	PINCTRL_PIN(202, "TIME_SYNC_0"),
+	/* GPP_E */
+	PINCTRL_PIN(203, "SATAXPCIE_0"),
+	PINCTRL_PIN(204, "SATAXPCIE_1"),
+	PINCTRL_PIN(205, "SATAXPCIE_2"),
+	PINCTRL_PIN(206, "CPU_GP_0"),
+	PINCTRL_PIN(207, "SATA_DEVSLP_0"),
+	PINCTRL_PIN(208, "SATA_DEVSLP_1"),
+	PINCTRL_PIN(209, "SATA_DEVSLP_2"),
+	PINCTRL_PIN(210, "CPU_GP_1"),
+	PINCTRL_PIN(211, "SATA_LEDB"),
+	PINCTRL_PIN(212, "USB2_OCB_0"),
+	PINCTRL_PIN(213, "USB2_OCB_1"),
+	PINCTRL_PIN(214, "USB2_OCB_2"),
+	PINCTRL_PIN(215, "USB2_OCB_3"),
+	/* GPP_F */
+	PINCTRL_PIN(216, "SATAXPCIE_3"),
+	PINCTRL_PIN(217, "SATAXPCIE_4"),
+	PINCTRL_PIN(218, "SATAXPCIE_5"),
+	PINCTRL_PIN(219, "SATAXPCIE_6"),
+	PINCTRL_PIN(220, "SATAXPCIE_7"),
+	PINCTRL_PIN(221, "SATA_DEVSLP_3"),
+	PINCTRL_PIN(222, "SATA_DEVSLP_4"),
+	PINCTRL_PIN(223, "SATA_DEVSLP_5"),
+	PINCTRL_PIN(224, "SATA_DEVSLP_6"),
+	PINCTRL_PIN(225, "SATA_DEVSLP_7"),
+	PINCTRL_PIN(226, "SATA_SCLOCK"),
+	PINCTRL_PIN(227, "SATA_SLOAD"),
+	PINCTRL_PIN(228, "SATA_SDATAOUT1"),
+	PINCTRL_PIN(229, "SATA_SDATAOUT0"),
+	PINCTRL_PIN(230, "EXT_PWR_GATEB"),
+	PINCTRL_PIN(231, "USB2_OCB_4"),
+	PINCTRL_PIN(232, "USB2_OCB_5"),
+	PINCTRL_PIN(233, "USB2_OCB_6"),
+	PINCTRL_PIN(234, "USB2_OCB_7"),
+	PINCTRL_PIN(235, "L_VDDEN"),
+	PINCTRL_PIN(236, "L_BKLTEN"),
+	PINCTRL_PIN(237, "L_BKLTCTL"),
+	PINCTRL_PIN(238, "DDPF_CTRLCLK"),
+	PINCTRL_PIN(239, "DDPF_CTRLDATA"),
+	/* SPI */
+	PINCTRL_PIN(240, "SPI0_IO_2"),
+	PINCTRL_PIN(241, "SPI0_IO_3"),
+	PINCTRL_PIN(242, "SPI0_MOSI_IO_0"),
+	PINCTRL_PIN(243, "SPI0_MISO_IO_1"),
+	PINCTRL_PIN(244, "SPI0_TPM_CSB"),
+	PINCTRL_PIN(245, "SPI0_FLASH_0_CSB"),
+	PINCTRL_PIN(246, "SPI0_FLASH_1_CSB"),
+	PINCTRL_PIN(247, "SPI0_CLK"),
+	PINCTRL_PIN(248, "SPI0_CLK_LOOPBK"),
+	/* CPU */
+	PINCTRL_PIN(249, "HDACPU_SDI"),
+	PINCTRL_PIN(250, "HDACPU_SDO"),
+	PINCTRL_PIN(251, "HDACPU_SCLK"),
+	PINCTRL_PIN(252, "PM_SYNC"),
+	PINCTRL_PIN(253, "PECI"),
+	PINCTRL_PIN(254, "CPUPWRGD"),
+	PINCTRL_PIN(255, "THRMTRIPB"),
+	PINCTRL_PIN(256, "PLTRST_CPUB"),
+	PINCTRL_PIN(257, "PM_DOWN"),
+	PINCTRL_PIN(258, "TRIGGER_IN"),
+	PINCTRL_PIN(259, "TRIGGER_OUT"),
+	/* JTAG */
+	PINCTRL_PIN(260, "JTAG_TDO"),
+	PINCTRL_PIN(261, "JTAGX"),
+	PINCTRL_PIN(262, "PRDYB"),
+	PINCTRL_PIN(263, "PREQB"),
+	PINCTRL_PIN(264, "CPU_TRSTB"),
+	PINCTRL_PIN(265, "JTAG_TDI"),
+	PINCTRL_PIN(266, "JTAG_TMS"),
+	PINCTRL_PIN(267, "JTAG_TCK"),
+	PINCTRL_PIN(268, "ITP_PMODE"),
+	/* GPP_I */
+	PINCTRL_PIN(269, "DDSP_HPD_0"),
+	PINCTRL_PIN(270, "DDSP_HPD_1"),
+	PINCTRL_PIN(271, "DDSP_HPD_2"),
+	PINCTRL_PIN(272, "DDSP_HPD_3"),
+	PINCTRL_PIN(273, "EDP_HPD"),
+	PINCTRL_PIN(274, "DDPB_CTRLCLK"),
+	PINCTRL_PIN(275, "DDPB_CTRLDATA"),
+	PINCTRL_PIN(276, "DDPC_CTRLCLK"),
+	PINCTRL_PIN(277, "DDPC_CTRLDATA"),
+	PINCTRL_PIN(278, "DDPD_CTRLCLK"),
+	PINCTRL_PIN(279, "DDPD_CTRLDATA"),
+	PINCTRL_PIN(280, "M2_SKT2_CFG_0"),
+	PINCTRL_PIN(281, "M2_SKT2_CFG_1"),
+	PINCTRL_PIN(282, "M2_SKT2_CFG_2"),
+	PINCTRL_PIN(283, "M2_SKT2_CFG_3"),
+	PINCTRL_PIN(284, "SYS_PWROK"),
+	PINCTRL_PIN(285, "SYS_RESETB"),
+	PINCTRL_PIN(286, "MLK_RSTB"),
+	/* GPP_J */
+	PINCTRL_PIN(287, "CNV_PA_BLANKING"),
+	PINCTRL_PIN(288, "CNV_GNSS_FTA"),
+	PINCTRL_PIN(289, "CNV_GNSS_SYSCK"),
+	PINCTRL_PIN(290, "CNV_RF_RESET_B"),
+	PINCTRL_PIN(291, "CNV_BRI_DT"),
+	PINCTRL_PIN(292, "CNV_BRI_RSP"),
+	PINCTRL_PIN(293, "CNV_RGI_DT"),
+	PINCTRL_PIN(294, "CNV_RGI_RSP"),
+	PINCTRL_PIN(295, "CNV_MFUART2_RXD"),
+	PINCTRL_PIN(296, "CNV_MFUART2_TXD"),
+	PINCTRL_PIN(297, "CNV_MODEM_CLKREQ"),
+	PINCTRL_PIN(298, "A4WP_PRESENT"),
+};
+
+static const struct intel_padgroup cnlh_community0_gpps[] = {
+	CNL_GPP(0, 0, 24, 0),			/* GPP_A */
+	CNL_GPP(1, 25, 50, 32),			/* GPP_B */
+};
+
+static const struct intel_padgroup cnlh_community1_gpps[] = {
+	CNL_GPP(0, 51, 74, 64),			/* GPP_C */
+	CNL_GPP(1, 75, 98, 96),			/* GPP_D */
+	CNL_GPP(2, 99, 106, 128),		/* GPP_G */
+	CNL_GPP(3, 107, 114, CNL_NO_GPIO),	/* AZA */
+	CNL_GPP(4, 115, 146, 160),		/* vGPIO_0 */
+	CNL_GPP(5, 147, 154, CNL_NO_GPIO),	/* vGPIO_1 */
+};
+
+static const struct intel_padgroup cnlh_community3_gpps[] = {
+	CNL_GPP(0, 155, 178, 192),		/* GPP_K */
+	CNL_GPP(1, 179, 202, 224),		/* GPP_H */
+	CNL_GPP(2, 203, 215, 256),		/* GPP_E */
+	CNL_GPP(3, 216, 239, 288),		/* GPP_F */
+	CNL_GPP(4, 240, 248, CNL_NO_GPIO),	/* SPI */
+};
+
+static const struct intel_padgroup cnlh_community4_gpps[] = {
+	CNL_GPP(0, 249, 259, CNL_NO_GPIO),	/* CPU */
+	CNL_GPP(1, 260, 268, CNL_NO_GPIO),	/* JTAG */
+	CNL_GPP(2, 269, 286, 320),		/* GPP_I */
+	CNL_GPP(3, 287, 298, 352),		/* GPP_J */
+};
+
+static const unsigned int cnlh_spi0_pins[] = { 40, 41, 42, 43 };
+static const unsigned int cnlh_spi1_pins[] = { 44, 45, 46, 47 };
+static const unsigned int cnlh_spi2_pins[] = { 84, 85, 86, 87 };
+
+static const unsigned int cnlh_uart0_pins[] = { 59, 60, 61, 62 };
+static const unsigned int cnlh_uart1_pins[] = { 63, 64, 65, 66 };
+static const unsigned int cnlh_uart2_pins[] = { 71, 72, 73, 74 };
+
+static const unsigned int cnlh_i2c0_pins[] = { 67, 68 };
+static const unsigned int cnlh_i2c1_pins[] = { 69, 70 };
+static const unsigned int cnlh_i2c2_pins[] = { 88, 89 };
+static const unsigned int cnlh_i2c3_pins[] = { 79, 98 };
+
+static const struct intel_pingroup cnlh_groups[] = {
+	PIN_GROUP("spi0_grp", cnlh_spi0_pins, 1),
+	PIN_GROUP("spi1_grp", cnlh_spi1_pins, 1),
+	PIN_GROUP("spi2_grp", cnlh_spi2_pins, 3),
+	PIN_GROUP("uart0_grp", cnlh_uart0_pins, 1),
+	PIN_GROUP("uart1_grp", cnlh_uart1_pins, 1),
+	PIN_GROUP("uart2_grp", cnlh_uart2_pins, 1),
+	PIN_GROUP("i2c0_grp", cnlh_i2c0_pins, 1),
+	PIN_GROUP("i2c1_grp", cnlh_i2c1_pins, 1),
+	PIN_GROUP("i2c2_grp", cnlh_i2c2_pins, 3),
+	PIN_GROUP("i2c3_grp", cnlh_i2c3_pins, 2),
+};
+
+static const char * const cnlh_spi0_groups[] = { "spi0_grp" };
+static const char * const cnlh_spi1_groups[] = { "spi1_grp" };
+static const char * const cnlh_spi2_groups[] = { "spi2_grp" };
+static const char * const cnlh_uart0_groups[] = { "uart0_grp" };
+static const char * const cnlh_uart1_groups[] = { "uart1_grp" };
+static const char * const cnlh_uart2_groups[] = { "uart2_grp" };
+static const char * const cnlh_i2c0_groups[] = { "i2c0_grp" };
+static const char * const cnlh_i2c1_groups[] = { "i2c1_grp" };
+static const char * const cnlh_i2c2_groups[] = { "i2c2_grp" };
+static const char * const cnlh_i2c3_groups[] = { "i2c3_grp" };
+
+static const struct intel_function cnlh_functions[] = {
+	FUNCTION("spi0", cnlh_spi0_groups),
+	FUNCTION("spi1", cnlh_spi1_groups),
+	FUNCTION("spi2", cnlh_spi2_groups),
+	FUNCTION("uart0", cnlh_uart0_groups),
+	FUNCTION("uart1", cnlh_uart1_groups),
+	FUNCTION("uart2", cnlh_uart2_groups),
+	FUNCTION("i2c0", cnlh_i2c0_groups),
+	FUNCTION("i2c1", cnlh_i2c1_groups),
+	FUNCTION("i2c2", cnlh_i2c2_groups),
+	FUNCTION("i2c3", cnlh_i2c3_groups),
+};
+
+static const struct intel_community cnlh_communities[] = {
+	CNLH_COMMUNITY(0, 0, 50, cnlh_community0_gpps),
+	CNLH_COMMUNITY(1, 51, 154, cnlh_community1_gpps),
+	CNLH_COMMUNITY(2, 155, 248, cnlh_community3_gpps),
+	CNLH_COMMUNITY(3, 249, 298, cnlh_community4_gpps),
+};
+
+static const struct intel_pinctrl_soc_data cnlh_soc_data = {
+	.pins = cnlh_pins,
+	.npins = ARRAY_SIZE(cnlh_pins),
+	.groups = cnlh_groups,
+	.ngroups = ARRAY_SIZE(cnlh_groups),
+	.functions = cnlh_functions,
+	.nfunctions = ARRAY_SIZE(cnlh_functions),
+	.communities = cnlh_communities,
+	.ncommunities = ARRAY_SIZE(cnlh_communities),
+};
+
+/* Cannon Lake-LP */
+static const struct pinctrl_pin_desc cnllp_pins[] = {
+	/* GPP_A */
+	PINCTRL_PIN(0, "RCINB"),
+	PINCTRL_PIN(1, "LAD_0"),
+	PINCTRL_PIN(2, "LAD_1"),
+	PINCTRL_PIN(3, "LAD_2"),
+	PINCTRL_PIN(4, "LAD_3"),
+	PINCTRL_PIN(5, "LFRAMEB"),
+	PINCTRL_PIN(6, "SERIRQ"),
+	PINCTRL_PIN(7, "PIRQAB"),
+	PINCTRL_PIN(8, "CLKRUNB"),
+	PINCTRL_PIN(9, "CLKOUT_LPC_0"),
+	PINCTRL_PIN(10, "CLKOUT_LPC_1"),
+	PINCTRL_PIN(11, "PMEB"),
+	PINCTRL_PIN(12, "BM_BUSYB"),
+	PINCTRL_PIN(13, "SUSWARNB_SUSPWRDNACK"),
+	PINCTRL_PIN(14, "SUS_STATB"),
+	PINCTRL_PIN(15, "SUSACKB"),
+	PINCTRL_PIN(16, "SD_1P8_SEL"),
+	PINCTRL_PIN(17, "SD_PWR_EN_B"),
+	PINCTRL_PIN(18, "ISH_GP_0"),
+	PINCTRL_PIN(19, "ISH_GP_1"),
+	PINCTRL_PIN(20, "ISH_GP_2"),
+	PINCTRL_PIN(21, "ISH_GP_3"),
+	PINCTRL_PIN(22, "ISH_GP_4"),
+	PINCTRL_PIN(23, "ISH_GP_5"),
+	PINCTRL_PIN(24, "ESPI_CLK_LOOPBK"),
+	/* GPP_B */
+	PINCTRL_PIN(25, "CORE_VID_0"),
+	PINCTRL_PIN(26, "CORE_VID_1"),
+	PINCTRL_PIN(27, "VRALERTB"),
+	PINCTRL_PIN(28, "CPU_GP_2"),
+	PINCTRL_PIN(29, "CPU_GP_3"),
+	PINCTRL_PIN(30, "SRCCLKREQB_0"),
+	PINCTRL_PIN(31, "SRCCLKREQB_1"),
+	PINCTRL_PIN(32, "SRCCLKREQB_2"),
+	PINCTRL_PIN(33, "SRCCLKREQB_3"),
+	PINCTRL_PIN(34, "SRCCLKREQB_4"),
+	PINCTRL_PIN(35, "SRCCLKREQB_5"),
+	PINCTRL_PIN(36, "EXT_PWR_GATEB"),
+	PINCTRL_PIN(37, "SLP_S0B"),
+	PINCTRL_PIN(38, "PLTRSTB"),
+	PINCTRL_PIN(39, "SPKR"),
+	PINCTRL_PIN(40, "GSPI0_CS0B"),
+	PINCTRL_PIN(41, "GSPI0_CLK"),
+	PINCTRL_PIN(42, "GSPI0_MISO"),
+	PINCTRL_PIN(43, "GSPI0_MOSI"),
+	PINCTRL_PIN(44, "GSPI1_CS0B"),
+	PINCTRL_PIN(45, "GSPI1_CLK"),
+	PINCTRL_PIN(46, "GSPI1_MISO"),
+	PINCTRL_PIN(47, "GSPI1_MOSI"),
+	PINCTRL_PIN(48, "SML1ALERTB"),
+	PINCTRL_PIN(49, "GSPI0_CLK_LOOPBK"),
+	PINCTRL_PIN(50, "GSPI1_CLK_LOOPBK"),
+	/* GPP_G */
+	PINCTRL_PIN(51, "SD3_CMD"),
+	PINCTRL_PIN(52, "SD3_D0_SD4_RCLK_P"),
+	PINCTRL_PIN(53, "SD3_D1_SD4_RCLK_N"),
+	PINCTRL_PIN(54, "SD3_D2"),
+	PINCTRL_PIN(55, "SD3_D3"),
+	PINCTRL_PIN(56, "SD3_CDB"),
+	PINCTRL_PIN(57, "SD3_CLK"),
+	PINCTRL_PIN(58, "SD3_WP"),
+	/* SPI */
+	PINCTRL_PIN(59, "SPI0_IO_2"),
+	PINCTRL_PIN(60, "SPI0_IO_3"),
+	PINCTRL_PIN(61, "SPI0_MOSI_IO_0"),
+	PINCTRL_PIN(62, "SPI0_MISO_IO_1"),
+	PINCTRL_PIN(63, "SPI0_TPM_CSB"),
+	PINCTRL_PIN(64, "SPI0_FLASH_0_CSB"),
+	PINCTRL_PIN(65, "SPI0_FLASH_1_CSB"),
+	PINCTRL_PIN(66, "SPI0_CLK"),
+	PINCTRL_PIN(67, "SPI0_CLK_LOOPBK"),
+	/* GPP_D */
+	PINCTRL_PIN(68, "SPI1_CSB"),
+	PINCTRL_PIN(69, "SPI1_CLK"),
+	PINCTRL_PIN(70, "SPI1_MISO_IO_1"),
+	PINCTRL_PIN(71, "SPI1_MOSI_IO_0"),
+	PINCTRL_PIN(72, "IMGCLKOUT_0"),
+	PINCTRL_PIN(73, "ISH_I2C0_SDA"),
+	PINCTRL_PIN(74, "ISH_I2C0_SCL"),
+	PINCTRL_PIN(75, "ISH_I2C1_SDA"),
+	PINCTRL_PIN(76, "ISH_I2C1_SCL"),
+	PINCTRL_PIN(77, "ISH_SPI_CSB"),
+	PINCTRL_PIN(78, "ISH_SPI_CLK"),
+	PINCTRL_PIN(79, "ISH_SPI_MISO"),
+	PINCTRL_PIN(80, "ISH_SPI_MOSI"),
+	PINCTRL_PIN(81, "ISH_UART0_RXD"),
+	PINCTRL_PIN(82, "ISH_UART0_TXD"),
+	PINCTRL_PIN(83, "ISH_UART0_RTSB"),
+	PINCTRL_PIN(84, "ISH_UART0_CTSB"),
+	PINCTRL_PIN(85, "DMIC_CLK_1"),
+	PINCTRL_PIN(86, "DMIC_DATA_1"),
+	PINCTRL_PIN(87, "DMIC_CLK_0"),
+	PINCTRL_PIN(88, "DMIC_DATA_0"),
+	PINCTRL_PIN(89, "SPI1_IO_2"),
+	PINCTRL_PIN(90, "SPI1_IO_3"),
+	PINCTRL_PIN(91, "SSP_MCLK"),
+	PINCTRL_PIN(92, "GSPI2_CLK_LOOPBK"),
+	/* GPP_F */
+	PINCTRL_PIN(93, "CNV_GNSS_PA_BLANKING"),
+	PINCTRL_PIN(94, "CNV_GNSS_FTA"),
+	PINCTRL_PIN(95, "CNV_GNSS_SYSCK"),
+	PINCTRL_PIN(96, "EMMC_HIP_MON"),
+	PINCTRL_PIN(97, "CNV_BRI_DT"),
+	PINCTRL_PIN(98, "CNV_BRI_RSP"),
+	PINCTRL_PIN(99, "CNV_RGI_DT"),
+	PINCTRL_PIN(100, "CNV_RGI_RSP"),
+	PINCTRL_PIN(101, "CNV_MFUART2_RXD"),
+	PINCTRL_PIN(102, "CNV_MFUART2_TXD"),
+	PINCTRL_PIN(103, "GPP_F_10"),
+	PINCTRL_PIN(104, "EMMC_CMD"),
+	PINCTRL_PIN(105, "EMMC_DATA_0"),
+	PINCTRL_PIN(106, "EMMC_DATA_1"),
+	PINCTRL_PIN(107, "EMMC_DATA_2"),
+	PINCTRL_PIN(108, "EMMC_DATA_3"),
+	PINCTRL_PIN(109, "EMMC_DATA_4"),
+	PINCTRL_PIN(110, "EMMC_DATA_5"),
+	PINCTRL_PIN(111, "EMMC_DATA_6"),
+	PINCTRL_PIN(112, "EMMC_DATA_7"),
+	PINCTRL_PIN(113, "EMMC_RCLK"),
+	PINCTRL_PIN(114, "EMMC_CLK"),
+	PINCTRL_PIN(115, "EMMC_RESETB"),
+	PINCTRL_PIN(116, "A4WP_PRESENT"),
+	/* GPP_H */
+	PINCTRL_PIN(117, "SSP2_SCLK"),
+	PINCTRL_PIN(118, "SSP2_SFRM"),
+	PINCTRL_PIN(119, "SSP2_TXD"),
+	PINCTRL_PIN(120, "SSP2_RXD"),
+	PINCTRL_PIN(121, "I2C2_SDA"),
+	PINCTRL_PIN(122, "I2C2_SCL"),
+	PINCTRL_PIN(123, "I2C3_SDA"),
+	PINCTRL_PIN(124, "I2C3_SCL"),
+	PINCTRL_PIN(125, "I2C4_SDA"),
+	PINCTRL_PIN(126, "I2C4_SCL"),
+	PINCTRL_PIN(127, "I2C5_SDA"),
+	PINCTRL_PIN(128, "I2C5_SCL"),
+	PINCTRL_PIN(129, "M2_SKT2_CFG_0"),
+	PINCTRL_PIN(130, "M2_SKT2_CFG_1"),
+	PINCTRL_PIN(131, "M2_SKT2_CFG_2"),
+	PINCTRL_PIN(132, "M2_SKT2_CFG_3"),
+	PINCTRL_PIN(133, "DDPF_CTRLCLK"),
+	PINCTRL_PIN(134, "DDPF_CTRLDATA"),
+	PINCTRL_PIN(135, "CPU_VCCIO_PWR_GATEB"),
+	PINCTRL_PIN(136, "TIMESYNC_0"),
+	PINCTRL_PIN(137, "IMGCLKOUT_1"),
+	PINCTRL_PIN(138, "GPPC_H_21"),
+	PINCTRL_PIN(139, "GPPC_H_22"),
+	PINCTRL_PIN(140, "GPPC_H_23"),
+	/* vGPIO */
+	PINCTRL_PIN(141, "CNV_BTEN"),
+	PINCTRL_PIN(142, "CNV_GNEN"),
+	PINCTRL_PIN(143, "CNV_WFEN"),
+	PINCTRL_PIN(144, "CNV_WCEN"),
+	PINCTRL_PIN(145, "CNV_BT_HOST_WAKEB"),
+	PINCTRL_PIN(146, "CNV_BT_IF_SELECT"),
+	PINCTRL_PIN(147, "vCNV_BT_UART_TXD"),
+	PINCTRL_PIN(148, "vCNV_BT_UART_RXD"),
+	PINCTRL_PIN(149, "vCNV_BT_UART_CTS_B"),
+	PINCTRL_PIN(150, "vCNV_BT_UART_RTS_B"),
+	PINCTRL_PIN(151, "vCNV_MFUART1_TXD"),
+	PINCTRL_PIN(152, "vCNV_MFUART1_RXD"),
+	PINCTRL_PIN(153, "vCNV_MFUART1_CTS_B"),
+	PINCTRL_PIN(154, "vCNV_MFUART1_RTS_B"),
+	PINCTRL_PIN(155, "vCNV_GNSS_UART_TXD"),
+	PINCTRL_PIN(156, "vCNV_GNSS_UART_RXD"),
+	PINCTRL_PIN(157, "vCNV_GNSS_UART_CTS_B"),
+	PINCTRL_PIN(158, "vCNV_GNSS_UART_RTS_B"),
+	PINCTRL_PIN(159, "vUART0_TXD"),
+	PINCTRL_PIN(160, "vUART0_RXD"),
+	PINCTRL_PIN(161, "vUART0_CTS_B"),
+	PINCTRL_PIN(162, "vUART0_RTS_B"),
+	PINCTRL_PIN(163, "vISH_UART0_TXD"),
+	PINCTRL_PIN(164, "vISH_UART0_RXD"),
+	PINCTRL_PIN(165, "vISH_UART0_CTS_B"),
+	PINCTRL_PIN(166, "vISH_UART0_RTS_B"),
+	PINCTRL_PIN(167, "vISH_UART1_TXD"),
+	PINCTRL_PIN(168, "vISH_UART1_RXD"),
+	PINCTRL_PIN(169, "vISH_UART1_CTS_B"),
+	PINCTRL_PIN(170, "vISH_UART1_RTS_B"),
+	PINCTRL_PIN(171, "vCNV_BT_I2S_BCLK"),
+	PINCTRL_PIN(172, "vCNV_BT_I2S_WS_SYNC"),
+	PINCTRL_PIN(173, "vCNV_BT_I2S_SDO"),
+	PINCTRL_PIN(174, "vCNV_BT_I2S_SDI"),
+	PINCTRL_PIN(175, "vSSP2_SCLK"),
+	PINCTRL_PIN(176, "vSSP2_SFRM"),
+	PINCTRL_PIN(177, "vSSP2_TXD"),
+	PINCTRL_PIN(178, "vSSP2_RXD"),
+	PINCTRL_PIN(179, "vCNV_GNSS_HOST_WAKEB"),
+	PINCTRL_PIN(180, "vSD3_CD_B"),
+	/* GPP_C */
+	PINCTRL_PIN(181, "SMBCLK"),
+	PINCTRL_PIN(182, "SMBDATA"),
+	PINCTRL_PIN(183, "SMBALERTB"),
+	PINCTRL_PIN(184, "SML0CLK"),
+	PINCTRL_PIN(185, "SML0DATA"),
+	PINCTRL_PIN(186, "SML0ALERTB"),
+	PINCTRL_PIN(187, "SML1CLK"),
+	PINCTRL_PIN(188, "SML1DATA"),
+	PINCTRL_PIN(189, "UART0_RXD"),
+	PINCTRL_PIN(190, "UART0_TXD"),
+	PINCTRL_PIN(191, "UART0_RTSB"),
+	PINCTRL_PIN(192, "UART0_CTSB"),
+	PINCTRL_PIN(193, "UART1_RXD"),
+	PINCTRL_PIN(194, "UART1_TXD"),
+	PINCTRL_PIN(195, "UART1_RTSB"),
+	PINCTRL_PIN(196, "UART1_CTSB"),
+	PINCTRL_PIN(197, "I2C0_SDA"),
+	PINCTRL_PIN(198, "I2C0_SCL"),
+	PINCTRL_PIN(199, "I2C1_SDA"),
+	PINCTRL_PIN(200, "I2C1_SCL"),
+	PINCTRL_PIN(201, "UART2_RXD"),
+	PINCTRL_PIN(202, "UART2_TXD"),
+	PINCTRL_PIN(203, "UART2_RTSB"),
+	PINCTRL_PIN(204, "UART2_CTSB"),
+	/* GPP_E */
+	PINCTRL_PIN(205, "SATAXPCIE_0"),
+	PINCTRL_PIN(206, "SATAXPCIE_1"),
+	PINCTRL_PIN(207, "SATAXPCIE_2"),
+	PINCTRL_PIN(208, "CPU_GP_0"),
+	PINCTRL_PIN(209, "SATA_DEVSLP_0"),
+	PINCTRL_PIN(210, "SATA_DEVSLP_1"),
+	PINCTRL_PIN(211, "SATA_DEVSLP_2"),
+	PINCTRL_PIN(212, "CPU_GP_1"),
+	PINCTRL_PIN(213, "SATA_LEDB"),
+	PINCTRL_PIN(214, "USB2_OCB_0"),
+	PINCTRL_PIN(215, "USB2_OCB_1"),
+	PINCTRL_PIN(216, "USB2_OCB_2"),
+	PINCTRL_PIN(217, "USB2_OCB_3"),
+	PINCTRL_PIN(218, "DDSP_HPD_0"),
+	PINCTRL_PIN(219, "DDSP_HPD_1"),
+	PINCTRL_PIN(220, "DDSP_HPD_2"),
+	PINCTRL_PIN(221, "DDSP_HPD_3"),
+	PINCTRL_PIN(222, "EDP_HPD"),
+	PINCTRL_PIN(223, "DDPB_CTRLCLK"),
+	PINCTRL_PIN(224, "DDPB_CTRLDATA"),
+	PINCTRL_PIN(225, "DDPC_CTRLCLK"),
+	PINCTRL_PIN(226, "DDPC_CTRLDATA"),
+	PINCTRL_PIN(227, "DDPD_CTRLCLK"),
+	PINCTRL_PIN(228, "DDPD_CTRLDATA"),
+	/* JTAG */
+	PINCTRL_PIN(229, "JTAG_TDO"),
+	PINCTRL_PIN(230, "JTAGX"),
+	PINCTRL_PIN(231, "PRDYB"),
+	PINCTRL_PIN(232, "PREQB"),
+	PINCTRL_PIN(233, "CPU_TRSTB"),
+	PINCTRL_PIN(234, "JTAG_TDI"),
+	PINCTRL_PIN(235, "JTAG_TMS"),
+	PINCTRL_PIN(236, "JTAG_TCK"),
+	PINCTRL_PIN(237, "ITP_PMODE"),
+	/* HVCMOS */
+	PINCTRL_PIN(238, "L_BKLTEN"),
+	PINCTRL_PIN(239, "L_BKLTCTL"),
+	PINCTRL_PIN(240, "L_VDDEN"),
+	PINCTRL_PIN(241, "SYS_PWROK"),
+	PINCTRL_PIN(242, "SYS_RESETB"),
+	PINCTRL_PIN(243, "MLK_RSTB"),
+};
+
+static const unsigned int cnllp_spi0_pins[] = { 40, 41, 42, 43, 7 };
+static const unsigned int cnllp_spi0_modes[] = { 1, 1, 1, 1, 2 };
+static const unsigned int cnllp_spi1_pins[] = { 44, 45, 46, 47, 11 };
+static const unsigned int cnllp_spi1_modes[] = { 1, 1, 1, 1, 2 };
+static const unsigned int cnllp_spi2_pins[] = { 77, 78, 79, 80, 83 };
+static const unsigned int cnllp_spi2_modes[] = { 3, 3, 3, 3, 2 };
+
+static const unsigned int cnllp_i2c0_pins[] = { 197, 198 };
+static const unsigned int cnllp_i2c1_pins[] = { 199, 200 };
+static const unsigned int cnllp_i2c2_pins[] = { 121, 122 };
+static const unsigned int cnllp_i2c3_pins[] = { 123, 124 };
+static const unsigned int cnllp_i2c4_pins[] = { 125, 126 };
+static const unsigned int cnllp_i2c5_pins[] = { 127, 128 };
+
+static const unsigned int cnllp_uart0_pins[] = { 189, 190, 191, 192 };
+static const unsigned int cnllp_uart1_pins[] = { 193, 194, 195, 196 };
+static const unsigned int cnllp_uart2_pins[] = { 201, 202, 203, 204 };
+
+static const struct intel_pingroup cnllp_groups[] = {
+	PIN_GROUP("spi0_grp", cnllp_spi0_pins, cnllp_spi0_modes),
+	PIN_GROUP("spi1_grp", cnllp_spi1_pins, cnllp_spi1_modes),
+	PIN_GROUP("spi2_grp", cnllp_spi2_pins, cnllp_spi2_modes),
+	PIN_GROUP("i2c0_grp", cnllp_i2c0_pins, 1),
+	PIN_GROUP("i2c1_grp", cnllp_i2c1_pins, 1),
+	PIN_GROUP("i2c2_grp", cnllp_i2c2_pins, 1),
+	PIN_GROUP("i2c3_grp", cnllp_i2c3_pins, 1),
+	PIN_GROUP("i2c4_grp", cnllp_i2c4_pins, 1),
+	PIN_GROUP("i2c5_grp", cnllp_i2c5_pins, 1),
+	PIN_GROUP("uart0_grp", cnllp_uart0_pins, 1),
+	PIN_GROUP("uart1_grp", cnllp_uart1_pins, 1),
+	PIN_GROUP("uart2_grp", cnllp_uart2_pins, 1),
+};
+
+static const char * const cnllp_spi0_groups[] = { "spi0_grp" };
+static const char * const cnllp_spi1_groups[] = { "spi1_grp" };
+static const char * const cnllp_spi2_groups[] = { "spi2_grp" };
+static const char * const cnllp_i2c0_groups[] = { "i2c0_grp" };
+static const char * const cnllp_i2c1_groups[] = { "i2c1_grp" };
+static const char * const cnllp_i2c2_groups[] = { "i2c2_grp" };
+static const char * const cnllp_i2c3_groups[] = { "i2c3_grp" };
+static const char * const cnllp_i2c4_groups[] = { "i2c4_grp" };
+static const char * const cnllp_i2c5_groups[] = { "i2c5_grp" };
+static const char * const cnllp_uart0_groups[] = { "uart0_grp" };
+static const char * const cnllp_uart1_groups[] = { "uart1_grp" };
+static const char * const cnllp_uart2_groups[] = { "uart2_grp" };
+
+static const struct intel_function cnllp_functions[] = {
+	FUNCTION("spi0", cnllp_spi0_groups),
+	FUNCTION("spi1", cnllp_spi1_groups),
+	FUNCTION("spi2", cnllp_spi2_groups),
+	FUNCTION("i2c0", cnllp_i2c0_groups),
+	FUNCTION("i2c1", cnllp_i2c1_groups),
+	FUNCTION("i2c2", cnllp_i2c2_groups),
+	FUNCTION("i2c3", cnllp_i2c3_groups),
+	FUNCTION("i2c4", cnllp_i2c4_groups),
+	FUNCTION("i2c5", cnllp_i2c5_groups),
+	FUNCTION("uart0", cnllp_uart0_groups),
+	FUNCTION("uart1", cnllp_uart1_groups),
+	FUNCTION("uart2", cnllp_uart2_groups),
+};
+
+static const struct intel_padgroup cnllp_community0_gpps[] = {
+	CNL_GPP(0, 0, 24, 0),			/* GPP_A */
+	CNL_GPP(1, 25, 50, 32),			/* GPP_B */
+	CNL_GPP(2, 51, 58, 64),			/* GPP_G */
+	CNL_GPP(3, 59, 67, CNL_NO_GPIO),	/* SPI */
+};
+
+static const struct intel_padgroup cnllp_community1_gpps[] = {
+	CNL_GPP(0, 68, 92, 96),			/* GPP_D */
+	CNL_GPP(1, 93, 116, 128),		/* GPP_F */
+	CNL_GPP(2, 117, 140, 160),		/* GPP_H */
+	CNL_GPP(3, 141, 172, 192),		/* vGPIO */
+	CNL_GPP(4, 173, 180, 224),		/* vGPIO */
+};
+
+static const struct intel_padgroup cnllp_community4_gpps[] = {
+	CNL_GPP(0, 181, 204, 256),		/* GPP_C */
+	CNL_GPP(1, 205, 228, 288),		/* GPP_E */
+	CNL_GPP(2, 229, 237, CNL_NO_GPIO),	/* JTAG */
+	CNL_GPP(3, 238, 243, CNL_NO_GPIO),	/* HVCMOS */
+};
+
+static const struct intel_community cnllp_communities[] = {
+	CNLLP_COMMUNITY(0, 0, 67, cnllp_community0_gpps),
+	CNLLP_COMMUNITY(1, 68, 180, cnllp_community1_gpps),
+	CNLLP_COMMUNITY(2, 181, 243, cnllp_community4_gpps),
+};
+
+static const struct intel_pinctrl_soc_data cnllp_soc_data = {
+	.pins = cnllp_pins,
+	.npins = ARRAY_SIZE(cnllp_pins),
+	.groups = cnllp_groups,
+	.ngroups = ARRAY_SIZE(cnllp_groups),
+	.functions = cnllp_functions,
+	.nfunctions = ARRAY_SIZE(cnllp_functions),
+	.communities = cnllp_communities,
+	.ncommunities = ARRAY_SIZE(cnllp_communities),
+};
+
+static const struct acpi_device_id cnl_pinctrl_acpi_match[] = {
+	{ "INT3450", (kernel_ulong_t)&cnlh_soc_data },
+	{ "INT34BB", (kernel_ulong_t)&cnllp_soc_data },
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, cnl_pinctrl_acpi_match);
+
+static int cnl_pinctrl_probe(struct platform_device *pdev)
+{
+	const struct intel_pinctrl_soc_data *soc_data;
+	const struct acpi_device_id *id;
+
+	id = acpi_match_device(cnl_pinctrl_acpi_match, &pdev->dev);
+	if (!id || !id->driver_data)
+		return -ENODEV;
+
+	soc_data = (const struct intel_pinctrl_soc_data *)id->driver_data;
+	return intel_pinctrl_probe(pdev, soc_data);
+}
+
+static const struct dev_pm_ops cnl_pinctrl_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
+				     intel_pinctrl_resume)
+};
+
+static struct platform_driver cnl_pinctrl_driver = {
+	.probe = cnl_pinctrl_probe,
+	.driver = {
+		.name = "cannonlake-pinctrl",
+		.acpi_match_table = cnl_pinctrl_acpi_match,
+		.pm = &cnl_pinctrl_pm_ops,
+	},
+};
+
+module_platform_driver(cnl_pinctrl_driver);
+
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+MODULE_DESCRIPTION("Intel Cannon Lake PCH pinctrl/GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/intel/pinctrl-cedarfork.c b/drivers/pinctrl/intel/pinctrl-cedarfork.c
new file mode 100644
index 0000000..c788e37
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-cedarfork.c
@@ -0,0 +1,372 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Cedar Fork PCH pinctrl/GPIO driver
+ *
+ * Copyright (C) 2017, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-intel.h"
+
+#define CDF_PAD_OWN	0x020
+#define CDF_PADCFGLOCK	0x0c0
+#define CDF_HOSTSW_OWN	0x120
+#define CDF_GPI_IS	0x200
+#define CDF_GPI_IE	0x230
+
+#define CDF_GPP(r, s, e)				\
+	{						\
+		.reg_num = (r),				\
+		.base = (s),				\
+		.size = ((e) - (s) + 1),		\
+	}
+
+#define CDF_COMMUNITY(b, s, e, g)			\
+	{						\
+		.barno = (b),				\
+		.padown_offset = CDF_PAD_OWN,		\
+		.padcfglock_offset = CDF_PADCFGLOCK,	\
+		.hostown_offset = CDF_HOSTSW_OWN,	\
+		.is_offset = CDF_GPI_IS,		\
+		.ie_offset = CDF_GPI_IE,		\
+		.pin_base = (s),			\
+		.npins = ((e) - (s) + 1),		\
+		.gpps = (g),				\
+		.ngpps = ARRAY_SIZE(g),			\
+	}
+
+/* Cedar Fork PCH */
+static const struct pinctrl_pin_desc cdf_pins[] = {
+	/* WEST2 */
+	PINCTRL_PIN(0, "GBE_SDP_TIMESYNC0_S2N"),
+	PINCTRL_PIN(1, "GBE_SDP_TIMESYNC1_S2N"),
+	PINCTRL_PIN(2, "GBE_SDP_TIMESYNC2_S2N"),
+	PINCTRL_PIN(3, "GBE_SDP_TIMESYNC3_S2N"),
+	PINCTRL_PIN(4, "GBE0_I2C_CLK"),
+	PINCTRL_PIN(5, "GBE0_I2C_DATA"),
+	PINCTRL_PIN(6, "GBE1_I2C_CLK"),
+	PINCTRL_PIN(7, "GBE1_I2C_DATA"),
+	PINCTRL_PIN(8, "GBE2_I2C_CLK"),
+	PINCTRL_PIN(9, "GBE2_I2C_DATA"),
+	PINCTRL_PIN(10, "GBE3_I2C_CLK"),
+	PINCTRL_PIN(11, "GBE3_I2C_DATA"),
+	PINCTRL_PIN(12, "GBE0_LED0"),
+	PINCTRL_PIN(13, "GBE0_LED1"),
+	PINCTRL_PIN(14, "GBE0_LED2"),
+	PINCTRL_PIN(15, "GBE1_LED0"),
+	PINCTRL_PIN(16, "GBE1_LED1"),
+	PINCTRL_PIN(17, "GBE1_LED2"),
+	PINCTRL_PIN(18, "GBE2_LED0"),
+	PINCTRL_PIN(19, "GBE2_LED1"),
+	PINCTRL_PIN(20, "GBE2_LED2"),
+	PINCTRL_PIN(21, "GBE3_LED0"),
+	PINCTRL_PIN(22, "GBE3_LED1"),
+	PINCTRL_PIN(23, "GBE3_LED2"),
+	/* WEST3 */
+	PINCTRL_PIN(24, "NCSI_RXD0"),
+	PINCTRL_PIN(25, "NCSI_CLK_IN"),
+	PINCTRL_PIN(26, "NCSI_RXD1"),
+	PINCTRL_PIN(27, "NCSI_CRS_DV"),
+	PINCTRL_PIN(28, "NCSI_ARB_IN"),
+	PINCTRL_PIN(29, "NCSI_TX_EN"),
+	PINCTRL_PIN(30, "NCSI_TXD0"),
+	PINCTRL_PIN(31, "NCSI_TXD1"),
+	PINCTRL_PIN(32, "NCSI_ARB_OUT"),
+	PINCTRL_PIN(33, "GBE_SMB_CLK"),
+	PINCTRL_PIN(34, "GBE_SMB_DATA"),
+	PINCTRL_PIN(35, "GBE_SMB_ALRT_N"),
+	PINCTRL_PIN(36, "THERMTRIP_N"),
+	PINCTRL_PIN(37, "PCHHOT_N"),
+	PINCTRL_PIN(38, "ERROR0_N"),
+	PINCTRL_PIN(39, "ERROR1_N"),
+	PINCTRL_PIN(40, "ERROR2_N"),
+	PINCTRL_PIN(41, "MSMI_N"),
+	PINCTRL_PIN(42, "CATERR_N"),
+	PINCTRL_PIN(43, "MEMTRIP_N"),
+	PINCTRL_PIN(44, "UART0_RXD"),
+	PINCTRL_PIN(45, "UART0_TXD"),
+	PINCTRL_PIN(46, "UART1_RXD"),
+	PINCTRL_PIN(47, "UART1_TXD"),
+	/* WEST01 */
+	PINCTRL_PIN(48, "GBE_GPIO13"),
+	PINCTRL_PIN(49, "AUX_PWR"),
+	PINCTRL_PIN(50, "CPU_GP_2"),
+	PINCTRL_PIN(51, "CPU_GP_3"),
+	PINCTRL_PIN(52, "FAN_PWM_0"),
+	PINCTRL_PIN(53, "FAN_PWM_1"),
+	PINCTRL_PIN(54, "FAN_PWM_2"),
+	PINCTRL_PIN(55, "FAN_PWM_3"),
+	PINCTRL_PIN(56, "FAN_TACH_0"),
+	PINCTRL_PIN(57, "FAN_TACH_1"),
+	PINCTRL_PIN(58, "FAN_TACH_2"),
+	PINCTRL_PIN(59, "FAN_TACH_3"),
+	PINCTRL_PIN(60, "ME_SMB0_CLK"),
+	PINCTRL_PIN(61, "ME_SMB0_DATA"),
+	PINCTRL_PIN(62, "ME_SMB0_ALRT_N"),
+	PINCTRL_PIN(63, "ME_SMB1_CLK"),
+	PINCTRL_PIN(64, "ME_SMB1_DATA"),
+	PINCTRL_PIN(65, "ME_SMB1_ALRT_N"),
+	PINCTRL_PIN(66, "ME_SMB2_CLK"),
+	PINCTRL_PIN(67, "ME_SMB2_DATA"),
+	PINCTRL_PIN(68, "ME_SMB2_ALRT_N"),
+	PINCTRL_PIN(69, "GBE_MNG_I2C_CLK"),
+	PINCTRL_PIN(70, "GBE_MNG_I2C_DATA"),
+	/* WEST5 */
+	PINCTRL_PIN(71, "IE_UART_RXD"),
+	PINCTRL_PIN(72, "IE_UART_TXD"),
+	PINCTRL_PIN(73, "VPP_SMB_CLK"),
+	PINCTRL_PIN(74, "VPP_SMB_DATA"),
+	PINCTRL_PIN(75, "VPP_SMB_ALRT_N"),
+	PINCTRL_PIN(76, "PCIE_CLKREQ0_N"),
+	PINCTRL_PIN(77, "PCIE_CLKREQ1_N"),
+	PINCTRL_PIN(78, "PCIE_CLKREQ2_N"),
+	PINCTRL_PIN(79, "PCIE_CLKREQ3_N"),
+	PINCTRL_PIN(80, "PCIE_CLKREQ4_N"),
+	PINCTRL_PIN(81, "PCIE_CLKREQ5_N"),
+	PINCTRL_PIN(82, "PCIE_CLKREQ6_N"),
+	PINCTRL_PIN(83, "PCIE_CLKREQ7_N"),
+	PINCTRL_PIN(84, "PCIE_CLKREQ8_N"),
+	PINCTRL_PIN(85, "PCIE_CLKREQ9_N"),
+	PINCTRL_PIN(86, "FLEX_CLK_SE0"),
+	PINCTRL_PIN(87, "FLEX_CLK_SE1"),
+	PINCTRL_PIN(88, "FLEX_CLK1_50"),
+	PINCTRL_PIN(89, "FLEX_CLK2_50"),
+	PINCTRL_PIN(90, "FLEX_CLK_125"),
+	/* WESTC */
+	PINCTRL_PIN(91, "TCK_PCH"),
+	PINCTRL_PIN(92, "JTAGX_PCH"),
+	PINCTRL_PIN(93, "TRST_N_PCH"),
+	PINCTRL_PIN(94, "TMS_PCH"),
+	PINCTRL_PIN(95, "TDI_PCH"),
+	PINCTRL_PIN(96, "TDO_PCH"),
+	/* WESTC_DFX */
+	PINCTRL_PIN(97, "CX_PRDY_N"),
+	PINCTRL_PIN(98, "CX_PREQ_N"),
+	PINCTRL_PIN(99, "CPU_FBREAK_OUT_N"),
+	PINCTRL_PIN(100, "TRIGGER0_N"),
+	PINCTRL_PIN(101, "TRIGGER1_N"),
+	/* WESTA */
+	PINCTRL_PIN(102, "DBG_PTI_CLK0"),
+	PINCTRL_PIN(103, "DBG_PTI_CLK3"),
+	PINCTRL_PIN(104, "DBG_PTI_DATA0"),
+	PINCTRL_PIN(105, "DBG_PTI_DATA1"),
+	PINCTRL_PIN(106, "DBG_PTI_DATA2"),
+	PINCTRL_PIN(107, "DBG_PTI_DATA3"),
+	PINCTRL_PIN(108, "DBG_PTI_DATA4"),
+	PINCTRL_PIN(109, "DBG_PTI_DATA5"),
+	PINCTRL_PIN(110, "DBG_PTI_DATA6"),
+	PINCTRL_PIN(111, "DBG_PTI_DATA7"),
+	/* WESTB */
+	PINCTRL_PIN(112, "DBG_PTI_DATA8"),
+	PINCTRL_PIN(113, "DBG_PTI_DATA9"),
+	PINCTRL_PIN(114, "DBG_PTI_DATA10"),
+	PINCTRL_PIN(115, "DBG_PTI_DATA11"),
+	PINCTRL_PIN(116, "DBG_PTI_DATA12"),
+	PINCTRL_PIN(117, "DBG_PTI_DATA13"),
+	PINCTRL_PIN(118, "DBG_PTI_DATA14"),
+	PINCTRL_PIN(119, "DBG_PTI_DATA15"),
+	PINCTRL_PIN(120, "DBG_SPARE0"),
+	PINCTRL_PIN(121, "DBG_SPARE1"),
+	PINCTRL_PIN(122, "DBG_SPARE2"),
+	PINCTRL_PIN(123, "DBG_SPARE3"),
+	/* WESTD */
+	PINCTRL_PIN(124, "CPU_PWR_GOOD"),
+	PINCTRL_PIN(125, "PLTRST_CPU_N"),
+	PINCTRL_PIN(126, "NAC_RESET_NAC_N"),
+	PINCTRL_PIN(127, "PCH_SBLINK_RX"),
+	PINCTRL_PIN(128, "PCH_SBLINK_TX"),
+	PINCTRL_PIN(129, "PMSYNC_CLK"),
+	PINCTRL_PIN(130, "CPU_ERR0_N"),
+	PINCTRL_PIN(131, "CPU_ERR1_N"),
+	PINCTRL_PIN(132, "CPU_ERR2_N"),
+	PINCTRL_PIN(133, "CPU_THERMTRIP_N"),
+	PINCTRL_PIN(134, "CPU_MSMI_N"),
+	PINCTRL_PIN(135, "CPU_CATERR_N"),
+	PINCTRL_PIN(136, "CPU_MEMTRIP_N"),
+	PINCTRL_PIN(137, "NAC_GR_N"),
+	PINCTRL_PIN(138, "NAC_XTAL_VALID"),
+	PINCTRL_PIN(139, "NAC_WAKE_N"),
+	PINCTRL_PIN(140, "NAC_SBLINK_CLK_S2N"),
+	PINCTRL_PIN(141, "NAC_SBLINK_N2S"),
+	PINCTRL_PIN(142, "NAC_SBLINK_S2N"),
+	PINCTRL_PIN(143, "NAC_SBLINK_CLK_N2S"),
+	/* WESTD_PECI */
+	PINCTRL_PIN(144, "ME_PECI"),
+	/* WESTF */
+	PINCTRL_PIN(145, "NAC_RMII_CLK"),
+	PINCTRL_PIN(146, "NAC_RGMII_CLK"),
+	PINCTRL_PIN(147, "NAC_SPARE0"),
+	PINCTRL_PIN(148, "NAC_SPARE1"),
+	PINCTRL_PIN(149, "NAC_SPARE2"),
+	PINCTRL_PIN(150, "NAC_INIT_SX_WAKE_N"),
+	PINCTRL_PIN(151, "NAC_GBE_GPIO0_S2N"),
+	PINCTRL_PIN(152, "NAC_GBE_GPIO1_S2N"),
+	PINCTRL_PIN(153, "NAC_GBE_GPIO2_S2N"),
+	PINCTRL_PIN(154, "NAC_GBE_GPIO3_S2N"),
+	PINCTRL_PIN(155, "NAC_NCSI_RXD0"),
+	PINCTRL_PIN(156, "NAC_NCSI_CLK_IN"),
+	PINCTRL_PIN(157, "NAC_NCSI_RXD1"),
+	PINCTRL_PIN(158, "NAC_NCSI_CRS_DV"),
+	PINCTRL_PIN(159, "NAC_NCSI_ARB_IN"),
+	PINCTRL_PIN(160, "NAC_NCSI_TX_EN"),
+	PINCTRL_PIN(161, "NAC_NCSI_TXD0"),
+	PINCTRL_PIN(162, "NAC_NCSI_TXD1"),
+	PINCTRL_PIN(163, "NAC_NCSI_ARB_OUT"),
+	PINCTRL_PIN(164, "NAC_NCSI_OE_N"),
+	PINCTRL_PIN(165, "NAC_GBE_SMB_CLK"),
+	PINCTRL_PIN(166, "NAC_GBE_SMB_DATA"),
+	PINCTRL_PIN(167, "NAC_GBE_SMB_ALRT_N"),
+	/* EAST2 */
+	PINCTRL_PIN(168, "USB_OC0_N"),
+	PINCTRL_PIN(169, "GBE_GPIO0"),
+	PINCTRL_PIN(170, "GBE_GPIO1"),
+	PINCTRL_PIN(171, "GBE_GPIO2"),
+	PINCTRL_PIN(172, "GBE_GPIO3"),
+	PINCTRL_PIN(173, "GBE_GPIO4"),
+	PINCTRL_PIN(174, "GBE_GPIO5"),
+	PINCTRL_PIN(175, "GBE_GPIO6"),
+	PINCTRL_PIN(176, "GBE_GPIO7"),
+	PINCTRL_PIN(177, "GBE_GPIO8"),
+	PINCTRL_PIN(178, "GBE_GPIO9"),
+	PINCTRL_PIN(179, "GBE_GPIO10"),
+	PINCTRL_PIN(180, "GBE_GPIO11"),
+	PINCTRL_PIN(181, "GBE_GPIO12"),
+	PINCTRL_PIN(182, "PECI_SMB_DATA"),
+	PINCTRL_PIN(183, "SATA0_LED_N"),
+	PINCTRL_PIN(184, "SATA1_LED_N"),
+	PINCTRL_PIN(185, "SATA_PDETECT0"),
+	PINCTRL_PIN(186, "SATA_PDETECT1"),
+	PINCTRL_PIN(187, "SATA0_SDOUT"),
+	PINCTRL_PIN(188, "SATA1_SDOUT"),
+	PINCTRL_PIN(189, "SATA2_LED_N"),
+	PINCTRL_PIN(190, "SATA_PDETECT2"),
+	PINCTRL_PIN(191, "SATA2_SDOUT"),
+	/* EAST3 */
+	PINCTRL_PIN(192, "ESPI_IO0"),
+	PINCTRL_PIN(193, "ESPI_IO1"),
+	PINCTRL_PIN(194, "ESPI_IO2"),
+	PINCTRL_PIN(195, "ESPI_IO3"),
+	PINCTRL_PIN(196, "ESPI_CLK"),
+	PINCTRL_PIN(197, "ESPI_RST_N"),
+	PINCTRL_PIN(198, "ESPI_CS0_N"),
+	PINCTRL_PIN(199, "ESPI_ALRT0_N"),
+	PINCTRL_PIN(200, "ESPI_CS1_N"),
+	PINCTRL_PIN(201, "ESPI_ALRT1_N"),
+	PINCTRL_PIN(202, "ESPI_CLK_LOOPBK"),
+	/* EAST0 */
+	PINCTRL_PIN(203, "SPI_CS0_N"),
+	PINCTRL_PIN(204, "SPI_CS1_N"),
+	PINCTRL_PIN(205, "SPI_MOSI_IO0"),
+	PINCTRL_PIN(206, "SPI_MISO_IO1"),
+	PINCTRL_PIN(207, "SPI_IO2"),
+	PINCTRL_PIN(208, "SPI_IO3"),
+	PINCTRL_PIN(209, "SPI_CLK"),
+	PINCTRL_PIN(210, "SPI_CLK_LOOPBK"),
+	PINCTRL_PIN(211, "SUSPWRDNACK"),
+	PINCTRL_PIN(212, "PMU_SUSCLK"),
+	PINCTRL_PIN(213, "ADR_COMPLETE"),
+	PINCTRL_PIN(214, "ADR_TRIGGER_N"),
+	PINCTRL_PIN(215, "PMU_SLP_S45_N"),
+	PINCTRL_PIN(216, "PMU_SLP_S3_N"),
+	PINCTRL_PIN(217, "PMU_WAKE_N"),
+	PINCTRL_PIN(218, "PMU_PWRBTN_N"),
+	PINCTRL_PIN(219, "PMU_RESETBUTTON_N"),
+	PINCTRL_PIN(220, "PMU_PLTRST_N"),
+	PINCTRL_PIN(221, "SUS_STAT_N"),
+	PINCTRL_PIN(222, "PMU_I2C_CLK"),
+	PINCTRL_PIN(223, "PMU_I2C_DATA"),
+	PINCTRL_PIN(224, "PECI_SMB_CLK"),
+	PINCTRL_PIN(225, "PECI_SMB_ALRT_N"),
+	/* EMMC */
+	PINCTRL_PIN(226, "EMMC_CMD"),
+	PINCTRL_PIN(227, "EMMC_STROBE"),
+	PINCTRL_PIN(228, "EMMC_CLK"),
+	PINCTRL_PIN(229, "EMMC_D0"),
+	PINCTRL_PIN(230, "EMMC_D1"),
+	PINCTRL_PIN(231, "EMMC_D2"),
+	PINCTRL_PIN(232, "EMMC_D3"),
+	PINCTRL_PIN(233, "EMMC_D4"),
+	PINCTRL_PIN(234, "EMMC_D5"),
+	PINCTRL_PIN(235, "EMMC_D6"),
+	PINCTRL_PIN(236, "EMMC_D7"),
+};
+
+static const struct intel_padgroup cdf_community0_gpps[] = {
+	CDF_GPP(0, 0, 23),	/* WEST2 */
+	CDF_GPP(1, 24, 47),	/* WEST3 */
+	CDF_GPP(2, 48, 70),	/* WEST01 */
+	CDF_GPP(3, 71, 90),	/* WEST5 */
+	CDF_GPP(4, 91, 96),	/* WESTC */
+	CDF_GPP(5, 97, 101),	/* WESTC_DFX */
+	CDF_GPP(6, 102, 111),	/* WESTA */
+	CDF_GPP(7, 112, 123),	/* WESTB */
+	CDF_GPP(8, 124, 143),	/* WESTD */
+	CDF_GPP(9, 144, 144),	/* WESTD_PECI */
+	CDF_GPP(10, 145, 167),	/* WESTF */
+};
+
+static const struct intel_padgroup cdf_community1_gpps[] = {
+	CDF_GPP(0, 168, 191),	/* EAST2 */
+	CDF_GPP(1, 192, 202),	/* EAST3 */
+	CDF_GPP(2, 203, 225),	/* EAST0 */
+	CDF_GPP(3, 226, 236),	/* EMMC */
+};
+
+static const struct intel_community cdf_communities[] = {
+	CDF_COMMUNITY(0, 0, 167, cdf_community0_gpps),		/* West */
+	CDF_COMMUNITY(1, 168, 236, cdf_community1_gpps),	/* East */
+};
+
+static const struct intel_pinctrl_soc_data cdf_soc_data = {
+	.pins = cdf_pins,
+	.npins = ARRAY_SIZE(cdf_pins),
+	.communities = cdf_communities,
+	.ncommunities = ARRAY_SIZE(cdf_communities),
+};
+
+static int cdf_pinctrl_probe(struct platform_device *pdev)
+{
+	return intel_pinctrl_probe(pdev, &cdf_soc_data);
+}
+
+static const struct dev_pm_ops cdf_pinctrl_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
+				     intel_pinctrl_resume)
+};
+
+static const struct acpi_device_id cdf_pinctrl_acpi_match[] = {
+	{ "INTC3001" },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, cdf_pinctrl_acpi_match);
+
+static struct platform_driver cdf_pinctrl_driver = {
+	.probe = cdf_pinctrl_probe,
+	.driver = {
+		.name = "cedarfork-pinctrl",
+		.acpi_match_table = cdf_pinctrl_acpi_match,
+		.pm = &cdf_pinctrl_pm_ops,
+	},
+};
+
+static int __init cdf_pinctrl_init(void)
+{
+	return platform_driver_register(&cdf_pinctrl_driver);
+}
+subsys_initcall(cdf_pinctrl_init);
+
+static void __exit cdf_pinctrl_exit(void)
+{
+	platform_driver_unregister(&cdf_pinctrl_driver);
+}
+module_exit(cdf_pinctrl_exit);
+
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+MODULE_DESCRIPTION("Intel Cedar Fork PCH pinctrl/GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c
new file mode 100644
index 0000000..6d31ad7
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -0,0 +1,1890 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Cherryview/Braswell pinctrl driver
+ *
+ * Copyright (C) 2014, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ *
+ * This driver is based on the original Cherryview GPIO driver by
+ *   Ning Li <ning.li@intel.com>
+ *   Alan Cox <alan@linux.intel.com>
+ */
+
+#include <linux/dmi.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
+#include <linux/acpi.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/platform_device.h>
+
+#define CHV_INTSTAT			0x300
+#define CHV_INTMASK			0x380
+
+#define FAMILY_PAD_REGS_OFF		0x4400
+#define FAMILY_PAD_REGS_SIZE		0x400
+#define MAX_FAMILY_PAD_GPIO_NO		15
+#define GPIO_REGS_SIZE			8
+
+#define CHV_PADCTRL0			0x000
+#define CHV_PADCTRL0_INTSEL_SHIFT	28
+#define CHV_PADCTRL0_INTSEL_MASK	(0xf << CHV_PADCTRL0_INTSEL_SHIFT)
+#define CHV_PADCTRL0_TERM_UP		BIT(23)
+#define CHV_PADCTRL0_TERM_SHIFT		20
+#define CHV_PADCTRL0_TERM_MASK		(7 << CHV_PADCTRL0_TERM_SHIFT)
+#define CHV_PADCTRL0_TERM_20K		1
+#define CHV_PADCTRL0_TERM_5K		2
+#define CHV_PADCTRL0_TERM_1K		4
+#define CHV_PADCTRL0_PMODE_SHIFT	16
+#define CHV_PADCTRL0_PMODE_MASK		(0xf << CHV_PADCTRL0_PMODE_SHIFT)
+#define CHV_PADCTRL0_GPIOEN		BIT(15)
+#define CHV_PADCTRL0_GPIOCFG_SHIFT	8
+#define CHV_PADCTRL0_GPIOCFG_MASK	(7 << CHV_PADCTRL0_GPIOCFG_SHIFT)
+#define CHV_PADCTRL0_GPIOCFG_GPIO	0
+#define CHV_PADCTRL0_GPIOCFG_GPO	1
+#define CHV_PADCTRL0_GPIOCFG_GPI	2
+#define CHV_PADCTRL0_GPIOCFG_HIZ	3
+#define CHV_PADCTRL0_GPIOTXSTATE	BIT(1)
+#define CHV_PADCTRL0_GPIORXSTATE	BIT(0)
+
+#define CHV_PADCTRL1			0x004
+#define CHV_PADCTRL1_CFGLOCK		BIT(31)
+#define CHV_PADCTRL1_INVRXTX_SHIFT	4
+#define CHV_PADCTRL1_INVRXTX_MASK	(0xf << CHV_PADCTRL1_INVRXTX_SHIFT)
+#define CHV_PADCTRL1_INVRXTX_TXENABLE	(2 << CHV_PADCTRL1_INVRXTX_SHIFT)
+#define CHV_PADCTRL1_ODEN		BIT(3)
+#define CHV_PADCTRL1_INVRXTX_RXDATA	(4 << CHV_PADCTRL1_INVRXTX_SHIFT)
+#define CHV_PADCTRL1_INTWAKECFG_MASK	7
+#define CHV_PADCTRL1_INTWAKECFG_FALLING	1
+#define CHV_PADCTRL1_INTWAKECFG_RISING	2
+#define CHV_PADCTRL1_INTWAKECFG_BOTH	3
+#define CHV_PADCTRL1_INTWAKECFG_LEVEL	4
+
+/**
+ * struct chv_alternate_function - A per group or per pin alternate function
+ * @pin: Pin number (only used in per pin configs)
+ * @mode: Mode the pin should be set in
+ * @invert_oe: Invert OE for this pin
+ */
+struct chv_alternate_function {
+	unsigned pin;
+	u8 mode;
+	bool invert_oe;
+};
+
+/**
+ * struct chv_pincgroup - describes a CHV pin group
+ * @name: Name of the group
+ * @pins: An array of pins in this group
+ * @npins: Number of pins in this group
+ * @altfunc: Alternate function applied to all pins in this group
+ * @overrides: Alternate function override per pin or %NULL if not used
+ * @noverrides: Number of per pin alternate function overrides if
+ *              @overrides != NULL.
+ */
+struct chv_pingroup {
+	const char *name;
+	const unsigned *pins;
+	size_t npins;
+	struct chv_alternate_function altfunc;
+	const struct chv_alternate_function *overrides;
+	size_t noverrides;
+};
+
+/**
+ * struct chv_function - A CHV pinmux function
+ * @name: Name of the function
+ * @groups: An array of groups for this function
+ * @ngroups: Number of groups in @groups
+ */
+struct chv_function {
+	const char *name;
+	const char * const *groups;
+	size_t ngroups;
+};
+
+/**
+ * struct chv_gpio_pinrange - A range of pins that can be used as GPIOs
+ * @base: Start pin number
+ * @npins: Number of pins in this range
+ */
+struct chv_gpio_pinrange {
+	unsigned base;
+	unsigned npins;
+};
+
+/**
+ * struct chv_community - A community specific configuration
+ * @uid: ACPI _UID used to match the community
+ * @pins: All pins in this community
+ * @npins: Number of pins
+ * @groups: All groups in this community
+ * @ngroups: Number of groups
+ * @functions: All functions in this community
+ * @nfunctions: Number of functions
+ * @gpio_ranges: An array of GPIO ranges in this community
+ * @ngpio_ranges: Number of GPIO ranges
+ * @nirqs: Total number of IRQs this community can generate
+ */
+struct chv_community {
+	const char *uid;
+	const struct pinctrl_pin_desc *pins;
+	size_t npins;
+	const struct chv_pingroup *groups;
+	size_t ngroups;
+	const struct chv_function *functions;
+	size_t nfunctions;
+	const struct chv_gpio_pinrange *gpio_ranges;
+	size_t ngpio_ranges;
+	size_t nirqs;
+	acpi_adr_space_type acpi_space_id;
+};
+
+struct chv_pin_context {
+	u32 padctrl0;
+	u32 padctrl1;
+};
+
+/**
+ * struct chv_pinctrl - CHV pinctrl private structure
+ * @dev: Pointer to the parent device
+ * @pctldesc: Pin controller description
+ * @pctldev: Pointer to the pin controller device
+ * @chip: GPIO chip in this pin controller
+ * @regs: MMIO registers
+ * @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO
+ *		offset (in GPIO number space)
+ * @community: Community this pinctrl instance represents
+ *
+ * The first group in @groups is expected to contain all pins that can be
+ * used as GPIOs.
+ */
+struct chv_pinctrl {
+	struct device *dev;
+	struct pinctrl_desc pctldesc;
+	struct pinctrl_dev *pctldev;
+	struct gpio_chip chip;
+	void __iomem *regs;
+	unsigned intr_lines[16];
+	const struct chv_community *community;
+	u32 saved_intmask;
+	struct chv_pin_context *saved_pin_context;
+};
+
+#define ALTERNATE_FUNCTION(p, m, i)		\
+	{					\
+		.pin = (p),			\
+		.mode = (m),			\
+		.invert_oe = (i),		\
+	}
+
+#define PIN_GROUP(n, p, m, i)			\
+	{					\
+		.name = (n),			\
+		.pins = (p),			\
+		.npins = ARRAY_SIZE((p)),	\
+		.altfunc.mode = (m),		\
+		.altfunc.invert_oe = (i),	\
+	}
+
+#define PIN_GROUP_WITH_OVERRIDE(n, p, m, i, o)	\
+	{					\
+		.name = (n),			\
+		.pins = (p),			\
+		.npins = ARRAY_SIZE((p)),	\
+		.altfunc.mode = (m),		\
+		.altfunc.invert_oe = (i),	\
+		.overrides = (o),		\
+		.noverrides = ARRAY_SIZE((o)),	\
+	}
+
+#define FUNCTION(n, g)				\
+	{					\
+		.name = (n),			\
+		.groups = (g),			\
+		.ngroups = ARRAY_SIZE((g)),	\
+	}
+
+#define GPIO_PINRANGE(start, end)		\
+	{					\
+		.base = (start),		\
+		.npins = (end) - (start) + 1,	\
+	}
+
+static const struct pinctrl_pin_desc southwest_pins[] = {
+	PINCTRL_PIN(0, "FST_SPI_D2"),
+	PINCTRL_PIN(1, "FST_SPI_D0"),
+	PINCTRL_PIN(2, "FST_SPI_CLK"),
+	PINCTRL_PIN(3, "FST_SPI_D3"),
+	PINCTRL_PIN(4, "FST_SPI_CS1_B"),
+	PINCTRL_PIN(5, "FST_SPI_D1"),
+	PINCTRL_PIN(6, "FST_SPI_CS0_B"),
+	PINCTRL_PIN(7, "FST_SPI_CS2_B"),
+
+	PINCTRL_PIN(15, "UART1_RTS_B"),
+	PINCTRL_PIN(16, "UART1_RXD"),
+	PINCTRL_PIN(17, "UART2_RXD"),
+	PINCTRL_PIN(18, "UART1_CTS_B"),
+	PINCTRL_PIN(19, "UART2_RTS_B"),
+	PINCTRL_PIN(20, "UART1_TXD"),
+	PINCTRL_PIN(21, "UART2_TXD"),
+	PINCTRL_PIN(22, "UART2_CTS_B"),
+
+	PINCTRL_PIN(30, "MF_HDA_CLK"),
+	PINCTRL_PIN(31, "MF_HDA_RSTB"),
+	PINCTRL_PIN(32, "MF_HDA_SDIO"),
+	PINCTRL_PIN(33, "MF_HDA_SDO"),
+	PINCTRL_PIN(34, "MF_HDA_DOCKRSTB"),
+	PINCTRL_PIN(35, "MF_HDA_SYNC"),
+	PINCTRL_PIN(36, "MF_HDA_SDI1"),
+	PINCTRL_PIN(37, "MF_HDA_DOCKENB"),
+
+	PINCTRL_PIN(45, "I2C5_SDA"),
+	PINCTRL_PIN(46, "I2C4_SDA"),
+	PINCTRL_PIN(47, "I2C6_SDA"),
+	PINCTRL_PIN(48, "I2C5_SCL"),
+	PINCTRL_PIN(49, "I2C_NFC_SDA"),
+	PINCTRL_PIN(50, "I2C4_SCL"),
+	PINCTRL_PIN(51, "I2C6_SCL"),
+	PINCTRL_PIN(52, "I2C_NFC_SCL"),
+
+	PINCTRL_PIN(60, "I2C1_SDA"),
+	PINCTRL_PIN(61, "I2C0_SDA"),
+	PINCTRL_PIN(62, "I2C2_SDA"),
+	PINCTRL_PIN(63, "I2C1_SCL"),
+	PINCTRL_PIN(64, "I2C3_SDA"),
+	PINCTRL_PIN(65, "I2C0_SCL"),
+	PINCTRL_PIN(66, "I2C2_SCL"),
+	PINCTRL_PIN(67, "I2C3_SCL"),
+
+	PINCTRL_PIN(75, "SATA_GP0"),
+	PINCTRL_PIN(76, "SATA_GP1"),
+	PINCTRL_PIN(77, "SATA_LEDN"),
+	PINCTRL_PIN(78, "SATA_GP2"),
+	PINCTRL_PIN(79, "MF_SMB_ALERTB"),
+	PINCTRL_PIN(80, "SATA_GP3"),
+	PINCTRL_PIN(81, "MF_SMB_CLK"),
+	PINCTRL_PIN(82, "MF_SMB_DATA"),
+
+	PINCTRL_PIN(90, "PCIE_CLKREQ0B"),
+	PINCTRL_PIN(91, "PCIE_CLKREQ1B"),
+	PINCTRL_PIN(92, "GP_SSP_2_CLK"),
+	PINCTRL_PIN(93, "PCIE_CLKREQ2B"),
+	PINCTRL_PIN(94, "GP_SSP_2_RXD"),
+	PINCTRL_PIN(95, "PCIE_CLKREQ3B"),
+	PINCTRL_PIN(96, "GP_SSP_2_FS"),
+	PINCTRL_PIN(97, "GP_SSP_2_TXD"),
+};
+
+static const unsigned southwest_fspi_pins[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+static const unsigned southwest_uart0_pins[] = { 16, 20 };
+static const unsigned southwest_uart1_pins[] = { 15, 16, 18, 20 };
+static const unsigned southwest_uart2_pins[] = { 17, 19, 21, 22 };
+static const unsigned southwest_i2c0_pins[] = { 61, 65 };
+static const unsigned southwest_hda_pins[] = { 30, 31, 32, 33, 34, 35, 36, 37 };
+static const unsigned southwest_lpe_pins[] = {
+	30, 31, 32, 33, 34, 35, 36, 37, 92, 94, 96, 97,
+};
+static const unsigned southwest_i2c1_pins[] = { 60, 63 };
+static const unsigned southwest_i2c2_pins[] = { 62, 66 };
+static const unsigned southwest_i2c3_pins[] = { 64, 67 };
+static const unsigned southwest_i2c4_pins[] = { 46, 50 };
+static const unsigned southwest_i2c5_pins[] = { 45, 48 };
+static const unsigned southwest_i2c6_pins[] = { 47, 51 };
+static const unsigned southwest_i2c_nfc_pins[] = { 49, 52 };
+static const unsigned southwest_smbus_pins[] = { 79, 81, 82 };
+static const unsigned southwest_spi3_pins[] = { 76, 79, 80, 81, 82 };
+
+/* LPE I2S TXD pins need to have invert_oe set */
+static const struct chv_alternate_function southwest_lpe_altfuncs[] = {
+	ALTERNATE_FUNCTION(30, 1, true),
+	ALTERNATE_FUNCTION(34, 1, true),
+	ALTERNATE_FUNCTION(97, 1, true),
+};
+
+/*
+ * Two spi3 chipselects are available in different mode than the main spi3
+ * functionality, which is using mode 1.
+ */
+static const struct chv_alternate_function southwest_spi3_altfuncs[] = {
+	ALTERNATE_FUNCTION(76, 3, false),
+	ALTERNATE_FUNCTION(80, 3, false),
+};
+
+static const struct chv_pingroup southwest_groups[] = {
+	PIN_GROUP("uart0_grp", southwest_uart0_pins, 2, false),
+	PIN_GROUP("uart1_grp", southwest_uart1_pins, 1, false),
+	PIN_GROUP("uart2_grp", southwest_uart2_pins, 1, false),
+	PIN_GROUP("hda_grp", southwest_hda_pins, 2, false),
+	PIN_GROUP("i2c0_grp", southwest_i2c0_pins, 1, true),
+	PIN_GROUP("i2c1_grp", southwest_i2c1_pins, 1, true),
+	PIN_GROUP("i2c2_grp", southwest_i2c2_pins, 1, true),
+	PIN_GROUP("i2c3_grp", southwest_i2c3_pins, 1, true),
+	PIN_GROUP("i2c4_grp", southwest_i2c4_pins, 1, true),
+	PIN_GROUP("i2c5_grp", southwest_i2c5_pins, 1, true),
+	PIN_GROUP("i2c6_grp", southwest_i2c6_pins, 1, true),
+	PIN_GROUP("i2c_nfc_grp", southwest_i2c_nfc_pins, 2, true),
+
+	PIN_GROUP_WITH_OVERRIDE("lpe_grp", southwest_lpe_pins, 1, false,
+				southwest_lpe_altfuncs),
+	PIN_GROUP_WITH_OVERRIDE("spi3_grp", southwest_spi3_pins, 2, false,
+				southwest_spi3_altfuncs),
+};
+
+static const char * const southwest_uart0_groups[] = { "uart0_grp" };
+static const char * const southwest_uart1_groups[] = { "uart1_grp" };
+static const char * const southwest_uart2_groups[] = { "uart2_grp" };
+static const char * const southwest_hda_groups[] = { "hda_grp" };
+static const char * const southwest_lpe_groups[] = { "lpe_grp" };
+static const char * const southwest_i2c0_groups[] = { "i2c0_grp" };
+static const char * const southwest_i2c1_groups[] = { "i2c1_grp" };
+static const char * const southwest_i2c2_groups[] = { "i2c2_grp" };
+static const char * const southwest_i2c3_groups[] = { "i2c3_grp" };
+static const char * const southwest_i2c4_groups[] = { "i2c4_grp" };
+static const char * const southwest_i2c5_groups[] = { "i2c5_grp" };
+static const char * const southwest_i2c6_groups[] = { "i2c6_grp" };
+static const char * const southwest_i2c_nfc_groups[] = { "i2c_nfc_grp" };
+static const char * const southwest_spi3_groups[] = { "spi3_grp" };
+
+/*
+ * Only do pinmuxing for certain LPSS devices for now. Rest of the pins are
+ * enabled only as GPIOs.
+ */
+static const struct chv_function southwest_functions[] = {
+	FUNCTION("uart0", southwest_uart0_groups),
+	FUNCTION("uart1", southwest_uart1_groups),
+	FUNCTION("uart2", southwest_uart2_groups),
+	FUNCTION("hda", southwest_hda_groups),
+	FUNCTION("lpe", southwest_lpe_groups),
+	FUNCTION("i2c0", southwest_i2c0_groups),
+	FUNCTION("i2c1", southwest_i2c1_groups),
+	FUNCTION("i2c2", southwest_i2c2_groups),
+	FUNCTION("i2c3", southwest_i2c3_groups),
+	FUNCTION("i2c4", southwest_i2c4_groups),
+	FUNCTION("i2c5", southwest_i2c5_groups),
+	FUNCTION("i2c6", southwest_i2c6_groups),
+	FUNCTION("i2c_nfc", southwest_i2c_nfc_groups),
+	FUNCTION("spi3", southwest_spi3_groups),
+};
+
+static const struct chv_gpio_pinrange southwest_gpio_ranges[] = {
+	GPIO_PINRANGE(0, 7),
+	GPIO_PINRANGE(15, 22),
+	GPIO_PINRANGE(30, 37),
+	GPIO_PINRANGE(45, 52),
+	GPIO_PINRANGE(60, 67),
+	GPIO_PINRANGE(75, 82),
+	GPIO_PINRANGE(90, 97),
+};
+
+static const struct chv_community southwest_community = {
+	.uid = "1",
+	.pins = southwest_pins,
+	.npins = ARRAY_SIZE(southwest_pins),
+	.groups = southwest_groups,
+	.ngroups = ARRAY_SIZE(southwest_groups),
+	.functions = southwest_functions,
+	.nfunctions = ARRAY_SIZE(southwest_functions),
+	.gpio_ranges = southwest_gpio_ranges,
+	.ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges),
+	/*
+	 * Southwest community can benerate GPIO interrupts only for the
+	 * first 8 interrupts. The upper half (8-15) can only be used to
+	 * trigger GPEs.
+	 */
+	.nirqs = 8,
+	.acpi_space_id = 0x91,
+};
+
+static const struct pinctrl_pin_desc north_pins[] = {
+	PINCTRL_PIN(0, "GPIO_DFX_0"),
+	PINCTRL_PIN(1, "GPIO_DFX_3"),
+	PINCTRL_PIN(2, "GPIO_DFX_7"),
+	PINCTRL_PIN(3, "GPIO_DFX_1"),
+	PINCTRL_PIN(4, "GPIO_DFX_5"),
+	PINCTRL_PIN(5, "GPIO_DFX_4"),
+	PINCTRL_PIN(6, "GPIO_DFX_8"),
+	PINCTRL_PIN(7, "GPIO_DFX_2"),
+	PINCTRL_PIN(8, "GPIO_DFX_6"),
+
+	PINCTRL_PIN(15, "GPIO_SUS0"),
+	PINCTRL_PIN(16, "SEC_GPIO_SUS10"),
+	PINCTRL_PIN(17, "GPIO_SUS3"),
+	PINCTRL_PIN(18, "GPIO_SUS7"),
+	PINCTRL_PIN(19, "GPIO_SUS1"),
+	PINCTRL_PIN(20, "GPIO_SUS5"),
+	PINCTRL_PIN(21, "SEC_GPIO_SUS11"),
+	PINCTRL_PIN(22, "GPIO_SUS4"),
+	PINCTRL_PIN(23, "SEC_GPIO_SUS8"),
+	PINCTRL_PIN(24, "GPIO_SUS2"),
+	PINCTRL_PIN(25, "GPIO_SUS6"),
+	PINCTRL_PIN(26, "CX_PREQ_B"),
+	PINCTRL_PIN(27, "SEC_GPIO_SUS9"),
+
+	PINCTRL_PIN(30, "TRST_B"),
+	PINCTRL_PIN(31, "TCK"),
+	PINCTRL_PIN(32, "PROCHOT_B"),
+	PINCTRL_PIN(33, "SVIDO_DATA"),
+	PINCTRL_PIN(34, "TMS"),
+	PINCTRL_PIN(35, "CX_PRDY_B_2"),
+	PINCTRL_PIN(36, "TDO_2"),
+	PINCTRL_PIN(37, "CX_PRDY_B"),
+	PINCTRL_PIN(38, "SVIDO_ALERT_B"),
+	PINCTRL_PIN(39, "TDO"),
+	PINCTRL_PIN(40, "SVIDO_CLK"),
+	PINCTRL_PIN(41, "TDI"),
+
+	PINCTRL_PIN(45, "GP_CAMERASB_05"),
+	PINCTRL_PIN(46, "GP_CAMERASB_02"),
+	PINCTRL_PIN(47, "GP_CAMERASB_08"),
+	PINCTRL_PIN(48, "GP_CAMERASB_00"),
+	PINCTRL_PIN(49, "GP_CAMERASB_06"),
+	PINCTRL_PIN(50, "GP_CAMERASB_10"),
+	PINCTRL_PIN(51, "GP_CAMERASB_03"),
+	PINCTRL_PIN(52, "GP_CAMERASB_09"),
+	PINCTRL_PIN(53, "GP_CAMERASB_01"),
+	PINCTRL_PIN(54, "GP_CAMERASB_07"),
+	PINCTRL_PIN(55, "GP_CAMERASB_11"),
+	PINCTRL_PIN(56, "GP_CAMERASB_04"),
+
+	PINCTRL_PIN(60, "PANEL0_BKLTEN"),
+	PINCTRL_PIN(61, "HV_DDI0_HPD"),
+	PINCTRL_PIN(62, "HV_DDI2_DDC_SDA"),
+	PINCTRL_PIN(63, "PANEL1_BKLTCTL"),
+	PINCTRL_PIN(64, "HV_DDI1_HPD"),
+	PINCTRL_PIN(65, "PANEL0_BKLTCTL"),
+	PINCTRL_PIN(66, "HV_DDI0_DDC_SDA"),
+	PINCTRL_PIN(67, "HV_DDI2_DDC_SCL"),
+	PINCTRL_PIN(68, "HV_DDI2_HPD"),
+	PINCTRL_PIN(69, "PANEL1_VDDEN"),
+	PINCTRL_PIN(70, "PANEL1_BKLTEN"),
+	PINCTRL_PIN(71, "HV_DDI0_DDC_SCL"),
+	PINCTRL_PIN(72, "PANEL0_VDDEN"),
+};
+
+static const struct chv_gpio_pinrange north_gpio_ranges[] = {
+	GPIO_PINRANGE(0, 8),
+	GPIO_PINRANGE(15, 27),
+	GPIO_PINRANGE(30, 41),
+	GPIO_PINRANGE(45, 56),
+	GPIO_PINRANGE(60, 72),
+};
+
+static const struct chv_community north_community = {
+	.uid = "2",
+	.pins = north_pins,
+	.npins = ARRAY_SIZE(north_pins),
+	.gpio_ranges = north_gpio_ranges,
+	.ngpio_ranges = ARRAY_SIZE(north_gpio_ranges),
+	/*
+	 * North community can generate GPIO interrupts only for the first
+	 * 8 interrupts. The upper half (8-15) can only be used to trigger
+	 * GPEs.
+	 */
+	.nirqs = 8,
+	.acpi_space_id = 0x92,
+};
+
+static const struct pinctrl_pin_desc east_pins[] = {
+	PINCTRL_PIN(0, "PMU_SLP_S3_B"),
+	PINCTRL_PIN(1, "PMU_BATLOW_B"),
+	PINCTRL_PIN(2, "SUS_STAT_B"),
+	PINCTRL_PIN(3, "PMU_SLP_S0IX_B"),
+	PINCTRL_PIN(4, "PMU_AC_PRESENT"),
+	PINCTRL_PIN(5, "PMU_PLTRST_B"),
+	PINCTRL_PIN(6, "PMU_SUSCLK"),
+	PINCTRL_PIN(7, "PMU_SLP_LAN_B"),
+	PINCTRL_PIN(8, "PMU_PWRBTN_B"),
+	PINCTRL_PIN(9, "PMU_SLP_S4_B"),
+	PINCTRL_PIN(10, "PMU_WAKE_B"),
+	PINCTRL_PIN(11, "PMU_WAKE_LAN_B"),
+
+	PINCTRL_PIN(15, "MF_ISH_GPIO_3"),
+	PINCTRL_PIN(16, "MF_ISH_GPIO_7"),
+	PINCTRL_PIN(17, "MF_ISH_I2C1_SCL"),
+	PINCTRL_PIN(18, "MF_ISH_GPIO_1"),
+	PINCTRL_PIN(19, "MF_ISH_GPIO_5"),
+	PINCTRL_PIN(20, "MF_ISH_GPIO_9"),
+	PINCTRL_PIN(21, "MF_ISH_GPIO_0"),
+	PINCTRL_PIN(22, "MF_ISH_GPIO_4"),
+	PINCTRL_PIN(23, "MF_ISH_GPIO_8"),
+	PINCTRL_PIN(24, "MF_ISH_GPIO_2"),
+	PINCTRL_PIN(25, "MF_ISH_GPIO_6"),
+	PINCTRL_PIN(26, "MF_ISH_I2C1_SDA"),
+};
+
+static const struct chv_gpio_pinrange east_gpio_ranges[] = {
+	GPIO_PINRANGE(0, 11),
+	GPIO_PINRANGE(15, 26),
+};
+
+static const struct chv_community east_community = {
+	.uid = "3",
+	.pins = east_pins,
+	.npins = ARRAY_SIZE(east_pins),
+	.gpio_ranges = east_gpio_ranges,
+	.ngpio_ranges = ARRAY_SIZE(east_gpio_ranges),
+	.nirqs = 16,
+	.acpi_space_id = 0x93,
+};
+
+static const struct pinctrl_pin_desc southeast_pins[] = {
+	PINCTRL_PIN(0, "MF_PLT_CLK0"),
+	PINCTRL_PIN(1, "PWM1"),
+	PINCTRL_PIN(2, "MF_PLT_CLK1"),
+	PINCTRL_PIN(3, "MF_PLT_CLK4"),
+	PINCTRL_PIN(4, "MF_PLT_CLK3"),
+	PINCTRL_PIN(5, "PWM0"),
+	PINCTRL_PIN(6, "MF_PLT_CLK5"),
+	PINCTRL_PIN(7, "MF_PLT_CLK2"),
+
+	PINCTRL_PIN(15, "SDMMC2_D3_CD_B"),
+	PINCTRL_PIN(16, "SDMMC1_CLK"),
+	PINCTRL_PIN(17, "SDMMC1_D0"),
+	PINCTRL_PIN(18, "SDMMC2_D1"),
+	PINCTRL_PIN(19, "SDMMC2_CLK"),
+	PINCTRL_PIN(20, "SDMMC1_D2"),
+	PINCTRL_PIN(21, "SDMMC2_D2"),
+	PINCTRL_PIN(22, "SDMMC2_CMD"),
+	PINCTRL_PIN(23, "SDMMC1_CMD"),
+	PINCTRL_PIN(24, "SDMMC1_D1"),
+	PINCTRL_PIN(25, "SDMMC2_D0"),
+	PINCTRL_PIN(26, "SDMMC1_D3_CD_B"),
+
+	PINCTRL_PIN(30, "SDMMC3_D1"),
+	PINCTRL_PIN(31, "SDMMC3_CLK"),
+	PINCTRL_PIN(32, "SDMMC3_D3"),
+	PINCTRL_PIN(33, "SDMMC3_D2"),
+	PINCTRL_PIN(34, "SDMMC3_CMD"),
+	PINCTRL_PIN(35, "SDMMC3_D0"),
+
+	PINCTRL_PIN(45, "MF_LPC_AD2"),
+	PINCTRL_PIN(46, "LPC_CLKRUNB"),
+	PINCTRL_PIN(47, "MF_LPC_AD0"),
+	PINCTRL_PIN(48, "LPC_FRAMEB"),
+	PINCTRL_PIN(49, "MF_LPC_CLKOUT1"),
+	PINCTRL_PIN(50, "MF_LPC_AD3"),
+	PINCTRL_PIN(51, "MF_LPC_CLKOUT0"),
+	PINCTRL_PIN(52, "MF_LPC_AD1"),
+
+	PINCTRL_PIN(60, "SPI1_MISO"),
+	PINCTRL_PIN(61, "SPI1_CSO_B"),
+	PINCTRL_PIN(62, "SPI1_CLK"),
+	PINCTRL_PIN(63, "MMC1_D6"),
+	PINCTRL_PIN(64, "SPI1_MOSI"),
+	PINCTRL_PIN(65, "MMC1_D5"),
+	PINCTRL_PIN(66, "SPI1_CS1_B"),
+	PINCTRL_PIN(67, "MMC1_D4_SD_WE"),
+	PINCTRL_PIN(68, "MMC1_D7"),
+	PINCTRL_PIN(69, "MMC1_RCLK"),
+
+	PINCTRL_PIN(75, "USB_OC1_B"),
+	PINCTRL_PIN(76, "PMU_RESETBUTTON_B"),
+	PINCTRL_PIN(77, "GPIO_ALERT"),
+	PINCTRL_PIN(78, "SDMMC3_PWR_EN_B"),
+	PINCTRL_PIN(79, "ILB_SERIRQ"),
+	PINCTRL_PIN(80, "USB_OC0_B"),
+	PINCTRL_PIN(81, "SDMMC3_CD_B"),
+	PINCTRL_PIN(82, "SPKR"),
+	PINCTRL_PIN(83, "SUSPWRDNACK"),
+	PINCTRL_PIN(84, "SPARE_PIN"),
+	PINCTRL_PIN(85, "SDMMC3_1P8_EN"),
+};
+
+static const unsigned southeast_pwm0_pins[] = { 5 };
+static const unsigned southeast_pwm1_pins[] = { 1 };
+static const unsigned southeast_sdmmc1_pins[] = {
+	16, 17, 20, 23, 24, 26, 63, 65, 67, 68, 69,
+};
+static const unsigned southeast_sdmmc2_pins[] = { 15, 18, 19, 21, 22, 25 };
+static const unsigned southeast_sdmmc3_pins[] = {
+	30, 31, 32, 33, 34, 35, 78, 81, 85,
+};
+static const unsigned southeast_spi1_pins[] = { 60, 61, 62, 64, 66 };
+static const unsigned southeast_spi2_pins[] = { 2, 3, 4, 6, 7 };
+
+static const struct chv_pingroup southeast_groups[] = {
+	PIN_GROUP("pwm0_grp", southeast_pwm0_pins, 1, false),
+	PIN_GROUP("pwm1_grp", southeast_pwm1_pins, 1, false),
+	PIN_GROUP("sdmmc1_grp", southeast_sdmmc1_pins, 1, false),
+	PIN_GROUP("sdmmc2_grp", southeast_sdmmc2_pins, 1, false),
+	PIN_GROUP("sdmmc3_grp", southeast_sdmmc3_pins, 1, false),
+	PIN_GROUP("spi1_grp", southeast_spi1_pins, 1, false),
+	PIN_GROUP("spi2_grp", southeast_spi2_pins, 4, false),
+};
+
+static const char * const southeast_pwm0_groups[] = { "pwm0_grp" };
+static const char * const southeast_pwm1_groups[] = { "pwm1_grp" };
+static const char * const southeast_sdmmc1_groups[] = { "sdmmc1_grp" };
+static const char * const southeast_sdmmc2_groups[] = { "sdmmc2_grp" };
+static const char * const southeast_sdmmc3_groups[] = { "sdmmc3_grp" };
+static const char * const southeast_spi1_groups[] = { "spi1_grp" };
+static const char * const southeast_spi2_groups[] = { "spi2_grp" };
+
+static const struct chv_function southeast_functions[] = {
+	FUNCTION("pwm0", southeast_pwm0_groups),
+	FUNCTION("pwm1", southeast_pwm1_groups),
+	FUNCTION("sdmmc1", southeast_sdmmc1_groups),
+	FUNCTION("sdmmc2", southeast_sdmmc2_groups),
+	FUNCTION("sdmmc3", southeast_sdmmc3_groups),
+	FUNCTION("spi1", southeast_spi1_groups),
+	FUNCTION("spi2", southeast_spi2_groups),
+};
+
+static const struct chv_gpio_pinrange southeast_gpio_ranges[] = {
+	GPIO_PINRANGE(0, 7),
+	GPIO_PINRANGE(15, 26),
+	GPIO_PINRANGE(30, 35),
+	GPIO_PINRANGE(45, 52),
+	GPIO_PINRANGE(60, 69),
+	GPIO_PINRANGE(75, 85),
+};
+
+static const struct chv_community southeast_community = {
+	.uid = "4",
+	.pins = southeast_pins,
+	.npins = ARRAY_SIZE(southeast_pins),
+	.groups = southeast_groups,
+	.ngroups = ARRAY_SIZE(southeast_groups),
+	.functions = southeast_functions,
+	.nfunctions = ARRAY_SIZE(southeast_functions),
+	.gpio_ranges = southeast_gpio_ranges,
+	.ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges),
+	.nirqs = 16,
+	.acpi_space_id = 0x94,
+};
+
+static const struct chv_community *chv_communities[] = {
+	&southwest_community,
+	&north_community,
+	&east_community,
+	&southeast_community,
+};
+
+/*
+ * Lock to serialize register accesses
+ *
+ * Due to a silicon issue, a shared lock must be used to prevent
+ * concurrent accesses across the 4 GPIO controllers.
+ *
+ * See Intel Atom Z8000 Processor Series Specification Update (Rev. 005),
+ * errata #CHT34, for further information.
+ */
+static DEFINE_RAW_SPINLOCK(chv_lock);
+
+static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned offset,
+				unsigned reg)
+{
+	unsigned family_no = offset / MAX_FAMILY_PAD_GPIO_NO;
+	unsigned pad_no = offset % MAX_FAMILY_PAD_GPIO_NO;
+
+	offset = FAMILY_PAD_REGS_OFF + FAMILY_PAD_REGS_SIZE * family_no +
+		 GPIO_REGS_SIZE * pad_no;
+
+	return pctrl->regs + offset + reg;
+}
+
+static void chv_writel(u32 value, void __iomem *reg)
+{
+	writel(value, reg);
+	/* simple readback to confirm the bus transferring done */
+	readl(reg);
+}
+
+/* When Pad Cfg is locked, driver can only change GPIOTXState or GPIORXState */
+static bool chv_pad_locked(struct chv_pinctrl *pctrl, unsigned offset)
+{
+	void __iomem *reg;
+
+	reg = chv_padreg(pctrl, offset, CHV_PADCTRL1);
+	return readl(reg) & CHV_PADCTRL1_CFGLOCK;
+}
+
+static int chv_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctrl->community->ngroups;
+}
+
+static const char *chv_get_group_name(struct pinctrl_dev *pctldev,
+				      unsigned group)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctrl->community->groups[group].name;
+}
+
+static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned group,
+			      const unsigned **pins, unsigned *npins)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	*pins = pctrl->community->groups[group].pins;
+	*npins = pctrl->community->groups[group].npins;
+	return 0;
+}
+
+static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+			     unsigned offset)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned long flags;
+	u32 ctrl0, ctrl1;
+	bool locked;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+
+	ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
+	ctrl1 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL1));
+	locked = chv_pad_locked(pctrl, offset);
+
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	if (ctrl0 & CHV_PADCTRL0_GPIOEN) {
+		seq_puts(s, "GPIO ");
+	} else {
+		u32 mode;
+
+		mode = ctrl0 & CHV_PADCTRL0_PMODE_MASK;
+		mode >>= CHV_PADCTRL0_PMODE_SHIFT;
+
+		seq_printf(s, "mode %d ", mode);
+	}
+
+	seq_printf(s, "0x%08x 0x%08x", ctrl0, ctrl1);
+
+	if (locked)
+		seq_puts(s, " [LOCKED]");
+}
+
+static const struct pinctrl_ops chv_pinctrl_ops = {
+	.get_groups_count = chv_get_groups_count,
+	.get_group_name = chv_get_group_name,
+	.get_group_pins = chv_get_group_pins,
+	.pin_dbg_show = chv_pin_dbg_show,
+};
+
+static int chv_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctrl->community->nfunctions;
+}
+
+static const char *chv_get_function_name(struct pinctrl_dev *pctldev,
+					 unsigned function)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctrl->community->functions[function].name;
+}
+
+static int chv_get_function_groups(struct pinctrl_dev *pctldev,
+				   unsigned function,
+				   const char * const **groups,
+				   unsigned * const ngroups)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = pctrl->community->functions[function].groups;
+	*ngroups = pctrl->community->functions[function].ngroups;
+	return 0;
+}
+
+static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
+			      unsigned group)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	const struct chv_pingroup *grp;
+	unsigned long flags;
+	int i;
+
+	grp = &pctrl->community->groups[group];
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+
+	/* Check first that the pad is not locked */
+	for (i = 0; i < grp->npins; i++) {
+		if (chv_pad_locked(pctrl, grp->pins[i])) {
+			dev_warn(pctrl->dev, "unable to set mode for locked pin %u\n",
+				 grp->pins[i]);
+			raw_spin_unlock_irqrestore(&chv_lock, flags);
+			return -EBUSY;
+		}
+	}
+
+	for (i = 0; i < grp->npins; i++) {
+		const struct chv_alternate_function *altfunc = &grp->altfunc;
+		int pin = grp->pins[i];
+		void __iomem *reg;
+		u32 value;
+
+		/* Check if there is pin-specific config */
+		if (grp->overrides) {
+			int j;
+
+			for (j = 0; j < grp->noverrides; j++) {
+				if (grp->overrides[j].pin == pin) {
+					altfunc = &grp->overrides[j];
+					break;
+				}
+			}
+		}
+
+		reg = chv_padreg(pctrl, pin, CHV_PADCTRL0);
+		value = readl(reg);
+		/* Disable GPIO mode */
+		value &= ~CHV_PADCTRL0_GPIOEN;
+		/* Set to desired mode */
+		value &= ~CHV_PADCTRL0_PMODE_MASK;
+		value |= altfunc->mode << CHV_PADCTRL0_PMODE_SHIFT;
+		chv_writel(value, reg);
+
+		/* Update for invert_oe */
+		reg = chv_padreg(pctrl, pin, CHV_PADCTRL1);
+		value = readl(reg) & ~CHV_PADCTRL1_INVRXTX_MASK;
+		if (altfunc->invert_oe)
+			value |= CHV_PADCTRL1_INVRXTX_TXENABLE;
+		chv_writel(value, reg);
+
+		dev_dbg(pctrl->dev, "configured pin %u mode %u OE %sinverted\n",
+			pin, altfunc->mode, altfunc->invert_oe ? "" : "not ");
+	}
+
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	return 0;
+}
+
+static int chv_gpio_request_enable(struct pinctrl_dev *pctldev,
+				   struct pinctrl_gpio_range *range,
+				   unsigned offset)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned long flags;
+	void __iomem *reg;
+	u32 value;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+
+	if (chv_pad_locked(pctrl, offset)) {
+		value = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
+		if (!(value & CHV_PADCTRL0_GPIOEN)) {
+			/* Locked so cannot enable */
+			raw_spin_unlock_irqrestore(&chv_lock, flags);
+			return -EBUSY;
+		}
+	} else {
+		int i;
+
+		/* Reset the interrupt mapping */
+		for (i = 0; i < ARRAY_SIZE(pctrl->intr_lines); i++) {
+			if (pctrl->intr_lines[i] == offset) {
+				pctrl->intr_lines[i] = 0;
+				break;
+			}
+		}
+
+		/* Disable interrupt generation */
+		reg = chv_padreg(pctrl, offset, CHV_PADCTRL1);
+		value = readl(reg);
+		value &= ~CHV_PADCTRL1_INTWAKECFG_MASK;
+		value &= ~CHV_PADCTRL1_INVRXTX_MASK;
+		chv_writel(value, reg);
+
+		reg = chv_padreg(pctrl, offset, CHV_PADCTRL0);
+		value = readl(reg);
+
+		/*
+		 * If the pin is in HiZ mode (both TX and RX buffers are
+		 * disabled) we turn it to be input now.
+		 */
+		if ((value & CHV_PADCTRL0_GPIOCFG_MASK) ==
+		     (CHV_PADCTRL0_GPIOCFG_HIZ << CHV_PADCTRL0_GPIOCFG_SHIFT)) {
+			value &= ~CHV_PADCTRL0_GPIOCFG_MASK;
+			value |= CHV_PADCTRL0_GPIOCFG_GPI <<
+				CHV_PADCTRL0_GPIOCFG_SHIFT;
+		}
+
+		/* Switch to a GPIO mode */
+		value |= CHV_PADCTRL0_GPIOEN;
+		chv_writel(value, reg);
+	}
+
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	return 0;
+}
+
+static void chv_gpio_disable_free(struct pinctrl_dev *pctldev,
+				  struct pinctrl_gpio_range *range,
+				  unsigned offset)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned long flags;
+	void __iomem *reg;
+	u32 value;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+
+	reg = chv_padreg(pctrl, offset, CHV_PADCTRL0);
+	value = readl(reg) & ~CHV_PADCTRL0_GPIOEN;
+	chv_writel(value, reg);
+
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+}
+
+static int chv_gpio_set_direction(struct pinctrl_dev *pctldev,
+				  struct pinctrl_gpio_range *range,
+				  unsigned offset, bool input)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	void __iomem *reg = chv_padreg(pctrl, offset, CHV_PADCTRL0);
+	unsigned long flags;
+	u32 ctrl0;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+
+	ctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIOCFG_MASK;
+	if (input)
+		ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT;
+	else
+		ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT;
+	chv_writel(ctrl0, reg);
+
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	return 0;
+}
+
+static const struct pinmux_ops chv_pinmux_ops = {
+	.get_functions_count = chv_get_functions_count,
+	.get_function_name = chv_get_function_name,
+	.get_function_groups = chv_get_function_groups,
+	.set_mux = chv_pinmux_set_mux,
+	.gpio_request_enable = chv_gpio_request_enable,
+	.gpio_disable_free = chv_gpio_disable_free,
+	.gpio_set_direction = chv_gpio_set_direction,
+};
+
+static int chv_config_get(struct pinctrl_dev *pctldev, unsigned pin,
+			  unsigned long *config)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	unsigned long flags;
+	u32 ctrl0, ctrl1;
+	u16 arg = 0;
+	u32 term;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+	ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
+	ctrl1 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1));
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (term)
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (!(ctrl0 & CHV_PADCTRL0_TERM_UP))
+			return -EINVAL;
+
+		switch (term) {
+		case CHV_PADCTRL0_TERM_20K:
+			arg = 20000;
+			break;
+		case CHV_PADCTRL0_TERM_5K:
+			arg = 5000;
+			break;
+		case CHV_PADCTRL0_TERM_1K:
+			arg = 1000;
+			break;
+		}
+
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (!term || (ctrl0 & CHV_PADCTRL0_TERM_UP))
+			return -EINVAL;
+
+		switch (term) {
+		case CHV_PADCTRL0_TERM_20K:
+			arg = 20000;
+			break;
+		case CHV_PADCTRL0_TERM_5K:
+			arg = 5000;
+			break;
+		}
+
+		break;
+
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		if (!(ctrl1 & CHV_PADCTRL1_ODEN))
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: {
+		u32 cfg;
+
+		cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
+		cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
+		if (cfg != CHV_PADCTRL0_GPIOCFG_HIZ)
+			return -EINVAL;
+
+		break;
+	}
+
+	default:
+		return -ENOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, arg);
+	return 0;
+}
+
+static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin,
+			       enum pin_config_param param, u32 arg)
+{
+	void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL0);
+	unsigned long flags;
+	u32 ctrl0, pull;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+	ctrl0 = readl(reg);
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP);
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP);
+
+		switch (arg) {
+		case 1000:
+			/* For 1k there is only pull up */
+			pull = CHV_PADCTRL0_TERM_1K << CHV_PADCTRL0_TERM_SHIFT;
+			break;
+		case 5000:
+			pull = CHV_PADCTRL0_TERM_5K << CHV_PADCTRL0_TERM_SHIFT;
+			break;
+		case 20000:
+			pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT;
+			break;
+		default:
+			raw_spin_unlock_irqrestore(&chv_lock, flags);
+			return -EINVAL;
+		}
+
+		ctrl0 |= CHV_PADCTRL0_TERM_UP | pull;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP);
+
+		switch (arg) {
+		case 5000:
+			pull = CHV_PADCTRL0_TERM_5K << CHV_PADCTRL0_TERM_SHIFT;
+			break;
+		case 20000:
+			pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT;
+			break;
+		default:
+			raw_spin_unlock_irqrestore(&chv_lock, flags);
+			return -EINVAL;
+		}
+
+		ctrl0 |= pull;
+		break;
+
+	default:
+		raw_spin_unlock_irqrestore(&chv_lock, flags);
+		return -EINVAL;
+	}
+
+	chv_writel(ctrl0, reg);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	return 0;
+}
+
+static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin,
+			       bool enable)
+{
+	void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1);
+	unsigned long flags;
+	u32 ctrl1;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+	ctrl1 = readl(reg);
+
+	if (enable)
+		ctrl1 |= CHV_PADCTRL1_ODEN;
+	else
+		ctrl1 &= ~CHV_PADCTRL1_ODEN;
+
+	chv_writel(ctrl1, reg);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	return 0;
+}
+
+static int chv_config_set(struct pinctrl_dev *pctldev, unsigned pin,
+			  unsigned long *configs, unsigned nconfigs)
+{
+	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param;
+	int i, ret;
+	u32 arg;
+
+	if (chv_pad_locked(pctrl, pin))
+		return -EBUSY;
+
+	for (i = 0; i < nconfigs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_DISABLE:
+		case PIN_CONFIG_BIAS_PULL_UP:
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			ret = chv_config_set_pull(pctrl, pin, param, arg);
+			if (ret)
+				return ret;
+			break;
+
+		case PIN_CONFIG_DRIVE_PUSH_PULL:
+			ret = chv_config_set_oden(pctrl, pin, false);
+			if (ret)
+				return ret;
+			break;
+
+		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+			ret = chv_config_set_oden(pctrl, pin, true);
+			if (ret)
+				return ret;
+			break;
+
+		default:
+			return -ENOTSUPP;
+		}
+
+		dev_dbg(pctrl->dev, "pin %d set config %d arg %u\n", pin,
+			param, arg);
+	}
+
+	return 0;
+}
+
+static int chv_config_group_get(struct pinctrl_dev *pctldev,
+				unsigned int group,
+				unsigned long *config)
+{
+	const unsigned int *pins;
+	unsigned int npins;
+	int ret;
+
+	ret = chv_get_group_pins(pctldev, group, &pins, &npins);
+	if (ret)
+		return ret;
+
+	ret = chv_config_get(pctldev, pins[0], config);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int chv_config_group_set(struct pinctrl_dev *pctldev,
+				unsigned int group, unsigned long *configs,
+				unsigned int num_configs)
+{
+	const unsigned int *pins;
+	unsigned int npins;
+	int i, ret;
+
+	ret = chv_get_group_pins(pctldev, group, &pins, &npins);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < npins; i++) {
+		ret = chv_config_set(pctldev, pins[i], configs, num_configs);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static const struct pinconf_ops chv_pinconf_ops = {
+	.is_generic = true,
+	.pin_config_set = chv_config_set,
+	.pin_config_get = chv_config_get,
+	.pin_config_group_get = chv_config_group_get,
+	.pin_config_group_set = chv_config_group_set,
+};
+
+static struct pinctrl_desc chv_pinctrl_desc = {
+	.pctlops = &chv_pinctrl_ops,
+	.pmxops = &chv_pinmux_ops,
+	.confops = &chv_pinconf_ops,
+	.owner = THIS_MODULE,
+};
+
+static int chv_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
+	unsigned long flags;
+	u32 ctrl0, cfg;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+	ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
+	cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
+
+	if (cfg == CHV_PADCTRL0_GPIOCFG_GPO)
+		return !!(ctrl0 & CHV_PADCTRL0_GPIOTXSTATE);
+	return !!(ctrl0 & CHV_PADCTRL0_GPIORXSTATE);
+}
+
+static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
+	unsigned long flags;
+	void __iomem *reg;
+	u32 ctrl0;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+
+	reg = chv_padreg(pctrl, offset, CHV_PADCTRL0);
+	ctrl0 = readl(reg);
+
+	if (value)
+		ctrl0 |= CHV_PADCTRL0_GPIOTXSTATE;
+	else
+		ctrl0 &= ~CHV_PADCTRL0_GPIOTXSTATE;
+
+	chv_writel(ctrl0, reg);
+
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+}
+
+static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+	struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
+	u32 ctrl0, direction;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+	ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
+	direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
+
+	return direction != CHV_PADCTRL0_GPIOCFG_GPO;
+}
+
+static int chv_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int chv_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+				     int value)
+{
+	chv_gpio_set(chip, offset, value);
+	return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
+static const struct gpio_chip chv_gpio_chip = {
+	.owner = THIS_MODULE,
+	.request = gpiochip_generic_request,
+	.free = gpiochip_generic_free,
+	.get_direction = chv_gpio_get_direction,
+	.direction_input = chv_gpio_direction_input,
+	.direction_output = chv_gpio_direction_output,
+	.get = chv_gpio_get,
+	.set = chv_gpio_set,
+};
+
+static void chv_gpio_irq_ack(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
+	int pin = irqd_to_hwirq(d);
+	u32 intr_line;
+
+	raw_spin_lock(&chv_lock);
+
+	intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
+	intr_line &= CHV_PADCTRL0_INTSEL_MASK;
+	intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT;
+	chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT);
+
+	raw_spin_unlock(&chv_lock);
+}
+
+static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
+	int pin = irqd_to_hwirq(d);
+	u32 value, intr_line;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+
+	intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
+	intr_line &= CHV_PADCTRL0_INTSEL_MASK;
+	intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT;
+
+	value = readl(pctrl->regs + CHV_INTMASK);
+	if (mask)
+		value &= ~BIT(intr_line);
+	else
+		value |= BIT(intr_line);
+	chv_writel(value, pctrl->regs + CHV_INTMASK);
+
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+}
+
+static void chv_gpio_irq_mask(struct irq_data *d)
+{
+	chv_gpio_irq_mask_unmask(d, true);
+}
+
+static void chv_gpio_irq_unmask(struct irq_data *d)
+{
+	chv_gpio_irq_mask_unmask(d, false);
+}
+
+static unsigned chv_gpio_irq_startup(struct irq_data *d)
+{
+	/*
+	 * Check if the interrupt has been requested with 0 as triggering
+	 * type. In that case it is assumed that the current values
+	 * programmed to the hardware are used (e.g BIOS configured
+	 * defaults).
+	 *
+	 * In that case ->irq_set_type() will never be called so we need to
+	 * read back the values from hardware now, set correct flow handler
+	 * and update mappings before the interrupt is being used.
+	 */
+	if (irqd_get_trigger_type(d) == IRQ_TYPE_NONE) {
+		struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+		struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
+		unsigned pin = irqd_to_hwirq(d);
+		irq_flow_handler_t handler;
+		unsigned long flags;
+		u32 intsel, value;
+
+		raw_spin_lock_irqsave(&chv_lock, flags);
+		intsel = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
+		intsel &= CHV_PADCTRL0_INTSEL_MASK;
+		intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
+
+		value = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1));
+		if (value & CHV_PADCTRL1_INTWAKECFG_LEVEL)
+			handler = handle_level_irq;
+		else
+			handler = handle_edge_irq;
+
+		if (!pctrl->intr_lines[intsel]) {
+			irq_set_handler_locked(d, handler);
+			pctrl->intr_lines[intsel] = pin;
+		}
+		raw_spin_unlock_irqrestore(&chv_lock, flags);
+	}
+
+	chv_gpio_irq_unmask(d);
+	return 0;
+}
+
+static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
+	unsigned pin = irqd_to_hwirq(d);
+	unsigned long flags;
+	u32 value;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+
+	/*
+	 * Pins which can be used as shared interrupt are configured in
+	 * BIOS. Driver trusts BIOS configurations and assigns different
+	 * handler according to the irq type.
+	 *
+	 * Driver needs to save the mapping between each pin and
+	 * its interrupt line.
+	 * 1. If the pin cfg is locked in BIOS:
+	 *	Trust BIOS has programmed IntWakeCfg bits correctly,
+	 *	driver just needs to save the mapping.
+	 * 2. If the pin cfg is not locked in BIOS:
+	 *	Driver programs the IntWakeCfg bits and save the mapping.
+	 */
+	if (!chv_pad_locked(pctrl, pin)) {
+		void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1);
+
+		value = readl(reg);
+		value &= ~CHV_PADCTRL1_INTWAKECFG_MASK;
+		value &= ~CHV_PADCTRL1_INVRXTX_MASK;
+
+		if (type & IRQ_TYPE_EDGE_BOTH) {
+			if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
+				value |= CHV_PADCTRL1_INTWAKECFG_BOTH;
+			else if (type & IRQ_TYPE_EDGE_RISING)
+				value |= CHV_PADCTRL1_INTWAKECFG_RISING;
+			else if (type & IRQ_TYPE_EDGE_FALLING)
+				value |= CHV_PADCTRL1_INTWAKECFG_FALLING;
+		} else if (type & IRQ_TYPE_LEVEL_MASK) {
+			value |= CHV_PADCTRL1_INTWAKECFG_LEVEL;
+			if (type & IRQ_TYPE_LEVEL_LOW)
+				value |= CHV_PADCTRL1_INVRXTX_RXDATA;
+		}
+
+		chv_writel(value, reg);
+	}
+
+	value = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
+	value &= CHV_PADCTRL0_INTSEL_MASK;
+	value >>= CHV_PADCTRL0_INTSEL_SHIFT;
+
+	pctrl->intr_lines[value] = pin;
+
+	if (type & IRQ_TYPE_EDGE_BOTH)
+		irq_set_handler_locked(d, handle_edge_irq);
+	else if (type & IRQ_TYPE_LEVEL_MASK)
+		irq_set_handler_locked(d, handle_level_irq);
+
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	return 0;
+}
+
+static struct irq_chip chv_gpio_irqchip = {
+	.name = "chv-gpio",
+	.irq_startup = chv_gpio_irq_startup,
+	.irq_ack = chv_gpio_irq_ack,
+	.irq_mask = chv_gpio_irq_mask,
+	.irq_unmask = chv_gpio_irq_unmask,
+	.irq_set_type = chv_gpio_irq_type,
+	.flags = IRQCHIP_SKIP_SET_WAKE,
+};
+
+static void chv_gpio_irq_handler(struct irq_desc *desc)
+{
+	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+	struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	unsigned long pending;
+	u32 intr_line;
+
+	chained_irq_enter(chip, desc);
+
+	pending = readl(pctrl->regs + CHV_INTSTAT);
+	for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) {
+		unsigned irq, offset;
+
+		offset = pctrl->intr_lines[intr_line];
+		irq = irq_find_mapping(gc->irq.domain, offset);
+		generic_handle_irq(irq);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+/*
+ * Certain machines seem to hardcode Linux IRQ numbers in their ACPI
+ * tables. Since we leave GPIOs that are not capable of generating
+ * interrupts out of the irqdomain the numbering will be different and
+ * cause devices using the hardcoded IRQ numbers fail. In order not to
+ * break such machines we will only mask pins from irqdomain if the machine
+ * is not listed below.
+ */
+static const struct dmi_system_id chv_no_valid_mask[] = {
+	/* See https://bugzilla.kernel.org/show_bug.cgi?id=194945 */
+	{
+		.ident = "Intel_Strago based Chromebooks (All models)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
+			DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_Strago"),
+			DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
+		},
+	},
+	{
+		.ident = "HP Chromebook 11 G5 (Setzer)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"),
+			DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
+		},
+	},
+	{
+		.ident = "Acer Chromebook R11 (Cyan)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Cyan"),
+			DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
+		},
+	},
+	{
+		.ident = "Samsung Chromebook 3 (Celes)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Celes"),
+			DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
+		},
+	},
+	{}
+};
+
+static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
+{
+	const struct chv_gpio_pinrange *range;
+	struct gpio_chip *chip = &pctrl->chip;
+	bool need_valid_mask = !dmi_check_system(chv_no_valid_mask);
+	const struct chv_community *community = pctrl->community;
+	int ret, i, irq_base;
+
+	*chip = chv_gpio_chip;
+
+	chip->ngpio = community->pins[community->npins - 1].number + 1;
+	chip->label = dev_name(pctrl->dev);
+	chip->parent = pctrl->dev;
+	chip->base = -1;
+	chip->irq.need_valid_mask = need_valid_mask;
+
+	ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl);
+	if (ret) {
+		dev_err(pctrl->dev, "Failed to register gpiochip\n");
+		return ret;
+	}
+
+	for (i = 0; i < community->ngpio_ranges; i++) {
+		range = &community->gpio_ranges[i];
+		ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev),
+					     range->base, range->base,
+					     range->npins);
+		if (ret) {
+			dev_err(pctrl->dev, "failed to add GPIO pin range\n");
+			return ret;
+		}
+	}
+
+	/* Do not add GPIOs that can only generate GPEs to the IRQ domain */
+	for (i = 0; i < community->npins; i++) {
+		const struct pinctrl_pin_desc *desc;
+		u32 intsel;
+
+		desc = &community->pins[i];
+
+		intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0));
+		intsel &= CHV_PADCTRL0_INTSEL_MASK;
+		intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
+
+		if (need_valid_mask && intsel >= community->nirqs)
+			clear_bit(i, chip->irq.valid_mask);
+	}
+
+	/*
+	 * The same set of machines in chv_no_valid_mask[] have incorrectly
+	 * configured GPIOs that generate spurious interrupts so we use
+	 * this same list to apply another quirk for them.
+	 *
+	 * See also https://bugzilla.kernel.org/show_bug.cgi?id=197953.
+	 */
+	if (!need_valid_mask) {
+		/*
+		 * Mask all interrupts the community is able to generate
+		 * but leave the ones that can only generate GPEs unmasked.
+		 */
+		chv_writel(GENMASK(31, pctrl->community->nirqs),
+			   pctrl->regs + CHV_INTMASK);
+	}
+
+	/* Clear all interrupts */
+	chv_writel(0xffff, pctrl->regs + CHV_INTSTAT);
+
+	if (!need_valid_mask) {
+		irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0,
+						community->npins, NUMA_NO_NODE);
+		if (irq_base < 0) {
+			dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n");
+			return irq_base;
+		}
+	}
+
+	ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, 0,
+				   handle_bad_irq, IRQ_TYPE_NONE);
+	if (ret) {
+		dev_err(pctrl->dev, "failed to add IRQ chip\n");
+		return ret;
+	}
+
+	if (!need_valid_mask) {
+		for (i = 0; i < community->ngpio_ranges; i++) {
+			range = &community->gpio_ranges[i];
+
+			irq_domain_associate_many(chip->irq.domain, irq_base,
+						  range->base, range->npins);
+			irq_base += range->npins;
+		}
+	}
+
+	gpiochip_set_chained_irqchip(chip, &chv_gpio_irqchip, irq,
+				     chv_gpio_irq_handler);
+	return 0;
+}
+
+static acpi_status chv_pinctrl_mmio_access_handler(u32 function,
+	acpi_physical_address address, u32 bits, u64 *value,
+	void *handler_context, void *region_context)
+{
+	struct chv_pinctrl *pctrl = region_context;
+	unsigned long flags;
+	acpi_status ret = AE_OK;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+
+	if (function == ACPI_WRITE)
+		chv_writel((u32)(*value), pctrl->regs + (u32)address);
+	else if (function == ACPI_READ)
+		*value = readl(pctrl->regs + (u32)address);
+	else
+		ret = AE_BAD_PARAMETER;
+
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	return ret;
+}
+
+static int chv_pinctrl_probe(struct platform_device *pdev)
+{
+	struct chv_pinctrl *pctrl;
+	struct acpi_device *adev;
+	struct resource *res;
+	acpi_status status;
+	int ret, irq, i;
+
+	adev = ACPI_COMPANION(&pdev->dev);
+	if (!adev)
+		return -ENODEV;
+
+	pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
+	if (!pctrl)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(chv_communities); i++)
+		if (!strcmp(adev->pnp.unique_id, chv_communities[i]->uid)) {
+			pctrl->community = chv_communities[i];
+			break;
+		}
+	if (i == ARRAY_SIZE(chv_communities))
+		return -ENODEV;
+
+	pctrl->dev = &pdev->dev;
+
+#ifdef CONFIG_PM_SLEEP
+	pctrl->saved_pin_context = devm_kcalloc(pctrl->dev,
+		pctrl->community->npins, sizeof(*pctrl->saved_pin_context),
+		GFP_KERNEL);
+	if (!pctrl->saved_pin_context)
+		return -ENOMEM;
+#endif
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	pctrl->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pctrl->regs))
+		return PTR_ERR(pctrl->regs);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get interrupt number\n");
+		return irq;
+	}
+
+	pctrl->pctldesc = chv_pinctrl_desc;
+	pctrl->pctldesc.name = dev_name(&pdev->dev);
+	pctrl->pctldesc.pins = pctrl->community->pins;
+	pctrl->pctldesc.npins = pctrl->community->npins;
+
+	pctrl->pctldev = devm_pinctrl_register(&pdev->dev, &pctrl->pctldesc,
+					       pctrl);
+	if (IS_ERR(pctrl->pctldev)) {
+		dev_err(&pdev->dev, "failed to register pinctrl driver\n");
+		return PTR_ERR(pctrl->pctldev);
+	}
+
+	ret = chv_gpio_probe(pctrl, irq);
+	if (ret)
+		return ret;
+
+	status = acpi_install_address_space_handler(adev->handle,
+					pctrl->community->acpi_space_id,
+					chv_pinctrl_mmio_access_handler,
+					NULL, pctrl);
+	if (ACPI_FAILURE(status))
+		dev_err(&pdev->dev, "failed to install ACPI addr space handler\n");
+
+	platform_set_drvdata(pdev, pctrl);
+
+	return 0;
+}
+
+static int chv_pinctrl_remove(struct platform_device *pdev)
+{
+	struct chv_pinctrl *pctrl = platform_get_drvdata(pdev);
+
+	acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev),
+					  pctrl->community->acpi_space_id,
+					  chv_pinctrl_mmio_access_handler);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int chv_pinctrl_suspend_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct chv_pinctrl *pctrl = platform_get_drvdata(pdev);
+	unsigned long flags;
+	int i;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+
+	pctrl->saved_intmask = readl(pctrl->regs + CHV_INTMASK);
+
+	for (i = 0; i < pctrl->community->npins; i++) {
+		const struct pinctrl_pin_desc *desc;
+		struct chv_pin_context *ctx;
+		void __iomem *reg;
+
+		desc = &pctrl->community->pins[i];
+		if (chv_pad_locked(pctrl, desc->number))
+			continue;
+
+		ctx = &pctrl->saved_pin_context[i];
+
+		reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL0);
+		ctx->padctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIORXSTATE;
+
+		reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL1);
+		ctx->padctrl1 = readl(reg);
+	}
+
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	return 0;
+}
+
+static int chv_pinctrl_resume_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct chv_pinctrl *pctrl = platform_get_drvdata(pdev);
+	unsigned long flags;
+	int i;
+
+	raw_spin_lock_irqsave(&chv_lock, flags);
+
+	/*
+	 * Mask all interrupts before restoring per-pin configuration
+	 * registers because we don't know in which state BIOS left them
+	 * upon exiting suspend.
+	 */
+	chv_writel(0, pctrl->regs + CHV_INTMASK);
+
+	for (i = 0; i < pctrl->community->npins; i++) {
+		const struct pinctrl_pin_desc *desc;
+		const struct chv_pin_context *ctx;
+		void __iomem *reg;
+		u32 val;
+
+		desc = &pctrl->community->pins[i];
+		if (chv_pad_locked(pctrl, desc->number))
+			continue;
+
+		ctx = &pctrl->saved_pin_context[i];
+
+		/* Only restore if our saved state differs from the current */
+		reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL0);
+		val = readl(reg) & ~CHV_PADCTRL0_GPIORXSTATE;
+		if (ctx->padctrl0 != val) {
+			chv_writel(ctx->padctrl0, reg);
+			dev_dbg(pctrl->dev, "restored pin %2u ctrl0 0x%08x\n",
+				desc->number, readl(reg));
+		}
+
+		reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL1);
+		val = readl(reg);
+		if (ctx->padctrl1 != val) {
+			chv_writel(ctx->padctrl1, reg);
+			dev_dbg(pctrl->dev, "restored pin %2u ctrl1 0x%08x\n",
+				desc->number, readl(reg));
+		}
+	}
+
+	/*
+	 * Now that all pins are restored to known state, we can restore
+	 * the interrupt mask register as well.
+	 */
+	chv_writel(0xffff, pctrl->regs + CHV_INTSTAT);
+	chv_writel(pctrl->saved_intmask, pctrl->regs + CHV_INTMASK);
+
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops chv_pinctrl_pm_ops = {
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(chv_pinctrl_suspend_noirq,
+				      chv_pinctrl_resume_noirq)
+};
+
+static const struct acpi_device_id chv_pinctrl_acpi_match[] = {
+	{ "INT33FF" },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match);
+
+static struct platform_driver chv_pinctrl_driver = {
+	.probe = chv_pinctrl_probe,
+	.remove = chv_pinctrl_remove,
+	.driver = {
+		.name = "cherryview-pinctrl",
+		.pm = &chv_pinctrl_pm_ops,
+		.acpi_match_table = chv_pinctrl_acpi_match,
+	},
+};
+
+static int __init chv_pinctrl_init(void)
+{
+	return platform_driver_register(&chv_pinctrl_driver);
+}
+subsys_initcall(chv_pinctrl_init);
+
+static void __exit chv_pinctrl_exit(void)
+{
+	platform_driver_unregister(&chv_pinctrl_driver);
+}
+module_exit(chv_pinctrl_exit);
+
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+MODULE_DESCRIPTION("Intel Cherryview/Braswell pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/intel/pinctrl-denverton.c b/drivers/pinctrl/intel/pinctrl-denverton.c
new file mode 100644
index 0000000..f321ab0
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-denverton.c
@@ -0,0 +1,299 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Denverton SoC pinctrl/GPIO driver
+ *
+ * Copyright (C) 2017, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-intel.h"
+
+#define DNV_PAD_OWN	0x020
+#define DNV_HOSTSW_OWN	0x0C0
+#define DNV_PADCFGLOCK	0x090
+#define DNV_GPI_IE	0x120
+
+#define DNV_GPP(n, s, e)				\
+	{						\
+		.reg_num = (n),				\
+		.base = (s),				\
+		.size = ((e) - (s) + 1),		\
+	}
+
+#define DNV_COMMUNITY(b, s, e, g)			\
+	{						\
+		.barno = (b),				\
+		.padown_offset = DNV_PAD_OWN,		\
+		.padcfglock_offset = DNV_PADCFGLOCK,	\
+		.hostown_offset = DNV_HOSTSW_OWN,	\
+		.ie_offset = DNV_GPI_IE,		\
+		.pin_base = (s),			\
+		.npins = ((e) - (s) + 1),		\
+		.gpps = (g),				\
+		.ngpps = ARRAY_SIZE(g),			\
+	}
+
+static const struct pinctrl_pin_desc dnv_pins[] = {
+	/* North ALL */
+	PINCTRL_PIN(0, "GBE0_SDP0"),
+	PINCTRL_PIN(1, "GBE1_SDP0"),
+	PINCTRL_PIN(2, "GBE0_SDP1"),
+	PINCTRL_PIN(3, "GBE1_SDP1"),
+	PINCTRL_PIN(4, "GBE0_SDP2"),
+	PINCTRL_PIN(5, "GBE1_SDP2"),
+	PINCTRL_PIN(6, "GBE0_SDP3"),
+	PINCTRL_PIN(7, "GBE1_SDP3"),
+	PINCTRL_PIN(8, "GBE2_LED0"),
+	PINCTRL_PIN(9, "GBE2_LED1"),
+	PINCTRL_PIN(10, "GBE0_I2C_CLK"),
+	PINCTRL_PIN(11, "GBE0_I2C_DATA"),
+	PINCTRL_PIN(12, "GBE1_I2C_CLK"),
+	PINCTRL_PIN(13, "GBE1_I2C_DATA"),
+	PINCTRL_PIN(14, "NCSI_RXD0"),
+	PINCTRL_PIN(15, "NCSI_CLK_IN"),
+	PINCTRL_PIN(16, "NCSI_RXD1"),
+	PINCTRL_PIN(17, "NCSI_CRS_DV"),
+	PINCTRL_PIN(18, "NCSI_ARB_IN"),
+	PINCTRL_PIN(19, "NCSI_TX_EN"),
+	PINCTRL_PIN(20, "NCSI_TXD0"),
+	PINCTRL_PIN(21, "NCSI_TXD1"),
+	PINCTRL_PIN(22, "NCSI_ARB_OUT"),
+	PINCTRL_PIN(23, "GBE0_LED0"),
+	PINCTRL_PIN(24, "GBE0_LED1"),
+	PINCTRL_PIN(25, "GBE1_LED0"),
+	PINCTRL_PIN(26, "GBE1_LED1"),
+	PINCTRL_PIN(27, "GPIO_0"),
+	PINCTRL_PIN(28, "PCIE_CLKREQ0_N"),
+	PINCTRL_PIN(29, "PCIE_CLKREQ1_N"),
+	PINCTRL_PIN(30, "PCIE_CLKREQ2_N"),
+	PINCTRL_PIN(31, "PCIE_CLKREQ3_N"),
+	PINCTRL_PIN(32, "PCIE_CLKREQ4_N"),
+	PINCTRL_PIN(33, "GPIO_1"),
+	PINCTRL_PIN(34, "GPIO_2"),
+	PINCTRL_PIN(35, "SVID_ALERT_N"),
+	PINCTRL_PIN(36, "SVID_DATA"),
+	PINCTRL_PIN(37, "SVID_CLK"),
+	PINCTRL_PIN(38, "THERMTRIP_N"),
+	PINCTRL_PIN(39, "PROCHOT_N"),
+	PINCTRL_PIN(40, "MEMHOT_N"),
+	/* South DFX */
+	PINCTRL_PIN(41, "DFX_PORT_CLK0"),
+	PINCTRL_PIN(42, "DFX_PORT_CLK1"),
+	PINCTRL_PIN(43, "DFX_PORT0"),
+	PINCTRL_PIN(44, "DFX_PORT1"),
+	PINCTRL_PIN(45, "DFX_PORT2"),
+	PINCTRL_PIN(46, "DFX_PORT3"),
+	PINCTRL_PIN(47, "DFX_PORT4"),
+	PINCTRL_PIN(48, "DFX_PORT5"),
+	PINCTRL_PIN(49, "DFX_PORT6"),
+	PINCTRL_PIN(50, "DFX_PORT7"),
+	PINCTRL_PIN(51, "DFX_PORT8"),
+	PINCTRL_PIN(52, "DFX_PORT9"),
+	PINCTRL_PIN(53, "DFX_PORT10"),
+	PINCTRL_PIN(54, "DFX_PORT11"),
+	PINCTRL_PIN(55, "DFX_PORT12"),
+	PINCTRL_PIN(56, "DFX_PORT13"),
+	PINCTRL_PIN(57, "DFX_PORT14"),
+	PINCTRL_PIN(58, "DFX_PORT15"),
+	/* South GPP0 */
+	PINCTRL_PIN(59, "GPIO_12"),
+	PINCTRL_PIN(60, "SMB5_GBE_ALRT_N"),
+	PINCTRL_PIN(61, "PCIE_CLKREQ5_N"),
+	PINCTRL_PIN(62, "PCIE_CLKREQ6_N"),
+	PINCTRL_PIN(63, "PCIE_CLKREQ7_N"),
+	PINCTRL_PIN(64, "UART0_RXD"),
+	PINCTRL_PIN(65, "UART0_TXD"),
+	PINCTRL_PIN(66, "SMB5_GBE_CLK"),
+	PINCTRL_PIN(67, "SMB5_GBE_DATA"),
+	PINCTRL_PIN(68, "ERROR2_N"),
+	PINCTRL_PIN(69, "ERROR1_N"),
+	PINCTRL_PIN(70, "ERROR0_N"),
+	PINCTRL_PIN(71, "IERR_N"),
+	PINCTRL_PIN(72, "MCERR_N"),
+	PINCTRL_PIN(73, "SMB0_LEG_CLK"),
+	PINCTRL_PIN(74, "SMB0_LEG_DATA"),
+	PINCTRL_PIN(75, "SMB0_LEG_ALRT_N"),
+	PINCTRL_PIN(76, "SMB1_HOST_DATA"),
+	PINCTRL_PIN(77, "SMB1_HOST_CLK"),
+	PINCTRL_PIN(78, "SMB2_PECI_DATA"),
+	PINCTRL_PIN(79, "SMB2_PECI_CLK"),
+	PINCTRL_PIN(80, "SMB4_CSME0_DATA"),
+	PINCTRL_PIN(81, "SMB4_CSME0_CLK"),
+	PINCTRL_PIN(82, "SMB4_CSME0_ALRT_N"),
+	PINCTRL_PIN(83, "USB_OC0_N"),
+	PINCTRL_PIN(84, "FLEX_CLK_SE0"),
+	PINCTRL_PIN(85, "FLEX_CLK_SE1"),
+	PINCTRL_PIN(86, "GPIO_4"),
+	PINCTRL_PIN(87, "GPIO_5"),
+	PINCTRL_PIN(88, "GPIO_6"),
+	PINCTRL_PIN(89, "GPIO_7"),
+	PINCTRL_PIN(90, "SATA0_LED_N"),
+	PINCTRL_PIN(91, "SATA1_LED_N"),
+	PINCTRL_PIN(92, "SATA_PDETECT0"),
+	PINCTRL_PIN(93, "SATA_PDETECT1"),
+	PINCTRL_PIN(94, "SATA0_SDOUT"),
+	PINCTRL_PIN(95, "SATA1_SDOUT"),
+	PINCTRL_PIN(96, "UART1_RXD"),
+	PINCTRL_PIN(97, "UART1_TXD"),
+	PINCTRL_PIN(98, "GPIO_8"),
+	PINCTRL_PIN(99, "GPIO_9"),
+	PINCTRL_PIN(100, "TCK"),
+	PINCTRL_PIN(101, "TRST_N"),
+	PINCTRL_PIN(102, "TMS"),
+	PINCTRL_PIN(103, "TDI"),
+	PINCTRL_PIN(104, "TDO"),
+	PINCTRL_PIN(105, "CX_PRDY_N"),
+	PINCTRL_PIN(106, "CX_PREQ_N"),
+	PINCTRL_PIN(107, "CTBTRIGINOUT"),
+	PINCTRL_PIN(108, "CTBTRIGOUT"),
+	PINCTRL_PIN(109, "DFX_SPARE2"),
+	PINCTRL_PIN(110, "DFX_SPARE3"),
+	PINCTRL_PIN(111, "DFX_SPARE4"),
+	/* South GPP1 */
+	PINCTRL_PIN(112, "SUSPWRDNACK"),
+	PINCTRL_PIN(113, "PMU_SUSCLK"),
+	PINCTRL_PIN(114, "ADR_TRIGGER"),
+	PINCTRL_PIN(115, "PMU_SLP_S45_N"),
+	PINCTRL_PIN(116, "PMU_SLP_S3_N"),
+	PINCTRL_PIN(117, "PMU_WAKE_N"),
+	PINCTRL_PIN(118, "PMU_PWRBTN_N"),
+	PINCTRL_PIN(119, "PMU_RESETBUTTON_N"),
+	PINCTRL_PIN(120, "PMU_PLTRST_N"),
+	PINCTRL_PIN(121, "SUS_STAT_N"),
+	PINCTRL_PIN(122, "SLP_S0IX_N"),
+	PINCTRL_PIN(123, "SPI_CS0_N"),
+	PINCTRL_PIN(124, "SPI_CS1_N"),
+	PINCTRL_PIN(125, "SPI_MOSI_IO0"),
+	PINCTRL_PIN(126, "SPI_MISO_IO1"),
+	PINCTRL_PIN(127, "SPI_IO2"),
+	PINCTRL_PIN(128, "SPI_IO3"),
+	PINCTRL_PIN(129, "SPI_CLK"),
+	PINCTRL_PIN(130, "SPI_CLK_LOOPBK"),
+	PINCTRL_PIN(131, "ESPI_IO0"),
+	PINCTRL_PIN(132, "ESPI_IO1"),
+	PINCTRL_PIN(133, "ESPI_IO2"),
+	PINCTRL_PIN(134, "ESPI_IO3"),
+	PINCTRL_PIN(135, "ESPI_CS0_N"),
+	PINCTRL_PIN(136, "ESPI_CLK"),
+	PINCTRL_PIN(137, "ESPI_RST_N"),
+	PINCTRL_PIN(138, "ESPI_ALRT0_N"),
+	PINCTRL_PIN(139, "GPIO_10"),
+	PINCTRL_PIN(140, "GPIO_11"),
+	PINCTRL_PIN(141, "ESPI_CLK_LOOPBK"),
+	PINCTRL_PIN(142, "EMMC_CMD"),
+	PINCTRL_PIN(143, "EMMC_STROBE"),
+	PINCTRL_PIN(144, "EMMC_CLK"),
+	PINCTRL_PIN(145, "EMMC_D0"),
+	PINCTRL_PIN(146, "EMMC_D1"),
+	PINCTRL_PIN(147, "EMMC_D2"),
+	PINCTRL_PIN(148, "EMMC_D3"),
+	PINCTRL_PIN(149, "EMMC_D4"),
+	PINCTRL_PIN(150, "EMMC_D5"),
+	PINCTRL_PIN(151, "EMMC_D6"),
+	PINCTRL_PIN(152, "EMMC_D7"),
+	PINCTRL_PIN(153, "GPIO_3"),
+};
+
+static const unsigned int dnv_uart0_pins[] = { 60, 61, 64, 65 };
+static const unsigned int dnv_uart0_modes[] = { 2, 3, 1, 1 };
+static const unsigned int dnv_uart1_pins[] = { 94, 95, 96, 97 };
+static const unsigned int dnv_uart2_pins[] = { 60, 61, 62, 63 };
+static const unsigned int dnv_uart2_modes[] = { 1, 2, 2, 2 };
+static const unsigned int dnv_emmc_pins[] = {
+	142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
+};
+
+static const struct intel_pingroup dnv_groups[] = {
+	PIN_GROUP("uart0_grp", dnv_uart0_pins, dnv_uart0_modes),
+	PIN_GROUP("uart1_grp", dnv_uart1_pins, 1),
+	PIN_GROUP("uart2_grp", dnv_uart2_pins, dnv_uart2_modes),
+	PIN_GROUP("emmc_grp", dnv_emmc_pins, 1),
+};
+
+static const char * const dnv_uart0_groups[] = { "uart0_grp" };
+static const char * const dnv_uart1_groups[] = { "uart1_grp" };
+static const char * const dnv_uart2_groups[] = { "uart2_grp" };
+static const char * const dnv_emmc_groups[] = { "emmc_grp" };
+
+static const struct intel_function dnv_functions[] = {
+	FUNCTION("uart0", dnv_uart0_groups),
+	FUNCTION("uart1", dnv_uart1_groups),
+	FUNCTION("uart2", dnv_uart2_groups),
+	FUNCTION("emmc", dnv_emmc_groups),
+};
+
+static const struct intel_padgroup dnv_north_gpps[] = {
+	DNV_GPP(0, 0, 31),	/* North ALL_0 */
+	DNV_GPP(1, 32, 40),	/* North ALL_1 */
+};
+
+static const struct intel_padgroup dnv_south_gpps[] = {
+	DNV_GPP(0, 41, 58),	/* South DFX */
+	DNV_GPP(1, 59, 90),	/* South GPP0_0 */
+	DNV_GPP(2, 91, 111),	/* South GPP0_1 */
+	DNV_GPP(3, 112, 143),	/* South GPP1_0 */
+	DNV_GPP(4, 144, 153),	/* South GPP1_1 */
+};
+
+static const struct intel_community dnv_communities[] = {
+	DNV_COMMUNITY(0, 0, 40, dnv_north_gpps),
+	DNV_COMMUNITY(1, 41, 153, dnv_south_gpps),
+};
+
+static const struct intel_pinctrl_soc_data dnv_soc_data = {
+	.pins = dnv_pins,
+	.npins = ARRAY_SIZE(dnv_pins),
+	.groups = dnv_groups,
+	.ngroups = ARRAY_SIZE(dnv_groups),
+	.functions = dnv_functions,
+	.nfunctions = ARRAY_SIZE(dnv_functions),
+	.communities = dnv_communities,
+	.ncommunities = ARRAY_SIZE(dnv_communities),
+};
+
+static int dnv_pinctrl_probe(struct platform_device *pdev)
+{
+	return intel_pinctrl_probe(pdev, &dnv_soc_data);
+}
+
+static const struct dev_pm_ops dnv_pinctrl_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
+				     intel_pinctrl_resume)
+};
+
+static const struct acpi_device_id dnv_pinctrl_acpi_match[] = {
+	{ "INTC3000" },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, dnv_pinctrl_acpi_match);
+
+static struct platform_driver dnv_pinctrl_driver = {
+	.probe = dnv_pinctrl_probe,
+	.driver = {
+		.name = "denverton-pinctrl",
+		.acpi_match_table = dnv_pinctrl_acpi_match,
+		.pm = &dnv_pinctrl_pm_ops,
+	},
+};
+
+static int __init dnv_pinctrl_init(void)
+{
+	return platform_driver_register(&dnv_pinctrl_driver);
+}
+subsys_initcall(dnv_pinctrl_init);
+
+static void __exit dnv_pinctrl_exit(void)
+{
+	platform_driver_unregister(&dnv_pinctrl_driver);
+}
+module_exit(dnv_pinctrl_exit);
+
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+MODULE_DESCRIPTION("Intel Denverton SoC pinctrl/GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/intel/pinctrl-geminilake.c b/drivers/pinctrl/intel/pinctrl-geminilake.c
new file mode 100644
index 0000000..5c4c967
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-geminilake.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Gemini Lake SoC pinctrl/GPIO driver
+ *
+ * Copyright (C) 2017 Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-intel.h"
+
+#define GLK_PAD_OWN	0x020
+#define GLK_HOSTSW_OWN	0x0b0
+#define GLK_PADCFGLOCK	0x080
+#define GLK_GPI_IE	0x110
+
+#define GLK_COMMUNITY(s, e)				\
+	{						\
+		.padown_offset = GLK_PAD_OWN,		\
+		.padcfglock_offset = GLK_PADCFGLOCK,	\
+		.hostown_offset = GLK_HOSTSW_OWN,	\
+		.ie_offset = GLK_GPI_IE,		\
+		.gpp_size = 32,                         \
+		.pin_base = (s),			\
+		.npins = ((e) - (s) + 1),		\
+	}
+
+/* GLK */
+static const struct pinctrl_pin_desc glk_northwest_pins[] = {
+	PINCTRL_PIN(0, "TCK"),
+	PINCTRL_PIN(1, "TRST_B"),
+	PINCTRL_PIN(2, "TMS"),
+	PINCTRL_PIN(3, "TDI"),
+	PINCTRL_PIN(4, "TDO"),
+	PINCTRL_PIN(5, "JTAGX"),
+	PINCTRL_PIN(6, "CX_PREQ_B"),
+	PINCTRL_PIN(7, "CX_PRDY_B"),
+	PINCTRL_PIN(8, "GPIO_8"),
+	PINCTRL_PIN(9, "GPIO_9"),
+	PINCTRL_PIN(10, "GPIO_10"),
+	PINCTRL_PIN(11, "GPIO_11"),
+	PINCTRL_PIN(12, "GPIO_12"),
+	PINCTRL_PIN(13, "GPIO_13"),
+	PINCTRL_PIN(14, "GPIO_14"),
+	PINCTRL_PIN(15, "GPIO_15"),
+	PINCTRL_PIN(16, "GPIO_16"),
+	PINCTRL_PIN(17, "GPIO_17"),
+	PINCTRL_PIN(18, "GPIO_18"),
+	PINCTRL_PIN(19, "GPIO_19"),
+	PINCTRL_PIN(20, "GPIO_20"),
+	PINCTRL_PIN(21, "GPIO_21"),
+	PINCTRL_PIN(22, "GPIO_22"),
+	PINCTRL_PIN(23, "GPIO_23"),
+	PINCTRL_PIN(24, "GPIO_24"),
+	PINCTRL_PIN(25, "GPIO_25"),
+	PINCTRL_PIN(26, "GPIO_26"),
+	PINCTRL_PIN(27, "GPIO_27"),
+	PINCTRL_PIN(28, "GPIO_28"),
+	PINCTRL_PIN(29, "GPIO_29"),
+	PINCTRL_PIN(30, "GPIO_30"),
+	PINCTRL_PIN(31, "GPIO_31"),
+	PINCTRL_PIN(32, "GPIO_32"),
+	PINCTRL_PIN(33, "GPIO_33"),
+	PINCTRL_PIN(34, "GPIO_34"),
+	PINCTRL_PIN(35, "GPIO_35"),
+	PINCTRL_PIN(36, "GPIO_36"),
+	PINCTRL_PIN(37, "GPIO_37"),
+	PINCTRL_PIN(38, "GPIO_38"),
+	PINCTRL_PIN(39, "GPIO_39"),
+	PINCTRL_PIN(40, "GPIO_40"),
+	PINCTRL_PIN(41, "GPIO_41"),
+	PINCTRL_PIN(42, "GP_INTD_DSI_TE1"),
+	PINCTRL_PIN(43, "GP_INTD_DSI_TE2"),
+	PINCTRL_PIN(44, "USB_OC0_B"),
+	PINCTRL_PIN(45, "USB_OC1_B"),
+	PINCTRL_PIN(46, "DSI_I2C_SDA"),
+	PINCTRL_PIN(47, "DSI_I2C_SCL"),
+	PINCTRL_PIN(48, "PMC_I2C_SDA"),
+	PINCTRL_PIN(49, "PMC_I2C_SCL"),
+	PINCTRL_PIN(50, "LPSS_I2C0_SDA"),
+	PINCTRL_PIN(51, "LPSS_I2C0_SCL"),
+	PINCTRL_PIN(52, "LPSS_I2C1_SDA"),
+	PINCTRL_PIN(53, "LPSS_I2C1_SCL"),
+	PINCTRL_PIN(54, "LPSS_I2C2_SDA"),
+	PINCTRL_PIN(55, "LPSS_I2C2_SCL"),
+	PINCTRL_PIN(56, "LPSS_I2C3_SDA"),
+	PINCTRL_PIN(57, "LPSS_I2C3_SCL"),
+	PINCTRL_PIN(58, "LPSS_I2C4_SDA"),
+	PINCTRL_PIN(59, "LPSS_I2C4_SCL"),
+	PINCTRL_PIN(60, "LPSS_UART0_RXD"),
+	PINCTRL_PIN(61, "LPSS_UART0_TXD"),
+	PINCTRL_PIN(62, "LPSS_UART0_RTS_B"),
+	PINCTRL_PIN(63, "LPSS_UART0_CTS_B"),
+	PINCTRL_PIN(64, "LPSS_UART2_RXD"),
+	PINCTRL_PIN(65, "LPSS_UART2_TXD"),
+	PINCTRL_PIN(66, "LPSS_UART2_RTS_B"),
+	PINCTRL_PIN(67, "LPSS_UART2_CTS_B"),
+	PINCTRL_PIN(68, "PMC_SPI_FS0"),
+	PINCTRL_PIN(69, "PMC_SPI_FS1"),
+	PINCTRL_PIN(70, "PMC_SPI_FS2"),
+	PINCTRL_PIN(71, "PMC_SPI_RXD"),
+	PINCTRL_PIN(72, "PMC_SPI_TXD"),
+	PINCTRL_PIN(73, "PMC_SPI_CLK"),
+	PINCTRL_PIN(74, "THERMTRIP_B"),
+	PINCTRL_PIN(75, "PROCHOT_B"),
+	PINCTRL_PIN(76, "EMMC_RST_B"),
+	PINCTRL_PIN(77, "GPIO_212"),
+	PINCTRL_PIN(78, "GPIO_213"),
+	PINCTRL_PIN(79, "GPIO_214"),
+};
+
+static const unsigned int glk_northwest_uart1_pins[] = { 26, 27, 28, 29 };
+static const unsigned int glk_northwest_pwm0_pins[] = { 42 };
+static const unsigned int glk_northwest_pwm1_pins[] = { 43 };
+static const unsigned int glk_northwest_pwm2_pins[] = { 44 };
+static const unsigned int glk_northwest_pwm3_pins[] = { 45 };
+static const unsigned int glk_northwest_i2c0_pins[] = { 50, 51 };
+static const unsigned int glk_northwest_i2c1_pins[] = { 52, 53 };
+static const unsigned int glk_northwest_i2c2_pins[] = { 54, 55 };
+static const unsigned int glk_northwest_i2c3_pins[] = { 56, 57 };
+static const unsigned int glk_northwest_i2c4_pins[] = { 58, 59 };
+static const unsigned int glk_northwest_uart0_pins[] = { 60, 61, 62, 63 };
+static const unsigned int glk_northwest_uart2_pins[] = { 64, 65, 66, 67 };
+
+static const struct intel_pingroup glk_northwest_groups[] = {
+	PIN_GROUP("uart1_grp", glk_northwest_uart1_pins, 2),
+	PIN_GROUP("pwm0_grp", glk_northwest_pwm0_pins, 2),
+	PIN_GROUP("pwm1_grp", glk_northwest_pwm1_pins, 2),
+	PIN_GROUP("pwm2_grp", glk_northwest_pwm2_pins, 2),
+	PIN_GROUP("pwm3_grp", glk_northwest_pwm3_pins, 2),
+	PIN_GROUP("i2c0_grp", glk_northwest_i2c0_pins, 1),
+	PIN_GROUP("i2c1_grp", glk_northwest_i2c1_pins, 1),
+	PIN_GROUP("i2c2_grp", glk_northwest_i2c2_pins, 1),
+	PIN_GROUP("i2c3_grp", glk_northwest_i2c3_pins, 1),
+	PIN_GROUP("i2c4_grp", glk_northwest_i2c4_pins, 1),
+	PIN_GROUP("uart0_grp", glk_northwest_uart0_pins, 1),
+	PIN_GROUP("uart2_grp", glk_northwest_uart2_pins, 1),
+};
+
+static const char * const glk_northwest_uart1_groups[] = { "uart1_grp" };
+static const char * const glk_northwest_pwm0_groups[] = { "pwm0_grp" };
+static const char * const glk_northwest_pwm1_groups[] = { "pwm1_grp" };
+static const char * const glk_northwest_pwm2_groups[] = { "pwm2_grp" };
+static const char * const glk_northwest_pwm3_groups[] = { "pwm3_grp" };
+static const char * const glk_northwest_i2c0_groups[] = { "i2c0_grp" };
+static const char * const glk_northwest_i2c1_groups[] = { "i2c1_grp" };
+static const char * const glk_northwest_i2c2_groups[] = { "i2c2_grp" };
+static const char * const glk_northwest_i2c3_groups[] = { "i2c3_grp" };
+static const char * const glk_northwest_i2c4_groups[] = { "i2c4_grp" };
+static const char * const glk_northwest_uart0_groups[] = { "uart0_grp" };
+static const char * const glk_northwest_uart2_groups[] = { "uart2_grp" };
+
+static const struct intel_function glk_northwest_functions[] = {
+	FUNCTION("uart1", glk_northwest_uart1_groups),
+	FUNCTION("pmw0", glk_northwest_pwm0_groups),
+	FUNCTION("pmw1", glk_northwest_pwm1_groups),
+	FUNCTION("pmw2", glk_northwest_pwm2_groups),
+	FUNCTION("pmw3", glk_northwest_pwm3_groups),
+	FUNCTION("i2c0", glk_northwest_i2c0_groups),
+	FUNCTION("i2c1", glk_northwest_i2c1_groups),
+	FUNCTION("i2c2", glk_northwest_i2c2_groups),
+	FUNCTION("i2c3", glk_northwest_i2c3_groups),
+	FUNCTION("i2c4", glk_northwest_i2c4_groups),
+	FUNCTION("uart0", glk_northwest_uart0_groups),
+	FUNCTION("uart2", glk_northwest_uart2_groups),
+};
+
+static const struct intel_community glk_northwest_communities[] = {
+	GLK_COMMUNITY(0, 79),
+};
+
+static const struct intel_pinctrl_soc_data glk_northwest_soc_data = {
+	.uid = "1",
+	.pins = glk_northwest_pins,
+	.npins = ARRAY_SIZE(glk_northwest_pins),
+	.groups = glk_northwest_groups,
+	.ngroups = ARRAY_SIZE(glk_northwest_groups),
+	.functions = glk_northwest_functions,
+	.nfunctions = ARRAY_SIZE(glk_northwest_functions),
+	.communities = glk_northwest_communities,
+	.ncommunities = ARRAY_SIZE(glk_northwest_communities),
+};
+
+static const struct pinctrl_pin_desc glk_north_pins[] = {
+	PINCTRL_PIN(0, "SVID0_ALERT_B"),
+	PINCTRL_PIN(1, "SVID0_DATA"),
+	PINCTRL_PIN(2, "SVID0_CLK"),
+	PINCTRL_PIN(3, "LPSS_SPI_0_CLK"),
+	PINCTRL_PIN(4, "LPSS_SPI_0_FS0"),
+	PINCTRL_PIN(5, "LPSS_SPI_0_FS1"),
+	PINCTRL_PIN(6, "LPSS_SPI_0_RXD"),
+	PINCTRL_PIN(7, "LPSS_SPI_0_TXD"),
+	PINCTRL_PIN(8, "LPSS_SPI_1_CLK"),
+	PINCTRL_PIN(9, "LPSS_SPI_1_FS0"),
+	PINCTRL_PIN(10, "LPSS_SPI_1_FS1"),
+	PINCTRL_PIN(11, "LPSS_SPI_1_FS2"),
+	PINCTRL_PIN(12, "LPSS_SPI_1_RXD"),
+	PINCTRL_PIN(13, "LPSS_SPI_1_TXD"),
+	PINCTRL_PIN(14, "FST_SPI_CS0_B"),
+	PINCTRL_PIN(15, "FST_SPI_CS1_B"),
+	PINCTRL_PIN(16, "FST_SPI_MOSI_IO0"),
+	PINCTRL_PIN(17, "FST_SPI_MISO_IO1"),
+	PINCTRL_PIN(18, "FST_SPI_IO2"),
+	PINCTRL_PIN(19, "FST_SPI_IO3"),
+	PINCTRL_PIN(20, "FST_SPI_CLK"),
+	PINCTRL_PIN(21, "FST_SPI_CLK_FB"),
+	PINCTRL_PIN(22, "PMU_PLTRST_B"),
+	PINCTRL_PIN(23, "PMU_PWRBTN_B"),
+	PINCTRL_PIN(24, "PMU_SLP_S0_B"),
+	PINCTRL_PIN(25, "PMU_SLP_S3_B"),
+	PINCTRL_PIN(26, "PMU_SLP_S4_B"),
+	PINCTRL_PIN(27, "SUSPWRDNACK"),
+	PINCTRL_PIN(28, "EMMC_PWR_EN_B"),
+	PINCTRL_PIN(29, "PMU_AC_PRESENT"),
+	PINCTRL_PIN(30, "PMU_BATLOW_B"),
+	PINCTRL_PIN(31, "PMU_RESETBUTTON_B"),
+	PINCTRL_PIN(32, "PMU_SUSCLK"),
+	PINCTRL_PIN(33, "SUS_STAT_B"),
+	PINCTRL_PIN(34, "LPSS_I2C5_SDA"),
+	PINCTRL_PIN(35, "LPSS_I2C5_SCL"),
+	PINCTRL_PIN(36, "LPSS_I2C6_SDA"),
+	PINCTRL_PIN(37, "LPSS_I2C6_SCL"),
+	PINCTRL_PIN(38, "LPSS_I2C7_SDA"),
+	PINCTRL_PIN(39, "LPSS_I2C7_SCL"),
+	PINCTRL_PIN(40, "PCIE_WAKE0_B"),
+	PINCTRL_PIN(41, "PCIE_WAKE1_B"),
+	PINCTRL_PIN(42, "PCIE_WAKE2_B"),
+	PINCTRL_PIN(43, "PCIE_WAKE3_B"),
+	PINCTRL_PIN(44, "PCIE_CLKREQ0_B"),
+	PINCTRL_PIN(45, "PCIE_CLKREQ1_B"),
+	PINCTRL_PIN(46, "PCIE_CLKREQ2_B"),
+	PINCTRL_PIN(47, "PCIE_CLKREQ3_B"),
+	PINCTRL_PIN(48, "HV_DDI0_DDC_SDA"),
+	PINCTRL_PIN(49, "HV_DDI0_DDC_SCL"),
+	PINCTRL_PIN(50, "HV_DDI1_DDC_SDA"),
+	PINCTRL_PIN(51, "HV_DDI1_DDC_SCL"),
+	PINCTRL_PIN(52, "PANEL0_VDDEN"),
+	PINCTRL_PIN(53, "PANEL0_BKLTEN"),
+	PINCTRL_PIN(54, "PANEL0_BKLTCTL"),
+	PINCTRL_PIN(55, "HV_DDI0_HPD"),
+	PINCTRL_PIN(56, "HV_DDI1_HPD"),
+	PINCTRL_PIN(57, "HV_EDP_HPD"),
+	PINCTRL_PIN(58, "GPIO_134"),
+	PINCTRL_PIN(59, "GPIO_135"),
+	PINCTRL_PIN(60, "GPIO_136"),
+	PINCTRL_PIN(61, "GPIO_137"),
+	PINCTRL_PIN(62, "GPIO_138"),
+	PINCTRL_PIN(63, "GPIO_139"),
+	PINCTRL_PIN(64, "GPIO_140"),
+	PINCTRL_PIN(65, "GPIO_141"),
+	PINCTRL_PIN(66, "GPIO_142"),
+	PINCTRL_PIN(67, "GPIO_143"),
+	PINCTRL_PIN(68, "GPIO_144"),
+	PINCTRL_PIN(69, "GPIO_145"),
+	PINCTRL_PIN(70, "GPIO_146"),
+	PINCTRL_PIN(71, "LPC_ILB_SERIRQ"),
+	PINCTRL_PIN(72, "LPC_CLKOUT0"),
+	PINCTRL_PIN(73, "LPC_CLKOUT1"),
+	PINCTRL_PIN(74, "LPC_AD0"),
+	PINCTRL_PIN(75, "LPC_AD1"),
+	PINCTRL_PIN(76, "LPC_AD2"),
+	PINCTRL_PIN(77, "LPC_AD3"),
+	PINCTRL_PIN(78, "LPC_CLKRUNB"),
+	PINCTRL_PIN(79, "LPC_FRAMEB"),
+};
+
+static const unsigned int glk_north_spi0_pins[] = { 3, 4, 5, 6, 7 };
+static const unsigned int glk_north_spi1_pins[] = { 8, 9, 10, 11, 12, 13 };
+static const unsigned int glk_north_i2c5_pins[] = { 34, 35 };
+static const unsigned int glk_north_i2c6_pins[] = { 36, 37 };
+static const unsigned int glk_north_i2c7_pins[] = { 38, 39 };
+static const unsigned int glk_north_uart0_pins[] = { 62, 63, 64, 65 };
+static const unsigned int glk_north_spi0b_pins[] = { 66, 67, 68, 69, 70 };
+
+static const struct intel_pingroup glk_north_groups[] = {
+	PIN_GROUP("spi0_grp", glk_north_spi0_pins, 1),
+	PIN_GROUP("spi1_grp", glk_north_spi1_pins, 1),
+	PIN_GROUP("i2c5_grp", glk_north_i2c5_pins, 1),
+	PIN_GROUP("i2c6_grp", glk_north_i2c6_pins, 1),
+	PIN_GROUP("i2c7_grp", glk_north_i2c7_pins, 1),
+	PIN_GROUP("uart0_grp", glk_north_uart0_pins, 2),
+	PIN_GROUP("spi0b_grp", glk_north_spi0b_pins, 2),
+};
+
+static const char * const glk_north_spi0_groups[] = { "spi0_grp", "spi0b_grp" };
+static const char * const glk_north_spi1_groups[] = { "spi1_grp" };
+static const char * const glk_north_i2c5_groups[] = { "i2c5_grp" };
+static const char * const glk_north_i2c6_groups[] = { "i2c6_grp" };
+static const char * const glk_north_i2c7_groups[] = { "i2c7_grp" };
+static const char * const glk_north_uart0_groups[] = { "uart0_grp" };
+
+static const struct intel_function glk_north_functions[] = {
+	FUNCTION("spi0", glk_north_spi0_groups),
+	FUNCTION("spi1", glk_north_spi1_groups),
+	FUNCTION("i2c5", glk_north_i2c5_groups),
+	FUNCTION("i2c6", glk_north_i2c6_groups),
+	FUNCTION("i2c7", glk_north_i2c7_groups),
+	FUNCTION("uart0", glk_north_uart0_groups),
+};
+
+static const struct intel_community glk_north_communities[] = {
+	GLK_COMMUNITY(0, 79),
+};
+
+static const struct intel_pinctrl_soc_data glk_north_soc_data = {
+	.uid = "2",
+	.pins = glk_north_pins,
+	.npins = ARRAY_SIZE(glk_north_pins),
+	.groups = glk_north_groups,
+	.ngroups = ARRAY_SIZE(glk_north_groups),
+	.functions = glk_north_functions,
+	.nfunctions = ARRAY_SIZE(glk_north_functions),
+	.communities = glk_north_communities,
+	.ncommunities = ARRAY_SIZE(glk_north_communities),
+};
+
+static const struct pinctrl_pin_desc glk_audio_pins[] = {
+	PINCTRL_PIN(0, "AVS_I2S0_MCLK"),
+	PINCTRL_PIN(1, "AVS_I2S0_BCLK"),
+	PINCTRL_PIN(2, "AVS_I2S0_WS_SYNC"),
+	PINCTRL_PIN(3, "AVS_I2S0_SDI"),
+	PINCTRL_PIN(4, "AVS_I2S0_SDO"),
+	PINCTRL_PIN(5, "AVS_I2S1_MCLK"),
+	PINCTRL_PIN(6, "AVS_I2S1_BCLK"),
+	PINCTRL_PIN(7, "AVS_I2S1_WS_SYNC"),
+	PINCTRL_PIN(8, "AVS_I2S1_SDI"),
+	PINCTRL_PIN(9, "AVS_I2S1_SDO"),
+	PINCTRL_PIN(10, "AVS_HDA_BCLK"),
+	PINCTRL_PIN(11, "AVS_HDA_WS_SYNC"),
+	PINCTRL_PIN(12, "AVS_HDA_SDI"),
+	PINCTRL_PIN(13, "AVS_HDA_SDO"),
+	PINCTRL_PIN(14, "AVS_HDA_RSTB"),
+	PINCTRL_PIN(15, "AVS_M_CLK_A1"),
+	PINCTRL_PIN(16, "AVS_M_CLK_B1"),
+	PINCTRL_PIN(17, "AVS_M_DATA_1"),
+	PINCTRL_PIN(18, "AVS_M_CLK_AB2"),
+	PINCTRL_PIN(19, "AVS_M_DATA_2"),
+};
+
+static const struct intel_community glk_audio_communities[] = {
+	GLK_COMMUNITY(0, 19),
+};
+
+static const struct intel_pinctrl_soc_data glk_audio_soc_data = {
+	.uid = "3",
+	.pins = glk_audio_pins,
+	.npins = ARRAY_SIZE(glk_audio_pins),
+	.communities = glk_audio_communities,
+	.ncommunities = ARRAY_SIZE(glk_audio_communities),
+};
+
+static const struct pinctrl_pin_desc glk_scc_pins[] = {
+	PINCTRL_PIN(0, "SMB_ALERTB"),
+	PINCTRL_PIN(1, "SMB_CLK"),
+	PINCTRL_PIN(2, "SMB_DATA"),
+	PINCTRL_PIN(3, "SDCARD_LVL_WP"),
+	PINCTRL_PIN(4, "SDCARD_CLK"),
+	PINCTRL_PIN(5, "SDCARD_CLK_FB"),
+	PINCTRL_PIN(6, "SDCARD_D0"),
+	PINCTRL_PIN(7, "SDCARD_D1"),
+	PINCTRL_PIN(8, "SDCARD_D2"),
+	PINCTRL_PIN(9, "SDCARD_D3"),
+	PINCTRL_PIN(10, "SDCARD_CMD"),
+	PINCTRL_PIN(11, "SDCARD_CD_B"),
+	PINCTRL_PIN(12, "SDCARD_PWR_DOWN_B"),
+	PINCTRL_PIN(13, "GPIO_210"),
+	PINCTRL_PIN(14, "OSC_CLK_OUT_0"),
+	PINCTRL_PIN(15, "OSC_CLK_OUT_1"),
+	PINCTRL_PIN(16, "CNV_BRI_DT"),
+	PINCTRL_PIN(17, "CNV_BRI_RSP"),
+	PINCTRL_PIN(18, "CNV_RGI_DT"),
+	PINCTRL_PIN(19, "CNV_RGI_RSP"),
+	PINCTRL_PIN(20, "CNV_RF_RESET_B"),
+	PINCTRL_PIN(21, "XTAL_CLKREQ"),
+	PINCTRL_PIN(22, "SDIO_CLK_FB"),
+	PINCTRL_PIN(23, "EMMC0_CLK"),
+	PINCTRL_PIN(24, "EMMC0_CLK_FB"),
+	PINCTRL_PIN(25, "EMMC0_D0"),
+	PINCTRL_PIN(26, "EMMC0_D1"),
+	PINCTRL_PIN(27, "EMMC0_D2"),
+	PINCTRL_PIN(28, "EMMC0_D3"),
+	PINCTRL_PIN(29, "EMMC0_D4"),
+	PINCTRL_PIN(30, "EMMC0_D5"),
+	PINCTRL_PIN(31, "EMMC0_D6"),
+	PINCTRL_PIN(32, "EMMC0_D7"),
+	PINCTRL_PIN(33, "EMMC0_CMD"),
+	PINCTRL_PIN(34, "EMMC0_STROBE"),
+};
+
+static const unsigned int glk_scc_i2c7_pins[] = { 1, 2 };
+static const unsigned int glk_scc_sdcard_pins[] = {
+	3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+};
+static const unsigned int glk_scc_sdio_pins[] = { 16, 17, 18, 19, 20, 21, 22 };
+static const unsigned int glk_scc_uart1_pins[] = { 16, 17, 18, 19 };
+static const unsigned int glk_scc_emmc_pins[] = {
+	23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+};
+
+static const struct intel_pingroup glk_scc_groups[] = {
+	PIN_GROUP("i2c7_grp", glk_scc_i2c7_pins, 2),
+	PIN_GROUP("sdcard_grp", glk_scc_sdcard_pins, 1),
+	PIN_GROUP("sdio_grp", glk_scc_sdio_pins, 2),
+	PIN_GROUP("uart1_grp", glk_scc_uart1_pins, 3),
+	PIN_GROUP("emmc_grp", glk_scc_emmc_pins, 1),
+};
+
+static const char * const glk_scc_i2c7_groups[] = { "i2c7_grp" };
+static const char * const glk_scc_sdcard_groups[] = { "sdcard_grp" };
+static const char * const glk_scc_sdio_groups[] = { "sdio_grp" };
+static const char * const glk_scc_uart1_groups[] = { "uart1_grp" };
+static const char * const glk_scc_emmc_groups[] = { "emmc_grp" };
+
+static const struct intel_function glk_scc_functions[] = {
+	FUNCTION("i2c7", glk_scc_i2c7_groups),
+	FUNCTION("sdcard", glk_scc_sdcard_groups),
+	FUNCTION("sdio", glk_scc_sdio_groups),
+	FUNCTION("uart1", glk_scc_uart1_groups),
+	FUNCTION("emmc", glk_scc_emmc_groups),
+};
+
+static const struct intel_community glk_scc_communities[] = {
+	GLK_COMMUNITY(0, 34),
+};
+
+static const struct intel_pinctrl_soc_data glk_scc_soc_data = {
+	.uid = "4",
+	.pins = glk_scc_pins,
+	.npins = ARRAY_SIZE(glk_scc_pins),
+	.groups = glk_scc_groups,
+	.ngroups = ARRAY_SIZE(glk_scc_groups),
+	.functions = glk_scc_functions,
+	.nfunctions = ARRAY_SIZE(glk_scc_functions),
+	.communities = glk_scc_communities,
+	.ncommunities = ARRAY_SIZE(glk_scc_communities),
+};
+
+static const struct intel_pinctrl_soc_data *glk_pinctrl_soc_data[] = {
+	&glk_northwest_soc_data,
+	&glk_north_soc_data,
+	&glk_audio_soc_data,
+	&glk_scc_soc_data,
+	NULL,
+};
+
+static const struct acpi_device_id glk_pinctrl_acpi_match[] = {
+	{ "INT3453" },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, glk_pinctrl_acpi_match);
+
+static int glk_pinctrl_probe(struct platform_device *pdev)
+{
+	const struct intel_pinctrl_soc_data *soc_data = NULL;
+	struct acpi_device *adev;
+	int i;
+
+	adev = ACPI_COMPANION(&pdev->dev);
+	if (!adev)
+		return -ENODEV;
+
+	for (i = 0; glk_pinctrl_soc_data[i]; i++) {
+		if (!strcmp(adev->pnp.unique_id,
+			    glk_pinctrl_soc_data[i]->uid)) {
+			soc_data = glk_pinctrl_soc_data[i];
+			break;
+		}
+	}
+
+	if (!soc_data)
+		return -ENODEV;
+
+	return intel_pinctrl_probe(pdev, soc_data);
+}
+
+static const struct dev_pm_ops glk_pinctrl_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
+				     intel_pinctrl_resume)
+};
+
+static struct platform_driver glk_pinctrl_driver = {
+	.probe = glk_pinctrl_probe,
+	.driver = {
+		.name = "geminilake-pinctrl",
+		.acpi_match_table = glk_pinctrl_acpi_match,
+		.pm = &glk_pinctrl_pm_ops,
+	},
+};
+
+static int __init glk_pinctrl_init(void)
+{
+	return platform_driver_register(&glk_pinctrl_driver);
+}
+subsys_initcall(glk_pinctrl_init);
+
+static void __exit glk_pinctrl_exit(void)
+{
+	platform_driver_unregister(&glk_pinctrl_driver);
+}
+module_exit(glk_pinctrl_exit);
+
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+MODULE_DESCRIPTION("Intel Gemini Lake SoC pinctrl/GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/intel/pinctrl-icelake.c b/drivers/pinctrl/intel/pinctrl-icelake.c
new file mode 100644
index 0000000..630b966
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-icelake.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Ice Lake PCH pinctrl/GPIO driver
+ *
+ * Copyright (C) 2018, Intel Corporation
+ * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+ *	    Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-intel.h"
+
+#define ICL_PAD_OWN	0x020
+#define ICL_PADCFGLOCK	0x080
+#define ICL_HOSTSW_OWN	0x0b0
+#define ICL_GPI_IE	0x110
+
+#define ICL_GPP(r, s, e, g)				\
+	{						\
+		.reg_num = (r),				\
+		.base = (s),				\
+		.size = ((e) - (s) + 1),		\
+		.gpio_base = (g),			\
+	}
+
+#define ICL_NO_GPIO	-1
+
+#define ICL_COMMUNITY(b, s, e, g)			\
+	{						\
+		.barno = (b),				\
+		.padown_offset = ICL_PAD_OWN,		\
+		.padcfglock_offset = ICL_PADCFGLOCK,	\
+		.hostown_offset = ICL_HOSTSW_OWN,	\
+		.ie_offset = ICL_GPI_IE,		\
+		.pin_base = (s),			\
+		.npins = ((e) - (s) + 1),		\
+		.gpps = (g),				\
+		.ngpps = ARRAY_SIZE(g),			\
+	}
+
+/* Ice Lake-LP */
+static const struct pinctrl_pin_desc icllp_pins[] = {
+	/* GPP_G */
+	PINCTRL_PIN(0, "SD3_CMD"),
+	PINCTRL_PIN(1, "SD3_D0"),
+	PINCTRL_PIN(2, "SD3_D1"),
+	PINCTRL_PIN(3, "SD3_D2"),
+	PINCTRL_PIN(4, "SD3_D3"),
+	PINCTRL_PIN(5, "SD3_CDB"),
+	PINCTRL_PIN(6, "SD3_CLK"),
+	PINCTRL_PIN(7, "SD3_WP"),
+	/* GPP_B */
+	PINCTRL_PIN(8, "CORE_VID_0"),
+	PINCTRL_PIN(9, "CORE_VID_1"),
+	PINCTRL_PIN(10, "VRALERTB"),
+	PINCTRL_PIN(11, "CPU_GP_2"),
+	PINCTRL_PIN(12, "CPU_GP_3"),
+	PINCTRL_PIN(13, "ISH_I2C0_SDA"),
+	PINCTRL_PIN(14, "ISH_I2C0_SCL"),
+	PINCTRL_PIN(15, "ISH_I2C1_SDA"),
+	PINCTRL_PIN(16, "ISH_I2C1_SCL"),
+	PINCTRL_PIN(17, "I2C5_SDA"),
+	PINCTRL_PIN(18, "I2C5_SCL"),
+	PINCTRL_PIN(19, "PMCALERTB"),
+	PINCTRL_PIN(20, "SLP_S0B"),
+	PINCTRL_PIN(21, "PLTRSTB"),
+	PINCTRL_PIN(22, "SPKR"),
+	PINCTRL_PIN(23, "GSPI0_CS0B"),
+	PINCTRL_PIN(24, "GSPI0_CLK"),
+	PINCTRL_PIN(25, "GSPI0_MISO"),
+	PINCTRL_PIN(26, "GSPI0_MOSI"),
+	PINCTRL_PIN(27, "GSPI1_CS0B"),
+	PINCTRL_PIN(28, "GSPI1_CLK"),
+	PINCTRL_PIN(29, "GSPI1_MISO"),
+	PINCTRL_PIN(30, "GSPI1_MOSI"),
+	PINCTRL_PIN(31, "SML1ALERTB"),
+	PINCTRL_PIN(32, "GSPI0_CLK_LOOPBK"),
+	PINCTRL_PIN(33, "GSPI1_CLK_LOOPBK"),
+	/* GPP_A */
+	PINCTRL_PIN(34, "ESPI_IO_0"),
+	PINCTRL_PIN(35, "ESPI_IO_1"),
+	PINCTRL_PIN(36, "ESPI_IO_2"),
+	PINCTRL_PIN(37, "ESPI_IO_3"),
+	PINCTRL_PIN(38, "ESPI_CSB"),
+	PINCTRL_PIN(39, "ESPI_CLK"),
+	PINCTRL_PIN(40, "ESPI_RESETB"),
+	PINCTRL_PIN(41, "I2S2_SCLK"),
+	PINCTRL_PIN(42, "I2S2_SFRM"),
+	PINCTRL_PIN(43, "I2S2_TXD"),
+	PINCTRL_PIN(44, "I2S2_RXD"),
+	PINCTRL_PIN(45, "SATA_DEVSLP_2"),
+	PINCTRL_PIN(46, "SATAXPCIE_1"),
+	PINCTRL_PIN(47, "SATAXPCIE_2"),
+	PINCTRL_PIN(48, "USB2_OCB_1"),
+	PINCTRL_PIN(49, "USB2_OCB_2"),
+	PINCTRL_PIN(50, "USB2_OCB_3"),
+	PINCTRL_PIN(51, "DDSP_HPD_C"),
+	PINCTRL_PIN(52, "DDSP_HPD_B"),
+	PINCTRL_PIN(53, "DDSP_HPD_1"),
+	PINCTRL_PIN(54, "DDSP_HPD_2"),
+	PINCTRL_PIN(55, "I2S5_TXD"),
+	PINCTRL_PIN(56, "I2S5_RXD"),
+	PINCTRL_PIN(57, "I2S1_SCLK"),
+	PINCTRL_PIN(58, "ESPI_CLK_LOOPBK"),
+	/* GPP_H */
+	PINCTRL_PIN(59, "SD_1P8_SEL"),
+	PINCTRL_PIN(60, "SD_PWR_EN_B"),
+	PINCTRL_PIN(61, "GPPC_H_2"),
+	PINCTRL_PIN(62, "SX_EXIT_HOLDOFFB"),
+	PINCTRL_PIN(63, "I2C2_SDA"),
+	PINCTRL_PIN(64, "I2C2_SCL"),
+	PINCTRL_PIN(65, "I2C3_SDA"),
+	PINCTRL_PIN(66, "I2C3_SCL"),
+	PINCTRL_PIN(67, "I2C4_SDA"),
+	PINCTRL_PIN(68, "I2C4_SCL"),
+	PINCTRL_PIN(69, "SRCCLKREQB_4"),
+	PINCTRL_PIN(70, "SRCCLKREQB_5"),
+	PINCTRL_PIN(71, "M2_SKT2_CFG_0"),
+	PINCTRL_PIN(72, "M2_SKT2_CFG_1"),
+	PINCTRL_PIN(73, "M2_SKT2_CFG_2"),
+	PINCTRL_PIN(74, "M2_SKT2_CFG_3"),
+	PINCTRL_PIN(75, "DDPB_CTRLCLK"),
+	PINCTRL_PIN(76, "DDPB_CTRLDATA"),
+	PINCTRL_PIN(77, "CPU_VCCIO_PWR_GATEB"),
+	PINCTRL_PIN(78, "TIME_SYNC_0"),
+	PINCTRL_PIN(79, "IMGCLKOUT_1"),
+	PINCTRL_PIN(80, "IMGCLKOUT_2"),
+	PINCTRL_PIN(81, "IMGCLKOUT_3"),
+	PINCTRL_PIN(82, "IMGCLKOUT_4"),
+	/* GPP_D */
+	PINCTRL_PIN(83, "ISH_GP_0"),
+	PINCTRL_PIN(84, "ISH_GP_1"),
+	PINCTRL_PIN(85, "ISH_GP_2"),
+	PINCTRL_PIN(86, "ISH_GP_3"),
+	PINCTRL_PIN(87, "IMGCLKOUT_0"),
+	PINCTRL_PIN(88, "SRCCLKREQB_0"),
+	PINCTRL_PIN(89, "SRCCLKREQB_1"),
+	PINCTRL_PIN(90, "SRCCLKREQB_2"),
+	PINCTRL_PIN(91, "SRCCLKREQB_3"),
+	PINCTRL_PIN(92, "ISH_SPI_CSB"),
+	PINCTRL_PIN(93, "ISH_SPI_CLK"),
+	PINCTRL_PIN(94, "ISH_SPI_MISO"),
+	PINCTRL_PIN(95, "ISH_SPI_MOSI"),
+	PINCTRL_PIN(96, "ISH_UART0_RXD"),
+	PINCTRL_PIN(97, "ISH_UART0_TXD"),
+	PINCTRL_PIN(98, "ISH_UART0_RTSB"),
+	PINCTRL_PIN(99, "ISH_UART0_CTSB"),
+	PINCTRL_PIN(100, "ISH_GP_4"),
+	PINCTRL_PIN(101, "ISH_GP_5"),
+	PINCTRL_PIN(102, "I2S_MCLK"),
+	PINCTRL_PIN(103, "GSPI2_CLK_LOOPBK"),
+	/* GPP_F */
+	PINCTRL_PIN(104, "CNV_BRI_DT"),
+	PINCTRL_PIN(105, "CNV_BRI_RSP"),
+	PINCTRL_PIN(106, "CNV_RGI_DT"),
+	PINCTRL_PIN(107, "CNV_RGI_RSP"),
+	PINCTRL_PIN(108, "CNV_RF_RESET_B"),
+	PINCTRL_PIN(109, "EMMC_HIP_MON"),
+	PINCTRL_PIN(110, "CNV_PA_BLANKING"),
+	PINCTRL_PIN(111, "EMMC_CMD"),
+	PINCTRL_PIN(112, "EMMC_DATA0"),
+	PINCTRL_PIN(113, "EMMC_DATA1"),
+	PINCTRL_PIN(114, "EMMC_DATA2"),
+	PINCTRL_PIN(115, "EMMC_DATA3"),
+	PINCTRL_PIN(116, "EMMC_DATA4"),
+	PINCTRL_PIN(117, "EMMC_DATA5"),
+	PINCTRL_PIN(118, "EMMC_DATA6"),
+	PINCTRL_PIN(119, "EMMC_DATA7"),
+	PINCTRL_PIN(120, "EMMC_RCLK"),
+	PINCTRL_PIN(121, "EMMC_CLK"),
+	PINCTRL_PIN(122, "EMMC_RESETB"),
+	PINCTRL_PIN(123, "A4WP_PRESENT"),
+	/* vGPIO */
+	PINCTRL_PIN(124, "CNV_BTEN"),
+	PINCTRL_PIN(125, "CNV_WCEN"),
+	PINCTRL_PIN(126, "CNV_BT_HOST_WAKEB"),
+	PINCTRL_PIN(127, "CNV_BT_IF_SELECT"),
+	PINCTRL_PIN(128, "vCNV_BT_UART_TXD"),
+	PINCTRL_PIN(129, "vCNV_BT_UART_RXD"),
+	PINCTRL_PIN(130, "vCNV_BT_UART_CTS_B"),
+	PINCTRL_PIN(131, "vCNV_BT_UART_RTS_B"),
+	PINCTRL_PIN(132, "vCNV_MFUART1_TXD"),
+	PINCTRL_PIN(133, "vCNV_MFUART1_RXD"),
+	PINCTRL_PIN(134, "vCNV_MFUART1_CTS_B"),
+	PINCTRL_PIN(135, "vCNV_MFUART1_RTS_B"),
+	PINCTRL_PIN(136, "vUART0_TXD"),
+	PINCTRL_PIN(137, "vUART0_RXD"),
+	PINCTRL_PIN(138, "vUART0_CTS_B"),
+	PINCTRL_PIN(139, "vUART0_RTS_B"),
+	PINCTRL_PIN(140, "vISH_UART0_TXD"),
+	PINCTRL_PIN(141, "vISH_UART0_RXD"),
+	PINCTRL_PIN(142, "vISH_UART0_CTS_B"),
+	PINCTRL_PIN(143, "vISH_UART0_RTS_B"),
+	PINCTRL_PIN(144, "vCNV_BT_I2S_BCLK"),
+	PINCTRL_PIN(145, "vCNV_BT_I2S_WS_SYNC"),
+	PINCTRL_PIN(146, "vCNV_BT_I2S_SDO"),
+	PINCTRL_PIN(147, "vCNV_BT_I2S_SDI"),
+	PINCTRL_PIN(148, "vI2S2_SCLK"),
+	PINCTRL_PIN(149, "vI2S2_SFRM"),
+	PINCTRL_PIN(150, "vI2S2_TXD"),
+	PINCTRL_PIN(151, "vI2S2_RXD"),
+	PINCTRL_PIN(152, "vSD3_CD_B"),
+	/* GPP_C */
+	PINCTRL_PIN(153, "SMBCLK"),
+	PINCTRL_PIN(154, "SMBDATA"),
+	PINCTRL_PIN(155, "SMBALERTB"),
+	PINCTRL_PIN(156, "SML0CLK"),
+	PINCTRL_PIN(157, "SML0DATA"),
+	PINCTRL_PIN(158, "SML0ALERTB"),
+	PINCTRL_PIN(159, "SML1CLK"),
+	PINCTRL_PIN(160, "SML1DATA"),
+	PINCTRL_PIN(161, "UART0_RXD"),
+	PINCTRL_PIN(162, "UART0_TXD"),
+	PINCTRL_PIN(163, "UART0_RTSB"),
+	PINCTRL_PIN(164, "UART0_CTSB"),
+	PINCTRL_PIN(165, "UART1_RXD"),
+	PINCTRL_PIN(166, "UART1_TXD"),
+	PINCTRL_PIN(167, "UART1_RTSB"),
+	PINCTRL_PIN(168, "UART1_CTSB"),
+	PINCTRL_PIN(169, "I2C0_SDA"),
+	PINCTRL_PIN(170, "I2C0_SCL"),
+	PINCTRL_PIN(171, "I2C1_SDA"),
+	PINCTRL_PIN(172, "I2C1_SCL"),
+	PINCTRL_PIN(173, "UART2_RXD"),
+	PINCTRL_PIN(174, "UART2_TXD"),
+	PINCTRL_PIN(175, "UART2_RTSB"),
+	PINCTRL_PIN(176, "UART2_CTSB"),
+	/* HVCMOS */
+	PINCTRL_PIN(177, "L_BKLTEN"),
+	PINCTRL_PIN(178, "L_BKLTCTL"),
+	PINCTRL_PIN(179, "L_VDDEN"),
+	PINCTRL_PIN(180, "SYS_PWROK"),
+	PINCTRL_PIN(181, "SYS_RESETB"),
+	PINCTRL_PIN(182, "MLK_RSTB"),
+	/* GPP_E */
+	PINCTRL_PIN(183, "SATAXPCIE_0"),
+	PINCTRL_PIN(184, "SPI1_IO_2"),
+	PINCTRL_PIN(185, "SPI1_IO_3"),
+	PINCTRL_PIN(186, "CPU_GP_0"),
+	PINCTRL_PIN(187, "SATA_DEVSLP_0"),
+	PINCTRL_PIN(188, "SATA_DEVSLP_1"),
+	PINCTRL_PIN(189, "GPPC_E_6"),
+	PINCTRL_PIN(190, "CPU_GP_1"),
+	PINCTRL_PIN(191, "SATA_LEDB"),
+	PINCTRL_PIN(192, "USB2_OCB_0"),
+	PINCTRL_PIN(193, "SPI1_CSB"),
+	PINCTRL_PIN(194, "SPI1_CLK"),
+	PINCTRL_PIN(195, "SPI1_MISO_IO_1"),
+	PINCTRL_PIN(196, "SPI1_MOSI_IO_0"),
+	PINCTRL_PIN(197, "DDSP_HPD_A"),
+	PINCTRL_PIN(198, "ISH_GP_6"),
+	PINCTRL_PIN(199, "ISH_GP_7"),
+	PINCTRL_PIN(200, "DISP_MISC_4"),
+	PINCTRL_PIN(201, "DDP1_CTRLCLK"),
+	PINCTRL_PIN(202, "DDP1_CTRLDATA"),
+	PINCTRL_PIN(203, "DDP2_CTRLCLK"),
+	PINCTRL_PIN(204, "DDP2_CTRLDATA"),
+	PINCTRL_PIN(205, "DDPA_CTRLCLK"),
+	PINCTRL_PIN(206, "DDPA_CTRLDATA"),
+	/* JTAG */
+	PINCTRL_PIN(207, "JTAG_TDO"),
+	PINCTRL_PIN(208, "JTAGX"),
+	PINCTRL_PIN(209, "PRDYB"),
+	PINCTRL_PIN(210, "PREQB"),
+	PINCTRL_PIN(211, "CPU_TRSTB"),
+	PINCTRL_PIN(212, "JTAG_TDI"),
+	PINCTRL_PIN(213, "JTAG_TMS"),
+	PINCTRL_PIN(214, "JTAG_TCK"),
+	PINCTRL_PIN(215, "ITP_PMODE"),
+	/* GPP_R */
+	PINCTRL_PIN(216, "HDA_BCLK"),
+	PINCTRL_PIN(217, "HDA_SYNC"),
+	PINCTRL_PIN(218, "HDA_SDO"),
+	PINCTRL_PIN(219, "HDA_SDI_0"),
+	PINCTRL_PIN(220, "HDA_RSTB"),
+	PINCTRL_PIN(221, "HDA_SDI_1"),
+	PINCTRL_PIN(222, "I2S1_TXD"),
+	PINCTRL_PIN(223, "I2S1_RXD"),
+	/* GPP_S */
+	PINCTRL_PIN(224, "SNDW1_CLK"),
+	PINCTRL_PIN(225, "SNDW1_DATA"),
+	PINCTRL_PIN(226, "SNDW2_CLK"),
+	PINCTRL_PIN(227, "SNDW2_DATA"),
+	PINCTRL_PIN(228, "SNDW3_CLK"),
+	PINCTRL_PIN(229, "SNDW3_DATA"),
+	PINCTRL_PIN(230, "SNDW4_CLK"),
+	PINCTRL_PIN(231, "SNDW4_DATA"),
+	/* SPI */
+	PINCTRL_PIN(232, "SPI0_IO_2"),
+	PINCTRL_PIN(233, "SPI0_IO_3"),
+	PINCTRL_PIN(234, "SPI0_MOSI_IO_0"),
+	PINCTRL_PIN(235, "SPI0_MISO_IO_1"),
+	PINCTRL_PIN(236, "SPI0_TPM_CSB"),
+	PINCTRL_PIN(237, "SPI0_FLASH_0_CSB"),
+	PINCTRL_PIN(238, "SPI0_FLASH_1_CSB"),
+	PINCTRL_PIN(239, "SPI0_CLK"),
+	PINCTRL_PIN(240, "SPI0_CLK_LOOPBK"),
+};
+
+static const struct intel_padgroup icllp_community0_gpps[] = {
+	ICL_GPP(0, 0, 7, 0),			/* GPP_G */
+	ICL_GPP(1, 8, 33, 32),			/* GPP_B */
+	ICL_GPP(2, 34, 58, 64),			/* GPP_A */
+};
+
+static const struct intel_padgroup icllp_community1_gpps[] = {
+	ICL_GPP(0, 59, 82, 96),			/* GPP_H */
+	ICL_GPP(1, 83, 103, 128),		/* GPP_D */
+	ICL_GPP(2, 104, 123, 160),		/* GPP_F */
+	ICL_GPP(3, 124, 152, 192),		/* vGPIO */
+};
+
+static const struct intel_padgroup icllp_community4_gpps[] = {
+	ICL_GPP(0, 153, 176, 224),		/* GPP_C */
+	ICL_GPP(1, 177, 182, ICL_NO_GPIO),	/* HVCMOS */
+	ICL_GPP(2, 183, 206, 256),		/* GPP_E */
+	ICL_GPP(3, 207, 215, ICL_NO_GPIO),	/* JTAG */
+};
+
+static const struct intel_padgroup icllp_community5_gpps[] = {
+	ICL_GPP(0, 216, 223, 288),		/* GPP_R */
+	ICL_GPP(1, 224, 231, 320),		/* GPP_S */
+	ICL_GPP(2, 232, 240, ICL_NO_GPIO),	/* SPI */
+};
+
+static const struct intel_community icllp_communities[] = {
+	ICL_COMMUNITY(0, 0, 58, icllp_community0_gpps),
+	ICL_COMMUNITY(1, 59, 152, icllp_community1_gpps),
+	ICL_COMMUNITY(2, 153, 215, icllp_community4_gpps),
+	ICL_COMMUNITY(3, 216, 240, icllp_community5_gpps),
+};
+
+static const unsigned int icllp_spi0_pins[] = { 22, 23, 24, 25, 26 };
+static const unsigned int icllp_spi0_modes[] = { 3, 1, 1, 1, 1 };
+static const unsigned int icllp_spi1_pins[] = { 27, 28, 29, 30, 31 };
+static const unsigned int icllp_spi1_modes[] = { 1, 1, 1, 1, 3 };
+static const unsigned int icllp_spi2_pins[] = { 92, 93, 94, 95, 98 };
+static const unsigned int icllp_spi2_modes[] = { 3, 3, 3, 3, 2 };
+
+static const unsigned int icllp_i2c0_pins[] = { 169, 170 };
+static const unsigned int icllp_i2c1_pins[] = { 171, 172 };
+static const unsigned int icllp_i2c2_pins[] = { 63, 64 };
+static const unsigned int icllp_i2c3_pins[] = { 65, 66 };
+static const unsigned int icllp_i2c4_pins[] = { 67, 68 };
+
+static const unsigned int icllp_uart0_pins[] = { 161, 162, 163, 164 };
+static const unsigned int icllp_uart1_pins[] = { 165, 166, 167, 168 };
+static const unsigned int icllp_uart2_pins[] = { 173, 174, 175, 176 };
+
+static const struct intel_pingroup icllp_groups[] = {
+	PIN_GROUP("spi0_grp", icllp_spi0_pins, icllp_spi0_modes),
+	PIN_GROUP("spi1_grp", icllp_spi1_pins, icllp_spi1_modes),
+	PIN_GROUP("spi2_grp", icllp_spi2_pins, icllp_spi2_modes),
+	PIN_GROUP("i2c0_grp", icllp_i2c0_pins, 1),
+	PIN_GROUP("i2c1_grp", icllp_i2c1_pins, 1),
+	PIN_GROUP("i2c2_grp", icllp_i2c2_pins, 1),
+	PIN_GROUP("i2c3_grp", icllp_i2c3_pins, 1),
+	PIN_GROUP("i2c4_grp", icllp_i2c4_pins, 1),
+	PIN_GROUP("uart0_grp", icllp_uart0_pins, 1),
+	PIN_GROUP("uart1_grp", icllp_uart1_pins, 1),
+	PIN_GROUP("uart2_grp", icllp_uart2_pins, 1),
+};
+
+static const char * const icllp_spi0_groups[] = { "spi0_grp" };
+static const char * const icllp_spi1_groups[] = { "spi1_grp" };
+static const char * const icllp_spi2_groups[] = { "spi2_grp" };
+static const char * const icllp_i2c0_groups[] = { "i2c0_grp" };
+static const char * const icllp_i2c1_groups[] = { "i2c1_grp" };
+static const char * const icllp_i2c2_groups[] = { "i2c2_grp" };
+static const char * const icllp_i2c3_groups[] = { "i2c3_grp" };
+static const char * const icllp_i2c4_groups[] = { "i2c4_grp" };
+static const char * const icllp_uart0_groups[] = { "uart0_grp" };
+static const char * const icllp_uart1_groups[] = { "uart1_grp" };
+static const char * const icllp_uart2_groups[] = { "uart2_grp" };
+
+static const struct intel_function icllp_functions[] = {
+	FUNCTION("spi0", icllp_spi0_groups),
+	FUNCTION("spi1", icllp_spi1_groups),
+	FUNCTION("spi2", icllp_spi2_groups),
+	FUNCTION("i2c0", icllp_i2c0_groups),
+	FUNCTION("i2c1", icllp_i2c1_groups),
+	FUNCTION("i2c2", icllp_i2c2_groups),
+	FUNCTION("i2c3", icllp_i2c3_groups),
+	FUNCTION("i2c4", icllp_i2c4_groups),
+	FUNCTION("uart0", icllp_uart0_groups),
+	FUNCTION("uart1", icllp_uart1_groups),
+	FUNCTION("uart2", icllp_uart2_groups),
+};
+
+static const struct intel_pinctrl_soc_data icllp_soc_data = {
+	.pins = icllp_pins,
+	.npins = ARRAY_SIZE(icllp_pins),
+	.groups = icllp_groups,
+	.ngroups = ARRAY_SIZE(icllp_groups),
+	.functions = icllp_functions,
+	.nfunctions = ARRAY_SIZE(icllp_functions),
+	.communities = icllp_communities,
+	.ncommunities = ARRAY_SIZE(icllp_communities),
+};
+
+static int icl_pinctrl_probe(struct platform_device *pdev)
+{
+	return intel_pinctrl_probe(pdev, &icllp_soc_data);
+}
+
+static const struct dev_pm_ops icl_pinctrl_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
+				     intel_pinctrl_resume)
+};
+
+static const struct acpi_device_id icl_pinctrl_acpi_match[] = {
+	{ "INT3455" },
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, icl_pinctrl_acpi_match);
+
+static struct platform_driver icl_pinctrl_driver = {
+	.probe = icl_pinctrl_probe,
+	.driver = {
+		.name = "icelake-pinctrl",
+		.acpi_match_table = icl_pinctrl_acpi_match,
+		.pm = &icl_pinctrl_pm_ops,
+	},
+};
+
+module_platform_driver(icl_pinctrl_driver);
+
+MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+MODULE_DESCRIPTION("Intel Ice Lake PCH pinctrl/GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
new file mode 100644
index 0000000..1ea3438
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -0,0 +1,1553 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel pinctrl/GPIO core driver.
+ *
+ * Copyright (C) 2015, Intel Corporation
+ * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
+ *          Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/gpio/driver.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+
+#include "../core.h"
+#include "pinctrl-intel.h"
+
+/* Offset from regs */
+#define REVID				0x000
+#define REVID_SHIFT			16
+#define REVID_MASK			GENMASK(31, 16)
+
+#define PADBAR				0x00c
+#define GPI_IS				0x100
+
+#define PADOWN_BITS			4
+#define PADOWN_SHIFT(p)			((p) % 8 * PADOWN_BITS)
+#define PADOWN_MASK(p)			(0xf << PADOWN_SHIFT(p))
+#define PADOWN_GPP(p)			((p) / 8)
+
+/* Offset from pad_regs */
+#define PADCFG0				0x000
+#define PADCFG0_RXEVCFG_SHIFT		25
+#define PADCFG0_RXEVCFG_MASK		(3 << PADCFG0_RXEVCFG_SHIFT)
+#define PADCFG0_RXEVCFG_LEVEL		0
+#define PADCFG0_RXEVCFG_EDGE		1
+#define PADCFG0_RXEVCFG_DISABLED	2
+#define PADCFG0_RXEVCFG_EDGE_BOTH	3
+#define PADCFG0_PREGFRXSEL		BIT(24)
+#define PADCFG0_RXINV			BIT(23)
+#define PADCFG0_GPIROUTIOXAPIC		BIT(20)
+#define PADCFG0_GPIROUTSCI		BIT(19)
+#define PADCFG0_GPIROUTSMI		BIT(18)
+#define PADCFG0_GPIROUTNMI		BIT(17)
+#define PADCFG0_PMODE_SHIFT		10
+#define PADCFG0_PMODE_MASK		(0xf << PADCFG0_PMODE_SHIFT)
+#define PADCFG0_GPIORXDIS		BIT(9)
+#define PADCFG0_GPIOTXDIS		BIT(8)
+#define PADCFG0_GPIORXSTATE		BIT(1)
+#define PADCFG0_GPIOTXSTATE		BIT(0)
+
+#define PADCFG1				0x004
+#define PADCFG1_TERM_UP			BIT(13)
+#define PADCFG1_TERM_SHIFT		10
+#define PADCFG1_TERM_MASK		(7 << PADCFG1_TERM_SHIFT)
+#define PADCFG1_TERM_20K		4
+#define PADCFG1_TERM_2K			3
+#define PADCFG1_TERM_5K			2
+#define PADCFG1_TERM_1K			1
+
+#define PADCFG2				0x008
+#define PADCFG2_DEBEN			BIT(0)
+#define PADCFG2_DEBOUNCE_SHIFT		1
+#define PADCFG2_DEBOUNCE_MASK		GENMASK(4, 1)
+
+#define DEBOUNCE_PERIOD			31250 /* ns */
+
+struct intel_pad_context {
+	u32 padcfg0;
+	u32 padcfg1;
+	u32 padcfg2;
+};
+
+struct intel_community_context {
+	u32 *intmask;
+};
+
+struct intel_pinctrl_context {
+	struct intel_pad_context *pads;
+	struct intel_community_context *communities;
+};
+
+/**
+ * struct intel_pinctrl - Intel pinctrl private structure
+ * @dev: Pointer to the device structure
+ * @lock: Lock to serialize register access
+ * @pctldesc: Pin controller description
+ * @pctldev: Pointer to the pin controller device
+ * @chip: GPIO chip in this pin controller
+ * @soc: SoC/PCH specific pin configuration data
+ * @communities: All communities in this pin controller
+ * @ncommunities: Number of communities in this pin controller
+ * @context: Configuration saved over system sleep
+ * @irq: pinctrl/GPIO chip irq number
+ */
+struct intel_pinctrl {
+	struct device *dev;
+	raw_spinlock_t lock;
+	struct pinctrl_desc pctldesc;
+	struct pinctrl_dev *pctldev;
+	struct gpio_chip chip;
+	const struct intel_pinctrl_soc_data *soc;
+	struct intel_community *communities;
+	size_t ncommunities;
+	struct intel_pinctrl_context context;
+	int irq;
+};
+
+#define pin_to_padno(c, p)	((p) - (c)->pin_base)
+#define padgroup_offset(g, p)	((p) - (g)->base)
+
+static struct intel_community *intel_get_community(struct intel_pinctrl *pctrl,
+						   unsigned pin)
+{
+	struct intel_community *community;
+	int i;
+
+	for (i = 0; i < pctrl->ncommunities; i++) {
+		community = &pctrl->communities[i];
+		if (pin >= community->pin_base &&
+		    pin < community->pin_base + community->npins)
+			return community;
+	}
+
+	dev_warn(pctrl->dev, "failed to find community for pin %u\n", pin);
+	return NULL;
+}
+
+static const struct intel_padgroup *
+intel_community_get_padgroup(const struct intel_community *community,
+			     unsigned pin)
+{
+	int i;
+
+	for (i = 0; i < community->ngpps; i++) {
+		const struct intel_padgroup *padgrp = &community->gpps[i];
+
+		if (pin >= padgrp->base && pin < padgrp->base + padgrp->size)
+			return padgrp;
+	}
+
+	return NULL;
+}
+
+static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, unsigned pin,
+				      unsigned reg)
+{
+	const struct intel_community *community;
+	unsigned padno;
+	size_t nregs;
+
+	community = intel_get_community(pctrl, pin);
+	if (!community)
+		return NULL;
+
+	padno = pin_to_padno(community, pin);
+	nregs = (community->features & PINCTRL_FEATURE_DEBOUNCE) ? 4 : 2;
+
+	if (reg == PADCFG2 && !(community->features & PINCTRL_FEATURE_DEBOUNCE))
+		return NULL;
+
+	return community->pad_regs + reg + padno * nregs * 4;
+}
+
+static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned pin)
+{
+	const struct intel_community *community;
+	const struct intel_padgroup *padgrp;
+	unsigned gpp, offset, gpp_offset;
+	void __iomem *padown;
+
+	community = intel_get_community(pctrl, pin);
+	if (!community)
+		return false;
+	if (!community->padown_offset)
+		return true;
+
+	padgrp = intel_community_get_padgroup(community, pin);
+	if (!padgrp)
+		return false;
+
+	gpp_offset = padgroup_offset(padgrp, pin);
+	gpp = PADOWN_GPP(gpp_offset);
+	offset = community->padown_offset + padgrp->padown_num * 4 + gpp * 4;
+	padown = community->regs + offset;
+
+	return !(readl(padown) & PADOWN_MASK(gpp_offset));
+}
+
+static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned pin)
+{
+	const struct intel_community *community;
+	const struct intel_padgroup *padgrp;
+	unsigned offset, gpp_offset;
+	void __iomem *hostown;
+
+	community = intel_get_community(pctrl, pin);
+	if (!community)
+		return true;
+	if (!community->hostown_offset)
+		return false;
+
+	padgrp = intel_community_get_padgroup(community, pin);
+	if (!padgrp)
+		return true;
+
+	gpp_offset = padgroup_offset(padgrp, pin);
+	offset = community->hostown_offset + padgrp->reg_num * 4;
+	hostown = community->regs + offset;
+
+	return !(readl(hostown) & BIT(gpp_offset));
+}
+
+static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
+{
+	struct intel_community *community;
+	const struct intel_padgroup *padgrp;
+	unsigned offset, gpp_offset;
+	u32 value;
+
+	community = intel_get_community(pctrl, pin);
+	if (!community)
+		return true;
+	if (!community->padcfglock_offset)
+		return false;
+
+	padgrp = intel_community_get_padgroup(community, pin);
+	if (!padgrp)
+		return true;
+
+	gpp_offset = padgroup_offset(padgrp, pin);
+
+	/*
+	 * If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad,
+	 * the pad is considered unlocked. Any other case means that it is
+	 * either fully or partially locked and we don't touch it.
+	 */
+	offset = community->padcfglock_offset + padgrp->reg_num * 8;
+	value = readl(community->regs + offset);
+	if (value & BIT(gpp_offset))
+		return true;
+
+	offset = community->padcfglock_offset + 4 + padgrp->reg_num * 8;
+	value = readl(community->regs + offset);
+	if (value & BIT(gpp_offset))
+		return true;
+
+	return false;
+}
+
+static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned pin)
+{
+	return intel_pad_owned_by_host(pctrl, pin) &&
+		!intel_pad_locked(pctrl, pin);
+}
+
+static int intel_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctrl->soc->ngroups;
+}
+
+static const char *intel_get_group_name(struct pinctrl_dev *pctldev,
+				      unsigned group)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctrl->soc->groups[group].name;
+}
+
+static int intel_get_group_pins(struct pinctrl_dev *pctldev, unsigned group,
+			      const unsigned **pins, unsigned *npins)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	*pins = pctrl->soc->groups[group].pins;
+	*npins = pctrl->soc->groups[group].npins;
+	return 0;
+}
+
+static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+			       unsigned pin)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	void __iomem *padcfg;
+	u32 cfg0, cfg1, mode;
+	bool locked, acpi;
+
+	if (!intel_pad_owned_by_host(pctrl, pin)) {
+		seq_puts(s, "not available");
+		return;
+	}
+
+	cfg0 = readl(intel_get_padcfg(pctrl, pin, PADCFG0));
+	cfg1 = readl(intel_get_padcfg(pctrl, pin, PADCFG1));
+
+	mode = (cfg0 & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
+	if (!mode)
+		seq_puts(s, "GPIO ");
+	else
+		seq_printf(s, "mode %d ", mode);
+
+	seq_printf(s, "0x%08x 0x%08x", cfg0, cfg1);
+
+	/* Dump the additional PADCFG registers if available */
+	padcfg = intel_get_padcfg(pctrl, pin, PADCFG2);
+	if (padcfg)
+		seq_printf(s, " 0x%08x", readl(padcfg));
+
+	locked = intel_pad_locked(pctrl, pin);
+	acpi = intel_pad_acpi_mode(pctrl, pin);
+
+	if (locked || acpi) {
+		seq_puts(s, " [");
+		if (locked) {
+			seq_puts(s, "LOCKED");
+			if (acpi)
+				seq_puts(s, ", ");
+		}
+		if (acpi)
+			seq_puts(s, "ACPI");
+		seq_puts(s, "]");
+	}
+}
+
+static const struct pinctrl_ops intel_pinctrl_ops = {
+	.get_groups_count = intel_get_groups_count,
+	.get_group_name = intel_get_group_name,
+	.get_group_pins = intel_get_group_pins,
+	.pin_dbg_show = intel_pin_dbg_show,
+};
+
+static int intel_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctrl->soc->nfunctions;
+}
+
+static const char *intel_get_function_name(struct pinctrl_dev *pctldev,
+					   unsigned function)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctrl->soc->functions[function].name;
+}
+
+static int intel_get_function_groups(struct pinctrl_dev *pctldev,
+				     unsigned function,
+				     const char * const **groups,
+				     unsigned * const ngroups)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = pctrl->soc->functions[function].groups;
+	*ngroups = pctrl->soc->functions[function].ngroups;
+	return 0;
+}
+
+static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
+				unsigned group)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	const struct intel_pingroup *grp = &pctrl->soc->groups[group];
+	unsigned long flags;
+	int i;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+	/*
+	 * All pins in the groups needs to be accessible and writable
+	 * before we can enable the mux for this group.
+	 */
+	for (i = 0; i < grp->npins; i++) {
+		if (!intel_pad_usable(pctrl, grp->pins[i])) {
+			raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+			return -EBUSY;
+		}
+	}
+
+	/* Now enable the mux setting for each pin in the group */
+	for (i = 0; i < grp->npins; i++) {
+		void __iomem *padcfg0;
+		u32 value;
+
+		padcfg0 = intel_get_padcfg(pctrl, grp->pins[i], PADCFG0);
+		value = readl(padcfg0);
+
+		value &= ~PADCFG0_PMODE_MASK;
+
+		if (grp->modes)
+			value |= grp->modes[i] << PADCFG0_PMODE_SHIFT;
+		else
+			value |= grp->mode << PADCFG0_PMODE_SHIFT;
+
+		writel(value, padcfg0);
+	}
+
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input)
+{
+	u32 value;
+
+	value = readl(padcfg0);
+	if (input) {
+		value &= ~PADCFG0_GPIORXDIS;
+		value |= PADCFG0_GPIOTXDIS;
+	} else {
+		value &= ~PADCFG0_GPIOTXDIS;
+		value |= PADCFG0_GPIORXDIS;
+	}
+	writel(value, padcfg0);
+}
+
+static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
+{
+	u32 value;
+
+	/* Put the pad into GPIO mode */
+	value = readl(padcfg0) & ~PADCFG0_PMODE_MASK;
+	/* Disable SCI/SMI/NMI generation */
+	value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI);
+	value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI);
+	writel(value, padcfg0);
+}
+
+static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
+				     struct pinctrl_gpio_range *range,
+				     unsigned pin)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	void __iomem *padcfg0;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+	if (!intel_pad_usable(pctrl, pin)) {
+		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+		return -EBUSY;
+	}
+
+	padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
+	intel_gpio_set_gpio_mode(padcfg0);
+	/* Disable TX buffer and enable RX (this will be input) */
+	__intel_gpio_set_direction(padcfg0, true);
+
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int intel_gpio_set_direction(struct pinctrl_dev *pctldev,
+				    struct pinctrl_gpio_range *range,
+				    unsigned pin, bool input)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	void __iomem *padcfg0;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+	padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
+	__intel_gpio_set_direction(padcfg0, input);
+
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static const struct pinmux_ops intel_pinmux_ops = {
+	.get_functions_count = intel_get_functions_count,
+	.get_function_name = intel_get_function_name,
+	.get_function_groups = intel_get_function_groups,
+	.set_mux = intel_pinmux_set_mux,
+	.gpio_request_enable = intel_gpio_request_enable,
+	.gpio_set_direction = intel_gpio_set_direction,
+};
+
+static int intel_config_get(struct pinctrl_dev *pctldev, unsigned pin,
+			    unsigned long *config)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	const struct intel_community *community;
+	u32 value, term;
+	u32 arg = 0;
+
+	if (!intel_pad_owned_by_host(pctrl, pin))
+		return -ENOTSUPP;
+
+	community = intel_get_community(pctrl, pin);
+	value = readl(intel_get_padcfg(pctrl, pin, PADCFG1));
+	term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (term)
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (!term || !(value & PADCFG1_TERM_UP))
+			return -EINVAL;
+
+		switch (term) {
+		case PADCFG1_TERM_1K:
+			arg = 1000;
+			break;
+		case PADCFG1_TERM_2K:
+			arg = 2000;
+			break;
+		case PADCFG1_TERM_5K:
+			arg = 5000;
+			break;
+		case PADCFG1_TERM_20K:
+			arg = 20000;
+			break;
+		}
+
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (!term || value & PADCFG1_TERM_UP)
+			return -EINVAL;
+
+		switch (term) {
+		case PADCFG1_TERM_1K:
+			if (!(community->features & PINCTRL_FEATURE_1K_PD))
+				return -EINVAL;
+			arg = 1000;
+			break;
+		case PADCFG1_TERM_5K:
+			arg = 5000;
+			break;
+		case PADCFG1_TERM_20K:
+			arg = 20000;
+			break;
+		}
+
+		break;
+
+	case PIN_CONFIG_INPUT_DEBOUNCE: {
+		void __iomem *padcfg2;
+		u32 v;
+
+		padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2);
+		if (!padcfg2)
+			return -ENOTSUPP;
+
+		v = readl(padcfg2);
+		if (!(v & PADCFG2_DEBEN))
+			return -EINVAL;
+
+		v = (v & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT;
+		arg = BIT(v) * DEBOUNCE_PERIOD / 1000;
+
+		break;
+	}
+
+	default:
+		return -ENOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, arg);
+	return 0;
+}
+
+static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned pin,
+				 unsigned long config)
+{
+	unsigned param = pinconf_to_config_param(config);
+	unsigned arg = pinconf_to_config_argument(config);
+	const struct intel_community *community;
+	void __iomem *padcfg1;
+	unsigned long flags;
+	int ret = 0;
+	u32 value;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+	community = intel_get_community(pctrl, pin);
+	padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
+	value = readl(padcfg1);
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		value &= ~(PADCFG1_TERM_MASK | PADCFG1_TERM_UP);
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		value &= ~PADCFG1_TERM_MASK;
+
+		value |= PADCFG1_TERM_UP;
+
+		switch (arg) {
+		case 20000:
+			value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT;
+			break;
+		case 5000:
+			value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT;
+			break;
+		case 2000:
+			value |= PADCFG1_TERM_2K << PADCFG1_TERM_SHIFT;
+			break;
+		case 1000:
+			value |= PADCFG1_TERM_1K << PADCFG1_TERM_SHIFT;
+			break;
+		default:
+			ret = -EINVAL;
+		}
+
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		value &= ~(PADCFG1_TERM_UP | PADCFG1_TERM_MASK);
+
+		switch (arg) {
+		case 20000:
+			value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT;
+			break;
+		case 5000:
+			value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT;
+			break;
+		case 1000:
+			if (!(community->features & PINCTRL_FEATURE_1K_PD)) {
+				ret = -EINVAL;
+				break;
+			}
+			value |= PADCFG1_TERM_1K << PADCFG1_TERM_SHIFT;
+			break;
+		default:
+			ret = -EINVAL;
+		}
+
+		break;
+	}
+
+	if (!ret)
+		writel(value, padcfg1);
+
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return ret;
+}
+
+static int intel_config_set_debounce(struct intel_pinctrl *pctrl, unsigned pin,
+				     unsigned debounce)
+{
+	void __iomem *padcfg0, *padcfg2;
+	unsigned long flags;
+	u32 value0, value2;
+	int ret = 0;
+
+	padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2);
+	if (!padcfg2)
+		return -ENOTSUPP;
+
+	padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+	value0 = readl(padcfg0);
+	value2 = readl(padcfg2);
+
+	/* Disable glitch filter and debouncer */
+	value0 &= ~PADCFG0_PREGFRXSEL;
+	value2 &= ~(PADCFG2_DEBEN | PADCFG2_DEBOUNCE_MASK);
+
+	if (debounce) {
+		unsigned long v;
+
+		v = order_base_2(debounce * 1000 / DEBOUNCE_PERIOD);
+		if (v < 3 || v > 15) {
+			ret = -EINVAL;
+			goto exit_unlock;
+		} else {
+			/* Enable glitch filter and debouncer */
+			value0 |= PADCFG0_PREGFRXSEL;
+			value2 |= v << PADCFG2_DEBOUNCE_SHIFT;
+			value2 |= PADCFG2_DEBEN;
+		}
+	}
+
+	writel(value0, padcfg0);
+	writel(value2, padcfg2);
+
+exit_unlock:
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return ret;
+}
+
+static int intel_config_set(struct pinctrl_dev *pctldev, unsigned pin,
+			  unsigned long *configs, unsigned nconfigs)
+{
+	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	int i, ret;
+
+	if (!intel_pad_usable(pctrl, pin))
+		return -ENOTSUPP;
+
+	for (i = 0; i < nconfigs; i++) {
+		switch (pinconf_to_config_param(configs[i])) {
+		case PIN_CONFIG_BIAS_DISABLE:
+		case PIN_CONFIG_BIAS_PULL_UP:
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			ret = intel_config_set_pull(pctrl, pin, configs[i]);
+			if (ret)
+				return ret;
+			break;
+
+		case PIN_CONFIG_INPUT_DEBOUNCE:
+			ret = intel_config_set_debounce(pctrl, pin,
+				pinconf_to_config_argument(configs[i]));
+			if (ret)
+				return ret;
+			break;
+
+		default:
+			return -ENOTSUPP;
+		}
+	}
+
+	return 0;
+}
+
+static const struct pinconf_ops intel_pinconf_ops = {
+	.is_generic = true,
+	.pin_config_get = intel_config_get,
+	.pin_config_set = intel_config_set,
+};
+
+static const struct pinctrl_desc intel_pinctrl_desc = {
+	.pctlops = &intel_pinctrl_ops,
+	.pmxops = &intel_pinmux_ops,
+	.confops = &intel_pinconf_ops,
+	.owner = THIS_MODULE,
+};
+
+/**
+ * intel_gpio_to_pin() - Translate from GPIO offset to pin number
+ * @pctrl: Pinctrl structure
+ * @offset: GPIO offset from gpiolib
+ * @commmunity: Community is filled here if not %NULL
+ * @padgrp: Pad group is filled here if not %NULL
+ *
+ * When coming through gpiolib irqchip, the GPIO offset is not
+ * automatically translated to pinctrl pin number. This function can be
+ * used to find out the corresponding pinctrl pin.
+ */
+static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset,
+			     const struct intel_community **community,
+			     const struct intel_padgroup **padgrp)
+{
+	int i;
+
+	for (i = 0; i < pctrl->ncommunities; i++) {
+		const struct intel_community *comm = &pctrl->communities[i];
+		int j;
+
+		for (j = 0; j < comm->ngpps; j++) {
+			const struct intel_padgroup *pgrp = &comm->gpps[j];
+
+			if (pgrp->gpio_base < 0)
+				continue;
+
+			if (offset >= pgrp->gpio_base &&
+			    offset < pgrp->gpio_base + pgrp->size) {
+				int pin;
+
+				pin = pgrp->base + offset - pgrp->gpio_base;
+				if (community)
+					*community = comm;
+				if (padgrp)
+					*padgrp = pgrp;
+
+				return pin;
+			}
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int intel_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
+	void __iomem *reg;
+	u32 padcfg0;
+	int pin;
+
+	pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
+	if (pin < 0)
+		return -EINVAL;
+
+	reg = intel_get_padcfg(pctrl, pin, PADCFG0);
+	if (!reg)
+		return -EINVAL;
+
+	padcfg0 = readl(reg);
+	if (!(padcfg0 & PADCFG0_GPIOTXDIS))
+		return !!(padcfg0 & PADCFG0_GPIOTXSTATE);
+
+	return !!(padcfg0 & PADCFG0_GPIORXSTATE);
+}
+
+static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
+	unsigned long flags;
+	void __iomem *reg;
+	u32 padcfg0;
+	int pin;
+
+	pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
+	if (pin < 0)
+		return;
+
+	reg = intel_get_padcfg(pctrl, pin, PADCFG0);
+	if (!reg)
+		return;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	padcfg0 = readl(reg);
+	if (value)
+		padcfg0 |= PADCFG0_GPIOTXSTATE;
+	else
+		padcfg0 &= ~PADCFG0_GPIOTXSTATE;
+	writel(padcfg0, reg);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
+	void __iomem *reg;
+	u32 padcfg0;
+	int pin;
+
+	pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
+	if (pin < 0)
+		return -EINVAL;
+
+	reg = intel_get_padcfg(pctrl, pin, PADCFG0);
+	if (!reg)
+		return -EINVAL;
+
+	padcfg0 = readl(reg);
+
+	if (padcfg0 & PADCFG0_PMODE_MASK)
+		return -EINVAL;
+
+	return !!(padcfg0 & PADCFG0_GPIOTXDIS);
+}
+
+static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int intel_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+				       int value)
+{
+	intel_gpio_set(chip, offset, value);
+	return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
+static const struct gpio_chip intel_gpio_chip = {
+	.owner = THIS_MODULE,
+	.request = gpiochip_generic_request,
+	.free = gpiochip_generic_free,
+	.get_direction = intel_gpio_get_direction,
+	.direction_input = intel_gpio_direction_input,
+	.direction_output = intel_gpio_direction_output,
+	.get = intel_gpio_get,
+	.set = intel_gpio_set,
+	.set_config = gpiochip_generic_config,
+};
+
+static void intel_gpio_irq_ack(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+	const struct intel_community *community;
+	const struct intel_padgroup *padgrp;
+	int pin;
+
+	pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
+	if (pin >= 0) {
+		unsigned gpp, gpp_offset, is_offset;
+
+		gpp = padgrp->reg_num;
+		gpp_offset = padgroup_offset(padgrp, pin);
+		is_offset = community->is_offset + gpp * 4;
+
+		raw_spin_lock(&pctrl->lock);
+		writel(BIT(gpp_offset), community->regs + is_offset);
+		raw_spin_unlock(&pctrl->lock);
+	}
+}
+
+static void intel_gpio_irq_enable(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+	const struct intel_community *community;
+	const struct intel_padgroup *padgrp;
+	int pin;
+
+	pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
+	if (pin >= 0) {
+		unsigned gpp, gpp_offset, is_offset;
+		unsigned long flags;
+		u32 value;
+
+		gpp = padgrp->reg_num;
+		gpp_offset = padgroup_offset(padgrp, pin);
+		is_offset = community->is_offset + gpp * 4;
+
+		raw_spin_lock_irqsave(&pctrl->lock, flags);
+		/* Clear interrupt status first to avoid unexpected interrupt */
+		writel(BIT(gpp_offset), community->regs + is_offset);
+
+		value = readl(community->regs + community->ie_offset + gpp * 4);
+		value |= BIT(gpp_offset);
+		writel(value, community->regs + community->ie_offset + gpp * 4);
+		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	}
+}
+
+static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+	const struct intel_community *community;
+	const struct intel_padgroup *padgrp;
+	int pin;
+
+	pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
+	if (pin >= 0) {
+		unsigned gpp, gpp_offset;
+		unsigned long flags;
+		void __iomem *reg;
+		u32 value;
+
+		gpp = padgrp->reg_num;
+		gpp_offset = padgroup_offset(padgrp, pin);
+
+		reg = community->regs + community->ie_offset + gpp * 4;
+
+		raw_spin_lock_irqsave(&pctrl->lock, flags);
+		value = readl(reg);
+		if (mask)
+			value &= ~BIT(gpp_offset);
+		else
+			value |= BIT(gpp_offset);
+		writel(value, reg);
+		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	}
+}
+
+static void intel_gpio_irq_mask(struct irq_data *d)
+{
+	intel_gpio_irq_mask_unmask(d, true);
+}
+
+static void intel_gpio_irq_unmask(struct irq_data *d)
+{
+	intel_gpio_irq_mask_unmask(d, false);
+}
+
+static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+	unsigned pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
+	unsigned long flags;
+	void __iomem *reg;
+	u32 value;
+
+	reg = intel_get_padcfg(pctrl, pin, PADCFG0);
+	if (!reg)
+		return -EINVAL;
+
+	/*
+	 * If the pin is in ACPI mode it is still usable as a GPIO but it
+	 * cannot be used as IRQ because GPI_IS status bit will not be
+	 * updated by the host controller hardware.
+	 */
+	if (intel_pad_acpi_mode(pctrl, pin)) {
+		dev_warn(pctrl->dev, "pin %u cannot be used as IRQ\n", pin);
+		return -EPERM;
+	}
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+	intel_gpio_set_gpio_mode(reg);
+
+	value = readl(reg);
+
+	value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV);
+
+	if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
+		value |= PADCFG0_RXEVCFG_EDGE_BOTH << PADCFG0_RXEVCFG_SHIFT;
+	} else if (type & IRQ_TYPE_EDGE_FALLING) {
+		value |= PADCFG0_RXEVCFG_EDGE << PADCFG0_RXEVCFG_SHIFT;
+		value |= PADCFG0_RXINV;
+	} else if (type & IRQ_TYPE_EDGE_RISING) {
+		value |= PADCFG0_RXEVCFG_EDGE << PADCFG0_RXEVCFG_SHIFT;
+	} else if (type & IRQ_TYPE_LEVEL_MASK) {
+		if (type & IRQ_TYPE_LEVEL_LOW)
+			value |= PADCFG0_RXINV;
+	} else {
+		value |= PADCFG0_RXEVCFG_DISABLED << PADCFG0_RXEVCFG_SHIFT;
+	}
+
+	writel(value, reg);
+
+	if (type & IRQ_TYPE_EDGE_BOTH)
+		irq_set_handler_locked(d, handle_edge_irq);
+	else if (type & IRQ_TYPE_LEVEL_MASK)
+		irq_set_handler_locked(d, handle_level_irq);
+
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+	unsigned pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
+
+	if (on)
+		enable_irq_wake(pctrl->irq);
+	else
+		disable_irq_wake(pctrl->irq);
+
+	dev_dbg(pctrl->dev, "%sable wake for pin %u\n", on ? "en" : "dis", pin);
+	return 0;
+}
+
+static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
+	const struct intel_community *community)
+{
+	struct gpio_chip *gc = &pctrl->chip;
+	irqreturn_t ret = IRQ_NONE;
+	int gpp;
+
+	for (gpp = 0; gpp < community->ngpps; gpp++) {
+		const struct intel_padgroup *padgrp = &community->gpps[gpp];
+		unsigned long pending, enabled, gpp_offset;
+
+		pending = readl(community->regs + community->is_offset +
+				padgrp->reg_num * 4);
+		enabled = readl(community->regs + community->ie_offset +
+				padgrp->reg_num * 4);
+
+		/* Only interrupts that are enabled */
+		pending &= enabled;
+
+		for_each_set_bit(gpp_offset, &pending, padgrp->size) {
+			unsigned irq;
+
+			irq = irq_find_mapping(gc->irq.domain,
+					       padgrp->gpio_base + gpp_offset);
+			generic_handle_irq(irq);
+
+			ret |= IRQ_HANDLED;
+		}
+	}
+
+	return ret;
+}
+
+static irqreturn_t intel_gpio_irq(int irq, void *data)
+{
+	const struct intel_community *community;
+	struct intel_pinctrl *pctrl = data;
+	irqreturn_t ret = IRQ_NONE;
+	int i;
+
+	/* Need to check all communities for pending interrupts */
+	for (i = 0; i < pctrl->ncommunities; i++) {
+		community = &pctrl->communities[i];
+		ret |= intel_gpio_community_irq_handler(pctrl, community);
+	}
+
+	return ret;
+}
+
+static struct irq_chip intel_gpio_irqchip = {
+	.name = "intel-gpio",
+	.irq_enable = intel_gpio_irq_enable,
+	.irq_ack = intel_gpio_irq_ack,
+	.irq_mask = intel_gpio_irq_mask,
+	.irq_unmask = intel_gpio_irq_unmask,
+	.irq_set_type = intel_gpio_irq_type,
+	.irq_set_wake = intel_gpio_irq_wake,
+	.flags = IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl,
+				     const struct intel_community *community)
+{
+	int ret = 0, i;
+
+	for (i = 0; i < community->ngpps; i++) {
+		const struct intel_padgroup *gpp = &community->gpps[i];
+
+		if (gpp->gpio_base < 0)
+			continue;
+
+		ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
+					     gpp->gpio_base, gpp->base,
+					     gpp->size);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static unsigned intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
+{
+	const struct intel_community *community;
+	unsigned ngpio = 0;
+	int i, j;
+
+	for (i = 0; i < pctrl->ncommunities; i++) {
+		community = &pctrl->communities[i];
+		for (j = 0; j < community->ngpps; j++) {
+			const struct intel_padgroup *gpp = &community->gpps[j];
+
+			if (gpp->gpio_base < 0)
+				continue;
+
+			if (gpp->gpio_base + gpp->size > ngpio)
+				ngpio = gpp->gpio_base + gpp->size;
+		}
+	}
+
+	return ngpio;
+}
+
+static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
+{
+	int ret, i;
+
+	pctrl->chip = intel_gpio_chip;
+
+	pctrl->chip.ngpio = intel_gpio_ngpio(pctrl);
+	pctrl->chip.label = dev_name(pctrl->dev);
+	pctrl->chip.parent = pctrl->dev;
+	pctrl->chip.base = -1;
+	pctrl->irq = irq;
+
+	ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl);
+	if (ret) {
+		dev_err(pctrl->dev, "failed to register gpiochip\n");
+		return ret;
+	}
+
+	for (i = 0; i < pctrl->ncommunities; i++) {
+		struct intel_community *community = &pctrl->communities[i];
+
+		ret = intel_gpio_add_pin_ranges(pctrl, community);
+		if (ret) {
+			dev_err(pctrl->dev, "failed to add GPIO pin range\n");
+			return ret;
+		}
+	}
+
+	/*
+	 * We need to request the interrupt here (instead of providing chip
+	 * to the irq directly) because on some platforms several GPIO
+	 * controllers share the same interrupt line.
+	 */
+	ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq,
+			       IRQF_SHARED | IRQF_NO_THREAD,
+			       dev_name(pctrl->dev), pctrl);
+	if (ret) {
+		dev_err(pctrl->dev, "failed to request interrupt\n");
+		return ret;
+	}
+
+	ret = gpiochip_irqchip_add(&pctrl->chip, &intel_gpio_irqchip, 0,
+				   handle_bad_irq, IRQ_TYPE_NONE);
+	if (ret) {
+		dev_err(pctrl->dev, "failed to add irqchip\n");
+		return ret;
+	}
+
+	gpiochip_set_chained_irqchip(&pctrl->chip, &intel_gpio_irqchip, irq,
+				     NULL);
+	return 0;
+}
+
+static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl,
+				       struct intel_community *community)
+{
+	struct intel_padgroup *gpps;
+	unsigned npins = community->npins;
+	unsigned padown_num = 0;
+	size_t ngpps, i;
+
+	if (community->gpps)
+		ngpps = community->ngpps;
+	else
+		ngpps = DIV_ROUND_UP(community->npins, community->gpp_size);
+
+	gpps = devm_kcalloc(pctrl->dev, ngpps, sizeof(*gpps), GFP_KERNEL);
+	if (!gpps)
+		return -ENOMEM;
+
+	for (i = 0; i < ngpps; i++) {
+		if (community->gpps) {
+			gpps[i] = community->gpps[i];
+		} else {
+			unsigned gpp_size = community->gpp_size;
+
+			gpps[i].reg_num = i;
+			gpps[i].base = community->pin_base + i * gpp_size;
+			gpps[i].size = min(gpp_size, npins);
+			npins -= gpps[i].size;
+		}
+
+		if (gpps[i].size > 32)
+			return -EINVAL;
+
+		if (!gpps[i].gpio_base)
+			gpps[i].gpio_base = gpps[i].base;
+
+		gpps[i].padown_num = padown_num;
+
+		/*
+		 * In older hardware the number of padown registers per
+		 * group is fixed regardless of the group size.
+		 */
+		if (community->gpp_num_padown_regs)
+			padown_num += community->gpp_num_padown_regs;
+		else
+			padown_num += DIV_ROUND_UP(gpps[i].size * 4, 32);
+	}
+
+	community->ngpps = ngpps;
+	community->gpps = gpps;
+
+	return 0;
+}
+
+static int intel_pinctrl_pm_init(struct intel_pinctrl *pctrl)
+{
+#ifdef CONFIG_PM_SLEEP
+	const struct intel_pinctrl_soc_data *soc = pctrl->soc;
+	struct intel_community_context *communities;
+	struct intel_pad_context *pads;
+	int i;
+
+	pads = devm_kcalloc(pctrl->dev, soc->npins, sizeof(*pads), GFP_KERNEL);
+	if (!pads)
+		return -ENOMEM;
+
+	communities = devm_kcalloc(pctrl->dev, pctrl->ncommunities,
+				   sizeof(*communities), GFP_KERNEL);
+	if (!communities)
+		return -ENOMEM;
+
+
+	for (i = 0; i < pctrl->ncommunities; i++) {
+		struct intel_community *community = &pctrl->communities[i];
+		u32 *intmask;
+
+		intmask = devm_kcalloc(pctrl->dev, community->ngpps,
+				       sizeof(*intmask), GFP_KERNEL);
+		if (!intmask)
+			return -ENOMEM;
+
+		communities[i].intmask = intmask;
+	}
+
+	pctrl->context.pads = pads;
+	pctrl->context.communities = communities;
+#endif
+
+	return 0;
+}
+
+int intel_pinctrl_probe(struct platform_device *pdev,
+			const struct intel_pinctrl_soc_data *soc_data)
+{
+	struct intel_pinctrl *pctrl;
+	int i, ret, irq;
+
+	if (!soc_data)
+		return -EINVAL;
+
+	pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
+	if (!pctrl)
+		return -ENOMEM;
+
+	pctrl->dev = &pdev->dev;
+	pctrl->soc = soc_data;
+	raw_spin_lock_init(&pctrl->lock);
+
+	/*
+	 * Make a copy of the communities which we can use to hold pointers
+	 * to the registers.
+	 */
+	pctrl->ncommunities = pctrl->soc->ncommunities;
+	pctrl->communities = devm_kcalloc(&pdev->dev, pctrl->ncommunities,
+				  sizeof(*pctrl->communities), GFP_KERNEL);
+	if (!pctrl->communities)
+		return -ENOMEM;
+
+	for (i = 0; i < pctrl->ncommunities; i++) {
+		struct intel_community *community = &pctrl->communities[i];
+		struct resource *res;
+		void __iomem *regs;
+		u32 padbar;
+
+		*community = pctrl->soc->communities[i];
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM,
+					    community->barno);
+		regs = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(regs))
+			return PTR_ERR(regs);
+
+		/*
+		 * Determine community features based on the revision if
+		 * not specified already.
+		 */
+		if (!community->features) {
+			u32 rev;
+
+			rev = (readl(regs + REVID) & REVID_MASK) >> REVID_SHIFT;
+			if (rev >= 0x94) {
+				community->features |= PINCTRL_FEATURE_DEBOUNCE;
+				community->features |= PINCTRL_FEATURE_1K_PD;
+			}
+		}
+
+		/* Read offset of the pad configuration registers */
+		padbar = readl(regs + PADBAR);
+
+		community->regs = regs;
+		community->pad_regs = regs + padbar;
+
+		if (!community->is_offset)
+			community->is_offset = GPI_IS;
+
+		ret = intel_pinctrl_add_padgroups(pctrl, community);
+		if (ret)
+			return ret;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get interrupt number\n");
+		return irq;
+	}
+
+	ret = intel_pinctrl_pm_init(pctrl);
+	if (ret)
+		return ret;
+
+	pctrl->pctldesc = intel_pinctrl_desc;
+	pctrl->pctldesc.name = dev_name(&pdev->dev);
+	pctrl->pctldesc.pins = pctrl->soc->pins;
+	pctrl->pctldesc.npins = pctrl->soc->npins;
+
+	pctrl->pctldev = devm_pinctrl_register(&pdev->dev, &pctrl->pctldesc,
+					       pctrl);
+	if (IS_ERR(pctrl->pctldev)) {
+		dev_err(&pdev->dev, "failed to register pinctrl driver\n");
+		return PTR_ERR(pctrl->pctldev);
+	}
+
+	ret = intel_gpio_probe(pctrl, irq);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, pctrl);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(intel_pinctrl_probe);
+
+#ifdef CONFIG_PM_SLEEP
+static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned pin)
+{
+	const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin);
+
+	if (!pd || !intel_pad_usable(pctrl, pin))
+		return false;
+
+	/*
+	 * Only restore the pin if it is actually in use by the kernel (or
+	 * by userspace). It is possible that some pins are used by the
+	 * BIOS during resume and those are not always locked down so leave
+	 * them alone.
+	 */
+	if (pd->mux_owner || pd->gpio_owner ||
+	    gpiochip_line_is_irq(&pctrl->chip, pin))
+		return true;
+
+	return false;
+}
+
+int intel_pinctrl_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct intel_pinctrl *pctrl = platform_get_drvdata(pdev);
+	struct intel_community_context *communities;
+	struct intel_pad_context *pads;
+	int i;
+
+	pads = pctrl->context.pads;
+	for (i = 0; i < pctrl->soc->npins; i++) {
+		const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i];
+		void __iomem *padcfg;
+		u32 val;
+
+		if (!intel_pinctrl_should_save(pctrl, desc->number))
+			continue;
+
+		val = readl(intel_get_padcfg(pctrl, desc->number, PADCFG0));
+		pads[i].padcfg0 = val & ~PADCFG0_GPIORXSTATE;
+		val = readl(intel_get_padcfg(pctrl, desc->number, PADCFG1));
+		pads[i].padcfg1 = val;
+
+		padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG2);
+		if (padcfg)
+			pads[i].padcfg2 = readl(padcfg);
+	}
+
+	communities = pctrl->context.communities;
+	for (i = 0; i < pctrl->ncommunities; i++) {
+		struct intel_community *community = &pctrl->communities[i];
+		void __iomem *base;
+		unsigned gpp;
+
+		base = community->regs + community->ie_offset;
+		for (gpp = 0; gpp < community->ngpps; gpp++)
+			communities[i].intmask[gpp] = readl(base + gpp * 4);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(intel_pinctrl_suspend);
+
+static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
+{
+	size_t i;
+
+	for (i = 0; i < pctrl->ncommunities; i++) {
+		const struct intel_community *community;
+		void __iomem *base;
+		unsigned gpp;
+
+		community = &pctrl->communities[i];
+		base = community->regs;
+
+		for (gpp = 0; gpp < community->ngpps; gpp++) {
+			/* Mask and clear all interrupts */
+			writel(0, base + community->ie_offset + gpp * 4);
+			writel(0xffff, base + community->is_offset + gpp * 4);
+		}
+	}
+}
+
+int intel_pinctrl_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct intel_pinctrl *pctrl = platform_get_drvdata(pdev);
+	const struct intel_community_context *communities;
+	const struct intel_pad_context *pads;
+	int i;
+
+	/* Mask all interrupts */
+	intel_gpio_irq_init(pctrl);
+
+	pads = pctrl->context.pads;
+	for (i = 0; i < pctrl->soc->npins; i++) {
+		const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i];
+		void __iomem *padcfg;
+		u32 val;
+
+		if (!intel_pinctrl_should_save(pctrl, desc->number))
+			continue;
+
+		padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG0);
+		val = readl(padcfg) & ~PADCFG0_GPIORXSTATE;
+		if (val != pads[i].padcfg0) {
+			writel(pads[i].padcfg0, padcfg);
+			dev_dbg(dev, "restored pin %u padcfg0 %#08x\n",
+				desc->number, readl(padcfg));
+		}
+
+		padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG1);
+		val = readl(padcfg);
+		if (val != pads[i].padcfg1) {
+			writel(pads[i].padcfg1, padcfg);
+			dev_dbg(dev, "restored pin %u padcfg1 %#08x\n",
+				desc->number, readl(padcfg));
+		}
+
+		padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG2);
+		if (padcfg) {
+			val = readl(padcfg);
+			if (val != pads[i].padcfg2) {
+				writel(pads[i].padcfg2, padcfg);
+				dev_dbg(dev, "restored pin %u padcfg2 %#08x\n",
+					desc->number, readl(padcfg));
+			}
+		}
+	}
+
+	communities = pctrl->context.communities;
+	for (i = 0; i < pctrl->ncommunities; i++) {
+		struct intel_community *community = &pctrl->communities[i];
+		void __iomem *base;
+		unsigned gpp;
+
+		base = community->regs + community->ie_offset;
+		for (gpp = 0; gpp < community->ngpps; gpp++) {
+			writel(communities[i].intmask[gpp], base + gpp * 4);
+			dev_dbg(dev, "restored mask %d/%u %#08x\n", i, gpp,
+				readl(base + gpp * 4));
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(intel_pinctrl_resume);
+#endif
+
+MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>");
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+MODULE_DESCRIPTION("Intel pinctrl/GPIO core driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h
new file mode 100644
index 0000000..1785abf
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-intel.h
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Core pinctrl/GPIO driver for Intel GPIO controllers
+ *
+ * Copyright (C) 2015, Intel Corporation
+ * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
+ *          Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#ifndef PINCTRL_INTEL_H
+#define PINCTRL_INTEL_H
+
+struct pinctrl_pin_desc;
+struct platform_device;
+struct device;
+
+/**
+ * struct intel_pingroup - Description about group of pins
+ * @name: Name of the groups
+ * @pins: All pins in this group
+ * @npins: Number of pins in this groups
+ * @mode: Native mode in which the group is muxed out @pins. Used if @modes
+ *        is %NULL.
+ * @modes: If not %NULL this will hold mode for each pin in @pins
+ */
+struct intel_pingroup {
+	const char *name;
+	const unsigned *pins;
+	size_t npins;
+	unsigned short mode;
+	const unsigned *modes;
+};
+
+/**
+ * struct intel_function - Description about a function
+ * @name: Name of the function
+ * @groups: An array of groups for this function
+ * @ngroups: Number of groups in @groups
+ */
+struct intel_function {
+	const char *name;
+	const char * const *groups;
+	size_t ngroups;
+};
+
+/**
+ * struct intel_padgroup - Hardware pad group information
+ * @reg_num: GPI_IS register number
+ * @base: Starting pin of this group
+ * @size: Size of this group (maximum is 32).
+ * @gpio_base: Starting GPIO base of this group (%0 if matches with @base,
+ *	       and %-1 if no GPIO mapping should be created)
+ * @padown_num: PAD_OWN register number (assigned by the core driver)
+ *
+ * If pad groups of a community are not the same size, use this structure
+ * to specify them.
+ */
+struct intel_padgroup {
+	unsigned reg_num;
+	unsigned base;
+	unsigned size;
+	int gpio_base;
+	unsigned padown_num;
+};
+
+/**
+ * struct intel_community - Intel pin community description
+ * @barno: MMIO BAR number where registers for this community reside
+ * @padown_offset: Register offset of PAD_OWN register from @regs. If %0
+ *                 then there is no support for owner.
+ * @padcfglock_offset: Register offset of PADCFGLOCK from @regs. If %0 then
+ *                     locking is not supported.
+ * @hostown_offset: Register offset of HOSTSW_OWN from @regs. If %0 then it
+ *                  is assumed that the host owns the pin (rather than
+ *                  ACPI).
+ * @is_offset: Register offset of GPI_IS from @regs. If %0 then uses the
+ *             default (%0x100).
+ * @ie_offset: Register offset of GPI_IE from @regs.
+ * @pin_base: Starting pin of pins in this community
+ * @gpp_size: Maximum number of pads in each group, such as PADCFGLOCK,
+ *            HOSTSW_OWN,  GPI_IS, GPI_IE, etc. Used when @gpps is %NULL.
+ * @gpp_num_padown_regs: Number of pad registers each pad group consumes at
+ *			 minimum. Use %0 if the number of registers can be
+ *			 determined by the size of the group.
+ * @npins: Number of pins in this community
+ * @features: Additional features supported by the hardware
+ * @gpps: Pad groups if the controller has variable size pad groups
+ * @ngpps: Number of pad groups in this community
+ * @regs: Community specific common registers (reserved for core driver)
+ * @pad_regs: Community specific pad registers (reserved for core driver)
+ *
+ * Most Intel GPIO host controllers this driver supports each pad group is
+ * of equal size (except the last one). In that case the driver can just
+ * fill in @gpp_size field and let the core driver to handle the rest. If
+ * the controller has pad groups of variable size the client driver can
+ * pass custom @gpps and @ngpps instead.
+ */
+struct intel_community {
+	unsigned barno;
+	unsigned padown_offset;
+	unsigned padcfglock_offset;
+	unsigned hostown_offset;
+	unsigned is_offset;
+	unsigned ie_offset;
+	unsigned pin_base;
+	unsigned gpp_size;
+	unsigned gpp_num_padown_regs;
+	size_t npins;
+	unsigned features;
+	const struct intel_padgroup *gpps;
+	size_t ngpps;
+	/* Reserved for the core driver */
+	void __iomem *regs;
+	void __iomem *pad_regs;
+};
+
+/* Additional features supported by the hardware */
+#define PINCTRL_FEATURE_DEBOUNCE	BIT(0)
+#define PINCTRL_FEATURE_1K_PD		BIT(1)
+
+/**
+ * PIN_GROUP - Declare a pin group
+ * @n: Name of the group
+ * @p: An array of pins this group consists
+ * @m: Mode which the pins are put when this group is active. Can be either
+ *     a single integer or an array of integers in which case mode is per
+ *     pin.
+ */
+#define PIN_GROUP(n, p, m)					\
+	{							\
+		.name = (n),					\
+		.pins = (p),					\
+		.npins = ARRAY_SIZE((p)),			\
+		.mode = __builtin_choose_expr(			\
+			__builtin_constant_p((m)), (m), 0),	\
+		.modes = __builtin_choose_expr(			\
+			__builtin_constant_p((m)), NULL, (m)),	\
+	}
+
+#define FUNCTION(n, g)				\
+	{					\
+		.name = (n),			\
+		.groups = (g),			\
+		.ngroups = ARRAY_SIZE((g)),	\
+	}
+
+/**
+ * struct intel_pinctrl_soc_data - Intel pin controller per-SoC configuration
+ * @uid: ACPI _UID for the probe driver use if needed
+ * @pins: Array if pins this pinctrl controls
+ * @npins: Number of pins in the array
+ * @groups: Array of pin groups
+ * @ngroups: Number of groups in the array
+ * @functions: Array of functions
+ * @nfunctions: Number of functions in the array
+ * @communities: Array of communities this pinctrl handles
+ * @ncommunities: Number of communities in the array
+ *
+ * The @communities is used as a template by the core driver. It will make
+ * copy of all communities and fill in rest of the information.
+ */
+struct intel_pinctrl_soc_data {
+	const char *uid;
+	const struct pinctrl_pin_desc *pins;
+	size_t npins;
+	const struct intel_pingroup *groups;
+	size_t ngroups;
+	const struct intel_function *functions;
+	size_t nfunctions;
+	const struct intel_community *communities;
+	size_t ncommunities;
+};
+
+int intel_pinctrl_probe(struct platform_device *pdev,
+			const struct intel_pinctrl_soc_data *soc_data);
+#ifdef CONFIG_PM_SLEEP
+int intel_pinctrl_suspend(struct device *dev);
+int intel_pinctrl_resume(struct device *dev);
+#endif
+
+#endif /* PINCTRL_INTEL_H */
diff --git a/drivers/pinctrl/intel/pinctrl-lewisburg.c b/drivers/pinctrl/intel/pinctrl-lewisburg.c
new file mode 100644
index 0000000..9989464
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-lewisburg.c
@@ -0,0 +1,340 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Lewisburg pinctrl/GPIO driver
+ *
+ * Copyright (C) 2017, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-intel.h"
+
+#define LBG_PAD_OWN	0x020
+#define LBG_PADCFGLOCK	0x060
+#define LBG_HOSTSW_OWN	0x080
+#define LBG_GPI_IE	0x110
+
+#define LBG_COMMUNITY(b, s, e)				\
+	{						\
+		.barno = (b),				\
+		.padown_offset = LBG_PAD_OWN,		\
+		.padcfglock_offset = LBG_PADCFGLOCK,	\
+		.hostown_offset = LBG_HOSTSW_OWN,	\
+		.ie_offset = LBG_GPI_IE,		\
+		.gpp_size = 24,				\
+		.pin_base = (s),			\
+		.npins = ((e) - (s) + 1),		\
+	}
+
+static const struct pinctrl_pin_desc lbg_pins[] = {
+	/* GPP_A */
+	PINCTRL_PIN(0, "RCINB"),
+	PINCTRL_PIN(1, "LAD_0"),
+	PINCTRL_PIN(2, "LAD_1"),
+	PINCTRL_PIN(3, "LAD_2"),
+	PINCTRL_PIN(4, "LAD_3"),
+	PINCTRL_PIN(5, "LFRAMEB"),
+	PINCTRL_PIN(6, "SERIRQ"),
+	PINCTRL_PIN(7, "PIRQAB"),
+	PINCTRL_PIN(8, "CLKRUNB"),
+	PINCTRL_PIN(9, "CLKOUT_LPC_0"),
+	PINCTRL_PIN(10, "CLKOUT_LPC_1"),
+	PINCTRL_PIN(11, "PMEB"),
+	PINCTRL_PIN(12, "BM_BUSYB"),
+	PINCTRL_PIN(13, "SUSWARNB_SUSPWRDNACK"),
+	PINCTRL_PIN(14, "ESPI_RESETB"),
+	PINCTRL_PIN(15, "SUSACKB"),
+	PINCTRL_PIN(16, "CLKOUT_LPC_2"),
+	PINCTRL_PIN(17, "GPP_A_17"),
+	PINCTRL_PIN(18, "GPP_A_18"),
+	PINCTRL_PIN(19, "GPP_A_19"),
+	PINCTRL_PIN(20, "GPP_A_20"),
+	PINCTRL_PIN(21, "GPP_A_21"),
+	PINCTRL_PIN(22, "GPP_A_22"),
+	PINCTRL_PIN(23, "GPP_A_23"),
+	/* GPP_B */
+	PINCTRL_PIN(24, "CORE_VID_0"),
+	PINCTRL_PIN(25, "CORE_VID_1"),
+	PINCTRL_PIN(26, "VRALERTB"),
+	PINCTRL_PIN(27, "CPU_GP_2"),
+	PINCTRL_PIN(28, "CPU_GP_3"),
+	PINCTRL_PIN(29, "SRCCLKREQB_0"),
+	PINCTRL_PIN(30, "SRCCLKREQB_1"),
+	PINCTRL_PIN(31, "SRCCLKREQB_2"),
+	PINCTRL_PIN(32, "SRCCLKREQB_3"),
+	PINCTRL_PIN(33, "SRCCLKREQB_4"),
+	PINCTRL_PIN(34, "SRCCLKREQB_5"),
+	PINCTRL_PIN(35, "GPP_B_11"),
+	PINCTRL_PIN(36, "GLB_RST_WARN_N"),
+	PINCTRL_PIN(37, "PLTRSTB"),
+	PINCTRL_PIN(38, "SPKR"),
+	PINCTRL_PIN(39, "GPP_B_15"),
+	PINCTRL_PIN(40, "GPP_B_16"),
+	PINCTRL_PIN(41, "GPP_B_17"),
+	PINCTRL_PIN(42, "GPP_B_18"),
+	PINCTRL_PIN(43, "GPP_B_19"),
+	PINCTRL_PIN(44, "GPP_B_20"),
+	PINCTRL_PIN(45, "GPP_B_21"),
+	PINCTRL_PIN(46, "GPP_B_22"),
+	PINCTRL_PIN(47, "SML1ALERTB"),
+	/* GPP_F */
+	PINCTRL_PIN(48, "SATAXPCIE_3"),
+	PINCTRL_PIN(49, "SATAXPCIE_4"),
+	PINCTRL_PIN(50, "SATAXPCIE_5"),
+	PINCTRL_PIN(51, "SATAXPCIE_6"),
+	PINCTRL_PIN(52, "SATAXPCIE_7"),
+	PINCTRL_PIN(53, "SATA_DEVSLP_3"),
+	PINCTRL_PIN(54, "SATA_DEVSLP_4"),
+	PINCTRL_PIN(55, "SATA_DEVSLP_5"),
+	PINCTRL_PIN(56, "SATA_DEVSLP_6"),
+	PINCTRL_PIN(57, "SATA_DEVSLP_7"),
+	PINCTRL_PIN(58, "SATA_SCLOCK"),
+	PINCTRL_PIN(59, "SATA_SLOAD"),
+	PINCTRL_PIN(60, "SATA_SDATAOUT1"),
+	PINCTRL_PIN(61, "SATA_SDATAOUT0"),
+	PINCTRL_PIN(62, "SSATA_LEDB"),
+	PINCTRL_PIN(63, "USB2_OCB_4"),
+	PINCTRL_PIN(64, "USB2_OCB_5"),
+	PINCTRL_PIN(65, "USB2_OCB_6"),
+	PINCTRL_PIN(66, "USB2_OCB_7"),
+	PINCTRL_PIN(67, "GBE_SMBUS_CLK"),
+	PINCTRL_PIN(68, "GBE_SMBDATA"),
+	PINCTRL_PIN(69, "GBE_SMBALRTN"),
+	PINCTRL_PIN(70, "SSATA_SCLOCK"),
+	PINCTRL_PIN(71, "SSATA_SLOAD"),
+	/* GPP_C */
+	PINCTRL_PIN(72, "SMBCLK"),
+	PINCTRL_PIN(73, "SMBDATA"),
+	PINCTRL_PIN(74, "SMBALERTB"),
+	PINCTRL_PIN(75, "SML0CLK"),
+	PINCTRL_PIN(76, "SML0DATA"),
+	PINCTRL_PIN(77, "SML0ALERTB"),
+	PINCTRL_PIN(78, "SML1CLK"),
+	PINCTRL_PIN(79, "SML1DATA"),
+	PINCTRL_PIN(80, "GPP_C_8"),
+	PINCTRL_PIN(81, "GPP_C_9"),
+	PINCTRL_PIN(82, "GPP_C_10"),
+	PINCTRL_PIN(83, "GPP_C_11"),
+	PINCTRL_PIN(84, "GPP_C_12"),
+	PINCTRL_PIN(85, "GPP_C_13"),
+	PINCTRL_PIN(86, "GPP_C_14"),
+	PINCTRL_PIN(87, "GPP_C_15"),
+	PINCTRL_PIN(88, "GPP_C_16"),
+	PINCTRL_PIN(89, "GPP_C_17"),
+	PINCTRL_PIN(90, "GPP_C_18"),
+	PINCTRL_PIN(91, "GPP_C_19"),
+	PINCTRL_PIN(92, "GPP_C_20"),
+	PINCTRL_PIN(93, "GPP_C_21"),
+	PINCTRL_PIN(94, "GPP_C_22"),
+	PINCTRL_PIN(95, "GPP_C_23"),
+	/* GPP_D */
+	PINCTRL_PIN(96, "GPP_D_0"),
+	PINCTRL_PIN(97, "GPP_D_1"),
+	PINCTRL_PIN(98, "GPP_D_2"),
+	PINCTRL_PIN(99, "GPP_D_3"),
+	PINCTRL_PIN(100, "GPP_D_4"),
+	PINCTRL_PIN(101, "SSP0_SFRM"),
+	PINCTRL_PIN(102, "SSP0_TXD"),
+	PINCTRL_PIN(103, "SSP0_RXD"),
+	PINCTRL_PIN(104, "SSP0_SCLK"),
+	PINCTRL_PIN(105, "SSATA_DEVSLP_3"),
+	PINCTRL_PIN(106, "SSATA_DEVSLP_4"),
+	PINCTRL_PIN(107, "SSATA_DEVSLP_5"),
+	PINCTRL_PIN(108, "SSATA_SDATAOUT1"),
+	PINCTRL_PIN(109, "SML0BCLK_SML0BCLKIE"),
+	PINCTRL_PIN(110, "SML0BDATA_SML0BDATAIE"),
+	PINCTRL_PIN(111, "SSATA_SDATAOUT0"),
+	PINCTRL_PIN(112, "SML0BALERTB_SML0BALERTBIE"),
+	PINCTRL_PIN(113, "DMIC_CLK_1"),
+	PINCTRL_PIN(114, "DMIC_DATA_1"),
+	PINCTRL_PIN(115, "DMIC_CLK_0"),
+	PINCTRL_PIN(116, "DMIC_DATA_0"),
+	PINCTRL_PIN(117, "IE_UART_RXD"),
+	PINCTRL_PIN(118, "IE_UART_TXD"),
+	PINCTRL_PIN(119, "GPP_D_23"),
+	/* GPP_E */
+	PINCTRL_PIN(120, "SATAXPCIE_0"),
+	PINCTRL_PIN(121, "SATAXPCIE_1"),
+	PINCTRL_PIN(122, "SATAXPCIE_2"),
+	PINCTRL_PIN(123, "CPU_GP_0"),
+	PINCTRL_PIN(124, "SATA_DEVSLP_0"),
+	PINCTRL_PIN(125, "SATA_DEVSLP_1"),
+	PINCTRL_PIN(126, "SATA_DEVSLP_2"),
+	PINCTRL_PIN(127, "CPU_GP_1"),
+	PINCTRL_PIN(128, "SATA_LEDB"),
+	PINCTRL_PIN(129, "USB2_OCB_0"),
+	PINCTRL_PIN(130, "USB2_OCB_1"),
+	PINCTRL_PIN(131, "USB2_OCB_2"),
+	PINCTRL_PIN(132, "USB2_OCB_3"),
+	/* GPP_I */
+	PINCTRL_PIN(133, "GBE_TDO"),
+	PINCTRL_PIN(134, "GBE_TCK"),
+	PINCTRL_PIN(135, "GBE_TMS"),
+	PINCTRL_PIN(136, "GBE_TDI"),
+	PINCTRL_PIN(137, "DO_RESET_INB"),
+	PINCTRL_PIN(138, "DO_RESET_OUTB"),
+	PINCTRL_PIN(139, "RESET_DONE"),
+	PINCTRL_PIN(140, "GBE_TRST_N"),
+	PINCTRL_PIN(141, "GBE_PCI_DIS"),
+	PINCTRL_PIN(142, "GBE_LAN_DIS"),
+	PINCTRL_PIN(143, "GPP_I_10"),
+	PINCTRL_PIN(144, "GPIO_RCOMP_3P3"),
+	/* GPP_J */
+	PINCTRL_PIN(145, "GBE_LED_0_0"),
+	PINCTRL_PIN(146, "GBE_LED_0_1"),
+	PINCTRL_PIN(147, "GBE_LED_1_0"),
+	PINCTRL_PIN(148, "GBE_LED_1_1"),
+	PINCTRL_PIN(149, "GBE_LED_2_0"),
+	PINCTRL_PIN(150, "GBE_LED_2_1"),
+	PINCTRL_PIN(151, "GBE_LED_3_0"),
+	PINCTRL_PIN(152, "GBE_LED_3_1"),
+	PINCTRL_PIN(153, "GBE_SCL_0"),
+	PINCTRL_PIN(154, "GBE_SDA_0"),
+	PINCTRL_PIN(155, "GBE_SCL_1"),
+	PINCTRL_PIN(156, "GBE_SDA_1"),
+	PINCTRL_PIN(157, "GBE_SCL_2"),
+	PINCTRL_PIN(158, "GBE_SDA_2"),
+	PINCTRL_PIN(159, "GBE_SCL_3"),
+	PINCTRL_PIN(160, "GBE_SDA_3"),
+	PINCTRL_PIN(161, "GBE_SDP_0_0"),
+	PINCTRL_PIN(162, "GBE_SDP_0_1"),
+	PINCTRL_PIN(163, "GBE_SDP_1_0"),
+	PINCTRL_PIN(164, "GBE_SDP_1_1"),
+	PINCTRL_PIN(165, "GBE_SDP_2_0"),
+	PINCTRL_PIN(166, "GBE_SDP_2_1"),
+	PINCTRL_PIN(167, "GBE_SDP_3_0"),
+	PINCTRL_PIN(168, "GBE_SDP_3_1"),
+	/* GPP_K */
+	PINCTRL_PIN(169, "GBE_RMIICLK"),
+	PINCTRL_PIN(170, "GBE_RMII_TXD_0"),
+	PINCTRL_PIN(171, "GBE_RMII_TXD_1"),
+	PINCTRL_PIN(172, "GBE_RMII_TX_EN"),
+	PINCTRL_PIN(173, "GBE_RMII_CRS_DV"),
+	PINCTRL_PIN(174, "GBE_RMII_RXD_0"),
+	PINCTRL_PIN(175, "GBE_RMII_RXD_1"),
+	PINCTRL_PIN(176, "GBE_RMII_RX_ER"),
+	PINCTRL_PIN(177, "GBE_RMII_ARBIN"),
+	PINCTRL_PIN(178, "GBE_RMII_ARB_OUT"),
+	PINCTRL_PIN(179, "PE_RST_N"),
+	PINCTRL_PIN(180, "GPIO_RCOMP_1P8_3P3"),
+	/* GPP_G */
+	PINCTRL_PIN(181, "FAN_TACH_0"),
+	PINCTRL_PIN(182, "FAN_TACH_1"),
+	PINCTRL_PIN(183, "FAN_TACH_2"),
+	PINCTRL_PIN(184, "FAN_TACH_3"),
+	PINCTRL_PIN(185, "FAN_TACH_4"),
+	PINCTRL_PIN(186, "FAN_TACH_5"),
+	PINCTRL_PIN(187, "FAN_TACH_6"),
+	PINCTRL_PIN(188, "FAN_TACH_7"),
+	PINCTRL_PIN(189, "FAN_PWM_0"),
+	PINCTRL_PIN(190, "FAN_PWM_1"),
+	PINCTRL_PIN(191, "FAN_PWM_2"),
+	PINCTRL_PIN(192, "FAN_PWM_3"),
+	PINCTRL_PIN(193, "GSXDOUT"),
+	PINCTRL_PIN(194, "GSXSLOAD"),
+	PINCTRL_PIN(195, "GSXDIN"),
+	PINCTRL_PIN(196, "GSXSRESETB"),
+	PINCTRL_PIN(197, "GSXCLK"),
+	PINCTRL_PIN(198, "ADR_COMPLETE"),
+	PINCTRL_PIN(199, "NMIB"),
+	PINCTRL_PIN(200, "SMIB"),
+	PINCTRL_PIN(201, "SSATA_DEVSLP_0"),
+	PINCTRL_PIN(202, "SSATA_DEVSLP_1"),
+	PINCTRL_PIN(203, "SSATA_DEVSLP_2"),
+	PINCTRL_PIN(204, "SSATAXPCIE0_SSATAGP0"),
+	/* GPP_H */
+	PINCTRL_PIN(205, "SRCCLKREQB_6"),
+	PINCTRL_PIN(206, "SRCCLKREQB_7"),
+	PINCTRL_PIN(207, "SRCCLKREQB_8"),
+	PINCTRL_PIN(208, "SRCCLKREQB_9"),
+	PINCTRL_PIN(209, "SRCCLKREQB_10"),
+	PINCTRL_PIN(210, "SRCCLKREQB_11"),
+	PINCTRL_PIN(211, "SRCCLKREQB_12"),
+	PINCTRL_PIN(212, "SRCCLKREQB_13"),
+	PINCTRL_PIN(213, "SRCCLKREQB_14"),
+	PINCTRL_PIN(214, "SRCCLKREQB_15"),
+	PINCTRL_PIN(215, "SML2CLK"),
+	PINCTRL_PIN(216, "SML2DATA"),
+	PINCTRL_PIN(217, "SML2ALERTB"),
+	PINCTRL_PIN(218, "SML3CLK"),
+	PINCTRL_PIN(219, "SML3DATA"),
+	PINCTRL_PIN(220, "SML3ALERTB"),
+	PINCTRL_PIN(221, "SML4CLK"),
+	PINCTRL_PIN(222, "SML4DATA"),
+	PINCTRL_PIN(223, "SML4ALERTB"),
+	PINCTRL_PIN(224, "SSATAXPCIE1_SSATAGP1"),
+	PINCTRL_PIN(225, "SSATAXPCIE2_SSATAGP2"),
+	PINCTRL_PIN(226, "SSATAXPCIE3_SSATAGP3"),
+	PINCTRL_PIN(227, "SSATAXPCIE4_SSATAGP4"),
+	PINCTRL_PIN(228, "SSATAXPCIE5_SSATAGP5"),
+	/* GPP_L */
+	PINCTRL_PIN(229, "VISA2CH0_D0"),
+	PINCTRL_PIN(230, "VISA2CH0_D1"),
+	PINCTRL_PIN(231, "VISA2CH0_D2"),
+	PINCTRL_PIN(232, "VISA2CH0_D3"),
+	PINCTRL_PIN(233, "VISA2CH0_D4"),
+	PINCTRL_PIN(234, "VISA2CH0_D5"),
+	PINCTRL_PIN(235, "VISA2CH0_D6"),
+	PINCTRL_PIN(236, "VISA2CH0_D7"),
+	PINCTRL_PIN(237, "VISA2CH0_CLK"),
+	PINCTRL_PIN(238, "VISA2CH1_D0"),
+	PINCTRL_PIN(239, "VISA2CH1_D1"),
+	PINCTRL_PIN(240, "VISA2CH1_D2"),
+	PINCTRL_PIN(241, "VISA2CH1_D3"),
+	PINCTRL_PIN(242, "VISA2CH1_D4"),
+	PINCTRL_PIN(243, "VISA2CH1_D5"),
+	PINCTRL_PIN(244, "VISA2CH1_D6"),
+	PINCTRL_PIN(245, "VISA2CH1_D7"),
+	PINCTRL_PIN(246, "VISA2CH1_CLK"),
+};
+
+static const struct intel_community lbg_communities[] = {
+	LBG_COMMUNITY(0, 0, 71),
+	LBG_COMMUNITY(1, 72, 132),
+	LBG_COMMUNITY(3, 133, 144),
+	LBG_COMMUNITY(4, 145, 180),
+	LBG_COMMUNITY(5, 181, 246),
+};
+
+static const struct intel_pinctrl_soc_data lbg_soc_data = {
+	.pins = lbg_pins,
+	.npins = ARRAY_SIZE(lbg_pins),
+	.communities = lbg_communities,
+	.ncommunities = ARRAY_SIZE(lbg_communities),
+};
+
+static int lbg_pinctrl_probe(struct platform_device *pdev)
+{
+	return intel_pinctrl_probe(pdev, &lbg_soc_data);
+}
+
+static const struct dev_pm_ops lbg_pinctrl_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
+				     intel_pinctrl_resume)
+};
+
+static const struct acpi_device_id lbg_pinctrl_acpi_match[] = {
+	{ "INT3536" },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, lbg_pinctrl_acpi_match);
+
+static struct platform_driver lbg_pinctrl_driver = {
+	.probe = lbg_pinctrl_probe,
+	.driver = {
+		.name = "lewisburg-pinctrl",
+		.acpi_match_table = lbg_pinctrl_acpi_match,
+		.pm = &lbg_pinctrl_pm_ops,
+	},
+};
+
+module_platform_driver(lbg_pinctrl_driver);
+
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+MODULE_DESCRIPTION("Intel Lewisburg pinctrl/GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c
new file mode 100644
index 0000000..4fa69f9
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-merrifield.c
@@ -0,0 +1,961 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Merrifield SoC pinctrl driver
+ *
+ * Copyright (C) 2016, Intel Corporation
+ * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-intel.h"
+
+#define MRFLD_FAMILY_NR			64
+#define MRFLD_FAMILY_LEN		0x400
+
+#define SLEW_OFFSET			0x000
+#define BUFCFG_OFFSET			0x100
+#define MISC_OFFSET			0x300
+
+#define BUFCFG_PINMODE_SHIFT		0
+#define BUFCFG_PINMODE_MASK		GENMASK(2, 0)
+#define BUFCFG_PINMODE_GPIO		0
+#define BUFCFG_PUPD_VAL_SHIFT		4
+#define BUFCFG_PUPD_VAL_MASK		GENMASK(5, 4)
+#define BUFCFG_PUPD_VAL_2K		0
+#define BUFCFG_PUPD_VAL_20K		1
+#define BUFCFG_PUPD_VAL_50K		2
+#define BUFCFG_PUPD_VAL_910		3
+#define BUFCFG_PU_EN			BIT(8)
+#define BUFCFG_PD_EN			BIT(9)
+#define BUFCFG_Px_EN_MASK		GENMASK(9, 8)
+#define BUFCFG_SLEWSEL			BIT(10)
+#define BUFCFG_OVINEN			BIT(12)
+#define BUFCFG_OVINEN_EN		BIT(13)
+#define BUFCFG_OVINEN_MASK		GENMASK(13, 12)
+#define BUFCFG_OVOUTEN			BIT(14)
+#define BUFCFG_OVOUTEN_EN		BIT(15)
+#define BUFCFG_OVOUTEN_MASK		GENMASK(15, 14)
+#define BUFCFG_INDATAOV_VAL		BIT(16)
+#define BUFCFG_INDATAOV_EN		BIT(17)
+#define BUFCFG_INDATAOV_MASK		GENMASK(17, 16)
+#define BUFCFG_OUTDATAOV_VAL		BIT(18)
+#define BUFCFG_OUTDATAOV_EN		BIT(19)
+#define BUFCFG_OUTDATAOV_MASK		GENMASK(19, 18)
+#define BUFCFG_OD_EN			BIT(21)
+
+/**
+ * struct mrfld_family - Intel pin family description
+ * @barno: MMIO BAR number where registers for this family reside
+ * @pin_base: Starting pin of pins in this family
+ * @npins: Number of pins in this family
+ * @protected: True if family is protected by access
+ * @regs: family specific common registers
+ */
+struct mrfld_family {
+	unsigned int barno;
+	unsigned int pin_base;
+	size_t npins;
+	bool protected;
+	void __iomem *regs;
+};
+
+#define MRFLD_FAMILY(b, s, e)				\
+	{						\
+		.barno = (b),				\
+		.pin_base = (s),			\
+		.npins = (e) - (s) + 1,			\
+	}
+
+#define MRFLD_FAMILY_PROTECTED(b, s, e)			\
+	{						\
+		.barno = (b),				\
+		.pin_base = (s),			\
+		.npins = (e) - (s) + 1,			\
+		.protected = true,			\
+	}
+
+static const struct pinctrl_pin_desc mrfld_pins[] = {
+	/* Family 0: OCP2SSC (0 pins) */
+	/* Family 1: ULPI (13 pins) */
+	PINCTRL_PIN(0, "ULPI_CLK"),
+	PINCTRL_PIN(1, "ULPI_D0"),
+	PINCTRL_PIN(2, "ULPI_D1"),
+	PINCTRL_PIN(3, "ULPI_D2"),
+	PINCTRL_PIN(4, "ULPI_D3"),
+	PINCTRL_PIN(5, "ULPI_D4"),
+	PINCTRL_PIN(6, "ULPI_D5"),
+	PINCTRL_PIN(7, "ULPI_D6"),
+	PINCTRL_PIN(8, "ULPI_D7"),
+	PINCTRL_PIN(9, "ULPI_DIR"),
+	PINCTRL_PIN(10, "ULPI_NXT"),
+	PINCTRL_PIN(11, "ULPI_REFCLK"),
+	PINCTRL_PIN(12, "ULPI_STP"),
+	/* Family 2: eMMC (24 pins) */
+	PINCTRL_PIN(13, "EMMC_CLK"),
+	PINCTRL_PIN(14, "EMMC_CMD"),
+	PINCTRL_PIN(15, "EMMC_D0"),
+	PINCTRL_PIN(16, "EMMC_D1"),
+	PINCTRL_PIN(17, "EMMC_D2"),
+	PINCTRL_PIN(18, "EMMC_D3"),
+	PINCTRL_PIN(19, "EMMC_D4"),
+	PINCTRL_PIN(20, "EMMC_D5"),
+	PINCTRL_PIN(21, "EMMC_D6"),
+	PINCTRL_PIN(22, "EMMC_D7"),
+	PINCTRL_PIN(23, "EMMC_RST_N"),
+	PINCTRL_PIN(24, "GP154"),
+	PINCTRL_PIN(25, "GP155"),
+	PINCTRL_PIN(26, "GP156"),
+	PINCTRL_PIN(27, "GP157"),
+	PINCTRL_PIN(28, "GP158"),
+	PINCTRL_PIN(29, "GP159"),
+	PINCTRL_PIN(30, "GP160"),
+	PINCTRL_PIN(31, "GP161"),
+	PINCTRL_PIN(32, "GP162"),
+	PINCTRL_PIN(33, "GP163"),
+	PINCTRL_PIN(34, "GP97"),
+	PINCTRL_PIN(35, "GP14"),
+	PINCTRL_PIN(36, "GP15"),
+	/* Family 3: SDIO (20 pins) */
+	PINCTRL_PIN(37, "GP77_SD_CD"),
+	PINCTRL_PIN(38, "GP78_SD_CLK"),
+	PINCTRL_PIN(39, "GP79_SD_CMD"),
+	PINCTRL_PIN(40, "GP80_SD_D0"),
+	PINCTRL_PIN(41, "GP81_SD_D1"),
+	PINCTRL_PIN(42, "GP82_SD_D2"),
+	PINCTRL_PIN(43, "GP83_SD_D3"),
+	PINCTRL_PIN(44, "GP84_SD_LS_CLK_FB"),
+	PINCTRL_PIN(45, "GP85_SD_LS_CMD_DIR"),
+	PINCTRL_PIN(46, "GP86_SD_LVL_D_DIR"),
+	PINCTRL_PIN(47, "GP88_SD_LS_SEL"),
+	PINCTRL_PIN(48, "GP87_SD_PD"),
+	PINCTRL_PIN(49, "GP89_SD_WP"),
+	PINCTRL_PIN(50, "GP90_SDIO_CLK"),
+	PINCTRL_PIN(51, "GP91_SDIO_CMD"),
+	PINCTRL_PIN(52, "GP92_SDIO_D0"),
+	PINCTRL_PIN(53, "GP93_SDIO_D1"),
+	PINCTRL_PIN(54, "GP94_SDIO_D2"),
+	PINCTRL_PIN(55, "GP95_SDIO_D3"),
+	PINCTRL_PIN(56, "GP96_SDIO_PD"),
+	/* Family 4: HSI (8 pins) */
+	PINCTRL_PIN(57, "HSI_ACDATA"),
+	PINCTRL_PIN(58, "HSI_ACFLAG"),
+	PINCTRL_PIN(59, "HSI_ACREADY"),
+	PINCTRL_PIN(60, "HSI_ACWAKE"),
+	PINCTRL_PIN(61, "HSI_CADATA"),
+	PINCTRL_PIN(62, "HSI_CAFLAG"),
+	PINCTRL_PIN(63, "HSI_CAREADY"),
+	PINCTRL_PIN(64, "HSI_CAWAKE"),
+	/* Family 5: SSP Audio (14 pins) */
+	PINCTRL_PIN(65, "GP70"),
+	PINCTRL_PIN(66, "GP71"),
+	PINCTRL_PIN(67, "GP32_I2S_0_CLK"),
+	PINCTRL_PIN(68, "GP33_I2S_0_FS"),
+	PINCTRL_PIN(69, "GP34_I2S_0_RXD"),
+	PINCTRL_PIN(70, "GP35_I2S_0_TXD"),
+	PINCTRL_PIN(71, "GP36_I2S_1_CLK"),
+	PINCTRL_PIN(72, "GP37_I2S_1_FS"),
+	PINCTRL_PIN(73, "GP38_I2S_1_RXD"),
+	PINCTRL_PIN(74, "GP39_I2S_1_TXD"),
+	PINCTRL_PIN(75, "GP40_I2S_2_CLK"),
+	PINCTRL_PIN(76, "GP41_I2S_2_FS"),
+	PINCTRL_PIN(77, "GP42_I2S_2_RXD"),
+	PINCTRL_PIN(78, "GP43_I2S_2_TXD"),
+	/* Family 6: GP SSP (22 pins) */
+	PINCTRL_PIN(79, "GP120_SPI_3_CLK"),
+	PINCTRL_PIN(80, "GP121_SPI_3_SS"),
+	PINCTRL_PIN(81, "GP122_SPI_3_RXD"),
+	PINCTRL_PIN(82, "GP123_SPI_3_TXD"),
+	PINCTRL_PIN(83, "GP102_SPI_4_CLK"),
+	PINCTRL_PIN(84, "GP103_SPI_4_SS_0"),
+	PINCTRL_PIN(85, "GP104_SPI_4_SS_1"),
+	PINCTRL_PIN(86, "GP105_SPI_4_SS_2"),
+	PINCTRL_PIN(87, "GP106_SPI_4_SS_3"),
+	PINCTRL_PIN(88, "GP107_SPI_4_RXD"),
+	PINCTRL_PIN(89, "GP108_SPI_4_TXD"),
+	PINCTRL_PIN(90, "GP109_SPI_5_CLK"),
+	PINCTRL_PIN(91, "GP110_SPI_5_SS_0"),
+	PINCTRL_PIN(92, "GP111_SPI_5_SS_1"),
+	PINCTRL_PIN(93, "GP112_SPI_5_SS_2"),
+	PINCTRL_PIN(94, "GP113_SPI_5_SS_3"),
+	PINCTRL_PIN(95, "GP114_SPI_5_RXD"),
+	PINCTRL_PIN(96, "GP115_SPI_5_TXD"),
+	PINCTRL_PIN(97, "GP116_SPI_6_CLK"),
+	PINCTRL_PIN(98, "GP117_SPI_6_SS"),
+	PINCTRL_PIN(99, "GP118_SPI_6_RXD"),
+	PINCTRL_PIN(100, "GP119_SPI_6_TXD"),
+	/* Family 7: I2C (14 pins) */
+	PINCTRL_PIN(101, "GP19_I2C_1_SCL"),
+	PINCTRL_PIN(102, "GP20_I2C_1_SDA"),
+	PINCTRL_PIN(103, "GP21_I2C_2_SCL"),
+	PINCTRL_PIN(104, "GP22_I2C_2_SDA"),
+	PINCTRL_PIN(105, "GP17_I2C_3_SCL_HDMI"),
+	PINCTRL_PIN(106, "GP18_I2C_3_SDA_HDMI"),
+	PINCTRL_PIN(107, "GP23_I2C_4_SCL"),
+	PINCTRL_PIN(108, "GP24_I2C_4_SDA"),
+	PINCTRL_PIN(109, "GP25_I2C_5_SCL"),
+	PINCTRL_PIN(110, "GP26_I2C_5_SDA"),
+	PINCTRL_PIN(111, "GP27_I2C_6_SCL"),
+	PINCTRL_PIN(112, "GP28_I2C_6_SDA"),
+	PINCTRL_PIN(113, "GP29_I2C_7_SCL"),
+	PINCTRL_PIN(114, "GP30_I2C_7_SDA"),
+	/* Family 8: UART (12 pins) */
+	PINCTRL_PIN(115, "GP124_UART_0_CTS"),
+	PINCTRL_PIN(116, "GP125_UART_0_RTS"),
+	PINCTRL_PIN(117, "GP126_UART_0_RX"),
+	PINCTRL_PIN(118, "GP127_UART_0_TX"),
+	PINCTRL_PIN(119, "GP128_UART_1_CTS"),
+	PINCTRL_PIN(120, "GP129_UART_1_RTS"),
+	PINCTRL_PIN(121, "GP130_UART_1_RX"),
+	PINCTRL_PIN(122, "GP131_UART_1_TX"),
+	PINCTRL_PIN(123, "GP132_UART_2_CTS"),
+	PINCTRL_PIN(124, "GP133_UART_2_RTS"),
+	PINCTRL_PIN(125, "GP134_UART_2_RX"),
+	PINCTRL_PIN(126, "GP135_UART_2_TX"),
+	/* Family 9: GPIO South (19 pins) */
+	PINCTRL_PIN(127, "GP177"),
+	PINCTRL_PIN(128, "GP178"),
+	PINCTRL_PIN(129, "GP179"),
+	PINCTRL_PIN(130, "GP180"),
+	PINCTRL_PIN(131, "GP181"),
+	PINCTRL_PIN(132, "GP182_PWM2"),
+	PINCTRL_PIN(133, "GP183_PWM3"),
+	PINCTRL_PIN(134, "GP184"),
+	PINCTRL_PIN(135, "GP185"),
+	PINCTRL_PIN(136, "GP186"),
+	PINCTRL_PIN(137, "GP187"),
+	PINCTRL_PIN(138, "GP188"),
+	PINCTRL_PIN(139, "GP189"),
+	PINCTRL_PIN(140, "GP64_FAST_INT0"),
+	PINCTRL_PIN(141, "GP65_FAST_INT1"),
+	PINCTRL_PIN(142, "GP66_FAST_INT2"),
+	PINCTRL_PIN(143, "GP67_FAST_INT3"),
+	PINCTRL_PIN(144, "GP12_PWM0"),
+	PINCTRL_PIN(145, "GP13_PWM1"),
+	/* Family 10: Camera Sideband (12 pins) */
+	PINCTRL_PIN(146, "GP0"),
+	PINCTRL_PIN(147, "GP1"),
+	PINCTRL_PIN(148, "GP2"),
+	PINCTRL_PIN(149, "GP3"),
+	PINCTRL_PIN(150, "GP4"),
+	PINCTRL_PIN(151, "GP5"),
+	PINCTRL_PIN(152, "GP6"),
+	PINCTRL_PIN(153, "GP7"),
+	PINCTRL_PIN(154, "GP8"),
+	PINCTRL_PIN(155, "GP9"),
+	PINCTRL_PIN(156, "GP10"),
+	PINCTRL_PIN(157, "GP11"),
+	/* Family 11: Clock (22 pins) */
+	PINCTRL_PIN(158, "GP137"),
+	PINCTRL_PIN(159, "GP138"),
+	PINCTRL_PIN(160, "GP139"),
+	PINCTRL_PIN(161, "GP140"),
+	PINCTRL_PIN(162, "GP141"),
+	PINCTRL_PIN(163, "GP142"),
+	PINCTRL_PIN(164, "GP16_HDMI_HPD"),
+	PINCTRL_PIN(165, "GP68_DSI_A_TE"),
+	PINCTRL_PIN(166, "GP69_DSI_C_TE"),
+	PINCTRL_PIN(167, "OSC_CLK_CTRL0"),
+	PINCTRL_PIN(168, "OSC_CLK_CTRL1"),
+	PINCTRL_PIN(169, "OSC_CLK0"),
+	PINCTRL_PIN(170, "OSC_CLK1"),
+	PINCTRL_PIN(171, "OSC_CLK2"),
+	PINCTRL_PIN(172, "OSC_CLK3"),
+	PINCTRL_PIN(173, "OSC_CLK4"),
+	PINCTRL_PIN(174, "RESETOUT"),
+	PINCTRL_PIN(175, "PMODE"),
+	PINCTRL_PIN(176, "PRDY"),
+	PINCTRL_PIN(177, "PREQ"),
+	PINCTRL_PIN(178, "GP190"),
+	PINCTRL_PIN(179, "GP191"),
+	/* Family 12: MSIC (15 pins) */
+	PINCTRL_PIN(180, "I2C_0_SCL"),
+	PINCTRL_PIN(181, "I2C_0_SDA"),
+	PINCTRL_PIN(182, "IERR"),
+	PINCTRL_PIN(183, "JTAG_TCK"),
+	PINCTRL_PIN(184, "JTAG_TDI"),
+	PINCTRL_PIN(185, "JTAG_TDO"),
+	PINCTRL_PIN(186, "JTAG_TMS"),
+	PINCTRL_PIN(187, "JTAG_TRST"),
+	PINCTRL_PIN(188, "PROCHOT"),
+	PINCTRL_PIN(189, "RTC_CLK"),
+	PINCTRL_PIN(190, "SVID_ALERT"),
+	PINCTRL_PIN(191, "SVID_CLK"),
+	PINCTRL_PIN(192, "SVID_D"),
+	PINCTRL_PIN(193, "THERMTRIP"),
+	PINCTRL_PIN(194, "STANDBY"),
+	/* Family 13: Keyboard (20 pins) */
+	PINCTRL_PIN(195, "GP44"),
+	PINCTRL_PIN(196, "GP45"),
+	PINCTRL_PIN(197, "GP46"),
+	PINCTRL_PIN(198, "GP47"),
+	PINCTRL_PIN(199, "GP48"),
+	PINCTRL_PIN(200, "GP49"),
+	PINCTRL_PIN(201, "GP50"),
+	PINCTRL_PIN(202, "GP51"),
+	PINCTRL_PIN(203, "GP52"),
+	PINCTRL_PIN(204, "GP53"),
+	PINCTRL_PIN(205, "GP54"),
+	PINCTRL_PIN(206, "GP55"),
+	PINCTRL_PIN(207, "GP56"),
+	PINCTRL_PIN(208, "GP57"),
+	PINCTRL_PIN(209, "GP58"),
+	PINCTRL_PIN(210, "GP59"),
+	PINCTRL_PIN(211, "GP60"),
+	PINCTRL_PIN(212, "GP61"),
+	PINCTRL_PIN(213, "GP62"),
+	PINCTRL_PIN(214, "GP63"),
+	/* Family 14: GPIO North (13 pins) */
+	PINCTRL_PIN(215, "GP164"),
+	PINCTRL_PIN(216, "GP165"),
+	PINCTRL_PIN(217, "GP166"),
+	PINCTRL_PIN(218, "GP167"),
+	PINCTRL_PIN(219, "GP168_MJTAG_TCK"),
+	PINCTRL_PIN(220, "GP169_MJTAG_TDI"),
+	PINCTRL_PIN(221, "GP170_MJTAG_TDO"),
+	PINCTRL_PIN(222, "GP171_MJTAG_TMS"),
+	PINCTRL_PIN(223, "GP172_MJTAG_TRST"),
+	PINCTRL_PIN(224, "GP173"),
+	PINCTRL_PIN(225, "GP174"),
+	PINCTRL_PIN(226, "GP175"),
+	PINCTRL_PIN(227, "GP176"),
+	/* Family 15: PTI (5 pins) */
+	PINCTRL_PIN(228, "GP72_PTI_CLK"),
+	PINCTRL_PIN(229, "GP73_PTI_D0"),
+	PINCTRL_PIN(230, "GP74_PTI_D1"),
+	PINCTRL_PIN(231, "GP75_PTI_D2"),
+	PINCTRL_PIN(232, "GP76_PTI_D3"),
+	/* Family 16: USB3 (0 pins) */
+	/* Family 17: HSIC (0 pins) */
+	/* Family 18: Broadcast (0 pins) */
+};
+
+static const unsigned int mrfld_sdio_pins[] = { 50, 51, 52, 53, 54, 55, 56 };
+static const unsigned int mrfld_spi5_pins[] = { 90, 91, 92, 93, 94, 95, 96 };
+static const unsigned int mrfld_uart0_pins[] = { 115, 116, 117, 118 };
+static const unsigned int mrfld_uart1_pins[] = { 119, 120, 121, 122 };
+static const unsigned int mrfld_uart2_pins[] = { 123, 124, 125, 126 };
+static const unsigned int mrfld_pwm0_pins[] = { 144 };
+static const unsigned int mrfld_pwm1_pins[] = { 145 };
+static const unsigned int mrfld_pwm2_pins[] = { 132 };
+static const unsigned int mrfld_pwm3_pins[] = { 133 };
+
+static const struct intel_pingroup mrfld_groups[] = {
+	PIN_GROUP("sdio_grp", mrfld_sdio_pins, 1),
+	PIN_GROUP("spi5_grp", mrfld_spi5_pins, 1),
+	PIN_GROUP("uart0_grp", mrfld_uart0_pins, 1),
+	PIN_GROUP("uart1_grp", mrfld_uart1_pins, 1),
+	PIN_GROUP("uart2_grp", mrfld_uart2_pins, 1),
+	PIN_GROUP("pwm0_grp", mrfld_pwm0_pins, 1),
+	PIN_GROUP("pwm1_grp", mrfld_pwm1_pins, 1),
+	PIN_GROUP("pwm2_grp", mrfld_pwm2_pins, 1),
+	PIN_GROUP("pwm3_grp", mrfld_pwm3_pins, 1),
+};
+
+static const char * const mrfld_sdio_groups[] = { "sdio_grp" };
+static const char * const mrfld_spi5_groups[] = { "spi5_grp" };
+static const char * const mrfld_uart0_groups[] = { "uart0_grp" };
+static const char * const mrfld_uart1_groups[] = { "uart1_grp" };
+static const char * const mrfld_uart2_groups[] = { "uart2_grp" };
+static const char * const mrfld_pwm0_groups[] = { "pwm0_grp" };
+static const char * const mrfld_pwm1_groups[] = { "pwm1_grp" };
+static const char * const mrfld_pwm2_groups[] = { "pwm2_grp" };
+static const char * const mrfld_pwm3_groups[] = { "pwm3_grp" };
+
+static const struct intel_function mrfld_functions[] = {
+	FUNCTION("sdio", mrfld_sdio_groups),
+	FUNCTION("spi5", mrfld_spi5_groups),
+	FUNCTION("uart0", mrfld_uart0_groups),
+	FUNCTION("uart1", mrfld_uart1_groups),
+	FUNCTION("uart2", mrfld_uart2_groups),
+	FUNCTION("pwm0", mrfld_pwm0_groups),
+	FUNCTION("pwm1", mrfld_pwm1_groups),
+	FUNCTION("pwm2", mrfld_pwm2_groups),
+	FUNCTION("pwm3", mrfld_pwm3_groups),
+};
+
+static const struct mrfld_family mrfld_families[] = {
+	MRFLD_FAMILY(1, 0, 12),
+	MRFLD_FAMILY(2, 13, 36),
+	MRFLD_FAMILY(3, 37, 56),
+	MRFLD_FAMILY(4, 57, 64),
+	MRFLD_FAMILY(5, 65, 78),
+	MRFLD_FAMILY(6, 79, 100),
+	MRFLD_FAMILY_PROTECTED(7, 101, 114),
+	MRFLD_FAMILY(8, 115, 126),
+	MRFLD_FAMILY(9, 127, 145),
+	MRFLD_FAMILY(10, 146, 157),
+	MRFLD_FAMILY(11, 158, 179),
+	MRFLD_FAMILY_PROTECTED(12, 180, 194),
+	MRFLD_FAMILY(13, 195, 214),
+	MRFLD_FAMILY(14, 215, 227),
+	MRFLD_FAMILY(15, 228, 232),
+};
+
+/**
+ * struct mrfld_pinctrl - Intel Merrifield pinctrl private structure
+ * @dev: Pointer to the device structure
+ * @lock: Lock to serialize register access
+ * @pctldesc: Pin controller description
+ * @pctldev: Pointer to the pin controller device
+ * @families: Array of families this pinctrl handles
+ * @nfamilies: Number of families in the array
+ * @functions: Array of functions
+ * @nfunctions: Number of functions in the array
+ * @groups: Array of pin groups
+ * @ngroups: Number of groups in the array
+ * @pins: Array of pins this pinctrl controls
+ * @npins: Number of pins in the array
+ */
+struct mrfld_pinctrl {
+	struct device *dev;
+	raw_spinlock_t lock;
+	struct pinctrl_desc pctldesc;
+	struct pinctrl_dev *pctldev;
+
+	/* Pin controller configuration */
+	const struct mrfld_family *families;
+	size_t nfamilies;
+	const struct intel_function *functions;
+	size_t nfunctions;
+	const struct intel_pingroup *groups;
+	size_t ngroups;
+	const struct pinctrl_pin_desc *pins;
+	size_t npins;
+};
+
+#define pin_to_bufno(f, p)		((p) - (f)->pin_base)
+
+static const struct mrfld_family *mrfld_get_family(struct mrfld_pinctrl *mp,
+						   unsigned int pin)
+{
+	const struct mrfld_family *family;
+	unsigned int i;
+
+	for (i = 0; i < mp->nfamilies; i++) {
+		family = &mp->families[i];
+		if (pin >= family->pin_base &&
+		    pin < family->pin_base + family->npins)
+			return family;
+	}
+
+	dev_warn(mp->dev, "failed to find family for pin %u\n", pin);
+	return NULL;
+}
+
+static bool mrfld_buf_available(struct mrfld_pinctrl *mp, unsigned int pin)
+{
+	const struct mrfld_family *family;
+
+	family = mrfld_get_family(mp, pin);
+	if (!family)
+		return false;
+
+	return !family->protected;
+}
+
+static void __iomem *mrfld_get_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin)
+{
+	const struct mrfld_family *family;
+	unsigned int bufno;
+
+	family = mrfld_get_family(mp, pin);
+	if (!family)
+		return NULL;
+
+	bufno = pin_to_bufno(family, pin);
+	return family->regs + BUFCFG_OFFSET + bufno * 4;
+}
+
+static int mrfld_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
+
+	return mp->ngroups;
+}
+
+static const char *mrfld_get_group_name(struct pinctrl_dev *pctldev,
+					unsigned int group)
+{
+	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
+
+	return mp->groups[group].name;
+}
+
+static int mrfld_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group,
+				const unsigned int **pins, unsigned int *npins)
+{
+	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
+
+	*pins = mp->groups[group].pins;
+	*npins = mp->groups[group].npins;
+	return 0;
+}
+
+static void mrfld_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+			       unsigned int pin)
+{
+	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
+	void __iomem *bufcfg;
+	u32 value, mode;
+
+	if (!mrfld_buf_available(mp, pin)) {
+		seq_puts(s, "not available");
+		return;
+	}
+
+	bufcfg = mrfld_get_bufcfg(mp, pin);
+	value = readl(bufcfg);
+
+	mode = (value & BUFCFG_PINMODE_MASK) >> BUFCFG_PINMODE_SHIFT;
+	if (!mode)
+		seq_puts(s, "GPIO ");
+	else
+		seq_printf(s, "mode %d ", mode);
+
+	seq_printf(s, "0x%08x", value);
+}
+
+static const struct pinctrl_ops mrfld_pinctrl_ops = {
+	.get_groups_count = mrfld_get_groups_count,
+	.get_group_name = mrfld_get_group_name,
+	.get_group_pins = mrfld_get_group_pins,
+	.pin_dbg_show = mrfld_pin_dbg_show,
+};
+
+static int mrfld_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
+
+	return mp->nfunctions;
+}
+
+static const char *mrfld_get_function_name(struct pinctrl_dev *pctldev,
+					   unsigned int function)
+{
+	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
+
+	return mp->functions[function].name;
+}
+
+static int mrfld_get_function_groups(struct pinctrl_dev *pctldev,
+				     unsigned int function,
+				     const char * const **groups,
+				     unsigned int * const ngroups)
+{
+	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = mp->functions[function].groups;
+	*ngroups = mp->functions[function].ngroups;
+	return 0;
+}
+
+static void mrfld_update_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin,
+				u32 bits, u32 mask)
+{
+	void __iomem *bufcfg;
+	u32 value;
+
+	bufcfg = mrfld_get_bufcfg(mp, pin);
+	value = readl(bufcfg);
+
+	value &= ~mask;
+	value |= bits & mask;
+
+	writel(value, bufcfg);
+}
+
+static int mrfld_pinmux_set_mux(struct pinctrl_dev *pctldev,
+				unsigned int function,
+				unsigned int group)
+{
+	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
+	const struct intel_pingroup *grp = &mp->groups[group];
+	u32 bits = grp->mode << BUFCFG_PINMODE_SHIFT;
+	u32 mask = BUFCFG_PINMODE_MASK;
+	unsigned long flags;
+	unsigned int i;
+
+	/*
+	 * All pins in the groups needs to be accessible and writable
+	 * before we can enable the mux for this group.
+	 */
+	for (i = 0; i < grp->npins; i++) {
+		if (!mrfld_buf_available(mp, grp->pins[i]))
+			return -EBUSY;
+	}
+
+	/* Now enable the mux setting for each pin in the group */
+	raw_spin_lock_irqsave(&mp->lock, flags);
+	for (i = 0; i < grp->npins; i++)
+		mrfld_update_bufcfg(mp, grp->pins[i], bits, mask);
+	raw_spin_unlock_irqrestore(&mp->lock, flags);
+
+	return 0;
+}
+
+static int mrfld_gpio_request_enable(struct pinctrl_dev *pctldev,
+				     struct pinctrl_gpio_range *range,
+				     unsigned int pin)
+{
+	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
+	u32 bits = BUFCFG_PINMODE_GPIO << BUFCFG_PINMODE_SHIFT;
+	u32 mask = BUFCFG_PINMODE_MASK;
+	unsigned long flags;
+
+	if (!mrfld_buf_available(mp, pin))
+		return -EBUSY;
+
+	raw_spin_lock_irqsave(&mp->lock, flags);
+	mrfld_update_bufcfg(mp, pin, bits, mask);
+	raw_spin_unlock_irqrestore(&mp->lock, flags);
+
+	return 0;
+}
+
+static const struct pinmux_ops mrfld_pinmux_ops = {
+	.get_functions_count = mrfld_get_functions_count,
+	.get_function_name = mrfld_get_function_name,
+	.get_function_groups = mrfld_get_function_groups,
+	.set_mux = mrfld_pinmux_set_mux,
+	.gpio_request_enable = mrfld_gpio_request_enable,
+};
+
+static int mrfld_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
+			    unsigned long *config)
+{
+	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	u32 value, term;
+	u16 arg = 0;
+
+	if (!mrfld_buf_available(mp, pin))
+		return -ENOTSUPP;
+
+	value = readl(mrfld_get_bufcfg(mp, pin));
+	term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (value & BUFCFG_Px_EN_MASK)
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PU_EN)
+			return -EINVAL;
+
+		switch (term) {
+		case BUFCFG_PUPD_VAL_910:
+			arg = 910;
+			break;
+		case BUFCFG_PUPD_VAL_2K:
+			arg = 2000;
+			break;
+		case BUFCFG_PUPD_VAL_20K:
+			arg = 20000;
+			break;
+		case BUFCFG_PUPD_VAL_50K:
+			arg = 50000;
+			break;
+		}
+
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PD_EN)
+			return -EINVAL;
+
+		switch (term) {
+		case BUFCFG_PUPD_VAL_910:
+			arg = 910;
+			break;
+		case BUFCFG_PUPD_VAL_2K:
+			arg = 2000;
+			break;
+		case BUFCFG_PUPD_VAL_20K:
+			arg = 20000;
+			break;
+		case BUFCFG_PUPD_VAL_50K:
+			arg = 50000;
+			break;
+		}
+
+		break;
+
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		if (!(value & BUFCFG_OD_EN))
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_SLEW_RATE:
+		if (!(value & BUFCFG_SLEWSEL))
+			arg = 0;
+		else
+			arg = 1;
+		break;
+
+	default:
+		return -ENOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, arg);
+	return 0;
+}
+
+static int mrfld_config_set_pin(struct mrfld_pinctrl *mp, unsigned int pin,
+				unsigned long config)
+{
+	unsigned int param = pinconf_to_config_param(config);
+	unsigned int arg = pinconf_to_config_argument(config);
+	u32 bits = 0, mask = 0;
+	unsigned long flags;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
+		bits |= BUFCFG_PU_EN;
+
+		switch (arg) {
+		case 50000:
+			bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT;
+			break;
+		case 20000:
+			bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT;
+			break;
+		case 2000:
+			bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
+		bits |= BUFCFG_PD_EN;
+
+		switch (arg) {
+		case 50000:
+			bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT;
+			break;
+		case 20000:
+			bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT;
+			break;
+		case 2000:
+			bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		break;
+
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		mask |= BUFCFG_OD_EN;
+		if (arg)
+			bits |= BUFCFG_OD_EN;
+		break;
+
+	case PIN_CONFIG_SLEW_RATE:
+		mask |= BUFCFG_SLEWSEL;
+		if (arg)
+			bits |= BUFCFG_SLEWSEL;
+		break;
+	}
+
+	raw_spin_lock_irqsave(&mp->lock, flags);
+	mrfld_update_bufcfg(mp, pin, bits, mask);
+	raw_spin_unlock_irqrestore(&mp->lock, flags);
+
+	return 0;
+}
+
+static int mrfld_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
+			    unsigned long *configs, unsigned int nconfigs)
+{
+	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
+	unsigned int i;
+	int ret;
+
+	if (!mrfld_buf_available(mp, pin))
+		return -ENOTSUPP;
+
+	for (i = 0; i < nconfigs; i++) {
+		switch (pinconf_to_config_param(configs[i])) {
+		case PIN_CONFIG_BIAS_DISABLE:
+		case PIN_CONFIG_BIAS_PULL_UP:
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		case PIN_CONFIG_SLEW_RATE:
+			ret = mrfld_config_set_pin(mp, pin, configs[i]);
+			if (ret)
+				return ret;
+			break;
+
+		default:
+			return -ENOTSUPP;
+		}
+	}
+
+	return 0;
+}
+
+static int mrfld_config_group_get(struct pinctrl_dev *pctldev,
+				  unsigned int group, unsigned long *config)
+{
+	const unsigned int *pins;
+	unsigned int npins;
+	int ret;
+
+	ret = mrfld_get_group_pins(pctldev, group, &pins, &npins);
+	if (ret)
+		return ret;
+
+	ret = mrfld_config_get(pctldev, pins[0], config);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int mrfld_config_group_set(struct pinctrl_dev *pctldev,
+				  unsigned int group, unsigned long *configs,
+				  unsigned int num_configs)
+{
+	const unsigned int *pins;
+	unsigned int npins;
+	int i, ret;
+
+	ret = mrfld_get_group_pins(pctldev, group, &pins, &npins);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < npins; i++) {
+		ret = mrfld_config_set(pctldev, pins[i], configs, num_configs);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static const struct pinconf_ops mrfld_pinconf_ops = {
+	.is_generic = true,
+	.pin_config_get = mrfld_config_get,
+	.pin_config_set = mrfld_config_set,
+	.pin_config_group_get = mrfld_config_group_get,
+	.pin_config_group_set = mrfld_config_group_set,
+};
+
+static const struct pinctrl_desc mrfld_pinctrl_desc = {
+	.pctlops = &mrfld_pinctrl_ops,
+	.pmxops = &mrfld_pinmux_ops,
+	.confops = &mrfld_pinconf_ops,
+	.owner = THIS_MODULE,
+};
+
+static int mrfld_pinctrl_probe(struct platform_device *pdev)
+{
+	struct mrfld_family *families;
+	struct mrfld_pinctrl *mp;
+	struct resource *mem;
+	void __iomem *regs;
+	size_t nfamilies;
+	unsigned int i;
+
+	mp = devm_kzalloc(&pdev->dev, sizeof(*mp), GFP_KERNEL);
+	if (!mp)
+		return -ENOMEM;
+
+	mp->dev = &pdev->dev;
+	raw_spin_lock_init(&mp->lock);
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(&pdev->dev, mem);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	/*
+	 * Make a copy of the families which we can use to hold pointers
+	 * to the registers.
+	 */
+	nfamilies = ARRAY_SIZE(mrfld_families),
+	families = devm_kmemdup(&pdev->dev, mrfld_families,
+					    sizeof(mrfld_families),
+					    GFP_KERNEL);
+	if (!families)
+		return -ENOMEM;
+
+	/* Splice memory resource by chunk per family */
+	for (i = 0; i < nfamilies; i++) {
+		struct mrfld_family *family = &families[i];
+
+		family->regs = regs + family->barno * MRFLD_FAMILY_LEN;
+	}
+
+	mp->families = families;
+	mp->nfamilies = nfamilies;
+	mp->functions = mrfld_functions;
+	mp->nfunctions = ARRAY_SIZE(mrfld_functions);
+	mp->groups = mrfld_groups;
+	mp->ngroups = ARRAY_SIZE(mrfld_groups);
+	mp->pctldesc = mrfld_pinctrl_desc;
+	mp->pctldesc.name = dev_name(&pdev->dev);
+	mp->pctldesc.pins = mrfld_pins;
+	mp->pctldesc.npins = ARRAY_SIZE(mrfld_pins);
+
+	mp->pctldev = devm_pinctrl_register(&pdev->dev, &mp->pctldesc, mp);
+	if (IS_ERR(mp->pctldev)) {
+		dev_err(&pdev->dev, "failed to register pinctrl driver\n");
+		return PTR_ERR(mp->pctldev);
+	}
+
+	platform_set_drvdata(pdev, mp);
+	return 0;
+}
+
+static const struct acpi_device_id mrfld_acpi_table[] = {
+	{ "INTC1002" },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, mrfld_acpi_table);
+
+static struct platform_driver mrfld_pinctrl_driver = {
+	.probe = mrfld_pinctrl_probe,
+	.driver = {
+		.name = "pinctrl-merrifield",
+		.acpi_match_table = mrfld_acpi_table,
+	},
+};
+
+static int __init mrfld_pinctrl_init(void)
+{
+	return platform_driver_register(&mrfld_pinctrl_driver);
+}
+subsys_initcall(mrfld_pinctrl_init);
+
+static void __exit mrfld_pinctrl_exit(void)
+{
+	platform_driver_unregister(&mrfld_pinctrl_driver);
+}
+module_exit(mrfld_pinctrl_exit);
+
+MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
+MODULE_DESCRIPTION("Intel Merrifield SoC pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:pinctrl-merrifield");
diff --git a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c
new file mode 100644
index 0000000..7984392
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c
@@ -0,0 +1,636 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Sunrisepoint PCH pinctrl/GPIO driver
+ *
+ * Copyright (C) 2015, Intel Corporation
+ * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
+ *          Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-intel.h"
+
+#define SPT_PAD_OWN	0x020
+#define SPT_PADCFGLOCK	0x0a0
+#define SPT_HOSTSW_OWN	0x0d0
+#define SPT_GPI_IE	0x120
+
+#define SPT_COMMUNITY(b, s, e)				\
+	{						\
+		.barno = (b),				\
+		.padown_offset = SPT_PAD_OWN,		\
+		.padcfglock_offset = SPT_PADCFGLOCK,	\
+		.hostown_offset = SPT_HOSTSW_OWN,	\
+		.ie_offset = SPT_GPI_IE,		\
+		.gpp_size = 24,				\
+		.gpp_num_padown_regs = 4,		\
+		.pin_base = (s),			\
+		.npins = ((e) - (s) + 1),		\
+	}
+
+#define SPTH_GPP(r, s, e, g)				\
+	{						\
+		.reg_num = (r),				\
+		.base = (s),				\
+		.size = ((e) - (s) + 1),		\
+		.gpio_base = (g),			\
+	}
+
+#define SPTH_COMMUNITY(b, s, e, g)			\
+	{						\
+		.barno = (b),				\
+		.padown_offset = SPT_PAD_OWN,		\
+		.padcfglock_offset = SPT_PADCFGLOCK,	\
+		.hostown_offset = SPT_HOSTSW_OWN,	\
+		.ie_offset = SPT_GPI_IE,		\
+		.pin_base = (s),			\
+		.npins = ((e) - (s) + 1),		\
+		.gpps = (g),				\
+		.ngpps = ARRAY_SIZE(g),			\
+	}
+
+/* Sunrisepoint-LP */
+static const struct pinctrl_pin_desc sptlp_pins[] = {
+	/* GPP_A */
+	PINCTRL_PIN(0, "RCINB"),
+	PINCTRL_PIN(1, "LAD_0"),
+	PINCTRL_PIN(2, "LAD_1"),
+	PINCTRL_PIN(3, "LAD_2"),
+	PINCTRL_PIN(4, "LAD_3"),
+	PINCTRL_PIN(5, "LFRAMEB"),
+	PINCTRL_PIN(6, "SERIQ"),
+	PINCTRL_PIN(7, "PIRQAB"),
+	PINCTRL_PIN(8, "CLKRUNB"),
+	PINCTRL_PIN(9, "CLKOUT_LPC_0"),
+	PINCTRL_PIN(10, "CLKOUT_LPC_1"),
+	PINCTRL_PIN(11, "PMEB"),
+	PINCTRL_PIN(12, "BM_BUSYB"),
+	PINCTRL_PIN(13, "SUSWARNB_SUS_PWRDNACK"),
+	PINCTRL_PIN(14, "SUS_STATB"),
+	PINCTRL_PIN(15, "SUSACKB"),
+	PINCTRL_PIN(16, "SD_1P8_SEL"),
+	PINCTRL_PIN(17, "SD_PWR_EN_B"),
+	PINCTRL_PIN(18, "ISH_GP_0"),
+	PINCTRL_PIN(19, "ISH_GP_1"),
+	PINCTRL_PIN(20, "ISH_GP_2"),
+	PINCTRL_PIN(21, "ISH_GP_3"),
+	PINCTRL_PIN(22, "ISH_GP_4"),
+	PINCTRL_PIN(23, "ISH_GP_5"),
+	/* GPP_B */
+	PINCTRL_PIN(24, "CORE_VID_0"),
+	PINCTRL_PIN(25, "CORE_VID_1"),
+	PINCTRL_PIN(26, "VRALERTB"),
+	PINCTRL_PIN(27, "CPU_GP_2"),
+	PINCTRL_PIN(28, "CPU_GP_3"),
+	PINCTRL_PIN(29, "SRCCLKREQB_0"),
+	PINCTRL_PIN(30, "SRCCLKREQB_1"),
+	PINCTRL_PIN(31, "SRCCLKREQB_2"),
+	PINCTRL_PIN(32, "SRCCLKREQB_3"),
+	PINCTRL_PIN(33, "SRCCLKREQB_4"),
+	PINCTRL_PIN(34, "SRCCLKREQB_5"),
+	PINCTRL_PIN(35, "EXT_PWR_GATEB"),
+	PINCTRL_PIN(36, "SLP_S0B"),
+	PINCTRL_PIN(37, "PLTRSTB"),
+	PINCTRL_PIN(38, "SPKR"),
+	PINCTRL_PIN(39, "GSPI0_CSB"),
+	PINCTRL_PIN(40, "GSPI0_CLK"),
+	PINCTRL_PIN(41, "GSPI0_MISO"),
+	PINCTRL_PIN(42, "GSPI0_MOSI"),
+	PINCTRL_PIN(43, "GSPI1_CSB"),
+	PINCTRL_PIN(44, "GSPI1_CLK"),
+	PINCTRL_PIN(45, "GSPI1_MISO"),
+	PINCTRL_PIN(46, "GSPI1_MOSI"),
+	PINCTRL_PIN(47, "SML1ALERTB"),
+	/* GPP_C */
+	PINCTRL_PIN(48, "SMBCLK"),
+	PINCTRL_PIN(49, "SMBDATA"),
+	PINCTRL_PIN(50, "SMBALERTB"),
+	PINCTRL_PIN(51, "SML0CLK"),
+	PINCTRL_PIN(52, "SML0DATA"),
+	PINCTRL_PIN(53, "SML0ALERTB"),
+	PINCTRL_PIN(54, "SML1CLK"),
+	PINCTRL_PIN(55, "SML1DATA"),
+	PINCTRL_PIN(56, "UART0_RXD"),
+	PINCTRL_PIN(57, "UART0_TXD"),
+	PINCTRL_PIN(58, "UART0_RTSB"),
+	PINCTRL_PIN(59, "UART0_CTSB"),
+	PINCTRL_PIN(60, "UART1_RXD"),
+	PINCTRL_PIN(61, "UART1_TXD"),
+	PINCTRL_PIN(62, "UART1_RTSB"),
+	PINCTRL_PIN(63, "UART1_CTSB"),
+	PINCTRL_PIN(64, "I2C0_SDA"),
+	PINCTRL_PIN(65, "I2C0_SCL"),
+	PINCTRL_PIN(66, "I2C1_SDA"),
+	PINCTRL_PIN(67, "I2C1_SCL"),
+	PINCTRL_PIN(68, "UART2_RXD"),
+	PINCTRL_PIN(69, "UART2_TXD"),
+	PINCTRL_PIN(70, "UART2_RTSB"),
+	PINCTRL_PIN(71, "UART2_CTSB"),
+	/* GPP_D */
+	PINCTRL_PIN(72, "SPI1_CSB"),
+	PINCTRL_PIN(73, "SPI1_CLK"),
+	PINCTRL_PIN(74, "SPI1_MISO_IO_1"),
+	PINCTRL_PIN(75, "SPI1_MOSI_IO_0"),
+	PINCTRL_PIN(76, "FLASHTRIG"),
+	PINCTRL_PIN(77, "ISH_I2C0_SDA"),
+	PINCTRL_PIN(78, "ISH_I2C0_SCL"),
+	PINCTRL_PIN(79, "ISH_I2C1_SDA"),
+	PINCTRL_PIN(80, "ISH_I2C1_SCL"),
+	PINCTRL_PIN(81, "ISH_SPI_CSB"),
+	PINCTRL_PIN(82, "ISH_SPI_CLK"),
+	PINCTRL_PIN(83, "ISH_SPI_MISO"),
+	PINCTRL_PIN(84, "ISH_SPI_MOSI"),
+	PINCTRL_PIN(85, "ISH_UART0_RXD"),
+	PINCTRL_PIN(86, "ISH_UART0_TXD"),
+	PINCTRL_PIN(87, "ISH_UART0_RTSB"),
+	PINCTRL_PIN(88, "ISH_UART0_CTSB"),
+	PINCTRL_PIN(89, "DMIC_CLK_1"),
+	PINCTRL_PIN(90, "DMIC_DATA_1"),
+	PINCTRL_PIN(91, "DMIC_CLK_0"),
+	PINCTRL_PIN(92, "DMIC_DATA_0"),
+	PINCTRL_PIN(93, "SPI1_IO_2"),
+	PINCTRL_PIN(94, "SPI1_IO_3"),
+	PINCTRL_PIN(95, "SSP_MCLK"),
+	/* GPP_E */
+	PINCTRL_PIN(96, "SATAXPCIE_0"),
+	PINCTRL_PIN(97, "SATAXPCIE_1"),
+	PINCTRL_PIN(98, "SATAXPCIE_2"),
+	PINCTRL_PIN(99, "CPU_GP_0"),
+	PINCTRL_PIN(100, "SATA_DEVSLP_0"),
+	PINCTRL_PIN(101, "SATA_DEVSLP_1"),
+	PINCTRL_PIN(102, "SATA_DEVSLP_2"),
+	PINCTRL_PIN(103, "CPU_GP_1"),
+	PINCTRL_PIN(104, "SATA_LEDB"),
+	PINCTRL_PIN(105, "USB2_OCB_0"),
+	PINCTRL_PIN(106, "USB2_OCB_1"),
+	PINCTRL_PIN(107, "USB2_OCB_2"),
+	PINCTRL_PIN(108, "USB2_OCB_3"),
+	PINCTRL_PIN(109, "DDSP_HPD_0"),
+	PINCTRL_PIN(110, "DDSP_HPD_1"),
+	PINCTRL_PIN(111, "DDSP_HPD_2"),
+	PINCTRL_PIN(112, "DDSP_HPD_3"),
+	PINCTRL_PIN(113, "EDP_HPD"),
+	PINCTRL_PIN(114, "DDPB_CTRLCLK"),
+	PINCTRL_PIN(115, "DDPB_CTRLDATA"),
+	PINCTRL_PIN(116, "DDPC_CTRLCLK"),
+	PINCTRL_PIN(117, "DDPC_CTRLDATA"),
+	PINCTRL_PIN(118, "DDPD_CTRLCLK"),
+	PINCTRL_PIN(119, "DDPD_CTRLDATA"),
+	/* GPP_F */
+	PINCTRL_PIN(120, "SSP2_SCLK"),
+	PINCTRL_PIN(121, "SSP2_SFRM"),
+	PINCTRL_PIN(122, "SSP2_TXD"),
+	PINCTRL_PIN(123, "SSP2_RXD"),
+	PINCTRL_PIN(124, "I2C2_SDA"),
+	PINCTRL_PIN(125, "I2C2_SCL"),
+	PINCTRL_PIN(126, "I2C3_SDA"),
+	PINCTRL_PIN(127, "I2C3_SCL"),
+	PINCTRL_PIN(128, "I2C4_SDA"),
+	PINCTRL_PIN(129, "I2C4_SCL"),
+	PINCTRL_PIN(130, "I2C5_SDA"),
+	PINCTRL_PIN(131, "I2C5_SCL"),
+	PINCTRL_PIN(132, "EMMC_CMD"),
+	PINCTRL_PIN(133, "EMMC_DATA_0"),
+	PINCTRL_PIN(134, "EMMC_DATA_1"),
+	PINCTRL_PIN(135, "EMMC_DATA_2"),
+	PINCTRL_PIN(136, "EMMC_DATA_3"),
+	PINCTRL_PIN(137, "EMMC_DATA_4"),
+	PINCTRL_PIN(138, "EMMC_DATA_5"),
+	PINCTRL_PIN(139, "EMMC_DATA_6"),
+	PINCTRL_PIN(140, "EMMC_DATA_7"),
+	PINCTRL_PIN(141, "EMMC_RCLK"),
+	PINCTRL_PIN(142, "EMMC_CLK"),
+	PINCTRL_PIN(143, "GPP_F_23"),
+	/* GPP_G */
+	PINCTRL_PIN(144, "SD_CMD"),
+	PINCTRL_PIN(145, "SD_DATA_0"),
+	PINCTRL_PIN(146, "SD_DATA_1"),
+	PINCTRL_PIN(147, "SD_DATA_2"),
+	PINCTRL_PIN(148, "SD_DATA_3"),
+	PINCTRL_PIN(149, "SD_CDB"),
+	PINCTRL_PIN(150, "SD_CLK"),
+	PINCTRL_PIN(151, "SD_WP"),
+};
+
+static const unsigned sptlp_spi0_pins[] = { 39, 40, 41, 42 };
+static const unsigned sptlp_spi1_pins[] = { 43, 44, 45, 46 };
+static const unsigned sptlp_uart0_pins[] = { 56, 57, 58, 59 };
+static const unsigned sptlp_uart1_pins[] = { 60, 61, 62, 63 };
+static const unsigned sptlp_uart2_pins[] = { 68, 69, 71, 71 };
+static const unsigned sptlp_i2c0_pins[] = { 64, 65 };
+static const unsigned sptlp_i2c1_pins[] = { 66, 67 };
+static const unsigned sptlp_i2c2_pins[] = { 124, 125 };
+static const unsigned sptlp_i2c3_pins[] = { 126, 127 };
+static const unsigned sptlp_i2c4_pins[] = { 128, 129 };
+static const unsigned sptlp_i2c4b_pins[] = { 85, 86 };
+static const unsigned sptlp_i2c5_pins[] = { 130, 131 };
+static const unsigned sptlp_ssp2_pins[] = { 120, 121, 122, 123 };
+static const unsigned sptlp_emmc_pins[] = {
+	132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
+};
+static const unsigned sptlp_sd_pins[] = {
+	144, 145, 146, 147, 148, 149, 150, 151,
+};
+
+static const struct intel_pingroup sptlp_groups[] = {
+	PIN_GROUP("spi0_grp", sptlp_spi0_pins, 1),
+	PIN_GROUP("spi1_grp", sptlp_spi1_pins, 1),
+	PIN_GROUP("uart0_grp", sptlp_uart0_pins, 1),
+	PIN_GROUP("uart1_grp", sptlp_uart1_pins, 1),
+	PIN_GROUP("uart2_grp", sptlp_uart2_pins, 1),
+	PIN_GROUP("i2c0_grp", sptlp_i2c0_pins, 1),
+	PIN_GROUP("i2c1_grp", sptlp_i2c1_pins, 1),
+	PIN_GROUP("i2c2_grp", sptlp_i2c2_pins, 1),
+	PIN_GROUP("i2c3_grp", sptlp_i2c3_pins, 1),
+	PIN_GROUP("i2c4_grp", sptlp_i2c4_pins, 1),
+	PIN_GROUP("i2c4b_grp", sptlp_i2c4b_pins, 3),
+	PIN_GROUP("i2c5_grp", sptlp_i2c5_pins, 1),
+	PIN_GROUP("ssp2_grp", sptlp_ssp2_pins, 1),
+	PIN_GROUP("emmc_grp", sptlp_emmc_pins, 1),
+	PIN_GROUP("sd_grp", sptlp_sd_pins, 1),
+};
+
+static const char * const sptlp_spi0_groups[] = { "spi0_grp" };
+static const char * const sptlp_spi1_groups[] = { "spi0_grp" };
+static const char * const sptlp_uart0_groups[] = { "uart0_grp" };
+static const char * const sptlp_uart1_groups[] = { "uart1_grp" };
+static const char * const sptlp_uart2_groups[] = { "uart2_grp" };
+static const char * const sptlp_i2c0_groups[] = { "i2c0_grp" };
+static const char * const sptlp_i2c1_groups[] = { "i2c1_grp" };
+static const char * const sptlp_i2c2_groups[] = { "i2c2_grp" };
+static const char * const sptlp_i2c3_groups[] = { "i2c3_grp" };
+static const char * const sptlp_i2c4_groups[] = { "i2c4_grp", "i2c4b_grp" };
+static const char * const sptlp_i2c5_groups[] = { "i2c5_grp" };
+static const char * const sptlp_ssp2_groups[] = { "ssp2_grp" };
+static const char * const sptlp_emmc_groups[] = { "emmc_grp" };
+static const char * const sptlp_sd_groups[] = { "sd_grp" };
+
+static const struct intel_function sptlp_functions[] = {
+	FUNCTION("spi0", sptlp_spi0_groups),
+	FUNCTION("spi1", sptlp_spi1_groups),
+	FUNCTION("uart0", sptlp_uart0_groups),
+	FUNCTION("uart1", sptlp_uart1_groups),
+	FUNCTION("uart2", sptlp_uart2_groups),
+	FUNCTION("i2c0", sptlp_i2c0_groups),
+	FUNCTION("i2c1", sptlp_i2c1_groups),
+	FUNCTION("i2c2", sptlp_i2c2_groups),
+	FUNCTION("i2c3", sptlp_i2c3_groups),
+	FUNCTION("i2c4", sptlp_i2c4_groups),
+	FUNCTION("i2c5", sptlp_i2c5_groups),
+	FUNCTION("ssp2", sptlp_ssp2_groups),
+	FUNCTION("emmc", sptlp_emmc_groups),
+	FUNCTION("sd", sptlp_sd_groups),
+};
+
+static const struct intel_community sptlp_communities[] = {
+	SPT_COMMUNITY(0, 0, 47),
+	SPT_COMMUNITY(1, 48, 119),
+	SPT_COMMUNITY(2, 120, 151),
+};
+
+static const struct intel_pinctrl_soc_data sptlp_soc_data = {
+	.pins = sptlp_pins,
+	.npins = ARRAY_SIZE(sptlp_pins),
+	.groups = sptlp_groups,
+	.ngroups = ARRAY_SIZE(sptlp_groups),
+	.functions = sptlp_functions,
+	.nfunctions = ARRAY_SIZE(sptlp_functions),
+	.communities = sptlp_communities,
+	.ncommunities = ARRAY_SIZE(sptlp_communities),
+};
+
+/* Sunrisepoint-H */
+static const struct pinctrl_pin_desc spth_pins[] = {
+	/* GPP_A */
+	PINCTRL_PIN(0, "RCINB"),
+	PINCTRL_PIN(1, "LAD_0"),
+	PINCTRL_PIN(2, "LAD_1"),
+	PINCTRL_PIN(3, "LAD_2"),
+	PINCTRL_PIN(4, "LAD_3"),
+	PINCTRL_PIN(5, "LFRAMEB"),
+	PINCTRL_PIN(6, "SERIQ"),
+	PINCTRL_PIN(7, "PIRQAB"),
+	PINCTRL_PIN(8, "CLKRUNB"),
+	PINCTRL_PIN(9, "CLKOUT_LPC_0"),
+	PINCTRL_PIN(10, "CLKOUT_LPC_1"),
+	PINCTRL_PIN(11, "PMEB"),
+	PINCTRL_PIN(12, "BM_BUSYB"),
+	PINCTRL_PIN(13, "SUSWARNB_SUS_PWRDNACK"),
+	PINCTRL_PIN(14, "SUS_STATB"),
+	PINCTRL_PIN(15, "SUSACKB"),
+	PINCTRL_PIN(16, "CLKOUT_48"),
+	PINCTRL_PIN(17, "ISH_GP_7"),
+	PINCTRL_PIN(18, "ISH_GP_0"),
+	PINCTRL_PIN(19, "ISH_GP_1"),
+	PINCTRL_PIN(20, "ISH_GP_2"),
+	PINCTRL_PIN(21, "ISH_GP_3"),
+	PINCTRL_PIN(22, "ISH_GP_4"),
+	PINCTRL_PIN(23, "ISH_GP_5"),
+	/* GPP_B */
+	PINCTRL_PIN(24, "CORE_VID_0"),
+	PINCTRL_PIN(25, "CORE_VID_1"),
+	PINCTRL_PIN(26, "VRALERTB"),
+	PINCTRL_PIN(27, "CPU_GP_2"),
+	PINCTRL_PIN(28, "CPU_GP_3"),
+	PINCTRL_PIN(29, "SRCCLKREQB_0"),
+	PINCTRL_PIN(30, "SRCCLKREQB_1"),
+	PINCTRL_PIN(31, "SRCCLKREQB_2"),
+	PINCTRL_PIN(32, "SRCCLKREQB_3"),
+	PINCTRL_PIN(33, "SRCCLKREQB_4"),
+	PINCTRL_PIN(34, "SRCCLKREQB_5"),
+	PINCTRL_PIN(35, "EXT_PWR_GATEB"),
+	PINCTRL_PIN(36, "SLP_S0B"),
+	PINCTRL_PIN(37, "PLTRSTB"),
+	PINCTRL_PIN(38, "SPKR"),
+	PINCTRL_PIN(39, "GSPI0_CSB"),
+	PINCTRL_PIN(40, "GSPI0_CLK"),
+	PINCTRL_PIN(41, "GSPI0_MISO"),
+	PINCTRL_PIN(42, "GSPI0_MOSI"),
+	PINCTRL_PIN(43, "GSPI1_CSB"),
+	PINCTRL_PIN(44, "GSPI1_CLK"),
+	PINCTRL_PIN(45, "GSPI1_MISO"),
+	PINCTRL_PIN(46, "GSPI1_MOSI"),
+	PINCTRL_PIN(47, "SML1ALERTB"),
+	/* GPP_C */
+	PINCTRL_PIN(48, "SMBCLK"),
+	PINCTRL_PIN(49, "SMBDATA"),
+	PINCTRL_PIN(50, "SMBALERTB"),
+	PINCTRL_PIN(51, "SML0CLK"),
+	PINCTRL_PIN(52, "SML0DATA"),
+	PINCTRL_PIN(53, "SML0ALERTB"),
+	PINCTRL_PIN(54, "SML1CLK"),
+	PINCTRL_PIN(55, "SML1DATA"),
+	PINCTRL_PIN(56, "UART0_RXD"),
+	PINCTRL_PIN(57, "UART0_TXD"),
+	PINCTRL_PIN(58, "UART0_RTSB"),
+	PINCTRL_PIN(59, "UART0_CTSB"),
+	PINCTRL_PIN(60, "UART1_RXD"),
+	PINCTRL_PIN(61, "UART1_TXD"),
+	PINCTRL_PIN(62, "UART1_RTSB"),
+	PINCTRL_PIN(63, "UART1_CTSB"),
+	PINCTRL_PIN(64, "I2C0_SDA"),
+	PINCTRL_PIN(65, "I2C0_SCL"),
+	PINCTRL_PIN(66, "I2C1_SDA"),
+	PINCTRL_PIN(67, "I2C1_SCL"),
+	PINCTRL_PIN(68, "UART2_RXD"),
+	PINCTRL_PIN(69, "UART2_TXD"),
+	PINCTRL_PIN(70, "UART2_RTSB"),
+	PINCTRL_PIN(71, "UART2_CTSB"),
+	/* GPP_D */
+	PINCTRL_PIN(72, "SPI1_CSB"),
+	PINCTRL_PIN(73, "SPI1_CLK"),
+	PINCTRL_PIN(74, "SPI1_MISO_IO_1"),
+	PINCTRL_PIN(75, "SPI1_MOSI_IO_0"),
+	PINCTRL_PIN(76, "ISH_I2C2_SDA"),
+	PINCTRL_PIN(77, "SSP0_SFRM"),
+	PINCTRL_PIN(78, "SSP0_TXD"),
+	PINCTRL_PIN(79, "SSP0_RXD"),
+	PINCTRL_PIN(80, "SSP0_SCLK"),
+	PINCTRL_PIN(81, "ISH_SPI_CSB"),
+	PINCTRL_PIN(82, "ISH_SPI_CLK"),
+	PINCTRL_PIN(83, "ISH_SPI_MISO"),
+	PINCTRL_PIN(84, "ISH_SPI_MOSI"),
+	PINCTRL_PIN(85, "ISH_UART0_RXD"),
+	PINCTRL_PIN(86, "ISH_UART0_TXD"),
+	PINCTRL_PIN(87, "ISH_UART0_RTSB"),
+	PINCTRL_PIN(88, "ISH_UART0_CTSB"),
+	PINCTRL_PIN(89, "DMIC_CLK_1"),
+	PINCTRL_PIN(90, "DMIC_DATA_1"),
+	PINCTRL_PIN(91, "DMIC_CLK_0"),
+	PINCTRL_PIN(92, "DMIC_DATA_0"),
+	PINCTRL_PIN(93, "SPI1_IO_2"),
+	PINCTRL_PIN(94, "SPI1_IO_3"),
+	PINCTRL_PIN(95, "ISH_I2C2_SCL"),
+	/* GPP_E */
+	PINCTRL_PIN(96, "SATAXPCIE_0"),
+	PINCTRL_PIN(97, "SATAXPCIE_1"),
+	PINCTRL_PIN(98, "SATAXPCIE_2"),
+	PINCTRL_PIN(99, "CPU_GP_0"),
+	PINCTRL_PIN(100, "SATA_DEVSLP_0"),
+	PINCTRL_PIN(101, "SATA_DEVSLP_1"),
+	PINCTRL_PIN(102, "SATA_DEVSLP_2"),
+	PINCTRL_PIN(103, "CPU_GP_1"),
+	PINCTRL_PIN(104, "SATA_LEDB"),
+	PINCTRL_PIN(105, "USB2_OCB_0"),
+	PINCTRL_PIN(106, "USB2_OCB_1"),
+	PINCTRL_PIN(107, "USB2_OCB_2"),
+	PINCTRL_PIN(108, "USB2_OCB_3"),
+	/* GPP_F */
+	PINCTRL_PIN(109, "SATAXPCIE_3"),
+	PINCTRL_PIN(110, "SATAXPCIE_4"),
+	PINCTRL_PIN(111, "SATAXPCIE_5"),
+	PINCTRL_PIN(112, "SATAXPCIE_6"),
+	PINCTRL_PIN(113, "SATAXPCIE_7"),
+	PINCTRL_PIN(114, "SATA_DEVSLP_3"),
+	PINCTRL_PIN(115, "SATA_DEVSLP_4"),
+	PINCTRL_PIN(116, "SATA_DEVSLP_5"),
+	PINCTRL_PIN(117, "SATA_DEVSLP_6"),
+	PINCTRL_PIN(118, "SATA_DEVSLP_7"),
+	PINCTRL_PIN(119, "SATA_SCLOCK"),
+	PINCTRL_PIN(120, "SATA_SLOAD"),
+	PINCTRL_PIN(121, "SATA_SDATAOUT1"),
+	PINCTRL_PIN(122, "SATA_SDATAOUT0"),
+	PINCTRL_PIN(123, "GPP_F_14"),
+	PINCTRL_PIN(124, "USB_OCB_4"),
+	PINCTRL_PIN(125, "USB_OCB_5"),
+	PINCTRL_PIN(126, "USB_OCB_6"),
+	PINCTRL_PIN(127, "USB_OCB_7"),
+	PINCTRL_PIN(128, "L_VDDEN"),
+	PINCTRL_PIN(129, "L_BKLTEN"),
+	PINCTRL_PIN(130, "L_BKLTCTL"),
+	PINCTRL_PIN(131, "GPP_F_22"),
+	PINCTRL_PIN(132, "GPP_F_23"),
+	/* GPP_G */
+	PINCTRL_PIN(133, "FAN_TACH_0"),
+	PINCTRL_PIN(134, "FAN_TACH_1"),
+	PINCTRL_PIN(135, "FAN_TACH_2"),
+	PINCTRL_PIN(136, "FAN_TACH_3"),
+	PINCTRL_PIN(137, "FAN_TACH_4"),
+	PINCTRL_PIN(138, "FAN_TACH_5"),
+	PINCTRL_PIN(139, "FAN_TACH_6"),
+	PINCTRL_PIN(140, "FAN_TACH_7"),
+	PINCTRL_PIN(141, "FAN_PWM_0"),
+	PINCTRL_PIN(142, "FAN_PWM_1"),
+	PINCTRL_PIN(143, "FAN_PWM_2"),
+	PINCTRL_PIN(144, "FAN_PWM_3"),
+	PINCTRL_PIN(145, "GSXDOUT"),
+	PINCTRL_PIN(146, "GSXSLOAD"),
+	PINCTRL_PIN(147, "GSXDIN"),
+	PINCTRL_PIN(148, "GSXRESETB"),
+	PINCTRL_PIN(149, "GSXCLK"),
+	PINCTRL_PIN(150, "ADR_COMPLETE"),
+	PINCTRL_PIN(151, "NMIB"),
+	PINCTRL_PIN(152, "SMIB"),
+	PINCTRL_PIN(153, "GPP_G_20"),
+	PINCTRL_PIN(154, "GPP_G_21"),
+	PINCTRL_PIN(155, "GPP_G_22"),
+	PINCTRL_PIN(156, "GPP_G_23"),
+	/* GPP_H */
+	PINCTRL_PIN(157, "SRCCLKREQB_6"),
+	PINCTRL_PIN(158, "SRCCLKREQB_7"),
+	PINCTRL_PIN(159, "SRCCLKREQB_8"),
+	PINCTRL_PIN(160, "SRCCLKREQB_9"),
+	PINCTRL_PIN(161, "SRCCLKREQB_10"),
+	PINCTRL_PIN(162, "SRCCLKREQB_11"),
+	PINCTRL_PIN(163, "SRCCLKREQB_12"),
+	PINCTRL_PIN(164, "SRCCLKREQB_13"),
+	PINCTRL_PIN(165, "SRCCLKREQB_14"),
+	PINCTRL_PIN(166, "SRCCLKREQB_15"),
+	PINCTRL_PIN(167, "SML2CLK"),
+	PINCTRL_PIN(168, "SML2DATA"),
+	PINCTRL_PIN(169, "SML2ALERTB"),
+	PINCTRL_PIN(170, "SML3CLK"),
+	PINCTRL_PIN(171, "SML3DATA"),
+	PINCTRL_PIN(172, "SML3ALERTB"),
+	PINCTRL_PIN(173, "SML4CLK"),
+	PINCTRL_PIN(174, "SML4DATA"),
+	PINCTRL_PIN(175, "SML4ALERTB"),
+	PINCTRL_PIN(176, "ISH_I2C0_SDA"),
+	PINCTRL_PIN(177, "ISH_I2C0_SCL"),
+	PINCTRL_PIN(178, "ISH_I2C1_SDA"),
+	PINCTRL_PIN(179, "ISH_I2C1_SCL"),
+	PINCTRL_PIN(180, "GPP_H_23"),
+	/* GPP_I */
+	PINCTRL_PIN(181, "DDSP_HDP_0"),
+	PINCTRL_PIN(182, "DDSP_HDP_1"),
+	PINCTRL_PIN(183, "DDSP_HDP_2"),
+	PINCTRL_PIN(184, "DDSP_HDP_3"),
+	PINCTRL_PIN(185, "EDP_HPD"),
+	PINCTRL_PIN(186, "DDPB_CTRLCLK"),
+	PINCTRL_PIN(187, "DDPB_CTRLDATA"),
+	PINCTRL_PIN(188, "DDPC_CTRLCLK"),
+	PINCTRL_PIN(189, "DDPC_CTRLDATA"),
+	PINCTRL_PIN(190, "DDPD_CTRLCLK"),
+	PINCTRL_PIN(191, "DDPD_CTRLDATA"),
+};
+
+static const unsigned spth_spi0_pins[] = { 39, 40, 41, 42 };
+static const unsigned spth_spi1_pins[] = { 43, 44, 45, 46 };
+static const unsigned spth_uart0_pins[] = { 56, 57, 58, 59 };
+static const unsigned spth_uart1_pins[] = { 60, 61, 62, 63 };
+static const unsigned spth_uart2_pins[] = { 68, 69, 71, 71 };
+static const unsigned spth_i2c0_pins[] = { 64, 65 };
+static const unsigned spth_i2c1_pins[] = { 66, 67 };
+static const unsigned spth_i2c2_pins[] = { 76, 95 };
+
+static const struct intel_pingroup spth_groups[] = {
+	PIN_GROUP("spi0_grp", spth_spi0_pins, 1),
+	PIN_GROUP("spi1_grp", spth_spi1_pins, 1),
+	PIN_GROUP("uart0_grp", spth_uart0_pins, 1),
+	PIN_GROUP("uart1_grp", spth_uart1_pins, 1),
+	PIN_GROUP("uart2_grp", spth_uart2_pins, 1),
+	PIN_GROUP("i2c0_grp", spth_i2c0_pins, 1),
+	PIN_GROUP("i2c1_grp", spth_i2c1_pins, 1),
+	PIN_GROUP("i2c2_grp", spth_i2c2_pins, 2),
+};
+
+static const char * const spth_spi0_groups[] = { "spi0_grp" };
+static const char * const spth_spi1_groups[] = { "spi0_grp" };
+static const char * const spth_uart0_groups[] = { "uart0_grp" };
+static const char * const spth_uart1_groups[] = { "uart1_grp" };
+static const char * const spth_uart2_groups[] = { "uart2_grp" };
+static const char * const spth_i2c0_groups[] = { "i2c0_grp" };
+static const char * const spth_i2c1_groups[] = { "i2c1_grp" };
+static const char * const spth_i2c2_groups[] = { "i2c2_grp" };
+
+static const struct intel_function spth_functions[] = {
+	FUNCTION("spi0", spth_spi0_groups),
+	FUNCTION("spi1", spth_spi1_groups),
+	FUNCTION("uart0", spth_uart0_groups),
+	FUNCTION("uart1", spth_uart1_groups),
+	FUNCTION("uart2", spth_uart2_groups),
+	FUNCTION("i2c0", spth_i2c0_groups),
+	FUNCTION("i2c1", spth_i2c1_groups),
+	FUNCTION("i2c2", spth_i2c2_groups),
+};
+
+static const struct intel_padgroup spth_community0_gpps[] = {
+	SPTH_GPP(0, 0, 23, 0),		/* GPP_A */
+	SPTH_GPP(1, 24, 47, 24),	/* GPP_B */
+};
+
+static const struct intel_padgroup spth_community1_gpps[] = {
+	SPTH_GPP(0, 48, 71, 48),	/* GPP_C */
+	SPTH_GPP(1, 72, 95, 72),	/* GPP_D */
+	SPTH_GPP(2, 96, 108, 96),	/* GPP_E */
+	SPTH_GPP(3, 109, 132, 120),	/* GPP_F */
+	SPTH_GPP(4, 133, 156, 144),	/* GPP_G */
+	SPTH_GPP(5, 157, 180, 168),	/* GPP_H */
+};
+
+static const struct intel_padgroup spth_community3_gpps[] = {
+	SPTH_GPP(0, 181, 191, 192),	/* GPP_I */
+};
+
+static const struct intel_community spth_communities[] = {
+	SPTH_COMMUNITY(0, 0, 47, spth_community0_gpps),
+	SPTH_COMMUNITY(1, 48, 180, spth_community1_gpps),
+	SPTH_COMMUNITY(2, 181, 191, spth_community3_gpps),
+};
+
+static const struct intel_pinctrl_soc_data spth_soc_data = {
+	.pins = spth_pins,
+	.npins = ARRAY_SIZE(spth_pins),
+	.groups = spth_groups,
+	.ngroups = ARRAY_SIZE(spth_groups),
+	.functions = spth_functions,
+	.nfunctions = ARRAY_SIZE(spth_functions),
+	.communities = spth_communities,
+	.ncommunities = ARRAY_SIZE(spth_communities),
+};
+
+static const struct acpi_device_id spt_pinctrl_acpi_match[] = {
+	{ "INT344B", (kernel_ulong_t)&sptlp_soc_data },
+	{ "INT345D", (kernel_ulong_t)&spth_soc_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, spt_pinctrl_acpi_match);
+
+static int spt_pinctrl_probe(struct platform_device *pdev)
+{
+	const struct intel_pinctrl_soc_data *soc_data;
+	const struct acpi_device_id *id;
+
+	id = acpi_match_device(spt_pinctrl_acpi_match, &pdev->dev);
+	if (!id || !id->driver_data)
+		return -ENODEV;
+
+	soc_data = (const struct intel_pinctrl_soc_data *)id->driver_data;
+	return intel_pinctrl_probe(pdev, soc_data);
+}
+
+static const struct dev_pm_ops spt_pinctrl_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
+				     intel_pinctrl_resume)
+};
+
+static struct platform_driver spt_pinctrl_driver = {
+	.probe = spt_pinctrl_probe,
+	.driver = {
+		.name = "sunrisepoint-pinctrl",
+		.acpi_match_table = spt_pinctrl_acpi_match,
+		.pm = &spt_pinctrl_pm_ops,
+	},
+};
+
+static int __init spt_pinctrl_init(void)
+{
+	return platform_driver_register(&spt_pinctrl_driver);
+}
+subsys_initcall(spt_pinctrl_init);
+
+static void __exit spt_pinctrl_exit(void)
+{
+	platform_driver_unregister(&spt_pinctrl_driver);
+}
+module_exit(spt_pinctrl_exit);
+
+MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>");
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+MODULE_DESCRIPTION("Intel Sunrisepoint PCH pinctrl/GPIO driver");
+MODULE_LICENSE("GPL v2");