Merge "Perf: Enable CP10 and CP11 access in CPACR" into msm-3.0
diff --git a/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt b/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt
index 8cc3c54..b5ca08e 100644
--- a/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt
+++ b/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt
@@ -17,6 +17,13 @@
Up to a maximum of 256 peripherals are supported and the mapping is target
specific.
+Data format of pmic-arb-ppid-map:
+<0x13100001>
+value is 32 bit.
+MSB 12 bits are the PPID
+12 bits padding
+LSB 8 bit are the APID
+
Example:
qcom,spmi@fc4c0000 {
@@ -27,6 +34,8 @@
interrupts = <0>;
qcom,pmic-arb-ee = <0>;
qcom,pmic-arb-channel = <0>;
- qcom,pmic-arb-ppid-map = <0x130 0x00>, /* PPID 0x130, APID 0 */
- <0x131 0x01>; /* PPID 0x131, APID 1 */
+ qcom,pmic-arb-ppid-map = <0x13000000>, /* PPID 0x130, APID 0 */
+ <0x13100001>, /* PPID 0x131, APID 1 */
};
+
+
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b46d7f1..f5046dc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -131,7 +131,7 @@
config GENERIC_LOCKBREAK
bool
- default y
+ default y if !ARM_TICKET_LOCKS
depends on SMP && PREEMPT
config ARM_TICKET_LOCKS
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index 725971d..74a3b3f 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dts
@@ -94,93 +94,96 @@
interrupts = <0 190 0 0 187 0>;
qcom,pmic-arb-ee = <0>;
qcom,pmic-arb-channel = <0>;
- qcom,pmic-arb-ppid-map = <0x130 0x00>, /* PM8941_LDO1 */
- <0x131 0x01>, /* PM8941_LDO2 */
- <0x132 0x02>, /* PM8941_LDO3 */
- <0x133 0x03>, /* PM8941_LDO4 */
- <0x134 0x04>, /* PM8941_LDO5 */
- <0x135 0x05>, /* PM8941_LDO6 */
- <0x136 0x06>, /* PM8941_LDO7 */
- <0x137 0x07>, /* PM8941_LDO8 */
- <0x138 0x08>, /* PM8941_LDO9 */
- <0x139 0x09>, /* PM8941_LDO10 */
- <0x13a 0x0a>, /* PM8941_LDO11 */
- <0x13b 0x0b>, /* PM8941_LDO12 */
- <0x13c 0x0c>, /* PM8941_LDO13 */
- <0x13d 0x0d>, /* PM8941_LDO14 */
- <0x13e 0x0e>, /* PM8941_LDO15 */
- <0x13f 0x0f>, /* PM8941_LDO16 */
- <0x140 0x10>, /* PM8941_LDO17 */
- <0x141 0x11>, /* PM8941_LDO18 */
- <0x142 0x12>, /* PM8941_LDO19 */
- <0x143 0x13>, /* PM8941_LDO20 */
- <0x144 0x14>, /* PM8941_LDO21 */
- <0x145 0x15>, /* PM8941_LDO22 */
- <0x146 0x16>, /* PM8941_LDO23 */
- <0x147 0x17>, /* PM8941_LDO24 */
- <0x148 0x18>, /* PM8941_LDO25 */
- <0x149 0x19>, /* PM8941_LDO26 */
- <0x0c0 0x1a>, /* PM8941_GPIO1 */
- <0x0c1 0x1b>, /* PM8941_GPIO2 */
- <0x0c2 0x1c>, /* PM8941_GPIO3 */
- <0x0c3 0x1d>, /* PM8941_GPIO4 */
- <0x0c4 0x1e>, /* PM8941_GPIO5 */
- <0x0c5 0x1f>, /* PM8941_GPIO6 */
- <0x0c6 0x20>, /* PM8941_GPIO7 */
- <0x0c7 0x21>, /* PM8941_GPIO8 */
- <0x0c8 0x22>, /* PM8941_GPIO9 */
- <0x0c9 0x23>, /* PM8941_GPIO10 */
- <0x0ca 0x24>, /* PM8941_GPIO11 */
- <0x0cb 0x25>, /* PM8941_GPIO12 */
- <0x0cc 0x26>, /* PM8941_GPIO13 */
- <0x0cd 0x27>, /* PM8941_GPIO14 */
- <0x0ce 0x28>, /* PM8941_GPIO15 */
- <0x0cf 0x29>, /* PM8941_GPIO16 */
- <0x0d0 0x2a>, /* PM8941_GPIO17 */
- <0x0d1 0x2b>, /* PM8941_GPIO18 */
- <0x0d2 0x2c>, /* PM8941_GPIO19 */
- <0x0d3 0x2d>, /* PM8941_GPIO20 */
- <0x0d4 0x2e>, /* PM8941_GPIO21 */
- <0x0d5 0x2f>, /* PM8941_GPIO22 */
- <0x0d6 0x30>, /* PM8941_GPIO23 */
- <0x0d7 0x31>, /* PM8941_GPIO24 */
- <0x0d8 0x32>, /* PM8941_GPIO25 */
- <0x0d9 0x33>, /* PM8941_GPIO26 */
- <0x0da 0x34>, /* PM8941_GPIO27 */
- <0x0db 0x35>, /* PM8941_GPIO28 */
- <0x0dc 0x36>, /* PM8941_GPIO29 */
- <0x0dd 0x37>, /* PM8941_GPIO30 */
- <0x0de 0x38>, /* PM8941_GPIO31 */
- <0x0df 0x39>, /* PM8941_GPIO32 */
- <0x0e0 0x3a>, /* PM8941_GPIO33 */
- <0x0e1 0x3b>, /* PM8941_GPIO34 */
- <0x0e2 0x3c>, /* PM8941_GPIO35 */
- <0x0e3 0x3d>, /* PM8941_GPIO36 */
- <0x028 0x3e>, /* COINCELL */
- <0x005 0x3f>, /* INTERRUPT */
- <0x001 0x40>, /* PM8941_0 */
- <0x201 0x41>, /* PM8841_0 */
- <0x101 0x42>, /* PM8941_1 */
- <0x301 0x43>, /* PM8841_1 */
- <0x008 0x44>, /* PON0 */
- <0x208 0x45>, /* PON1 */
- <0x110 0x46>, /* PM8941_SMPS1 */
- <0x111 0x47>, /* PM8941_SMPS2 */
- <0x112 0x48>, /* PM8941_SMPS3 */
- <0x310 0x49>, /* PM8841_SMPS1 */
- <0x311 0x4a>, /* PM8841_SMPS2 */
- <0x312 0x4b>, /* PM8841_SMPS3 */
- <0x313 0x4c>, /* PM8841_SMPS4 */
- <0x314 0x4d>, /* PM8841_SMPS5 */
- <0x315 0x4e>, /* PM8841_SMPS6 */
- <0x316 0x4f>, /* PM8841_SMPS7 */
- <0x317 0x50>, /* PM8841_SMPS8 */
- <0x050 0x51>, /* SHARED_XO */
- <0x051 0x52>, /* BB_CLK1 */
- <0x052 0x53>, /* BB_CLK2 */
- <0x059 0x54>, /* SLEEP_CLK */
- <0x010 0x55>, /* SMBC_OVP */
- <0x011 0x56>, /* SMBC_CHG */
- <0x012 0x57>; /* SMBC_BIF */
+ qcom,pmic-arb-ppid-map = <0x13000000>, /* PM8941_LDO1 */
+ <0x13100001>, /* PM8941_LDO2 */
+ <0x13200002>, /* PM8941_LDO3 */
+ <0x13300003>, /* PM8941_LDO4 */
+ <0x13400004>, /* PM8941_LDO5 */
+ <0x13500005>, /* PM8941_LDO6 */
+ <0x13600006>, /* PM8941_LDO7 */
+ <0x13700007>, /* PM8941_LDO8 */
+ <0x13800008>, /* PM8941_LDO9 */
+ <0x13900009>, /* PM8941_LDO10 */
+ <0x13a0000a>, /* PM8941_LDO11 */
+ <0x13b0000b>, /* PM8941_LDO12 */
+ <0x13c0000c>, /* PM8941_LDO13 */
+ <0x13d0000d>, /* PM8941_LDO14 */
+ <0x13e0000e>, /* PM8941_LDO15 */
+ <0x13f0000f>, /* PM8941_LDO16 */
+ <0x14000010>, /* PM8941_LDO17 */
+ <0x14100011>, /* PM8941_LDO18 */
+ <0x14200012>, /* PM8941_LDO19 */
+ <0x14300013>, /* PM8941_LDO20 */
+ <0x14400014>, /* PM8941_LDO21 */
+ <0x14500015>, /* PM8941_LDO22 */
+ <0x14600016>, /* PM8941_LDO23 */
+ <0x14700017>, /* PM8941_LDO24 */
+ <0x14800018>, /* PM8941_LDO25 */
+ <0x14900019>, /* PM8941_LDO26 */
+ <0x0c00001a>, /* PM8941_GPIO1 */
+ <0x0c10001b>, /* PM8941_GPIO2 */
+ <0x0c20001c>, /* PM8941_GPIO3 */
+ <0x0c30001d>, /* PM8941_GPIO4 */
+ <0x0c40001e>, /* PM8941_GPIO5 */
+ <0x0c50001f>, /* PM8941_GPIO6 */
+ <0x0c600020>, /* PM8941_GPIO7 */
+ <0x0c700021>, /* PM8941_GPIO8 */
+ <0x0c800022>, /* PM8941_GPIO9 */
+ <0x0c900023>, /* PM8941_GPIO10 */
+ <0x0ca00024>, /* PM8941_GPIO11 */
+ <0x0cb00025>, /* PM8941_GPIO12 */
+ <0x0cc00026>, /* PM8941_GPIO13 */
+ <0x0cd00027>, /* PM8941_GPIO14 */
+ <0x0ce00028>, /* PM8941_GPIO15 */
+ <0x0cf00029>, /* PM8941_GPIO16 */
+ <0x0d00002a>, /* PM8941_GPIO17 */
+ <0x0d10002b>, /* PM8941_GPIO18 */
+ <0x0d20002c>, /* PM8941_GPIO19 */
+ <0x0d30002d>, /* PM8941_GPIO20 */
+ <0x0d40002e>, /* PM8941_GPIO21 */
+ <0x0d50002f>, /* PM8941_GPIO22 */
+ <0x0d600030>, /* PM8941_GPIO23 */
+ <0x0d700031>, /* PM8941_GPIO24 */
+ <0x0d800032>, /* PM8941_GPIO25 */
+ <0x0d900033>, /* PM8941_GPIO26 */
+ <0x0da00034>, /* PM8941_GPIO27 */
+ <0x0db00035>, /* PM8941_GPIO28 */
+ <0x0dc00036>, /* PM8941_GPIO29 */
+ <0x0dd00037>, /* PM8941_GPIO30 */
+ <0x0de00038>, /* PM8941_GPIO31 */
+ <0x0df00039>, /* PM8941_GPIO32 */
+ <0x0e00003a>, /* PM8941_GPIO33 */
+ <0x0e10003b>, /* PM8941_GPIO34 */
+ <0x0e20003c>, /* PM8941_GPIO35 */
+ <0x0e30003d>, /* PM8941_GPIO36 */
+ <0x0280003e>, /* COINCELL */
+ <0x0100003f>, /* SMBC_OVP */
+ <0x01100040>, /* SMBC_CHG */
+ <0x01200041>, /* SMBC_BIF */
+ <0x00500042>, /* INTERRUPT */
+ <0x00100043>, /* PM8941_0 */
+ <0x20100044>, /* PM8841_0 */
+ <0x10100045>, /* PM8941_1 */
+ <0x30100046>, /* PM8841_1 */
+ <0x00800047>, /* PON0 */
+ <0x20800048>, /* PON1 */
+ <0x11000049>, /* PM8941_SMPS1 */
+ <0x1110004a>, /* PM8941_SMPS2 */
+ <0x1120004b>, /* PM8941_SMPS3 */
+ <0x3100004c>, /* PM8841_SMPS1 */
+ <0x3110004d>, /* PM8841_SMPS2 */
+ <0x3120004e>, /* PM8841_SMPS3 */
+ <0x3130004f>, /* PM8841_SMPS4 */
+ <0x31400050>, /* PM8841_SMPS5 */
+ <0x31500051>, /* PM8841_SMPS6 */
+ <0x31600052>, /* PM8841_SMPS7 */
+ <0x31700053>, /* PM8841_SMPS8 */
+ <0x05000054>, /* SHARED_XO */
+ <0x05100055>, /* BB_CLK1 */
+ <0x05200056>, /* BB_CLK2 */
+ <0x05900057>, /* SLEEP_CLK */
+ <0x07000058>, /* PBS_CORE */
+ <0x07100059>, /* PBS_CLIENT1 */
+ <0x0720005a>; /* PBS_CLIENT2 */
};
};
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 7d8284a..d14757b 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -191,8 +191,10 @@
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
CONFIG_IP6_NF_MANGLE=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
@@ -337,7 +339,7 @@
CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
CONFIG_FB_MSM_OVERLAY1_WRITEBACK=y
CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
-CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 406992a..dafaffc 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -193,8 +193,10 @@
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
CONFIG_IP6_NF_MANGLE=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 0f31a0f..1004683 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -222,6 +222,7 @@
select MSM_SPM_V2
select MSM_L2_SPM
select MSM_PM8X60 if PM
+ select CPU_HAS_L2_PMU
config ARCH_MSMCOPPER
bool "MSM Copper"
@@ -485,6 +486,14 @@
help
Support for the Qualcomm MSM8625 SURF.
+config MACH_MSM8625_EVB
+ depends on ARCH_MSM8625
+ depends on !MSM_STACKED_MEMORY
+ default y
+ bool "MSM8625 EVB"
+ help
+ Support for the Qualcomm MSM8625 Reference Design.
+
config MACH_MSM7X30_SURF
depends on ARCH_MSM7X30
depends on !MSM_STACKED_MEMORY
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 2f55215..525dce4 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -54,7 +54,7 @@
msm-etm-objs := etm.o
obj-$(CONFIG_MSM_ETM) += msm-etm.o
-obj-$(CONFIG_MSM_QDSS) += qdss.o qdss-etb.o qdss-tpiu.o qdss-funnel.o qdss-ptm.o
+obj-$(CONFIG_MSM_QDSS) += qdss.o qdss-etb.o qdss-tpiu.o qdss-funnel.o qdss-etm.o
quiet_cmd_mkrpcsym = MKCAP $@
cmd_mkrpcsym = $(PERL) $(srctree)/$(src)/mkrpcsym.pl $< $@
@@ -232,6 +232,7 @@
obj-$(CONFIG_ARCH_MSM8625) += devices-msm7x27a.o clock-pcom-lookup.o
obj-$(CONFIG_MACH_MSM8625_RUMI3) += board-msm7x27a.o
obj-$(CONFIG_MACH_MSM8625_SURF) += board-msm7x27a.o board-7627a-all.o
+obj-$(CONFIG_MACH_MSM8625_EVB) += board-qrd7627a.o board-7627a-all.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o memory_topology.o
obj-$(CONFIG_ARCH_MSM7X30) += clock-local.o clock-7x30.o acpuclock-7x30.o
obj-$(CONFIG_MACH_MSM7X25_SURF) += board-msm7x27.o devices-msm7x25.o
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index 781d896..ae4b084 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -49,12 +49,12 @@
* enum - For acpuclock PLL IDs
*/
enum {
- ACPU_PLL_TCXO = -1,
ACPU_PLL_0 = 0,
ACPU_PLL_1,
ACPU_PLL_2,
ACPU_PLL_3,
ACPU_PLL_4,
+ ACPU_PLL_TCXO,
ACPU_PLL_END,
};
diff --git a/arch/arm/mach-msm/acpuclock-7x30.c b/arch/arm/mach-msm/acpuclock-7x30.c
index 7ee4e5b..f2fb292 100644
--- a/arch/arm/mach-msm/acpuclock-7x30.c
+++ b/arch/arm/mach-msm/acpuclock-7x30.c
@@ -1,7 +1,7 @@
/*
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-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
@@ -76,7 +76,6 @@
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 };
@@ -259,7 +258,6 @@
/* 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]);
@@ -392,19 +390,6 @@
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)];
@@ -479,7 +464,6 @@
pll2_fixup();
populate_plls();
acpuclk_hw_init();
- lpj_init();
setup_cpufreq_table();
acpuclk_register(&acpuclk_7x30_data);
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 99c3d78..8d35148 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -194,7 +194,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x200,
.aux_clk_sel = MSM_ACC0_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait0", 1150000 },
+ .vreg[VREG_CORE] = { "krait0", 1300000 },
.vreg[VREG_MEM] = { "krait0_mem", 1150000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8921_L24 },
@@ -209,7 +209,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x240,
.aux_clk_sel = MSM_ACC1_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait1", 1150000 },
+ .vreg[VREG_CORE] = { "krait1", 1300000 },
.vreg[VREG_MEM] = { "krait1_mem", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_L24 },
@@ -224,7 +224,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x280,
.aux_clk_sel = MSM_ACC2_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait2", 1150000 },
+ .vreg[VREG_CORE] = { "krait2", 1300000 },
.vreg[VREG_MEM] = { "krait2_mem", 1150000,
RPM_VREG_VOTER4,
RPM_VREG_ID_PM8921_L24 },
@@ -239,7 +239,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x2C0,
.aux_clk_sel = MSM_ACC3_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait3", 1150000 },
+ .vreg[VREG_CORE] = { "krait3", 1300000 },
.vreg[VREG_MEM] = { "krait3_mem", 1150000,
RPM_VREG_VOTER5,
RPM_VREG_ID_PM8921_L24 },
@@ -375,6 +375,7 @@
[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
[5] = BW_MBPS(3600), /* At least 450 MHz on bus. */
[6] = BW_MBPS(3936), /* At least 492 MHz on bus. */
+ [7] = BW_MBPS(4264), /* At least 533 MHz on bus. */
};
static struct msm_bus_scale_pdata bus_client_pdata = {
@@ -546,47 +547,48 @@
#define L2(x) (&l2_freq_tbl_8064[(x)])
static struct l2_level l2_freq_tbl_8064[] = {
[0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, 1050000, 1050000, 0 },
- [1] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 0 },
- [2] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 1 },
- [3] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 1 },
- [4] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 1 },
+ [1] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
+ [2] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 2 },
+ [3] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 2 },
+ [4] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 2 },
[5] = { { 594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
- [6] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 2 },
- [7] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 2 },
- [8] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 3 },
- [9] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 3 },
- [10] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 3 },
- [11] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 3 },
- [12] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 3 },
- [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 3 },
- [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 4 },
- [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 4 },
- [16] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 4 },
- [17] = { { 1242000, HFPLL, 1, 0, 0x2E }, 1150000, 1150000, 4 },
- [18] = { { 1296000, HFPLL, 1, 0, 0x30 }, 1150000, 1150000, 4 },
- [19] = { { 1350000, HFPLL, 1, 0, 0x32 }, 1150000, 1150000, 4 },
- [20] = { { 1404000, HFPLL, 1, 0, 0x34 }, 1150000, 1150000, 4 },
- [21] = { { 1458000, HFPLL, 1, 0, 0x36 }, 1150000, 1150000, 5 },
- [22] = { { 1512000, HFPLL, 1, 0, 0x38 }, 1150000, 1150000, 5 },
- [23] = { { 1566000, HFPLL, 1, 0, 0x3A }, 1150000, 1150000, 5 },
- [24] = { { 1620000, HFPLL, 1, 0, 0x3C }, 1150000, 1150000, 5 },
- [25] = { { 1674000, HFPLL, 1, 0, 0x3E }, 1150000, 1150000, 5 },
+ [6] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 4 },
+ [7] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 4 },
+ [8] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 4 },
+ [9] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 4 },
+ [10] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 4 },
+ [11] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 7 },
+ [12] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 7 },
+ [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 7 },
+ [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 7 },
+ [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 7 },
};
/* TODO: Update core voltages when data is available. */
static struct acpu_level acpu_freq_tbl_8064[] = {
- { 0, {STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 1050000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 1050000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(2), 1050000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(3), 1050000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(4), 1050000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 1050000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1050000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 1050000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(8), 1150000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(9), 1150000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1150000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1150000 },
+ { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 975000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 975000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 1000000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 1025000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 1075000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1100000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1125000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1175000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1200000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1225000 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1237500 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(15), 1237500 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(15), 1250000 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 604769d..62e5dda 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -66,7 +66,6 @@
}
};
-#define PANEL_NAME_MAX_LEN 30
#define LVDS_CHIMEI_PANEL_NAME "lvds_chimei_wxga"
#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
#define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME "mipi_video_chimei_wxga"
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index e9b497b..9fbb1c7 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -151,17 +151,17 @@
.pwrlevel = {
{
.gpu_freq = 400000000,
- .bus_freq = 4,
+ .bus_freq = 3,
.io_fraction = 0,
},
{
.gpu_freq = 320000000,
- .bus_freq = 3,
+ .bus_freq = 2,
.io_fraction = 33,
},
{
.gpu_freq = 1920000000,
- .bus_freq = 2,
+ .bus_freq = 1,
.io_fraction = 100,
},
{
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 05002a2..f4650a9 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -141,6 +141,8 @@
/* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
PM8921_MPP_INIT(7, D_OUTPUT, PM8921_MPP_DIG_LEVEL_VPH, DOUT_CTRL_LOW),
PM8921_MPP_INIT(8, D_OUTPUT, PM8921_MPP_DIG_LEVEL_S4, DOUT_CTRL_LOW),
+ /*MPP9 is used to detect docking station connection/removal on Liquid*/
+ PM8921_MPP_INIT(9, D_INPUT, PM8921_MPP_DIG_LEVEL_S4, DIN_TO_INT),
};
void __init apq8064_pm8xxx_gpio_mpp_init(void)
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 247b230..e25f418 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -226,6 +226,7 @@
};
VREG_CONSUMERS(EXT_MPP8) = {
REGULATOR_SUPPLY("ext_mpp8", NULL),
+ REGULATOR_SUPPLY("vbus", "msm_ehci_host.1"),
};
VREG_CONSUMERS(EXT_3P3V) = {
REGULATOR_SUPPLY("ext_3p3v", NULL),
@@ -469,15 +470,15 @@
/* SAW regulator constraints */
struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5 =
/* ID vreg_name min_uV max_uV */
- SAW_VREG_INIT(S5, "8921_s5", 950000, 1150000);
+ SAW_VREG_INIT(S5, "8921_s5", 950000, 1300000);
struct regulator_init_data msm8064_saw_regulator_pdata_8921_s6 =
- SAW_VREG_INIT(S6, "8921_s6", 950000, 1150000);
+ SAW_VREG_INIT(S6, "8921_s6", 950000, 1300000);
struct regulator_init_data msm8064_saw_regulator_pdata_8821_s0 =
/* ID vreg_name min_uV max_uV */
- SAW_VREG_INIT(8821_S0, "8821_s0", 950000, 1150000);
+ SAW_VREG_INIT(8821_S0, "8821_s0", 950000, 1300000);
struct regulator_init_data msm8064_saw_regulator_pdata_8821_s1 =
- SAW_VREG_INIT(8821_S1, "8821_s1", 950000, 1150000);
+ SAW_VREG_INIT(8821_S1, "8821_s1", 950000, 1300000);
/* PM8921 regulator constraints */
struct pm8xxx_regulator_platform_data
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index 41be3e7..e9c455d 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -210,6 +210,8 @@
#endif
.sup_clk_table = sdc1_sup_clk_rates,
.sup_clk_cnt = ARRAY_SIZE(sdc1_sup_clk_rates),
+ .pclk_src_dfab = 1,
+ .nonremovable = 1,
.pin_data = &mmc_slot_pin_data[SDCC1],
.vreg_data = &mmc_slot_vreg_data[SDCC1],
};
@@ -228,6 +230,7 @@
.mmc_bus_width = MMC_CAP_4_BIT_DATA,
.sup_clk_table = sdc3_sup_clk_rates,
.sup_clk_cnt = ARRAY_SIZE(sdc3_sup_clk_rates),
+ .pclk_src_dfab = 1,
.pin_data = &mmc_slot_pin_data[SDCC3],
.vreg_data = &mmc_slot_vreg_data[SDCC3],
.status_gpio = 26,
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index ac937a2..0ea3ea8 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -54,6 +54,7 @@
#include <linux/bootmem.h>
#include <asm/setup.h>
#include <mach/dma.h>
+#include <mach/msm_dsps.h>
#include <mach/msm_bus_board.h>
#include <mach/cpuidle.h>
#include <mach/mdm2.h>
@@ -468,24 +469,75 @@
},
};
+/* Bandwidth requests (zero) if no vote placed */
+static struct msm_bus_vectors usb_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+
+/* Bus bandwidth requests in Bytes/sec */
+static struct msm_bus_vectors usb_max_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 60000000, /* At least 480Mbps on bus. */
+ .ib = 960000000, /* MAX bursts rate */
+ },
+};
+
+static struct msm_bus_paths usb_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(usb_init_vectors),
+ usb_init_vectors,
+ },
+ {
+ ARRAY_SIZE(usb_max_vectors),
+ usb_max_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata usb_bus_scale_pdata = {
+ usb_bus_scale_usecases,
+ ARRAY_SIZE(usb_bus_scale_usecases),
+ .name = "usb",
+};
+
static struct msm_otg_platform_data msm_otg_pdata = {
.mode = USB_OTG,
.otg_control = OTG_PMIC_CONTROL,
.phy_type = SNPS_28NM_INTEGRATED_PHY,
.pmic_id_irq = PM8921_USB_ID_IN_IRQ(PM8921_IRQ_BASE),
.power_budget = 750,
+ .bus_scale_table = &usb_bus_scale_pdata,
};
-static struct msm_usb_host_platform_data msm_ehci_host_pdata = {
+static struct msm_usb_host_platform_data msm_ehci_host_pdata3 = {
.power_budget = 500,
};
+#ifdef CONFIG_USB_EHCI_MSM_HOST4
+static struct msm_usb_host_platform_data msm_ehci_host_pdata4;
+#endif
+
static void __init apq8064_ehci_host_init(void)
{
if (machine_is_apq8064_liquid()) {
+ msm_ehci_host_pdata3.dock_connect_irq =
+ PM8921_MPP_IRQ(PM8921_IRQ_BASE, 9);
+
apq8064_device_ehci_host3.dev.platform_data =
- &msm_ehci_host_pdata;
+ &msm_ehci_host_pdata3;
platform_device_register(&apq8064_device_ehci_host3);
+
+#ifdef CONFIG_USB_EHCI_MSM_HOST4
+ apq8064_device_ehci_host4.dev.platform_data =
+ &msm_ehci_host_pdata4;
+ platform_device_register(&apq8064_device_ehci_host4);
+#endif
}
}
@@ -1847,6 +1899,18 @@
},
};
+/* Sensors DSPS platform data */
+#define DSPS_PIL_GENERIC_NAME "dsps"
+static void __init apq8064_init_dsps(void)
+{
+ struct msm_dsps_platform_data *pdata =
+ msm_dsps_device_8064.dev.platform_data;
+ pdata->pil_name = DSPS_PIL_GENERIC_NAME;
+ pdata->gpios = NULL;
+ pdata->gpios_num = 0;
+
+ platform_device_register(&msm_dsps_device_8064);
+}
static void __init apq8064_clock_init(void)
{
@@ -1970,6 +2034,7 @@
platform_device_register(&apq8064_slim_ctrl);
slim_register_board_info(apq8064_slim_devices,
ARRAY_SIZE(apq8064_slim_devices));
+ apq8064_init_dsps();
msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
acpuclk_init(&acpuclk_8064_soc_data);
msm_spm_l2_init(msm_spm_l2_data);
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index a840877..2f18897 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -68,7 +68,6 @@
#define MDP_VSYNC_GPIO 0
-#define PANEL_NAME_MAX_LEN 30
#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME "mipi_cmd_novatek_qhd"
#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME "mipi_video_novatek_qhd"
#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
@@ -781,8 +780,7 @@
platform_device_register(&mipi_dsi_novatek_panel_device);
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
- if (!cpu_is_msm8930())
- platform_device_register(&hdmi_msm_device);
+ platform_device_register(&hdmi_msm_device);
#endif
platform_device_register(&mipi_dsi_toshiba_panel_device);
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index e89bed4..26211bf 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -52,7 +52,7 @@
.name = "sdc_vdd",
.high_vol_level = 2950000,
.low_vol_level = 2950000,
- .hpm_uA = 600000, /* 600mA */
+ .hpm_uA = 800000, /* 800mA */
}
};
@@ -208,11 +208,11 @@
};
static unsigned int sdc1_sup_clk_rates[] = {
- 400000, 24000000, 48000000
+ 400000, 24000000, 48000000,
};
static unsigned int sdc3_sup_clk_rates[] = {
- 400000, 24000000, 48000000, 96000000
+ 400000, 24000000, 48000000, 96000000, 192000000,
};
#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
@@ -264,7 +264,7 @@
.xpc_cap = 1,
.uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
- MMC_CAP_MAX_CURRENT_600),
+ MMC_CAP_UHS_SDR104 | MMC_CAP_MAX_CURRENT_800),
};
#endif
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index 4dba1be..80372c5 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -46,13 +46,8 @@
#define MSM_FB_EXT_BUF_SIZE 0
#endif
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-/* 4 bpp x 2 page HDMI case */
-#define MSM_FB_SIZE roundup((1920 * 1088 * 4 * 2), 4096)
-#else
/* Note: must be multiple of 4096 */
#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE, 4096)
-#endif
#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
#define MSM_FB_OVERLAY0_WRITEBACK_SIZE roundup((1920 * 1200 * 3 * 2), 4096)
@@ -68,7 +63,6 @@
#define MDP_VSYNC_GPIO 0
-#define PANEL_NAME_MAX_LEN 30
#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME "mipi_cmd_novatek_qhd"
#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME "mipi_video_novatek_qhd"
#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
@@ -80,6 +74,12 @@
#define HDMI_PANEL_NAME "hdmi_msm"
#define TVOUT_PANEL_NAME "tvout_msm"
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+unsigned char hdmi_is_primary = 1;
+#else
+unsigned char hdmi_is_primary;
+#endif
+
static struct resource msm_fb_resources[] = {
{
.flags = IORESOURCE_DMA,
@@ -624,29 +624,16 @@
#endif
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-static int mdp_core_clk_rate_table[] = {
- 200000000,
- 200000000,
- 200000000,
- 200000000,
-};
-#else
static int mdp_core_clk_rate_table[] = {
85330000,
128000000,
160000000,
200000000,
};
-#endif
static struct msm_panel_common_pdata mdp_pdata = {
.gpio = MDP_VSYNC_GPIO,
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- .mdp_core_clk_rate = 200000000,
-#else
.mdp_core_clk_rate = 85330000,
-#endif
.mdp_core_clk_table = mdp_core_clk_rate_table,
.num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
#ifdef CONFIG_MSM_BUS_SCALING
@@ -833,16 +820,6 @@
},
};
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-static struct msm_bus_vectors dtv_bus_def_vectors[] = {
- {
- .src = MSM_BUS_MASTER_MDP_PORT0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 2000000000,
- .ib = 2000000000,
- },
-};
-#else
static struct msm_bus_vectors dtv_bus_def_vectors[] = {
{
.src = MSM_BUS_MASTER_MDP_PORT0,
@@ -851,7 +828,6 @@
.ib = 707616000 * 2,
},
};
-#endif
static struct msm_bus_paths dtv_bus_scale_usecases[] = {
{
@@ -1108,3 +1084,27 @@
pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
size, addr, __pa(addr));
}
+
+void __init msm8960_set_display_params(char *prim_panel, char *ext_panel)
+{
+ if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
+ strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
+ PANEL_NAME_MAX_LEN);
+ pr_debug("msm_fb_pdata.prim_panel_name %s\n",
+ msm_fb_pdata.prim_panel_name);
+
+ if (!strncmp((char *)msm_fb_pdata.prim_panel_name,
+ HDMI_PANEL_NAME, strnlen(HDMI_PANEL_NAME,
+ PANEL_NAME_MAX_LEN))) {
+ pr_debug("HDMI is the primary display by"
+ " boot parameter\n");
+ hdmi_is_primary = 1;
+ }
+ }
+ if (strnlen(ext_panel, PANEL_NAME_MAX_LEN)) {
+ strlcpy(msm_fb_pdata.ext_panel_name, ext_panel,
+ PANEL_NAME_MAX_LEN);
+ pr_debug("msm_fb_pdata.ext_panel_name %s\n",
+ msm_fb_pdata.ext_panel_name);
+ }
+}
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index d47bf96..3b0f8be 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -131,12 +131,9 @@
#define MSM_PMEM_ADSP_SIZE 0x7800000
#define MSM_PMEM_AUDIO_SIZE 0x2B4000
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-#define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
-#else
#define MSM_PMEM_SIZE 0x2800000 /* 40 Mbytes */
-#endif
#define MSM_LIQUID_PMEM_SIZE 0x4000000 /* 64 Mbytes */
+#define MSM_HDMI_PRIM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
#define MSM_PMEM_KERNEL_EBI1_SIZE 0x280000
@@ -148,7 +145,9 @@
#define MSM_ION_AUDIO_SIZE MSM_PMEM_AUDIO_SIZE
#define MSM_ION_HEAP_NUM 8
#define MSM_LIQUID_ION_MM_SIZE (MSM_ION_MM_SIZE + 0x600000)
-static unsigned int msm_ion_cp_mm_size = MSM_ION_MM_SIZE;
+#define MSM_LIQUID_ION_SF_SIZE MSM_LIQUID_PMEM_SIZE
+#define MSM_HDMI_PRIM_ION_SF_SIZE MSM_HDMI_PRIM_PMEM_SIZE
+static unsigned msm_ion_sf_size = MSM_ION_SF_SIZE;
#else
#define MSM_PMEM_KERNEL_EBI1_SIZE 0x110C000
#define MSM_ION_HEAP_NUM 1
@@ -308,8 +307,13 @@
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
android_pmem_adsp_pdata.size = pmem_adsp_size;
- if (!pmem_param_set && machine_is_msm8960_liquid())
- pmem_size = MSM_LIQUID_PMEM_SIZE;
+ if (!pmem_param_set) {
+ if (machine_is_msm8960_liquid())
+ pmem_size = MSM_LIQUID_PMEM_SIZE;
+ if (hdmi_is_primary)
+ pmem_size = MSM_HDMI_PRIM_PMEM_SIZE;
+ }
+
android_pmem_pdata.size = pmem_size;
#endif
android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
@@ -463,14 +467,22 @@
{
unsigned int i;
- if (!pmem_param_set && machine_is_msm8960_liquid()) {
- msm_ion_cp_mm_size = MSM_LIQUID_ION_MM_SIZE;
- for (i = 0; i < ion_pdata.nr; i++) {
- if (ion_pdata.heaps[i].id == ION_CP_MM_HEAP_ID) {
- ion_pdata.heaps[i].size = msm_ion_cp_mm_size;
- pr_debug("msm_ion_cp_mm_size 0x%x\n",
- msm_ion_cp_mm_size);
- break;
+ if (!pmem_param_set) {
+ if (machine_is_msm8960_liquid())
+ msm_ion_sf_size = MSM_LIQUID_ION_SF_SIZE;
+
+ if (hdmi_is_primary)
+ msm_ion_sf_size = MSM_HDMI_PRIM_ION_SF_SIZE;
+
+ if (machine_is_msm8960_liquid() || hdmi_is_primary) {
+ for (i = 0; i < ion_pdata.nr; i++) {
+ if (ion_pdata.heaps[i].id == ION_SF_HEAP_ID) {
+ ion_pdata.heaps[i].size =
+ msm_ion_sf_size;
+ pr_debug("msm_ion_sf_size 0x%x\n",
+ msm_ion_sf_size);
+ break;
+ }
}
}
}
@@ -633,8 +645,27 @@
place_movable_zone();
}
+static char prim_panel_name[PANEL_NAME_MAX_LEN];
+static char ext_panel_name[PANEL_NAME_MAX_LEN];
+static int __init prim_display_setup(char *param)
+{
+ if (strnlen(param, PANEL_NAME_MAX_LEN))
+ strlcpy(prim_panel_name, param, PANEL_NAME_MAX_LEN);
+ return 0;
+}
+early_param("prim_display", prim_display_setup);
+
+static int __init ext_display_setup(char *param)
+{
+ if (strnlen(param, PANEL_NAME_MAX_LEN))
+ strlcpy(ext_panel_name, param, PANEL_NAME_MAX_LEN);
+ return 0;
+}
+early_param("ext_display", ext_display_setup);
+
static void __init msm8960_reserve(void)
{
+ msm8960_set_display_params(prim_panel_name, ext_panel_name);
msm_reserve();
fmem_pdata.phys = reserve_memory_for_fmem(fmem_pdata.size);
}
@@ -1884,6 +1915,7 @@
.variant_id = 0x0,
.version = 0x10,
.build = 0xAA,
+ .bootldr_id = MXT_BOOTLOADER_ID_1386,
},
{
.config = mxt1386e_config_data_v1_0,
@@ -1892,6 +1924,7 @@
.variant_id = 0x2,
.version = 0x10,
.build = 0xAA,
+ .bootldr_id = MXT_BOOTLOADER_ID_1386E,
.fw_name = "atmel_8960_liquid_v2_1_AA.hex",
},
{
@@ -1901,6 +1934,7 @@
.variant_id = 0x7,
.version = 0x21,
.build = 0xAA,
+ .bootldr_id = MXT_BOOTLOADER_ID_1386E,
},
};
@@ -2120,6 +2154,14 @@
&msm_device_bam_dmux,
&msm_fm_platform_init,
+#if defined(CONFIG_TSIF) || defined(CONFIG_TSIF_MODULE)
+#ifdef CONFIG_MSM_USE_TSIF1
+ &msm_device_tsif[1],
+#else
+ &msm_device_tsif[0],
+#endif
+#endif
+
#ifdef CONFIG_HW_RANDOM_MSM
&msm_device_rng,
#endif
diff --git a/arch/arm/mach-msm/board-8960.h b/arch/arm/mach-msm/board-8960.h
index 20af7b8..dc63fee 100644
--- a/arch/arm/mach-msm/board-8960.h
+++ b/arch/arm/mach-msm/board-8960.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -73,12 +73,15 @@
extern struct sx150x_platform_data msm8960_sx150x_data[];
extern struct msm_camera_board_info msm8960_camera_board_info;
+extern unsigned char hdmi_is_primary;
+
void msm8960_init_cam(void);
void msm8960_init_fb(void);
void msm8960_init_pmic(void);
void msm8960_init_mmc(void);
int msm8960_init_gpiomux(void);
void msm8960_allocate_fb_region(void);
+void msm8960_set_display_params(char *prim_panel, char *ext_panel);
void msm8960_pm8921_gpio_mpp_init(void);
void msm8960_mdp_writeback(struct memtype_reserve *reserve_table);
uint32_t msm_rpm_get_swfi_latency(void);
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index 9f79abb..a8ab81a 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -100,7 +100,7 @@
{
if (machine_is_msm7627a_qrd1())
gpio_bt_sys_rest_en = 114;
- if (machine_is_msm7627a_evb())
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
gpio_bt_sys_rest_en = 16;
}
@@ -109,14 +109,36 @@
int rc = 0;
struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
+ pr_debug("%s: Setting SYS_RST_PIN(%d) to %d\n",
+ __func__, gpio_bt_sys_rest_en, on);
if (on) {
- rc = gpio_direction_output(gpio_bt_sys_rest_en, 1);
+
+ if (machine_is_msm7627a_evb()) {
+ rc = gpio_tlmm_config(GPIO_CFG(gpio_bt_sys_rest_en, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA),
+ GPIO_CFG_ENABLE);
+
+ gpio_set_value(gpio_bt_sys_rest_en, 1);
+ } else {
+ rc = gpio_direction_output(gpio_bt_sys_rest_en, 1);
+ }
msleep(100);
} else {
+
if (!marimba_get_fm_status(&config) &&
!marimba_get_bt_status(&config)) {
- gpio_set_value_cansleep(gpio_bt_sys_rest_en, 0);
- rc = gpio_direction_input(gpio_bt_sys_rest_en);
+ if (machine_is_msm7627a_evb()) {
+ gpio_set_value(gpio_bt_sys_rest_en, 0);
+ rc = gpio_tlmm_config(GPIO_CFG(
+ gpio_bt_sys_rest_en, 0,
+ GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA),
+ GPIO_CFG_ENABLE);
+ } else {
+ gpio_set_value_cansleep(gpio_bt_sys_rest_en, 0);
+ rc = gpio_direction_input(gpio_bt_sys_rest_en);
+ }
msleep(100);
}
}
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 06fbb7b..7b075cd 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -1041,7 +1041,7 @@
pr_debug("msm7627a_camera_init Entered\n");
/* LCD and camera power (VREG & LDO) init */
- if (machine_is_msm7627a_evb())
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
lcd_camera_power_init();
#ifndef CONFIG_MSM_CAMERA_V4L2
@@ -1049,7 +1049,7 @@
qrd1_camera_gpio_cfg();
platform_add_devices(camera_devices_qrd,
ARRAY_SIZE(camera_devices_qrd));
- } else if (machine_is_msm7627a_evb()) {
+ } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
evb_camera_gpio_cfg();
platform_add_devices(camera_devices_evb,
ARRAY_SIZE(camera_devices_evb));
@@ -1059,7 +1059,8 @@
platform_add_devices(camera_devices_msm,
ARRAY_SIZE(camera_devices_msm));
#endif
- if (!machine_is_msm7627a_qrd1() || !machine_is_msm7627a_evb())
+ if (!machine_is_msm7627a_qrd1() || !machine_is_msm7627a_evb()
+ || !machine_is_msm8625_evb())
register_i2c_devices();
rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_camera), regs_camera);
@@ -1083,7 +1084,7 @@
i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
i2c_camera_devices_qrd,
ARRAY_SIZE(i2c_camera_devices_qrd));
- } else if (machine_is_msm7627a_evb()) {
+ } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
pr_debug("machine_is_msm7627a_evb i2c_register_board_info\n");
i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
i2c_camera_devices_evb,
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 8093295..b1fe0c7 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -208,7 +208,6 @@
}
};
-#define PANEL_NAME_MAX_LEN 30
#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
@@ -227,7 +226,7 @@
} else if (machine_is_msm7627a_qrd1()) {
if (!strncmp(name, "mipi_video_truly_wvga", 21))
ret = 0;
- } else if (machine_is_msm7627a_evb()) {
+ } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
ret = 0;
}
@@ -558,7 +557,7 @@
if (machine_is_msm7627a_qrd1())
rc = msm_fb_dsi_client_qrd1_reset();
- else if (machine_is_msm7627a_evb())
+ else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
rc = msm_fb_dsi_client_qrd3_reset();
else
rc = msm_fb_dsi_client_msm_reset();
@@ -823,7 +822,7 @@
if (machine_is_msm7627a_qrd1())
rc = mipi_dsi_panel_qrd1_power(on);
- else if (machine_is_msm7627a_evb())
+ else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
rc = mipi_dsi_panel_qrd3_power(on);
else
rc = mipi_dsi_panel_msm_power(on);
@@ -846,7 +845,7 @@
if (machine_is_msm7627a_qrd1())
platform_add_devices(qrd_fb_devices,
ARRAY_SIZE(qrd_fb_devices));
- else if (machine_is_msm7627a_evb())
+ 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())
diff --git a/arch/arm/mach-msm/board-msm7627a-storage.c b/arch/arm/mach-msm/board-msm7627a-storage.c
index 3bb9c8b..e4ee52e 100644
--- a/arch/arm/mach-msm/board-msm7627a-storage.c
+++ b/arch/arm/mach-msm/board-msm7627a-storage.c
@@ -150,7 +150,8 @@
static int gpio_sdc1_hw_det = 85;
static void gpio_sdc1_config(void)
{
- if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb())
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+ || machine_is_msm8625_evb())
gpio_sdc1_hw_det = 42;
}
@@ -251,7 +252,8 @@
status = gpio_direction_input(gpio_sdc1_hw_det);
if (!status) {
if (machine_is_msm7627a_qrd1() ||
- machine_is_msm7627a_evb())
+ machine_is_msm7627a_evb() ||
+ machine_is_msm8625_evb())
status = !gpio_get_value(gpio_sdc1_hw_det);
else
status = gpio_get_value(gpio_sdc1_hw_det);
diff --git a/arch/arm/mach-msm/board-msm7627a-wlan.c b/arch/arm/mach-msm/board-msm7627a-wlan.c
index 6df7626..53d3c56 100644
--- a/arch/arm/mach-msm/board-msm7627a-wlan.c
+++ b/arch/arm/mach-msm/board-msm7627a-wlan.c
@@ -48,7 +48,8 @@
int gpio_wlan_sys_rest_en = 134;
static void gpio_wlan_config(void)
{
- if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb())
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+ || machine_is_msm8625_evb())
gpio_wlan_sys_rest_en = 124;
}
@@ -229,7 +230,8 @@
* gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
* EVB1.0 and QRD8625,so the below step is required for those devices.
*/
- if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+ || machine_is_msm8625_evb()) {
rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
@@ -302,7 +304,8 @@
* gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
* EVB1.0 and QRD8625,so the below step is required for those devices.
*/
- if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+ || machine_is_msm8625_evb()) {
rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
diff --git a/arch/arm/mach-msm/board-msm7627a.h b/arch/arm/mach-msm/board-msm7627a.h
index 8737de8..bde9b61 100644
--- a/arch/arm/mach-msm/board-msm7627a.h
+++ b/arch/arm/mach-msm/board-msm7627a.h
@@ -66,6 +66,7 @@
QRD_GPIO_CAM_GP_CAMIF_RESET,
};
+#define ADSP_RPC_PROG 0x3000000a
#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
#define FPGA_MSM_CNTRL_REG2 0x90008010
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index b73f422..b44b03f 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -61,7 +61,6 @@
#define PMEM_KERNEL_EBI1_SIZE 0x3A000
#define MSM_PMEM_AUDIO_SIZE 0x5B000
-#define ADSP_RPC_PROG 0x3000000a
#if defined(CONFIG_GPIO_SX150X)
enum {
@@ -826,6 +825,7 @@
&msm8625_device_smd,
&msm8625_device_otg,
&msm8625_device_gadget_peripheral,
+ &msm8625_kgsl_3d0,
};
static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE;
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index e3fc97f..9b5e1e2 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -119,7 +119,6 @@
#define LCDC_AUO_SPI_DEVICE_NAME "lcdc_auo_nt35582"
#define LCDC_NT35582_PANEL_NAME "lcdc_nt35582_wvga"
-#define PANEL_NAME_MAX_LEN 30
#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME "mipi_cmd_novatek_qhd"
#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME "mipi_video_novatek_qhd"
#define MIPI_VIDEO_TOSHIBA_WVGA_PANEL_NAME "mipi_video_toshiba_wvga"
@@ -2660,19 +2659,17 @@
#define MSM_FB_EXT_BUFT_SIZE 0
#endif
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-/* 4 bpp x 2 page HDMI case */
-#define MSM_FB_SIZE roundup((1920 * 1088 * 4 * 2), 4096)
-#else
/* Note: must be multiple of 4096 */
#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE + \
MSM_FB_DSUB_PMEM_ADDER, 4096)
-#endif
+
+#define MSM_PMEM_SF_SIZE 0x4000000 /* 64 Mbytes */
+#define MSM_HDMI_PRIM_PMEM_SF_SIZE 0x4000000 /* 64 Mbytes */
#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-#define MSM_PMEM_SF_SIZE 0x8000000 /* 128 Mbytes */
+unsigned char hdmi_is_primary = 1;
#else
-#define MSM_PMEM_SF_SIZE 0x4000000 /* 64 Mbytes */
+unsigned char hdmi_is_primary;
#endif
#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
@@ -2712,6 +2709,8 @@
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
#define MSM_ION_HEAP_NUM 9
+#define MSM_HDMI_PRIM_ION_SF_SIZE MSM_HDMI_PRIM_PMEM_SF_SIZE
+static unsigned msm_ion_sf_size = MSM_ION_SF_SIZE;
#else
#define MSM_ION_HEAP_NUM 1
#endif
@@ -3159,7 +3158,11 @@
void *addr;
unsigned long size;
- size = MSM_FB_SIZE;
+ if (hdmi_is_primary)
+ size = roundup((1920 * 1088 * 4 * 2), 4096);
+ else
+ size = MSM_FB_SIZE;
+
addr = alloc_bootmem_align(size, 0x1000);
msm_fb_resources[0].start = __pa(addr);
msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
@@ -3168,6 +3171,30 @@
}
+void __init msm8x60_set_display_params(char *prim_panel, char *ext_panel)
+{
+ if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
+ strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
+ PANEL_NAME_MAX_LEN);
+ pr_debug("msm_fb_pdata.prim_panel_name %s\n",
+ msm_fb_pdata.prim_panel_name);
+
+ if (!strncmp((char *)msm_fb_pdata.prim_panel_name,
+ HDMI_PANEL_NAME, strnlen(HDMI_PANEL_NAME,
+ PANEL_NAME_MAX_LEN))) {
+ pr_debug("HDMI is the primary display by"
+ " boot parameter\n");
+ hdmi_is_primary = 1;
+ }
+ }
+ if (strnlen(ext_panel, PANEL_NAME_MAX_LEN)) {
+ strlcpy(msm_fb_pdata.ext_panel_name, ext_panel,
+ PANEL_NAME_MAX_LEN);
+ pr_debug("msm_fb_pdata.ext_panel_name %s\n",
+ msm_fb_pdata.ext_panel_name);
+ }
+}
+
#if defined(CONFIG_TOUCHSCREEN_CYTTSP_I2C) || \
defined(CONFIG_TOUCHSCREEN_CYTTSP_I2C_MODULE)
/*virtual key support */
@@ -5410,7 +5437,21 @@
static void reserve_ion_memory(void)
{
#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
- msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
+ unsigned int i;
+
+ if (hdmi_is_primary) {
+ msm_ion_sf_size = MSM_HDMI_PRIM_ION_SF_SIZE;
+ for (i = 0; i < ion_pdata.nr; i++) {
+ if (ion_pdata.heaps[i].id == ION_SF_HEAP_ID) {
+ ion_pdata.heaps[i].size = msm_ion_sf_size;
+ pr_debug("msm_ion_sf_size 0x%x\n",
+ msm_ion_sf_size);
+ break;
+ }
+ }
+ }
+
+ msm8x60_reserve_table[MEMTYPE_EBI1].size += msm_ion_sf_size;
msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MM_FW_SIZE;
msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MM_SIZE;
msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MFC_SIZE;
@@ -5426,6 +5467,9 @@
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
android_pmem_adsp_pdata.size = pmem_adsp_size;
android_pmem_smipool_pdata.size = MSM_PMEM_SMIPOOL_SIZE;
+
+ if (hdmi_is_primary)
+ pmem_sf_size = MSM_HDMI_PRIM_PMEM_SF_SIZE;
android_pmem_pdata.size = pmem_sf_size;
#endif
android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
@@ -5475,8 +5519,27 @@
.paddr_to_memtype = msm8x60_paddr_to_memtype,
};
+static char prim_panel_name[PANEL_NAME_MAX_LEN];
+static char ext_panel_name[PANEL_NAME_MAX_LEN];
+static int __init prim_display_setup(char *param)
+{
+ if (strnlen(param, PANEL_NAME_MAX_LEN))
+ strlcpy(prim_panel_name, param, PANEL_NAME_MAX_LEN);
+ return 0;
+}
+early_param("prim_display", prim_display_setup);
+
+static int __init ext_display_setup(char *param)
+{
+ if (strnlen(param, PANEL_NAME_MAX_LEN))
+ strlcpy(ext_panel_name, param, PANEL_NAME_MAX_LEN);
+ return 0;
+}
+early_param("ext_display", ext_display_setup);
+
static void __init msm8x60_reserve(void)
{
+ msm8x60_set_display_params(prim_panel_name, ext_panel_name);
reserve_info = &msm8x60_reserve_info;
msm_reserve();
}
@@ -9422,26 +9485,7 @@
.ib = 0,
},
};
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-static struct msm_bus_vectors dtv_bus_def_vectors[] = {
- /* For now, 0th array entry is reserved.
- * Please leave 0 as is and don't use it
- */
- {
- .src = MSM_BUS_MASTER_MDP_PORT0,
- .dst = MSM_BUS_SLAVE_SMI,
- .ab = 2000000000,
- .ib = 2000000000,
- },
- /* Master and slaves can be from different fabrics */
- {
- .src = MSM_BUS_MASTER_MDP_PORT0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 2000000000,
- .ib = 2000000000,
- },
-};
-#else
+
static struct msm_bus_vectors dtv_bus_def_vectors[] = {
/* For now, 0th array entry is reserved.
* Please leave 0 as is and don't use it
@@ -9460,7 +9504,26 @@
.ib = 707616000,
},
};
-#endif
+
+static struct msm_bus_vectors dtv_bus_hdmi_prim_vectors[] = {
+ /* For now, 0th array entry is reserved.
+ * Please leave 0 as is and don't use it
+ */
+ {
+ .src = MSM_BUS_MASTER_MDP_PORT0,
+ .dst = MSM_BUS_SLAVE_SMI,
+ .ab = 2000000000,
+ .ib = 2000000000,
+ },
+ /* Master and slaves can be from different fabrics */
+ {
+ .src = MSM_BUS_MASTER_MDP_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 2000000000,
+ .ib = 2000000000,
+ },
+};
+
static struct msm_bus_paths dtv_bus_scale_usecases[] = {
{
ARRAY_SIZE(dtv_bus_init_vectors),
@@ -9471,6 +9534,7 @@
dtv_bus_def_vectors,
},
};
+
static struct msm_bus_scale_pdata dtv_bus_scale_pdata = {
dtv_bus_scale_usecases,
ARRAY_SIZE(dtv_bus_scale_usecases),
@@ -9480,6 +9544,27 @@
static struct lcdc_platform_data dtv_pdata = {
.bus_scale_table = &dtv_bus_scale_pdata,
};
+
+static struct msm_bus_paths dtv_hdmi_prim_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(dtv_bus_init_vectors),
+ dtv_bus_init_vectors,
+ },
+ {
+ ARRAY_SIZE(dtv_bus_hdmi_prim_vectors),
+ dtv_bus_hdmi_prim_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata dtv_hdmi_prim_bus_scale_pdata = {
+ dtv_hdmi_prim_bus_scale_usecases,
+ ARRAY_SIZE(dtv_hdmi_prim_bus_scale_usecases),
+ .name = "dtv",
+};
+
+static struct lcdc_platform_data dtv_hdmi_prim_pdata = {
+ .bus_scale_table = &dtv_hdmi_prim_bus_scale_pdata,
+};
#endif
@@ -9601,13 +9686,6 @@
160000000,
200000000,
};
-#elif defined(CONFIG_FB_MSM_HDMI_AS_PRIMARY)
-int mdp_core_clk_rate_table[] = {
- 200000000,
- 200000000,
- 200000000,
- 200000000,
-};
#else
int mdp_core_clk_rate_table[] = {
59080000,
@@ -9619,11 +9697,7 @@
static struct msm_panel_common_pdata mdp_pdata = {
.gpio = MDP_VSYNC_GPIO,
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- .mdp_core_clk_rate = 200000000,
-#else
.mdp_core_clk_rate = 59080000,
-#endif
.mdp_core_clk_table = mdp_core_clk_rate_table,
.num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
#ifdef CONFIG_MSM_BUS_SCALING
@@ -9729,7 +9803,10 @@
msm_fb_register_device("lcdc", &lcdc_pdata);
msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
#ifdef CONFIG_MSM_BUS_SCALING
- msm_fb_register_device("dtv", &dtv_pdata);
+ if (hdmi_is_primary)
+ msm_fb_register_device("dtv", &dtv_hdmi_prim_pdata);
+ else
+ msm_fb_register_device("dtv", &dtv_pdata);
#endif
#ifdef CONFIG_FB_MSM_TVOUT
msm_fb_register_device("tvenc", &atv_pdata);
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index aef9275..ac590d3 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -28,9 +28,11 @@
#include <linux/input/rmi_i2c.h>
#include <linux/i2c/atmel_mxt_ts.h>
#include <linux/regulator/consumer.h>
+#include <linux/memblock.h>
#include <asm/mach/mmc.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/hardware/gic.h>
#include <mach/board.h>
#include <mach/msm_iomap.h>
#include <mach/msm_hsusb.h>
@@ -659,7 +661,20 @@
.dev.platform_data = &msm_psy_batt_data,
};
-static struct platform_device *qrd_common_devices[] __initdata = {
+static struct platform_device *common_devices[] __initdata = {
+ &android_usb_device,
+ &android_pmem_device,
+ &android_pmem_adsp_device,
+ &android_pmem_audio_device,
+ &msm_batt_device,
+ &msm_device_adspdec,
+ &msm_device_snd,
+ &asoc_msm_pcm,
+ &asoc_msm_dai0,
+ &asoc_msm_dai1,
+};
+
+static struct platform_device *qrd7627a_devices[] __initdata = {
&msm_device_dmov,
&msm_device_smd,
&msm_device_uart1,
@@ -668,23 +683,24 @@
&msm_gsbi1_qup_i2c_device,
&msm_device_otg,
&msm_device_gadget_peripheral,
- &android_usb_device,
- &android_pmem_device,
- &android_pmem_adsp_device,
- &android_pmem_audio_device,
- &msm_device_snd,
- &msm_device_adspdec,
- &msm_batt_device,
&msm_kgsl_3d0,
- &asoc_msm_pcm,
- &asoc_msm_dai0,
- &asoc_msm_dai1,
};
static struct platform_device *qrd3_devices[] __initdata = {
&msm_device_nand,
};
+static struct platform_device *msm8625_evb_devices[] __initdata = {
+ &msm8625_device_dmov,
+ &msm8625_device_smd,
+ &msm8625_gsbi0_qup_i2c_device,
+ &msm8625_gsbi1_qup_i2c_device,
+ &msm8625_device_uart1,
+ &msm8625_device_otg,
+ &msm8625_device_gadget_peripheral,
+ &msm8625_kgsl_3d0,
+};
+
static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE;
static int __init pmem_kernel_ebi1_size_setup(char *p)
{
@@ -759,12 +775,49 @@
msm_reserve();
}
-static void __init msm_device_i2c_init(void)
+static void __init msm8625_reserve(void)
+{
+ memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
+ msm7627a_reserve();
+}
+
+static void msmqrd_adsp_add_pdev(void)
+{
+ int rc = 0;
+ struct rpc_board_dev *rpc_adsp_pdev;
+
+ rpc_adsp_pdev = kzalloc(sizeof(struct rpc_board_dev), GFP_KERNEL);
+ if (rpc_adsp_pdev == NULL) {
+ pr_err("%s: Memory Allocation failure\n", __func__);
+ return;
+ }
+ rpc_adsp_pdev->prog = ADSP_RPC_PROG;
+
+ if (cpu_is_msm8625())
+ rpc_adsp_pdev->pdev = msm8625_device_adsp;
+ else
+ rpc_adsp_pdev->pdev = msm_adsp_device;
+ rc = msm_rpc_add_board_dev(rpc_adsp_pdev, 1);
+ if (rc < 0) {
+ pr_err("%s: return val: %d\n", __func__, rc);
+ kfree(rpc_adsp_pdev);
+ }
+}
+
+static void __init msm7627a_device_i2c_init(void)
{
msm_gsbi0_qup_i2c_device.dev.platform_data = &msm_gsbi0_qup_i2c_pdata;
msm_gsbi1_qup_i2c_device.dev.platform_data = &msm_gsbi1_qup_i2c_pdata;
}
+static void __init msm8625_device_i2c_init(void)
+{
+ msm8625_gsbi0_qup_i2c_device.dev.platform_data
+ = &msm_gsbi0_qup_i2c_pdata;
+ msm8625_gsbi1_qup_i2c_device.dev.platform_data
+ = &msm_gsbi1_qup_i2c_pdata;
+}
+
static struct msm_handset_platform_data hs_platform_data = {
.hs_name = "7k_handset",
.pwr_key_delay_ms = 500, /* 0 will disable end key */
@@ -955,7 +1008,7 @@
i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
synaptic_i2c_clearpad3k,
ARRAY_SIZE(synaptic_i2c_clearpad3k));
- } else if (machine_is_msm7627a_evb()) {
+ } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
rc = gpio_tlmm_config(GPIO_CFG(MXT_TS_IRQ_GPIO, 0,
GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
GPIO_CFG_8MA), GPIO_CFG_ENABLE);
@@ -986,11 +1039,11 @@
#endif
/* keypad */
- if (machine_is_msm7627a_evb())
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
platform_device_register(&kp_pdev_8625);
/* leds */
- if (machine_is_msm7627a_evb()) {
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
rc = gpio_tlmm_config(GPIO_CFG(LED_RED_GPIO_8625, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
GPIO_CFG_16MA), GPIO_CFG_ENABLE);
@@ -1019,32 +1072,63 @@
static void add_platform_devices(void)
{
- platform_add_devices(qrd_common_devices,
- ARRAY_SIZE(qrd_common_devices));
-
- if (machine_is_msm7627a_qrd3())
- platform_add_devices(qrd3_devices,
- ARRAY_SIZE(qrd3_devices));
+ if (machine_is_msm8625_evb())
+ platform_add_devices(msm8625_evb_devices,
+ ARRAY_SIZE(msm8625_evb_devices));
+ else {
+ platform_add_devices(qrd7627a_devices,
+ ARRAY_SIZE(qrd7627a_devices));
+ if (machine_is_msm7627a_qrd3())
+ platform_add_devices(qrd3_devices,
+ ARRAY_SIZE(qrd3_devices));
+ }
+ platform_add_devices(common_devices,
+ ARRAY_SIZE(common_devices));
}
#define UART1DM_RX_GPIO 45
+static void __init qrd7627a_uart1dm_config(void)
+{
+ msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(UART1DM_RX_GPIO);
+ if (cpu_is_msm8625())
+ msm8625_device_uart_dm1.dev.platform_data =
+ &msm_uart_dm1_pdata;
+ else
+ msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata;
+}
+
+static void __init qrd7627a_otg_gadget(void)
+{
+ msm_otg_pdata.swfi_latency = msm7627a_pm_data
+ [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
+
+ if (cpu_is_msm8625()) {
+ msm8625_device_otg.dev.platform_data = &msm_otg_pdata;
+ msm8625_device_gadget_peripheral.dev.platform_data =
+ &msm_gadget_pdata;
+
+ } else {
+ msm_device_otg.dev.platform_data = &msm_otg_pdata;
+ msm_device_gadget_peripheral.dev.platform_data =
+ &msm_gadget_pdata;
+ }
+}
+
static void __init msm_qrd_init(void)
{
msm7x2x_misc_init();
msm7627a_init_regulators();
- msm_device_i2c_init();
-#ifdef CONFIG_SERIAL_MSM_HS
- msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(UART1DM_RX_GPIO);
- msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata;
-#endif
+ msmqrd_adsp_add_pdev();
-#ifdef CONFIG_USB_MSM_OTG_72K
- msm_otg_pdata.swfi_latency = msm7627a_pm_data
- [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
- msm_device_otg.dev.platform_data = &msm_otg_pdata;
-#endif
- msm_device_gadget_peripheral.dev.platform_data =
- &msm_gadget_pdata;
+ if (cpu_is_msm8625())
+ msm8625_device_i2c_init();
+ else
+ msm7627a_device_i2c_init();
+
+ /* uart1dm*/
+ qrd7627a_uart1dm_config();
+ /*OTG gadget*/
+ qrd7627a_otg_gadget();
add_platform_devices();
@@ -1055,9 +1139,11 @@
#ifdef CONFIG_USB_EHCI_MSM_72K
msm7627a_init_host();
#endif
- msm_pm_set_platform_data(msm7627a_pm_data,
+ if (!machine_is_msm8625_evb()) {
+ msm_pm_set_platform_data(msm7627a_pm_data,
ARRAY_SIZE(msm7627a_pm_data));
- BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+ BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+ }
msm_fb_add_devices();
@@ -1066,8 +1152,8 @@
#endif
msm7627a_camera_init();
-
msm7627a_add_io_devices();
+ msm7x25a_kgsl_3d0_init();
}
static void __init qrd7627a_init_early(void)
@@ -1105,3 +1191,13 @@
.init_early = qrd7627a_init_early,
.handle_irq = vic_handle_irq,
MACHINE_END
+MACHINE_START(MSM8625_EVB, "QRD MSM8625 EVB")
+ .boot_params = PHYS_OFFSET + 0x100,
+ .map_io = msm8625_map_io,
+ .reserve = msm8625_reserve,
+ .init_irq = msm8625_init_irq,
+ .init_machine = msm_qrd_init,
+ .timer = &msm_timer,
+ .init_early = qrd7627a_init_early,
+ .handle_irq = gic_handle_irq,
+MACHINE_END
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 5996388..cb264a4 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4461,6 +4461,9 @@
DEFINE_CLK_RPM(sfab_clk, sfab_a_clk, SYSTEM_FABRIC, NULL);
DEFINE_CLK_RPM(sfpb_clk, sfpb_a_clk, SFPB, NULL);
+static DEFINE_CLK_VOTER(sfab_msmbus_a_clk, &sfab_a_clk.c);
+static DEFINE_CLK_VOTER(sfab_tmr_a_clk, &sfab_a_clk.c);
+
static DEFINE_CLK_VOTER(dfab_dsps_clk, &dfab_clk.c);
static DEFINE_CLK_VOTER(dfab_usb_hs_clk, &dfab_clk.c);
static DEFINE_CLK_VOTER(dfab_usb_hs3_clk, &dfab_clk.c);
@@ -4898,7 +4901,7 @@
CLK_LOOKUP("bus_clk", cfpb_clk.c, "msm_cpss_fpb"),
CLK_LOOKUP("bus_a_clk", cfpb_a_clk.c, "msm_cpss_fpb"),
CLK_LOOKUP("bus_clk", sfab_clk.c, "msm_sys_fab"),
- CLK_LOOKUP("bus_a_clk", sfab_a_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("bus_a_clk", sfab_msmbus_a_clk.c, "msm_sys_fab"),
CLK_LOOKUP("bus_clk", sfpb_clk.c, "msm_sys_fpb"),
CLK_LOOKUP("bus_a_clk", sfpb_a_clk.c, "msm_sys_fpb"),
CLK_LOOKUP("bus_clk", mmfab_clk.c, "msm_mm_fab"),
@@ -5045,7 +5048,7 @@
CLK_LOOKUP("tv_clk", mdp_tv_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("hdmi_clk", hdmi_tv_clk.c, ""),
CLK_LOOKUP("core_clk", hdmi_app_clk.c, ""),
- CLK_LOOKUP("vpe_clk", vpe_clk.c, ""),
+ CLK_LOOKUP("vpe_clk", vpe_clk.c, "msm_vpe.0"),
CLK_LOOKUP("core_clk", vpe_clk.c, "footswitch-8x60.9"),
CLK_LOOKUP("vfe_clk", vfe_clk.c, "msm_vfe.0"),
CLK_LOOKUP("core_clk", vfe_clk.c, "footswitch-8x60.8"),
@@ -5082,7 +5085,7 @@
CLK_LOOKUP("iface_clk", vcodec_p_clk.c, "footswitch-8x60.7"),
CLK_LOOKUP("vfe_pclk", vfe_p_clk.c, "msm_vfe.0"),
CLK_LOOKUP("iface_clk", vfe_p_clk.c, "footswitch-8x60.8"),
- CLK_LOOKUP("vpe_pclk", vpe_p_clk.c, ""),
+ CLK_LOOKUP("vpe_pclk", vpe_p_clk.c, "msm_vpe.0"),
CLK_LOOKUP("iface_clk", vpe_p_clk.c, "footswitch-8x60.9"),
CLK_LOOKUP("bit_clk", mi2s_bit_clk.c, "msm-dai-q6.6"),
@@ -5175,7 +5178,7 @@
CLK_LOOKUP("bus_clk", cfpb_clk.c, "msm_cpss_fpb"),
CLK_LOOKUP("bus_a_clk", cfpb_a_clk.c, "msm_cpss_fpb"),
CLK_LOOKUP("bus_clk", sfab_clk.c, "msm_sys_fab"),
- CLK_LOOKUP("bus_a_clk", sfab_a_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("bus_a_clk", sfab_msmbus_a_clk.c, "msm_sys_fab"),
CLK_LOOKUP("bus_clk", sfpb_clk.c, "msm_sys_fpb"),
CLK_LOOKUP("bus_a_clk", sfpb_a_clk.c, "msm_sys_fpb"),
CLK_LOOKUP("bus_clk", mmfab_clk.c, "msm_mm_fab"),
@@ -5763,6 +5766,14 @@
rcg_clk_disable(&tssc_clk.c);
clk_enable(&usb_hsic_hsic_clk.c);
clk_disable(&usb_hsic_hsic_clk.c);
+
+ /*
+ * Keep sfab floor @ 54MHz so that Krait AHB is at least 27MHz at all
+ * times when Apps CPU is active. This ensures the timer's requirement
+ * of Krait AHB running 4 times as fast as the timer itself.
+ */
+ clk_set_rate(&sfab_tmr_a_clk.c, 54000000);
+ clk_enable(&sfab_tmr_a_clk.c);
}
static int __init msm8960_clock_late_init(void)
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index d41589b..657751b 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -23,6 +23,7 @@
#include <mach/usbdiag.h>
#include <mach/msm_sps.h>
#include <mach/dma.h>
+#include <mach/msm_dsps.h>
#include <sound/msm-dai-q6.h>
#include <sound/apr_audio.h>
#include <mach/msm_bus_board.h>
@@ -73,6 +74,11 @@
#define MSM_HSUSB3_PHYS 0x12520000
#define MSM_HSUSB3_SIZE SZ_4K
+/* Address of HS USB4 */
+#define MSM_HSUSB4_PHYS 0x12530000
+#define MSM_HSUSB4_SIZE SZ_4K
+
+
static struct msm_watchdog_pdata msm_watchdog_pdata = {
.pet_time = 10000,
.bark_time = 11000,
@@ -679,6 +685,30 @@
},
};
+static struct resource resources_ehci_host4[] = {
+{
+ .start = MSM_HSUSB4_PHYS,
+ .end = MSM_HSUSB4_PHYS + MSM_HSUSB4_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = USB4_HS_IRQ,
+ .end = USB4_HS_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device apq8064_device_ehci_host4 = {
+ .name = "msm_ehci_host",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(resources_ehci_host4),
+ .resource = resources_ehci_host4,
+ .dev = {
+ .dma_mask = &dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
/* MSM Video core device */
#ifdef CONFIG_MSM_BUS_SCALING
static struct msm_bus_vectors vidc_init_vectors[] = {
@@ -1901,6 +1931,53 @@
},
};
+/* Sensors DSPS platform data */
+
+#define PPSS_REG_PHYS_BASE 0x12080000
+
+static struct dsps_clk_info dsps_clks[] = {};
+static struct dsps_regulator_info dsps_regs[] = {};
+
+/*
+ * Note: GPIOs field is intialized in run-time at the function
+ * apq8064_init_dsps().
+ */
+
+struct msm_dsps_platform_data msm_dsps_pdata_8064 = {
+ .clks = dsps_clks,
+ .clks_num = ARRAY_SIZE(dsps_clks),
+ .gpios = NULL,
+ .gpios_num = 0,
+ .regs = dsps_regs,
+ .regs_num = ARRAY_SIZE(dsps_regs),
+ .dsps_pwr_ctl_en = 1,
+ .signature = DSPS_SIGNATURE,
+};
+
+static struct resource msm_dsps_resources[] = {
+ {
+ .start = PPSS_REG_PHYS_BASE,
+ .end = PPSS_REG_PHYS_BASE + SZ_8K - 1,
+ .name = "ppss_reg",
+ .flags = IORESOURCE_MEM,
+ },
+
+ {
+ .start = PPSS_WDOG_TIMER_IRQ,
+ .end = PPSS_WDOG_TIMER_IRQ,
+ .name = "ppss_wdog",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_dsps_device_8064 = {
+ .name = "msm_dsps",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(msm_dsps_resources),
+ .resource = msm_dsps_resources,
+ .dev.platform_data = &msm_dsps_pdata_8064,
+};
+
#ifdef CONFIG_MSM_MPM
static uint16_t msm_mpm_irqs_m2a[MSM_MPM_NR_MPM_IRQS] __initdata = {
[1] = MSM_GPIO_TO_INT(26),
@@ -2040,4 +2117,3 @@
.num_resources = ARRAY_SIZE(mdm_resources),
.resource = mdm_resources,
};
-
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index e8b446c..718cfb1 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -33,6 +33,7 @@
#include <mach/msm_smd.h>
#include <sound/msm-dai-q6.h>
#include <sound/apr_audio.h>
+#include <mach/msm_tsif.h>
#include "clock.h"
#include "devices.h"
#include "devices-msm8x60.h"
@@ -1505,6 +1506,111 @@
};
#endif
+#define MSM_TSIF0_PHYS (0x18200000)
+#define MSM_TSIF1_PHYS (0x18201000)
+#define MSM_TSIF_SIZE (0x200)
+
+#define TSIF_0_CLK GPIO_CFG(75, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_0_EN GPIO_CFG(76, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_0_DATA GPIO_CFG(77, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_0_SYNC GPIO_CFG(82, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_CLK GPIO_CFG(79, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_EN GPIO_CFG(80, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_DATA GPIO_CFG(81, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_SYNC GPIO_CFG(78, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+
+static const struct msm_gpio tsif0_gpios[] = {
+ { .gpio_cfg = TSIF_0_CLK, .label = "tsif_clk", },
+ { .gpio_cfg = TSIF_0_EN, .label = "tsif_en", },
+ { .gpio_cfg = TSIF_0_DATA, .label = "tsif_data", },
+ { .gpio_cfg = TSIF_0_SYNC, .label = "tsif_sync", },
+};
+
+static const struct msm_gpio tsif1_gpios[] = {
+ { .gpio_cfg = TSIF_1_CLK, .label = "tsif_clk", },
+ { .gpio_cfg = TSIF_1_EN, .label = "tsif_en", },
+ { .gpio_cfg = TSIF_1_DATA, .label = "tsif_data", },
+ { .gpio_cfg = TSIF_1_SYNC, .label = "tsif_sync", },
+};
+
+struct msm_tsif_platform_data tsif1_platform_data = {
+ .num_gpios = ARRAY_SIZE(tsif1_gpios),
+ .gpios = tsif1_gpios,
+ .tsif_pclk = "tsif_pclk",
+ .tsif_ref_clk = "tsif_ref_clk",
+};
+
+struct resource tsif1_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_IRQ,
+ .start = TSIF2_IRQ,
+ .end = TSIF2_IRQ,
+ },
+ [1] = {
+ .flags = IORESOURCE_MEM,
+ .start = MSM_TSIF1_PHYS,
+ .end = MSM_TSIF1_PHYS + MSM_TSIF_SIZE - 1,
+ },
+ [2] = {
+ .flags = IORESOURCE_DMA,
+ .start = DMOV_TSIF_CHAN,
+ .end = DMOV_TSIF_CRCI,
+ },
+};
+
+struct msm_tsif_platform_data tsif0_platform_data = {
+ .num_gpios = ARRAY_SIZE(tsif0_gpios),
+ .gpios = tsif0_gpios,
+ .tsif_pclk = "tsif_pclk",
+ .tsif_ref_clk = "tsif_ref_clk",
+};
+struct resource tsif0_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_IRQ,
+ .start = TSIF1_IRQ,
+ .end = TSIF1_IRQ,
+ },
+ [1] = {
+ .flags = IORESOURCE_MEM,
+ .start = MSM_TSIF0_PHYS,
+ .end = MSM_TSIF0_PHYS + MSM_TSIF_SIZE - 1,
+ },
+ [2] = {
+ .flags = IORESOURCE_DMA,
+ .start = DMOV_TSIF_CHAN,
+ .end = DMOV_TSIF_CRCI,
+ },
+};
+
+struct platform_device msm_device_tsif[2] = {
+ {
+ .name = "msm_tsif",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(tsif0_resources),
+ .resource = tsif0_resources,
+ .dev = {
+ .platform_data = &tsif0_platform_data
+ },
+ },
+ {
+ .name = "msm_tsif",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(tsif1_resources),
+ .resource = tsif1_resources,
+ .dev = {
+ .platform_data = &tsif1_platform_data
+ },
+ }
+};
+
static struct resource resources_ssbi_pmic[] = {
{
.start = MSM_PMIC1_SSBI_CMD_PHYS,
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 9a4696f..c19c133 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -797,7 +797,9 @@
kgsl_3d0_pdata.pwrlevel[0].bus_freq = 160000000;
kgsl_3d0_pdata.pwrlevel[1].gpu_freq = 96000000;
kgsl_3d0_pdata.pwrlevel[1].bus_freq = 0;
- }
+ } else if (cpu_is_msm8625())
+ /* msm8625 has an idle_timout of 50 hours */
+ kgsl_3d0_pdata.idle_timeout = 18000000;
}
static void __init msm_register_device(struct platform_device *pdev, void *data)
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 82a3fa1..4371c23 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -112,6 +112,7 @@
extern struct platform_device apq8064_device_hsusb_host;
extern struct platform_device apq8064_device_hsic_host;
extern struct platform_device apq8064_device_ehci_host3;
+extern struct platform_device apq8064_device_ehci_host4;
extern struct platform_device msm_device_i2c;
@@ -323,3 +324,5 @@
extern struct platform_device msm_bus_8064_cpss_fpb;
extern struct platform_device mdm_8064_device;
+
+extern struct platform_device msm_dsps_device_8064;
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 96b0083..105a46f 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -417,10 +417,13 @@
int *gpio;
};
+#define PANEL_NAME_MAX_LEN 50
struct msm_fb_platform_data {
int (*detect_client)(const char *name);
int mddi_prescan;
int (*allow_set_offset)(void);
+ char prim_panel_name[PANEL_NAME_MAX_LEN];
+ char ext_panel_name[PANEL_NAME_MAX_LEN];
};
struct msm_hdmi_platform_data {
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 3cb79b7..d170f5f 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -177,6 +177,9 @@
#define DMOV_CE_OUT_CHAN 1
#define DMOV_CE_OUT_CRCI 3
+#define DMOV_TSIF_CHAN 2
+#define DMOV_TSIF_CRCI 11
+
#define DMOV_HSUART_GSBI6_TX_CHAN 7
#define DMOV_HSUART_GSBI6_TX_CRCI 6
diff --git a/arch/arm/mach-msm/include/mach/timex.h b/arch/arm/mach-msm/include/mach/timex.h
index 61f1996..ca7c4c7 100644
--- a/arch/arm/mach-msm/include/mach/timex.h
+++ b/arch/arm/mach-msm/include/mach/timex.h
@@ -18,8 +18,6 @@
#define CLOCK_TICK_RATE 1000000
-#ifdef CONFIG_MSM_SMP
#define ARCH_HAS_READ_CURRENT_TIMER
-#endif
#endif
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 7445a61..04c29cc 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -242,6 +242,8 @@
static int mdm_subsys_powerup(const struct subsys_data *crashed_subsys)
{
+ gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 0);
+ gpio_direction_output(mdm_drv->ap2mdm_status_gpio, 1);
mdm_drv->ops->power_on_mdm_cb(mdm_drv);
mdm_drv->boot_type = CHARM_NORMAL_BOOT;
complete(&mdm_needs_reload);
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index 5bff832..28b5995 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -304,6 +304,9 @@
static void init_watchdog_work(struct work_struct *work)
{
u64 timeout = (bark_time * WDT_HZ)/1000;
+
+ configure_bark_dump();
+
__raw_writel(timeout, msm_tmr0_base + WDT0_BARK_TIME);
__raw_writel(timeout + 3*WDT_HZ, msm_tmr0_base + WDT0_BITE_TIME);
@@ -366,8 +369,6 @@
if (pdata->needs_expired_enable)
__raw_writel(0x1, MSM_CLK_CTL_BASE + 0x3820);
- configure_bark_dump();
-
delay_time = msecs_to_jiffies(pdata->pet_time);
schedule_work_on(0, &init_dogwork_struct);
return 0;
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index 1004e01..6d1a5f0 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.c
@@ -20,9 +20,11 @@
#include <linux/mutex.h>
#include <linux/memblock.h>
#include <linux/slab.h>
+#include <linux/atomic.h>
#include <asm/uaccess.h>
#include <asm/setup.h>
+#include <mach/peripheral-loader.h>
#include "peripheral-loader.h"
@@ -30,34 +32,35 @@
struct pil_desc *desc;
int count;
struct mutex lock;
- struct list_head list;
+ struct device dev;
+ struct module *owner;
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *dentry;
+#endif
};
-static DEFINE_MUTEX(pil_list_lock);
-static LIST_HEAD(pil_list);
+#define to_pil_device(d) container_of(d, struct pil_device, dev)
-static struct pil_device *__find_peripheral(const char *str)
+struct bus_type pil_bus_type = {
+ .name = "pil",
+};
+
+static int __find_peripheral(struct device *dev, void *data)
{
- struct pil_device *dev;
-
- list_for_each_entry(dev, &pil_list, list)
- if (!strcmp(dev->desc->name, str))
- return dev;
- return NULL;
+ struct pil_device *pdev = to_pil_device(dev);
+ return !strncmp(pdev->desc->name, data, INT_MAX);
}
static struct pil_device *find_peripheral(const char *str)
{
- struct pil_device *dev;
+ struct device *dev;
if (!str)
return NULL;
- mutex_lock(&pil_list_lock);
- dev = __find_peripheral(str);
- mutex_unlock(&pil_list_lock);
-
- return dev;
+ dev = bus_find_device(&pil_bus_type, NULL, (void *)str,
+ __find_peripheral);
+ return dev ? to_pil_device(dev) : NULL;
}
#define IOMAP_SIZE SZ_4M
@@ -71,24 +74,23 @@
const u8 *data;
if (memblock_is_region_memory(phdr->p_paddr, phdr->p_memsz)) {
- dev_err(pil->desc->dev, "Kernel memory would be overwritten");
+ dev_err(&pil->dev, "Kernel memory would be overwritten");
return -EPERM;
}
if (phdr->p_filesz) {
snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d",
pil->desc->name, num);
- ret = request_firmware(&fw, fw_name, pil->desc->dev);
+ ret = request_firmware(&fw, fw_name, &pil->dev);
if (ret) {
- dev_err(pil->desc->dev, "Failed to locate blob %s\n",
+ dev_err(&pil->dev, "Failed to locate blob %s\n",
fw_name);
return ret;
}
if (fw->size != phdr->p_filesz) {
- dev_err(pil->desc->dev,
- "Blob size %u doesn't match %u\n", fw->size,
- phdr->p_filesz);
+ dev_err(&pil->dev, "Blob size %u doesn't match %u\n",
+ fw->size, phdr->p_filesz);
ret = -EPERM;
goto release_fw;
}
@@ -105,7 +107,7 @@
size = min_t(size_t, IOMAP_SIZE, count);
buf = ioremap(paddr, size);
if (!buf) {
- dev_err(pil->desc->dev, "Failed to map memory\n");
+ dev_err(&pil->dev, "Failed to map memory\n");
ret = -ENOMEM;
goto release_fw;
}
@@ -126,7 +128,7 @@
size = min_t(size_t, IOMAP_SIZE, count);
buf = ioremap(paddr, size);
if (!buf) {
- dev_err(pil->desc->dev, "Failed to map memory\n");
+ dev_err(&pil->dev, "Failed to map memory\n");
ret = -ENOMEM;
goto release_fw;
}
@@ -140,7 +142,7 @@
ret = pil->desc->ops->verify_blob(pil->desc, phdr->p_paddr,
phdr->p_memsz);
if (ret)
- dev_err(pil->desc->dev, "Blob %u failed verification\n", num);
+ dev_err(&pil->dev, "Blob %u failed verification\n", num);
release_fw:
release_firmware(fw);
@@ -163,40 +165,40 @@
const struct firmware *fw;
snprintf(fw_name, sizeof(fw_name), "%s.mdt", pil->desc->name);
- ret = request_firmware(&fw, fw_name, pil->desc->dev);
+ ret = request_firmware(&fw, fw_name, &pil->dev);
if (ret) {
- dev_err(pil->desc->dev, "Failed to locate %s\n", fw_name);
+ dev_err(&pil->dev, "Failed to locate %s\n", fw_name);
goto out;
}
if (fw->size < sizeof(*ehdr)) {
- dev_err(pil->desc->dev, "Not big enough to be an elf header\n");
+ dev_err(&pil->dev, "Not big enough to be an elf header\n");
ret = -EIO;
goto release_fw;
}
ehdr = (struct elf32_hdr *)fw->data;
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
- dev_err(pil->desc->dev, "Not an elf header\n");
+ dev_err(&pil->dev, "Not an elf header\n");
ret = -EIO;
goto release_fw;
}
if (ehdr->e_phnum == 0) {
- dev_err(pil->desc->dev, "No loadable segments\n");
+ dev_err(&pil->dev, "No loadable segments\n");
ret = -EIO;
goto release_fw;
}
if (sizeof(struct elf32_phdr) * ehdr->e_phnum +
sizeof(struct elf32_hdr) > fw->size) {
- dev_err(pil->desc->dev, "Program headers not within mdt\n");
+ dev_err(&pil->dev, "Program headers not within mdt\n");
ret = -EIO;
goto release_fw;
}
ret = pil->desc->ops->init_image(pil->desc, fw->data, fw->size);
if (ret) {
- dev_err(pil->desc->dev, "Invalid firmware metadata\n");
+ dev_err(&pil->dev, "Invalid firmware metadata\n");
goto release_fw;
}
@@ -207,7 +209,7 @@
ret = load_segment(phdr, i, pil);
if (ret) {
- dev_err(pil->desc->dev, "Failed to load segment %d\n",
+ dev_err(&pil->dev, "Failed to load segment %d\n",
i);
goto release_fw;
}
@@ -215,10 +217,10 @@
ret = pil->desc->ops->auth_and_reset(pil->desc);
if (ret) {
- dev_err(pil->desc->dev, "Failed to bring out of reset\n");
+ dev_err(&pil->dev, "Failed to bring out of reset\n");
goto release_fw;
}
- dev_info(pil->desc->dev, "brought out of reset\n");
+ dev_info(&pil->dev, "brought %s out of reset\n", pil->desc->name);
release_fw:
release_firmware(fw);
@@ -242,33 +244,41 @@
struct pil_device *pil_d;
void *retval;
+ if (!name)
+ return NULL;
+
pil = retval = find_peripheral(name);
if (!pil)
return ERR_PTR(-ENODEV);
+ if (!try_module_get(pil->owner)) {
+ put_device(&pil->dev);
+ return ERR_PTR(-ENODEV);
+ }
- pil_d = find_peripheral(pil->desc->depends_on);
- if (pil_d) {
- void *p = pil_get(pil_d->desc->name);
- if (IS_ERR(p))
- return p;
+ pil_d = pil_get(pil->desc->depends_on);
+ if (IS_ERR(pil_d)) {
+ retval = pil_d;
+ goto err_depends;
}
mutex_lock(&pil->lock);
- if (pil->count) {
- pil->count++;
- goto unlock;
+ if (!pil->count++) {
+ ret = load_image(pil);
+ if (ret) {
+ retval = ERR_PTR(ret);
+ goto err_load;
+ }
}
-
- ret = load_image(pil);
- if (ret) {
- retval = ERR_PTR(ret);
- goto unlock;
- }
-
- pil->count++;
-unlock:
mutex_unlock(&pil->lock);
+out:
return retval;
+err_load:
+ mutex_unlock(&pil->lock);
+ pil_put(pil_d);
+err_depends:
+ put_device(&pil->dev);
+ module_put(pil->owner);
+ goto out;
}
EXPORT_SYMBOL(pil_get);
@@ -281,22 +291,29 @@
*/
void pil_put(void *peripheral_handle)
{
- struct pil_device *pil_d;
- struct pil_device *pil = peripheral_handle;
- if (!pil || IS_ERR(pil))
+ struct pil_device *pil_d, *pil = peripheral_handle;
+
+ if (IS_ERR_OR_NULL(pil))
return;
mutex_lock(&pil->lock);
- WARN(!pil->count, "%s: Reference count mismatch\n", __func__);
- if (pil->count)
- pil->count--;
- if (pil->count == 0)
+ if (WARN(!pil->count, "%s: Reference count mismatch\n", __func__))
+ goto err_out;
+ if (!--pil->count)
pil->desc->ops->shutdown(pil->desc);
mutex_unlock(&pil->lock);
pil_d = find_peripheral(pil->desc->depends_on);
- if (pil_d)
+ module_put(pil->owner);
+ if (pil_d) {
pil_put(pil_d);
+ put_device(&pil_d->dev);
+ }
+ put_device(&pil->dev);
+ return;
+err_out:
+ mutex_unlock(&pil->lock);
+ return;
}
EXPORT_SYMBOL(pil_put);
@@ -312,6 +329,7 @@
if (!WARN(!pil->count, "%s: Reference count mismatch\n", __func__))
pil->desc->ops->shutdown(pil->desc);
mutex_unlock(&pil->lock);
+ put_device(&pil->dev);
}
EXPORT_SYMBOL(pil_force_shutdown);
@@ -328,13 +346,14 @@
if (!WARN(!pil->count, "%s: Reference count mismatch\n", __func__))
ret = load_image(pil);
mutex_unlock(&pil->lock);
+ put_device(&pil->dev);
return ret;
}
EXPORT_SYMBOL(pil_force_boot);
#ifdef CONFIG_DEBUG_FS
-int msm_pil_debugfs_open(struct inode *inode, struct file *filp)
+static int msm_pil_debugfs_open(struct inode *inode, struct file *filp)
{
filp->private_data = inode->i_private;
return 0;
@@ -384,7 +403,7 @@
static struct dentry *pil_base_dir;
-static int msm_pil_debugfs_init(void)
+static int __init msm_pil_debugfs_init(void)
{
pil_base_dir = debugfs_create_dir("pil", NULL);
if (!pil_base_dir) {
@@ -394,52 +413,119 @@
return 0;
}
-arch_initcall(msm_pil_debugfs_init);
+
+static void __exit msm_pil_debugfs_exit(void)
+{
+ debugfs_remove_recursive(pil_base_dir);
+}
static int msm_pil_debugfs_add(struct pil_device *pil)
{
if (!pil_base_dir)
return -ENOMEM;
- if (!debugfs_create_file(pil->desc->name, S_IRUGO | S_IWUSR,
- pil_base_dir, pil, &msm_pil_debugfs_fops))
- return -ENOMEM;
- return 0;
+ pil->dentry = debugfs_create_file(pil->desc->name, S_IRUGO | S_IWUSR,
+ pil_base_dir, pil, &msm_pil_debugfs_fops);
+ return !pil->dentry ? -ENOMEM : 0;
+}
+
+static void msm_pil_debugfs_remove(struct pil_device *pil)
+{
+ debugfs_remove(pil->dentry);
}
#else
+static int __init msm_pil_debugfs_init(void) { return 0; };
+static void __exit msm_pil_debugfs_exit(void) { return 0; };
static int msm_pil_debugfs_add(struct pil_device *pil) { return 0; }
+static void msm_pil_debugfs_remove(struct pil_device *pil) { }
#endif
+static int __msm_pil_shutdown(struct device *dev, void *data)
+{
+ struct pil_device *pil = to_pil_device(dev);
+ pil->desc->ops->shutdown(pil->desc);
+ return 0;
+}
+
static int msm_pil_shutdown_at_boot(void)
{
- struct pil_device *pil;
-
- mutex_lock(&pil_list_lock);
- list_for_each_entry(pil, &pil_list, list)
- pil->desc->ops->shutdown(pil->desc);
- mutex_unlock(&pil_list_lock);
-
- return 0;
+ return bus_for_each_dev(&pil_bus_type, NULL, NULL, __msm_pil_shutdown);
}
late_initcall(msm_pil_shutdown_at_boot);
-int msm_pil_register(struct pil_desc *desc)
+static void pil_device_release(struct device *dev)
{
+ struct pil_device *pil = to_pil_device(dev);
+ mutex_destroy(&pil->lock);
+ kfree(pil);
+}
+
+struct pil_device *msm_pil_register(struct pil_desc *desc)
+{
+ int err;
+ static atomic_t pil_count = ATOMIC_INIT(-1);
struct pil_device *pil = kzalloc(sizeof(*pil), GFP_KERNEL);
+
if (!pil)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
mutex_init(&pil->lock);
- INIT_LIST_HEAD(&pil->list);
pil->desc = desc;
+ pil->owner = desc->owner;
+ pil->dev.parent = desc->dev;
+ pil->dev.bus = &pil_bus_type;
+ pil->dev.release = pil_device_release;
- mutex_lock(&pil_list_lock);
- list_add(&pil->list, &pil_list);
- mutex_unlock(&pil_list_lock);
+ dev_set_name(&pil->dev, "pil%d", atomic_inc_return(&pil_count));
+ err = device_register(&pil->dev);
+ if (err) {
+ put_device(&pil->dev);
+ mutex_destroy(&pil->lock);
+ kfree(pil);
+ return ERR_PTR(err);
+ }
- return msm_pil_debugfs_add(pil);
+ err = msm_pil_debugfs_add(pil);
+ if (err) {
+ device_unregister(&pil->dev);
+ return ERR_PTR(err);
+ }
+
+ return pil;
}
EXPORT_SYMBOL(msm_pil_register);
+void msm_pil_unregister(struct pil_device *pil)
+{
+ if (IS_ERR_OR_NULL(pil))
+ return;
+
+ if (get_device(&pil->dev)) {
+ mutex_lock(&pil->lock);
+ WARN_ON(pil->count);
+ msm_pil_debugfs_remove(pil);
+ device_unregister(&pil->dev);
+ mutex_unlock(&pil->lock);
+ put_device(&pil->dev);
+ }
+}
+EXPORT_SYMBOL(msm_pil_unregister);
+
+static int __init msm_pil_init(void)
+{
+ int ret = msm_pil_debugfs_init();
+ if (ret)
+ return ret;
+ return bus_register(&pil_bus_type);
+}
+subsys_initcall(msm_pil_init);
+
+static void __exit msm_pil_exit(void)
+{
+ bus_unregister(&pil_bus_type);
+ msm_pil_debugfs_exit();
+}
+module_exit(msm_pil_exit);
+
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Load peripheral images and bring peripherals out of reset");
diff --git a/arch/arm/mach-msm/peripheral-loader.h b/arch/arm/mach-msm/peripheral-loader.h
index 3d4b4b2..cc00446 100644
--- a/arch/arm/mach-msm/peripheral-loader.h
+++ b/arch/arm/mach-msm/peripheral-loader.h
@@ -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
@@ -13,12 +13,14 @@
#define __MSM_PERIPHERAL_LOADER_H
struct device;
+struct module;
struct pil_desc {
const char *name;
const char *depends_on;
struct device *dev;
const struct pil_reset_ops *ops;
+ struct module *owner;
};
struct pil_reset_ops {
@@ -29,6 +31,9 @@
int (*shutdown)(struct pil_desc *pil);
};
-extern int msm_pil_register(struct pil_desc *desc);
+struct pil_device;
+
+extern struct pil_device *msm_pil_register(struct pil_desc *desc);
+extern void msm_pil_unregister(struct pil_device *pil);
#endif
diff --git a/arch/arm/mach-msm/peripheral-reset-8960.c b/arch/arm/mach-msm/peripheral-reset-8960.c
index 6fd8464..7965193 100644
--- a/arch/arm/mach-msm/peripheral-reset-8960.c
+++ b/arch/arm/mach-msm/peripheral-reset-8960.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
@@ -91,6 +91,7 @@
.name = "dsps",
.dev = &pil_dsps.dev,
.ops = &pil_dsps_ops,
+ .owner = THIS_MODULE,
};
static void __init use_secure_pil(void)
@@ -114,8 +115,8 @@
use_secure_pil();
BUG_ON(platform_device_register(&pil_dsps));
- BUG_ON(msm_pil_register(&pil_dsps_desc));
+ BUG_ON(IS_ERR(msm_pil_register(&pil_dsps_desc)));
return 0;
}
-arch_initcall(msm_peripheral_reset_init);
+module_init(msm_peripheral_reset_init);
diff --git a/arch/arm/mach-msm/peripheral-reset.c b/arch/arm/mach-msm/peripheral-reset.c
index 88b07a5..45617e3 100644
--- a/arch/arm/mach-msm/peripheral-reset.c
+++ b/arch/arm/mach-msm/peripheral-reset.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
@@ -101,6 +101,7 @@
.name = "dsps",
.dev = &pil_dsps.dev,
.ops = &pil_dsps_ops,
+ .owner = THIS_MODULE,
};
static int __init msm_peripheral_reset_init(void)
@@ -114,12 +115,12 @@
if (machine_is_msm8x60_fluid())
pil_dsps_desc.name = "dsps_fluid";
BUG_ON(platform_device_register(&pil_dsps));
- BUG_ON(msm_pil_register(&pil_dsps_desc));
+ BUG_ON(IS_ERR(msm_pil_register(&pil_dsps_desc)));
return 0;
}
-arch_initcall(msm_peripheral_reset_init);
+module_init(msm_peripheral_reset_init);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Validate and bring peripherals out of reset");
diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c
index 26b97fa..c4477ff 100644
--- a/arch/arm/mach-msm/pil-gss.c
+++ b/arch/arm/mach-msm/pil-gss.c
@@ -64,6 +64,7 @@
unsigned long start_addr;
struct delayed_work work;
struct clk *xo;
+ struct pil_device *pil;
};
static int nop_verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
@@ -329,7 +330,6 @@
struct gss_data *drv;
struct resource *res;
struct pil_desc *desc;
- int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
@@ -363,6 +363,7 @@
desc->name = "gss";
desc->dev = &pdev->dev;
+ desc->owner = THIS_MODULE;
if (pas_supported(PAS_GSS) > 0) {
desc->ops = &pil_gss_ops_trusted;
@@ -374,17 +375,19 @@
INIT_DELAYED_WORK(&drv->work, remove_gss_proxy_votes);
- ret = msm_pil_register(desc);
- if (ret) {
+ drv->pil = msm_pil_register(desc);
+ if (IS_ERR(drv->pil)) {
flush_delayed_work_sync(&drv->work);
clk_put(drv->xo);
+ return PTR_ERR(drv->pil);
}
- return ret;
+ return 0;
}
static int __devexit pil_gss_remove(struct platform_device *pdev)
{
struct gss_data *drv = platform_get_drvdata(pdev);
+ msm_pil_unregister(drv->pil);
flush_delayed_work_sync(&drv->work);
clk_put(drv->xo);
return 0;
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index 1d13508..a85d13c 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.c
@@ -53,6 +53,7 @@
struct modem_data {
void __iomem *base;
unsigned long start_addr;
+ struct pil_device *pil;
struct clk *xo;
struct delayed_work work;
};
@@ -277,7 +278,6 @@
struct modem_data *drv;
struct resource *res;
struct pil_desc *desc;
- int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
@@ -303,6 +303,7 @@
desc->name = "modem";
desc->depends_on = "q6";
desc->dev = &pdev->dev;
+ desc->owner = THIS_MODULE;
if (pas_supported(PAS_MODEM) > 0) {
desc->ops = &pil_modem_ops_trusted;
@@ -313,17 +314,19 @@
}
INIT_DELAYED_WORK(&drv->work, remove_modem_proxy_votes);
- ret = msm_pil_register(desc);
- if (ret) {
+ drv->pil = msm_pil_register(desc);
+ if (IS_ERR(drv->pil)) {
flush_delayed_work_sync(&drv->work);
clk_put(drv->xo);
+ return PTR_ERR(drv->pil);
}
- return ret;
+ return 0;
}
static int __devexit pil_modem_driver_exit(struct platform_device *pdev)
{
struct modem_data *drv = platform_get_drvdata(pdev);
+ msm_pil_unregister(drv->pil);
flush_delayed_work_sync(&drv->work);
clk_put(drv->xo);
return 0;
diff --git a/arch/arm/mach-msm/pil-q6v3.c b/arch/arm/mach-msm/pil-q6v3.c
index 06b98e5..54356b8 100644
--- a/arch/arm/mach-msm/pil-q6v3.c
+++ b/arch/arm/mach-msm/pil-q6v3.c
@@ -66,6 +66,7 @@
struct q6v3_data {
void __iomem *base;
unsigned long start_addr;
+ struct pil_device *pil;
struct clk *pll;
struct delayed_work work;
};
@@ -260,6 +261,7 @@
desc->name = "q6";
desc->dev = &pdev->dev;
+ desc->owner = THIS_MODULE;
if (pas_supported(PAS_Q6) > 0) {
desc->ops = &pil_q6v3_ops_trusted;
@@ -271,9 +273,10 @@
INIT_DELAYED_WORK(&drv->work, q6v3_remove_proxy_votes);
- if (msm_pil_register(desc)) {
+ drv->pil = msm_pil_register(desc);
+ if (IS_ERR(drv->pil)) {
flush_delayed_work_sync(&drv->work);
- return -EINVAL;
+ return PTR_ERR(drv->pil);
}
return 0;
}
@@ -281,6 +284,7 @@
static int __devexit pil_q6v3_driver_exit(struct platform_device *pdev)
{
struct q6v3_data *drv = platform_get_drvdata(pdev);
+ msm_pil_unregister(drv->pil);
flush_delayed_work_sync(&drv->work);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
index b0bce02..17f5a41 100644
--- a/arch/arm/mach-msm/pil-q6v4.c
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -71,6 +71,7 @@
bool vreg_enabled;
struct clk *xo;
struct delayed_work work;
+ struct pil_device *pil;
};
static int pil_q6v4_init_image(struct pil_desc *pil, const u8 *metadata,
@@ -421,6 +422,7 @@
desc->name = pdata->name;
desc->depends_on = pdata->depends;
desc->dev = &pdev->dev;
+ desc->owner = THIS_MODULE;
if (pas_supported(pdata->pas_id) > 0) {
desc->ops = &pil_q6v4_ops_trusted;
@@ -443,9 +445,11 @@
}
INIT_DELAYED_WORK(&drv->work, pil_q6v4_remove_proxy_votes);
- ret = msm_pil_register(desc);
- if (ret)
+ drv->pil = msm_pil_register(desc);
+ if (IS_ERR(drv->pil)) {
+ ret = PTR_ERR(drv->pil);
goto err_pil;
+ }
return 0;
err_pil:
flush_delayed_work_sync(&drv->work);
@@ -464,6 +468,7 @@
clk_put(drv->xo);
regulator_put(drv->vreg);
regulator_put(drv->pll_supply);
+ msm_pil_unregister(drv->pil);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index bd49fc0..198572c 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -86,6 +86,7 @@
bool use_cxo;
struct delayed_work work;
struct regulator *pll_supply;
+ struct pil_device *pil;
};
static int pil_riva_make_proxy_votes(struct device *dev)
@@ -390,6 +391,7 @@
desc->name = "wcnss";
desc->dev = &pdev->dev;
+ desc->owner = THIS_MODULE;
if (pas_supported(PAS_RIVA) > 0) {
desc->ops = &pil_riva_ops_trusted;
@@ -406,9 +408,11 @@
}
INIT_DELAYED_WORK(&drv->work, pil_riva_remove_proxy_votes);
- ret = msm_pil_register(desc);
- if (ret)
+ drv->pil = msm_pil_register(desc);
+ if (IS_ERR(drv->pil)) {
+ ret = PTR_ERR(drv->pil);
goto err_register;
+ }
return 0;
err_register:
flush_delayed_work_sync(&drv->work);
@@ -421,6 +425,7 @@
static int __devexit pil_riva_remove(struct platform_device *pdev)
{
struct riva_data *drv = platform_get_drvdata(pdev);
+ msm_pil_unregister(drv->pil);
flush_delayed_work_sync(&drv->work);
clk_put(drv->xo);
regulator_put(drv->pll_supply);
diff --git a/arch/arm/mach-msm/pil-tzapps.c b/arch/arm/mach-msm/pil-tzapps.c
index 90ac1d9..b6e5343 100644
--- a/arch/arm/mach-msm/pil-tzapps.c
+++ b/arch/arm/mach-msm/pil-tzapps.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
@@ -50,6 +50,7 @@
static int __devinit pil_tzapps_driver_probe(struct platform_device *pdev)
{
struct pil_desc *desc;
+ struct pil_device *pil;
if (pas_supported(PAS_TZAPPS) < 0)
return -ENOSYS;
@@ -61,13 +62,18 @@
desc->name = "tzapps";
desc->dev = &pdev->dev;
desc->ops = &pil_tzapps_ops;
- if (msm_pil_register(desc))
- return -EINVAL;
+ desc->owner = THIS_MODULE;
+ pil = msm_pil_register(desc);
+ if (IS_ERR(pil))
+ return PTR_ERR(pil);
+ platform_set_drvdata(pdev, pil);
return 0;
}
static int __devexit pil_tzapps_driver_exit(struct platform_device *pdev)
{
+ struct pil_device *pil = platform_get_drvdata(pdev);
+ msm_pil_unregister(pil);
return 0;
}
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 1396463..4d63b6d 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -1769,6 +1769,8 @@
pmd_t *pmd;
unsigned long pmdval;
+ if (cpu_is_msm8625())
+ return 0;
/* Page table for cores to come back up safely. */
pc_pgd = pgd_alloc(&init_mm);
if (!pc_pgd)
diff --git a/arch/arm/mach-msm/qdsp5/audio_voicememo.c b/arch/arm/mach-msm/qdsp5/audio_voicememo.c
index 7a962b2..2011c42 100644
--- a/arch/arm/mach-msm/qdsp5/audio_voicememo.c
+++ b/arch/arm/mach-msm/qdsp5/audio_voicememo.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
*
* This code is based in part on arch/arm/mach-msm/qdsp5/audio_mp3.c
*
@@ -836,6 +836,7 @@
file->private_data = audio;
audio->opened = 1;
+ audio->stopped = 0;
rc = 0;
done:
mutex_unlock(&audio->lock);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
index 0887577..41a7387 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
@@ -28,8 +28,8 @@
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/earlysuspend.h>
+#include <linux/ion.h>
#include <linux/list.h>
-#include <linux/android_pmem.h>
#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/ioctls.h>
@@ -88,10 +88,10 @@
int event_type;
union msm_audio_event_payload payload;
};
-
-struct audlpa_pmem_region {
+struct audlpa_ion_region {
struct list_head list;
- struct file *file;
+ struct ion_handle *handle;
+ struct ion_client *client;
int fd;
void *vaddr;
unsigned long paddr;
@@ -115,12 +115,13 @@
static void audlpa_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload);
-static unsigned long audlpa_pmem_fixup(struct audio *audio, void *addr,
+
+static unsigned long audlpa_ion_fixup(struct audio *audio, void *addr,
unsigned long len, int ref_up);
+static void audlpa_unmap_ion_region(struct audio *audio);
static void audlpa_async_send_data(struct audio *audio, unsigned needed,
uint32_t token);
static int audlpa_pause(struct audio *audio);
-static void audlpa_unmap_pmem_region(struct audio *audio);
static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static int audlpa_set_pcm_params(void *data);
@@ -422,7 +423,7 @@
drv_evt->event_type == AUDIO_EVENT_READ_DONE)) {
pr_debug("%s: AUDIO_EVENT_WRITE_DONE completing\n", __func__);
mutex_lock(&audio->lock);
- audlpa_pmem_fixup(audio, drv_evt->payload.aio_buf.buf_addr,
+ audlpa_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr,
drv_evt->payload.aio_buf.buf_len, 0);
mutex_unlock(&audio->lock);
}
@@ -432,38 +433,41 @@
return rc;
}
-static int audlpa_pmem_check(struct audio *audio,
- void *vaddr, unsigned long len)
+static int audlpa_ion_check(struct audio *audio,
+ void *vaddr, unsigned long len)
{
- struct audlpa_pmem_region *region_elt;
- struct audlpa_pmem_region t = { .vaddr = vaddr, .len = len };
+ struct audlpa_ion_region *region_elt;
+ struct audlpa_ion_region t = {.vaddr = vaddr, .len = len };
- list_for_each_entry(region_elt, &audio->pmem_region_queue, list) {
+ list_for_each_entry(region_elt, &audio->ion_region_queue, list) {
if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
OVERLAPS(region_elt, &t)) {
- pr_err("%s: region (vaddr %p len %ld)"
- " clashes with registered region"
- " (vaddr %p paddr %p len %ld)\n",
- __func__, vaddr, len,
- region_elt->vaddr,
- (void *)region_elt->paddr,
- region_elt->len);
+ pr_err("%s[%p]:region (vaddr %p len %ld)"
+ " clashes with registered region"
+ " (vaddr %p paddr %p len %ld)\n",
+ __func__, audio, vaddr, len,
+ region_elt->vaddr,
+ (void *)region_elt->paddr, region_elt->len);
return -EINVAL;
}
}
return 0;
}
-
-static int audlpa_pmem_add(struct audio *audio,
- struct msm_audio_pmem_info *info)
+static int audlpa_ion_add(struct audio *audio,
+ struct msm_audio_ion_info *info)
{
- unsigned long paddr, kvaddr, len;
- struct file *file;
- struct audlpa_pmem_region *region;
+ ion_phys_addr_t paddr;
+ size_t len;
+ unsigned long kvaddr;
+ struct audlpa_ion_region *region;
int rc = -EINVAL;
+ struct ion_handle *handle;
+ struct ion_client *client;
+ unsigned long ionflag;
+ void *temp_ptr;
- pr_debug("%s:\n", __func__);
+ pr_debug("%s[%p]:\n", __func__, audio);
region = kmalloc(sizeof(*region), GFP_KERNEL);
if (!region) {
@@ -471,61 +475,105 @@
goto end;
}
- if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
- kfree(region);
- goto end;
+ client = msm_ion_client_create(UINT_MAX, "Audio_LPA_Client");
+ if (IS_ERR_OR_NULL(client)) {
+ pr_err("Unable to create ION client\n");
+ goto client_error;
}
- rc = audlpa_pmem_check(audio, info->vaddr, len);
+ handle = ion_import_fd(client, info->fd);
+ if (IS_ERR_OR_NULL(handle)) {
+ pr_err("%s: could not get handle of the given fd\n", __func__);
+ goto import_error;
+ }
+
+ rc = ion_handle_get_flags(client, handle, &ionflag);
+ if (rc) {
+ pr_err("%s: could not get flags for the handle\n", __func__);
+ goto flag_error;
+ }
+
+ temp_ptr = ion_map_kernel(client, handle, ionflag);
+ if (IS_ERR_OR_NULL(temp_ptr)) {
+ pr_err("%s: could not get virtual address\n", __func__);
+ goto map_error;
+ }
+ kvaddr = (unsigned long) temp_ptr;
+
+ rc = ion_phys(client, handle, &paddr, &len);
+ if (rc) {
+ pr_err("%s: could not get physical address\n", __func__);
+ goto ion_error;
+ }
+
+ rc = audlpa_ion_check(audio, info->vaddr, len);
if (rc < 0) {
- put_pmem_file(file);
- kfree(region);
- goto end;
+ pr_err("%s: audlpa_ion_check failed\n", __func__);
+ goto ion_error;
}
+ region->client = client;
+ region->handle = handle;
region->vaddr = info->vaddr;
region->fd = info->fd;
region->paddr = paddr;
region->kvaddr = kvaddr;
region->len = len;
- region->file = file;
region->ref_cnt = 0;
- pr_debug("%s: add region paddr %lx vaddr %p, len %lu\n", __func__,
- region->paddr, region->vaddr,
- region->len);
- list_add_tail(®ion->list, &audio->pmem_region_queue);
+ pr_debug("%s[%p]:add region paddr %lx vaddr %p, len %lu kvaddr %lx\n",
+ __func__, audio,
+ region->paddr, region->vaddr, region->len, region->kvaddr);
+ list_add_tail(®ion->list, &audio->ion_region_queue);
+
rc = q6asm_memory_map(audio->ac, (uint32_t)paddr, IN, (uint32_t)len, 1);
- if (rc < 0)
- pr_err("%s: memory map failed\n", __func__);
+ if (rc < 0) {
+ pr_err("%s[%p]: memory map failed\n", __func__, audio);
+ goto ion_error;
+ } else {
+ goto end;
+ }
+
+ion_error:
+ ion_unmap_kernel(client, handle);
+map_error:
+ ion_free(client, handle);
+flag_error:
+import_error:
+ ion_client_destroy(client);
+client_error:
+ kfree(region);
end:
return rc;
}
-static int audlpa_pmem_remove(struct audio *audio,
- struct msm_audio_pmem_info *info)
+static int audlpa_ion_remove(struct audio *audio,
+ struct msm_audio_ion_info *info)
{
- struct audlpa_pmem_region *region;
+ struct audlpa_ion_region *region;
struct list_head *ptr, *next;
int rc = -EINVAL;
- list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
- region = list_entry(ptr, struct audlpa_pmem_region, list);
+ list_for_each_safe(ptr, next, &audio->ion_region_queue) {
+ region = list_entry(ptr, struct audlpa_ion_region, list);
- if ((region != NULL) && (region->fd == info->fd) &&
- (region->vaddr == info->vaddr)) {
+ if (region != NULL && (region->fd == info->fd) &&
+ (region->vaddr == info->vaddr)) {
if (region->ref_cnt) {
- pr_debug("%s: region %p in use ref_cnt %d\n",
- __func__, region, region->ref_cnt);
+ pr_debug("%s[%p]:region %p in use ref_cnt %d\n",
+ __func__, audio, region,
+ region->ref_cnt);
break;
}
rc = q6asm_memory_unmap(audio->ac,
- (uint32_t)region->paddr,
- IN);
+ (uint32_t) region->paddr, IN);
if (rc < 0)
- pr_err("%s: memory unmap failed\n", __func__);
+ pr_err("%s[%p]: memory unmap failed\n",
+ __func__, audio);
list_del(®ion->list);
- put_pmem_file(region->file);
+ ion_unmap_kernel(region->client, region->handle);
+ ion_free(region->client, region->handle);
+ ion_client_destroy(region->client);
kfree(region);
rc = 0;
break;
@@ -535,24 +583,21 @@
return rc;
}
-static int audlpa_pmem_lookup_vaddr(struct audio *audio, void *addr,
- unsigned long len, struct audlpa_pmem_region **region)
+static int audlpa_ion_lookup_vaddr(struct audio *audio, void *addr,
+ unsigned long len, struct audlpa_ion_region **region)
{
- struct audlpa_pmem_region *region_elt;
-
+ struct audlpa_ion_region *region_elt;
int match_count = 0;
-
*region = NULL;
/* returns physical address or zero */
- list_for_each_entry(region_elt, &audio->pmem_region_queue,
- list) {
+ list_for_each_entry(region_elt, &audio->ion_region_queue, list) {
if (addr >= region_elt->vaddr &&
- addr < region_elt->vaddr + region_elt->len &&
- addr + len <= region_elt->vaddr + region_elt->len) {
+ addr < region_elt->vaddr + region_elt->len &&
+ addr + len <= region_elt->vaddr + region_elt->len) {
/* offset since we could pass vaddr inside a registerd
- * pmem buffer
- */
+ * ion buffer
+ */
match_count++;
if (!*region)
@@ -561,32 +606,33 @@
}
if (match_count > 1) {
- pr_err("%s: multiple hits for vaddr %p, len %ld\n", __func__,
- addr, len);
- list_for_each_entry(region_elt,
- &audio->pmem_region_queue, list) {
- if (addr >= region_elt->vaddr &&
- addr < region_elt->vaddr + region_elt->len &&
- addr + len <= region_elt->vaddr + region_elt->len)
- pr_err("%s: \t%p, %ld --> %p\n", __func__,
- region_elt->vaddr, region_elt->len,
- (void *)region_elt->paddr);
+ pr_err("%s[%p]:multiple hits for vaddr %p, len %ld\n",
+ __func__, audio, addr, len);
+ list_for_each_entry(region_elt, &audio->ion_region_queue,
+ list) {
+ if (addr >= region_elt->vaddr &&
+ addr < region_elt->vaddr + region_elt->len &&
+ addr + len <= region_elt->vaddr + region_elt->len)
+ pr_err("\t%s[%p]:%p, %ld --> %p\n",
+ __func__, audio,
+ region_elt->vaddr,
+ region_elt->len,
+ (void *)region_elt->paddr);
}
}
-
return *region ? 0 : -1;
}
-
-unsigned long audlpa_pmem_fixup(struct audio *audio, void *addr,
- unsigned long len, int ref_up)
+static unsigned long audlpa_ion_fixup(struct audio *audio, void *addr,
+ unsigned long len, int ref_up)
{
- struct audlpa_pmem_region *region;
+ struct audlpa_ion_region *region;
unsigned long paddr;
int ret;
- ret = audlpa_pmem_lookup_vaddr(audio, addr, len, ®ion);
+ ret = audlpa_ion_lookup_vaddr(audio, addr, len, ®ion);
if (ret) {
- pr_err("%s: lookup (%p, %ld) failed\n", __func__, addr, len);
+ pr_err("%s[%p]:lookup (%p, %ld) failed\n",
+ __func__, audio, addr, len);
return 0;
}
if (ref_up)
@@ -613,7 +659,7 @@
return -EFAULT;
}
- buf_node->paddr = audlpa_pmem_fixup(
+ buf_node->paddr = audlpa_ion_fixup(
audio, buf_node->buf.buf_addr,
buf_node->buf.buf_len, 1);
if (dir) {
@@ -921,25 +967,26 @@
}
break;
- case AUDIO_REGISTER_PMEM: {
- struct msm_audio_pmem_info info;
- pr_debug("%s: AUDIO_REGISTER_PMEM\n", __func__);
- if (copy_from_user(&info, (void *) arg, sizeof(info)))
- rc = -EFAULT;
- else
- rc = audlpa_pmem_add(audio, &info);
- break;
- }
+ case AUDIO_REGISTER_ION: {
+ struct msm_audio_ion_info info;
+ pr_debug("%s: AUDIO_REGISTER_ION\n", __func__);
+ if (copy_from_user(&info, (void *)arg, sizeof(info)))
+ rc = -EFAULT;
+ else
+ rc = audlpa_ion_add(audio, &info);
+ break;
+ }
- case AUDIO_DEREGISTER_PMEM: {
- struct msm_audio_pmem_info info;
- pr_debug("%s: AUDIO_DEREGISTER_PMEM\n", __func__);
- if (copy_from_user(&info, (void *) arg, sizeof(info)))
- rc = -EFAULT;
- else
- rc = audlpa_pmem_remove(audio, &info);
- break;
- }
+ case AUDIO_DEREGISTER_ION: {
+ struct msm_audio_ion_info info;
+ pr_debug("%s: AUDIO_DEREGISTER_ION\n", __func__);
+ if (copy_from_user(&info, (void *)arg, sizeof(info)))
+ rc = -EFAULT;
+ else
+ rc = audlpa_ion_remove(audio, &info);
+ break;
+ }
+
case AUDIO_ASYNC_WRITE:
pr_debug("%s: AUDIO_ASYNC_WRITE\n", __func__);
if (audio->drv_status & ADRV_STATUS_FSYNC)
@@ -1038,34 +1085,37 @@
return audlpa_async_fsync(audio);
}
-static void audlpa_reset_pmem_region(struct audio *audio)
+void audlpa_reset_ion_region(struct audio *audio)
{
- struct audlpa_pmem_region *region;
+ struct audlpa_ion_region *region;
struct list_head *ptr, *next;
- list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
- region = list_entry(ptr, struct audlpa_pmem_region, list);
+ list_for_each_safe(ptr, next, &audio->ion_region_queue) {
+ region = list_entry(ptr, struct audlpa_ion_region, list);
list_del(®ion->list);
- put_pmem_file(region->file);
+ ion_unmap_kernel(region->client, region->handle);
+ ion_free(region->client, region->handle);
+ ion_client_destroy(region->client);
kfree(region);
}
return;
}
-static void audlpa_unmap_pmem_region(struct audio *audio)
+static void audlpa_unmap_ion_region(struct audio *audio)
{
- struct audlpa_pmem_region *region;
+ struct audlpa_ion_region *region;
struct list_head *ptr, *next;
int rc = -EINVAL;
- pr_debug("%s:\n", __func__);
- list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
- region = list_entry(ptr, struct audlpa_pmem_region, list);
- pr_debug("%s: phy_address = 0x%lx\n", __func__, region->paddr);
+ pr_debug("%s[%p]:\n", __func__, audio);
+ list_for_each_safe(ptr, next, &audio->ion_region_queue) {
+ region = list_entry(ptr, struct audlpa_ion_region, list);
+ pr_debug("%s[%p]: phy_address = 0x%lx\n",
+ __func__, audio, region->paddr);
if (region != NULL) {
rc = q6asm_memory_unmap(audio->ac,
- (uint32_t)region->paddr, IN);
+ (uint32_t)region->paddr, IN);
if (rc < 0)
pr_err("%s: memory unmap failed\n", __func__);
}
@@ -1084,12 +1134,12 @@
if (audio->out_enabled)
audlpa_async_flush(audio);
audio->wflush = 0;
- audlpa_unmap_pmem_region(audio);
+ audlpa_unmap_ion_region(audio);
audio_disable(audio);
msm_clear_session_id(audio->ac->session);
auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->ac->session);
q6asm_audio_client_free(audio->ac);
- audlpa_reset_pmem_region(audio);
+ audlpa_reset_ion_region(audio);
#ifdef CONFIG_HAS_EARLYSUSPEND
unregister_early_suspend(&audio->suspend_ctl.node);
#endif
@@ -1099,7 +1149,6 @@
audio->event_abort = 1;
wake_up(&audio->event_wait);
audlpa_reset_event_queue(audio);
- pmem_kfree(audio->phys);
if (audio->stopped == 0)
audlpa_allow_sleep(audio);
wake_lock_destroy(&audio->wakelock);
@@ -1277,7 +1326,7 @@
spin_lock_init(&audio->dsp_lock);
init_waitqueue_head(&audio->write_wait);
INIT_LIST_HEAD(&audio->out_queue);
- INIT_LIST_HEAD(&audio->pmem_region_queue);
+ INIT_LIST_HEAD(&audio->ion_region_queue);
INIT_LIST_HEAD(&audio->free_event_queue);
INIT_LIST_HEAD(&audio->event_queue);
init_waitqueue_head(&audio->wait);
@@ -1342,7 +1391,6 @@
return rc;
err:
q6asm_audio_client_free(audio->ac);
- pmem_kfree(audio->phys);
kfree(audio);
return rc;
}
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
index ffc27ad..34b53f2 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
@@ -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
@@ -88,7 +88,7 @@
uint32_t device_events;
- struct list_head pmem_region_queue; /* protected by lock */
+ struct list_head ion_region_queue; /* protected by lock */
int eq_enable;
int eq_needs_commit;
diff --git a/arch/arm/mach-msm/qdss-ptm.c b/arch/arm/mach-msm/qdss-etm.c
similarity index 100%
rename from arch/arm/mach-msm/qdss-ptm.c
rename to arch/arm/mach-msm/qdss-etm.c
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 158015a..542d224 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -622,13 +622,25 @@
mutex_lock(&smd_pkt_devp->ch_lock);
if (smd_pkt_devp->ch == 0) {
+ init_completion(&smd_pkt_devp->ch_allocated);
+ smd_pkt_devp->driver.probe = smd_pkt_dummy_probe;
+ smd_pkt_devp->driver.driver.name =
+ smd_ch_name[smd_pkt_devp->i];
+ smd_pkt_devp->driver.driver.owner = THIS_MODULE;
+ r = platform_driver_register(&smd_pkt_devp->driver);
+ if (r) {
+ pr_err("%s: %s Platform driver reg. failed\n",
+ __func__, smd_ch_name[smd_pkt_devp->i]);
+ goto out;
+ }
+
peripheral = smd_edge_to_subsystem(
smd_ch_edge[smd_pkt_devp->i]);
if (peripheral) {
smd_pkt_devp->pil = pil_get(peripheral);
if (IS_ERR(smd_pkt_devp->pil)) {
r = PTR_ERR(smd_pkt_devp->pil);
- goto out;
+ goto release_pd;
}
/* Wait for the modem SMSM to be inited for the SMD
@@ -697,6 +709,10 @@
release_pil:
if (peripheral && (r < 0))
pil_put(smd_pkt_devp->pil);
+
+release_pd:
+ if (r < 0)
+ platform_driver_unregister(&smd_pkt_devp->driver);
out:
mutex_unlock(&smd_pkt_devp->ch_lock);
@@ -722,6 +738,7 @@
smd_pkt_devp->ch = 0;
smd_pkt_devp->blocking_write = 0;
smd_pkt_devp->poll_mode = 0;
+ platform_driver_unregister(&smd_pkt_devp->driver);
if (smd_pkt_devp->pil)
pil_put(smd_pkt_devp->pil);
}
@@ -798,7 +815,6 @@
mutex_init(&smd_pkt_devp[i]->ch_lock);
mutex_init(&smd_pkt_devp[i]->rx_lock);
mutex_init(&smd_pkt_devp[i]->tx_lock);
- init_completion(&smd_pkt_devp[i]->ch_allocated);
cdev_init(&smd_pkt_devp[i]->cdev, &smd_pkt_fops);
smd_pkt_devp[i]->cdev.owner = THIS_MODULE;
@@ -839,13 +855,6 @@
&dev_attr_open_timeout))
pr_err("%s: unable to create device attr on #%d\n",
__func__, i);
-
- smd_pkt_devp[i]->driver.probe = smd_pkt_dummy_probe;
- smd_pkt_devp[i]->driver.driver.name = smd_ch_name[i];
- smd_pkt_devp[i]->driver.driver.owner = THIS_MODULE;
- r = platform_driver_register(&smd_pkt_devp[i]->driver);
- if (r)
- goto error2;
}
INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker);
@@ -856,7 +865,6 @@
error2:
if (i > 0) {
while (--i >= 0) {
- platform_driver_unregister(&smd_pkt_devp[i]->driver);
cdev_del(&smd_pkt_devp[i]->cdev);
kfree(smd_pkt_devp[i]);
device_destroy(smd_pkt_classp,
@@ -876,7 +884,6 @@
int i;
for (i = 0; i < NUM_SMD_PKT_PORTS; ++i) {
- platform_driver_unregister(&smd_pkt_devp[i]->driver);
cdev_del(&smd_pkt_devp[i]->cdev);
kfree(smd_pkt_devp[i]);
device_destroy(smd_pkt_classp,
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 883dec1..1f85194 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -169,11 +169,7 @@
reg = saw_bases[cpu];
- if (cpu_is_msm8960() || cpu_is_msm8930()) {
- val = 0xB0;
- reg += 0x14;
- timeout = 512;
- } else if (cpu_is_apq8064()) {
+ if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_apq8064()) {
val = 0xA4;
reg += 0x14;
timeout = 512;
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 0bc080c..2dfde6f 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1123,11 +1123,8 @@
}
msm_sched_clock_init();
- if (is_smp()) {
- __raw_writel(1,
- msm_clocks[MSM_CLOCK_DGT].regbase + TIMER_ENABLE);
- set_delay_fn(read_current_timer_delay_loop);
- }
+ __raw_writel(1, msm_clocks[MSM_CLOCK_DGT].regbase + TIMER_ENABLE);
+ set_delay_fn(read_current_timer_delay_loop);
}
#ifdef CONFIG_SMP
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index 59abfe6..1bdec12 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -52,6 +52,9 @@
static void smsm_state_cb_hdlr(void *data, uint32_t old_state,
uint32_t new_state)
{
+ if (!(new_state & SMSM_RESET))
+ return;
+
riva_crash = true;
pr_err("%s: smsm state changed to smsm reset\n", MODULE_NAME);
@@ -60,10 +63,8 @@
MODULE_NAME);
return;
}
- if (new_state & SMSM_RESET) {
- ss_restart_inprogress = true;
- schedule_work(&riva_smsm_cb_work);
- }
+ ss_restart_inprogress = true;
+ schedule_work(&riva_smsm_cb_work);
}
static void riva_fatal_fn(struct work_struct *work)
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 321abe8..edede47 100755
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1140,3 +1140,4 @@
mpq8064_dtv MACH_MPQ8064_DTV MPQ8064_DTV 3995
msm7627a_qrd3 MACH_MSM7627A_QRD3 MSM7627A_QRD3 4005
msm8625_surf MACH_MSM8625_SURF MSM8625_SURF 4037
+msm8625_evb MACH_MSM8625_EVB MSM8625_EVB 4042
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index a701773..228c77fb 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -23,6 +23,7 @@
#include <asm/mach-types.h>
/* Size of the USB buffers used for read and write*/
#define USB_MAX_OUT_BUF 4096
+#define APPS_BUF_SIZE 2000
#define IN_BUF_SIZE 16384
#define MAX_IN_BUF_SIZE 32768
#define MAX_SYNC_OBJ_NAME_SIZE 32
@@ -50,6 +51,9 @@
#define USER_SPACE_DATA 8000
#define PKT_SIZE 4096
#define MAX_EQUIP_ID 12
+#define DIAG_CTRL_MSG_LOG_MASK 9
+#define DIAG_CTRL_MSG_EVENT_MASK 10
+#define DIAG_CTRL_MSG_F3_MASK 11
/* Maximum number of pkt reg supported at initialization*/
extern unsigned int diag_max_reg;
@@ -130,6 +134,7 @@
int num_clients;
int polling_reg_flag;
struct diag_write_device *buf_tbl;
+ int use_device_tree;
/* Memory pool parameters */
unsigned int itemsize;
@@ -148,7 +153,10 @@
int count_hdlc_pool;
int count_write_struct_pool;
int used;
-
+ /* Buffers for masks */
+ struct diag_ctrl_event_mask *event_mask;
+ struct diag_ctrl_log_mask *log_mask;
+ struct diag_ctrl_msg_mask *msg_mask;
/* State for diag forwarding */
unsigned char *buf_in_1;
unsigned char *buf_in_2;
@@ -161,6 +169,10 @@
unsigned char *usb_buf_out;
unsigned char *apps_rsp_buf;
unsigned char *user_space_data;
+ /* buffer for updating mask to peripherals */
+ unsigned char *buf_msg_mask_update;
+ unsigned char *buf_log_mask_update;
+ unsigned char *buf_event_mask_update;
smd_channel_t *ch;
smd_channel_t *ch_cntl;
smd_channel_t *chqdsp;
@@ -190,6 +202,13 @@
struct work_struct diag_read_smd_qdsp_cntl_work;
struct work_struct diag_read_smd_wcnss_work;
struct work_struct diag_read_smd_wcnss_cntl_work;
+ struct workqueue_struct *diag_cntl_wq;
+ struct work_struct diag_msg_mask_update_work;
+ struct work_struct diag_log_mask_update_work;
+ struct work_struct diag_event_mask_update_work;
+ struct work_struct diag_modem_mask_update_work;
+ struct work_struct diag_qdsp_mask_update_work;
+ struct work_struct diag_wcnss_mask_update_work;
uint8_t *msg_masks;
uint8_t *log_masks;
int log_masks_length;
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 7f26856..f16aa0c 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -21,6 +21,7 @@
#include <linux/diagchar.h>
#include <linux/delay.h>
#include <linux/reboot.h>
+#include <linux/of.h>
#ifdef CONFIG_DIAG_OVER_USB
#include <mach/usbdiag.h>
#endif
@@ -43,8 +44,15 @@
static unsigned int buf_tbl_size = 8; /*Number of entries in table of buffers */
struct diag_master_table entry;
smd_channel_t *ch_temp, *chqdsp_temp, *ch_wcnss_temp;
+int diag_event_num_bytes;
+int diag_event_config;
struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
+struct mask_info {
+ int equip_id;
+ int num_items;
+ int index;
+};
#define ENCODE_RSP_AND_SEND(buf_length) \
do { \
@@ -54,7 +62,7 @@
send.terminate = 1; \
if (!driver->in_busy_1) { \
enc.dest = driver->buf_in_1; \
- enc.dest_last = (void *)(driver->buf_in_1 + 499); \
+ enc.dest_last = (void *)(driver->buf_in_1 + APPS_BUF_SIZE - 1);\
diag_hdlc_encode(&send, &enc); \
driver->write_ptr_1->buf = driver->buf_in_1; \
driver->write_ptr_1->length = (int)(enc.dest - \
@@ -62,55 +70,80 @@
driver->in_busy_1 = 1; \
diag_device_write(driver->buf_in_1, MODEM_DATA, \
driver->write_ptr_1); \
- memset(driver->apps_rsp_buf, '\0', 500); \
+ memset(driver->apps_rsp_buf, '\0', APPS_BUF_SIZE); \
} \
} while (0)
#define CHK_OVERFLOW(bufStart, start, end, length) \
((bufStart <= start) && (end - start >= length)) ? 1 : 0
+/* Determine if this device uses a device tree */
+#ifdef CONFIG_OF
+static int has_device_tree(void)
+{
+ struct device_node *node;
+
+ node = of_find_node_by_path("/");
+ if (node) {
+ of_node_put(node);
+ return 1;
+ }
+ return 0;
+}
+#else
+static int has_device_tree(void)
+{
+ return 0;
+}
+#endif
+
int chk_config_get_id(void)
{
/* For all Fusion targets, Modem will always be present */
if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
return 0;
- switch (socinfo_get_id()) {
- case APQ8060_MACHINE_ID:
- case MSM8660_MACHINE_ID:
- return APQ8060_TOOLS_ID;
- case AO8960_MACHINE_ID:
- case MSM8260A_MACHINE_ID:
- return AO8960_TOOLS_ID;
- case APQ8064_MACHINE_ID:
- return APQ8064_TOOLS_ID;
- case MSM8930_MACHINE_ID:
- return MSM8930_TOOLS_ID;
- case MSM8974_MACHINE_ID:
- return MSM8974_TOOLS_ID;
- default:
- return 0;
+ if (driver->use_device_tree) {
+ if (machine_is_copper())
+ return MSM8974_TOOLS_ID;
+ else
+ return 0;
+ } else {
+ switch (socinfo_get_msm_cpu()) {
+ case MSM_CPU_8X60:
+ return APQ8060_TOOLS_ID;
+ case MSM_CPU_8960:
+ return AO8960_TOOLS_ID;
+ case MSM_CPU_8064:
+ return APQ8064_TOOLS_ID;
+ case MSM_CPU_8930:
+ return MSM8930_TOOLS_ID;
+ case MSM_CPU_COPPER:
+ return MSM8974_TOOLS_ID;
+ case MSM_CPU_8625:
+ return MSM8625_TOOLS_ID;
+ default:
+ return 0;
+ }
}
}
/*
- * This will return TRUE for targets which support apps only mode.
+ * This will return TRUE for targets which support apps only mode and hence SSR.
* This applies to 8960 and newer targets.
*/
int chk_apps_only(void)
{
- switch (socinfo_get_id()) {
- case AO8960_MACHINE_ID:
- case APQ8064_MACHINE_ID:
- case MSM8930_MACHINE_ID:
- case MSM8630_MACHINE_ID:
- case MSM8230_MACHINE_ID:
- case APQ8030_MACHINE_ID:
- case MSM8627_MACHINE_ID:
- case MSM8227_MACHINE_ID:
- case MSM8974_MACHINE_ID:
- case MDM9615_MACHINE_ID:
- case MSM8260A_MACHINE_ID:
+ if (driver->use_device_tree)
+ return 1;
+
+ switch (socinfo_get_msm_cpu()) {
+ case MSM_CPU_8960:
+ case MSM_CPU_8064:
+ case MSM_CPU_8930:
+ case MSM_CPU_8627:
+ case MSM_CPU_9615:
+ case MSM_CPU_COPPER:
return 1;
default:
return 0;
@@ -124,8 +157,28 @@
*/
int chk_apps_master(void)
{
- if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615() ||
- cpu_is_apq8064() || cpu_is_msm8627())
+ if (driver->use_device_tree)
+ return 1;
+ else if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615() ||
+ cpu_is_apq8064() || cpu_is_msm8627())
+ return 1;
+ else
+ return 0;
+}
+
+inline int chk_polling_response(void)
+{
+ if (!(driver->polling_reg_flag) && chk_apps_master())
+ /*
+ * If the apps processor is master and no other processor
+ * has registered to respond for polling
+ */
+ return 1;
+ else if (!(driver->ch) && !(chk_apps_master()))
+ /*
+ * If the apps processor is not the master and the modem
+ * is not up
+ */
return 1;
else
return 0;
@@ -400,8 +453,8 @@
uint8_t *ptr_buffer_end = &(*(driver->msg_masks)) + MSG_MASK_SIZE;
mutex_lock(&driver->diagchar_mutex);
- /* First SSID can be zero : So check that last is non-zero */
+ /* First SSID can be zero : So check that last is non-zero */
while (*(uint32_t *)(ptr + 4)) {
first = *(uint32_t *)ptr;
ptr += 4;
@@ -446,7 +499,7 @@
}
-static void diag_update_event_mask(uint8_t *buf, int toggle, int num_bits)
+static void diag_update_event_mask(uint8_t *buf, int toggle, int num_bytes)
{
uint8_t *ptr = driver->event_masks;
uint8_t *temp = buf + 2;
@@ -456,9 +509,8 @@
memset(ptr, 0 , EVENT_MASK_SIZE);
else
if (CHK_OVERFLOW(ptr, ptr,
- ptr+EVENT_MASK_SIZE,
- num_bits/8 + 1))
- memcpy(ptr, temp , num_bits/8 + 1);
+ ptr+EVENT_MASK_SIZE, num_bytes))
+ memcpy(ptr, temp , num_bytes);
else
printk(KERN_CRIT "Not enough buffer space "
"for EVENT_MASK\n");
@@ -468,10 +520,6 @@
static void diag_update_log_mask(int equip_id, uint8_t *buf, int num_items)
{
uint8_t *temp = buf;
- struct mask_info {
- int equip_id;
- int index;
- };
int i = 0;
unsigned char *ptr_data;
int offset = 8*MAX_EQUIP_ID;
@@ -485,8 +533,9 @@
break;
}
if ((ptr->equip_id == 0) && (ptr->index == 0)) {
- /*Reached a null entry */
+ /* Reached a null entry */
ptr->equip_id = equip_id;
+ ptr->num_items = num_items;
ptr->index = driver->log_masks_length;
offset = driver->log_masks_length;
driver->log_masks_length += ((num_items+7)/8);
@@ -571,6 +620,123 @@
}
}
+void diag_modem_mask_update_fn(struct work_struct *work)
+{
+ diag_send_msg_mask_update(driver->ch_cntl);
+ diag_send_log_mask_update(driver->ch_cntl);
+ diag_send_event_mask_update(driver->ch_cntl, diag_event_num_bytes);
+}
+
+void diag_qdsp_mask_update_fn(struct work_struct *work)
+{
+ diag_send_msg_mask_update(driver->chqdsp_cntl);
+ diag_send_log_mask_update(driver->chqdsp_cntl);
+ diag_send_event_mask_update(driver->chqdsp_cntl, diag_event_num_bytes);
+}
+
+void diag_wcnss_mask_update_fn(struct work_struct *work)
+{
+ diag_send_msg_mask_update(driver->ch_wcnss_cntl);
+ diag_send_log_mask_update(driver->ch_wcnss_cntl);
+ diag_send_event_mask_update(driver->ch_wcnss_cntl,
+ diag_event_num_bytes);
+}
+
+void diag_msg_mask_update_fn(struct work_struct *work)
+{
+ diag_send_msg_mask_update(driver->ch_cntl);
+ diag_send_msg_mask_update(driver->chqdsp_cntl);
+ diag_send_msg_mask_update(driver->ch_wcnss_cntl);
+}
+
+void diag_log_mask_update_fn(struct work_struct *work)
+{
+ diag_send_log_mask_update(driver->ch_cntl);
+ diag_send_log_mask_update(driver->chqdsp_cntl);
+ diag_send_log_mask_update(driver->ch_wcnss_cntl);
+}
+
+void diag_send_log_mask_update(smd_channel_t *ch)
+{
+ void *buf = driver->buf_log_mask_update;
+ int header_size = sizeof(struct diag_ctrl_log_mask);
+ struct mask_info *ptr = (struct mask_info *)driver->log_masks;
+ int i, size = (driver->log_mask->num_items+7)/8;
+
+ for (i = 0; i < MAX_EQUIP_ID; i++) {
+ /* reached null entry */
+ if ((ptr->equip_id == 0) && (ptr->index == 0))
+ break;
+ driver->log_mask->cmd_type = DIAG_CTRL_MSG_LOG_MASK;
+ driver->log_mask->num_items = ptr->num_items;
+ driver->log_mask->data_len = 11 + size;
+ driver->log_mask->stream_id = 1; /* 2, if dual stream */
+ driver->log_mask->status = 3; /* status for valid mask */
+ driver->log_mask->equip_id = ptr->equip_id;
+ driver->log_mask->log_mask_size = size;
+ memcpy(buf, driver->log_mask, header_size);
+ memcpy(buf+header_size, driver->log_masks+ptr->index, size);
+ msleep(100);
+ if (ch)
+ smd_write(ch, buf, header_size + size);
+ ptr++;
+ }
+}
+
+void diag_send_event_mask_update(smd_channel_t *ch, int num_bytes)
+{
+ void *buf = driver->buf_event_mask_update;
+ int header_size = sizeof(struct diag_ctrl_event_mask);
+
+ /* send event mask update */
+ driver->event_mask->cmd_type = DIAG_CTRL_MSG_EVENT_MASK;
+ driver->event_mask->data_len = 7 + num_bytes;
+ driver->event_mask->stream_id = 1; /* 2, if dual stream */
+ driver->event_mask->status = 3; /* status for valid mask */
+ driver->event_mask->event_config = diag_event_config; /* event config */
+ driver->event_mask->event_mask_size = num_bytes;
+ memcpy(buf, driver->event_mask, header_size);
+ memcpy(buf+header_size, driver->event_masks, num_bytes);
+ msleep(100);
+ if (ch)
+ smd_write(ch, buf, header_size + num_bytes);
+}
+
+void diag_send_msg_mask_update(smd_channel_t *ch)
+{
+ void *buf = driver->buf_msg_mask_update;
+ int first, last;
+ int header_size = sizeof(struct diag_ctrl_msg_mask);
+ uint8_t *ptr = driver->msg_masks;
+
+ while (*(uint32_t *)(ptr + 4)) {
+ first = *(uint32_t *)ptr;
+ ptr += 4;
+ last = *(uint32_t *)ptr;
+ ptr += 4;
+ /* send event mask update */
+ driver->msg_mask->cmd_type = DIAG_CTRL_MSG_F3_MASK;
+ driver->msg_mask->msg_mask_size = last - first + 1;
+ driver->msg_mask->data_len = 11 +
+ 4 * (driver->msg_mask->msg_mask_size);
+ driver->msg_mask->stream_id = 1; /* 2, if dual stream */
+ driver->msg_mask->status = 3; /* status for valid mask */
+ driver->msg_mask->msg_mode = 0; /* Legcay mode */
+ driver->msg_mask->ssid_first = first;
+ driver->msg_mask->ssid_last = last;
+ memcpy(buf, driver->msg_mask, header_size);
+ memcpy(buf+header_size, ptr,
+ 4 * (driver->msg_mask->msg_mask_size));
+ /* since mask updates are slow, so sleep needed as to
+ prevent modem running out of DSM items */
+ msleep(100);
+ if (ch)
+ smd_write(ch, buf,
+ header_size + 4*(driver->msg_mask->msg_mask_size));
+ ptr += ((last - first) + 1)*4;
+ }
+}
+
static int diag_process_apps_pkt(unsigned char *buf, int len)
{
uint16_t subsys_cmd_code;
@@ -583,6 +749,93 @@
unsigned char *ptr;
#endif
+ /* Set log masks */
+ if (*buf == 0x73 && *(int *)(buf+4) == 3) {
+ buf += 8;
+ /* Read Equip ID and pass as first param below*/
+ diag_update_log_mask(*(int *)buf, buf+8, *(int *)(buf+4));
+ diag_update_userspace_clients(LOG_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x73;
+ *(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
+ *(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
+ payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
+ for (i = 0; i < payload_length; i++)
+ *(int *)(driver->apps_rsp_buf+12+i) = *(buf+i);
+ queue_work(driver->diag_cntl_wq,
+ &(driver->diag_log_mask_update_work));
+ ENCODE_RSP_AND_SEND(12 + payload_length - 1);
+ return 0;
+ } else
+ buf = temp;
+#endif
+ } /* Check for set message mask */
+ else if ((*buf == 0x7d) && (*(buf+1) == 0x4)) {
+ ssid_first = *(uint16_t *)(buf + 2);
+ ssid_last = *(uint16_t *)(buf + 4);
+ ssid_range = 4 * (ssid_last - ssid_first + 1);
+ diag_update_msg_mask(ssid_first, ssid_last , buf + 8);
+ diag_update_userspace_clients(MSG_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ for (i = 0; i < 8 + ssid_range; i++)
+ *(driver->apps_rsp_buf + i) = *(buf+i);
+ *(driver->apps_rsp_buf + 6) = 0x1;
+ queue_work(driver->diag_cntl_wq,
+ &(driver->diag_msg_mask_update_work));
+ ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
+ return 0;
+ } else
+ buf = temp;
+#endif
+ } else if (*buf == 0x82) { /* event mask change */
+ buf += 4;
+ diag_event_num_bytes = (*(uint16_t *)buf)/8+1;
+ diag_update_event_mask(buf, 1, (*(uint16_t *)buf)/8+1);
+ diag_update_userspace_clients(EVENT_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x82;
+ driver->apps_rsp_buf[1] = 0x0;
+ *(uint16_t *)(driver->apps_rsp_buf + 2) = 0x0;
+ *(uint16_t *)(driver->apps_rsp_buf + 4) =
+ EVENT_LAST_ID + 1;
+ for (i = 0; i < EVENT_LAST_ID/8 + 1; i++)
+ *(unsigned char *)(driver->apps_rsp_buf + 6 + i)
+ = 0x0;
+ /* cannot do this on work queue, as each event update
+ needs a num_bytes variable. Each queue_work call will
+ overwrite the previous input, as its the same struct */
+ diag_send_event_mask_update(driver->ch_cntl,
+ diag_event_num_bytes);
+ diag_send_event_mask_update(driver->chqdsp_cntl,
+ diag_event_num_bytes);
+ diag_send_event_mask_update(driver->ch_wcnss_cntl,
+ diag_event_num_bytes);
+ ENCODE_RSP_AND_SEND(6 + EVENT_LAST_ID/8);
+ return 0;
+ } else
+ buf = temp;
+#endif
+ } else if (*buf == 0x60) {
+ diag_event_config = *(buf+1);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x60;
+ driver->apps_rsp_buf[1] = 0x0;
+ driver->apps_rsp_buf[2] = 0x0;
+ diag_send_event_mask_update(driver->ch_cntl,
+ diag_event_num_bytes);
+ diag_send_event_mask_update(driver->chqdsp_cntl,
+ diag_event_num_bytes);
+ diag_send_event_mask_update(driver->ch_wcnss_cntl,
+ diag_event_num_bytes);
+ ENCODE_RSP_AND_SEND(2);
+ return 0;
+ }
+#endif
+ }
/* Check for registered clients and forward packet to apropriate proc */
cmd_code = (int)(*(char *)buf);
temp++;
@@ -632,70 +885,9 @@
}
}
}
- /* set event mask */
- if (*buf == 0x82) {
- buf += 4;
- diag_update_event_mask(buf, 1, *(uint16_t *)buf);
- diag_update_userspace_clients(EVENT_MASKS_TYPE);
- }
- /* event mask change */
- else if ((*buf == 0x60) && (*(buf+1) == 0x0)) {
- diag_update_event_mask(buf+1, 0, 0);
- diag_update_userspace_clients(EVENT_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- /* Check for Apps Only */
- if (!(driver->ch) && chk_apps_only()) {
- /* echo response back for apps only DIAG */
- driver->apps_rsp_buf[0] = 0x60;
- driver->apps_rsp_buf[1] = 0x0;
- driver->apps_rsp_buf[2] = 0x0;
- ENCODE_RSP_AND_SEND(2);
- return 0;
- }
-#endif
- }
- /* Set log masks */
- else if (*buf == 0x73 && *(int *)(buf+4) == 3) {
- buf += 8;
- /* Read Equip ID and pass as first param below*/
- diag_update_log_mask(*(int *)buf, buf+8, *(int *)(buf+4));
- diag_update_userspace_clients(LOG_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- /* Check for Apps Only */
- if (!(driver->ch) && chk_apps_only()) {
- /* echo response back for Apps only DIAG */
- driver->apps_rsp_buf[0] = 0x73;
- *(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
- *(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
- payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
- for (i = 0; i < payload_length; i++)
- *(int *)(driver->apps_rsp_buf+12+i) =
- *(buf+8+i);
- ENCODE_RSP_AND_SEND(12 + payload_length - 1);
- return 0;
- }
-#endif
- }
- /* Check for set message mask */
- else if ((*buf == 0x7d) && (*(buf+1) == 0x4)) {
- ssid_first = *(uint16_t *)(buf + 2);
- ssid_last = *(uint16_t *)(buf + 4);
- ssid_range = 4 * (ssid_last - ssid_first + 1);
- diag_update_msg_mask(ssid_first, ssid_last , buf + 8);
- diag_update_userspace_clients(MSG_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- if (!(driver->ch) && chk_apps_only()) {
- /* echo response back for apps only DIAG */
- for (i = 0; i < 8 + ssid_range; i++)
- *(driver->apps_rsp_buf + i) = *(buf+i);
- ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
- return 0;
- }
-#endif
- }
#if defined(CONFIG_DIAG_OVER_USB)
/* Check for Apps Only & get event mask request */
- else if (!(driver->ch) && chk_apps_only() && *buf == 0x81) {
+ if (!(driver->ch) && chk_apps_only() && *buf == 0x81) {
driver->apps_rsp_buf[0] = 0x81;
driver->apps_rsp_buf[1] = 0x0;
*(uint16_t *)(driver->apps_rsp_buf + 2) = 0x0;
@@ -776,7 +968,15 @@
*(uint16_t *)(driver->apps_rsp_buf + 78) = MSG_SSID_17_LAST;
*(uint16_t *)(driver->apps_rsp_buf + 80) = MSG_SSID_18;
*(uint16_t *)(driver->apps_rsp_buf + 82) = MSG_SSID_18_LAST;
- ENCODE_RSP_AND_SEND(83);
+ *(uint16_t *)(driver->apps_rsp_buf + 84) = MSG_SSID_19;
+ *(uint16_t *)(driver->apps_rsp_buf + 86) = MSG_SSID_19_LAST;
+ *(uint16_t *)(driver->apps_rsp_buf + 88) = MSG_SSID_20;
+ *(uint16_t *)(driver->apps_rsp_buf + 90) = MSG_SSID_20_LAST;
+ *(uint16_t *)(driver->apps_rsp_buf + 92) = MSG_SSID_21;
+ *(uint16_t *)(driver->apps_rsp_buf + 94) = MSG_SSID_21_LAST;
+ *(uint16_t *)(driver->apps_rsp_buf + 96) = MSG_SSID_22;
+ *(uint16_t *)(driver->apps_rsp_buf + 98) = MSG_SSID_22_LAST;
+ ENCODE_RSP_AND_SEND(99);
return 0;
}
/* Check for Apps Only Respond to Get Subsys Build mask */
@@ -871,6 +1071,22 @@
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_18[i/4];
break;
+ case MSG_SSID_19:
+ for (i = 0; i < ssid_range; i += 4)
+ *(int *)(ptr + i) = msg_bld_masks_19[i/4];
+ break;
+ case MSG_SSID_20:
+ for (i = 0; i < ssid_range; i += 4)
+ *(int *)(ptr + i) = msg_bld_masks_20[i/4];
+ break;
+ case MSG_SSID_21:
+ for (i = 0; i < ssid_range; i += 4)
+ *(int *)(ptr + i) = msg_bld_masks_21[i/4];
+ break;
+ case MSG_SSID_22:
+ for (i = 0; i < ssid_range; i += 4)
+ *(int *)(ptr + i) = msg_bld_masks_22[i/4];
+ break;
}
ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
return 0;
@@ -892,7 +1108,7 @@
else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
(*(buf+2) == 0x03)) {
/* If no one has registered for polling */
- if (!(driver->polling_reg_flag)) {
+ if (chk_polling_response()) {
/* Respond to polling for Apps only DIAG */
for (i = 0; i < 3; i++)
driver->apps_rsp_buf[i] = *(buf+i);
@@ -904,7 +1120,7 @@
}
}
/* Check for ID for NO MODEM present */
- else if (!(driver->polling_reg_flag)) {
+ else if (chk_polling_response()) {
/* respond to 0x0 command */
if (*buf == 0x00) {
for (i = 0; i < 55; i++)
@@ -1311,6 +1527,26 @@
{
diag_debug_buf_idx = 0;
driver->read_len_legacy = 0;
+ driver->use_device_tree = has_device_tree();
+
+ if (driver->event_mask == NULL) {
+ driver->event_mask = kzalloc(sizeof(
+ struct diag_ctrl_event_mask), GFP_KERNEL);
+ if (driver->event_mask == NULL)
+ goto err;
+ }
+ if (driver->msg_mask == NULL) {
+ driver->msg_mask = kzalloc(sizeof(
+ struct diag_ctrl_msg_mask), GFP_KERNEL);
+ if (driver->msg_mask == NULL)
+ goto err;
+ }
+ if (driver->log_mask == NULL) {
+ driver->log_mask = kzalloc(sizeof(
+ struct diag_ctrl_log_mask), GFP_KERNEL);
+ if (driver->log_mask == NULL)
+ goto err;
+ }
if (driver->buf_in_1 == NULL) {
driver->buf_in_1 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
if (driver->buf_in_1 == NULL)
@@ -1336,6 +1572,24 @@
if (driver->buf_in_wcnss == NULL)
goto err;
}
+ if (driver->buf_msg_mask_update == NULL) {
+ driver->buf_msg_mask_update = kzalloc(APPS_BUF_SIZE,
+ GFP_KERNEL);
+ if (driver->buf_msg_mask_update == NULL)
+ goto err;
+ }
+ if (driver->buf_log_mask_update == NULL) {
+ driver->buf_log_mask_update = kzalloc(APPS_BUF_SIZE,
+ GFP_KERNEL);
+ if (driver->buf_log_mask_update == NULL)
+ goto err;
+ }
+ if (driver->buf_event_mask_update == NULL) {
+ driver->buf_event_mask_update = kzalloc(APPS_BUF_SIZE,
+ GFP_KERNEL);
+ if (driver->buf_event_mask_update == NULL)
+ goto err;
+ }
if (driver->usb_buf_out == NULL &&
(driver->usb_buf_out = kzalloc(USB_MAX_OUT_BUF,
GFP_KERNEL)) == NULL)
@@ -1419,7 +1673,7 @@
GFP_KERNEL)) == NULL)
goto err;
if (driver->apps_rsp_buf == NULL) {
- driver->apps_rsp_buf = kzalloc(500, GFP_KERNEL);
+ driver->apps_rsp_buf = kzalloc(APPS_BUF_SIZE, GFP_KERNEL);
if (driver->apps_rsp_buf == NULL)
goto err;
}
@@ -1427,6 +1681,16 @@
#ifdef CONFIG_DIAG_OVER_USB
INIT_WORK(&(driver->diag_proc_hdlc_work), diag_process_hdlc_fn);
INIT_WORK(&(driver->diag_read_work), diag_read_work_fn);
+ INIT_WORK(&(driver->diag_msg_mask_update_work),
+ diag_msg_mask_update_fn);
+ INIT_WORK(&(driver->diag_log_mask_update_work),
+ diag_log_mask_update_fn);
+ INIT_WORK(&(driver->diag_modem_mask_update_work),
+ diag_modem_mask_update_fn);
+ INIT_WORK(&(driver->diag_qdsp_mask_update_work),
+ diag_qdsp_mask_update_fn);
+ INIT_WORK(&(driver->diag_wcnss_mask_update_work),
+ diag_wcnss_mask_update_fn);
driver->legacy_ch = usb_diag_open(DIAG_LEGACY, driver,
diag_usb_legacy_notifier);
if (IS_ERR(driver->legacy_ch)) {
@@ -1440,11 +1704,17 @@
return;
err:
pr_err("diag: Could not initialize diag buffers");
+ kfree(driver->event_mask);
+ kfree(driver->log_mask);
+ kfree(driver->msg_mask);
kfree(driver->buf_in_1);
kfree(driver->buf_in_2);
kfree(driver->buf_in_qdsp_1);
kfree(driver->buf_in_qdsp_2);
kfree(driver->buf_in_wcnss);
+ kfree(driver->buf_msg_mask_update);
+ kfree(driver->buf_log_mask_update);
+ kfree(driver->buf_event_mask_update);
kfree(driver->usb_buf_out);
kfree(driver->hdlc_buf);
kfree(driver->msg_masks);
@@ -1482,11 +1752,17 @@
#endif
platform_driver_unregister(&msm_smd_ch1_driver);
platform_driver_unregister(&diag_smd_lite_driver);
+ kfree(driver->event_mask);
+ kfree(driver->log_mask);
+ kfree(driver->msg_mask);
kfree(driver->buf_in_1);
kfree(driver->buf_in_2);
kfree(driver->buf_in_qdsp_1);
kfree(driver->buf_in_qdsp_2);
kfree(driver->buf_in_wcnss);
+ kfree(driver->buf_msg_mask_update);
+ kfree(driver->buf_log_mask_update);
+ kfree(driver->buf_event_mask_update);
kfree(driver->usb_buf_out);
kfree(driver->hdlc_buf);
kfree(driver->msg_masks);
diff --git a/drivers/char/diag/diagfwd.h b/drivers/char/diag/diagfwd.h
index 6dacab7..9ef0199 100644
--- a/drivers/char/diag/diagfwd.h
+++ b/drivers/char/diag/diagfwd.h
@@ -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
@@ -28,6 +28,9 @@
int mask_request_validate(unsigned char mask_buf[]);
void diag_clear_reg(int);
int chk_apps_only(void);
+void diag_send_event_mask_update(smd_channel_t *, int num_bytes);
+void diag_send_msg_mask_update(smd_channel_t *);
+void diag_send_log_mask_update(smd_channel_t *);
/* State for diag forwarding */
#ifdef CONFIG_DIAG_OVER_USB
int diagfwd_connect(void);
@@ -35,5 +38,5 @@
#endif
extern int diag_debug_buf_idx;
extern unsigned char diag_debug_buf[1024];
-
+extern int diag_event_num_bytes;
#endif
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 2c3dc54..01ed28d 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -36,6 +36,10 @@
else
pr_debug("diag: incomplete pkt on Modem CNTL ch\n");
break;
+ case SMD_EVENT_OPEN:
+ queue_work(driver->diag_cntl_wq,
+ &(driver->diag_modem_mask_update_work));
+ break;
}
}
@@ -56,6 +60,10 @@
else
pr_debug("diag: incomplete pkt on LPASS CNTL ch\n");
break;
+ case SMD_EVENT_OPEN:
+ queue_work(driver->diag_cntl_wq,
+ &(driver->diag_qdsp_mask_update_work));
+ break;
}
}
@@ -76,6 +84,10 @@
else
pr_debug("diag: incomplete pkt on WCNSS CNTL ch\n");
break;
+ case SMD_EVENT_OPEN:
+ queue_work(driver->diag_cntl_wq,
+ &(driver->diag_wcnss_mask_update_work));
+ break;
}
}
@@ -259,6 +271,7 @@
void diagfwd_cntl_init(void)
{
driver->polling_reg_flag = 0;
+ driver->diag_cntl_wq = create_singlethread_workqueue("diag_cntl_wq");
if (driver->buf_in_cntl == NULL) {
driver->buf_in_cntl = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
if (driver->buf_in_cntl == NULL)
@@ -283,6 +296,8 @@
kfree(driver->buf_in_cntl);
kfree(driver->buf_in_qdsp_cntl);
kfree(driver->buf_in_wcnss_cntl);
+ if (driver->diag_cntl_wq)
+ destroy_workqueue(driver->diag_cntl_wq);
}
void diagfwd_cntl_exit(void)
@@ -293,6 +308,7 @@
driver->ch_cntl = 0;
driver->chqdsp_cntl = 0;
driver->ch_wcnss_cntl = 0;
+ destroy_workqueue(driver->diag_cntl_wq);
platform_driver_unregister(&msm_smd_ch1_cntl_driver);
platform_driver_unregister(&diag_smd_lite_cntl_driver);
diff --git a/drivers/char/diag/diagfwd_cntl.h b/drivers/char/diag/diagfwd_cntl.h
index a76d36d..ad1fec9 100644
--- a/drivers/char/diag/diagfwd_cntl.h
+++ b/drivers/char/diag/diagfwd_cntl.h
@@ -21,10 +21,6 @@
#define DIAG_CTRL_MSG_DIAGMODE 3
/* Diag data based on "light" diag mask */
#define DIAG_CTRL_MSG_DIAGDATA 4
-/* Deprecated */
-#define DIAG_CTRL_MSG_LOG_MASK 5
-#define DIAG_CTRL_MSG_EVENT_MASK 6
-#define DIAG_CTRL_MSG_F3_MASK 7
/* Send diag internal feature mask 'diag_int_feature_mask' */
#define DIAG_CTRL_MSG_FEATURE 8
/* Send Diag log mask for a particular equip id */
@@ -48,6 +44,39 @@
uint16_t port;
};
+struct diag_ctrl_event_mask {
+ uint32_t cmd_type;
+ uint32_t data_len;
+ uint8_t stream_id;
+ uint8_t status;
+ uint8_t event_config;
+ uint32_t event_mask_size;
+ /* Copy event mask here */
+} __packed;
+
+struct diag_ctrl_log_mask {
+ uint32_t cmd_type;
+ uint32_t data_len;
+ uint8_t stream_id;
+ uint8_t status;
+ uint8_t equip_id;
+ uint32_t num_items; /* Last log code for this equip_id */
+ uint32_t log_mask_size; /* Size of log mask stored in log_mask[] */
+ /* Copy log mask here */
+} __packed;
+
+struct diag_ctrl_msg_mask {
+ uint32_t cmd_type;
+ uint32_t data_len;
+ uint8_t stream_id;
+ uint8_t status;
+ uint8_t msg_mode;
+ uint16_t ssid_first; /* Start of range of supported SSIDs */
+ uint16_t ssid_last; /* Last SSID in range */
+ uint32_t msg_mask_size; /* ssid_last - ssid_first + 1 */
+ /* Copy msg mask here */
+} __packed;
+
void diagfwd_cntl_init(void);
void diagfwd_cntl_exit(void);
void diag_read_smd_cntl_work_fn(struct work_struct *);
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index bd48925..3d9c9d1 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -749,7 +749,8 @@
}
static int get_img(struct msmfb_data *fbd, unsigned long *start,
- unsigned long *len, struct file **p_file, struct ion_handle **p_ihdl)
+ unsigned long *len, struct file **p_file, int *p_need,
+ struct ion_handle **p_ihdl)
{
int ret = 0;
#ifdef CONFIG_FB
@@ -760,6 +761,8 @@
unsigned long vstart;
#endif
+ *p_need = 0;
+
#ifdef CONFIG_FB
if (fbd->flags & MDP_MEMORY_ID_TYPE_FB) {
file = fget_light(fbd->memory_id, &put_needed);
@@ -770,8 +773,10 @@
fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
if (get_fb_phys_info(start, len, fb_num))
ret = -1;
- else
+ else {
*p_file = file;
+ *p_need = put_needed;
+ }
} else
ret = -1;
if (ret)
@@ -822,6 +827,7 @@
struct file *srcp1_file = NULL, *dstp1_file = NULL;
struct ion_handle *srcp0_ihdl = NULL, *dstp0_ihdl = NULL;
struct ion_handle *srcp1_ihdl = NULL, *dstp1_ihdl = NULL;
+ int ps0_need, p_need;
unsigned int in_chroma_paddr = 0, out_chroma_paddr = 0;
unsigned int in_chroma2_paddr = 0;
struct msm_rotator_img_info *img_info;
@@ -872,8 +878,9 @@
goto do_rotate_unlock_mutex;
}
+
rc = get_img(&info.src, (unsigned long *)&in_paddr,
- (unsigned long *)&src_len, &srcp0_file, &srcp0_ihdl);
+ (unsigned long *)&src_len, &srcp0_file, &ps0_need, &srcp0_ihdl);
if (rc) {
pr_err("%s: in get_img() failed id=0x%08x\n",
DRIVER_NAME, info.src.memory_id);
@@ -881,7 +888,7 @@
}
rc = get_img(&info.dst, (unsigned long *)&out_paddr,
- (unsigned long *)&dst_len, &dstp0_file, &dstp0_ihdl);
+ (unsigned long *)&dst_len, &dstp0_file, &p_need, &dstp0_ihdl);
if (rc) {
pr_err("%s: out get_img() failed id=0x%08x\n",
DRIVER_NAME, info.dst.memory_id);
@@ -911,7 +918,7 @@
rc = get_img(&info.src_chroma,
(unsigned long *)&in_chroma_paddr,
- (unsigned long *)&src_len, &srcp1_file,
+ (unsigned long *)&src_len, &srcp1_file, &p_need,
&srcp1_ihdl);
if (rc) {
pr_err("%s: in chroma get_img() failed id=0x%08x\n",
@@ -921,7 +928,7 @@
rc = get_img(&info.dst_chroma,
(unsigned long *)&out_chroma_paddr,
- (unsigned long *)&dst_len, &dstp1_file,
+ (unsigned long *)&dst_len, &dstp1_file, &p_need,
&dstp1_ihdl);
if (rc) {
pr_err("%s: out chroma get_img() failed id=0x%08x\n",
@@ -1089,7 +1096,12 @@
put_img(dstp1_file, dstp1_ihdl);
put_img(srcp1_file, srcp1_ihdl);
put_img(dstp0_file, dstp0_ihdl);
- put_img(srcp0_file, srcp0_ihdl);
+
+ /* only source may use frame buffer */
+ if (info.src.flags & MDP_MEMORY_ID_TYPE_FB)
+ fput_light(srcp0_file, ps0_need);
+ else
+ put_img(srcp0_file, srcp0_ihdl);
mutex_unlock(&msm_rotator_dev->rotator_lock);
dev_dbg(msm_rotator_dev->device, "%s() returning rc = %d\n",
__func__, rc);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index ff15497..36375c05 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -273,8 +273,10 @@
trace_cpu_frequency(freqs->new, freqs->cpu);
srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
CPUFREQ_POSTCHANGE, freqs);
- if (likely(policy) && likely(policy->cpu == freqs->cpu))
+ if (likely(policy) && likely(policy->cpu == freqs->cpu)) {
policy->cur = freqs->new;
+ sysfs_notify(&policy->kobj, NULL, "scaling_cur_freq");
+ }
break;
}
}
diff --git a/drivers/crypto/msm/qce40.c b/drivers/crypto/msm/qce40.c
index 5276bcc..0d3c4c3 100644
--- a/drivers/crypto/msm/qce40.c
+++ b/drivers/crypto/msm/qce40.c
@@ -155,10 +155,14 @@
ret = readl_relaxed(pce_dev->iobase + CRYPTO_CONFIG_REG);
if (ret) {
- val = (CRYPTO_REQ_SIZE_ENUM_64_BYTES <<
- CRYPTO_REQ_SIZE) |
- (CRYPTO_FIFO_ENUM_64_BYTES <<
- CRYPTO_FIFO_THRESHOLD);
+ val = BIT(CRYPTO_MASK_DOUT_INTR) |
+ BIT(CRYPTO_MASK_DIN_INTR) |
+ BIT(CRYPTO_MASK_OP_DONE_INTR) |
+ BIT(CRYPTO_MASK_ERR_INTR) |
+ (CRYPTO_REQ_SIZE_ENUM_64_BYTES <<
+ CRYPTO_REQ_SIZE) |
+ (CRYPTO_FIFO_ENUM_64_BYTES <<
+ CRYPTO_FIFO_THRESHOLD);
writel_relaxed(val, pce_dev->iobase +
CRYPTO_CONFIG_REG);
@@ -183,24 +187,6 @@
return 0;
};
-static void config_ce_engine(struct qce_device *pce_dev)
-{
- unsigned int val = 0;
- unsigned int ret = 0;
-
- /* Crypto config register returns a 0 when it is XPU protected. */
- ret = readl_relaxed(pce_dev->iobase + CRYPTO_CONFIG_REG);
-
- /* Configure the crypto register if it is not XPU protected. */
- if (ret) {
- val = BIT(CRYPTO_MASK_DOUT_INTR) |
- BIT(CRYPTO_MASK_DIN_INTR) |
- BIT(CRYPTO_MASK_OP_DONE_INTR) |
- BIT(CRYPTO_MASK_ERR_INTR);
-
- writel_relaxed(val, pce_dev->iobase + CRYPTO_CONFIG_REG);
- }
-}
static void _check_probe_done_call_back(struct msm_dmov_cmd *cmd_ptr,
unsigned int result, struct msm_dmov_errdata *err)
@@ -234,9 +220,6 @@
*/
mb();
- /* Configure the CE Engine */
- config_ce_engine(pce_dev);
-
/*
* Clear ACCESS_VIOL bit in CRYPTO_STATUS REGISTER
*/
@@ -2622,4 +2605,4 @@
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
MODULE_DESCRIPTION("Crypto Engine driver");
-MODULE_VERSION("2.15");
+MODULE_VERSION("2.16");
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index c1a65fc..fff494c 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1,6 +1,6 @@
/* Qualcomm CE device driver.
*
- * 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
@@ -172,7 +172,7 @@
#endif
}
-static int qcedev_ce_high_bw_req(struct qcedev_control *podev,
+static void qcedev_ce_high_bw_req(struct qcedev_control *podev,
bool high_bw_req)
{
int ret = 0;
@@ -180,18 +180,22 @@
mutex_lock(&sent_bw_req);
if (high_bw_req) {
if (podev->high_bw_req_count == 0)
- msm_bus_scale_client_update_request(
+ ret = msm_bus_scale_client_update_request(
podev->bus_scale_handle, 1);
+ if (ret)
+ pr_err("%s Unable to set to high bandwidth\n",
+ __func__);
podev->high_bw_req_count++;
} else {
if (podev->high_bw_req_count == 1)
- msm_bus_scale_client_update_request(
+ ret = msm_bus_scale_client_update_request(
podev->bus_scale_handle, 0);
+ if (ret)
+ pr_err("%s Unable to set to low bandwidth\n",
+ __func__);
podev->high_bw_req_count--;
}
mutex_unlock(&sent_bw_req);
-
- return ret;
}
@@ -331,7 +335,7 @@
handle->cntl = podev;
file->private_data = handle;
if (podev->platform_support.bus_scale_table != NULL)
- return qcedev_ce_high_bw_req(podev, true);
+ qcedev_ce_high_bw_req(podev, true);
return 0;
}
@@ -349,7 +353,7 @@
kzfree(handle);
file->private_data = NULL;
if (podev->platform_support.bus_scale_table != NULL)
- return qcedev_ce_high_bw_req(podev, false);
+ qcedev_ce_high_bw_req(podev, false);
return 0;
}
@@ -2218,7 +2222,7 @@
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
MODULE_DESCRIPTION("Qualcomm DEV Crypto driver");
-MODULE_VERSION("1.25");
+MODULE_VERSION("1.26");
module_init(qcedev_init);
module_exit(qcedev_exit);
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 3fff05c..21c3aff 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -1,6 +1,6 @@
/* Qualcomm Crypto driver
*
- * 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
@@ -329,7 +329,7 @@
}
}
-static int qcrypto_ce_high_bw_req(struct crypto_priv *cp, bool high_bw_req)
+static void qcrypto_ce_high_bw_req(struct crypto_priv *cp, bool high_bw_req)
{
int ret = 0;
@@ -338,16 +338,20 @@
if (cp->high_bw_req_count == 0)
ret = msm_bus_scale_client_update_request(
cp->bus_scale_handle, 1);
+ if (ret)
+ pr_err("%s Unable to set to high bandwidth\n",
+ __func__);
cp->high_bw_req_count++;
} else {
if (cp->high_bw_req_count == 1)
ret = msm_bus_scale_client_update_request(
cp->bus_scale_handle, 0);
+ if (ret)
+ pr_err("%s Unable to set to low bandwidth\n",
+ __func__);
cp->high_bw_req_count--;
}
mutex_unlock(&sent_bw_req);
-
- return ret;
}
static void _start_qcrypto_process(struct crypto_priv *cp);
@@ -403,7 +407,7 @@
/* random first IV */
get_random_bytes(ctx->iv, QCRYPTO_MAX_IV_LENGTH);
if (ctx->cp->platform_support.bus_scale_table != NULL)
- return qcrypto_ce_high_bw_req(ctx->cp, true);
+ qcrypto_ce_high_bw_req(ctx->cp, true);
return 0;
};
@@ -440,7 +444,7 @@
sha_ctx->ahash_req = NULL;
if (sha_ctx->cp->platform_support.bus_scale_table != NULL)
- return qcrypto_ce_high_bw_req(sha_ctx->cp, true);
+ qcrypto_ce_high_bw_req(sha_ctx->cp, true);
return 0;
};
@@ -3359,4 +3363,4 @@
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
MODULE_DESCRIPTION("Qualcomm Crypto driver");
-MODULE_VERSION("1.20");
+MODULE_VERSION("1.21");
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index e33155f..0cadc33 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -993,8 +993,7 @@
if (!kgsl_mmu_pt_equal(priv->pagetable, pt_base))
continue;
spin_lock(&priv->mem_lock);
- entry = kgsl_sharedmem_find_region(priv, gpuaddr,
- sizeof(unsigned int));
+ entry = kgsl_sharedmem_find_region(priv, gpuaddr, size);
if (entry) {
result = &entry->memdesc;
spin_unlock(&priv->mem_lock);
@@ -1274,7 +1273,7 @@
default:
KGSL_DRV_INFO(dev_priv->device,
"invalid ioctl code %08x\n", cmd);
- result = -EINVAL;
+ result = -ENOIOCTLCMD;
break;
}
return result;
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index b53ca8f..68299cf 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,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
@@ -23,7 +23,8 @@
#include "a2xx_reg.h"
unsigned int kgsl_cff_dump_enable;
-int kgsl_pm_regs_enabled;
+int adreno_pm_regs_enabled;
+int adreno_pm_ib_enabled;
static struct dentry *pm_d_debugfs;
@@ -46,20 +47,37 @@
static int pm_regs_enabled_set(void *data, u64 val)
{
- kgsl_pm_regs_enabled = val ? 1 : 0;
+ adreno_pm_regs_enabled = val ? 1 : 0;
return 0;
}
static int pm_regs_enabled_get(void *data, u64 *val)
{
- *val = kgsl_pm_regs_enabled;
+ *val = adreno_pm_regs_enabled;
return 0;
}
+static int pm_ib_enabled_set(void *data, u64 val)
+{
+ adreno_pm_ib_enabled = val ? 1 : 0;
+ return 0;
+}
+
+static int pm_ib_enabled_get(void *data, u64 *val)
+{
+ *val = adreno_pm_ib_enabled;
+ return 0;
+}
+
+
DEFINE_SIMPLE_ATTRIBUTE(pm_regs_enabled_fops,
pm_regs_enabled_get,
pm_regs_enabled_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(pm_ib_enabled_fops,
+ pm_ib_enabled_get,
+ pm_ib_enabled_set, "%llu\n");
+
static int kgsl_cff_dump_enable_set(void *data, u64 val)
{
@@ -358,4 +376,6 @@
&pm_dump_fops);
debugfs_create_file("regs_enabled", 0644, pm_d_debugfs, device,
&pm_regs_enabled_fops);
+ debugfs_create_file("ib_enabled", 0644, pm_d_debugfs, device,
+ &pm_ib_enabled_fops);
}
diff --git a/drivers/gpu/msm/adreno_debugfs.h b/drivers/gpu/msm/adreno_debugfs.h
index 0356ac6..5f8d89a 100644
--- a/drivers/gpu/msm/adreno_debugfs.h
+++ b/drivers/gpu/msm/adreno_debugfs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,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
@@ -17,11 +17,17 @@
int adreno_debugfs_init(struct kgsl_device *device);
-extern int kgsl_pm_regs_enabled;
+extern int adreno_pm_regs_enabled;
+extern int adreno_pm_ib_enabled;
-static inline int kgsl_pmregs_enabled(void)
+static inline int is_adreno_pm_regs_enabled(void)
{
- return kgsl_pm_regs_enabled;
+ return adreno_pm_regs_enabled;
+}
+
+static inline int is_adreno_pm_ib_enabled(void)
+{
+ return adreno_pm_ib_enabled;
}
#else
diff --git a/drivers/gpu/msm/adreno_pm4types.h b/drivers/gpu/msm/adreno_pm4types.h
index f99462e..75512d0 100644
--- a/drivers/gpu/msm/adreno_pm4types.h
+++ b/drivers/gpu/msm/adreno_pm4types.h
@@ -209,4 +209,14 @@
/* gmem command buffer length */
#define CP_REG(reg) ((0x4 << 16) | (SUBBLOCK_OFFSET(reg)))
+
+/* Return 1 if the command is an indirect buffer of any kind */
+static inline int adreno_cmd_is_ib(unsigned int cmd)
+{
+ return (cmd == cp_type3_packet(CP_INDIRECT_BUFFER_PFE, 2) ||
+ cmd == cp_type3_packet(CP_INDIRECT_BUFFER_PFD, 2) ||
+ cmd == cp_type3_packet(CP_COND_INDIRECT_BUFFER_PFE, 2) ||
+ cmd == cp_type3_packet(CP_COND_INDIRECT_BUFFER_PFD, 2));
+}
+
#endif /* __ADRENO_PM4TYPES_H */
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 7902f30..e4bc470 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -201,7 +201,7 @@
for (i = 0; i+3 < ib1_size; ) {
value = ib1_addr[i++];
- if (value == cp_type3_packet(CP_INDIRECT_BUFFER_PFD, 2)) {
+ if (adreno_cmd_is_ib(value)) {
uint32_t ib2_base = ib1_addr[i++];
uint32_t ib2_size = ib1_addr[i++];
@@ -294,15 +294,6 @@
}
}
-static bool adreno_ib_dump_enabled(void)
-{
-#ifdef CONFIG_MSM_KGSL_PSTMRTMDMP_NO_IB_DUMP
- return 0;
-#else
- return 1;
-#endif
-}
-
struct log_field {
bool show;
const char *display;
@@ -778,7 +769,7 @@
i = 0;
for (read_idx = 0; read_idx < num_item; ) {
uint32_t this_cmd = rb_copy[read_idx++];
- if (this_cmd == cp_type3_packet(CP_INDIRECT_BUFFER_PFD, 2)) {
+ if (adreno_cmd_is_ib(this_cmd)) {
uint32_t ib_addr = rb_copy[read_idx++];
uint32_t ib_size = rb_copy[read_idx++];
dump_ib1(device, cur_pt_base, (read_idx-3)<<2, ib_addr,
@@ -817,12 +808,11 @@
cp_rb_base, cp_rb_rptr, cp_rb_wptr, read_idx);
adreno_dump_rb(device, rb_copy, num_item<<2, read_idx, rb_count);
- if (adreno_ib_dump_enabled()) {
+ if (is_adreno_pm_ib_enabled()) {
for (read_idx = NUM_DWORDS_OF_RINGBUFFER_HISTORY;
read_idx >= 0; --read_idx) {
uint32_t this_cmd = rb_copy[read_idx];
- if (this_cmd == cp_type3_packet(
- CP_INDIRECT_BUFFER_PFD, 2)) {
+ if (adreno_cmd_is_ib(this_cmd)) {
uint32_t ib_addr = rb_copy[read_idx+1];
uint32_t ib_size = rb_copy[read_idx+2];
if (ib_size && cp_ib1_base == ib_addr) {
@@ -849,16 +839,17 @@
}
/* Dump the registers if the user asked for it */
-
- if (adreno_is_a20x(adreno_dev))
- adreno_dump_regs(device, a200_registers,
- a200_registers_count);
- else if (adreno_is_a22x(adreno_dev))
- adreno_dump_regs(device, a220_registers,
- a220_registers_count);
- else if (adreno_is_a3xx(adreno_dev))
- adreno_dump_regs(device, a3xx_registers,
- a3xx_registers_count);
+ if (is_adreno_pm_regs_enabled()) {
+ if (adreno_is_a20x(adreno_dev))
+ adreno_dump_regs(device, a200_registers,
+ a200_registers_count);
+ else if (adreno_is_a22x(adreno_dev))
+ adreno_dump_regs(device, a220_registers,
+ a220_registers_count);
+ else if (adreno_is_a3xx(adreno_dev))
+ adreno_dump_regs(device, a3xx_registers,
+ a3xx_registers_count);
+ }
error_vfree:
vfree(rb_copy);
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index a4899a2..9836043 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -104,15 +104,6 @@
return 0;
}
-/* Return 1 if the packet starting at ptr is an indirect buffer of any kind */
-static inline int packet_is_buffer(unsigned int *ptr)
-{
- return (*ptr == cp_type3_packet(CP_INDIRECT_BUFFER_PFE, 2) ||
- *ptr == cp_type3_packet(CP_INDIRECT_BUFFER_PFD, 2) ||
- *ptr == cp_type3_packet(CP_COND_INDIRECT_BUFFER_PFE, 2) ||
- *ptr == cp_type3_packet(CP_COND_INDIRECT_BUFFER_PFD, 2));
-}
-
/* Snapshot the istore memory */
static int snapshot_istore(struct kgsl_device *device, void *snapshot,
int remain, void *priv)
@@ -258,7 +249,7 @@
if (index == rptr)
parse_ibs = 0;
- if (parse_ibs && packet_is_buffer(&rbptr[index]))
+ if (parse_ibs && adreno_cmd_is_ib(rbptr[index]))
push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
rbptr[index + 1], rbptr[index + 2]);
@@ -312,7 +303,7 @@
*dst = *src;
/* If another IB is discovered, then push it on the list too */
- if (packet_is_buffer(src))
+ if (adreno_cmd_is_ib(*src))
push_object(device, SNAPSHOT_OBJ_TYPE_IB, obj->ptbase,
*(src + 1), *(src + 2));
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 45007da..b7356ac 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1024,6 +1024,7 @@
spin_lock(&entry->priv->mem_lock);
list_del(&entry->list);
spin_unlock(&entry->priv->mem_lock);
+ trace_kgsl_mem_timestamp_free(entry, timestamp);
kgsl_mem_entry_put(entry);
}
@@ -1034,12 +1035,18 @@
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;
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);
if (entry) {
+ cur = device->ftbl->readtimestamp(device,
+ KGSL_TIMESTAMP_RETIRED);
+
+ trace_kgsl_mem_timestamp_queue(entry, cur);
result = kgsl_add_event(dev_priv->device, param->timestamp,
kgsl_freemem_event_cb, entry, dev_priv);
} else {
@@ -1118,6 +1125,7 @@
spin_unlock(&private->mem_lock);
if (entry) {
+ trace_kgsl_mem_free(entry);
kgsl_mem_entry_put(entry);
} else {
KGSL_CORE_ERR("invalid gpuaddr %08x\n", param->gpuaddr);
@@ -1218,6 +1226,7 @@
kgsl_mem_entry_attach_process(entry, private);
+ trace_kgsl_mem_alloc(entry);
/* Process specific statistics */
kgsl_process_add_stats(private, entry->memtype, len);
@@ -1652,6 +1661,7 @@
kgsl_process_add_stats(private, entry->memtype, param->len);
kgsl_mem_entry_attach_process(entry, private);
+ trace_kgsl_mem_map(entry, param->fd);
kgsl_check_idle(dev_priv->device);
return result;
@@ -1718,6 +1728,7 @@
param->gpuaddr = entry->memdesc.gpuaddr;
kgsl_process_add_stats(private, entry->memtype, param->size);
+ trace_kgsl_mem_alloc(entry);
} else
kfree(entry);
@@ -1964,7 +1975,7 @@
if (!func) {
KGSL_DRV_INFO(dev_priv->device,
"invalid ioctl code %08x\n", cmd);
- ret = -EINVAL;
+ ret = -ENOIOCTLCMD;
goto done;
}
lock = 1;
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 389ed6d..7264c25 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -150,7 +150,7 @@
#endif
MEM_ENTRY_STAT(KGSL_MEM_ENTRY_USER, user),
#ifdef CONFIG_ION
- MEM_ENTRY_STAT(KGSL_MEM_ENTRY_USER, ion),
+ MEM_ENTRY_STAT(KGSL_MEM_ENTRY_ION, ion),
#endif
};
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index de39ee4..93fdc08 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -10,7 +10,6 @@
* GNU General Public License for more details.
*/
-#include <linux/vmalloc.h>
#include <linux/time.h>
#include <linux/sysfs.h>
#include <linux/utsname.h>
@@ -299,6 +298,10 @@
/* Freeze the snapshot on a hang until it gets read */
device->snapshot_frozen = (hang) ? 1 : 0;
+ /* log buffer info to aid in ramdump recovery */
+ KGSL_DRV_ERR(device, "snapshot created at va %p pa %lx size %d\n",
+ device->snapshot, __pa(device->snapshot),
+ device->snapshot_size);
return 0;
}
EXPORT_SYMBOL(kgsl_device_snapshot);
@@ -448,7 +451,7 @@
int ret;
if (device->snapshot == NULL)
- device->snapshot = vmalloc(KGSL_SNAPSHOT_MEMSIZE);
+ device->snapshot = kzalloc(KGSL_SNAPSHOT_MEMSIZE, GFP_KERNEL);
if (device->snapshot == NULL)
return -ENOMEM;
@@ -491,7 +494,7 @@
kobject_put(&device->snapshot_kobj);
- vfree(device->snapshot);
+ kfree(device->snapshot);
device->snapshot = NULL;
device->snapshot_maxsize = 0;
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index 86a9adc..22bc576 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.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
@@ -257,6 +257,122 @@
TP_ARGS(device, state)
);
+TRACE_EVENT(kgsl_mem_alloc,
+
+ TP_PROTO(struct kgsl_mem_entry *mem_entry),
+
+ TP_ARGS(mem_entry),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, gpuaddr)
+ __field(unsigned int, size)
+ ),
+
+ TP_fast_assign(
+ __entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+ __entry->size = mem_entry->memdesc.size;
+ ),
+
+ TP_printk(
+ "gpuaddr=0x%08x size=%d",
+ __entry->gpuaddr, __entry->size
+ )
+);
+
+TRACE_EVENT(kgsl_mem_map,
+
+ TP_PROTO(struct kgsl_mem_entry *mem_entry, int fd),
+
+ TP_ARGS(mem_entry, fd),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, gpuaddr)
+ __field(unsigned int, size)
+ __field(int, fd)
+ __field(int, type)
+ ),
+
+ TP_fast_assign(
+ __entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+ __entry->size = mem_entry->memdesc.size;
+ __entry->fd = fd;
+ __entry->type = mem_entry->memtype;
+ ),
+
+ TP_printk(
+ "gpuaddr=0x%08x size=%d type=%d fd=%d",
+ __entry->gpuaddr, __entry->size,
+ __entry->type, __entry->fd
+ )
+);
+
+TRACE_EVENT(kgsl_mem_free,
+
+ TP_PROTO(struct kgsl_mem_entry *mem_entry),
+
+ TP_ARGS(mem_entry),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, gpuaddr)
+ __field(unsigned int, size)
+ __field(int, type)
+ __field(int, fd)
+ ),
+
+ TP_fast_assign(
+ __entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+ __entry->size = mem_entry->memdesc.size;
+ __entry->type = mem_entry->memtype;
+ ),
+
+ TP_printk(
+ "gpuaddr=0x%08x size=%d type=%d",
+ __entry->gpuaddr, __entry->size, __entry->type
+ )
+);
+
+DECLARE_EVENT_CLASS(kgsl_mem_timestamp_template,
+
+ TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int curr_ts),
+
+ TP_ARGS(mem_entry, curr_ts),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, gpuaddr)
+ __field(unsigned int, size)
+ __field(int, type)
+ __field(unsigned int, drawctxt_id)
+ __field(unsigned int, curr_ts)
+ __field(unsigned int, free_ts)
+ ),
+
+ TP_fast_assign(
+ __entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+ __entry->size = mem_entry->memdesc.size;
+ __entry->drawctxt_id = 1337;
+ __entry->type = mem_entry->memtype;
+ __entry->curr_ts = curr_ts;
+ __entry->free_ts = mem_entry->free_timestamp;
+ ),
+
+ TP_printk(
+ "gpuaddr=0x%08x size=%d type=%d ctx=%u curr_ts=0x%08x free_ts=0x%08x",
+ __entry->gpuaddr, __entry->size, __entry->type,
+ __entry->drawctxt_id, __entry->curr_ts, __entry->free_ts
+ )
+);
+
+DEFINE_EVENT(kgsl_mem_timestamp_template, kgsl_mem_timestamp_queue,
+ 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 curr_ts),
+ TP_ARGS(mem_entry, curr_ts)
+);
+
+
#endif /* _KGSL_TRACE_H */
/* This part must be outside protection */
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index cb3da90..6c43a75 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -339,13 +339,15 @@
*p++ = ADDR_VGV3_LAST << 24;
}
-static void z180_cmdstream_start(struct kgsl_device *device)
+static void z180_cmdstream_start(struct kgsl_device *device, int init_ram)
{
struct z180_device *z180_dev = Z180_DEVICE(device);
unsigned int cmd = VGV3_NEXTCMD_JUMP << VGV3_NEXTCMD_NEXTCMD_FSHIFT;
- z180_dev->timestamp = 0;
- z180_dev->current_timestamp = 0;
+ if (init_ram) {
+ z180_dev->timestamp = 0;
+ z180_dev->current_timestamp = 0;
+ }
addmarker(&z180_dev->ringbuffer, 0);
@@ -566,7 +568,7 @@
if (status)
goto error_clk_off;
- z180_cmdstream_start(device);
+ z180_cmdstream_start(device, init_ram);
mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index f18c2d0..f5bfc7b 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -514,6 +514,31 @@
}
}
+static int mxt_get_bootloader_id(struct i2c_client *client)
+{
+ u8 val;
+ u8 buf[3];
+
+ if (i2c_master_recv(client, &val, 1) != 1) {
+ dev_err(&client->dev, "%s: i2c recv failed\n", __func__);
+ return -EIO;
+ }
+
+ if (val | MXT_BOOT_EXTENDED_ID) {
+ if (i2c_master_recv(client, &buf[0], 3) != 3) {
+ dev_err(&client->dev, "%s: i2c recv failed\n",
+ __func__);
+ return -EIO;
+ }
+ return buf[1];
+ } else {
+ dev_info(&client->dev, "Bootloader ID:%d",
+ val & MXT_BOOT_ID_MASK);
+
+ return val & MXT_BOOT_ID_MASK;
+ }
+}
+
static int mxt_check_bootloader(struct i2c_client *client,
unsigned int state)
{
@@ -1449,24 +1474,69 @@
return ret;
}
+static const char *
+mxt_search_fw_name(struct mxt_data *data, u8 bootldr_id)
+{
+ const struct mxt_platform_data *pdata = data->pdata;
+ const struct mxt_config_info *cfg_info;
+ const char *fw_name = NULL;
+ int i;
+
+ for (i = 0; i < pdata->config_array_size; i++) {
+ cfg_info = &pdata->config_array[i];
+ if (bootldr_id == cfg_info->bootldr_id && cfg_info->fw_name) {
+ data->config_info = cfg_info;
+ data->info.family_id = cfg_info->family_id;
+ fw_name = cfg_info->fw_name;
+ }
+ }
+
+ return fw_name;
+}
+
static ssize_t mxt_update_fw_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct mxt_data *data = dev_get_drvdata(dev);
int error;
+ const char *fw_name;
+ u8 bootldr_id;
/* If fw_name is set, then the existing firmware has an upgrade */
if (!data->fw_name) {
- dev_err(dev, "Firmware name not specifed in platform data\n");
- return -EINVAL;
+ /*
+ * If the device boots up in the bootloader mode, check if
+ * there is a firmware to upgrade.
+ */
+ if (data->state == BOOTLOADER) {
+ bootldr_id = mxt_get_bootloader_id(data->client);
+ if (bootldr_id <= 0) {
+ dev_err(dev,
+ "Unable to retrieve bootloader id\n");
+ return -EINVAL;
+ }
+ fw_name = mxt_search_fw_name(data, bootldr_id);
+ if (fw_name == NULL) {
+ dev_err(dev,
+ "Unable to find fw from bootloader id\n");
+ return -EINVAL;
+ }
+ } else {
+ /* In APPMODE, if the f/w name does not exist, quit */
+ dev_err(dev,
+ "Firmware name not specified in platform data\n");
+ return -EINVAL;
+ }
+ } else {
+ fw_name = data->fw_name;
}
- dev_info(dev, "Upgrading the firmware file to %s\n", data->fw_name);
+ dev_info(dev, "Upgrading the firmware file to %s\n", fw_name);
disable_irq(data->irq);
- error = mxt_load_fw(dev, data->fw_name);
+ error = mxt_load_fw(dev, fw_name);
if (error) {
dev_err(dev, "The firmware update failed(%d)\n", error);
count = error;
@@ -1559,10 +1629,12 @@
struct mxt_data *data = input_get_drvdata(dev);
int error;
- error = mxt_start(data);
- if (error < 0) {
- dev_err(&data->client->dev, "mxt_start failed in input_open\n");
- return error;
+ if (data->state == APPMODE) {
+ error = mxt_start(data);
+ if (error < 0) {
+ dev_err(&data->client->dev, "mxt_start failed in input_open\n");
+ return error;
+ }
}
return 0;
@@ -1573,10 +1645,11 @@
struct mxt_data *data = input_get_drvdata(dev);
int error;
- error = mxt_stop(data);
- if (error < 0)
- dev_err(&data->client->dev, "mxt_stop failed in input_close\n");
-
+ if (data->state == APPMODE) {
+ error = mxt_stop(data);
+ if (error < 0)
+ dev_err(&data->client->dev, "mxt_stop failed in input_close\n");
+ }
}
static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA)
diff --git a/drivers/media/video/msm/wfd/enc-subdev.c b/drivers/media/video/msm/wfd/enc-subdev.c
index 6c52e21..31b8239 100644
--- a/drivers/media/video/msm/wfd/enc-subdev.c
+++ b/drivers/media/video/msm/wfd/enc-subdev.c
@@ -334,16 +334,26 @@
struct vcd_buffer_requirement buf_req;
struct venc_inst *inst = sd->dev_priv;
struct video_client_ctx *client_ctx = &inst->venc_client;
+ int aligned_width, aligned_height;
if (!client_ctx) {
WFD_MSG_ERR("Invalid client context");
rc = -EINVAL;
goto err;
}
+ aligned_width = ALIGN(b->width, 16);
+ aligned_height = ALIGN(b->height, 16);
+
+ if (aligned_width != b->width) {
+ WFD_MSG_ERR("Width not 16 byte aligned\n");
+ rc = -EINVAL;
+ goto err;
+ }
+
buf_req.actual_count = b->count;
buf_req.min_count = b->count;
buf_req.max_count = b->count;
- buf_req.sz = (((b->height * b->width) + 2047) & (~2047))
- + (((b->height * b->width * 1/2) + 2047) & (~2047));
+ buf_req.sz = ALIGN(aligned_height * aligned_width, SZ_2K)
+ + ALIGN(aligned_height * aligned_width * 1/2, SZ_2K);
buf_req.align = 0;
inst->width = b->width;
inst->height = b->height;
diff --git a/drivers/media/video/msm/wfd/wfd-ioctl.c b/drivers/media/video/msm/wfd/wfd-ioctl.c
index ce81746..e38bb80 100644
--- a/drivers/media/video/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm/wfd/wfd-ioctl.c
@@ -561,6 +561,11 @@
"V4L2_PIX_FMT_H264 are supported\n");
return -EINVAL;
}
+
+ if (fmt->fmt.pix.width % 16) {
+ WFD_MSG_ERR("Only 16 byte aligned widths are supported\n");
+ return -ENOTSUPP;
+ }
rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl, SET_FORMAT,
(void *)fmt);
if (rc) {
diff --git a/drivers/mfd/pm8xxx-irq.c b/drivers/mfd/pm8xxx-irq.c
index 17b518e..ac39e80 100644
--- a/drivers/mfd/pm8xxx-irq.c
+++ b/drivers/mfd/pm8xxx-irq.c
@@ -449,7 +449,7 @@
return chip;
}
-int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip)
+int pm8xxx_irq_exit(struct pm_irq_chip *chip)
{
irq_set_chained_handler(chip->devirq, NULL);
kfree(chip);
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index e4c3152..a8f9f35 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -199,7 +199,7 @@
};
static int __qseecom_is_svc_unique(struct qseecom_dev_handle *data,
- struct qseecom_register_listener_req svc)
+ struct qseecom_register_listener_req *svc)
{
struct qseecom_registered_listener_list *ptr;
int unique = 1;
@@ -207,7 +207,7 @@
spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags);
list_for_each_entry(ptr, &qseecom.registered_listener_list_head, list) {
- if (ptr->svc.listener_id == svc.listener_id) {
+ if (ptr->svc.listener_id == svc->listener_id) {
pr_err("Service id: %u is already registered\n",
ptr->svc.listener_id);
unique = 0;
@@ -333,16 +333,12 @@
pr_err("copy_from_user failed\n");
return ret;
}
-
- if (!__qseecom_is_svc_unique(data, rcvd_lstnr)) {
+ data->listener.id = 0;
+ data->service = true;
+ if (!__qseecom_is_svc_unique(data, &rcvd_lstnr)) {
pr_err("Service is not unique and is already registered\n");
- return ret;
- }
-
- ret = copy_to_user(argp, &rcvd_lstnr, sizeof(rcvd_lstnr));
- if (ret) {
- pr_err("copy_to_user failed\n");
- return ret;
+ data->released = true;
+ return -EBUSY;
}
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
@@ -360,13 +356,14 @@
kzfree(new_entry);
return -ENOMEM;
}
+
data->listener.id = rcvd_lstnr.listener_id;
- data->service = true;
init_waitqueue_head(&new_entry->rcv_req_wq);
spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags);
list_add_tail(&new_entry->list, &qseecom.registered_listener_list_head);
spin_unlock_irqrestore(&qseecom.registered_listener_list_lock, flags);
+
return ret;
}
@@ -743,6 +740,7 @@
break;
} else {
ptr_app->ref_cnt--;
+ data->released = true;
break;
}
}
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 03be6d0..122ffb5 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -299,10 +299,11 @@
mmc_card_ddr_mode(card) ? "DDR " : "",
type);
} else {
- printk(KERN_INFO "%s: new %s%s%s card at address %04x\n",
+ pr_info("%s: new %s%s%s%s card at address %04x\n",
mmc_hostname(card->host),
mmc_sd_card_uhs(card) ? "ultra high speed " :
(mmc_card_highspeed(card) ? "high speed " : ""),
+ (mmc_card_hs200(card) ? "HS200 " : ""),
mmc_card_ddr_mode(card) ? "DDR " : "",
type, card->rca);
}
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 998797e..c1b0405 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -113,6 +113,9 @@
case MMC_TIMING_SD_HS:
str = "sd high-speed";
break;
+ case MMC_TIMING_MMC_HS200:
+ str = "mmc high-speed SDR200";
+ break;
default:
str = "invalid";
break;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 0c70d4a..b7b899e 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -283,6 +283,27 @@
}
card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
+ case EXT_CSD_CARD_TYPE_SDR_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200;
+ break;
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V;
+ break;
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V;
+ break;
case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 |
EXT_CSD_CARD_TYPE_26:
card->ext_csd.hs_max_dtr = 52000000;
@@ -645,6 +666,79 @@
}
/*
+ * Selects the desired buswidth and switch to the HS200 mode
+ * if bus width set without error
+ */
+static int mmc_select_hs200(struct mmc_card *card)
+{
+ int idx, err = 0;
+ struct mmc_host *host;
+ static unsigned ext_csd_bits[] = {
+ EXT_CSD_BUS_WIDTH_4,
+ EXT_CSD_BUS_WIDTH_8,
+ };
+ static unsigned bus_widths[] = {
+ MMC_BUS_WIDTH_4,
+ MMC_BUS_WIDTH_8,
+ };
+
+ BUG_ON(!card);
+
+ host = card->host;
+
+ if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_2V &&
+ host->caps2 & MMC_CAP2_HS200_1_2V_SDR)
+ if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0))
+ err = mmc_set_signal_voltage(host,
+ MMC_SIGNAL_VOLTAGE_180, 0);
+
+ /* If fails try again during next card power cycle */
+ if (err)
+ goto err;
+
+ idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 1 : 0;
+
+ /*
+ * Unlike SD, MMC cards dont have a configuration register to notify
+ * supported bus width. So bus test command should be run to identify
+ * the supported bus width or compare the ext csd values of current
+ * bus width and ext csd values of 1 bit mode read earlier.
+ */
+ for (; idx >= 0; idx--) {
+
+ /*
+ * Host is capable of 8bit transfer, then switch
+ * the device to work in 8bit transfer mode. If the
+ * mmc switch command returns error then switch to
+ * 4bit transfer mode. On success set the corresponding
+ * bus width on the host.
+ */
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_BUS_WIDTH,
+ ext_csd_bits[idx],
+ card->ext_csd.generic_cmd6_time);
+ if (err)
+ continue;
+
+ mmc_set_bus_width(card->host, bus_widths[idx]);
+
+ if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
+ err = mmc_compare_ext_csds(card, bus_widths[idx]);
+ else
+ err = mmc_bus_test(card, bus_widths[idx]);
+ if (!err)
+ break;
+ }
+
+ /* switch to HS200 mode if bus width set successfully */
+ if (!err)
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_HS_TIMING, 2, 0);
+err:
+ return err;
+}
+
+/*
* Handle the detection and initialisation of a card.
*
* In the case of a resume, "oldcard" will contain the card
@@ -848,11 +942,16 @@
/*
* Activate high speed (if supported)
*/
- if ((card->ext_csd.hs_max_dtr != 0) &&
- (host->caps & MMC_CAP_MMC_HIGHSPEED)) {
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_HS_TIMING, 1,
- card->ext_csd.generic_cmd6_time);
+ if (card->ext_csd.hs_max_dtr != 0) {
+ err = 0;
+ if (card->ext_csd.hs_max_dtr > 52000000 &&
+ host->caps2 & MMC_CAP2_HS200)
+ err = mmc_select_hs200(card);
+ else if (host->caps & MMC_CAP_MMC_HIGHSPEED)
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_HS_TIMING, 1,
+ card->ext_csd.generic_cmd6_time);
+
if (err && err != -EBADMSG)
goto free_card;
@@ -861,33 +960,24 @@
mmc_hostname(card->host));
err = 0;
} else {
- mmc_card_set_highspeed(card);
- mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+ if (card->ext_csd.hs_max_dtr > 52000000 &&
+ host->caps2 & MMC_CAP2_HS200) {
+ mmc_card_set_hs200(card);
+ mmc_set_timing(card->host,
+ MMC_TIMING_MMC_HS200);
+ } else {
+ mmc_card_set_highspeed(card);
+ mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+ }
}
}
/*
- * Enable HPI feature (if supported)
- */
- if (card->ext_csd.hpi) {
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_HPI_MGMT, 1, 0);
- if (err && err != -EBADMSG)
- goto free_card;
- if (err) {
- pr_warning("%s: Enabling HPI failed\n",
- mmc_hostname(card->host));
- err = 0;
- } else
- card->ext_csd.hpi_en = 1;
- }
-
- /*
* Compute bus speed.
*/
max_dtr = (unsigned int)-1;
- if (mmc_card_highspeed(card)) {
+ if (mmc_card_highspeed(card) || mmc_card_hs200(card)) {
if (max_dtr > card->ext_csd.hs_max_dtr)
max_dtr = card->ext_csd.hs_max_dtr;
} else if (max_dtr > card->csd.max_dtr) {
@@ -913,9 +1003,51 @@
}
/*
+ * Indicate HS200 SDR mode (if supported).
+ */
+ if (mmc_card_hs200(card)) {
+ u32 ext_csd_bits;
+ u32 bus_width = card->host->ios.bus_width;
+
+ /*
+ * For devices supporting HS200 mode, the bus width has
+ * to be set before executing the tuning function. If
+ * set before tuning, then device will respond with CRC
+ * errors for responses on CMD line. So for HS200 the
+ * sequence will be
+ * 1. set bus width 4bit / 8 bit (1 bit not supported)
+ * 2. switch to HS200 mode
+ * 3. set the clock to > 52Mhz <=200MHz and
+ * 4. execute tuning for HS200
+ */
+ if ((host->caps2 & MMC_CAP2_HS200) &&
+ card->host->ops->execute_tuning) {
+ mmc_host_clk_hold(card->host);
+ err = card->host->ops->execute_tuning(card->host,
+ MMC_SEND_TUNING_BLOCK_HS200);
+ mmc_host_clk_release(card->host);
+ }
+ if (err) {
+ pr_warning("%s: tuning execution failed\n",
+ mmc_hostname(card->host));
+ goto err;
+ }
+
+ ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
+ EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
+ err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
+ if (err) {
+ pr_err("%s: power class selection to bus width %d failed\n",
+ mmc_hostname(card->host), 1 << bus_width);
+ goto err;
+ }
+ }
+
+ /*
* Activate wide bus and DDR (if supported).
*/
- if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
+ if (!mmc_card_hs200(card) &&
+ (card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
static unsigned ext_csd_bits[][2] = {
{ EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 },
@@ -1014,6 +1146,23 @@
}
/*
+ * Enable HPI feature (if supported)
+ */
+ if (card->ext_csd.hpi) {
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_HPI_MGMT, 1,
+ card->ext_csd.generic_cmd6_time);
+ if (err && err != -EBADMSG)
+ goto free_card;
+ if (err) {
+ pr_warning("%s: Enabling HPI failed\n",
+ mmc_hostname(card->host));
+ err = 0;
+ } else
+ card->ext_csd.hpi_en = 1;
+ }
+
+ /*
* If cache size is higher than 0, this indicates
* the existence of cache and it can be turned on.
*/
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 6522efb..cd0eb4e 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -651,7 +651,8 @@
/* SPI mode doesn't define CMD19 */
if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) {
mmc_host_clk_hold(card->host);
- err = card->host->ops->execute_tuning(card->host);
+ err = card->host->ops->execute_tuning(card->host,
+ MMC_SEND_TUNING_BLOCK);
mmc_host_clk_release(card->host);
}
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 8ac2e59..1d6cf1d 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -14,6 +14,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 0d2b11d..a1ad63e 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -134,6 +134,7 @@
u32 c);
static inline void msmsdcc_delay(struct msmsdcc_host *host);
static void msmsdcc_dump_sdcc_state(struct msmsdcc_host *host);
+static void msmsdcc_sg_start(struct msmsdcc_host *host);
static inline unsigned short msmsdcc_get_nr_sg(struct msmsdcc_host *host)
{
@@ -1076,21 +1077,15 @@
/* Is data transfer in PIO mode required? */
if (!(datactrl & MCI_DPSM_DMAENABLE)) {
- unsigned int sg_miter_flags = SG_MITER_ATOMIC;
-
if (data->flags & MMC_DATA_READ) {
- sg_miter_flags |= SG_MITER_TO_SG;
pio_irqmask = MCI_RXFIFOHALFFULLMASK;
if (host->curr.xfer_remain < MCI_FIFOSIZE)
pio_irqmask |= MCI_RXDATAAVLBLMASK;
- } else {
- sg_miter_flags |= SG_MITER_FROM_SG;
+ } else
pio_irqmask = MCI_TXFIFOHALFEMPTYMASK |
MCI_TXFIFOEMPTYMASK;
- }
- sg_miter_start(&host->sg_miter, data->sg, data->sg_len,
- sg_miter_flags);
+ msmsdcc_sg_start(host);
}
if (data->flags & MMC_DATA_READ)
@@ -1250,6 +1245,144 @@
return ptr - buffer;
}
+/*
+ * Copy up to a word (4 bytes) between a scatterlist
+ * and a temporary bounce buffer when the word lies across
+ * two pages. The temporary buffer can then be read to/
+ * written from the FIFO once.
+ */
+static void _msmsdcc_sg_consume_word(struct msmsdcc_host *host)
+{
+ struct msmsdcc_pio_data *pio = &host->pio;
+ unsigned int bytes_avail;
+
+ if (host->curr.data->flags & MMC_DATA_READ)
+ memcpy(pio->sg_miter.addr, pio->bounce_buf,
+ pio->bounce_buf_len);
+ else
+ memcpy(pio->bounce_buf, pio->sg_miter.addr,
+ pio->bounce_buf_len);
+
+ while (pio->bounce_buf_len != 4) {
+ if (!sg_miter_next(&pio->sg_miter))
+ break;
+ bytes_avail = min_t(unsigned int, pio->sg_miter.length,
+ 4 - pio->bounce_buf_len);
+ if (host->curr.data->flags & MMC_DATA_READ)
+ memcpy(pio->sg_miter.addr,
+ &pio->bounce_buf[pio->bounce_buf_len],
+ bytes_avail);
+ else
+ memcpy(&pio->bounce_buf[pio->bounce_buf_len],
+ pio->sg_miter.addr, bytes_avail);
+
+ pio->sg_miter.consumed = bytes_avail;
+ pio->bounce_buf_len += bytes_avail;
+ }
+}
+
+/*
+ * Use sg_miter_next to return as many 4-byte aligned
+ * chunks as possible, using a temporary 4 byte buffer
+ * for alignment if necessary
+ */
+static int msmsdcc_sg_next(struct msmsdcc_host *host, char **buf, int *len)
+{
+ struct msmsdcc_pio_data *pio = &host->pio;
+ unsigned int length, rlength;
+ char *buffer;
+
+ if (!sg_miter_next(&pio->sg_miter))
+ return 0;
+
+ buffer = pio->sg_miter.addr;
+ length = pio->sg_miter.length;
+
+ if (length < host->curr.xfer_remain) {
+ rlength = round_down(length, 4);
+ if (rlength) {
+ /*
+ * We have a 4-byte aligned chunk.
+ * The rounding will be reflected by
+ * a call to msmsdcc_sg_consumed
+ */
+ length = rlength;
+ goto sg_next_end;
+ }
+ /*
+ * We have a length less than 4 bytes. Check to
+ * see if more buffer is available, and combine
+ * to make 4 bytes if possible.
+ */
+ pio->bounce_buf_len = length;
+ memset(pio->bounce_buf, 0, 4);
+
+ /*
+ * On a read, get 4 bytes from FIFO, and distribute
+ * (4-bouce_buf_len) bytes into consecutive
+ * sgl buffers when msmsdcc_sg_consumed is called
+ */
+ if (host->curr.data->flags & MMC_DATA_READ) {
+ buffer = pio->bounce_buf;
+ length = 4;
+ goto sg_next_end;
+ } else {
+ _msmsdcc_sg_consume_word(host);
+ buffer = pio->bounce_buf;
+ length = pio->bounce_buf_len;
+ }
+ }
+
+sg_next_end:
+ *buf = buffer;
+ *len = length;
+ return 1;
+}
+
+/*
+ * Update sg_miter.consumed based on how many bytes were
+ * consumed. If the bounce buffer was used to read from FIFO,
+ * redistribute into sgls.
+ */
+static void msmsdcc_sg_consumed(struct msmsdcc_host *host,
+ unsigned int length)
+{
+ struct msmsdcc_pio_data *pio = &host->pio;
+
+ if (host->curr.data->flags & MMC_DATA_READ) {
+ if (length > pio->sg_miter.consumed)
+ /*
+ * consumed 4 bytes, but sgl
+ * describes < 4 bytes
+ */
+ _msmsdcc_sg_consume_word(host);
+ else
+ pio->sg_miter.consumed = length;
+ } else
+ if (length < pio->sg_miter.consumed)
+ pio->sg_miter.consumed = length;
+}
+
+static void msmsdcc_sg_start(struct msmsdcc_host *host)
+{
+ unsigned int sg_miter_flags = SG_MITER_ATOMIC;
+
+ host->pio.bounce_buf_len = 0;
+
+ if (host->curr.data->flags & MMC_DATA_READ)
+ sg_miter_flags |= SG_MITER_TO_SG;
+ else
+ sg_miter_flags |= SG_MITER_FROM_SG;
+
+ sg_miter_start(&host->pio.sg_miter, host->curr.data->sg,
+ host->curr.data->sg_len, sg_miter_flags);
+}
+
+static void msmsdcc_sg_stop(struct msmsdcc_host *host)
+{
+ sg_miter_stop(&host->pio.sg_miter);
+}
+
static irqreturn_t
msmsdcc_pio_irq(int irq, void *dev_id)
{
@@ -1257,6 +1390,8 @@
void __iomem *base = host->base;
uint32_t status;
unsigned long flags;
+ unsigned int remain;
+ char *buffer;
spin_lock(&host->lock);
@@ -1267,45 +1402,43 @@
spin_unlock(&host->lock);
return IRQ_NONE;
}
-
#if IRQ_DEBUG
msmsdcc_print_status(host, "irq1-r", status);
#endif
local_irq_save(flags);
- while (sg_miter_next(&host->sg_miter)) {
-
- unsigned int remain, len;
- char *buffer;
+ do {
+ unsigned int len;
if (!(status & (MCI_TXFIFOHALFEMPTY | MCI_TXFIFOEMPTY
| MCI_RXDATAAVLBL)))
break;
- buffer = host->sg_miter.addr;
- remain = host->sg_miter.length;
+ if (!msmsdcc_sg_next(host, &buffer, &remain))
+ break;
len = 0;
if (status & MCI_RXACTIVE)
len = msmsdcc_pio_read(host, buffer, remain);
if (status & MCI_TXACTIVE)
len = msmsdcc_pio_write(host, buffer, remain);
+
/* len might have aligned to 32bits above */
if (len > remain)
len = remain;
- host->sg_miter.consumed = len;
host->curr.xfer_remain -= len;
host->curr.data_xfered += len;
remain -= len;
+ msmsdcc_sg_consumed(host, len);
if (remain) /* Done with this page? */
break; /* Nope */
status = readl_relaxed(base + MMCISTATUS);
- }
+ } while (1);
- sg_miter_stop(&host->sg_miter);
+ msmsdcc_sg_stop(host);
local_irq_restore(flags);
if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE) {
@@ -2955,7 +3088,7 @@
return ret;
}
-static int msmsdcc_execute_tuning(struct mmc_host *mmc)
+static int msmsdcc_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
int rc = 0;
struct msmsdcc_host *host = mmc_priv(mmc);
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 319d721..8a728f2 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -281,9 +281,10 @@
};
struct msmsdcc_pio_data {
- struct scatterlist *sg;
- unsigned int sg_len;
- unsigned int sg_off;
+ struct sg_mapping_iter sg_miter;
+ char bounce_buf[4];
+ /* valid bytes in bounce_buf */
+ int bounce_buf_len;
};
struct msmsdcc_curr_req {
@@ -361,7 +362,7 @@
struct msmsdcc_sps_data sps;
bool is_dma_mode;
bool is_sps_mode;
- struct sg_mapping_iter sg_miter;
+ struct msmsdcc_pio_data pio;
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
diff --git a/drivers/mtd/devices/msm_nand.c b/drivers/mtd/devices/msm_nand.c
index 5ced423..2479a11 100644
--- a/drivers/mtd/devices/msm_nand.c
+++ b/drivers/mtd/devices/msm_nand.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-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
@@ -6718,7 +6718,7 @@
supported_flash.pagesize = 1024 << (devcfg & 0x3);
supported_flash.blksize = (64 * 1024) <<
((devcfg >> 4) & 0x3);
- supported_flash.oobsize = (8 << ((devcfg >> 2) & 1)) *
+ supported_flash.oobsize = (8 << ((devcfg >> 2) & 0x3)) *
(supported_flash.pagesize >> 9);
} else {
supported_flash.flash_id = flash_id;
diff --git a/drivers/net/wireless/libra/libra_sdioif.c b/drivers/net/wireless/libra/libra_sdioif.c
index 3955642..3421f84 100644
--- a/drivers/net/wireless/libra/libra_sdioif.c
+++ b/drivers/net/wireless/libra/libra_sdioif.c
@@ -29,6 +29,37 @@
static suspend_handler_t *libra_suspend_hldr;
static resume_handler_t *libra_resume_hldr;
+int libra_enable_sdio_irq_in_chip(struct sdio_func *func, u8 enable)
+{
+ unsigned char reg = 0;
+ int err = 0;
+
+ sdio_claim_host(func);
+
+ /* Read the value into reg */
+ libra_sdiocmd52(func, SDIO_CCCR_IENx, ®, 0, &err);
+ if (err)
+ printk(KERN_ERR "%s: Could not read SDIO_CCCR_IENx register "
+ "err=%d\n", __func__, err);
+
+ if (libra_mmc_host) {
+ if (enable) {
+ reg |= 1 << func->num;
+ reg |= 1;
+ } else {
+ reg &= ~(1 << func->num);
+ }
+ libra_sdiocmd52(func, SDIO_CCCR_IENx, ®, 1, &err);
+ if (err)
+ printk(KERN_ERR "%s: Could not enable/disable irq "
+ "err=%d\n", __func__, err);
+ }
+ sdio_release_host(func);
+
+ return err;
+}
+EXPORT_SYMBOL(libra_enable_sdio_irq_in_chip);
+
/**
* libra_sdio_configure() - Function to configure the SDIO device param
* @libra_sdio_rxhandler Rx handler
@@ -89,6 +120,8 @@
goto cfg_error;
}
+ libra_enable_sdio_irq_in_chip(func, 0);
+
sdio_release_host(func);
return 0;
diff --git a/drivers/net/wireless/libra/qcomwlan_pwrif.c b/drivers/net/wireless/libra/qcomwlan_pwrif.c
index 6a0c78f..94ea0b3 100644
--- a/drivers/net/wireless/libra/qcomwlan_pwrif.c
+++ b/drivers/net/wireless/libra/qcomwlan_pwrif.c
@@ -154,7 +154,7 @@
/* WLAN VREG settings */
for (i = 0; i < ARRAY_SIZE(vregs_qwlan_name); i++) {
- if (vregs_qwlan[i] == NULL) {
+ if (on && !wlan_on) {
vregs_qwlan[i] = regulator_get(NULL,
vregs_qwlan_name[i]);
if (IS_ERR(vregs_qwlan[i])) {
@@ -187,8 +187,7 @@
goto vreg_fail;
}
}
- }
- if (on && !wlan_on) {
+
if (vregs_qwlan_peek_current[i]) {
rc = regulator_set_optimum_mode(vregs_qwlan[i],
vregs_qwlan_peek_current[i]);
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index e5a9d40..632db71 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -78,8 +78,14 @@
#define PMIC_ARB_MAX_PERIPHS 256
#define PMIC_ARB_PERIPH_ID_VALID (1 << 15)
#define PMIC_ARB_TIMEOUT_US 100
-#define PMIC_ARB_APID_MASK 0xFF
-#define PMIC_ARB_PPID_MASK 0xFFF
+
+#define PMIC_ARB_APID_MASK 0xFF
+#define PMIC_ARB_PPID_MASK 0xFFF
+/* extract PPID and APID from interrupt map in .dts config file format */
+#define PMIC_ARB_DEV_TRE_2_PPID(MAP_COMPRS_VAL) \
+ ((MAP_COMPRS_VAL) >> (20))
+#define PMIC_ARB_DEV_TRE_2_APID(MAP_COMPRS_VAL) \
+ ((MAP_COMPRS_VAL) & PMIC_ARB_APID_MASK)
/**
* base - base address of the PMIC Arbiter core registers.
@@ -504,7 +510,7 @@
int ret;
int map_size;
u32 *map_data;
- const int map_width = 2 * sizeof(*map_data);
+ const int map_width = sizeof(*map_data);
const struct device_node *of_node = pdev->dev.of_node;
/* Get size of the mapping table (in bytes) */
@@ -514,8 +520,7 @@
}
/* Map size can't exceed the maximum number of peripherals */
- if (map_size == 0 || map_size % map_width ||
- map_size > map_width * PMIC_ARB_MAX_PERIPHS) {
+ if (map_size == 0 || map_size > map_width * PMIC_ARB_MAX_PERIPHS) {
dev_err(&pdev->dev, "map size of %d is not valid\n", map_size);
return -ENODEV;
}
@@ -538,20 +543,9 @@
/* Build the mapping table from the data */
for (i = 0; i < map_size/sizeof(u32);) {
- u32 ppid = map_data[i++];
- u32 apid = map_data[i++];
-
- if (apid > PMIC_ARB_APID_MASK) {
- ret = -ENODEV;
- dev_err(&pdev->dev, "invalid APID: 0x%x\n", apid);
- goto err;
- }
-
- if (ppid > PMIC_ARB_PPID_MASK) {
- ret = -ENODEV;
- dev_err(&pdev->dev, "invalid PPID: 0x%x\n", ppid);
- goto err;
- }
+ u32 map_compressed_val = map_data[i++];
+ u32 ppid = PMIC_ARB_DEV_TRE_2_PPID(map_compressed_val) ;
+ u32 apid = PMIC_ARB_DEV_TRE_2_APID(map_compressed_val) ;
if (pmic_arb->periph_id_map[apid] & PMIC_ARB_PERIPH_ID_VALID)
dev_warn(&pdev->dev, "duplicate APID 0x%x\n", apid);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 97c5690..5cd6bb1 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1285,10 +1285,20 @@
struct usb_bus *bus =
container_of(work, struct usb_bus, hnp_polling.work);
struct usb_device *udev = bus->root_hub->children[bus->otg_port - 1];
- u8 *status = kmalloc(sizeof(*status), GFP_KERNEL);
+ u8 *status = NULL;
+ /*
+ * The OTG-B device must hand back the host role to OTG PET
+ * within 100 msec irrespective of host_request flag.
+ */
+ if (bus->quick_hnp) {
+ bus->quick_hnp = 0;
+ goto start_hnp;
+ }
+
+ status = kmalloc(sizeof(*status), GFP_KERNEL);
if (!status)
- return;
+ goto reschedule;
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_DEVICE,
@@ -1300,17 +1310,20 @@
goto out;
}
- /* Spec says host must suspend the bus with in 2 sec. */
- if (*status & (1 << HOST_REQUEST_FLAG)) {
- do_unbind_rebind(udev, DO_UNBIND);
- udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
- ret = usb_suspend_both(udev, PMSG_USER_SUSPEND);
- if (ret)
- dev_info(&udev->dev, "suspend failed\n");
- } else {
- schedule_delayed_work(&bus->hnp_polling,
- msecs_to_jiffies(THOST_REQ_POLL));
- }
+ if (!(*status & (1 << HOST_REQUEST_FLAG)))
+ goto reschedule;
+
+start_hnp:
+ do_unbind_rebind(udev, DO_UNBIND);
+ udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
+ ret = usb_suspend_both(udev, PMSG_USER_SUSPEND);
+ if (ret)
+ dev_info(&udev->dev, "suspend failed\n");
+ goto out;
+
+reschedule:
+ schedule_delayed_work(&bus->hnp_polling,
+ msecs_to_jiffies(THOST_REQ_POLL));
out:
kfree(status);
}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5442297..7347c3d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1690,7 +1690,7 @@
#ifdef CONFIG_USB_OTG
if (udev->bus->hnp_support && udev->portnum == udev->bus->otg_port) {
- cancel_delayed_work(&udev->bus->hnp_polling);
+ cancel_delayed_work_sync(&udev->bus->hnp_polling);
udev->bus->hnp_support = 0;
}
#endif
@@ -1778,6 +1778,7 @@
int err = 0;
#ifdef CONFIG_USB_OTG
+ bool old_otg = false;
/*
* OTG-aware devices on OTG-capable root hubs may be able to use SRP,
* to wake us after we've powered off VBUS; and HNP, switching roles
@@ -1811,7 +1812,10 @@
* compliant to revision 2.0 or subsequent
* versions.
*/
- if (le16_to_cpu(desc->bcdOTG) >= 0x0200)
+
+ if ((le16_to_cpu(desc->bLength) ==
+ USB_DT_OTG_SIZE) &&
+ le16_to_cpu(desc->bcdOTG) >= 0x0200)
goto out;
/* Legacy B-device i.e compliant to spec
@@ -1819,6 +1823,7 @@
* a_hnp_support or b_hnp_enable before
* selecting configuration.
*/
+ old_otg = true;
/* enable HNP before suspend, it's simpler */
err = usb_control_msg(udev,
@@ -1839,6 +1844,14 @@
}
}
out:
+ if ((udev->quirks & USB_QUIRK_OTG_PET)) {
+ if (le16_to_cpu(udev->descriptor.bcdDevice) &
+ OTG_TTST_VBUS_OFF)
+ udev->bus->otg_vbus_off = 1;
+ if (udev->bus->is_b_host || old_otg)
+ udev->bus->quick_hnp = 1;
+ }
+
if (!is_targeted(udev)) {
otg_send_event(OTG_EVENT_DEV_NOT_SUPPORTED);
@@ -1859,8 +1872,12 @@
* re-armed if device returns STALL. B-Host also perform
* HNP polling.
*/
- schedule_delayed_work(&udev->bus->hnp_polling,
- msecs_to_jiffies(THOST_REQ_POLL));
+ if (udev->bus->quick_hnp)
+ schedule_delayed_work(&udev->bus->hnp_polling,
+ msecs_to_jiffies(OTG_TTST_SUSP));
+ else
+ schedule_delayed_work(&udev->bus->hnp_polling,
+ msecs_to_jiffies(THOST_REQ_POLL));
}
#endif
return err;
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h
index cec4167..7bb6747 100644
--- a/drivers/usb/core/otg_whitelist.h
+++ b/drivers/usb/core/otg_whitelist.h
@@ -59,6 +59,11 @@
le16_to_cpu(dev->descriptor.idProduct) == 0xbadd))
return 0;
+ /* OTG PET device is always targeted (see OTG 2.0 ECN 6.4.2) */
+ if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x0200))
+ return 1;
+
/* NOTE: can't use usb_match_id() since interface caches
* aren't set up yet. this is cut/paste from that code.
*/
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 81ce6a8..d5a29b3 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -96,6 +96,9 @@
/* INTEL VALUE SSD */
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Protocol and OTG Electrical Test Device */
+ { USB_DEVICE(0x1a0a, 0x0200), .driver_info = USB_QUIRK_OTG_PET },
+
{ } /* terminating entry must be last */
};
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 4c33695..4fe494b 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -858,6 +858,7 @@
u16 w_length = le16_to_cpu(ctrl->wLength);
struct usb_function *f = NULL;
u8 endp;
+ struct usb_configuration *c;
if (w_length > USB_BUFSIZ)
@@ -902,6 +903,16 @@
if (value >= 0)
value = min(w_length, (u16) value);
break;
+ case USB_DT_OTG:
+ if (!gadget_is_otg(gadget))
+ break;
+ c = list_first_entry(&cdev->configs,
+ struct usb_configuration, list);
+ if (c && c->descriptors)
+ value = usb_find_descriptor_fillbuf(req->buf,
+ USB_BUFSIZ, c->descriptors,
+ USB_DT_OTG);
+ break;
case USB_DT_STRING:
value = get_string(cdev, req->buf,
w_index, w_value & 0xff);
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index 09084fd..384332c 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -28,6 +28,40 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
+/**
+ * usb_find_descriptor_fillbuf - fill buffer with the requested descriptor
+ * @buf: Buffer to be filled
+ * @buflen: Size of buf
+ * @src: Array of descriptor pointers, terminated by null pointer.
+ * @desc_type: bDescriptorType field of the requested descriptor.
+ *
+ * Copies the requested descriptor into the buffer, returning the length
+ * or a negative error code if it is not found or can't be copied. Useful
+ * when DT_OTG descriptor is requested.
+ */
+int
+usb_find_descriptor_fillbuf(void *buf, unsigned buflen,
+ const struct usb_descriptor_header **src, u8 desc_type)
+{
+ if (!src)
+ return -EINVAL;
+
+ for (; NULL != *src; src++) {
+ unsigned len;
+
+ if ((*src)->bDescriptorType != desc_type)
+ continue;
+
+ len = (*src)->bLength;
+ if (len > buflen)
+ return -EINVAL;
+
+ memcpy(buf, *src, len);
+ return len;
+ }
+
+ return -ENOENT;
+}
/**
* usb_descriptor_fillbuf - fill buffer with descriptors
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index 2829231..d491bd0 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -410,15 +410,6 @@
ep->driver_data = dev; /* claim the endpoint */
dev->ep_out = ep;
- ep = usb_ep_autoconfig(cdev->gadget, out_desc);
- if (!ep) {
- DBG(cdev, "usb_ep_autoconfig for ep_out failed\n");
- return -ENODEV;
- }
- DBG(cdev, "usb_ep_autoconfig for mtp ep_out got %s\n", ep->name);
- ep->driver_data = dev; /* claim the endpoint */
- dev->ep_out = ep;
-
ep = usb_ep_autoconfig(cdev->gadget, intr_desc);
if (!ep) {
DBG(cdev, "usb_ep_autoconfig for ep_intr failed\n");
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index ece6785..bda6745 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -189,6 +189,13 @@
for chip-to-chip interconnect (having maximum circuit length of
10cm) as it removes the analog transceivers.
+config USB_EHCI_MSM_HOST4
+ bool "Support for MSM on-chip EHCI USB controller# 4"
+ depends on USB_EHCI_HCD && ARCH_MSM && ARCH_APQ8064
+ ---help---
+ Enables support for the EHCI Compliant USB Host controller# 4
+ present on the Qualcomm chipsets.
+
config USB_EHCI_TEGRA
boolean "NVIDIA Tegra HCD support"
depends on USB_EHCI_HCD && ARCH_TEGRA
diff --git a/drivers/usb/host/ehci-msm2.c b/drivers/usb/host/ehci-msm2.c
index 4f6fe3e..4318efb 100644
--- a/drivers/usb/host/ehci-msm2.c
+++ b/drivers/usb/host/ehci-msm2.c
@@ -48,6 +48,7 @@
struct regulator *hsusb_1p8;
struct regulator *vbus;
bool async_int;
+ bool vbus_on;
atomic_t in_lpm;
struct wake_lock wlock;
};
@@ -174,17 +175,24 @@
}
#ifdef CONFIG_PM_SLEEP
-#define HSUSB_PHY_SUSP_DIG_VOL 500000
+#define HSUSB_PHY_SUSP_DIG_VOL_P50 500000
+#define HSUSB_PHY_SUSP_DIG_VOL_P75 750000
static int msm_ehci_config_vddcx(struct msm_hcd *mhcd, int high)
{
+ struct msm_usb_host_platform_data *pdata;
int max_vol = HSUSB_PHY_VDD_DIG_VOL_MAX;
int min_vol;
int ret;
+ pdata = mhcd->dev->platform_data;
+
if (high)
min_vol = HSUSB_PHY_VDD_DIG_VOL_MIN;
+ else if (pdata && pdata->dock_connect_irq &&
+ !irq_read_line(pdata->dock_connect_irq))
+ min_vol = HSUSB_PHY_SUSP_DIG_VOL_P75;
else
- min_vol = HSUSB_PHY_SUSP_DIG_VOL;
+ min_vol = HSUSB_PHY_SUSP_DIG_VOL_P50;
ret = regulator_set_voltage(mhcd->hsusb_vddcx, min_vol, max_vol);
if (ret) {
@@ -205,29 +213,6 @@
}
#endif
-static int msm_ehci_init_vbus(struct msm_hcd *mhcd, int init)
-{
- struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
- struct msm_usb_host_platform_data *pdata;
-
- if (!init) {
- regulator_put(mhcd->vbus);
- return 0;
- }
-
- mhcd->vbus = regulator_get(mhcd->dev, "vbus");
- if (IS_ERR(mhcd->vbus)) {
- pr_err("Unable to get vbus\n");
- return -ENODEV;
- }
-
- pdata = mhcd->dev->platform_data;
- if (pdata)
- hcd->power_budget = pdata->power_budget;
-
- return 0;
-}
-
static void msm_ehci_vbus_power(struct msm_hcd *mhcd, bool on)
{
int ret;
@@ -236,21 +221,86 @@
pr_err("vbus is NULL.");
return;
}
+
+ if (mhcd->vbus_on == on)
+ return;
+
if (on) {
ret = regulator_enable(mhcd->vbus);
if (ret) {
pr_err("unable to enable vbus\n");
return;
}
+ mhcd->vbus_on = true;
} else {
ret = regulator_disable(mhcd->vbus);
if (ret) {
pr_err("unable to disable vbus\n");
return;
}
+ mhcd->vbus_on = false;
}
}
+static irqreturn_t msm_ehci_dock_connect_irq(int irq, void *data)
+{
+ const struct msm_usb_host_platform_data *pdata;
+ struct msm_hcd *mhcd = data;
+ struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
+
+ pdata = mhcd->dev->platform_data;
+
+ if (atomic_read(&mhcd->in_lpm))
+ usb_hcd_resume_root_hub(hcd);
+
+ if (irq_read_line(pdata->dock_connect_irq)) {
+ dev_dbg(mhcd->dev, "%s:Dock removed disable vbus\n", __func__);
+ msm_ehci_vbus_power(mhcd, 0);
+ } else {
+ dev_dbg(mhcd->dev, "%s:Dock connected enable vbus\n", __func__);
+ msm_ehci_vbus_power(mhcd, 1);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int msm_ehci_init_vbus(struct msm_hcd *mhcd, int init)
+{
+ int rc = 0;
+ struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
+ const struct msm_usb_host_platform_data *pdata;
+
+ 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");
+ if (IS_ERR(mhcd->vbus)) {
+ pr_err("Unable to get vbus\n");
+ return -ENODEV;
+ }
+
+ if (pdata) {
+ hcd->power_budget = pdata->power_budget;
+
+ if (pdata->dock_connect_irq) {
+ rc = request_threaded_irq(pdata->dock_connect_irq, NULL,
+ msm_ehci_dock_connect_irq,
+ IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING |
+ IRQF_ONESHOT, "msm_ehci_host", mhcd);
+ if (!rc)
+ enable_irq_wake(pdata->dock_connect_irq);
+ }
+ }
+ return rc;
+}
+
static int msm_ehci_ldo_enable(struct msm_hcd *mhcd, int on)
{
int ret = 0;
@@ -772,6 +822,7 @@
struct usb_hcd *hcd;
struct resource *res;
struct msm_hcd *mhcd;
+ const struct msm_usb_host_platform_data *pdata;
int ret;
dev_dbg(&pdev->dev, "ehci_msm2 probe\n");
@@ -859,8 +910,10 @@
goto vbus_deinit;
}
- /*TBD:for now enable vbus here*/
- msm_ehci_vbus_power(mhcd, 1);
+ pdata = mhcd->dev->platform_data;
+ if (pdata && (!pdata->dock_connect_irq ||
+ !irq_read_line(pdata->dock_connect_irq)))
+ msm_ehci_vbus_power(mhcd, 1);
device_init_wakeup(&pdev->dev, 1);
wake_lock_init(&mhcd->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev));
@@ -903,6 +956,7 @@
pm_runtime_set_suspended(&pdev->dev);
usb_remove_hcd(hcd);
+
msm_ehci_vbus_power(mhcd, 0);
msm_ehci_init_vbus(mhcd, 0);
msm_ehci_ldo_enable(mhcd, 0);
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index a77d98f..cce819f 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -1013,6 +1013,7 @@
#define PID9001_IFACE_MASK 0xC
#define PID9034_IFACE_MASK 0xC
#define PID9048_IFACE_MASK 0x18
+#define PID904C_IFACE_MASK 0x28
static const struct usb_device_id bridge_ids[] = {
{ USB_DEVICE(0x5c6, 0x9001),
@@ -1024,6 +1025,9 @@
{ USB_DEVICE(0x5c6, 0x9048),
.driver_info = PID9048_IFACE_MASK,
},
+ { USB_DEVICE(0x5c6, 0x904c),
+ .driver_info = PID904C_IFACE_MASK,
+ },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 6964835..dd07d4e 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -67,6 +67,7 @@
static DECLARE_COMPLETION(pmic_vbus_init);
static struct msm_otg *the_msm_otg;
static bool debug_aca_enabled;
+static bool debug_bus_voting_enabled;
/* Prevent idle power collapse(pc) while operating in peripheral mode */
static void otg_pm_qos_update_latency(struct msm_otg *dev, int vote)
@@ -1155,7 +1156,7 @@
*/
otg_pm_qos_update_latency(motg, 1);
/* Configure BUS performance parameters for MAX bandwidth */
- if (motg->bus_perf_client) {
+ if (motg->bus_perf_client && debug_bus_voting_enabled) {
ret = msm_bus_scale_client_update_request(
motg->bus_perf_client, 1);
if (ret)
@@ -2232,13 +2233,64 @@
.release = single_release,
};
+static int msm_otg_bus_show(struct seq_file *s, void *unused)
+{
+ if (debug_bus_voting_enabled)
+ seq_printf(s, "enabled\n");
+ else
+ seq_printf(s, "disabled\n");
+
+ return 0;
+}
+
+static int msm_otg_bus_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, msm_otg_bus_show, inode->i_private);
+}
+
+static ssize_t msm_otg_bus_write(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ char buf[8];
+ int ret;
+ struct seq_file *s = file->private_data;
+ struct msm_otg *motg = s->private;
+
+ memset(buf, 0x00, sizeof(buf));
+
+ if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+ return -EFAULT;
+
+ if (!strncmp(buf, "enable", 6)) {
+ /* Do not vote here. Let OTG statemachine decide when to vote */
+ debug_bus_voting_enabled = true;
+ } else {
+ debug_bus_voting_enabled = false;
+ if (motg->bus_perf_client) {
+ ret = msm_bus_scale_client_update_request(
+ motg->bus_perf_client, 0);
+ if (ret)
+ dev_err(motg->otg.dev, "%s: Failed to devote "
+ "for bus bw %d\n", __func__, ret);
+ }
+ }
+
+ return count;
+}
+
+const struct file_operations msm_otg_bus_fops = {
+ .open = msm_otg_bus_open,
+ .read = seq_read,
+ .write = msm_otg_bus_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static struct dentry *msm_otg_dbg_root;
-static struct dentry *msm_otg_dbg_mode;
-static struct dentry *msm_otg_chg_type;
-static struct dentry *msm_otg_dbg_aca;
static int msm_otg_debugfs_init(struct msm_otg *motg)
{
+ struct dentry *msm_otg_dentry;
msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL);
@@ -2248,35 +2300,43 @@
if (motg->pdata->mode == USB_OTG &&
motg->pdata->otg_control == OTG_USER_CONTROL) {
- msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO |
+ msm_otg_dentry = debugfs_create_file("mode", S_IRUGO |
S_IWUSR, msm_otg_dbg_root, motg,
&msm_otg_mode_fops);
- if (!msm_otg_dbg_mode) {
+ if (!msm_otg_dentry) {
debugfs_remove(msm_otg_dbg_root);
msm_otg_dbg_root = NULL;
return -ENODEV;
}
}
- msm_otg_chg_type = debugfs_create_file("chg_type", S_IRUGO,
+ msm_otg_dentry = debugfs_create_file("chg_type", S_IRUGO,
msm_otg_dbg_root, motg,
&msm_otg_chg_fops);
- if (!msm_otg_chg_type) {
+ if (!msm_otg_dentry) {
debugfs_remove_recursive(msm_otg_dbg_root);
return -ENODEV;
}
- msm_otg_dbg_aca = debugfs_create_file("aca", S_IRUGO | S_IWUSR,
+ msm_otg_dentry = debugfs_create_file("aca", S_IRUGO | S_IWUSR,
msm_otg_dbg_root, motg,
&msm_otg_aca_fops);
- if (!msm_otg_dbg_aca) {
+ if (!msm_otg_dentry) {
debugfs_remove_recursive(msm_otg_dbg_root);
return -ENODEV;
}
+ msm_otg_dentry = debugfs_create_file("bus_voting", S_IRUGO | S_IWUSR,
+ msm_otg_dbg_root, motg,
+ &msm_otg_bus_fops);
+
+ if (!msm_otg_dentry) {
+ debugfs_remove_recursive(msm_otg_dbg_root);
+ return -ENODEV;
+ }
return 0;
}
@@ -2642,6 +2702,8 @@
if (!motg->bus_perf_client)
dev_err(motg->otg.dev, "%s: Failed to register BUS "
"scaling client!!\n", __func__);
+ else
+ debug_bus_voting_enabled = true;
}
return 0;
diff --git a/drivers/usb/serial/csvt.c b/drivers/usb/serial/csvt.c
index 5bfb2dc..28eba8a 100644
--- a/drivers/usb/serial/csvt.c
+++ b/drivers/usb/serial/csvt.c
@@ -46,7 +46,7 @@
};
static const struct usb_device_id id_table[] = {
- { USB_DEVICE_AND_INTERFACE_INFO(0x05c6 , 0x904c, 0xff, 0x00, 0xff)},
+ { USB_DEVICE_AND_INTERFACE_INFO(0x05c6 , 0x904c, 0xff, 0xfe, 0xff)},
{}, /* terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 44e887c..ef022c1 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -1,7 +1,7 @@
/*
* Qualcomm Serial USB driver
*
- * Copyright (c) 2008, 2012 QUALCOMM Incorporated.
+ * Copyright (c) 2008, 2012 Code Aurora Forum. All rights reserved.
* Copyright (c) 2009 Greg Kroah-Hartman <gregkh@suse.de>
* Copyright (c) 2009 Novell Inc.
*
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index 0110df9..af8c669 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -609,6 +609,7 @@
Support for EBI2 TMD QVGA (240x320) and Epson QCIF (176x220) panel
config FB_MSM_HDMI_AS_PRIMARY
+ depends on FB_MSM_HDMI_COMMON
bool "Use HDMI as primary panel"
---help---
Support for using HDMI as primary
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 0a86a50..d6f59aa 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -347,11 +347,12 @@
struct device_attribute *attr, const char *buf, size_t count)
{
ssize_t ret = strnlen(buf, PAGE_SIZE);
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- int hpd = 1;
-#else
- int hpd = atoi(buf);
-#endif
+ int hpd;
+ if (hdmi_prim_display)
+ hpd = 1;
+ else
+ hpd = atoi(buf);
+
if (external_common_state->hpd_feature) {
if (hpd == 0 && external_common_state->hpd_feature_on) {
external_common_state->hpd_feature(0);
@@ -652,6 +653,14 @@
return ret;
}
+static ssize_t hdmi_common_rda_hdmi_primary(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret = snprintf(buf, PAGE_SIZE, "%d\n",
+ hdmi_prim_display);
+ DEV_DBG("%s: '%d'\n", __func__, hdmi_prim_display);
+ return ret;
+}
static DEVICE_ATTR(video_mode, S_IRUGO | S_IWUGO,
external_common_rda_video_mode, external_common_wta_video_mode);
@@ -671,6 +680,7 @@
static DEVICE_ATTR(format_3d, S_IRUGO | S_IWUGO, hdmi_3d_rda_format_3d,
hdmi_3d_wta_format_3d);
#endif
+static DEVICE_ATTR(hdmi_primary, S_IRUGO, hdmi_common_rda_hdmi_primary, NULL);
static struct attribute *external_common_fs_attrs[] = {
&dev_attr_video_mode.attr,
@@ -693,6 +703,7 @@
&dev_attr_cec_rd_frame.attr,
&dev_attr_cec_wr_frame.attr,
#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+ &dev_attr_hdmi_primary.attr,
NULL,
};
static struct attribute_group external_common_fs_attr_group = {
@@ -1567,11 +1578,10 @@
pinfo->pdest = DISPLAY_2;
pinfo->wait_cycle = 0;
pinfo->bpp = 24;
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- pinfo->fb_num = 2;
-#else
- pinfo->fb_num = 1;
-#endif
+ if (hdmi_prim_display)
+ pinfo->fb_num = 2;
+ else
+ pinfo->fb_num = 1;
/* blk */
pinfo->lcdc.border_clr = 0;
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 96d9487..1c47d89 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -4512,12 +4512,13 @@
{
int rc;
- if (cpu_is_msm8930())
- return 0;
-
if (msm_fb_detect_client("hdmi_msm"))
return 0;
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+ hdmi_prim_display = 1;
+#endif
+
hdmi_msm_setup_video_mode_lut();
hdmi_msm_state = kzalloc(sizeof(*hdmi_msm_state), GFP_KERNEL);
if (!hdmi_msm_state) {
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index d374b4c..6dcc293 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -87,6 +87,7 @@
extern struct mdp_ccs mdp_ccs_yuv2rgb ;
extern struct mdp_ccs mdp_ccs_rgb2yuv ;
+extern unsigned char hdmi_prim_display;
/*
* MDP Image Structure
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index f7f48e4..c4f6a04 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -445,14 +445,7 @@
}
#endif
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
void mdp4_dtv_set_black_screen(void);
-#else
-static inline void mdp4_dtv_set_black_screen(void)
-{
- /* empty */
-}
-#endif
static inline int mdp4_overlay_borderfill_supported(void)
{
diff --git a/drivers/video/msm/mdp4_dtv.c b/drivers/video/msm/mdp4_dtv.c
index ba774b9..09bc9c2 100644
--- a/drivers/video/msm/mdp4_dtv.c
+++ b/drivers/video/msm/mdp4_dtv.c
@@ -225,11 +225,11 @@
* get/set panel specific fb info
*/
mfd->panel_info = pdata->panel_info;
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- mfd->fb_imgType = MSMFB_DEFAULT_TYPE;
-#else
- mfd->fb_imgType = MDP_RGB_565;
-#endif
+ if (hdmi_prim_display)
+ mfd->fb_imgType = MSMFB_DEFAULT_TYPE;
+ else
+ mfd->fb_imgType = MDP_RGB_565;
+
fbi = mfd->fbi;
fbi->var.pixclock = mfd->panel_info.clk_rate;
fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 3768284..033a73c 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1887,7 +1887,7 @@
static int get_img(struct msmfb_data *img, struct fb_info *info,
unsigned long *start, unsigned long *len, struct file **srcp_file,
- struct ion_handle **srcp_ihdl)
+ int *p_need, struct ion_handle **srcp_ihdl)
{
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
@@ -1897,6 +1897,8 @@
#ifdef CONFIG_ANDROID_PMEM
unsigned long vstart;
#endif
+ *p_need = 0;
+
if (img->flags & MDP_BLIT_SRC_GEM) {
*srcp_file = NULL;
return kgsl_gem_obj_addr(img->memory_id, (int) img->priv,
@@ -1912,8 +1914,10 @@
fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
if (get_fb_phys_info(start, len, fb_num))
ret = -1;
- else
+ else {
*srcp_file = file;
+ *p_need = put_needed;
+ }
} else
ret = -1;
if (ret)
@@ -2483,6 +2487,7 @@
struct file *srcp1_file = NULL, *srcp2_file = NULL;
struct ion_handle *srcp0_ihdl = NULL;
struct ion_handle *srcp1_ihdl = NULL, *srcp2_ihdl = NULL;
+ int ps0_need, p_need;
uint32_t overlay_version = 0;
int ret = 0;
@@ -2502,7 +2507,7 @@
return -EINTR;
img = &req->data;
- get_img(img, info, &start, &len, &srcp0_file, &srcp0_ihdl);
+ get_img(img, info, &start, &len, &srcp0_file, &ps0_need, &srcp0_ihdl);
if (len == 0) {
mutex_unlock(&mfd->dma->ov_mutex);
pr_err("%s: pmem Error\n", __func__);
@@ -2521,7 +2526,7 @@
if (overlay_version > 0) {
img = &req->plane1_data;
get_img(img, info, &start, &len, &srcp1_file,
- &srcp1_ihdl);
+ &p_need, &srcp1_ihdl);
if (len == 0) {
mutex_unlock(&mfd->dma->ov_mutex);
pr_err("%s: Error to get plane1\n", __func__);
@@ -2553,7 +2558,7 @@
if (overlay_version > 0) {
img = &req->plane1_data;
get_img(img, info, &start, &len, &srcp1_file,
- &srcp1_ihdl);
+ &p_need, &srcp1_ihdl);
if (len == 0) {
mutex_unlock(&mfd->dma->ov_mutex);
pr_err("%s: Error to get plane1\n", __func__);
@@ -2564,7 +2569,7 @@
img = &req->plane2_data;
get_img(img, info, &start, &len, &srcp2_file,
- &srcp2_ihdl);
+ &p_need, &srcp2_ihdl);
if (len == 0) {
mutex_unlock(&mfd->dma->ov_mutex);
pr_err("%s: Error to get plane2\n", __func__);
@@ -2692,9 +2697,13 @@
if (srcp2_file)
put_pmem_file(srcp2_file);
#endif
+ /* only source may use frame buffer */
+ if (img->flags & MDP_MEMORY_ID_TYPE_FB)
+ fput_light(srcp0_file, ps0_need);
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- if (!IS_ERR_OR_NULL(srcp0_ihdl))
+ else if (!IS_ERR_OR_NULL(srcp0_ihdl))
ion_free(mfd->iclient, srcp0_ihdl);
+
if (!IS_ERR_OR_NULL(srcp1_ihdl))
ion_free(mfd->iclient, srcp1_ihdl);
if (!IS_ERR_OR_NULL(srcp2_ihdl))
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 3bbe0e5..0b86028 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -102,12 +102,12 @@
var = &fbi->var;
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- if (is_mdp4_hw_reset()) {
- mdp4_hw_init();
- outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
+ if (hdmi_prim_display) {
+ if (is_mdp4_hw_reset()) {
+ mdp4_hw_init();
+ outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
+ }
}
-#endif
mdp4_overlay_dmae_cfg(mfd, 0);
/*
@@ -301,7 +301,7 @@
/* MSP_BORDER_COLOR */
MDP_OUTP(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x5008,
(0x0 & 0xFFF)); /* 12-bit R */
- mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
} else {
switch (mfd->ibuf.bpp) {
case 2:
@@ -312,11 +312,10 @@
break;
case 4:
default:
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- pipe->src_format = MSMFB_DEFAULT_TYPE;
-#else
- pipe->src_format = MDP_ARGB_8888;
-#endif
+ if (hdmi_prim_display)
+ pipe->src_format = MSMFB_DEFAULT_TYPE;
+ else
+ pipe->src_format = MDP_ARGB_8888;
break;
}
}
@@ -355,7 +354,7 @@
if (pipe != NULL && pipe->mixer_stage == MDP4_MIXER_STAGE_BASE &&
pipe->pipe_type == OVERLAY_TYPE_RGB)
dtv_pipe = pipe; /* keep it */
- else if (mdp4_overlay_borderfill_supported())
+ else if (!hdmi_prim_display && mdp4_overlay_borderfill_supported())
mdp4_overlay_dtv_alloc_pipe(mfd, OVERLAY_TYPE_BF);
else
mdp4_overlay_dtv_alloc_pipe(mfd, OVERLAY_TYPE_RGB);
@@ -512,7 +511,6 @@
complete_all(&dtv_pipe->comp);
}
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
void mdp4_dtv_set_black_screen(void)
{
char *rgb_base;
@@ -520,8 +518,9 @@
uint32 color = 0x00000000;
uint32 temp_src_format;
- if (!dtv_pipe) {
- pr_err("dtv_pipe is not configured yet\n");
+ if (!dtv_pipe || !hdmi_prim_display) {
+ pr_err("dtv_pipe/hdmi as primary are not"
+ " configured yet\n");
return;
}
rgb_base = MDP_BASE + MDP4_RGB_BASE;
@@ -540,7 +539,6 @@
mdp4_mixer_stage_up(dtv_pipe);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
-#endif
static void mdp4_overlay_dtv_wait4dmae(struct msm_fb_data_type *mfd)
{
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 2962393..63fe1f3 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -189,13 +189,44 @@
#endif
static struct msm_fb_platform_data *msm_fb_pdata;
+unsigned char hdmi_prim_display;
int msm_fb_detect_client(const char *name)
{
int ret = 0;
+ u32 len;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
u32 id;
#endif
+ if (!msm_fb_pdata)
+ return -EPERM;
+
+ len = strnlen(name, PANEL_NAME_MAX_LEN);
+ if (strnlen(msm_fb_pdata->prim_panel_name, PANEL_NAME_MAX_LEN)) {
+ pr_err("\n name = %s, prim_display = %s",
+ name, msm_fb_pdata->prim_panel_name);
+ if (!strncmp((char *)msm_fb_pdata->prim_panel_name,
+ name, len)) {
+ if (!strncmp((char *)msm_fb_pdata->prim_panel_name,
+ "hdmi_msm", len))
+ hdmi_prim_display = 1;
+ return 0;
+ } else {
+ ret = -EPERM;
+ }
+ }
+
+ if (strnlen(msm_fb_pdata->ext_panel_name, PANEL_NAME_MAX_LEN)) {
+ pr_err("\n name = %s, ext_display = %s",
+ name, msm_fb_pdata->ext_panel_name);
+ if (!strncmp((char *)msm_fb_pdata->ext_panel_name, name, len))
+ return 0;
+ else
+ ret = -EPERM;
+ }
+
+ if (ret)
+ return ret;
ret = -EPERM;
if (msm_fb_pdata && msm_fb_pdata->detect_client) {
@@ -3349,11 +3380,10 @@
*/
if (type == HDMI_PANEL || type == DTV_PANEL ||
type == TV_PANEL || type == WRITEBACK_PANEL) {
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- pdata->panel_info.fb_num = 2;
-#else
- pdata->panel_info.fb_num = 1;
-#endif
+ if (hdmi_prim_display)
+ pdata->panel_info.fb_num = 2;
+ else
+ pdata->panel_info.fb_num = 1;
}
else
pdata->panel_info.fb_num = MSM_FB_NUM;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
index 3f54756..267e924 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 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
@@ -246,6 +246,8 @@
DDL_METADATA_ALIGNSIZE(suffix);
encoder->suffix = suffix;
encoder->output_buf_req.sz += suffix;
+ encoder->output_buf_req.sz =
+ DDL_ALIGN(encoder->output_buf_req.sz, DDL_KILO_BYTE(4));
}
u32 ddl_set_metadata_params(struct ddl_client_context *ddl,
@@ -454,6 +456,7 @@
return;
}
out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
+ DDL_MSG_LOW("processing metadata for encoder");
start_addr = (u32) ((u8 *)out_frame->virtual + out_frame->offset);
qfiller = (u32 *)((out_frame->data_len +
start_addr + 3) & ~3);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index 51a72c8..444db9f 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -915,10 +915,15 @@
}
case VCD_I_METADATA_ENABLE:
case VCD_I_METADATA_HEADER:
- DDL_MSG_ERROR("Meta Data Interface is Requested");
- vcd_status = ddl_set_metadata_params(ddl, property_hdr,
- property_value);
- vcd_status = VCD_S_SUCCESS;
+ DDL_MSG_LOW("Meta Data Interface is Requested");
+ if (!res_trk_check_for_sec_session()) {
+ vcd_status = ddl_set_metadata_params(ddl,
+ property_hdr, property_value);
+ } else {
+ DDL_MSG_ERROR("Meta Data Interface is not "
+ "supported in secure session");
+ vcd_status = VCD_ERR_ILLEGAL_OP;
+ }
break;
case VCD_I_META_BUFFER_MODE:
vcd_status = VCD_S_SUCCESS;
@@ -1836,8 +1841,16 @@
/*original_buf_req->align <= req_buf_req->align,*/
original_buf_req->sz <= req_buf_req->sz)
status = true;
- else
+ else {
DDL_MSG_ERROR("ddl_valid_buf_req:Failed");
+ DDL_MSG_ERROR("codec_buf_req: min_cnt=%d, mx_cnt=%d, "
+ "align=%d, sz=%d\n", original_buf_req->min_count,
+ original_buf_req->max_count, original_buf_req->align,
+ original_buf_req->sz);
+ DDL_MSG_ERROR("client_buffs: actual_count=%d, align=%d, "
+ "sz=%d\n", req_buf_req->actual_count,
+ req_buf_req->align, req_buf_req->sz);
+ }
return status;
}
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 6d6dcdc..3c25751 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1575,6 +1575,34 @@
}
break;
}
+ case VEN_IOCTL_SET_EXTRADATA:
+ case VEN_IOCTL_GET_EXTRADATA:
+ {
+ u32 extradata_flag;
+ DBG("VEN_IOCTL_(G)SET_EXTRADATA\n");
+ if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+ return -EFAULT;
+ if (cmd == VEN_IOCTL_SET_EXTRADATA) {
+ if (copy_from_user(&extradata_flag, venc_msg.in,
+ sizeof(u32)))
+ return -EFAULT;
+ result = vid_enc_set_get_extradata(client_ctx,
+ &extradata_flag, true);
+ } else {
+ result = vid_enc_set_get_extradata(client_ctx,
+ &extradata_flag, false);
+ if (result) {
+ if (copy_to_user(venc_msg.out, &extradata_flag,
+ sizeof(u32)))
+ return -EFAULT;
+ }
+ }
+ if (!result) {
+ ERR("setting VEN_IOCTL_(G)SET_LIVE_MODE failed\n");
+ return -EIO;
+ }
+ break;
+ }
case VEN_IOCTL_SET_AC_PREDICTION:
case VEN_IOCTL_GET_AC_PREDICTION:
case VEN_IOCTL_SET_RVLC:
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index f362f7b..cac5dc4 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -316,6 +316,42 @@
return true;
}
+u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx,
+ u32 *extradata_flag, u32 set_flag)
+{
+ struct vcd_property_hdr vcd_property_hdr;
+ struct vcd_property_meta_data_enable vcd_meta_data;
+ u32 vcd_status = VCD_ERR_FAIL;
+ if (!client_ctx || !extradata_flag)
+ return false;
+ vcd_property_hdr.prop_id = VCD_I_METADATA_ENABLE;
+ vcd_property_hdr.sz = sizeof(struct vcd_property_meta_data_enable);
+ if (set_flag) {
+ DBG("vcd_set_property: VCD_I_METADATA_ENABLE = %d\n",
+ *extradata_flag);
+ vcd_meta_data.meta_data_enable_flag = *extradata_flag;
+ vcd_status = vcd_set_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &vcd_meta_data);
+ if (vcd_status) {
+ ERR("%s(): Set VCD_I_METADATA_ENABLE Failed\n",
+ __func__);
+ return false;
+ }
+ } else {
+ vcd_status = vcd_get_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &vcd_meta_data);
+ if (vcd_status) {
+ ERR("%s(): Get VCD_I_METADATA_ENABLE Failed\n",
+ __func__);
+ return false;
+ }
+ *extradata_flag = vcd_meta_data.meta_data_enable_flag;
+ DBG("vcd_get_property: VCD_I_METADATA_ENABLE = %d\n",
+ *extradata_flag);
+ }
+ return true;
+}
+
u32 vid_enc_set_get_framerate(struct video_client_ctx *client_ctx,
struct venc_framerate *frame_rate, u32 set_flag)
{
@@ -1494,6 +1530,11 @@
venc_buf_req->alignment = buffer_req.align;
venc_buf_req->bufpoolid = buffer_req.buf_pool_id;
venc_buf_req->suffixsize = 0;
+ DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, "
+ "max_count=%d, buf_pool_id=%d\n", __func__,
+ buffer_req.actual_count, buffer_req.align,
+ buffer_req.sz, buffer_req.min_count,
+ buffer_req.max_count, buffer_req.buf_pool_id);
}
return status;
}
@@ -1521,6 +1562,11 @@
buffer_req.align = venc_buf_req->alignment;
buffer_req.buf_pool_id = 0;
+ DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, "
+ "max_count=%d, buf_pool_id=%d\n", __func__,
+ buffer_req.actual_count, buffer_req.align, buffer_req.sz,
+ buffer_req.min_count, buffer_req.max_count,
+ buffer_req.buf_pool_id);
vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle,
buffer, &buffer_req);
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.h b/drivers/video/msm/vidc/common/enc/venc_internal.h
index a07f7ab..8a07fdb 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.h
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.h
@@ -68,6 +68,9 @@
u32 vid_enc_set_get_live_mode(struct video_client_ctx *client_ctx,
struct venc_switch *encoder_switch, u32 set_flag);
+u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx,
+ u32 *extradata_flag, u32 set_flag);
+
u32 vid_enc_set_get_short_header(struct video_client_ctx *client_ctx,
struct venc_switch *encoder_switch, u32 set_flag);
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 1cb5401..5d3a6a1 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -36,23 +36,11 @@
#define DIAG_IOCTL_GET_DELAYED_RSP_ID 8
#define DIAG_IOCTL_LSM_DEINIT 9
-/* Machine ID and corresponding PC Tools IDs */
-#define APQ8060_MACHINE_ID 86
-#define AO8960_MACHINE_ID 87
-#define MSM8660_MACHINE_ID 71
-#define MDM9615_MACHINE_ID 104
-#define APQ8064_MACHINE_ID 109
-#define MSM8930_MACHINE_ID 116
-#define MSM8630_MACHINE_ID 117
-#define MSM8230_MACHINE_ID 118
-#define APQ8030_MACHINE_ID 119
-#define MSM8627_MACHINE_ID 120
-#define MSM8227_MACHINE_ID 121
-#define MSM8260A_MACHINE_ID 123
-#define MSM8974_MACHINE_ID 126
+/* PC Tools IDs */
#define APQ8060_TOOLS_ID 4062
#define AO8960_TOOLS_ID 4064
#define APQ8064_TOOLS_ID 4072
+#define MSM8625_TOOLS_ID 4075
#define MSM8930_TOOLS_ID 4076
#define MSM8630_TOOLS_ID 4077
#define MSM8230_TOOLS_ID 4078
@@ -114,11 +102,11 @@
/* This needs to be modified manually now, when we add
a new RANGE of SSIDs to the msg_mask_tbl */
-#define MSG_MASK_TBL_CNT 19
+#define MSG_MASK_TBL_CNT 23
#define EVENT_LAST_ID 0x083F
#define MSG_SSID_0 0
-#define MSG_SSID_0_LAST 68
+#define MSG_SSID_0_LAST 90
#define MSG_SSID_1 500
#define MSG_SSID_1_LAST 506
#define MSG_SSID_2 1000
@@ -126,19 +114,19 @@
#define MSG_SSID_3 2000
#define MSG_SSID_3_LAST 2008
#define MSG_SSID_4 3000
-#define MSG_SSID_4_LAST 3012
+#define MSG_SSID_4_LAST 3014
#define MSG_SSID_5 4000
#define MSG_SSID_5_LAST 4010
#define MSG_SSID_6 4500
#define MSG_SSID_6_LAST 4526
#define MSG_SSID_7 4600
-#define MSG_SSID_7_LAST 4611
+#define MSG_SSID_7_LAST 4612
#define MSG_SSID_8 5000
-#define MSG_SSID_8_LAST 5024
+#define MSG_SSID_8_LAST 5029
#define MSG_SSID_9 5500
-#define MSG_SSID_9_LAST 5514
+#define MSG_SSID_9_LAST 5516
#define MSG_SSID_10 6000
-#define MSG_SSID_10_LAST 6050
+#define MSG_SSID_10_LAST 6072
#define MSG_SSID_11 6500
#define MSG_SSID_11_LAST 6521
#define MSG_SSID_12 7000
@@ -155,6 +143,14 @@
#define MSG_SSID_17_LAST 9008
#define MSG_SSID_18 9500
#define MSG_SSID_18_LAST 9509
+#define MSG_SSID_19 10200
+#define MSG_SSID_19_LAST 10210
+#define MSG_SSID_20 10251
+#define MSG_SSID_20_LAST 10255
+#define MSG_SSID_21 10300
+#define MSG_SSID_21_LAST 10300
+#define MSG_SSID_22 10350
+#define MSG_SSID_22_LAST 10361
struct diagpkt_delay_params {
void *rsp_ptr;
@@ -249,6 +245,28 @@
MSG_LVL_MED,
MSG_LVL_LOW,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
+ MSG_LVL_MED,
+ MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
+ MSG_LVL_LOW,
+ MSG_LVL_MED,
+ MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_1[] = {
@@ -258,7 +276,7 @@
MSG_LVL_LOW,
MSG_LVL_HIGH,
MSG_LVL_HIGH,
- MSG_LVL_HIGH,
+ MSG_LVL_HIGH
};
static const uint32_t msg_bld_masks_2[] = {
@@ -297,7 +315,9 @@
MSG_LVL_HIGH,
MSG_LVL_HIGH,
MSG_LVL_HIGH,
- MSG_LVL_HIGH
+ MSG_LVL_HIGH,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_5[] = {
@@ -310,7 +330,8 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
- MSG_LVL_MED,
+ MSG_LVL_MED|MSG_LVL_MED|MSG_MASK_5|MSG_MASK_6|MSG_MASK_7| \
+ MSG_MASK_8|MSG_MASK_9,
MSG_LVL_MED
};
@@ -357,6 +378,7 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
+ MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_8[] = {
@@ -385,6 +407,11 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED
};
static const uint32_t msg_bld_masks_9[] = {
@@ -403,6 +430,8 @@
MSG_LVL_MED|MSG_MASK_5,
MSG_LVL_MED|MSG_MASK_5,
MSG_LVL_MED|MSG_MASK_5,
+ MSG_LVL_MED|MSG_MASK_5,
+ MSG_LVL_MED|MSG_MASK_5
};
static const uint32_t msg_bld_masks_10[] = {
@@ -462,6 +491,28 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_11[] = {
@@ -584,6 +635,47 @@
MSG_LVL_LOW
};
+static const uint32_t msg_bld_masks_19[] = {
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW
+};
+
+static const uint32_t msg_bld_masks_20[] = {
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW
+};
+
+static const uint32_t msg_bld_masks_21[] = {
+ MSG_LVL_HIGH
+};
+
+static const uint32_t msg_bld_masks_22[] = {
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH
+};
+
/* LOG CODES */
#define LOG_0 0x0
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index 3ac41bc..a2391e3 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -29,6 +29,12 @@
/* MXT_TOUCH_KEYARRAY_T15 */
#define MXT_KEYARRAY_MAX_KEYS 32
+/* Bootoader IDs */
+#define MXT_BOOTLOADER_ID_224 0x0A
+#define MXT_BOOTLOADER_ID_224E 0x06
+#define MXT_BOOTLOADER_ID_1386 0x01
+#define MXT_BOOTLOADER_ID_1386E 0x10
+
/* Config data for a given maXTouch controller with a specific firmware */
struct mxt_config_info {
const u8 *config;
@@ -37,6 +43,7 @@
u8 variant_id;
u8 version;
u8 build;
+ u8 bootldr_id;
/* Points to the firmware name to be upgraded to */
const char *fw_name;
};
diff --git a/include/linux/libra_sdioif.h b/include/linux/libra_sdioif.h
index 965e2b5..08be83a 100644
--- a/include/linux/libra_sdioif.h
+++ b/include/linux/libra_sdioif.h
@@ -35,6 +35,7 @@
typedef int (suspend_handler_t)(struct sdio_func *);
typedef void (resume_handler_t)(struct sdio_func *);
+int libra_enable_sdio_irq_in_chip(struct sdio_func *func, u8 enable);
int libra_sdio_configure(sdio_irq_handler_t libra_sdio_rxhandler,
void (*func_drv_fn)(int *status),
u32 funcdrv_timeout, u32 blksize);
diff --git a/include/linux/mfd/pm8xxx/irq.h b/include/linux/mfd/pm8xxx/irq.h
index 1e1fe6c..78fbed3 100644
--- a/include/linux/mfd/pm8xxx/irq.h
+++ b/include/linux/mfd/pm8xxx/irq.h
@@ -39,21 +39,20 @@
#ifdef CONFIG_MFD_PM8XXX_IRQ
int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq);
-struct pm_irq_chip * __devinit pm8xxx_irq_init(struct device *dev,
+struct pm_irq_chip *pm8xxx_irq_init(struct device *dev,
const struct pm8xxx_irq_platform_data *pdata);
-int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip);
+int pm8xxx_irq_exit(struct pm_irq_chip *chip);
#else
static inline int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
{
return -ENXIO;
}
-static inline struct pm_irq_chip * __devinit pm8xxx_irq_init(
- const struct device *dev,
+static inline struct pm_irq_chip *pm8xxx_irq_init(const struct device *dev,
const struct pm8xxx_irq_platform_data *pdata)
{
return ERR_PTR(-ENXIO);
}
-static inline int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip)
+static inline int pm8xxx_irq_exit(struct pm_irq_chip *chip)
{
return -ENXIO;
}
diff --git a/include/linux/mfd/wcd9xxx/wcd9310_registers.h b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
index d2736ea..67c2a6b 100644
--- a/include/linux/mfd/wcd9xxx/wcd9310_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
@@ -897,6 +897,38 @@
#define TABLA_A_CDC_DEBUG_B5_CTL__POR (0x00000000)
#define TABLA_A_CDC_DEBUG_B6_CTL (0x0000036D)
#define TABLA_A_CDC_DEBUG_B6_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B1_CTL (0x00000370)
+#define TABLA_A_CDC_COMP1_B1_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B2_CTL (0x00000371)
+#define TABLA_A_CDC_COMP1_B2_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B3_CTL (0x00000372)
+#define TABLA_A_CDC_COMP1_B3_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B4_CTL (0x00000373)
+#define TABLA_A_CDC_COMP1_B4_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B5_CTL (0x00000374)
+#define TABLA_A_CDC_COMP1_B5_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B6_CTL (0x00000375)
+#define TABLA_A_CDC_COMP1_B6_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS (0x00000376)
+#define TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_FS_CFG (0x00000377)
+#define TABLA_A_CDC_COMP1_FS_CFG__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B1_CTL (0x00000378)
+#define TABLA_A_CDC_COMP2_B1_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B2_CTL (0x00000379)
+#define TABLA_A_CDC_COMP2_B2_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B3_CTL (0x0000037A)
+#define TABLA_A_CDC_COMP2_B3_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B4_CTL (0x0000037B)
+#define TABLA_A_CDC_COMP2_B4_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B5_CTL (0x0000037C)
+#define TABLA_A_CDC_COMP2_B5_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B6_CTL (0x0000037D)
+#define TABLA_A_CDC_COMP2_B6_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS (0x0000037E)
+#define TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_FS_CFG (0x0000037F)
+#define TABLA_A_CDC_COMP2_FS_CFG__POR (0x00000000)
#define TABLA_A_CDC_CONN_RX1_B1_CTL (0x00000380)
#define TABLA_A_CDC_CONN_RX1_B1_CTL__POR (0x00000000)
#define TABLA_A_CDC_CONN_RX1_B2_CTL (0x00000381)
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index ff53742..dedbe5c 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -190,6 +190,7 @@
#define MMC_STATE_ULTRAHIGHSPEED (1<<5) /* card is in ultra high speed mode */
#define MMC_CARD_SDXC (1<<6) /* card is SDXC */
#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
+#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
@@ -328,6 +329,7 @@
#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
#define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY)
#define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED)
+#define mmc_card_hs200(c) ((c)->state & MMC_STATE_HIGHSPEED_200)
#define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR)
#define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR)
#define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
@@ -337,6 +339,7 @@
#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
#define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED)
+#define mmc_card_set_hs200(c) ((c)->state |= MMC_STATE_HIGHSPEED_200)
#define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR)
#define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR)
#define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 35137d6..73a68c9 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -56,12 +56,15 @@
#define MMC_TIMING_UHS_SDR50 3
#define MMC_TIMING_UHS_SDR104 4
#define MMC_TIMING_UHS_DDR50 5
+#define MMC_TIMING_MMC_HS200 6
unsigned char ddr; /* dual data rate used */
#define MMC_SDR_MODE 0
#define MMC_1_2V_DDR_MODE 1
#define MMC_1_8V_DDR_MODE 2
+#define MMC_1_2V_SDR_MODE 3
+#define MMC_1_8V_SDR_MODE 4
unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */
@@ -147,7 +150,9 @@
void (*init_card)(struct mmc_host *host, struct mmc_card *card);
int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios);
- int (*execute_tuning)(struct mmc_host *host);
+
+ /* The tuning command opcode value is different for SD and eMMC cards */
+ int (*execute_tuning)(struct mmc_host *host, u32 opcode);
void (*enable_preset_value)(struct mmc_host *host, bool enable);
void (*hw_reset)(struct mmc_host *host);
};
@@ -239,7 +244,10 @@
#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 */
-
+#define MMC_CAP2_HS200_1_8V_SDR (1 << 5) /* can support */
+#define MMC_CAP2_HS200_1_2V_SDR (1 << 6) /* can support */
+#define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \
+ MMC_CAP2_HS200_1_2V_SDR)
mmc_pm_flag_t pm_caps; /* supported pm features */
unsigned int power_notify_type;
#define MMC_HOST_PW_NOTIFY_NONE 0
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 0a72bf8..e124fbe 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -51,6 +51,7 @@
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
+#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
/* class 3 */
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
@@ -331,13 +332,76 @@
#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */
-#define EXT_CSD_CARD_TYPE_MASK 0xF /* Mask out reserved bits */
+#define EXT_CSD_CARD_TYPE_MASK 0x3F /* Mask out reserved bits */
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
/* DDR mode @1.8V or 3V I/O */
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
/* DDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
| EXT_CSD_CARD_TYPE_DDR_1_2V)
+#define EXT_CSD_CARD_TYPE_SDR_1_8V (1<<4) /* Card can run at 200MHz */
+#define EXT_CSD_CARD_TYPE_SDR_1_2V (1<<5) /* Card can run at 200MHz */
+ /* SDR mode @1.2V I/O */
+
+#define EXT_CSD_CARD_TYPE_SDR_200 (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_SDR_1_2V)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_ALL (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_ALL (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_DDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_DDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_DDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_DDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52 (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_DDR_52 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52 (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_DDR_52 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_DDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_DDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52 (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_DDR_52 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index 1f264e9..bf149eb 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -52,6 +52,11 @@
#define VEN_BUFFLAG_EXTRADATA 0x00000040
#define VEN_BUFFLAG_CODECCONFIG 0x00000080
+/*Post processing flags bit masks*/
+#define VEN_EXTRADATA_NONE 0x001
+#define VEN_EXTRADATA_QCOMFILLER 0x002
+#define VEN_EXTRADATA_SLICEINFO 0x100
+
/*ENCODER CONFIGURATION CONSTANTS*/
/*Encoded video frame types*/
@@ -257,6 +262,8 @@
#define VEN_IOCTL_GET_RECON_BUFFER_SIZE \
_IOW(VEN_IOCTLBASE_NENC, 22, struct venc_ioctl_msg)
+
+
/*ENCODER PROPERTY CONFIGURATION & CAPABILITY IOCTLs*/
/*IOCTL params:SET: InputData - venc_basecfg, OutputData - NULL
@@ -439,6 +446,14 @@
#define VEN_IOCTL_SET_METABUFFER_MODE \
_IOW(VEN_IOCTLBASE_ENC, 47, struct venc_ioctl_msg)
+
+/*IOCTL params:SET: InputData - unsigned int, OutputData - NULL.*/
+#define VEN_IOCTL_SET_EXTRADATA \
+ _IOW(VEN_IOCTLBASE_ENC, 48, struct venc_ioctl_msg)
+/*IOCTL params:GET: InputData - NULL, OutputData - unsigned int.*/
+#define VEN_IOCTL_GET_EXTRADATA \
+ _IOR(VEN_IOCTLBASE_ENC, 49, struct venc_ioctl_msg)
+
struct venc_switch{
unsigned char status;
};
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 583ceb8..60decb6 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -322,6 +322,13 @@
unsigned is_b_host:1; /* true during some HNP roleswitches */
unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */
unsigned hnp_support:1; /* OTG: HNP is supported on OTG port */
+ unsigned quick_hnp:1; /* OTG: Indiacates if hnp is required
+ irrespective of host_request flag
+ */
+ unsigned otg_vbus_off:1; /* OTG: OTG test device feature bit that
+ * tells A-device to turn off VBUS after
+ * B-device is disconnected.
+ */
struct delayed_work hnp_polling;/* OTG: HNP polling work */
unsigned sg_tablesize; /* 0 or largest number of sg list entries */
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index 736203b..ea49aa1 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -133,6 +133,12 @@
#define TEST_PACKET 4
#define TEST_FORCE_EN 5
+/* OTG test mode feature bits
+ * See ECN OTG2.0 spec Table 6-8
+ */
+#define TEST_OTG_SRP_REQD 6
+#define TEST_OTG_HNP_REQD 7
+
/*
* New Feature Selectors as added by USB 3.0
* See USB 3.0 spec Table 9-6
@@ -146,9 +152,12 @@
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
-#define OTG_STATUS_SELECTOR 0xF000
-#define THOST_REQ_POLL 2000 /* msec */
-#define HOST_REQUEST_FLAG 0
+#define OTG_STATUS_SELECTOR 0xF000
+#define HOST_REQUEST_FLAG 0
+#define THOST_REQ_POLL 1500 /* msec (1000 - 2000) */
+#define OTG_TTST_SUSP 70 /* msec (0 - 100) */
+
+#define OTG_TTST_VBUS_OFF 1
/* Bit array elements as returned by the USB_REQ_GET_STATUS request. */
#define USB_DEV_STAT_U1_ENABLED 2 /* transition into U1 state */
@@ -617,8 +626,10 @@
__u8 bDescriptorType;
__u8 bmAttributes; /* support for HNP, SRP, etc */
+ __le16 bcdOTG;
} __attribute__ ((packed));
+#define USB_DT_OTG_SIZE 5
/* from usb_otg_descriptor.bmAttributes */
#define USB_OTG_SRP (1 << 0)
#define USB_OTG_HNP (1 << 1) /* swap host/device roles */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 47e8427..35c9cd1 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -453,6 +453,9 @@
* only supports HNP on a different root port.
* @b_hnp_enable: OTG device feature flag, indicating that the A-Host
* enabled HNP support.
+ * @host_request: A flag set by user when wishes to take up host role.
+ * @otg_srp_reqd: OTG test mode feature to initiate SRP after the end of
+ * current session.
* @name: Identifies the controller hardware type. Used in diagnostics
* and sometimes configuration.
* @dev: Driver model state for this abstract device.
@@ -488,6 +491,7 @@
unsigned a_hnp_support:1;
unsigned a_alt_hnp_support:1;
unsigned host_request:1;
+ unsigned otg_srp_reqd:1;
const char *name;
struct device dev;
};
@@ -860,6 +864,11 @@
/* utility to simplify managing config descriptors */
+/* Find and fill the requested descriptor into buffer */
+int
+usb_find_descriptor_fillbuf(void *, unsigned,
+ const struct usb_descriptor_header **, u8);
+
/* write vector of descriptors into buffer */
int usb_descriptor_fillbuf(void *, unsigned,
const struct usb_descriptor_header **);
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 79fb177..f2ad7e1 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -279,6 +279,7 @@
struct msm_usb_host_platform_data {
unsigned int power_budget;
+ unsigned int dock_connect_irq;
};
struct usb_bam_pipe_connect {
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index 3e93de7..fb1ca8c 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -30,4 +30,6 @@
descriptor */
#define USB_QUIRK_DELAY_INIT 0x00000040
+#define USB_QUIRK_OTG_PET 0x00000080
+
#endif /* __LINUX_USB_QUIRKS_H */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 164d3b4..fe14055 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -570,7 +570,7 @@
struct hci_conn *hci_le_conn_add(struct hci_dev *hdev, bdaddr_t *dst,
__u8 addr_type);
int hci_conn_del(struct hci_conn *conn);
-void hci_conn_hash_flush(struct hci_dev *hdev);
+void hci_conn_hash_flush(struct hci_dev *hdev, u8 is_process);
void hci_conn_check_pending(struct hci_dev *hdev);
struct hci_chan *hci_chan_add(struct hci_dev *hdev);
@@ -751,7 +751,8 @@
int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
int (*connect_cfm) (struct hci_conn *conn, __u8 status);
int (*disconn_ind) (struct hci_conn *conn);
- int (*disconn_cfm) (struct hci_conn *conn, __u8 reason);
+ int (*disconn_cfm) (struct hci_conn *conn, __u8 reason,
+ __u8 is_process);
int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
@@ -808,17 +809,18 @@
return reason;
}
-static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
+static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason,
+ __u8 is_process)
{
register struct hci_proto *hp;
hp = hci_proto[HCI_PROTO_L2CAP];
if (hp && hp->disconn_cfm)
- hp->disconn_cfm(conn, reason);
+ hp->disconn_cfm(conn, reason, is_process);
hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->disconn_cfm)
- hp->disconn_cfm(conn, reason);
+ hp->disconn_cfm(conn, reason, is_process);
if (conn->disconn_cfm_cb)
conn->disconn_cfm_cb(conn, reason);
diff --git a/kernel/power/fbearlysuspend.c b/kernel/power/fbearlysuspend.c
index 1513765..4877372 100644
--- a/kernel/power/fbearlysuspend.c
+++ b/kernel/power/fbearlysuspend.c
@@ -19,7 +19,10 @@
#include "power.h"
+#define MAX_BUF 100
+
static wait_queue_head_t fb_state_wq;
+static int display = 1;
static DEFINE_SPINLOCK(fb_state_lock);
static enum {
FB_STATE_STOPPED_DRAWING,
@@ -71,10 +74,16 @@
ret = wait_event_interruptible(fb_state_wq,
fb_state != FB_STATE_DRAWING_OK);
- if (ret && fb_state == FB_STATE_DRAWING_OK)
+ if (ret && fb_state == FB_STATE_DRAWING_OK) {
return ret;
- else
+ } else {
s += sprintf(buf, "sleeping");
+ if (display == 1) {
+ display = 0;
+ sysfs_notify(power_kobj, NULL, "wait_for_fb_status");
+ }
+ }
+
return s - buf;
}
@@ -96,28 +105,47 @@
fb_state == FB_STATE_DRAWING_OK);
if (ret && fb_state != FB_STATE_DRAWING_OK)
return ret;
- else
+ else {
s += sprintf(buf, "awake");
-
+ if (display == 0) {
+ display = 1;
+ sysfs_notify(power_kobj, NULL, "wait_for_fb_status");
+ }
+ }
return s - buf;
}
-#define power_ro_attr(_name) \
-static struct kobj_attribute _name##_attr = { \
- .attr = { \
- .name = __stringify(_name), \
- .mode = 0444, \
- }, \
- .show = _name##_show, \
- .store = NULL, \
+static ssize_t wait_for_fb_status_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ int ret = 0;
+
+ if (display == 1)
+ ret = snprintf(buf, strnlen("on", MAX_BUF) + 1, "on");
+ else
+ ret = snprintf(buf, strnlen("off", MAX_BUF) + 1, "off");
+
+ return ret;
}
+#define power_ro_attr(_name) \
+ static struct kobj_attribute _name##_attr = { \
+ .attr = { \
+ .name = __stringify(_name), \
+ .mode = 0444, \
+ }, \
+ .show = _name##_show, \
+ .store = NULL, \
+ }
+
power_ro_attr(wait_for_fb_sleep);
power_ro_attr(wait_for_fb_wake);
+power_ro_attr(wait_for_fb_status);
static struct attribute *g[] = {
&wait_for_fb_sleep_attr.attr,
&wait_for_fb_wake_attr.attr,
+ &wait_for_fb_status_attr.attr,
NULL,
};
diff --git a/kernel/power/main.c b/kernel/power/main.c
index ff29679..6aeabf9 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -15,6 +15,8 @@
#include "power.h"
+#define MAX_BUF 100
+
DEFINE_MUTEX(pm_mutex);
#ifdef CONFIG_PM_SLEEP
@@ -23,6 +25,10 @@
static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
+static struct hrtimer in_ev_timer;
+static int input_processed;
+static ktime_t touch_evt_timer_val;
+
int register_pm_notifier(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&pm_chain_head, nb);
@@ -67,6 +73,72 @@
power_attr(pm_async);
+static ssize_t
+touch_event_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ if (input_processed == 0)
+ return snprintf(buf, strnlen("touch_event", MAX_BUF) + 1,
+ "touch_event");
+ else
+ return snprintf(buf, strnlen("null", MAX_BUF) + 1,
+ "null");
+}
+
+static ssize_t
+touch_event_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+
+ hrtimer_cancel(&in_ev_timer);
+ input_processed = 0;
+
+ /* set a timer to notify the userspace to stop processing
+ * touch event
+ */
+ hrtimer_start(&in_ev_timer, touch_evt_timer_val, HRTIMER_MODE_REL);
+
+ /* wakeup the userspace poll */
+ sysfs_notify(kobj, NULL, "touch_event");
+
+ return n;
+}
+
+power_attr(touch_event);
+
+static ssize_t
+touch_event_timer_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return snprintf(buf, MAX_BUF, "%lld", touch_evt_timer_val.tv64);
+}
+
+static ssize_t
+touch_event_timer_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned long val;
+
+ if (strict_strtoul(buf, 10, &val))
+ return -EINVAL;
+
+ touch_evt_timer_val = ktime_set(0, val*1000);
+
+ return n;
+}
+
+power_attr(touch_event_timer);
+
+static enum hrtimer_restart input_event_stop(struct hrtimer *hrtimer)
+{
+ /* wakeup the userspace poll */
+ input_processed = 1;
+ sysfs_notify(power_kobj, NULL, "touch_event");
+ return HRTIMER_NORESTART;
+}
+
#ifdef CONFIG_PM_DEBUG
int pm_test_level = TEST_NONE;
@@ -313,7 +385,9 @@
power_attr(wake_unlock);
#endif
-static struct attribute * g[] = {
+static struct attribute *g[] = {
+ &touch_event_attr.attr,
+ &touch_event_timer_attr.attr,
&state_attr.attr,
#ifdef CONFIG_PM_TRACE
&pm_trace_attr.attr,
@@ -358,6 +432,11 @@
return error;
hibernate_image_size_init();
hibernate_reserved_size_init();
+
+ touch_evt_timer_val = ktime_set(2, 0);
+ hrtimer_init(&in_ev_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ in_ev_timer.function = &input_event_stop;
+
power_kobj = kobject_create_and_add("power", NULL);
if (!power_kobj)
return -ENOMEM;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 899c538..ca33664 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -728,7 +728,7 @@
{
BT_DBG("conn %p", conn);
- hci_proto_disconn_cfm(conn, reason);
+ hci_proto_disconn_cfm(conn, reason, 0);
}
EXPORT_SYMBOL(hci_disconnect);
@@ -1027,7 +1027,7 @@
EXPORT_SYMBOL(hci_chan_modify);
/* Drop all connection on the device */
-void hci_conn_hash_flush(struct hci_dev *hdev)
+void hci_conn_hash_flush(struct hci_dev *hdev, u8 is_process)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p;
@@ -1043,7 +1043,7 @@
c->state = BT_CLOSED;
- hci_proto_disconn_cfm(c, 0x16);
+ hci_proto_disconn_cfm(c, 0x16, is_process);
hci_conn_del(c);
}
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4c2bd37..c0eb50c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -626,7 +626,7 @@
return ret;
}
-static int hci_dev_do_close(struct hci_dev *hdev)
+static int hci_dev_do_close(struct hci_dev *hdev, u8 is_process)
{
unsigned long keepflags = 0;
@@ -647,7 +647,7 @@
hci_dev_lock_bh(hdev);
inquiry_cache_flush(hdev);
- hci_conn_hash_flush(hdev);
+ hci_conn_hash_flush(hdev, is_process);
hci_dev_unlock_bh(hdev);
hci_notify(hdev, HCI_DEV_DOWN);
@@ -714,7 +714,7 @@
hdev = hci_dev_get(dev);
if (!hdev)
return -ENODEV;
- err = hci_dev_do_close(hdev);
+ err = hci_dev_do_close(hdev, 1);
hci_dev_put(hdev);
return err;
}
@@ -740,7 +740,7 @@
hci_dev_lock_bh(hdev);
inquiry_cache_flush(hdev);
- hci_conn_hash_flush(hdev);
+ hci_conn_hash_flush(hdev, 0);
hci_dev_unlock_bh(hdev);
if (hdev->flush)
@@ -953,7 +953,7 @@
if (!blocked)
return 0;
- hci_dev_do_close(hdev);
+ hci_dev_do_close(hdev, 0);
return 0;
}
@@ -1563,7 +1563,7 @@
list_del(&hdev->list);
write_unlock_bh(&hci_dev_list_lock);
- hci_dev_do_close(hdev);
+ hci_dev_do_close(hdev, 0);
for (i = 0; i < NUM_REASSEMBLY; i++)
kfree_skb(hdev->reassembly[i]);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index fec6f32..a1a5a72 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1106,9 +1106,25 @@
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
if (conn) {
- if (status && conn->state == BT_CONFIG) {
- hci_proto_connect_cfm(conn, status);
- hci_conn_put(conn);
+ if (status) {
+ mgmt_auth_failed(hdev->id, &conn->dst, status);
+ clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
+
+ if (conn->state == BT_CONFIG) {
+ conn->state = BT_CONNECTED;
+ hci_proto_connect_cfm(conn, status);
+ hci_conn_put(conn);
+ } else {
+ hci_auth_cfm(conn, status);
+ hci_conn_hold(conn);
+ conn->disc_timeout = HCI_DISCONN_TIMEOUT;
+ hci_conn_put(conn);
+ }
+
+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+ hci_encrypt_cfm(conn, status, 0x00);
+ }
}
conn->auth_initiator = 1;
}
@@ -1748,7 +1764,7 @@
if (conn->type == LE_LINK)
del_timer(&conn->smp_timer);
- hci_proto_disconn_cfm(conn, ev->reason);
+ hci_proto_disconn_cfm(conn, ev->reason, 0);
hci_conn_del(conn);
unlock:
@@ -3289,7 +3305,7 @@
if (conn) {
conn->state = BT_CLOSED;
- hci_proto_disconn_cfm(conn, ev->reason);
+ hci_proto_disconn_cfm(conn, ev->reason, 0);
hci_conn_del(conn);
}
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a3d5e34..6a95c79 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -89,7 +89,7 @@
static int l2cap_create_cfm(struct hci_chan *chan, u8 status);
static int l2cap_deaggregate(struct hci_chan *chan, struct l2cap_pinfo *pi);
static void l2cap_chan_ready(struct sock *sk);
-static void l2cap_conn_del(struct hci_conn *hcon, int err);
+static void l2cap_conn_del(struct hci_conn *hcon, int err, u8 is_process);
static u16 l2cap_get_smallest_flushto(struct l2cap_chan_list *l);
static void l2cap_set_acl_flushto(struct hci_conn *hcon, u16 flush_to);
@@ -1160,7 +1160,7 @@
return conn;
}
-static void l2cap_conn_del(struct hci_conn *hcon, int err)
+static void l2cap_conn_del(struct hci_conn *hcon, int err, u8 is_process)
{
struct l2cap_conn *conn = hcon->l2cap_data;
struct sock *sk;
@@ -1181,9 +1181,15 @@
BT_DBG("ampcon %p", l2cap_pi(sk)->ampcon);
if ((conn->hcon == hcon) || (l2cap_pi(sk)->ampcon == hcon)) {
next = l2cap_pi(sk)->next_c;
- bh_lock_sock(sk);
+ if (is_process)
+ lock_sock(sk);
+ else
+ bh_lock_sock(sk);
l2cap_chan_del(sk, err);
- bh_unlock_sock(sk);
+ if (is_process)
+ release_sock(sk);
+ else
+ bh_unlock_sock(sk);
l2cap_sock_kill(sk);
sk = next;
} else
@@ -7332,7 +7338,7 @@
case L2CAP_CID_SMP:
if (smp_sig_channel(conn, skb))
- l2cap_conn_del(conn->hcon, EACCES);
+ l2cap_conn_del(conn->hcon, EACCES, 0);
break;
default:
@@ -7407,7 +7413,7 @@
if (conn)
l2cap_conn_ready(conn);
} else
- l2cap_conn_del(hcon, bt_err(status));
+ l2cap_conn_del(hcon, bt_err(status), 0);
return 0;
}
@@ -7424,14 +7430,14 @@
return conn->disc_reason;
}
-static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
+static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason, u8 is_process)
{
BT_DBG("hcon %p reason %d", hcon, reason);
if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
return -EINVAL;
- l2cap_conn_del(hcon, bt_err(reason));
+ l2cap_conn_del(hcon, bt_err(reason), is_process);
return 0;
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 910ef77..25ad435 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2672,8 +2672,11 @@
if ((conn->auth_type & HCI_AT_DEDICATED_BONDING) &&
conn->auth_initiator && rem_cap == 0x03)
ev.auto_confirm = 1;
- else if (loc_cap == 0x01 && (rem_cap == 0x00 || rem_cap == 0x03))
+ else if (loc_cap == 0x01 && (rem_cap == 0x00 || rem_cap == 0x03)) {
+ if (!loc_mitm && !rem_mitm)
+ value = 0;
goto no_auto_confirm;
+ }
if ((!loc_mitm || rem_cap == 0x03) && (!rem_mitm || loc_cap == 0x03))
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 99c4559..f8c3bba 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -62,7 +62,7 @@
static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
static void sco_chan_del(struct sock *sk, int err);
-static int sco_conn_del(struct hci_conn *conn, int err);
+static int sco_conn_del(struct hci_conn *conn, int err, u8 is_process);
static void sco_sock_close(struct sock *sk);
static void sco_sock_kill(struct sock *sk);
@@ -135,7 +135,7 @@
return sk;
}
-static int sco_conn_del(struct hci_conn *hcon, int err)
+static int sco_conn_del(struct hci_conn *hcon, int err, u8 is_process)
{
struct sco_conn *conn = hcon->sco_data;
struct sock *sk;
@@ -148,10 +148,16 @@
/* Kill socket */
sk = sco_chan_get(conn);
if (sk) {
- bh_lock_sock(sk);
+ if (is_process)
+ lock_sock(sk);
+ else
+ bh_lock_sock(sk);
sco_sock_clear_timer(sk);
sco_chan_del(sk, err);
- bh_unlock_sock(sk);
+ if (is_process)
+ release_sock(sk);
+ else
+ bh_unlock_sock(sk);
sco_sock_kill(sk);
}
@@ -952,19 +958,19 @@
if (conn)
sco_conn_ready(conn);
} else
- sco_conn_del(hcon, bt_err(status));
+ sco_conn_del(hcon, bt_err(status), 0);
return 0;
}
-static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
+static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason, __u8 is_process)
{
BT_DBG("hcon %p reason %d", hcon, reason);
if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
return -EINVAL;
- sco_conn_del(hcon, bt_err(reason));
+ sco_conn_del(hcon, bt_err(reason), is_process);
return 0;
}
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 0d41625..11e1a67 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -8,9 +8,10 @@
use strict;
use constant BEFORE_SHORTTEXT => 0;
-use constant IN_SHORTTEXT => 1;
-use constant AFTER_SHORTTEXT => 2;
-use constant CHECK_NEXT_SHORTTEXT => 3;
+use constant IN_SHORTTEXT_BLANKLINE => 1;
+use constant IN_SHORTTEXT => 2;
+use constant AFTER_SHORTTEXT => 3;
+use constant CHECK_NEXT_SHORTTEXT => 4;
use constant SHORTTEXT_LIMIT => 75;
my $P = $0;
@@ -1233,6 +1234,7 @@
my $shorttext = BEFORE_SHORTTEXT;
my $shorttext_exspc = 0;
+ my $commit_text_present = 0;
sanitise_line_reset();
cleanup_continuation_headers();
@@ -1416,8 +1418,24 @@
my $hereprev = "$here\n$prevrawline\n$rawline\n";
if ($shorttext != AFTER_SHORTTEXT) {
+ if ($shorttext == IN_SHORTTEXT_BLANKLINE && $line=~/\S/) {
+ # the subject line was just processed,
+ # a blank line must be next
+ WARN("non-blank line after summary line\n" . $herecurr);
+ $shorttext = IN_SHORTTEXT;
+ # this non-blank line may or may not be commit text -
+ # a warning has been generated so assume it is commit
+ # text and move on
+ $commit_text_present = 1;
+ # fall through and treat this line as IN_SHORTTEXT
+ }
if ($shorttext == IN_SHORTTEXT) {
if ($line=~/^---/ || $line=~/^diff.*/) {
+ if ($commit_text_present == 0) {
+ WARN("please add commit text explaining " .
+ "*why* the change is needed\n" .
+ $herecurr);
+ }
$shorttext = AFTER_SHORTTEXT;
} elsif (length($line) > (SHORTTEXT_LIMIT +
$shorttext_exspc)
@@ -1427,7 +1445,22 @@
WARN("commit text line over " .
SHORTTEXT_LIMIT .
" characters\n" . $herecurr);
+ } elsif ($line=~/^\s*[\x21-\x39\x3b-\x7e]+:/) {
+ # this is a tag, there must be commit
+ # text by now
+ if ($commit_text_present == 0) {
+ WARN("please add commit text explaining " .
+ "*why* the change is needed\n" .
+ $herecurr);
+ # prevent duplicate warnings
+ $commit_text_present = 1;
+ }
+ } elsif ($line=~/\S/) {
+ $commit_text_present = 1;
}
+ } elsif ($shorttext == IN_SHORTTEXT_BLANKLINE) {
+ # case of non-blank line in this state handled above
+ $shorttext = IN_SHORTTEXT;
} elsif ($shorttext == CHECK_NEXT_SHORTTEXT) {
# The Subject line doesn't have to be the last header in the patch.
# Avoid moving to the IN_SHORTTEXT state until clear of all headers.
@@ -1435,16 +1468,25 @@
# text which looks like a header is definitely a header.
if ($line!~/^[\x21-\x39\x3b-\x7e]+:/) {
$shorttext = IN_SHORTTEXT;
-# Check for Subject line followed by a blank line.
+ # Check for Subject line followed by a blank line.
if (length($line) != 0) {
WARN("non-blank line after " .
"summary line\n" .
$sublinenr . $here .
"\n" . $subjectline .
"\n" . $line . "\n");
+ # this non-blank line may or may not
+ # be commit text - a warning has been
+ # generated so assume it is commit
+ # text and move on
+ $commit_text_present = 1;
}
}
+ # The next two cases are BEFORE_SHORTTEXT.
} elsif ($line=~/^Subject: \[[^\]]*\] (.*)/) {
+ # This is the subject line. Go to
+ # CHECK_NEXT_SHORTTEXT to wait for the commit
+ # text to show up.
$shorttext = CHECK_NEXT_SHORTTEXT;
$subjectline = $line;
$sublinenr = "#$linenr & ";
@@ -1455,7 +1497,10 @@
" characters\n" . $herecurr);
}
} elsif ($line=~/^ (.*)/) {
- $shorttext = IN_SHORTTEXT;
+ # Indented format, this must be the summary
+ # line (i.e. git show). There will be no more
+ # headers so we are now in the shorttext.
+ $shorttext = IN_SHORTTEXT_BLANKLINE;
$shorttext_exspc = 4;
if (length($1) > SHORTTEXT_LIMIT) {
WARN("summary line over " .
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 4d40384..2c52866 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -55,16 +55,17 @@
echo "+"
return
fi
- # If we are past a tagged commit (like
- # "v2.6.30-rc5-302-g72357d5"), we pretty print it.
- if atag="`git describe 2>/dev/null`"; then
- echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
-
- # If we don't have a tag at all we print -g{commitish}.
- else
- printf '%s%s' -g $head
- fi
fi
+ # If we are past a tagged commit (like
+ # "v2.6.30-rc5-302-g72357d5"), we pretty print it but strip
+ # off the v2.6.30-rc5 part because that's in the Makefile.
+ if atag="`git describe 2>/dev/null`"; then
+ atag="-${atag/v$KERNELVERSION-/}"
+ # If we don't have a tag at all we print -g{commitish}.
+ else
+ atag="-g$head"
+ fi
+ printf '%s' "$atag"
# Is this git on svn?
if git config --get svn-remote.svn.url >/dev/null; then
diff --git a/sound/soc/codecs/wcd9310-tables.c b/sound/soc/codecs/wcd9310-tables.c
index e0ad541..2cba59d 100644
--- a/sound/soc/codecs/wcd9310-tables.c
+++ b/sound/soc/codecs/wcd9310-tables.c
@@ -451,6 +451,22 @@
[TABLA_A_CDC_DEBUG_B4_CTL] = 1,
[TABLA_A_CDC_DEBUG_B5_CTL] = 1,
[TABLA_A_CDC_DEBUG_B6_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B1_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B2_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B3_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B4_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B5_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B6_CTL] = 1,
+ [TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS] = 1,
+ [TABLA_A_CDC_COMP1_FS_CFG] = 1,
+ [TABLA_A_CDC_COMP2_B1_CTL] = 1,
+ [TABLA_A_CDC_COMP2_B2_CTL] = 1,
+ [TABLA_A_CDC_COMP2_B3_CTL] = 1,
+ [TABLA_A_CDC_COMP2_B4_CTL] = 1,
+ [TABLA_A_CDC_COMP2_B5_CTL] = 1,
+ [TABLA_A_CDC_COMP2_B6_CTL] = 1,
+ [TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS] = 1,
+ [TABLA_A_CDC_COMP2_FS_CFG] = 1,
[TABLA_A_CDC_CONN_RX1_B1_CTL] = 1,
[TABLA_A_CDC_CONN_RX1_B2_CTL] = 1,
[TABLA_A_CDC_CONN_RX1_B3_CTL] = 1,
@@ -993,6 +1009,24 @@
[TABLA_A_CDC_DEBUG_B4_CTL] = TABLA_A_CDC_DEBUG_B4_CTL__POR,
[TABLA_A_CDC_DEBUG_B5_CTL] = TABLA_A_CDC_DEBUG_B5_CTL__POR,
[TABLA_A_CDC_DEBUG_B6_CTL] = TABLA_A_CDC_DEBUG_B6_CTL__POR,
+ [TABLA_A_CDC_COMP1_B1_CTL] = TABLA_A_CDC_COMP1_B1_CTL__POR,
+ [TABLA_A_CDC_COMP1_B2_CTL] = TABLA_A_CDC_COMP1_B2_CTL__POR,
+ [TABLA_A_CDC_COMP1_B3_CTL] = TABLA_A_CDC_COMP1_B3_CTL__POR,
+ [TABLA_A_CDC_COMP1_B4_CTL] = TABLA_A_CDC_COMP1_B4_CTL__POR,
+ [TABLA_A_CDC_COMP1_B5_CTL] = TABLA_A_CDC_COMP1_B5_CTL__POR,
+ [TABLA_A_CDC_COMP1_B6_CTL] = TABLA_A_CDC_COMP1_B6_CTL__POR,
+ [TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS] =
+ TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS__POR,
+ [TABLA_A_CDC_COMP1_FS_CFG] = TABLA_A_CDC_COMP1_FS_CFG__POR,
+ [TABLA_A_CDC_COMP2_B1_CTL] = TABLA_A_CDC_COMP2_B1_CTL__POR,
+ [TABLA_A_CDC_COMP2_B2_CTL] = TABLA_A_CDC_COMP2_B2_CTL__POR,
+ [TABLA_A_CDC_COMP2_B3_CTL] = TABLA_A_CDC_COMP2_B3_CTL__POR,
+ [TABLA_A_CDC_COMP2_B4_CTL] = TABLA_A_CDC_COMP2_B4_CTL__POR,
+ [TABLA_A_CDC_COMP2_B5_CTL] = TABLA_A_CDC_COMP2_B5_CTL__POR,
+ [TABLA_A_CDC_COMP2_B6_CTL] = TABLA_A_CDC_COMP2_B6_CTL__POR,
+ [TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS] =
+ TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS__POR,
+ [TABLA_A_CDC_COMP2_FS_CFG] = TABLA_A_CDC_COMP2_FS_CFG__POR,
[TABLA_A_CDC_CONN_RX1_B1_CTL] = TABLA_A_CDC_CONN_RX1_B1_CTL__POR,
[TABLA_A_CDC_CONN_RX1_B2_CTL] = TABLA_A_CDC_CONN_RX1_B2_CTL__POR,
[TABLA_A_CDC_CONN_RX1_B3_CTL] = TABLA_A_CDC_CONN_RX1_B3_CTL__POR,
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 082b29e..0ae9680 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -53,6 +53,7 @@
#define AIF1_CAP 2
#define AIF2_PB 3
#define NUM_CODEC_DAIS 3
+#define TABLA_COMP_DIGITAL_GAIN_OFFSET 3
struct tabla_codec_dai_data {
u32 rate;
@@ -103,6 +104,20 @@
BAND_MAX,
};
+enum {
+ COMPANDER_1 = 0,
+ COMPANDER_2,
+ COMPANDER_MAX,
+};
+
+enum {
+ COMPANDER_FS_8KHZ = 0,
+ COMPANDER_FS_16KHZ,
+ COMPANDER_FS_32KHZ,
+ COMPANDER_FS_48KHZ,
+ COMPANDER_FS_MAX,
+};
+
/* Flags to track of PA and DAC state.
* PA and DAC should be tracked separately as AUXPGA loopback requires
* only PA to be turned on without DAC being on. */
@@ -113,6 +128,13 @@
TABLA_HPHR_DAC_OFF_ACK
};
+
+struct comp_sample_dependent_params {
+ u32 peak_det_timeout;
+ u32 rms_meter_div_fact;
+ u32 rms_meter_resamp_fact;
+};
+
/* Data used by MBHC */
struct mbhc_internal_cal_data {
u16 dce_z;
@@ -210,12 +232,56 @@
/* num of slim ports required */
struct tabla_codec_dai_data dai[NUM_CODEC_DAIS];
+
+ /*compander*/
+ int comp_enabled[COMPANDER_MAX];
+ u32 comp_fs[COMPANDER_MAX];
};
#ifdef CONFIG_DEBUG_FS
struct tabla_priv *debug_tabla_priv;
#endif
+static const u32 comp_shift[] = {
+ 0,
+ 2,
+};
+
+static const int comp_rx_path[] = {
+ COMPANDER_1,
+ COMPANDER_1,
+ COMPANDER_2,
+ COMPANDER_2,
+ COMPANDER_2,
+ COMPANDER_2,
+ COMPANDER_MAX,
+};
+
+static const struct comp_sample_dependent_params comp_samp_params[] = {
+ {
+ .peak_det_timeout = 0x2,
+ .rms_meter_div_fact = 0x8 << 4,
+ .rms_meter_resamp_fact = 0x21,
+ },
+ {
+ .peak_det_timeout = 0x3,
+ .rms_meter_div_fact = 0x9 << 4,
+ .rms_meter_resamp_fact = 0x28,
+ },
+
+ {
+ .peak_det_timeout = 0x5,
+ .rms_meter_div_fact = 0xB << 4,
+ .rms_meter_resamp_fact = 0x28,
+ },
+
+ {
+ .peak_det_timeout = 0x5,
+ .rms_meter_div_fact = 0xB << 4,
+ .rms_meter_resamp_fact = 0x28,
+ },
+};
+
static int tabla_codec_enable_charge_pump(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -479,6 +545,192 @@
return 0;
}
+static int tabla_compander_gain_offset(
+ struct snd_soc_codec *codec, u32 enable,
+ unsigned int reg, int mask, int event)
+{
+ int pa_mode = snd_soc_read(codec, reg) & mask;
+ int gain_offset = 0;
+ /* if PMU && enable is 1-> offset is 3
+ * if PMU && enable is 0-> offset is 0
+ * if PMD && pa_mode is PA -> offset is 0: PMU compander is off
+ * if PMD && pa_mode is comp -> offset is -3: PMU compander is on.
+ */
+
+ if (SND_SOC_DAPM_EVENT_ON(event) && (enable != 0))
+ gain_offset = TABLA_COMP_DIGITAL_GAIN_OFFSET;
+ if (SND_SOC_DAPM_EVENT_OFF(event) && (pa_mode == 0))
+ gain_offset = -TABLA_COMP_DIGITAL_GAIN_OFFSET;
+ return gain_offset;
+}
+
+
+static int tabla_config_gain_compander(
+ struct snd_soc_codec *codec,
+ u32 compander, u32 enable, int event)
+{
+ int value = 0;
+ int mask = 1 << 4;
+ int gain = 0;
+ int gain_offset;
+ if (compander >= COMPANDER_MAX) {
+ pr_err("%s: Error, invalid compander channel\n", __func__);
+ return -EINVAL;
+ }
+
+ if ((enable == 0) || SND_SOC_DAPM_EVENT_OFF(event))
+ value = 1 << 4;
+
+ if (compander == COMPANDER_1) {
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_HPH_L_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_HPH_L_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_HPH_R_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_HPH_R_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ } else if (compander == COMPANDER_2) {
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_LINE_1_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_LINE_1_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_LINE_3_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_LINE_3_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_LINE_2_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_LINE_2_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_LINE_4_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_LINE_4_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ }
+ return 0;
+}
+static int tabla_get_compander(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ int comp = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->max;
+ struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = tabla->comp_enabled[comp];
+
+ return 0;
+}
+
+static int tabla_set_compander(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+ int comp = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->max;
+ int value = ucontrol->value.integer.value[0];
+
+ if (value == tabla->comp_enabled[comp]) {
+ pr_debug("%s: compander #%d enable %d no change\n",
+ __func__, comp, value);
+ return 0;
+ }
+ tabla->comp_enabled[comp] = value;
+ return 0;
+}
+
+
+static int tabla_config_compander(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+ u32 rate = tabla->comp_fs[w->shift];
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (tabla->comp_enabled[w->shift] != 0) {
+ /* Enable both L/R compander clocks */
+ snd_soc_update_bits(codec,
+ TABLA_A_CDC_CLK_RX_B2_CTL,
+ 0x03 << comp_shift[w->shift],
+ 0x03 << comp_shift[w->shift]);
+ /* Clar the HALT for the compander*/
+ snd_soc_update_bits(codec,
+ TABLA_A_CDC_COMP1_B1_CTL +
+ w->shift * 8, 1 << 2, 0);
+ /* Toggle compander reset bits*/
+ snd_soc_update_bits(codec,
+ TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+ 0x03 << comp_shift[w->shift],
+ 0x03 << comp_shift[w->shift]);
+ snd_soc_update_bits(codec,
+ TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+ 0x03 << comp_shift[w->shift], 0);
+ tabla_config_gain_compander(codec, w->shift, 1, event);
+ /* Update the RMS meter resampling*/
+ snd_soc_update_bits(codec,
+ TABLA_A_CDC_COMP1_B3_CTL +
+ w->shift * 8, 0xFF, 0x01);
+ /* Wait for 1ms*/
+ usleep_range(1000, 1000);
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ /* Set sample rate dependent paramater*/
+ if (tabla->comp_enabled[w->shift] != 0) {
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_FS_CFG +
+ w->shift * 8, 0x03, rate);
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
+ w->shift * 8, 0x0F,
+ comp_samp_params[rate].peak_det_timeout);
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
+ w->shift * 8, 0xF0,
+ comp_samp_params[rate].rms_meter_div_fact);
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B3_CTL +
+ w->shift * 8, 0xFF,
+ comp_samp_params[rate].rms_meter_resamp_fact);
+ /* Compander enable -> 0x370/0x378*/
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+ w->shift * 8, 0x03, 0x03);
+ }
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ /* Halt the compander*/
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+ w->shift * 8, 1 << 2, 1 << 2);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* Restore the gain */
+ tabla_config_gain_compander(codec, w->shift,
+ tabla->comp_enabled[w->shift], event);
+ /* Disable the compander*/
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+ w->shift * 8, 0x03, 0x00);
+ /* Turn off the clock for compander in pair*/
+ snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_B2_CTL,
+ 0x03 << comp_shift[w->shift], 0);
+ break;
+ }
+ return 0;
+}
+
static const char *tabla_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
static const struct soc_enum tabla_ear_pa_gain_enum[] = {
SOC_ENUM_SINGLE_EXT(2, tabla_ear_pa_gain_text),
@@ -696,6 +948,10 @@
tabla_get_iir_band_audio_mixer, tabla_put_iir_band_audio_mixer),
SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
tabla_get_iir_band_audio_mixer, tabla_put_iir_band_audio_mixer),
+ SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, 1, COMPANDER_1, 0,
+ tabla_get_compander, tabla_set_compander),
+ SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, 0, COMPANDER_2, 0,
+ tabla_get_compander, tabla_set_compander),
};
static const struct snd_kcontrol_new tabla_1_x_snd_controls[] = {
@@ -2075,6 +2331,12 @@
{"LINEOUT4 DAC", NULL, "RX_BIAS"},
{"LINEOUT5 DAC", NULL, "RX_BIAS"},
+ {"RX1 MIX1", NULL, "COMP1_CLK"},
+ {"RX2 MIX1", NULL, "COMP1_CLK"},
+ {"RX3 MIX1", NULL, "COMP2_CLK"},
+ {"RX5 MIX1", NULL, "COMP2_CLK"},
+
+
{"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
{"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
{"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
@@ -2748,6 +3010,7 @@
u8 path, shift;
u16 tx_fs_reg, rx_fs_reg;
u8 tx_fs_rate, rx_fs_rate, rx_state, tx_state;
+ u32 compander_fs;
pr_debug("%s: DAI-ID %x rate %d\n", __func__, dai->id,
params_rate(params));
@@ -2756,18 +3019,22 @@
case 8000:
tx_fs_rate = 0x00;
rx_fs_rate = 0x00;
+ compander_fs = COMPANDER_FS_8KHZ;
break;
case 16000:
tx_fs_rate = 0x01;
rx_fs_rate = 0x20;
+ compander_fs = COMPANDER_FS_16KHZ;
break;
case 32000:
tx_fs_rate = 0x02;
rx_fs_rate = 0x40;
+ compander_fs = COMPANDER_FS_32KHZ;
break;
case 48000:
tx_fs_rate = 0x03;
rx_fs_rate = 0x60;
+ compander_fs = COMPANDER_FS_48KHZ;
break;
default:
pr_err("%s: Invalid sampling rate %d\n", __func__,
@@ -2845,6 +3112,9 @@
+ (BITS_PER_REG*(path-1));
snd_soc_update_bits(codec, rx_fs_reg,
0xE0, rx_fs_rate);
+ if (comp_rx_path[shift] < COMPANDER_MAX)
+ tabla->comp_fs[comp_rx_path[shift]]
+ = compander_fs;
}
}
if (tabla->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
@@ -3229,6 +3499,13 @@
SND_SOC_DAPM_SUPPLY("LDO_H", TABLA_A_LDO_H_MODE_1, 7, 0,
tabla_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_SUPPLY("COMP1_CLK", SND_SOC_NOPM, 0, 0,
+ tabla_config_compander, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("COMP2_CLK", SND_SOC_NOPM, 1, 0,
+ tabla_config_compander, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
+
SND_SOC_DAPM_INPUT("AMIC1"),
SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TABLA_A_MICB_1_CTL, 7, 0,
tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
@@ -4989,6 +5266,10 @@
tabla->mbhc_fake_ins_start = 0;
tabla->no_mic_headset_override = false;
tabla->codec = codec;
+ for (i = 0; i < COMPANDER_MAX; i++) {
+ tabla->comp_enabled[i] = 0;
+ tabla->comp_fs[i] = COMPANDER_FS_48KHZ;
+ }
tabla->pdata = dev_get_platdata(codec->dev->parent);
tabla->intf_type = wcd9xxx_get_intf_type();
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index ff50ba6..ae4e403 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -1278,7 +1278,7 @@
};
struct snd_soc_card snd_soc_card_msm = {
- .name = "msm-snd-card",
+ .name = "apq8064-tabla-snd-card",
.dai_link = msm_dai,
.num_links = ARRAY_SIZE(msm_dai),
};
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d528f4b..76091e3 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1144,6 +1144,11 @@
struct snd_soc_codec *codec;
int i;
+ if (!card->instantiated) {
+ dev_dbg(card->dev, "uninsantiated card found card->name = %s\n",
+ card->name);
+ return 0;
+ }
/* If the initialization of this soc device failed, there is no codec
* associated with it. Just bail out in this case.
*/
@@ -1397,6 +1402,11 @@
struct snd_soc_card *card = dev_get_drvdata(dev);
int i, ac97_control = 0;
+ if (!card->instantiated) {
+ dev_dbg(card->dev, "uninsantiated card found card->name = %s\n",
+ card->name);
+ return 0;
+ }
/* AC97 devices might have other drivers hanging off them so
* need to resume immediately. Other drivers don't have that
* problem and may take a substantial amount of time to resume