Merge "msm: mdm: do not pull AP2MDM_STATUS gpio low during normal shutdown" into msm-3.0
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 64877d1..b6570c7 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -6,6 +6,10 @@
config GIC_NON_BANKED
bool
+config GIC_SECURE
+ bool
+ depends on ARM_GIC
+
config ARM_VIC
bool
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index bb4d971..4e43cb2 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -156,7 +156,7 @@
return d->hwirq;
}
-#ifdef CONFIG_CPU_V7
+#if defined(CONFIG_CPU_V7) && defined(CONFIG_GIC_SECURE)
static const inline bool is_cpu_secure(void)
{
unsigned int dscr;
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index d3ff90b..863a963 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -99,6 +99,8 @@
CONFIG_DCC_TTY=y
CONFIG_SPMI=y
CONFIG_SPMI_MSM_PMIC_ARB=y
+CONFIG_MSM_QPNP=y
+CONFIG_MSM_QPNP_INT=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_POWER_SUPPLY=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 7decf0a..6a5497d 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -208,6 +208,7 @@
CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+CONFIG_TOUCHSCREEN_FT5X06=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=y
@@ -255,6 +256,7 @@
CONFIG_FB_MSM_TRIPLE_BUFFER=y
CONFIG_FB_MSM_MDP30=y
CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 052c715..11c4224 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -208,6 +208,7 @@
CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+CONFIG_TOUCHSCREEN_FT5X06=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=y
@@ -256,6 +257,7 @@
CONFIG_FB_MSM_TRIPLE_BUFFER=y
CONFIG_FB_MSM_MDP30=y
CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index e865552..ab3f8da 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -74,6 +74,7 @@
CONFIG_MSM_MODEM_8960=y
CONFIG_MSM_LPASS_8960=y
CONFIG_MSM_WCNSS_SSR_8960=y
+CONFIG_MSM_GSS_SSR_8064=y
CONFIG_MSM_TZ_LOG=y
CONFIG_MSM_RPM_LOG=y
CONFIG_MSM_RPM_STATS_LOG=y
@@ -84,6 +85,7 @@
CONFIG_MSM_DLOAD_MODE=y
CONFIG_MSM_QDSS=y
CONFIG_MSM_SLEEP_STATS=y
+CONFIG_MSM_DCVS=y
CONFIG_STRICT_MEMORY_RWX=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 6104d65..75dff22 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -73,6 +73,7 @@
CONFIG_MSM_MODEM_8960=y
CONFIG_MSM_LPASS_8960=y
CONFIG_MSM_WCNSS_SSR_8960=y
+CONFIG_MSM_GSS_SSR_8064=y
CONFIG_MSM_TZ_LOG=y
CONFIG_MSM_RPM_LOG=y
CONFIG_MSM_RPM_STATS_LOG=y
@@ -84,6 +85,7 @@
CONFIG_MSM_QDSS=y
CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE=y
CONFIG_MSM_SLEEP_STATS=y
+CONFIG_MSM_DCVS=y
CONFIG_MSM_RTB=y
CONFIG_MSM_RTB_SEPARATE_CPUS=y
CONFIG_STRICT_MEMORY_RWX=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 71cda29..c9ce881 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -43,6 +43,7 @@
# CONFIG_MSM_RESET_MODEM is not set
CONFIG_MSM_IPC_ROUTER=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_PIL_QDSP6V4=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
# CONFIG_MSM_SYSMON_COMM is not set
CONFIG_MSM_MODEM_8960=y
@@ -201,8 +202,13 @@
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS8960=y
CONFIG_MFD_PM8018_CORE=y
+CONFIG_WCD9310_CODEC=y
CONFIG_REGULATOR_PM8XXX=y
CONFIG_REGULATOR_GPIO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_MDM9615=y
# CONFIG_HID_SUPPORT is not set
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index cb7dd40..dbf1e6e 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -33,7 +33,7 @@
/*
* Enable the SCU
*/
-void __init scu_enable(void __iomem *scu_base)
+void scu_enable(void __iomem *scu_base)
{
u32 scu_ctrl;
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 023d289..370bc3f 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -250,6 +250,7 @@
config ARCH_MSM9615
bool "MSM9615"
select ARM_GIC
+ select GIC_SECURE
select ARCH_MSM_CORTEX_A5
select CPU_V7
select MSM_V2_TLMM
@@ -262,6 +263,9 @@
select MULTI_IRQ_HANDLER
select MSM_PM8X60 if PM
select MSM_XO
+ select MSM_PIL
+ select MSM_QDSP6_APR
+ select MSM_AUDIO_QDSP6 if SND_SOC
config ARCH_MSM8625
bool "MSM8625"
@@ -314,11 +318,13 @@
config ARCH_MSM_SCORPIONMP
select ARCH_MSM_SCORPION
select MSM_SMP
+ select HAVE_ARCH_HAS_CURRENT_TIMER
bool
config ARCH_MSM_KRAITMP
select ARCH_MSM_KRAIT
select MSM_SMP
+ select HAVE_ARCH_HAS_CURRENT_TIMER
bool
config ARCH_MSM_CORTEXMP
@@ -1810,6 +1816,14 @@
monitors WCNSS hardware watchdog interrupt lines and plugs WCNSS
into the subsystem restart framework.
+config MSM_GSS_SSR_8064
+ bool "MSM 8064 GSS restart driver"
+ depends on (ARCH_APQ8064)
+ help
+ This option enables the gps subsystem restart driver for APQ8064, which monitors
+ gss hardware watchdog interrupt lines and plugs into the subsystem
+ restart and PIL drivers.
+
config SCORPION_Uni_45nm_BUG
bool "Scorpion Uni 45nm(SC45U): Workaround for ICIMVAU and BPIMVA"
depends on ARCH_MSM7X30 || (ARCH_QSD8X50 && MSM_SOC_REV_A)
@@ -2185,4 +2199,6 @@
algorithm and the algorithm returns a frequency for the core which is
passed to the frequency change driver.
+config HAVE_ARCH_HAS_CURRENT_TIMER
+ bool
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 6df96ad..cd6e36c 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -192,6 +192,7 @@
obj-$(CONFIG_MSM_MODEM_8960) += modem-8960.o
obj-$(CONFIG_MSM_LPASS_8960) += lpass-8960.o
obj-$(CONFIG_MSM_WCNSS_SSR_8960) += wcnss-ssr-8960.o
+obj-$(CONFIG_MSM_GSS_SSR_8064) += gss-8064.o
ifdef CONFIG_CPU_IDLE
obj-$(CONFIG_ARCH_APQ8064) += cpuidle.o
@@ -245,7 +246,7 @@
obj-$(CONFIG_ARCH_MSM8960) += devices-8960.o
obj-$(CONFIG_ARCH_APQ8064) += devices-8960.o devices-8064.o
board-8960-all-objs += board-8960.o board-8960-camera.o board-8960-display.o board-8960-pmic.o board-8960-storage.o board-8960-gpiomux.o
-board-8930-all-objs += board-8930.o board-8930-camera.o board-8930-display.o board-8930-pmic.o board-8930-storage.o board-8930-gpiomux.o devices-8930.o
+board-8930-all-objs += board-8930.o board-8930-camera.o board-8930-display.o board-8930-pmic.o board-8930-storage.o board-8930-gpiomux.o devices-8930.o board-8930-gpu.o
board-8064-all-objs += board-8064.o board-8064-pmic.o board-8064-storage.o board-8064-gpiomux.o board-8064-camera.o board-8064-display.o board-8064-gpu.o
obj-$(CONFIG_MACH_MSM8960_SIM) += board-8960-all.o board-8960-regulator.o
obj-$(CONFIG_MACH_MSM8960_RUMI3) += board-8960-all.o board-8960-regulator.o
@@ -313,7 +314,7 @@
obj-$(CONFIG_MSM_SLEEP_STATS) += msm_rq_stats.o idle_stats.o
obj-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += idle_stats_device.o
-obj-$(CONFIG_MSM_DCVS) += msm_dcvs_scm.o msm_dcvs.o
+obj-$(CONFIG_MSM_DCVS) += msm_dcvs_scm.o msm_dcvs.o msm_dcvs_idle.o
obj-$(CONFIG_MSM_SHOW_RESUME_IRQ) += msm_show_resume_irq.o
obj-$(CONFIG_BT_MSM_PINTEST) += btpintest.o
obj-$(CONFIG_MSM_FAKE_BATTERY) += fish_battery.o
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index 687033c..35e8eba 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -29,8 +29,9 @@
#include <linux/sort.h>
#include <mach/board.h>
#include <mach/msm_iomap.h>
-#include <asm/mach-types.h>
#include <mach/socinfo.h>
+#include <asm/mach-types.h>
+#include <asm/cpu.h>
#include "smd_private.h"
#include "acpuclock.h"
@@ -87,6 +88,7 @@
unsigned int ahbclk_div;
int vdd;
unsigned int axiclk_khz;
+ unsigned long lpj; /* loops_per_jiffy */
/* Pointers in acpu_freq_tbl[] for max up/down steppings. */
struct clkctl_acpu_speed *down[ACPU_PLL_END];
struct clkctl_acpu_speed *up[ACPU_PLL_END];
@@ -114,7 +116,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 160000 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627 with CDMA capable modem */
@@ -128,7 +130,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 160000 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627 with GSM capable modem - PLL2 @ 800 */
@@ -142,7 +144,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 1, 133333, 2, 5, 160000 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
{ 1, 800000, ACPU_PLL_2, 2, 0, 200000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627 with CDMA capable modem - PLL2 @ 800 */
@@ -156,7 +158,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 1, 133333, 2, 5, 160000 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
{ 1, 800000, ACPU_PLL_2, 2, 0, 200000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627a PLL2 @ 1200MHz with GSM capable modem */
@@ -171,7 +173,7 @@
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627a PLL2 @ 1200MHz with CDMA capable modem */
@@ -186,7 +188,7 @@
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627aa PLL4 @ 1008MHz with GSM capable modem */
@@ -201,7 +203,7 @@
{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627aa PLL4 @ 1008MHz with CDMA capable modem */
@@ -216,7 +218,7 @@
{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 8625 PLL4 @ 1209MHz with GSM capable modem */
@@ -230,7 +232,7 @@
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 200000 },
{ 1, 1209600, ACPU_PLL_4, 6, 0, 151200, 3, 7, 200000},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 8625 PLL4 @ 1209MHz with CDMA capable modem */
@@ -244,7 +246,7 @@
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 200000 },
{ 1, 1209600, ACPU_PLL_4, 6, 0, 151200, 3, 7, 200000},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7625a PLL2 @ 1200MHz with GSM capable modem */
@@ -258,7 +260,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 2, 50000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627a PLL2 @ 1200MHz with GSM capable modem */
@@ -273,7 +275,7 @@
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627a PLL2 @ 1200MHz with CDMA capable modem */
@@ -288,7 +290,7 @@
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627aa PLL4 @ 1008MHz with GSM capable modem */
@@ -303,7 +305,7 @@
{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627aa PLL4 @ 1008MHz with CDMA capable modem */
@@ -318,7 +320,7 @@
{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7625a PLL2 @ 1200MHz with GSM capable modem */
@@ -332,7 +334,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 2, 50000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
#define PLL_CONFIG(m0, m1, m2, m4) { \
@@ -607,6 +609,16 @@
acpuclk_set_div(cur_s);
drv_state.current_speed = cur_s;
+ /* Re-adjust lpj for the new clock speed. */
+#ifdef CONFIG_SMP
+ for_each_possible_cpu(cpu) {
+ per_cpu(cpu_data, cpu).loops_per_jiffy =
+ cur_s->lpj;
+ }
+#endif
+ /* Adjust the global one */
+ loops_per_jiffy = cur_s->lpj;
+
mb();
udelay(50);
}
@@ -790,6 +802,27 @@
return found_khz;
}
+static void __init lpj_init(void)
+{
+ int i = 0, cpu;
+ const struct clkctl_acpu_speed *base_clk = drv_state.current_speed;
+ unsigned long loops;
+
+ for_each_possible_cpu(cpu) {
+#ifdef CONFIG_SMP
+ loops = per_cpu(cpu_data, cpu).loops_per_jiffy;
+#else
+ loops = loops_per_jiffy;
+#endif
+ for (i = 0; acpu_freq_tbl[i].a11clk_khz; i++) {
+ acpu_freq_tbl[i].lpj = cpufreq_scale(
+ loops,
+ base_clk->a11clk_khz,
+ acpu_freq_tbl[i].a11clk_khz);
+ }
+ }
+}
+
static void __init precompute_stepping(void)
{
int i, step_idx;
@@ -882,6 +915,7 @@
acpuclk_7627_data.wait_for_irq_khz = find_wait_for_irq_khz();
precompute_stepping();
acpuclk_hw_init();
+ lpj_init();
print_acpu_freq_tbl();
acpuclk_register(&acpuclk_7627_data);
diff --git a/arch/arm/mach-msm/acpuclock-7x30.c b/arch/arm/mach-msm/acpuclock-7x30.c
index 598b7c5..54d2aa9 100644
--- a/arch/arm/mach-msm/acpuclock-7x30.c
+++ b/arch/arm/mach-msm/acpuclock-7x30.c
@@ -76,6 +76,7 @@
unsigned int vdd_mv;
unsigned int vdd_raw;
struct pll *pll_rate;
+ unsigned long lpj; /* loops_per_jiffy */
};
static struct clock_state drv_state = { 0 };
@@ -258,6 +259,7 @@
/* Perform the frequency switch */
acpuclk_set_src(tgt_s);
drv_state.current_speed = tgt_s;
+ loops_per_jiffy = tgt_s->lpj;
if (tgt_s->src == PLL_2 && strt_s->src == PLL_2)
clk_disable(acpuclk_sources[backup_s->src]);
@@ -390,6 +392,19 @@
return;
}
+/* Initalize the lpj field in the acpu_freq_tbl. */
+static void __init lpj_init(void)
+{
+ int i;
+ const struct clkctl_acpu_speed *base_clk = drv_state.current_speed;
+
+ for (i = 0; acpu_freq_tbl[i].acpu_clk_khz; i++) {
+ acpu_freq_tbl[i].lpj = cpufreq_scale(loops_per_jiffy,
+ base_clk->acpu_clk_khz,
+ acpu_freq_tbl[i].acpu_clk_khz);
+ }
+}
+
#ifdef CONFIG_CPU_FREQ_MSM
static struct cpufreq_frequency_table cpufreq_tbl[ARRAY_SIZE(acpu_freq_tbl)];
@@ -464,6 +479,7 @@
pll2_fixup();
populate_plls();
acpuclk_hw_init();
+ lpj_init();
setup_cpufreq_table();
acpuclk_register(&acpuclk_7x30_data);
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index b52004a..cd8fba5 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -214,6 +214,7 @@
.nonremovable = 1,
.pin_data = &mmc_slot_pin_data[SDCC1],
.vreg_data = &mmc_slot_vreg_data[SDCC1],
+ .uhs_caps = MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50,
};
static struct mmc_platform_data *apq8064_sdc1_pdata = &sdc1_data;
#else
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index d798da6..54d68d3 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1776,6 +1776,8 @@
#ifdef CONFIG_MSM_RTB
&msm_rtb_device,
#endif
+ &apq8064_cpu_idle_device,
+ &apq8064_msm_gov_device,
};
static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8930-gpu.c b/arch/arm/mach-msm/board-8930-gpu.c
new file mode 100644
index 0000000..a5157038
--- /dev/null
+++ b/arch/arm/mach-msm/board-8930-gpu.c
@@ -0,0 +1,163 @@
+/* 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/msm_kgsl.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+
+#include "devices.h"
+#include "board-8930.h"
+
+#ifdef CONFIG_MSM_BUS_SCALING
+static struct msm_bus_vectors grp3d_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_GRAPHICS_3D,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+
+static struct msm_bus_vectors grp3d_low_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_GRAPHICS_3D,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = KGSL_CONVERT_TO_MBPS(2000),
+ },
+};
+
+static struct msm_bus_vectors grp3d_nominal_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_GRAPHICS_3D,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = KGSL_CONVERT_TO_MBPS(3200),
+ },
+};
+
+static struct msm_bus_vectors grp3d_max_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_GRAPHICS_3D,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = KGSL_CONVERT_TO_MBPS(3200),
+ },
+};
+
+static struct msm_bus_paths grp3d_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(grp3d_init_vectors),
+ grp3d_init_vectors,
+ },
+ {
+ ARRAY_SIZE(grp3d_low_vectors),
+ grp3d_low_vectors,
+ },
+ {
+ ARRAY_SIZE(grp3d_nominal_vectors),
+ grp3d_nominal_vectors,
+ },
+ {
+ ARRAY_SIZE(grp3d_max_vectors),
+ grp3d_max_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata grp3d_bus_scale_pdata = {
+ grp3d_bus_scale_usecases,
+ ARRAY_SIZE(grp3d_bus_scale_usecases),
+ .name = "grp3d",
+};
+#endif
+
+static struct resource kgsl_3d0_resources[] = {
+ {
+ .name = KGSL_3D0_REG_MEMORY,
+ .start = 0x04300000, /* GFX3D address */
+ .end = 0x0431ffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = KGSL_3D0_IRQ,
+ .start = GFX3D_IRQ,
+ .end = GFX3D_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const char *kgsl_3d0_iommu0_ctx_names[] = {
+ "gfx3d_user",
+ /* priv_ctx goes here */
+};
+
+static struct kgsl_device_iommu_data kgsl_3d0_iommu_data[] = {
+ {
+ .iommu_ctx_names = kgsl_3d0_iommu0_ctx_names,
+ .iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu0_ctx_names),
+ .physstart = 0x07C00000,
+ .physend = 0x07C00000 + SZ_1M - 1,
+ },
+};
+
+static struct kgsl_device_platform_data kgsl_3d0_pdata = {
+ .pwrlevel = {
+ {
+ .gpu_freq = 200000000,
+ .bus_freq = 3,
+ .io_fraction = 0,
+ },
+ {
+ .gpu_freq = 200000000,
+ .bus_freq = 2,
+ .io_fraction = 33,
+ },
+ {
+ .gpu_freq = 200000000,
+ .bus_freq = 1,
+ .io_fraction = 100,
+ },
+ {
+ .gpu_freq = 27000000,
+ .bus_freq = 0,
+ },
+ },
+ .init_level = 0,
+ .num_levels = 4,
+ .set_grp_async = NULL,
+ .idle_timeout = 0x1FFFFFFF,
+ .nap_allowed = false,
+ .clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE,
+#ifdef CONFIG_MSM_BUS_SCALING
+ .bus_scale_table = &grp3d_bus_scale_pdata,
+#endif
+ .iommu_data = kgsl_3d0_iommu_data,
+ .iommu_count = ARRAY_SIZE(kgsl_3d0_iommu_data),
+};
+
+static struct platform_device device_kgsl_3d0 = {
+ .name = "kgsl-3d0",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(kgsl_3d0_resources),
+ .resource = kgsl_3d0_resources,
+ .dev = {
+ .platform_data = &kgsl_3d0_pdata,
+ },
+};
+
+void __init msm8930_init_gpu(void)
+{
+ platform_device_register(&device_kgsl_3d0);
+}
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 9dcbb67..2a2cc42 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -952,15 +952,17 @@
{
#ifdef CONFIG_MSM_BUS_SCALING
msm_bus_rpm_set_mt_mask();
- msm_bus_8960_apps_fabric_pdata.rpm_enabled = 1;
- msm_bus_8960_sys_fabric_pdata.rpm_enabled = 1;
- msm_bus_8960_mm_fabric_pdata.rpm_enabled = 1;
- msm_bus_apps_fabric.dev.platform_data =
- &msm_bus_8960_apps_fabric_pdata;
- msm_bus_sys_fabric.dev.platform_data = &msm_bus_8960_sys_fabric_pdata;
- msm_bus_mm_fabric.dev.platform_data = &msm_bus_8960_mm_fabric_pdata;
- msm_bus_sys_fpb.dev.platform_data = &msm_bus_8960_sys_fpb_pdata;
- msm_bus_cpss_fpb.dev.platform_data = &msm_bus_8960_cpss_fpb_pdata;
+ msm_bus_8930_apps_fabric_pdata.rpm_enabled = 1;
+ msm_bus_8930_sys_fabric_pdata.rpm_enabled = 1;
+ msm_bus_8930_mm_fabric_pdata.rpm_enabled = 1;
+ msm_bus_8930_apps_fabric.dev.platform_data =
+ &msm_bus_8930_apps_fabric_pdata;
+ msm_bus_8930_sys_fabric.dev.platform_data =
+ &msm_bus_8930_sys_fabric_pdata;
+ msm_bus_8930_mm_fabric.dev.platform_data =
+ &msm_bus_8930_mm_fabric_pdata;
+ msm_bus_8930_sys_fpb.dev.platform_data = &msm_bus_8930_sys_fpb_pdata;
+ msm_bus_8930_cpss_fpb.dev.platform_data = &msm_bus_8930_cpss_fpb_pdata;
#endif
}
@@ -1783,7 +1785,6 @@
#endif
&android_pmem_audio_device,
#endif
- &msm_device_vidc,
&msm_device_bam_dmux,
&msm_fm_platform_init,
@@ -1812,6 +1813,13 @@
#ifdef CONFIG_MSM_RTB
&msm_rtb_device,
#endif
+ &msm8930_cpu_idle_device,
+ &msm8930_msm_gov_device,
+ &msm_bus_8930_apps_fabric,
+ &msm_bus_8930_sys_fabric,
+ &msm_bus_8930_mm_fabric,
+ &msm_bus_8930_sys_fpb,
+ &msm_bus_8930_cpss_fpb,
};
static struct platform_device *cdp_devices[] __initdata = {
@@ -1832,11 +1840,6 @@
&msm_cpudai_auxpcm_tx,
&msm_cpu_fe,
&msm_stub_codec,
- &msm_kgsl_3d0,
-#ifdef CONFIG_MSM_KGSL_2D
- &msm_kgsl_2d0,
- &msm_kgsl_2d1,
-#endif
#ifdef CONFIG_MSM_GEMINI
&msm8960_gemini_device,
#endif
@@ -1853,11 +1856,6 @@
&msm_cpudai_incall_record_rx,
&msm_cpudai_incall_record_tx,
&msm_pcm_hostless,
- &msm_bus_apps_fabric,
- &msm_bus_sys_fabric,
- &msm_bus_mm_fabric,
- &msm_bus_sys_fpb,
- &msm_bus_cpss_fpb,
};
static void __init msm8930_i2c_init(void)
@@ -1878,17 +1876,6 @@
&msm8960_i2c_qup_gsbi12_pdata;
}
-static void __init msm8930_gfx_init(void)
-{
- uint32_t soc_platform_version = socinfo_get_version();
- if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
- struct kgsl_device_platform_data *kgsl_3d0_pdata =
- msm_kgsl_3d0.dev.platform_data;
- kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
- kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
- }
-}
-
static struct msm_cpuidle_state msm_cstates[] __initdata = {
{0, 0, "C0", "WFI",
MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT},
@@ -2203,13 +2190,14 @@
msm8930_init_pmic();
#endif
msm8930_i2c_init();
- msm8930_gfx_init();
+ msm8930_init_gpu();
msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
msm_spm_l2_init(msm_spm_l2_data);
msm8930_init_buses();
platform_add_devices(msm_footswitch_devices,
msm_num_footswitch_devices);
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+ msm8930_add_vidc_device();
/*
* TODO: When physical 8930/PM8038 hardware becomes
* available, remove this block or add the config
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index cefaff5..45fe40f 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -109,6 +109,7 @@
void msm8930_init_cam(void);
void msm8930_init_fb(void);
void msm8930_init_pmic(void);
+extern void msm8930_add_vidc_device(void);
/*
* TODO: When physical 8930/PM8038 hardware becomes
@@ -125,6 +126,7 @@
void msm8930_allocate_fb_region(void);
void msm8930_pm8038_gpio_mpp_init(void);
void msm8930_mdp_writeback(struct memtype_reserve *reserve_table);
+void __init msm8930_init_gpu(void);
#define PLATFORM_IS_CHARM25() \
(machine_is_msm8930_cdp() && \
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index e2ba303..db0bbff 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -140,7 +140,7 @@
#define MSM_ION_SF_SIZE MSM_PMEM_SIZE
#define MSM_ION_MM_FW_SIZE 0x200000 /* (2MB) */
#define MSM_ION_MM_SIZE MSM_PMEM_ADSP_SIZE
-#define MSM_ION_QSECOM_SIZE 0x300000 /* (3MB) */
+#define MSM_ION_QSECOM_SIZE 0x600000 /* (6MB) */
#define MSM_ION_MFC_SIZE SZ_8K
#define MSM_ION_AUDIO_SIZE MSM_PMEM_AUDIO_SIZE
#define MSM_ION_HEAP_NUM 8
@@ -2190,6 +2190,8 @@
#ifdef CONFIG_MSM_RTB
&msm_rtb_device,
#endif
+ &msm8960_cpu_idle_device,
+ &msm8960_msm_gov_device,
};
static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-9615-gpiomux.c b/arch/arm/mach-msm/board-9615-gpiomux.c
index ea8caf5..e61f001 100644
--- a/arch/arm/mach-msm/board-9615-gpiomux.c
+++ b/arch/arm/mach-msm/board-9615-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -79,6 +79,21 @@
.pull = GPIOMUX_PULL_DOWN,
};
+static struct gpiomux_setting cdc_mclk = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct msm_gpiomux_config msm9615_audio_codec_configs[] __initdata = {
+ {
+ .gpio = 24,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &cdc_mclk,
+ },
+ },
+};
+
static struct msm_gpiomux_config msm9615_sdcc2_configs[] __initdata = {
{
/* SDC2_DATA_0 */
@@ -271,6 +286,8 @@
msm_gpiomux_install(msm9615_ltc4088_charger_config,
ARRAY_SIZE(msm9615_ltc4088_charger_config));
#endif
+ msm_gpiomux_install(msm9615_audio_codec_configs,
+ ARRAY_SIZE(msm9615_audio_codec_configs));
return 0;
}
diff --git a/arch/arm/mach-msm/board-9615-regulator.c b/arch/arm/mach-msm/board-9615-regulator.c
index 11d35f4..dd83d6f 100644
--- a/arch/arm/mach-msm/board-9615-regulator.c
+++ b/arch/arm/mach-msm/board-9615-regulator.c
@@ -74,10 +74,22 @@
};
VREG_CONSUMERS(S2) = {
REGULATOR_SUPPLY("8018_s2", NULL),
+ REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "tabla-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "tabla2x-slim"),
+ REGULATOR_SUPPLY("VDDD_CDC_D", "tabla-slim"),
+ REGULATOR_SUPPLY("VDDD_CDC_D", "tabla2x-slim"),
};
VREG_CONSUMERS(S3) = {
REGULATOR_SUPPLY("8018_s3", NULL),
REGULATOR_SUPPLY("wlan_vreg", "wlan_ar6000_pm_dev"),
+ REGULATOR_SUPPLY("CDC_VDD_CP", "tabla-slim"),
+ REGULATOR_SUPPLY("CDC_VDD_CP", "tabla2x-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_RX", "tabla-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_RX", "tabla2x-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_TX", "tabla-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_TX", "tabla2x-slim"),
+ REGULATOR_SUPPLY("VDDIO_CDC", "tabla-slim"),
+ REGULATOR_SUPPLY("VDDIO_CDC", "tabla2x-slim"),
};
VREG_CONSUMERS(S4) = {
REGULATOR_SUPPLY("8018_s4", NULL),
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 8fe55ff..40cd9ea 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -15,6 +15,10 @@
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/slimbus/slimbus.h>
+#ifdef CONFIG_WCD9310_CODEC
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
+#endif
#include <linux/msm_ssbi.h>
#include <linux/memblock.h>
#include <linux/usb/android.h>
@@ -30,9 +34,11 @@
#include <mach/board.h>
#include <mach/msm_iomap.h>
#include <mach/gpio.h>
+#include <mach/socinfo.h>
#include <mach/msm_spi.h>
#include <mach/msm_bus_board.h>
#include <mach/msm_xo.h>
+#include <mach/dma.h>
#include "timer.h"
#include "devices.h"
#include "board-9615.h"
@@ -231,8 +237,96 @@
#endif
}
+#ifdef CONFIG_WCD9310_CODEC
+
+#define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
+
+/* Micbias setting is based on 8660 CDP/MTP/FLUID requirement
+ * 4 micbiases are used to power various analog and digital
+ * microphones operating at 1800 mV. Technically, all micbiases
+ * can source from single cfilter since all microphones operate
+ * at the same voltage level. The arrangement below is to make
+ * sure all cfilters are exercised. LDO_H regulator ouput level
+ * does not need to be as high as 2.85V. It is choosen for
+ * microphone sensitivity purpose.
+ */
+
+static struct wcd9xxx_pdata tabla20_platform_data = {
+ .slimbus_slave_device = {
+ .name = "tabla-slave",
+ .e_addr = {0, 0, 0x60, 0, 0x17, 2},
+ },
+ .irq = 85,
+ .irq_base = TABLA_INTERRUPT_BASE,
+ .num_irqs = NR_WCD9XXX_IRQS,
+ .reset_gpio = 84,
+ .micbias = {
+ .ldoh_v = TABLA_LDOH_2P85_V,
+ .cfilt1_mv = 1800,
+ .cfilt2_mv = 1800,
+ .cfilt3_mv = 1800,
+ .bias1_cfilt_sel = TABLA_CFILT1_SEL,
+ .bias2_cfilt_sel = TABLA_CFILT2_SEL,
+ .bias3_cfilt_sel = TABLA_CFILT3_SEL,
+ .bias4_cfilt_sel = TABLA_CFILT3_SEL,
+ },
+ .regulator = {
+ {
+ .name = "CDC_VDD_CP",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_CDC_VDDA_CP_CUR_MAX,
+ },
+ {
+ .name = "CDC_VDDA_RX",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_CDC_VDDA_RX_CUR_MAX,
+ },
+ {
+ .name = "CDC_VDDA_TX",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_CDC_VDDA_TX_CUR_MAX,
+ },
+ {
+ .name = "VDDIO_CDC",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_VDDIO_CDC_CUR_MAX,
+ },
+ {
+ .name = "VDDD_CDC_D",
+ .min_uV = 1225000,
+ .max_uV = 1225000,
+ .optimum_uA = WCD9XXX_VDDD_CDC_D_CUR_MAX,
+ },
+ {
+ .name = "CDC_VDDA_A_1P2V",
+ .min_uV = 1225000,
+ .max_uV = 1225000,
+ .optimum_uA = WCD9XXX_VDDD_CDC_A_CUR_MAX,
+ },
+ },
+};
+
+static struct slim_device msm_slim_tabla20 = {
+ .name = "tabla2x-slim",
+ .e_addr = {0, 1, 0x60, 0, 0x17, 2},
+ .dev = {
+ .platform_data = &tabla20_platform_data,
+ },
+};
+#endif
+
static struct slim_boardinfo msm_slim_devices[] = {
/* add slimbus slaves as needed */
+#ifdef CONFIG_WCD9310_CODEC
+ {
+ .bus_num = 1,
+ .slim_slave = &msm_slim_tabla20,
+ },
+#endif
};
static struct msm_spi_platform_data msm9615_qup_spi_gsbi3_pdata = {
@@ -545,6 +639,26 @@
&msm_device_rng,
#endif
+ &msm_pcm,
+ &msm_multi_ch_pcm,
+ &msm_pcm_routing,
+ &msm_cpudai0,
+ &msm_cpudai1,
+ &msm_cpudai_bt_rx,
+ &msm_cpudai_bt_tx,
+ &msm_cpu_fe,
+ &msm_stub_codec,
+ &msm_voice,
+ &msm_voip,
+ &msm_pcm_hostless,
+ &msm_cpudai_afe_01_rx,
+ &msm_cpudai_afe_01_tx,
+ &msm_cpudai_afe_02_rx,
+ &msm_cpudai_afe_02_tx,
+ &msm_pcm_afe,
+ &msm_cpudai_auxpcm_rx,
+ &msm_cpudai_auxpcm_tx,
+
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
&msm9615_qcrypto_device,
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index bf1a4c5..950815a 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -44,6 +44,245 @@
early_param("fb_size", fb_size_setup);
+static uint32_t lcdc_truly_gpio_initialized;
+static struct regulator_bulk_data regs_truly_lcdc[] = {
+ { .supply = "rfrx1", .min_uV = 1800000, .max_uV = 1800000 },
+};
+
+#define SKU3_LCDC_GPIO_DISPLAY_RESET 90
+#define SKU3_LCDC_GPIO_SPI_MOSI 19
+#define SKU3_LCDC_GPIO_SPI_CLK 20
+#define SKU3_LCDC_GPIO_SPI_CS0_N 21
+#define SKU3_LCDC_LCD_CAMERA_LDO_2V8 35 /*LCD_CAMERA_LDO_2V8*/
+#define SKU3_LCDC_LCD_CAMERA_LDO_1V8 34 /*LCD_CAMERA_LDO_1V8*/
+#define SKU3_1_LCDC_LCD_CAMERA_LDO_1V8 58 /*LCD_CAMERA_LDO_1V8*/
+
+static uint32_t lcdc_truly_gpio_table[] = {
+ 19,
+ 20,
+ 21,
+ 89,
+ 90,
+};
+
+static char *lcdc_gpio_name_table[5] = {
+ "spi_mosi",
+ "spi_clk",
+ "spi_cs",
+ "gpio_bkl_en",
+ "gpio_disp_reset",
+};
+
+static int lcdc_truly_gpio_init(void)
+{
+ int i;
+ int rc = 0;
+
+ if (!lcdc_truly_gpio_initialized) {
+ for (i = 0; i < ARRAY_SIZE(lcdc_truly_gpio_table); i++) {
+ rc = gpio_request(lcdc_truly_gpio_table[i],
+ lcdc_gpio_name_table[i]);
+ if (rc < 0) {
+ pr_err("Error request gpio %s\n",
+ lcdc_gpio_name_table[i]);
+ goto truly_gpio_fail;
+ }
+ rc = gpio_tlmm_config(GPIO_CFG(lcdc_truly_gpio_table[i],
+ 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("Error config lcdc gpio:%d\n",
+ lcdc_truly_gpio_table[i]);
+ goto truly_gpio_fail;
+ }
+ rc = gpio_direction_output(lcdc_truly_gpio_table[i], 0);
+ if (rc < 0) {
+ pr_err("Error direct lcdc gpio:%d\n",
+ lcdc_truly_gpio_table[i]);
+ goto truly_gpio_fail;
+ }
+ }
+
+ lcdc_truly_gpio_initialized = 1;
+ }
+
+ return rc;
+
+truly_gpio_fail:
+ for (; i >= 0; i--) {
+ pr_err("Freeing GPIO: %d", lcdc_truly_gpio_table[i]);
+ gpio_free(lcdc_truly_gpio_table[i]);
+ }
+
+ lcdc_truly_gpio_initialized = 0;
+ return rc;
+}
+
+
+void sku3_lcdc_lcd_camera_power_init(void)
+{
+ int rc = 0;
+ u32 socinfo = socinfo_get_platform_type();
+
+ /* LDO_EXT2V8 */
+ if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_2V8, "lcd_camera_ldo_2v8")) {
+ pr_err("failed to request gpio lcd_camera_ldo_2v8\n");
+ return;
+ }
+
+ rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ GPIO_CFG_ENABLE);
+
+ if (rc < 0) {
+ pr_err("%s:unable to enable lcd_camera_ldo_2v8!\n", __func__);
+ goto fail_gpio2;
+ }
+
+ /* LDO_EVT1V8 */
+ if (socinfo == 0x0B) {
+ if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
+ "lcd_camera_ldo_1v8")) {
+ pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
+ goto fail_gpio1;
+ }
+
+ rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_1V8, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ GPIO_CFG_ENABLE);
+
+ if (rc < 0) {
+ pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
+ __func__);
+ goto fail_gpio1;
+ }
+ } else if (socinfo == 0x0F) {
+ if (gpio_request(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
+ "lcd_camera_ldo_1v8")) {
+ pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
+ goto fail_gpio1;
+ }
+
+ rc = gpio_tlmm_config(GPIO_CFG(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
+ 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ GPIO_CFG_ENABLE);
+
+ if (rc < 0) {
+ pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
+ __func__);
+ goto fail_gpio1;
+ }
+ }
+
+ rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_truly_lcdc),
+ regs_truly_lcdc);
+ if (rc)
+ pr_err("%s: could not get regulators: %d\n", __func__, rc);
+
+ rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_truly_lcdc),
+ regs_truly_lcdc);
+ if (rc)
+ pr_err("%s: could not set voltages: %d\n", __func__, rc);
+
+ return;
+
+fail_gpio1:
+ if (socinfo == 0x0B)
+ gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_1V8);
+ else if (socinfo == 0x0F)
+ gpio_free(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8);
+fail_gpio2:
+ gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_2V8);
+ return;
+}
+
+int sku3_lcdc_lcd_camera_power_onoff(int on)
+{
+ int rc = 0;
+ u32 socinfo = socinfo_get_platform_type();
+
+ if (on) {
+ if (socinfo == 0x0B)
+ gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
+ 1);
+ else if (socinfo == 0x0F)
+ gpio_set_value_cansleep(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
+ 1);
+
+ gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 1);
+
+ rc = regulator_bulk_enable(ARRAY_SIZE(regs_truly_lcdc),
+ regs_truly_lcdc);
+ if (rc)
+ pr_err("%s: could not enable regulators: %d\n",
+ __func__, rc);
+ } else {
+ if (socinfo == 0x0B)
+ gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
+ 0);
+ else if (socinfo == 0x0F)
+ gpio_set_value_cansleep(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
+ 0);
+
+ gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 0);
+
+ rc = regulator_bulk_disable(ARRAY_SIZE(regs_truly_lcdc),
+ regs_truly_lcdc);
+ if (rc)
+ pr_err("%s: could not disable regulators: %d\n",
+ __func__, rc);
+ }
+
+ return rc;
+}
+
+static int sku3_lcdc_power_save(int on)
+{
+ int rc = 0;
+
+ if (on) {
+ sku3_lcdc_lcd_camera_power_onoff(1);
+ rc = lcdc_truly_gpio_init();
+ if (rc < 0) {
+ pr_err("%s(): Truly GPIO initializations failed",
+ __func__);
+ return rc;
+ }
+
+ if (lcdc_truly_gpio_initialized) {
+ /*LCD reset*/
+ gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
+ msleep(20);
+ gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
+ msleep(20);
+ gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
+ msleep(20);
+ }
+ } else {
+ /* pull down LCD IO to avoid current leakage */
+ gpio_set_value(SKU3_LCDC_GPIO_SPI_MOSI, 0);
+ gpio_set_value(SKU3_LCDC_GPIO_SPI_CLK, 0);
+ gpio_set_value(SKU3_LCDC_GPIO_SPI_CS0_N, 0);
+ gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
+
+ sku3_lcdc_lcd_camera_power_onoff(0);
+ }
+ return rc;
+}
+
+static struct msm_panel_common_pdata lcdc_truly_panel_data = {
+ .panel_config_gpio = NULL,
+ .gpio_num = lcdc_truly_gpio_table,
+};
+
+static struct platform_device lcdc_truly_panel_device = {
+ .name = "lcdc_truly_hvga_ips3p2335_pt",
+ .id = 0,
+ .dev = {
+ .platform_data = &lcdc_truly_panel_data,
+ }
+};
+
static struct regulator_bulk_data regs_lcdc[] = {
{ .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
{ .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
@@ -176,9 +415,21 @@
return ret;
}
+
+static int msm_lcdc_power_save(int on)
+{
+ int rc = 0;
+ if (machine_is_msm7627a_qrd3())
+ rc = sku3_lcdc_power_save(on);
+ else
+ rc = msm_fb_lcdc_power_save(on);
+
+ return rc;
+}
+
static struct lcdc_platform_data lcdc_pdata = {
.lcdc_gpio_config = NULL,
- .lcdc_power_save = msm_fb_lcdc_power_save,
+ .lcdc_power_save = msm_lcdc_power_save,
};
static int lcd_panel_spi_gpio_num[] = {
@@ -226,6 +477,9 @@
} else if (machine_is_msm7627a_qrd1()) {
if (!strncmp(name, "mipi_video_truly_wvga", 21))
ret = 0;
+ } else if (machine_is_msm7627a_qrd3()) {
+ if (!strncmp(name, "lcdc_truly_hvga_ips3p2335_pt", 28))
+ ret = 0;
} else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
ret = 0;
@@ -332,6 +586,11 @@
&mipi_dsi_truly_panel_device,
};
+static struct platform_device *qrd3_fb_devices[] __initdata = {
+ &msm_fb_device,
+ &lcdc_truly_panel_device,
+};
+
static struct platform_device *evb_fb_devices[] __initdata = {
&msm_fb_device,
&mipi_dsi_NT35510_panel_device,
@@ -836,7 +1095,7 @@
#define MDP_303_VSYNC_GPIO 97
-#ifdef CONFIG_FB_MSM_MDP303
+#ifdef CONFIG_FB_MSM_MIPI_DSI
static struct mipi_dsi_platform_data mipi_dsi_pdata = {
.vsync_gpio = MDP_303_VSYNC_GPIO,
.dsi_power_save = mipi_dsi_panel_power,
@@ -853,17 +1112,19 @@
else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
platform_add_devices(evb_fb_devices,
ARRAY_SIZE(evb_fb_devices));
- else if (machine_is_msm7627a_qrd3())
- return;
- else
+ else if (machine_is_msm7627a_qrd3()) {
+ sku3_lcdc_lcd_camera_power_init();
+ platform_add_devices(qrd3_fb_devices,
+ ARRAY_SIZE(qrd3_fb_devices));
+ } else
platform_add_devices(msm_fb_devices,
ARRAY_SIZE(msm_fb_devices));
msm_fb_register_device("mdp", &mdp_pdata);
if (machine_is_msm7625a_surf() || machine_is_msm7x27a_surf() ||
- machine_is_msm8625_surf())
+ machine_is_msm8625_surf() || machine_is_msm7627a_qrd3())
msm_fb_register_device("lcdc", &lcdc_pdata);
-#ifdef CONFIG_FB_MSM_MDP303
+#ifdef CONFIG_FB_MSM_MIPI_DSI
msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
#endif
}
diff --git a/arch/arm/mach-msm/board-msm7x27a-regulator.c b/arch/arm/mach-msm/board-msm7x27a-regulator.c
index 5be382f..469c543 100644
--- a/arch/arm/mach-msm/board-msm7x27a-regulator.c
+++ b/arch/arm/mach-msm/board-msm7x27a-regulator.c
@@ -85,6 +85,7 @@
REGULATOR_SUPPLY("smps3", NULL),
REGULATOR_SUPPLY("msme1", NULL),
REGULATOR_SUPPLY("vcc_i2c", "1-004a"),
+ REGULATOR_SUPPLY("vcc_i2c", "1-0038"),
};
PCOM_VREG_CONSUMERS(smps4) = {
@@ -160,6 +161,7 @@
REGULATOR_SUPPLY("ldo12", NULL),
REGULATOR_SUPPLY("gp2", NULL),
REGULATOR_SUPPLY("vdd_ana", "1-004a"),
+ REGULATOR_SUPPLY("vdd", "1-0038"),
};
PCOM_VREG_CONSUMERS(ldo13) = {
@@ -215,7 +217,7 @@
PCOM_VREG_SMP(smps2, 4, NULL, 1100000, 1100000, 0, -1, 0, 0, 0, 0, s),
PCOM_VREG_SMP(smps3, 2, NULL, 1800000, 1800000, 0, -1, 0, 0, 0, 0, s),
PCOM_VREG_SMP(smps4, 24, NULL, 2100000, 2100000, 0, -1, 0, 0, 0, 0, s),
- PCOM_VREG_LDO(ldo01, 12, NULL, 2100000, 2100000, 0, -1, 0, 0, 0, 0, p),
+ PCOM_VREG_LDO(ldo01, 12, NULL, 1800000, 2100000, 0, -1, 0, 0, 0, 0, p),
PCOM_VREG_LDO(ldo02, 13, NULL, 2850000, 2850000, 0, -1, 0, 0, 0, 0, p),
PCOM_VREG_LDO(ldo03, 49, NULL, 1200000, 1200000, 0, -1, 0, 0, 0, 0, n),
PCOM_VREG_LDO(ldo04, 50, NULL, 1100000, 1100000, 0, -1, 0, 0, 0, 0, n),
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index a6be53b..70efcce 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -2704,7 +2704,7 @@
#define MSM_ION_MM_SIZE 0x3600000 /* (54MB) */
#define MSM_ION_MFC_SIZE SZ_8K
#define MSM_ION_WB_SIZE 0x600000 /* 6MB */
-#define MSM_ION_QSECOM_SIZE 0x300000 /* (3MB) */
+#define MSM_ION_QSECOM_SIZE 0x600000 /* (6MB) */
#define MSM_ION_AUDIO_SIZE MSM_PMEM_AUDIO_SIZE
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 219af6d..ba534e8 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -29,6 +29,7 @@
#include <linux/i2c/atmel_mxt_ts.h>
#include <linux/regulator/consumer.h>
#include <linux/memblock.h>
+#include <linux/input/ft5x06_ts.h>
#include <asm/mach/mmc.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -258,6 +259,89 @@
}
#endif
+#define FT5X06_IRQ_GPIO 48
+#define FT5X06_RESET_GPIO 26
+
+static ssize_t
+ft5x06_virtual_keys_register(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return snprintf(buf, 200,
+ __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":40:510:80:60"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":120:510:80:60"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":200:510:80:60"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":280:510:80:60"
+ "\n");
+}
+
+static struct kobj_attribute ft5x06_virtual_keys_attr = {
+ .attr = {
+ .name = "virtualkeys.ft5x06_ts",
+ .mode = S_IRUGO,
+ },
+ .show = &ft5x06_virtual_keys_register,
+};
+
+static struct attribute *ft5x06_virtual_key_properties_attrs[] = {
+ &ft5x06_virtual_keys_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ft5x06_virtual_key_properties_attr_group = {
+ .attrs = ft5x06_virtual_key_properties_attrs,
+};
+
+struct kobject *ft5x06_virtual_key_properties_kobj;
+
+static struct ft5x06_ts_platform_data ft5x06_platformdata = {
+ .x_max = 320,
+ .y_max = 480,
+ .reset_gpio = FT5X06_RESET_GPIO,
+ .irq_gpio = FT5X06_IRQ_GPIO,
+ .irqflags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+};
+
+static struct i2c_board_info ft5x06_device_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ft5x06_ts", 0x38),
+ .platform_data = &ft5x06_platformdata,
+ .irq = MSM_GPIO_TO_INT(FT5X06_IRQ_GPIO),
+ },
+};
+
+static void ft5x06_touchpad_setup(void)
+{
+ int rc;
+
+ rc = gpio_tlmm_config(GPIO_CFG(FT5X06_IRQ_GPIO, 0,
+ GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
+ GPIO_CFG_8MA), GPIO_CFG_ENABLE);
+ if (rc)
+ pr_err("%s: gpio_tlmm_config for %d failed\n",
+ __func__, FT5X06_IRQ_GPIO);
+
+ rc = gpio_tlmm_config(GPIO_CFG(FT5X06_RESET_GPIO, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_8MA), GPIO_CFG_ENABLE);
+ if (rc)
+ pr_err("%s: gpio_tlmm_config for %d failed\n",
+ __func__, FT5X06_RESET_GPIO);
+
+ ft5x06_virtual_key_properties_kobj =
+ kobject_create_and_add("board_properties", NULL);
+
+ if (ft5x06_virtual_key_properties_kobj)
+ rc = sysfs_create_group(ft5x06_virtual_key_properties_kobj,
+ &ft5x06_virtual_key_properties_attr_group);
+
+ if (!ft5x06_virtual_key_properties_kobj || rc)
+ pr_err("%s: failed to create board_properties\n", __func__);
+
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ ft5x06_device_info,
+ ARRAY_SIZE(ft5x06_device_info));
+}
static struct android_usb_platform_data android_usb_pdata = {
.update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
@@ -1096,6 +1180,8 @@
i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
mxt_device_info,
ARRAY_SIZE(mxt_device_info));
+ } else if (machine_is_msm7627a_qrd3()) {
+ ft5x06_touchpad_setup();
}
/* headset */
@@ -1146,10 +1232,12 @@
static void add_platform_devices(void)
{
- if (machine_is_msm8625_evb())
+ if (machine_is_msm8625_evb()) {
platform_add_devices(msm8625_evb_devices,
ARRAY_SIZE(msm8625_evb_devices));
- else {
+ platform_add_devices(qrd3_devices,
+ ARRAY_SIZE(qrd3_devices));
+ } else {
platform_add_devices(qrd7627a_devices,
ARRAY_SIZE(qrd7627a_devices));
if (machine_is_msm7627a_qrd3())
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 119f89c..9ab630d 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4865,6 +4865,7 @@
CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.2"),
CLK_LOOKUP("xo", cxo_clk.c, "pil_gss"),
CLK_LOOKUP("xo", cxo_clk.c, "BAM_RMNT"),
+ CLK_LOOKUP("xo", cxo_clk.c, "msm_xo"),
CLK_LOOKUP("pll2", pll2_clk.c, NULL),
CLK_LOOKUP("pll8", pll8_clk.c, NULL),
CLK_LOOKUP("pll4", pll4_clk.c, NULL),
@@ -5147,6 +5148,7 @@
CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.1"),
CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.2"),
CLK_LOOKUP("xo", cxo_clk.c, "BAM_RMNT"),
+ CLK_LOOKUP("xo", cxo_clk.c, "msm_xo"),
CLK_LOOKUP("pll2", pll2_clk.c, NULL),
CLK_LOOKUP("pll8", pll8_clk.c, NULL),
CLK_LOOKUP("pll4", pll4_clk.c, NULL),
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 3e059b6..e1dc2ae 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1602,6 +1602,7 @@
CLK_LOOKUP("xo", cxo_a_clk.c, ""),
CLK_LOOKUP("xo", cxo_clk.c, "msm_otg"),
CLK_LOOKUP("xo", cxo_clk.c, "BAM_RMNT"),
+ CLK_LOOKUP("xo", cxo_clk.c, "msm_xo"),
CLK_LOOKUP("pll0", pll0_clk.c, NULL),
CLK_LOOKUP("pll8", pll8_clk.c, NULL),
CLK_LOOKUP("pll14", pll14_clk.c, NULL),
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 3632d80..6586329 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -30,6 +30,7 @@
#include <mach/rpm.h>
#include <mach/mdm2.h>
#include <mach/msm_smd.h>
+#include <mach/msm_dcvs.h>
#include <linux/ion.h>
#include "clock.h"
#include "devices.h"
@@ -2139,3 +2140,50 @@
.num_resources = ARRAY_SIZE(mdm_resources),
.resource = mdm_resources,
};
+
+static int apq8064_LPM_latency = 1000; /* >100 usec for WFI */
+
+struct platform_device apq8064_cpu_idle_device = {
+ .name = "msm_cpu_idle",
+ .id = -1,
+ .dev = {
+ .platform_data = &apq8064_LPM_latency,
+ },
+};
+
+static struct msm_dcvs_freq_entry apq8064_freq[] = {
+ { 384000, 166981, 345600},
+ { 702000, 213049, 632502},
+ {1026000, 285712, 925613},
+ {1242000, 383945, 1176550},
+ {1458000, 419729, 1465478},
+ {1512000, 434116, 1546674},
+
+};
+
+static struct msm_dcvs_core_info apq8064_core_info = {
+ .freq_tbl = &apq8064_freq[0],
+ .core_param = {
+ .max_time_us = 100000,
+ .num_freq = ARRAY_SIZE(apq8064_freq),
+ },
+ .algo_param = {
+ .slack_time_us = 58000,
+ .scale_slack_time = 0,
+ .scale_slack_time_pct = 0,
+ .disable_pc_threshold = 1458000,
+ .em_window_size = 100000,
+ .em_max_util_pct = 97,
+ .ss_window_size = 1000000,
+ .ss_util_pct = 95,
+ .ss_iobusy_conv = 100,
+ },
+};
+
+struct platform_device apq8064_msm_gov_device = {
+ .name = "msm_dcvs_gov",
+ .id = -1,
+ .dev = {
+ .platform_data = &apq8064_core_info,
+ },
+};
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index 81c52d1..da3574b 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -13,9 +13,15 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/ion.h>
#include <mach/msm_iomap.h>
#include <mach/irqs-8930.h>
#include <mach/rpm.h>
+#include <mach/msm_dcvs.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/socinfo.h>
#include "devices.h"
#include "rpm_log.h"
@@ -59,7 +65,7 @@
APPS_FABRIC_CFG_CLKMOD, 3),
MSM_RPM_MAP(8930, APPS_FABRIC_CFG_IOCTL,
APPS_FABRIC_CFG_IOCTL, 1),
- MSM_RPM_MAP(8930, APPS_FABRIC_ARB_0, APPS_FABRIC_ARB, 12),
+ MSM_RPM_MAP(8930, APPS_FABRIC_ARB_0, APPS_FABRIC_ARB, 6),
MSM_RPM_MAP(8930, SYS_FABRIC_CFG_HALT_0,
SYS_FABRIC_CFG_HALT, 2),
MSM_RPM_MAP(8930, SYS_FABRIC_CFG_CLKMOD_0,
@@ -67,14 +73,14 @@
MSM_RPM_MAP(8930, SYS_FABRIC_CFG_IOCTL,
SYS_FABRIC_CFG_IOCTL, 1),
MSM_RPM_MAP(8930, SYSTEM_FABRIC_ARB_0,
- SYSTEM_FABRIC_ARB, 29),
+ SYSTEM_FABRIC_ARB, 20),
MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_HALT_0,
MMSS_FABRIC_CFG_HALT, 2),
MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_CLKMOD_0,
MMSS_FABRIC_CFG_CLKMOD, 3),
MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_IOCTL,
MMSS_FABRIC_CFG_IOCTL, 1),
- MSM_RPM_MAP(8930, MM_FABRIC_ARB_0, MM_FABRIC_ARB, 23),
+ MSM_RPM_MAP(8930, MM_FABRIC_ARB_0, MM_FABRIC_ARB, 11),
MSM_RPM_MAP(8930, PM8038_S1_0, PM8038_S1, 2),
MSM_RPM_MAP(8930, PM8038_S2_0, PM8038_S2, 2),
MSM_RPM_MAP(8930, PM8038_S3_0, PM8038_S3, 2),
@@ -275,3 +281,349 @@
},
};
+static int msm8930_LPM_latency = 1000; /* >100 usec for WFI */
+
+struct platform_device msm8930_cpu_idle_device = {
+ .name = "msm_cpu_idle",
+ .id = -1,
+ .dev = {
+ .platform_data = &msm8930_LPM_latency,
+ },
+};
+
+static struct msm_dcvs_freq_entry msm8930_freq[] = {
+ { 384000, 166981, 345600},
+ { 702000, 213049, 632502},
+ {1026000, 285712, 925613},
+ {1242000, 383945, 1176550},
+ {1458000, 419729, 1465478},
+ {1512000, 434116, 1546674},
+
+};
+
+static struct msm_dcvs_core_info msm8930_core_info = {
+ .freq_tbl = &msm8930_freq[0],
+ .core_param = {
+ .max_time_us = 100000,
+ .num_freq = ARRAY_SIZE(msm8930_freq),
+ },
+ .algo_param = {
+ .slack_time_us = 58000,
+ .scale_slack_time = 0,
+ .scale_slack_time_pct = 0,
+ .disable_pc_threshold = 1458000,
+ .em_window_size = 100000,
+ .em_max_util_pct = 97,
+ .ss_window_size = 1000000,
+ .ss_util_pct = 95,
+ .ss_iobusy_conv = 100,
+ },
+};
+
+struct platform_device msm8930_msm_gov_device = {
+ .name = "msm_dcvs_gov",
+ .id = -1,
+ .dev = {
+ .platform_data = &msm8930_core_info,
+ },
+};
+
+struct platform_device msm_bus_8930_sys_fabric = {
+ .name = "msm_bus_fabric",
+ .id = MSM_BUS_FAB_SYSTEM,
+};
+struct platform_device msm_bus_8930_apps_fabric = {
+ .name = "msm_bus_fabric",
+ .id = MSM_BUS_FAB_APPSS,
+};
+struct platform_device msm_bus_8930_mm_fabric = {
+ .name = "msm_bus_fabric",
+ .id = MSM_BUS_FAB_MMSS,
+};
+struct platform_device msm_bus_8930_sys_fpb = {
+ .name = "msm_bus_fabric",
+ .id = MSM_BUS_FAB_SYSTEM_FPB,
+};
+struct platform_device msm_bus_8930_cpss_fpb = {
+ .name = "msm_bus_fabric",
+ .id = MSM_BUS_FAB_CPSS_FPB,
+};
+
+/* MSM Video core device */
+#ifdef CONFIG_MSM_BUS_SCALING
+static struct msm_bus_vectors vidc_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+static struct msm_bus_vectors vidc_venc_vga_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 54525952,
+ .ib = 436207616,
+ },
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 72351744,
+ .ib = 289406976,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 500000,
+ .ib = 1000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 500000,
+ .ib = 1000000,
+ },
+};
+static struct msm_bus_vectors vidc_vdec_vga_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 40894464,
+ .ib = 327155712,
+ },
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 48234496,
+ .ib = 192937984,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 500000,
+ .ib = 2000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 500000,
+ .ib = 2000000,
+ },
+};
+static struct msm_bus_vectors vidc_venc_720p_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 163577856,
+ .ib = 1308622848,
+ },
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 219152384,
+ .ib = 876609536,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 1750000,
+ .ib = 3500000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 1750000,
+ .ib = 3500000,
+ },
+};
+static struct msm_bus_vectors vidc_vdec_720p_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 121634816,
+ .ib = 973078528,
+ },
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 155189248,
+ .ib = 620756992,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 1750000,
+ .ib = 7000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 1750000,
+ .ib = 7000000,
+ },
+};
+static struct msm_bus_vectors vidc_venc_1080p_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 372244480,
+ .ib = 2560000000U,
+ },
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 501219328,
+ .ib = 2560000000U,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 2500000,
+ .ib = 5000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 2500000,
+ .ib = 5000000,
+ },
+};
+static struct msm_bus_vectors vidc_vdec_1080p_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 222298112,
+ .ib = 2560000000U,
+ },
+ {
+ .src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 330301440,
+ .ib = 2560000000U,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 2500000,
+ .ib = 700000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 2500000,
+ .ib = 10000000,
+ },
+};
+
+static struct msm_bus_paths vidc_bus_client_config[] = {
+ {
+ ARRAY_SIZE(vidc_init_vectors),
+ vidc_init_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_venc_vga_vectors),
+ vidc_venc_vga_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_vdec_vga_vectors),
+ vidc_vdec_vga_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_venc_720p_vectors),
+ vidc_venc_720p_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_vdec_720p_vectors),
+ vidc_vdec_720p_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_venc_1080p_vectors),
+ vidc_venc_1080p_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_vdec_1080p_vectors),
+ vidc_vdec_1080p_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata vidc_bus_client_data = {
+ vidc_bus_client_config,
+ ARRAY_SIZE(vidc_bus_client_config),
+ .name = "vidc",
+};
+#endif
+
+#define MSM_VIDC_BASE_PHYS 0x04400000
+#define MSM_VIDC_BASE_SIZE 0x00100000
+
+static struct resource apq8930_device_vidc_resources[] = {
+ {
+ .start = MSM_VIDC_BASE_PHYS,
+ .end = MSM_VIDC_BASE_PHYS + MSM_VIDC_BASE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = VCODEC_IRQ,
+ .end = VCODEC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct msm_vidc_platform_data apq8930_vidc_platform_data = {
+#ifdef CONFIG_MSM_BUS_SCALING
+ .vidc_bus_client_pdata = &vidc_bus_client_data,
+#endif
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ .memtype = ION_CP_MM_HEAP_ID,
+ .enable_ion = 1,
+#else
+ .memtype = MEMTYPE_EBI1,
+ .enable_ion = 0,
+#endif
+ .disable_dmx = 0,
+ .disable_fullhd = 0,
+};
+
+struct platform_device apq8930_msm_device_vidc = {
+ .name = "msm_vidc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(apq8930_device_vidc_resources),
+ .resource = apq8930_device_vidc_resources,
+ .dev = {
+ .platform_data = &apq8930_vidc_platform_data,
+ },
+};
+
+struct platform_device *vidc_device[] __initdata = {
+ &apq8930_msm_device_vidc
+};
+
+void __init msm8930_add_vidc_device(void)
+{
+ if (cpu_is_msm8627()) {
+ struct msm_vidc_platform_data *pdata;
+ pdata = (struct msm_vidc_platform_data *)
+ apq8930_msm_device_vidc.dev.platform_data;
+ pdata->disable_fullhd = 1;
+ }
+ platform_add_devices(vidc_device, ARRAY_SIZE(vidc_device));
+}
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index f4af677..243e0c8 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -43,6 +43,7 @@
#include "rpm_stats.h"
#include "pil-q6v4.h"
#include "scm-pas.h"
+#include <mach/msm_dcvs.h>
#ifdef CONFIG_MSM_MPM
#include "mpm.h"
@@ -3219,3 +3220,50 @@
};
#endif
+
+static int msm8960_LPM_latency = 1000; /* >100 usec for WFI */
+
+struct platform_device msm8960_cpu_idle_device = {
+ .name = "msm_cpu_idle",
+ .id = -1,
+ .dev = {
+ .platform_data = &msm8960_LPM_latency,
+ },
+};
+
+static struct msm_dcvs_freq_entry msm8960_freq[] = {
+ { 384000, 166981, 345600},
+ { 702000, 213049, 632502},
+ {1026000, 285712, 925613},
+ {1242000, 383945, 1176550},
+ {1458000, 419729, 1465478},
+ {1512000, 434116, 1546674},
+
+};
+
+static struct msm_dcvs_core_info msm8960_core_info = {
+ .freq_tbl = &msm8960_freq[0],
+ .core_param = {
+ .max_time_us = 100000,
+ .num_freq = ARRAY_SIZE(msm8960_freq),
+ },
+ .algo_param = {
+ .slack_time_us = 58000,
+ .scale_slack_time = 0,
+ .scale_slack_time_pct = 0,
+ .disable_pc_threshold = 1458000,
+ .em_window_size = 100000,
+ .em_max_util_pct = 97,
+ .ss_window_size = 1000000,
+ .ss_util_pct = 95,
+ .ss_iobusy_conv = 100,
+ },
+};
+
+struct platform_device msm8960_msm_gov_device = {
+ .name = "msm_dcvs_gov",
+ .id = -1,
+ .dev = {
+ .platform_data = &msm8960_core_info,
+ },
+};
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 331fc26..bb0d9b9 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -17,6 +17,8 @@
#include <linux/io.h>
#include <linux/platform_data/qcom_crypto_device.h>
#include <linux/dma-mapping.h>
+#include <sound/msm-dai-q6.h>
+#include <sound/apr_audio.h>
#include <asm/hardware/gic.h>
#include <asm/mach/flash.h>
#include <mach/board.h>
@@ -387,6 +389,124 @@
},
};
+struct platform_device msm_pcm = {
+ .name = "msm-pcm-dsp",
+ .id = -1,
+};
+
+struct platform_device msm_multi_ch_pcm = {
+ .name = "msm-multi-ch-pcm-dsp",
+ .id = -1,
+};
+
+struct platform_device msm_pcm_routing = {
+ .name = "msm-pcm-routing",
+ .id = -1,
+};
+
+struct platform_device msm_cpudai0 = {
+ .name = "msm-dai-q6",
+ .id = 0x4000,
+};
+
+struct platform_device msm_cpudai1 = {
+ .name = "msm-dai-q6",
+ .id = 0x4001,
+};
+
+struct platform_device msm_cpudai_bt_rx = {
+ .name = "msm-dai-q6",
+ .id = 0x3000,
+};
+
+struct platform_device msm_cpudai_bt_tx = {
+ .name = "msm-dai-q6",
+ .id = 0x3001,
+};
+
+/*
+ * Machine specific data for AUX PCM Interface
+ * which the driver will be unware of.
+ */
+struct msm_dai_auxpcm_pdata auxpcm_rx_pdata = {
+ .clk = "pcm_clk",
+ .mode = AFE_PCM_CFG_MODE_PCM,
+ .sync = AFE_PCM_CFG_SYNC_INT,
+ .frame = AFE_PCM_CFG_FRM_256BPF,
+ .quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+ .slot = 0,
+ .data = AFE_PCM_CFG_CDATAOE_MASTER,
+ .pcm_clk_rate = 2048000,
+};
+
+struct platform_device msm_cpudai_auxpcm_rx = {
+ .name = "msm-dai-q6",
+ .id = 2,
+ .dev = {
+ .platform_data = &auxpcm_rx_pdata,
+ },
+};
+
+struct platform_device msm_cpudai_auxpcm_tx = {
+ .name = "msm-dai-q6",
+ .id = 3,
+};
+
+struct platform_device msm_cpu_fe = {
+ .name = "msm-dai-fe",
+ .id = -1,
+};
+
+struct platform_device msm_stub_codec = {
+ .name = "msm-stub-codec",
+ .id = 1,
+};
+
+struct platform_device msm_voice = {
+ .name = "msm-pcm-voice",
+ .id = -1,
+};
+
+struct platform_device msm_voip = {
+ .name = "msm-voip-dsp",
+ .id = -1,
+};
+
+struct platform_device msm_compr_dsp = {
+ .name = "msm-compr-dsp",
+ .id = -1,
+};
+
+struct platform_device msm_pcm_hostless = {
+ .name = "msm-pcm-hostless",
+ .id = -1,
+};
+
+struct platform_device msm_cpudai_afe_01_rx = {
+ .name = "msm-dai-q6",
+ .id = 0xE0,
+};
+
+struct platform_device msm_cpudai_afe_01_tx = {
+ .name = "msm-dai-q6",
+ .id = 0xF0,
+};
+
+struct platform_device msm_cpudai_afe_02_rx = {
+ .name = "msm-dai-q6",
+ .id = 0xF1,
+};
+
+struct platform_device msm_cpudai_afe_02_tx = {
+ .name = "msm-dai-q6",
+ .id = 0xE1,
+};
+
+struct platform_device msm_pcm_afe = {
+ .name = "msm-pcm-afe",
+ .id = -1,
+};
+
static struct resource resources_ssbi_pmic1[] = {
{
.start = MSM_PMIC1_SSBI_CMD_PHYS,
diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c
index 057a006..96ee564 100644
--- a/arch/arm/mach-msm/devices-iommu.c
+++ b/arch/arm/mach-msm/devices-iommu.c
@@ -995,59 +995,45 @@
}
/* Initialize common devs */
- ret = platform_add_devices(msm_iommu_common_devs,
- ARRAY_SIZE(msm_iommu_common_devs));
- if (ret != 0)
- goto failure2;
+ platform_add_devices(msm_iommu_common_devs,
+ ARRAY_SIZE(msm_iommu_common_devs));
/* Initialize soc-specific devs */
- if (cpu_is_apq8064()) {
- ret = platform_add_devices(msm_iommu_8064_devs,
- ARRAY_SIZE(msm_iommu_8064_devs));
- } else {
- ret = platform_add_devices(msm_iommu_gfx2d_devs,
- ARRAY_SIZE(msm_iommu_gfx2d_devs));
+ if (cpu_is_msm8x60() || cpu_is_msm8960()) {
+ platform_add_devices(msm_iommu_jpegd_devs,
+ ARRAY_SIZE(msm_iommu_jpegd_devs));
+ platform_add_devices(msm_iommu_gfx2d_devs,
+ ARRAY_SIZE(msm_iommu_gfx2d_devs));
}
- if (ret != 0)
- goto failure2;
- if (!cpu_is_msm8930()) {
- ret = platform_add_devices(msm_iommu_jpegd_devs,
- ARRAY_SIZE(msm_iommu_jpegd_devs));
-
- if (ret != 0)
- goto failure2;
+ if (cpu_is_apq8064()) {
+ platform_add_devices(msm_iommu_jpegd_devs,
+ ARRAY_SIZE(msm_iommu_jpegd_devs));
+ platform_add_devices(msm_iommu_8064_devs,
+ ARRAY_SIZE(msm_iommu_8064_devs));
}
/* Initialize common ctx_devs */
ret = platform_add_devices(msm_iommu_common_ctx_devs,
- ARRAY_SIZE(msm_iommu_common_ctx_devs));
- if (ret != 0)
- goto failure2;
+ ARRAY_SIZE(msm_iommu_common_ctx_devs));
/* Initialize soc-specific ctx_devs */
- if (cpu_is_apq8064()) {
- ret = platform_add_devices(msm_iommu_8064_ctx_devs,
- ARRAY_SIZE(msm_iommu_8064_ctx_devs));
- } else {
- ret = platform_add_devices(msm_iommu_gfx2d_ctx_devs,
- ARRAY_SIZE(msm_iommu_gfx2d_ctx_devs));
+ if (cpu_is_msm8x60() || cpu_is_msm8960()) {
+ platform_add_devices(msm_iommu_jpegd_ctx_devs,
+ ARRAY_SIZE(msm_iommu_jpegd_ctx_devs));
+ platform_add_devices(msm_iommu_gfx2d_ctx_devs,
+ ARRAY_SIZE(msm_iommu_gfx2d_ctx_devs));
}
- if (ret != 0)
- goto failure2;
- if (!cpu_is_msm8930()) {
- ret = platform_add_devices(msm_iommu_jpegd_ctx_devs,
- ARRAY_SIZE(msm_iommu_jpegd_ctx_devs));
-
- if (ret != 0)
- goto failure2;
+ if (cpu_is_apq8064()) {
+ platform_add_devices(msm_iommu_jpegd_ctx_devs,
+ ARRAY_SIZE(msm_iommu_jpegd_ctx_devs));
+ platform_add_devices(msm_iommu_8064_ctx_devs,
+ ARRAY_SIZE(msm_iommu_8064_ctx_devs));
}
return 0;
-failure2:
- platform_device_unregister(&msm_root_iommu_dev);
failure:
return ret;
}
@@ -1060,34 +1046,34 @@
for (i = 0; i < ARRAY_SIZE(msm_iommu_common_ctx_devs); i++)
platform_device_unregister(msm_iommu_common_ctx_devs[i]);
- /* soc-specific ctx_devs. */
- if (cpu_is_apq8064()) {
- for (i = 0; i < ARRAY_SIZE(msm_iommu_8064_ctx_devs); i++)
- platform_device_unregister(msm_iommu_8064_ctx_devs[i]);
- } else {
- for (i = 0; i < ARRAY_SIZE(msm_iommu_gfx2d_ctx_devs); i++)
- platform_device_unregister(msm_iommu_gfx2d_ctx_devs[i]);
- }
-
- if (!cpu_is_msm8930()) {
- for (i = 0; i < ARRAY_SIZE(msm_iommu_jpegd_ctx_devs); i++)
- platform_device_unregister(msm_iommu_jpegd_ctx_devs[i]);
- }
-
/* Common devs. */
for (i = 0; i < ARRAY_SIZE(msm_iommu_common_devs); ++i)
platform_device_unregister(msm_iommu_common_devs[i]);
- /* soc-specific devs. */
- if (cpu_is_apq8064()) {
- for (i = 0; i < ARRAY_SIZE(msm_iommu_8064_devs); i++)
- platform_device_unregister(msm_iommu_8064_devs[i]);
- } else {
+ if (cpu_is_msm8x60() || cpu_is_msm8960()) {
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_gfx2d_ctx_devs); i++)
+ platform_device_unregister(msm_iommu_gfx2d_ctx_devs[i]);
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_jpegd_ctx_devs); i++)
+ platform_device_unregister(msm_iommu_jpegd_ctx_devs[i]);
+
for (i = 0; i < ARRAY_SIZE(msm_iommu_gfx2d_devs); i++)
platform_device_unregister(msm_iommu_gfx2d_devs[i]);
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_jpegd_devs); i++)
+ platform_device_unregister(msm_iommu_jpegd_devs[i]);
}
- if (!cpu_is_msm8930()) {
+ if (cpu_is_apq8064()) {
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_8064_ctx_devs); i++)
+ platform_device_unregister(msm_iommu_8064_ctx_devs[i]);
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_jpegd_ctx_devs); i++)
+ platform_device_unregister(msm_iommu_jpegd_ctx_devs[i]);
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_8064_devs); i++)
+ platform_device_unregister(msm_iommu_8064_devs[i]);
+
for (i = 0; i < ARRAY_SIZE(msm_iommu_jpegd_devs); i++)
platform_device_unregister(msm_iommu_jpegd_devs[i]);
}
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index aa09056..199ff85 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -330,3 +330,17 @@
extern struct platform_device msm_dsps_device_8064;
extern struct platform_device *msm_copper_stub_regulator_devices[];
extern int msm_copper_stub_regulator_devices_len;
+
+extern struct platform_device msm8960_cpu_idle_device;
+extern struct platform_device msm8930_cpu_idle_device;
+extern struct platform_device apq8064_cpu_idle_device;
+
+extern struct platform_device msm8960_msm_gov_device;
+extern struct platform_device msm8930_msm_gov_device;
+extern struct platform_device apq8064_msm_gov_device;
+
+extern struct platform_device msm_bus_8930_apps_fabric;
+extern struct platform_device msm_bus_8930_sys_fabric;
+extern struct platform_device msm_bus_8930_mm_fabric;
+extern struct platform_device msm_bus_8930_sys_fpb;
+extern struct platform_device msm_bus_8930_cpss_fpb;
diff --git a/arch/arm/mach-msm/gss-8064.c b/arch/arm/mach-msm/gss-8064.c
new file mode 100644
index 0000000..1ddb7a3
--- /dev/null
+++ b/arch/arm/mach-msm/gss-8064.c
@@ -0,0 +1,259 @@
+/* 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/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/workqueue.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+
+#include <mach/irqs.h>
+#include <mach/scm.h>
+#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
+#include <mach/subsystem_notif.h>
+#include <mach/socinfo.h>
+
+#include "smd_private.h"
+#include "modem_notifier.h"
+#include "ramdump.h"
+
+static struct gss_8064_data {
+ struct miscdevice gss_dev;
+ void *pil_handle;
+ void *gss_ramdump_dev;
+ void *smem_ramdump_dev;
+} gss_data;
+
+static int crash_shutdown;
+
+static void gss_fatal_fn(struct work_struct *work)
+{
+ uint32_t panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD;
+ uint32_t reset_smsm_states = SMSM_SYSTEM_REBOOT_USR |
+ SMSM_SYSTEM_PWRDWN_USR;
+ uint32_t gss_state;
+
+ pr_err("Watchdog bite received from GSS!\n");
+
+ gss_state = smsm_get_state(SMSM_MODEM_STATE);
+
+ if (gss_state & panic_smsm_states) {
+
+ pr_err("GSS SMSM state changed to SMSM_RESET.\n"
+ "Probable err_fatal on the GSS. "
+ "Calling subsystem restart...\n");
+ subsystem_restart("gss");
+
+ } else if (gss_state & reset_smsm_states) {
+
+ pr_err("%s: User-invoked system reset/powerdown. "
+ "Resetting the SoC now.\n",
+ __func__);
+ kernel_restart(NULL);
+ } else {
+ /* TODO: Bus unlock code/sequence goes _here_ */
+ subsystem_restart("gss");
+ }
+}
+
+static DECLARE_WORK(gss_fatal_work, gss_fatal_fn);
+
+static void smsm_state_cb(void *data, uint32_t old_state, uint32_t new_state)
+{
+ /* Ignore if we're the one that set SMSM_RESET */
+ if (crash_shutdown)
+ return;
+
+ if (new_state & SMSM_RESET) {
+ pr_err("GSS SMSM state changed to SMSM_RESET.\n"
+ "Probable err_fatal on the GSS. "
+ "Calling subsystem restart...\n");
+ subsystem_restart("gss");
+ }
+}
+
+#define Q6_FW_WDOG_ENABLE 0x08882024
+#define Q6_SW_WDOG_ENABLE 0x08982024
+static int gss_shutdown(const struct subsys_data *subsys)
+{
+ pil_force_shutdown("gss");
+ disable_irq_nosync(GSS_A5_WDOG_EXPIRED);
+
+ return 0;
+}
+
+static int gss_powerup(const struct subsys_data *subsys)
+{
+ pil_force_boot("gss");
+ enable_irq(GSS_A5_WDOG_EXPIRED);
+ return 0;
+}
+
+void gss_crash_shutdown(const struct subsys_data *subsys)
+{
+ crash_shutdown = 1;
+ smsm_reset_modem(SMSM_RESET);
+}
+
+/* FIXME: Get address, size from PIL */
+static struct ramdump_segment gss_segments[] = {
+ {0x89D00000 - 0x89000000}
+};
+
+static struct ramdump_segment smem_segments[] = {
+ {0x80000000, 0x00200000},
+};
+
+static int gss_ramdump(int enable,
+ const struct subsys_data *crashed_subsys)
+{
+ int ret = 0;
+
+ if (enable) {
+ ret = do_ramdump(gss_data.gss_ramdump_dev, gss_segments,
+ ARRAY_SIZE(gss_segments));
+
+ if (ret < 0) {
+ pr_err("Unable to dump gss memory (rc = %d).\n",
+ ret);
+ goto out;
+ }
+
+ ret = do_ramdump(gss_data.smem_ramdump_dev, smem_segments,
+ ARRAY_SIZE(smem_segments));
+
+ if (ret < 0) {
+ pr_err("Unable to dump smem memory (rc = %d).\n", ret);
+ goto out;
+ }
+ }
+
+out:
+ return ret;
+}
+
+static irqreturn_t gss_wdog_bite_irq(int irq, void *dev_id)
+{
+ schedule_work(&gss_fatal_work);
+ disable_irq_nosync(GSS_A5_WDOG_EXPIRED);
+
+ return IRQ_HANDLED;
+}
+
+static struct subsys_data gss_8064 = {
+ .name = "gss",
+ .shutdown = gss_shutdown,
+ .powerup = gss_powerup,
+ .ramdump = gss_ramdump,
+ .crash_shutdown = gss_crash_shutdown
+};
+
+static int gss_subsystem_restart_init(void)
+{
+ return ssr_register_subsystem(&gss_8064);
+}
+
+static int gss_open(struct inode *inode, struct file *filep)
+{
+ void *ret;
+ gss_data.pil_handle = ret = pil_get("gss");
+ if (!ret)
+ pr_debug("%s - pil_get returned NULL\n", __func__);
+ return 0;
+}
+
+static int gss_release(struct inode *inode, struct file *filep)
+{
+ pil_put(gss_data.pil_handle);
+ pr_debug("%s pil_put called on GSS\n", __func__);
+ return 0;
+}
+
+const struct file_operations gss_file_ops = {
+ .open = gss_open,
+ .release = gss_release,
+};
+
+static int __init gss_8064_init(void)
+{
+ int ret;
+
+ if (!cpu_is_apq8064())
+ return -ENODEV;
+
+ ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
+ smsm_state_cb, 0);
+
+ if (ret < 0)
+ pr_err("%s: Unable to register SMSM callback! (%d)\n",
+ __func__, ret);
+
+ ret = request_irq(GSS_A5_WDOG_EXPIRED, gss_wdog_bite_irq,
+ IRQF_TRIGGER_RISING, "gss_a5_wdog", NULL);
+
+ if (ret < 0) {
+ pr_err("%s: Unable to request gss watchdog IRQ. (%d)\n",
+ __func__, ret);
+ disable_irq_nosync(GSS_A5_WDOG_EXPIRED);
+ goto out;
+ }
+
+ ret = gss_subsystem_restart_init();
+
+ if (ret < 0) {
+ pr_err("%s: Unable to reg with subsystem restart. (%d)\n",
+ __func__, ret);
+ goto out;
+ }
+
+ gss_data.gss_dev.minor = MISC_DYNAMIC_MINOR;
+ gss_data.gss_dev.name = "gss";
+ gss_data.gss_dev.fops = &gss_file_ops;
+ ret = misc_register(&gss_data.gss_dev);
+
+ if (ret) {
+ pr_err("%s: misc_registers failed for %s (%d)", __func__,
+ gss_data.gss_dev.name, ret);
+ goto out;
+ }
+
+ gss_data.gss_ramdump_dev = create_ramdump_device("gss");
+
+ if (!gss_data.gss_ramdump_dev) {
+ pr_err("%s: Unable to create gss ramdump device. (%d)\n",
+ __func__, -ENOMEM);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ gss_data.smem_ramdump_dev = create_ramdump_device("smem");
+
+ if (!gss_data.smem_ramdump_dev) {
+ pr_err("%s: Unable to create smem ramdump device. (%d)\n",
+ __func__, -ENOMEM);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ pr_info("%s: gss fatal driver init'ed.\n", __func__);
+out:
+ return ret;
+}
+
+module_init(gss_8064_init);
diff --git a/arch/arm/mach-msm/include/mach/irqs-9615.h b/arch/arm/mach-msm/include/mach/irqs-9615.h
index cd8f2a3..6252cef 100644
--- a/arch/arm/mach-msm/include/mach/irqs-9615.h
+++ b/arch/arm/mach-msm/include/mach/irqs-9615.h
@@ -185,7 +185,9 @@
#define NR_MSM_IRQS 288
#define NR_GPIO_IRQS 88
#define NR_PM8018_IRQS 256
-#define NR_BOARD_IRQS NR_PM8018_IRQS
+#define NR_WCD9XXX_IRQS 49
+#define NR_TABLA_IRQS NR_WCD9XXX_IRQS
+#define NR_BOARD_IRQS (NR_PM8018_IRQS + NR_WCD9XXX_IRQS)
#define NR_TLMM_MSM_DIR_CONN_IRQ 8 /*Need to Verify this Count*/
#define NR_MSM_GPIOS NR_GPIO_IRQS
diff --git a/arch/arm/mach-msm/include/mach/msm_bus_board.h b/arch/arm/mach-msm/include/mach/msm_bus_board.h
index fd61c98..f62bc86 100644
--- a/arch/arm/mach-msm/include/mach/msm_bus_board.h
+++ b/arch/arm/mach-msm/include/mach/msm_bus_board.h
@@ -72,6 +72,13 @@
extern struct msm_bus_fabric_registration msm_bus_9615_sys_fabric_pdata;
extern struct msm_bus_fabric_registration msm_bus_9615_def_fab_pdata;
+
+extern struct msm_bus_fabric_registration msm_bus_8930_apps_fabric_pdata;
+extern struct msm_bus_fabric_registration msm_bus_8930_sys_fabric_pdata;
+extern struct msm_bus_fabric_registration msm_bus_8930_mm_fabric_pdata;
+extern struct msm_bus_fabric_registration msm_bus_8930_sys_fpb_pdata;
+extern struct msm_bus_fabric_registration msm_bus_8930_cpss_fpb_pdata;
+
void msm_bus_rpm_set_mt_mask(void);
int msm_bus_board_rpm_get_il_ids(uint16_t *id);
int msm_bus_board_get_iid(int id);
diff --git a/arch/arm/mach-msm/include/mach/rpm-8930.h b/arch/arm/mach-msm/include/mach/rpm-8930.h
index 3bcd42e..0211b67 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8930.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8930.h
@@ -141,106 +141,106 @@
MSM_RPM_8930_ID_APPS_FABRIC_CFG_CLKMOD_2 = 39,
MSM_RPM_8930_ID_APPS_FABRIC_CFG_IOCTL = 40,
MSM_RPM_8930_ID_APPS_FABRIC_ARB_0 = 41,
- MSM_RPM_8930_ID_APPS_FABRIC_ARB_11 =
- MSM_RPM_8930_ID_APPS_FABRIC_ARB_0 + 11,
- MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_0 = 53,
- MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_1 = 54,
- MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_0 = 55,
- MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_1 = 56,
- MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_2 = 57,
- MSM_RPM_8930_ID_SYS_FABRIC_CFG_IOCTL = 58,
- MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0 = 59,
- MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_28 =
- MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0 + 28,
- MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_0 = 88,
- MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_1 = 89,
- MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_0 = 90,
- MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_1 = 91,
- MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_2 = 92,
- MSM_RPM_8930_ID_MMSS_FABRIC_CFG_IOCTL = 93,
- MSM_RPM_8930_ID_MM_FABRIC_ARB_0 = 94,
- MSM_RPM_8930_ID_MM_FABRIC_ARB_22 =
- MSM_RPM_8930_ID_MM_FABRIC_ARB_0 + 22,
+ MSM_RPM_8930_ID_APPS_FABRIC_ARB_5 =
+ MSM_RPM_8930_ID_APPS_FABRIC_ARB_0 + 5,
+ MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_0 = 47,
+ MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_1 = 48,
+ MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_0 = 49,
+ MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_1 = 50,
+ MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_2 = 51,
+ MSM_RPM_8930_ID_SYS_FABRIC_CFG_IOCTL = 52,
+ MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0 = 53,
+ MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_19 =
+ MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0 + 19,
+ MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_0 = 73,
+ MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_1 = 74,
+ MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_0 = 75,
+ MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_1 = 76,
+ MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_2 = 77,
+ MSM_RPM_8930_ID_MMSS_FABRIC_CFG_IOCTL = 78,
+ MSM_RPM_8930_ID_MM_FABRIC_ARB_0 = 79,
+ MSM_RPM_8930_ID_MM_FABRIC_ARB_10 =
+ MSM_RPM_8930_ID_MM_FABRIC_ARB_0 + 10,
- MSM_RPM_8930_ID_PM8038_S1_0 = 117,
- MSM_RPM_8930_ID_PM8038_S1_1 = 118,
- MSM_RPM_8930_ID_PM8038_S2_0 = 119,
- MSM_RPM_8930_ID_PM8038_S2_1 = 120,
- MSM_RPM_8930_ID_PM8038_S3_0 = 121,
- MSM_RPM_8930_ID_PM8038_S3_1 = 122,
- MSM_RPM_8930_ID_PM8038_S4_0 = 123,
- MSM_RPM_8930_ID_PM8038_S4_1 = 124,
- MSM_RPM_8930_ID_PM8038_S5_0 = 125,
- MSM_RPM_8930_ID_PM8038_S5_1 = 126,
- MSM_RPM_8930_ID_PM8038_S6_0 = 127,
- MSM_RPM_8930_ID_PM8038_S6_1 = 128,
- MSM_RPM_8930_ID_PM8038_L1_0 = 129,
- MSM_RPM_8930_ID_PM8038_L1_1 = 130,
- MSM_RPM_8930_ID_PM8038_L2_0 = 131,
- MSM_RPM_8930_ID_PM8038_L2_1 = 132,
- MSM_RPM_8930_ID_PM8038_L3_0 = 133,
- MSM_RPM_8930_ID_PM8038_L3_1 = 134,
- MSM_RPM_8930_ID_PM8038_L4_0 = 135,
- MSM_RPM_8930_ID_PM8038_L4_1 = 136,
- MSM_RPM_8930_ID_PM8038_L5_0 = 137,
- MSM_RPM_8930_ID_PM8038_L5_1 = 138,
- MSM_RPM_8930_ID_PM8038_L6_0 = 139,
- MSM_RPM_8930_ID_PM8038_L6_1 = 140,
- MSM_RPM_8930_ID_PM8038_L7_0 = 141,
- MSM_RPM_8930_ID_PM8038_L7_1 = 142,
- MSM_RPM_8930_ID_PM8038_L8_0 = 143,
- MSM_RPM_8930_ID_PM8038_L8_1 = 144,
- MSM_RPM_8930_ID_PM8038_L9_0 = 145,
- MSM_RPM_8930_ID_PM8038_L9_1 = 146,
- MSM_RPM_8930_ID_PM8038_L10_0 = 147,
- MSM_RPM_8930_ID_PM8038_L10_1 = 148,
- MSM_RPM_8930_ID_PM8038_L11_0 = 149,
- MSM_RPM_8930_ID_PM8038_L11_1 = 150,
- MSM_RPM_8930_ID_PM8038_L12_0 = 151,
- MSM_RPM_8930_ID_PM8038_L12_1 = 152,
- MSM_RPM_8930_ID_PM8038_L13_0 = 153,
- MSM_RPM_8930_ID_PM8038_L13_1 = 154,
- MSM_RPM_8930_ID_PM8038_L14_0 = 155,
- MSM_RPM_8930_ID_PM8038_L14_1 = 156,
- MSM_RPM_8930_ID_PM8038_L15_0 = 157,
- MSM_RPM_8930_ID_PM8038_L15_1 = 158,
- MSM_RPM_8930_ID_PM8038_L16_0 = 159,
- MSM_RPM_8930_ID_PM8038_L16_1 = 160,
- MSM_RPM_8930_ID_PM8038_L17_0 = 161,
- MSM_RPM_8930_ID_PM8038_L17_1 = 162,
- MSM_RPM_8930_ID_PM8038_L18_0 = 163,
- MSM_RPM_8930_ID_PM8038_L18_1 = 164,
- MSM_RPM_8930_ID_PM8038_L19_0 = 165,
- MSM_RPM_8930_ID_PM8038_L19_1 = 166,
- MSM_RPM_8930_ID_PM8038_L20_0 = 167,
- MSM_RPM_8930_ID_PM8038_L20_1 = 168,
- MSM_RPM_8930_ID_PM8038_L21_0 = 169,
- MSM_RPM_8930_ID_PM8038_L21_1 = 170,
- MSM_RPM_8930_ID_PM8038_L22_0 = 171,
- MSM_RPM_8930_ID_PM8038_L22_1 = 172,
- MSM_RPM_8930_ID_PM8038_L23_0 = 173,
- MSM_RPM_8930_ID_PM8038_L23_1 = 174,
- MSM_RPM_8930_ID_PM8038_L24_0 = 175,
- MSM_RPM_8930_ID_PM8038_L24_1 = 176,
- MSM_RPM_8930_ID_PM8038_L25_0 = 177,
- MSM_RPM_8930_ID_PM8038_L25_1 = 178,
- MSM_RPM_8930_ID_PM8038_L26_0 = 179,
- MSM_RPM_8930_ID_PM8038_L26_1 = 180,
- MSM_RPM_8930_ID_PM8038_L27_0 = 181,
- MSM_RPM_8930_ID_PM8038_L27_1 = 182,
- MSM_RPM_8930_ID_PM8038_CLK1_0 = 183,
- MSM_RPM_8930_ID_PM8038_CLK1_1 = 184,
- MSM_RPM_8930_ID_PM8038_CLK2_0 = 185,
- MSM_RPM_8930_ID_PM8038_CLK2_1 = 186,
- MSM_RPM_8930_ID_PM8038_LVS1 = 187,
- MSM_RPM_8930_ID_PM8038_LVS2 = 188,
- MSM_RPM_8930_ID_NCP_0 = 189,
- MSM_RPM_8930_ID_NCP_1 = 190,
- MSM_RPM_8930_ID_CXO_BUFFERS = 191,
- MSM_RPM_8930_ID_USB_OTG_SWITCH = 192,
- MSM_RPM_8930_ID_HDMI_SWITCH = 193,
- MSM_RPM_8930_ID_QDSS_CLK = 194,
- MSM_RPM_8930_ID_VOLTAGE_CORNER = 195,
+ MSM_RPM_8930_ID_PM8038_S1_0 = 90,
+ MSM_RPM_8930_ID_PM8038_S1_1 = 91,
+ MSM_RPM_8930_ID_PM8038_S2_0 = 92,
+ MSM_RPM_8930_ID_PM8038_S2_1 = 93,
+ MSM_RPM_8930_ID_PM8038_S3_0 = 94,
+ MSM_RPM_8930_ID_PM8038_S3_1 = 95,
+ MSM_RPM_8930_ID_PM8038_S4_0 = 96,
+ MSM_RPM_8930_ID_PM8038_S4_1 = 97,
+ MSM_RPM_8930_ID_PM8038_S5_0 = 98,
+ MSM_RPM_8930_ID_PM8038_S5_1 = 99,
+ MSM_RPM_8930_ID_PM8038_S6_0 = 100,
+ MSM_RPM_8930_ID_PM8038_S6_1 = 101,
+ MSM_RPM_8930_ID_PM8038_L1_0 = 102,
+ MSM_RPM_8930_ID_PM8038_L1_1 = 103,
+ MSM_RPM_8930_ID_PM8038_L2_0 = 104,
+ MSM_RPM_8930_ID_PM8038_L2_1 = 105,
+ MSM_RPM_8930_ID_PM8038_L3_0 = 106,
+ MSM_RPM_8930_ID_PM8038_L3_1 = 107,
+ MSM_RPM_8930_ID_PM8038_L4_0 = 108,
+ MSM_RPM_8930_ID_PM8038_L4_1 = 109,
+ MSM_RPM_8930_ID_PM8038_L5_0 = 110,
+ MSM_RPM_8930_ID_PM8038_L5_1 = 111,
+ MSM_RPM_8930_ID_PM8038_L6_0 = 112,
+ MSM_RPM_8930_ID_PM8038_L6_1 = 113,
+ MSM_RPM_8930_ID_PM8038_L7_0 = 114,
+ MSM_RPM_8930_ID_PM8038_L7_1 = 115,
+ MSM_RPM_8930_ID_PM8038_L8_0 = 116,
+ MSM_RPM_8930_ID_PM8038_L8_1 = 117,
+ MSM_RPM_8930_ID_PM8038_L9_0 = 118,
+ MSM_RPM_8930_ID_PM8038_L9_1 = 119,
+ MSM_RPM_8930_ID_PM8038_L10_0 = 120,
+ MSM_RPM_8930_ID_PM8038_L10_1 = 121,
+ MSM_RPM_8930_ID_PM8038_L11_0 = 122,
+ MSM_RPM_8930_ID_PM8038_L11_1 = 123,
+ MSM_RPM_8930_ID_PM8038_L12_0 = 124,
+ MSM_RPM_8930_ID_PM8038_L12_1 = 125,
+ MSM_RPM_8930_ID_PM8038_L13_0 = 126,
+ MSM_RPM_8930_ID_PM8038_L13_1 = 127,
+ MSM_RPM_8930_ID_PM8038_L14_0 = 128,
+ MSM_RPM_8930_ID_PM8038_L14_1 = 129,
+ MSM_RPM_8930_ID_PM8038_L15_0 = 130,
+ MSM_RPM_8930_ID_PM8038_L15_1 = 131,
+ MSM_RPM_8930_ID_PM8038_L16_0 = 132,
+ MSM_RPM_8930_ID_PM8038_L16_1 = 133,
+ MSM_RPM_8930_ID_PM8038_L17_0 = 134,
+ MSM_RPM_8930_ID_PM8038_L17_1 = 135,
+ MSM_RPM_8930_ID_PM8038_L18_0 = 136,
+ MSM_RPM_8930_ID_PM8038_L18_1 = 137,
+ MSM_RPM_8930_ID_PM8038_L19_0 = 138,
+ MSM_RPM_8930_ID_PM8038_L19_1 = 139,
+ MSM_RPM_8930_ID_PM8038_L20_0 = 140,
+ MSM_RPM_8930_ID_PM8038_L20_1 = 141,
+ MSM_RPM_8930_ID_PM8038_L21_0 = 142,
+ MSM_RPM_8930_ID_PM8038_L21_1 = 143,
+ MSM_RPM_8930_ID_PM8038_L22_0 = 144,
+ MSM_RPM_8930_ID_PM8038_L22_1 = 145,
+ MSM_RPM_8930_ID_PM8038_L23_0 = 146,
+ MSM_RPM_8930_ID_PM8038_L23_1 = 147,
+ MSM_RPM_8930_ID_PM8038_L24_0 = 148,
+ MSM_RPM_8930_ID_PM8038_L24_1 = 149,
+ MSM_RPM_8930_ID_PM8038_L25_0 = 150,
+ MSM_RPM_8930_ID_PM8038_L25_1 = 151,
+ MSM_RPM_8930_ID_PM8038_L26_0 = 152,
+ MSM_RPM_8930_ID_PM8038_L26_1 = 153,
+ MSM_RPM_8930_ID_PM8038_L27_0 = 154,
+ MSM_RPM_8930_ID_PM8038_L27_1 = 155,
+ MSM_RPM_8930_ID_PM8038_CLK1_0 = 156,
+ MSM_RPM_8930_ID_PM8038_CLK1_1 = 157,
+ MSM_RPM_8930_ID_PM8038_CLK2_0 = 158,
+ MSM_RPM_8930_ID_PM8038_CLK2_1 = 159,
+ MSM_RPM_8930_ID_PM8038_LVS1 = 160,
+ MSM_RPM_8930_ID_PM8038_LVS2 = 161,
+ MSM_RPM_8930_ID_NCP_0 = 162,
+ MSM_RPM_8930_ID_NCP_1 = 163,
+ MSM_RPM_8930_ID_CXO_BUFFERS = 164,
+ MSM_RPM_8930_ID_USB_OTG_SWITCH = 165,
+ MSM_RPM_8930_ID_HDMI_SWITCH = 166,
+ MSM_RPM_8930_ID_QDSS_CLK = 167,
+ MSM_RPM_8930_ID_VOLTAGE_CORNER = 168,
MSM_RPM_8930_ID_LAST = MSM_RPM_8930_ID_VOLTAGE_CORNER,
};
diff --git a/arch/arm/mach-msm/include/mach/scm.h b/arch/arm/mach-msm/include/mach/scm.h
index af4691a..7cc5f7a 100644
--- a/arch/arm/mach-msm/include/mach/scm.h
+++ b/arch/arm/mach-msm/include/mach/scm.h
@@ -38,6 +38,7 @@
extern u32 scm_get_version(void);
extern int scm_is_call_available(u32 svc_id, u32 cmd_id);
+extern int scm_get_feat_version(u32 feat);
#else
@@ -73,5 +74,10 @@
return 0;
}
+static inline int scm_get_feat_version(u32 feat)
+{
+ return 0;
+}
+
#endif
#endif
diff --git a/arch/arm/mach-msm/include/mach/timex.h b/arch/arm/mach-msm/include/mach/timex.h
index ca7c4c7..542aba3 100644
--- a/arch/arm/mach-msm/include/mach/timex.h
+++ b/arch/arm/mach-msm/include/mach/timex.h
@@ -18,6 +18,8 @@
#define CLOCK_TICK_RATE 1000000
+#ifdef CONFIG_HAVE_ARCH_HAS_CURRENT_TIMER
#define ARCH_HAS_READ_CURRENT_TIMER
+#endif
#endif
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index 853888a..a310ba0 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -685,6 +685,19 @@
return ret;
}
+static unsigned int get_phys_addr(struct scatterlist *sg)
+{
+ /*
+ * Try sg_dma_address first so that we can
+ * map carveout regions that do not have a
+ * struct page associated with them.
+ */
+ unsigned int pa = sg_dma_address(sg);
+ if (pa == 0)
+ pa = sg_phys(sg);
+ return pa;
+}
+
static int msm_iommu_map_range(struct iommu_domain *domain, unsigned int va,
struct scatterlist *sg, unsigned int len,
int prot)
@@ -722,7 +735,12 @@
sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
sl_offset = SL_OFFSET(va);
- chunk_pa = sg_phys(sg);
+ chunk_pa = get_phys_addr(sg);
+ if (chunk_pa == 0) {
+ pr_debug("No dma address for sg %p\n", sg);
+ ret = -EINVAL;
+ goto fail;
+ }
while (offset < len) {
/* Set up a 2nd level page table if one doesn't exist */
@@ -764,7 +782,13 @@
if (chunk_offset >= sg->length && offset < len) {
chunk_offset = 0;
sg = sg_next(sg);
- chunk_pa = sg_phys(sg);
+ chunk_pa = get_phys_addr(sg);
+ if (chunk_pa == 0) {
+ pr_debug("No dma address for sg %p\n",
+ sg);
+ ret = -EINVAL;
+ goto fail;
+ }
}
}
diff --git a/arch/arm/mach-msm/jtag.c b/arch/arm/mach-msm/jtag.c
index a2ec89b..b35ca34 100644
--- a/arch/arm/mach-msm/jtag.c
+++ b/arch/arm/mach-msm/jtag.c
@@ -18,6 +18,7 @@
#include <linux/smp.h>
#include <linux/printk.h>
#include <linux/ratelimit.h>
+#include <mach/scm.h>
#include "qdss.h"
#include "cp14.h"
@@ -31,6 +32,8 @@
#define DBGDSCR_MASK (0x6C30FC3C)
#define CPMR_ETMCLKEN (0x8)
+#define TZ_DBG_ETM_FEAT_ID (0x8)
+#define TZ_DBG_ETM_VER (0x400000)
uint32_t msm_jtag_save_cntr[NR_CPUS];
@@ -38,7 +41,7 @@
struct dbg_ctx {
uint8_t arch;
- bool arch_supported;
+ bool save_restore_enabled;
uint8_t nr_wp;
uint8_t nr_bp;
uint8_t nr_ctx_cmp;
@@ -48,7 +51,7 @@
struct etm_ctx {
uint8_t arch;
- bool arch_supported;
+ bool save_restore_enabled;
uint8_t nr_addr_cmp;
uint8_t nr_cntr;
uint8_t nr_ext_inp;
@@ -1022,9 +1025,9 @@
/* ensure counter is updated before moving forward */
mb();
- if (dbg.arch_supported)
+ if (dbg.save_restore_enabled)
dbg_save_state(cpu);
- if (etm.arch_supported)
+ if (etm.save_restore_enabled)
etm_save_state(cpu);
}
@@ -1038,9 +1041,9 @@
/* ensure counter is updated before moving forward */
mb();
- if (dbg.arch_supported)
+ if (dbg.save_restore_enabled)
dbg_restore_state(cpu);
- if (etm.arch_supported)
+ if (etm.save_restore_enabled)
etm_restore_state(cpu);
}
@@ -1052,17 +1055,25 @@
/* This will run on core0 so use it to populate parameters */
/* Populate dbg_ctx data */
+
dbgdidr = dbg_read(DBGDIDR);
dbg.arch = BMVAL(dbgdidr, 16, 19);
- dbg.arch_supported = dbg_arch_supported(dbg.arch);
- if (!dbg.arch_supported) {
- pr_info("dbg arch %u not supported\n", dbg.arch);
- goto dbg_out;
- }
dbg.nr_ctx_cmp = BMVAL(dbgdidr, 20, 23) + 1;
dbg.nr_bp = BMVAL(dbgdidr, 24, 27) + 1;
dbg.nr_wp = BMVAL(dbgdidr, 28, 31) + 1;
+ if (dbg_arch_supported(dbg.arch)) {
+ if (scm_get_feat_version(TZ_DBG_ETM_FEAT_ID) < TZ_DBG_ETM_VER) {
+ dbg.save_restore_enabled = true;
+ } else {
+ pr_info("dbg save-restore supported by TZ\n");
+ goto dbg_out;
+ }
+ } else {
+ pr_info("dbg arch %u not supported\n", dbg.arch);
+ goto dbg_out;
+ }
+
/* Allocate dbg state save space */
dbg.state = kzalloc(MAX_DBG_STATE_SIZE * sizeof(uint32_t), GFP_KERNEL);
if (!dbg.state) {
@@ -1090,13 +1101,10 @@
isb();
/* Populate etm_ctx data */
+
etmidr = etm_read(ETMIDR);
etm.arch = BMVAL(etmidr, 4, 11);
- etm.arch_supported = etm_arch_supported(etm.arch);
- if (!etm.arch_supported) {
- pr_info("etm arch %u not supported\n", etm.arch);
- goto etm_out;
- }
+
etmccr = etm_read(ETMCCR);
etm.nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
etm.nr_cntr = BMVAL(etmccr, 13, 15);
@@ -1104,6 +1112,18 @@
etm.nr_ext_out = BMVAL(etmccr, 20, 22);
etm.nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
+ if (etm_arch_supported(etm.arch)) {
+ if (scm_get_feat_version(TZ_DBG_ETM_FEAT_ID) < TZ_DBG_ETM_VER) {
+ etm.save_restore_enabled = true;
+ } else {
+ pr_info("etm save-restore supported by TZ\n");
+ goto etm_out;
+ }
+ } else {
+ pr_info("etm arch %u not supported\n", etm.arch);
+ goto etm_out;
+ }
+
/* Vote for ETM power/clock disable */
etm_clk_disable();
@@ -1114,6 +1134,7 @@
goto etm_err;
}
etm_out:
+ etm_clk_disable();
return 0;
etm_err:
return ret;
diff --git a/arch/arm/mach-msm/lpass-8960.c b/arch/arm/mach-msm/lpass-8960.c
index 5eccf06..7775740 100644
--- a/arch/arm/mach-msm/lpass-8960.c
+++ b/arch/arm/mach-msm/lpass-8960.c
@@ -31,12 +31,10 @@
#define SCM_Q6_NMI_CMD 0x1
#define MODULE_NAME "lpass_8960"
-#define Q6SS_SOFT_INTR_WAKEUP 0x28800024
/* Subsystem restart: QDSP6 data, functions */
static void lpass_fatal_fn(struct work_struct *);
static DECLARE_WORK(lpass_fatal_work, lpass_fatal_fn);
-void __iomem *q6_wakeup_intr;
struct lpass_ssr {
void *lpass_ramdump_dev;
} lpass_ssr;
@@ -118,11 +116,6 @@
scm_call(SCM_SVC_UTIL, SCM_Q6_NMI_CMD,
&cmd, sizeof(cmd), NULL, 0);
- /* Wakeup the Q6 */
- if (q6_wakeup_intr)
- writel_relaxed(0x01, q6_wakeup_intr);
- mb();
-
/* Q6 requires worstcase 100ms to dump caches etc.*/
mdelay(100);
pr_debug("%s: Q6 NMI was sent.\n", __func__);
@@ -212,9 +205,6 @@
__func__, ret);
goto out;
}
- q6_wakeup_intr = ioremap_nocache(Q6SS_SOFT_INTR_WAKEUP, 8);
- if (!q6_wakeup_intr)
- pr_err("%s: Unable to request q6 wakeup interrupt\n", __func__);
lpass_ssr_8960.lpass_ramdump_dev = create_ramdump_device("lpass");
@@ -230,7 +220,6 @@
ret = PTR_ERR(ssr_notif_hdle);
pr_err("%s: subsys_register_notifier for Riva: err = %d\n",
__func__, ret);
- iounmap(q6_wakeup_intr);
free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
goto out;
}
@@ -242,7 +231,6 @@
pr_err("%s: subsys_register_notifier for Modem: err = %d\n",
__func__, ret);
subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
- iounmap(q6_wakeup_intr);
free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
goto out;
}
@@ -256,7 +244,6 @@
{
subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
subsys_notif_unregister_notifier(ssr_modem_notif_hdle, &mnb);
- iounmap(q6_wakeup_intr);
free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
}
diff --git a/arch/arm/mach-msm/msm_dcvs_idle.c b/arch/arm/mach-msm/msm_dcvs_idle.c
new file mode 100644
index 0000000..59f2742
--- /dev/null
+++ b/arch/arm/mach-msm/msm_dcvs_idle.c
@@ -0,0 +1,170 @@
+/* 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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/cpu_pm.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos_params.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+#include <mach/msm_dcvs.h>
+
+struct cpu_idle_info {
+ int cpu;
+ int enabled;
+ int handle;
+ struct msm_dcvs_idle dcvs_notifier;
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct cpu_idle_info, cpu_idle_info);
+static DEFINE_PER_CPU_SHARED_ALIGNED(u64, iowait_on_cpu);
+static char core_name[NR_CPUS][10];
+static struct pm_qos_request_list qos_req;
+static uint32_t latency;
+
+static int msm_dcvs_idle_notifier(struct msm_dcvs_idle *self,
+ enum msm_core_control_event event)
+{
+ struct cpu_idle_info *info = container_of(self,
+ struct cpu_idle_info, dcvs_notifier);
+
+ switch (event) {
+ case MSM_DCVS_ENABLE_IDLE_PULSE:
+ info->enabled = true;
+ break;
+
+ case MSM_DCVS_DISABLE_IDLE_PULSE:
+ info->enabled = false;
+ break;
+
+ case MSM_DCVS_ENABLE_HIGH_LATENCY_MODES:
+ pm_qos_update_request(&qos_req, PM_QOS_DEFAULT_VALUE);
+ break;
+
+ case MSM_DCVS_DISABLE_HIGH_LATENCY_MODES:
+ pm_qos_update_request(&qos_req, latency);
+ break;
+ }
+
+ return 0;
+}
+
+static int msm_cpuidle_notifier(struct notifier_block *self, unsigned long cmd,
+ void *v)
+{
+ struct cpu_idle_info *info =
+ &per_cpu(cpu_idle_info, smp_processor_id());
+ u64 io_wait_us = 0;
+ u64 prev_io_wait_us = 0;
+ u64 last_update_time = 0;
+ u64 val = 0;
+ uint32_t iowaited = 0;
+
+ if (!info->enabled)
+ return NOTIFY_OK;
+
+ switch (cmd) {
+ case CPU_PM_ENTER:
+ val = get_cpu_iowait_time_us(smp_processor_id(),
+ &last_update_time);
+ /* val could be -1 when NOHZ is not enabled */
+ if (val == (u64)-1)
+ val = 0;
+ per_cpu(iowait_on_cpu, smp_processor_id()) = val;
+ msm_dcvs_idle(info->handle, MSM_DCVS_IDLE_ENTER, 0);
+ break;
+
+ case CPU_PM_ENTER_FAILED:
+ case CPU_PM_EXIT:
+ prev_io_wait_us = per_cpu(iowait_on_cpu, smp_processor_id());
+ val = get_cpu_iowait_time_us(smp_processor_id(),
+ &last_update_time);
+ if (val == (u64)-1)
+ val = 0;
+ io_wait_us = val;
+ iowaited = (io_wait_us - prev_io_wait_us);
+ msm_dcvs_idle(info->handle, MSM_DCVS_IDLE_EXIT, iowaited);
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block idle_nb = {
+ .notifier_call = msm_cpuidle_notifier,
+};
+
+static int msm_dcvs_idle_probe(struct platform_device *pdev)
+{
+ int cpu;
+ struct cpu_idle_info *info = NULL;
+ struct msm_dcvs_idle *inotify = NULL;
+
+ for_each_possible_cpu(cpu) {
+ info = &per_cpu(cpu_idle_info, cpu);
+ info->cpu = cpu;
+ inotify = &info->dcvs_notifier;
+ snprintf(core_name[cpu], 10, "cpu%d", cpu);
+ inotify->core_name = core_name[cpu];
+ inotify->enable = msm_dcvs_idle_notifier;
+ info->handle = msm_dcvs_idle_source_register(inotify);
+ BUG_ON(info->handle < 0);
+ }
+
+ latency = *((uint32_t *)pdev->dev.platform_data);
+ pm_qos_add_request(&qos_req, PM_QOS_CPU_DMA_LATENCY,
+ PM_QOS_DEFAULT_VALUE);
+
+ return cpu_pm_register_notifier(&idle_nb);
+}
+
+static int msm_dcvs_idle_remove(struct platform_device *pdev)
+{
+ int ret = 0;
+ int rc = 0;
+ int cpu = 0;
+ struct msm_dcvs_idle *inotify = NULL;
+ struct cpu_idle_info *info = NULL;
+
+ rc = cpu_pm_unregister_notifier(&idle_nb);
+
+ for_each_possible_cpu(cpu) {
+ info = &per_cpu(cpu_idle_info, cpu);
+ inotify = &info->dcvs_notifier;
+ ret = msm_dcvs_idle_source_unregister(inotify);
+ if (ret) {
+ rc = -EFAULT;
+ pr_err("Error de-registering core %d idle notifier.\n",
+ cpu);
+ }
+ }
+
+ return rc;
+}
+
+static struct platform_driver idle_pdrv = {
+ .probe = msm_dcvs_idle_probe,
+ .remove = __devexit_p(msm_dcvs_idle_remove),
+ .driver = {
+ .name = "msm_cpu_idle",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int msm_dcvs_idle_init(void)
+{
+ return platform_driver_register(&idle_pdrv);
+}
+late_initcall(msm_dcvs_idle_init);
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index 28b5995..994dca6 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -47,6 +47,7 @@
static unsigned long delay_time;
static unsigned long bark_time;
static unsigned long long last_pet;
+static bool has_vic;
/*
* On the kernel command line specify
@@ -161,9 +162,14 @@
if (!old_val) {
__raw_writel(0, msm_tmr0_base + WDT0_EN);
mb();
- disable_percpu_irq(WDT0_ACCSCSSNBARK_INT);
- free_percpu_irq(WDT0_ACCSCSSNBARK_INT, percpu_pdata);
- free_percpu(percpu_pdata);
+ if (has_vic) {
+ free_irq(WDT0_ACCSCSSNBARK_INT, 0);
+ } else {
+ disable_percpu_irq(WDT0_ACCSCSSNBARK_INT);
+ free_percpu_irq(WDT0_ACCSCSSNBARK_INT,
+ percpu_pdata);
+ free_percpu(percpu_pdata);
+ }
enable = 0;
atomic_notifier_chain_unregister(&panic_notifier_list,
&panic_blk);
@@ -221,9 +227,13 @@
if (enable) {
__raw_writel(0, msm_tmr0_base + WDT0_EN);
mb();
- disable_percpu_irq(WDT0_ACCSCSSNBARK_INT);
- free_percpu_irq(WDT0_ACCSCSSNBARK_INT, percpu_pdata);
- free_percpu(percpu_pdata);
+ if (has_vic) {
+ free_irq(WDT0_ACCSCSSNBARK_INT, 0);
+ } else {
+ disable_percpu_irq(WDT0_ACCSCSSNBARK_INT);
+ free_percpu_irq(WDT0_ACCSCSSNBARK_INT, percpu_pdata);
+ free_percpu(percpu_pdata);
+ }
enable = 0;
/* In case we got suspended mid-exit */
__raw_writel(0, msm_tmr0_base + WDT0_EN);
@@ -338,26 +348,34 @@
appsbark = 1;
bark_time = pdata->bark_time;
+ has_vic = pdata->has_vic;
msm_tmr0_base = msm_timer_get_timer0_base();
- percpu_pdata = alloc_percpu(struct msm_watchdog_pdata *);
- if (!percpu_pdata) {
- pr_err("%s: memory allocation failed for percpu data\n",
- __func__);
- return -ENOMEM;
- }
+ if (has_vic) {
+ ret = request_irq(WDT0_ACCSCSSNBARK_INT, wdog_bark_handler, 0,
+ "apps_wdog_bark", NULL);
+ if (ret)
+ return ret;
+ } else {
+ percpu_pdata = alloc_percpu(struct msm_watchdog_pdata *);
+ if (!percpu_pdata) {
+ pr_err("%s: memory allocation failed for percpu data\n",
+ __func__);
+ return -ENOMEM;
+ }
- *__this_cpu_ptr(percpu_pdata) = pdata;
- /* Must request irq before sending scm command */
- ret = request_percpu_irq(WDT0_ACCSCSSNBARK_INT, wdog_bark_handler,
- "apps_wdog_bark", percpu_pdata);
- if (ret) {
- free_percpu(percpu_pdata);
- return ret;
- }
+ *__this_cpu_ptr(percpu_pdata) = pdata;
+ /* Must request irq before sending scm command */
+ ret = request_percpu_irq(WDT0_ACCSCSSNBARK_INT,
+ wdog_bark_handler, "apps_wdog_bark", percpu_pdata);
+ if (ret) {
+ free_percpu(percpu_pdata);
+ return ret;
+ }
- enable_percpu_irq(WDT0_ACCSCSSNBARK_INT, IRQ_TYPE_EDGE_RISING);
+ enable_percpu_irq(WDT0_ACCSCSSNBARK_INT, IRQ_TYPE_EDGE_RISING);
+ }
/*
* This is only temporary till SBLs turn on the XPUs
diff --git a/arch/arm/mach-msm/msm_watchdog.h b/arch/arm/mach-msm/msm_watchdog.h
index 33e9e0c..7156dfc 100644
--- a/arch/arm/mach-msm/msm_watchdog.h
+++ b/arch/arm/mach-msm/msm_watchdog.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -20,6 +20,7 @@
unsigned int bark_time;
bool has_secure;
bool needs_expired_enable;
+ bool has_vic;
};
#ifdef CONFIG_MSM_WATCHDOG
diff --git a/arch/arm/mach-msm/msm_xo.c b/arch/arm/mach-msm/msm_xo.c
index 936fd6b..86776d3 100644
--- a/arch/arm/mach-msm/msm_xo.c
+++ b/arch/arm/mach-msm/msm_xo.c
@@ -21,6 +21,7 @@
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include <linux/string.h>
+#include <linux/clk.h>
#include <mach/msm_xo.h>
#include <mach/rpm.h>
@@ -232,6 +233,9 @@
{
int ret;
struct msm_xo *xo = xo_voter->xo;
+ int is_d0 = xo == &msm_xo_sources[MSM_XO_TCXO_D0];
+ int needs_workaround = cpu_is_msm8960() || cpu_is_apq8064() ||
+ cpu_is_msm8930() || cpu_is_msm9615();
if (xo_voter->mode == mode)
return 0;
@@ -244,6 +248,20 @@
xo->votes[mode]--;
goto out;
}
+ /* TODO: Remove once RPM separates the concept of D0 and CXO */
+ if (is_d0 && needs_workaround) {
+ static struct clk *xo_clk;
+
+ if (!xo_clk) {
+ xo_clk = clk_get_sys("msm_xo", "xo");
+ BUG_ON(IS_ERR(xo_clk));
+ }
+ /* Ignore transitions from pin to on or vice versa */
+ if (mode && xo_voter->mode == MSM_XO_MODE_OFF)
+ clk_enable(xo_clk);
+ else if (!mode)
+ clk_disable(xo_clk);
+ }
xo_voter->mode = mode;
out:
return ret;
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
index 3c46d0f..82aeb16 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/interrupt.h>
#include <asm/cacheflush.h>
#include <asm/hardware/gic.h>
@@ -59,6 +60,78 @@
}
static DEFINE_SPINLOCK(boot_lock);
+static DEFINE_RAW_SPINLOCK(irq_controller_lock);
+
+/*
+ * MP_CORE_IPC will be used to generate interrupt and can be used by either
+ * of core.
+ * To bring core1 out of GDFS we need to raise the SPI using the MP_CORE_IPC.
+ */
+static void raise_clear_spi(unsigned int cpu, bool set)
+{
+ int value;
+
+ value = __raw_readl(MSM_CSR_BASE + 0x54);
+ if (set)
+ __raw_writel(value | BIT(cpu), MSM_CSR_BASE + 0x54);
+ else
+ __raw_writel(value & ~BIT(cpu), MSM_CSR_BASE + 0x54);
+ mb();
+}
+
+/*
+ * Configure the GIC after we come out of power collapse.
+ * This function will configure some of the GIC registers so as to prepare the
+ * core1 to receive an SPI(ACSR_MP_CORE_IPC1, (32 + 8)), which will bring
+ * core1 out of GDFS.
+ */
+static void core1_gic_configure_and_raise(void)
+{
+ unsigned int value = 0;
+
+ raw_spin_lock(&irq_controller_lock);
+
+ value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_ACTIVE_BIT + 0x4);
+ value |= BIT(8);
+ __raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_ACTIVE_BIT + 0x4);
+ mb();
+
+ value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x24);
+ value |= BIT(13);
+ __raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x24);
+ mb();
+
+ value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x28);
+ value |= BIT(1);
+ __raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x28);
+ mb();
+
+ value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET + 0x4);
+ value |= BIT(8);
+ __raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET + 0x4);
+ mb();
+
+ value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_PENDING_SET + 0x4);
+ value |= BIT(8);
+ __raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_PENDING_SET + 0x4);
+ mb();
+
+ raise_clear_spi(1, true);
+ raw_spin_unlock(&irq_controller_lock);
+}
+
+void clear_pending_spi(unsigned int irq)
+{
+ struct irq_data *d = irq_get_irq_data(irq);
+ struct irq_chip *c = irq_data_get_irq_chip(d);
+
+ /* Clear the IRQ from the ENABLE_SET */
+ c->irq_mask(d);
+ local_irq_disable();
+ gic_clear_spi_pending(irq);
+ c->irq_unmask(d);
+ local_irq_enable();
+}
void __cpuinit platform_secondary_init(unsigned int cpu)
{
@@ -153,8 +226,16 @@
* Send the secondary CPU a soft interrupt, thereby causing
* the boot monitor to read the system wide flags register,
* and branch to the address found there.
+ *
+ * power_collapsed is the flag which will be updated for Powercollapse.
+ * Once we are out of PC, as Core1 will be in the state of GDFS which
+ * needs to be brought out by raising an SPI.
*/
- gic_raise_softirq(cpumask_of(cpu), 1);
+
+ if (power_collapsed)
+ core1_gic_configure_and_raise();
+ else
+ gic_raise_softirq(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
@@ -165,6 +246,13 @@
udelay(10);
}
+ /* Now we should clear the pending SPI */
+ if (power_collapsed) {
+ raise_clear_spi(1, false);
+ clear_pending_spi(MSM8625_INT_ACSR_MP_CORE_IPC1);
+ power_collapsed = 0;
+ }
+
/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index 892472b..4e9cc3c 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -27,6 +27,8 @@
#define msm_secondary_startup NULL
#endif
+extern int power_collapsed;
+
enum msm_pm_sleep_mode {
MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND,
MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 6b026ac..94bc98f 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -80,6 +80,7 @@
};
static int msm_pm_debug_mask;
+int power_collapsed;
module_param_named(
debug_mask, msm_pm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
);
diff --git a/arch/arm/mach-msm/qdsp6v2/Makefile b/arch/arm/mach-msm/qdsp6v2/Makefile
index 6d36495..083a9f1 100644
--- a/arch/arm/mach-msm/qdsp6v2/Makefile
+++ b/arch/arm/mach-msm/qdsp6v2/Makefile
@@ -14,7 +14,9 @@
endif
obj-$(CONFIG_MSM_QDSP6_APR) += apr.o apr_tal.o q6core.o dsp_debug.o
obj-y += audio_acdb.o
+ifndef CONFIG_ARCH_MSM9615
obj-y += aac_in.o qcelp_in.o evrc_in.o amrnb_in.o audio_utils.o
obj-y += audio_wma.o audio_wmapro.o audio_aac.o audio_multi_aac.o audio_utils_aio.o
obj-$(CONFIG_MSM_ULTRASOUND) += ultrasound/
obj-y += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_evrc.o audio_qcelp.o amrwb_in.o
+endif
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
index cdb0cbe..e664414 100644
--- a/arch/arm/mach-msm/scm.c
+++ b/arch/arm/mach-msm/scm.c
@@ -414,6 +414,19 @@
}
EXPORT_SYMBOL(scm_is_call_available);
+#define GET_FEAT_VERSION_CMD 3
+int scm_get_feat_version(u32 feat)
+{
+ if (scm_is_call_available(SCM_SVC_INFO, GET_FEAT_VERSION_CMD)) {
+ u32 version;
+ if (!scm_call(SCM_SVC_INFO, GET_FEAT_VERSION_CMD, &feat,
+ sizeof(feat), &version, sizeof(version)))
+ return version;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(scm_get_feat_version);
+
static int scm_init(void)
{
u32 ctr;
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index 78a6203..04dc392 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -577,7 +577,8 @@
n_restart_orders = ARRAY_SIZE(orders_8x60_all);
}
- if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615()) {
+ if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615() ||
+ cpu_is_apq8064()) {
restart_orders = restart_orders_8960;
n_restart_orders = ARRAY_SIZE(restart_orders_8960);
}
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 2dfde6f..ae7bc32 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1123,8 +1123,13 @@
}
msm_sched_clock_init();
- __raw_writel(1, msm_clocks[MSM_CLOCK_DGT].regbase + TIMER_ENABLE);
- set_delay_fn(read_current_timer_delay_loop);
+#ifdef ARCH_HAS_READ_CURRENT_TIMER
+ if (is_smp()) {
+ __raw_writel(1,
+ msm_clocks[MSM_CLOCK_DGT].regbase + TIMER_ENABLE);
+ set_delay_fn(read_current_timer_delay_loop);
+ }
+#endif
}
#ifdef CONFIG_SMP
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 332922e..8f51e2d 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -48,6 +48,7 @@
static int hcismd_set_enable(const char *val, struct kernel_param *kp);
module_param_call(hcismd_set, hcismd_set_enable, NULL, &hcismd_set, 0644);
+static void hci_dev_smd_open(struct work_struct *worker);
static void hci_dev_restart(struct work_struct *worker);
struct hci_smd_data {
@@ -315,6 +316,8 @@
struct hci_dev *hdev = hs.hdev;
struct hci_smd_data *hsmd = &hs;
struct work_struct *reset_worker;
+ struct work_struct *open_worker;
+
int len = 0;
if (!hdev) {
@@ -334,6 +337,13 @@
case SMD_EVENT_OPEN:
BT_INFO("opening HCI-SMD channel :%s", EVENT_CHANNEL);
hci_smd_open(hdev);
+ open_worker = kzalloc(sizeof(*open_worker), GFP_ATOMIC);
+ if (!open_worker) {
+ BT_ERR("Out of memory");
+ break;
+ }
+ INIT_WORK(open_worker, hci_dev_smd_open);
+ schedule_work(open_worker);
break;
case SMD_EVENT_CLOSE:
BT_INFO("Closing HCI-SMD channel :%s", EVENT_CHANNEL);
@@ -384,9 +394,24 @@
}
-static int hci_smd_register_dev(struct hci_smd_data *hsmd)
+static int hci_smd_hci_register_dev(struct hci_smd_data *hsmd)
{
- static struct hci_dev *hdev;
+ struct hci_dev *hdev;
+
+ hdev = hsmd->hdev;
+
+ if (hci_register_dev(hdev) < 0) {
+ BT_ERR("Can't register HCI device");
+ hci_free_dev(hdev);
+ hsmd->hdev = NULL;
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static int hci_smd_register_smd(struct hci_smd_data *hsmd)
+{
+ struct hci_dev *hdev;
int rc;
/* Initialize and register HCI device */
@@ -421,7 +446,7 @@
if (rc < 0) {
BT_ERR("Cannot open the command channel");
hci_free_dev(hdev);
- hdev = NULL;
+ hsmd->hdev = NULL;
return -ENODEV;
}
@@ -430,18 +455,13 @@
if (rc < 0) {
BT_ERR("Failed to open the Data channel");
hci_free_dev(hdev);
- hdev = NULL;
+ hsmd->hdev = NULL;
return -ENODEV;
}
/* Disable the read interrupts on the channel */
smd_disable_read_intr(hsmd->event_channel);
smd_disable_read_intr(hsmd->data_channel);
- if (hci_register_dev(hdev) < 0) {
- BT_ERR("Can't register HCI device");
- hci_free_dev(hdev);
- return -ENODEV;
- }
return 0;
}
@@ -478,7 +498,15 @@
{
mutex_lock(&hci_smd_enable);
hci_smd_deregister_dev(&hs);
- hci_smd_register_dev(&hs);
+ hci_smd_register_smd(&hs);
+ mutex_unlock(&hci_smd_enable);
+ kfree(worker);
+}
+
+static void hci_dev_smd_open(struct work_struct *worker)
+{
+ mutex_lock(&hci_smd_enable);
+ hci_smd_hci_register_dev(&hs);
mutex_unlock(&hci_smd_enable);
kfree(worker);
}
@@ -497,7 +525,7 @@
switch (hcismd_set) {
case 1:
- hci_smd_register_dev(&hs);
+ hci_smd_register_smd(&hs);
break;
case 0:
hci_smd_deregister_dev(&hs);
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index c044060..75ec72d 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -42,3 +42,4 @@
# ARM SoC drivers
obj-$(CONFIG_UX500_SOC_DB8500) += db8500-cpufreq.o
+obj-$(CONFIG_MSM_DCVS) += cpufreq_gov_msm.o
diff --git a/drivers/cpufreq/cpufreq_gov_msm.c b/drivers/cpufreq/cpufreq_gov_msm.c
new file mode 100644
index 0000000..9c49f80
--- /dev/null
+++ b/drivers/cpufreq/cpufreq_gov_msm.c
@@ -0,0 +1,176 @@
+/* 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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/kobject.h>
+#include <linux/cpufreq.h>
+#include <linux/platform_device.h>
+#include <mach/msm_dcvs.h>
+
+struct msm_gov {
+ int cpu;
+ unsigned int cur_freq;
+ unsigned int min_freq;
+ unsigned int max_freq;
+ struct msm_dcvs_freq gov_notifier;
+ struct cpufreq_policy *policy;
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct mutex, gov_mutex);
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct msm_gov, msm_gov_info);
+static char core_name[NR_CPUS][10];
+
+static void msm_gov_check_limits(struct cpufreq_policy *policy)
+{
+ struct msm_gov *gov = &per_cpu(msm_gov_info, policy->cpu);
+
+ if (policy->max < gov->cur_freq)
+ __cpufreq_driver_target(policy, policy->max,
+ CPUFREQ_RELATION_H);
+ else if (policy->min > gov->min_freq)
+ __cpufreq_driver_target(policy, policy->min,
+ CPUFREQ_RELATION_L);
+ else
+ __cpufreq_driver_target(policy, gov->cur_freq,
+ CPUFREQ_RELATION_L);
+
+ gov->cur_freq = policy->cur;
+ gov->min_freq = policy->min;
+ gov->max_freq = policy->max;
+}
+
+static int msm_dcvs_freq_set(struct msm_dcvs_freq *self,
+ unsigned int freq)
+{
+ int ret = -EINVAL;
+ struct msm_gov *gov =
+ container_of(self, struct msm_gov, gov_notifier);
+
+ mutex_lock(&per_cpu(gov_mutex, gov->cpu));
+
+ if (freq < gov->min_freq)
+ freq = gov->min_freq;
+ if (freq > gov->max_freq)
+ freq = gov->max_freq;
+
+ ret = __cpufreq_driver_target(gov->policy, freq, CPUFREQ_RELATION_L);
+ gov->cur_freq = gov->policy->cur;
+
+ mutex_unlock(&per_cpu(gov_mutex, gov->cpu));
+
+ if (!ret)
+ return gov->cur_freq;
+
+ return ret;
+}
+
+static unsigned int msm_dcvs_freq_get(struct msm_dcvs_freq *self)
+{
+ struct msm_gov *gov =
+ container_of(self, struct msm_gov, gov_notifier);
+
+ return gov->cur_freq;
+}
+
+static int cpufreq_governor_msm(struct cpufreq_policy *policy,
+ unsigned int event)
+{
+ unsigned int cpu = policy->cpu;
+ int ret = 0;
+ int handle = 0;
+ struct msm_gov *gov = &per_cpu(msm_gov_info, policy->cpu);
+ struct msm_dcvs_freq *dcvs_notifier =
+ &(per_cpu(msm_gov_info, cpu).gov_notifier);
+
+ switch (event) {
+ case CPUFREQ_GOV_START:
+ if (!cpu_online(cpu))
+ return -EINVAL;
+ BUG_ON(!policy->cur);
+ mutex_lock(&per_cpu(gov_mutex, cpu));
+ per_cpu(msm_gov_info, cpu).cpu = cpu;
+ gov->policy = policy;
+ dcvs_notifier->core_name = core_name[cpu];
+ dcvs_notifier->set_frequency = msm_dcvs_freq_set;
+ dcvs_notifier->get_frequency = msm_dcvs_freq_get;
+ handle = msm_dcvs_freq_sink_register(dcvs_notifier);
+ BUG_ON(handle < 0);
+ msm_gov_check_limits(policy);
+ mutex_unlock(&per_cpu(gov_mutex, cpu));
+ break;
+
+ case CPUFREQ_GOV_STOP:
+ mutex_lock(&per_cpu(gov_mutex, cpu));
+ msm_dcvs_freq_sink_unregister(dcvs_notifier);
+ mutex_unlock(&per_cpu(gov_mutex, cpu));
+ break;
+
+ case CPUFREQ_GOV_LIMITS:
+ mutex_lock(&per_cpu(gov_mutex, cpu));
+ msm_gov_check_limits(policy);
+ mutex_unlock(&per_cpu(gov_mutex, cpu));
+ break;
+ };
+
+ return ret;
+}
+
+struct cpufreq_governor cpufreq_gov_msm = {
+ .name = "msm-dcvs",
+ .governor = cpufreq_governor_msm,
+ .owner = THIS_MODULE,
+};
+
+static int __devinit msm_gov_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ int cpu;
+ uint32_t group_id = 0x43505530; /* CPU0 */
+ struct msm_dcvs_core_info *core = NULL;
+
+ core = pdev->dev.platform_data;
+
+ for_each_possible_cpu(cpu) {
+ mutex_init(&per_cpu(gov_mutex, cpu));
+ snprintf(core_name[cpu], 10, "cpu%d", cpu);
+ ret = msm_dcvs_register_core(core_name[cpu], group_id, core);
+ if (ret)
+ pr_err("Unable to register core for %d\n", cpu);
+ }
+
+ return cpufreq_register_governor(&cpufreq_gov_msm);
+}
+
+static int __devexit msm_gov_remove(struct platform_device *pdev)
+{
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static struct platform_driver msm_gov_driver = {
+ .probe = msm_gov_probe,
+ .remove = __devexit_p(msm_gov_remove),
+ .driver = {
+ .name = "msm_dcvs_gov",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init cpufreq_gov_msm_init(void)
+{
+ return platform_driver_register(&msm_gov_driver);
+}
+late_initcall(cpufreq_gov_msm_init);
diff --git a/drivers/gpio/pm8xxx-gpio.c b/drivers/gpio/pm8xxx-gpio.c
index 53305e3..f317c37 100644
--- a/drivers/gpio/pm8xxx-gpio.c
+++ b/drivers/gpio/pm8xxx-gpio.c
@@ -1,7 +1,7 @@
/*
* Qualcomm PMIC8XXX GPIO driver
*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
@@ -302,7 +302,7 @@
pm_gpio_chip->gpio_chip.set = pm_gpio_write;
pm_gpio_chip->gpio_chip.dbg_show = pm_gpio_dbg_show;
pm_gpio_chip->gpio_chip.ngpio = pdata->gpio_cdata.ngpios;
- pm_gpio_chip->gpio_chip.can_sleep = 1;
+ pm_gpio_chip->gpio_chip.can_sleep = 0;
pm_gpio_chip->gpio_chip.dev = &pdev->dev;
pm_gpio_chip->gpio_chip.base = pdata->gpio_base;
pm_gpio_chip->irq_base = platform_get_irq(pdev, 0);
diff --git a/drivers/gpio/pm8xxx-mpp.c b/drivers/gpio/pm8xxx-mpp.c
index 82a11a2..9afd5d1 100644
--- a/drivers/gpio/pm8xxx-mpp.c
+++ b/drivers/gpio/pm8xxx-mpp.c
@@ -1,7 +1,7 @@
/*
* Qualcomm PM8XXX Multi-Purpose Pin (MPP) driver
*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
@@ -250,7 +250,7 @@
mpp_chip->gpio_chip.set = pm8xxx_mpp_set;
mpp_chip->gpio_chip.dbg_show = pm8xxx_mpp_dbg_show;
mpp_chip->gpio_chip.ngpio = pdata->core_data.nmpps;
- mpp_chip->gpio_chip.can_sleep = 1;
+ mpp_chip->gpio_chip.can_sleep = 0;
mpp_chip->gpio_chip.dev = &pdev->dev;
mpp_chip->gpio_chip.base = pdata->mpp_base;
mpp_chip->irq_base = platform_get_irq(pdev, 0);
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index 347ab88..7a08e50 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -110,17 +110,15 @@
struct ion_buffer *buffer)
{
struct scatterlist *sglist;
- struct page *page = phys_to_page(buffer->priv_phys);
-
- if (page == NULL)
- return NULL;
sglist = vmalloc(sizeof(struct scatterlist));
if (!sglist)
return ERR_PTR(-ENOMEM);
sg_init_table(sglist, 1);
- sg_set_page(sglist, page, buffer->size, 0);
+ sglist->length = buffer->size;
+ sglist->offset = 0;
+ sglist->dma_address = buffer->priv_phys;
return sglist;
}
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index ff561dc..85c0534 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -299,17 +299,15 @@
struct ion_buffer *buffer)
{
struct scatterlist *sglist;
- struct page *page = phys_to_page(buffer->priv_phys);
-
- if (page == NULL)
- return NULL;
sglist = vmalloc(sizeof(*sglist));
if (!sglist)
return ERR_PTR(-ENOMEM);
sg_init_table(sglist, 1);
- sg_set_page(sglist, page, buffer->size, 0);
+ sglist->length = buffer->size;
+ sglist->offset = 0;
+ sglist->dma_address = buffer->priv_phys;
return sglist;
}
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 88e95da..521564a 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -610,13 +610,13 @@
struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
unsigned int timestamp;
unsigned int num_rb_contents;
+ unsigned int bad_context;
unsigned int reftimestamp;
unsigned int enable_ts;
unsigned int soptimestamp;
unsigned int eoptimestamp;
- unsigned int context_id;
+ struct adreno_context *drawctxt;
struct kgsl_context *context;
- struct adreno_context *adreno_context;
int next = 0;
KGSL_DRV_ERR(device, "Starting recovery from 3D GPU hang....\n");
@@ -632,35 +632,22 @@
ret = adreno_ringbuffer_extract(rb, rb_buffer, &num_rb_contents);
if (ret)
goto done;
- kgsl_sharedmem_readl(&device->memstore, &context_id,
- KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
- current_context));
- context = idr_find(&device->context_idr, context_id);
- if (context == NULL) {
- KGSL_DRV_ERR(device, "Last context unknown id:%d\n",
- context_id);
- context_id = KGSL_MEMSTORE_GLOBAL;
- }
-
- timestamp = rb->timestamp[KGSL_MEMSTORE_GLOBAL];
- KGSL_DRV_ERR(device, "Last issued global timestamp: %x\n", timestamp);
-
+ timestamp = rb->timestamp;
+ KGSL_DRV_ERR(device, "Last issued timestamp: %x\n", timestamp);
+ kgsl_sharedmem_readl(&device->memstore, &bad_context,
+ KGSL_DEVICE_MEMSTORE_OFFSET(current_context));
kgsl_sharedmem_readl(&device->memstore, &reftimestamp,
- KGSL_MEMSTORE_OFFSET(context_id,
- ref_wait_ts));
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts));
kgsl_sharedmem_readl(&device->memstore, &enable_ts,
- KGSL_MEMSTORE_OFFSET(context_id,
- ts_cmp_enable));
+ KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable));
kgsl_sharedmem_readl(&device->memstore, &soptimestamp,
- KGSL_MEMSTORE_OFFSET(context_id,
- soptimestamp));
+ KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp));
kgsl_sharedmem_readl(&device->memstore, &eoptimestamp,
- KGSL_MEMSTORE_OFFSET(context_id,
- eoptimestamp));
+ KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp));
/* Make sure memory is synchronized before restarting the GPU */
mb();
KGSL_CTXT_ERR(device,
- "Context id that caused a GPU hang: %d\n", context_id);
+ "Context that caused a GPU hang: %x\n", bad_context);
/* restart device */
ret = adreno_stop(device);
if (ret)
@@ -671,20 +658,20 @@
KGSL_DRV_ERR(device, "Device has been restarted after hang\n");
/* Restore timestamp states */
kgsl_sharedmem_writel(&device->memstore,
- KGSL_MEMSTORE_OFFSET(context_id, soptimestamp),
+ KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp),
soptimestamp);
kgsl_sharedmem_writel(&device->memstore,
- KGSL_MEMSTORE_OFFSET(context_id, eoptimestamp),
+ KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp),
eoptimestamp);
kgsl_sharedmem_writel(&device->memstore,
- KGSL_MEMSTORE_OFFSET(context_id, soptimestamp),
+ KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp),
soptimestamp);
if (num_rb_contents) {
kgsl_sharedmem_writel(&device->memstore,
- KGSL_MEMSTORE_OFFSET(context_id, ref_wait_ts),
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
reftimestamp);
kgsl_sharedmem_writel(&device->memstore,
- KGSL_MEMSTORE_OFFSET(context_id, ts_cmp_enable),
+ KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable),
enable_ts);
}
/* Make sure all writes are posted before the GPU reads them */
@@ -692,12 +679,12 @@
/* Mark the invalid context so no more commands are accepted from
* that context */
- adreno_context = context->devctxt;
+ drawctxt = (struct adreno_context *) bad_context;
KGSL_CTXT_ERR(device,
- "Context that caused a GPU hang: %d\n", adreno_context->id);
+ "Context that caused a GPU hang: %x\n", bad_context);
- adreno_context->flags |= CTXT_FLAGS_GPU_HANG;
+ drawctxt->flags |= CTXT_FLAGS_GPU_HANG;
/*
* Set the reset status of all contexts to
@@ -707,7 +694,7 @@
while ((context = idr_get_next(&device->context_idr, &next))) {
if (KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT !=
context->reset_status) {
- if (context->id != context_id)
+ if (context->devctxt != drawctxt)
context->reset_status =
KGSL_CTX_STAT_INNOCENT_CONTEXT_RESET_EXT;
else
@@ -719,7 +706,7 @@
/* Restore valid commands in ringbuffer */
adreno_ringbuffer_restore(rb, rb_buffer, num_rb_contents);
- rb->timestamp[KGSL_MEMSTORE_GLOBAL] = timestamp;
+ rb->timestamp = timestamp;
done:
vfree(rb_buffer);
return ret;
@@ -820,8 +807,7 @@
shadowprop.size = device->memstore.size;
/* GSL needs this to be set, even if it
appears to be meaningless */
- shadowprop.flags = KGSL_FLAGS_INITIALIZED |
- KGSL_FLAGS_PER_CONTEXT_TIMESTAMPS;
+ shadowprop.flags = KGSL_FLAGS_INITIALIZED;
}
if (copy_to_user(value, &shadowprop,
sizeof(shadowprop))) {
@@ -1089,58 +1075,38 @@
__raw_writel(value, reg);
}
-static unsigned int _get_context_id(struct kgsl_context *k_ctxt)
-{
- unsigned int context_id = KGSL_MEMSTORE_GLOBAL;
-
- if (k_ctxt != NULL) {
- struct adreno_context *a_ctxt = k_ctxt->devctxt;
- /*
- * if the context was not created with per context timestamp
- * support, we must use the global timestamp since issueibcmds
- * will be returning that one.
- */
- if (a_ctxt->flags & CTXT_FLAGS_PER_CONTEXT_TS)
- context_id = a_ctxt->id;
- }
-
- return context_id;
-}
-
static int kgsl_check_interrupt_timestamp(struct kgsl_device *device,
- struct kgsl_context *context, unsigned int timestamp)
+ unsigned int timestamp)
{
int status;
unsigned int ref_ts, enableflag;
- unsigned int context_id = _get_context_id(context);
- status = kgsl_check_timestamp(device, context, timestamp);
+ status = kgsl_check_timestamp(device, timestamp);
if (!status) {
mutex_lock(&device->mutex);
kgsl_sharedmem_readl(&device->memstore, &enableflag,
- KGSL_MEMSTORE_OFFSET(context_id, ts_cmp_enable));
+ KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable));
mb();
if (enableflag) {
kgsl_sharedmem_readl(&device->memstore, &ref_ts,
- KGSL_MEMSTORE_OFFSET(context_id,
- ref_wait_ts));
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts));
mb();
if (timestamp_cmp(ref_ts, timestamp) >= 0) {
kgsl_sharedmem_writel(&device->memstore,
- KGSL_MEMSTORE_OFFSET(context_id,
- ref_wait_ts), timestamp);
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
+ timestamp);
wmb();
}
} else {
unsigned int cmds[2];
kgsl_sharedmem_writel(&device->memstore,
- KGSL_MEMSTORE_OFFSET(context_id,
- ref_wait_ts), timestamp);
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
+ timestamp);
enableflag = 1;
kgsl_sharedmem_writel(&device->memstore,
- KGSL_MEMSTORE_OFFSET(context_id,
- ts_cmp_enable), enableflag);
+ KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable),
+ enableflag);
wmb();
/* submit a dummy packet so that even if all
* commands upto timestamp get executed we will still
@@ -1174,7 +1140,6 @@
/* MUST be called with the device mutex held */
static int adreno_waittimestamp(struct kgsl_device *device,
- struct kgsl_context *context,
unsigned int timestamp,
unsigned int msecs)
{
@@ -1186,19 +1151,15 @@
int retries;
unsigned int msecs_first;
unsigned int msecs_part;
- unsigned int ts_issued;
- unsigned int context_id = _get_context_id(context);
-
- ts_issued = adreno_dev->ringbuffer.timestamp[context_id];
/* Don't wait forever, set a max value for now */
if (msecs == -1)
msecs = adreno_dev->wait_timeout;
- if (timestamp_cmp(timestamp, ts_issued) > 0) {
- KGSL_DRV_ERR(device, "Cannot wait for invalid ts <%d:0x%x>, "
- "last issued ts <%d:0x%x>\n",
- context_id, timestamp, context_id, ts_issued);
+ if (timestamp_cmp(timestamp, adreno_dev->ringbuffer.timestamp) > 0) {
+ KGSL_DRV_ERR(device, "Cannot wait for invalid ts: %x, "
+ "rb->timestamp: %x\n",
+ timestamp, adreno_dev->ringbuffer.timestamp);
status = -EINVAL;
goto done;
}
@@ -1210,7 +1171,7 @@
msecs_first = (msecs <= 100) ? ((msecs + 4) / 5) : 100;
msecs_part = (msecs - msecs_first + 3) / 4;
for (retries = 0; retries < 5; retries++) {
- if (kgsl_check_timestamp(device, context, timestamp)) {
+ if (kgsl_check_timestamp(device, timestamp)) {
/* if the timestamp happens while we're not
* waiting, there's a chance that an interrupt
* will not be generated and thus the timestamp
@@ -1232,7 +1193,7 @@
status = kgsl_wait_event_interruptible_timeout(
device->wait_queue,
kgsl_check_interrupt_timestamp(device,
- context, timestamp),
+ timestamp),
msecs_to_jiffies(retries ?
msecs_part : msecs_first), io);
mutex_lock(&device->mutex);
@@ -1249,10 +1210,9 @@
}
status = -ETIMEDOUT;
KGSL_DRV_ERR(device,
- "Device hang detected while waiting for timestamp: "
- "<%d:0x%x>, last submitted timestamp: <%d:0x%x>, "
- "wptr: 0x%x\n",
- context_id, timestamp, context_id, ts_issued,
+ "Device hang detected while waiting for timestamp: %x,"
+ "last submitted(rb->timestamp): %x, wptr: %x\n",
+ timestamp, adreno_dev->ringbuffer.timestamp,
adreno_dev->ringbuffer.wptr);
if (!adreno_dump_and_recover(device)) {
/* wait for idle after recovery as the
@@ -1266,17 +1226,15 @@
}
static unsigned int adreno_readtimestamp(struct kgsl_device *device,
- struct kgsl_context *context, enum kgsl_timestamp_type type)
+ enum kgsl_timestamp_type type)
{
unsigned int timestamp = 0;
- unsigned int context_id = _get_context_id(context);
if (type == KGSL_TIMESTAMP_CONSUMED)
adreno_regread(device, REG_CP_TIMESTAMP, ×tamp);
else if (type == KGSL_TIMESTAMP_RETIRED)
kgsl_sharedmem_readl(&device->memstore, ×tamp,
- KGSL_MEMSTORE_OFFSET(context_id,
- eoptimestamp));
+ KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp));
rmb();
return timestamp;
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index cbafddd..f31d120 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1521,8 +1521,8 @@
cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER;
cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2);
cmds[3] = device->memstore.gpuaddr +
- KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context);
- cmds[4] = context->id;
+ KGSL_DEVICE_MEMSTORE_OFFSET(current_context);
+ cmds[4] = (unsigned int) context;
adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE, cmds, 5);
kgsl_mmu_setstate(device, context->pagetable);
@@ -1648,18 +1648,11 @@
if (status & CP_INT_CNTL__RB_INT_MASK) {
/* signal intr completion event */
- unsigned int context_id;
- kgsl_sharedmem_readl(&device->memstore,
- &context_id,
- KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
- current_context));
- if (context_id < KGSL_MEMSTORE_MAX) {
- kgsl_sharedmem_writel(&rb->device->memstore,
- KGSL_MEMSTORE_OFFSET(context_id,
- ts_cmp_enable), 0);
- device->last_expired_ctxt_id = context_id;
- wmb();
- }
+ unsigned int enableflag = 0;
+ kgsl_sharedmem_writel(&rb->device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable),
+ enableflag);
+ wmb();
KGSL_CMD_WARN(rb->device, "ringbuffer rb interrupt\n");
}
@@ -1872,6 +1865,7 @@
static void a2xx_start(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = &adreno_dev->dev;
+ int init_reftimestamp = 0x7fffffff;
/*
* We need to make sure all blocks are powered up and clocked
@@ -1923,6 +1917,12 @@
else
adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0x80);
+ kgsl_sharedmem_set(&device->memstore, 0, 0, device->memstore.size);
+
+ kgsl_sharedmem_writel(&device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
+ init_reftimestamp);
+
adreno_regwrite(device, REG_RBBM_DEBUG, 0x00080000);
/* Make sure interrupts are disabled */
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 4602299..c01e676 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -12,6 +12,7 @@
*/
#include <linux/delay.h>
+#include <mach/socinfo.h>
#include "kgsl.h"
#include "adreno.h"
@@ -2266,8 +2267,8 @@
cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER;
cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2);
cmds[3] = device->memstore.gpuaddr +
- KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context);
- cmds[4] = context->id;
+ KGSL_DEVICE_MEMSTORE_OFFSET(current_context);
+ cmds[4] = (unsigned int)context;
adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE, cmds, 5);
kgsl_mmu_setstate(device, context->pagetable);
@@ -2410,17 +2411,9 @@
struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
if (irq == A3XX_INT_CP_RB_INT) {
- unsigned int context_id;
- kgsl_sharedmem_readl(&adreno_dev->dev.memstore,
- &context_id,
- KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
- current_context));
- if (context_id < KGSL_MEMSTORE_MAX) {
- kgsl_sharedmem_writel(&rb->device->memstore,
- KGSL_MEMSTORE_OFFSET(context_id,
- ts_cmp_enable), 0);
- wmb();
- }
+ kgsl_sharedmem_writel(&rb->device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable), 0);
+ wmb();
KGSL_CMD_WARN(rb->device, "ringbuffer rb interrupt\n");
}
@@ -2575,10 +2568,11 @@
adreno_regwrite(device, A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003C);
adreno_regwrite(device, A3XX_VBIF_OUT_AXI_AOOO, 0x003C003C);
- /* Enable 1K sort */
- adreno_regwrite(device, A3XX_VBIF_ABIT_SORT, 0x000000FF);
- adreno_regwrite(device, A3XX_VBIF_ABIT_SORT_CONF, 0x000000A4);
-
+ if (cpu_is_apq8064()) {
+ /* Enable 1K sort */
+ adreno_regwrite(device, A3XX_VBIF_ABIT_SORT, 0x000000FF);
+ adreno_regwrite(device, A3XX_VBIF_ABIT_SORT_CONF, 0x000000A4);
+ }
/* Make all blocks contribute to the GPU BUSY perf counter */
adreno_regwrite(device, A3XX_RBBM_GPU_BUSY_MASKED, 0xFFFFFFFF);
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index d773521..aeb89b3 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -17,8 +17,6 @@
#include "kgsl_sharedmem.h"
#include "adreno.h"
-#define KGSL_INIT_REFTIMESTAMP 0x7FFFFFFF
-
/* quad for copying GMEM to context shadow */
#define QUAD_LEN 12
#define QUAD_RESTORE_LEN 14
@@ -156,7 +154,6 @@
drawctxt->pagetable = pagetable;
drawctxt->bin_base_offset = 0;
- drawctxt->id = context->id;
if (flags & KGSL_CONTEXT_PREAMBLE)
drawctxt->flags |= CTXT_FLAGS_PREAMBLE;
@@ -164,17 +161,10 @@
if (flags & KGSL_CONTEXT_NO_GMEM_ALLOC)
drawctxt->flags |= CTXT_FLAGS_NOGMEMALLOC;
- if (flags & KGSL_CONTEXT_PER_CONTEXT_TS)
- drawctxt->flags |= CTXT_FLAGS_PER_CONTEXT_TS;
-
ret = adreno_dev->gpudev->ctxt_create(adreno_dev, drawctxt);
if (ret)
goto err;
- kgsl_sharedmem_writel(&device->memstore,
- KGSL_MEMSTORE_OFFSET(drawctxt->id, ref_wait_ts),
- KGSL_INIT_REFTIMESTAMP);
-
context->devctxt = drawctxt;
return 0;
err:
@@ -197,12 +187,11 @@
struct kgsl_context *context)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
- struct adreno_context *drawctxt;
+ struct adreno_context *drawctxt = context->devctxt;
- if (context == NULL)
+ if (drawctxt == NULL)
return;
- drawctxt = context->devctxt;
/* deactivate context */
if (adreno_dev->drawctxt_active == drawctxt) {
/* no need to save GMEM or shader, the context is
diff --git a/drivers/gpu/msm/adreno_drawctxt.h b/drivers/gpu/msm/adreno_drawctxt.h
index 3eb1aba..9a7ae3f 100644
--- a/drivers/gpu/msm/adreno_drawctxt.h
+++ b/drivers/gpu/msm/adreno_drawctxt.h
@@ -40,10 +40,6 @@
#define CTXT_FLAGS_GPU_HANG 0x00008000
/* Specifies there is no need to save GMEM */
#define CTXT_FLAGS_NOGMEMALLOC 0x00010000
-/* Trash state for context */
-#define CTXT_FLAGS_TRASHSTATE 0x00020000
-/* per context timestamps enabled */
-#define CTXT_FLAGS_PER_CONTEXT_TS 0x00040000
struct kgsl_device;
struct adreno_device;
@@ -76,7 +72,6 @@
};
struct adreno_context {
- unsigned int id;
uint32_t flags;
struct kgsl_pagetable *pagetable;
struct kgsl_memdesc gpustate;
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 73be388..e4bc470 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -14,7 +14,6 @@
#include <linux/vmalloc.h>
#include "kgsl.h"
-#include "kgsl_sharedmem.h"
#include "adreno.h"
#include "adreno_pm4types.h"
@@ -690,9 +689,7 @@
const uint32_t *rb_vaddr;
int num_item = 0;
int read_idx, write_idx;
- unsigned int ts_processed = 0xdeaddead;
- struct kgsl_context *context;
- unsigned int context_id;
+ unsigned int ts_processed;
static struct ib_list ib_list;
@@ -718,18 +715,9 @@
kgsl_regread(device, REG_CP_IB2_BASE, &cp_ib2_base);
kgsl_regread(device, REG_CP_IB2_BUFSZ, &cp_ib2_bufsz);
- kgsl_sharedmem_readl(&device->memstore,
- (unsigned int *) &context_id,
- KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
- current_context));
- context = idr_find(&device->context_idr, context_id);
- if (context) {
- ts_processed = device->ftbl->readtimestamp(device, context,
- KGSL_TIMESTAMP_RETIRED);
- KGSL_LOG_DUMP(device, "CTXT: %d TIMESTM RTRD: %08X\n",
- context->id, ts_processed);
- } else
- KGSL_LOG_DUMP(device, "BAD CTXT: %d\n", context_id);
+ ts_processed = device->ftbl->readtimestamp(device,
+ KGSL_TIMESTAMP_RETIRED);
+ KGSL_LOG_DUMP(device, "TIMESTM RTRD: %08X\n", ts_processed);
num_item = adreno_ringbuffer_count(&adreno_dev->ringbuffer,
cp_rb_rptr);
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 6d4734d..d6648e2 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -235,7 +235,7 @@
return 0;
if (init_ram) {
- rb->timestamp[KGSL_MEMSTORE_GLOBAL] = 0;
+ rb->timestamp = 0;
GSL_RB_INIT_TIMESTAMP(rb);
}
@@ -320,9 +320,9 @@
}
/* setup scratch/timestamp */
- adreno_regwrite(device, REG_SCRATCH_ADDR, device->memstore.gpuaddr +
- KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
- soptimestamp));
+ adreno_regwrite(device, REG_SCRATCH_ADDR,
+ device->memstore.gpuaddr +
+ KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp));
adreno_regwrite(device, REG_SCRATCH_UMSK,
GSL_RB_MEMPTRS_SCRATCH_MASK);
@@ -425,28 +425,15 @@
static uint32_t
adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb,
- struct adreno_context *context,
unsigned int flags, unsigned int *cmds,
int sizedwords)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(rb->device);
unsigned int *ringcmds;
unsigned int timestamp;
- unsigned int total_sizedwords = sizedwords;
+ unsigned int total_sizedwords = sizedwords + 6;
unsigned int i;
unsigned int rcmd_gpu;
- unsigned int context_id = KGSL_MEMSTORE_GLOBAL;
- unsigned int gpuaddr = rb->device->memstore.gpuaddr;
-
- if (context != NULL) {
- /*
- * if the context was not created with per context timestamp
- * support, we must use the global timestamp since issueibcmds
- * will be returning that one.
- */
- if (context->flags & CTXT_FLAGS_PER_CONTEXT_TS)
- context_id = context->id;
- }
/* reserve space to temporarily turn off protected mode
* error checking if needed
@@ -458,13 +445,6 @@
if (adreno_is_a3xx(adreno_dev))
total_sizedwords += 7;
- total_sizedwords += 2; /* scratchpad ts for recovery */
- if (context) {
- total_sizedwords += 3; /* sop timestamp */
- total_sizedwords += 4; /* eop timestamp */
- }
- total_sizedwords += 4; /* global timestamp for recovery*/
-
ringcmds = adreno_ringbuffer_allocspace(rb, total_sizedwords);
rcmd_gpu = rb->buffer_desc.gpuaddr
+ sizeof(uint)*(rb->wptr-total_sizedwords);
@@ -492,20 +472,12 @@
GSL_RB_WRITE(ringcmds, rcmd_gpu, 1);
}
- /* always increment the global timestamp. once. */
- rb->timestamp[KGSL_MEMSTORE_GLOBAL]++;
- if (context) {
- if (context_id == KGSL_MEMSTORE_GLOBAL)
- rb->timestamp[context_id] =
- rb->timestamp[KGSL_MEMSTORE_GLOBAL];
- else
- rb->timestamp[context_id]++;
- }
- timestamp = rb->timestamp[context_id];
+ rb->timestamp++;
+ timestamp = rb->timestamp;
- /* scratchpad ts for recovery */
+ /* start-of-pipeline and end-of-pipeline timestamps */
GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type0_packet(REG_CP_TIMESTAMP, 1));
- GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp);
if (adreno_is_a3xx(adreno_dev)) {
/*
@@ -521,41 +493,22 @@
GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x00);
}
- if (context) {
- /* start-of-pipeline timestamp */
- GSL_RB_WRITE(ringcmds, rcmd_gpu,
- cp_type3_packet(CP_MEM_WRITE, 2));
- GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
- KGSL_MEMSTORE_OFFSET(context->id, soptimestamp)));
- GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
-
- /* end-of-pipeline timestamp */
- GSL_RB_WRITE(ringcmds, rcmd_gpu,
- cp_type3_packet(CP_EVENT_WRITE, 3));
- GSL_RB_WRITE(ringcmds, rcmd_gpu, CACHE_FLUSH_TS);
- GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
- KGSL_MEMSTORE_OFFSET(context->id, eoptimestamp)));
- GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
- }
-
GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type3_packet(CP_EVENT_WRITE, 3));
GSL_RB_WRITE(ringcmds, rcmd_gpu, CACHE_FLUSH_TS);
- GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
- KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
- eoptimestamp)));
- GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+ GSL_RB_WRITE(ringcmds, rcmd_gpu,
+ (rb->device->memstore.gpuaddr +
+ KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp)));
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp);
if (!(flags & KGSL_CMD_FLAGS_NO_TS_CMP)) {
/* Conditional execution based on memory values */
GSL_RB_WRITE(ringcmds, rcmd_gpu,
cp_type3_packet(CP_COND_EXEC, 4));
- GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
- KGSL_MEMSTORE_OFFSET(
- context_id, ts_cmp_enable)) >> 2);
- GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
- KGSL_MEMSTORE_OFFSET(
- context_id, ref_wait_ts)) >> 2);
- GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, (rb->device->memstore.gpuaddr +
+ KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable)) >> 2);
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, (rb->device->memstore.gpuaddr +
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts)) >> 2);
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp);
/* # of conditional command DWORDs */
GSL_RB_WRITE(ringcmds, rcmd_gpu, 2);
GSL_RB_WRITE(ringcmds, rcmd_gpu,
@@ -574,6 +527,7 @@
adreno_ringbuffer_submit(rb);
+ /* return timestamp of issued coREG_ands */
return timestamp;
}
@@ -588,7 +542,7 @@
if (device->state & KGSL_STATE_HUNG)
return;
- adreno_ringbuffer_addcmds(rb, NULL, flags, cmds, sizedwords);
+ adreno_ringbuffer_addcmds(rb, flags, cmds, sizedwords);
}
int
@@ -653,7 +607,6 @@
adreno_drawctxt_switch(adreno_dev, drawctxt, flags);
*timestamp = adreno_ringbuffer_addcmds(&adreno_dev->ringbuffer,
- drawctxt,
KGSL_CMD_FLAGS_NOT_KERNEL_CMD,
&link[0], (cmds - link));
@@ -687,26 +640,12 @@
unsigned int val2;
unsigned int val3;
unsigned int copy_rb_contents = 0;
- struct kgsl_context *context;
- unsigned int context_id;
+ unsigned int cur_context;
GSL_RB_GET_READPTR(rb, &rb->rptr);
- /* current_context is the context that is presently active in the
- * GPU, i.e the context in which the hang is caused */
- kgsl_sharedmem_readl(&device->memstore, &context_id,
- KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
- current_context));
- KGSL_DRV_ERR(device, "Last context id: %d\n", context_id);
- context = idr_find(&device->context_idr, context_id);
- if (context == NULL) {
- KGSL_DRV_ERR(device,
- "GPU recovery from hang not possible because last"
- " context id is invalid.\n");
- return -EINVAL;
- }
- retired_timestamp = device->ftbl->readtimestamp(device, context,
- KGSL_TIMESTAMP_RETIRED);
+ retired_timestamp = device->ftbl->readtimestamp(device,
+ KGSL_TIMESTAMP_RETIRED);
KGSL_DRV_ERR(device, "GPU successfully executed till ts: %x\n",
retired_timestamp);
/*
@@ -740,8 +679,7 @@
(val1 == cp_type3_packet(CP_EVENT_WRITE, 3)
&& val2 == CACHE_FLUSH_TS &&
val3 == (rb->device->memstore.gpuaddr +
- KGSL_MEMSTORE_OFFSET(context_id,
- eoptimestamp)))) {
+ KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp)))) {
rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
rb->buffer_desc.size);
KGSL_DRV_ERR(device,
@@ -787,6 +725,10 @@
return -EINVAL;
}
+ /* current_context is the context that is presently active in the
+ * GPU, i.e the context in which the hang is caused */
+ kgsl_sharedmem_readl(&device->memstore, &cur_context,
+ KGSL_DEVICE_MEMSTORE_OFFSET(current_context));
while ((rb_rptr / sizeof(unsigned int)) != rb->wptr) {
kgsl_sharedmem_readl(&rb->buffer_desc, &value, rb_rptr);
rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
@@ -801,8 +743,7 @@
rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
rb->buffer_desc.size);
BUG_ON(val1 != (device->memstore.gpuaddr +
- KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
- current_context)));
+ KGSL_DEVICE_MEMSTORE_OFFSET(current_context)));
kgsl_sharedmem_readl(&rb->buffer_desc, &value, rb_rptr);
rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
rb->buffer_desc.size);
@@ -814,7 +755,7 @@
* and leave.
*/
- if ((copy_rb_contents == 0) && (value == context_id)) {
+ if ((copy_rb_contents == 0) && (value == cur_context)) {
KGSL_DRV_ERR(device, "GPU recovery could not "
"find the previous context\n");
return -EINVAL;
@@ -830,7 +771,7 @@
/* if context switches to a context that did not cause
* hang then start saving the rb contents as those
* commands can be executed */
- if (value != context_id) {
+ if (value != cur_context) {
copy_rb_contents = 1;
temp_rb_buffer[temp_idx++] = cp_nop_packet(1);
temp_rb_buffer[temp_idx++] =
diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h
index a459c1b..0361387 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.h
+++ b/drivers/gpu/msm/adreno_ringbuffer.h
@@ -58,8 +58,7 @@
unsigned int wptr; /* write pointer offset in dwords from baseaddr */
unsigned int rptr; /* read pointer offset in dwords from baseaddr */
-
- unsigned int timestamp[KGSL_MEMSTORE_MAX];
+ uint32_t timestamp;
};
@@ -85,7 +84,7 @@
#else
#define GSL_RB_MEMPTRS_SCRATCH_MASK 0x0
#define GSL_RB_INIT_TIMESTAMP(rb) \
- adreno_regwrite((rb)->device, REG_CP_TIMESTAMP, 0)
+ adreno_regwrite((rb)->device->id, REG_CP_TIMESTAMP, 0)
#endif /* GSL_RB_USE_MEMTIMESTAMP */
@@ -100,7 +99,7 @@
#define GSL_RB_CNTL_NO_UPDATE 0x1 /* disable */
#define GSL_RB_GET_READPTR(rb, data) \
do { \
- adreno_regread((rb)->device, REG_CP_RB_RPTR, (data)); \
+ adreno_regread((rb)->device->id, REG_CP_RB_RPTR, (data)); \
} while (0)
#endif /* GSL_RB_USE_MEMRPTR */
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index d058eeb..5464bbb 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -59,30 +59,22 @@
* @returns - 0 on success or error code on failure
*/
-static int kgsl_add_event(struct kgsl_device *device, u32 id, u32 ts,
- void (*cb)(struct kgsl_device *, void *, u32, u32), void *priv,
+static int kgsl_add_event(struct kgsl_device *device, u32 ts,
+ void (*cb)(struct kgsl_device *, void *, u32), void *priv,
struct kgsl_device_private *owner)
{
struct kgsl_event *event;
struct list_head *n;
- unsigned int cur_ts;
- struct kgsl_context *context = NULL;
+ unsigned int cur = device->ftbl->readtimestamp(device,
+ KGSL_TIMESTAMP_RETIRED);
if (cb == NULL)
return -EINVAL;
- if (id != KGSL_MEMSTORE_GLOBAL) {
- context = idr_find(&device->context_idr, id);
- if (context == NULL)
- return -EINVAL;
- }
- cur_ts = device->ftbl->readtimestamp(device, context,
- KGSL_TIMESTAMP_RETIRED);
-
/* Check to see if the requested timestamp has already fired */
- if (timestamp_cmp(cur_ts, ts) >= 0) {
- cb(device, priv, id, cur_ts);
+ if (timestamp_cmp(cur, ts) >= 0) {
+ cb(device, priv, cur);
return 0;
}
@@ -90,24 +82,17 @@
if (event == NULL)
return -ENOMEM;
- event->context = context;
event->timestamp = ts;
event->priv = priv;
event->func = cb;
event->owner = owner;
- /*
- * Add the event in order to the list. Order is by context id
- * first and then by timestamp for that context.
- */
+ /* Add the event in order to the list */
for (n = device->events.next ; n != &device->events; n = n->next) {
struct kgsl_event *e =
list_entry(n, struct kgsl_event, list);
- if (e->context != context)
- continue;
-
if (timestamp_cmp(e->timestamp, ts) > 0) {
list_add(&event->list, n->prev);
break;
@@ -131,16 +116,12 @@
struct kgsl_device_private *owner)
{
struct kgsl_event *event, *event_tmp;
- unsigned int id, cur;
+ unsigned int cur = device->ftbl->readtimestamp(device,
+ KGSL_TIMESTAMP_RETIRED);
list_for_each_entry_safe(event, event_tmp, &device->events, list) {
if (event->owner != owner)
continue;
-
- cur = device->ftbl->readtimestamp(device, event->context,
- KGSL_TIMESTAMP_RETIRED);
-
- id = event->context ? event->context->id : KGSL_MEMSTORE_GLOBAL;
/*
* "cancel" the events by calling their callback.
* Currently, events are used for lock and memory
@@ -148,7 +129,7 @@
* thing to do is release or free.
*/
if (event->func)
- event->func(device, event->priv, id, cur);
+ event->func(device, event->priv, cur);
list_del(&event->list);
kfree(event);
@@ -285,8 +266,8 @@
return NULL;
}
- ret = idr_get_new_above(&dev_priv->device->context_idr,
- context, 1, &id);
+ ret = idr_get_new(&dev_priv->device->context_idr,
+ context, &id);
if (ret != -EAGAIN)
break;
@@ -297,16 +278,6 @@
return NULL;
}
- /* MAX - 1, there is one memdesc in memstore for device info */
- if (id >= KGSL_MEMSTORE_MAX) {
- KGSL_DRV_ERR(dev_priv->device, "cannot have more than %d "
- "ctxts due to memstore limitation\n",
- KGSL_MEMSTORE_MAX);
- idr_remove(&dev_priv->device->context_idr, id);
- kfree(context);
- return NULL;
- }
-
context->id = id;
context->dev_priv = dev_priv;
@@ -337,28 +308,25 @@
ts_expired_ws);
struct kgsl_event *event, *event_tmp;
uint32_t ts_processed;
- unsigned int id;
mutex_lock(&device->mutex);
+ /* get current EOP timestamp */
+ ts_processed = device->ftbl->readtimestamp(device,
+ KGSL_TIMESTAMP_RETIRED);
+
/* Process expired events */
list_for_each_entry_safe(event, event_tmp, &device->events, list) {
- ts_processed = device->ftbl->readtimestamp(device,
- event->context, KGSL_TIMESTAMP_RETIRED);
if (timestamp_cmp(ts_processed, event->timestamp) < 0)
- continue;
-
- id = event->context ? event->context->id : KGSL_MEMSTORE_GLOBAL;
+ break;
if (event->func)
- event->func(device, event->priv, id, ts_processed);
+ event->func(device, event->priv, ts_processed);
list_del(&event->list);
kfree(event);
}
- device->last_expired_ctxt_id = KGSL_CONTEXT_INVALID;
-
mutex_unlock(&device->mutex);
}
@@ -433,15 +401,11 @@
}
EXPORT_SYMBOL(kgsl_unregister_ts_notifier);
-int kgsl_check_timestamp(struct kgsl_device *device,
- struct kgsl_context *context, unsigned int timestamp)
+int kgsl_check_timestamp(struct kgsl_device *device, unsigned int timestamp)
{
unsigned int ts_processed;
- unsigned int global;
- ts_processed = device->ftbl->readtimestamp(device, context,
- KGSL_TIMESTAMP_RETIRED);
- global = device->ftbl->readtimestamp(device, NULL,
+ ts_processed = device->ftbl->readtimestamp(device,
KGSL_TIMESTAMP_RETIRED);
return (timestamp_cmp(ts_processed, timestamp) >= 0);
@@ -776,9 +740,6 @@
kgsl_check_suspended(device);
if (device->open_count == 0) {
- kgsl_sharedmem_set(&device->memstore, 0, 0,
- device->memstore.size);
-
result = device->ftbl->start(device, true);
if (result) {
@@ -917,23 +878,23 @@
return result;
}
-static long _device_waittimestamp(struct kgsl_device_private *dev_priv,
- struct kgsl_context *context,
- unsigned int timestamp,
- unsigned int timeout)
+static long kgsl_ioctl_device_waittimestamp(struct kgsl_device_private
+ *dev_priv, unsigned int cmd,
+ void *data)
{
int result = 0;
+ struct kgsl_device_waittimestamp *param = data;
- /* Set the active count so that suspend doesn't do the wrong thing */
+ /* Set the active count so that suspend doesn't do the
+ wrong thing */
dev_priv->device->active_cnt++;
- trace_kgsl_waittimestamp_entry(dev_priv->device,
- context ? context->id : KGSL_MEMSTORE_GLOBAL,
- timestamp, timeout);
+ trace_kgsl_waittimestamp_entry(dev_priv->device, param);
result = dev_priv->device->ftbl->waittimestamp(dev_priv->device,
- context, timestamp, timeout);
+ param->timestamp,
+ param->timeout);
trace_kgsl_waittimestamp_exit(dev_priv->device, result);
@@ -945,35 +906,6 @@
return result;
}
-
-static long kgsl_ioctl_device_waittimestamp(struct kgsl_device_private
- *dev_priv, unsigned int cmd,
- void *data)
-{
- struct kgsl_device_waittimestamp *param = data;
-
- return _device_waittimestamp(dev_priv, KGSL_MEMSTORE_GLOBAL,
- param->timestamp, param->timeout);
-}
-
-static long kgsl_ioctl_device_waittimestamp_ctxtid(struct kgsl_device_private
- *dev_priv, unsigned int cmd,
- void *data)
-{
- struct kgsl_device_waittimestamp_ctxtid *param = data;
- struct kgsl_context *context;
-
- context = kgsl_find_context(dev_priv, param->context_id);
- if (context == NULL) {
- KGSL_DRV_ERR(dev_priv->device, "invalid context_id %d\n",
- param->context_id);
- return -EINVAL;
- }
-
- return _device_waittimestamp(dev_priv, context,
- param->timestamp, param->timeout);
-}
-
static bool check_ibdesc(struct kgsl_device_private *dev_priv,
struct kgsl_ibdesc *ibdesc, unsigned int numibs,
bool parse)
@@ -1021,7 +953,7 @@
if (context == NULL) {
result = -EINVAL;
KGSL_DRV_ERR(dev_priv->device,
- "invalid context_id %d\n",
+ "invalid drawctxt drawctxt_id %d\n",
param->drawctxt_id);
goto done;
}
@@ -1087,6 +1019,7 @@
param->flags);
trace_kgsl_issueibcmds(dev_priv->device, param, result);
+
if (result != 0)
goto free_ibdesc;
@@ -1106,117 +1039,60 @@
return result;
}
-static long _cmdstream_readtimestamp(struct kgsl_device_private *dev_priv,
- struct kgsl_context *context, unsigned int type,
- unsigned int *timestamp)
-{
- *timestamp = dev_priv->device->ftbl->readtimestamp(dev_priv->device,
- context, type);
-
- trace_kgsl_readtimestamp(dev_priv->device,
- context ? context->id : KGSL_MEMSTORE_GLOBAL,
- type, *timestamp);
-
- return 0;
-}
-
static long kgsl_ioctl_cmdstream_readtimestamp(struct kgsl_device_private
*dev_priv, unsigned int cmd,
void *data)
{
struct kgsl_cmdstream_readtimestamp *param = data;
- return _cmdstream_readtimestamp(dev_priv, NULL,
- param->type, ¶m->timestamp);
-}
+ param->timestamp =
+ dev_priv->device->ftbl->readtimestamp(dev_priv->device,
+ param->type);
-static long kgsl_ioctl_cmdstream_readtimestamp_ctxtid(struct kgsl_device_private
- *dev_priv, unsigned int cmd,
- void *data)
-{
- struct kgsl_cmdstream_readtimestamp_ctxtid *param = data;
- struct kgsl_context *context;
+ trace_kgsl_readtimestamp(dev_priv->device, param);
- context = kgsl_find_context(dev_priv, param->context_id);
- if (context == NULL) {
- KGSL_DRV_ERR(dev_priv->device, "invalid context_id %d\n",
- param->context_id);
- return -EINVAL;
- }
-
- return _cmdstream_readtimestamp(dev_priv, context,
- param->type, ¶m->timestamp);
+ return 0;
}
static void kgsl_freemem_event_cb(struct kgsl_device *device,
- void *priv, u32 id, u32 timestamp)
+ void *priv, u32 timestamp)
{
struct kgsl_mem_entry *entry = priv;
spin_lock(&entry->priv->mem_lock);
list_del(&entry->list);
spin_unlock(&entry->priv->mem_lock);
- trace_kgsl_mem_timestamp_free(entry, id, timestamp);
+ trace_kgsl_mem_timestamp_free(entry, timestamp);
kgsl_mem_entry_detach_process(entry);
}
-static long _cmdstream_freememontimestamp(struct kgsl_device_private *dev_priv,
- unsigned int gpuaddr, struct kgsl_context *context,
- unsigned int timestamp, unsigned int type)
-{
- int result = 0;
- struct kgsl_mem_entry *entry = NULL;
- struct kgsl_device *device = dev_priv->device;
- unsigned int cur;
- unsigned int context_id = context ? context->id : KGSL_MEMSTORE_GLOBAL;
-
- spin_lock(&dev_priv->process_priv->mem_lock);
- entry = kgsl_sharedmem_find(dev_priv->process_priv, gpuaddr);
- spin_unlock(&dev_priv->process_priv->mem_lock);
-
- if (entry) {
- cur = device->ftbl->readtimestamp(device, context,
- KGSL_TIMESTAMP_RETIRED);
-
- trace_kgsl_mem_timestamp_queue(entry, context_id, cur);
- result = kgsl_add_event(dev_priv->device, context_id,
- timestamp, kgsl_freemem_event_cb,
- entry, dev_priv);
- } else {
- KGSL_DRV_ERR(dev_priv->device,
- "invalid gpuaddr %08x\n", gpuaddr);
- result = -EINVAL;
- }
-
- return result;
-}
-
static long kgsl_ioctl_cmdstream_freememontimestamp(struct kgsl_device_private
*dev_priv, unsigned int cmd,
void *data)
{
+ int result = 0;
struct kgsl_cmdstream_freememontimestamp *param = data;
+ struct kgsl_mem_entry *entry = NULL;
+ struct kgsl_device *device = dev_priv->device;
+ unsigned int cur;
- return _cmdstream_freememontimestamp(dev_priv, param->gpuaddr,
- NULL, param->timestamp, param->type);
-}
+ spin_lock(&dev_priv->process_priv->mem_lock);
+ entry = kgsl_sharedmem_find(dev_priv->process_priv, param->gpuaddr);
+ spin_unlock(&dev_priv->process_priv->mem_lock);
-static long kgsl_ioctl_cmdstream_freememontimestamp_ctxtid(
- struct kgsl_device_private
- *dev_priv, unsigned int cmd,
- void *data)
-{
- struct kgsl_cmdstream_freememontimestamp_ctxtid *param = data;
- struct kgsl_context *context;
+ if (entry) {
+ cur = device->ftbl->readtimestamp(device,
+ KGSL_TIMESTAMP_RETIRED);
- context = kgsl_find_context(dev_priv, param->context_id);
- if (context == NULL) {
+ trace_kgsl_mem_timestamp_queue(entry, cur);
+ result = kgsl_add_event(dev_priv->device, param->timestamp,
+ kgsl_freemem_event_cb, entry, dev_priv);
+ } else {
KGSL_DRV_ERR(dev_priv->device,
- "invalid drawctxt context_id %d\n", param->context_id);
- return -EINVAL;
+ "invalid gpuaddr %08x\n", param->gpuaddr);
+ result = -EINVAL;
}
- return _cmdstream_freememontimestamp(dev_priv, param->gpuaddr,
- context, param->timestamp, param->type);
+ return result;
}
static long kgsl_ioctl_drawctxt_create(struct kgsl_device_private *dev_priv,
@@ -1239,6 +1115,7 @@
context, param->flags);
param->drawctxt_id = context->id;
+
done:
if (result && context)
kgsl_destroy_context(dev_priv, context);
@@ -1936,14 +1813,13 @@
* kgsl_genlock_event_cb - Event callback for a genlock timestamp event
* @device - The KGSL device that expired the timestamp
* @priv - private data for the event
- * @context_id - the context id that goes with the timestamp
* @timestamp - the timestamp that triggered the event
*
* Release a genlock lock following the expiration of a timestamp
*/
static void kgsl_genlock_event_cb(struct kgsl_device *device,
- void *priv, u32 context_id, u32 timestamp)
+ void *priv, u32 timestamp)
{
struct kgsl_genlock_event_priv *ev = priv;
int ret;
@@ -1971,7 +1847,7 @@
*/
static int kgsl_add_genlock_event(struct kgsl_device *device,
- u32 context_id, u32 timestamp, void __user *data, int len,
+ u32 timestamp, void __user *data, int len,
struct kgsl_device_private *owner)
{
struct kgsl_genlock_event_priv *event;
@@ -1997,8 +1873,8 @@
return ret;
}
- ret = kgsl_add_event(device, context_id, timestamp,
- kgsl_genlock_event_cb, event, owner);
+ ret = kgsl_add_event(device, timestamp, kgsl_genlock_event_cb, event,
+ owner);
if (ret)
kfree(event);
@@ -2006,7 +1882,7 @@
}
#else
static long kgsl_add_genlock_event(struct kgsl_device *device,
- u32 context_id, u32 timestamp, void __user *data, int len,
+ u32 timestamp, void __user *data, int len,
struct kgsl_device_private *owner)
{
return -EINVAL;
@@ -2030,8 +1906,8 @@
switch (param->type) {
case KGSL_TIMESTAMP_EVENT_GENLOCK:
ret = kgsl_add_genlock_event(dev_priv->device,
- param->context_id, param->timestamp, param->priv,
- param->len, dev_priv);
+ param->timestamp, param->priv, param->len,
+ dev_priv);
break;
default:
ret = -EINVAL;
@@ -2055,18 +1931,12 @@
kgsl_ioctl_device_getproperty, 1),
KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_WAITTIMESTAMP,
kgsl_ioctl_device_waittimestamp, 1),
- KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID,
- kgsl_ioctl_device_waittimestamp_ctxtid, 1),
KGSL_IOCTL_FUNC(IOCTL_KGSL_RINGBUFFER_ISSUEIBCMDS,
kgsl_ioctl_rb_issueibcmds, 1),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_READTIMESTAMP,
kgsl_ioctl_cmdstream_readtimestamp, 1),
- KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_CTXTID,
- kgsl_ioctl_cmdstream_readtimestamp_ctxtid, 1),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP,
kgsl_ioctl_cmdstream_freememontimestamp, 1),
- KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP_CTXTID,
- kgsl_ioctl_cmdstream_freememontimestamp_ctxtid, 1),
KGSL_IOCTL_FUNC(IOCTL_KGSL_DRAWCTXT_CREATE,
kgsl_ioctl_drawctxt_create, 1),
KGSL_IOCTL_FUNC(IOCTL_KGSL_DRAWCTXT_DESTROY,
@@ -2396,13 +2266,13 @@
INIT_LIST_HEAD(&device->events);
- device->last_expired_ctxt_id = KGSL_CONTEXT_INVALID;
-
ret = kgsl_mmu_init(device);
if (ret != 0)
goto err_dest_work_q;
- ret = kgsl_allocate_contiguous(&device->memstore, KGSL_MEMSTORE_SIZE);
+ ret = kgsl_allocate_contiguous(&device->memstore,
+ sizeof(struct kgsl_devmemstore));
+
if (ret != 0)
goto err_close_mmu;
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index e908173..06f78fc 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -24,14 +24,6 @@
#define KGSL_NAME "kgsl"
-/* The number of memstore arrays limits the number of contexts allowed.
- * If more contexts are needed, update multiple for MEMSTORE_SIZE
- */
-#define KGSL_MEMSTORE_SIZE ((int)(PAGE_SIZE * 2))
-#define KGSL_MEMSTORE_GLOBAL (0)
-#define KGSL_MEMSTORE_MAX (KGSL_MEMSTORE_SIZE / \
- sizeof(struct kgsl_devmemstore) - 1)
-
/*cache coherency ops */
#define DRM_KGSL_GEM_CACHE_OP_TO_DEV 0x0001
#define DRM_KGSL_GEM_CACHE_OP_FROM_DEV 0x0002
@@ -146,7 +138,6 @@
void *priv_data;
struct list_head list;
uint32_t free_timestamp;
- unsigned int context_id;
/* back pointer to private structure under whose context this
* allocation is made */
struct kgsl_process_private *priv;
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index d63709d..2eacf22 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -76,10 +76,9 @@
enum kgsl_property_type type, void *value,
unsigned int sizebytes);
int (*waittimestamp) (struct kgsl_device *device,
- struct kgsl_context *context, unsigned int timestamp,
- unsigned int msecs);
+ unsigned int timestamp, unsigned int msecs);
unsigned int (*readtimestamp) (struct kgsl_device *device,
- struct kgsl_context *context, enum kgsl_timestamp_type type);
+ enum kgsl_timestamp_type type);
int (*issueibcmds) (struct kgsl_device_private *dev_priv,
struct kgsl_context *context, struct kgsl_ibdesc *ibdesc,
unsigned int sizedwords, uint32_t *timestamp,
@@ -124,9 +123,8 @@
};
struct kgsl_event {
- struct kgsl_context *context;
uint32_t timestamp;
- void (*func)(struct kgsl_device *, void *, u32, u32);
+ void (*func)(struct kgsl_device *, void *, u32);
void *priv;
struct list_head list;
struct kgsl_device_private *owner;
@@ -158,7 +156,6 @@
uint32_t state;
uint32_t requested_state;
- unsigned int last_expired_ctxt_id;
unsigned int active_cnt;
struct completion suspend_gate;
@@ -333,8 +330,7 @@
return (ctxt && ctxt->dev_priv == dev_priv) ? ctxt : NULL;
}
-int kgsl_check_timestamp(struct kgsl_device *device,
- struct kgsl_context *context, unsigned int timestamp);
+int kgsl_check_timestamp(struct kgsl_device *device, unsigned int timestamp);
int kgsl_register_ts_notifier(struct kgsl_device *device,
struct notifier_block *nb);
diff --git a/drivers/gpu/msm/kgsl_drm.c b/drivers/gpu/msm/kgsl_drm.c
index 8a38587..03f8c42 100644
--- a/drivers/gpu/msm/kgsl_drm.c
+++ b/drivers/gpu/msm/kgsl_drm.c
@@ -1397,7 +1397,7 @@
}
device = kgsl_get_device(ts_device);
- ts_done = kgsl_check_timestamp(device, NULL, args->timestamp);
+ ts_done = kgsl_check_timestamp(device, args->timestamp);
mutex_lock(&dev->struct_mutex);
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index 97b5ef1..98216f8 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -682,7 +682,7 @@
flushtlb = 1;
for_each_sg(memdesc->sg, s, memdesc->sglen, i) {
- unsigned int paddr = sg_phys(s);
+ unsigned int paddr = kgsl_get_sg_pa(s);
unsigned int j;
/* Each sg entry might be multiple pages long */
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 0ea52c4..319addb 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -556,8 +556,11 @@
return -ENOMEM;
}
- spin_lock(&pagetable->lock);
+ if (KGSL_MMU_TYPE_IOMMU != kgsl_mmu_get_mmutype())
+ spin_lock(&pagetable->lock);
ret = pagetable->pt_ops->mmu_map(pagetable->priv, memdesc, protflags);
+ if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype())
+ spin_lock(&pagetable->lock);
if (ret)
goto err_free_gpuaddr;
@@ -593,8 +596,11 @@
memdesc->gpuaddr = 0;
return 0;
}
- spin_lock(&pagetable->lock);
+ if (KGSL_MMU_TYPE_IOMMU != kgsl_mmu_get_mmutype())
+ spin_lock(&pagetable->lock);
pagetable->pt_ops->mmu_unmap(pagetable->priv, memdesc);
+ if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype())
+ spin_lock(&pagetable->lock);
/* Remove the statistics */
pagetable->stats.entries--;
pagetable->stats.mapped -= memdesc->size;
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index f61a196..d083702 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -284,7 +284,7 @@
int i;
for_each_sg(sg, s, sglen, i) {
- unsigned int paddr = sg_phys(s);
+ unsigned int paddr = kgsl_get_sg_pa(s);
_outer_cache_range_op(op, paddr, s->length);
}
}
diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h
index af0d74d..a1e4c91 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.h
+++ b/drivers/gpu/msm/kgsl_sharedmem.h
@@ -80,12 +80,22 @@
int kgsl_sharedmem_init_sysfs(void);
void kgsl_sharedmem_uninit_sysfs(void);
+static inline unsigned int kgsl_get_sg_pa(struct scatterlist *sg)
+{
+ /*
+ * Try sg_dma_address first to support ion carveout
+ * regions which do not work with sg_phys().
+ */
+ unsigned int pa = sg_dma_address(sg);
+ if (pa == 0)
+ pa = sg_phys(sg);
+ return pa;
+}
+
static inline int
memdesc_sg_phys(struct kgsl_memdesc *memdesc,
unsigned int physaddr, unsigned int size)
{
- struct page *page = phys_to_page(physaddr);
-
memdesc->sg = vmalloc(sizeof(struct scatterlist) * 1);
if (memdesc->sg == NULL)
return -ENOMEM;
@@ -94,7 +104,9 @@
memdesc->sglen = 1;
sg_init_table(memdesc->sg, 1);
- sg_set_page(&memdesc->sg[0], page, size, 0);
+ memdesc->sg[0].length = size;
+ memdesc->sg[0].offset = 0;
+ memdesc->sg[0].dma_address = physaddr;
return 0;
}
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index c24576d..cfcb2ea 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -64,7 +64,7 @@
header->timestamp_queued = -1;
header->timestamp_retired = device->ftbl->readtimestamp(device,
- context, KGSL_TIMESTAMP_RETIRED);
+ KGSL_TIMESTAMP_RETIRED);
_ctxtptr += sizeof(struct kgsl_snapshot_linux_context);
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index 84d7f94..22bc576 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -76,30 +76,25 @@
TRACE_EVENT(kgsl_readtimestamp,
TP_PROTO(struct kgsl_device *device,
- unsigned int context_id,
- unsigned int type,
- unsigned int timestamp),
+ struct kgsl_cmdstream_readtimestamp *cmd),
- TP_ARGS(device, context_id, type, timestamp),
+ TP_ARGS(device, cmd),
TP_STRUCT__entry(
__string(device_name, device->name)
- __field(unsigned int, context_id)
__field(unsigned int, type)
__field(unsigned int, timestamp)
),
TP_fast_assign(
__assign_str(device_name, device->name);
- __entry->context_id = context_id;
- __entry->type = type;
- __entry->timestamp = timestamp;
+ __entry->type = cmd->type;
+ __entry->timestamp = cmd->timestamp;
),
TP_printk(
- "d_name=%s context_id=%u type=%u timestamp=%u",
+ "d_name=%s type=%u timestamp=%u",
__get_str(device_name),
- __entry->context_id,
__entry->type,
__entry->timestamp
)
@@ -111,30 +106,25 @@
TRACE_EVENT(kgsl_waittimestamp_entry,
TP_PROTO(struct kgsl_device *device,
- unsigned int context_id,
- unsigned int timestamp,
- unsigned int timeout),
+ struct kgsl_device_waittimestamp *cmd),
- TP_ARGS(device, context_id, timestamp, timeout),
+ TP_ARGS(device, cmd),
TP_STRUCT__entry(
__string(device_name, device->name)
- __field(unsigned int, context_id)
__field(unsigned int, timestamp)
__field(unsigned int, timeout)
),
TP_fast_assign(
__assign_str(device_name, device->name);
- __entry->context_id = context_id;
- __entry->timestamp = timestamp;
- __entry->timeout = timeout;
+ __entry->timestamp = cmd->timestamp;
+ __entry->timeout = cmd->timeout;
),
TP_printk(
- "d_name=%s context_id=%u timestamp=%u timeout=%u",
+ "d_name=%s timestamp=%u timeout=%u",
__get_str(device_name),
- __entry->context_id,
__entry->timestamp,
__entry->timeout
)
@@ -343,10 +333,9 @@
DECLARE_EVENT_CLASS(kgsl_mem_timestamp_template,
- TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int id,
- unsigned int curr_ts),
+ TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int curr_ts),
- TP_ARGS(mem_entry, id, curr_ts),
+ TP_ARGS(mem_entry, curr_ts),
TP_STRUCT__entry(
__field(unsigned int, gpuaddr)
@@ -360,7 +349,7 @@
TP_fast_assign(
__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
__entry->size = mem_entry->memdesc.size;
- __entry->drawctxt_id = id;
+ __entry->drawctxt_id = 1337;
__entry->type = mem_entry->memtype;
__entry->curr_ts = curr_ts;
__entry->free_ts = mem_entry->free_timestamp;
@@ -374,15 +363,13 @@
);
DEFINE_EVENT(kgsl_mem_timestamp_template, kgsl_mem_timestamp_queue,
- TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int id,
- unsigned int curr_ts),
- TP_ARGS(mem_entry, id, curr_ts)
+ TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int curr_ts),
+ TP_ARGS(mem_entry, curr_ts)
);
DEFINE_EVENT(kgsl_mem_timestamp_template, kgsl_mem_timestamp_free,
- TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int id,
- unsigned int curr_ts),
- TP_ARGS(mem_entry, id, curr_ts)
+ TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int curr_ts),
+ TP_ARGS(mem_entry, curr_ts)
);
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 02cf734..6c43a75 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -101,7 +101,6 @@
static int z180_start(struct kgsl_device *device, unsigned int init_ram);
static int z180_stop(struct kgsl_device *device);
static int z180_wait(struct kgsl_device *device,
- struct kgsl_context *context,
unsigned int timestamp,
unsigned int msecs);
static void z180_regread(struct kgsl_device *device,
@@ -386,8 +385,8 @@
if (timestamp_cmp(z180_dev->current_timestamp,
z180_dev->timestamp) > 0)
- status = z180_wait(device, NULL,
- z180_dev->current_timestamp, timeout);
+ status = z180_wait(device, z180_dev->current_timestamp,
+ timeout);
if (status)
KGSL_DRV_ERR(device, "z180_waittimestamp() timed out\n");
@@ -799,16 +798,14 @@
}
static unsigned int z180_readtimestamp(struct kgsl_device *device,
- struct kgsl_context *context, enum kgsl_timestamp_type type)
+ enum kgsl_timestamp_type type)
{
struct z180_device *z180_dev = Z180_DEVICE(device);
- (void)context;
/* get current EOP timestamp */
return z180_dev->timestamp;
}
static int z180_waittimestamp(struct kgsl_device *device,
- struct kgsl_context *context,
unsigned int timestamp,
unsigned int msecs)
{
@@ -819,14 +816,13 @@
msecs = 10 * MSEC_PER_SEC;
mutex_unlock(&device->mutex);
- status = z180_wait(device, context, timestamp, msecs);
+ status = z180_wait(device, timestamp, msecs);
mutex_lock(&device->mutex);
return status;
}
static int z180_wait(struct kgsl_device *device,
- struct kgsl_context *context,
unsigned int timestamp,
unsigned int msecs)
{
@@ -835,7 +831,7 @@
timeout = wait_io_event_interruptible_timeout(
device->wait_queue,
- kgsl_check_timestamp(device, context, timestamp),
+ kgsl_check_timestamp(device, timestamp),
msecs_to_jiffies(msecs));
if (timeout > 0)
diff --git a/drivers/hwmon/pm8xxx-adc.c b/drivers/hwmon/pm8xxx-adc.c
index 0902c61..2f59235 100644
--- a/drivers/hwmon/pm8xxx-adc.c
+++ b/drivers/hwmon/pm8xxx-adc.c
@@ -131,7 +131,6 @@
struct mutex adc_lock;
struct mutex mpp_adc_lock;
spinlock_t btm_lock;
- uint32_t adc_num_channel;
uint32_t adc_num_board_channel;
struct completion adc_rslt_completion;
struct pm8xxx_adc_amux *adc_channel;
@@ -201,6 +200,17 @@
static bool pm8xxx_adc_calib_first_adc;
static bool pm8xxx_adc_initialized, pm8xxx_adc_calib_device_init;
+static int32_t pm8xxx_adc_check_channel_valid(uint32_t channel)
+{
+ if (channel < CHANNEL_VCOIN ||
+ (channel > CHANNEL_MUXOFF && channel < ADC_MPP_1_ATEST_8) ||
+ (channel > ADC_MPP_1_ATEST_7 && channel < ADC_MPP_2_ATEST_8)
+ || (channel >= ADC_CHANNEL_MAX_NUM))
+ return -EBADF;
+ else
+ return 0;
+}
+
static int32_t pm8xxx_adc_arb_cntrl(uint32_t arb_cntrl,
uint32_t channel)
{
@@ -675,12 +685,13 @@
mutex_lock(&adc_pmic->adc_lock);
- for (i = 0; i < adc_pmic->adc_num_channel; i++) {
+ for (i = 0; i < adc_pmic->adc_num_board_channel; i++) {
if (channel == adc_pmic->adc_channel[i].channel_name)
break;
}
- if (i == adc_pmic->adc_num_channel) {
+ if (i == adc_pmic->adc_num_board_channel ||
+ (pm8xxx_adc_check_channel_valid(channel) != 0)) {
rc = -EBADF;
goto fail_unlock;
}
@@ -1001,12 +1012,10 @@
struct device_attribute *devattr, char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct pm8xxx_adc *adc_pmic = pmic_adc;
struct pm8xxx_adc_chan_result result;
int rc = -1;
- if (attr->index < adc_pmic->adc_num_channel)
- rc = pm8xxx_adc_read(attr->index, &result);
+ rc = pm8xxx_adc_read(attr->index, &result);
if (rc)
return 0;
@@ -1076,9 +1085,14 @@
static int32_t pm8xxx_adc_init_hwmon(struct platform_device *pdev)
{
struct pm8xxx_adc *adc_pmic = pmic_adc;
- int rc = 0, i;
+ int rc = 0, i, channel;
for (i = 0; i < pmic_adc->adc_num_board_channel; i++) {
+ channel = adc_pmic->adc_channel[i].channel_name;
+ if (pm8xxx_adc_check_channel_valid(channel)) {
+ pr_err("Invalid ADC init HWMON channel: %d\n", channel);
+ continue;
+ }
pm8xxx_adc_attr.index = adc_pmic->adc_channel[i].channel_name;
pm8xxx_adc_attr.dev_attr.attr.name =
adc_pmic->adc_channel[i].name;
@@ -1184,7 +1198,6 @@
init_completion(&adc_pmic->adc_rslt_completion);
adc_pmic->adc_channel = pdata->adc_channel;
adc_pmic->adc_num_board_channel = pdata->adc_num_board_channel;
- adc_pmic->adc_num_channel = ADC_MPP_2_CHANNEL_NONE;
adc_pmic->mpp_base = pdata->adc_mpp_base;
mutex_init(&adc_pmic->adc_lock);
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 87cdb02..eef0891 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -817,4 +817,18 @@
To compile this driver as a module, choose M here: the
module will be called cyttsp-i2c.
+
+config TOUCHSCREEN_FT5X06
+ tristate "FocalTech touchscreens"
+ depends on I2C
+ help
+ Say Y here if you have a ft5X06 touchscreen.
+ Ft5x06 controllers are multi touch controllers which can
+ report 5 touches at a time.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ft5x06_ts.
+
endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 1d67427..616b3a4 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -26,6 +26,7 @@
obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
obj-$(CONFIG_TOUCHSCREEN_ELAN_I2C_8232) += elan8232_i2c.o
obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
+obj-$(CONFIG_TOUCHSCREEN_FT5X06) += ft5x06_ts.o
obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
new file mode 100644
index 0000000..c9905a4
--- /dev/null
+++ b/drivers/input/touchscreen/ft5x06_ts.c
@@ -0,0 +1,654 @@
+/*
+ *
+ * FocalTech ft5x06 TouchScreen driver.
+ *
+ * Copyright (c) 2010 Focal tech Ltd.
+ * Copyright (c) 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
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/i2c.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/input/ft5x06_ts.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+/* Early-suspend level */
+#define FT5X06_SUSPEND_LEVEL 1
+#endif
+
+#define CFG_MAX_TOUCH_POINTS 5
+
+#define FT_STARTUP_DLY 150
+#define FT_RESET_DLY 20
+
+#define FT_PRESS 0x7F
+#define FT_MAX_ID 0x0F
+#define FT_TOUCH_STEP 6
+#define FT_TOUCH_X_H_POS 3
+#define FT_TOUCH_X_L_POS 4
+#define FT_TOUCH_Y_H_POS 5
+#define FT_TOUCH_Y_L_POS 6
+#define FT_TOUCH_EVENT_POS 3
+#define FT_TOUCH_ID_POS 5
+
+#define POINT_READ_BUF (3 + FT_TOUCH_STEP * CFG_MAX_TOUCH_POINTS)
+
+/*register address*/
+#define FT5X06_REG_PMODE 0xA5
+#define FT5X06_REG_FW_VER 0xA6
+#define FT5X06_REG_POINT_RATE 0x88
+#define FT5X06_REG_THGROUP 0x80
+
+/* power register bits*/
+#define FT5X06_PMODE_ACTIVE 0x00
+#define FT5X06_PMODE_MONITOR 0x01
+#define FT5X06_PMODE_STANDBY 0x02
+#define FT5X06_PMODE_HIBERNATE 0x03
+
+#define FT5X06_VTG_MIN_UV 2600000
+#define FT5X06_VTG_MAX_UV 3300000
+#define FT5X06_I2C_VTG_MIN_UV 1800000
+#define FT5X06_I2C_VTG_MAX_UV 1800000
+
+struct ts_event {
+ u16 x[CFG_MAX_TOUCH_POINTS]; /*x coordinate */
+ u16 y[CFG_MAX_TOUCH_POINTS]; /*y coordinate */
+ /* touch event: 0 -- down; 1-- contact; 2 -- contact */
+ u8 touch_event[CFG_MAX_TOUCH_POINTS];
+ u8 finger_id[CFG_MAX_TOUCH_POINTS]; /*touch ID */
+ u16 pressure;
+ u8 touch_point;
+};
+
+struct ft5x06_ts_data {
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct ts_event event;
+ const struct ft5x06_ts_platform_data *pdata;
+ struct regulator *vdd;
+ struct regulator *vcc_i2c;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+};
+
+static int ft5x06_i2c_read(struct i2c_client *client, char *writebuf,
+ int writelen, char *readbuf, int readlen)
+{
+ int ret;
+
+ if (writelen > 0) {
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = writelen,
+ .buf = writebuf,
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = readlen,
+ .buf = readbuf,
+ },
+ };
+ ret = i2c_transfer(client->adapter, msgs, 2);
+ if (ret < 0)
+ dev_err(&client->dev, "%s: i2c read error.\n",
+ __func__);
+ } else {
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = readlen,
+ .buf = readbuf,
+ },
+ };
+ ret = i2c_transfer(client->adapter, msgs, 1);
+ if (ret < 0)
+ dev_err(&client->dev, "%s:i2c read error.\n", __func__);
+ }
+ return ret;
+}
+
+static int ft5x06_i2c_write(struct i2c_client *client, char *writebuf,
+ int writelen)
+{
+ int ret;
+
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = writelen,
+ .buf = writebuf,
+ },
+ };
+ ret = i2c_transfer(client->adapter, msgs, 1);
+ if (ret < 0)
+ dev_err(&client->dev, "%s: i2c write error.\n", __func__);
+
+ return ret;
+}
+
+static void ft5x06_report_value(struct ft5x06_ts_data *data)
+{
+ struct ts_event *event = &data->event;
+ int i;
+ int fingerdown = 0;
+
+ for (i = 0; i < event->touch_point; i++) {
+ if (event->touch_event[i] == 0 || event->touch_event[i] == 2) {
+ event->pressure = FT_PRESS;
+ fingerdown++;
+ } else {
+ event->pressure = 0;
+ }
+
+ input_report_abs(data->input_dev, ABS_MT_POSITION_X,
+ event->x[i]);
+ input_report_abs(data->input_dev, ABS_MT_POSITION_Y,
+ event->y[i]);
+ input_report_abs(data->input_dev, ABS_MT_PRESSURE,
+ event->pressure);
+ input_report_abs(data->input_dev, ABS_MT_TRACKING_ID,
+ event->finger_id[i]);
+ input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,
+ event->pressure);
+ input_mt_sync(data->input_dev);
+ }
+
+ input_report_key(data->input_dev, BTN_TOUCH, !!fingerdown);
+ input_sync(data->input_dev);
+}
+
+static int ft5x06_handle_touchdata(struct ft5x06_ts_data *data)
+{
+ struct ts_event *event = &data->event;
+ int ret, i;
+ u8 buf[POINT_READ_BUF] = { 0 };
+ u8 pointid = FT_MAX_ID;
+
+ ret = ft5x06_i2c_read(data->client, buf, 1, buf, POINT_READ_BUF);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "%s read touchdata failed.\n",
+ __func__);
+ return ret;
+ }
+ memset(event, 0, sizeof(struct ts_event));
+
+ event->touch_point = 0;
+ for (i = 0; i < CFG_MAX_TOUCH_POINTS; i++) {
+ pointid = (buf[FT_TOUCH_ID_POS + FT_TOUCH_STEP * i]) >> 4;
+ if (pointid >= FT_MAX_ID)
+ break;
+ else
+ event->touch_point++;
+ event->x[i] =
+ (s16) (buf[FT_TOUCH_X_H_POS + FT_TOUCH_STEP * i] & 0x0F) <<
+ 8 | (s16) buf[FT_TOUCH_X_L_POS + FT_TOUCH_STEP * i];
+ event->y[i] =
+ (s16) (buf[FT_TOUCH_Y_H_POS + FT_TOUCH_STEP * i] & 0x0F) <<
+ 8 | (s16) buf[FT_TOUCH_Y_L_POS + FT_TOUCH_STEP * i];
+ event->touch_event[i] =
+ buf[FT_TOUCH_EVENT_POS + FT_TOUCH_STEP * i] >> 6;
+ event->finger_id[i] =
+ (buf[FT_TOUCH_ID_POS + FT_TOUCH_STEP * i]) >> 4;
+ }
+
+ ft5x06_report_value(data);
+
+ return 0;
+}
+
+static irqreturn_t ft5x06_ts_interrupt(int irq, void *dev_id)
+{
+ struct ft5x06_ts_data *data = dev_id;
+ int rc;
+
+ rc = ft5x06_handle_touchdata(data);
+ if (rc)
+ pr_err("%s: handling touchdata failed\n", __func__);
+
+ return IRQ_HANDLED;
+}
+
+static int ft5x06_power_on(struct ft5x06_ts_data *data, bool on)
+{
+ int rc;
+
+ if (!on)
+ goto power_off;
+
+ rc = regulator_enable(data->vdd);
+ if (rc) {
+ dev_err(&data->client->dev,
+ "Regulator vdd enable failed rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = regulator_enable(data->vcc_i2c);
+ if (rc) {
+ dev_err(&data->client->dev,
+ "Regulator vcc_i2c enable failed rc=%d\n", rc);
+ regulator_disable(data->vdd);
+ }
+
+ return rc;
+
+power_off:
+ rc = regulator_disable(data->vdd);
+ if (rc) {
+ dev_err(&data->client->dev,
+ "Regulator vdd disable failed rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = regulator_disable(data->vcc_i2c);
+ if (rc) {
+ dev_err(&data->client->dev,
+ "Regulator vcc_i2c disable failed rc=%d\n", rc);
+ regulator_enable(data->vdd);
+ }
+
+ return rc;
+}
+
+static int ft5x06_power_init(struct ft5x06_ts_data *data, bool on)
+{
+ int rc;
+
+ if (!on)
+ goto pwr_deinit;
+
+ data->vdd = regulator_get(&data->client->dev, "vdd");
+ if (IS_ERR(data->vdd)) {
+ rc = PTR_ERR(data->vdd);
+ dev_err(&data->client->dev,
+ "Regulator get failed vdd rc=%d\n", rc);
+ return rc;
+ }
+
+ if (regulator_count_voltages(data->vdd) > 0) {
+ rc = regulator_set_voltage(data->vdd, FT5X06_VTG_MIN_UV,
+ FT5X06_VTG_MAX_UV);
+ if (rc) {
+ dev_err(&data->client->dev,
+ "Regulator set_vtg failed vdd rc=%d\n", rc);
+ goto reg_vdd_put;
+ }
+ }
+
+ data->vcc_i2c = regulator_get(&data->client->dev, "vcc_i2c");
+ if (IS_ERR(data->vcc_i2c)) {
+ rc = PTR_ERR(data->vcc_i2c);
+ dev_err(&data->client->dev,
+ "Regulator get failed vcc_i2c rc=%d\n", rc);
+ goto reg_vdd_set_vtg;
+ }
+
+ if (regulator_count_voltages(data->vcc_i2c) > 0) {
+ rc = regulator_set_voltage(data->vcc_i2c, FT5X06_I2C_VTG_MIN_UV,
+ FT5X06_I2C_VTG_MAX_UV);
+ if (rc) {
+ dev_err(&data->client->dev,
+ "Regulator set_vtg failed vcc_i2c rc=%d\n", rc);
+ goto reg_vcc_i2c_put;
+ }
+ }
+
+ return 0;
+
+reg_vcc_i2c_put:
+ regulator_put(data->vcc_i2c);
+reg_vdd_set_vtg:
+ if (regulator_count_voltages(data->vdd) > 0)
+ regulator_set_voltage(data->vdd, 0, FT5X06_VTG_MAX_UV);
+reg_vdd_put:
+ regulator_put(data->vdd);
+ return rc;
+
+pwr_deinit:
+ if (regulator_count_voltages(data->vdd) > 0)
+ regulator_set_voltage(data->vdd, 0, FT5X06_VTG_MAX_UV);
+
+ regulator_put(data->vdd);
+
+ if (regulator_count_voltages(data->vcc_i2c) > 0)
+ regulator_set_voltage(data->vcc_i2c, 0, FT5X06_I2C_VTG_MAX_UV);
+
+ regulator_put(data->vcc_i2c);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ft5x06_ts_suspend(struct device *dev)
+{
+ struct ft5x06_ts_data *data = dev_get_drvdata(dev);
+ char txbuf[2];
+
+ disable_irq(data->client->irq);
+
+ if (gpio_is_valid(data->pdata->reset_gpio)) {
+ txbuf[0] = FT5X06_REG_PMODE;
+ txbuf[1] = FT5X06_PMODE_HIBERNATE;
+ ft5x06_i2c_write(data->client, txbuf, sizeof(txbuf));
+ }
+
+ return 0;
+}
+
+static int ft5x06_ts_resume(struct device *dev)
+{
+ struct ft5x06_ts_data *data = dev_get_drvdata(dev);
+
+ if (gpio_is_valid(data->pdata->reset_gpio)) {
+ gpio_set_value_cansleep(data->pdata->reset_gpio, 0);
+ msleep(FT_RESET_DLY);
+ gpio_set_value_cansleep(data->pdata->reset_gpio, 1);
+ }
+ enable_irq(data->client->irq);
+
+ return 0;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void ft5x06_ts_early_suspend(struct early_suspend *handler)
+{
+ struct ft5x06_ts_data *data = container_of(handler,
+ struct ft5x06_ts_data,
+ early_suspend);
+
+ ft5x06_ts_suspend(&data->client->dev);
+}
+
+static void ft5x06_ts_late_resume(struct early_suspend *handler)
+{
+ struct ft5x06_ts_data *data = container_of(handler,
+ struct ft5x06_ts_data,
+ early_suspend);
+
+ ft5x06_ts_resume(&data->client->dev);
+}
+#endif
+
+static const struct dev_pm_ops ft5x06_ts_pm_ops = {
+#ifndef CONFIG_HAS_EARLYSUSPEND
+ .suspend = ft5x06_ts_suspend,
+ .resume = ft5x06_ts_resume,
+#endif
+};
+#endif
+
+static int ft5x06_ts_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ const struct ft5x06_ts_platform_data *pdata = client->dev.platform_data;
+ struct ft5x06_ts_data *data;
+ struct input_dev *input_dev;
+ u8 reg_value;
+ u8 reg_addr;
+ int err;
+
+ if (!pdata) {
+ dev_err(&client->dev, "Invalid pdata\n");
+ return -EINVAL;
+ }
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "I2C not supported\n");
+ return -ENODEV;
+ }
+
+ data = kzalloc(sizeof(struct ft5x06_ts_data), GFP_KERNEL);
+ if (!data) {
+ dev_err(&client->dev, "Not enough memory\n");
+ return -ENOMEM;
+ }
+
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ err = -ENOMEM;
+ dev_err(&client->dev, "failed to allocate input device\n");
+ goto free_mem;
+ }
+
+ data->input_dev = input_dev;
+ data->client = client;
+ data->pdata = pdata;
+
+ input_dev->name = "ft5x06_ts";
+ input_dev->id.bustype = BUS_I2C;
+ input_dev->dev.parent = &client->dev;
+
+ input_set_drvdata(input_dev, data);
+ i2c_set_clientdata(client, data);
+
+ __set_bit(EV_KEY, input_dev->evbit);
+ __set_bit(EV_ABS, input_dev->evbit);
+ __set_bit(BTN_TOUCH, input_dev->keybit);
+
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
+ pdata->x_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
+ pdata->y_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
+ CFG_MAX_TOUCH_POINTS, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, FT_PRESS, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, FT_PRESS, 0, 0);
+
+ err = input_register_device(input_dev);
+ if (err) {
+ dev_err(&client->dev, "Input device registration failed\n");
+ goto free_inputdev;
+ }
+
+ if (pdata->power_init) {
+ err = pdata->power_init(true);
+ if (err) {
+ dev_err(&client->dev, "power init failed");
+ goto unreg_inputdev;
+ }
+ } else {
+ err = ft5x06_power_init(data, true);
+ if (err) {
+ dev_err(&client->dev, "power init failed");
+ goto unreg_inputdev;
+ }
+ }
+
+ if (pdata->power_on) {
+ err = pdata->power_on(true);
+ if (err) {
+ dev_err(&client->dev, "power on failed");
+ goto pwr_deinit;
+ }
+ } else {
+ err = ft5x06_power_on(data, true);
+ if (err) {
+ dev_err(&client->dev, "power on failed");
+ goto pwr_deinit;
+ }
+ }
+
+ if (gpio_is_valid(pdata->irq_gpio)) {
+ err = gpio_request(pdata->irq_gpio, "ft5x06_irq_gpio");
+ if (err) {
+ dev_err(&client->dev, "irq gpio request failed");
+ goto pwr_off;
+ }
+ err = gpio_direction_input(pdata->irq_gpio);
+ if (err) {
+ dev_err(&client->dev,
+ "set_direction for irq gpio failed\n");
+ goto free_irq_gpio;
+ }
+ }
+
+ if (gpio_is_valid(pdata->reset_gpio)) {
+ err = gpio_request(pdata->reset_gpio, "ft5x06_reset_gpio");
+ if (err) {
+ dev_err(&client->dev, "reset gpio request failed");
+ goto free_irq_gpio;
+ }
+
+ err = gpio_direction_output(pdata->reset_gpio, 0);
+ if (err) {
+ dev_err(&client->dev,
+ "set_direction for reset gpio failed\n");
+ goto free_reset_gpio;
+ }
+ msleep(FT_RESET_DLY);
+ gpio_set_value_cansleep(data->pdata->reset_gpio, 1);
+ }
+
+ /* make sure CTP already finish startup process */
+ msleep(FT_STARTUP_DLY);
+
+ /*get some register information */
+ reg_addr = FT5X06_REG_FW_VER;
+ err = ft5x06_i2c_read(client, ®_addr, 1, ®_value, 1);
+ if (err)
+ dev_err(&client->dev, "version read failed");
+
+ dev_info(&client->dev, "[FTS] Firmware version = 0x%x\n", reg_value);
+
+ reg_addr = FT5X06_REG_POINT_RATE;
+ ft5x06_i2c_read(client, ®_addr, 1, ®_value, 1);
+ if (err)
+ dev_err(&client->dev, "report rate read failed");
+ dev_info(&client->dev, "[FTS] report rate is %dHz.\n", reg_value * 10);
+
+ reg_addr = FT5X06_REG_THGROUP;
+ err = ft5x06_i2c_read(client, ®_addr, 1, ®_value, 1);
+ if (err)
+ dev_err(&client->dev, "threshold read failed");
+ dev_dbg(&client->dev, "[FTS] touch threshold is %d.\n", reg_value * 4);
+
+ err = request_threaded_irq(client->irq, NULL,
+ ft5x06_ts_interrupt, pdata->irqflags,
+ client->dev.driver->name, data);
+ if (err) {
+ dev_err(&client->dev, "request irq failed\n");
+ goto free_reset_gpio;
+ }
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
+ FT5X06_SUSPEND_LEVEL;
+ data->early_suspend.suspend = ft5x06_ts_early_suspend;
+ data->early_suspend.resume = ft5x06_ts_late_resume;
+ register_early_suspend(&data->early_suspend);
+#endif
+
+ return 0;
+
+free_reset_gpio:
+ if (gpio_is_valid(pdata->reset_gpio))
+ gpio_free(pdata->reset_gpio);
+free_irq_gpio:
+ if (gpio_is_valid(pdata->irq_gpio))
+ gpio_free(pdata->reset_gpio);
+pwr_off:
+ if (pdata->power_on)
+ pdata->power_on(false);
+ else
+ ft5x06_power_on(data, false);
+pwr_deinit:
+ if (pdata->power_init)
+ pdata->power_init(false);
+ else
+ ft5x06_power_init(data, false);
+unreg_inputdev:
+ input_unregister_device(input_dev);
+ input_dev = NULL;
+free_inputdev:
+ input_free_device(input_dev);
+free_mem:
+ kfree(data);
+ return err;
+}
+
+static int __devexit ft5x06_ts_remove(struct i2c_client *client)
+{
+ struct ft5x06_ts_data *data = i2c_get_clientdata(client);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&data->early_suspend);
+#endif
+ free_irq(client->irq, data);
+
+ if (gpio_is_valid(data->pdata->reset_gpio))
+ gpio_free(data->pdata->reset_gpio);
+
+ if (gpio_is_valid(data->pdata->irq_gpio))
+ gpio_free(data->pdata->reset_gpio);
+
+ if (data->pdata->power_on)
+ data->pdata->power_on(false);
+ else
+ ft5x06_power_on(data, false);
+
+ if (data->pdata->power_init)
+ data->pdata->power_init(false);
+ else
+ ft5x06_power_init(data, false);
+
+ input_unregister_device(data->input_dev);
+ kfree(data);
+
+ return 0;
+}
+
+static const struct i2c_device_id ft5x06_ts_id[] = {
+ {"ft5x06_ts", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ft5x06_ts_id);
+
+static struct i2c_driver ft5x06_ts_driver = {
+ .probe = ft5x06_ts_probe,
+ .remove = __devexit_p(ft5x06_ts_remove),
+ .driver = {
+ .name = "ft5x06_ts",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &ft5x06_ts_pm_ops,
+#endif
+ },
+ .id_table = ft5x06_ts_id,
+};
+
+static int __init ft5x06_ts_init(void)
+{
+ return i2c_add_driver(&ft5x06_ts_driver);
+}
+module_init(ft5x06_ts_init);
+
+static void __exit ft5x06_ts_exit(void)
+{
+ i2c_del_driver(&ft5x06_ts_driver);
+}
+module_exit(ft5x06_ts_exit);
+
+MODULE_DESCRIPTION("FocalTech ft5x06 TouchScreen driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index 288ec6d..fb73321 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -3001,7 +3001,7 @@
* queue the READY event from the host side
* in case of FM off
*/
- tavarua_q_event(radio, TAVARUA_EVT_RADIO_READY);
+ tavarua_q_event(radio, TAVARUA_EVT_RADIO_DISABLED);
FMDBG("%s, Disable All Interrupts\n", __func__);
/* disable irq */
diff --git a/drivers/media/video/msm/csi/msm_csic.c b/drivers/media/video/msm/csi/msm_csic.c
index 476615d..3a642c7 100644
--- a/drivers/media/video/msm/csi/msm_csic.c
+++ b/drivers/media/video/msm/csi/msm_csic.c
@@ -142,6 +142,7 @@
struct csic_device *csic_dev;
struct msm_camera_csi_params *csic_params;
void __iomem *csicbase;
+ int i;
csic_dev = v4l2_get_subdevdata(cfg_params->subdev);
csicbase = csic_dev->base;
@@ -163,24 +164,14 @@
CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val);
msm_io_w(val, csicbase + MIPI_PROTOCOL_CONTROL);
- val = (0x1 << MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT) |
- (0x1 <<
- MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT) |
- (0x1 << MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT) |
- (0x1 << MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT);
- CDBG("%s MIPI_CALIBRATION_CONTROL val=0x%x\n", __func__, val);
- msm_io_w(val, csicbase + MIPI_CALIBRATION_CONTROL);
-
val = (csic_params->settle_cnt <<
MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
(0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
- msm_io_w(val, csicbase + MIPI_PHY_D0_CONTROL2);
- msm_io_w(val, csicbase + MIPI_PHY_D1_CONTROL2);
- msm_io_w(val, csicbase + MIPI_PHY_D2_CONTROL2);
- msm_io_w(val, csicbase + MIPI_PHY_D3_CONTROL2);
+ for (i = 0; i < csic_params->lane_cnt; i++)
+ msm_io_w(val, csicbase + MIPI_PHY_D0_CONTROL2 + i * 4);
val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
@@ -233,7 +224,9 @@
pr_info("msm_csic_irq: %x\n", (unsigned int)csic_dev->base);
irq = msm_io_r(csic_dev->base + MIPI_INTERRUPT_STATUS);
- pr_info("%s MIPI_INTERRUPT_STATUS = 0x%x\n", __func__, irq);
+ pr_info("%s MIPI_INTERRUPT_STATUS = 0x%x 0x%x\n",
+ __func__, irq,
+ msm_io_r(csic_dev->base + MIPI_PROTOCOL_CONTROL));
msm_io_w(irq, csic_dev->base + MIPI_INTERRUPT_STATUS);
/* TODO: Needs to send this info to upper layers */
@@ -372,7 +365,7 @@
}
rc = request_irq(new_csic_dev->irq->start, msm_csic_irq,
- IRQF_TRIGGER_RISING, "csic", new_csic_dev);
+ IRQF_TRIGGER_HIGH, "csic", new_csic_dev);
if (rc < 0) {
release_mem_region(new_csic_dev->mem->start,
resource_size(new_csic_dev->mem));
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
index e1f4532..a332fba 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
@@ -614,6 +614,24 @@
msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
cmd_data, len);
vfe2x_ctrl->start_pending = 0;
+ } else if (vfe2x_ctrl->stop_pending) {
+ CDBG("Send STOP\n");
+ cmd_data = buf;
+ *(uint32_t *)cmd_data = VFE_STOP;
+ /* Send Stop cmd here */
+ len = 4;
+ msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+ cmd_data, len);
+ vfe2x_ctrl->stop_pending = 0;
+ } else if (vfe2x_ctrl->update_pending) {
+ CDBG("Send Update\n");
+ cmd_data = buf;
+ *(uint32_t *)cmd_data = VFE_UPDATE;
+ /* Send Update cmd here */
+ len = 4;
+ msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+ cmd_data, len);
+ vfe2x_ctrl->update_pending = 0;
}
vfe2x_ctrl->tableack_pending = 0;
spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
@@ -1105,7 +1123,9 @@
case VFE_CMD_CAPTURE_RAW:
spin_lock_irqsave(&vfe2x_ctrl->table_lock,
flags);
- if (!list_empty(&vfe2x_ctrl->table_q)) {
+ if ((!list_empty(&vfe2x_ctrl->table_q)) ||
+ vfe2x_ctrl->tableack_pending) {
+ CDBG("start pending\n");
vfe2x_ctrl->start_pending = 1;
spin_unlock_irqrestore(
&vfe2x_ctrl->table_lock,
@@ -1126,9 +1146,36 @@
break;
case VFE_CMD_STOP:
vfestopped = 1;
+ spin_lock_irqsave(&vfe2x_ctrl->table_lock,
+ flags);
+ if ((!list_empty(&vfe2x_ctrl->table_q)) ||
+ vfe2x_ctrl->tableack_pending) {
+ CDBG("stop pending\n");
+ vfe2x_ctrl->stop_pending = 1;
+ spin_unlock_irqrestore(
+ &vfe2x_ctrl->table_lock,
+ flags);
+ return 0;
+ }
+ spin_unlock_irqrestore(&vfe2x_ctrl->table_lock,
+ flags);
vfe2x_ctrl->vfe_started = 0;
goto config_send;
-
+ case VFE_CMD_UPDATE:
+ spin_lock_irqsave(&vfe2x_ctrl->table_lock,
+ flags);
+ if ((!list_empty(&vfe2x_ctrl->table_q)) ||
+ vfe2x_ctrl->tableack_pending) {
+ CDBG("update pending\n");
+ vfe2x_ctrl->update_pending = 1;
+ spin_unlock_irqrestore(
+ &vfe2x_ctrl->table_lock,
+ flags);
+ return 0;
+ }
+ spin_unlock_irqrestore(&vfe2x_ctrl->table_lock,
+ flags);
+ goto config_send;
default:
break;
}
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.h b/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
index 90237bd..2b77159 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
@@ -97,6 +97,8 @@
struct vfe_cmd_start start_cmd;
uint32_t start_pending;
uint32_t vfe_started;
+ uint32_t stop_pending;
+ uint32_t update_pending;
/* v4l2 subdev */
struct v4l2_subdev subdev;
diff --git a/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c b/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
index 4373e22..99e96f0 100644
--- a/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
@@ -597,6 +597,22 @@
return rc;
}
+static int32_t ov7692_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+ uint16_t gain, uint32_t line)
+{
+ CDBG("ov7692_write_exp_gain : Not supported\n");
+ return 0;
+}
+
+int32_t ov7692_sensor_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
+ struct fps_cfg *fps)
+{
+ CDBG("ov7692_sensor_set_fps: Not supported\n");
+ return 0;
+}
+
+
+
static void ov7692_sw_reset(struct msm_sensor_ctrl_t *s_ctrl)
{
@@ -671,7 +687,7 @@
.sensor_stop_stream = msm_sensor_stop_stream,
.sensor_group_hold_on = msm_sensor_group_hold_on,
.sensor_group_hold_off = msm_sensor_group_hold_off,
- .sensor_set_fps = msm_sensor_set_fps,
+ .sensor_set_fps = ov7692_sensor_set_fps,
.sensor_setting = msm_sensor_setting3,
.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
.sensor_mode_init = msm_sensor_mode_init,
@@ -679,6 +695,8 @@
.sensor_config = msm_sensor_config,
.sensor_power_up = ov7692_sensor_power_up,
.sensor_power_down = msm_sensor_power_down,
+ .sensor_write_exp_gain = ov7692_write_exp_gain,
+ .sensor_write_snapshot_exp_gain = ov7692_write_exp_gain,
};
static struct msm_sensor_reg_t ov7692_regs = {
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 66b98a1..68395e3 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -439,6 +439,7 @@
PLDO("8917_l33", "8917_l33_pc", 0x0C6, 0x0C7, LDO_150),
PLDO("8917_l34", "8917_l34_pc", 0x0D2, 0x0D3, LDO_150),
PLDO("8917_l35", "8917_l35_pc", 0x0D4, 0x0D5, LDO_300),
+ PLDO("8917_l36", "8917_l36_pc", 0x0A9, 0x0AA, LDO_50),
/* name ctrl */
BOOST("8917_boost", 0x04B),
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 4634e75..93aacef 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1517,7 +1517,7 @@
if (!mmc_card_mmc(card))
return 0;
- if (card->ext_csd.boot_size) {
+ if (card->ext_csd.boot_size && mmc_boot_partition_access(card->host)) {
ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_BOOT0,
card->ext_csd.boot_size >> 9,
true,
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index f20ae4b..c4613ba 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -2228,6 +2228,11 @@
{
unsigned int sel_clk = -1;
+ if (req_clk < msmsdcc_get_min_sup_clk_rate(host)) {
+ sel_clk = msmsdcc_get_min_sup_clk_rate(host);
+ goto out;
+ }
+
if (host->plat->sup_clk_table && host->plat->sup_clk_cnt) {
unsigned char cnt;
@@ -2248,6 +2253,7 @@
sel_clk = req_clk;
}
+out:
return sel_clk;
}
@@ -4495,6 +4501,7 @@
mmc->caps |= (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 |
MMC_CAP_SET_XPC_180);
+ mmc->caps2 |= MMC_CAP2_BOOTPART_NOACC;
if (pdev->dev.of_node) {
if (of_get_property((&pdev->dev)->of_node,
"qcom,sdcc-hs200", NULL))
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 67c8709..0f008b3 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -240,6 +240,8 @@
pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
}
+ slot->host->mmc->caps2 = MMC_CAP2_BOOTPART_NOACC;
+
return 0;
}
diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
index 6d12c7e..84fd462 100644
--- a/drivers/spmi/Kconfig
+++ b/drivers/spmi/Kconfig
@@ -30,6 +30,7 @@
depends on SPARSE_IRQ
depends on ARCH_MSMCOPPER
depends on OF_SPMI
+ depends on MSM_QPNP
bool "MSM QPNP INT"
help
Say 'y' here to include support for the Qualcomm QPNP interrupt
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 91c3123..042eb4f 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -470,7 +470,7 @@
}
bind_config:
- for (i = 0; i < ports; i++) {
+ for (i = 0; i < ports; i++) {
err = gser_bind_config(c, i);
if (err) {
pr_err("serial: bind_config failed for port %d", i);
@@ -989,6 +989,31 @@
NULL
};
+static void android_cleanup_functions(struct android_usb_function **functions)
+{
+ struct android_usb_function *f;
+ struct device_attribute **attrs;
+ struct device_attribute *attr;
+
+ while (*functions) {
+ f = *functions++;
+
+ if (f->dev) {
+ device_destroy(android_class, f->dev->devt);
+ kfree(f->dev_name);
+ } else
+ continue;
+
+ if (f->cleanup)
+ f->cleanup(f);
+
+ attrs = f->attributes;
+ if (attrs) {
+ while ((attr = *attrs++))
+ device_remove_file(f->dev, attr);
+ }
+ }
+}
static int android_init_functions(struct android_usb_function **functions,
struct usb_composite_dev *cdev)
@@ -998,16 +1023,21 @@
struct device_attribute **attrs;
struct device_attribute *attr;
int err = 0;
- int index = 0;
+ int index = 1; /* index 0 is for android0 device */
for (; (f = *functions++); index++) {
f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
+ if (!f->dev_name) {
+ err = -ENOMEM;
+ goto err_out;
+ }
f->dev = device_create(android_class, dev->dev,
MKDEV(0, index), f, f->dev_name);
if (IS_ERR(f->dev)) {
pr_err("%s: Failed to create dev %s", __func__,
f->dev_name);
err = PTR_ERR(f->dev);
+ f->dev = NULL;
goto err_create;
}
@@ -1016,7 +1046,7 @@
if (err) {
pr_err("%s: Failed to init %s", __func__,
f->name);
- goto err_out;
+ goto err_init;
}
}
@@ -1028,35 +1058,26 @@
if (err) {
pr_err("%s: Failed to create function %s attributes",
__func__, f->name);
- goto err_out;
+ goto err_attrs;
}
}
return 0;
-err_out:
+err_attrs:
+ for (attr = *(attrs -= 2); attrs != f->attributes; attr = *(attrs--))
+ device_remove_file(f->dev, attr);
+ if (f->cleanup)
+ f->cleanup(f);
+err_init:
device_destroy(android_class, f->dev->devt);
err_create:
+ f->dev = NULL;
kfree(f->dev_name);
+err_out:
+ android_cleanup_functions(dev->functions);
return err;
}
-static void android_cleanup_functions(struct android_usb_function **functions)
-{
- struct android_usb_function *f;
-
- while (*functions) {
- f = *functions++;
-
- if (f->dev) {
- device_destroy(android_class, f->dev->devt);
- kfree(f->dev_name);
- }
-
- if (f->cleanup)
- f->cleanup(f);
- }
-}
-
static int
android_bind_enabled_functions(struct android_dev *dev,
struct usb_configuration *c)
@@ -1393,6 +1414,9 @@
{
struct android_dev *dev = _android_dev;
+ manufacturer_string[0] = '\0';
+ product_string[0] = '\0';
+ serial_string[0] = '0';
cancel_work_sync(&dev->work);
android_cleanup_functions(dev->functions);
return 0;
@@ -1502,15 +1526,29 @@
{
struct android_usb_platform_data *pdata = pdev->dev.platform_data;
struct android_dev *dev = _android_dev;
+ int ret = 0;
dev->pdata = pdata;
+ ret = usb_composite_probe(&android_usb_driver, android_bind);
+ if (ret) {
+ pr_err("%s(): Failed to register android "
+ "composite driver\n", __func__);
+ }
+
+ return ret;
+}
+
+static int android_remove(struct platform_device *pdev)
+{
+ usb_composite_unregister(&android_usb_driver);
return 0;
}
static struct platform_driver android_platform_driver = {
- .probe = android_probe,
.driver = { .name = "android_usb"},
+ .probe = android_probe,
+ .remove = android_remove,
};
static int __init init(void)
@@ -1550,13 +1588,7 @@
"platform driver\n", __func__);
goto err_probe;
}
- ret = usb_composite_probe(&android_usb_driver, android_bind);
- if (ret) {
- pr_err("%s(): Failed to register android"
- "composite driver\n", __func__);
- platform_driver_unregister(&android_platform_driver);
- goto err_probe;
- }
+
return ret;
err_probe:
@@ -1570,9 +1602,10 @@
static void __exit cleanup(void)
{
- usb_composite_unregister(&android_usb_driver);
- class_destroy(android_class);
+ platform_driver_unregister(&android_platform_driver);
+ android_destroy_device(_android_dev);
kfree(_android_dev);
+ class_destroy(android_class);
_android_dev = NULL;
}
module_exit(cleanup);
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c
index fac777c..eb727b8 100644
--- a/drivers/usb/gadget/ci13xxx_msm.c
+++ b/drivers/usb/gadget/ci13xxx_msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-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
@@ -21,6 +21,12 @@
#define MSM_USB_BASE (udc->regs)
+struct ci13xxx_udc_context {
+ int irq;
+ void __iomem *regs;
+};
+static struct ci13xxx_udc_context _udc_ctxt;
+
static irqreturn_t msm_udc_irq(int irq, void *data)
{
return udc_irq();
@@ -56,8 +62,6 @@
static int ci13xxx_msm_probe(struct platform_device *pdev)
{
struct resource *res;
- void __iomem *regs;
- int irq;
int ret;
dev_dbg(&pdev->dev, "ci13xxx_msm_probe\n");
@@ -68,26 +72,27 @@
return -ENXIO;
}
- regs = ioremap(res->start, resource_size(res));
- if (!regs) {
+ _udc_ctxt.regs = ioremap(res->start, resource_size(res));
+ if (!_udc_ctxt.regs) {
dev_err(&pdev->dev, "ioremap failed\n");
return -ENOMEM;
}
- ret = udc_probe(&ci13xxx_msm_udc_driver, &pdev->dev, regs);
+ ret = udc_probe(&ci13xxx_msm_udc_driver, &pdev->dev, _udc_ctxt.regs);
if (ret < 0) {
dev_err(&pdev->dev, "udc_probe failed\n");
goto iounmap;
}
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
+ _udc_ctxt.irq = platform_get_irq(pdev, 0);
+ if (_udc_ctxt.irq < 0) {
dev_err(&pdev->dev, "IRQ not found\n");
ret = -ENXIO;
goto udc_remove;
}
- ret = request_irq(irq, msm_udc_irq, IRQF_SHARED, pdev->name, pdev);
+ ret = request_irq(_udc_ctxt.irq, msm_udc_irq, IRQF_SHARED, pdev->name,
+ pdev);
if (ret < 0) {
dev_err(&pdev->dev, "request_irq failed\n");
goto udc_remove;
@@ -101,14 +106,24 @@
udc_remove:
udc_remove();
iounmap:
- iounmap(regs);
+ iounmap(_udc_ctxt.regs);
return ret;
}
+int ci13xxx_msm_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+ free_irq(_udc_ctxt.irq, pdev);
+ udc_remove();
+ iounmap(_udc_ctxt.regs);
+ return 0;
+}
+
static struct platform_driver ci13xxx_msm_driver = {
.probe = ci13xxx_msm_probe,
.driver = { .name = "msm_hsusb", },
+ .remove = ci13xxx_msm_remove,
};
static int __init ci13xxx_msm_init(void)
@@ -116,3 +131,11 @@
return platform_driver_register(&ci13xxx_msm_driver);
}
module_init(ci13xxx_msm_init);
+
+static void __exit ci13xxx_msm_exit(void)
+{
+ platform_driver_unregister(&ci13xxx_msm_driver);
+}
+module_exit(ci13xxx_msm_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/gadget/ci13xxx_msm_hsic.c b/drivers/usb/gadget/ci13xxx_msm_hsic.c
index 12b6774..3736367 100644
--- a/drivers/usb/gadget/ci13xxx_msm_hsic.c
+++ b/drivers/usb/gadget/ci13xxx_msm_hsic.c
@@ -767,3 +767,4 @@
module_init(msm_hsic_peripheral_init);
module_exit(msm_hsic_peripheral_exit);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index c9d9c07..4f2946c 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1634,6 +1634,8 @@
int usb_composite_probe(struct usb_composite_driver *driver,
int (*bind)(struct usb_composite_dev *cdev))
{
+ int retval;
+
if (!driver || !driver->dev || !bind || composite)
return -EINVAL;
@@ -1648,7 +1650,10 @@
composite = driver;
composite_gadget_bind = bind;
- return usb_gadget_probe_driver(&composite_driver, composite_bind);
+ retval = usb_gadget_probe_driver(&composite_driver, composite_bind);
+ if (retval)
+ composite = NULL;
+ return retval;
}
/**
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index c85d499..0e619e6 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -495,7 +495,17 @@
}
/* wait for a request to complete */
- ret = wait_event_interruptible(dev->read_wq, dev->rx_done);
+ ret = wait_event_interruptible(dev->read_wq,
+ dev->rx_done || dev->state != STATE_BUSY);
+ if (dev->state == STATE_CANCELED) {
+ r = -ECANCELED;
+ if (!dev->rx_done)
+ usb_ep_dequeue(dev->ep_out, req);
+ spin_lock_irq(&dev->lock);
+ dev->state = STATE_CANCELED;
+ spin_unlock_irq(&dev->lock);
+ goto done;
+ }
if (ret < 0) {
r = ret;
usb_ep_dequeue(dev->ep_out, req);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 795e7a8..2d43a78 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -24,7 +24,6 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
-#include <linux/irq.h>
#include <linux/err.h>
#include <linux/wakelock.h>
#include <linux/pm_runtime.h>
@@ -55,6 +54,7 @@
struct wake_lock wlock;
int peripheral_status_irq;
int wakeup_irq;
+ bool wakeup_irq_enabled;
};
static inline struct msm_hsic_hcd *hcd_to_hsic(struct usb_hcd *hcd)
@@ -750,6 +750,12 @@
dev_dbg(mehci->dev, "%s: hsic remote wakeup interrupt\n", __func__);
+ if (mehci->wakeup_irq_enabled) {
+ mehci->wakeup_irq_enabled = 0;
+ disable_irq_wake(irq);
+ disable_irq_nosync(irq);
+ }
+
return IRQ_HANDLED;
}
@@ -878,7 +884,6 @@
"msm_hsic_wakeup", mehci);
if (!ret) {
disable_irq_nosync(mehci->wakeup_irq);
- enable_irq_wake(mehci->wakeup_irq);
} else {
dev_err(&pdev->dev, "request_irq(%d) failed: %d\n",
mehci->wakeup_irq, ret);
@@ -923,8 +928,10 @@
if (mehci->peripheral_status_irq)
free_irq(mehci->peripheral_status_irq, mehci);
+
if (mehci->wakeup_irq) {
- disable_irq_wake(mehci->wakeup_irq);
+ if (mehci->wakeup_irq_enabled)
+ disable_irq_wake(mehci->wakeup_irq);
free_irq(mehci->wakeup_irq, mehci);
}
@@ -959,7 +966,22 @@
enable_irq_wake(hcd->irq);
return msm_hsic_suspend(mehci);
+}
+static int msm_hsic_pm_suspend_noirq(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
+
+ dev_dbg(dev, "ehci-msm-hsic PM suspend_noirq\n");
+
+ if (device_may_wakeup(dev) && !mehci->wakeup_irq_enabled) {
+ enable_irq(mehci->wakeup_irq);
+ enable_irq_wake(mehci->wakeup_irq);
+ mehci->wakeup_irq_enabled = 1;
+ }
+
+ return 0;
}
static int msm_hsic_pm_resume(struct device *dev)
@@ -973,6 +995,12 @@
if (device_may_wakeup(dev))
disable_irq_wake(hcd->irq);
+ if (mehci->wakeup_irq_enabled) {
+ mehci->wakeup_irq_enabled = 0;
+ disable_irq_wake(mehci->wakeup_irq);
+ disable_irq_nosync(mehci->wakeup_irq);
+ }
+
ret = msm_hsic_resume(mehci);
if (ret)
return ret;
@@ -1016,6 +1044,7 @@
#ifdef CONFIG_PM
static const struct dev_pm_ops msm_hsic_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(msm_hsic_pm_suspend, msm_hsic_pm_resume)
+ .suspend_noirq = msm_hsic_pm_suspend_noirq,
SET_RUNTIME_PM_OPS(msm_hsic_runtime_suspend, msm_hsic_runtime_resume,
msm_hsic_runtime_idle)
};
diff --git a/drivers/usb/host/ehci-msm2.c b/drivers/usb/host/ehci-msm2.c
index 4318efb..fc43a0d 100644
--- a/drivers/usb/host/ehci-msm2.c
+++ b/drivers/usb/host/ehci-msm2.c
@@ -82,7 +82,7 @@
if (!init)
goto disable_reg;
- mhcd->hsusb_vddcx = regulator_get(mhcd->dev, "HSUSB_VDDCX");
+ mhcd->hsusb_vddcx = devm_regulator_get(mhcd->dev, "HSUSB_VDDCX");
if (IS_ERR(mhcd->hsusb_vddcx)) {
dev_err(mhcd->dev, "unable to get ehci vddcx\n");
return PTR_ERR(mhcd->hsusb_vddcx);
@@ -94,7 +94,7 @@
if (ret) {
dev_err(mhcd->dev, "unable to set the voltage"
"for ehci vddcx\n");
- goto reg_set_voltage_err;
+ return ret;
}
ret = regulator_set_optimum_mode(mhcd->hsusb_vddcx,
@@ -120,9 +120,6 @@
reg_optimum_mode_err:
regulator_set_voltage(mhcd->hsusb_vddcx, 0,
HSUSB_PHY_VDD_DIG_VOL_MIN);
-reg_set_voltage_err:
- regulator_put(mhcd->hsusb_vddcx);
-
return ret;
}
@@ -134,7 +131,7 @@
if (!init)
goto put_1p8;
- mhcd->hsusb_3p3 = regulator_get(mhcd->dev, "HSUSB_3p3");
+ mhcd->hsusb_3p3 = devm_regulator_get(mhcd->dev, "HSUSB_3p3");
if (IS_ERR(mhcd->hsusb_3p3)) {
dev_err(mhcd->dev, "unable to get hsusb 3p3\n");
return PTR_ERR(mhcd->hsusb_3p3);
@@ -145,9 +142,9 @@
if (rc) {
dev_err(mhcd->dev, "unable to set voltage level for"
"hsusb 3p3\n");
- goto put_3p3;
+ return rc;
}
- mhcd->hsusb_1p8 = regulator_get(mhcd->dev, "HSUSB_1p8");
+ mhcd->hsusb_1p8 = devm_regulator_get(mhcd->dev, "HSUSB_1p8");
if (IS_ERR(mhcd->hsusb_1p8)) {
dev_err(mhcd->dev, "unable to get hsusb 1p8\n");
rc = PTR_ERR(mhcd->hsusb_1p8);
@@ -165,11 +162,8 @@
put_1p8:
regulator_set_voltage(mhcd->hsusb_1p8, 0, HSUSB_PHY_1P8_VOL_MAX);
- regulator_put(mhcd->hsusb_1p8);
put_3p3_lpm:
regulator_set_voltage(mhcd->hsusb_3p3, 0, HSUSB_PHY_3P3_VOL_MAX);
-put_3p3:
- regulator_put(mhcd->hsusb_3p3);
return rc;
}
@@ -273,13 +267,12 @@
pdata = mhcd->dev->platform_data;
if (!init) {
- regulator_put(mhcd->vbus);
if (pdata && pdata->dock_connect_irq)
free_irq(pdata->dock_connect_irq, mhcd);
return rc;
}
- mhcd->vbus = regulator_get(mhcd->dev, "vbus");
+ mhcd->vbus = devm_regulator_get(mhcd->dev, "vbus");
if (IS_ERR(mhcd->vbus)) {
pr_err("Unable to get vbus\n");
return -ENODEV;
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index a064d11..606d349 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -249,6 +249,20 @@
select FB_MSM_LCDC_PANEL
default n
+config FB_MSM_LCDC_TRULY_HVGA_IPS3P2335
+ bool
+ select FB_MSM_LCDC_PANEL
+ default n
+
+config FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL
+ depends on FB_MSM_LCDC_HW
+ bool "LCDC Truly HVGA PT Panel"
+ select FB_MSM_LCDC_TRULY_HVGA_IPS3P2335
+ default n
+ ---help---
+ Support for LCDC Truly HVGA PT panel
+
+
config FB_MSM_LCDC_SAMSUNG_OLED_PT
bool
select FB_MSM_LCDC_PANEL
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index aabe490..e6c869f 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -165,6 +165,7 @@
obj-$(CONFIG_FB_MSM_LVDS_CHIMEI_WXGA) += lvds_chimei_wxga.o
obj-$(CONFIG_FB_MSM_HDMI_MSM_PANEL) += hdmi_msm.o
obj-$(CONFIG_FB_MSM_EXT_INTERFACE_COMMON) += external_common.o
+obj-$(CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335) += lcdc_truly_ips3p2335.o
obj-$(CONFIG_FB_MSM_TVOUT) += tvout_msm.o
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index a056328..7c5a653 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -4142,6 +4142,19 @@
return 0;
}
+static int hdmi_msm_power_ctrl(boolean enable)
+{
+ if (!external_common_state->hpd_feature_on)
+ return 0;
+
+ if (enable)
+ hdmi_msm_hpd_on(true);
+ else
+ hdmi_msm_hpd_off();
+
+ return 0;
+}
+
static int hdmi_msm_power_on(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
@@ -4163,7 +4176,7 @@
#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
changed = hdmi_common_get_video_format_from_drv_data(mfd);
- if (!external_common_state->hpd_feature_on) {
+ if (!external_common_state->hpd_feature_on || mfd->ref_cnt) {
int rc = hdmi_msm_hpd_on(true);
DEV_INFO("HPD: panel power without 'hpd' feature on\n");
if (rc) {
@@ -4198,6 +4211,8 @@
*/
static int hdmi_msm_power_off(struct platform_device *pdev)
{
+ struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+
if (!hdmi_msm_state->hdmi_app_clk)
return -ENODEV;
@@ -4223,7 +4238,7 @@
hdmi_msm_hpd_on(true);
mutex_lock(&external_common_state_hpd_mutex);
- if (!external_common_state->hpd_feature_on)
+ if (!external_common_state->hpd_feature_on || mfd->ref_cnt)
hdmi_msm_hpd_off();
mutex_unlock(&external_common_state_hpd_mutex);
@@ -4497,6 +4512,7 @@
static struct msm_fb_panel_data hdmi_msm_panel_data = {
.on = hdmi_msm_power_on,
.off = hdmi_msm_power_off,
+ .power_ctrl = hdmi_msm_power_ctrl,
};
static struct platform_device this_device = {
diff --git a/drivers/video/msm/lcdc_truly_ips3p2335.c b/drivers/video/msm/lcdc_truly_ips3p2335.c
new file mode 100644
index 0000000..838c083
--- /dev/null
+++ b/drivers/video/msm/lcdc_truly_ips3p2335.c
@@ -0,0 +1,305 @@
+/* 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/delay.h>
+#include <linux/module.h>
+#include <mach/gpio.h>
+#include <mach/pmic.h>
+#include "msm_fb.h"
+
+static int prev_bl = 17;
+
+static int spi_cs;
+static int spi_sclk;
+static int spi_mosi;
+static int gpio_backlight_en;
+static int gpio_display_reset;
+
+struct truly_state_type {
+ boolean disp_initialized;
+ boolean display_on;
+ boolean disp_powered_up;
+};
+
+static struct truly_state_type truly_state = { 0 };
+static struct msm_panel_common_pdata *lcdc_truly_pdata;
+
+static char init_item_v1[] = { 0xff, 0x83, 0x57, };
+static char init_item_v2[] = { 0x03, };
+static char init_item_v3[] = { 0x00, 0x13, 0x1C, 0x1C, 0x83, 0x48, };
+static char init_item_v4[] = { 0x43, 0x06, 0x06, 0x06, };
+static char init_item_v5[] = { 0x53, };
+static char init_item_v6[] = { 0x02, 0x40, 0x00, 0x2a, 0x2a, 0x0d, 0x3f, };
+static char init_item_v7[] = { 0x70, 0x50, 0x01, 0x3c, 0xe8, 0x08, };
+static char init_item_v8[] = { 0x17, 0x0f, };
+static char init_item_v9[] = { 0x60};
+static char init_item_v10[] = { 0x00, 0x13, 0x1a, 0x29, 0x2d, 0x41, 0x49,
+ 0x52, 0x48, 0x41, 0x3c, 0x33, 0x30, 0x1c,
+ 0x19, 0x03, 0x00, 0x13, 0x1a, 0x29, 0x2d,
+ 0x41, 0x49, 0x52, 0x48, 0x41, 0x3c, 0x33,
+ 0x31, 0x1c, 0x19, 0x03, 0x00, 0x01,
+ };
+static char init_item_v11[] = { 0x40, };
+
+static inline void truly_spi_write_byte(char dc, uint8 data)
+{
+ uint32 bit;
+ int bnum;
+
+ gpio_set_value_cansleep(spi_sclk, 0); /* clk low */
+ /* dc: 0 for command, 1 for parameter */
+ gpio_set_value_cansleep(spi_mosi, dc);
+ udelay(1); /* at least 20 ns */
+ gpio_set_value_cansleep(spi_sclk, 1); /* clk high */
+ udelay(1); /* at least 20 ns */
+ bnum = 8; /* 8 data bits */
+ bit = 0x80;
+ while (bnum) {
+ gpio_set_value_cansleep(spi_sclk, 0); /* clk low */
+ if (data & bit)
+ gpio_set_value_cansleep(spi_mosi, 1);
+ else
+ gpio_set_value_cansleep(spi_mosi, 0);
+ udelay(1);
+ gpio_set_value_cansleep(spi_sclk, 1); /* clk high */
+ udelay(1);
+ bit >>= 1;
+ bnum--;
+ }
+}
+
+static inline int truly_spi_write(char cmd, char *data, int num)
+{
+ int i;
+
+ gpio_set_value_cansleep(spi_cs, 0); /* cs low */
+ /* command byte first */
+ truly_spi_write_byte(0, cmd);
+ /* followed by parameter bytes */
+ for (i = 0; i < num; i++) {
+ if (data)
+ truly_spi_write_byte(1, data[i]);
+ }
+ gpio_set_value_cansleep(spi_mosi, 1); /* mosi high */
+ gpio_set_value_cansleep(spi_cs, 1); /* cs high */
+ udelay(10);
+ return 0;
+}
+
+static void spi_pin_assign(void)
+{
+ /* Setting the Default GPIO's */
+ spi_mosi = *(lcdc_truly_pdata->gpio_num);
+ spi_sclk = *(lcdc_truly_pdata->gpio_num + 1);
+ spi_cs = *(lcdc_truly_pdata->gpio_num + 2);
+ gpio_backlight_en = *(lcdc_truly_pdata->gpio_num + 3);
+ gpio_display_reset = *(lcdc_truly_pdata->gpio_num + 4);
+ pr_debug("spi_mosi:%d spi_sclk:%d spi_cs:%d backlight:%d reset:%d\n",
+ spi_mosi, spi_sclk, spi_cs, gpio_backlight_en,
+ gpio_display_reset);
+
+}
+
+static void truly_disp_powerup(void)
+{
+ /* Reset the hardware first */
+ /* Include DAC power up implementation here */
+ if (!truly_state.disp_powered_up && !truly_state.display_on)
+ truly_state.disp_powered_up = TRUE;
+}
+
+static void truly_disp_reginit(void)
+{
+ pr_debug("%s disp_powered_up:%d display_on:%d\n", __func__,
+ truly_state.disp_powered_up, truly_state.display_on);
+ if (truly_state.disp_powered_up && !truly_state.display_on) {
+ gpio_set_value_cansleep(spi_cs, 1); /* cs high */
+
+ truly_spi_write(0xb9, init_item_v1, sizeof(init_item_v1));
+ msleep(20);
+ truly_spi_write(0xcc, init_item_v2, sizeof(init_item_v2));
+ truly_spi_write(0xb1, init_item_v3, sizeof(init_item_v3));
+ truly_spi_write(0xb3, init_item_v4, sizeof(init_item_v4));
+ truly_spi_write(0xb6, init_item_v5, sizeof(init_item_v5));
+ truly_spi_write(0xb4, init_item_v6, sizeof(init_item_v6));
+ truly_spi_write(0xc0, init_item_v7, sizeof(init_item_v7));
+ truly_spi_write(0xe3, init_item_v8, sizeof(init_item_v8));
+ truly_spi_write(0x3a, init_item_v9, sizeof(init_item_v9));
+ truly_spi_write(0xe0, init_item_v10, sizeof(init_item_v10));
+ truly_spi_write(0x36, init_item_v11, sizeof(init_item_v11));
+ truly_spi_write(0x11, NULL, 0);
+ msleep(150);
+ truly_spi_write(0x29, NULL, 0);
+ msleep(25);
+
+ truly_state.display_on = TRUE;
+ }
+}
+
+static int lcdc_truly_panel_on(struct platform_device *pdev)
+{
+ /* Configure reset GPIO that drives DAC */
+ if (lcdc_truly_pdata->panel_config_gpio)
+ lcdc_truly_pdata->panel_config_gpio(1);
+ gpio_set_value_cansleep(gpio_display_reset, 1);
+ truly_disp_powerup();
+ truly_disp_reginit();
+ truly_state.disp_initialized = TRUE;
+ return 0;
+}
+
+static int lcdc_truly_panel_off(struct platform_device *pdev)
+{
+ if (truly_state.disp_powered_up && truly_state.display_on) {
+ /* Main panel power off (Pull down reset) */
+ gpio_set_value_cansleep(gpio_display_reset, 0);
+ truly_state.display_on = FALSE;
+ truly_state.disp_initialized = FALSE;
+ }
+ return 0;
+}
+
+static void lcdc_truly_set_backlight(struct msm_fb_data_type *mfd)
+{
+ int step = 0, i = 0;
+ unsigned long flags;
+ int bl_level = mfd->bl_level;
+
+ /* real backlight level, 1 - max, 16 - min, 17 - off */
+ bl_level = 17 - bl_level;
+
+ if (bl_level > prev_bl) {
+ step = bl_level - prev_bl;
+ if (bl_level == 17)
+ step--;
+ } else if (bl_level < prev_bl) {
+ step = bl_level + 16 - prev_bl;
+ } else {
+ pr_info("%s: no change\n", __func__);
+ return;
+ }
+
+ if (bl_level == 17) {
+ /* turn off backlight */
+ gpio_set_value(gpio_backlight_en, 0);
+ } else {
+ local_irq_save(flags);
+
+ if (prev_bl == 17) {
+ /* turn on backlight */
+ gpio_set_value(gpio_backlight_en, 1);
+ udelay(30);
+ }
+
+ /* adjust backlight level */
+ for (i = 0; i < step; i++) {
+ gpio_set_value(gpio_backlight_en, 0);
+ udelay(1);
+ gpio_set_value(gpio_backlight_en, 1);
+ udelay(1);
+ }
+
+ local_irq_restore(flags);
+ }
+ msleep(20);
+ prev_bl = bl_level;
+
+ return;
+}
+
+static int __devinit truly_probe(struct platform_device *pdev)
+{
+
+ if (pdev->id == 0) {
+ lcdc_truly_pdata = pdev->dev.platform_data;
+
+ if (!lcdc_truly_pdata)
+ pr_err("%s pdata is null\n", __func__);
+
+ spi_pin_assign();
+ return 0;
+ }
+ msm_fb_add_device(pdev);
+
+ return 0;
+}
+
+static struct platform_driver this_driver = {
+ .probe = truly_probe,
+ .driver = {
+ .name = "lcdc_truly_hvga_ips3p2335_pt",
+ },
+};
+
+static struct msm_fb_panel_data truly_panel_data = {
+ .on = lcdc_truly_panel_on,
+ .off = lcdc_truly_panel_off,
+ .set_backlight = lcdc_truly_set_backlight,
+};
+
+static struct platform_device this_device = {
+ .name = "lcdc_truly_hvga_ips3p2335_pt",
+ .id = 1,
+ .dev = {
+ .platform_data = &truly_panel_data,
+ }
+};
+
+static int __init lcdc_truly_panel_init(void)
+{
+ int ret;
+ struct msm_panel_info *pinfo;
+
+ ret = msm_fb_detect_client("lcdc_truly_hvga_ips3p2335_pt");
+ if (ret)
+ return 0;
+
+ ret = platform_driver_register(&this_driver);
+ if (ret) {
+ pr_err("%s() driver registration failed", __func__);
+ return ret;
+ }
+
+ pinfo = &truly_panel_data.panel_info;
+ pinfo->xres = 320;
+ pinfo->yres = 480;
+ MSM_FB_SINGLE_MODE_PANEL(pinfo);
+ pinfo->type = LCDC_PANEL;
+ pinfo->pdest = DISPLAY_1;
+ pinfo->wait_cycle = 0;
+ pinfo->bpp = 18;
+ pinfo->fb_num = 2;
+ /* 10Mhz mdp_lcdc_pclk and mdp_lcdc_pad_pcl */
+ pinfo->clk_rate = 10240000;
+ pinfo->bl_max = 16;
+ pinfo->bl_min = 1;
+
+ pinfo->lcdc.h_back_porch = 16; /* hsw = 8 + hbp=16 */
+ pinfo->lcdc.h_front_porch = 4;
+ pinfo->lcdc.h_pulse_width = 8;
+ pinfo->lcdc.v_back_porch = 7; /* vsw=1 + vbp = 7 */
+ pinfo->lcdc.v_front_porch = 3;
+ pinfo->lcdc.v_pulse_width = 1;
+ pinfo->lcdc.border_clr = 0; /* blk */
+ pinfo->lcdc.underflow_clr = 0xff; /* blue */
+ pinfo->lcdc.hsync_skew = 0;
+
+ ret = platform_device_register(&this_device);
+ if (ret) {
+ pr_err("%s not able to register the device\n", __func__);
+ platform_driver_unregister(&this_driver);
+ }
+ return ret;
+}
+
+device_initcall(lcdc_truly_panel_init);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index b69fe6e..a3b03b8 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1360,44 +1360,63 @@
}
}
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
if (ctrl->mixer_cfg[mixer] != cfg[mixer]) {
- if (mixer <= MDP4_MIXER1) {
+ if ((ctrl->mixer_cfg[MDP4_MIXER0] != cfg[MDP4_MIXER0]) ||
+ (ctrl->mixer_cfg[MDP4_MIXER1] != cfg[MDP4_MIXER1])) {
off = 0x10100;
if (ctrl->mixer_cfg[MDP4_MIXER0] != cfg[MDP4_MIXER0]) {
flush_bits |= 0x1;
ctrl->mixer_cfg[MDP4_MIXER0] = cfg[MDP4_MIXER0];
+
+ if ((ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) ||
+ (ctrl->panel_mode & MDP4_PANEL_LCDC))
+ pull_mode = 1;
}
if (ctrl->mixer_cfg[MDP4_MIXER1] != cfg[MDP4_MIXER1]) {
flush_bits |= 0x2;
ctrl->mixer_cfg[MDP4_MIXER1] = cfg[MDP4_MIXER1];
+
+ pull_mode = 1;
}
+
data = cfg[MDP4_MIXER0] | cfg[MDP4_MIXER1];
- } else {
+
+ pr_debug("%s: mixer=%d data=%x flush=%x\n", __func__,
+ mixer, data, flush_bits);
+
+ outpdw(MDP_BASE + off, data); /* LAYERMIXER_IN_CFG */
+ if (pull_mode)
+ outpdw(MDP_BASE + 0x18000, flush_bits);
+ }
+
+ if (ctrl->mixer_cfg[MDP4_MIXER2] != cfg[MDP4_MIXER2]) {
+ /* wait for vsync on both pull mode interfaces */
+ if (pull_mode)
+ msleep(20);
+
off = 0x100F0;
ctrl->mixer_cfg[MDP4_MIXER2] = cfg[MDP4_MIXER2];
data = cfg[MDP4_MIXER2];
+
+ pr_debug("%s: mixer=%d data=%x\n", __func__,
+ mixer, data);
+
+ outpdw(MDP_BASE + off, data); /* LAYERMIXER_IN_CFG */
+ }
+ } else {
+ if (mixer == MDP4_MIXER0) {
+ if ((ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) ||
+ (ctrl->panel_mode & MDP4_PANEL_LCDC))
+ pull_mode = 1;
+ } else if (mixer == MDP4_MIXER1) {
+ pull_mode = 1;
}
- pr_debug("%s: mixer=%d data=%x flush=%x\n", __func__,
- mixer, data, flush_bits);
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
- outpdw(MDP_BASE + off, data); /* MDP_LAYERMIXER_IN_CFG */
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ if (pull_mode)
+ outpdw(MDP_BASE + 0x18000, flush_bits);
}
-
- if (mixer == MDP4_MIXER0) {
- if ((ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) ||
- (ctrl->panel_mode & MDP4_PANEL_LCDC))
- pull_mode = 1;
- } else if (mixer == MDP4_MIXER1) {
- pull_mode = 1;
- }
-
- if (pull_mode) {
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
- outpdw(MDP_BASE + 0x18000, flush_bits);
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
- }
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
if (data && pipe_cnt == 1)
mdp4_update_perf_level(OVERLAY_PERF_LEVEL4);
diff --git a/drivers/video/msm/msm_dss_io_8x60.c b/drivers/video/msm/msm_dss_io_8x60.c
index 0daf727..6dac6c1 100644
--- a/drivers/video/msm/msm_dss_io_8x60.c
+++ b/drivers/video/msm/msm_dss_io_8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -579,6 +579,14 @@
void hdmi_msm_powerdown_phy(void)
{
+ /* Assert RESET PHY from controller */
+ HDMI_OUTP_ND(0x02D4, 0x4);
+ udelay(10);
+ /* De-assert RESET PHY from controller */
+ HDMI_OUTP_ND(0x02D4, 0x0);
+ /* Turn off Driver */
+ HDMI_OUTP_ND(0x0308, 0x1F);
+ udelay(10);
/* Disable PLL */
HDMI_OUTP_ND(0x030C, 0x00);
/* Power down PHY */
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index db47a31..1b0dfbe 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -542,10 +542,13 @@
static int msm_fb_resume_sub(struct msm_fb_data_type *mfd)
{
int ret = 0;
+ struct msm_fb_panel_data *pdata = NULL;
if ((!mfd) || (mfd->key != MFD_KEY))
return 0;
+ pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+
/* attach display channel irq if there's any */
if (mfd->channel_irq != 0)
enable_irq(mfd->channel_irq);
@@ -560,6 +563,9 @@
mfd->op_enable);
if (ret)
MSM_FB_INFO("msm_fb_resume: can't turn on display!\n");
+ } else {
+ if (pdata->power_ctrl)
+ pdata->power_ctrl(TRUE);
}
return ret;
@@ -795,6 +801,9 @@
mfd->panel_power_on = curr_pwr_state;
mfd->op_enable = TRUE;
+ } else {
+ if (pdata->power_ctrl)
+ pdata->power_ctrl(FALSE);
}
break;
}
diff --git a/drivers/video/msm/msm_fb_panel.h b/drivers/video/msm/msm_fb_panel.h
index 903c865..a4072c8 100644
--- a/drivers/video/msm/msm_fb_panel.h
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -188,6 +188,7 @@
/* function entry chain */
int (*on) (struct platform_device *pdev);
int (*off) (struct platform_device *pdev);
+ int (*power_ctrl) (boolean enable);
struct platform_device *next;
int (*clk_func) (int enable);
};
diff --git a/include/linux/input/ft5x06_ts.h b/include/linux/input/ft5x06_ts.h
new file mode 100644
index 0000000..b2fb3c4
--- /dev/null
+++ b/include/linux/input/ft5x06_ts.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * FocalTech ft5x06 TouchScreen driver header file.
+ *
+ * Copyright (c) 2010 Focal tech Ltd.
+ * Copyright (c) 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
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 __LINUX_FT5X06_TS_H__
+#define __LINUX_FT5X06_TS_H__
+
+struct ft5x06_ts_platform_data {
+ unsigned long irqflags;
+ u32 x_max;
+ u32 y_max;
+ u32 irq_gpio;
+ u32 reset_gpio;
+ int (*power_init) (bool);
+ int (*power_on) (bool);
+};
+
+#endif
diff --git a/include/linux/mfd/pm8xxx/pm8xxx-adc.h b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
index a572ae3..d2b1cfc 100644
--- a/include/linux/mfd/pm8xxx/pm8xxx-adc.h
+++ b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
@@ -75,7 +75,6 @@
ADC_MPP_1_ATEST_5,
ADC_MPP_1_ATEST_6,
ADC_MPP_1_ATEST_7,
- ADC_MPP_1_CHANNEL_NONE,
ADC_MPP_2_ATEST_8 = 40,
ADC_MPP_2_USB_SNS_DIV20,
ADC_MPP_2_DCIN_SNS_DIV20,
@@ -92,7 +91,7 @@
ADC_MPP_2_ATEST_5,
ADC_MPP_2_ATEST_6,
ADC_MPP_2_ATEST_7,
- ADC_MPP_2_CHANNEL_NONE,
+ ADC_CHANNEL_MAX_NUM,
};
#define PM8XXX_ADC_PMIC_0 0x0
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index db14e38..46f71a1 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -241,6 +241,7 @@
unsigned int caps2; /* More host capabilities */
+#define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */
#define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */
#define MMC_CAP2_POWEROFF_NOTIFY (1 << 2) /* Notify poweroff supported */
#define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */
@@ -475,6 +476,11 @@
return host->caps & MMC_CAP_CMD23;
}
+static inline int mmc_boot_partition_access(struct mmc_host *host)
+{
+ return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC);
+}
+
#ifdef CONFIG_MMC_CLKGATE
void mmc_host_clk_hold(struct mmc_host *host);
void mmc_host_clk_release(struct mmc_host *host);
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 8e10232..0e62644 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -2,18 +2,14 @@
#define _MSM_KGSL_H
#define KGSL_VERSION_MAJOR 3
-#define KGSL_VERSION_MINOR 9
+#define KGSL_VERSION_MINOR 8
/*context flags */
-#define KGSL_CONTEXT_SAVE_GMEM 0x00000001
-#define KGSL_CONTEXT_NO_GMEM_ALLOC 0x00000002
-#define KGSL_CONTEXT_SUBMIT_IB_LIST 0x00000004
-#define KGSL_CONTEXT_CTX_SWITCH 0x00000008
-#define KGSL_CONTEXT_PREAMBLE 0x00000010
-#define KGSL_CONTEXT_TRASH_STATE 0x00000020
-#define KGSL_CONTEXT_PER_CONTEXT_TS 0x00000040
-
-#define KGSL_CONTEXT_INVALID 0xffffffff
+#define KGSL_CONTEXT_SAVE_GMEM 1
+#define KGSL_CONTEXT_NO_GMEM_ALLOC 2
+#define KGSL_CONTEXT_SUBMIT_IB_LIST 4
+#define KGSL_CONTEXT_CTX_SWITCH 8
+#define KGSL_CONTEXT_PREAMBLE 16
/* Memory allocayion flags */
#define KGSL_MEMFLAGS_GPUREADONLY 0x01000000
@@ -29,7 +25,6 @@
#define KGSL_FLAGS_RESERVED1 0x00000040
#define KGSL_FLAGS_RESERVED2 0x00000080
#define KGSL_FLAGS_SOFT_RESET 0x00000100
-#define KGSL_FLAGS_PER_CONTEXT_TIMESTAMPS 0x00000200
/* Clock flags to show which clocks should be controled by a given platform */
#define KGSL_CLK_SRC 0x00000001
@@ -104,9 +99,9 @@
unsigned int sbz5;
};
-#define KGSL_MEMSTORE_OFFSET(ctxt_id, field) \
- ((ctxt_id)*sizeof(struct kgsl_devmemstore) + \
- offsetof(struct kgsl_devmemstore, field))
+#define KGSL_DEVICE_MEMSTORE_OFFSET(field) \
+ offsetof(struct kgsl_devmemstore, field)
+
/* timestamp id*/
enum kgsl_timestamp_type {
@@ -223,14 +218,6 @@
#define IOCTL_KGSL_DEVICE_WAITTIMESTAMP \
_IOW(KGSL_IOC_TYPE, 0x6, struct kgsl_device_waittimestamp)
-struct kgsl_device_waittimestamp_ctxtid {
- unsigned int context_id;
- unsigned int timestamp;
- unsigned int timeout;
-};
-
-#define IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID \
- _IOW(KGSL_IOC_TYPE, 0x7, struct kgsl_device_waittimestamp_ctxtid)
/* issue indirect commands to the GPU.
* drawctxt_id must have been created with IOCTL_KGSL_DRAWCTXT_CREATE
@@ -324,26 +311,6 @@
#define IOCTL_KGSL_MAP_USER_MEM \
_IOWR(KGSL_IOC_TYPE, 0x15, struct kgsl_map_user_mem)
-struct kgsl_cmdstream_readtimestamp_ctxtid {
- unsigned int context_id;
- unsigned int type;
- unsigned int timestamp; /*output param */
-};
-
-#define IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_CTXTID \
- _IOWR(KGSL_IOC_TYPE, 0x16, struct kgsl_cmdstream_readtimestamp_ctxtid)
-
-struct kgsl_cmdstream_freememontimestamp_ctxtid {
- unsigned int context_id;
- unsigned int gpuaddr;
- unsigned int type;
- unsigned int timestamp;
-};
-
-#define IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP_CTXTID \
- _IOW(KGSL_IOC_TYPE, 0x17, \
- struct kgsl_cmdstream_freememontimestamp_ctxtid)
-
/* add a block of pmem or fb into the GPU address space */
struct kgsl_sharedmem_from_pmem {
int pmem_fd;
diff --git a/include/media/tavarua.h b/include/media/tavarua.h
index 211d146..381f5c4 100644
--- a/include/media/tavarua.h
+++ b/include/media/tavarua.h
@@ -472,7 +472,8 @@
TAVARUA_EVT_NEW_SRCH_LIST,
TAVARUA_EVT_NEW_AF_LIST,
TAVARUA_EVT_TXRDSDAT,
- TAVARUA_EVT_TXRDSDONE
+ TAVARUA_EVT_TXRDSDONE,
+ TAVARUA_EVT_RADIO_DISABLED
};
enum tavarua_region_t {
diff --git a/sound/soc/msm/msm-pcm-lpa.c b/sound/soc/msm/msm-pcm-lpa.c
index 1acb57f..575839d6 100644
--- a/sound/soc/msm/msm-pcm-lpa.c
+++ b/sound/soc/msm/msm-pcm-lpa.c
@@ -94,6 +94,8 @@
pr_debug("ASM_DATA_EVENT_WRITE_DONE\n");
pr_debug("Buffer Consumed = 0x%08x\n", *ptrmem);
prtd->pcm_irq_pos += prtd->pcm_count;
+ if (prtd->pcm_irq_pos >= prtd->pcm_size)
+ prtd->pcm_irq_pos = 0;
if (atomic_read(&prtd->start))
snd_pcm_period_elapsed(substream);
else
@@ -415,8 +417,6 @@
struct snd_pcm_runtime *runtime = substream->runtime;
struct msm_audio *prtd = runtime->private_data;
- if (prtd->pcm_irq_pos >= prtd->pcm_size)
- prtd->pcm_irq_pos = 0;
pr_debug("%s: pcm_irq_pos = %d\n", __func__, prtd->pcm_irq_pos);
return bytes_to_frames(runtime, (prtd->pcm_irq_pos));
}