diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2019-05-10 06:47:22 -0700 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2019-05-10 06:47:22 -0700 |
commit | cb2608fb6c759ccab3470f841778a7130fa10a09 (patch) | |
tree | 10381a9b23fa8a6c3c3938f85435306f705df815 | |
parent | e47a761d21f6b75faa980bf4d5a74f7c2df051bd (diff) | |
parent | c6349b48eee5364e84dd4972f891c56a8d256c53 (diff) |
Merge c6349b48eee5364e84dd4972f891c56a8d256c53 on remote branchLA.UM.7.3.r1-07800-sdm845.0
Change-Id: Iff19602a382ce69170584a6fac0b435bc877358c
104 files changed, 1899 insertions, 535 deletions
diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig index 5eaa0eb983a6..b65fbac85719 100644 --- a/arch/arm/configs/msm8937_defconfig +++ b/arch/arm/configs/msm8937_defconfig @@ -677,7 +677,6 @@ CONFIG_PANIC_ON_RT_THROTTLING=y CONFIG_SCHEDSTATS=y CONFIG_SCHED_STACK_END_CHECK=y # CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_ATOMIC_SLEEP=y CONFIG_DEBUG_LIST=y diff --git a/arch/arm/configs/msm8937go_defconfig b/arch/arm/configs/msm8937go_defconfig index 4c3f53b1ae16..b76c4183a762 100644 --- a/arch/arm/configs/msm8937go_defconfig +++ b/arch/arm/configs/msm8937go_defconfig @@ -674,7 +674,6 @@ CONFIG_PANIC_ON_SCHED_BUG=y CONFIG_PANIC_ON_RT_THROTTLING=y CONFIG_SCHED_STACK_END_CHECK=y # CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_ATOMIC_SLEEP=y CONFIG_DEBUG_LIST=y diff --git a/arch/arm64/boot/dts/qcom/msm8909w-pm660-regulator.dtsi b/arch/arm64/boot/dts/qcom/msm8909w-pm660-regulator.dtsi index 47a925e4c34a..96a282673b56 100644 --- a/arch/arm64/boot/dts/qcom/msm8909w-pm660-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8909w-pm660-regulator.dtsi @@ -329,16 +329,43 @@ /* CPR controlled regulator */ &soc { + /delete-node/ regulator@1942130; mem_acc_vreg_corner: regulator@1942130 { compatible = "qcom,mem-acc-regulator"; - reg = <0x1942130 0x4>; - reg-names = "acc-sel-l1"; regulator-name = "mem_acc_corner"; regulator-min-microvolt = <1>; regulator-max-microvolt = <3>; - qcom,acc-sel-l1-bit-pos = <0>; - qcom,corner-acc-map = <0 1 1>; + qcom,acc-reg-addr-list = + <0x1942130 0x1942120>; + + qcom,acc-init-reg-config = <1 0x1>, <2 0x0>; + qcom,num-acc-corners = <3>; + qcom,boot-acc-corner = <2>; + + qcom,corner1-reg-config = + /* SVS => SVS */ + <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>, + /* SVS => NOM */ + < 1 0x0 >, < 2 0x09240000>, < 1 0x1 >, + /* SVS => TURBO */ + < 1 0x1 >, < 2 0x0>, < (-1) (-1) >; + + qcom,corner2-reg-config = + /* NOM => SVS */ + < 1 0x0 >, < 2 0x09240000>, < 2 0x0 >, + /* NOM => NOM */ + <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>, + /* NOM => TURBO */ + < 1 0x1 >, < 2 0x08200000>, < 2 0x0 >; + + qcom,corner3-reg-config = + /* TURBO => SVS */ + < 1 0x0 >, < 2 0x0>, < (-1) (-1) >, + /* TURBO => NOM */ + < 1 0x1 >, < 2 0x08200000>, < 2 0x09240000 >, + /* TURBO => TURBO */ + <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>; }; apc_vreg_corner: regulator@b018000 { diff --git a/arch/arm64/boot/dts/qcom/msm8937-camera-sensor-cdp.dtsi b/arch/arm64/boot/dts/qcom/msm8937-camera-sensor-cdp.dtsi new file mode 100644 index 000000000000..8f174fbda46e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8937-camera-sensor-cdp.dtsi @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2015-2016, 2019, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&cci { + actuator0: qcom,actuator@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; + cam_vaf-supply = <&pm8937_l17>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-min-voltage = <2850000>; + qcom,cam-vreg-max-voltage = <2850000>; + qcom,cam-vreg-op-mode = <80000>; + }; + + actuator1: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; + cam_vaf-supply = <&pm8937_l17>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-min-voltage = <2850000>; + qcom,cam-vreg-max-voltage = <2850000>; + qcom,cam-vreg-op-mode = <80000>; + }; + + eeprom0: qcom,eeprom@0 { + cell-index = <0>; + compatible = "qcom,eeprom"; + qcom,cci-master = <0>; + reg = <0x0>; + cam_vana-supply = <&pm8937_l22>; + cam_vio-supply = <&pm8937_l6>; + cam_vaf-supply = <&pm8937_l17>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-min-voltage = <0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <0 2800000 2850000>; + qcom,cam-vreg-op-mode = <0 80000 100000>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_reset + &cam_sensor_rear_standby + &cam_sensor_rear_vdig>; + pinctrl-1 = <&cam_sensor_mclk0_sleep + &cam_sensor_rear_reset_sleep + &cam_sensor_rear_standby_sleep + &cam_sensor_rear_vdig_sleep>; + gpios = <&tlmm 26 0>, + <&tlmm 36 0>, + <&tlmm 35 0>, + <&tlmm 62 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-vdig = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0", + "CAM_VDIG"; + status = "ok"; + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + + eeprom1: qcom,eeprom@1 { + cell-index = <1>; + reg = <0x1>; + qcom,eeprom-name = "sunny_8865"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0x6c>; + qcom,cci-master = <0>; + qcom,num-blocks = <8>; + + qcom,page0 = <1 0x0100 2 0x01 1 1>; + qcom,poll0 = <0 0x0 2 0x0 1 0>; + qcom,mem0 = <0 0x0 2 0x0 1 0>; + + qcom,page1 = <1 0x5002 2 0x00 1 0>; + qcom,poll1 = <0 0x0 2 0x0 1 0>; + qcom,mem1 = <0 0x0 2 0x0 1 0>; + + qcom,page2 = <1 0x3d84 2 0xc0 1 0>; + qcom,poll2 = <0 0x0 2 0x0 1 0>; + qcom,mem2 = <0 0x0 2 0x0 1 0>; + + qcom,page3 = <1 0x3d88 2 0x70 1 0>; + qcom,poll3 = <0 0x0 2 0x0 1 0>; + qcom,mem3 = <0 0x0 2 0x0 1 0>; + + qcom,page4 = <1 0x3d89 2 0x10 1 0>; + qcom,poll4 = <0 0x0 2 0x0 1 0>; + qcom,mem4 = <0 0x0 2 0x0 1 0>; + + qcom,page5 = <1 0x3d8a 2 0x70 1 0>; + qcom,poll5 = <0 0x0 2 0x0 1 0>; + qcom,mem5 = <0 0x0 2 0x0 1 0>; + + qcom,page6 = <1 0x3d8b 2 0xf4 1 0>; + qcom,poll6 = <0 0x0 2 0x0 1 0>; + qcom,mem6 = <0 0x0 2 0x0 1 0>; + + qcom,page7 = <1 0x3d81 2 0x01 1 10>; + qcom,poll7 = <0 0x0 2 0x0 1 1>; + qcom,mem7 = <1536 0x7010 2 0 1 0>; + + cam_vdig-supply = <&pm8937_l23>; + cam_vana-supply = <&pm8937_l22>; + cam_vio-supply = <&pm8937_l6>; + cam_vaf-supply = <&pm8937_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_vaf"; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_default + &cam_sensor_front1_default>; + pinctrl-1 = <&cam_sensor_mclk2_sleep &cam_sensor_front1_sleep>; + gpios = <&tlmm 28 0>, + <&tlmm 40 0>, + <&tlmm 39 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_STANDBY2"; + qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg", + "sensor_vreg", + "sensor_gpio", "sensor_gpio" , "sensor_clk"; + qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio", + "sensor_gpio_reset", "sensor_gpio_standby", + "sensor_cam_mclk"; + qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>; + qcom,cam-power-seq-delay = <1 1 1 30 30 5>; + status = "ok"; + clocks = <&clock_gcc clk_mclk2_clk_src>, + <&clock_gcc clk_gcc_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + + qcom,camera@0 { + cell-index = <0>; + compatible = "qcom,camera"; + reg = <0x0>; + qcom,csiphy-sd-index = <0>; + qcom,csid-sd-index = <0>; + qcom,mount-angle = <270>; + qcom,led-flash-src = <&led_flash0>; + qcom,eeprom-src = <&eeprom0>; + qcom,actuator-src = <&actuator0>; + cam_vana-supply = <&pm8937_l22>; + cam_vio-supply = <&pm8937_l6>; + cam_vaf-supply = <&pm8937_l17>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-min-voltage = <0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <0 2800000 2850000>; + qcom,cam-vreg-op-mode = <0 80000 100000>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_reset + &cam_sensor_rear_standby + &cam_sensor_rear_vdig>; + pinctrl-1 = <&cam_sensor_mclk0_sleep + &cam_sensor_rear_reset_sleep + &cam_sensor_rear_standby_sleep + &cam_sensor_rear_vdig_sleep>; + gpios = <&tlmm 26 0>, + <&tlmm 36 0>, + <&tlmm 35 0>, + <&tlmm 62 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-vdig = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0", + "CAM_VDIG"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; + + qcom,camera@1 { + cell-index = <1>; + compatible = "qcom,camera"; + reg = <0x1>; + qcom,csiphy-sd-index = <1>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <90>; + cam_vdig-supply = <&pm8937_l23>; + cam_vana-supply = <&pm8937_l22>; + cam_vio-supply = <&pm8937_l6>; + cam_vaf-supply = <&pm8937_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_vaf"; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <200000 0 80000 100000>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_default + &cam_sensor_front_default>; + pinctrl-1 = <&cam_sensor_mclk1_sleep + &cam_sensor_front_sleep>; + gpios = <&tlmm 27 0>, + <&tlmm 38 0>, + <&tlmm 50 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_STANDBY1"; + qcom,sensor-position = <0x100>; + qcom,sensor-mode = <1>; + qcom,cci-master = <1>; + clocks = <&clock_gcc clk_mclk1_clk_src>, + <&clock_gcc clk_gcc_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; + + qcom,camera@2 { + cell-index = <2>; + compatible = "qcom,camera"; + reg = <0x02>; + qcom,csiphy-sd-index = <1>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <90>; + qcom,eeprom-src = <&eeprom1>; + qcom,actuator-src = <&actuator1>; + cam_vdig-supply = <&pm8937_l23>; + cam_vana-supply = <&pm8937_l22>; + cam_vio-supply = <&pm8937_l6>; + cam_vaf-supply = <&pm8937_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_vaf"; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_default + &cam_sensor_front1_default>; + pinctrl-1 = <&cam_sensor_mclk2_sleep + &cam_sensor_front1_sleep>; + gpios = <&tlmm 28 0>, + <&tlmm 40 0>, + <&tlmm 39 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_STANDBY2"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_gcc clk_mclk2_clk_src>, + <&clock_gcc clk_gcc_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8937-cdp.dtsi b/arch/arm64/boot/dts/qcom/msm8937-cdp.dtsi index 46e480ed7f11..c4100ab27c9d 100644 --- a/arch/arm64/boot/dts/qcom/msm8937-cdp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8937-cdp.dtsi @@ -12,6 +12,7 @@ */ #include <dt-bindings/clock/msm-clocks-8952.h> +#include "msm8937-camera-sensor-cdp.dtsi" &soc { gpio_keys { diff --git a/arch/arm64/boot/dts/qcom/pm8937.dtsi b/arch/arm64/boot/dts/qcom/pm8937.dtsi index 18a3270c3a0d..b97cec6b7871 100644 --- a/arch/arm64/boot/dts/qcom/pm8937.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8937.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, 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 @@ -284,6 +284,7 @@ qcom,adc-bit-resolution = <15>; qcom,adc-vdd-reference = <1800>; qcom,adc_tm-vadc = <&pm8937_vadc>; + #thermal-sensor-cells = <1>; chan@36 { label = "pa_therm0"; diff --git a/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts b/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts index f7b9ec1d9207..5df6dc42f122 100644 --- a/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts +++ b/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts @@ -26,8 +26,10 @@ qcom,msm-id = <245 0>, <258 0>, <275 0>, - <300 0>; - qcom,board-id = <8 0x10f>; + <300 0>, + <301 0>; + qcom,board-id = <8 0x10f>, + <8 0x117>; qcom,pmic-id = <0x0001001b 0x0 0x0 0x0>, <0x0001011b 0x0 0x0 0x0>; }; diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c index 6254f45ca907..2ba2c204758b 100644 --- a/drivers/cpufreq/cpufreq_times.c +++ b/drivers/cpufreq/cpufreq_times.c @@ -29,8 +29,10 @@ static DECLARE_HASHTABLE(uid_hash_table, UID_HASH_BITS); -static DEFINE_SPINLOCK(task_time_in_state_lock); /* task->time_in_state */ -static DEFINE_SPINLOCK(uid_lock); /* uid_hash_table */ +/* task->time_in_state */ +static __cacheline_aligned_in_smp DEFINE_SPINLOCK(task_time_in_state_lock); +/* uid_hash_table */ +static __cacheline_aligned_in_smp DEFINE_SPINLOCK(uid_lock); struct uid_entry { uid_t uid; diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index a0a0daf42c6a..f80c371b4666 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, 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 @@ -140,9 +140,18 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) struct sde_hdcp_ops *ops; int rc = 0; u32 hdcp_auth_state; + u8 sink_status = 0; dp = container_of(dw, struct dp_display_private, hdcp_cb_work); + drm_dp_dpcd_readb(dp->aux->drm_aux, DP_SINK_STATUS, &sink_status); + sink_status &= (DP_RECEIVE_PORT_0_STATUS | DP_RECEIVE_PORT_1_STATUS); + if (sink_status < 1) { + pr_debug("Sink not synchronized. Queuing again then exiting\n"); + queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ); + return; + } + rc = dp->catalog->ctrl.read_hdcp_status(&dp->catalog->ctrl); if (rc >= 0) { hdcp_auth_state = (rc >> 20) & 0x3; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h b/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h index cdcb331dbf9d..9f81ed1411e0 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, 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 @@ -261,13 +261,13 @@ void *dsi_register_clk_handle(void *clk_mngr, char *client); int dsi_deregister_clk_handle(void *client); /** - * dsi_display_link_clk_force_update_ctrl() - force to set link clks + * dsi_display_link_clk_force_update() - force to set link clks * @handle: Handle of desired DSI clock client. * * return: error code in case of failure or 0 for success. */ -int dsi_display_link_clk_force_update_ctrl(void *handle); +int dsi_display_link_clk_force_update(void *handle); /** * dsi_display_clk_ctrl() - set frequencies for link clks @@ -277,7 +277,8 @@ int dsi_display_link_clk_force_update_ctrl(void *handle); * * return: error code in case of failure or 0 for success. */ -int dsi_display_clk_ctrl(void *handle, u32 clk_type, u32 clk_state); +int dsi_display_clk_ctrl(void *handle, enum dsi_clk_type clk_type, + enum dsi_clk_state clk_state); /** * dsi_clk_set_link_frequencies() - set frequencies for link clks @@ -331,4 +332,14 @@ int dsi_clk_prepare_enable(struct dsi_clk_link_set *clk); * @clk: list of src clocks. */ void dsi_clk_disable_unprepare(struct dsi_clk_link_set *clk); + +/** + * dsi_clk_req_state() - request to change dsi clock state + * @client: DSI clocl client pointer. + * @clk: DSI clock list. + * @state: Requested state of the clock. + */ +int dsi_clk_req_state(void *client, enum dsi_clk_type clk, + enum dsi_clk_state state); + #endif /* _DSI_CLK_H_ */ diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c index 9592603f7491..2faccadd829c 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, 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 @@ -1255,9 +1255,7 @@ int dsi_clk_req_state(void *client, enum dsi_clk_type clk, return rc; } -DEFINE_MUTEX(dsi_mngr_clk_mutex); - -static int dsi_display_link_clk_force_update(void *client) +int dsi_display_link_clk_force_update(void *client) { int rc = 0; struct dsi_clk_client_info *c = client; @@ -1304,42 +1302,6 @@ error: } -int dsi_display_link_clk_force_update_ctrl(void *handle) -{ - int rc = 0; - - if (!handle) { - pr_err("%s: Invalid arg\n", __func__); - return -EINVAL; - } - - mutex_lock(&dsi_mngr_clk_mutex); - - rc = dsi_display_link_clk_force_update(handle); - - mutex_unlock(&dsi_mngr_clk_mutex); - - return rc; -} - -int dsi_display_clk_ctrl(void *handle, u32 clk_type, u32 clk_state) -{ - int rc = 0; - - if (!handle) { - pr_err("%s: Invalid arg\n", __func__); - return -EINVAL; - } - - mutex_lock(&dsi_mngr_clk_mutex); - rc = dsi_clk_req_state(handle, clk_type, clk_state); - if (rc) - pr_err("%s: failed set clk state, rc = %d\n", __func__, rc); - mutex_unlock(&dsi_mngr_clk_mutex); - - return rc; -} - void *dsi_register_clk_handle(void *clk_mngr, char *client) { void *handle = NULL; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index f8170b2df2b1..612cea70f4f1 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, 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 @@ -45,6 +45,9 @@ static DEFINE_MUTEX(dsi_display_list_lock); static LIST_HEAD(dsi_display_list); + +static DEFINE_MUTEX(dsi_display_clk_mutex); + static char dsi_display_primary[MAX_CMDLINE_PARAM_LEN]; static char dsi_display_secondary[MAX_CMDLINE_PARAM_LEN]; static struct dsi_display_boot_param boot_displays[MAX_DSI_ACTIVE_DISPLAY]; @@ -4261,6 +4264,7 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, int i; struct dsi_display_ctrl *ctrl; struct dsi_display_mode_priv_info *priv_info; + struct dsi_host_config *config; priv_info = mode->priv_info; if (!dsi_display_has_ext_bridge(display) && !priv_info) { @@ -4269,9 +4273,9 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, return -EINVAL; } - rc = dsi_panel_get_host_cfg_for_mode(display->panel, - mode, - &display->config); + config = &display->config; + + rc = dsi_panel_get_host_cfg_for_mode(display->panel, mode, config); if (rc) { pr_err("[%s] failed to get host config for mode, rc=%d\n", display->name, rc); @@ -4303,8 +4307,16 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, for (i = 0; i < display->ctrl_count; i++) { ctrl = &display->ctrl[i]; - rc = dsi_ctrl_update_host_config(ctrl->ctrl, &display->config, - mode->dsi_mode_flags, display->dsi_clk_handle); + /* + * if bit clock is overridden then update the phy timings + * and clock out control values first. + */ + if (config->bit_clk_rate_hz) + dsi_phy_update_phy_timings(ctrl->phy, config); + + rc = dsi_ctrl_update_host_config(ctrl->ctrl, config, + mode->dsi_mode_flags, + display->dsi_clk_handle); if (rc) { pr_err("[%s] failed to update ctrl config, rc=%d\n", display->name, rc); @@ -4515,6 +4527,43 @@ int dsi_display_splash_res_cleanup(struct dsi_display *display) return rc; } +static int dsi_display_link_clk_force_update_ctrl(void *handle) +{ + int rc = 0; + + if (!handle) { + pr_err("%s: Invalid arg\n", __func__); + return -EINVAL; + } + + mutex_lock(&dsi_display_clk_mutex); + + rc = dsi_display_link_clk_force_update(handle); + + mutex_unlock(&dsi_display_clk_mutex); + + return rc; +} + +int dsi_display_clk_ctrl(void *handle, + enum dsi_clk_type clk_type, enum dsi_clk_state clk_state) +{ + int rc = 0; + + if (!handle) { + pr_err("%s: Invalid arg\n", __func__); + return -EINVAL; + } + + mutex_lock(&dsi_display_clk_mutex); + rc = dsi_clk_req_state(handle, clk_type, clk_state); + if (rc) + pr_err("%s: failed set clk state, rc = %d\n", __func__, rc); + mutex_unlock(&dsi_display_clk_mutex); + + return rc; +} + static int dsi_display_force_update_dsi_clk(struct dsi_display *display) { int rc = 0; @@ -4603,6 +4652,7 @@ static ssize_t sysfs_dynamic_dsi_clk_write(struct device *dev, mutex_lock(&display->display_lock); + mutex_lock(&dsi_display_clk_mutex); display->cached_clk_rate = clk_rate; rc = dsi_display_update_dsi_bitrate(display, clk_rate); if (!rc) { @@ -4615,12 +4665,14 @@ static ssize_t sysfs_dynamic_dsi_clk_write(struct device *dev, atomic_set(&display->clkrate_change_pending, 0); display->cached_clk_rate = 0; + mutex_unlock(&dsi_display_clk_mutex); mutex_unlock(&display->display_lock); return rc; } atomic_set(&display->clkrate_change_pending, 1); + mutex_unlock(&dsi_display_clk_mutex); mutex_unlock(&display->display_lock); return count; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c index ebc699aa13ff..32497ffe9abd 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, 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 @@ -883,6 +883,8 @@ int dsi_phy_update_phy_timings(struct msm_dsi_phy *phy, &phy->cfg.timing, true); if (rc) pr_err("failed to calculate phy timings %d\n", rc); + else + phy->cfg.is_phy_timing_present = true; return rc; } @@ -1045,6 +1047,9 @@ int dsi_phy_set_timing_params(struct msm_dsi_phy *phy, return -EINVAL; } + if (phy->cfg.is_phy_timing_present) + return rc; + mutex_lock(&phy->phy_lock); if (phy->hw.ops.phy_timing_val) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_timing_calc.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_timing_calc.c index 44d092846117..5d9759d90467 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_timing_calc.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_timing_calc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, 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 @@ -434,6 +434,44 @@ error: return rc; } +static int calc_clk_post(struct dsi_phy_hw *phy, + struct phy_clk_params *clk_params, + struct phy_timing_desc *desc) +{ + struct timing_entry *t = &desc->clk_post; + int temp = 0, rc; + + temp = DIV_ROUND_UP(((60 * clk_params->bitclk_mbps) + 9000), 8000) - 1; + t->rec = DIV_ROUND_UP((t->rec_max + (9 * temp)), 10); + + rc = dsi_phy_cmn_validate_and_set(t, "clk_post"); + + pr_debug("clk_post val 0x%x\n", t->reg_value); + return rc; +} + +static int calc_clk_pre(struct dsi_phy_hw *phy, + struct phy_clk_params *clk_params, + struct phy_timing_desc *desc) +{ + struct timing_entry *t = &desc->clk_pre; + int temp = 0, rc; + + temp = desc->clk_prepare.reg_value + desc->clk_zero.reg_value + + desc->hs_rqst_clk.reg_value + 2; + + if (temp > t->rec_max) { + t->rec = DIV_ROUND_UP(((2 * t->rec_max) + (9 * temp)), 10); + t->rec = t->rec / 2; + } else + t->rec = DIV_ROUND_UP((t->rec_max + (9 * temp)), 10); + + rc = dsi_phy_cmn_validate_and_set(t, "clk_pre"); + + pr_debug("clk_pre val 0x%x\n", t->reg_value); + return rc; +} + /** * dsi_phy_calc_timing_params - calculates timing paramets for a given bit clock */ @@ -501,6 +539,19 @@ static int dsi_phy_cmn_calc_timing_params(struct dsi_phy_hw *phy, pr_err("hs_rqst_clk calculations failed, rc=%d\n", rc); goto error; } + + rc = calc_clk_post(phy, clk_params, desc); + if (rc) { + pr_err("clk_post calculation failed, rc= %d\n", rc); + goto error; + } + + rc = calc_clk_pre(phy, clk_params, desc); + if (rc) { + pr_err("clk_pre calculation failed, rc= %d\n", rc); + goto error; + } + error: return rc; } @@ -582,6 +633,8 @@ int dsi_phy_hw_calculate_timing_params(struct dsi_phy_hw *phy, desc.hs_exit.rec_max = hs_exit_reco_max; desc.hs_rqst.mipi_min = hs_rqst_spec_min; desc.hs_rqst_clk.mipi_min = hs_rqst_spec_min; + desc.clk_post.rec_max = 63; + desc.clk_pre.rec_max = 63; if (ops->get_default_phy_params) { ops->get_default_phy_params(&clk_params); @@ -611,6 +664,9 @@ int dsi_phy_hw_calculate_timing_params(struct dsi_phy_hw *phy, if (ops->update_timing_params) { ops->update_timing_params(timing, &desc); + /* update clock out timing control values */ + host->t_clk_pre = desc.clk_pre.reg_value; + host->t_clk_post = desc.clk_post.reg_value; } else { rc = -EINVAL; goto error; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_timing_v3_0.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_timing_v3_0.c index c0e9d441542d..c169a435981b 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_timing_v3_0.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_timing_v3_0.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, 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 @@ -17,14 +17,14 @@ void dsi_phy_hw_v3_0_get_default_phy_params( struct phy_clk_params *params) { - params->clk_prep_buf = 0; - params->clk_zero_buf = 0; - params->clk_trail_buf = 0; - params->hs_prep_buf = 0; - params->hs_zero_buf = 0; - params->hs_trail_buf = 0; + params->clk_prep_buf = 50; + params->clk_zero_buf = 2; + params->clk_trail_buf = 30; + params->hs_prep_buf = 50; + params->hs_zero_buf = 10; + params->hs_trail_buf = 30; params->hs_rqst_buf = 0; - params->hs_exit_buf = 0; + params->hs_exit_buf = 10; } int32_t dsi_phy_hw_v3_0_calc_clk_zero(s64 rec_temp1, s64 mult) diff --git a/drivers/leds/leds-qti-tri-led.c b/drivers/leds/leds-qti-tri-led.c index c303893e1a28..c49465532f83 100644 --- a/drivers/leds/leds-qti-tri-led.c +++ b/drivers/leds/leds-qti-tri-led.c @@ -43,14 +43,14 @@ #define PWM_PERIOD_DEFAULT_NS 1000000 struct pwm_setting { - u32 pre_period_ns; - u32 period_ns; - u32 duty_ns; + u64 pre_period_ns; + u64 period_ns; + u64 duty_ns; }; struct led_setting { - u32 on_ms; - u32 off_ms; + u64 on_ms; + u64 off_ms; enum led_brightness brightness; bool blink; bool breath; @@ -164,24 +164,16 @@ static int __tri_led_set(struct qpnp_led_dev *led) static int qpnp_tri_led_set(struct qpnp_led_dev *led) { - u32 on_ms, off_ms, period_ns, duty_ns; + u64 on_ms, off_ms, period_ns, duty_ns; enum led_brightness brightness = led->led_setting.brightness; int rc = 0; if (led->led_setting.blink) { on_ms = led->led_setting.on_ms; off_ms = led->led_setting.off_ms; - if (on_ms > INT_MAX / NSEC_PER_MSEC) - duty_ns = INT_MAX - 1; - else - duty_ns = on_ms * NSEC_PER_MSEC; - if (on_ms + off_ms > INT_MAX / NSEC_PER_MSEC) { - period_ns = INT_MAX; - duty_ns = (period_ns / (on_ms + off_ms)) * on_ms; - } else { - period_ns = (on_ms + off_ms) * NSEC_PER_MSEC; - } + duty_ns = on_ms * NSEC_PER_MSEC; + period_ns = (on_ms + off_ms) * NSEC_PER_MSEC; if (period_ns < duty_ns && duty_ns != 0) period_ns = duty_ns + 1; @@ -191,15 +183,14 @@ static int qpnp_tri_led_set(struct qpnp_led_dev *led) if (brightness == LED_OFF) duty_ns = 0; - else if (period_ns > INT_MAX / brightness) - duty_ns = (period_ns / LED_FULL) * brightness; - else - duty_ns = (period_ns * brightness) / LED_FULL; + + duty_ns = period_ns * brightness; + do_div(duty_ns, LED_FULL); if (period_ns < duty_ns && duty_ns != 0) period_ns = duty_ns + 1; } - dev_dbg(led->chip->dev, "PWM settings for %s led: period = %dns, duty = %dns\n", + dev_dbg(led->chip->dev, "PWM settings for %s led: period = %lluns, duty = %lluns\n", led->cdev.name, period_ns, duty_ns); led->pwm_setting.duty_ns = duty_ns; diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_virtual_core.c b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_virtual_core.c index 9021ecabb27c..b2575825f983 100644 --- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_virtual_core.c +++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_virtual_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -118,6 +118,14 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw, if ((!rc) && (vaddr_ptr) && (len) && (len >= cdm_cmd->cmd[i].offset)) { + + + if ((len - cdm_cmd->cmd[i].offset) <= + cdm_cmd->cmd[i].len) { + CAM_ERR(CAM_CDM, "Not enough buffer"); + rc = -EINVAL; + break; + } CAM_DBG(CAM_CDM, "hdl=%x vaddr=%pK offset=%d cmdlen=%d:%zu", cdm_cmd->cmd[i].bl_addr.mem_handle, diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context.c b/drivers/media/platform/msm/camera/cam_core/cam_context.c index 4ed53f9b576c..8a3dbba5ec19 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_context.c +++ b/drivers/media/platform/msm/camera/cam_core/cam_context.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -454,7 +454,7 @@ int cam_context_init(struct cam_context *ctx, mutex_init(&ctx->sync_mutex); spin_lock_init(&ctx->lock); - ctx->dev_name = dev_name; + strlcpy(ctx->dev_name, dev_name, CAM_CTX_DEV_NAME_MAX_LENGTH); ctx->dev_id = dev_id; ctx->ctx_id = ctx_id; ctx->ctx_crm_intf = NULL; diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context.h b/drivers/media/platform/msm/camera/cam_core/cam_context.h index 420f9f65987c..8bc4340b9f06 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_context.h +++ b/drivers/media/platform/msm/camera/cam_core/cam_context.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -22,6 +22,9 @@ /* Forward declarations */ struct cam_context; +/* max device name string length*/ +#define CAM_CTX_DEV_NAME_MAX_LENGTH 20 + /* max request number */ #define CAM_CTX_REQ_MAX 20 #define CAM_CTX_CFG_MAX 20 @@ -179,7 +182,7 @@ struct cam_ctx_ops { * */ struct cam_context { - const char *dev_name; + char dev_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; uint64_t dev_id; uint32_t ctx_id; struct list_head list; diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c index 8021f12934a9..dc16733f3bbb 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c +++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -275,6 +275,7 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, uintptr_t packet_addr; struct cam_packet *packet; size_t len = 0; + size_t remain_len = 0; int32_t i = 0, j = 0; if (!ctx || !cmd) { @@ -323,12 +324,21 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, goto free_req; } + remain_len = len; + if ((len < sizeof(struct cam_packet)) || + ((size_t)cmd->offset >= len - sizeof(struct cam_packet))) { + CAM_ERR(CAM_CTXT, "invalid buff length: %zu or offset", len); + return -EINVAL; + } + + remain_len -= (size_t)cmd->offset; packet = (struct cam_packet *) ((uint8_t *)packet_addr + (uint32_t)cmd->offset); /* preprocess the configuration */ memset(&cfg, 0, sizeof(cfg)); cfg.packet = packet; + cfg.remain_len = remain_len; cfg.ctxt_to_hw_map = ctx->ctxt_to_hw_map; cfg.max_hw_update_entries = CAM_CTX_CFG_MAX; cfg.num_hw_update_entries = req->num_hw_update_entries; diff --git a/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h b/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h index 54b0f4d63bf8..656fcfac3996 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h +++ b/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -152,6 +152,7 @@ struct cam_hw_mgr_dump_pf_data { * struct cam_hw_prepare_update_args - Payload for prepare command * * @packet: CSL packet from user mode driver + * @remain_len Remaining length of CPU buffer after config offset * @ctxt_to_hw_map: HW context from the acquire * @max_hw_update_entries: Maximum hardware update entries supported * @hw_update_entries: Actual hardware update configuration (returned) @@ -168,6 +169,7 @@ struct cam_hw_mgr_dump_pf_data { */ struct cam_hw_prepare_update_args { struct cam_packet *packet; + size_t remain_len; void *ctxt_to_hw_map; uint32_t max_hw_update_entries; struct cam_hw_update_entry *hw_update_entries; diff --git a/drivers/media/platform/msm/camera/cam_core/cam_node.c b/drivers/media/platform/msm/camera/cam_core/cam_node.c index 212a11bf2ee7..0f3f2859a420 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_node.c +++ b/drivers/media/platform/msm/camera/cam_core/cam_node.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -34,7 +34,7 @@ static void cam_node_print_ctx_state( spin_lock(&ctx->lock); CAM_INFO(CAM_CORE, "[%s][%d] : state=%d, refcount=%d, active_req_list=%d, pending_req_list=%d, wait_req_list=%d, free_req_list=%d", - ctx->dev_name ? ctx->dev_name : "null", + ctx->dev_name, i, ctx->state, atomic_read(&(ctx->refcount.refcount)), list_empty(&ctx->active_req_list), @@ -154,6 +154,12 @@ static int __cam_node_handle_start_dev(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + rc = cam_context_handle_start_dev(ctx, start); if (rc) CAM_ERR(CAM_CORE, "Start failure for node %s", node->name); @@ -187,6 +193,12 @@ static int __cam_node_handle_stop_dev(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + rc = cam_context_handle_stop_dev(ctx, stop); if (rc) CAM_ERR(CAM_CORE, "Stop failure for node %s", node->name); @@ -220,6 +232,12 @@ static int __cam_node_handle_config_dev(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + rc = cam_context_handle_config_dev(ctx, config); if (rc) CAM_ERR(CAM_CORE, "Config failure for node %s", node->name); @@ -253,6 +271,12 @@ static int __cam_node_handle_flush_dev(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + rc = cam_context_handle_flush_dev(ctx, flush); if (rc) CAM_ERR(CAM_CORE, "Flush failure for node %s", node->name); @@ -286,6 +310,12 @@ static int __cam_node_handle_release_dev(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + if (ctx->state > CAM_CTX_UNINIT && ctx->state < CAM_CTX_STATE_MAX) { rc = cam_context_handle_release_dev(ctx, release); if (rc) diff --git a/drivers/media/platform/msm/camera/cam_core/cam_node.h b/drivers/media/platform/msm/camera/cam_core/cam_node.h index 4303ee38dd54..e270bb4105fd 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_node.h +++ b/drivers/media/platform/msm/camera/cam_core/cam_node.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -18,7 +18,6 @@ #include "cam_hw_mgr_intf.h" #include "cam_req_mgr_interface.h" -#define CAM_NODE_NAME_LENGTH_MAX 256 #define CAM_NODE_STATE_UNINIT 0 #define CAM_NODE_STATE_INIT 1 @@ -38,7 +37,7 @@ * */ struct cam_node { - char name[CAM_NODE_NAME_LENGTH_MAX]; + char name[CAM_CTX_DEV_NAME_MAX_LENGTH]; uint32_t state; /* context pool */ diff --git a/drivers/media/platform/msm/camera/cam_fd/cam_fd_context.c b/drivers/media/platform/msm/camera/cam_fd/cam_fd_context.c index 99c509c62809..70ff72c39028 100644 --- a/drivers/media/platform/msm/camera/cam_fd/cam_fd_context.c +++ b/drivers/media/platform/msm/camera/cam_fd/cam_fd_context.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -17,7 +17,7 @@ #include "cam_fd_context.h" #include "cam_trace.h" -static const char fd_dev_name[] = "fd"; +static const char fd_dev_name[] = "cam-fd"; /* Functions in Available state */ static int __cam_fd_ctx_acquire_dev_in_available(struct cam_context *ctx, diff --git a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c index 7e78f458ec2b..c72893561980 100644 --- a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -30,7 +30,8 @@ static struct cam_fd_hw_mgr g_fd_hw_mgr; -static int cam_fd_mgr_util_packet_validate(struct cam_packet *packet) +static int cam_fd_mgr_util_packet_validate(struct cam_packet *packet, + size_t remain_len) { struct cam_cmd_buf_desc *cmd_desc = NULL; int i, rc; @@ -50,7 +51,7 @@ static int cam_fd_mgr_util_packet_validate(struct cam_packet *packet) packet->patch_offset, packet->num_patches, packet->kmd_cmd_buf_offset, packet->kmd_cmd_buf_index); - if (cam_packet_util_validate_packet(packet)) { + if (cam_packet_util_validate_packet(packet, remain_len)) { CAM_ERR(CAM_FD, "invalid packet:%d %d %d %d %d", packet->kmd_cmd_buf_index, packet->num_cmd_buf, packet->cmd_buf_offset, @@ -608,7 +609,13 @@ static int cam_fd_mgr_util_prepare_io_buf_info(int32_t iommu_hdl, rc); return rc; } - + if (io_cfg[i].offsets[plane] >= size) { + CAM_ERR(CAM_FD, + "Invalid cpu buf %d %d %d", + io_cfg[i].direction, + io_cfg[i].resource_type, plane); + return -EINVAL; + } cpu_addr[plane] += io_cfg[i].offsets[plane]; } @@ -1559,7 +1566,8 @@ static int cam_fd_mgr_hw_prepare_update(void *hw_mgr_priv, goto error; } - rc = cam_fd_mgr_util_packet_validate(prepare->packet); + rc = cam_fd_mgr_util_packet_validate(prepare->packet, + prepare->remain_len); if (rc) { CAM_ERR(CAM_FD, "Error in packet validation %d", rc); goto error; diff --git a/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c b/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c index 522a602883eb..7ad562e058af 100644 --- a/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c +++ b/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -27,7 +27,7 @@ #include "cam_debug_util.h" #include "cam_packet_util.h" -static const char icp_dev_name[] = "icp"; +static const char icp_dev_name[] = "cam-icp"; static int cam_icp_context_dump_active_request(void *data, unsigned long iova, uint32_t buf_info) diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index ca8bb3c8d543..94e259311326 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -3698,6 +3698,9 @@ static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv, packet = prepare_args->packet; + if (cam_packet_util_validate_packet(packet, prepare_args->remain_len)) + return -EINVAL; + rc = cam_icp_mgr_pkt_validation(packet); if (rc) { mutex_unlock(&ctx_data->ctx_mutex); diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index aaa172deea97..6a85bfca4021 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -27,7 +27,7 @@ #include "cam_context_utils.h" #include "cam_common_util.h" -static const char isp_dev_name[] = "isp"; +static const char isp_dev_name[] = "cam-isp"; static int cam_isp_context_dump_active_request(void *data, unsigned long iova, uint32_t buf_info); @@ -2035,6 +2035,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( uintptr_t packet_addr; struct cam_packet *packet; size_t len = 0; + size_t remain_len = 0; struct cam_hw_prepare_update_args cfg; struct cam_req_mgr_add_request add_req; struct cam_isp_context *ctx_isp = @@ -2069,6 +2070,14 @@ static int __cam_isp_ctx_config_dev_in_top_state( goto free_req; } + remain_len = len; + if ((len < sizeof(struct cam_packet)) || + ((size_t)cmd->offset >= len - sizeof(struct cam_packet))) { + CAM_ERR(CAM_ISP, "invalid buff length: %zu or offset", len); + return -EINVAL; + } + + remain_len -= (size_t)cmd->offset; packet = (struct cam_packet *)(packet_addr + (uint32_t)cmd->offset); CAM_DBG(CAM_ISP, "pack_handle %llx", cmd->packet_handle); CAM_DBG(CAM_ISP, "packet address is 0x%zx", packet_addr); @@ -2082,6 +2091,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( /* preprocess the configuration */ memset(&cfg, 0, sizeof(cfg)); cfg.packet = packet; + cfg.remain_len = remain_len; cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; cfg.max_hw_update_entries = CAM_ISP_CTX_CFG_MAX; cfg.hw_update_entries = req_isp->cfg; diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index e8e9aa1890b3..45f88b3e79da 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -2675,7 +2675,8 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, ctx = (struct cam_ife_hw_mgr_ctx *) prepare->ctxt_to_hw_map; hw_mgr = (struct cam_ife_hw_mgr *)hw_mgr_priv; - rc = cam_packet_util_validate_packet(prepare->packet); + rc = cam_packet_util_validate_packet(prepare->packet, + prepare->remain_len); if (rc) return rc; diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index f652256d3dc5..abf208cb0361 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -105,7 +105,7 @@ static int cam_isp_update_dual_config( struct cam_isp_hw_dual_isp_update_args dual_isp_update_args; uint32_t outport_id; uint32_t ports_plane_idx; - size_t len = 0; + size_t len = 0, remain_len = 0; uint32_t *cpu_addr; uint32_t i, j; @@ -117,9 +117,22 @@ static int cam_isp_update_dual_config( if (rc) return rc; + if ((len < sizeof(struct cam_isp_dual_config)) || + (cmd_desc->offset >= + (len - sizeof(struct cam_isp_dual_config)))) { + CAM_ERR(CAM_UTIL, "not enough buffer provided"); + return -EINVAL; + } + remain_len = len - cmd_desc->offset; cpu_addr += (cmd_desc->offset / 4); dual_config = (struct cam_isp_dual_config *)cpu_addr; + if ((dual_config->num_ports * + sizeof(struct cam_isp_dual_stripe_config)) > + (remain_len - offsetof(struct cam_isp_dual_config, stripes))) { + CAM_ERR(CAM_UTIL, "not enough buffer for all the dual configs"); + return -EINVAL; + } for (i = 0; i < dual_config->num_ports; i++) { if (i >= CAM_ISP_IFE_OUT_RES_MAX) { diff --git a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c index 287d4a4162fc..1c910621b655 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -22,7 +22,7 @@ #include "cam_debug_util.h" #include "cam_packet_util.h" -static const char jpeg_dev_name[] = "jpeg"; +static const char jpeg_dev_name[] = "cam-jpeg"; static int cam_jpeg_context_dump_active_request(void *data, unsigned long iova, uint32_t buf_info) diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 7f0199f6e119..77fea6bfbc06 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -275,6 +275,12 @@ static int cam_jpeg_insert_cdm_change_base( "unable to get src buf info for cmd buf: %d", rc); return rc; } + + if (config_args->hw_update_entries[CAM_JPEG_CHBASE].offset >= + ch_base_len) { + CAM_ERR(CAM_JPEG, "Not enough buf"); + return -EINVAL; + } CAM_DBG(CAM_JPEG, "iova %pK len %zu offset %d", (void *)iova_addr, ch_base_len, config_args->hw_update_entries[CAM_JPEG_CHBASE].offset); @@ -713,7 +719,7 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv, return -EINVAL; } - rc = cam_packet_util_validate_packet(packet); + rc = cam_packet_util_validate_packet(packet, prepare_args->remain_len); if (rc) { CAM_ERR(CAM_JPEG, "invalid packet %d", rc); return rc; diff --git a/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_context.c b/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_context.c index 99a8fe1f8eca..26bdc31250d1 100644 --- a/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_context.c +++ b/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_context.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -16,7 +16,7 @@ #include "cam_debug_util.h" #include "cam_lrme_context.h" -static const char lrme_dev_name[] = "lrme"; +static const char lrme_dev_name[] = "cam-lrme"; static int __cam_lrme_ctx_acquire_dev_in_available(struct cam_context *ctx, struct cam_acquire_dev_cmd *cmd) diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c index eecba3972875..c6250327b640 100644 --- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -83,7 +83,8 @@ static int cam_lrme_mgr_util_get_device(struct cam_lrme_hw_mgr *hw_mgr, return 0; } -static int cam_lrme_mgr_util_packet_validate(struct cam_packet *packet) +static int cam_lrme_mgr_util_packet_validate(struct cam_packet *packet, + size_t remain_len) { struct cam_cmd_buf_desc *cmd_desc = NULL; int i, rc; @@ -105,7 +106,7 @@ static int cam_lrme_mgr_util_packet_validate(struct cam_packet *packet) packet->patch_offset, packet->num_patches, packet->kmd_cmd_buf_offset, packet->kmd_cmd_buf_index); - if (cam_packet_util_validate_packet(packet)) { + if (cam_packet_util_validate_packet(packet, remain_len)) { CAM_ERR(CAM_LRME, "invalid packet:%d %d %d %d %d", packet->kmd_cmd_buf_index, packet->num_cmd_buf, packet->cmd_buf_offset, @@ -166,13 +167,6 @@ static int cam_lrme_mgr_util_prepare_io_buffer(int32_t iommu_hdl, io_cfg[i].resource_type, io_cfg[i].fence, io_cfg[i].format); - if ((num_in_buf > io_buf_size) || - (num_out_buf > io_buf_size)) { - CAM_ERR(CAM_LRME, "Invalid number of buffers %d %d %d", - num_in_buf, num_out_buf, io_buf_size); - return -EINVAL; - } - memset(io_addr, 0, sizeof(io_addr)); for (plane = 0; plane < CAM_PACKET_MAX_PLANES; plane++) { if (!io_cfg[i].mem_handle[plane]) @@ -186,6 +180,12 @@ static int cam_lrme_mgr_util_prepare_io_buffer(int32_t iommu_hdl, return -ENOMEM; } + if ((size_t)io_cfg[i].offsets[plane] >= size) { + CAM_ERR(CAM_LRME, "Invalid plane offset: %zu", + (size_t)io_cfg[i].offsets[plane]); + return -EINVAL; + } + io_addr[plane] += io_cfg[i].offsets[plane]; CAM_DBG(CAM_LRME, "IO Address[%d][%d] : %llu", @@ -194,6 +194,12 @@ static int cam_lrme_mgr_util_prepare_io_buffer(int32_t iommu_hdl, switch (io_cfg[i].direction) { case CAM_BUF_INPUT: { + if (num_in_buf >= io_buf_size) { + CAM_ERR(CAM_LRME, + "Invalid number of buffers %d %d %d", + num_in_buf, num_out_buf, io_buf_size); + return -EINVAL; + } prepare->in_map_entries[num_in_buf].resource_handle = io_cfg[i].resource_type; prepare->in_map_entries[num_in_buf].sync_id = @@ -209,6 +215,12 @@ static int cam_lrme_mgr_util_prepare_io_buffer(int32_t iommu_hdl, break; } case CAM_BUF_OUTPUT: { + if (num_out_buf >= io_buf_size) { + CAM_ERR(CAM_LRME, + "Invalid number of buffers %d %d %d", + num_in_buf, num_out_buf, io_buf_size); + return -EINVAL; + } prepare->out_map_entries[num_out_buf].resource_handle = io_cfg[i].resource_type; prepare->out_map_entries[num_out_buf].sync_id = @@ -841,7 +853,7 @@ static int cam_lrme_mgr_hw_prepare_update(void *hw_mgr_priv, goto error; } - rc = cam_lrme_mgr_util_packet_validate(args->packet); + rc = cam_lrme_mgr_util_packet_validate(args->packet, args->remain_len); if (rc) { CAM_ERR(CAM_LRME, "Error in packet validation %d", rc); goto error; diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c index f2c243e8c7a9..66142dbf3f74 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, 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 @@ -23,6 +23,7 @@ #include "cam_debug_util.h" static struct cam_mem_table tbl; +static atomic_t cam_mem_mgr_state = ATOMIC_INIT(CAM_MEM_MGR_UNINITIALIZED); static int cam_mem_util_map_cpu_va(struct ion_handle *hdl, uintptr_t *vaddr, @@ -108,6 +109,7 @@ int cam_mem_mgr_init(void) tbl.bufq[i].buf_handle = -1; } mutex_init(&tbl.m_lock); + atomic_set(&cam_mem_mgr_state, CAM_MEM_MGR_INITIALIZED); return rc; bitmap_fail: @@ -151,6 +153,11 @@ int cam_mem_get_io_buf(int32_t buf_handle, int32_t mmu_handle, { int rc = 0, idx; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + idx = CAM_MEM_MGR_GET_HDL_IDX(buf_handle); if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) return -EINVAL; @@ -191,6 +198,10 @@ int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr, size_t *len) uintptr_t kvaddr = 0; size_t klen = 0; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } if (!buf_handle || !vaddr_ptr || !len) return -EINVAL; @@ -242,6 +253,11 @@ int cam_mem_mgr_cache_ops(struct cam_mem_cache_ops_cmd *cmd) uint32_t ion_cache_ops; unsigned long ion_flag = 0; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!cmd) return -EINVAL; @@ -518,6 +534,11 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) dma_addr_t hw_vaddr = 0; size_t len; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!cmd) { CAM_ERR(CAM_MEM, " Invalid argument"); return -EINVAL; @@ -616,6 +637,11 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) dma_addr_t hw_vaddr = 0; size_t len = 0; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!cmd || (cmd->fd < 0)) { CAM_ERR(CAM_MEM, "Invalid argument"); return -EINVAL; @@ -801,6 +827,7 @@ static int cam_mem_mgr_cleanup_table(void) void cam_mem_mgr_deinit(void) { + atomic_set(&cam_mem_mgr_state, CAM_MEM_MGR_UNINITIALIZED); cam_mem_mgr_cleanup_table(); mutex_lock(&tbl.m_lock); bitmap_zero(tbl.bitmap, tbl.bits); @@ -889,6 +916,11 @@ int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd) int idx; int rc; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!cmd) { CAM_ERR(CAM_MEM, "Invalid argument"); return -EINVAL; @@ -936,6 +968,11 @@ int cam_mem_mgr_request_mem(struct cam_mem_mgr_request_desc *inp, enum cam_smmu_region_id region = CAM_SMMU_REGION_SHARED; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!inp || !out) { CAM_ERR(CAM_MEM, "Invalid params"); return -EINVAL; @@ -1054,6 +1091,11 @@ int cam_mem_mgr_release_mem(struct cam_mem_mgr_memory_desc *inp) int32_t idx; int rc; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!inp) { CAM_ERR(CAM_MEM, "Invalid argument"); return -EINVAL; @@ -1103,6 +1145,11 @@ int cam_mem_mgr_reserve_memory_region(struct cam_mem_mgr_request_desc *inp, int32_t smmu_hdl = 0; int32_t num_hdl = 0; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!inp || !out) { CAM_ERR(CAM_MEM, "Invalid param(s)"); return -EINVAL; @@ -1195,6 +1242,11 @@ int cam_mem_mgr_free_memory_region(struct cam_mem_mgr_memory_desc *inp) int rc; int32_t smmu_hdl; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!inp) { CAM_ERR(CAM_MEM, "Invalid argument"); return -EINVAL; diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.h index 92c366d723f9..73f0eb3d3425 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.h +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, 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 @@ -20,6 +20,12 @@ #define CAM_MEM_BUFQ_MAX 1024 +/* Enum for possible mem mgr states */ +enum cam_mem_mgr_state { + CAM_MEM_MGR_UNINITIALIZED, + CAM_MEM_MGR_INITIALIZED, +}; + /*Enum for possible SMMU operations */ enum cam_smmu_mapping_client { CAM_SMMU_MAPPING_USER, diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index 1295e291ce28..8de297db8ff7 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -2779,7 +2779,8 @@ int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control) goto end; } - if (control->num_links > MAX_LINKS_PER_SESSION) { + if ((control->num_links <= 0) || + (control->num_links > MAX_LINKS_PER_SESSION)) { CAM_ERR(CAM_CRM, "Invalid number of links %d", control->num_links); rc = -EINVAL; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c index c14a74d7c862..8519115cb437 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -17,6 +17,7 @@ #include "cam_trace.h" #include "cam_res_mgr_api.h" #include "cam_common_util.h" +#include "cam_packet_util.h" int32_t cam_actuator_construct_default_power_setting( struct cam_sensor_power_ctrl_t *power_info) @@ -214,12 +215,12 @@ static int32_t cam_actuator_i2c_modes_util( } int32_t cam_actuator_slaveInfo_pkt_parser(struct cam_actuator_ctrl_t *a_ctrl, - uint32_t *cmd_buf) + uint32_t *cmd_buf, size_t len) { int32_t rc = 0; struct cam_cmd_i2c_info *i2c_info; - if (!a_ctrl || !cmd_buf) { + if (!a_ctrl || !cmd_buf || (len < sizeof(struct cam_cmd_i2c_info))) { CAM_ERR(CAM_ACTUATOR, "Invalid Args"); return -EINVAL; } @@ -413,6 +414,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, int32_t i = 0; uint32_t total_cmd_buf_in_bytes = 0; size_t len_of_buff = 0; + size_t remain_len = 0; uint32_t *offset = NULL; uint32_t *cmd_buf = NULL; uintptr_t generic_ptr; @@ -449,16 +451,27 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, return rc; } - if (config.offset > len_of_buff) { + remain_len = len_of_buff; + if ((sizeof(struct cam_packet) > len_of_buff) || + ((size_t)config.offset >= len_of_buff - + sizeof(struct cam_packet))) { CAM_ERR(CAM_ACTUATOR, - "offset is out of bounds: offset: %lld len: %zu", - config.offset, len_of_buff); + "Inval cam_packet strut size: %zu, len_of_buff: %zu", + sizeof(struct cam_packet), len_of_buff); return -EINVAL; } - csl_packet = - (struct cam_packet *)(generic_ptr + (uint32_t)config.offset); - CAM_DBG(CAM_ACTUATOR, "Pkt opcode: %d", csl_packet->header.op_code); + remain_len -= (size_t)config.offset; + csl_packet = (struct cam_packet *) + (generic_ptr + (uint32_t)config.offset); + + if (cam_packet_util_validate_packet(csl_packet, + remain_len)) { + CAM_ERR(CAM_ACTUATOR, "Invalid packet params"); + return -EINVAL; + } + + CAM_DBG(CAM_ACTUATOR, "Pkt opcode: %d", csl_packet->header.op_code); switch (csl_packet->header.op_code & 0xFFFFFF) { case CAM_ACTUATOR_PACKET_OPCODE_INIT: @@ -482,6 +495,14 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, CAM_ERR(CAM_ACTUATOR, "invalid cmd buf"); return -EINVAL; } + if ((len_of_buff < sizeof(struct common_header)) || + (cmd_desc[i].offset > (len_of_buff - + sizeof(struct common_header)))) { + CAM_ERR(CAM_ACTUATOR, + "Invalid length for sensor cmd"); + return -EINVAL; + } + remain_len = len_of_buff - cmd_desc[i].offset; cmd_buf += cmd_desc[i].offset / sizeof(uint32_t); cmm_hdr = (struct common_header *)cmd_buf; @@ -490,7 +511,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, CAM_DBG(CAM_ACTUATOR, "Received slave info buffer"); rc = cam_actuator_slaveInfo_pkt_parser( - a_ctrl, cmd_buf); + a_ctrl, cmd_buf, remain_len); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Failed to parse slave info: %d", rc); @@ -504,7 +525,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, rc = cam_sensor_update_power_settings( cmd_buf, total_cmd_buf_in_bytes, - power_info); + power_info, remain_len); if (rc) { CAM_ERR(CAM_ACTUATOR, "Failed:parse power settings: %d", diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.h index c4333a023607..e581823a9add 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -34,6 +34,7 @@ #include "cam_sensor_util.h" #include "cam_soc_util.h" #include "cam_debug_util.h" +#include "cam_context.h" #define NUM_MASTERS 2 #define NUM_QUEUES 2 @@ -92,6 +93,7 @@ struct intf_params { /** * struct cam_actuator_ctrl_t + * @device_name: Device name * @i2c_driver: I2C device info * @pdev: Platform device * @cci_i2c_master: I2C structure @@ -107,9 +109,9 @@ struct intf_params { * @i2c_data: I2C register settings structure * @act_info: Sensor query cap structure * @of_node: Node ptr - * @device_name: Device name */ struct cam_actuator_ctrl_t { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct i2c_driver *i2c_driver; enum cci_i2c_master_t cci_i2c_master; struct camera_io_master io_master_info; @@ -123,7 +125,6 @@ struct cam_actuator_ctrl_t { struct i2c_data_settings i2c_data; struct cam_actuator_query_cap act_info; struct intf_params bridge_intf; - char device_name[20]; }; #endif /* _CAM_ACTUATOR_DEV_H_ */ diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/Makefile index 8edbea5c2723..e2e79e331322 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/Makefile +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/Makefile @@ -5,5 +5,6 @@ ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_ut ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/ +ccflags-y += -Idrivers/media/platform/msm/camera/cam_core obj-$(CONFIG_SPECTRA_CAMERA) += cam_csiphy_soc.o cam_csiphy_dev.o cam_csiphy_core.o diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index 03c7d7b6c007..9a1188537dd7 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -15,6 +15,8 @@ #include "cam_csiphy_dev.h" #include "cam_csiphy_soc.h" #include "cam_common_util.h" +#include "cam_packet_util.h" + #include <soc/qcom/scm.h> #include <cam_mem_mgr.h> @@ -168,6 +170,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev, uint32_t *cmd_buf = NULL; struct cam_csiphy_info *cam_cmd_csiphy_info = NULL; size_t len; + size_t remain_len; if (!cfg_dev || !csiphy_dev) { CAM_ERR(CAM_CSIPHY, "Invalid Args"); @@ -181,16 +184,25 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev, return rc; } - if (cfg_dev->offset > len) { + remain_len = len; + if ((sizeof(struct cam_packet) > len) || + ((size_t)cfg_dev->offset >= len - sizeof(struct cam_packet))) { CAM_ERR(CAM_CSIPHY, "offset is out of bounds: offset: %lld len: %zu", cfg_dev->offset, len); return -EINVAL; } + remain_len -= (size_t)cfg_dev->offset; csl_packet = (struct cam_packet *) (generic_ptr + (uint32_t)cfg_dev->offset); + if (cam_packet_util_validate_packet(csl_packet, + remain_len)) { + CAM_ERR(CAM_CSIPHY, "Invalid packet params"); + return -EINVAL; + } + cmd_desc = (struct cam_cmd_buf_desc *) ((uint32_t *)&csl_packet->payload + csl_packet->cmd_buf_offset / 4); @@ -203,6 +215,13 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev, return rc; } + if ((len < sizeof(struct cam_csiphy_info)) || + (cmd_desc->offset > (len - sizeof(struct cam_csiphy_info)))) { + CAM_ERR(CAM_CSIPHY, + "Not enough buffer provided for cam_cisphy_info"); + return -EINVAL; + } + cmd_buf = (uint32_t *)generic_ptr; cmd_buf += cmd_desc->offset / 4; cam_cmd_csiphy_info = (struct cam_csiphy_info *)cmd_buf; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h index ac9625501035..5ece65112ea9 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -35,6 +35,7 @@ #include <cam_cpas_api.h> #include "cam_soc_util.h" #include "cam_debug_util.h" +#include "cam_context.h" #define MAX_CSIPHY 3 #define MAX_DPHY_DATA_LN 4 @@ -194,6 +195,7 @@ struct cam_csiphy_param { /** * struct csiphy_device + * @device_name: Device name * @pdev: Platform device * @irq: Interrupt structure * @base: Base address @@ -219,6 +221,7 @@ struct cam_csiphy_param { * device is for combo mode */ struct csiphy_device { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct mutex mutex; uint32_t hw_version; enum cam_csiphy_state csiphy_state; @@ -237,7 +240,6 @@ struct csiphy_device { uint32_t clk_lane; uint32_t acquire_count; uint32_t start_dev_count; - char device_name[20]; uint32_t is_acquired_dev_combo_mode; struct cam_hw_soc_info soc_info; uint32_t cpas_handle; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/Makefile index 5490992365fc..75172556ed60 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/Makefile +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/Makefile @@ -5,4 +5,6 @@ ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_ut ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/ +ccflags-y += -Idrivers/media/platform/msm/camera/cam_core + obj-$(CONFIG_SPECTRA_CAMERA) += cam_eeprom_dev.o cam_eeprom_core.o cam_eeprom_soc.o diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 92bace40be4a..4dce293eb7ab 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -18,6 +18,7 @@ #include "cam_eeprom_soc.h" #include "cam_debug_util.h" #include "cam_common_util.h" +#include "cam_packet_util.h" /** * cam_eeprom_read_memory() - read map data into buffer @@ -413,7 +414,7 @@ static int32_t cam_eeprom_update_slaveInfo(struct cam_eeprom_ctrl_t *e_ctrl, static int32_t cam_eeprom_parse_memory_map( struct cam_eeprom_memory_block_t *data, void *cmd_buf, int cmd_length, uint16_t *cmd_length_bytes, - int *num_map) + int *num_map, size_t remain_buf_len) { int32_t rc = 0; int32_t cnt = 0; @@ -427,8 +428,21 @@ static int32_t cam_eeprom_parse_memory_map( struct cam_cmd_i2c_continuous_rd *i2c_cont_rd = NULL; struct cam_cmd_conditional_wait *i2c_poll = NULL; struct cam_cmd_unconditional_wait *i2c_uncond_wait = NULL; + size_t validate_size = 0; generic_op_code = cmm_hdr->third_byte; + + if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR) + validate_size = sizeof(struct cam_cmd_i2c_random_wr); + else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD) + validate_size = sizeof(struct cam_cmd_i2c_continuous_rd); + else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) + validate_size = sizeof(struct cam_cmd_unconditional_wait); + + if (remain_buf_len < validate_size) { + CAM_ERR(CAM_EEPROM, "not enough buffer"); + return -EINVAL; + } switch (cmm_hdr->cmd_type) { case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR: i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf; @@ -535,6 +549,7 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl, uint32_t *cmd_buf = NULL; uintptr_t generic_pkt_addr; size_t pkt_len = 0; + size_t remain_len = 0; uint32_t total_cmd_buf_in_bytes = 0; uint32_t processed_cmd_buf_in_bytes = 0; struct common_header *cmm_hdr = NULL; @@ -577,13 +592,36 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl, CAM_ERR(CAM_EEPROM, "invalid cmd buf"); return -EINVAL; } + + if ((pkt_len < sizeof(struct common_header)) || + (cmd_desc[i].offset > (pkt_len - + sizeof(struct common_header)))) { + CAM_ERR(CAM_EEPROM, "Not enough buffer"); + return -EINVAL; + } + remain_len = pkt_len - cmd_desc[i].offset; cmd_buf += cmd_desc[i].offset / sizeof(uint32_t); + + if (total_cmd_buf_in_bytes > remain_len) { + CAM_ERR(CAM_EEPROM, "Not enough buffer for command"); + return -EINVAL; + } /* Loop through multiple cmd formats in one cmd buffer */ while (processed_cmd_buf_in_bytes < total_cmd_buf_in_bytes) { + if ((remain_len - processed_cmd_buf_in_bytes) < + sizeof(struct common_header)) { + CAM_ERR(CAM_EEPROM, "Not enough buf"); + return -EINVAL; + } cmm_hdr = (struct common_header *)cmd_buf; switch (cmm_hdr->cmd_type) { case CAMERA_SENSOR_CMD_TYPE_I2C_INFO: i2c_info = (struct cam_cmd_i2c_info *)cmd_buf; + if ((remain_len - processed_cmd_buf_in_bytes) < + sizeof(struct cam_cmd_i2c_info)) { + CAM_ERR(CAM_EEPROM, "Not enough buf"); + return -EINVAL; + } /* Configure the following map slave address */ map[num_map + 1].saddr = i2c_info->slave_addr; rc = cam_eeprom_update_slaveInfo(e_ctrl, @@ -599,7 +637,9 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl, case CAMERA_SENSOR_CMD_TYPE_PWR_DOWN: cmd_length_in_bytes = total_cmd_buf_in_bytes; rc = cam_sensor_update_power_settings(cmd_buf, - cmd_length_in_bytes, power_info); + cmd_length_in_bytes, power_info, + (remain_len - + processed_cmd_buf_in_bytes)); processed_cmd_buf_in_bytes += cmd_length_in_bytes; cmd_buf += cmd_length_in_bytes/ @@ -616,7 +656,9 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl, rc = cam_eeprom_parse_memory_map( &e_ctrl->cal_data, cmd_buf, total_cmd_buf_in_bytes, - &cmd_length_in_bytes, &num_map); + &cmd_length_in_bytes, &num_map, + (remain_len - + processed_cmd_buf_in_bytes)); processed_cmd_buf_in_bytes += cmd_length_in_bytes; cmd_buf += cmd_length_in_bytes/sizeof(uint32_t); @@ -647,6 +689,7 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl, uintptr_t buf_addr; size_t buf_size; uint8_t *read_buffer; + size_t remain_len = 0; io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *) &csl_packet->payload + @@ -660,6 +703,17 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl, if (io_cfg->direction == CAM_BUF_OUTPUT) { rc = cam_mem_get_cpu_buf(io_cfg->mem_handle[0], &buf_addr, &buf_size); + if (rc) { + CAM_ERR(CAM_EEPROM, "Fail in get buffer: %d", + rc); + return rc; + } + if (buf_size <= io_cfg->offsets[0]) { + CAM_ERR(CAM_EEPROM, "Not enough buffer"); + return -EINVAL; + } + + remain_len = buf_size - io_cfg->offsets[0]; CAM_DBG(CAM_EEPROM, "buf_addr : %pK, buf_size : %zu\n", (void *)buf_addr, buf_size); @@ -671,7 +725,7 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl, } read_buffer += io_cfg->offsets[0]; - if (buf_size < e_ctrl->cal_data.num_data) { + if (remain_len < e_ctrl->cal_data.num_data) { CAM_ERR(CAM_EEPROM, "failed to copy, Invalid size"); return -EINVAL; @@ -704,6 +758,7 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) struct cam_config_dev_cmd dev_config; uintptr_t generic_pkt_addr; size_t pkt_len; + size_t remain_len = 0; struct cam_packet *csl_packet = NULL; struct cam_eeprom_soc_private *soc_private = (struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private; @@ -723,15 +778,26 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) return rc; } - if (dev_config.offset > pkt_len) { + remain_len = pkt_len; + if ((sizeof(struct cam_packet) > pkt_len) || + ((size_t)dev_config.offset >= pkt_len - + sizeof(struct cam_packet))) { CAM_ERR(CAM_EEPROM, - "Offset is out of bound: off: %lld, %zu", - dev_config.offset, pkt_len); + "Inval cam_packet strut size: %zu, len_of_buff: %zu", + sizeof(struct cam_packet), pkt_len); return -EINVAL; } + remain_len -= (size_t)dev_config.offset; csl_packet = (struct cam_packet *) (generic_pkt_addr + (uint32_t)dev_config.offset); + + if (cam_packet_util_validate_packet(csl_packet, + remain_len)) { + CAM_ERR(CAM_EEPROM, "Invalid packet params"); + return -EINVAL; + } + switch (csl_packet->header.op_code & 0xFFFFFF) { case CAM_EEPROM_PACKET_OPCODE_INIT: if (e_ctrl->userspace_probe == false) { diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h index 4a2190da7c70..3adb7ea002b7 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -27,6 +27,7 @@ #include <cam_mem_mgr.h> #include <cam_subdev.h> #include "cam_soc_util.h" +#include "cam_context.h" #define DEFINE_MSM_MUTEX(mutexname) \ static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) @@ -151,6 +152,7 @@ struct cam_eeprom_intf_params { /** * struct cam_cmd_conditional_wait - Conditional wait command + * @device_name : Device name * @pdev : platform device * @spi : spi device * @eeprom_mutex : eeprom mutex @@ -163,10 +165,10 @@ struct cam_eeprom_intf_params { * @cam_eeprom_state: eeprom_device_state * @userspace_probe : flag indicates userspace or kernel probe * @cal_data : Calibration data - * @device_name : Device name * */ struct cam_eeprom_ctrl_t { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct platform_device *pdev; struct spi_device *spi; struct mutex eeprom_mutex; @@ -180,7 +182,6 @@ struct cam_eeprom_ctrl_t { enum cam_eeprom_state cam_eeprom_state; bool userspace_probe; struct cam_eeprom_memory_block_t cal_data; - char device_name[20]; }; int32_t cam_eeprom_update_i2c_info(struct cam_eeprom_ctrl_t *e_ctrl, diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c index 0ca9845f8dd0..182eec325789 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c @@ -16,6 +16,7 @@ #include "cam_flash_core.h" #include "cam_res_mgr_api.h" #include "cam_common_util.h" +#include "cam_packet_util.h" static int cam_flash_prepare(struct cam_flash_ctrl *flash_ctrl, bool regulator_enable) @@ -591,11 +592,15 @@ static int cam_flash_pmic_delete_req(struct cam_flash_ctrl *fctrl, } static int32_t cam_flash_slaveInfo_pkt_parser(struct cam_flash_ctrl *fctrl, - uint32_t *cmd_buf) + uint32_t *cmd_buf, size_t len) { int32_t rc = 0; struct cam_cmd_i2c_info *i2c_info = (struct cam_cmd_i2c_info *)cmd_buf; + if (len < sizeof(struct cam_cmd_i2c_info)) { + CAM_ERR(CAM_FLASH, "Not enough buffer"); + return -EINVAL; + } if (fctrl->io_master_info.master_type == CCI_MASTER) { fctrl->io_master_info.cci_client->cci_i2c_master = fctrl->cci_i2c_master; @@ -889,6 +894,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) uint32_t *offset = NULL; uint32_t frm_offset = 0; size_t len_of_buffer; + size_t remain_len; struct cam_flash_init *flash_init = NULL; struct common_header *cmn_hdr = NULL; struct cam_control *ioctl_ctrl = NULL; @@ -920,16 +926,27 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) return rc; } - if (config.offset > len_of_buffer) { + remain_len = len_of_buffer; + if ((sizeof(struct cam_packet) > len_of_buffer) || + ((size_t)config.offset >= len_of_buffer - + sizeof(struct cam_packet))) { CAM_ERR(CAM_FLASH, "offset is out of bounds: offset: %lld len: %zu", config.offset, len_of_buffer); return -EINVAL; } + remain_len -= (size_t)config.offset; /* Add offset to the flash csl header */ - csl_packet = (struct cam_packet *)(uintptr_t)(generic_ptr + - config.offset); + csl_packet = (struct cam_packet *)(generic_ptr + + (uintptr_t)config.offset); + + if (cam_packet_util_validate_packet(csl_packet, + remain_len)) { + CAM_ERR(CAM_FLASH, "Invalid packet params"); + return -EINVAL; + } + switch (csl_packet->header.op_code & 0xFFFFFF) { case CAM_FLASH_PACKET_OPCODE_INIT: { /* INIT packet*/ @@ -954,6 +971,15 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "invalid cmd buf"); return -EINVAL; } + + if ((len_of_buffer < sizeof(struct common_header)) || + (cmd_desc[i].offset > + (len_of_buffer - + sizeof(struct common_header)))) { + CAM_ERR(CAM_FLASH, "invalid cmd buf length"); + return -EINVAL; + } + remain_len = len_of_buffer - cmd_desc[i].offset; cmd_buf += cmd_desc[i].offset / sizeof(uint32_t); cmn_hdr = (struct common_header *)cmd_buf; @@ -964,6 +990,12 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) total_cmd_buf_in_bytes); switch (cmn_hdr->cmd_type) { case CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_INFO: + if (len_of_buffer < + sizeof(struct cam_flash_init)) { + CAM_ERR(CAM_FLASH, "Not enough buffer"); + return -EINVAL; + } + flash_init = (struct cam_flash_init *)cmd_buf; fctrl->flash_type = flash_init->flash_type; cmd_length_in_bytes = @@ -975,7 +1007,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) break; case CAMERA_SENSOR_CMD_TYPE_I2C_INFO: rc = cam_flash_slaveInfo_pkt_parser( - fctrl, cmd_buf); + fctrl, cmd_buf, remain_len); if (rc < 0) { CAM_ERR(CAM_FLASH, "Failed parsing slave info: rc: %d", @@ -998,7 +1030,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) rc = cam_sensor_update_power_settings( cmd_buf, total_cmd_buf_in_bytes, - &fctrl->power_info); + &fctrl->power_info, remain_len); processed_cmd_buf_in_bytes += cmd_length_in_bytes; cmd_buf += cmd_length_in_bytes/ @@ -1196,6 +1228,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) uint32_t *offset = NULL; uint32_t frm_offset = 0; size_t len_of_buffer; + size_t remain_len; struct cam_control *ioctl_ctrl = NULL; struct cam_packet *csl_packet = NULL; struct cam_cmd_buf_desc *cmd_desc = NULL; @@ -1230,16 +1263,26 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) return rc; } - if (config.offset > len_of_buffer) { + remain_len = len_of_buffer; + if ((sizeof(struct cam_packet) > len_of_buffer) || + ((size_t)config.offset >= len_of_buffer - + sizeof(struct cam_packet))) { CAM_ERR(CAM_FLASH, "offset is out of bounds: offset: %lld len: %zu", config.offset, len_of_buffer); return -EINVAL; } + remain_len -= (size_t)config.offset; /* Add offset to the flash csl header */ - csl_packet = - (struct cam_packet *)(generic_ptr + (uint32_t)config.offset); + csl_packet = (struct cam_packet *)(generic_ptr + + (uintptr_t)config.offset); + + if (cam_packet_util_validate_packet(csl_packet, + remain_len)) { + CAM_ERR(CAM_FLASH, "Invalid packet params"); + return -EINVAL; + } switch (csl_packet->header.op_code & 0xFFFFFF) { case CAM_FLASH_PACKET_OPCODE_INIT: { @@ -1249,6 +1292,18 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) cmd_desc = (struct cam_cmd_buf_desc *)(offset); rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle, &generic_ptr, &len_of_buffer); + if (rc) { + CAM_ERR(CAM_FLASH, "Fail in get buffer: %d", rc); + return -EINVAL; + } + if ((len_of_buffer < sizeof(struct cam_flash_init)) || + (cmd_desc->offset > + (len_of_buffer - sizeof(struct cam_flash_init)))) { + CAM_ERR(CAM_FLASH, "Not enough buffer"); + return -EINVAL; + } + + remain_len = len_of_buffer - cmd_desc->offset; cmd_buf = (uint32_t *)((uint8_t *)generic_ptr + cmd_desc->offset); cam_flash_info = (struct cam_flash_init *)cmd_buf; @@ -1278,8 +1333,23 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) case CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_FIRE: { CAM_DBG(CAM_FLASH, "INIT_FIRE Operation"); + if (remain_len < sizeof(struct cam_flash_set_on_off)) { + CAM_ERR(CAM_FLASH, "Not enough buffer"); + return -EINVAL; + } + flash_operation_info = (struct cam_flash_set_on_off *) cmd_buf; + if (!flash_operation_info) { + CAM_ERR(CAM_FLASH, + "flash_operation_info Null"); + return -EINVAL; + } + if (flash_operation_info->count > + CAM_FLASH_MAX_LED_TRIGGERS) { + CAM_ERR(CAM_FLASH, "led count out of limit"); + return -EINVAL; + } fctrl->nrt_info.cmn_attr.count = flash_operation_info->count; fctrl->nrt_info.cmn_attr.request_id = 0; @@ -1327,9 +1397,22 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) cmd_desc = (struct cam_cmd_buf_desc *)(offset); rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle, &generic_ptr, &len_of_buffer); + if (rc) { + CAM_ERR(CAM_FLASH, "Fail in get buffer: 0x%x", + cmd_desc->mem_handle); + return -EINVAL; + } + + if ((len_of_buffer < sizeof(struct common_header)) || + (cmd_desc->offset > + (len_of_buffer - sizeof(struct common_header)))) { + CAM_ERR(CAM_FLASH, "not enough buffer"); + return -EINVAL; + } + remain_len = len_of_buffer - cmd_desc->offset; + cmd_buf = (uint32_t *)((uint8_t *)generic_ptr + cmd_desc->offset); - if (!cmd_buf) return -EINVAL; @@ -1347,6 +1430,10 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) flash_data->cmn_attr.is_settings_valid = false; return 0; } + if (remain_len < sizeof(struct cam_flash_set_on_off)) { + CAM_ERR(CAM_FLASH, "Not enough buffer"); + return -EINVAL; + } flash_operation_info = (struct cam_flash_set_on_off *) cmd_buf; @@ -1355,6 +1442,11 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) "flash_operation_info Null"); return -EINVAL; } + if (flash_operation_info->count > + CAM_FLASH_MAX_LED_TRIGGERS) { + CAM_ERR(CAM_FLASH, "led count out of limit"); + return -EINVAL; + } flash_data->opcode = flash_operation_info->opcode; flash_data->cmn_attr.count = @@ -1378,6 +1470,18 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) cmd_desc = (struct cam_cmd_buf_desc *)(offset); rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle, &generic_ptr, &len_of_buffer); + if (rc) { + CAM_ERR(CAM_FLASH, "Fail in get buffer: %d", rc); + return -EINVAL; + } + + if ((len_of_buffer < sizeof(struct common_header)) || + (cmd_desc->offset > + (len_of_buffer - sizeof(struct common_header)))) { + CAM_ERR(CAM_FLASH, "Not enough buffer"); + return -EINVAL; + } + remain_len = len_of_buffer - cmd_desc->offset; cmd_buf = (uint32_t *)((uint8_t *)generic_ptr + cmd_desc->offset); cmn_hdr = (struct common_header *)cmd_buf; @@ -1385,8 +1489,23 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) switch (cmn_hdr->cmd_type) { case CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET: { CAM_DBG(CAM_FLASH, "Widget Flash Operation"); + if (remain_len < sizeof(struct cam_flash_set_on_off)) { + CAM_ERR(CAM_FLASH, "Not enough buffer"); + return -EINVAL; + } flash_operation_info = (struct cam_flash_set_on_off *) cmd_buf; + if (!flash_operation_info) { + CAM_ERR(CAM_FLASH, + "flash_operation_info Null"); + return -EINVAL; + } + if (flash_operation_info->count > + CAM_FLASH_MAX_LED_TRIGGERS) { + CAM_ERR(CAM_FLASH, "led count out of limit"); + return -EINVAL; + } + fctrl->nrt_info.cmn_attr.count = flash_operation_info->count; fctrl->nrt_info.cmn_attr.request_id = 0; @@ -1408,6 +1527,10 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) case CAMERA_SENSOR_FLASH_CMD_TYPE_QUERYCURR: { int query_curr_ma = 0; + if (remain_len < sizeof(struct cam_flash_query_curr)) { + CAM_ERR(CAM_FLASH, "Not enough buffer"); + return -EINVAL; + } flash_query_info = (struct cam_flash_query_curr *)cmd_buf; @@ -1425,7 +1548,22 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) } case CAMERA_SENSOR_FLASH_CMD_TYPE_RER: { rc = 0; + if (remain_len < sizeof(struct cam_flash_set_rer)) { + CAM_ERR(CAM_FLASH, "Not enough buffer"); + return -EINVAL; + } flash_rer_info = (struct cam_flash_set_rer *)cmd_buf; + if (!flash_rer_info) { + CAM_ERR(CAM_FLASH, + "flash_rer_info Null"); + return -EINVAL; + } + if (flash_rer_info->count > + CAM_FLASH_MAX_LED_TRIGGERS) { + CAM_ERR(CAM_FLASH, "led count out of limit"); + return -EINVAL; + } + fctrl->nrt_info.cmn_attr.cmd_type = CAMERA_SENSOR_FLASH_CMD_TYPE_RER; fctrl->nrt_info.opcode = flash_rer_info->opcode; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c index 4a6307da01b0..cdd6a98d2bf1 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -367,6 +367,8 @@ static int cam_flash_init_subdev(struct cam_flash_ctrl *fctrl) { int rc = 0; + strlcpy(fctrl->device_name, CAM_FLASH_NAME, + sizeof(fctrl->device_name)); fctrl->v4l2_dev_str.internal_ops = &cam_flash_internal_ops; fctrl->v4l2_dev_str.ops = &cam_flash_subdev_ops; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h index cb542395df38..6a1ce99bace8 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -35,6 +35,7 @@ #include "cam_debug_util.h" #include "cam_sensor_io.h" #include "cam_flash_core.h" +#include "cam_context.h" #define CAMX_FLASH_DEV_NAME "cam-flash-dev" @@ -158,6 +159,7 @@ struct cam_flash_func_tbl { /** * struct cam_flash_ctrl + * @device_name : Device name * @soc_info : Soc related information * @pdev : Platform device * @per_frame[] : Per_frame setting array @@ -182,6 +184,7 @@ struct cam_flash_func_tbl { * @i2c_data : I2C register settings */ struct cam_flash_ctrl { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct cam_hw_soc_info soc_info; struct platform_device *pdev; struct cam_sensor_power_ctrl_t power_info; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/Makefile index 9397c6844737..e525c46656be 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/Makefile +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/Makefile @@ -6,5 +6,6 @@ ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_ut ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/ +ccflags-y += -Idrivers/media/platform/msm/camera/cam_core obj-$(CONFIG_SPECTRA_CAMERA) += cam_ois_dev.o cam_ois_core.o cam_ois_soc.o diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c index 850b315c26a7..281b25482864 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -19,6 +19,7 @@ #include "cam_debug_util.h" #include "cam_res_mgr_api.h" #include "cam_common_util.h" +#include "cam_packet_util.h" int32_t cam_ois_construct_default_power_setting( struct cam_sensor_power_ctrl_t *power_info) @@ -256,12 +257,12 @@ static int cam_ois_apply_settings(struct cam_ois_ctrl_t *o_ctrl, } static int cam_ois_slaveInfo_pkt_parser(struct cam_ois_ctrl_t *o_ctrl, - uint32_t *cmd_buf) + uint32_t *cmd_buf, size_t len) { int32_t rc = 0; struct cam_cmd_ois_info *ois_info; - if (!o_ctrl || !cmd_buf) { + if (!o_ctrl || !cmd_buf || len < sizeof(struct cam_cmd_ois_info)) { CAM_ERR(CAM_OIS, "Invalid Args"); return -EINVAL; } @@ -274,7 +275,8 @@ static int cam_ois_slaveInfo_pkt_parser(struct cam_ois_ctrl_t *o_ctrl, ois_info->slave_addr >> 1; o_ctrl->ois_fw_flag = ois_info->ois_fw_flag; o_ctrl->is_ois_calib = ois_info->is_ois_calib; - memcpy(o_ctrl->ois_name, ois_info->ois_name, 32); + memcpy(o_ctrl->ois_name, ois_info->ois_name, OIS_NAME_LEN); + o_ctrl->ois_name[OIS_NAME_LEN - 1] = '\0'; o_ctrl->io_master_info.cci_client->retries = 3; o_ctrl->io_master_info.cci_client->id_map = 0; memcpy(&(o_ctrl->opcode), &(ois_info->opcode), @@ -433,6 +435,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) struct cam_cmd_buf_desc *cmd_desc = NULL; uintptr_t generic_pkt_addr; size_t pkt_len; + size_t remain_len = 0; struct cam_packet *csl_packet = NULL; size_t len_of_buff = 0; uint32_t *offset = NULL, *cmd_buf; @@ -453,15 +456,26 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) return rc; } - if (dev_config.offset > pkt_len) { + remain_len = pkt_len; + if ((sizeof(struct cam_packet) > pkt_len) || + ((size_t)dev_config.offset >= pkt_len - + sizeof(struct cam_packet))) { CAM_ERR(CAM_OIS, "offset is out of bound: off: %lld len: %zu", dev_config.offset, pkt_len); return -EINVAL; } + remain_len -= (size_t)dev_config.offset; csl_packet = (struct cam_packet *) (generic_pkt_addr + (uint32_t)dev_config.offset); + + if (cam_packet_util_validate_packet(csl_packet, + remain_len)) { + CAM_ERR(CAM_OIS, "Invalid packet params"); + return -EINVAL; + } + switch (csl_packet->header.op_code & 0xFFFFFF) { case CAM_OIS_PACKET_OPCODE_INIT: offset = (uint32_t *)&csl_packet->payload; @@ -485,13 +499,22 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_ERR(CAM_OIS, "invalid cmd buf"); return -EINVAL; } + + if ((len_of_buff < sizeof(struct common_header)) || + (cmd_desc[i].offset > (len_of_buff - + sizeof(struct common_header)))) { + CAM_ERR(CAM_OIS, + "Invalid length for sensor cmd"); + return -EINVAL; + } + remain_len = len_of_buff - cmd_desc[i].offset; cmd_buf += cmd_desc[i].offset / sizeof(uint32_t); cmm_hdr = (struct common_header *)cmd_buf; switch (cmm_hdr->cmd_type) { case CAMERA_SENSOR_CMD_TYPE_I2C_INFO: rc = cam_ois_slaveInfo_pkt_parser( - o_ctrl, cmd_buf); + o_ctrl, cmd_buf, remain_len); if (rc < 0) { CAM_ERR(CAM_OIS, "Failed in parsing slave info"); @@ -505,7 +528,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) rc = cam_sensor_update_power_settings( cmd_buf, total_cmd_buf_in_bytes, - power_info); + power_info, remain_len); if (rc) { CAM_ERR(CAM_OIS, "Failed: parse power settings"); diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.h index d6f0ec564508..06022ababf4e 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -16,6 +16,8 @@ #include <linux/dma-contiguous.h> #include "cam_ois_dev.h" +#define OIS_NAME_LEN 32 + /** * @power_info: power setting info to control the power * diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_dev.h index 3b7195e5c7a3..96b1a981c900 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -27,6 +27,7 @@ #include <cam_mem_mgr.h> #include <cam_subdev.h> #include "cam_soc_util.h" +#include "cam_context.h" #define DEFINE_MSM_MUTEX(mutexname) \ static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) @@ -90,6 +91,7 @@ struct cam_ois_intf_params { /** * struct cam_ois_ctrl_t - OIS ctrl private data + * @device_name : ois device_name * @pdev : platform device * @ois_mutex : ois mutex * @soc_info : ois soc related info @@ -110,6 +112,7 @@ struct cam_ois_intf_params { * */ struct cam_ois_ctrl_t { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct platform_device *pdev; struct mutex ois_mutex; struct cam_hw_soc_info soc_info; @@ -122,7 +125,6 @@ struct cam_ois_ctrl_t { struct i2c_settings_array i2c_mode_data; enum msm_camera_device_type_t ois_device_type; enum cam_ois_state cam_ois_state; - char device_name[20]; char ois_name[32]; uint8_t ois_fw_flag; uint8_t is_ois_calib; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c index c88e96980ff9..a9985e5e1ff5 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -17,6 +17,8 @@ #include "cam_soc_util.h" #include "cam_trace.h" #include "cam_common_util.h" +#include "cam_packet_util.h" + static void cam_sensor_update_req_mgr( struct cam_sensor_ctrl_t *s_ctrl, @@ -94,6 +96,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl, struct cam_cmd_buf_desc *cmd_desc = NULL; struct i2c_settings_array *i2c_reg_settings = NULL; size_t len_of_buff = 0; + size_t remain_len = 0; uint32_t *offset = NULL; struct cam_config_dev_cmd config; struct i2c_data_settings *i2c_data = NULL; @@ -119,12 +122,23 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl, return rc; } + remain_len = len_of_buff; + if ((sizeof(struct cam_packet) > len_of_buff) || + ((size_t)config.offset >= len_of_buff - + sizeof(struct cam_packet))) { + CAM_ERR(CAM_SENSOR, + "Inval cam_packet strut size: %zu, len_of_buff: %zu", + sizeof(struct cam_packet), len_of_buff); + return -EINVAL; + } + + remain_len -= (size_t)config.offset; csl_packet = (struct cam_packet *)(generic_ptr + (uint32_t)config.offset); - if (config.offset > len_of_buff) { - CAM_ERR(CAM_SENSOR, - "offset is out of bounds: off: %lld len: %zu", - config.offset, len_of_buff); + + if (cam_packet_util_validate_packet(csl_packet, + remain_len)) { + CAM_ERR(CAM_SENSOR, "Invalid packet params"); return -EINVAL; } @@ -342,7 +356,7 @@ int32_t cam_sensor_update_slave_info(struct cam_cmd_probe *probe_info, int32_t cam_handle_cmd_buffers_for_probe(void *cmd_buf, struct cam_sensor_ctrl_t *s_ctrl, - int32_t cmd_buf_num, int cmd_buf_length) + int32_t cmd_buf_num, uint32_t cmd_buf_length, size_t remain_len) { int32_t rc = 0; @@ -351,6 +365,13 @@ int32_t cam_handle_cmd_buffers_for_probe(void *cmd_buf, struct cam_cmd_i2c_info *i2c_info = NULL; struct cam_cmd_probe *probe_info; + if (remain_len < + (sizeof(struct cam_cmd_i2c_info) + + sizeof(struct cam_cmd_probe))) { + CAM_ERR(CAM_SENSOR, + "not enough buffer for cam_cmd_i2c_info"); + return -EINVAL; + } i2c_info = (struct cam_cmd_i2c_info *)cmd_buf; rc = cam_sensor_update_i2c_info(i2c_info, s_ctrl); if (rc < 0) { @@ -369,7 +390,8 @@ int32_t cam_handle_cmd_buffers_for_probe(void *cmd_buf, break; case 1: { rc = cam_sensor_update_power_settings(cmd_buf, - cmd_buf_length, &s_ctrl->sensordata->power_info); + cmd_buf_length, &s_ctrl->sensordata->power_info, + remain_len); if (rc < 0) { CAM_ERR(CAM_SENSOR, "Failed in updating power settings"); @@ -390,10 +412,11 @@ int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl) uint32_t *cmd_buf; void *ptr; size_t len; - struct cam_packet *pkt; - struct cam_cmd_buf_desc *cmd_desc; + struct cam_packet *pkt = NULL; + struct cam_cmd_buf_desc *cmd_desc = NULL; uintptr_t cmd_buf1 = 0; uintptr_t packet = 0; + size_t remain_len = 0; rc = cam_mem_get_cpu_buf(handle, &packet, &len); @@ -401,7 +424,19 @@ int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl) CAM_ERR(CAM_SENSOR, "Failed to get the command Buffer"); return -EINVAL; } + pkt = (struct cam_packet *)packet; + if (pkt == NULL) { + CAM_ERR(CAM_SENSOR, "packet pos is invalid"); + return -EINVAL; + } + + if ((len < sizeof(struct cam_packet)) || + (pkt->cmd_buf_offset >= (len - sizeof(struct cam_packet)))) { + CAM_ERR(CAM_SENSOR, "Not enough buf provided"); + return -EINVAL; + } + cmd_desc = (struct cam_cmd_buf_desc *) ((uint32_t *)&pkt->payload + pkt->cmd_buf_offset/4); if (cmd_desc == NULL) { @@ -423,12 +458,23 @@ int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl) "Failed to parse the command Buffer Header"); return -EINVAL; } + if (cmd_desc[i].offset >= len) { + CAM_ERR(CAM_SENSOR, + "offset past length of buffer"); + return -EINVAL; + } + remain_len = len - cmd_desc[i].offset; + if (cmd_desc[i].length > remain_len) { + CAM_ERR(CAM_SENSOR, + "Not enough buffer provided for cmd"); + return -EINVAL; + } cmd_buf = (uint32_t *)cmd_buf1; cmd_buf += cmd_desc[i].offset/4; ptr = (void *) cmd_buf; rc = cam_handle_cmd_buffers_for_probe(ptr, s_ctrl, - i, cmd_desc[i].length); + i, cmd_desc[i].length, remain_len); if (rc < 0) { CAM_ERR(CAM_SENSOR, "Failed to parse the command Buffer Header"); diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.h index 34f8b8dba696..38205098aa83 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -32,6 +32,7 @@ #include <cam_subdev.h> #include <cam_sensor_io.h> #include "cam_debug_util.h" +#include "cam_context.h" #define NUM_MASTERS 2 #define NUM_QUEUES 2 @@ -74,6 +75,7 @@ struct intf_params { /** * struct cam_sensor_ctrl_t: Camera control structure + * @device_name: Sensor device name * @pdev: Platform device * @cam_sensor_mutex: Sensor mutex * @sensordata: Sensor board Information @@ -89,13 +91,13 @@ struct intf_params { * @i2c_data: Sensor I2C register settings * @sensor_info: Sensor query cap structure * @bridge_intf: Bridge interface structure - * @device_name: Sensor device structure * @streamon_count: Count to hold the number of times stream on called * @streamoff_count: Count to hold the number of times stream off called * @bob_reg_index: Hold to BoB regulator index * @bob_pwm_switch: Boolean flag to switch into PWM mode for BoB regulator */ struct cam_sensor_ctrl_t { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct platform_device *pdev; struct cam_hw_soc_info soc_info; struct mutex cam_sensor_mutex; @@ -112,7 +114,6 @@ struct cam_sensor_ctrl_t { struct i2c_data_settings i2c_data; struct cam_sensor_query_cap sensor_info; struct intf_params bridge_intf; - char device_name[20]; uint32_t streamon_count; uint32_t streamoff_count; int bob_reg_index; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c index 5c1143ece162..061e054c3f9f 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -298,6 +298,8 @@ int cam_sensor_i2c_command_parser( size_t len_of_buff = 0; uintptr_t generic_ptr; uint16_t cmd_length_in_bytes = 0; + size_t remain_len = 0; + size_t tot_size = 0; for (i = 0; i < num_cmd_buffers; i++) { uint32_t *cmd_buf = NULL; @@ -319,16 +321,34 @@ int cam_sensor_i2c_command_parser( rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle, &generic_ptr, &len_of_buff); - cmd_buf = (uint32_t *)generic_ptr; if (rc < 0) { CAM_ERR(CAM_SENSOR, "cmd hdl failed:%d, Err: %d, Buffer_len: %zd", cmd_desc[i].mem_handle, rc, len_of_buff); return rc; } + + remain_len = len_of_buff; + if ((len_of_buff < sizeof(struct common_header)) || + (cmd_desc[i].offset > + (len_of_buff - sizeof(struct common_header)))) { + CAM_ERR(CAM_SENSOR, "buffer provided too small"); + return -EINVAL; + } + cmd_buf = (uint32_t *)generic_ptr; cmd_buf += cmd_desc[i].offset / sizeof(uint32_t); + if (remain_len < cmd_desc[i].length) { + CAM_ERR(CAM_SENSOR, "buffer provided too small"); + return -EINVAL; + } + while (byte_cnt < cmd_desc[i].length) { + if ((remain_len - byte_cnt) < + sizeof(struct common_header)) { + CAM_ERR(CAM_SENSOR, "Not enough buffer"); + return -EINVAL; + } cmm_hdr = (struct common_header *)cmd_buf; generic_op_code = cmm_hdr->third_byte; switch (cmm_hdr->cmd_type) { @@ -338,6 +358,22 @@ int cam_sensor_i2c_command_parser( *cam_cmd_i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf; + if ((remain_len - byte_cnt) < + sizeof(struct cam_cmd_i2c_random_wr)) { + CAM_ERR(CAM_SENSOR, + "Not enough buffer provided"); + return -EINVAL; + } + tot_size = sizeof(struct i2c_rdwr_header) + + (sizeof(struct i2c_random_wr_payload) * + cam_cmd_i2c_random_wr->header.count); + + if (tot_size > (remain_len - byte_cnt)) { + CAM_ERR(CAM_SENSOR, + "Not enough buffer provided"); + return -EINVAL; + } + rc = cam_sensor_handle_random_write( cam_cmd_i2c_random_wr, i2c_reg_settings, @@ -360,6 +396,24 @@ int cam_sensor_i2c_command_parser( (struct cam_cmd_i2c_continuous_wr *) cmd_buf; + if ((remain_len - byte_cnt) < + sizeof(struct cam_cmd_i2c_continuous_wr)) { + CAM_ERR(CAM_SENSOR, + "Not enough buffer provided"); + return -EINVAL; + } + + tot_size = sizeof(struct i2c_rdwr_header) + + sizeof(cam_cmd_i2c_continuous_wr->reg_addr) + + (sizeof(struct cam_cmd_read) * + cam_cmd_i2c_continuous_wr->header.count); + + if (tot_size > (remain_len - byte_cnt)) { + CAM_ERR(CAM_SENSOR, + "Not enough buffer provided"); + return -EINVAL; + } + rc = cam_sensor_handle_continuous_write( cam_cmd_i2c_continuous_wr, i2c_reg_settings, @@ -376,11 +430,16 @@ int cam_sensor_i2c_command_parser( break; } case CAMERA_SENSOR_CMD_TYPE_WAIT: { + if ((remain_len - byte_cnt) < + sizeof(struct cam_cmd_unconditional_wait)) { + CAM_ERR(CAM_SENSOR, + "Not enough buffer space"); + return -EINVAL; + } if (generic_op_code == CAMERA_SENSOR_WAIT_OP_HW_UCND || generic_op_code == CAMERA_SENSOR_WAIT_OP_SW_UCND) { - rc = cam_sensor_handle_delay( &cmd_buf, generic_op_code, i2c_reg_settings, j, &byte_cnt, @@ -412,6 +471,12 @@ int cam_sensor_i2c_command_parser( break; } case CAMERA_SENSOR_CMD_TYPE_I2C_INFO: { + if (remain_len - byte_cnt < + sizeof(struct cam_cmd_i2c_info)) { + CAM_ERR(CAM_SENSOR, + "Not enough buffer space"); + return -EINVAL; + } rc = cam_sensor_handle_slave_info( io_master, cmd_buf); if (rc) { @@ -750,8 +815,32 @@ int cam_sensor_util_request_gpio_table( return rc; } + +static int32_t cam_sensor_validate(void *ptr, size_t remain_buf) +{ + struct common_header *cmm_hdr = (struct common_header *)ptr; + size_t validate_size = 0; + + if (remain_buf < sizeof(struct common_header)) + return -EINVAL; + + if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_PWR_UP || + cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_PWR_DOWN) + validate_size = sizeof(struct cam_cmd_power); + else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) + validate_size = sizeof(struct cam_cmd_unconditional_wait); + + if (remain_buf < validate_size) { + CAM_ERR(CAM_SENSOR, "Invalid cmd_buf len %zu min %zu", + remain_buf, validate_size); + return -EINVAL; + } + return 0; +} + int32_t cam_sensor_update_power_settings(void *cmd_buf, - int cmd_length, struct cam_sensor_power_ctrl_t *power_info) + uint32_t cmd_length, struct cam_sensor_power_ctrl_t *power_info, + size_t cmd_buf_len) { int32_t rc = 0, tot_size = 0, last_cmd_type = 0; int32_t i = 0, pwr_up = 0, pwr_down = 0; @@ -760,7 +849,8 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf, struct cam_cmd_power *pwr_cmd = (struct cam_cmd_power *)cmd_buf; struct common_header *cmm_hdr = (struct common_header *)cmd_buf; - if (!pwr_cmd || !cmd_length) { + if (!pwr_cmd || !cmd_length || cmd_buf_len < (size_t)cmd_length || + cam_sensor_validate(cmd_buf, cmd_buf_len)) { CAM_ERR(CAM_SENSOR, "Invalid Args: pwr_cmd %pK, cmd_length: %d", pwr_cmd, cmd_length); return -EINVAL; @@ -787,6 +877,10 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf, } while (tot_size < cmd_length) { + if (cam_sensor_validate(ptr, (cmd_length - tot_size))) { + rc = -EINVAL; + goto free_power_settings; + } if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_PWR_UP) { struct cam_cmd_power *pwr_cmd = diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h index 583ddb14243b..85497fda011c 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -60,7 +60,8 @@ int msm_camera_fill_vreg_params(struct cam_hw_soc_info *soc_info, uint16_t power_setting_size); int32_t cam_sensor_update_power_settings(void *cmd_buf, - int cmd_length, struct cam_sensor_power_ctrl_t *power_info); + uint32_t cmd_length, struct cam_sensor_power_ctrl_t *power_info, + size_t cmd_buf_len); int cam_sensor_bob_pwm_mode_switch(struct cam_hw_soc_info *soc_info, int bob_reg_idx, bool flag); diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c index 66a4487af172..a1a372008cb8 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c +++ b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -50,23 +50,44 @@ int cam_packet_util_validate_cmd_desc(struct cam_cmd_buf_desc *cmd_desc) return 0; } -int cam_packet_util_validate_packet(struct cam_packet *packet) +int cam_packet_util_validate_packet(struct cam_packet *packet, + size_t remain_len) { + size_t sum_cmd_desc = 0; + size_t sum_io_cfgs = 0; + size_t sum_patch_desc = 0; + size_t pkt_wo_payload = 0; + if (!packet) return -EINVAL; + if ((size_t)packet->header.size > remain_len) { + CAM_ERR(CAM_UTIL, + "Invalid packet size: %zu, CPU buf length: %zu", + (size_t)packet->header.size, remain_len); + return -EINVAL; + } + + CAM_DBG(CAM_UTIL, "num cmd buf:%d num of io config:%d kmd buf index:%d", packet->num_cmd_buf, packet->num_io_configs, packet->kmd_cmd_buf_index); - if ((packet->kmd_cmd_buf_index >= packet->num_cmd_buf) || - (!packet->header.size) || - (packet->cmd_buf_offset > packet->header.size) || - (packet->io_configs_offset > packet->header.size)) { - CAM_ERR(CAM_UTIL, "invalid packet:%d %d %d %d %d", - packet->kmd_cmd_buf_index, - packet->num_cmd_buf, packet->cmd_buf_offset, - packet->io_configs_offset, packet->header.size); + sum_cmd_desc = packet->num_cmd_buf * sizeof(struct cam_cmd_buf_desc); + sum_io_cfgs = packet->num_io_configs * sizeof(struct cam_buf_io_cfg); + sum_patch_desc = packet->num_patches * sizeof(struct cam_patch_desc); + pkt_wo_payload = offsetof(struct cam_packet, payload); + + if ((!packet->header.size) || + ((pkt_wo_payload + (size_t)packet->cmd_buf_offset + + sum_cmd_desc) > (size_t)packet->header.size) || + ((pkt_wo_payload + (size_t)packet->io_configs_offset + + sum_io_cfgs) > (size_t)packet->header.size) || + ((pkt_wo_payload + (size_t)packet->patch_offset + + sum_patch_desc) > (size_t)packet->header.size)) { + CAM_ERR(CAM_UTIL, "params not within mem len:%zu %zu %zu %zu", + (size_t)packet->header.size, sum_cmd_desc, + sum_io_cfgs, sum_patch_desc); return -EINVAL; } @@ -78,6 +99,7 @@ int cam_packet_util_get_kmd_buffer(struct cam_packet *packet, { int rc = 0; size_t len = 0; + size_t remain_len = 0; struct cam_cmd_buf_desc *cmd_desc; uint32_t *cpu_addr; @@ -86,6 +108,13 @@ int cam_packet_util_get_kmd_buffer(struct cam_packet *packet, return -EINVAL; } + if ((packet->kmd_cmd_buf_index < 0) || + (packet->kmd_cmd_buf_index > packet->num_cmd_buf)) { + CAM_ERR(CAM_UTIL, "Invalid kmd buf index: %d", + packet->kmd_cmd_buf_index); + return -EINVAL; + } + /* Take first command descriptor and add offset to it for kmd*/ cmd_desc = (struct cam_cmd_buf_desc *) ((uint8_t *) &packet->payload + packet->cmd_buf_offset); @@ -100,12 +129,21 @@ int cam_packet_util_get_kmd_buffer(struct cam_packet *packet, if (rc) return rc; - if (len < cmd_desc->size) { + remain_len = len; + if (((size_t)cmd_desc->offset >= len) || + ((size_t)cmd_desc->size >= (len - (size_t)cmd_desc->offset))) { CAM_ERR(CAM_UTIL, "invalid memory len:%zd and cmd desc size:%d", len, cmd_desc->size); return -EINVAL; } + remain_len -= (size_t)cmd_desc->offset; + if ((size_t)packet->kmd_cmd_buf_offset >= remain_len) { + CAM_ERR(CAM_UTIL, "Invalid kmd cmd buf offset: %zu", + (size_t)packet->kmd_cmd_buf_offset); + return -EINVAL; + } + cpu_addr += (cmd_desc->offset / 4) + (packet->kmd_cmd_buf_offset / 4); CAM_DBG(CAM_UTIL, "total size %d, cmd size: %d, KMD buffer size: %d", cmd_desc->size, cmd_desc->length, @@ -171,21 +209,17 @@ int cam_packet_util_process_patches(struct cam_packet *packet, patch_desc[i].dst_buf_hdl, patch_desc[i].dst_offset, patch_desc[i].src_buf_hdl, patch_desc[i].src_offset); - if (patch_desc[i].src_offset >= src_buf_size) { - CAM_ERR_RATE_LIMIT(CAM_UTIL, - "Inval src offset:0x%x src len:0x%x reqid:%lld", - patch_desc[i].src_offset, - (unsigned int)src_buf_size, - packet->header.request_id); + if ((size_t)patch_desc[i].src_offset >= src_buf_size) { + CAM_ERR(CAM_UTIL, + "Invalid src buf patch offset"); return -EINVAL; } - if (patch_desc[i].dst_offset >= dst_buf_len) { - CAM_ERR_RATE_LIMIT(CAM_UTIL, - "Inval dst offset:0x%x dst len:0x%x reqid:%lld", - patch_desc[i].dst_offset, - (unsigned int)dst_buf_len, - packet->header.request_id); + if ((dst_buf_len < sizeof(void *)) || + ((dst_buf_len - sizeof(void *)) < + (size_t)patch_desc[i].dst_offset)) { + CAM_ERR(CAM_UTIL, + "Invalid dst buf patch offset"); return -EINVAL; } @@ -211,6 +245,7 @@ int cam_packet_util_process_generic_cmd_buffer( int rc; uintptr_t cpu_addr; size_t buf_size; + size_t remain_len = 0; uint32_t *blob_ptr; uint32_t blob_type, blob_size, blob_block_size, len_read; @@ -233,6 +268,21 @@ int cam_packet_util_process_generic_cmd_buffer( return rc; } + remain_len = buf_size; + if ((buf_size < sizeof(uint32_t)) || + ((size_t)cmd_buf->offset > (buf_size - sizeof(uint32_t)))) { + CAM_ERR(CAM_UTIL, "Invalid offset for cmd buf: %zu", + (size_t)cmd_buf->offset); + return -EINVAL; + } + remain_len -= (size_t)cmd_buf->offset; + + if (remain_len < (size_t)cmd_buf->length) { + CAM_ERR(CAM_UTIL, "Invalid length for cmd buf: %zu", + (size_t)cmd_buf->length); + return -EINVAL; + } + blob_ptr = (uint32_t *)(((uint8_t *)cpu_addr) + cmd_buf->offset); diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h index 94d269313c7d..284f0a520aed 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h +++ b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -59,10 +59,13 @@ int cam_packet_util_get_cmd_mem_addr(int handle, uint32_t **buf_addr, * * @packet: Packet to be validated * + * @remain_len: CPU buff length after config offset + * * @return: 0 for success * -EINVAL for Fail */ -int cam_packet_util_validate_packet(struct cam_packet *packet); +int cam_packet_util_validate_packet(struct cam_packet *packet, + size_t remain_len); /** * cam_packet_util_validate_cmd_desc() diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c index 5f9d1e06d8a8..98f72da87df6 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c @@ -527,7 +527,7 @@ int cam_context_init(struct cam_context *ctx, mutex_init(&ctx->sync_mutex); spin_lock_init(&ctx->lock); - ctx->dev_name = dev_name; + strlcpy(ctx->dev_name, dev_name, CAM_CTX_DEV_NAME_MAX_LENGTH); ctx->dev_id = dev_id; ctx->ctx_id = ctx_id; ctx->last_flush_req = 0; diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context.h b/drivers/media/platform/msm/camera_v3/cam_core/cam_context.h index cf07d95eb7f6..2d8c6e0ae819 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context.h +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -22,6 +22,9 @@ /* Forward declarations */ struct cam_context; +/* max device name string length*/ +#define CAM_CTX_DEV_NAME_MAX_LENGTH 20 + /* max request number */ #define CAM_CTX_REQ_MAX 20 #define CAM_CTX_CFG_MAX 20 @@ -184,7 +187,7 @@ struct cam_ctx_ops { * */ struct cam_context { - const char *dev_name; + char dev_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; uint64_t dev_id; uint32_t ctx_id; struct list_head list; diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c index e5232c482a17..174469e473da 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c @@ -262,6 +262,7 @@ int32_t cam_context_release_dev_to_hw(struct cam_context *ctx, ctx->session_hdl = -1; ctx->dev_hdl = -1; ctx->link_hdl = -1; + ctx->last_flush_req = 0; return 0; } diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_node.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_node.c index ee9b2bfc1bfa..2578fb93a615 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_node.c +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_node.c @@ -34,7 +34,7 @@ static void cam_node_print_ctx_state( spin_lock_bh(&ctx->lock); CAM_INFO(CAM_CORE, "[%s][%d] : state=%d, refcount=%d, active_req_list=%d, pending_req_list=%d, wait_req_list=%d, free_req_list=%d", - ctx->dev_name ? ctx->dev_name : "null", + ctx->dev_name, i, ctx->state, atomic_read(&(ctx->refcount.refcount)), list_empty(&ctx->active_req_list), @@ -155,6 +155,12 @@ static int __cam_node_handle_acquire_hw_v1(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + rc = cam_context_handle_acquire_hw(ctx, acquire); if (rc) { CAM_ERR(CAM_CORE, "Acquire device failed for node %s", @@ -194,6 +200,12 @@ static int __cam_node_handle_start_dev(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + rc = cam_context_handle_start_dev(ctx, start); if (rc) CAM_ERR(CAM_CORE, "Start failure for node %s", node->name); @@ -227,6 +239,12 @@ static int __cam_node_handle_stop_dev(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + rc = cam_context_handle_stop_dev(ctx, stop); if (rc) CAM_ERR(CAM_CORE, "Stop failure for node %s", node->name); @@ -260,6 +278,12 @@ static int __cam_node_handle_config_dev(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + rc = cam_context_handle_config_dev(ctx, config); if (rc) CAM_ERR(CAM_CORE, "Config failure for node %s", node->name); @@ -293,6 +317,12 @@ static int __cam_node_handle_flush_dev(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + rc = cam_context_handle_flush_dev(ctx, flush); if (rc) CAM_ERR(CAM_CORE, "Flush failure for node %s", node->name); @@ -326,6 +356,12 @@ static int __cam_node_handle_release_dev(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + if (ctx->state > CAM_CTX_UNINIT && ctx->state < CAM_CTX_STATE_MAX) { rc = cam_context_handle_release_dev(ctx, release); if (rc) @@ -381,6 +417,12 @@ static int __cam_node_handle_release_hw_v1(struct cam_node *node, return -EINVAL; } + if (strcmp(node->name, ctx->dev_name)) { + CAM_ERR(CAM_CORE, "node name %s dev name:%s not matching", + node->name, ctx->dev_name); + return -EINVAL; + } + rc = cam_context_handle_release_hw(ctx, release); if (rc) CAM_ERR(CAM_CORE, "context release failed node %s", node->name); diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_node.h b/drivers/media/platform/msm/camera_v3/cam_core/cam_node.h index c5216bac0606..e270bb4105fd 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_node.h +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_node.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -18,7 +18,6 @@ #include "cam_hw_mgr_intf.h" #include "cam_req_mgr_interface.h" -#define CAM_NODE_NAME_LENGTH_MAX 256 #define CAM_NODE_STATE_UNINIT 0 #define CAM_NODE_STATE_INIT 1 @@ -38,7 +37,7 @@ * */ struct cam_node { - char name[CAM_NODE_NAME_LENGTH_MAX]; + char name[CAM_CTX_DEV_NAME_MAX_LENGTH]; uint32_t state; /* context pool */ diff --git a/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_context.c b/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_context.c index 99c509c62809..70ff72c39028 100644 --- a/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_context.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -17,7 +17,7 @@ #include "cam_fd_context.h" #include "cam_trace.h" -static const char fd_dev_name[] = "fd"; +static const char fd_dev_name[] = "cam-fd"; /* Functions in Available state */ static int __cam_fd_ctx_acquire_dev_in_available(struct cam_context *ctx, diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_context.c b/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_context.c index cba6f985bca4..cd50cfb3f613 100644 --- a/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_context.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -28,7 +28,7 @@ #include "cam_debug_util.h" #include "cam_packet_util.h" -static const char icp_dev_name[] = "icp"; +static const char icp_dev_name[] = "cam-icp"; static int cam_icp_context_dump_active_request(void *data, unsigned long iova, uint32_t buf_info) diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c index 3e8fe117ac2d..8685e34e0ea9 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c @@ -27,7 +27,7 @@ #include "cam_isp_context.h" #include "cam_common_util.h" -static const char isp_dev_name[] = "isp"; +static const char isp_dev_name[] = "cam-isp"; #define INC_STATE_MONITOR_HEAD(head) \ (atomic64_add_return(1, head) % \ diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 9fb67570b51a..582d4858e18b 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -3551,8 +3551,8 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, struct cam_hw_prepare_update_args *prepare = NULL; if (!blob_data || (blob_size == 0) || !blob_info) { - CAM_ERR(CAM_ISP, "Invalid info blob %pK %d prepare %pK", - blob_data, blob_size, prepare); + CAM_ERR(CAM_ISP, "Invalid args data %pK size %d info %pK", + blob_data, blob_size, blob_info); return -EINVAL; } @@ -3572,8 +3572,29 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_DBG(CAM_ISP, "FS2: BLOB Type: %d", blob_type); switch (blob_type) { case CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG: { - struct cam_isp_resource_hfr_config *hfr_config = - (struct cam_isp_resource_hfr_config *)blob_data; + struct cam_isp_resource_hfr_config *hfr_config; + + if (blob_size < sizeof(struct cam_isp_resource_hfr_config)) { + CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size); + return -EINVAL; + } + + hfr_config = (struct cam_isp_resource_hfr_config *)blob_data; + + if (hfr_config->num_ports > CAM_ISP_IFE_OUT_RES_MAX) { + CAM_ERR(CAM_ISP, "Invalid num_ports %u in hfr config", + hfr_config->num_ports); + return -EINVAL; + } + + if (blob_size < (sizeof(uint32_t) * 2 + hfr_config->num_ports * + sizeof(struct cam_isp_port_hfr_config))) { + CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu", + blob_size, sizeof(uint32_t) * 2 + + sizeof(struct cam_isp_port_hfr_config) * + hfr_config->num_ports); + return -EINVAL; + } rc = cam_isp_blob_hfr_update(blob_type, blob_info, hfr_config, prepare); @@ -3582,8 +3603,29 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, } break; case CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG: { - struct cam_isp_clock_config *clock_config = - (struct cam_isp_clock_config *)blob_data; + struct cam_isp_clock_config *clock_config; + + if (blob_size < sizeof(struct cam_isp_clock_config)) { + CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size); + return -EINVAL; + } + + clock_config = (struct cam_isp_clock_config *)blob_data; + + if (clock_config->num_rdi > CAM_IFE_RDI_NUM_MAX) { + CAM_ERR(CAM_ISP, "Invalid num_rdi %u in clock config", + clock_config->num_rdi); + return -EINVAL; + } + + if (blob_size < (sizeof(uint32_t) * 2 + sizeof(uint64_t) * + (clock_config->num_rdi + 2))) { + CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu", + blob_size, + sizeof(uint32_t) * 2 + sizeof(uint64_t) * + (clock_config->num_rdi + 2)); + return -EINVAL; + } rc = cam_isp_blob_clock_update(blob_type, blob_info, clock_config, prepare); @@ -3592,10 +3634,31 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, } break; case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG: { - struct cam_isp_bw_config *bw_config = - (struct cam_isp_bw_config *)blob_data; + struct cam_isp_bw_config *bw_config; struct cam_isp_prepare_hw_update_data *prepare_hw_data; + if (blob_size < sizeof(struct cam_isp_bw_config)) { + CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size); + return -EINVAL; + } + + bw_config = (struct cam_isp_bw_config *)blob_data; + + if (bw_config->num_rdi > CAM_IFE_RDI_NUM_MAX) { + CAM_ERR(CAM_ISP, "Invalid num_rdi %u in bw config", + bw_config->num_rdi); + return -EINVAL; + } + + if (blob_size < (sizeof(uint32_t) * 2 + (bw_config->num_rdi + 2) + * sizeof(struct cam_isp_bw_vote))) { + CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu", + blob_size, + sizeof(uint32_t) * 2 + (bw_config->num_rdi + 2) + * sizeof(struct cam_isp_bw_vote)); + return -EINVAL; + } + if (!prepare || !prepare->priv || (bw_config->usage_type >= CAM_IFE_HW_NUM_MAX)) { CAM_ERR(CAM_ISP, "Invalid inputs"); @@ -3613,8 +3676,29 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, } break; case CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG: { - struct cam_ubwc_config *ubwc_config = - (struct cam_ubwc_config *)blob_data; + struct cam_ubwc_config *ubwc_config; + + if (blob_size < sizeof(struct cam_ubwc_config)) { + CAM_ERR(CAM_ISP, "Invalid blob_size %u", blob_size); + return -EINVAL; + } + + ubwc_config = (struct cam_ubwc_config *)blob_data; + + if (ubwc_config->num_ports > CAM_ISP_IFE_OUT_RES_MAX) { + CAM_ERR(CAM_ISP, "Invalid num_ports %u in ubwc config", + ubwc_config->num_ports); + return -EINVAL; + } + + if (blob_size < (sizeof(uint32_t) * 2 + ubwc_config->num_ports * + sizeof(struct cam_ubwc_plane_cfg_v1) * 2)) { + CAM_ERR(CAM_ISP, "Invalid blob_size %u expected %lu", + blob_size, + sizeof(uint32_t) * 2 + ubwc_config->num_ports * + sizeof(struct cam_ubwc_plane_cfg_v1) * 2); + return -EINVAL; + } rc = cam_isp_blob_ubwc_update(blob_type, blob_info, ubwc_config, prepare); @@ -3623,8 +3707,16 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, } break; case CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG: { - struct cam_isp_csid_clock_config *clock_config = - (struct cam_isp_csid_clock_config *)blob_data; + struct cam_isp_csid_clock_config *clock_config; + + if (blob_size < sizeof(struct cam_isp_csid_clock_config)) { + CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu", + blob_size, + sizeof(struct cam_isp_csid_clock_config)); + return -EINVAL; + } + + clock_config = (struct cam_isp_csid_clock_config *)blob_data; rc = cam_isp_blob_csid_clock_update(blob_type, blob_info, clock_config, prepare); @@ -3633,8 +3725,16 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, } break; case CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG: { - struct cam_fe_config *fe_config = - (struct cam_fe_config *)blob_data; + struct cam_fe_config *fe_config; + + if (blob_size < sizeof(struct cam_fe_config)) { + CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu", + blob_size, sizeof(struct cam_fe_config)); + return -EINVAL; + } + + fe_config = (struct cam_fe_config *)blob_data; + rc = cam_isp_blob_fe_update(blob_type, blob_info, fe_config, prepare); if (rc) diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index 779d04460e2c..2d6e23cb7961 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -1059,7 +1059,7 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw) CAM_DBG(CAM_ISP, "CSID:%d init CSID HW", csid_hw->hw_intf->hw_idx); - clk_lvl = cam_ife_csid_get_vote_level(soc_info, csid_hw->clk_rate); + clk_lvl = cam_soc_util_get_vote_level(soc_info, csid_hw->clk_rate); CAM_DBG(CAM_ISP, "CSID clock lvl %u", clk_lvl); rc = cam_ife_csid_enable_soc_resources(soc_info, clk_lvl); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c index 890dad3b66b2..5e02609088c4 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -117,7 +117,7 @@ int cam_ife_csid_deinit_soc_resources( } int cam_ife_csid_enable_soc_resources( - struct cam_hw_soc_info *soc_info, uint32_t clk_lvl) + struct cam_hw_soc_info *soc_info, enum cam_vote_level clk_level) { int rc = 0; struct cam_csid_soc_private *soc_private; @@ -142,7 +142,7 @@ int cam_ife_csid_enable_soc_resources( } rc = cam_soc_util_enable_platform_resource(soc_info, true, - clk_lvl, true); + clk_level, true); if (rc) { CAM_ERR(CAM_ISP, "enable platform failed"); goto stop_cpas; @@ -235,24 +235,3 @@ int cam_ife_csid_disable_ife_force_clock_on(struct cam_hw_soc_info *soc_info, return rc; } - -uint32_t cam_ife_csid_get_vote_level(struct cam_hw_soc_info *soc_info, - uint64_t clock_rate) -{ - int i = 0; - - if (!clock_rate) - return CAM_SVS_VOTE; - - for (i = 0; i < CAM_MAX_VOTE; i++) { - if (soc_info->clk_rate[i][soc_info->num_clk - 1] >= - clock_rate) { - CAM_DBG(CAM_ISP, - "Clock rate %lld, selected clock level %d", - clock_rate, i); - return i; - } - } - - return CAM_TURBO_VOTE; -} diff --git a/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_context.c b/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_context.c index 287d4a4162fc..1c910621b655 100644 --- a/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_context.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -22,7 +22,7 @@ #include "cam_debug_util.h" #include "cam_packet_util.h" -static const char jpeg_dev_name[] = "jpeg"; +static const char jpeg_dev_name[] = "cam-jpeg"; static int cam_jpeg_context_dump_active_request(void *data, unsigned long iova, uint32_t buf_info) diff --git a/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_context.c b/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_context.c index 99a8fe1f8eca..26bdc31250d1 100644 --- a/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_context.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -16,7 +16,7 @@ #include "cam_debug_util.h" #include "cam_lrme_context.h" -static const char lrme_dev_name[] = "lrme"; +static const char lrme_dev_name[] = "cam-lrme"; static int __cam_lrme_ctx_acquire_dev_in_available(struct cam_context *ctx, struct cam_acquire_dev_cmd *cmd) diff --git a/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c index 47bf68c16c03..11e9069b3c79 100644 --- a/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c @@ -167,13 +167,6 @@ static int cam_lrme_mgr_util_prepare_io_buffer(int32_t iommu_hdl, io_cfg[i].resource_type, io_cfg[i].fence, io_cfg[i].format); - if ((num_in_buf > io_buf_size) || - (num_out_buf > io_buf_size)) { - CAM_ERR(CAM_LRME, "Invalid number of buffers %d %d %d", - num_in_buf, num_out_buf, io_buf_size); - return -EINVAL; - } - memset(io_addr, 0, sizeof(io_addr)); for (plane = 0; plane < CAM_PACKET_MAX_PLANES; plane++) { if (!io_cfg[i].mem_handle[plane]) @@ -201,6 +194,12 @@ static int cam_lrme_mgr_util_prepare_io_buffer(int32_t iommu_hdl, switch (io_cfg[i].direction) { case CAM_BUF_INPUT: { + if (num_in_buf >= io_buf_size) { + CAM_ERR(CAM_LRME, + "Invalid number of buffers %d %d %d", + num_in_buf, num_out_buf, io_buf_size); + return -EINVAL; + } prepare->in_map_entries[num_in_buf].resource_handle = io_cfg[i].resource_type; prepare->in_map_entries[num_in_buf].sync_id = @@ -216,6 +215,12 @@ static int cam_lrme_mgr_util_prepare_io_buffer(int32_t iommu_hdl, break; } case CAM_BUF_OUTPUT: { + if (num_out_buf >= io_buf_size) { + CAM_ERR(CAM_LRME, + "Invalid number of buffers %d %d %d", + num_in_buf, num_out_buf, io_buf_size); + return -EINVAL; + } prepare->out_map_entries[num_out_buf].resource_handle = io_cfg[i].resource_type; prepare->out_map_entries[num_out_buf].sync_id = diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_mem_mgr.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_mem_mgr.c index cff48e599f04..284742ef33ee 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_mem_mgr.c @@ -23,6 +23,7 @@ #include "cam_debug_util.h" static struct cam_mem_table tbl; +static atomic_t cam_mem_mgr_state = ATOMIC_INIT(CAM_MEM_MGR_UNINITIALIZED); static int cam_mem_util_map_cpu_va(struct ion_handle *hdl, uintptr_t *vaddr, @@ -108,6 +109,7 @@ int cam_mem_mgr_init(void) tbl.bufq[i].buf_handle = -1; } mutex_init(&tbl.m_lock); + atomic_set(&cam_mem_mgr_state, CAM_MEM_MGR_INITIALIZED); return rc; bitmap_fail: @@ -151,6 +153,11 @@ int cam_mem_get_io_buf(int32_t buf_handle, int32_t mmu_handle, { int rc = 0, idx; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + idx = CAM_MEM_MGR_GET_HDL_IDX(buf_handle); if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) return -EINVAL; @@ -191,6 +198,11 @@ int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr, size_t *len) uintptr_t kvaddr = 0; size_t klen = 0; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!buf_handle || !vaddr_ptr || !len) return -EINVAL; @@ -254,6 +266,11 @@ int cam_mem_mgr_cache_ops(struct cam_mem_cache_ops_cmd *cmd) uint32_t ion_cache_ops; unsigned long ion_flag = 0; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!cmd) return -EINVAL; @@ -530,6 +547,11 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) dma_addr_t hw_vaddr = 0; size_t len; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!cmd) { CAM_ERR(CAM_MEM, " Invalid argument"); return -EINVAL; @@ -628,6 +650,11 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) dma_addr_t hw_vaddr = 0; size_t len = 0; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!cmd || (cmd->fd < 0)) { CAM_ERR(CAM_MEM, "Invalid argument"); return -EINVAL; @@ -813,6 +840,7 @@ static int cam_mem_mgr_cleanup_table(void) void cam_mem_mgr_deinit(void) { + atomic_set(&cam_mem_mgr_state, CAM_MEM_MGR_UNINITIALIZED); cam_mem_mgr_cleanup_table(); mutex_lock(&tbl.m_lock); bitmap_zero(tbl.bitmap, tbl.bits); @@ -901,6 +929,11 @@ int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd) int idx; int rc; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!cmd) { CAM_ERR(CAM_MEM, "Invalid argument"); return -EINVAL; @@ -948,6 +981,11 @@ int cam_mem_mgr_request_mem(struct cam_mem_mgr_request_desc *inp, enum cam_smmu_region_id region = CAM_SMMU_REGION_SHARED; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!inp || !out) { CAM_ERR(CAM_MEM, "Invalid params"); return -EINVAL; @@ -1066,6 +1104,11 @@ int cam_mem_mgr_release_mem(struct cam_mem_mgr_memory_desc *inp) int32_t idx; int rc; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!inp) { CAM_ERR(CAM_MEM, "Invalid argument"); return -EINVAL; @@ -1115,6 +1158,11 @@ int cam_mem_mgr_reserve_memory_region(struct cam_mem_mgr_request_desc *inp, int32_t smmu_hdl = 0; int32_t num_hdl = 0; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!inp || !out) { CAM_ERR(CAM_MEM, "Invalid param(s)"); return -EINVAL; @@ -1207,6 +1255,11 @@ int cam_mem_mgr_free_memory_region(struct cam_mem_mgr_memory_desc *inp) int rc; int32_t smmu_hdl; + if (!atomic_read(&cam_mem_mgr_state)) { + CAM_ERR(CAM_CRM, "failed. mem_mgr not initialized"); + return -EINVAL; + } + if (!inp) { CAM_ERR(CAM_MEM, "Invalid argument"); return -EINVAL; diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_mem_mgr.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_mem_mgr.h index 92c366d723f9..73f0eb3d3425 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_mem_mgr.h +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_mem_mgr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, 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 @@ -20,6 +20,12 @@ #define CAM_MEM_BUFQ_MAX 1024 +/* Enum for possible mem mgr states */ +enum cam_mem_mgr_state { + CAM_MEM_MGR_UNINITIALIZED, + CAM_MEM_MGR_INITIALIZED, +}; + /*Enum for possible SMMU operations */ enum cam_smmu_mapping_client { CAM_SMMU_MAPPING_USER, diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_dev.h index 36b2994b9d71..2016996fba94 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_dev.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -34,6 +34,7 @@ #include "cam_sensor_util.h" #include "cam_soc_util.h" #include "cam_debug_util.h" +#include "cam_context.h" #define NUM_MASTERS 2 #define NUM_QUEUES 2 @@ -92,6 +93,7 @@ struct intf_params { /** * struct cam_actuator_ctrl_t + * @device_name: Device name * @i2c_driver: I2C device info * @pdev: Platform device * @cci_i2c_master: I2C structure @@ -107,10 +109,10 @@ struct intf_params { * @i2c_data: I2C register settings structure * @act_info: Sensor query cap structure * @of_node: Node ptr - * @device_name: Device name * @last_flush_req: Last request to flush */ struct cam_actuator_ctrl_t { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct i2c_driver *i2c_driver; enum cci_i2c_master_t cci_i2c_master; enum cci_device_num cci_num; @@ -125,7 +127,6 @@ struct cam_actuator_ctrl_t { struct i2c_data_settings i2c_data; struct cam_actuator_query_cap act_info; struct intf_params bridge_intf; - char device_name[20]; uint32_t last_flush_req; }; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/Makefile b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/Makefile index ded58fefec16..eb3bb5946df0 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/Makefile +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/Makefile @@ -5,5 +5,6 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_req_mgr ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_smmu/ +ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_core obj-$(CONFIG_SPECTRA_CAMERA) += cam_csiphy_soc.o cam_csiphy_dev.o cam_csiphy_core.o diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h index 248903251d62..51cf9e953a41 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -35,6 +35,7 @@ #include <cam_cpas_api.h> #include "cam_soc_util.h" #include "cam_debug_util.h" +#include "cam_context.h" #define MAX_CSIPHY 3 #define MAX_DPHY_DATA_LN 4 @@ -205,6 +206,7 @@ struct cam_csiphy_param { /** * struct csiphy_device + * @device_name: Device name * @pdev: Platform device * @irq: Interrupt structure * @base: Base address @@ -234,6 +236,7 @@ struct cam_csiphy_param { * @csiphy_cpas_cp_reg_mask: CP reg mask for phy instance */ struct csiphy_device { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct mutex mutex; uint32_t hw_version; enum cam_csiphy_state csiphy_state; @@ -252,7 +255,6 @@ struct csiphy_device { uint32_t clk_lane; uint32_t acquire_count; uint32_t start_dev_count; - char device_name[20]; uint32_t is_acquired_dev_combo_mode; struct cam_hw_soc_info soc_info; uint32_t cpas_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/Makefile b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/Makefile index f0a05e3c9814..6edc929aad4c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/Makefile +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/Makefile @@ -5,4 +5,6 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_req_mgr ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_smmu/ +ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_core + obj-$(CONFIG_SPECTRA_CAMERA) += cam_eeprom_dev.o cam_eeprom_core.o cam_eeprom_soc.o diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h index ff9b244a3391..7ffafc377da6 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -27,6 +27,7 @@ #include <cam_mem_mgr.h> #include <cam_subdev.h> #include "cam_soc_util.h" +#include "cam_context.h" #define DEFINE_MSM_MUTEX(mutexname) \ static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) @@ -151,6 +152,7 @@ struct cam_eeprom_intf_params { /** * struct cam_cmd_conditional_wait - Conditional wait command + * @device_name : Device name * @pdev : platform device * @spi : spi device * @eeprom_mutex : eeprom mutex @@ -163,10 +165,10 @@ struct cam_eeprom_intf_params { * @cam_eeprom_state: eeprom_device_state * @userspace_probe : flag indicates userspace or kernel probe * @cal_data : Calibration data - * @device_name : Device name * */ struct cam_eeprom_ctrl_t { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct platform_device *pdev; struct spi_device *spi; struct mutex eeprom_mutex; @@ -181,7 +183,6 @@ struct cam_eeprom_ctrl_t { enum cam_eeprom_state cam_eeprom_state; bool userspace_probe; struct cam_eeprom_memory_block_t cal_data; - char device_name[20]; }; int32_t cam_eeprom_update_i2c_info(struct cam_eeprom_ctrl_t *e_ctrl, diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c index 948fc9a9c990..1a0edb8d4d02 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -387,6 +387,8 @@ static int cam_flash_init_subdev(struct cam_flash_ctrl *fctrl) { int rc = 0; + strlcpy(fctrl->device_name, CAM_FLASH_NAME, + sizeof(fctrl->device_name)); fctrl->v4l2_dev_str.internal_ops = &cam_flash_internal_ops; fctrl->v4l2_dev_str.ops = &cam_flash_subdev_ops; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.h index ea5ea3c9997b..59ebb70352d3 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.h @@ -36,6 +36,7 @@ #include "cam_debug_util.h" #include "cam_sensor_io.h" #include "cam_flash_core.h" +#include "cam_context.h" #define CAMX_FLASH_DEV_NAME "cam-flash-dev" @@ -161,6 +162,7 @@ struct cam_flash_func_tbl { /** * struct cam_flash_ctrl + * @device_name : Device name * @soc_info : Soc related information * @pdev : Platform device * @per_frame[] : Per_frame setting array @@ -186,6 +188,7 @@ struct cam_flash_func_tbl { * @last_flush_req : last request to flush */ struct cam_flash_ctrl { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct cam_hw_soc_info soc_info; struct platform_device *pdev; struct cam_sensor_power_ctrl_t power_info; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/Makefile b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/Makefile index 18cc2498985a..fc7013b7f9b6 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/Makefile +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/Makefile @@ -6,5 +6,6 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_req_mgr ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_smmu/ +ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_core obj-$(CONFIG_SPECTRA_CAMERA) += cam_ois_dev.o cam_ois_core.o cam_ois_soc.o diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_dev.h index ea648594ccc0..3b717542ee28 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -27,6 +27,7 @@ #include <cam_mem_mgr.h> #include <cam_subdev.h> #include "cam_soc_util.h" +#include "cam_context.h" #define DEFINE_MSM_MUTEX(mutexname) \ static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) @@ -90,6 +91,7 @@ struct cam_ois_intf_params { /** * struct cam_ois_ctrl_t - OIS ctrl private data + * @device_name : ois device_name * @pdev : platform device * @ois_mutex : ois mutex * @soc_info : ois soc related info @@ -102,7 +104,6 @@ struct cam_ois_intf_params { * @i2c_calib_data : ois i2c calib settings * @ois_device_type : ois device type * @cam_ois_state : ois_device_state - * @ois_name : ois name * @ois_fw_flag : flag for firmware download * @is_ois_calib : flag for Calibration data * @opcode : ois opcode @@ -110,6 +111,7 @@ struct cam_ois_intf_params { * */ struct cam_ois_ctrl_t { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct platform_device *pdev; struct mutex ois_mutex; struct cam_hw_soc_info soc_info; @@ -123,7 +125,6 @@ struct cam_ois_ctrl_t { struct i2c_settings_array i2c_mode_data; enum msm_camera_device_type_t ois_device_type; enum cam_ois_state cam_ois_state; - char device_name[20]; char ois_name[32]; uint8_t ois_fw_flag; uint8_t is_ois_calib; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_dev.h index e98a592dd5ea..73e187bb9246 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_dev.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -32,6 +32,7 @@ #include <cam_subdev.h> #include <cam_sensor_io.h> #include "cam_debug_util.h" +#include "cam_context.h" #define NUM_MASTERS 2 #define NUM_QUEUES 2 @@ -74,6 +75,7 @@ struct intf_params { /** * struct cam_sensor_ctrl_t: Camera control structure + * @device_name: Sensor device name * @pdev: Platform device * @cam_sensor_mutex: Sensor mutex * @sensordata: Sensor board Information @@ -89,7 +91,6 @@ struct intf_params { * @i2c_data: Sensor I2C register settings * @sensor_info: Sensor query cap structure * @bridge_intf: Bridge interface structure - * @device_name: Sensor device structure * @streamon_count: Count to hold the number of times stream on called * @streamoff_count: Count to hold the number of times stream off called * @bob_reg_index: Hold to BoB regulator index @@ -98,6 +99,7 @@ struct intf_params { * @pipeline_delay: Sensor pipeline delay */ struct cam_sensor_ctrl_t { + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; struct platform_device *pdev; struct cam_hw_soc_info soc_info; struct mutex cam_sensor_mutex; @@ -115,7 +117,6 @@ struct cam_sensor_ctrl_t { struct i2c_data_settings i2c_data; struct cam_sensor_query_cap sensor_info; struct intf_params bridge_intf; - char device_name[20]; uint32_t streamon_count; uint32_t streamoff_count; int bob_reg_index; diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c index 59a33889c013..693b0da29be2 100644 --- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c +++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c @@ -1770,3 +1770,25 @@ int cam_soc_util_reg_dump(struct cam_hw_soc_info *soc_info, return 0; } + +uint32_t cam_soc_util_get_vote_level(struct cam_hw_soc_info *soc_info, + uint64_t clock_rate) +{ + int i = 0; + + if (!clock_rate) + return CAM_SVS_VOTE; + + for (i = 0; i < CAM_MAX_VOTE; i++) { + if (soc_info->clk_level_valid[i] && + soc_info->clk_rate[i][soc_info->src_clk_idx] >= + clock_rate) { + CAM_DBG(CAM_UTIL, + "Clock rate %lld, selected clock level %d", + clock_rate, i); + return i; + } + } + + return CAM_TURBO_VOTE; +} diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h index 80faed3edae2..ee07f0eb0a5d 100644 --- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h +++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h @@ -637,6 +637,10 @@ void cam_soc_util_clk_disable_default(struct cam_hw_soc_info *soc_info); int cam_soc_util_clk_enable_default(struct cam_hw_soc_info *soc_info, enum cam_vote_level clk_level); + +uint32_t cam_soc_util_get_vote_level(struct cam_hw_soc_info *soc_info, + uint64_t clock_rate); + /** * cam_soc_util_get_soc_id() * diff --git a/drivers/media/platform/msm/vidc_3x/msm_smem.c b/drivers/media/platform/msm/vidc_3x/msm_smem.c index a6d54765bd88..b67da1fc75b7 100644 --- a/drivers/media/platform/msm/vidc_3x/msm_smem.c +++ b/drivers/media/platform/msm/vidc_3x/msm_smem.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, 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 @@ -476,7 +476,8 @@ bool msm_smem_compare_buffers(void *clt, int fd, void *priv) } handle = ion_import_dma_buf_fd(client->clnt, fd); ret = handle == priv; - handle ? ion_free(client->clnt, handle) : 0; + if (!IS_ERR_OR_NULL(handle)) + ion_free(client->clnt, handle); return ret; } diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h b/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h index 552e578e15c0..e383a6c56ffe 100644 --- a/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h +++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, 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 @@ -40,8 +40,8 @@ #define MSM_VIDC_VERSION KERNEL_VERSION(0, 0, 1) #define MAX_DEBUGFS_NAME 50 #define DEFAULT_TIMEOUT 3 -#define DEFAULT_HEIGHT 1088 -#define DEFAULT_WIDTH 1920 +#define DEFAULT_HEIGHT 144 +#define DEFAULT_WIDTH 176 #define MIN_SUPPORTED_WIDTH 32 #define MIN_SUPPORTED_HEIGHT 32 #define DEFAULT_FPS 15 diff --git a/drivers/misc/hdcp_qseecom.c b/drivers/misc/hdcp_qseecom.c index 13175d041833..f45dca30b11a 100644 --- a/drivers/misc/hdcp_qseecom.c +++ b/drivers/misc/hdcp_qseecom.c @@ -42,7 +42,7 @@ #define HDCP1_APP_NAME "hdcp1" #define QSEECOM_SBUFF_SIZE 0x1000 -#define MAX_TX_MESSAGE_SIZE 129 +#define MAX_TX_MESSAGE_SIZE 132 #define MAX_RX_MESSAGE_SIZE 534 #define MAX_TOPOLOGY_ELEMS 32 #define HDCP1_AKSV_SIZE 8 diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index eb9ff362184e..f0324ec5e1dc 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -3434,8 +3434,14 @@ int mmc_resume_bus(struct mmc_host *host) spin_unlock_irqrestore(&host->lock, flags); mmc_bus_get(host); - if (host->ops->get_cd) + if (host->ops->get_cd) { card_present = host->ops->get_cd(host); + if (!card_present) { + pr_err("%s: Card removed - card_present:%d\n", + mmc_hostname(host), card_present); + mmc_card_set_removed(host->card); + } + } if (host->bus_ops && !host->bus_dead && host->card && card_present) { mmc_power_up(host, host->card->ocr); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 71a1cfb82d7e..6dd88ff389a3 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1376,11 +1376,21 @@ static int mmc_sd_resume(struct mmc_host *host) MMC_TRACE(host, "%s: Enter\n", __func__); err = _mmc_sd_resume(host); - pm_runtime_set_active(&host->card->dev); - pm_runtime_mark_last_busy(&host->card->dev); - pm_runtime_enable(&host->card->dev); - MMC_TRACE(host, "%s: Exit err: %d\n", __func__, err); + if (err) { + pr_err("%s: sd resume err: %d\n", mmc_hostname(host), err); + if (host->ops->get_cd && !host->ops->get_cd(host)) { + err = -ENOMEDIUM; + mmc_card_set_removed(host->card); + } + } + if (err != -ENOMEDIUM) { + pm_runtime_set_active(&host->card->dev); + pm_runtime_mark_last_busy(&host->card->dev); + pm_runtime_enable(&host->card->dev); + } + + MMC_TRACE(host, "%s: Exit err: %d\n", __func__, err); return err; } diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index c7a7f6becd88..7f16f4bea79b 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -3910,6 +3910,15 @@ int rmnet_ipa3_send_lan_client_msg( IPAWANERR("Can't allocate memory for tether_info\n"); return -ENOMEM; } + + if (data->client_event != IPA_PER_CLIENT_STATS_CONNECT_EVENT && + data->client_event != IPA_PER_CLIENT_STATS_DISCONNECT_EVENT) { + IPAWANERR("Wrong event given. Event:- %d\n", + data->client_event); + kfree(lan_client); + return -EINVAL; + } + data->lan_client.lanIface[IPA_RESOURCE_NAME_MAX-1] = '\0'; memset(&msg_meta, 0, sizeof(struct ipa_msg_meta)); memcpy(lan_client, &data->lan_client, sizeof(struct ipa_lan_client_msg)); diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c index 05a8c66d57aa..465e0793951c 100644 --- a/drivers/platform/msm/sps/sps.c +++ b/drivers/platform/msm/sps/sps.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2019, 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 @@ -675,7 +675,8 @@ int sps_get_bam_debug_info(unsigned long dev, u32 option, u32 para, /* Search for the target BAM device */ bam = sps_h2bam(dev); if (bam == NULL) { - pr_err("sps:Can't find any BAM with handle 0x%lx.", dev); + pr_err("sps:Can't find any BAM with handle 0x%pK.", + (void *)dev); mutex_unlock(&sps->lock); return SPS_ERROR; } @@ -1226,7 +1227,7 @@ struct sps_bam *sps_h2bam(unsigned long h) { struct sps_bam *bam; - SPS_DBG1(sps, "sps:%s: BAM handle:0x%lx.", __func__, h); + SPS_DBG1(sps, "sps:%s: BAM handle:0x%pK.", __func__, (void *)h); if (h == SPS_DEV_HANDLE_MEM || h == SPS_DEV_HANDLE_INVALID) return NULL; @@ -1236,7 +1237,7 @@ struct sps_bam *sps_h2bam(unsigned long h) return bam; } - SPS_ERR(sps, "sps:Can't find BAM device for handle 0x%lx.", h); + SPS_ERR(sps, "sps:Can't find BAM device for handle 0x%pK.", (void *)h); return NULL; } @@ -1341,16 +1342,17 @@ int sps_connect(struct sps_pipe *h, struct sps_connect *connect) bam = sps_h2bam(dev); if (bam == NULL) { - SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%lx", dev); + SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%pK", + (void *)dev); result = SPS_ERROR; goto exit_err; } mutex_lock(&bam->lock); - SPS_DBG2(bam, "sps:sps_connect: bam %pa src 0x%lx dest 0x%lx mode %s", + SPS_DBG2(bam, "sps:sps_connect: bam %pa src 0x%pK dest 0x%pK mode %s", BAM_ID(bam), - connect->source, - connect->destination, + (void *)connect->source, + (void *)connect->destination, connect->mode == SPS_MODE_SRC ? "SRC" : "DEST"); /* Allocate resources for the specified connection */ @@ -1414,10 +1416,10 @@ int sps_disconnect(struct sps_pipe *h) } SPS_DBG2(bam, - "sps:sps_disconnect: bam %pa src 0x%lx dest 0x%lx mode %s", + "sps:sps_disconnect: bam %pa src 0x%pK dest 0x%pK mode %s", BAM_ID(bam), - pipe->connect.source, - pipe->connect.destination, + (void *)pipe->connect.source, + (void *)pipe->connect.destination, pipe->connect.mode == SPS_MODE_SRC ? "SRC" : "DEST"); result = SPS_ERROR; @@ -1813,7 +1815,8 @@ int sps_device_reset(unsigned long dev) /* Search for the target BAM device */ bam = sps_h2bam(dev); if (bam == NULL) { - SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%lx", dev); + SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%pK", + (void *)dev); result = SPS_ERROR; goto exit_err; } @@ -1824,7 +1827,8 @@ int sps_device_reset(unsigned long dev) result = sps_bam_reset(bam); mutex_unlock(&bam->lock); if (result) { - SPS_ERR(sps, "sps:Fail to reset BAM device: 0x%lx", dev); + SPS_ERR(sps, "sps:Fail to reset BAM device: 0x%pK", + (void *)dev); goto exit_err; } diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c index 7d6a7eb039f6..475e9db39bd8 100644 --- a/drivers/platform/msm/sps/sps_bam.c +++ b/drivers/platform/msm/sps/sps_bam.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2019, 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 @@ -895,8 +895,8 @@ int sps_bam_pipe_connect(struct sps_pipe *bam_pipe, else iova = bam_pipe->connect.source_iova; SPS_DBG2(dev, - "sps:BAM %pa pipe %d uses IOVA 0x%lx.\n", - BAM_ID(dev), pipe_index, iova); + "sps:BAM %pa pipe %d uses IOVA 0x%pK.\n", + BAM_ID(dev), pipe_index, (void *)iova); hw_params.peer_phys_addr = (u32)iova; } else { hw_params.peer_phys_addr = peer_bam->props.phys_addr; @@ -918,9 +918,9 @@ int sps_bam_pipe_connect(struct sps_pipe *bam_pipe, hw_params.data_base = (phys_addr_t)bam_pipe->connect.data.iova; SPS_DBG2(dev, - "sps:BAM %pa pipe %d uses IOVA 0x%lx for data FIFO.\n", + "sps:BAM %pa pipe %d uses IOVA 0x%pK for data FIFO.\n", BAM_ID(dev), pipe_index, - bam_pipe->connect.data.iova); + (void *)(bam_pipe->connect.data.iova)); } else { hw_params.data_base = map->data.phys_base; } @@ -971,9 +971,9 @@ int sps_bam_pipe_connect(struct sps_pipe *bam_pipe, hw_params.desc_base = (phys_addr_t)bam_pipe->connect.desc.iova; SPS_DBG2(dev, - "sps:BAM %pa pipe %d uses IOVA 0x%lx for desc FIFO.\n", + "sps:BAM %pa pipe %d uses IOVA 0x%pK for desc FIFO.\n", BAM_ID(dev), pipe_index, - bam_pipe->connect.desc.iova); + (void *)(bam_pipe->connect.desc.iova)); } else { hw_params.desc_base = map->desc.phys_base; } @@ -1424,8 +1424,9 @@ int sps_bam_pipe_transfer_one(struct sps_bam *dev, u32 next_write; static int show_recom; - SPS_DBG(dev, "sps:BAM %pa pipe %d addr 0x%x size 0x%x flags 0x%x\n", - BAM_ID(dev), pipe_index, addr, size, flags); + SPS_DBG(dev, "sps:BAM %pa pipe %d addr 0x%pK size 0x%x flags 0x%x\n", + BAM_ID(dev), pipe_index, + (void *)(long)addr, size, flags); /* Is this a BAM-to-BAM or satellite connection? */ if ((pipe->state & (BAM_STATE_BAM2BAM | BAM_STATE_REMOTE))) { @@ -1951,8 +1952,8 @@ static void pipe_handler_eot(struct sps_bam *dev, struct sps_pipe *pipe) user = &pipe->sys.user_ptrs[offset / sizeof(struct sps_iovec)]; for (;;) { SPS_DBG(dev, - "sps:%s; pipe index:%d; iovec addr:0x%x; size:0x%x; flags:0x%x; enabled:0x%x; *user is %s NULL.\n", - __func__, pipe->pipe_index, cache->addr, + "sps:%s; pipe index:%d; iovec addr:0x%pK; size:0x%x; flags:0x%x; enabled:0x%x; *user is %s NULL.\n", + __func__, pipe->pipe_index, (void *)(long)cache->addr, cache->size, cache->flags, enabled, (*user == NULL) ? "" : "not"); @@ -2240,8 +2241,8 @@ int sps_bam_pipe_get_iovec(struct sps_bam *dev, u32 pipe_index, pipe->sys.acked_offset = 0; SPS_DBG(dev, - "sps:%s; pipe index:%d; iovec addr:0x%x; size:0x%x; flags:0x%x; acked_offset:0x%x.\n", - __func__, pipe->pipe_index, desc->addr, + "sps:%s; pipe index:%d; iovec addr:0x%pK; size:0x%x; flags:0x%x; acked_offset:0x%x.\n", + __func__, pipe->pipe_index, (void *)(long)desc->addr, desc->size, desc->flags, pipe->sys.acked_offset); return 0; diff --git a/drivers/platform/msm/sps/sps_dma.c b/drivers/platform/msm/sps/sps_dma.c index abdcabc8cddd..0cc428399ecf 100644 --- a/drivers/platform/msm/sps/sps_dma.c +++ b/drivers/platform/msm/sps/sps_dma.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2013, 2015, 2017, The Linux Foundation. All rights +/* Copyright (c) 2011-2013, 2015, 2017, 2019, The Linux Foundation. All rights * reserved. * * This program is free software; you can redistribute it and/or modify @@ -381,7 +381,7 @@ int sps_dma_device_de_init(unsigned long h) dev = sps_dma_find_device(h); if (dev == NULL) { - SPS_ERR(sps, "sps:BAM-DMA: not registered: %lx", h); + SPS_ERR(sps, "sps:BAM-DMA: not registered: %pK", (void *)h); result = SPS_ERROR; goto exit_err; } @@ -547,8 +547,8 @@ int sps_alloc_dma_chan(const struct sps_alloc_dma_chan *alloc, dev = sps_dma_find_device(alloc->dev); if (dev == NULL) { - SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %lx", - alloc->dev); + SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %pK", + (void *)alloc->dev); goto exit_err; } @@ -621,7 +621,8 @@ int sps_free_dma_chan(struct sps_dma_chan *chan) dev = sps_dma_find_device(chan->dev); if (dev == NULL) { - SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %lx", chan->dev); + SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %pK", + (void *)chan->dev); result = SPS_ERROR; goto exit_err; } diff --git a/drivers/platform/msm/sps/sps_mem.c b/drivers/platform/msm/sps/sps_mem.c index 105135a0e022..f5e026ba62ed 100644 --- a/drivers/platform/msm/sps/sps_mem.c +++ b/drivers/platform/msm/sps/sps_mem.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2013, 2015, 2017, The Linux Foundation. +/* Copyright (c) 2011-2013, 2015, 2017, 2019, The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -75,8 +75,8 @@ phys_addr_t sps_mem_alloc_io(u32 bytes) return SPS_ADDR_INVALID; } - SPS_DBG3(sps, "sps:sps_mem_alloc_io.phys=%pa.virt=0x%lx.size=0x%x.", - &phys_addr, virt_addr, bytes); + SPS_DBG3(sps, "sps:sps_mem_alloc_io.phys=%pa.virt=0x%pK.size=0x%x.", + &phys_addr, (void *)virt_addr, bytes); return phys_addr; } @@ -92,8 +92,8 @@ void sps_mem_free_io(phys_addr_t phys_addr, u32 bytes) iomem_offset = phys_addr - iomem_phys; virt_addr = (uintptr_t) iomem_virt + iomem_offset; - SPS_DBG3(sps, "sps:sps_mem_free_io.phys=%pa.virt=0x%lx.size=0x%x.", - &phys_addr, virt_addr, bytes); + SPS_DBG3(sps, "sps:sps_mem_free_io.phys=%pa.virt=0x%pK.size=0x%x.", + &phys_addr, (void *)virt_addr, bytes); gen_pool_free(pool, virt_addr, bytes); total_free += bytes; diff --git a/drivers/platform/msm/sps/sps_rm.c b/drivers/platform/msm/sps/sps_rm.c index 276b847979e1..ef6029a9e518 100644 --- a/drivers/platform/msm/sps/sps_rm.c +++ b/drivers/platform/msm/sps/sps_rm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2015, 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2015, 2017, 2019, 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 @@ -380,8 +380,8 @@ static struct sps_connection *sps_rm_create(struct sps_pipe *pipe) map->src.bam = sps_h2bam(map->src.dev); if (map->src.bam == NULL) { if (map->src.dev != SPS_DEV_HANDLE_MEM) { - SPS_ERR(sps, "sps:Invalid BAM handle: %pa", - &map->src.dev); + SPS_ERR(sps, "sps:Invalid BAM handle: %pK", + (void *)(&map->src.dev)); goto exit_err; } map->src.pipe_index = SPS_BAM_PIPE_INVALID; @@ -389,8 +389,8 @@ static struct sps_connection *sps_rm_create(struct sps_pipe *pipe) map->dest.bam = sps_h2bam(map->dest.dev); if (map->dest.bam == NULL) { if (map->dest.dev != SPS_DEV_HANDLE_MEM) { - SPS_ERR(sps, "sps:Invalid BAM handle: %pa", - &map->dest.dev); + SPS_ERR(sps, "sps:Invalid BAM handle: %pK", + (void *)(&map->dest.dev)); goto exit_err; } map->dest.pipe_index = SPS_BAM_PIPE_INVALID; @@ -399,8 +399,8 @@ static struct sps_connection *sps_rm_create(struct sps_pipe *pipe) /* Check the BAM device for the pipe */ if ((dir == SPS_MODE_SRC && map->src.bam == NULL) || (dir != SPS_MODE_SRC && map->dest.bam == NULL)) { - SPS_ERR(sps, "sps:Invalid BAM endpt: dir %d src %pa dest %pa", - dir, &map->src.dev, &map->dest.dev); + SPS_ERR(sps, "sps:Invalid BAM endpt: dir %d src %pK dest %pK", + dir, (void *)(&map->src.dev), (void *)(&map->dest.dev)); goto exit_err; } diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 17b808ca843d..1b7af04730ba 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -526,9 +526,19 @@ int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state) if (state->period != pwm->state.period || state->duty_cycle != pwm->state.duty_cycle) { - err = pwm->chip->ops->config(pwm->chip, pwm, - state->duty_cycle, - state->period); + if (pwm->chip->ops->config_extend) { + err = pwm->chip->ops->config_extend(pwm->chip, + pwm, state->duty_cycle, + state->period); + } else { + if (state->period > UINT_MAX) + pr_warn("period %llu duty_cycle %llu will be truncated\n", + state->period, + state->duty_cycle); + err = pwm->chip->ops->config(pwm->chip, pwm, + state->duty_cycle, + state->period); + } if (err) return err; @@ -1017,8 +1027,8 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s) if (state.enabled) seq_puts(s, " enabled"); - seq_printf(s, " period: %u ns", state.period); - seq_printf(s, " duty: %u ns", state.duty_cycle); + seq_printf(s, " period: %llu ns", state.period); + seq_printf(s, " duty: %llu ns", state.duty_cycle); seq_printf(s, " polarity: %s", state.polarity ? "inverse" : "normal"); diff --git a/drivers/pwm/pwm-qti-lpg.c b/drivers/pwm/pwm-qti-lpg.c index d24bef10c1d7..f5c5e399af7f 100644 --- a/drivers/pwm/pwm-qti-lpg.c +++ b/drivers/pwm/pwm-qti-lpg.c @@ -164,7 +164,7 @@ struct lpg_pwm_config { u32 prediv; u32 clk_exp; u16 pwm_value; - u32 best_period_ns; + u64 best_period_ns; }; struct qpnp_lpg_lut { @@ -185,8 +185,8 @@ struct qpnp_lpg_channel { u8 src_sel; u8 subtype; bool lut_written; - int current_period_ns; - int current_duty_ns; + u64 current_period_ns; + u64 current_duty_ns; }; struct qpnp_lpg_chip { @@ -723,17 +723,17 @@ static int qpnp_lpg_set_ramp_config(struct qpnp_lpg_channel *lpg) return rc; } -static void __qpnp_lpg_calc_pwm_period(int period_ns, +static void __qpnp_lpg_calc_pwm_period(u64 period_ns, struct lpg_pwm_config *pwm_config) { struct qpnp_lpg_channel *lpg = container_of(pwm_config, struct qpnp_lpg_channel, pwm_config); struct lpg_pwm_config configs[NUM_PWM_SIZE]; int i, j, m, n; - int tmp1, tmp2; - int clk_period_ns = 0, pwm_clk_period_ns; - int clk_delta_ns = INT_MAX, min_clk_delta_ns = INT_MAX; - int pwm_period_delta = INT_MAX, min_pwm_period_delta = INT_MAX; + u64 tmp1, tmp2; + u64 clk_period_ns = 0, pwm_clk_period_ns; + u64 clk_delta_ns = U64_MAX, min_clk_delta_ns = U64_MAX; + u64 pwm_period_delta = U64_MAX, min_pwm_period_delta = U64_MAX; int pwm_size_step; /* @@ -755,7 +755,8 @@ static void __qpnp_lpg_calc_pwm_period(int period_ns, for (m = 0; m < ARRAY_SIZE(pwm_exponent); m++) { tmp1 = 1 << pwm_exponent[m]; tmp1 *= clk_prediv[j]; - tmp2 = NSEC_PER_SEC / clk_freq_hz[i]; + tmp2 = NSEC_PER_SEC; + do_div(tmp2, clk_freq_hz[i]); clk_period_ns = tmp1 * tmp2; @@ -785,10 +786,7 @@ static void __qpnp_lpg_calc_pwm_period(int period_ns, configs[n].best_period_ns *= 1 << pwm_size[n]; /* Find the closest setting for PWM period */ - if (min_clk_delta_ns < INT_MAX >> pwm_size[n]) - pwm_period_delta = min_clk_delta_ns << pwm_size[n]; - else - pwm_period_delta = INT_MAX; + pwm_period_delta = min_clk_delta_ns << pwm_size[n]; if (pwm_period_delta < min_pwm_period_delta) { min_pwm_period_delta = pwm_period_delta; memcpy(pwm_config, &configs[n], @@ -806,21 +804,20 @@ static void __qpnp_lpg_calc_pwm_period(int period_ns, pwm_config->clk_exp -= pwm_size_step; } } - pr_debug("PWM setting for period_ns %d: pwm_clk = %dHZ, prediv = %d, exponent = %d, pwm_size = %d\n", + pr_debug("PWM setting for period_ns %llu: pwm_clk = %dHZ, prediv = %d, exponent = %d, pwm_size = %d\n", period_ns, pwm_config->pwm_clk, pwm_config->prediv, pwm_config->clk_exp, pwm_config->pwm_size); - pr_debug("Actual period: %dns\n", pwm_config->best_period_ns); + pr_debug("Actual period: %lluns\n", pwm_config->best_period_ns); } -static void __qpnp_lpg_calc_pwm_duty(int period_ns, int duty_ns, +static void __qpnp_lpg_calc_pwm_duty(u64 period_ns, u64 duty_ns, struct lpg_pwm_config *pwm_config) { u16 pwm_value, max_pwm_value; + u64 tmp; - if ((1 << pwm_config->pwm_size) > (INT_MAX / duty_ns)) - pwm_value = duty_ns / (period_ns >> pwm_config->pwm_size); - else - pwm_value = (duty_ns << pwm_config->pwm_size) / period_ns; + tmp = (u64)duty_ns << pwm_config->pwm_size; + pwm_value = (u16)div64_u64(tmp, period_ns); max_pwm_value = (1 << pwm_config->pwm_size) - 1; if (pwm_value > max_pwm_value) @@ -828,20 +825,13 @@ static void __qpnp_lpg_calc_pwm_duty(int period_ns, int duty_ns, pwm_config->pwm_value = pwm_value; } -static int qpnp_lpg_pwm_config(struct pwm_chip *pwm_chip, - struct pwm_device *pwm, int duty_ns, int period_ns) +static int qpnp_lpg_config(struct qpnp_lpg_channel *lpg, + u64 duty_ns, u64 period_ns) { - struct qpnp_lpg_channel *lpg; - int rc = 0; - - lpg = pwm_dev_to_qpnp_lpg(pwm_chip, pwm); - if (lpg == NULL) { - dev_err(pwm_chip->dev, "lpg not found\n"); - return -ENODEV; - } + int rc; if (duty_ns > period_ns) { - dev_err(pwm_chip->dev, "Duty %dns is larger than period %dns\n", + dev_err(lpg->chip->dev, "Duty %lluns is larger than period %lluns\n", duty_ns, period_ns); return -EINVAL; } @@ -855,7 +845,7 @@ static int qpnp_lpg_pwm_config(struct pwm_chip *pwm_chip, lpg->ramp_config.pattern, lpg->ramp_config.pattern_length); if (rc < 0) { - dev_err(pwm_chip->dev, "set LUT pattern failed for LPG%d, rc=%d\n", + dev_err(lpg->chip->dev, "set LUT pattern failed for LPG%d, rc=%d\n", lpg->lpg_idx, rc); return rc; } @@ -869,7 +859,7 @@ static int qpnp_lpg_pwm_config(struct pwm_chip *pwm_chip, rc = qpnp_lpg_set_pwm_config(lpg); if (rc < 0) { - dev_err(pwm_chip->dev, "Config PWM failed for channel %d, rc=%d\n", + dev_err(lpg->chip->dev, "Config PWM failed for channel %d, rc=%d\n", lpg->lpg_idx, rc); return rc; } @@ -880,6 +870,34 @@ static int qpnp_lpg_pwm_config(struct pwm_chip *pwm_chip, return rc; } +static int qpnp_lpg_pwm_config(struct pwm_chip *pwm_chip, + struct pwm_device *pwm, int duty_ns, int period_ns) +{ + struct qpnp_lpg_channel *lpg; + + lpg = pwm_dev_to_qpnp_lpg(pwm_chip, pwm); + if (lpg == NULL) { + dev_err(pwm_chip->dev, "lpg not found\n"); + return -ENODEV; + } + + return qpnp_lpg_config(lpg, (u64)duty_ns, (u64)period_ns); +} + +static int qpnp_lpg_pwm_config_extend(struct pwm_chip *pwm_chip, + struct pwm_device *pwm, u64 duty_ns, u64 period_ns) +{ + struct qpnp_lpg_channel *lpg; + + lpg = pwm_dev_to_qpnp_lpg(pwm_chip, pwm); + if (lpg == NULL) { + dev_err(pwm_chip->dev, "lpg not found\n"); + return -ENODEV; + } + + return qpnp_lpg_config(lpg, duty_ns, period_ns); +} + static int qpnp_lpg_pbs_trigger_enable(struct qpnp_lpg_channel *lpg, bool en) { struct qpnp_lpg_chip *chip = lpg->chip; @@ -1065,8 +1083,9 @@ static int qpnp_lpg_pwm_set_output_pattern(struct pwm_chip *pwm_chip, struct pwm_device *pwm, struct pwm_output_pattern *output_pattern) { struct qpnp_lpg_channel *lpg; - int rc = 0, i, period_ns, duty_ns; + u64 period_ns, duty_ns, tmp; u32 *percentages; + int rc = 0, i; lpg = pwm_dev_to_qpnp_lpg(pwm_chip, pwm); if (lpg == NULL) { @@ -1086,19 +1105,17 @@ static int qpnp_lpg_pwm_set_output_pattern(struct pwm_chip *pwm_chip, if (!percentages) return -ENOMEM; - period_ns = pwm_get_period(pwm); + period_ns = pwm_get_period_extend(pwm); for (i = 0; i < output_pattern->num_entries; i++) { duty_ns = output_pattern->duty_pattern[i]; if (duty_ns > period_ns) { - dev_err(lpg->chip->dev, "duty %dns is larger than period %dns\n", + dev_err(lpg->chip->dev, "duty %lluns is larger than period %lluns\n", duty_ns, period_ns); goto err; } /* Translate the pattern in duty_ns to percentage */ - if ((INT_MAX / duty_ns) < 100) - percentages[i] = duty_ns / (period_ns / 100); - else - percentages[i] = (duty_ns * 100) / period_ns; + tmp = (u64)duty_ns * 100; + percentages[i] = (u32)div64_u64(tmp, period_ns); } rc = qpnp_lpg_set_lut_pattern(lpg, percentages, @@ -1114,12 +1131,10 @@ static int qpnp_lpg_pwm_set_output_pattern(struct pwm_chip *pwm_chip, output_pattern->num_entries); lpg->ramp_config.hi_idx = lpg->ramp_config.lo_idx + output_pattern->num_entries - 1; - if ((INT_MAX / period_ns) > output_pattern->cycles_per_duty) - lpg->ramp_config.step_ms = output_pattern->cycles_per_duty * - period_ns / NSEC_PER_MSEC; - else - lpg->ramp_config.step_ms = (period_ns / NSEC_PER_MSEC) * - output_pattern->cycles_per_duty; + + tmp = (u64)output_pattern->cycles_per_duty * period_ns; + do_div(tmp, NSEC_PER_MSEC); + lpg->ramp_config.step_ms = (u16)tmp; rc = qpnp_lpg_set_ramp_config(lpg); if (rc < 0) @@ -1241,8 +1256,8 @@ static void qpnp_lpg_pwm_dbg_show(struct pwm_chip *pwm_chip, struct seq_file *s) seq_printf(s, " prediv = %d\n", cfg->prediv); seq_printf(s, " exponent = %d\n", cfg->clk_exp); seq_printf(s, " pwm_value = %d\n", cfg->pwm_value); - seq_printf(s, " Requested period: %dns, best period = %dns\n", - pwm_get_period(pwm), cfg->best_period_ns); + seq_printf(s, " Requested period: %lluns, best period = %lluns\n", + pwm_get_period_extend(pwm), cfg->best_period_ns); ramp = &lpg->ramp_config; if (pwm_get_output_type(pwm) == PWM_OUTPUT_MODULATED) { @@ -1273,6 +1288,7 @@ static void qpnp_lpg_pwm_dbg_show(struct pwm_chip *pwm_chip, struct seq_file *s) static const struct pwm_ops qpnp_lpg_pwm_ops = { .config = qpnp_lpg_pwm_config, + .config_extend = qpnp_lpg_pwm_config_extend, .get_output_type_supported = qpnp_lpg_pwm_output_types_supported, .set_output_type = qpnp_lpg_pwm_set_output_type, .set_output_pattern = qpnp_lpg_pwm_set_output_pattern, diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c index ea2b53d17199..50b7a3b278c1 100644 --- a/drivers/pwm/sysfs.c +++ b/drivers/pwm/sysfs.c @@ -50,7 +50,7 @@ static ssize_t period_show(struct device *child, pwm_get_state(pwm, &state); - return sprintf(buf, "%u\n", state.period); + return sprintf(buf, "%llu\n", state.period); } static ssize_t period_store(struct device *child, @@ -85,7 +85,7 @@ static ssize_t duty_cycle_show(struct device *child, pwm_get_state(pwm, &state); - return sprintf(buf, "%u\n", state.duty_cycle); + return sprintf(buf, "%llu\n", state.duty_cycle); } static ssize_t duty_cycle_store(struct device *child, @@ -220,7 +220,7 @@ static ssize_t capture_show(struct device *child, if (ret) return ret; - return sprintf(buf, "%u %u\n", result.period, result.duty_cycle); + return sprintf(buf, "%llu %llu\n", result.period, result.duty_cycle); } static ssize_t output_type_show(struct device *child, diff --git a/drivers/soc/qcom/secure_buffer.c b/drivers/soc/qcom/secure_buffer.c index 5b82c0b25d38..b77eb388c6b6 100644 --- a/drivers/soc/qcom/secure_buffer.c +++ b/drivers/soc/qcom/secure_buffer.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Google, Inc - * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019, 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 @@ -55,8 +55,8 @@ struct dest_vm_and_perm_info { u32 ctx_size; }; -static void *qcom_secure_mem; -#define QCOM_SECURE_MEM_SIZE (512*1024) +#define BATCH_MAX_SIZE SZ_2M +#define BATCH_MAX_SECTIONS 32 static int secure_buffer_change_chunk(u32 chunks, u32 nchunks, @@ -216,43 +216,68 @@ populate_dest_info(int *dest_vmids, int nelements, int *dest_perms, } /* Must hold secure_buffer_mutex while allocated buffer is in use */ -static struct mem_prot_info *get_info_list_from_table(struct sg_table *table, - size_t *size_in_bytes) +static unsigned int get_batches_from_sgl(struct mem_prot_info *sg_table_copy, + struct scatterlist *sgl, + struct scatterlist **next_sgl) { - int i; - struct scatterlist *sg; - struct mem_prot_info *info; - size_t size; + u64 batch_size = 0; + unsigned int i = 0; + struct scatterlist *curr_sgl = sgl; + + /* Ensure no zero size batches */ + do { + sg_table_copy[i].addr = page_to_phys(sg_page(curr_sgl)); + sg_table_copy[i].size = curr_sgl->length; + batch_size += sg_table_copy[i].size; + curr_sgl = sg_next(curr_sgl); + i++; + } while (curr_sgl && i < BATCH_MAX_SECTIONS && + curr_sgl->length + batch_size < BATCH_MAX_SIZE); + + *next_sgl = curr_sgl; + return i; +} - size = table->nents * sizeof(*info); +static int batched_hyp_assign(struct sg_table *table, struct scm_desc *desc) +{ + unsigned int entries_size; + unsigned int batch_start = 0; + unsigned int batches_processed; + struct scatterlist *curr_sgl = table->sgl; + struct scatterlist *next_sgl; + int ret = 0; + struct mem_prot_info *sg_table_copy = kcalloc(BATCH_MAX_SECTIONS, + sizeof(*sg_table_copy), + GFP_KERNEL); - if (size >= QCOM_SECURE_MEM_SIZE) { - pr_err("%s: Not enough memory allocated. Required size %zd\n", - __func__, size); - return NULL; - } + if (!sg_table_copy) + return -ENOMEM; - if (!qcom_secure_mem) { - pr_err("%s is not functional as qcom_secure_mem is not allocated.\n", - __func__); - return NULL; - } + while (batch_start < table->nents) { + batches_processed = get_batches_from_sgl(sg_table_copy, + curr_sgl, &next_sgl); + curr_sgl = next_sgl; + entries_size = batches_processed * sizeof(*sg_table_copy); + dmac_flush_range(sg_table_copy, + (void *)sg_table_copy + entries_size); + desc->args[0] = virt_to_phys(sg_table_copy); + desc->args[1] = entries_size; - /* "Allocate" it */ - info = qcom_secure_mem; + ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, + MEM_PROT_ASSIGN_ID), desc); + if (ret) { + pr_info("%s: Failed to assign memory protection, ret = %d\n", + __func__, ret); + break; + } - for_each_sg(table->sgl, sg, table->nents, i) { - info[i].addr = page_to_phys(sg_page(sg)); - info[i].size = sg->length; + batch_start += batches_processed; } - *size_in_bytes = size; - return info; + kfree(sg_table_copy); + return ret; } -#define BATCH_MAX_SIZE SZ_2M -#define BATCH_MAX_SECTIONS 32 - int hyp_assign_table(struct sg_table *table, u32 *source_vm_list, int source_nelems, int *dest_vmids, int *dest_perms, @@ -264,11 +289,10 @@ int hyp_assign_table(struct sg_table *table, size_t source_vm_copy_size; struct dest_vm_and_perm_info *dest_vm_copy; size_t dest_vm_copy_size; - struct mem_prot_info *sg_table_copy; - size_t sg_table_copy_size; - int batch_start, batch_end; - u64 batch_size; + if (!table || !table->sgl || !source_vm_list || !source_nelems || + !dest_vmids || !dest_perms || !dest_nelems) + return -EINVAL; /* * We can only pass cache-aligned sizes to hypervisor, so we need @@ -286,19 +310,11 @@ int hyp_assign_table(struct sg_table *table, &dest_vm_copy_size); if (!dest_vm_copy) { ret = -ENOMEM; - goto out_free; + goto out_free_source; } mutex_lock(&secure_buffer_mutex); - sg_table_copy = get_info_list_from_table(table, &sg_table_copy_size); - if (!sg_table_copy) { - ret = -ENOMEM; - goto out_unlock; - } - - desc.args[0] = virt_to_phys(sg_table_copy); - desc.args[1] = sg_table_copy_size; desc.args[2] = virt_to_phys(source_vm_copy); desc.args[3] = source_vm_copy_size; desc.args[4] = virt_to_phys(dest_vm_copy); @@ -310,50 +326,14 @@ int hyp_assign_table(struct sg_table *table, dmac_flush_range(source_vm_copy, (void *)source_vm_copy + source_vm_copy_size); - dmac_flush_range(sg_table_copy, - (void *)sg_table_copy + sg_table_copy_size); dmac_flush_range(dest_vm_copy, (void *)dest_vm_copy + dest_vm_copy_size); - batch_start = 0; - while (batch_start < table->nents) { - /* Ensure no size zero batches */ - batch_size = sg_table_copy[batch_start].size; - batch_end = batch_start + 1; - while (1) { - u64 size; - - if (batch_end >= table->nents) - break; - if (batch_end - batch_start >= BATCH_MAX_SECTIONS) - break; - - size = sg_table_copy[batch_end].size; - if (size + batch_size >= BATCH_MAX_SIZE) - break; - - batch_size += size; - batch_end++; - } - - desc.args[0] = virt_to_phys(&sg_table_copy[batch_start]); - desc.args[1] = (batch_end - batch_start) * - sizeof(sg_table_copy[0]); - - ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, - MEM_PROT_ASSIGN_ID), &desc); - if (ret) { - pr_info("%s: Failed to assign memory protection, ret = %d\n", - __func__, ret); - break; - } - batch_start = batch_end; - } + ret = batched_hyp_assign(table, &desc); -out_unlock: mutex_unlock(&secure_buffer_mutex); kfree(dest_vm_copy); -out_free: +out_free_source: kfree(source_vm_copy); return ret; } @@ -436,23 +416,3 @@ bool msm_secure_v2_is_supported(void) return (scm_get_feat_version(FEATURE_ID_CP) >= MAKE_CP_VERSION(1, 1, 0)); } - -static int __init alloc_secure_shared_memory(void) -{ - int ret = 0; - dma_addr_t dma_handle; - - qcom_secure_mem = kzalloc(QCOM_SECURE_MEM_SIZE, GFP_KERNEL); - if (!qcom_secure_mem) { - /* Fallback to CMA-DMA memory */ - qcom_secure_mem = dma_alloc_coherent(NULL, QCOM_SECURE_MEM_SIZE, - &dma_handle, GFP_KERNEL); - if (!qcom_secure_mem) { - pr_err("Couldn't allocate memory for secure use-cases. hyp_assign_table will not work\n"); - return -ENOMEM; - } - } - - return ret; -} -pure_initcall(alloc_secure_shared_memory); diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c index 9fe601da80f0..64ff2843afd8 100644 --- a/drivers/thermal/qpnp-adc-tm.c +++ b/drivers/thermal/qpnp-adc-tm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, 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 @@ -3239,7 +3239,7 @@ static int qpnp_adc_tm_probe(struct platform_device *pdev) } else { rc = devm_request_irq(&pdev->dev, chip->adc->adc_irq_eoc, qpnp_adc_tm_rc_thr_isr, - IRQF_TRIGGER_HIGH, "qpnp_adc_tm_interrupt", chip); + IRQF_TRIGGER_RISING, "qpnp_adc_tm_interrupt", chip); if (rc) dev_err(&pdev->dev, "failed to request adc irq\n"); else diff --git a/include/linux/pwm.h b/include/linux/pwm.h index 6c0168b0f44c..b40287e0ce16 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -38,7 +38,7 @@ enum pwm_polarity { * current PWM hardware state. */ struct pwm_args { - unsigned int period; + u64 period; enum pwm_polarity polarity; }; @@ -65,9 +65,9 @@ enum pwm_output_type { * @cycles_per_duty: number of PWM period cycles an entry stays at */ struct pwm_output_pattern { - unsigned int *duty_pattern; + u64 *duty_pattern; unsigned int num_entries; - unsigned int cycles_per_duty; + u64 cycles_per_duty; }; /* @@ -78,8 +78,8 @@ struct pwm_output_pattern { * @enabled: PWM enabled status */ struct pwm_state { - unsigned int period; - unsigned int duty_cycle; + u64 period; + u64 duty_cycle; enum pwm_polarity polarity; enum pwm_output_type output_type; struct pwm_output_pattern *output_pattern; @@ -135,12 +135,30 @@ static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period) pwm->state.period = period; } +static inline void pwm_set_period_extend(struct pwm_device *pwm, u64 period) +{ + if (pwm) + pwm->state.period = period; +} + static inline unsigned int pwm_get_period(const struct pwm_device *pwm) { struct pwm_state state; pwm_get_state(pwm, &state); + if (state.period > UINT_MAX) + pr_warn("PWM period %llu is truncated\n", state.period); + + return (unsigned int)state.period; +} + +static inline u64 pwm_get_period_extend(const struct pwm_device *pwm) +{ + struct pwm_state state; + + pwm_get_state(pwm, &state); + return state.period; } @@ -150,12 +168,30 @@ static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty) pwm->state.duty_cycle = duty; } +static inline void pwm_set_duty_cycle_extend(struct pwm_device *pwm, u64 duty) +{ + if (pwm) + pwm->state.duty_cycle = duty; +} + static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm) { struct pwm_state state; pwm_get_state(pwm, &state); + if (state.duty_cycle > UINT_MAX) + pr_warn("PWM duty cycle %llu is truncated\n", state.duty_cycle); + + return (unsigned int)state.duty_cycle; +} + +static inline u64 pwm_get_duty_cycle_extend(const struct pwm_device *pwm) +{ + struct pwm_state state; + + pwm_get_state(pwm, &state); + return state.duty_cycle; } @@ -287,6 +323,8 @@ pwm_set_relative_duty_cycle(struct pwm_state *state, unsigned int duty_cycle, * @request: optional hook for requesting a PWM * @free: optional hook for freeing a PWM * @config: configure duty cycles and period length for this PWM + * @config_extend: configure duty cycles and period length for this + * PWM with u64 data type * @set_polarity: configure the polarity of this PWM * @capture: capture and report PWM signal * @enable: enable PWM output toggling @@ -309,6 +347,8 @@ struct pwm_ops { void (*free)(struct pwm_chip *chip, struct pwm_device *pwm); int (*config)(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns); + int (*config_extend)(struct pwm_chip *chip, struct pwm_device *pwm, + u64 duty_ns, u64 period_ns); int (*set_polarity)(struct pwm_chip *chip, struct pwm_device *pwm, enum pwm_polarity polarity); int (*capture)(struct pwm_chip *chip, struct pwm_device *pwm, @@ -366,8 +406,8 @@ struct pwm_chip { * @duty_cycle: duty cycle of the PWM signal (in nanoseconds) */ struct pwm_capture { - unsigned int period; - unsigned int duty_cycle; + u64 period; + u64 duty_cycle; }; #if IS_ENABLED(CONFIG_PWM) @@ -421,6 +461,31 @@ static inline int pwm_config(struct pwm_device *pwm, int duty_ns, } /** + * pwm_config_extend() - change PWM period and duty length with u64 data type + * @pwm: PWM device + * @duty_ns: "on" time (in nanoseconds) + * @period_ns: duration (in nanoseconds) of one cycle + * + * Returns: 0 on success or a negative error code on failure. + */ +static inline int pwm_config_extend(struct pwm_device *pwm, u64 duty_ns, + u64 period_ns) +{ + struct pwm_state state; + + if (!pwm) + return -EINVAL; + + pwm_get_state(pwm, &state); + if (state.duty_cycle == duty_ns && state.period == period_ns) + return 0; + + state.duty_cycle = duty_ns; + state.period = period_ns; + return pwm_apply_state(pwm, &state); +} + +/** * pwm_set_polarity() - configure the polarity of a PWM signal * @pwm: PWM device * @polarity: new polarity of the PWM signal diff --git a/lib/qmi_encdec.c b/lib/qmi_encdec.c index d7221d898238..2808f7b72e3f 100644 --- a/lib/qmi_encdec.c +++ b/lib/qmi_encdec.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 2019 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 @@ -706,8 +706,8 @@ static int qmi_decode_string_elem(struct elem_info *ei_array, void *buf_dst, decoded_bytes += rc; } - if (string_len > temp_ei->elem_len) { - pr_err("%s: String len %d > Max Len %d\n", + if (string_len >= temp_ei->elem_len) { + pr_err("%s: String len %d >= Max Len %d\n", __func__, string_len, temp_ei->elem_len); return -ETOOSMALL; } else if (string_len > tlv_len) { |