Merge "defconfig: msm7627a: Disable RC_CORE and DEBUG_LL" into msm-3.0
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 1004683..7216c12 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -269,6 +269,7 @@
 	select ARM_GIC
 	select ARCH_MSM_CORTEXMP
 	select MULTI_IRQ_HANDLER
+	select ARM_TICKET_LOCKS
 endmenu
 
 choice
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 525dce4..6cde804 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -229,7 +229,7 @@
 obj-$(CONFIG_MACH_MSM7627A_QRD1) += board-qrd7627a.o board-7627a-all.o
 obj-$(CONFIG_MACH_MSM7627A_QRD3) += board-qrd7627a.o board-7627a-all.o
 obj-$(CONFIG_MACH_MSM7627A_EVB) += board-qrd7627a.o board-7627a-all.o
-obj-$(CONFIG_ARCH_MSM8625) += devices-msm7x27a.o clock-pcom-lookup.o
+obj-$(CONFIG_ARCH_MSM8625) += devices-msm7x27a.o clock-pcom-lookup.o mpm-8625.o
 obj-$(CONFIG_MACH_MSM8625_RUMI3) += board-msm7x27a.o
 obj-$(CONFIG_MACH_MSM8625_SURF) +=  board-msm7x27a.o board-7627a-all.o
 obj-$(CONFIG_MACH_MSM8625_EVB) +=  board-qrd7627a.o board-7627a-all.o
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index 206bebd..e8dfc21 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -502,28 +502,6 @@
 	},
 };
 
-static struct gpiomux_setting gpio_rotate_key_act_config = {
-	.pull = GPIOMUX_PULL_UP,
-	.drv = GPIOMUX_DRV_8MA,
-	.func = GPIOMUX_FUNC_GPIO,
-};
-
-static struct gpiomux_setting gpio_rotate_key_sus_config = {
-	.pull = GPIOMUX_PULL_NONE,
-	.drv = GPIOMUX_DRV_2MA,
-	.func = GPIOMUX_FUNC_GPIO,
-};
-
-struct msm_gpiomux_config apq8064_rotate_key_config[] = {
-	{
-		.gpio = 46,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_rotate_key_sus_config,
-			[GPIOMUX_ACTIVE] = &gpio_rotate_key_act_config,
-		}
-	},
-};
-
 static struct msm_gpiomux_config apq8064_mxt_configs[] __initdata = {
 	{	/* TS INTERRUPT */
 		.gpio = 6,
@@ -629,8 +607,4 @@
 	if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid())
 		msm_gpiomux_install(apq8064_mxt_configs,
 			ARRAY_SIZE(apq8064_mxt_configs));
-
-	if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid())
-		msm_gpiomux_install(apq8064_rotate_key_config,
-				ARRAY_SIZE(apq8064_rotate_key_config));
 }
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index f4650a9..7f932f7 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -133,6 +133,7 @@
 
 static struct pm8xxx_gpio_init pm8921_cdp_kp_gpios[] __initdata = {
 	PM8921_GPIO_INPUT(37, PM_GPIO_PULL_UP_1P5),
+	PM8921_GPIO_INPUT(42, PM_GPIO_PULL_UP_1P5),
 };
 
 /* Initial PM8XXX MPP configurations */
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 540f5c9..35f17ce 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1709,6 +1709,9 @@
 	&apq8064_device_uart_gsbi1,
 	&apq8064_device_uart_gsbi7,
 	&msm_device_sps_apq8064,
