diff --git a/Documentation/devicetree/bindings/gpio/gpio-msm.txt b/Documentation/devicetree/bindings/gpio/gpio-msm.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ac20e68a004e13e6c1544644f04d35715c0d456b
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-msm.txt
@@ -0,0 +1,26 @@
+MSM GPIO controller bindings
+
+Required properties:
+- compatible:
+  - "qcom,msm-gpio" for MSM controllers
+- #gpio-cells : Should be two.
+  - first cell is the pin number
+  - second cell is used to specify optional parameters (unused)
+- gpio-controller : Marks the device node as a GPIO controller.
+- #interrupt-cells : Should be 2.
+- interrupt-controller: Mark the device node as an interrupt controller
+- interrupts : Specify the TLMM summary interrupt number
+- ngpio : Specify the number of MSM GPIOs
+
+Example:
+
+	msmgpio: gpio@fd510000 {
+		compatible = "qcom,msm-gpio";
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		reg = <0xfd510000 0x4000>;
+		interrupts = <0 208 0>;
+		ngpio = <150>;
+	};
diff --git a/arch/arm/boot/dts/msm8660-surf.dts b/arch/arm/boot/dts/msm8660-surf.dts
index d347082d28f3a1a541297bd5c2c36b6d083adfe7..cdc010e0f93edcd330be85f74bda223951d6eaae 100644
--- a/arch/arm/boot/dts/msm8660-surf.dts
+++ b/arch/arm/boot/dts/msm8660-surf.dts
@@ -26,6 +26,17 @@ timer@2000000 {
 		cpu-offset = <0x40000>;
 	};
 
