Merge tag 'intel-pinctrl-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel into devel

intel-pinctrl for v5.4

A collection of improvements and fixes for Intel pinctrl drivers
including:

  - Converting drivers to use new devm_platform_ioremap_resource()
    helper function.

  - Make Interrupt Status (IS) register configurable.

  - Allow locked pins to be requested and used as long as they are not
    modified.

  - Fix intel_pinctrl_should_save() to translate pin number to GPIO
    number where needed. This fixes Asus X571GT touchpad
    unresponsiveness issue after suspend/resume cycle.
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index e5a112a..db6c5ca 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -98,13 +98,6 @@ struct byt_gpio_pin_context {
 	u32 val;
 };
 
-struct byt_community {
-	unsigned int pin_base;
-	size_t npins;
-	const unsigned int *pad_map;
-	void __iomem *reg_base;
-};
-
 #define COMMUNITY(p, n, map)		\
 	{				\
 		.pin_base	= (p),	\
@@ -112,26 +105,14 @@ struct byt_community {
 		.pad_map	= (map),\
 	}
 
-struct byt_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 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;
+	const struct intel_pinctrl_soc_data *soc_data;
+	struct intel_community *communities_copy;
 	struct byt_gpio_pin_context *saved_context;
 };
 
@@ -383,11 +364,11 @@ static const struct intel_function byt_score_functions[] = {
 	FUNCTION("gpio", byt_score_gpio_groups),
 };
 