+#ifdef CONFIG_MSM_ROTATOR
+	&msm_rotator_device,
+#endif
 };
 
 static struct msm_spi_platform_data apq8064_qup_spi_gsbi5_pdata = {
@@ -1801,7 +1804,7 @@
 #define GPIO_KEY_VOLUME_DOWN	PM8921_GPIO_PM_TO_SYS(38)
 #define GPIO_KEY_CAM_FOCUS	PM8921_GPIO_PM_TO_SYS(3)
 #define GPIO_KEY_CAM_SNAP	PM8921_GPIO_PM_TO_SYS(4)
-#define GPIO_KEY_ROTATION	46
+#define GPIO_KEY_ROTATION	PM8921_GPIO_PM_TO_SYS(42)
 
 static struct gpio_keys_button cdp_keys[] = {
 	{
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index b44b03f..91185ea 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -948,7 +948,6 @@
 static void __init msm8625_reserve(void)
 {
 	msm7x27a_reserve();
-	memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
 	msm_pm_8625_boot_pdata.p_addr = memblock_alloc(SZ_8, SZ_64K);
 }
 
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index ac590d3..fc97043 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -696,6 +696,7 @@
 	&msm8625_gsbi0_qup_i2c_device,
 	&msm8625_gsbi1_qup_i2c_device,
 	&msm8625_device_uart1,
+	&msm8625_device_uart_dm1,
 	&msm8625_device_otg,
 	&msm8625_device_gadget_peripheral,
 	&msm8625_kgsl_3d0,
@@ -775,12 +776,6 @@
 	msm_reserve();
 }
 
-static void __init msm8625_reserve(void)
-{
-	memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
-	msm7627a_reserve();
-}
-
 static void msmqrd_adsp_add_pdev(void)
 {
 	int rc = 0;
@@ -1070,6 +1065,12 @@
 	return platform_device_register(&msm_wlan_ar6000_pm_device);
 }
 
+static void __init msm_add_footswitch_devices(void)
+{
+	platform_add_devices(msm_footswitch_devices,
+				msm_num_footswitch_devices);
+}
+
 static void add_platform_devices(void)
 {
 	if (machine_is_msm8625_evb())
@@ -1130,6 +1131,7 @@
 	/*OTG gadget*/
 	qrd7627a_otg_gadget();
 
+	msm_add_footswitch_devices();
 	add_platform_devices();
 
 	/* Ensure ar6000pm device is registered before MMC/SDC */
@@ -1194,7 +1196,7 @@
 MACHINE_START(MSM8625_EVB, "QRD MSM8625 EVB")
 	.boot_params	= PHYS_OFFSET + 0x100,
 	.map_io		= msm8625_map_io,
-	.reserve	= msm8625_reserve,
+	.reserve	= msm7627a_reserve,
 	.init_irq	= msm8625_init_irq,
 	.init_machine	= msm_qrd_init,
 	.timer		= &msm_timer,
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index c19c133..ff11c7a 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -17,6 +17,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/memblock.h>
 #include <mach/irqs.h>
 #include <mach/msm_iomap.h>
 #include <mach/board.h>
@@ -34,6 +35,7 @@
 #include "footswitch.h"
 #include "acpuclock.h"
 #include "spm.h"
+#include "mpm-8625.h"
 
 /* Address of GSBI blocks */
 #define MSM_GSBI0_PHYS		0xA1200000
@@ -1584,12 +1586,37 @@
 
 void __init msm8625_init_irq(void)
 {
+	msm_gic_irq_extn_init(MSM_QGIC_DIST_BASE, MSM_QGIC_CPU_BASE);
 	gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
 			(void *)MSM_QGIC_CPU_BASE);
 }
 
+static phys_addr_t msm8625_phys_base;
+
+static void __init msm_reserve_sdram_memblock(void)
+{
+	phys_addr_t paddr;
+
+	paddr = memblock_alloc(SZ_8, SZ_64K);
+	pr_debug("%s physical address = %x\n", __func__, paddr);
+
+	if (!paddr) {
+		pr_err("%s: failed to reserve SZ_8 bytes\n", __func__);
+		return;
+	}
+
+	msm8625_phys_base = paddr;
+}
+
+phys_addr_t msm8625_get_phys_base(void)
+{
+	return msm8625_phys_base;
+}
+EXPORT_SYMBOL(msm8625_get_phys_base);
+
 void __init msm8625_map_io(void)
 {
+	msm_reserve_sdram_memblock();
 	msm_map_msm8625_io();
 
 	if (socinfo_init() < 0)
diff --git a/arch/arm/mach-msm/devices-msm7x2xa.h b/arch/arm/mach-msm/devices-msm7x2xa.h
index 3c81ccf..73b58e0 100644
--- a/arch/arm/mach-msm/devices-msm7x2xa.h
+++ b/arch/arm/mach-msm/devices-msm7x2xa.h
@@ -31,4 +31,5 @@
 void __init msm8625_map_io(void);
 int  ar600x_wlan_power(bool on);
 void __init msm8x25_spm_device_init(void);
+phys_addr_t msm8625_get_phys_base(void);
 #endif
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index ad1aecd..087227c 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-msm/dma.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -286,9 +286,11 @@
 	int ch = DMOV_ID_TO_CHAN(id);
 
 	spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
-	if (dmov_conf[adm].clk_ctl == CLK_DIS)
-		msm_dmov_clk_toggle(adm, 1);
-	else if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS)
+	if (dmov_conf[adm].clk_ctl == CLK_DIS) {
+		status = msm_dmov_clk_toggle(adm, 1);
+		if (status != 0)
+			goto error;
+	} else if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS)
 		del_timer(&dmov_conf[adm].timer);
 	dmov_conf[adm].clk_ctl = CLK_EN;
 
@@ -316,6 +318,7 @@
 		    "%x\n", id, status);
 		list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
 	}
