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;