Merge "defconfig: Disable OCMEM on msm8610"
diff --git a/Makefile b/Makefile
index be32c2f..0c11d69 100644
--- a/Makefile
+++ b/Makefile
@@ -864,6 +864,7 @@
# Generate .S file with all kernel symbols
quiet_cmd_kallsyms = KSYM $@
cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
+ --page-offset=$(CONFIG_PAGE_OFFSET) \
$(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
diff --git a/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi b/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi
index 8c79bb9..25e5072 100755
--- a/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi
@@ -17,7 +17,7 @@
*---------------------------------------------------------------------------*/
&mdss_mdp {
dsi_hx8389b_qhd_vid: qcom,mdss_dsi_hx8389b_qhd_video {
- qcom,mdss-dsi-panel-name = "HX8389b qhd video mode dsi panel";
+ qcom,mdss-dsi-panel-name = "hx8389b qhd video mode dsi panel";
qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
qcom,mdss-dsi-panel-type = "dsi_video_mode";
qcom,mdss-dsi-panel-destination = "display_1";
@@ -26,89 +26,35 @@
qcom,mdss-dsi-stream = <0>;
qcom,mdss-dsi-panel-width = <540>;
qcom,mdss-dsi-panel-height = <960>;
- qcom,mdss-dsi-h-front-porch = <48>;
- qcom,mdss-dsi-h-back-porch = <96>;
- qcom,mdss-dsi-h-pulse-width = <96>;
+ qcom,mdss-dsi-h-front-porch = <60>;
+ qcom,mdss-dsi-h-back-porch = <39>;
+ qcom,mdss-dsi-h-pulse-width = <39>;
qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <13>;
qcom,mdss-dsi-v-front-porch = <9>;
qcom,mdss-dsi-v-pulse-width = <3>;
- qcom,mdss-dsi-v-back-porch = <13>;
qcom,mdss-dsi-h-left-border = <0>;
qcom,mdss-dsi-h-right-border = <0>;
qcom,mdss-dsi-v-top-border = <0>;
qcom,mdss-dsi-v-bottom-border = <0>;
qcom,mdss-dsi-bpp = <24>;
+ qcom,mdss-dsi-color-order = <0>;
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
- qcom,mdss-dsi-on-command = [
- 39 01 00 00 00 00 04
- B9 FF 83 89
- 39 01 00 00 00 00 08
- BA 41 93 00
- 16 A4 10 18
- 23 01 00 00 00 00 02
- C6 08
- 39 01 00 00 00 00 03
- BC 02 00
- 23 01 00 00 00 00 02
- CC 02
- 39 01 00 00 00 00 14
- B1 00 00 07
- E8 50 10 11
- 98 f8 21 29
- 27 27 43 01
- 58 F0 00 E6
- 39 01 00 00 00 00 08
- B2 00 00 78
- 0C 07 3F 80
- 39 01 00 00 00 00 18
- b4 82 08 00
- 32 10 04 32
- 10 00 32 10
- 00 37 0a 40
- 08 37 0a 40
- 14 46 50 0a
- 39 01 00 00 00 00 39
- d5 00 00 00
- 00 01 00 00
- 00 60 00 99
- 88 AA BB 88
- 23 88 01 88
- 67 88 45 01
- 23 88 88 88
- 88 88 88 99
- BB AA 88 54
- 88 76 88 10
- 88 32 32 10
- 88 88 88 88
- 88 00 04 00
- 00 00 00 00
- 00
- 39 01 00 00 00 00 03
- CB 07 07
- 39 01 00 00 00 00 05
- BB 00 00 FF
- 80
- 39 01 00 00 00 00 04
- DE 05 58 10
- 39 01 00 00 00 00 05
- B6 00 8A 00
- 8A
- 39 01 00 00 00 00 23
- E0 01 08 0C
- 1F 25 36 12
- 35 05 09 0D
- 10 11 0F 0F
- 1C 1D 01 08
- 0C 1F 25 36
- 12 35 05 09
- 0D 10 11 0F
- 0F 1C 1D
- 05 01 00 00 96 00 02
- 11 00
- 05 01 00 00 96 00 02
- 29 00
- ];
+ qcom,mdss-dsi-on-command = [39 01 00 00 0A 00 04 B9 FF 83 89
+ 15 01 00 00 01 00 02 CC 02
+ 39 01 00 00 01 00 03 C0 43 17
+ 39 01 00 00 01 00 08 BA 41 93 00 16 A4 10 18
+ 39 01 00 00 01 00 14 B1 00 00 06 EB 59 10 11 EE EE 3A 42 3F 3F 43 01 5A F6 00 E6
+ 39 01 00 00 01 00 08 B2 00 00 78 0C 07 3F 80
+ 39 01 00 00 01 00 04 b7 00 00 50
+ 39 01 00 00 01 00 18 B4 80 08 00 32 10 04 32 10 00 32 10 00 37 0a 40 08 37 00 46 02 58 58 02
+ 39 01 00 00 01 00 39 D5 00 00 00 00 01 00 00 00 60 00 99 88 AA BB 88 23 88 01 88 67 88 45 01 23 88 88 88 88 88 88 99 BB AA 88 54 88 76 88 10 88 32 32 10 88 88 88 88 88 3C 04 00 00 00 00 00 00
+ 39 01 00 00 01 00 23 E0 05 11 16 35 3F 3F 21 43 07 0C 0F 11 12 10 10 1D 18 05 11 16 35 3F 3F 21 43 07 0C 0F 11 12 10 10 1D 18
+ 39 01 00 00 05 00 80 C1 01 00 07 13 21 29 2F 34 3B 42 48 50 58 61 69 71 79 81 88 90 98 A0 A9 B1 B9 C1 C8 CE D6 DF E6 EF F7 FF 0E 5A 73 69 36 8E 69 5F C0 00 07 13 21 29 2F 34 3B 42 48 50 58 61 69 71 79 81 88 90 98 A0 A9 B1 B9 C1 C8 CE D6 DF E6 EF F7 FF 0E 5A 73 69 36 8E 69 5F C0 00 07 13 21 29 2F 34 3B 42 48 50 58 61 69 71 79 81 88 90 98 A0 A9 B1 B9 C1 C8 CE D6 DF E6 EF F7 FF 0E 5A 73 69 36 8E 69 5F C0
+ 39 01 00 00 01 00 05 B6 00 88 00 88
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 32 00 02 29 00];
qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
05 01 00 00 78 00 02 10 00];
qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
@@ -120,7 +66,7 @@
qcom,mdss-dsi-bllp-power-mode;
qcom,mdss-dsi-lane-0-state;
qcom,mdss-dsi-lane-1-state;
- qcom,mdss-dsi-panel-timings = [97 23 17 00 4B 53 1C 27 27 03 04 00];
+ qcom,mdss-dsi-panel-timings = [87 1E 14 00 44 4B 19 21 22 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x04>;
qcom,mdss-dsi-t-clk-pre = <0x1b>;
qcom,mdss-dsi-bl-min-level = <26>;
@@ -129,6 +75,5 @@
qcom,mdss-dsi-mdp-trigger = "none";
qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
qcom,mdss-dsi-reset-sequence = <1 20>, <0 2>, <1 20>;
-
};
};
diff --git a/arch/arm/boot/dts/msm8226-v1-pm.dtsi b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
index 38ca03b..a1a8480 100644
--- a/arch/arm/boot/dts/msm8226-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
@@ -160,7 +160,7 @@
qcom,ss-power = <315>;
qcom,energy-overhead = <1027150>;
qcom,time-overhead = <2400>;
- qcom,min-cpu-mode= "spc";
+ qcom,min-cpu-mode= "standalone_pc";
qcom,sync-cpus;
};
diff --git a/arch/arm/boot/dts/msm8226-v2-pm.dtsi b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
index a0da9cc..2e9f6db 100644
--- a/arch/arm/boot/dts/msm8226-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
@@ -162,7 +162,7 @@
qcom,ss-power = <315>;
qcom,energy-overhead = <1027150>;
qcom,time-overhead = <2400>;
- qcom,min-cpu-mode= "spc";
+ qcom,min-cpu-mode= "standalone_pc";
qcom,sync-cpus;
};
diff --git a/arch/arm/boot/dts/msm8610-cdp.dtsi b/arch/arm/boot/dts/msm8610-cdp.dtsi
index d63c6e5..04eca14 100644
--- a/arch/arm/boot/dts/msm8610-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8610-cdp.dtsi
@@ -143,7 +143,11 @@
"MIC BIAS External", "Handset Mic",
"MIC BIAS Internal2", "Headset Mic",
"AMIC1", "MIC BIAS External",
- "AMIC2", "MIC BIAS Internal2";
+ "AMIC2", "MIC BIAS Internal2",
+ "MIC BIAS External", "Digital Mic1",
+ "MIC BIAS External", "Digital Mic2",
+ "DMIC1", "MIC BIAS External",
+ "DMIC2", "MIC BIAS External";
qcom,headset-jack-type-NC;
};
};
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index f9bafb4..543f59e 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -50,8 +50,8 @@
1275000 1275000 1275000 1275000 1275000
1275000 1275000>;
qti,pvs-corner-ceiling-slow = <1150000 1150000 1275000>;
- qti,pvs-corner-ceiling-nom = <1075000 1075000 1200000>;
- qti,pvs-corner-ceiling-fast = <1050000 1050000 1140000>;
+ qti,pvs-corner-ceiling-nom = <1075000 1075000 1275000>;
+ qti,pvs-corner-ceiling-fast = <1050000 1050000 1275000>;
vdd-apc-supply = <&pm8110_s2>;
vdd-mx-supply = <&pm8110_l3_ao>;
diff --git a/arch/arm/boot/dts/msm8610-v1-pm.dtsi b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
index e5aa53c..ea37413 100644
--- a/arch/arm/boot/dts/msm8610-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
@@ -160,7 +160,7 @@
qcom,ss-power = <315>;
qcom,energy-overhead = <1027150>;
qcom,time-overhead = <2400>;
- qcom,min-cpu-mode= "spc";
+ qcom,min-cpu-mode= "standalone_pc";
qcom,sync-cpus;
};
diff --git a/arch/arm/boot/dts/msm8610-v2-pm.dtsi b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
index c819c49..19fb185 100644
--- a/arch/arm/boot/dts/msm8610-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
@@ -162,7 +162,7 @@
qcom,ss-power = <315>;
qcom,energy-overhead = <1027150>;
qcom,time-overhead = <2400>;
- qcom,min-cpu-mode= "spc";
+ qcom,min-cpu-mode= "standalone_pc";
qcom,sync-cpus;
};
@@ -198,24 +198,40 @@
<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
<2 216>, /* tsens_upper_lower_int */
<41 63>, /* dino_gen_purpose_irq35 */
+ <0xff 18>, /* APC_qgicQTmrSecPhysIrptReq */
+ <0xff 19>, /* APC_qgicQTmrNonSecPhysIrptReq */
+ <0xff 35>, /* WDT_barkInt */
+ <0xff 40>, /* qtmr_phy_irq[0] */
+ <0xff 47>, /* rbif_irq[0] */
<0xff 56>, /* q6_wdog_expired_irq */
<0xff 57>, /* mss_to_apps_irq(0) */
<0xff 58>, /* mss_to_apps_irq(1) */
<0xff 59>, /* mss_to_apps_irq(2) */
<0xff 60>, /* mss_to_apps_irq(3) */
<0xff 61>, /* mss_a2_bam_irq */
+ <0xff 65>, /* o_gc_sys_irq[0] */
+ <0xff 74>, /* venus0_mmu_cirpt[1] */
+ <0xff 75>, /* venus0_mmu_cirpt[0] */
+ <0xff 78>, /* mdss_mmu_cirpt[0] */
+ <0xff 79>, /* mdss_mmu_cirpt[1] */
+ <0xff 97>, /* camss_vfe_mmu_cirpt[1] */
+ <0xff 102>, /* camss_jpeg_mmu_cirpt[1] */
+ <0xff 109>, /* ocmem_dm_nonsec_irq */
+ <0xff 131>, /* blsp1_qup_5_irq */
+ <0xff 141>, /* blsp1_uart_3_irq */
+ <0xff 155>, /* sdc1_irq(0) */
+ <0xff 157>, /* sdc2_irq(0) */
+ <0xff 161>, /* lpass_irq_out_spare[4] */
+ <0xff 162>, /* lpass_irq_out_spare[5]*/
+ <0xff 170>, /* sdc1_pwr_cmd_irq */
<0xff 173>, /* o_wcss_apss_smd_hi */
<0xff 174>, /* o_wcss_apss_smd_med */
<0xff 175>, /* o_wcss_apss_smd_low */
<0xff 176>, /* o_wcss_apss_smsm_irq */
<0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */
<0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */
- <0xff 179>, /* o_wcss_apss_asic_intr
+ <0xff 179>, /* o_wcss_apss_asic_intr */
<0xff 181>, /* o_wcss_apss_wdog_bite_and_reset_rdy */
- <0xff 161>, /* lpass_irq_out_spare[4] /
- <0xff 162>, /* lpass_irq_out_spare[5]*/
- <0xff 234>, /* lpass_irq_out_spare[6]*/
- <0xff 235>, /* lpass_irq_out_spare[7]*/
<0xff 188>, /* lpass_irq_out_apcs(0) */
<0xff 189>, /* lpass_irq_out_apcs(1) */
<0xff 190>, /* lpass_irq_out_apcs(2) */
@@ -230,12 +246,16 @@
<0xff 205>, /* rpm_ipc(25) */
<0xff 206>, /* rpm_ipc(26) */
<0xff 207>, /* rpm_ipc(27) */
+ <0xff 234>, /* lpass_irq_out_spare[6]*/
+ <0xff 235>, /* lpass_irq_out_spare[7]*/
+ <0xff 240>, /* summary_irq_kpss */
+ <0xff 253>, /* sdc2_pwr_cmd_irq */
<0xff 258>, /* rpm_ipc(28) */
<0xff 259>, /* rpm_ipc(29) */
- <0xff 275>, /* rpm_ipc(30) */
- <0xff 276>, /* rpm_ipc(31) */
<0xff 269>, /* rpm_wdog_expired_irq */
- <0xff 240>; /* summary_irq_kpss */
+ <0xff 270>, /* blsp1_bam_irq[0] */
+ <0xff 275>, /* rpm_ipc(30) */
+ <0xff 276>; /* rpm_ipc(31) */
qcom,gpio-parent = <&msmgpio>;
qcom,gpio-map = <3 1>,
diff --git a/arch/arm/boot/dts/msm8974pro-pm.dtsi b/arch/arm/boot/dts/msm8974pro-pm.dtsi
index 366faef..938a2cc 100644
--- a/arch/arm/boot/dts/msm8974pro-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm.dtsi
@@ -214,6 +214,7 @@
<50 172>, /* usb1_hs_async_wakeup_irq */
<53 104>, /* mdss_irq */
<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+ <0xff 33>, /*l2_perf_mon*/
<0xff 34>, /* APCC_qgicL2ErrorIrptReq */
<0xff 35>, /* WDT_barkInt */
<0xff 40>, /* qtimer_phy_irq */
diff --git a/arch/arm/boot/dts/msm8974pro-pma8084.dtsi b/arch/arm/boot/dts/msm8974pro-pma8084.dtsi
index 8b13387..71fbeae 100644
--- a/arch/arm/boot/dts/msm8974pro-pma8084.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pma8084.dtsi
@@ -183,6 +183,10 @@
qcom,use-phase-switching;
};
+&mdss_mdp {
+ vdd-cx-supply = <&pma8084_s2_corner>;
+};
+
&tspp {
vdd_cx-supply = <&pma8084_s2_corner>;
};
diff --git a/arch/arm/configs/fsm9xxx-perf_defconfig b/arch/arm/configs/fsm9xxx-perf_defconfig
index 37c9554..30b2346 100644
--- a/arch/arm/configs/fsm9xxx-perf_defconfig
+++ b/arch/arm/configs/fsm9xxx-perf_defconfig
@@ -185,3 +185,5 @@
CONFIG_CRYPTO_DEV_QCE=y
CONFIG_CRYPTO_DEV_OTA_CRYPTO=y
CONFIG_CRC_CCITT=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 431ac58..9af4009 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -399,3 +399,5 @@
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_CRYPTO_TWOFISH=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8226-perf_defconfig b/arch/arm/configs/msm8226-perf_defconfig
index 2a82d5b..1e32cfa 100644
--- a/arch/arm/configs/msm8226-perf_defconfig
+++ b/arch/arm/configs/msm8226-perf_defconfig
@@ -458,3 +458,5 @@
CONFIG_TOUCHSCREEN_GT9XX=y
CONFIG_GT9XX_TOUCHPANEL_DRIVER=y
CONFIG_MSM_RDBG=m
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index 58fea9e..e46bfef 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -426,3 +426,5 @@
CONFIG_SENSORS_CAPELLA_CM36283=y
CONFIG_NFC_QNCI=y
CONFIG_MSM_RDBG=m
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index da4de08..b4f21ad 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -461,3 +461,5 @@
CONFIG_CRYPTO_DEV_QCRYPTO=m
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCEDEV=m
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 4610597..fd8245f 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -554,3 +554,5 @@
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 200433d..10f2919 100755
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -98,6 +98,7 @@
CONFIG_CC_STACKPROTECTOR=y
CONFIG_CP_ACCESS=y
CONFIG_USE_OF=y
+CONFIG_SECURE_TOUCH=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -504,3 +505,5 @@
CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y
CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
CONFIG_MSM_RDBG=m
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index c106913..0b9ba76 100755
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -104,6 +104,7 @@
CONFIG_CC_STACKPROTECTOR=y
CONFIG_CP_ACCESS=y
CONFIG_USE_OF=y
+CONFIG_SECURE_TOUCH=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
diff --git a/arch/arm/configs/msm9625-perf_defconfig b/arch/arm/configs/msm9625-perf_defconfig
index 9a5aaf0..4c0a82d 100644
--- a/arch/arm/configs/msm9625-perf_defconfig
+++ b/arch/arm/configs/msm9625-perf_defconfig
@@ -319,3 +319,5 @@
CONFIG_CRC_CCITT=y
CONFIG_LIBCRC32C=y
CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/mach-msm/board-8610-gpiomux.c b/arch/arm/mach-msm/board-8610-gpiomux.c
index 03f8837..affe6bd 100644
--- a/arch/arm/mach-msm/board-8610-gpiomux.c
+++ b/arch/arm/mach-msm/board-8610-gpiomux.c
@@ -631,6 +631,28 @@
},
};
+static struct gpiomux_setting gpio_cdc_dmic_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_4MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+
+static struct msm_gpiomux_config msm_cdc_dmic_configs[] __initdata = {
+ {
+ .gpio = 100, /* DMIC CLK */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_cdc_dmic_cfg,
+ },
+ },
+ {
+ .gpio = 101, /* DMIC DATA */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_cdc_dmic_cfg,
+ },
+ },
+};
+
void __init msm8610_init_gpiomux(void)
{
int rc;
@@ -668,4 +690,7 @@
msm_gpiomux_install(msm_non_qrd_configs,
ARRAY_SIZE(msm_non_qrd_configs));
}
+ if (of_board_is_cdp())
+ msm_gpiomux_install(msm_cdc_dmic_configs,
+ ARRAY_SIZE(msm_cdc_dmic_configs));
}
diff --git a/arch/arm/mach-msm/hsic_sysmon_test.c b/arch/arm/mach-msm/hsic_sysmon_test.c
index fac6575..a910cd26 100644
--- a/arch/arm/mach-msm/hsic_sysmon_test.c
+++ b/arch/arm/mach-msm/hsic_sysmon_test.c
@@ -63,9 +63,13 @@
if (!dev)
return -ENODEV;
+ /* Add check for user buf count greater than RD_BUF_SIZE */
+ if (count > RD_BUF_SIZE)
+ count = RD_BUF_SIZE;
+
if (copy_from_user(dev->buf, ubuf, count)) {
pr_err("error copying for writing");
- return 0;
+ return -EFAULT;
}
ret = hsic_sysmon_write(id, dev->buf, count, 1000);
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index b707df1..b9dcf88 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -291,7 +291,7 @@
system_level->num_cpu_votes != num_powered_cores)
continue;
- if (latency_us < pwr_param->latency_us)
+ if (latency_us < pwr_param->latency_us && from_idle)
continue;
if (sleep_us < pwr_param->time_overhead_us)
diff --git a/arch/arm/mach-msm/pm-stats.c b/arch/arm/mach-msm/pm-stats.c
index ac4ed25..c4e52be 100644
--- a/arch/arm/mach-msm/pm-stats.c
+++ b/arch/arm/mach-msm/pm-stats.c
@@ -36,72 +36,132 @@
struct msm_pm_time_stats stats[MSM_PM_STAT_COUNT];
};
+static struct msm_pm_time_stats suspend_stats;
+
static DEFINE_SPINLOCK(msm_pm_stats_lock);
static DEFINE_PER_CPU_SHARED_ALIGNED(
struct msm_pm_cpu_time_stats, msm_pm_stats);
-
/*
- * Add the given time data to the statistics collection.
+ * Function to update stats
*/
-void msm_pm_add_stat(enum msm_pm_time_stats_id id, int64_t t)
+static void update_stats(struct msm_pm_time_stats *stats, int64_t t)
{
- unsigned long flags;
- struct msm_pm_time_stats *stats;
int64_t bt;
int i;
- spin_lock_irqsave(&msm_pm_stats_lock, flags);
- stats = __get_cpu_var(msm_pm_stats).stats;
+ if (!stats)
+ return;
- if (!stats[id].enabled)
- goto add_bail;
-
- stats[id].total_time += t;
- stats[id].count++;
+ stats->total_time += t;
+ stats->count++;
bt = t;
- do_div(bt, stats[id].first_bucket_time);
+ do_div(bt, stats->first_bucket_time);
if (bt < 1ULL << (CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT *
- (CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1)))
+ (CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1)))
i = DIV_ROUND_UP(fls((uint32_t)bt),
- CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT);
+ CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT);
else
i = CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1;
if (i >= CONFIG_MSM_IDLE_STATS_BUCKET_COUNT)
i = CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1;
- stats[id].bucket[i]++;
+ stats->bucket[i]++;
- if (t < stats[id].min_time[i] || !stats[id].max_time[i])
- stats[id].min_time[i] = t;
- if (t > stats[id].max_time[i])
- stats[id].max_time[i] = t;
+ if (t < stats->min_time[i] || !stats->max_time[i])
+ stats->min_time[i] = t;
+ if (t > stats->max_time[i])
+ stats->max_time[i] = t;
+}
+/*
+ * Add the given time data to the statistics collection.
+ */
+void msm_pm_add_stat(enum msm_pm_time_stats_id id, int64_t t)
+{
+ struct msm_pm_time_stats *stats;
+ unsigned long flags;
+
+ spin_lock_irqsave(&msm_pm_stats_lock, flags);
+ if (id == MSM_PM_STAT_SUSPEND) {
+ stats = &suspend_stats;
+ } else {
+ stats = __get_cpu_var(msm_pm_stats).stats;
+ if (!stats[id].enabled)
+ goto add_bail;
+ stats = &stats[id];
+ }
+ update_stats(stats, t);
add_bail:
spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
}
-/*
- * Write out the power management statistics.
- */
-
-static int msm_pm_stats_show(struct seq_file *m, void *v)
+static void stats_show(struct seq_file *m,
+ struct msm_pm_time_stats *stats,
+ int cpu, int suspend)
{
- int cpu;
+ int64_t bucket_time;
+ int64_t s;
+ uint32_t ns;
+ int i;
int bucket_count = CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1;
int bucket_shift = CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT;
- for_each_possible_cpu(cpu) {
- unsigned long flags;
- struct msm_pm_time_stats *stats;
- int i, id;
- int64_t bucket_time;
- int64_t s;
- uint32_t ns;
+ if (!stats || !m)
+ return;
- spin_lock_irqsave(&msm_pm_stats_lock, flags);
+ s = stats->total_time;
+ ns = do_div(s, NSEC_PER_SEC);
+ if (suspend)
+ seq_printf(m,
+ "%s:\n"
+ " count: %7d\n"
+ " total_time: %lld.%09u\n",
+ stats->name,
+ stats->count,
+ s, ns);
+ else
+ seq_printf(m,
+ "[cpu %u] %s:\n"
+ " count: %7d\n"
+ " total_time: %lld.%09u\n",
+ cpu, stats->name,
+ stats->count,
+ s, ns);
+
+ bucket_time = stats->first_bucket_time;
+ for (i = 0; i < bucket_count; i++) {
+ s = bucket_time;
+ ns = do_div(s, NSEC_PER_SEC);
+ seq_printf(m,
+ " <%6lld.%09u: %7d (%lld-%lld)\n",
+ s, ns, stats->bucket[i],
+ stats->min_time[i],
+ stats->max_time[i]);
+ bucket_time <<= bucket_shift;
+ }
+
+ seq_printf(m, " >=%6lld.%09u: %7d (%lld-%lld)\n",
+ s, ns, stats->bucket[i],
+ stats->min_time[i],
+ stats->max_time[i]);
+}
+/*
+ * Write out the power management statistics.
+ */
+static int msm_pm_stats_show(struct seq_file *m, void *v)
+{
+ int cpu;
+ int id;
+ unsigned long flags;
+
+ spin_lock_irqsave(&msm_pm_stats_lock, flags);
+
+ for_each_possible_cpu(cpu) {
+ struct msm_pm_time_stats *stats;
+
stats = per_cpu(msm_pm_stats, cpu).stats;
for (id = 0; id < MSM_PM_STAT_COUNT; id++) {
@@ -109,38 +169,14 @@
if (!stats[id].enabled)
continue;
- s = stats[id].total_time;
- ns = do_div(s, NSEC_PER_SEC);
- seq_printf(m,
- "[cpu %u] %s:\n"
- " count: %7d\n"
- " total_time: %lld.%09u\n",
- cpu, stats[id].name,
- stats[id].count,
- s, ns);
+ if (id == MSM_PM_STAT_SUSPEND)
+ continue;
- bucket_time = stats[id].first_bucket_time;
- for (i = 0; i < bucket_count; i++) {
- s = bucket_time;
- ns = do_div(s, NSEC_PER_SEC);
- seq_printf(m,
- " <%6lld.%09u: %7d (%lld-%lld)\n",
- s, ns, stats[id].bucket[i],
- stats[id].min_time[i],
- stats[id].max_time[i]);
-
- bucket_time <<= bucket_shift;
- }
-
- seq_printf(m, " >=%6lld.%09u: %7d (%lld-%lld)\n",
- s, ns, stats[id].bucket[i],
- stats[id].min_time[i],
- stats[id].max_time[i]);
+ stats_show(m, &stats[id], cpu, false);
}
-
- spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
}
-
+ stats_show(m, &suspend_stats, cpu, true);
+ spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
return 0;
}
@@ -259,14 +295,6 @@
first_bucket_time =
CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
- stats[MSM_PM_STAT_SUSPEND].name = "suspend";
- stats[MSM_PM_STAT_SUSPEND].first_bucket_time =
- CONFIG_MSM_SUSPEND_STATS_FIRST_BUCKET;
-
- stats[MSM_PM_STAT_FAILED_SUSPEND].name = "failed-suspend";
- stats[MSM_PM_STAT_FAILED_SUSPEND].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
-
stats[MSM_PM_STAT_NOT_IDLE].name = "not-idle";
stats[MSM_PM_STAT_NOT_IDLE].first_bucket_time =
CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
@@ -275,6 +303,9 @@
stats[enable_stats[i]].enabled = true;
}
+ suspend_stats.name = "system_suspend";
+ suspend_stats.first_bucket_time =
+ CONFIG_MSM_SUSPEND_STATS_FIRST_BUCKET;
d_entry = proc_create_data("msm_pm_stats", S_IRUGO | S_IWUSR | S_IWGRP,
NULL, &msm_pm_stats_fops, NULL);
diff --git a/arch/arm/mach-msm/rpm_stats.c b/arch/arm/mach-msm/rpm_stats.c
index cb8ed19..1447854 100644
--- a/arch/arm/mach-msm/rpm_stats.c
+++ b/arch/arm/mach-msm/rpm_stats.c
@@ -54,7 +54,7 @@
u32 num_records;
u32 read_idx;
u32 len;
- char buf[256];
+ char buf[320];
struct msm_rpmstats_platform_data *platform_data;
};
@@ -64,7 +64,8 @@
u64 last_entered_at;
u64 last_exited_at;
u64 accumulated;
- u32 reserved[4];
+ u32 client_votes;
+ u32 reserved[3];
};
static inline u64 get_time_in_sec(u64 counter)
@@ -98,10 +99,12 @@
actual_last_sleep = get_time_in_msec(data->accumulated);
return snprintf(buf , buflength,
- "RPM Mode:%s\n\t count:%d\n time in last mode(msec):%llu\n"
- "time since last mode(sec):%llu\n actual last sleep(msec):%llu\n",
+ "RPM Mode:%s\n\t count:%d\ntime in last mode(msec):%llu\n"
+ "time since last mode(sec):%llu\nactual last sleep(msec):%llu\n"
+ "client votes: %#010x\n\n",
stat_type, data->count, time_in_last_mode,
- time_since_last_mode, actual_last_sleep);
+ time_since_last_mode, actual_last_sleep,
+ data->client_votes);
}
static inline u32 msm_rpmstats_read_long_register_v2(void __iomem *regbase,
@@ -147,6 +150,9 @@
data.accumulated = msm_rpmstats_read_quad_register_v2(reg,
i, offsetof(struct msm_rpm_stats_data_v2,
accumulated));
+ data.client_votes = msm_rpmstats_read_long_register_v2(reg,
+ i, offsetof(struct msm_rpm_stats_data_v2,
+ client_votes));
length += msm_rpmstats_append_data_to_buf(prvdata->buf + length,
&data, sizeof(prvdata->buf) - length);
prvdata->read_idx++;
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index b6fbb3c2..cc8cf47 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -125,16 +125,38 @@
return n;
}
+struct fastrpc_buf {
+ struct ion_handle *handle;
+ void *virt;
+ ion_phys_addr_t phys;
+ int size;
+ int used;
+};
+
+struct smq_context_list;
+
struct smq_invoke_ctx {
+ struct hlist_node hn;
struct completion work;
int retval;
- atomic_t free;
+ int pid;
+ remote_arg_t *pra;
+ remote_arg_t *rpra;
+ struct fastrpc_buf obuf;
+ struct fastrpc_buf *abufs;
+ struct fastrpc_device *dev;
+ struct fastrpc_apps *apps;
+ int *fds;
+ struct ion_handle **handles;
+ int nbufs;
+ bool smmu;
+ uint32_t sc;
};
struct smq_context_list {
- struct smq_invoke_ctx *ls;
- int size;
- int last;
+ struct hlist_head pending;
+ struct hlist_head interrupted;
+ spinlock_t hlock;
};
struct fastrpc_smmu {
@@ -165,22 +187,16 @@
struct hlist_node hn;
struct ion_handle *handle;
void *virt;
+ ion_phys_addr_t phys;
uint32_t vaddrin;
uint32_t vaddrout;
int size;
};
-struct fastrpc_buf {
- struct ion_handle *handle;
- void *virt;
- ion_phys_addr_t phys;
- int size;
- int used;
-};
-
struct file_data {
spinlock_t hlock;
struct hlist_head hlst;
+ uint32_t mode;
};
struct fastrpc_device {
@@ -214,6 +230,11 @@
{
struct fastrpc_apps *me = &gfa;
if (!IS_ERR_OR_NULL(map->handle)) {
+ if (me->smmu.enabled && map->phys) {
+ ion_unmap_iommu(me->iclient, map->handle,
+ me->smmu.domain_id, 0);
+ map->phys = 0;
+ }
if (!IS_ERR_OR_NULL(map->virt)) {
ion_unmap_kernel(me->iclient, map->handle);
map->virt = 0;
@@ -263,65 +284,186 @@
return err;
}
-static int context_list_ctor(struct smq_context_list *me, int size)
+static int context_restore_interrupted(struct fastrpc_apps *me,
+ struct fastrpc_ioctl_invoke_fd *invokefd,
+ struct smq_invoke_ctx **po)
{
int err = 0;
- VERIFY(err, 0 != (me->ls = kzalloc(size, GFP_KERNEL)));
- if (err)
- goto bail;
- me->size = size / sizeof(*me->ls);
- me->last = 0;
- bail:
+ struct smq_invoke_ctx *ctx = 0, *ictx = 0;
+ struct hlist_node *pos, *n;
+ struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
+ spin_lock(&me->clst.hlock);
+ hlist_for_each_entry_safe(ictx, pos, n, &me->clst.interrupted, hn) {
+ if (ictx->pid == current->pid) {
+ if (invoke->sc != ictx->sc)
+ err = -1;
+ else {
+ ctx = ictx;
+ hlist_del(&ctx->hn);
+ hlist_add_head(&ctx->hn, &me->clst.pending);
+ }
+ break;
+ }
+ }
+ spin_unlock(&me->clst.hlock);
+ if (ctx)
+ *po = ctx;
return err;
}
-static void context_list_dtor(struct smq_context_list *me)
+static int context_alloc(struct fastrpc_apps *me, uint32_t kernel,
+ struct fastrpc_ioctl_invoke_fd *invokefd,
+ struct smq_invoke_ctx **po)
{
- kfree(me->ls);
-}
+ int err = 0, bufs, size = 0;
+ struct smq_invoke_ctx *ctx = 0;
+ struct smq_context_list *clst = &me->clst;
+ struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
-static void context_list_alloc_ctx(struct smq_context_list *me,
- struct smq_invoke_ctx **po)
-{
- int i = me->last;
- struct smq_invoke_ctx *ctx;
-
- for (;;) {
- i = i % me->size;
- ctx = &me->ls[i];
- if (atomic_read(&ctx->free) == 0)
- if (atomic_cmpxchg(&ctx->free, 0, 1) == 0)
- break;
- i++;
+ bufs = REMOTE_SCALARS_INBUFS(invoke->sc) +
+ REMOTE_SCALARS_OUTBUFS(invoke->sc);
+ if (bufs) {
+ size = bufs * sizeof(*ctx->pra);
+ if (invokefd->fds)
+ size = size + bufs * sizeof(*ctx->fds) +
+ bufs * sizeof(*ctx->handles);
}
- me->last = i;
+
+ VERIFY(err, 0 != (ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)));
+ if (err)
+ goto bail;
+
+ INIT_HLIST_NODE(&ctx->hn);
+ ctx->pra = (remote_arg_t *)(&ctx[1]);
+ ctx->fds = invokefd->fds == 0 ? 0 : (int *)(&ctx->pra[bufs]);
+ ctx->handles = invokefd->fds == 0 ? 0 :
+ (struct ion_handle **)(&ctx->fds[bufs]);
+ if (!kernel) {
+ VERIFY(err, 0 == copy_from_user(ctx->pra, invoke->pra,
+ bufs * sizeof(*ctx->pra)));
+ if (err)
+ goto bail;
+ } else {
+ memmove(ctx->pra, invoke->pra, bufs * sizeof(*ctx->pra));
+ }
+
+ if (invokefd->fds) {
+ if (!kernel) {
+ VERIFY(err, 0 == copy_from_user(ctx->fds, invokefd->fds,
+ bufs * sizeof(*ctx->fds)));
+ if (err)
+ goto bail;
+ } else {
+ memmove(ctx->fds, invokefd->fds,
+ bufs * sizeof(*ctx->fds));
+ }
+ }
+ ctx->sc = invoke->sc;
ctx->retval = -1;
+ ctx->pid = current->pid;
+ ctx->apps = me;
init_completion(&ctx->work);
+ spin_lock(&clst->hlock);
+ hlist_add_head(&ctx->hn, &clst->pending);
+ spin_unlock(&clst->hlock);
+
*po = ctx;
+bail:
+ if (ctx && err)
+ kfree(ctx);
+ return err;
}
-static void context_free(struct smq_invoke_ctx *me)
+static void context_save_interrupted(struct smq_invoke_ctx *ctx)
{
- if (me)
- atomic_set(&me->free, 0);
+ struct smq_context_list *clst = &ctx->apps->clst;
+ spin_lock(&clst->hlock);
+ hlist_del(&ctx->hn);
+ hlist_add_head(&ctx->hn, &clst->interrupted);
+ spin_unlock(&clst->hlock);
}
-static void context_notify_user(struct smq_invoke_ctx *me, int retval)
+static void add_dev(struct fastrpc_apps *me, struct fastrpc_device *dev);
+
+static void context_free(struct smq_invoke_ctx *ctx, bool lock)
{
- me->retval = retval;
- complete(&me->work);
+ struct smq_context_list *clst = &ctx->apps->clst;
+ struct fastrpc_apps *apps = ctx->apps;
+ struct ion_client *clnt = apps->iclient;
+ struct fastrpc_smmu *smmu = &apps->smmu;
+ struct fastrpc_buf *b;
+ int i, bufs;
+ if (ctx->smmu) {
+ bufs = REMOTE_SCALARS_INBUFS(ctx->sc) +
+ REMOTE_SCALARS_OUTBUFS(ctx->sc);
+ if (ctx->fds) {
+ for (i = 0; i < bufs; i++)
+ if (!IS_ERR_OR_NULL(ctx->handles[i])) {
+ ion_unmap_iommu(clnt, ctx->handles[i],
+ smmu->domain_id, 0);
+ ion_free(clnt, ctx->handles[i]);
+ }
+ }
+ iommu_detach_group(smmu->domain, smmu->group);
+ }
+ for (i = 0, b = ctx->abufs; i < ctx->nbufs; ++i, ++b)
+ free_mem(b);
+
+ kfree(ctx->abufs);
+ if (ctx->dev) {
+ add_dev(apps, ctx->dev);
+ if (ctx->obuf.handle != ctx->dev->buf.handle)
+ free_mem(&ctx->obuf);
+ }
+ if (lock)
+ spin_lock(&clst->hlock);
+ hlist_del(&ctx->hn);
+ if (lock)
+ spin_unlock(&clst->hlock);
+ kfree(ctx);
+}
+
+static void context_notify_user(struct smq_invoke_ctx *ctx, int retval)
+{
+ ctx->retval = retval;
+ complete(&ctx->work);
}
static void context_notify_all_users(struct smq_context_list *me)
{
- int i;
-
- if (!me->ls)
- return;
- for (i = 0; i < me->size; ++i) {
- if (atomic_read(&me->ls[i].free) != 0)
- complete(&me->ls[i].work);
+ struct smq_invoke_ctx *ictx = 0;
+ struct hlist_node *pos, *n;
+ spin_lock(&me->hlock);
+ hlist_for_each_entry_safe(ictx, pos, n, &me->pending, hn) {
+ complete(&ictx->work);
}
+ hlist_for_each_entry_safe(ictx, pos, n, &me->interrupted, hn) {
+ complete(&ictx->work);
+ }
+ spin_unlock(&me->hlock);
+
+}
+
+static void context_list_ctor(struct smq_context_list *me)
+{
+ INIT_HLIST_HEAD(&me->interrupted);
+ INIT_HLIST_HEAD(&me->pending);
+ spin_lock_init(&me->hlock);
+}
+
+static void context_list_dtor(struct fastrpc_apps *me,
+ struct smq_context_list *clst)
+{
+ struct smq_invoke_ctx *ictx = 0;
+ struct hlist_node *pos, *n;
+ spin_lock(&clst->hlock);
+ hlist_for_each_entry_safe(ictx, pos, n, &clst->interrupted, hn) {
+ context_free(ictx, 0);
+ }
+ hlist_for_each_entry_safe(ictx, pos, n, &clst->pending, hn) {
+ context_free(ictx, 0);
+ }
+ spin_unlock(&clst->hlock);
}
static int get_page_list(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
@@ -400,13 +542,12 @@
static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
remote_arg_t *rpra, remote_arg_t *upra,
struct fastrpc_buf *ibuf, struct fastrpc_buf **abufs,
- int *nbufs, int *fds)
+ int *nbufs, int *fds, struct ion_handle **handles)
{
struct fastrpc_apps *me = &gfa;
struct smq_invoke_buf *list;
struct fastrpc_buf *pbuf = ibuf, *obufs = 0;
struct smq_phy_page *pages;
- struct ion_handle **handles = NULL;
void *args;
int i, rlen, size, used, inh, bufs = 0, err = 0;
int inbufs = REMOTE_SCALARS_INBUFS(sc);
@@ -418,8 +559,6 @@
used = ALIGN(pbuf->used, BALIGN);
args = (void *)((char *)pbuf->virt + used);
rlen = pbuf->size - used;
- if (fds)
- handles = (struct ion_handle **)(fds + inbufs + outbufs);
for (i = 0; i < inbufs + outbufs; ++i) {
rpra[i].buf.len = pra[i].buf.len;
@@ -614,7 +753,6 @@
struct fastrpc_apps *me = &gfa;
smd_close(me->chan);
- context_list_dtor(&me->clst);
ion_client_destroy(me->iclient);
me->iclient = 0;
me->chan = 0;
@@ -667,16 +805,14 @@
spin_lock_init(&me->wrlock);
init_completion(&me->work);
mutex_init(&me->smd_mutex);
+ context_list_ctor(&me->clst);
for (i = 0; i < RPC_HASH_SZ; ++i)
INIT_HLIST_HEAD(&me->htbl[i]);
- VERIFY(err, 0 == context_list_ctor(&me->clst, SZ_4K));
- if (err)
- goto context_list_bail;
me->iclient = msm_ion_client_create(ION_HEAP_CARVEOUT_MASK,
DEVICE_NAME);
VERIFY(err, 0 == IS_ERR_OR_NULL(me->iclient));
if (err)
- goto ion_bail;
+ goto bail;
node = of_find_compatible_node(NULL, NULL,
"qcom,msm-audio-ion");
if (node)
@@ -697,9 +833,7 @@
return 0;
-ion_bail:
- context_list_dtor(&me->clst);
-context_list_bail:
+bail:
return err;
}
@@ -783,96 +917,88 @@
static int fastrpc_release_current_dsp_process(void);
-static int fastrpc_internal_invoke(struct fastrpc_apps *me, uint32_t kernel,
- struct fastrpc_ioctl_invoke *invoke, remote_arg_t *pra,
- int *fds)
+static int fastrpc_internal_invoke(struct fastrpc_apps *me, uint32_t mode,
+ uint32_t kernel,
+ struct fastrpc_ioctl_invoke_fd *invokefd)
{
- remote_arg_t *rpra = 0;
- struct fastrpc_device *dev = 0;
struct smq_invoke_ctx *ctx = 0;
- struct fastrpc_buf obuf, *abufs = 0, *b;
- struct ion_handle **handles = NULL;
+ struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
int interrupted = 0;
- uint32_t sc;
- int i, bufs, nbufs = 0, err = 0;
+ int err = 0;
- sc = invoke->sc;
- obuf.handle = 0;
+ if (!kernel) {
+ VERIFY(err, 0 == context_restore_interrupted(me, invokefd,
+ &ctx));
+ if (err)
+ goto bail;
+ if (ctx)
+ goto wait;
+ }
+
+ VERIFY(err, 0 == context_alloc(me, kernel, invokefd, &ctx));
+ if (err)
+ goto bail;
+
if (me->smmu.enabled) {
VERIFY(err, 0 == iommu_attach_group(me->smmu.domain,
me->smmu.group));
if (err)
- return err;
+ goto bail;
+ ctx->smmu = 1;
}
- if (REMOTE_SCALARS_LENGTH(sc)) {
- VERIFY(err, 0 == get_dev(me, &dev));
+ if (REMOTE_SCALARS_LENGTH(ctx->sc)) {
+ VERIFY(err, 0 == get_dev(me, &ctx->dev));
if (err)
goto bail;
- VERIFY(err, 0 == get_page_list(kernel, sc, pra, &dev->buf,
- &obuf));
+ VERIFY(err, 0 == get_page_list(kernel, ctx->sc, ctx->pra,
+ &ctx->dev->buf, &ctx->obuf));
if (err)
goto bail;
- rpra = (remote_arg_t *)obuf.virt;
- VERIFY(err, 0 == get_args(kernel, sc, pra, rpra, invoke->pra,
- &obuf, &abufs, &nbufs, fds));
+ ctx->rpra = (remote_arg_t *)ctx->obuf.virt;
+ VERIFY(err, 0 == get_args(kernel, ctx->sc, ctx->pra, ctx->rpra,
+ invoke->pra, &ctx->obuf, &ctx->abufs,
+ &ctx->nbufs, ctx->fds, ctx->handles));
if (err)
goto bail;
}
- context_list_alloc_ctx(&me->clst, &ctx);
- inv_args_pre(sc, rpra);
- VERIFY(err, 0 == fastrpc_invoke_send(me, kernel, invoke->handle, sc,
- ctx, &obuf));
+ inv_args_pre(ctx->sc, ctx->rpra);
+ if (FASTRPC_MODE_SERIAL == mode)
+ inv_args(ctx->sc, ctx->rpra, ctx->obuf.used);
+ VERIFY(err, 0 == fastrpc_invoke_send(me, kernel, invoke->handle,
+ ctx->sc, ctx, &ctx->obuf));
if (err)
goto bail;
- inv_args(sc, rpra, obuf.used);
- VERIFY(err, 0 == (interrupted =
- wait_for_completion_interruptible(&ctx->work)));
- if (err)
- goto bail;
+ if (FASTRPC_MODE_PARALLEL == mode)
+ inv_args(ctx->sc, ctx->rpra, ctx->obuf.used);
+ wait:
+ if (kernel)
+ wait_for_completion(&ctx->work);
+ else {
+ interrupted = wait_for_completion_interruptible(&ctx->work);
+ VERIFY(err, 0 == (err = interrupted));
+ if (err)
+ goto bail;
+ }
VERIFY(err, 0 == (err = ctx->retval));
if (err)
goto bail;
- VERIFY(err, 0 == put_args(kernel, sc, pra, rpra, invoke->pra));
+ VERIFY(err, 0 == put_args(kernel, ctx->sc, ctx->pra, ctx->rpra,
+ invoke->pra));
if (err)
goto bail;
bail:
- if (interrupted) {
- if (!kernel)
- (void)fastrpc_release_current_dsp_process();
- wait_for_completion(&ctx->work);
- }
- context_free(ctx);
-
- if (me->smmu.enabled) {
- bufs = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc);
- if (fds) {
- handles = (struct ion_handle **)(fds + bufs);
- for (i = 0; i < bufs; i++)
- if (!IS_ERR_OR_NULL(handles[i])) {
- ion_unmap_iommu(me->iclient, handles[i],
- me->smmu.domain_id, 0);
- ion_free(me->iclient, handles[i]);
- }
- }
- iommu_detach_group(me->smmu.domain, me->smmu.group);
- }
- for (i = 0, b = abufs; i < nbufs; ++i, ++b)
- free_mem(b);
-
- kfree(abufs);
- if (dev) {
- add_dev(me, dev);
- if (obuf.handle != dev->buf.handle)
- free_mem(&obuf);
- }
+ if (ctx && interrupted == -ERESTARTSYS)
+ context_save_interrupted(ctx);
+ else if (ctx)
+ context_free(ctx, 1);
return err;
}
static int fastrpc_create_current_dsp_process(void)
{
int err = 0;
- struct fastrpc_ioctl_invoke ioctl;
+ struct fastrpc_ioctl_invoke_fd ioctl;
struct fastrpc_apps *me = &gfa;
remote_arg_t ra[1];
int tgid = 0;
@@ -880,10 +1006,12 @@
tgid = current->tgid;
ra[0].buf.pv = &tgid;
ra[0].buf.len = sizeof(tgid);
- ioctl.handle = 1;
- ioctl.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
- ioctl.pra = ra;
- VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, 1, &ioctl, ra, 0)));
+ ioctl.inv.handle = 1;
+ ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
+ ioctl.inv.pra = ra;
+ ioctl.fds = 0;
+ VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
+ FASTRPC_MODE_PARALLEL, 1, &ioctl)));
return err;
}
@@ -891,17 +1019,19 @@
{
int err = 0;
struct fastrpc_apps *me = &gfa;
- struct fastrpc_ioctl_invoke ioctl;
+ struct fastrpc_ioctl_invoke_fd ioctl;
remote_arg_t ra[1];
int tgid = 0;
tgid = current->tgid;
ra[0].buf.pv = &tgid;
ra[0].buf.len = sizeof(tgid);
- ioctl.handle = 1;
- ioctl.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
- ioctl.pra = ra;
- VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, 1, &ioctl, ra, 0)));
+ ioctl.inv.handle = 1;
+ ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
+ ioctl.inv.pra = ra;
+ ioctl.fds = 0;
+ VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
+ FASTRPC_MODE_PARALLEL, 1, &ioctl)));
return err;
}
@@ -910,7 +1040,7 @@
struct smq_phy_page *pages,
int num)
{
- struct fastrpc_ioctl_invoke ioctl;
+ struct fastrpc_ioctl_invoke_fd ioctl;
remote_arg_t ra[3];
int err = 0;
struct {
@@ -936,10 +1066,12 @@
ra[2].buf.pv = &routargs;
ra[2].buf.len = sizeof(routargs);
- ioctl.handle = 1;
- ioctl.sc = REMOTE_SCALARS_MAKE(2, 2, 1);
- ioctl.pra = ra;
- VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, 1, &ioctl, ra, 0)));
+ ioctl.inv.handle = 1;
+ ioctl.inv.sc = REMOTE_SCALARS_MAKE(2, 2, 1);
+ ioctl.inv.pra = ra;
+ ioctl.fds = 0;
+ VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
+ FASTRPC_MODE_PARALLEL, 1, &ioctl)));
mmap->vaddrout = routargs.vaddrout;
if (err)
goto bail;
@@ -950,7 +1082,7 @@
static int fastrpc_munmap_on_dsp(struct fastrpc_apps *me,
struct fastrpc_ioctl_munmap *munmap)
{
- struct fastrpc_ioctl_invoke ioctl;
+ struct fastrpc_ioctl_invoke_fd ioctl;
remote_arg_t ra[1];
int err = 0;
struct {
@@ -965,10 +1097,12 @@
ra[0].buf.pv = &inargs;
ra[0].buf.len = sizeof(inargs);
- ioctl.handle = 1;
- ioctl.sc = REMOTE_SCALARS_MAKE(3, 1, 0);
- ioctl.pra = ra;
- VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, 1, &ioctl, ra, 0)));
+ ioctl.inv.handle = 1;
+ ioctl.inv.sc = REMOTE_SCALARS_MAKE(3, 1, 0);
+ ioctl.inv.pra = ra;
+ ioctl.fds = 0;
+ VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
+ FASTRPC_MODE_PARALLEL, 1, &ioctl)));
return err;
}
@@ -1010,7 +1144,7 @@
struct fastrpc_mmap *map = 0;
struct smq_phy_page *pages = 0;
void *buf;
- int len;
+ unsigned long len;
int num;
int err = 0;
@@ -1031,9 +1165,22 @@
VERIFY(err, 0 != (pages = kzalloc(num * sizeof(*pages), GFP_KERNEL)));
if (err)
goto bail;
- VERIFY(err, 0 < (num = buf_get_pages(buf, len, num, 1, pages, num)));
- if (err)
- goto bail;
+
+ if (me->smmu.enabled) {
+ VERIFY(err, 0 == ion_map_iommu(clnt, map->handle,
+ me->smmu.domain_id, 0,
+ SZ_4K, 0, &map->phys, &len, 0, 0));
+ if (err)
+ goto bail;
+ pages->addr = map->phys;
+ pages->size = len;
+ num = 1;
+ } else {
+ VERIFY(err, 0 < (num = buf_get_pages(buf, len, num, 1,
+ pages, num)));
+ if (err)
+ goto bail;
+ }
VERIFY(err, 0 == fastrpc_mmap_on_dsp(me, mmap, pages, num));
if (err)
@@ -1100,7 +1247,7 @@
(void)fastrpc_release_current_dsp_process();
cleanup_current_dev();
if (fdata) {
- struct fastrpc_mmap *map;
+ struct fastrpc_mmap *map = 0;
struct hlist_node *n, *pos;
file->private_data = 0;
hlist_for_each_entry_safe(map, pos, n, &fdata->hlst, hn) {
@@ -1179,48 +1326,23 @@
{
struct fastrpc_apps *me = &gfa;
struct fastrpc_ioctl_invoke_fd invokefd;
- struct fastrpc_ioctl_invoke *invoke = &invokefd.inv;
struct fastrpc_ioctl_mmap mmap;
struct fastrpc_ioctl_munmap munmap;
- remote_arg_t *pra = 0;
void *param = (char *)ioctl_param;
struct file_data *fdata = (struct file_data *)file->private_data;
- int *fds = 0;
- int bufs, size = 0, err = 0;
+ int size = 0, err = 0;
switch (ioctl_num) {
case FASTRPC_IOCTL_INVOKE_FD:
case FASTRPC_IOCTL_INVOKE:
invokefd.fds = 0;
size = (ioctl_num == FASTRPC_IOCTL_INVOKE) ?
- sizeof(*invoke) : sizeof(invokefd);
+ sizeof(invokefd.inv) : sizeof(invokefd);
VERIFY(err, 0 == copy_from_user(&invokefd, param, size));
if (err)
goto bail;
- bufs = REMOTE_SCALARS_INBUFS(invoke->sc) +
- REMOTE_SCALARS_OUTBUFS(invoke->sc);
- if (bufs) {
- size = bufs * sizeof(*pra);
- if (invokefd.fds)
- size = size + bufs * sizeof(*fds) +
- bufs * sizeof(struct ion_handle *);
- VERIFY(err, 0 != (pra = kzalloc(size, GFP_KERNEL)));
- if (err)
- goto bail;
- }
- VERIFY(err, 0 == copy_from_user(pra, invoke->pra,
- bufs * sizeof(*pra)));
- if (err)
- goto bail;
- if (invokefd.fds) {
- fds = (int *)(pra + bufs);
- VERIFY(err, 0 == copy_from_user(fds, invokefd.fds,
- bufs * sizeof(*fds)));
- if (err)
- goto bail;
- }
- VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, 0, invoke,
- pra, fds)));
+ VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, fdata->mode,
+ 0, &invokefd)));
if (err)
goto bail;
break;
@@ -1247,12 +1369,22 @@
if (err)
goto bail;
break;
+ case FASTRPC_IOCTL_SETMODE:
+ switch ((uint32_t)ioctl_param) {
+ case FASTRPC_MODE_PARALLEL:
+ case FASTRPC_MODE_SERIAL:
+ fdata->mode = (uint32_t)ioctl_param;
+ break;
+ default:
+ err = -ENOTTY;
+ break;
+ }
+ break;
default:
err = -ENOTTY;
break;
}
bail:
- kfree(pra);
return err;
}
@@ -1307,7 +1439,9 @@
{
struct fastrpc_apps *me = &gfa;
+ context_list_dtor(me, &me->clst);
fastrpc_deinit();
+ cleanup_current_dev();
device_destroy(me->class, MKDEV(MAJOR(me->dev_no), 0));
class_destroy(me->class);
cdev_del(&me->cdev);
diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h
index da70eb5..f5d7450 100644
--- a/drivers/char/adsprpc_shared.h
+++ b/drivers/char/adsprpc_shared.h
@@ -20,9 +20,16 @@
#define FASTRPC_IOCTL_MMAP _IOWR('R', 2, struct fastrpc_ioctl_mmap)
#define FASTRPC_IOCTL_MUNMAP _IOWR('R', 3, struct fastrpc_ioctl_munmap)
#define FASTRPC_IOCTL_INVOKE_FD _IOWR('R', 4, struct fastrpc_ioctl_invoke_fd)
+#define FASTRPC_IOCTL_SETMODE _IOWR('R', 5, uint32_t)
#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
#define DEVICE_NAME "adsprpc-smd"
+/* Driver should operate in parallel with the co-processor */
+#define FASTRPC_MODE_PARALLEL 0
+
+/* Driver should operate in serial mode with the co-processor */
+#define FASTRPC_MODE_SERIAL 1
+
/* Retrives number of input buffers from the scalars parameter */
#define REMOTE_SCALARS_INBUFS(sc) (((sc) >> 16) & 0x0ff)
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index 03304dc..c9be39a 100644
--- a/drivers/char/diag/diag_dci.h
+++ b/drivers/char/diag/diag_dci.h
@@ -24,7 +24,7 @@
#define DISABLE_LOG_MASK 0
#define MAX_EVENT_SIZE 512
#define DCI_CLIENT_INDEX_INVALID -1
-#define DCI_PKT_REQ_MIN_LEN 8
+#define DCI_PKT_REQ_MIN_LEN 5
#define DCI_LOG_CON_MIN_LEN 14
#define DCI_EVENT_CON_MIN_LEN 16
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 4f5893c..8f7d39c 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -318,6 +318,7 @@
show_one(down_differential, down_differential);
show_one(sampling_down_factor, sampling_down_factor);
show_one(ignore_nice_load, ignore_nice);
+show_one(down_differential_multi_core, down_differential_multi_core);
show_one(optimal_freq, optimal_freq);
show_one(up_threshold_any_cpu_load, up_threshold_any_cpu_load);
show_one(sync_freq, sync_freq);
@@ -437,6 +438,20 @@
return count;
}
+static ssize_t store_down_differential_multi_core(struct kobject *a,
+ struct attribute *b, const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+ dbs_tuners_ins.down_differential_multi_core = input;
+ return count;
+}
+
+
static ssize_t store_optimal_freq(struct kobject *a, struct attribute *b,
const char *buf, size_t count)
{
@@ -695,6 +710,7 @@
define_one_global_rw(ignore_nice_load);
define_one_global_rw(powersave_bias);
define_one_global_rw(up_threshold_multi_core);
+define_one_global_rw(down_differential_multi_core);
define_one_global_rw(optimal_freq);
define_one_global_rw(up_threshold_any_cpu_load);
define_one_global_rw(sync_freq);
@@ -710,6 +726,7 @@
&powersave_bias.attr,
&io_is_busy.attr,
&up_threshold_multi_core.attr,
+ &down_differential_multi_core.attr,
&optimal_freq.attr,
&up_threshold_any_cpu_load.attr,
&sync_freq.attr,
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 0809308..514385c 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -36,6 +36,7 @@
#include <linux/uaccess.h>
#include <linux/debugfs.h>
#include <linux/dma-buf.h>
+#include <linux/idr.h>
#include <linux/msm_ion.h>
#include <trace/events/kmem.h>
@@ -70,6 +71,7 @@
* @node: node in the tree of all clients
* @dev: backpointer to ion device
* @handles: an rb tree of all the handles in this client
+ * @idr: an idr space for allocating handle ids
* @lock: lock protecting the tree of handles
* @name: used for debugging
* @task: used for debugging
@@ -82,6 +84,7 @@
struct rb_node node;
struct ion_device *dev;
struct rb_root handles;
+ struct idr idr;
struct mutex lock;
char *name;
struct task_struct *task;
@@ -96,7 +99,7 @@
* @buffer: pointer to the buffer
* @node: node in the client's handle rbtree
* @kmap_cnt: count of times this client has mapped to kernel
- * @dmap_cnt: count of times this client has mapped for dma
+ * @id: client-unique id allocated by client->idr
*
* Modifications to node, map_cnt or mapping should be protected by the
* lock in the client. Other fields are never changed after initialization.
@@ -107,6 +110,7 @@
struct ion_buffer *buffer;
struct rb_node node;
unsigned int kmap_cnt;
+ int id;
};
bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer)
@@ -343,6 +347,7 @@
ion_handle_kmap_put(handle);
mutex_unlock(&buffer->lock);
+ idr_remove(&client->idr, handle->id);
if (!RB_EMPTY_NODE(&handle->node))
rb_erase(&handle->node, &client->handles);
@@ -362,9 +367,16 @@
kref_get(&handle->ref);
}
-static int ion_handle_put(struct ion_handle *handle)
+int ion_handle_put(struct ion_handle *handle)
{
- return kref_put(&handle->ref, ion_handle_destroy);
+ struct ion_client *client = handle->client;
+ int ret;
+
+ mutex_lock(&client->lock);
+ ret = kref_put(&handle->ref, ion_handle_destroy);
+ mutex_unlock(&client->lock);
+
+ return ret;
}
static struct ion_handle *ion_handle_lookup(struct ion_client *client,
@@ -374,36 +386,52 @@
for (n = rb_first(&client->handles); n; n = rb_next(n)) {
struct ion_handle *handle = rb_entry(n, struct ion_handle,
- node);
+ node);
if (handle->buffer == buffer)
return handle;
}
return NULL;
}
-static bool ion_handle_validate(struct ion_client *client, struct ion_handle *handle)
+struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
+ int id)
{
- struct rb_node *n = client->handles.rb_node;
+ struct ion_handle *handle;
- while (n) {
- struct ion_handle *handle_node = rb_entry(n, struct ion_handle,
- node);
- if (handle < handle_node)
- n = n->rb_left;
- else if (handle > handle_node)
- n = n->rb_right;
- else
- return true;
- }
- return false;
+ mutex_lock(&client->lock);
+ handle = idr_find(&client->idr, id);
+ if (handle)
+ ion_handle_get(handle);
+ mutex_unlock(&client->lock);
+
+ return handle ? handle : ERR_PTR(-EINVAL);
}
-static void ion_handle_add(struct ion_client *client, struct ion_handle *handle)
+static bool ion_handle_validate(struct ion_client *client, struct ion_handle *handle)
{
+ WARN_ON(!mutex_is_locked(&client->lock));
+ return (idr_find(&client->idr, handle->id) == handle);
+}
+
+static int ion_handle_add(struct ion_client *client, struct ion_handle *handle)
+{
+ int rc;
struct rb_node **p = &client->handles.rb_node;
struct rb_node *parent = NULL;
struct ion_handle *entry;
+ do {
+ int id;
+ rc = idr_pre_get(&client->idr, GFP_KERNEL);
+ if (!rc)
+ return -ENOMEM;
+ rc = idr_get_new_above(&client->idr, handle, 1, &id);
+ handle->id = id;
+ } while (rc == -EAGAIN);
+
+ if (rc < 0)
+ return rc;
+
while (*p) {
parent = *p;
entry = rb_entry(parent, struct ion_handle, node);
@@ -418,6 +446,8 @@
rb_link_node(&handle->node, parent, p);
rb_insert_color(&handle->node, &client->handles);
+
+ return 0;
}
struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
@@ -428,6 +458,7 @@
struct ion_device *dev = client->dev;
struct ion_buffer *buffer = NULL;
struct ion_heap *heap;
+ int ret;
unsigned long secure_allocation = flags & ION_FLAG_SECURE;
const unsigned int MAX_DBG_STR_LEN = 64;
char dbg_str[MAX_DBG_STR_LEN];
@@ -518,12 +549,16 @@
*/
ion_buffer_put(buffer);
- if (!IS_ERR(handle)) {
- mutex_lock(&client->lock);
- ion_handle_add(client, handle);
- mutex_unlock(&client->lock);
- }
+ if (IS_ERR(handle))
+ return handle;
+ mutex_lock(&client->lock);
+ ret = ion_handle_add(client, handle);
+ mutex_unlock(&client->lock);
+ if (ret) {
+ ion_handle_put(handle);
+ handle = ERR_PTR(ret);
+ }
return handle;
}
@@ -542,8 +577,8 @@
mutex_unlock(&client->lock);
return;
}
- ion_handle_put(handle);
mutex_unlock(&client->lock);
+ ion_handle_put(handle);
}
EXPORT_SYMBOL(ion_free);
@@ -775,6 +810,7 @@
client->dev = dev;
client->handles = RB_ROOT;
+ idr_init(&client->idr);
mutex_init(&client->lock);
client->name = kzalloc(name_len+1, GFP_KERNEL);
@@ -831,6 +867,10 @@
node);
ion_handle_destroy(&handle->ref);
}
+
+ idr_remove_all(&client->idr);
+ idr_destroy(&client->idr);
+
down_write(&dev->lock);
if (client->task)
put_task_struct(client->task);
@@ -1175,14 +1215,15 @@
mutex_lock(&client->lock);
valid_handle = ion_handle_validate(client, handle);
- mutex_unlock(&client->lock);
if (!valid_handle) {
WARN(1, "%s: invalid handle passed to share.\n", __func__);
+ mutex_unlock(&client->lock);
return ERR_PTR(-EINVAL);
}
-
buffer = handle->buffer;
ion_buffer_get(buffer);
+ mutex_unlock(&client->lock);
+
dmabuf = dma_buf_export(buffer, &dma_buf_ops, buffer->size, O_RDWR);
if (IS_ERR(dmabuf)) {
ion_buffer_put(buffer);
@@ -1215,6 +1256,7 @@
struct dma_buf *dmabuf;
struct ion_buffer *buffer;
struct ion_handle *handle;
+ int ret;
dmabuf = dma_buf_get(fd);
if (IS_ERR_OR_NULL(dmabuf))
@@ -1234,14 +1276,24 @@
handle = ion_handle_lookup(client, buffer);
if (!IS_ERR_OR_NULL(handle)) {
ion_handle_get(handle);
+ mutex_unlock(&client->lock);
goto end;
}
+ mutex_unlock(&client->lock);
+
handle = ion_handle_create(client, buffer);
if (IS_ERR_OR_NULL(handle))
goto end;
- ion_handle_add(client, handle);
-end:
+
+ mutex_lock(&client->lock);
+ ret = ion_handle_add(client, handle);
mutex_unlock(&client->lock);
+ if (ret) {
+ ion_handle_put(handle);
+ handle = ERR_PTR(ret);
+ }
+
+end:
dma_buf_put(dmabuf);
return handle;
}
@@ -1279,17 +1331,20 @@
case ION_IOC_ALLOC:
{
struct ion_allocation_data data;
+ struct ion_handle *handle;
if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
return -EFAULT;
- data.handle = ion_alloc(client, data.len, data.align,
+ handle = ion_alloc(client, data.len, data.align,
data.heap_mask, data.flags);
- if (IS_ERR(data.handle))
- return PTR_ERR(data.handle);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+
+ data.handle = (ion_user_handle_t)handle->id;
if (copy_to_user((void __user *)arg, &data, sizeof(data))) {
- ion_free(client, data.handle);
+ ion_free(client, handle);
return -EFAULT;
}
break;
@@ -1297,28 +1352,31 @@
case ION_IOC_FREE:
{
struct ion_handle_data data;
- bool valid;
+ struct ion_handle *handle;
if (copy_from_user(&data, (void __user *)arg,
sizeof(struct ion_handle_data)))
return -EFAULT;
- mutex_lock(&client->lock);
- valid = ion_handle_validate(client, data.handle);
- mutex_unlock(&client->lock);
- if (!valid)
- return -EINVAL;
- ion_free(client, data.handle);
+ handle = ion_handle_get_by_id(client, (int)data.handle);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ ion_free(client, handle);
+ ion_handle_put(handle);
break;
}
case ION_IOC_SHARE:
case ION_IOC_MAP:
{
struct ion_fd_data data;
+ struct ion_handle *handle;
if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
return -EFAULT;
- data.fd = ion_share_dma_buf_fd(client, data.handle);
-
+ handle = ion_handle_get_by_id(client, (int)data.handle);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ data.fd = ion_share_dma_buf_fd(client, handle);
+ ion_handle_put(handle);
if (copy_to_user((void __user *)arg, &data, sizeof(data)))
return -EFAULT;
if (data.fd < 0)
@@ -1328,15 +1386,17 @@
case ION_IOC_IMPORT:
{
struct ion_fd_data data;
+ struct ion_handle *handle;
int ret = 0;
if (copy_from_user(&data, (void __user *)arg,
sizeof(struct ion_fd_data)))
return -EFAULT;
- data.handle = ion_import_dma_buf(client, data.fd);
- if (IS_ERR(data.handle)) {
- ret = PTR_ERR(data.handle);
- data.handle = NULL;
- }
+ handle = ion_import_dma_buf(client, data.fd);
+ if (IS_ERR(handle))
+ ret = PTR_ERR(handle);
+ else
+ data.handle = (ion_user_handle_t)handle->id;
+
if (copy_to_user((void __user *)arg, &data,
sizeof(struct ion_fd_data)))
return -EFAULT;
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index f5d0287..aa0a9e2 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -396,4 +396,9 @@
int ion_walk_heaps(struct ion_client *client, int heap_id, void *data,
int (*f)(struct ion_heap *heap, void *data));
+struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
+ int id);
+
+int ion_handle_put(struct ion_handle *handle);
+
#endif /* _ION_PRIV_H */
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index 213bcb1..cdd31e1 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -973,11 +973,18 @@
sizeof(struct ion_flush_data)))
return -EFAULT;
- if (!data.handle) {
+ if (data.handle >= 0) {
+ handle = ion_handle_get_by_id(client, (int)data.handle);
+ if (IS_ERR(handle)) {
+ pr_info("%s: Could not find handle: %d\n",
+ __func__, (int)data.handle);
+ return PTR_ERR(handle);
+ }
+ } else {
handle = ion_import_dma_buf(client, data.fd);
if (IS_ERR(handle)) {
- pr_info("%s: Could not import handle: %d\n",
- __func__, (int)handle);
+ pr_info("%s: Could not import handle: %p\n",
+ __func__, handle);
return -EINVAL;
}
}
@@ -988,28 +995,20 @@
end = (unsigned long) data.vaddr + data.length;
if (start && check_vaddr_bounds(start, end)) {
- up_read(&mm->mmap_sem);
pr_err("%s: virtual address %p is out of bounds\n",
__func__, data.vaddr);
- if (!data.handle)
- ion_free(client, handle);
- return -EINVAL;
+ ret = -EINVAL;
+ } else {
+ ret = ion_do_cache_op(client, handle, data.vaddr,
+ data.offset, data.length, cmd);
}
-
- ret = ion_do_cache_op(client,
- data.handle ? data.handle : handle,
- data.vaddr, data.offset, data.length,
- cmd);
-
up_read(&mm->mmap_sem);
- if (!data.handle)
- ion_free(client, handle);
+ ion_free(client, handle);
if (ret < 0)
return ret;
break;
-
}
case ION_IOC_PREFETCH:
{
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index e5f5ad7..3d4c66a 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -4077,6 +4077,7 @@
static int a3xx_perfcounter_init(struct adreno_device *adreno_dev)
{
int ret;
+ struct kgsl_device *device = &adreno_dev->dev;
/* SP[3] counter is broken on a330 so disable it if a330 device */
if (adreno_is_a330(adreno_dev))
a3xx_perfcounters_sp[3].countable = KGSL_PERFCOUNTER_BROKEN;
@@ -4088,15 +4089,18 @@
ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_PWR, 1,
NULL, PERFCOUNTER_FLAG_KERNEL);
- /* VBIF waiting for RAM */
- ret |= adreno_perfcounter_get(adreno_dev,
+ if (device->pwrctrl.bus_control) {
+ /* VBIF waiting for RAM */
+ ret |= adreno_perfcounter_get(adreno_dev,
KGSL_PERFCOUNTER_GROUP_VBIF_PWR, 0,
NULL, PERFCOUNTER_FLAG_KERNEL);
- /* VBIF DDR cycles */
- ret |= adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_VBIF,
+ /* VBIF DDR cycles */
+ ret |= adreno_perfcounter_get(adreno_dev,
+ KGSL_PERFCOUNTER_GROUP_VBIF,
VBIF_AXI_TOTAL_BEATS,
&adreno_dev->ram_cycles_lo,
PERFCOUNTER_FLAG_KERNEL);
+ }
/* Default performance counter profiling to false */
adreno_dev->profile.enabled = false;
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index fe99a4b..9aefda6 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2878,7 +2878,7 @@
bool full_flush = false;
if (param->id_list == NULL || param->count == 0
- || param->count > (UINT_MAX/sizeof(unsigned int)))
+ || param->count > (PAGE_SIZE / sizeof(unsigned int)))
return -EINVAL;
id_list = kzalloc(param->count * sizeof(unsigned int), GFP_KERNEL);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 2be1f01..59b648d 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -122,6 +122,8 @@
{
int i, rc = -1;
struct msm_isp_buffer_mapped_info *mapped_info;
+ struct buffer_cmd *buf_pending = NULL;
+
for (i = 0; i < v4l2_buf->length; i++) {
mapped_info = &buf_info->mapped_info[i];
mapped_info->handle =
@@ -144,6 +146,15 @@
mapped_info->paddr += v4l2_buf->m.planes[i].data_offset;
CDBG("%s: plane: %d addr:%lu\n",
__func__, i, mapped_info->paddr);
+
+ buf_pending = kzalloc(sizeof(struct buffer_cmd), GFP_ATOMIC);
+ if (!buf_pending) {
+ pr_err("No free memory for buf_pending\n");
+ return rc;
+ }
+
+ buf_pending->mapped_info = mapped_info;
+ list_add_tail(&buf_pending->list, &buf_mgr->buffer_q);
}
buf_info->num_planes = v4l2_buf->length;
return 0;
@@ -163,11 +174,26 @@
{
int i;
struct msm_isp_buffer_mapped_info *mapped_info;
+ struct buffer_cmd *buf_pending = NULL;
+
for (i = 0; i < buf_info->num_planes; i++) {
mapped_info = &buf_info->mapped_info[i];
- ion_unmap_iommu(buf_mgr->client, mapped_info->handle,
- buf_mgr->iommu_domain_num, 0);
- ion_free(buf_mgr->client, mapped_info->handle);
+
+ list_for_each_entry(buf_pending, &buf_mgr->buffer_q, list) {
+ if (!buf_pending)
+ break;
+
+ if (buf_pending->mapped_info == mapped_info) {
+ ion_unmap_iommu(buf_mgr->client,
+ mapped_info->handle,
+ buf_mgr->iommu_domain_num, 0);
+ ion_free(buf_mgr->client, mapped_info->handle);
+
+ list_del_init(&buf_pending->list);
+ kfree(buf_pending);
+ break;
+ }
+ }
}
return;
}
@@ -586,7 +612,7 @@
}
} else {
bufq = msm_isp_get_bufq(buf_mgr, info->handle);
- if (BUF_SRC(bufq->stream_id)) {
+ if (bufq && BUF_SRC(bufq->stream_id)) {
rc = msm_isp_put_buf(buf_mgr,
info->handle, info->buf_idx);
if (rc < 0) {
@@ -691,6 +717,7 @@
if (!bufq->bufq_handle)
continue;
msm_isp_buf_unprepare(buf_mgr, bufq->bufq_handle);
+
kfree(bufq->bufs);
msm_isp_free_buf_handle(buf_mgr, bufq->bufq_handle);
}
@@ -739,9 +766,10 @@
pr_err("Invalid buffer queue number\n");
return rc;
}
-
CDBG("%s: E\n", __func__);
+
msm_isp_attach_ctx(buf_mgr);
+ INIT_LIST_HEAD(&buf_mgr->buffer_q);
buf_mgr->num_buf_q = num_buf_q;
buf_mgr->bufq =
kzalloc(sizeof(struct msm_isp_bufq) * num_buf_q,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
index 6d6ff9d..d8d3ba2 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
@@ -44,6 +44,11 @@
struct ion_handle *handle;
};
+struct buffer_cmd {
+ struct list_head list;
+ struct msm_isp_buffer_mapped_info *mapped_info;
+};
+
struct msm_isp_buffer {
/*Common Data structure*/
int num_planes;
@@ -138,6 +143,7 @@
int num_iommu_ctx;
struct device *iommu_ctx[2];
+ struct list_head buffer_q;
};
int msm_isp_create_isp_buf_mgr(struct msm_isp_buf_mgr *buf_mgr,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
index 2c5e136..80a0073 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
@@ -140,6 +140,7 @@
&vfe_vb2_ops, &vfe_layout);
if (rc < 0) {
pr_err("%s: Unable to create buffer manager\n", __func__);
+ msm_sd_unregister(&vfe_dev->subdev);
kfree(vfe_dev);
return -EINVAL;
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index 87bffde..9dd0085 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -106,7 +106,7 @@
uint32_t reload_mask);
void (*enable_wm) (struct vfe_device *vfe_dev,
uint8_t wm_idx, uint8_t enable);
- void (*cfg_io_format) (struct vfe_device *vfe_dev,
+ int32_t (*cfg_io_format) (struct vfe_device *vfe_dev,
enum msm_vfe_axi_stream_src stream_src,
uint32_t io_format);
void (*cfg_framedrop) (struct vfe_device *vfe_dev,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index f5529cd..410fe8f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -74,6 +74,8 @@
goto fs_failed;
}
}
+ else
+ goto fs_failed;
rc = msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_1_clk_info,
vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_1_clk_info), 1);
@@ -495,12 +497,17 @@
}
}
-static void msm_vfe32_cfg_io_format(struct vfe_device *vfe_dev,
+static int32_t msm_vfe32_cfg_io_format(struct vfe_device *vfe_dev,
enum msm_vfe_axi_stream_src stream_src, uint32_t io_format)
{
int bpp, bpp_reg = 0, pack_fmt = 0, pack_reg = 0;
uint32_t io_format_reg;
bpp = msm_isp_get_bit_per_pixel(io_format);
+ if (bpp < 0) {
+ pr_err("%s:%d invalid io_format %d bpp %d", __func__, __LINE__,
+ io_format, bpp);
+ return -EINVAL;
+ }
switch (bpp) {
case 8:
@@ -512,6 +519,9 @@
case 12:
bpp_reg = 1 << 1;
break;
+ default:
+ pr_err("%s:%d invalid bpp %d", __func__, __LINE__, bpp);
+ return -EINVAL;
}
if (stream_src == IDEAL_RAW) {
@@ -537,7 +547,7 @@
break;
default:
pr_err("%s: invalid pack fmt!\n", __func__);
- return;
+ return -EINVAL;
}
}
@@ -558,9 +568,10 @@
case RDI_INTF_2:
default:
pr_err("%s: Invalid stream source\n", __func__);
- return;
+ return -EINVAL;
}
msm_camera_io_w(io_format_reg, vfe_dev->vfe_base + 0x6F8);
+ return 0;
}
static void msm_vfe32_cfg_camif(struct vfe_device *vfe_dev,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index 50a25bd..ad4b75f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -268,6 +268,8 @@
goto fs_failed;
}
}
+ else
+ goto fs_failed;
rc = msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe40_clk_info,
vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe40_clk_info), 1);
@@ -724,13 +726,18 @@
VFE40_WM_BASE(stream_info->wm[i]) + 0x1C);
}
-static void msm_vfe40_cfg_io_format(struct vfe_device *vfe_dev,
+static int32_t msm_vfe40_cfg_io_format(struct vfe_device *vfe_dev,
enum msm_vfe_axi_stream_src stream_src, uint32_t io_format)
{
int bpp, bpp_reg = 0, pack_reg = 0;
enum msm_isp_pack_fmt pack_fmt = 0;
uint32_t io_format_reg; /*io format register bit*/
bpp = msm_isp_get_bit_per_pixel(io_format);
+ if (bpp < 0) {
+ pr_err("%s:%d invalid io_format %d bpp %d", __func__, __LINE__,
+ io_format, bpp);
+ return -EINVAL;
+ }
switch (bpp) {
case 8:
@@ -742,6 +749,9 @@
case 12:
bpp_reg = 1 << 1;
break;
+ default:
+ pr_err("%s:%d invalid bpp %d", __func__, __LINE__, bpp);
+ return -EINVAL;
}
if (stream_src == IDEAL_RAW) {
@@ -768,7 +778,7 @@
break;
default:
pr_err("%s: invalid pack fmt!\n", __func__);
- return;
+ return -EINVAL;
}
}
@@ -789,9 +799,10 @@
case RDI_INTF_2:
default:
pr_err("%s: Invalid stream source\n", __func__);
- return;
+ return -EINVAL;
}
msm_camera_io_w(io_format_reg, vfe_dev->vfe_base + 0x54);
+ return 0;
}
static void msm_vfe40_cfg_camif(struct vfe_device *vfe_dev,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 3202cdb..97b6347 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -68,9 +68,17 @@
struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
{
int rc = -1, i;
- struct msm_vfe_axi_stream *stream_info =
- &axi_data->stream_info[
- HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
+ struct msm_vfe_axi_stream *stream_info = NULL;
+ uint32_t idx = 0;
+
+ if (NULL == stream_cfg_cmd || NULL == axi_data)
+ return rc;
+
+ idx = HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle);
+ if (idx < MAX_NUM_STREAM)
+ stream_info = &axi_data->stream_info[idx];
+ else
+ return rc;
switch (stream_cfg_cmd->output_format) {
case V4L2_PIX_FMT_SBGGR8:
@@ -428,11 +436,22 @@
struct msm_vfe_axi_shared_data *axi_data,
struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
{
- struct msm_vfe_axi_stream *stream_info =
- &axi_data->stream_info[
- HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
- uint32_t framedrop_period = msm_isp_get_framedrop_period(
- stream_cfg_cmd->frame_skip_pattern);
+ struct msm_vfe_axi_stream *stream_info = NULL;
+ uint32_t framedrop_period = 0;
+ uint8_t idx = 0;
+
+ if (NULL == axi_data || NULL == stream_cfg_cmd)
+ return;
+
+ idx = HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle);
+
+ if (idx < MAX_NUM_STREAM)
+ stream_info = &axi_data->stream_info[idx];
+ else
+ return;
+
+ framedrop_period = msm_isp_get_framedrop_period(
+ stream_cfg_cmd->frame_skip_pattern);
if (stream_cfg_cmd->frame_skip_pattern == SKIP_ALL)
stream_info->framedrop_pattern = 0x0;
@@ -520,8 +539,17 @@
io_format = stream_info->output_format;
}
- vfe_dev->hw_info->vfe_ops.axi_ops.cfg_io_format(
+ rc = vfe_dev->hw_info->vfe_ops.axi_ops.cfg_io_format(
vfe_dev, stream_info->stream_src, io_format);
+ if (rc) {
+ pr_err("%s: cfg io format failed\n", __func__);
+ msm_isp_axi_free_wm(&vfe_dev->axi_data,
+ stream_info);
+ msm_isp_axi_destroy_stream(&vfe_dev->axi_data,
+ HANDLE_TO_IDX(
+ stream_cfg_cmd->axi_stream_handle));
+ return rc;
+ }
}
msm_isp_calculate_framedrop(&vfe_dev->axi_data, stream_cfg_cmd);
@@ -763,8 +791,9 @@
rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr,
vfe_dev->pdev->id, bufq_handle, &buf);
if (rc < 0) {
- vfe_dev->error_info.
- stream_framedrop_count[stream_idx]++;
+ if(stream_idx < MAX_NUM_STREAM)
+ vfe_dev->error_info.
+ stream_framedrop_count[stream_idx]++;
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
index b479857..8b83144 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
@@ -39,8 +39,9 @@
rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr,
vfe_dev->pdev->id, bufq_handle, &buf);
if (rc < 0) {
- vfe_dev->error_info.stats_framedrop_count[
- STATS_IDX(stream_info->stream_handle)]++;
+ uint8_t idx = STATS_IDX(stream_info->stream_handle);
+ if (idx < MSM_ISP_STATS_MAX)
+ vfe_dev->error_info.stats_framedrop_count[idx]++;
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index ea0195d..3cb48d1 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -77,6 +77,25 @@
.name = "msm_camera_isp",
};
+static void msm_isp_print_fourcc_error(const char *origin,
+ uint32_t fourcc_format)
+{
+ int i;
+ char text[5];
+ text[4] = '\0';
+ for (i = 0; i < 4; i++) {
+ text[i] = (char)(((fourcc_format) >> (i * 8)) & 0xFF);
+ if ((text[i] < '0') || (text[i] > 'z')) {
+ pr_err("%s: Invalid output format %d (unprintable)\n",
+ origin, fourcc_format);
+ return;
+ }
+ }
+ pr_err("%s: Invalid output format %s\n",
+ origin, text);
+ return;
+}
+
int msm_isp_init_bandwidth_mgr(enum msm_isp_hw_client client)
{
int rc = 0;
@@ -735,7 +754,7 @@
break;
/*TD: Add more image format*/
default:
- pr_err("%s: Invalid output format\n", __func__);
+ msm_isp_print_fourcc_error(__func__, output_format);
break;
}
return val;
@@ -771,7 +790,7 @@
case V4L2_PIX_FMT_QRGGB12:
return QCOM;
default:
- pr_err("%s: Invalid output format\n", __func__);
+ msm_isp_print_fourcc_error(__func__, output_format);
break;
}
return -EINVAL;
@@ -780,6 +799,10 @@
int msm_isp_get_bit_per_pixel(uint32_t output_format)
{
switch (output_format) {
+ case V4L2_PIX_FMT_Y4:
+ return 4;
+ case V4L2_PIX_FMT_Y6:
+ return 6;
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
@@ -790,6 +813,29 @@
case V4L2_PIX_FMT_QRGGB8:
case V4L2_PIX_FMT_JPEG:
case V4L2_PIX_FMT_META:
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV14:
+ case V4L2_PIX_FMT_NV41:
+ case V4L2_PIX_FMT_YVU410:
+ case V4L2_PIX_FMT_YVU420:
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_YYUV:
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_VYUY:
+ case V4L2_PIX_FMT_YUV422P:
+ case V4L2_PIX_FMT_YUV411P:
+ case V4L2_PIX_FMT_Y41P:
+ case V4L2_PIX_FMT_YUV444:
+ case V4L2_PIX_FMT_YUV555:
+ case V4L2_PIX_FMT_YUV565:
+ case V4L2_PIX_FMT_YUV32:
+ case V4L2_PIX_FMT_YUV410:
+ case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_GREY:
+ case V4L2_PIX_FMT_PAL8:
+ case MSM_V4L2_PIX_FMT_META:
return 8;
case V4L2_PIX_FMT_SBGGR10:
case V4L2_PIX_FMT_SGBRG10:
@@ -799,6 +845,8 @@
case V4L2_PIX_FMT_QGBRG10:
case V4L2_PIX_FMT_QGRBG10:
case V4L2_PIX_FMT_QRGGB10:
+ case V4L2_PIX_FMT_Y10:
+ case V4L2_PIX_FMT_Y10BPACK:
return 10;
case V4L2_PIX_FMT_SBGGR12:
case V4L2_PIX_FMT_SGBRG12:
@@ -808,21 +856,17 @@
case V4L2_PIX_FMT_QGBRG12:
case V4L2_PIX_FMT_QGRBG12:
case V4L2_PIX_FMT_QRGGB12:
+ case V4L2_PIX_FMT_Y12:
return 12;
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- case V4L2_PIX_FMT_NV14:
- case V4L2_PIX_FMT_NV41:
- return 8;
case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV61:
+ case V4L2_PIX_FMT_Y16:
return 16;
/*TD: Add more image format*/
default:
- pr_err("%s: Invalid output format\n", __func__);
- break;
+ msm_isp_print_fourcc_error(__func__, output_format);
+ return -EINVAL;
}
- return -EINVAL;
}
void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev)
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
index 8f080ce..407b81f 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
@@ -31,14 +31,19 @@
int msm_jpeg_platform_set_clk_rate(struct msm_jpeg_device *pgmn_dev,
long clk_rate)
{
- struct msm_cam_clk_info jpeg_core_clk_info[] = {
- {"core_clk", JPEG_CLK_RATE, 0}
- };
+ int rc = 0;
+ struct clk *jpeg_clk;
- jpeg_core_clk_info[0].clk_rate = clk_rate;
+ jpeg_clk = clk_get(&pgmn_dev->pdev->dev, "core_clk");
+ if (IS_ERR(jpeg_clk)) {
+ JPEG_PR_ERR("%s get failed\n", "core_clk");
+ rc = PTR_ERR(jpeg_clk);
+ return rc;
+ }
- return msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_core_clk_info,
- pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_core_clk_info), 1);
+ rc = clk_set_rate(jpeg_clk, clk_rate);
+
+ return rc;
}
void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file *file,
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index c79b3a3..8a2c8e5 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -1001,8 +1001,10 @@
video_set_drvdata(pvdev->vdev, pvdev);
msm_session_q = kzalloc(sizeof(*msm_session_q), GFP_KERNEL);
- if (WARN_ON(!msm_session_q))
- goto v4l2_fail;
+ if (WARN_ON(!msm_session_q)) {
+ rc = -ENOMEM;
+ goto session_fail;
+ }
msm_init_queue(msm_session_q);
spin_lock_init(&msm_eventq_lock);
@@ -1010,6 +1012,8 @@
INIT_LIST_HEAD(&ordered_sd_list);
goto probe_end;
+session_fail:
+ video_unregister_device(pvdev->vdev);
v4l2_fail:
v4l2_device_unregister(pvdev->vdev->v4l2_dev);
register_fail:
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 69f0a3d..532bebc 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -1845,6 +1845,11 @@
cpp_dev->timer_wq = create_workqueue("msm_cpp_workqueue");
cpp_dev->work = kmalloc(sizeof(struct msm_cpp_work_t),
GFP_KERNEL);
+ if (!cpp_dev->work) {
+ pr_err("cpp_dev->work is NULL\n");
+ rc = -ENOMEM;
+ goto ERROR3;
+ }
INIT_WORK((struct work_struct *)cpp_dev->work, msm_cpp_do_timeout_work);
cpp_dev->cpp_open_cnt = 0;
cpp_dev->is_firmware_loaded = 0;
diff --git a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
index dc29199..8d14363 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
@@ -691,43 +691,47 @@
if (queue->len > 0) {
frame_qcmd = msm_dequeue(queue, list_frame);
- processed_frame = frame_qcmd->command;
- do_gettimeofday(&(processed_frame->out_time));
- kfree(frame_qcmd);
- event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_ATOMIC);
- if (!event_qcmd) {
- pr_err("%s: Insufficient memory\n", __func__);
- return -ENOMEM;
- }
- atomic_set(&event_qcmd->on_heap, 1);
- event_qcmd->command = processed_frame;
- VPE_DBG("fid %d\n", processed_frame->frame_id);
- msm_enqueue(&vpe_dev->eventData_q, &event_qcmd->list_eventdata);
+ if(frame_qcmd) {
+ processed_frame = frame_qcmd->command;
+ do_gettimeofday(&(processed_frame->out_time));
+ kfree(frame_qcmd);
+ event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_ATOMIC);
+ if (!event_qcmd) {
+ pr_err("%s: Insufficient memory\n", __func__);
+ return -ENOMEM;
+ }
+ atomic_set(&event_qcmd->on_heap, 1);
+ event_qcmd->command = processed_frame;
+ VPE_DBG("fid %d\n", processed_frame->frame_id);
+ msm_enqueue(&vpe_dev->eventData_q, &event_qcmd->list_eventdata);
- if (!processed_frame->output_buffer_info.processed_divert) {
- memset(&buff_mgr_info, 0 ,
- sizeof(buff_mgr_info));
- buff_mgr_info.session_id =
- ((processed_frame->identity >> 16) & 0xFFFF);
- buff_mgr_info.stream_id =
- (processed_frame->identity & 0xFFFF);
- buff_mgr_info.frame_id = processed_frame->frame_id;
- buff_mgr_info.timestamp = processed_frame->timestamp;
- buff_mgr_info.index =
- processed_frame->output_buffer_info.index;
- rc = msm_vpe_buffer_ops(vpe_dev,
+ if (!processed_frame->output_buffer_info.processed_divert) {
+ memset(&buff_mgr_info, 0 ,
+ sizeof(buff_mgr_info));
+ buff_mgr_info.session_id =
+ ((processed_frame->identity >> 16) & 0xFFFF);
+ buff_mgr_info.stream_id =
+ (processed_frame->identity & 0xFFFF);
+ buff_mgr_info.frame_id = processed_frame->frame_id;
+ buff_mgr_info.timestamp = processed_frame->timestamp;
+ buff_mgr_info.index =
+ processed_frame->output_buffer_info.index;
+ rc = msm_vpe_buffer_ops(vpe_dev,
VIDIOC_MSM_BUF_MNGR_BUF_DONE,
&buff_mgr_info);
- if (rc < 0) {
- pr_err("%s: error doing VIDIOC_MSM_BUF_MNGR_BUF_DONE\n",
- __func__);
- rc = -EINVAL;
+ if (rc < 0) {
+ pr_err("%s: error doing VIDIOC_MSM_BUF_MNGR_BUF_DONE\n",
+ __func__);
+ rc = -EINVAL;
+ }
}
- }
- v4l2_evt.id = processed_frame->inst_id;
- v4l2_evt.type = V4L2_EVENT_VPE_FRAME_DONE;
- v4l2_event_queue(vpe_dev->msm_sd.sd.devnode, &v4l2_evt);
+ v4l2_evt.id = processed_frame->inst_id;
+ v4l2_evt.type = V4L2_EVENT_VPE_FRAME_DONE;
+ v4l2_event_queue(vpe_dev->msm_sd.sd.devnode, &v4l2_evt);
+ }
+ else
+ rc = -EFAULT;
}
return rc;
}
@@ -1368,6 +1372,8 @@
struct msm_vpe_frame_info_t *process_frame;
VPE_DBG("VIDIOC_MSM_VPE_GET_EVENTPAYLOAD\n");
event_qcmd = msm_dequeue(queue, list_eventdata);
+ if (NULL == event_qcmd)
+ break;
process_frame = event_qcmd->command;
VPE_DBG("fid %d\n", process_frame->frame_id);
if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
index 45db19c..69c1faa 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
@@ -809,6 +809,7 @@
e_ctrl->is_supported = 0;
if (!of_node) {
pr_err("%s dev.of_node NULL\n", __func__);
+ kfree(e_ctrl);
return -EINVAL;
}
@@ -817,6 +818,7 @@
CDBG("cell-index %d, rc %d\n", pdev->id, rc);
if (rc < 0) {
pr_err("failed rc %d\n", rc);
+ kfree(e_ctrl);
return rc;
}
e_ctrl->subdev_id = pdev->id;
@@ -826,12 +828,14 @@
CDBG("qcom,cci-master %d, rc %d\n", e_ctrl->cci_master, rc);
if (rc < 0) {
pr_err("%s failed rc %d\n", __func__, rc);
+ kfree(e_ctrl);
return rc;
}
rc = of_property_read_u32(of_node, "qcom,slave-addr",
&temp);
if (rc < 0) {
pr_err("%s failed rc %d\n", __func__, rc);
+ kfree(e_ctrl);
return rc;
}
@@ -844,6 +848,7 @@
struct msm_camera_cci_client), GFP_KERNEL);
if (!e_ctrl->i2c_client.cci_client) {
pr_err("%s failed no memory\n", __func__);
+ kfree(e_ctrl);
return -ENOMEM;
}
@@ -936,6 +941,7 @@
kfree(e_ctrl->eboard_info);
cciclient_free:
kfree(e_ctrl->i2c_client.cci_client);
+ kfree(e_ctrl);
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
index 699142a..b88ac00 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
@@ -71,9 +71,9 @@
case MSM_CAMERA_LED_LOW:
if (fctrl->torch_trigger) {
max_curr_l = fctrl->torch_max_current;
- if (cfg->led_current > 0 &&
- cfg->led_current < max_curr_l) {
- curr_l = cfg->led_current;
+ if (cfg->torch_current > 0 &&
+ cfg->torch_current < max_curr_l) {
+ curr_l = cfg->torch_current;
} else {
curr_l = fctrl->torch_op_current;
pr_err("LED current clamped to %d\n",
@@ -90,9 +90,9 @@
for (i = 0; i < fctrl->num_sources; i++)
if (fctrl->flash_trigger[i]) {
max_curr_l = fctrl->flash_max_current[i];
- if (cfg->led_current > 0 &&
- cfg->led_current < max_curr_l) {
- curr_l = cfg->led_current;
+ if (cfg->flash_current[i] > 0 &&
+ cfg->flash_current[i] < max_curr_l) {
+ curr_l = cfg->flash_current[i];
} else {
curr_l = fctrl->flash_op_current[i];
pr_err("LED current clamped to %d\n",
diff --git a/drivers/media/radio/radio-iris-transport.c b/drivers/media/radio/radio-iris-transport.c
index 9a9b385..2e8837d 100644
--- a/drivers/media/radio/radio-iris-transport.c
+++ b/drivers/media/radio/radio-iris-transport.c
@@ -105,6 +105,7 @@
skb = alloc_skb(len, GFP_ATOMIC);
if (!skb) {
FMDERR("Memory not allocated for the socket");
+ kfree(worker);
return;
}
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index a554749..3886c52 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -3159,7 +3159,7 @@
struct v4l2_ext_controls *ctrl)
{
int retval = 0;
- int bytes_to_copy;
+ size_t bytes_to_copy;
struct hci_fm_tx_ps tx_ps;
struct hci_fm_tx_rt tx_rt;
struct hci_fm_def_data_wr_req default_data;
@@ -3168,18 +3168,20 @@
struct iris_device *radio = video_get_drvdata(video_devdata(file));
char *data = NULL;
- if (radio == NULL) {
- FMDERR(":radio is null");
- return -EINVAL;
+ if ((ctrl == NULL) || (ctrl->controls == NULL)
+ || (ctrl->count == 0)) {
+ retval = -EINVAL;
+ return retval;
}
+
switch ((ctrl->controls[0]).id) {
case V4L2_CID_RDS_TX_PS_NAME:
FMDBG("In V4L2_CID_RDS_TX_PS_NAME\n");
/*Pass a sample PS string */
memset(tx_ps.ps_data, 0, MAX_PS_LENGTH);
- bytes_to_copy = min((int)(ctrl->controls[0]).size,
- MAX_PS_LENGTH);
+ bytes_to_copy = min(ctrl->controls[0].size,
+ (size_t)MAX_PS_LENGTH);
data = (ctrl->controls[0]).string;
if (copy_from_user(tx_ps.ps_data,
@@ -3196,7 +3198,7 @@
break;
case V4L2_CID_RDS_TX_RADIO_TEXT:
bytes_to_copy =
- min((int)(ctrl->controls[0]).size, MAX_RT_LENGTH);
+ min((ctrl->controls[0]).size, (size_t)MAX_RT_LENGTH);
data = (ctrl->controls[0]).string;
memset(tx_rt.rt_data, 0, MAX_RT_LENGTH);
@@ -4470,11 +4472,11 @@
if (kfifo_alloc_rc != 0) {
FMDERR("failed allocating buffers %d\n",
kfifo_alloc_rc);
- for (; i > -1; i--) {
+ for (; i > -1; i--)
kfifo_free(&radio->data_buf[i]);
- kfree(radio);
- return -ENOMEM;
- }
+ video_device_release(radio->videodev);
+ kfree(radio);
+ return -ENOMEM;
}
}
@@ -4502,8 +4504,17 @@
} else {
priv_videodev = kzalloc(sizeof(struct video_device),
GFP_KERNEL);
- memcpy(priv_videodev, radio->videodev,
- sizeof(struct video_device));
+ if (priv_videodev != NULL) {
+ memcpy(priv_videodev, radio->videodev,
+ sizeof(struct video_device));
+ } else {
+ video_unregister_device(radio->videodev);
+ video_device_release(radio->videodev);
+ for (; i > -1; i--)
+ kfifo_free(&radio->data_buf[i]);
+ kfree(radio);
+ return -ENOMEM;
+ }
}
return 0;
}
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index 6b9f2b3..c44e2a5 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -185,6 +185,10 @@
if (bahama_present == -ENODEV)
return -ENODEV;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
if (bahama_present)
radio->marimba->mod_id = SLAVE_ID_BAHAMA_FM;
else
@@ -216,6 +220,11 @@
* (otherwise, it may have already been there and will not be added a second
* time).
*/
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
queue_delayed_work(radio->wqueue, &radio->work,
msecs_to_jiffies(TAVARUA_DELAY));
return IRQ_HANDLED;
@@ -243,6 +252,12 @@
unsigned char offset, int len)
{
int retval = 0, i = 0;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
retval = set_fm_slave_id(radio);
if (retval == -ENODEV)
@@ -282,6 +297,12 @@
unsigned char offset, unsigned char value)
{
int retval;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
retval = set_fm_slave_id(radio);
if (retval == -ENODEV)
@@ -322,6 +343,12 @@
int i;
int retval;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
retval = set_fm_slave_id(radio);
if (retval == -ENODEV)
@@ -358,6 +385,11 @@
*/
static int read_data_blocks(struct tavarua_device *radio, unsigned char offset)
{
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
/* read all 3 RDS blocks */
return tavarua_read_registers(radio, offset, RDS_BLOCK*4);
}
@@ -376,10 +408,17 @@
*/
static void tavarua_rds_read(struct tavarua_device *radio)
{
- struct kfifo *rds_buf = &radio->data_buf[TAVARUA_BUF_RAW_RDS];
+ struct kfifo *rds_buf;
unsigned char blocknum;
unsigned char tmp[3];
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return;
+ }
+
+ rds_buf = &radio->data_buf[TAVARUA_BUF_RAW_RDS];
+
if (read_data_blocks(radio, RAW_RDS) < 0)
return;
/* copy all four RDS blocks to internal buffer */
@@ -430,6 +469,12 @@
static int request_read_xfr(struct tavarua_device *radio,
enum tavarua_xfr_ctrl_t mode){
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
tavarua_write_register(radio, XFRCTRL, mode);
msleep(TAVARUA_DELAY);
return 0;
@@ -457,8 +502,17 @@
static int copy_from_xfr(struct tavarua_device *radio,
enum tavarua_buf_t buf_type, unsigned int n){
- struct kfifo *data_fifo = &radio->data_buf[buf_type];
- unsigned char *xfr_regs = &radio->registers[XFRCTRL+1];
+ struct kfifo *data_fifo;
+ unsigned char *xfr_regs;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ data_fifo = &radio->data_buf[buf_type];
+ xfr_regs = &radio->registers[XFRCTRL+1];
+
kfifo_in_locked(data_fifo, xfr_regs, n, &radio->buf_lock[buf_type]);
return 0;
}
@@ -496,6 +550,12 @@
char *buf, int len)
{
char buffer[len+1];
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
memcpy(buffer+1, buf, len);
/* buffer[0] corresponds to XFRCTRL register
set the CTRL bit to 1 for write mode
@@ -520,6 +580,11 @@
static int xfr_intf_own(struct tavarua_device *radio)
{
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
mutex_lock(&radio->lock);
if (radio->xfr_in_progress) {
radio->pending_xfrs[TAVARUA_XFR_SYNC] = 1;
@@ -552,6 +617,12 @@
enum tavarua_xfr_ctrl_t xfr_type, unsigned char *buf)
{
int retval;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
retval = xfr_intf_own(radio);
if (retval < 0)
return retval;
@@ -590,6 +661,17 @@
enum tavarua_xfr_ctrl_t xfr_type, unsigned char *buf)
{
int retval;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(buf == NULL)) {
+ FMDERR("%s:buf is null", __func__);
+ return -EINVAL;
+ }
+
retval = xfr_intf_own(radio);
if (retval < 0)
return retval;
@@ -627,6 +709,12 @@
{
int i;
enum tavarua_xfr_t xfr;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return;
+ }
+
for (i = 0; i < TAVARUA_XFR_MAX; i++) {
if (radio->pending_xfrs[i]) {
radio->xfr_in_progress = 1;
@@ -681,8 +769,16 @@
enum tavarua_evt_t event)
{
- struct kfifo *data_b = &radio->data_buf[TAVARUA_BUF_EVENTS];
+ struct kfifo *data_b;
unsigned char evt = event;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return;
+ }
+
+ data_b = &radio->data_buf[TAVARUA_BUF_EVENTS];
+
FMDBG("updating event_q with event %x\n", event);
if (kfifo_in_locked(data_b, &evt, 1, &radio->buf_lock[TAVARUA_BUF_EVENTS]))
wake_up_interruptible(&radio->event_queue);
@@ -707,12 +803,18 @@
static void tavarua_start_xfr(struct tavarua_device *radio,
enum tavarua_xfr_t pending_id, enum tavarua_xfr_ctrl_t xfr_id)
{
- if (radio->xfr_in_progress)
- radio->pending_xfrs[pending_id] = 1;
- else {
- radio->xfr_in_progress = 1;
- request_read_xfr(radio, xfr_id);
- }
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return;
+ }
+
+ if (radio->xfr_in_progress)
+ radio->pending_xfrs[pending_id] = 1;
+ else {
+ radio->xfr_in_progress = 1;
+ request_read_xfr(radio, xfr_id);
+ }
}
/*=============================================================================
@@ -739,6 +841,12 @@
int i;
int retval, adj_channel_tune_req = 0;
unsigned char xfr_status;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return;
+ }
+
if (!radio->handle_irq) {
FMDBG("IRQ happend, but I wont handle it\n");
return;
@@ -1143,15 +1251,34 @@
*/
static void read_int_stat(struct work_struct *work)
{
- struct tavarua_device *radio = container_of(work,
- struct tavarua_device, work.work);
+ struct tavarua_device *radio;
+
+ if (unlikely(work == NULL)) {
+ FMDERR("%s:work is null", __func__);
+ return;
+ }
+
+ radio = container_of(work, struct tavarua_device, work.work);
+
tavarua_handle_interrupts(radio);
}
static void fm_shutdown(struct work_struct *work)
{
- struct tavarua_device *radio = container_of(work,
- struct tavarua_device, work.work);
+ struct tavarua_device *radio;
+
+ if (unlikely(work == NULL)) {
+ FMDERR("%s:work is null", __func__);
+ return;
+ }
+
+ radio = container_of(work, struct tavarua_device, work.work);
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return;
+ }
+
FMDERR("%s: Releasing the FM I2S GPIO\n", __func__);
if (radio->pdata->config_i2s_gpio != NULL)
radio->pdata->config_i2s_gpio(FM_I2S_OFF);
@@ -1178,9 +1305,14 @@
static int tavarua_request_irq(struct tavarua_device *radio)
{
int retval;
- int irq = radio->pdata->irq;
- if (radio == NULL)
+ int irq;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
return -EINVAL;
+ }
+
+ irq = radio->pdata->irq;
/* A workqueue created with create_workqueue() will have one worker thread
* for each CPU on the system; create_singlethread_workqueue(), instead,
@@ -1237,8 +1369,12 @@
static int tavarua_disable_irq(struct tavarua_device *radio)
{
int irq;
- if (!radio)
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
return -EINVAL;
+ }
+
irq = radio->pdata->irq;
disable_irq_wake(irq);
free_irq(irq, radio);
@@ -1255,6 +1391,11 @@
unsigned int rdsMask = 0;
unsigned char value = 0;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
adie_type_bahma = is_bahama();
switch (region) {
@@ -1435,9 +1576,17 @@
*/
static int tavarua_search(struct tavarua_device *radio, int on, int dir)
{
- enum search_t srch = radio->registers[SRCHCTRL] & SRCH_MODE;
+ enum search_t srch;
FMDBG("In tavarua_search\n");
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ srch = radio->registers[SRCHCTRL] & SRCH_MODE;
+
if (on) {
radio->registers[SRCHRDS1] = 0x00;
radio->registers[SRCHRDS2] = 0x00;
@@ -1503,6 +1652,11 @@
enum tavarua_region_t region = req_region;
unsigned char adie_type_bahma;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
adie_type_bahma = is_bahama();
/* Set freq band */
@@ -1671,6 +1825,17 @@
unsigned short chan;
unsigned int band_bottom;
unsigned int spacing;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(freq == NULL)) {
+ FMDERR("%s:freq is null", __func__);
+ return -EINVAL;
+ }
+
band_bottom = radio->region_params.band_low;
spacing = 0.100 * FREQ_MUL;
/* read channel */
@@ -1716,6 +1881,12 @@
unsigned char cmd[] = {0x00, 0x00};
unsigned int spacing;
int retval;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
band_bottom = radio->region_params.band_low;
spacing = 0.100 * FREQ_MUL;
if ((freq % 1600) == 800) {
@@ -1760,8 +1931,19 @@
size_t count, loff_t *ppos)
{
struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
- struct kfifo *rds_buf = &radio->data_buf[TAVARUA_BUF_RAW_RDS];
+ struct kfifo *rds_buf;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(buf == NULL)) {
+ FMDERR("%s:buf is null", __func__);
+ return -EINVAL;
+ }
+
+ rds_buf = &radio->data_buf[TAVARUA_BUF_RAW_RDS];
/* block if no new data available */
while (!kfifo_len(rds_buf)) {
if (file->f_flags & O_NONBLOCK)
@@ -1810,6 +1992,17 @@
int bytes_left;
int chunk_index = 0;
unsigned char tx_data[XFR_REG_NUM];
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(data == NULL)) {
+ FMDERR("%s:data is null", __func__);
+ return -EINVAL;
+ }
+
/* Disable TX of this type first */
switch (radio->tx_mode) {
case TAVARUA_TX_RT:
@@ -1897,6 +2090,11 @@
char buffer[] = {0x00, 0x48, 0x8A, 0x8E, 0x97, 0xB7};
int bahama_present = -ENODEV;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
INIT_DELAYED_WORK(&radio->work, read_int_stat);
if (!atomic_dec_and_test(&radio->users)) {
pr_err("%s: Device already in use."
@@ -2518,6 +2716,16 @@
{
struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(capability == NULL)) {
+ FMDERR("%s:capability is null", __func__);
+ return -EINVAL;
+ }
+
strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
sprintf(capability->bus_info, "I2C");
@@ -2553,6 +2761,12 @@
unsigned char i;
int retval = -EINVAL;
+ if (unlikely(qc == NULL)) {
+ FMDERR("%s:qc is null", __func__);
+ return -EINVAL;
+ }
+
+
for (i = 0; i < ARRAY_SIZE(tavarua_v4l2_queryctrl); i++) {
if (qc->id && qc->id == tavarua_v4l2_queryctrl[i].id) {
memcpy(qc, &(tavarua_v4l2_queryctrl[i]), sizeof(*qc));
@@ -2574,6 +2788,11 @@
int index = 0, offset = 0, addr = 0x0, val = 0;
int retval = 0, temp = 0, cnt = 0, j = 0;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
memset(xfr_buf, 0x0, XFR_REG_NUM);
/* Read the SPUR Table Size */
@@ -2651,6 +2870,15 @@
unsigned char xfr_buf[XFR_REG_NUM + 1];
int retval = 0, temp = 0;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(buf == NULL)) {
+ FMDERR("%s:buf is null", __func__);
+ return -EINVAL;
+ }
/* zero initialize the buffer */
memset(xfr_buf, 0x0, XFR_REG_NUM);
@@ -2725,6 +2953,11 @@
int ct = 0;
unsigned char size = 0;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
/*
Poking the MPX_DCC_BYPASS register to freeze the
value of MPX_DCC from changing while we access it
@@ -2844,6 +3077,16 @@
signed char ioc;
unsigned char size = 0;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(ctrl == NULL)) {
+ FMDERR("%s:ctrl is null", __func__);
+ return -EINVAL;
+ }
+
switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME:
break;
@@ -3059,6 +3302,18 @@
int extra_name_byte = 0;
int name_bytes = 0;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(ctrl == NULL) ||
+ unlikely(ctrl->controls == NULL) ||
+ unlikely(ctrl->count <= 0)) {
+ FMDERR("%s:ctrl is null", __func__);
+ return -EINVAL;
+ }
+
switch ((ctrl->controls[0]).id) {
case V4L2_CID_RDS_TX_PS_NAME: {
FMDBG("In V4L2_CID_RDS_TX_PS_NAME\n");
@@ -3191,6 +3446,16 @@
unsigned int freq = 0, mpx_dcc = 0;
unsigned long curr = 0, prev = 0;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(ctrl == NULL)) {
+ FMDERR("%s:ctrl is null", __func__);
+ return -EINVAL;
+ }
+
memset(xfr_buf, 0x0, XFR_REG_NUM);
switch (ctrl->id) {
@@ -3797,6 +4062,16 @@
char rmssi = 0;
unsigned char size = 0;
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(tuner == NULL)) {
+ FMDERR("%s:tuner is null", __func__);
+ return -EINVAL;
+ }
+
if (tuner->index > 0)
return -EINVAL;
@@ -3863,6 +4138,17 @@
struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
int retval;
int audmode;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(tuner == NULL)) {
+ FMDERR("%s:tuner is null", __func__);
+ return -EINVAL;
+ }
+
if (tuner->index > 0)
return -EINVAL;
@@ -3910,6 +4196,17 @@
struct v4l2_frequency *freq)
{
struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(freq == NULL)) {
+ FMDERR("%s:freq is null", __func__);
+ return -EINVAL;
+ }
+
freq->type = V4L2_TUNER_RADIO;
return tavarua_get_freq(radio, freq);
@@ -3945,6 +4242,16 @@
FMDBG("%s\n", __func__);
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(freq == NULL)) {
+ FMDERR("%s:freq is null", __func__);
+ return -EINVAL;
+ }
+
if (freq->type != V4L2_TUNER_RADIO)
return -EINVAL;
@@ -4108,6 +4415,17 @@
{
struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
int dir;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(seek == NULL)) {
+ FMDERR("%s:seek is null", __func__);
+ return -EINVAL;
+ }
+
if (seek->seek_upward)
dir = SRCH_DIR_UP;
else
@@ -4159,6 +4477,11 @@
int retval;
unsigned char int_ctrl[XFR_REG_NUM];
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
if (!radio->lp_mode)
return 0;
@@ -4222,6 +4545,12 @@
{
unsigned char lpm_buf[XFR_REG_NUM];
int retval;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
if (radio->lp_mode)
return 0;
FMDBG("%s\n", __func__);
@@ -4270,6 +4599,12 @@
int retval;
FMDBG("%s <%d>\n", __func__, state);
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
/* set geographic region */
radio->region_params.region = TAVARUA_REGION_US;
@@ -4305,6 +4640,12 @@
int retval;
int users = 0;
printk(KERN_INFO DRIVER_NAME "%s: radio suspend\n\n", __func__);
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
if (radio) {
users = atomic_read(&radio->users);
if (!users) {
@@ -4336,6 +4677,12 @@
int retval;
int users = 0;
printk(KERN_INFO DRIVER_NAME "%s: radio resume\n\n", __func__);
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
if (radio) {
users = atomic_read(&radio->users);
@@ -4380,8 +4727,12 @@
struct tavarua_device *radio = private_data;
int rx_on = radio->registers[RDCTRL] & FM_RECV;
int retval = 0;
- if (!radio)
- return -ENOMEM;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
/* RX */
FMDBG("%s: digital: %d analog: %d\n", __func__, digital_on, analog_on);
if ((radio->pdata != NULL) && (radio->pdata->config_i2s_gpio != NULL)) {
@@ -4469,6 +4820,12 @@
int retval = 0;
int i = 0, j = 0;
FMDBG("%s: probe called\n", __func__);
+
+ if (unlikely(pdev == NULL)) {
+ FMDERR("%s:pdev is null", __func__);
+ return -EINVAL;
+ }
+
/* private data allocation */
radio = kzalloc(sizeof(struct tavarua_device), GFP_KERNEL);
if (!radio) {
@@ -4593,6 +4950,11 @@
int i;
struct tavarua_device *radio = platform_get_drvdata(pdev);
+ if (unlikely(radio == NULL)) {
+ FMDERR("%s:radio is null", __func__);
+ return -EINVAL;
+ }
+
/* disable irq */
tavarua_disable_irq(radio);
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 421774f..b36faff 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -467,6 +467,7 @@
}
kfree(card->wr_pack_stats.packing_events);
+ kfree(card->cached_ext_csd);
put_device(&card->dev);
}
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 997e14b..b295bb8 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1189,9 +1189,9 @@
mmc_set_timing(card->host, MMC_TIMING_LEGACY);
mmc_set_clock(card->host, MMC_HIGH_26_MAX_DTR);
- err = mmc_select_hs(card, &card->cached_ext_csd);
+ err = mmc_select_hs(card, card->cached_ext_csd);
} else {
- err = mmc_select_hs400(card, &card->cached_ext_csd);
+ err = mmc_select_hs400(card, card->cached_ext_csd);
}
return err;
@@ -1439,7 +1439,7 @@
err = mmc_get_ext_csd(card, &ext_csd);
if (err)
goto free_card;
- memcpy(&card->cached_ext_csd, ext_csd, sizeof(card->ext_csd));
+ card->cached_ext_csd = ext_csd;
err = mmc_read_ext_csd(card, ext_csd);
if (err)
goto free_card;
@@ -1637,15 +1637,12 @@
if (!oldcard)
host->card = card;
- mmc_free_ext_csd(ext_csd);
return 0;
free_card:
if (!oldcard)
mmc_remove_card(card);
err:
- mmc_free_ext_csd(ext_csd);
-
return err;
}
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 95f0a04..c335be1 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -6962,7 +6962,7 @@
static const struct of_device_id msmsdcc_dt_match[] = {
{.compatible = "qcom,msm-sdcc"},
-
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, msmsdcc_dt_match);
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index e391a06..4d3a560 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -3113,6 +3113,7 @@
#endif
static const struct of_device_id sdhci_msm_dt_match[] = {
{.compatible = "qcom,sdhci-msm"},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sdhci_msm_dt_match);
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 76eb15b..12c5704 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -50,6 +50,7 @@
/* module params */
#define WCNSS_CONFIG_UNSPECIFIED (-1)
+#define UINT32_MAX (0xFFFFFFFFU)
static int has_48mhz_xo = WCNSS_CONFIG_UNSPECIFIED;
module_param(has_48mhz_xo, int, S_IWUSR | S_IRUGO);
@@ -355,7 +356,7 @@
int fw_cal_available;
int user_cal_read;
int user_cal_available;
- int user_cal_rcvd;
+ u32 user_cal_rcvd;
int user_cal_exp_size;
int device_opened;
int iris_xo_mode_set;
@@ -2134,7 +2135,7 @@
*user_buffer, size_t count, loff_t *position)
{
int rc = 0;
- int size = 0;
+ size_t size = 0;
if (!penv || !penv->device_opened || penv->user_cal_available)
return -EFAULT;
@@ -2142,7 +2143,7 @@
if (penv->user_cal_rcvd == 0 && count >= 4
&& !penv->user_cal_data) {
rc = copy_from_user((void *)&size, user_buffer, 4);
- if (size > MAX_CALIBRATED_DATA_SIZE) {
+ if (!size || size > MAX_CALIBRATED_DATA_SIZE) {
pr_err(DEVICE " invalid size to write %d\n", size);
return -EFAULT;
}
@@ -2161,7 +2162,8 @@
} else if (penv->user_cal_rcvd == 0 && count < 4)
return -EFAULT;
- if (MAX_CALIBRATED_DATA_SIZE < count + penv->user_cal_rcvd) {
+ if ((UINT32_MAX - count < penv->user_cal_rcvd) ||
+ MAX_CALIBRATED_DATA_SIZE < count + penv->user_cal_rcvd) {
pr_err(DEVICE " invalid size to write %d\n", count +
penv->user_cal_rcvd);
rc = -ENOMEM;
diff --git a/drivers/platform/msm/qpnp-clkdiv.c b/drivers/platform/msm/qpnp-clkdiv.c
index c55ed09..696c84f 100644
--- a/drivers/platform/msm/qpnp-clkdiv.c
+++ b/drivers/platform/msm/qpnp-clkdiv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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
@@ -202,6 +202,7 @@
if (!res) {
dev_err(&spmi->dev, "%s: unable to get device reg resource\n",
__func__);
+ return -EINVAL;
}
q_clkdiv->slave = spmi->sid;
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 8572616..6ea4ea6 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -1285,6 +1285,21 @@
return 0;
}
+static int
+qpnp_chg_vddmax_get(struct qpnp_chg_chip *chip)
+{
+ int rc;
+ u8 vddmax = 0;
+
+ rc = qpnp_chg_read(chip, &vddmax, chip->chgr_base + CHGR_VDD_MAX, 1);
+ if (rc) {
+ pr_err("Failed to write vddmax: %d\n", rc);
+ return rc;
+ }
+
+ return QPNP_CHG_V_MIN_MV + (int)vddmax * QPNP_CHG_V_STEP_MV;
+}
+
/* JEITA compliance logic */
static void
qpnp_chg_set_appropriate_vddmax(struct qpnp_chg_chip *chip)
@@ -2077,6 +2092,8 @@
if (battery_status != POWER_SUPPLY_STATUS_CHARGING
&& bms_status != POWER_SUPPLY_STATUS_CHARGING
&& charger_in
+ && !chip->bat_is_cool
+ && !chip->bat_is_warm
&& !chip->resuming_charging
&& !chip->charging_disabled
&& chip->soc_resume_limit
@@ -3118,10 +3135,17 @@
count = 0;
} else {
if (count == CONSECUTIVE_COUNT) {
- pr_info("End of Charging\n");
+ if (!chip->bat_is_cool && !chip->bat_is_warm) {
+ pr_info("End of Charging\n");
+ chip->chg_done = true;
+ } else {
+ pr_info("stop charging: battery is %s, vddmax = %d reached\n",
+ chip->bat_is_cool
+ ? "cool" : "warm",
+ qpnp_chg_vddmax_get(chip));
+ }
chip->delta_vddmax_mv = 0;
qpnp_chg_set_appropriate_vddmax(chip);
- chip->chg_done = true;
qpnp_chg_charge_en(chip, 0);
/* sleep for a second before enabling */
msleep(2000);
diff --git a/drivers/usb/host/ehci-msm2.c b/drivers/usb/host/ehci-msm2.c
index dd04f49..7ae0a54 100644
--- a/drivers/usb/host/ehci-msm2.c
+++ b/drivers/usb/host/ehci-msm2.c
@@ -1063,7 +1063,7 @@
memset(kbuf, 0, 10);
- if (copy_from_user(kbuf, buf, count > 10 ? 10 : count))
+ if (copy_from_user(kbuf, buf, min_t(size_t, sizeof(kbuf) - 1, count)))
return -EFAULT;
if (sscanf(kbuf, "%x", &data) != 1)
@@ -1088,7 +1088,7 @@
memset(kbuf, 0, 10);
- if (copy_from_user(kbuf, buf, count > 10 ? 10 : count))
+ if (copy_from_user(kbuf, buf, min_t(size_t, sizeof(kbuf) - 1, count)))
return -EFAULT;
if (sscanf(kbuf, "%x", &temp) != 1)
diff --git a/drivers/video/msm/mdss/dsi_host_v2.c b/drivers/video/msm/mdss/dsi_host_v2.c
index 738660a..f0860d3 100644
--- a/drivers/video/msm/mdss/dsi_host_v2.c
+++ b/drivers/video/msm/mdss/dsi_host_v2.c
@@ -935,17 +935,18 @@
if (req->cb)
req->cb(len);
}
-void msm_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
+int msm_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
{
struct dcs_cmd_req *req;
int dsi_on;
+ int ret = -EINVAL;
mutex_lock(&ctrl->mutex);
dsi_on = dsi_host_private->dsi_on;
mutex_unlock(&ctrl->mutex);
if (!dsi_on) {
pr_err("try to send DSI commands while dsi is off\n");
- return;
+ return ret;
}
mutex_lock(&ctrl->cmd_mutex);
@@ -953,21 +954,20 @@
if (!req) {
mutex_unlock(&ctrl->cmd_mutex);
- return;
+ return ret;
}
msm_dsi_clk_ctrl(&ctrl->panel_data, 1);
- dsi_set_tx_power_mode(0);
if (req->flags & CMD_REQ_RX)
msm_dsi_cmdlist_rx(ctrl, req);
else
msm_dsi_cmdlist_tx(ctrl, req);
- dsi_set_tx_power_mode(1);
msm_dsi_clk_ctrl(&ctrl->panel_data, 0);
mutex_unlock(&ctrl->cmd_mutex);
+ return 0;
}
static int msm_dsi_cal_clk_rate(struct mdss_panel_data *pdata,
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 3999db9..cf20666 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -186,6 +186,7 @@
int i = 0;
struct mdp3_hw_resource *mdata = (struct mdp3_hw_resource *)ptr;
u32 mdp_interrupt = 0;
+ u32 mdp_status = 0;
spin_lock(&mdata->irq_lock);
if (!mdata->irq_mask)
@@ -194,8 +195,8 @@
clk_enable(mdp3_res->clocks[MDP3_CLK_AHB]);
clk_enable(mdp3_res->clocks[MDP3_CLK_CORE]);
- mdp_interrupt = MDP3_REG_READ(MDP3_REG_INTR_STATUS);
- MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, mdp_interrupt);
+ mdp_status = MDP3_REG_READ(MDP3_REG_INTR_STATUS);
+ mdp_interrupt = mdp_status;
pr_debug("mdp3_irq_handler irq=%d\n", mdp_interrupt);
mdp_interrupt &= mdata->irq_mask;
@@ -206,6 +207,7 @@
mdp_interrupt = mdp_interrupt >> 1;
i++;
}
+ MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, mdp_status);
clk_disable(mdp3_res->clocks[MDP3_CLK_AHB]);
clk_disable(mdp3_res->clocks[MDP3_CLK_CORE]);
@@ -1443,7 +1445,9 @@
ret = 0;
} else {
ret = PTR_ERR(iommu_meta);
- goto out_unlock;
+ mutex_unlock(&mdp3_res->iommu_lock);
+ pr_err("%s: meta_create failed err=%d", __func__, ret);
+ return ret;
}
} else {
if (iommu_meta->flags != iommu_flags) {
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index 91b0380..a6fc20d 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -613,9 +613,6 @@
panel = mdp3_session->panel;
mutex_lock(&mdp3_session->lock);
- if (panel && panel->set_backlight)
- panel->set_backlight(panel, 0);
-
if (!mdp3_session->status) {
pr_debug("fb%d is off already", mfd->index);
goto off_error;
@@ -982,7 +979,7 @@
mdp3_bufq_push(&mdp3_session->bufq_out, data);
}
- if (mdp3_bufq_count(&mdp3_session->bufq_out) > 2) {
+ if (mdp3_bufq_count(&mdp3_session->bufq_out) > 1) {
data = mdp3_bufq_pop(&mdp3_session->bufq_out);
mdp3_put_img(data, MDP3_CLIENT_DMA_P);
}
@@ -1724,14 +1721,14 @@
kobject_uevent(&dev->kobj, KOBJ_ADD);
pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");
+ if (mdp3_get_cont_spash_en())
+ mdp3_session->clk_on = 1;
+
if (splash_mismatch) {
pr_err("splash memory mismatch, stop splash\n");
mdp3_ctrl_off(mfd);
}
- if (mdp3_get_cont_spash_en())
- mdp3_session->clk_on = 1;
-
mdp3_session->vsync_before_commit = true;
init_done:
if (IS_ERR_VALUE(rc))
diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
index 2ebcb8a..ae7598f 100644
--- a/drivers/video/msm/mdss/mdp3_dma.c
+++ b/drivers/video/msm/mdss/mdp3_dma.c
@@ -28,16 +28,22 @@
{
struct mdp3_dma *dma = (struct mdp3_dma *)arg;
struct mdp3_vsync_notification vsync_client;
+ unsigned int wait_for_next_vs;
pr_debug("mdp3_vsync_intr_handler\n");
spin_lock(&dma->dma_lock);
vsync_client = dma->vsync_client;
- complete(&dma->vsync_comp);
+ wait_for_next_vs = !dma->vsync_status;
+ dma->vsync_status = 0;
+ if (wait_for_next_vs)
+ complete(&dma->vsync_comp);
spin_unlock(&dma->dma_lock);
- if (vsync_client.handler)
+ if (vsync_client.handler) {
vsync_client.handler(vsync_client.arg);
- else
- mdp3_irq_disable_nosync(type);
+ } else {
+ if (wait_for_next_vs)
+ mdp3_irq_disable_nosync(type);
+ }
}
static void mdp3_dma_done_intr_handler(int type, void *arg)
@@ -567,7 +573,9 @@
intf->start(intf);
}
- wmb();
+ mb();
+ dma->vsync_status = MDP3_REG_READ(MDP3_REG_INTR_STATUS) &
+ (1 << MDP3_INTR_LCDC_START_OF_FRAME);
init_completion(&dma->vsync_comp);
spin_unlock_irqrestore(&dma->dma_lock, flag);
diff --git a/drivers/video/msm/mdss/mdp3_dma.h b/drivers/video/msm/mdss/mdp3_dma.h
index 9d439ad..6ad4c79 100644
--- a/drivers/video/msm/mdss/mdp3_dma.h
+++ b/drivers/video/msm/mdss/mdp3_dma.h
@@ -256,6 +256,7 @@
struct mdp3_dma_histogram_config histogram_config;
int histo_state;
struct mdp3_dma_histogram_data histo_data;
+ unsigned int vsync_status;
int (*dma_config)(struct mdp3_dma *dma,
struct mdp3_dma_source *source_config,
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index d743c42..855ec6c 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -233,7 +233,7 @@
int (*off) (struct mdss_panel_data *pdata);
int (*partial_update_fnc) (struct mdss_panel_data *pdata);
int (*check_status) (struct mdss_dsi_ctrl_pdata *pdata);
- void (*cmdlist_commit)(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
+ int (*cmdlist_commit)(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
struct mdss_panel_data panel_data;
unsigned char *ctrl_base;
int reg_size;
@@ -336,7 +336,7 @@
void mdss_dsi_ctrl_init(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl);
-void mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
+int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
void mdss_dsi_cmdlist_kickoff(int intf);
int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl);
diff --git a/drivers/video/msm/mdss/mdss_dsi_cmd.c b/drivers/video/msm/mdss/mdss_dsi_cmd.c
index 9a3e638..8fc1115c0 100644
--- a/drivers/video/msm/mdss/mdss_dsi_cmd.c
+++ b/drivers/video/msm/mdss/mdss_dsi_cmd.c
@@ -655,7 +655,7 @@
{
struct dcs_cmd_req *req;
struct dcs_cmd_list *clist;
- int ret = 0;
+ int ret = -EINVAL;
mutex_lock(&ctrl->cmd_mutex);
clist = &ctrl->cmdlist;
@@ -674,7 +674,6 @@
}
mutex_unlock(&ctrl->cmd_mutex);
- ret++;
pr_debug("%s: tot=%d put=%d get=%d\n", __func__,
clist->tot, clist->put, clist->get);
@@ -682,7 +681,7 @@
if (!ctrl->cmdlist_commit)
pr_err("cmdlist_commit not implemented!\n");
else
- ctrl->cmdlist_commit(ctrl, 0);
+ ret = ctrl->cmdlist_commit(ctrl, 0);
}
return ret;
}
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 6739747..65e6214 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -1155,38 +1155,55 @@
__func__, current->pid);
}
-void mdss_dsi_cmdlist_tx(struct mdss_dsi_ctrl_pdata *ctrl,
+int mdss_dsi_cmdlist_tx(struct mdss_dsi_ctrl_pdata *ctrl,
struct dcs_cmd_req *req)
{
- int ret;
+ int ret, ret_val = -EINVAL;
ret = mdss_dsi_cmds_tx(ctrl, req->cmds, req->cmds_cnt);
+ if (!IS_ERR_VALUE(ret))
+ ret_val = 0;
+
if (req->cb)
req->cb(ret);
+
+ return ret_val;
}
-void mdss_dsi_cmdlist_rx(struct mdss_dsi_ctrl_pdata *ctrl,
+int mdss_dsi_cmdlist_rx(struct mdss_dsi_ctrl_pdata *ctrl,
struct dcs_cmd_req *req)
{
struct dsi_buf *rp;
- int len = 0;
+ int len = 0, ret = -EINVAL;
if (req->rbuf) {
rp = &ctrl->rx_buf;
len = mdss_dsi_cmds_rx(ctrl, req->cmds, req->rlen);
memcpy(req->rbuf, rp->data, rp->len);
+ /*
+ * For dual DSI cases, early return of controller - 0
+ * is valid. Hence, for those cases the return value
+ * is zero even though we don't send any commands.
+ *
+ */
+ if ((ctrl->shared_pdata.broadcast_enable &&
+ ctrl->ndx == DSI_CTRL_0) || (len != 0))
+ ret = 0;
} else {
pr_err("%s: No rx buffer provided\n", __func__);
}
if (req->cb)
req->cb(len);
+
+ return ret;
}
-void mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
+int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
{
struct dcs_cmd_req *req;
+ int ret = -EINVAL;
mutex_lock(&ctrl->cmd_mutex);
req = mdss_dsi_cmdlist_get(ctrl);
@@ -1211,9 +1228,9 @@
mdss_dsi_clk_ctrl(ctrl, 1);
if (req->flags & CMD_REQ_RX)
- mdss_dsi_cmdlist_rx(ctrl, req);
+ ret = mdss_dsi_cmdlist_rx(ctrl, req);
else
- mdss_dsi_cmdlist_tx(ctrl, req);
+ ret = mdss_dsi_cmdlist_tx(ctrl, req);
mdss_dsi_clk_ctrl(ctrl, 0);
mdss_bus_bandwidth_ctrl(0);
@@ -1224,6 +1241,7 @@
mdss_dsi_cmd_mdp_start(ctrl);
mutex_unlock(&ctrl->cmd_mutex);
+ return ret;
}
static void dsi_send_events(struct mdss_dsi_ctrl_pdata *ctrl, u32 events)
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index c15c02b..94b2cbd 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -2187,6 +2187,7 @@
struct platform_device *fb_pdev, *mdss_pdev;
struct device_node *node;
int rc = 0;
+ bool master_panel = true;
if (!pdev || !pdev->dev.of_node) {
pr_err("Invalid device node\n");
@@ -2214,6 +2215,8 @@
fb_pdev = of_find_device_by_node(node);
if (fb_pdev) {
rc = mdss_fb_register_extra_panel(fb_pdev, pdata);
+ if (rc == 0)
+ master_panel = false;
} else {
pr_info("adding framebuffer device %s\n", dev_name(&pdev->dev));
fb_pdev = of_platform_device_create(node, NULL,
@@ -2221,7 +2224,7 @@
fb_pdev->dev.platform_data = pdata;
}
- if (mdp_instance->panel_register_done)
+ if (master_panel && mdp_instance->panel_register_done)
mdp_instance->panel_register_done(pdata);
mdss_notfound:
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 769f9b2..fad6b0c 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -289,6 +289,7 @@
struct mdss_ad_info {
u8 num;
u8 calc_hw_num;
+ u32 ops;
u32 sts;
u32 reg_sts;
u32 state;
@@ -516,7 +517,7 @@
int mdss_mdp_ctl_split_display_setup(struct mdss_mdp_ctl *ctl,
struct mdss_panel_data *pdata);
int mdss_mdp_ctl_destroy(struct mdss_mdp_ctl *ctl);
-int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl);
+int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff);
int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl);
int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg);
int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe,
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index bad4d06..f73b583 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1062,26 +1062,34 @@
return rc;
}
-static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl)
+static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl, bool handoff)
{
struct mdss_mdp_mixer *mixer;
u32 outsize, temp;
int ret = 0;
int i, nmixers;
- if (ctl->start_fnc)
- ret = ctl->start_fnc(ctl);
- else
- pr_warn("no start function for ctl=%d type=%d\n", ctl->num,
- ctl->panel_data->panel_info.type);
-
- if (ret) {
- pr_err("unable to start intf\n");
- return ret;
- }
-
pr_debug("ctl_num=%d\n", ctl->num);
+ /*
+ * Need start_fnc in 2 cases:
+ * (1) handoff
+ * (2) continuous splash finished.
+ */
+ if (handoff || !ctl->panel_data->panel_info.cont_splash_enabled) {
+ if (ctl->start_fnc)
+ ret = ctl->start_fnc(ctl);
+ else
+ pr_warn("no start function for ctl=%d type=%d\n",
+ ctl->num,
+ ctl->panel_data->panel_info.type);
+
+ if (ret) {
+ pr_err("unable to start intf\n");
+ return ret;
+ }
+ }
+
if (!ctl->panel_data->panel_info.cont_splash_enabled) {
nmixers = MDSS_MDP_INTF_MAX_LAYERMIXER +
MDSS_MDP_WB_MAX_LAYERMIXER;
@@ -1108,7 +1116,7 @@
return ret;
}
-int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl)
+int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff)
{
struct mdss_mdp_ctl *sctl;
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
@@ -1123,12 +1131,17 @@
if (ret)
return ret;
-
sctl = mdss_mdp_get_split_ctl(ctl);
mutex_lock(&ctl->lock);
- ctl->power_on = true;
+ /*
+ * keep power_on false during handoff to avoid unexpected
+ * operations to overlay.
+ */
+ if (!handoff)
+ ctl->power_on = true;
+
ctl->bus_ab_quota = 0;
ctl->bus_ib_quota = 0;
ctl->clk_rate = 0;
@@ -1141,10 +1154,10 @@
goto error;
}
- ret = mdss_mdp_ctl_start_sub(ctl);
+ ret = mdss_mdp_ctl_start_sub(ctl, handoff);
if (ret == 0) {
if (sctl) { /* split display is available */
- ret = mdss_mdp_ctl_start_sub(sctl);
+ ret = mdss_mdp_ctl_start_sub(sctl, handoff);
if (!ret)
mdss_mdp_ctl_split_display_enable(1, ctl, sctl);
} else if (ctl->mixer_right) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 14b486a..4c89064 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -859,7 +859,7 @@
mdss_hw_init(mdss_res);
}
- rc = mdss_mdp_ctl_start(ctl);
+ rc = mdss_mdp_ctl_start(ctl, false);
if (rc == 0) {
atomic_inc(&ov_active_panels);
@@ -1580,8 +1580,8 @@
return -ENODEV;
if (!ctl->add_vsync_handler || !ctl->remove_vsync_handler)
return -EOPNOTSUPP;
-
- if (!ctl->power_on) {
+ if (!ctl->panel_data->panel_info.cont_splash_enabled
+ && !ctl->power_on) {
pr_debug("fb%d vsync pending first update en=%d\n",
mfd->index, en);
return -EPERM;
@@ -1698,7 +1698,9 @@
u64 vsync_ticks;
int ret;
- if (!mdp5_data->ctl || !mdp5_data->ctl->power_on)
+ if (!mdp5_data->ctl ||
+ (!mdp5_data->ctl->panel_data->panel_info.cont_splash_enabled
+ && !mdp5_data->ctl->power_on))
return -EAGAIN;
vsync_ticks = ktime_to_ns(mdp5_data->vsync_time);
@@ -2535,9 +2537,15 @@
mdp5_data->ctl = ctl;
}
- rc = mdss_mdp_ctl_setup(ctl);
- if (rc)
+ /*
+ * vsync interrupt needs on during continuous splash, this is
+ * to initialize necessary ctl members here.
+ */
+ rc = mdss_mdp_ctl_start(ctl, true);
+ if (rc) {
+ pr_err("Failed to initialize ctl\n");
goto error;
+ }
ctl->clk_rate = mdss_mdp_get_clk_rate(MDSS_CLK_MDP_SRC);
pr_debug("Set the ctl clock rate to %d Hz\n", ctl->clk_rate);
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 0dc61d0..d0d2157 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -205,6 +205,10 @@
#define PP_AD_BAD_HW_NUM 255
+#define MDSS_SIDE_NONE 0
+#define MDSS_SIDE_LEFT 1
+#define MDSS_SIDE_RIGHT 2
+
#define PP_AD_STATE_INIT 0x2
#define PP_AD_STATE_CFG 0x4
#define PP_AD_STATE_DATA 0x8
@@ -293,15 +297,15 @@
struct mdp_gamut_cfg_data gamut_disp_cfg[MDSS_BLOCK_DISP_NUM];
uint16_t gamut_tbl[MDSS_BLOCK_DISP_NUM][GAMUT_TOTAL_TABLE_SIZE];
u32 hist_data[MDSS_BLOCK_DISP_NUM][HIST_V_SIZE];
- /* physical info */
struct pp_sts_type pp_disp_sts[MDSS_BLOCK_DISP_NUM];
+ /* physical info */
struct pp_hist_col_info dspp_hist[MDSS_MDP_MAX_DSPP];
};
static DEFINE_MUTEX(mdss_pp_mutex);
static struct mdss_pp_res_type *mdss_pp_res;
-static void pp_hist_read(char __iomem *v_addr,
+static u32 pp_hist_read(char __iomem *v_addr,
struct pp_hist_col_info *hist_info);
static int pp_histogram_setup(u32 *op, u32 block, struct mdss_mdp_mixer *mix);
static int pp_histogram_disable(struct pp_hist_col_info *hist_info,
@@ -340,8 +344,9 @@
static void pp_dither_config(char __iomem *addr,
struct pp_sts_type *pp_sts,
struct mdp_dither_cfg_data *dither_cfg);
-static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode,
- int mdp_rev);
+static void pp_dspp_opmode_config(struct mdss_mdp_ctl *ctl, u32 num,
+ struct pp_sts_type *pp_sts, int mdp_rev,
+ u32 *opmode);
static void pp_sharp_config(char __iomem *addr,
struct pp_sts_type *pp_sts,
struct mdp_sharp_cfg *sharp_config);
@@ -375,11 +380,15 @@
struct mdss_ad_info *ad, struct mdss_mdp_ctl *ctl);
static void pp_ad_input_write(struct mdss_mdp_ad *ad_hw,
struct mdss_ad_info *ad);
-static void pp_ad_bypass_config(struct mdss_ad_info *ad, u32 *opmode);
static int pp_ad_setup_hw_nums(struct msm_fb_data_type *mfd,
struct mdss_ad_info *ad);
+static void pp_ad_bypass_config(struct mdss_ad_info *ad,
+ struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode);
static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd);
static void pp_ad_cfg_lut(char __iomem *addr, u32 *data);
+static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num);
+static inline bool pp_sts_is_enabled(u32 sts, int side);
+static inline void pp_sts_set_split_bits(u32 *sts, u32 bits);
static u32 last_sts, last_state;
@@ -511,6 +520,7 @@
pp_sts->gamut_sts &= ~PP_STS_ENABLE;
else if (gamut_cfg->flags & MDP_PP_OPS_ENABLE)
pp_sts->gamut_sts |= PP_STS_ENABLE;
+ pp_sts_set_split_bits(&pp_sts->gamut_sts, gamut_cfg->flags);
}
static void pp_pa_config(unsigned long flags, char __iomem *addr,
@@ -679,6 +689,7 @@
if (pa_v2_config->flags & MDP_PP_PA_SIX_ZONE_VAL_MASK)
pp_sts->pa_sts |= PP_STS_PA_SIX_ZONE_VAL_MASK;
+ pp_sts_set_split_bits(&pp_sts->pa_sts, pa_v2_config->flags);
}
static void pp_pcc_config(unsigned long flags, char __iomem *addr,
@@ -693,6 +704,7 @@
pp_sts->pcc_sts &= ~PP_STS_ENABLE;
else if (pcc_config->ops & MDP_PP_OPS_ENABLE)
pp_sts->pcc_sts |= PP_STS_ENABLE;
+ pp_sts_set_split_bits(&pp_sts->pcc_sts, pcc_config->ops);
}
}
@@ -720,6 +732,7 @@
pp_sts->igc_sts &= ~PP_STS_ENABLE;
else if (igc_config->ops & MDP_PP_OPS_ENABLE)
pp_sts->igc_sts |= PP_STS_ENABLE;
+ pp_sts_set_split_bits(&pp_sts->igc_sts, igc_config->ops);
}
}
@@ -1324,12 +1337,20 @@
pp_sts->dither_sts &= ~PP_STS_ENABLE;
else if (dither_cfg->flags & MDP_PP_OPS_ENABLE)
pp_sts->dither_sts |= PP_STS_ENABLE;
+ pp_sts_set_split_bits(&pp_sts->dither_sts, dither_cfg->flags);
}
-static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode,
- int mdp_rev)
+static void pp_dspp_opmode_config(struct mdss_mdp_ctl *ctl, u32 num,
+ struct pp_sts_type *pp_sts, int mdp_rev,
+ u32 *opmode)
{
- if (pp_sts->pa_sts & PP_STS_ENABLE)
+ int side;
+ side = pp_num_to_side(ctl, num);
+
+ if (side < 0)
+ return;
+
+ if (pp_sts_is_enabled(pp_sts->pa_sts, side))
*opmode |= MDSS_MDP_DSPP_OP_PA_EN; /* PA_EN */
if (mdp_rev >= MDSS_MDP_HW_REV_103) {
if (pp_sts->pa_sts & PP_STS_PA_HUE_MASK)
@@ -1357,10 +1378,10 @@
if (pp_sts->pa_sts & PP_STS_PA_SIX_ZONE_VAL_MASK)
*opmode |= MDSS_MDP_DSPP_OP_PA_SIX_ZONE_VAL_MASK;
}
- if (pp_sts->pcc_sts & PP_STS_ENABLE)
+ if (pp_sts_is_enabled(pp_sts->pcc_sts, side))
*opmode |= MDSS_MDP_DSPP_OP_PCC_EN; /* PCC_EN */
- if (pp_sts->igc_sts & PP_STS_ENABLE) {
+ if (pp_sts_is_enabled(pp_sts->igc_sts, side)) {
*opmode |= MDSS_MDP_DSPP_OP_IGC_LUT_EN | /* IGC_LUT_EN */
(pp_sts->igc_tbl_idx << 1);
}
@@ -1368,14 +1389,14 @@
*opmode |= MDSS_MDP_DSPP_OP_HIST_LUTV_EN | /* HIST_LUT_EN */
MDSS_MDP_DSPP_OP_PA_EN; /* PA_EN */
}
- if (pp_sts->dither_sts & PP_STS_ENABLE)
+ if (pp_sts_is_enabled(pp_sts->dither_sts, side))
*opmode |= MDSS_MDP_DSPP_OP_DST_DITHER_EN; /* DITHER_EN */
- if (pp_sts->gamut_sts & PP_STS_ENABLE) {
+ if (pp_sts_is_enabled(pp_sts->gamut_sts, side)) {
*opmode |= MDSS_MDP_DSPP_OP_GAMUT_EN; /* GAMUT_EN */
if (pp_sts->gamut_sts & PP_STS_GAMUT_FIRST)
*opmode |= MDSS_MDP_DSPP_OP_GAMUT_PCC_ORDER;
}
- if (pp_sts->pgc_sts & PP_STS_ENABLE)
+ if (pp_sts_is_enabled(pp_sts->pgc_sts, side))
*opmode |= MDSS_MDP_DSPP_OP_ARGC_LUT_EN;
}
@@ -1481,6 +1502,7 @@
pp_sts->pgc_sts &= ~PP_STS_ENABLE;
else if (pgc_config->flags & MDP_PP_OPS_ENABLE)
pp_sts->pgc_sts |= PP_STS_ENABLE;
+ pp_sts_set_split_bits(&pp_sts->pgc_sts, pgc_config->flags);
}
if (ad_hw) {
@@ -1492,12 +1514,12 @@
pp_ad_init_write(ad_hw, ad, ctl);
if (ad_flags & PP_AD_STS_DIRTY_CFG)
pp_ad_cfg_write(ad_hw, ad);
- pp_ad_bypass_config(ad, &ad_bypass);
+ pp_ad_bypass_config(ad, ctl, ad_hw->num, &ad_bypass);
writel_relaxed(ad_bypass, ad_hw->base);
mutex_unlock(&ad->lock);
}
- pp_dspp_opmode_config(pp_sts, &opmode, mdata->mdp_rev);
+ pp_dspp_opmode_config(ctl, dspp_num, pp_sts, mdata->mdp_rev, &opmode);
flush_exit:
writel_relaxed(opmode, base + MDSS_MDP_REG_DSPP_OP_MODE);
ctl->flush_bits |= BIT(13 + dspp_num);
@@ -1836,6 +1858,12 @@
(config->block >= MDP_BLOCK_MAX))
return -EINVAL;
+ if ((config->pa_v2_data.flags & MDSS_PP_SPLIT_MASK) ==
+ MDSS_PP_SPLIT_MASK) {
+ pr_warn("Can't set both split bits\n");
+ return -EINVAL;
+ }
+
mutex_lock(&mdss_pp_mutex);
disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
@@ -2119,6 +2147,11 @@
(config->block >= MDP_BLOCK_MAX))
return -EINVAL;
+ if ((config->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+ pr_warn("Can't set both split bits\n");
+ return -EINVAL;
+ }
+
mutex_lock(&mdss_pp_mutex);
disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
@@ -2238,6 +2271,11 @@
if (config->len != IGC_LUT_ENTRIES)
return -EINVAL;
+ if ((config->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+ pr_warn("Can't set both split bits\n");
+ return -EINVAL;
+ }
+
mutex_lock(&mdss_pp_mutex);
disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
@@ -2437,6 +2475,11 @@
(PP_BLOCK(config->block) >= MDP_BLOCK_MAX))
return -EINVAL;
+ if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+ pr_warn("Can't set both split bits\n");
+ return -EINVAL;
+ }
+
mutex_lock(&mdss_pp_mutex);
disp_num = PP_BLOCK(config->block) - MDP_LOGICAL_BLOCK_DISP_0;
@@ -2608,6 +2651,11 @@
if (config->flags & MDP_PP_OPS_READ)
return -ENOTSUPP;
+ if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+ pr_warn("Can't set both split bits\n");
+ return -EINVAL;
+ }
+
mutex_lock(&mdss_pp_mutex);
disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
mdss_pp_res->dither_disp_cfg[disp_num] = *config;
@@ -2657,6 +2705,11 @@
if (pp_gm_has_invalid_lut_size(config))
return -EINVAL;
+ if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+ pr_warn("Can't set both split bits\n");
+ return -EINVAL;
+ }
+
mutex_lock(&mdss_pp_mutex);
disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
@@ -2773,19 +2826,27 @@
mutex_unlock(&mdss_pp_mutex);
return ret;
}
-static void pp_hist_read(char __iomem *v_addr,
+
+static u32 pp_hist_read(char __iomem *v_addr,
struct pp_hist_col_info *hist_info)
{
int i, i_start;
+ u32 sum = 0;
u32 data;
data = readl_relaxed(v_addr);
i_start = data >> 24;
hist_info->data[i_start] = data & 0xFFFFFF;
- for (i = i_start + 1; i < HIST_V_SIZE; i++)
+ sum += hist_info->data[i_start];
+ for (i = i_start + 1; i < HIST_V_SIZE; i++) {
hist_info->data[i] = readl_relaxed(v_addr) & 0xFFFFFF;
- for (i = 0; i < i_start - 1; i++)
+ sum += hist_info->data[i];
+ }
+ for (i = 0; i < i_start; i++) {
hist_info->data[i] = readl_relaxed(v_addr) & 0xFFFFFF;
+ sum += hist_info->data[i];
+ }
hist_info->hist_cnt_read++;
+ return sum;
}
/* Assumes that relevant clocks are enabled */
@@ -3168,10 +3229,10 @@
static int pp_hist_collect(struct mdp_histogram_data *hist,
struct pp_hist_col_info *hist_info,
- char __iomem *ctl_base)
+ char __iomem *ctl_base, u32 expect_sum)
{
int wait_ret, ret = 0;
- u32 timeout;
+ u32 timeout, sum;
char __iomem *v_base;
unsigned long flag;
struct mdss_pipe_pp_res *res;
@@ -3238,10 +3299,13 @@
spin_unlock_irqrestore(&hist_info->hist_lock, flag);
v_base = ctl_base + 0x1C;
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- pp_hist_read(v_base, hist_info);
+ sum = pp_hist_read(v_base, hist_info);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
spin_lock_irqsave(&hist_info->hist_lock, flag);
- hist_info->read_request = false;
+ if (!expect_sum || sum == expect_sum)
+ hist_info->read_request = false;
+ else
+ ret = -ENODATA;
hist_info->col_state = HIST_IDLE;
}
spin_unlock_irqrestore(&hist_info->hist_lock, flag);
@@ -3261,6 +3325,7 @@
u32 *hist_data_addr;
u32 pipe_cnt = 0;
u32 pipe_num = MDSS_MDP_SSPP_VIG0;
+ u32 exp_sum = 0;
struct mdss_mdp_pipe *pipe;
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
@@ -3290,7 +3355,10 @@
hist_info = &mdss_pp_res->dspp_hist[dspp_num];
ctl_base = mdss_mdp_get_dspp_addr_off(dspp_num) +
MDSS_MDP_REG_DSPP_HIST_CTL_BASE;
- ret = pp_hist_collect(hist, hist_info, ctl_base);
+ exp_sum = (mdata->mixer_intf[dspp_num].width *
+ mdata->mixer_intf[dspp_num].height);
+ ret = pp_hist_collect(hist, hist_info, ctl_base,
+ exp_sum);
if (ret)
goto hist_collect_exit;
}
@@ -3359,7 +3427,8 @@
hist_info = &pipe->pp_res.hist;
ctl_base = pipe->base +
MDSS_MDP_REG_VIG_HIST_CTL_BASE;
- ret = pp_hist_collect(hist, hist_info, ctl_base);
+ ret = pp_hist_collect(hist, hist_info, ctl_base,
+ exp_sum);
mdss_mdp_pipe_unmap(pipe);
if (ret)
goto hist_collect_exit;
@@ -3490,6 +3559,53 @@
return out;
}
+static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num)
+{
+ u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
+ u32 mixer_num;
+
+ if (!ctl || !ctl->mfd)
+ return -EINVAL;
+ mixer_num = mdss_mdp_get_ctl_mixers(ctl->mfd->index, mixer_id);
+ if (mixer_num < 2)
+ return MDSS_SIDE_NONE;
+ else if (mixer_id[1] == num)
+ return MDSS_SIDE_RIGHT;
+ else if (mixer_id[0] == num)
+ return MDSS_SIDE_LEFT;
+ else
+ pr_err("invalid, not on any side");
+ return -EINVAL;
+}
+
+static inline void pp_sts_set_split_bits(u32 *sts, u32 bits)
+{
+ u32 tmp = *sts;
+ tmp &= ~MDSS_PP_SPLIT_MASK;
+ tmp |= bits & MDSS_PP_SPLIT_MASK;
+ *sts = tmp;
+}
+
+static inline bool pp_sts_is_enabled(u32 sts, int side)
+{
+ bool ret = false;
+ /*
+ * If there are no sides, or if there are no split mode bits set, the
+ * side can't be disabled via split mode.
+ *
+ * Otherwise, if the side being checked opposes the split mode
+ * configuration, the side is disabled.
+ */
+ if ((side == MDSS_SIDE_NONE) || !(sts & MDSS_PP_SPLIT_MASK))
+ ret = true;
+ else if ((sts & MDSS_PP_SPLIT_RIGHT_ONLY) && (side == MDSS_SIDE_RIGHT))
+ ret = true;
+ else if ((sts & MDSS_PP_SPLIT_LEFT_ONLY) && (side == MDSS_SIDE_LEFT))
+ ret = true;
+
+ return ret && (sts & PP_STS_ENABLE);
+}
+
static int mdss_ad_init_checks(struct msm_fb_data_type *mfd)
{
u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
@@ -3586,7 +3702,7 @@
struct mdss_mdp_ctl *ctl;
struct msm_fb_data_type *bl_mfd;
int lin_ret = -1, inv_ret = -1, ret = 0;
- u32 ratio_temp, shift = 0;
+ u32 ratio_temp, shift = 0, last_ops;
ret = mdss_mdp_get_ad(mfd, &ad);
if (ret)
@@ -3599,6 +3715,11 @@
bl_mfd = mfd;
}
+ if ((init_cfg->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+ pr_warn("Can't set both split bits\n");
+ return -EINVAL;
+ }
+
mutex_lock(&ad->lock);
if (init_cfg->ops & MDP_PP_AD_INIT) {
memcpy(&ad->init, &init_cfg->params.init,
@@ -3638,6 +3759,22 @@
ad->sts |= PP_AD_STS_DIRTY_CFG;
}
+ last_ops = ad->ops & MDSS_PP_SPLIT_MASK;
+ ad->ops = init_cfg->ops & MDSS_PP_SPLIT_MASK;
+ /*
+ * if there is a change in the split mode config, the init values
+ * need to be re-written to hardware (if they have already been
+ * written or if there is data pending to be written). Check for
+ * pending data (DIRTY_INIT) is not checked here since it will not
+ * affect the outcome of this conditional (i.e. if init hasn't
+ * already been written (*_STATE_INIT is set), this conditional will
+ * only evaluate to true (and set the DIRTY bit) if the DIRTY bit has
+ * already been set).
+ */
+ if ((last_ops ^ ad->ops) && (ad->state & PP_AD_STATE_INIT))
+ ad->sts |= PP_AD_STS_DIRTY_INIT;
+
+
if (!ret && (init_cfg->ops & MDP_PP_OPS_DISABLE)) {
ad->sts &= ~PP_STS_ENABLE;
mutex_unlock(&ad->lock);
@@ -3792,8 +3929,9 @@
u32 temp;
u32 frame_start, frame_end, procs_start, procs_end, tile_ctrl;
u32 num;
+ int side;
char __iomem *base;
- bool is_calc, is_dual_pipe;
+ bool is_calc, is_dual_pipe, split_mode;
u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
u32 mixer_num;
mixer_num = mdss_mdp_get_ctl_mixers(ctl->mfd->index, mixer_id);
@@ -3804,6 +3942,7 @@
base = ad_hw->base;
is_calc = ad->calc_hw_num == ad_hw->num;
+ split_mode = !!(ad->ops & MDSS_PP_SPLIT_MASK);
writel_relaxed(ad->init.i_control[0] & 0x1F,
base + MDSS_MDP_REG_AD_CON_CTRL_0);
@@ -3829,7 +3968,10 @@
writel_relaxed(ad->init.format, base + MDSS_MDP_REG_AD_CTRL_0);
writel_relaxed(ad->init.auto_size, base + MDSS_MDP_REG_AD_CTRL_1);
- temp = ad->init.frame_w << 16;
+ if (split_mode)
+ temp = mdata->mixer_intf[ad_hw->num].width << 16;
+ else
+ temp = ad->init.frame_w << 16;
temp |= ad->init.frame_h & 0xFFFF;
writel_relaxed(temp, base + MDSS_MDP_REG_AD_FRAME_SIZE);
@@ -3841,17 +3983,26 @@
pp_ad_cfg_lut(base + MDSS_MDP_REG_AD_LUT_CC, ad->init.color_corr_lut);
if (mdata->mdp_rev >= MDSS_MDP_HW_REV_103) {
- if (is_dual_pipe) {
+ if (is_dual_pipe && !split_mode) {
num = ad_hw->num;
+ side = pp_num_to_side(ctl, num);
tile_ctrl = 0x5;
- if (is_calc) {
+ if ((ad->calc_hw_num + 1) == num)
+ tile_ctrl |= 0x10;
+
+ if (side <= MDSS_SIDE_NONE) {
+ WARN(1, "error finding sides, %d", side);
+ frame_start = 0;
+ procs_start = frame_start;
+ frame_end = 0;
+ procs_end = frame_end;
+ } else if (side == MDSS_SIDE_LEFT) {
frame_start = 0;
procs_start = 0;
frame_end = mdata->mixer_intf[num].width +
MDSS_AD_MERGED_WIDTH;
procs_end = mdata->mixer_intf[num].width;
} else {
- tile_ctrl |= 0x10;
procs_start = ad->init.frame_w -
(mdata->mixer_intf[num].width);
procs_end = ad->init.frame_w;
@@ -3866,8 +4017,13 @@
frame_end = 0xFFFF;
procs_start = 0x0;
procs_end = 0xFFFF;
- tile_ctrl = 0x1;
+ if (split_mode)
+ tile_ctrl = 0x0;
+ else
+ tile_ctrl = 0x1;
}
+
+
writel_relaxed(frame_start, base + MDSS_MDP_REG_AD_FRAME_START);
writel_relaxed(frame_end, base + MDSS_MDP_REG_AD_FRAME_END);
writel_relaxed(procs_start, base + MDSS_MDP_REG_AD_PROCS_START);
@@ -3931,12 +4087,17 @@
}
#define MDSS_PP_AD_BYPASS_DEF 0x101
-static void pp_ad_bypass_config(struct mdss_ad_info *ad, u32 *opmode)
+static void pp_ad_bypass_config(struct mdss_ad_info *ad,
+ struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode)
{
- if (ad->reg_sts & PP_STS_ENABLE)
+ int side = pp_num_to_side(ctl, num);
+
+ if (pp_sts_is_enabled(ad->reg_sts | (ad->ops & MDSS_PP_SPLIT_MASK),
+ side)) {
*opmode = 0;
- else
+ } else {
*opmode = MDSS_PP_AD_BYPASS_DEF;
+ }
}
static int pp_ad_setup_hw_nums(struct msm_fb_data_type *mfd,
@@ -3951,6 +4112,8 @@
/* default to left mixer */
ad->calc_hw_num = mixer_id[0];
+ if ((mixer_num > 1) && (ad->ops & MDSS_PP_SPLIT_RIGHT_ONLY))
+ ad->calc_hw_num = mixer_id[1];
return 0;
}
@@ -4258,6 +4421,7 @@
mdata->ad_off[i].base = mdata->mdp_base + ad_offsets[i];
mdata->ad_off[i].num = i;
mdata->ad_cfgs[i].num = i;
+ mdata->ad_cfgs[i].ops = 0;
mdata->ad_cfgs[i].reg_sts = 0;
mdata->ad_cfgs[i].calc_itr = 0;
mdata->ad_cfgs[i].last_str = 0xFFFFFFFF;
diff --git a/include/linux/ion.h b/include/linux/ion.h
index f36298b..7131da3 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -22,6 +22,8 @@
#include <linux/types.h>
struct ion_handle;
+typedef struct ion_handle *ion_user_handle_t;
+
/**
* enum ion_heap_types - list of all possible types of heaps
* @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc
@@ -350,7 +352,7 @@
size_t align;
unsigned int heap_mask;
unsigned int flags;
- struct ion_handle *handle;
+ ion_user_handle_t handle;
};
/**
@@ -364,7 +366,7 @@
* provides the file descriptor and the kernel returns the handle.
*/
struct ion_fd_data {
- struct ion_handle *handle;
+ ion_user_handle_t handle;
int fd;
};
@@ -373,7 +375,7 @@
* @handle: a handle
*/
struct ion_handle_data {
- struct ion_handle *handle;
+ ion_user_handle_t handle;
};
/**
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 1bcfd28..43aebb5 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -392,7 +392,7 @@
unsigned int idle_timeout;
struct notifier_block reboot_notify;
bool issue_long_pon;
- u8 cached_ext_csd;
+ u8 *cached_ext_csd;
};
/*
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 724e573..4903939 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -802,6 +802,10 @@
DCM_BLANK,
};
+#define MDSS_PP_SPLIT_LEFT_ONLY 0x10000000
+#define MDSS_PP_SPLIT_RIGHT_ONLY 0x20000000
+#define MDSS_PP_SPLIT_MASK 0x30000000
+
#define MDSS_MAX_BL_BRIGHTNESS 255
#define AD_BL_LIN_LEN 256
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index c48586e..a01dd9a 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -571,7 +571,8 @@
struct msm_camera_led_cfg_t {
enum msm_camera_led_config_t cfgtype;
- uint32_t led_current;
+ uint32_t torch_current;
+ uint32_t flash_current[2];
};
#define VIDIOC_MSM_SENSOR_CFG \
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index 6d22836..955a47b 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -108,7 +108,7 @@
static void __spin_lock_debug(raw_spinlock_t *lock)
{
u64 i;
- u64 loops = (loops_per_jiffy * HZ) >> 1;
+ u64 loops = (loops_per_jiffy * HZ);
for (i = 0; i < loops; i++) {
if (arch_spin_trylock(&lock->raw_lock))
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index e174693..fa8a793 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -184,36 +184,6 @@
return ret;
}
-#ifdef ENABLE_VMALLOC_SAVING
-int is_vmalloc_addr(const void *x)
-{
- struct rb_node *n;
- struct vmap_area *va;
- int ret = 0;
-
- spin_lock(&vmap_area_lock);
-
- for (n = rb_first(vmap_area_root); n; rb_next(n)) {
- va = rb_entry(n, struct vmap_area, rb_node);
- if (x >= va->va_start && x < va->va_end) {
- ret = 1;
- break;
- }
- }
-
- spin_unlock(&vmap_area_lock);
- return ret;
-}
-#else
-int is_vmalloc_addr(const void *x)
-{
- unsigned long addr = (unsigned long)x;
-
- return addr >= VMALLOC_START && addr < VMALLOC_END;
-}
-#endif
-EXPORT_SYMBOL(is_vmalloc_addr);
-
int is_vmalloc_or_module_addr(const void *x)
{
/*
@@ -302,6 +272,47 @@
static unsigned long vmap_area_pcpu_hole;
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+int is_vmalloc_addr(const void *x)
+{
+ struct vmap_area *va;
+ int ret = 0;
+
+ spin_lock(&vmap_area_lock);
+ list_for_each_entry(va, &vmap_area_list, list) {
+ if (va->flags & (VM_LAZY_FREE | VM_LAZY_FREEING))
+ continue;
+
+ if (!(va->flags & VM_VM_AREA))
+ continue;
+
+ if (va->vm == NULL)
+ continue;
+
+ if (va->vm->flags & VM_LOWMEM)
+ continue;
+
+ if ((unsigned long)x >= va->va_start &&
+ (unsigned long)x < va->va_end) {
+ ret = 1;
+ break;
+ }
+ }
+ spin_unlock(&vmap_area_lock);
+ return ret;
+}
+#else
+int is_vmalloc_addr(const void *x)
+{
+ unsigned long addr = (unsigned long)x;
+
+ return addr >= VMALLOC_START && addr < VMALLOC_END;
+}
+#endif
+EXPORT_SYMBOL(is_vmalloc_addr);
+
+
+
static struct vmap_area *__find_vmap_area(unsigned long addr)
{
struct rb_node *n = vmap_area_root.rb_node;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 9962c88..6c78c0c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1457,7 +1457,7 @@
head = p; id++;
}
- sprintf(hdev->name, "hci%d", id);
+ snprintf(hdev->name, sizeof(hdev->name), "hci%d", id);
hdev->id = id;
list_add(&hdev->list, head);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 2628937..b2b0e99 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3443,10 +3443,7 @@
tcp_done(sk);
bh_unlock_sock(sk);
local_bh_enable();
- if (!sock_flag(sk, SOCK_DEAD)) {
- sock_orphan(sk);
- sock_put(sk);
- }
+ sock_put(sk);
goto restart;
}
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 487ac6f..9a11f9f 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -55,6 +55,7 @@
static unsigned int table_size, table_cnt;
static int all_symbols = 0;
static char symbol_prefix_char = '\0';
+static unsigned long long kernel_start_addr = 0;
int token_profit[0x10000];
@@ -65,7 +66,10 @@
static void usage(void)
{
- fprintf(stderr, "Usage: kallsyms [--all-symbols] [--symbol-prefix=<prefix char>] < in.map > out.S\n");
+ fprintf(stderr, "Usage: kallsyms [--all-symbols] "
+ "[--symbol-prefix=<prefix char>] "
+ "[--page-offset=<CONFIG_PAGE_OFFSET>] "
+ "< in.map > out.S\n");
exit(1);
}
@@ -194,6 +198,9 @@
int i;
int offset = 1;
+ if (s->addr < kernel_start_addr)
+ return 0;
+
/* skip prefix char */
if (symbol_prefix_char && *(s->sym + 1) == symbol_prefix_char)
offset++;
@@ -646,6 +653,9 @@
if ((*p == '"' && *(p+2) == '"') || (*p == '\'' && *(p+2) == '\''))
p++;
symbol_prefix_char = *p;
+ } else if (strncmp(argv[i], "--page-offset=", 14) == 0) {
+ const char *p = &argv[i][14];
+ kernel_start_addr = strtoull(p, NULL, 16);
} else
usage();
}
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index 55fec32..1962ff0 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -1396,7 +1396,10 @@
switch (decimator) {
case 1:
case 2:
- adc_dmic_sel = 0x0;
+ if ((dec_mux == 3) || (dec_mux == 4))
+ adc_dmic_sel = 0x1;
+ else
+ adc_dmic_sel = 0x0;
break;
default:
dev_err(codec->dev, "%s: Invalid Decimator = %u\n",
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 28d4c84..14218d8 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -213,7 +213,6 @@
/* called under codec_resource_lock acquisition */
static void wcd9xxx_start_hs_polling(struct wcd9xxx_mbhc *mbhc)
{
- s16 v_brh, v_b1_hu;
struct snd_soc_codec *codec = mbhc->codec;
int mbhc_state = mbhc->mbhc_state;
@@ -254,17 +253,6 @@
/* set to max */
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL, 0x7F);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL, 0xFF);
-
- v_brh = wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_BR_H);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
- (v_brh >> 8) & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
- v_brh & 0xFF);
- v_b1_hu = wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_B1_HU);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
- v_b1_hu & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
- (v_b1_hu >> 8) & 0xFF);
}
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x1);
@@ -325,22 +313,32 @@
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL,
(d->v_ins_hu[MBHC_V_IDX_VDDIO] >> 8) &
0xFF);
- /* Threshods for button press */
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
- d->v_b1_hu[MBHC_V_IDX_VDDIO] & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
- (d->v_b1_hu[MBHC_V_IDX_VDDIO] >> 8) &
- 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL,
- d->v_b1_h[MBHC_V_IDX_VDDIO] & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
- (d->v_b1_h[MBHC_V_IDX_VDDIO] >> 8) &
- 0xFF);
- /* Threshods for button release */
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
- d->v_brh[MBHC_V_IDX_VDDIO] & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
- (d->v_brh[MBHC_V_IDX_VDDIO] >> 8) & 0xFF);
+
+ if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
+ /* Threshods for button press */
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
+ d->v_b1_hu[MBHC_V_IDX_VDDIO] & 0xFF);
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
+ (d->v_b1_hu[MBHC_V_IDX_VDDIO] >> 8) &
+ 0xFF);
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL,
+ d->v_b1_h[MBHC_V_IDX_VDDIO] & 0xFF);
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
+ (d->v_b1_h[MBHC_V_IDX_VDDIO] >> 8) &
+ 0xFF);
+ /* Threshods for button release */
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
+ d->v_brh[MBHC_V_IDX_VDDIO] & 0xFF);
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
+ (d->v_brh[MBHC_V_IDX_VDDIO] >> 8) &
+ 0xFF);
+ }
pr_debug("%s: Programmed MBHC thresholds to VDDIO\n",
__func__);
}
@@ -376,22 +374,31 @@
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL,
(d->v_ins_hu[MBHC_V_IDX_CFILT] >> 8) &
0xFF);
- /* Revert threshods for button press */
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
- d->v_b1_hu[MBHC_V_IDX_CFILT] & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
- (d->v_b1_hu[MBHC_V_IDX_CFILT] >> 8) &
- 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL,
- d->v_b1_h[MBHC_V_IDX_CFILT] & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
- (d->v_b1_h[MBHC_V_IDX_CFILT] >> 8) &
- 0xFF);
- /* Revert threshods for button release */
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
- d->v_brh[MBHC_V_IDX_CFILT] & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
- (d->v_brh[MBHC_V_IDX_CFILT] >> 8) & 0xFF);
+ if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
+ /* Revert threshods for button press */
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
+ d->v_b1_hu[MBHC_V_IDX_CFILT] & 0xFF);
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
+ (d->v_b1_hu[MBHC_V_IDX_CFILT] >> 8) &
+ 0xFF);
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL,
+ d->v_b1_h[MBHC_V_IDX_CFILT] & 0xFF);
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
+ (d->v_b1_h[MBHC_V_IDX_CFILT] >> 8) &
+ 0xFF);
+ /* Revert threshods for button release */
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
+ d->v_brh[MBHC_V_IDX_CFILT] & 0xFF);
+ snd_soc_write(codec,
+ WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
+ (d->v_brh[MBHC_V_IDX_CFILT] >> 8) &
+ 0xFF);
+ }
pr_debug("%s: Programmed MBHC thresholds to MICBIAS\n",
__func__);
}
@@ -489,19 +496,25 @@
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B1_CTL, v_ins_hu & 0xFF);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL,
(v_ins_hu >> 8) & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
- (v_b1_hu >> 8) & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL, v_b1_h & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
- (v_b1_h >> 8) & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
- (v_brh >> 8) & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B11_CTL,
- mbhc->mbhc_data.v_brl & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B12_CTL,
- (mbhc->mbhc_data.v_brl >> 8) & 0xFF);
+
+ if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu &
+ 0xFF);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
+ (v_b1_hu >> 8) & 0xFF);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL, v_b1_h &
+ 0xFF);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
+ (v_b1_h >> 8) & 0xFF);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh &
+ 0xFF);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
+ (v_brh >> 8) & 0xFF);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B11_CTL,
+ mbhc->mbhc_data.v_brl & 0xFF);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B12_CTL,
+ (mbhc->mbhc_data.v_brl >> 8) & 0xFF);
+ }
}
static void wcd9xxx_codec_switch_cfilt_mode(struct wcd9xxx_mbhc *mbhc,
@@ -3148,15 +3161,22 @@
mv = ceilmv + btn_det->v_btn_press_delta_cic;
pr_debug("%s: reprogram vb1hu/vbrh to %dmv\n", __func__, mv);
- /* update LSB first so mbhc hardware block doesn't see too low value */
- v_b1_hu = wcd9xxx_codec_v_sta_dce(mbhc, STA, mv, false);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
- (v_b1_hu >> 8) & 0xFF);
- v_brh = wcd9xxx_codec_v_sta_dce(mbhc, DCE, mv, false);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh & 0xFF);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
- (v_brh >> 8) & 0xFF);
+ if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
+ /*
+ * update LSB first so mbhc hardware block
+ * doesn't see too low value.
+ */
+ v_b1_hu = wcd9xxx_codec_v_sta_dce(mbhc, STA, mv, false);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu &
+ 0xFF);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
+ (v_b1_hu >> 8) & 0xFF);
+ v_brh = wcd9xxx_codec_v_sta_dce(mbhc, DCE, mv, false);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh &
+ 0xFF);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
+ (v_brh >> 8) & 0xFF);
+ }
return 0;
}
diff --git a/sound/soc/msm/msm8x10.c b/sound/soc/msm/msm8x10.c
index 408ec03..c1ba26a 100644
--- a/sound/soc/msm/msm8x10.c
+++ b/sound/soc/msm/msm8x10.c
@@ -163,6 +163,8 @@
SND_SOC_DAPM_MIC("Handset Mic", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_MIC("Secondary Mic", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic1", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic2", NULL),
};
static int msm8x10_ext_spk_power_amp_init(void)
{
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.c b/sound/soc/msm/qdsp6v2/audio_acdb.c
index 58c3cdf..4e04bef 100644
--- a/sound/soc/msm/qdsp6v2/audio_acdb.c
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.c
@@ -405,9 +405,9 @@
done:
mutex_unlock(&acdb_data.acdb_mutex);
-ret:
pr_debug("ACDB=> %s: Path = %d samplerate = %u usec = %u status %d\n",
__func__, path, entry->sample_rate, entry->delay_usec, result);
+ret:
return result;
}