+error:
 	spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
 }
 EXPORT_SYMBOL(msm_dmov_enqueue_cmd_ext);
diff --git a/arch/arm/mach-msm/footswitch-pcom.c b/arch/arm/mach-msm/footswitch-pcom.c
index f8e84fc..673253b 100644
--- a/arch/arm/mach-msm/footswitch-pcom.c
+++ b/arch/arm/mach-msm/footswitch-pcom.c
@@ -306,8 +306,6 @@
 	struct footswitch *fs;
 	int ret;
 
-	if (cpu_is_msm8625())
-		return 0;
 	/*
 	 * Enable all footswitches in manual mode (ie. not controlled along
 	 * with pcom clocks).
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
index 7479712..96bc35e 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
@@ -103,4 +103,7 @@
 #define APQ8064_SIC_NON_SECURE_PHYS	0x12100000
 #define APQ8064_SIC_NON_SECURE_SIZE	SZ_64K
 
+#define APQ8064_HDMI_PHYS		0x04A00000
+#define APQ8064_HDMI_SIZE		SZ_4K
+
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 27965d3..48e3837 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -93,8 +93,6 @@
 							  0xFB600000 */
 
 #define MSM_STRONGLY_ORDERED_PAGE	0xFA0F0000
-#define MSM8625_SECONDARY_PHYS		0x0FE00000
-
 
 #if defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_MSM7X27)
 #define MSM_SHARED_RAM_SIZE	SZ_1M
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index a643c68..bad8237 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -273,6 +273,7 @@
 	MSM_CHIP_DEVICE(SAW3, APQ8064),
 	MSM_CHIP_DEVICE(SAW_L2, APQ8064),
 	MSM_CHIP_DEVICE(IMEM, APQ8064),