-static const struct byt_community byt_score_communities[] = {
+static const struct intel_community byt_score_communities[] = {
 	COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
 };
 
-static const struct byt_pinctrl_soc_data byt_score_soc_data = {
+static const struct intel_pinctrl_soc_data byt_score_soc_data = {
 	.uid		= BYT_SCORE_ACPI_UID,
 	.pins		= byt_score_pins,
 	.npins		= ARRAY_SIZE(byt_score_pins),
@@ -496,11 +477,11 @@ static const struct intel_function byt_sus_functions[] = {
 	FUNCTION("gpio", byt_sus_gpio_groups),
 };
 
-static const struct byt_community byt_sus_communities[] = {
+static const struct intel_community byt_sus_communities[] = {
 	COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
 };
 
-static const struct byt_pinctrl_soc_data byt_sus_soc_data = {
+static const struct intel_pinctrl_soc_data byt_sus_soc_data = {
 	.uid		= BYT_SUS_ACPI_UID,
 	.pins		= byt_sus_pins,
 	.npins		= ARRAY_SIZE(byt_sus_pins),
@@ -549,11 +530,11 @@ static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
 	3, 6, 10, 13, 2, 5, 9, 7,
 };
 
-static const struct byt_community byt_ncore_communities[] = {
+static const struct intel_community byt_ncore_communities[] = {
 	COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
 };
 
-static const struct byt_pinctrl_soc_data byt_ncore_soc_data = {
+static const struct intel_pinctrl_soc_data byt_ncore_soc_data = {
 	.uid		= BYT_NCORE_ACPI_UID,
 	.pins		= byt_ncore_pins,
 	.npins		= ARRAY_SIZE(byt_ncore_pins),
@@ -561,17 +542,17 @@ static const struct byt_pinctrl_soc_data byt_ncore_soc_data = {
 	.ncommunities	= ARRAY_SIZE(byt_ncore_communities),
 };
 
-static const struct byt_pinctrl_soc_data *byt_soc_data[] = {
+static const struct intel_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)
+static struct intel_community *byt_get_community(struct byt_gpio *vg,
+						 unsigned int pin)
 {
-	struct byt_community *comm;
+	struct intel_community *comm;
 	int i;
 
 	for (i = 0; i < vg->soc_data->ncommunities; i++) {
@@ -586,7 +567,7 @@ static struct byt_community *byt_get_community(struct byt_gpio *vg,
 static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
 				  int reg)
 {
-	struct byt_community *comm = byt_get_community(vg, offset);
+	struct intel_community *comm = byt_get_community(vg, offset);
 	u32 reg_offset;
 
 	if (!comm)
@@ -605,7 +586,7 @@ static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
 		break;
 	}
 
-	return comm->reg_base + reg_offset + reg;
+	return comm->pad_regs + reg_offset + reg;
 }
 
 static int byt_get_groups_count(struct pinctrl_dev *pctldev)
@@ -1211,7 +1192,7 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 	u32 conf0, val;
 
 	for (i = 0; i < vg->soc_data->npins; i++) {
-		const struct byt_community *comm;
+		const struct intel_community *comm;
 		const char *pull_str = NULL;
 		const char *pull = NULL;
 		void __iomem *reg;
@@ -1566,7 +1547,7 @@ static int byt_gpio_probe(struct byt_gpio *vg)
 }
 
 static int byt_set_soc_data(struct byt_gpio *vg,
-			    const struct byt_pinctrl_soc_data *soc_data)
+			    const struct intel_pinctrl_soc_data *soc_data)
 {
 	int i;
 
@@ -1579,15 +1560,13 @@ static int byt_set_soc_data(struct byt_gpio *vg,
 		return -ENOMEM;
 
 	for (i = 0; i < soc_data->ncommunities; i++) {
-		struct byt_community *comm = vg->communities_copy + i;
-		struct resource *mem_rc;
+		struct intel_community *comm = vg->communities_copy + i;
 
 		*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);
+		comm->pad_regs = devm_platform_ioremap_resource(vg->pdev, 0);
+		if (IS_ERR(comm->pad_regs))
+			return PTR_ERR(comm->pad_regs);
 	}
 
 	return 0;
@@ -1601,8 +1580,8 @@ static const struct acpi_device_id 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 intel_pinctrl_soc_data *soc_data = NULL;
+	const struct intel_pinctrl_soc_data **soc_table;
 	struct acpi_device *acpi_dev;
 	struct byt_gpio *vg;
 	int i, ret;
@@ -1611,7 +1590,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
 	if (!acpi_dev)
 		return -ENODEV;
 
-	soc_table = (const struct byt_pinctrl_soc_data **)device_get_match_data(&pdev->dev);
+	soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(&pdev->dev);
 
 	for (i = 0; soc_table[i]; i++) {
 		if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) {
diff --git a/drivers/pinctrl/intel/pinctrl-broxton.c b/drivers/pinctrl/intel/pinctrl-broxton.c
index e2d4505..2be7e41 100644
--- a/drivers/pinctrl/intel/pinctrl-broxton.c
+++ b/drivers/pinctrl/intel/pinctrl-broxton.c
@@ -15,8 +15,9 @@
 #include "pinctrl-intel.h"
 
 #define BXT_PAD_OWN	0x020
-#define BXT_HOSTSW_OWN	0x080
 #define BXT_PADCFGLOCK	0x060
+#define BXT_HOSTSW_OWN	0x080
+#define BXT_GPI_IS	0x100
 #define BXT_GPI_IE	0x110
 
 #define BXT_COMMUNITY(s, e)				\
@@ -24,6 +25,7 @@
 		.padown_offset = BXT_PAD_OWN,		\
 		.padcfglock_offset = BXT_PADCFGLOCK,	\
 		.hostown_offset = BXT_HOSTSW_OWN,	\
+		.is_offset = BXT_GPI_IS,		\
 		.ie_offset = BXT_GPI_IE,		\
 		.gpp_size = 32,                         \
 		.pin_base = (s),			\
diff --git a/drivers/pinctrl/intel/pinctrl-cannonlake.c b/drivers/pinctrl/intel/pinctrl-cannonlake.c
index 08024b0..f51b27b 100644
--- a/drivers/pinctrl/intel/pinctrl-cannonlake.c
+++ b/drivers/pinctrl/intel/pinctrl-cannonlake.c
@@ -19,6 +19,7 @@
 #define CNL_PADCFGLOCK		0x080
 #define CNL_LP_HOSTSW_OWN	0x0b0
 #define CNL_H_HOSTSW_OWN	0x0c0
+#define CNL_GPI_IS		0x100
 #define CNL_GPI_IE		0x120
 
 #define CNL_GPP(r, s, e, g)				\
@@ -37,6 +38,7 @@
 		.padown_offset = CNL_PAD_OWN,		\
 		.padcfglock_offset = CNL_PADCFGLOCK,	\
 		.hostown_offset = (o),			\
+		.is_offset = CNL_GPI_IS,		\
 		.ie_offset = CNL_GPI_IE,		\
 		.pin_base = (s),			\
 		.npins = ((e) - (s) + 1),		\
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c
index 03ec7a5..cfb7168 100644
--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
+++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -1667,7 +1667,6 @@ 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;
 
@@ -1697,16 +1696,13 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
 		return -ENOMEM;
 #endif
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	pctrl->regs = devm_ioremap_resource(&pdev->dev, res);
+	pctrl->regs = devm_platform_ioremap_resource(pdev, 0);
 	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");
+	if (irq < 0)
 		return irq;
-	}
 
 	pctrl->pctldesc = chv_pinctrl_desc;
 	pctrl->pctldesc.name = dev_name(&pdev->dev);
diff --git a/drivers/pinctrl/intel/pinctrl-denverton.c b/drivers/pinctrl/intel/pinctrl-denverton.c
index 3a4932b..f26d030 100644
--- a/drivers/pinctrl/intel/pinctrl-denverton.c
+++ b/drivers/pinctrl/intel/pinctrl-denverton.c
@@ -15,8 +15,9 @@
 #include "pinctrl-intel.h"
 
 #define DNV_PAD_OWN	0x020
-#define DNV_HOSTSW_OWN	0x0C0
 #define DNV_PADCFGLOCK	0x090
+#define DNV_HOSTSW_OWN	0x0C0
+#define DNV_GPI_IS	0x100
 #define DNV_GPI_IE	0x120
 
 #define DNV_GPP(n, s, e)				\
@@ -32,6 +33,7 @@
 		.padown_offset = DNV_PAD_OWN,		\
 		.padcfglock_offset = DNV_PADCFGLOCK,	\
 		.hostown_offset = DNV_HOSTSW_OWN,	\
+		.is_offset = DNV_GPI_IS,		\
 		.ie_offset = DNV_GPI_IE,		\
 		.pin_base = (s),			\
 		.npins = ((e) - (s) + 1),		\
@@ -39,6 +41,7 @@
 		.ngpps = ARRAY_SIZE(g),			\
 	}
 
+/* Denverton */
 static const struct pinctrl_pin_desc dnv_pins[] = {
 	/* North ALL */
 	PINCTRL_PIN(0, "GBE0_SDP0"),
@@ -59,7 +62,7 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
 	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(18, "IDSLDO_VID_TICKLE"),
 	PINCTRL_PIN(19, "NCSI_TX_EN"),
 	PINCTRL_PIN(20, "NCSI_TXD0"),
 	PINCTRL_PIN(21, "NCSI_TXD1"),
@@ -68,14 +71,14 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
 	PINCTRL_PIN(24, "GBE0_LED1"),
 	PINCTRL_PIN(25, "GBE1_LED0"),
 	PINCTRL_PIN(26, "GBE1_LED1"),
-	PINCTRL_PIN(27, "GPIO_0"),
+	PINCTRL_PIN(27, "SPARE_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(33, "GBE_MDC"),
+	PINCTRL_PIN(34, "GBE_MDIO"),
 	PINCTRL_PIN(35, "SVID_ALERT_N"),
 	PINCTRL_PIN(36, "SVID_DATA"),
 	PINCTRL_PIN(37, "SVID_CLK"),
@@ -102,15 +105,15 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
 	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(59, "SPI_TPM_CS_N"),
+	PINCTRL_PIN(60, "UART2_CTS"),
 	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(66, "CPU_RESET_N"),
+	PINCTRL_PIN(67, "NMI"),
 	PINCTRL_PIN(68, "ERROR2_N"),
 	PINCTRL_PIN(69, "ERROR1_N"),
 	PINCTRL_PIN(70, "ERROR0_N"),
@@ -129,20 +132,20 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
 	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(86, "SPARE_4"),
+	PINCTRL_PIN(87, "SMB3_IE0_CLK"),
+	PINCTRL_PIN(88, "SMB3_IE0_DATA"),
+	PINCTRL_PIN(89, "SMB3_IE0_ALRT_N"),
 	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(94, "UART1_RTS"),
+	PINCTRL_PIN(95, "UART1_CTS"),
 	PINCTRL_PIN(96, "UART1_RXD"),
 	PINCTRL_PIN(97, "UART1_TXD"),
-	PINCTRL_PIN(98, "GPIO_8"),
-	PINCTRL_PIN(99, "GPIO_9"),
+	PINCTRL_PIN(98, "SPARE_8"),
+	PINCTRL_PIN(99, "SPARE_9"),
 	PINCTRL_PIN(100, "TCK"),
 	PINCTRL_PIN(101, "TRST_N"),
 	PINCTRL_PIN(102, "TMS"),
@@ -150,11 +153,11 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
 	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"),
+	PINCTRL_PIN(107, "TAP1_TCK"),
+	PINCTRL_PIN(108, "TAP1_TRST_N"),
+	PINCTRL_PIN(109, "TAP1_TMS"),
+	PINCTRL_PIN(110, "TAP1_TDI"),
+	PINCTRL_PIN(111, "TAP1_TDO"),
 	/* South GPP1 */
 	PINCTRL_PIN(112, "SUSPWRDNACK"),
 	PINCTRL_PIN(113, "PMU_SUSCLK"),
@@ -183,8 +186,8 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
 	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(139, "ESPI_CS1_N"),
+	PINCTRL_PIN(140, "ESPI_ALRT1_N"),
 	PINCTRL_PIN(141, "ESPI_CLK_LOOPBK"),
 	PINCTRL_PIN(142, "EMMC_CMD"),
 	PINCTRL_PIN(143, "EMMC_STROBE"),
@@ -197,7 +200,7 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
 	PINCTRL_PIN(150, "EMMC_D5"),
 	PINCTRL_PIN(151, "EMMC_D6"),
 	PINCTRL_PIN(152, "EMMC_D7"),
-	PINCTRL_PIN(153, "GPIO_3"),
+	PINCTRL_PIN(153, "SPARE_3"),
 };
 
 static const unsigned int dnv_uart0_pins[] = { 60, 61, 64, 65 };
diff --git a/drivers/pinctrl/intel/pinctrl-geminilake.c b/drivers/pinctrl/intel/pinctrl-geminilake.c
index 331b8fd..df02028 100644
--- a/drivers/pinctrl/intel/pinctrl-geminilake.c
+++ b/drivers/pinctrl/intel/pinctrl-geminilake.c
@@ -17,6 +17,7 @@
 #define GLK_PAD_OWN	0x020
 #define GLK_PADCFGLOCK	0x080
 #define GLK_HOSTSW_OWN	0x0b0
+#define GLK_GPI_IS	0x100
 #define GLK_GPI_IE	0x110
 
 #define GLK_COMMUNITY(s, e)				\
@@ -24,6 +25,7 @@
 		.padown_offset = GLK_PAD_OWN,		\
 		.padcfglock_offset = GLK_PADCFGLOCK,	\
 		.hostown_offset = GLK_HOSTSW_OWN,	\
+		.is_offset = GLK_GPI_IS,		\
 		.ie_offset = GLK_GPI_IE,		\
 		.gpp_size = 32,                         \
 		.pin_base = (s),			\
diff --git a/drivers/pinctrl/intel/pinctrl-icelake.c b/drivers/pinctrl/intel/pinctrl-icelake.c
index 5f2f5c6..6489e9b 100644
--- a/drivers/pinctrl/intel/pinctrl-icelake.c
+++ b/drivers/pinctrl/intel/pinctrl-icelake.c
@@ -18,6 +18,7 @@
 #define ICL_PAD_OWN	0x020
 #define ICL_PADCFGLOCK	0x080
 #define ICL_HOSTSW_OWN	0x0b0
+#define ICL_GPI_IS	0x100
 #define ICL_GPI_IE	0x110
 
 #define ICL_GPP(r, s, e, g)				\
@@ -36,6 +37,7 @@
 		.padown_offset = ICL_PAD_OWN,		\
 		.padcfglock_offset = ICL_PADCFGLOCK,	\
 		.hostown_offset = ICL_HOSTSW_OWN,	\
+		.is_offset = ICL_GPI_IS,		\
 		.ie_offset = ICL_GPI_IE,		\
 		.pin_base = (s),			\
 		.npins = ((e) - (s) + 1),		\
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
index a18d6ee..d66fe2b 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -8,12 +8,13 @@
  */
 
 #include <linux/acpi.h>
-#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/gpio/driver.h>
 #include <linux/log2.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/property.h>
+#include <linux/time.h>
 
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
@@ -29,7 +30,6 @@
 #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)
@@ -71,7 +71,7 @@
 #define PADCFG2_DEBOUNCE_SHIFT		1
 #define PADCFG2_DEBOUNCE_MASK		GENMASK(4, 1)
 
-#define DEBOUNCE_PERIOD			31250 /* ns */
+#define DEBOUNCE_PERIOD_NSEC		31250
 
 struct intel_pad_context {
 	u32 padcfg0;
@@ -165,7 +165,7 @@ static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl,
 	padno = pin_to_padno(community, pin);
 	nregs = (community->features & PINCTRL_FEATURE_DEBOUNCE) ? 4 : 2;
 
-	if (reg == PADCFG2 && !(community->features & PINCTRL_FEATURE_DEBOUNCE))
+	if (reg >= nregs * 4)
 		return NULL;
 
 	return community->pad_regs + reg + padno * nregs * 4;
@@ -220,47 +220,71 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin)
 	return !(readl(hostown) & BIT(gpp_offset));
 }
 
-static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
+/**
+ * enum - Locking variants of the pad configuration
+ *
+ * @PAD_UNLOCKED:	pad is fully controlled by the configuration registers
+ * @PAD_LOCKED:		pad configuration registers, except TX state, are locked
+ * @PAD_LOCKED_TX:	pad configuration TX state is locked
+ * @PAD_LOCKED_FULL:	pad configuration registers are locked completely
+ *
+ * Locking is considered as read-only mode for corresponding registers and
+ * their respective fields. That said, TX state bit is locked separately from
+ * the main locking scheme.
+ */
+enum {
+	PAD_UNLOCKED	= 0,
+	PAD_LOCKED	= 1,
+	PAD_LOCKED_TX	= 2,
+	PAD_LOCKED_FULL	= PAD_LOCKED | PAD_LOCKED_TX,
+};
+
+static int intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
 {
 	struct intel_community *community;
 	const struct intel_padgroup *padgrp;
 	unsigned int offset, gpp_offset;
 	u32 value;
+	int ret = PAD_UNLOCKED;
 
 	community = intel_get_community(pctrl, pin);
 	if (!community)
-		return true;
+		return PAD_LOCKED_FULL;
 	if (!community->padcfglock_offset)
-		return false;
+		return PAD_UNLOCKED;
 
 	padgrp = intel_community_get_padgroup(community, pin);
 	if (!padgrp)
-		return true;
+		return PAD_LOCKED_FULL;
 
 	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.
+	 * either fully or partially locked.
 	 */
-	offset = community->padcfglock_offset + padgrp->reg_num * 8;
+	offset = community->padcfglock_offset + 0 + padgrp->reg_num * 8;
 	value = readl(community->regs + offset);
 	if (value & BIT(gpp_offset))
-		return true;
+		ret |= PAD_LOCKED;
 
 	offset = community->padcfglock_offset + 4 + padgrp->reg_num * 8;
 	value = readl(community->regs + offset);
 	if (value & BIT(gpp_offset))
-		return true;
+		ret |= PAD_LOCKED_TX;
 
-	return false;
+	return ret;
+}
+
+static bool intel_pad_is_unlocked(struct intel_pinctrl *pctrl, unsigned int pin)
+{
+	return (intel_pad_locked(pctrl, pin) & PAD_LOCKED) == PAD_UNLOCKED;
 }
 
 static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned int pin)
 {
-	return intel_pad_owned_by_host(pctrl, pin) &&
-		!intel_pad_locked(pctrl, pin);
+	return intel_pad_owned_by_host(pctrl, pin) && intel_pad_is_unlocked(pctrl, pin);
 }
 
 static int intel_get_groups_count(struct pinctrl_dev *pctldev)
@@ -294,7 +318,8 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
 	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
 	void __iomem *padcfg;
 	u32 cfg0, cfg1, mode;
-	bool locked, acpi;
+	int locked;
+	bool acpi;
 
 	if (!intel_pad_owned_by_host(pctrl, pin)) {
 		seq_puts(s, "not available");
@@ -322,11 +347,16 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
 
 	if (locked || acpi) {
 		seq_puts(s, " [");
-		if (locked) {
+		if (locked)
 			seq_puts(s, "LOCKED");
-			if (acpi)
-				seq_puts(s, ", ");
-		}
+		if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_TX)
+			seq_puts(s, " tx");
+		else if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_FULL)
+			seq_puts(s, " full");
+
+		if (locked && acpi)
+			seq_puts(s, ", ");
+
 		if (acpi)
 			seq_puts(s, "ACPI");
 		seq_puts(s, "]");
@@ -448,11 +478,16 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
 
 	raw_spin_lock_irqsave(&pctrl->lock, flags);
 
-	if (!intel_pad_usable(pctrl, pin)) {
+	if (!intel_pad_owned_by_host(pctrl, pin)) {
 		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
 		return -EBUSY;
 	}
 
+	if (!intel_pad_is_unlocked(pctrl, pin)) {
+		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+		return 0;
+	}
+
 	padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
 	intel_gpio_set_gpio_mode(padcfg0);
 	/* Disable TX buffer and enable RX (this will be input) */
@@ -566,7 +601,7 @@ static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
 			return -EINVAL;
 
 		v = (v & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT;
-		arg = BIT(v) * DEBOUNCE_PERIOD / 1000;
+		arg = BIT(v) * DEBOUNCE_PERIOD_NSEC / NSEC_PER_USEC;
 
 		break;
 	}
@@ -683,7 +718,7 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl,
 	if (debounce) {
 		unsigned long v;
 
-		v = order_base_2(debounce * 1000 / DEBOUNCE_PERIOD);
+		v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC);
 		if (v < 3 || v > 15) {
 			ret = -EINVAL;
 			goto exit_unlock;
@@ -796,6 +831,29 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset,
 	return -EINVAL;
 }
 
+/**
+ * intel_pin_to_gpio() - Translate from pin number to GPIO offset
+ * @pctrl: Pinctrl structure
+ * @pin: pin number
+ *
+ * Translate the pin number of pinctrl to GPIO offset
+ */
+static int intel_pin_to_gpio(struct intel_pinctrl *pctrl, int pin)
+{
+	const struct intel_community *community;
+	const struct intel_padgroup *padgrp;
+
+	community = intel_get_community(pctrl, pin);
+	if (!community)
+		return -EINVAL;
+
+	padgrp = intel_community_get_padgroup(community, pin);
+	if (!padgrp)
+		return -EINVAL;
+
+	return pin - padgrp->base + padgrp->gpio_base;
+}
+
 static int intel_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
 	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
@@ -1313,15 +1371,12 @@ static int intel_pinctrl_probe(struct platform_device *pdev,
 
 	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);
+		regs = devm_platform_ioremap_resource(pdev, community->barno);
 		if (IS_ERR(regs))
 			return PTR_ERR(regs);
 
@@ -1345,19 +1400,14 @@ static int intel_pinctrl_probe(struct platform_device *pdev,
 		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");
+	if (irq < 0)
 		return irq;
-	}
 
 	ret = intel_pinctrl_pm_init(pctrl);
 	if (ret)
@@ -1421,8 +1471,6 @@ int intel_pinctrl_probe_by_uid(struct platform_device *pdev)
 		table = (const struct intel_pinctrl_soc_data **)id->driver_data;
 		data = table[pdev->id];
 	}
-	if (!data)
-		return -ENODEV;
 
 	return intel_pinctrl_probe(pdev, data);
 }
@@ -1443,7 +1491,7 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int
 	 * them alone.
 	 */
 	if (pd->mux_owner || pd->gpio_owner ||
-	    gpiochip_line_is_irq(&pctrl->chip, pin))
+	    gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin)))
 		return true;
 
 	return false;
diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h
index a8e958f..34b38a3 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.h
+++ b/drivers/pinctrl/intel/pinctrl-intel.h
@@ -75,9 +75,9 @@ struct intel_padgroup {
  * @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).
+ * @is_offset: Register offset of GPI_IS from @regs.
  * @ie_offset: Register offset of GPI_IE from @regs.
+ * @features: Additional features supported by the hardware
  * @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.
@@ -85,9 +85,9 @@ struct intel_padgroup {
  *			 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
+ * @pad_map: Optional non-linear mapping of the pads
  * @regs: Community specific common registers (reserved for core driver)
  * @pad_regs: Community specific pad registers (reserved for core driver)
  *
@@ -104,13 +104,14 @@ struct intel_community {
 	unsigned int hostown_offset;
 	unsigned int is_offset;
 	unsigned int ie_offset;
+	unsigned int features;
 	unsigned int pin_base;
 	unsigned int gpp_size;
 	unsigned int gpp_num_padown_regs;
 	size_t npins;
-	unsigned int features;
 	const struct intel_padgroup *gpps;
 	size_t ngpps;
+	const unsigned int *pad_map;
 	/* Reserved for the core driver */
 	void __iomem *regs;
 	void __iomem *pad_regs;
diff --git a/drivers/pinctrl/intel/pinctrl-lewisburg.c b/drivers/pinctrl/intel/pinctrl-lewisburg.c
index 03b04c7..2e06fb1 100644
--- a/drivers/pinctrl/intel/pinctrl-lewisburg.c
+++ b/drivers/pinctrl/intel/pinctrl-lewisburg.c
@@ -17,6 +17,7 @@
 #define LBG_PAD_OWN	0x020
 #define LBG_PADCFGLOCK	0x060
 #define LBG_HOSTSW_OWN	0x080
+#define LBG_GPI_IS	0x100
 #define LBG_GPI_IE	0x110
 
 #define LBG_COMMUNITY(b, s, e)				\
@@ -25,6 +26,7 @@
 		.padown_offset = LBG_PAD_OWN,		\
 		.padcfglock_offset = LBG_PADCFGLOCK,	\
 		.hostown_offset = LBG_HOSTSW_OWN,	\
+		.is_offset = LBG_GPI_IS,		\
 		.ie_offset = LBG_GPI_IE,		\
 		.gpp_size = 24,				\
 		.pin_base = (s),			\
diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c
index 4b65e12..04ca8ae 100644
--- a/drivers/pinctrl/intel/pinctrl-merrifield.c
+++ b/drivers/pinctrl/intel/pinctrl-merrifield.c
@@ -885,7 +885,6 @@ 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;
@@ -897,8 +896,7 @@ static int mrfld_pinctrl_probe(struct platform_device *pdev)
 	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);
+	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs))
 		return PTR_ERR(regs);
 
diff --git a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c
index ccafeea..44d7f50 100644
--- a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c
+++ b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c
@@ -18,6 +18,7 @@
 #define SPT_PAD_OWN	0x020
 #define SPT_PADCFGLOCK	0x0a0
 #define SPT_HOSTSW_OWN	0x0d0
+#define SPT_GPI_IS	0x100
 #define SPT_GPI_IE	0x120
 
 #define SPT_COMMUNITY(b, s, e)				\
@@ -26,6 +27,7 @@
 		.padown_offset = SPT_PAD_OWN,		\
 		.padcfglock_offset = SPT_PADCFGLOCK,	\
 		.hostown_offset = SPT_HOSTSW_OWN,	\
+		.is_offset = SPT_GPI_IS,		\
 		.ie_offset = SPT_GPI_IE,		\
 		.gpp_size = 24,				\
 		.gpp_num_padown_regs = 4,		\