+	msmgpio: gpio@800000 {
+		compatible = "qcom,msm-gpio";
+		reg = <0x00800000 0x1000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		ngpio = <173>;
+		interrupts = <0 32 0x4>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
 	serial@19c40000 {
 		compatible = "qcom,msm-hsuart", "qcom,msm-uart";
 		reg = <0x19c40000 0x1000>,
diff --git a/arch/arm/boot/dts/msm8960-cdp.dts b/arch/arm/boot/dts/msm8960-cdp.dts
index 7c9ef9b80c159afa8f2de2b6ea31d157d7c64642..e9eb83541c975850af157b532fab6e3d61d2518d 100644
--- a/arch/arm/boot/dts/msm8960-cdp.dts
+++ b/arch/arm/boot/dts/msm8960-cdp.dts
@@ -26,7 +26,18 @@ timer@200a000 {
 		cpu-offset = <0x80000>;
 	};
 
-	serial@16440000 {
+	msmgpio: gpio@fd510000 {
+		compatible = "qcom,msm-gpio";
+		gpio-controller;
+		#gpio-cells = <2>;
+		ngpio = <150>;
+		interrupts = <0 32 0x4>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		reg = <0xfd510000 0x4000>;
+	};
+
+	serial@19440000 {
 		compatible = "qcom,msm-hsuart", "qcom,msm-uart";
 		reg = <0x16440000 0x1000>,
 		      <0x16400000 0x1000>;
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index fceb093b949425724ebc0219471a63e6a1e94715..614e41e7881b538b77bc4c5ab0b5430de7175bea 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -48,9 +48,7 @@ config ARCH_MSM8X60
 	select CPU_V7
 	select GPIO_MSM_V2
 	select HAVE_SMP
-	select MSM_GPIOMUX
 	select MSM_SCM if SMP
-	select MSM_V2_TLMM
 	select USE_OF
 
 config ARCH_MSM8960
@@ -58,9 +56,8 @@ config ARCH_MSM8960
 	select ARM_GIC
 	select CPU_V7
 	select HAVE_SMP
-	select MSM_GPIOMUX
+	select GPIO_MSM_V2
 	select MSM_SCM if SMP
-	select MSM_V2_TLMM
 	select USE_OF
 
 config MSM_HAS_DEBUG_UART_HS
@@ -124,10 +121,10 @@ config MSM_SMD
 	bool
 
 config MSM_GPIOMUX
-	bool
-
-config MSM_V2_TLMM
-	bool
+	depends on !(ARCH_MSM8X60 || ARCH_MSM8960)
+	bool "MSM V1 TLMM GPIOMUX architecture"
+	help
+	  Support for MSM V1 TLMM GPIOMUX architecture.
 
 config MSM_SCM
 	bool
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 17519faf082f5b0c016953222490a0f93db241cf..1a26d04c9400d46a7a72266aeb040e0b9e66dd9f 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -27,7 +27,5 @@ obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
 obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
 obj-$(CONFIG_ARCH_MSM8X60) += board-dt-8660.o
 obj-$(CONFIG_ARCH_MSM8960) += board-dt-8960.o
-
-obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-v1.o gpiomux.o
-obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o
-obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o
+obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
+obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
diff --git a/arch/arm/mach-msm/board-dt-8660.c b/arch/arm/mach-msm/board-dt-8660.c
index 7dcfc5300bbd2e6a8345d73899f7b74d4568825e..492f5cd87b0a74d7ba3fd02545adf7a7297f656b 100644
--- a/arch/arm/mach-msm/board-dt-8660.c
+++ b/arch/arm/mach-msm/board-dt-8660.c
@@ -11,7 +11,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/irqchip.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 
@@ -44,7 +43,6 @@ static const char *msm8x60_fluid_match[] __initdata = {
 DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
 	.smp = smp_ops(msm_smp_ops),
 	.map_io = msm_map_msm8x60_io,
-	.init_irq = irqchip_init,
 	.init_machine = msm8x60_dt_init,
 	.init_late = msm8x60_init_late,
 	.init_time	= msm_dt_timer_init,
diff --git a/arch/arm/mach-msm/board-dt-8960.c b/arch/arm/mach-msm/board-dt-8960.c
index 73019363ffa4db099ea801a85fe7a9d8a4b0b3ff..bb5530957c4fcfd4d0fc0086d3b162ff69438644 100644
--- a/arch/arm/mach-msm/board-dt-8960.c
+++ b/arch/arm/mach-msm/board-dt-8960.c
@@ -11,7 +11,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/irqchip.h>
 #include <linux/of_platform.h>
 
 #include <asm/mach/arch.h>
@@ -31,7 +30,6 @@ static const char * const msm8960_dt_match[] __initconst = {
 DT_MACHINE_START(MSM8960_DT, "Qualcomm MSM (Flattened Device Tree)")
 	.smp = smp_ops(msm_smp_ops),
 	.map_io = msm_map_msm8960_io,
-	.init_irq = irqchip_init,
 	.init_time	= msm_dt_timer_init,
 	.init_machine = msm_dt_init,
 	.dt_compat = msm8960_dt_match,
diff --git a/arch/arm/mach-msm/core.h b/arch/arm/mach-msm/core.h
deleted file mode 100644
index a9bab53dddf467931f83af64eb9b59e545cbc5d9..0000000000000000000000000000000000000000
--- a/arch/arm/mach-msm/core.h
+++ /dev/null
@@ -1,2 +0,0 @@
-extern struct smp_operations msm_smp_ops;
-extern void msm_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-msm/gpiomux-8x60.c b/arch/arm/mach-msm/gpiomux-8x60.c
deleted file mode 100644
index 7b380b31bd0e26cfd44879cca656466b556b38b3..0000000000000000000000000000000000000000
--- a/arch/arm/mach-msm/gpiomux-8x60.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-#include "gpiomux.h"
-
-struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {};
diff --git a/arch/arm/mach-msm/gpiomux-v2.c b/arch/arm/mach-msm/gpiomux-v2.c
deleted file mode 100644
index 273396d2b12779578a8ce0692941059e68fc1a42..0000000000000000000000000000000000000000
--- a/arch/arm/mach-msm/gpiomux-v2.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-#include <linux/io.h>
-#include <mach/msm_iomap.h>
-#include "gpiomux.h"
-
-void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
-{
-	writel(val & ~GPIOMUX_CTL_MASK,
-	       MSM_TLMM_BASE + 0x1000 + (0x10 * gpio));
-}
diff --git a/arch/arm/mach-msm/gpiomux-v2.h b/arch/arm/mach-msm/gpiomux-v2.h
deleted file mode 100644
index 3bf10e7f03815f65e0b24fb39b8375c96b010117..0000000000000000000000000000000000000000
--- a/arch/arm/mach-msm/gpiomux-v2.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
-#define __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
-
-#define GPIOMUX_NGPIOS 173
-
-typedef u16 gpiomux_config_t;
-
-enum {
-	GPIOMUX_DRV_2MA  = 0UL << 6,
-	GPIOMUX_DRV_4MA  = 1UL << 6,
-	GPIOMUX_DRV_6MA  = 2UL << 6,
-	GPIOMUX_DRV_8MA  = 3UL << 6,
-	GPIOMUX_DRV_10MA = 4UL << 6,
-	GPIOMUX_DRV_12MA = 5UL << 6,
-	GPIOMUX_DRV_14MA = 6UL << 6,
-	GPIOMUX_DRV_16MA = 7UL << 6,
-};
-
-enum {
-	GPIOMUX_FUNC_GPIO = 0UL  << 2,
-	GPIOMUX_FUNC_1    = 1UL  << 2,
-	GPIOMUX_FUNC_2    = 2UL  << 2,
-	GPIOMUX_FUNC_3    = 3UL  << 2,
-	GPIOMUX_FUNC_4    = 4UL  << 2,
-	GPIOMUX_FUNC_5    = 5UL  << 2,
-	GPIOMUX_FUNC_6    = 6UL  << 2,
-	GPIOMUX_FUNC_7    = 7UL  << 2,
-	GPIOMUX_FUNC_8    = 8UL  << 2,
-	GPIOMUX_FUNC_9    = 9UL  << 2,
-	GPIOMUX_FUNC_A    = 10UL << 2,
-	GPIOMUX_FUNC_B    = 11UL << 2,
-	GPIOMUX_FUNC_C    = 12UL << 2,
-	GPIOMUX_FUNC_D    = 13UL << 2,
-	GPIOMUX_FUNC_E    = 14UL << 2,
-	GPIOMUX_FUNC_F    = 15UL << 2,
-};
-
-enum {
-	GPIOMUX_PULL_NONE   = 0UL,
-	GPIOMUX_PULL_DOWN   = 1UL,
-	GPIOMUX_PULL_KEEPER = 2UL,
-	GPIOMUX_PULL_UP     = 3UL,
-};
-
-#endif
diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
index 53af21abd155bba6c15f2ad281c00e03cfb05067..2b8e2d21708269bb41b4d16593d560fcb5d18e0f 100644
--- a/arch/arm/mach-msm/gpiomux.c
+++ b/arch/arm/mach-msm/gpiomux.c
@@ -17,9 +17,24 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include "gpiomux.h"
+#include "proc_comm.h"
 
 static DEFINE_SPINLOCK(gpiomux_lock);
 
+static void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
+{
+	unsigned tlmm_config  = (val & ~GPIOMUX_CTL_MASK) |
+				((gpio & 0x3ff) << 4);
+	unsigned tlmm_disable = 0;
+	int rc;
+
+	rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX,
+			   &tlmm_config, &tlmm_disable);
+	if (rc)
+		pr_err("%s: unexpected proc_comm failure %d: %08x %08x\n",
+		       __func__, rc, tlmm_config, tlmm_disable);
+}
+
 int msm_gpiomux_write(unsigned gpio,
 		      gpiomux_config_t active,
 		      gpiomux_config_t suspended)
diff --git a/arch/arm/mach-msm/gpiomux.h b/arch/arm/mach-msm/gpiomux.h
index 00459f6ee13c337ede196e8f512234128b2a391a..8e82f41a89235e4fbef3f7f2b7e0b7c26c84dbfc 100644
--- a/arch/arm/mach-msm/gpiomux.h
+++ b/arch/arm/mach-msm/gpiomux.h
@@ -20,12 +20,7 @@
 #include <linux/bitops.h>
 #include <linux/errno.h>
 #include <mach/msm_gpiomux.h>
-
-#if defined(CONFIG_MSM_V2_TLMM)
-#include "gpiomux-v2.h"
-#else
 #include "gpiomux-v1.h"
-#endif
 
 /**
  * struct msm_gpiomux_config: gpiomux settings for one gpio line.
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
index 9819a556acae5d0837d63cfc703d97344eddd53f..7bca8d7108d687f70ff0f532654d09ec45af0db1 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
@@ -32,13 +32,6 @@
  *
  */
 
-
-#define MSM8960_QGIC_DIST_PHYS	0x02000000
-#define MSM8960_QGIC_DIST_SIZE	SZ_4K
-
-#define MSM8960_QGIC_CPU_PHYS	0x02002000
-#define MSM8960_QGIC_CPU_SIZE	SZ_4K
-
 #define MSM8960_TMR_PHYS	0x0200A000
 #define MSM8960_TMR_SIZE	SZ_4K
 
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
index 199372e62defbf3241ea20eb0b48bce3c917614d..75a7b62c1c7439033bbac975b8f2147503c30f33 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
@@ -35,12 +35,6 @@
  *
  */
 
-#define MSM8X60_QGIC_DIST_PHYS	0x02080000
-#define MSM8X60_QGIC_DIST_SIZE	SZ_4K
-
-#define MSM8X60_QGIC_CPU_PHYS	0x02081000
-#define MSM8X60_QGIC_CPU_SIZE	SZ_4K
-
 #define MSM_TLMM_BASE		IOMEM(0xF0004000)
 #define MSM_TLMM_PHYS		0x00800000
 #define MSM_TLMM_SIZE		SZ_16K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 2ab7cf0919b37f53afc3b4c563b850170f65fa64..c56e81ffdcdead314be34247d2fd040f4b20a399 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -62,8 +62,6 @@
 
 /* Virtual addresses shared across all MSM targets. */
 #define MSM_CSR_BASE		IOMEM(0xE0001000)
-#define MSM_QGIC_DIST_BASE	IOMEM(0xF0000000)
-#define MSM_QGIC_CPU_BASE	IOMEM(0xF0001000)
 #define MSM_TMR_BASE		IOMEM(0xF0200000)
 #define MSM_TMR0_BASE		IOMEM(0xF0201000)
 #define MSM_GPIO1_BASE		IOMEM(0xE0003000)
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 123ef9cbce1b2c42f605b3bb19aaacb44dbdd378..efa113e4de86ff47b05739cb09b138dd5fec1ff9 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -107,8 +107,6 @@ void __init msm_map_qsd8x50_io(void)
 
 #ifdef CONFIG_ARCH_MSM8X60
 static struct map_desc msm8x60_io_desc[] __initdata = {
-	MSM_CHIP_DEVICE(QGIC_DIST, MSM8X60),
-	MSM_CHIP_DEVICE(QGIC_CPU, MSM8X60),
 	MSM_CHIP_DEVICE(TMR, MSM8X60),
 	MSM_CHIP_DEVICE(TMR0, MSM8X60),
 #ifdef CONFIG_DEBUG_MSM8660_UART
@@ -124,8 +122,6 @@ void __init msm_map_msm8x60_io(void)
 
 #ifdef CONFIG_ARCH_MSM8960
 static struct map_desc msm8960_io_desc[] __initdata = {
-	MSM_CHIP_DEVICE(QGIC_DIST, MSM8960),
-	MSM_CHIP_DEVICE(QGIC_CPU, MSM8960),
 	MSM_CHIP_DEVICE(TMR, MSM8960),
 	MSM_CHIP_DEVICE(TMR0, MSM8960),
 #ifdef CONFIG_DEBUG_MSM8960_UART
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 573c449c49b9138a69f8aaf9a999e8a41898d2e1..847a6dc15a543cbf4e9544a1fe0a60057117a45b 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -165,7 +165,7 @@ config GPIO_MSM_V1
 
 config GPIO_MSM_V2
 	tristate "Qualcomm MSM GPIO v2"
-	depends on GPIOLIB && ARCH_MSM
+	depends on GPIOLIB && OF && ARCH_MSM
 	help
 	  Say yes here to support the GPIO interface on ARM v7 based
 	  Qualcomm MSM chips.  Most of the pins on the MSM can be
diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c
index dd2eddeb1e0c43e1511edd98b5617c31b3538ce7..f4491a497cc8760ef59484ac2c6c264573b3b8a9 100644
--- a/drivers/gpio/gpio-msm-v2.c
+++ b/drivers/gpio/gpio-msm-v2.c
@@ -19,18 +19,21 @@
 
 #include <linux/bitmap.h>
 #include <linux/bitops.h>
+#include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/module.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
-#include <mach/msm_gpiomux.h>
-#include <mach/msm_iomap.h>
+#define MAX_NR_GPIO 300
 
 /* Bits of interest in the GPIO_IN_OUT register.
  */
@@ -77,13 +80,6 @@ enum {
 	TARGET_PROC_NONE     = 7,
 };
 
-
-#define GPIO_INTR_CFG_SU(gpio)    (MSM_TLMM_BASE + 0x0400 + (0x04 * (gpio)))
-#define GPIO_CONFIG(gpio)         (MSM_TLMM_BASE + 0x1000 + (0x10 * (gpio)))
-#define GPIO_IN_OUT(gpio)         (MSM_TLMM_BASE + 0x1004 + (0x10 * (gpio)))
-#define GPIO_INTR_CFG(gpio)       (MSM_TLMM_BASE + 0x1008 + (0x10 * (gpio)))
-#define GPIO_INTR_STATUS(gpio)    (MSM_TLMM_BASE + 0x100c + (0x10 * (gpio)))
-
 /**
  * struct msm_gpio_dev: the MSM8660 SoC GPIO device structure
  *
@@ -102,11 +98,27 @@ enum {
  */
 struct msm_gpio_dev {
 	struct gpio_chip gpio_chip;
-	DECLARE_BITMAP(enabled_irqs, NR_GPIO_IRQS);
-	DECLARE_BITMAP(wake_irqs, NR_GPIO_IRQS);
-	DECLARE_BITMAP(dual_edge_irqs, NR_GPIO_IRQS);
+	DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
+	DECLARE_BITMAP(wake_irqs, MAX_NR_GPIO);
+	DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
+	struct irq_domain *domain;
+	unsigned int summary_irq;
+	void __iomem *msm_tlmm_base;
 };
 
+struct msm_gpio_dev msm_gpio;
+
+#define GPIO_INTR_CFG_SU(gpio)    (msm_gpio.msm_tlmm_base + 0x0400 + \
+								(0x04 * (gpio)))
+#define GPIO_CONFIG(gpio)         (msm_gpio.msm_tlmm_base + 0x1000 + \
+								(0x10 * (gpio)))
+#define GPIO_IN_OUT(gpio)         (msm_gpio.msm_tlmm_base + 0x1004 + \
+								(0x10 * (gpio)))
+#define GPIO_INTR_CFG(gpio)       (msm_gpio.msm_tlmm_base + 0x1008 + \
+								(0x10 * (gpio)))
+#define GPIO_INTR_STATUS(gpio)    (msm_gpio.msm_tlmm_base + 0x100c + \
+								(0x10 * (gpio)))
+
 static DEFINE_SPINLOCK(tlmm_lock);
 
 static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip)
@@ -159,37 +171,29 @@ static int msm_gpio_direction_output(struct gpio_chip *chip,
 
 static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
 {
-	return msm_gpiomux_get(chip->base + offset);
+	return 0;
 }
 
 static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
 {
-	msm_gpiomux_put(chip->base + offset);
+	return;
 }
 
 static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
-	return MSM_GPIO_TO_INT(chip->base + offset);
+	struct msm_gpio_dev *g_dev = to_msm_gpio_dev(chip);
+	struct irq_domain *domain = g_dev->domain;
+
+	return irq_create_mapping(domain, offset);
 }
 
 static inline int msm_irq_to_gpio(struct gpio_chip *chip, unsigned irq)
 {
-	return irq - MSM_GPIO_TO_INT(chip->base);
+	struct irq_data *irq_data = irq_get_irq_data(irq);
+
+	return irq_data->hwirq;
 }
 
-static struct msm_gpio_dev msm_gpio = {
-	.gpio_chip = {
-		.base             = 0,
-		.ngpio            = NR_GPIO_IRQS,
-		.direction_input  = msm_gpio_direction_input,
-		.direction_output = msm_gpio_direction_output,
-		.get              = msm_gpio_get,
-		.set              = msm_gpio_set,
-		.to_irq           = msm_gpio_to_irq,
-		.request          = msm_gpio_request,
-		.free             = msm_gpio_free,
-	},
-};
 
 /* For dual-edge interrupts in software, since the hardware has no
  * such support:
@@ -227,9 +231,9 @@ static void msm_gpio_update_dual_edge_pos(unsigned gpio)
 		if (intstat || val == val2)
 			return;
 	} while (loop_limit-- > 0);
-	pr_err("dual-edge irq failed to stabilize, "
+	pr_err("%s: dual-edge irq failed to stabilize, "
 	       "interrupts dropped. %#08x != %#08x\n",
-	       val, val2);
+	       __func__, val, val2);
 }
 
 static void msm_gpio_irq_ack(struct irq_data *d)
@@ -316,10 +320,10 @@ static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc)
 
 	chained_irq_enter(chip, desc);
 
-	for_each_set_bit(i, msm_gpio.enabled_irqs, NR_GPIO_IRQS) {
+	for_each_set_bit(i, msm_gpio.enabled_irqs, MAX_NR_GPIO) {
 		if (readl(GPIO_INTR_STATUS(i)) & BIT(INTR_STATUS))
-			generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
-							   i));
+			generic_handle_irq(irq_find_mapping(msm_gpio.domain,
+								i));
 	}
 
 	chained_irq_exit(chip, desc);
@@ -330,13 +334,13 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
 	int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
 
 	if (on) {
-		if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
-			irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1);
+		if (bitmap_empty(msm_gpio.wake_irqs, MAX_NR_GPIO))
+			irq_set_irq_wake(msm_gpio.summary_irq, 1);
 		set_bit(gpio, msm_gpio.wake_irqs);
 	} else {
 		clear_bit(gpio, msm_gpio.wake_irqs);
-		if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
-			irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0);
+		if (bitmap_empty(msm_gpio.wake_irqs, MAX_NR_GPIO))
+			irq_set_irq_wake(msm_gpio.summary_irq, 0);
 	}
 
 	return 0;
@@ -351,30 +355,86 @@ static struct irq_chip msm_gpio_irq_chip = {
 	.irq_set_wake	= msm_gpio_irq_set_wake,
 };
 
-static int msm_gpio_probe(struct platform_device *dev)
+static struct lock_class_key msm_gpio_lock_class;
+
+static int msm_gpio_irq_domain_map(struct irq_domain *d, unsigned int irq,
+				   irq_hw_number_t hwirq)
 {
-	int i, irq, ret;
+	irq_set_lockdep_class(irq, &msm_gpio_lock_class);
+	irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
+			handle_level_irq);
+	set_irq_flags(irq, IRQF_VALID);
+
+	return 0;
+}
+
+static const struct irq_domain_ops msm_gpio_irq_domain_ops = {
+	.xlate = irq_domain_xlate_twocell,
+	.map = msm_gpio_irq_domain_map,
+};
+
+static int msm_gpio_probe(struct platform_device *pdev)
+{
+	int ret, ngpio;
+	struct resource *res;
+
+	if (!of_property_read_u32(pdev->dev.of_node, "ngpio", &ngpio)) {
+		dev_err(&pdev->dev, "%s: ngpio property missing\n", __func__);
+		return -EINVAL;
+	}
+
+	if (ngpio > MAX_NR_GPIO)
+		WARN(1, "ngpio exceeds the MAX_NR_GPIO. Increase MAX_NR_GPIO\n");
+
+	bitmap_zero(msm_gpio.enabled_irqs, MAX_NR_GPIO);
+	bitmap_zero(msm_gpio.wake_irqs, MAX_NR_GPIO);
+	bitmap_zero(msm_gpio.dual_edge_irqs, MAX_NR_GPIO);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	msm_gpio.msm_tlmm_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(msm_gpio.msm_tlmm_base))
+		return PTR_ERR(msm_gpio.msm_tlmm_base);
+
+	msm_gpio.gpio_chip.ngpio = ngpio;
+	msm_gpio.gpio_chip.label = pdev->name;
+	msm_gpio.gpio_chip.dev = &pdev->dev;
+	msm_gpio.gpio_chip.base = 0;
+	msm_gpio.gpio_chip.direction_input = msm_gpio_direction_input;
+	msm_gpio.gpio_chip.direction_output = msm_gpio_direction_output;
+	msm_gpio.gpio_chip.get = msm_gpio_get;
+	msm_gpio.gpio_chip.set = msm_gpio_set;
+	msm_gpio.gpio_chip.to_irq = msm_gpio_to_irq;
+	msm_gpio.gpio_chip.request = msm_gpio_request;
+	msm_gpio.gpio_chip.free = msm_gpio_free;
 
-	bitmap_zero(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
-	bitmap_zero(msm_gpio.wake_irqs, NR_GPIO_IRQS);
-	bitmap_zero(msm_gpio.dual_edge_irqs, NR_GPIO_IRQS);
-	msm_gpio.gpio_chip.label = dev->name;
 	ret = gpiochip_add(&msm_gpio.gpio_chip);
-	if (ret < 0)
+	if (ret < 0) {
+		dev_err(&pdev->dev, "gpiochip_add failed with error %d\n", ret);
 		return ret;
+	}
 
-	for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
-		irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
-		irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
-					 handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
+	msm_gpio.summary_irq = platform_get_irq(pdev, 0);
+	if (msm_gpio.summary_irq < 0) {
+		dev_err(&pdev->dev, "No Summary irq defined for msmgpio\n");
+		return msm_gpio.summary_irq;
 	}
 
-	irq_set_chained_handler(TLMM_SCSS_SUMMARY_IRQ,
-				msm_summary_irq_handler);
+	msm_gpio.domain = irq_domain_add_linear(pdev->dev.of_node, ngpio,
+						&msm_gpio_irq_domain_ops,
+						&msm_gpio);
+	if (!msm_gpio.domain)
+		return -ENODEV;
+
+	irq_set_chained_handler(msm_gpio.summary_irq, msm_summary_irq_handler);
+
 	return 0;
 }
 
+static struct of_device_id msm_gpio_of_match[] = {
+	{ .compatible = "qcom,msm-gpio", },
+	{ },
+};
+
 static int msm_gpio_remove(struct platform_device *dev)
 {
 	int ret = gpiochip_remove(&msm_gpio.gpio_chip);
@@ -382,7 +442,7 @@ static int msm_gpio_remove(struct platform_device *dev)
 	if (ret < 0)
 		return ret;
 
-	irq_set_handler(TLMM_SCSS_SUMMARY_IRQ, NULL);
+	irq_set_handler(msm_gpio.summary_irq, NULL);
 
 	return 0;
 }
@@ -393,36 +453,11 @@ static struct platform_driver msm_gpio_driver = {
 	.driver = {
 		.name = "msmgpio",
 		.owner = THIS_MODULE,
+		.of_match_table = msm_gpio_of_match,
 	},
 };
 
-static struct platform_device msm_device_gpio = {
-	.name = "msmgpio",
-	.id   = -1,
-};
-
-static int __init msm_gpio_init(void)
-{
-	int rc;
-
-	rc = platform_driver_register(&msm_gpio_driver);
-	if (!rc) {
-		rc = platform_device_register(&msm_device_gpio);
-		if (rc)
-			platform_driver_unregister(&msm_gpio_driver);
-	}
-
-	return rc;
-}
-
-static void __exit msm_gpio_exit(void)
-{
-	platform_device_unregister(&msm_device_gpio);
-	platform_driver_unregister(&msm_gpio_driver);
-}
-
-postcore_initcall(msm_gpio_init);
-module_exit(msm_gpio_exit);
+module_platform_driver(msm_gpio_driver)
 
 MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>");
 MODULE_DESCRIPTION("Driver for Qualcomm MSM TLMMv2 SoC GPIOs");
diff --git a/drivers/ssbi/ssbi.c b/drivers/ssbi/ssbi.c
index e561d3be54a59664b03e0aaba54bd5ee25099cb6..102a228442979abcaf18d2de2e2293914c0082b1 100644
--- a/drivers/ssbi/ssbi.c
+++ b/drivers/ssbi/ssbi.c
@@ -268,35 +268,23 @@ static int ssbi_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	struct resource *mem_res;
 	struct ssbi *ssbi;
-	int ret = 0;
 	const char *type;
 
-	ssbi = kzalloc(sizeof(struct ssbi), GFP_KERNEL);
-	if (!ssbi) {
-		pr_err("can not allocate ssbi_data\n");
+	ssbi = devm_kzalloc(&pdev->dev, sizeof(*ssbi), GFP_KERNEL);
+	if (!ssbi)
 		return -ENOMEM;
-	}
 
 	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mem_res) {
-		pr_err("missing mem resource\n");
-		ret = -EINVAL;
-		goto err_get_mem_res;
-	}
+	ssbi->base = devm_ioremap_resource(&pdev->dev, mem_res);
+	if (IS_ERR(ssbi->base))
+		return PTR_ERR(ssbi->base);
 
-	ssbi->base = ioremap(mem_res->start, resource_size(mem_res));
-	if (!ssbi->base) {
-		pr_err("ioremap of 0x%p failed\n", (void *)mem_res->start);
-		ret = -EINVAL;
-		goto err_ioremap;
-	}
 	platform_set_drvdata(pdev, ssbi);
 
 	type = of_get_property(np, "qcom,controller-type", NULL);
 	if (type == NULL) {
-		pr_err("Missing qcom,controller-type property\n");
-		ret = -EINVAL;
-		goto err_ssbi_controller;
+		dev_err(&pdev->dev, "Missing qcom,controller-type property\n");
+		return -EINVAL;
 	}
 	dev_info(&pdev->dev, "SSBI controller type: '%s'\n", type);
 	if (strcmp(type, "ssbi") == 0)
@@ -306,9 +294,8 @@ static int ssbi_probe(struct platform_device *pdev)
 	else if (strcmp(type, "pmic-arbiter") == 0)
 		ssbi->controller_type = MSM_SBI_CTRL_PMIC_ARBITER;
 	else {
-		pr_err("Unknown qcom,controller-type\n");
-		ret = -EINVAL;
-		goto err_ssbi_controller;
+		dev_err(&pdev->dev, "Unknown qcom,controller-type\n");
+		return -EINVAL;
 	}
 
 	if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) {
@@ -321,29 +308,7 @@ static int ssbi_probe(struct platform_device *pdev)
 
 	spin_lock_init(&ssbi->lock);
 
-	ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
-	if (ret)
-		goto err_ssbi_controller;
-
-	return 0;
-
-err_ssbi_controller:
-	platform_set_drvdata(pdev, NULL);
-	iounmap(ssbi->base);
-err_ioremap:
-err_get_mem_res:
-	kfree(ssbi);
-	return ret;
-}
-
-static int ssbi_remove(struct platform_device *pdev)
-{
-	struct ssbi *ssbi = platform_get_drvdata(pdev);
-
-	platform_set_drvdata(pdev, NULL);
-	iounmap(ssbi->base);
-	kfree(ssbi);
-	return 0;
+	return of_platform_populate(np, NULL, NULL, &pdev->dev);
 }
 
 static struct of_device_id ssbi_match_table[] = {
@@ -354,25 +319,13 @@ MODULE_DEVICE_TABLE(of, ssbi_match_table);
 
 static struct platform_driver ssbi_driver = {
 	.probe		= ssbi_probe,
-	.remove		= ssbi_remove,
 	.driver		= {
 		.name	= "ssbi",
 		.owner	= THIS_MODULE,
 		.of_match_table = ssbi_match_table,
 	},
 };
-
-static int __init ssbi_init(void)
-{
-	return platform_driver_register(&ssbi_driver);
-}
-module_init(ssbi_init);
-
-static void __exit ssbi_exit(void)
-{
-	platform_driver_unregister(&ssbi_driver);
-}
-module_exit(ssbi_exit)
+module_platform_driver(ssbi_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_VERSION("1.0");