+	MSM_CHIP_DEVICE(HDMI, APQ8064),
 	{
 		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
 		.length =   MSM_SHARED_RAM_SIZE,
diff --git a/arch/arm/mach-msm/mpm-8625.c b/arch/arm/mach-msm/mpm-8625.c
new file mode 100644
index 0000000..63de944
--- /dev/null
+++ b/arch/arm/mach-msm/mpm-8625.c
@@ -0,0 +1,454 @@
+/* Copyright (c) 2012, 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.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware/gic.h>
+#include <mach/msm_smsm.h>
+
+#define NUM_REGS_ENABLE		2
+/* (NR_MSM_IRQS/32) 96 max irqs supported */
+#define NUM_REGS_DISABLE	3
+#define GIC_IRQ_MASK(irq)	BIT(irq % 32)
+#define GIC_IRQ_INDEX(irq)	(irq / 32)
+
+#ifdef CONFIG_PM
+u32 saved_spi_enable[DIV_ROUND_UP(256, 32)];
+u32 saved_spi_conf[DIV_ROUND_UP(256, 16)];
+u32 saved_spi_target[DIV_ROUND_UP(256, 4)];
+u32 __percpu *saved_ppi_enable;
+u32 __percpu *saved_ppi_conf;
+#endif
+
+enum {
+	IRQ_DEBUG_SLEEP_INT_TRIGGER	= BIT(0),
+	IRQ_DEBUG_SLEEP_INT		= BIT(1),
+	IRQ_DEBUG_SLEEP_ABORT		= BIT(2),
+	IRQ_DEBUG_SLEEP			= BIT(3),
+	IRQ_DEBUG_SLEEP_REQUEST		= BIT(4)
+};
+
+static int msm_gic_irq_debug_mask;
+module_param_named(debug_mask, msm_gic_irq_debug_mask, int,
+		S_IRUGO | S_IWUSR | S_IWGRP);
+
+static uint32_t msm_gic_irq_smsm_wake_enable[NUM_REGS_ENABLE];
+static uint32_t msm_gic_irq_idle_disable[NUM_REGS_DISABLE];
+
+static DEFINE_RAW_SPINLOCK(gic_controller_lock);
+static void __iomem *dist_base, *cpu_base;
+static unsigned int max_irqs;
+
+ /*
+  * Some of the interrupts which will not be considered as wake capable
+  * should be marked as FAKE.
+  * Interrupts: GPIO, Timers etc..
+  */
+#define SMSM_FAKE_IRQ	(0xff)
+
+ /* msm_gic_irq_to_smsm:  IRQ's those will be monitored by Modem */
+static uint8_t msm_gic_irq_to_smsm[NR_IRQS] = {
+	[MSM8625_INT_USB_OTG]		= 4,
+	[MSM8625_INT_PWB_I2C]		= 5,
+	[MSM8625_INT_SDC1_0]		= 6,
+	[MSM8625_INT_SDC1_1]		= 7,
+	[MSM8625_INT_SDC2_0]		= 8,
+	[MSM8625_INT_SDC2_1]		= 9,
+	[MSM8625_INT_ADSP_A9_A11]	= 10,
+	[MSM8625_INT_UART1]		= 11,
+	[MSM8625_INT_UART2]		= 12,
+	[MSM8625_INT_UART3]		= 13,
+	[MSM8625_INT_UART1_RX]		= 14,
+	[MSM8625_INT_UART2_RX]		= 15,
+	[MSM8625_INT_UART3_RX]		= 16,
+	[MSM8625_INT_UART1DM_IRQ]	= 17,
+	[MSM8625_INT_UART1DM_RX]	= 18,
+	[MSM8625_INT_KEYSENSE]		= 19,
+	[MSM8625_INT_AD_HSSD]		= 20,
+	[MSM8625_INT_NAND_WR_ER_DONE]	= 21,
+	[MSM8625_INT_NAND_OP_DONE]	= 22,
+	[MSM8625_INT_TCHSCRN1]		= 23,
+	[MSM8625_INT_TCHSCRN2]		= 24,
+	[MSM8625_INT_TCHSCRN_SSBI]	= 25,
+	[MSM8625_INT_USB_HS]		= 26,
+	[MSM8625_INT_UART2DM_RX]	= 27,
+	[MSM8625_INT_UART2DM_IRQ]	= 28,
+	[MSM8625_INT_SDC4_1]		= 29,
+	[MSM8625_INT_SDC4_0]		= 30,
+	[MSM8625_INT_SDC3_1]		= 31,
+	[MSM8625_INT_SDC3_0]		= 32,
+
+	/* fake wakeup interrupts */
+	[MSM8625_INT_GPIO_GROUP1]	= SMSM_FAKE_IRQ,
+	[MSM8625_INT_GPIO_GROUP2]	= SMSM_FAKE_IRQ,
+	[MSM8625_INT_A9_M2A_0]		= SMSM_FAKE_IRQ,
+	[MSM8625_INT_A9_M2A_1]		= SMSM_FAKE_IRQ,
+	[MSM8625_INT_A9_M2A_5]		= SMSM_FAKE_IRQ,
+	[MSM8625_INT_GP_TIMER_EXP]	= SMSM_FAKE_IRQ,
+	[MSM8625_INT_DEBUG_TIMER_EXP]	= SMSM_FAKE_IRQ,
+	[MSM8625_INT_ADSP_A11]		= SMSM_FAKE_IRQ,
+};
+
+static void msm_gic_mask_irq(struct irq_data *d)
+{
+	unsigned int index = GIC_IRQ_INDEX(d->irq);
+	uint32_t mask;
+	int smsm_irq = msm_gic_irq_to_smsm[d->irq];
+
+	mask = GIC_IRQ_MASK(d->irq);
+
+	if (smsm_irq == 0) {
+		msm_gic_irq_idle_disable[index] &= ~mask;
+	} else {
+		mask = GIC_IRQ_MASK(smsm_irq - 1);
+		msm_gic_irq_smsm_wake_enable[0] &= ~mask;
+	}
+}
+
+static void msm_gic_unmask_irq(struct irq_data *d)
+{
+	unsigned int index = GIC_IRQ_INDEX(d->irq);
+	uint32_t mask;
+	int smsm_irq = msm_gic_irq_to_smsm[d->irq];
+
+	mask = GIC_IRQ_MASK(d->irq);
+
+	if (smsm_irq == 0) {
+		msm_gic_irq_idle_disable[index] |= mask;
+	} else {
+		mask = GIC_IRQ_MASK(smsm_irq - 1);
+		msm_gic_irq_smsm_wake_enable[0] |= mask;
+	}
+}
+
+static int msm_gic_set_irq_wake(struct irq_data *d, unsigned int on)
+{
+	uint32_t mask;
+	int smsm_irq = msm_gic_irq_to_smsm[d->irq];
+
+	if (smsm_irq == 0) {
+		pr_err("bad wake up irq %d\n", d->irq);
+		return  -EINVAL;
+	}
+
+	if (smsm_irq == SMSM_FAKE_IRQ)
+		return 0;
+
+	mask = GIC_IRQ_MASK(smsm_irq - 1);
+	if (on)
+		msm_gic_irq_smsm_wake_enable[1] |= mask;
+	else
+		msm_gic_irq_smsm_wake_enable[1] &= ~mask;
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static void __init msm_gic_pm_init(void)
+{
+	saved_ppi_enable =  __alloc_percpu(DIV_ROUND_UP(32, 32) * 4,
+						sizeof(u32));
+	BUG_ON(!saved_ppi_enable);
+
+	saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4,
+						sizeof(u32));
+	BUG_ON(!saved_ppi_conf);
+}
+#endif
+
+void msm_gic_irq_extn_init(void __iomem *db, void __iomem *cb)
+{
+	dist_base = db;
+	cpu_base = cb;
+	max_irqs = readl_relaxed(dist_base + GIC_DIST_CTR) & 0x11f;
+	max_irqs = (max_irqs + 1) * 32;
+
+	gic_arch_extn.irq_mask	= msm_gic_mask_irq;
+	gic_arch_extn.irq_unmask = msm_gic_unmask_irq;
+	gic_arch_extn.irq_disable = msm_gic_mask_irq;
+	gic_arch_extn.irq_set_wake = msm_gic_set_irq_wake;
+
+#ifdef CONFIG_PM
+	msm_gic_pm_init();
+#endif
+}
+
+/* GIC APIs */
+
+ /*
+  * Save the GIC cpu and distributor context before PC and
+  * restor it back after coming out of PC.
+  */
+static void msm_gic_save(void)
+{
+	int i;
+	u32 *ptr;
+
+	/* Save the Per CPU PPI's */
+	ptr = __this_cpu_ptr(saved_ppi_enable);
+	/* 0 - 31 the SGI and PPI */
+	ptr[0] = readl_relaxed(dist_base +  GIC_DIST_ENABLE_SET);
+
+	ptr = __this_cpu_ptr(saved_ppi_conf);
+	for (i = 0; i < 2; i++)
+		ptr[i] =  readl_relaxed(dist_base +  GIC_DIST_CONFIG + i * 4);
+
+	/* Save the SPIs */
+	for (i = 0; (i * 16) < max_irqs; i++)
+		saved_spi_conf[i] =
+			readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
+
+	for (i = 0; (i * 4) < max_irqs; i++)
+		saved_spi_target[i] =
+			readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4);
+
+	for (i = 0; (i * 32) < max_irqs; i++)
+		saved_spi_enable[i] =
+		readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+}
+
+static void msm_gic_restore(void)
+{
+	int i;
+	u32 *ptr;
+
+	/* restore CPU Interface */
+	/* Per CPU SGIs and PPIs */
+	ptr = __this_cpu_ptr(saved_ppi_enable);
+	writel_relaxed(ptr[0], dist_base + GIC_DIST_ENABLE_SET);
+
+	ptr = __this_cpu_ptr(saved_ppi_conf);
+	for (i = 0; i < 2; i++)
+		writel_relaxed(ptr[i], dist_base +  GIC_DIST_CONFIG + i * 4);
+
+	for (i = 0; (i * 4) < max_irqs; i++)
+		writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);
+
+	writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
+	writel_relaxed(1, cpu_base + GIC_CPU_CTRL);
+
+	/* restore Distributor */
+	writel_relaxed(0, dist_base + GIC_DIST_CTRL);
+
+	for (i = 0; (i * 16) < max_irqs; i++)
+		writel_relaxed(saved_spi_conf[i],
+				dist_base + GIC_DIST_CONFIG + i * 4);
+
+	for (i = 0; (i * 4) < max_irqs; i++)
+		writel_relaxed(0xa0a0a0a0,
+				dist_base + GIC_DIST_PRI + i * 4);
+
+	for (i = 0; (i * 4) < max_irqs; i++)
+		writel_relaxed(saved_spi_target[i],
+				dist_base + GIC_DIST_TARGET + i * 4);
+
+	for (i = 0; (i * 32) < max_irqs; i++)
+		writel_relaxed(saved_spi_enable[i],
+				dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+	writel_relaxed(1, dist_base + GIC_DIST_CTRL);
+
+	mb();
+}
+
+/* Power APIs */
+
+ /*
+  *  Check for any interrupts which are enabled are pending
+  *  in the pending set or not.
+  *  Return :
+  *       0 : No pending interrupts
+  *       1 : Pending interrupts other than A9_M2A_5
+  */
+unsigned int msm_gic_spi_ppi_pending(void)
+{
+	unsigned int i, bit = 0;
+	unsigned int pending_enb = 0, pending = 0;
+	unsigned long value = 0;
+
+	raw_spin_lock(&gic_controller_lock);
+	/*
+	 * PPI and SGI to be included.
+	 * MSM8625_INT_A9_M2A_5 needs to be ignored, as A9_M2A_5
+	 * requesting sleep triggers it
+	 */
+	for (i = 0; (i * 32) < max_irqs; i++) {
+		pending = readl_relaxed(dist_base +
+				GIC_DIST_PENDING_SET + i * 4);
+		pending_enb = readl_relaxed(dist_base +
+				GIC_DIST_ENABLE_SET + i * 4);
+		value = pending & pending_enb;
+
+		if (value) {
+			for (bit = 0; bit < 32; bit++) {
+				bit = find_next_bit(&value, 32, bit);
+				if ((bit + 32 * i) != MSM8625_INT_A9_M2A_5) {
+					raw_spin_unlock(&gic_controller_lock);
+					return 1;
+				}
+			}
+		}
+	}
+	raw_spin_unlock(&gic_controller_lock);
+
+	return 0;
+}
+
+ /*
+  * Iterate over the disable list
+  */
+
+int msm_gic_irq_idle_sleep_allowed(void)
+{
+	uint32_t i, disable = 0;
+
+	for (i = 0; i < NUM_REGS_DISABLE; i++)
+		disable |= msm_gic_irq_idle_disable[i];
+
+	return !disable;
+}
+
+ /*
+  * Prepare interrupt subsystem for entering sleep -- phase 1
+  * If modem_wake is true, return currently enabled interrupt
+  * mask in  *irq_mask
+  */
+void msm_gic_irq_enter_sleep1(bool modem_wake, int from_idle, uint32_t
+		*irq_mask)
+{
+	if (modem_wake) {
+		*irq_mask = msm_gic_irq_smsm_wake_enable[!from_idle];
+		if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP)
+			pr_info("%s irq_mask %x\n", __func__, *irq_mask);
+	}
+}
+
+ /*
+  * Prepare interrupt susbsytem for entering sleep -- phase 2
+  * Detect any pending interrupts and configure interrupt hardware.
+  * Return value:
+  * -EAGAIN: there are pending interrupt(s); interrupt configuration is not
+  *		changed
+  *	  0: Success
+  */
+int msm_gic_irq_enter_sleep2(bool modem_wake, int from_idle)
+{
+
+	if (from_idle && !modem_wake)
+		return 0;
+
+	/* edge triggered interrupt may get lost if this mode is used */
+	WARN_ON_ONCE(!modem_wake && !from_idle);
+
+	if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP)
+		pr_info("%s interrupts pending\n", __func__);
+
+	/* check the pending interrupts */
+	if (msm_gic_spi_ppi_pending()) {
+		if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP_ABORT)
+			pr_info("%s aborted....\n", __func__);
+		return -EAGAIN;
+	}
+
+	if (modem_wake) {
+		irq_set_irq_type(MSM8625_INT_A9_M2A_6, IRQF_TRIGGER_RISING);
+		/* save the contents of GIC CPU interface and Distributor */
+		msm_gic_save();
+		enable_irq(MSM8625_INT_A9_M2A_6);
+		pr_info("%s Good to go for sleep now\n", __func__);
+	}
+
+	return 0;
+}
+
+ /*
+  * Restore interrupt subsystem from sleep -- phase 1
+  * Configure the interrupt hardware.
+  */
+void msm_gic_irq_exit_sleep1(uint32_t irq_mask, uint32_t wakeup_reason,
+		uint32_t pending_irqs)
+{
+	/* Restore GIC contents, which were saved */
+	msm_gic_restore();
+
+	/* Disable A9_M2A_6 */
+	disable_irq(MSM8625_INT_A9_M2A_6);
+
+	if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP)
+		pr_info("%s %x %x %x now\n", __func__, irq_mask,
+				pending_irqs, wakeup_reason);
+}
+
+ /*
+  * Restore interrupt subsystem from sleep -- phase 2
+  * Poke the specified pending interrupts into interrupt hardware.
+  */
+void msm_gic_irq_exit_sleep2(uint32_t irq_mask, uint32_t wakeup_reason,
+			uint32_t pending)
+{
+	int i, smsm_irq, smsm_mask;
+	struct irq_desc *desc;
+
+	if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP)
+		pr_info("%s %x %x %x now\n", __func__, irq_mask,
+				 pending, wakeup_reason);
+
+	for (i = 0; pending && i < ARRAY_SIZE(msm_gic_irq_to_smsm); i++) {
+		smsm_irq = msm_gic_irq_to_smsm[i];
+
+		if (smsm_irq == 0)
+			continue;
+
+		smsm_mask = BIT(smsm_irq - 1);
+		if (!(pending & smsm_mask))
+			continue;
+
+		pending &= ~smsm_mask;
+
+		if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP_INT)
+			pr_info("%s, irq %d, still pending %x now\n",
+					__func__, i, pending);
+		/* Peding IRQ */
+		desc = i ? irq_to_desc(i) : NULL;
+
+		/* Check if the pending */
+		if (desc && !irqd_is_level_type(&desc->irq_data)) {
+			/* Mark the IRQ as pending, if not Level */
+			irq_set_pending(i);
+			check_irq_resend(desc, i);
+		}
+	}
+}
+
+ /*
+  * Restore interrupt subsystem from sleep -- phase 3
+  * Print debug information
+  */
+void msm_gic_irq_exit_sleep3(uint32_t irq_mask, uint32_t wakeup_reason,
+		uint32_t pending_irqs)
+{
+	if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP)
+		pr_info("%s, irq_mask %x pending_irqs %x, wakeup_reason %x,"
+				"state %x now\n", __func__, irq_mask,
+				pending_irqs, wakeup_reason,
+				smsm_get_state(SMSM_MODEM_STATE));
+}
diff --git a/arch/arm/mach-msm/mpm-8625.h b/arch/arm/mach-msm/mpm-8625.h
new file mode 100644
index 0000000..4ada9e2
--- /dev/null
+++ b/arch/arm/mach-msm/mpm-8625.h
@@ -0,0 +1,30 @@
+/* Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef _ARCH_ARM_MACH_MSM_MPM_8625_H_
+#define _ARCH_ARM_MACH_MSM_MPM_8625_H_
+
+void msm_gic_irq_extn_init(void __iomem *, void __iomem *);
+
+unsigned int msm_gic_spi_ppi_pending(void);
+int msm_gic_irq_idle_sleep_allowed(void);
+void msm_gic_irq_enter_sleep1(bool modem_wake, int from_idle, uint32_t
+		*irq_mask);
+int msm_gic_irq_enter_sleep2(bool modem_wake, int from_idle);
+void msm_gic_irq_exit_sleep1(uint32_t irq_mask, uint32_t wakeup_reason,
+		uint32_t pending_irqs);
+void msm_gic_irq_exit_sleep2(uint32_t irq_mask, uint32_t wakeup_reason,
+		uint32_t pending);
+void msm_gic_irq_exit_sleep3(uint32_t irq_mask, uint32_t wakeup_reason,
+		uint32_t pending_irqs);
+#endif
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
index 3c46d0f..92ed764 100644
--- a/arch/arm/mach-msm/platsmp-8625.c
+++ b/arch/arm/mach-msm/platsmp-8625.c
@@ -17,6 +17,7 @@
 #include <linux/jiffies.h>
 #include <linux/smp.h>
 #include <linux/io.h>
+#include <linux/highmem.h>
 
 #include <asm/cacheflush.h>
 #include <asm/hardware/gic.h>
@@ -25,7 +26,9 @@
 #include <asm/unified.h>
 #include <mach/msm_iomap.h>
 #include <mach/smp.h>
+
 #include "pm.h"
+#include "devices-msm7x2xa.h"
 
 #define MSM_CORE1_RESET		0xA8600590
 #define MSM_CORE1_STATUS_MSK	0x02800000
@@ -206,7 +209,8 @@
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
 	int i, value;
-	void __iomem *second_ptr;
+	phys_addr_t base;
+	void *vaddr;
 
 	/*
 	 * Initialise the present map, which describes the set of CPUs
@@ -221,18 +225,14 @@
 	 * Write the address of secondary startup into the
 	 * boot remapper register. The secondary CPU branches to this address.
 	 */
-	__raw_writel(MSM8625_SECONDARY_PHYS, (MSM_CFG_CTL_BASE + 0x34));
+	base = msm8625_get_phys_base();
+	__raw_writel(base, (MSM_CFG_CTL_BASE + 0x34));
 	mb();
 
-	second_ptr = ioremap_nocache(MSM8625_SECONDARY_PHYS, SZ_8);
-	if (!second_ptr) {
-		pr_err("failed to ioremap for secondary core\n");
-		return;
-	}
+	vaddr = kmap_atomic(phys_to_page(base));
 
-	msm8625_boot_vector_init(second_ptr,
-			virt_to_phys(msm_secondary_startup));
-	iounmap(second_ptr);
+	msm8625_boot_vector_init(vaddr, virt_to_phys(msm_secondary_startup));
+	kunmap_atomic(vaddr);
 
 	/* Enable boot remapper address: bit 26 for core1 */
 	value = __raw_readl(MSM_CFG_CTL_BASE + 0x30);
diff --git a/drivers/video/msm/lvds.c b/drivers/video/msm/lvds.c
index a69c64f..e93b238 100644
--- a/drivers/video/msm/lvds.c
+++ b/drivers/video/msm/lvds.c
@@ -110,23 +110,43 @@
 	mb();
 
 	if (mfd->panel_info.bpp == 24) {
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
-		MDP_OUTP(MDP_BASE +  0xc2014, 0x03040508);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
-		MDP_OUTP(MDP_BASE +  0xc2018, 0x00000102);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
-		MDP_OUTP(MDP_BASE +  0xc201c, 0x0c0d1011);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
-		MDP_OUTP(MDP_BASE +  0xc2020, 0x00090a0b);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
-		MDP_OUTP(MDP_BASE +  0xc2024, 0x151a191a);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
-		MDP_OUTP(MDP_BASE +  0xc2028, 0x00121314);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
-		MDP_OUTP(MDP_BASE +  0xc202c, 0x1706071b);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
-		MDP_OUTP(MDP_BASE +  0xc2030, 0x000e0f16);
-
+		if (lvds_pdata &&
+		    lvds_pdata->lvds_pixel_remap &&
+		    lvds_pdata->lvds_pixel_remap()) {
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+			MDP_OUTP(MDP_BASE +  0xc2014, 0x05080001);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+			MDP_OUTP(MDP_BASE +  0xc2018, 0x00020304);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+			MDP_OUTP(MDP_BASE +  0xc201c, 0x1011090a);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+			MDP_OUTP(MDP_BASE +  0xc2020, 0x000b0c0d);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+			MDP_OUTP(MDP_BASE +  0xc2024, 0x191a1213);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+			MDP_OUTP(MDP_BASE +  0xc2028, 0x00141518);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
+			MDP_OUTP(MDP_BASE +  0xc202c, 0x171b0607);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
+			MDP_OUTP(MDP_BASE +  0xc2030, 0x000e0f16);
+		} else {
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+			MDP_OUTP(MDP_BASE +  0xc2014, 0x03040508);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+			MDP_OUTP(MDP_BASE +  0xc2018, 0x00000102);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+			MDP_OUTP(MDP_BASE +  0xc201c, 0x0c0d1011);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+			MDP_OUTP(MDP_BASE +  0xc2020, 0x00090a0b);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+			MDP_OUTP(MDP_BASE +  0xc2024, 0x151a191a);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+			MDP_OUTP(MDP_BASE +  0xc2028, 0x00121314);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
+			MDP_OUTP(MDP_BASE +  0xc202c, 0x1706071b);
+			/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
+			MDP_OUTP(MDP_BASE +  0xc2030, 0x000e0f16);
+		}
 		if (mfd->panel_info.lvds.channel_mode ==
 			LVDS_DUAL_CHANNEL_MODE) {
 			lvds_intf = 0x0001ff80;