Merge "Merge remote-tracking branch '4.9/tmp-4979478' into msm-4.9" into msm-4.9
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_bus_adhoc.txt b/Documentation/devicetree/bindings/arm/msm/msm_bus_adhoc.txt
index 96e42c5..6bf6a57 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_bus_adhoc.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_bus_adhoc.txt
@@ -218,7 +218,16 @@
master-id, slave-id, arbitrated bandwidth
in KBps, instantaneous bandwidth in KBps
-Example:
+The following are optional properties for client's device nodes:
+
+- qcom,msm-bus,alc-voter: Boolean alc_voter flag to indicate that client
+ will vote as an Active Latency Client.
+- qcom,msm-bus,vectors-alc: Arrays of unsigned integers representing:
+ first access latency, idle time in ns, this
+ property is required if qcom,msm-bus,alc-voter
+ is present.
+
+Example for default client:
qcom,msm-bus,name = "client-name";
qcom,msm-bus,num-cases = <3>;
@@ -229,3 +238,12 @@
<22 512 320000 3200000>, <26 512 3200000 3200000>,
<22 512 160000 1600000>, <26 512 1600000 1600000>;
+Example for ALC client:
+
+ qcom,msm-bus,name = "client-name";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,alc-voter;
+ qcom,msm-bus,vectors-alc =
+ <0 0>,
+ <500 1600>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-bus.dtsi b/arch/arm64/boot/dts/qcom/sdm845-bus.dtsi
index a51f411..1702e80 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-bus.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-bus.dtsi
@@ -191,6 +191,7 @@
cell-id = <MSM_BUS_BCM_QUP0>;
label = "QUP0";
qcom,bcm-name = "QUP0";
+ qcom,rscs = <&rsc_apps>;
qcom,bcm-dev;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-cdp.dtsi
new file mode 100644
index 0000000..fce1687
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-cdp.dtsi
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2016-2017, 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.
+ */
+
+&soc {
+ led_flash_rear: qcom,camera-flash@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-source = <&pmi8998_flash0 &pmi8998_flash1>;
+ qcom,torch-source = <&pmi8998_torch0 &pmi8998_torch1>;
+ qcom,switch-source = <&pmi8998_switch0>;
+ status = "ok";
+ };
+
+ led_flash_front: qcom,camera-flash@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-source = <&pmi8998_flash2>;
+ qcom,torch-source = <&pmi8998_torch2>;
+ qcom,switch-source = <&pmi8998_switch1>;
+ status = "ok";
+ };
+
+ actuator_regulator: gpio-regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0x0>;
+ regulator-name = "actuator_regulator";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <100>;
+ enable-active-high;
+ gpio = <&tlmm 27 0>;
+ vin-supply = <&pmi8998_bob>;
+ };
+
+ camera_rear_ldo: gpio-regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <0x1>;
+ regulator-name = "camera_rear_ldo";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-enable-ramp-delay = <135>;
+ enable-active-high;
+ gpio = <&pm8998_gpios 12 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&camera_rear_dvdd_en_default>;
+ vin-supply = <&pm8998_s3>;
+ };
+
+ camera_ldo: gpio-regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <0x2>;
+ regulator-name = "camera_ldo";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-enable-ramp-delay = <233>;
+ enable-active-high;
+ gpio = <&pm8998_gpios 9 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&camera_dvdd_en_default>;
+ vin-supply = <&pm8998_s3>;
+ };
+};
+
+&cci {
+ actuator_rear: qcom,actuator@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000>;
+ qcom,cam-vreg-max-voltage = <2800000>;
+ qcom,cam-vreg-op-mode = <0>;
+ };
+
+ actuator_front: qcom,actuator@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <1>;
+ cam_vaf-supply = <&actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000>;
+ qcom,cam-vreg-max-voltage = <2800000>;
+ qcom,cam-vreg-op-mode = <0>;
+ };
+
+ ois_rear: qcom,ois@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,ois";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000>;
+ qcom,cam-vreg-max-voltage = <2800000>;
+ qcom,cam-vreg-op-mode = <0>;
+ status = "disabled";
+ };
+
+ eeprom_rear: qcom,eeprom@0 {
+ cell-index = <0>;
+ reg = <0>;
+ compatible = "qcom,eeprom";
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ cam_vdig-supply = <&camera_rear_ldo>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 3312000 1050000>;
+ qcom,cam-vreg-max-voltage = <0 3600000 1050000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_active
+ &cam_sensor_rear_active>;
+ pinctrl-1 = <&cam_sensor_mclk0_suspend
+ &cam_sensor_rear_suspend>;
+ gpios = <&tlmm 13 0>,
+ <&tlmm 80 0>,
+ <&tlmm 79 0>,
+ <&tlmm 27 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-vaf = <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_VANA0",
+ "CAM_VAF";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+
+ eeprom_rear_aux: qcom,eeprom@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,eeprom";
+ cam_vdig-supply = <&camera_ldo>;
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-min-voltage = <1050000 0 3312000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 3600000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_active
+ &cam_sensor_rear2_active>;
+ pinctrl-1 = <&cam_sensor_mclk2_suspend
+ &cam_sensor_rear2_suspend>;
+ gpios = <&tlmm 15 0>,
+ <&tlmm 9 0>,
+ <&tlmm 8 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <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_VANA1";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK2_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+
+ eeprom_front: qcom,eeprom@2 {
+ cell-index = <2>;
+ reg = <0x2>;
+ compatible = "qcom,eeprom";
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ cam_vdig-supply = <&camera_ldo>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 3312000 1050000>;
+ qcom,cam-vreg-max-voltage = <0 3600000 1050000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_active
+ &cam_sensor_front_active>;
+ pinctrl-1 = <&cam_sensor_mclk1_suspend
+ &cam_sensor_front_suspend>;
+ gpios = <&tlmm 14 0>,
+ <&tlmm 28 0>,
+ <&tlmm 8 0>,
+ <&tlmm 27 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-vaf = <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_MCLK2",
+ "CAM_RESET2",
+ "CAM_VANA2",
+ "CAM_VAF";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK1_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+
+ qcom,cam-sensor@0 {
+ cell-index = <0>;
+ compatible = "qcom,cam-sensor";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,sensor-position-roll = <90>;
+ qcom,sensor-position-pitch = <0>;
+ qcom,sensor-position-yaw = <180>;
+ qcom,led-flash-src = <&led_flash_rear>;
+ qcom,actuator-src = <&actuator_rear>;
+ qcom,ois-src = <&ois_rear>;
+ qcom,eeprom-src = <&eeprom_rear>;
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ cam_vdig-supply = <&camera_rear_ldo>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 3312000 1050000>;
+ qcom,cam-vreg-max-voltage = <0 3600000 1050000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_active
+ &cam_sensor_rear_active>;
+ pinctrl-1 = <&cam_sensor_mclk0_suspend
+ &cam_sensor_rear_suspend>;
+ gpios = <&tlmm 13 0>,
+ <&tlmm 80 0>,
+ <&tlmm 79 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_VANA";
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+
+ qcom,cam-sensor@1 {
+ cell-index = <1>;
+ compatible = "qcom,cam-sensor";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,sensor-position-roll = <90>;
+ qcom,sensor-position-pitch = <0>;
+ qcom,sensor-position-yaw = <180>;
+ qcom,eeprom-src = <&eeprom_rear_aux>;
+ cam_vdig-supply = <&camera_ldo>;
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-min-voltage = <1050000 0 3312000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 3600000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_active
+ &cam_sensor_rear2_active>;
+ pinctrl-1 = <&cam_sensor_mclk2_suspend
+ &cam_sensor_rear2_suspend>;
+ gpios = <&tlmm 15 0>,
+ <&tlmm 9 0>,
+ <&tlmm 8 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <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_VANA1";
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK2_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+
+ qcom,cam-sensor@2 {
+ cell-index = <2>;
+ compatible = "qcom,cam-sensor";
+ reg = <0x02>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,sensor-position-roll = <90>;
+ qcom,sensor-position-pitch = <0>;
+ qcom,sensor-position-yaw = <0>;
+ qcom,eeprom-src = <&eeprom_front>;
+ qcom,actuator-src = <&actuator_front>;
+ qcom,led-flash-src = <&led_flash_front>;
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ cam_vdig-supply = <&camera_ldo>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 3312000 1050000>;
+ qcom,cam-vreg-max-voltage = <0 3600000 1050000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_active
+ &cam_sensor_front_active>;
+ pinctrl-1 = <&cam_sensor_mclk1_suspend
+ &cam_sensor_front_suspend>;
+ gpios = <&tlmm 14 0>,
+ <&tlmm 28 0>,
+ <&tlmm 8 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <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_VANA1";
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK1_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..fce1687
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-mtp.dtsi
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2016-2017, 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.
+ */
+
+&soc {
+ led_flash_rear: qcom,camera-flash@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-source = <&pmi8998_flash0 &pmi8998_flash1>;
+ qcom,torch-source = <&pmi8998_torch0 &pmi8998_torch1>;
+ qcom,switch-source = <&pmi8998_switch0>;
+ status = "ok";
+ };
+
+ led_flash_front: qcom,camera-flash@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-source = <&pmi8998_flash2>;
+ qcom,torch-source = <&pmi8998_torch2>;
+ qcom,switch-source = <&pmi8998_switch1>;
+ status = "ok";
+ };
+
+ actuator_regulator: gpio-regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0x0>;
+ regulator-name = "actuator_regulator";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <100>;
+ enable-active-high;
+ gpio = <&tlmm 27 0>;
+ vin-supply = <&pmi8998_bob>;
+ };
+
+ camera_rear_ldo: gpio-regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <0x1>;
+ regulator-name = "camera_rear_ldo";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-enable-ramp-delay = <135>;
+ enable-active-high;
+ gpio = <&pm8998_gpios 12 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&camera_rear_dvdd_en_default>;
+ vin-supply = <&pm8998_s3>;
+ };
+
+ camera_ldo: gpio-regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <0x2>;
+ regulator-name = "camera_ldo";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-enable-ramp-delay = <233>;
+ enable-active-high;
+ gpio = <&pm8998_gpios 9 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&camera_dvdd_en_default>;
+ vin-supply = <&pm8998_s3>;
+ };
+};
+
+&cci {
+ actuator_rear: qcom,actuator@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000>;
+ qcom,cam-vreg-max-voltage = <2800000>;
+ qcom,cam-vreg-op-mode = <0>;
+ };
+
+ actuator_front: qcom,actuator@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <1>;
+ cam_vaf-supply = <&actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000>;
+ qcom,cam-vreg-max-voltage = <2800000>;
+ qcom,cam-vreg-op-mode = <0>;
+ };
+
+ ois_rear: qcom,ois@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,ois";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000>;
+ qcom,cam-vreg-max-voltage = <2800000>;
+ qcom,cam-vreg-op-mode = <0>;
+ status = "disabled";
+ };
+
+ eeprom_rear: qcom,eeprom@0 {
+ cell-index = <0>;
+ reg = <0>;
+ compatible = "qcom,eeprom";
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ cam_vdig-supply = <&camera_rear_ldo>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 3312000 1050000>;
+ qcom,cam-vreg-max-voltage = <0 3600000 1050000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_active
+ &cam_sensor_rear_active>;
+ pinctrl-1 = <&cam_sensor_mclk0_suspend
+ &cam_sensor_rear_suspend>;
+ gpios = <&tlmm 13 0>,
+ <&tlmm 80 0>,
+ <&tlmm 79 0>,
+ <&tlmm 27 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-vaf = <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_VANA0",
+ "CAM_VAF";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+
+ eeprom_rear_aux: qcom,eeprom@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,eeprom";
+ cam_vdig-supply = <&camera_ldo>;
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-min-voltage = <1050000 0 3312000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 3600000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_active
+ &cam_sensor_rear2_active>;
+ pinctrl-1 = <&cam_sensor_mclk2_suspend
+ &cam_sensor_rear2_suspend>;
+ gpios = <&tlmm 15 0>,
+ <&tlmm 9 0>,
+ <&tlmm 8 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <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_VANA1";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK2_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+
+ eeprom_front: qcom,eeprom@2 {
+ cell-index = <2>;
+ reg = <0x2>;
+ compatible = "qcom,eeprom";
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ cam_vdig-supply = <&camera_ldo>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 3312000 1050000>;
+ qcom,cam-vreg-max-voltage = <0 3600000 1050000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_active
+ &cam_sensor_front_active>;
+ pinctrl-1 = <&cam_sensor_mclk1_suspend
+ &cam_sensor_front_suspend>;
+ gpios = <&tlmm 14 0>,
+ <&tlmm 28 0>,
+ <&tlmm 8 0>,
+ <&tlmm 27 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-vaf = <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_MCLK2",
+ "CAM_RESET2",
+ "CAM_VANA2",
+ "CAM_VAF";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK1_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+
+ qcom,cam-sensor@0 {
+ cell-index = <0>;
+ compatible = "qcom,cam-sensor";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,sensor-position-roll = <90>;
+ qcom,sensor-position-pitch = <0>;
+ qcom,sensor-position-yaw = <180>;
+ qcom,led-flash-src = <&led_flash_rear>;
+ qcom,actuator-src = <&actuator_rear>;
+ qcom,ois-src = <&ois_rear>;
+ qcom,eeprom-src = <&eeprom_rear>;
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ cam_vdig-supply = <&camera_rear_ldo>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 3312000 1050000>;
+ qcom,cam-vreg-max-voltage = <0 3600000 1050000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_active
+ &cam_sensor_rear_active>;
+ pinctrl-1 = <&cam_sensor_mclk0_suspend
+ &cam_sensor_rear_suspend>;
+ gpios = <&tlmm 13 0>,
+ <&tlmm 80 0>,
+ <&tlmm 79 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_VANA";
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+
+ qcom,cam-sensor@1 {
+ cell-index = <1>;
+ compatible = "qcom,cam-sensor";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,sensor-position-roll = <90>;
+ qcom,sensor-position-pitch = <0>;
+ qcom,sensor-position-yaw = <180>;
+ qcom,eeprom-src = <&eeprom_rear_aux>;
+ cam_vdig-supply = <&camera_ldo>;
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-min-voltage = <1050000 0 3312000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 3600000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_active
+ &cam_sensor_rear2_active>;
+ pinctrl-1 = <&cam_sensor_mclk2_suspend
+ &cam_sensor_rear2_suspend>;
+ gpios = <&tlmm 15 0>,
+ <&tlmm 9 0>,
+ <&tlmm 8 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <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_VANA1";
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK2_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+
+ qcom,cam-sensor@2 {
+ cell-index = <2>;
+ compatible = "qcom,cam-sensor";
+ reg = <0x02>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,sensor-position-roll = <90>;
+ qcom,sensor-position-pitch = <0>;
+ qcom,sensor-position-yaw = <0>;
+ qcom,eeprom-src = <&eeprom_front>;
+ qcom,actuator-src = <&actuator_front>;
+ qcom,led-flash-src = <&led_flash_front>;
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pmi8998_bob>;
+ cam_vdig-supply = <&camera_ldo>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 3312000 1050000>;
+ qcom,cam-vreg-max-voltage = <0 3600000 1050000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_active
+ &cam_sensor_front_active>;
+ pinctrl-1 = <&cam_sensor_mclk1_suspend
+ &cam_sensor_front_suspend>;
+ gpios = <&tlmm 14 0>,
+ <&tlmm 28 0>,
+ <&tlmm 8 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <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_VANA1";
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK1_CLK>;
+ clock-names = "cam_clk";
+ qcom,clock-rates = <24000000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
index c197d65..cd9c8a8 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
@@ -16,4 +16,213 @@
compatible = "qcom,cam-req-mgr";
status = "ok";
};
+
+ qcom,csiphy@ac65000 {
+ cell-index = <0>;
+ compatible = "qcom,csiphy-v1.0", "qcom,csiphy";
+ reg = <0x0ac65000 0x1000>;
+ reg-names = "csiphy";
+ interrupts = <0 477 0>;
+ interrupt-names = "csiphy";
+ gdscr-supply = <&titan_top_gdsc>;
+ qcom,cam-vreg-name = "gdscr";
+ qcom,csi-vdd-voltage = <1200000>;
+ qcom,mipi-csi-vdd-supply = <&pm8998_l26>;
+ clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSIPHY0_CLK>,
+ <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_CSID_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_CSID_CLK_SRC>;
+ clock-names = "camnoc_axi_clk",
+ "soc_ahb_clk",
+ "slow_ahb_src_clk",
+ "cpas_ahb_clk",
+ "cphy_rx_clk_src",
+ "csiphy0_clk",
+ "csi0phytimer_clk_src",
+ "csi0phytimer_clk",
+ "ife_0_csid_clk",
+ "ife_0_csid_clk_src";
+ qcom,clock-rates =
+ <0 0 80000000 0 320000000 0 269333333 0 0 384000000>;
+ status = "ok";
+ };
+
+ qcom,csiphy@ac66000{
+ cell-index = <1>;
+ compatible = "qcom,csiphy-v1.0", "qcom,csiphy";
+ reg = <0xac66000 0x1000>;
+ reg-names = "csiphy";
+ interrupts = <0 478 0>;
+ interrupt-names = "csiphy";
+ gdscr-supply = <&titan_top_gdsc>;
+ qcom,cam-vreg-name = "gdscr";
+ qcom,csi-vdd-voltage = <1200000>;
+ qcom,mipi-csi-vdd-supply = <&pm8998_l26>;
+ clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSIPHY1_CLK>,
+ <&clock_camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK>,
+ <&clock_camcc CAM_CC_IFE_1_CSID_CLK>,
+ <&clock_camcc CAM_CC_IFE_1_CSID_CLK_SRC>;
+ clock-names = "camnoc_axi_clk",
+ "soc_ahb_clk",
+ "slow_ahb_src_clk",
+ "cpas_ahb_clk",
+ "cphy_rx_clk_src",
+ "csiphy1_clk",
+ "csi1phytimer_clk_src",
+ "csi1phytimer_clk",
+ "ife_1_csid_clk",
+ "ife_1_csid_clk_src";
+ qcom,clock-rates =
+ <0 0 80000000 0 320000000 0 269333333 0 0 384000000>;
+
+ status = "ok";
+ };
+
+ qcom,csiphy@ac67000 {
+ cell-index = <2>;
+ compatible = "qcom,csiphy-v1.0", "qcom,csiphy";
+ reg = <0xac67000 0x1000>;
+ reg-names = "csiphy";
+ interrupts = <0 479 0>;
+ interrupt-names = "csiphy";
+ gdscr-supply = <&titan_top_gdsc>;
+ qcom,cam-vreg-name = "gdscr";
+ qcom,csi-vdd-voltage = <1200000>;
+ qcom,mipi-csi-vdd-supply = <&pm8998_l26>;
+ clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSIPHY2_CLK>,
+ <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK>,
+ <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK>,
+ <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>;
+ clock-names = "camnoc_axi_clk",
+ "soc_ahb_clk",
+ "slow_ahb_src_clk",
+ "cpas_ahb_clk",
+ "cphy_rx_clk_src",
+ "csiphy2_clk",
+ "csi2phytimer_clk_src",
+ "csi2phytimer_clk",
+ "ife_lite_csid_clk",
+ "ife_lite_csid_clk_src";
+ qcom,clock-rates =
+ <0 0 80000000 0 320000000 0 269333333 0 0 384000000>;
+ status = "ok";
+ };
+
+ cci: qcom,cci@ac4a000 {
+ cell-index = <0>;
+ compatible = "qcom,cci";
+ reg = <0xac4a000 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "cci";
+ interrupts = <0 460 0>;
+ interrupt-names = "cci";
+ status = "ok";
+ gdscr-supply = <&titan_top_gdsc>;
+ qcom,cam-vreg-name = "gdscr";
+ clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CCI_CLK>,
+ <&clock_camcc CAM_CC_CCI_CLK_SRC>;
+ clock-names = "camnoc_axi_clk",
+ "soc_ahb_clk",
+ "slow_ahb_src_clk",
+ "cpas_ahb_clk",
+ "cci_clk",
+ "cci_clk_src";
+ qcom,clock-rates = <0 0 80000000 0 0 37500000>;
+ pinctrl-names = "cci_default", "cci_suspend";
+ pinctrl-0 = <&cci0_active &cci1_active>;
+ pinctrl-1 = <&cci0_suspend &cci1_suspend>;
+ gpios = <&tlmm 17 0>,
+ <&tlmm 18 0>,
+ <&tlmm 19 0>,
+ <&tlmm 20 0>;
+ qcom,gpio-tbl-num = <0 1 2 3>;
+ qcom,gpio-tbl-flags = <1 1 1 1>;
+ qcom,gpio-tbl-label = "CCI_I2C_DATA0",
+ "CCI_I2C_CLK0",
+ "CCI_I2C_DATA1",
+ "CCI_I2C_CLK1";
+
+ i2c_freq_100Khz: qcom,i2c_standard_mode {
+ qcom,hw-thigh = <201>;
+ qcom,hw-tlow = <174>;
+ qcom,hw-tsu-sto = <204>;
+ qcom,hw-tsu-sta = <231>;
+ qcom,hw-thd-dat = <22>;
+ qcom,hw-thd-sta = <162>;
+ qcom,hw-tbuf = <227>;
+ qcom,hw-scl-stretch-en = <0>;
+ qcom,hw-trdhld = <6>;
+ qcom,hw-tsp = <3>;
+ qcom,cci-clk-src = <37500000>;
+ status = "ok";
+ };
+
+ i2c_freq_400Khz: qcom,i2c_fast_mode {
+ qcom,hw-thigh = <38>;
+ qcom,hw-tlow = <56>;
+ qcom,hw-tsu-sto = <40>;
+ qcom,hw-tsu-sta = <40>;
+ qcom,hw-thd-dat = <22>;
+ qcom,hw-thd-sta = <35>;
+ qcom,hw-tbuf = <62>;
+ qcom,hw-scl-stretch-en = <0>;
+ qcom,hw-trdhld = <6>;
+ qcom,hw-tsp = <3>;
+ qcom,cci-clk-src = <37500000>;
+ status = "ok";
+ };
+
+ i2c_freq_custom: qcom,i2c_custom_mode {
+ qcom,hw-thigh = <38>;
+ qcom,hw-tlow = <56>;
+ qcom,hw-tsu-sto = <40>;
+ qcom,hw-tsu-sta = <40>;
+ qcom,hw-thd-dat = <22>;
+ qcom,hw-thd-sta = <35>;
+ qcom,hw-tbuf = <62>;
+ qcom,hw-scl-stretch-en = <1>;
+ qcom,hw-trdhld = <6>;
+ qcom,hw-tsp = <3>;
+ qcom,cci-clk-src = <37500000>;
+ status = "ok";
+ };
+
+ i2c_freq_1Mhz: qcom,i2c_fast_plus_mode {
+ qcom,hw-thigh = <16>;
+ qcom,hw-tlow = <22>;
+ qcom,hw-tsu-sto = <17>;
+ qcom,hw-tsu-sta = <18>;
+ qcom,hw-thd-dat = <16>;
+ qcom,hw-thd-sta = <15>;
+ qcom,hw-tbuf = <24>;
+ qcom,hw-scl-stretch-en = <0>;
+ qcom,hw-trdhld = <3>;
+ qcom,hw-tsp = <3>;
+ qcom,cci-clk-src = <37500000>;
+ status = "ok";
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
index 7f9351d..96ce5a8 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
@@ -11,7 +11,7 @@
*/
#include <dt-bindings/gpio/gpio.h>
-
+#include "sdm845-camera-sensor-cdp.dtsi"
&soc {
sound-tavil {
qcom,us-euro-gpios = <&tavil_us_euro_sw>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
index f7da384..e36ccf2 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
@@ -11,7 +11,7 @@
*/
#include <dt-bindings/gpio/gpio.h>
-
+#include "sdm845-camera-sensor-mtp.dtsi"
&soc {
gpio_keys {
compatible = "gpio-keys";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
index a5ed9aa..bd09c7c 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
@@ -2285,6 +2285,231 @@
};
};
};
+
+ cci0_active: cci0_active {
+ mux {
+ /* CLK, DATA */
+ pins = "gpio17","gpio18"; // Only 2
+ function = "cci_i2c";
+ };
+
+ config {
+ pins = "gpio17","gpio18";
+ bias-pull-up; /* PULL UP*/
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cci0_suspend: cci0_suspend {
+ mux {
+ /* CLK, DATA */
+ pins = "gpio17","gpio18";
+ function = "cci_i2c";
+ };
+
+ config {
+ pins = "gpio17","gpio18";
+ bias-pull-down; /* PULL DOWN */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cci1_active: cci1_active {
+ mux {
+ /* CLK, DATA */
+ pins = "gpio19","gpio20";
+ function = "cci_i2c";
+ };
+
+ config {
+ pins = "gpio19","gpio20";
+ bias-pull-up; /* PULL UP*/
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cci1_suspend: cci1_suspend {
+ mux {
+ /* CLK, DATA */
+ pins = "gpio19","gpio20";
+ function = "cci_i2c";
+ };
+
+ config {
+ pins = "gpio19","gpio20";
+ bias-pull-down; /* PULL DOWN */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_mclk0_active: cam_sensor_mclk0_active {
+ /* MCLK0 */
+ mux {
+ pins = "gpio13";
+ function = "cam_mclk";
+ };
+
+ config {
+ pins = "gpio13";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend {
+ /* MCLK0 */
+ mux {
+ pins = "gpio13";
+ function = "cam_mclk";
+ };
+
+ config {
+ pins = "gpio13";
+ bias-pull-down; /* PULL DOWN */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear_active: cam_sensor_rear_active {
+ /* RESET, AVDD LDO */
+ mux {
+ pins = "gpio80","gpio79";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio80","gpio79";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear_suspend: cam_sensor_rear_suspend {
+ /* RESET, AVDD LDO */
+ mux {
+ pins = "gpio80","gpio79";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio80","gpio79";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_mclk1_active: cam_sensor_mclk1_active {
+ /* MCLK1 */
+ mux {
+ pins = "gpio14";
+ function = "cam_mclk";
+ };
+
+ config {
+ pins = "gpio14";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend {
+ /* MCLK1 */
+ mux {
+ pins = "gpio14";
+ function = "cam_mclk";
+ };
+
+ config {
+ pins = "gpio14";
+ bias-pull-down; /* PULL DOWN */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_front_active: cam_sensor_front_active {
+ /* RESET AVDD_LDO*/
+ mux {
+ pins = "gpio28", "gpio8";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio28", "gpio8";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_front_suspend: cam_sensor_front_suspend {
+ /* RESET */
+ mux {
+ pins = "gpio28";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio28";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_mclk2_active: cam_sensor_mclk2_active {
+ /* MCLK1 */
+ mux {
+ /* CLK, DATA */
+ pins = "gpio15";
+ function = "cam_mclk";
+ };
+
+ config {
+ pins = "gpio15";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend {
+ /* MCLK1 */
+ mux {
+ /* CLK, DATA */
+ pins = "gpio15";
+ function = "cam_mclk";
+ };
+
+ config {
+ pins = "gpio15";
+ bias-pull-down; /* PULL DOWN */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear2_active: cam_sensor_rear2_active {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio9","gpio8";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio9","gpio8";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear2_suspend: cam_sensor_rear2_suspend {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio9","gpio8";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio9","gpio8";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
};
};
@@ -2328,6 +2553,24 @@
power-source = <0>;
};
};
+
+ camera_dvdd_en {
+ camera_dvdd_en_default: camera_dvdd_en_default {
+ pins = "gpio9";
+ function = "normal";
+ power-source = <0>;
+ output-low;
+ };
+ };
+
+ camera_rear_dvdd_en {
+ camera_rear_dvdd_en_default: camera_rear_dvdd_en_default {
+ pins = "gpio12";
+ function = "normal";
+ power-source = <0>;
+ output-low;
+ };
+ };
};
&pmi8998_gpios {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-vidc.dtsi b/arch/arm64/boot/dts/qcom/sdm845-vidc.dtsi
index af88108..2d181a4 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-vidc.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-vidc.dtsi
@@ -17,11 +17,13 @@
&soc {
msm_vidc: qcom,vidc@aa00000 {
compatible = "qcom,msm-vidc";
- status = "disabled";
+ status = "ok";
reg = <0xaa00000 0x200000>;
interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
qcom,hfi = "venus";
qcom,firmware-name = "venus";
+ qcom,never-unload-fw;
+ qcom,sw-power-collapse;
qcom,max-secure-instances = <5>;
qcom,max-hw-load = <2563200>; /* Full 4k @ 60 + 1080p @ 60 */
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index f27f75b..259c5b7 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -1379,7 +1379,7 @@
compatible = "qcom,msm-watchdog";
reg = <0x17980000 0x1000>;
reg-names = "wdt-base";
- interrupts = <0 3 0>, <0 4 0>;
+ interrupts = <0 0 0>, <0 1 0>;
qcom,bark-time = <11000>;
qcom,pet-time = <10000>;
qcom,ipi-ping;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index ac777b0..c44a9ea 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -701,6 +701,11 @@
list_for_each_safe(start, temp, &driver->cmd_reg_list) {
item = list_entry(start, struct diag_cmd_reg_t, link);
+ if (item == NULL || &item->entry == NULL) {
+ pr_err("diag: In %s, unable to search command\n",
+ __func__);
+ return NULL;
+ }
temp_entry = &item->entry;
if (temp_entry->cmd_code == entry->cmd_code &&
temp_entry->subsys_id == entry->subsys_id &&
diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c
index 4f7c1e0..6685be3 100644
--- a/drivers/char/diag/diagfwd_peripheral.c
+++ b/drivers/char/diag/diagfwd_peripheral.c
@@ -983,8 +983,6 @@
}
if (fwd_info->buf_1 && !atomic_read(&fwd_info->buf_1->in_busy)) {
- temp_buf = fwd_info->buf_1;
- atomic_set(&temp_buf->in_busy, 1);
if (driver->feature[fwd_info->peripheral].encode_hdlc &&
(fwd_info->type == TYPE_DATA ||
fwd_info->type == TYPE_CMD)) {
@@ -994,9 +992,11 @@
read_buf = fwd_info->buf_1->data;
read_len = fwd_info->buf_1->len;
}
+ if (read_buf) {
+ temp_buf = fwd_info->buf_1;
+ atomic_set(&temp_buf->in_busy, 1);
+ }
} else if (fwd_info->buf_2 && !atomic_read(&fwd_info->buf_2->in_busy)) {
- temp_buf = fwd_info->buf_2;
- atomic_set(&temp_buf->in_busy, 1);
if (driver->feature[fwd_info->peripheral].encode_hdlc &&
(fwd_info->type == TYPE_DATA ||
fwd_info->type == TYPE_CMD)) {
@@ -1006,6 +1006,10 @@
read_buf = fwd_info->buf_2->data;
read_len = fwd_info->buf_2->len;
}
+ if (read_buf) {
+ temp_buf = fwd_info->buf_2;
+ atomic_set(&temp_buf->in_busy, 1);
+ }
} else {
pr_debug("diag: In %s, both buffers are empty for p: %d, t: %d\n",
__func__, fwd_info->peripheral, fwd_info->type);
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
index a68da4e..5b59828 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
@@ -135,8 +135,7 @@
phys_enc);
}
-static bool _sde_encoder_phys_is_ppsplit_slave(
- struct sde_encoder_phys *phys_enc)
+static bool _sde_encoder_phys_is_ppsplit(struct sde_encoder_phys *phys_enc)
{
enum sde_rm_topology_name topology;
@@ -144,8 +143,7 @@
return false;
topology = sde_connector_get_topology_name(phys_enc->connector);
- if (topology == SDE_RM_TOPOLOGY_PPSPLIT &&
- phys_enc->split_role == ENC_ROLE_SLAVE)
+ if (topology == SDE_RM_TOPOLOGY_PPSPLIT)
return true;
return false;
@@ -199,6 +197,16 @@
return -ETIMEDOUT;
}
+static bool _sde_encoder_phys_is_ppsplit_slave(
+ struct sde_encoder_phys *phys_enc)
+{
+ if (!phys_enc)
+ return false;
+
+ return _sde_encoder_phys_is_ppsplit(phys_enc) &&
+ phys_enc->split_role == ENC_ROLE_SLAVE;
+}
+
static int _sde_encoder_phys_cmd_wait_for_idle(
struct sde_encoder_phys *phys_enc)
{
@@ -463,13 +471,10 @@
static bool sde_encoder_phys_cmd_needs_single_flush(
struct sde_encoder_phys *phys_enc)
{
- enum sde_rm_topology_name topology;
-
if (!phys_enc)
return false;
- topology = sde_connector_get_topology_name(phys_enc->connector);
- return topology == SDE_RM_TOPOLOGY_PPSPLIT;
+ return _sde_encoder_phys_is_ppsplit(phys_enc);
}
static int sde_encoder_phys_cmd_control_vblank_irq(
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index d278389..944faa3 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -810,7 +810,7 @@
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct gmu_device *gmu = &device->gmu;
- if (!kgsl_gmu_isenabled(device))
+ if (!gmu->pdev)
return -EINVAL;
kgsl_gmu_regwrite(device, A6XX_GMU_GX_SPTPRAC_POWER_CONTROL,
@@ -837,7 +837,7 @@
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct gmu_device *gmu = &device->gmu;
- if (!kgsl_gmu_isenabled(device))
+ if (!gmu->pdev)
return;
kgsl_gmu_regwrite(device, A6XX_GMU_GX_SPTPRAC_POWER_CONTROL,
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 366d8c3..c807c28 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -1,7 +1,7 @@
/*
* Device tree based initialization code for reserved memory.
*
- * Copyright (c) 2013, 2015 The Linux Foundation. All Rights Reserved.
+ * Copyright (c) 2013, 2015, 2017 The Linux Foundation. All Rights Reserved.
* Copyright (c) 2013,2014 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* Author: Marek Szyprowski <m.szyprowski@samsung.com>
@@ -25,7 +25,7 @@
#include <linux/sort.h>
#include <linux/slab.h>
-#define MAX_RESERVED_REGIONS 16
+#define MAX_RESERVED_REGIONS 32
static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
static int reserved_mem_count;
diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig
index 54a9cb2..3a6e214 100644
--- a/drivers/platform/msm/Kconfig
+++ b/drivers/platform/msm/Kconfig
@@ -144,4 +144,12 @@
If you choose to build it as a module, it will be called
msm_11ad_proxy.
+config SEEMP_CORE
+ tristate "SEEMP Core"
+ help
+ This option enables QTI Snapdragron Smart Protection to detect
+ anomalies in various activities. It records task activities in
+ a log and rates the actions according to whether a typical user would
+ use the tools.
+
endmenu
diff --git a/drivers/platform/msm/Makefile b/drivers/platform/msm/Makefile
index 0bf87f4..cf24d7a 100644
--- a/drivers/platform/msm/Makefile
+++ b/drivers/platform/msm/Makefile
@@ -9,4 +9,5 @@
obj-$(CONFIG_QPNP_REVID) += qpnp-revid.o
obj-$(CONFIG_MSM_MHI_DEV) += mhi_dev/
obj-$(CONFIG_USB_BAM) += usb_bam.o
-obj-$(CONFIG_MSM_11AD) += msm_11ad/
\ No newline at end of file
+obj-$(CONFIG_MSM_11AD) += msm_11ad/
+obj-$(CONFIG_SEEMP_CORE) += seemp_core/
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 82c71353b..db3d6a4 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -4163,6 +4163,7 @@
/* queue a work to start polling if don't have one */
atomic_set(&ipa3_ctx->transport_pm.eot_activity, 1);
if (!atomic_read(&ep->sys->curr_polling_state)) {
+ ipa3_inc_acquire_wakelock();
atomic_set(&ep->sys->curr_polling_state, 1);
queue_work(ep->sys->wq, &ep->sys->work);
}
diff --git a/drivers/platform/msm/seemp_core/Makefile b/drivers/platform/msm/seemp_core/Makefile
new file mode 100644
index 0000000..a26db43
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/Makefile
@@ -0,0 +1,3 @@
+ccflags-y += -Iinclude/linux
+obj-$(CONFIG_SEEMP_CORE) += seemp_core.o
+seemp_core-objs:= seemp_logk.o seemp_ringbuf.o seemp_event_encoder.o
\ No newline at end of file
diff --git a/drivers/platform/msm/seemp_core/seemp_event_encoder.c b/drivers/platform/msm/seemp_core/seemp_event_encoder.c
new file mode 100644
index 0000000..6d9aa81
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_event_encoder.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ */
+
+#include <linux/seemp_param_id.h>
+#include "seemp_logk.h"
+#include "seemp_event_encoder.h"
+
+static char *scan_id(char *s);
+static void encode_seemp_section(char *section_start, char *section_eq,
+ char *section_end, bool param, bool numeric,
+ int id, __s32 numeric_value);
+
+static void check_param_range(char *section_eq, bool param,
+ bool *numeric, int val_len, __s32 *numeric_value)
+{
+ long long_value = 0;
+
+ if (param && *numeric) {
+ /*check if 2 bytes & in[-99999,999999]*/
+ *numeric = (val_len >= 2) && (val_len <= 6);
+ if (*numeric) {
+ if (kstrtol(section_eq + 1, 10, &long_value)
+ != 0) {
+ *numeric = false;
+ } else {
+ *numeric_value = (__s32)long_value;
+ /* We are checking whether the value
+ * lies within 16bits
+ */
+ *numeric = (long_value >= -32768) &&
+ (long_value <= 32767);
+ }
+ }
+ }
+}
+
+void encode_seemp_params(struct seemp_logk_blk *blk)
+{
+ struct seemp_logk_blk tmp;
+ char *s = 0;
+ char *msg_section_start = 0;
+ char *msg_section_eq = 0;
+ char *msg_s = 0;
+
+ memcpy(tmp.payload.msg, blk->payload.msg, BLK_MAX_MSG_SZ);
+ s = tmp.payload.msg + 1;
+ tmp.payload.msg[BLK_MAX_MSG_SZ - 1] = 0; /* zero-terminate */
+
+ while (true) {
+ char *section_start = s;
+ char *section_eq = scan_id(s);
+ bool param = (section_eq - section_start >= 2) &&
+ (*section_eq == '=') && (section_eq[1] != ' ');
+ bool numeric = false;
+ int id = -1;
+ __s32 numeric_value = 0;
+ int id_len;
+ int val_len;
+ char ch;
+
+ if (param) {
+ id = param_id_index(section_start, section_eq);
+
+ if (id < 0)
+ param = false;
+ }
+
+ if (!param) {
+ s = section_eq;
+ while ((*s != 0) && (*s != ','))
+ s++;
+ } else {
+ s = section_eq + 1; /* equal sign */
+ numeric = (*s == '-') || ((*s >= '0') && (*s <= '9'));
+
+ if (numeric)
+ s++; /* first char of number */
+
+ while ((*s != 0) && (*s != ',')) {
+ if (*s == '=')
+ param = false;
+ else if (!((*s >= '0') && (*s <= '9')))
+ numeric = false;
+
+ s++;
+ }
+
+ if (param) {
+ id_len = section_eq - section_start;
+ val_len = s - (section_eq + 1);
+ param = (id_len >= 2) && (id_len <= 31)
+ && (val_len <= 31);
+ ch = *s;
+ *s = 0;
+
+ check_param_range(section_eq, param,
+ &numeric, val_len, &numeric_value);
+ *s = ch;
+ }
+ }
+
+ msg_section_start = blk->payload.msg + (section_start -
+ tmp.payload.msg);
+ msg_section_eq = blk->payload.msg + (section_eq -
+ tmp.payload.msg);
+ msg_s = blk->payload.msg + (s - tmp.payload.msg);
+ encode_seemp_section(msg_section_start, msg_section_eq,
+ msg_s, param, numeric, id, numeric_value);
+
+ if (*s == 0)
+ break;
+
+ s++;
+ }
+
+ blk->len = s - blk->payload.msg;
+}
+
+static char *scan_id(char *s)
+{
+ while ((*s == '_') ||
+ ((*s >= 'A') && (*s <= 'Z')) ||
+ ((*s >= 'a') && (*s <= 'z'))) {
+ s++;
+ }
+
+ return s;
+}
+
+static void encode_seemp_section(char *section_start, char *section_eq,
+ char *section_end, bool param, bool numeric,
+ int id, __s32 numeric_value) {
+ param = param && (section_eq + 1 < section_end);
+
+ if (!param) {
+ /* Encode skip section */
+ int skip_len = section_end - section_start;
+ char skip_len_hi = skip_len & 0xE0;
+ char skip_len_lo = skip_len & 0x1F;
+
+ if (skip_len < 32) {
+ section_start[-1] = 0xC0 | skip_len_lo;
+ /* [1:1:0:0 0000] */
+ } else {
+ section_start[-1] = 0xE0 | skip_len_lo;
+ /* [1:1:1:0 0000] */
+
+ if (skip_len_hi & 0x20)
+ section_start[0] |= 0x80;
+
+ if (skip_len_hi & 0x40)
+ section_start[1] |= 0x80;
+
+ if (skip_len_hi & 0x80)
+ section_start[2] |= 0x80;
+ }
+ } else {
+ /* Encode ID=VALUE section */
+ char id_len = section_eq - section_start;
+ char value_len = section_end - (section_eq + 1);
+
+ section_start[-1] = 0x00 | id_len;
+ *(__s16 *)section_start = id;
+ section_eq[0] = (!numeric ? 0x80 : 0x00) | value_len;
+
+ if (numeric)
+ *(__s16 *)(section_eq + 1) = numeric_value;
+ }
+}
diff --git a/drivers/platform/msm/seemp_core/seemp_event_encoder.h b/drivers/platform/msm/seemp_core/seemp_event_encoder.h
new file mode 100644
index 0000000..7cb7274
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_event_encoder.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ */
+
+#ifndef __SEEMP_EVENT_ENCODER_H__
+#define __SEEMP_EVENT_ENCODER_H__
+
+#include "seemp_logk.h"
+
+void encode_seemp_params(struct seemp_logk_blk *blk);
+
+#endif /* __SEEMP_EVENT_ENCODER_H__ */
diff --git a/drivers/platform/msm/seemp_core/seemp_logk.c b/drivers/platform/msm/seemp_core/seemp_logk.c
new file mode 100644
index 0000000..ce073ed
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_logk.c
@@ -0,0 +1,688 @@
+/*
+ * Copyright (c) 2014-2015, 2017, 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.
+ */
+
+#define pr_fmt(fmt) "seemp: %s: " fmt, __func__
+
+#include "seemp_logk.h"
+#include "seemp_ringbuf.h"
+
+#ifndef VM_RESERVED
+#define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
+#endif
+
+#define MASK_BUFFER_SIZE 256
+#define FOUR_MB 4
+#define YEAR_BASE 1900
+
+static struct seemp_logk_dev *slogk_dev;
+
+static unsigned int ring_sz = FOUR_MB;
+
+/*
+ * default is besteffort, apps do not get blocked
+ */
+static unsigned int block_apps;
+
+
+/*
+ * When this flag is turned on,
+ * kmalloc should be used for ring buf allocation
+ * otherwise it is vmalloc.
+ * default is to use vmalloc
+ * kmalloc has a limit of 4MB
+ */
+unsigned int kmalloc_flag;
+
+static struct class *cl;
+
+static rwlock_t filter_lock;
+static struct seemp_source_mask *pmask;
+static unsigned int num_sources;
+
+static long seemp_logk_reserve_rdblks(
+ struct seemp_logk_dev *sdev, unsigned long arg);
+static long seemp_logk_set_mask(unsigned long arg);
+static long seemp_logk_set_mapping(unsigned long arg);
+static long seemp_logk_check_filter(unsigned long arg);
+
+void* (*seemp_logk_kernel_begin)(char **buf);
+
+void (*seemp_logk_kernel_end)(void *blck);
+
+/*
+ * the last param is the permission bits *
+ * kernel logging is done in three steps:
+ * (1) fetch a block, fill everything except payload.
+ * (2) return payload pointer to the caller.
+ * (3) caller fills its data directly into the payload area.
+ * (4) caller invoked finish_record(), to finish writing.
+ */
+void *seemp_logk_kernel_start_record(char **buf)
+{
+ struct seemp_logk_blk *blk;
+ struct timespec now;
+ struct tm ts;
+ int idx;
+ int ret;
+
+ DEFINE_WAIT(write_wait);
+
+ ret = 0;
+ idx = 0;
+ now = current_kernel_time();
+ blk = ringbuf_fetch_wr_block(slogk_dev);
+ if (!blk) {
+ /*
+ * there is no blk to write
+ * if block_apps == 0; quietly return
+ */
+ if (!block_apps) {
+ *buf = NULL;
+ return NULL;
+ }
+ /*else wait for the blks to be available*/
+ while (1) {
+ mutex_lock(&slogk_dev->lock);
+ prepare_to_wait(&slogk_dev->writers_wq,
+ &write_wait, TASK_INTERRUPTIBLE);
+ ret = (slogk_dev->num_write_avail_blks <= 0);
+ if (!ret) {
+ /* don't have to wait*/
+ break;
+ }
+ mutex_unlock(&slogk_dev->lock);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ break;
+ }
+ schedule();
+ }
+
+ finish_wait(&slogk_dev->writers_wq, &write_wait);
+ if (ret)
+ return NULL;
+
+ idx = slogk_dev->write_idx;
+ slogk_dev->write_idx =
+ (slogk_dev->write_idx + 1) % slogk_dev->num_tot_blks;
+ slogk_dev->num_write_avail_blks--;
+ slogk_dev->num_write_in_prog_blks++;
+ slogk_dev->num_writers++;
+
+ blk = &slogk_dev->ring[idx];
+ /*mark block invalid*/
+ blk->status = 0x0;
+ mutex_unlock(&slogk_dev->lock);
+ }
+
+ blk->version = OBSERVER_VERSION;
+ blk->pid = current->tgid;
+ blk->tid = current->pid;
+ blk->uid = (current_uid()).val;
+ blk->sec = now.tv_sec;
+ blk->nsec = now.tv_nsec;
+ strlcpy(blk->appname, current->comm, TASK_COMM_LEN);
+ time_to_tm(now.tv_sec, 0, &ts);
+ ts.tm_year += YEAR_BASE;
+ ts.tm_mon += 1;
+
+ snprintf(blk->ts, TS_SIZE, "%04ld-%02d-%02d %02d:%02d:%02d",
+ ts.tm_year, ts.tm_mon, ts.tm_mday,
+ ts.tm_hour, ts.tm_min, ts.tm_sec);
+
+ *buf = blk->payload.msg;
+
+ return blk;
+}
+
+void seemp_logk_kernel_end_record(void *blck)
+{
+ struct seemp_logk_blk *blk = (struct seemp_logk_blk *)blck;
+
+ if (blk) {
+ /*update status at the very end*/
+ blk->status |= 0x1;
+ blk->uid = (current_uid()).val;
+
+ ringbuf_finish_writer(slogk_dev, blk);
+ }
+}
+
+static int seemp_logk_usr_record(const char __user *buf, size_t count)
+{
+ struct seemp_logk_blk *blk;
+ struct seemp_logk_blk usr_blk;
+ struct seemp_logk_blk *local_blk;
+ struct timespec now;
+ struct tm ts;
+ int idx, ret;
+
+ DEFINE_WAIT(write_wait);
+
+ if (buf) {
+ local_blk = (struct seemp_logk_blk *)buf;
+ if (copy_from_user(&usr_blk.pid, &local_blk->pid,
+ sizeof(usr_blk.pid)) != 0)
+ return -EFAULT;
+ if (copy_from_user(&usr_blk.tid, &local_blk->tid,
+ sizeof(usr_blk.tid)) != 0)
+ return -EFAULT;
+ if (copy_from_user(&usr_blk.uid, &local_blk->uid,
+ sizeof(usr_blk.uid)) != 0)
+ return -EFAULT;
+ if (copy_from_user(&usr_blk.len, &local_blk->len,
+ sizeof(usr_blk.len)) != 0)
+ return -EFAULT;
+ if (copy_from_user(&usr_blk.payload, &local_blk->payload,
+ sizeof(struct blk_payload)) != 0)
+ return -EFAULT;
+ } else {
+ return -EFAULT;
+ }
+ idx = ret = 0;
+ now = current_kernel_time();
+ blk = ringbuf_fetch_wr_block(slogk_dev);
+ if (!blk) {
+ if (!block_apps)
+ return 0;
+ while (1) {
+ mutex_lock(&slogk_dev->lock);
+ prepare_to_wait(&slogk_dev->writers_wq,
+ &write_wait,
+ TASK_INTERRUPTIBLE);
+ ret = (slogk_dev->num_write_avail_blks <= 0);
+ if (!ret)
+ break;
+ mutex_unlock(&slogk_dev->lock);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ break;
+ }
+ schedule();
+ }
+ finish_wait(&slogk_dev->writers_wq, &write_wait);
+ if (ret)
+ return -EINTR;
+
+ idx = slogk_dev->write_idx;
+ slogk_dev->write_idx =
+ (slogk_dev->write_idx + 1) % slogk_dev->num_tot_blks;
+ slogk_dev->num_write_avail_blks--;
+ slogk_dev->num_write_in_prog_blks++;
+ slogk_dev->num_writers++;
+ blk = &slogk_dev->ring[idx];
+ /*mark block invalid*/
+ blk->status = 0x0;
+ mutex_unlock(&slogk_dev->lock);
+ }
+ if (usr_blk.len > sizeof(struct blk_payload)-1)
+ usr_blk.len = sizeof(struct blk_payload)-1;
+
+ memcpy(&blk->payload, &usr_blk.payload, sizeof(struct blk_payload));
+ blk->pid = usr_blk.pid;
+ blk->uid = usr_blk.uid;
+ blk->tid = usr_blk.tid;
+ blk->sec = now.tv_sec;
+ blk->nsec = now.tv_nsec;
+ time_to_tm(now.tv_sec, 0, &ts);
+ ts.tm_year += YEAR_BASE;
+ ts.tm_mon += 1;
+ snprintf(blk->ts, TS_SIZE, "%02ld-%02d-%02d %02d:%02d:%02d",
+ ts.tm_year, ts.tm_mon, ts.tm_mday,
+ ts.tm_hour, ts.tm_min, ts.tm_sec);
+ strlcpy(blk->appname, current->comm, TASK_COMM_LEN);
+ blk->status |= 0x1;
+ ringbuf_finish_writer(slogk_dev, blk);
+ return ret;
+}
+
+static void seemp_logk_attach(void)
+{
+ seemp_logk_kernel_end = seemp_logk_kernel_end_record;
+ seemp_logk_kernel_begin = seemp_logk_kernel_start_record;
+}
+
+static void seemp_logk_detach(void)
+{
+ seemp_logk_kernel_begin = NULL;
+ seemp_logk_kernel_end = NULL;
+}
+
+static ssize_t
+seemp_logk_write(struct file *file, const char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ return seemp_logk_usr_record(buf, count);
+}
+
+static int
+seemp_logk_open(struct inode *inode, struct file *filp)
+{
+ int ret;
+
+ /*disallow seeks on this file*/
+ ret = nonseekable_open(inode, filp);
+ if (ret) {
+ pr_err("ret= %d\n", ret);
+ return ret;
+ }
+
+ slogk_dev->minor = iminor(inode);
+ filp->private_data = slogk_dev;
+
+ return 0;
+}
+
+static bool seemp_logk_get_bit_from_vector(__u8 *pVec, __u32 index)
+{
+ unsigned int byte_num = index/8;
+ unsigned int bit_num = index%8;
+ unsigned char byte;
+
+ if (DIV_ROUND_UP(index, 8) > MASK_BUFFER_SIZE)
+ return false;
+
+ byte = pVec[byte_num];
+
+ return !(byte & (1 << bit_num));
+}
+
+static long seemp_logk_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct seemp_logk_dev *sdev;
+ int ret;
+
+ sdev = (struct seemp_logk_dev *) filp->private_data;
+
+ if (cmd == SEEMP_CMD_RESERVE_RDBLKS) {
+ return seemp_logk_reserve_rdblks(sdev, arg);
+ } else if (cmd == SEEMP_CMD_RELEASE_RDBLKS) {
+ mutex_lock(&sdev->lock);
+ sdev->read_idx = (sdev->read_idx + sdev->num_read_in_prog_blks)
+ % sdev->num_tot_blks;
+ sdev->num_write_avail_blks += sdev->num_read_in_prog_blks;
+ ret = sdev->num_read_in_prog_blks;
+ sdev->num_read_in_prog_blks = 0;
+ /*wake up any waiting writers*/
+ mutex_unlock(&sdev->lock);
+ if (ret && block_apps)
+ wake_up_interruptible(&sdev->writers_wq);
+ } else if (cmd == SEEMP_CMD_GET_RINGSZ) {
+ if (copy_to_user((unsigned int *)arg, &sdev->ring_sz,
+ sizeof(unsigned int)))
+ return -EFAULT;
+ } else if (cmd == SEEMP_CMD_GET_BLKSZ) {
+ if (copy_to_user((unsigned int *)arg, &sdev->blk_sz,
+ sizeof(unsigned int)))
+ return -EFAULT;
+ } else if (cmd == SEEMP_CMD_SET_MASK) {
+ return seemp_logk_set_mask(arg);
+ } else if (cmd == SEEMP_CMD_SET_MAPPING) {
+ return seemp_logk_set_mapping(arg);
+ } else if (cmd == SEEMP_CMD_CHECK_FILTER) {
+ return seemp_logk_check_filter(arg);
+ }
+ pr_err("Invalid Request %X\n", cmd);
+ return -ENOIOCTLCMD;
+}
+
+static long seemp_logk_reserve_rdblks(
+ struct seemp_logk_dev *sdev, unsigned long arg)
+{
+ int ret;
+ struct read_range rrange;
+
+ DEFINE_WAIT(read_wait);
+
+ mutex_lock(&sdev->lock);
+ if (sdev->num_writers > 0 || sdev->num_read_avail_blks <= 0) {
+ ret = -EPERM;
+ pr_debug("(reserve): blocking, cannot read.\n");
+ pr_debug("num_writers=%d num_read_avail_blks=%d\n",
+ sdev->num_writers,
+ sdev->num_read_avail_blks);
+ mutex_unlock(&sdev->lock);
+ /*
+ * unlock the device
+ * wait on a wait queue
+ * after wait, grab the dev lock again
+ */
+ while (1) {
+ mutex_lock(&sdev->lock);
+ prepare_to_wait(&sdev->readers_wq, &read_wait,
+ TASK_INTERRUPTIBLE);
+ ret = (sdev->num_writers > 0 ||
+ sdev->num_read_avail_blks <= 0);
+ if (!ret) {
+ /*don't have to wait*/
+ break;
+ }
+ mutex_unlock(&sdev->lock);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ break;
+ }
+ schedule();
+ }
+
+ finish_wait(&sdev->readers_wq, &read_wait);
+ if (ret)
+ return -EINTR;
+ }
+
+ /*sdev->lock is held at this point*/
+ sdev->num_read_in_prog_blks = sdev->num_read_avail_blks;
+ sdev->num_read_avail_blks = 0;
+ rrange.start_idx = sdev->read_idx;
+ rrange.num = sdev->num_read_in_prog_blks;
+ mutex_unlock(&sdev->lock);
+
+ if (copy_to_user((unsigned int *)arg, &rrange,
+ sizeof(struct read_range)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static long seemp_logk_set_mask(unsigned long arg)
+{
+ __u8 buffer[256];
+ int i;
+ unsigned int num_elements;
+
+ if (copy_from_user(&num_elements,
+ (unsigned int __user *) arg, sizeof(unsigned int)))
+ return -EFAULT;
+
+ read_lock(&filter_lock);
+ if (num_sources == 0) {
+ read_unlock(&filter_lock);
+ return -EINVAL;
+ }
+
+ if (num_elements == 0 ||
+ DIV_ROUND_UP(num_sources, 8) > MASK_BUFFER_SIZE) {
+ read_unlock(&filter_lock);
+ return -EINVAL;
+ }
+
+ if (copy_from_user(buffer,
+ (__u8 *)arg, DIV_ROUND_UP(num_sources, 8))) {
+ read_unlock(&filter_lock);
+ return -EFAULT;
+ }
+
+ read_unlock(&filter_lock);
+ write_lock(&filter_lock);
+ if (num_elements != num_sources) {
+ write_unlock(&filter_lock);
+ return -EPERM;
+ }
+
+ for (i = 0; i < num_sources; i++) {
+ pmask[i].isOn =
+ seemp_logk_get_bit_from_vector(
+ (__u8 *)buffer, i);
+ }
+ write_unlock(&filter_lock);
+ return 0;
+}
+
+static long seemp_logk_set_mapping(unsigned long arg)
+{
+ __u32 num_elements;
+ __u32 *pbuffer;
+ int i;
+ struct seemp_source_mask *pnewmask;
+
+ if (copy_from_user(&num_elements,
+ (__u32 __user *)arg, sizeof(__u32)))
+ return -EFAULT;
+
+ if ((num_elements == 0) || (num_elements >
+ (UINT_MAX / sizeof(struct seemp_source_mask))))
+ return -EFAULT;
+
+ write_lock(&filter_lock);
+ if (pmask != NULL) {
+ /*
+ * Mask is getting set again.
+ * seemp_core was probably restarted.
+ */
+ struct seemp_source_mask *ptempmask;
+
+ num_sources = 0;
+ ptempmask = pmask;
+ pmask = NULL;
+ kfree(ptempmask);
+ }
+ write_unlock(&filter_lock);
+ pbuffer = kmalloc(sizeof(struct seemp_source_mask)
+ * num_elements, GFP_KERNEL);
+ if (pbuffer == NULL)
+ return -ENOMEM;
+
+ /*
+ * Use our new table as scratch space for now.
+ * We copy an ordered list of hash values into our buffer.
+ */
+ if (copy_from_user(pbuffer, &((__u32 __user *)arg)[1],
+ num_elements*sizeof(unsigned int))) {
+ kfree(pbuffer);
+ return -EFAULT;
+ }
+ /*
+ * We arrange the user data into a more usable form.
+ * This is done in-place.
+ */
+ pnewmask = (struct seemp_source_mask *) pbuffer;
+ for (i = num_elements - 1; i >= 0; i--) {
+ pnewmask[i].hash = pbuffer[i];
+ /* Observer is off by default*/
+ pnewmask[i].isOn = 0;
+ }
+ write_lock(&filter_lock);
+ pmask = pnewmask;
+ num_sources = num_elements;
+ write_unlock(&filter_lock);
+ return 0;
+}
+
+static long seemp_logk_check_filter(unsigned long arg)
+{
+ int i;
+ unsigned int hash = (unsigned int) arg;
+
+ /*
+ * This lock may be a bit long.
+ * If it is a problem, it can be fixed.
+ */
+ read_lock(&filter_lock);
+ for (i = 0; i < num_sources; i++) {
+ if (hash == pmask[i].hash) {
+ int result = pmask[i].isOn;
+
+ read_unlock(&filter_lock);
+ return result;
+ }
+ }
+ read_unlock(&filter_lock);
+ return 0;
+}
+
+static int seemp_logk_mmap(struct file *filp,
+ struct vm_area_struct *vma)
+{
+ int ret;
+ char *vptr;
+ unsigned long length, pfn;
+ unsigned long start = vma->vm_start;
+
+ length = vma->vm_end - vma->vm_start;
+
+ if (length > (unsigned long) slogk_dev->ring_sz) {
+ pr_err("len check failed\n");
+ return -EIO;
+ }
+
+ vma->vm_flags |= VM_RESERVED | VM_SHARED;
+ vptr = (char *) slogk_dev->ring;
+ ret = 0;
+
+ if (kmalloc_flag) {
+ ret = remap_pfn_range(vma,
+ start,
+ virt_to_phys((void *)
+ ((unsigned long)slogk_dev->ring)) >> PAGE_SHIFT,
+ length,
+ vma->vm_page_prot);
+ if (ret != 0) {
+ pr_err("remap_pfn_range() fails with ret = %d\n",
+ ret);
+ return -EAGAIN;
+ }
+ } else {
+ while (length > 0) {
+ pfn = vmalloc_to_pfn(vptr);
+
+ ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE,
+ vma->vm_page_prot);
+ if (ret < 0) {
+ pr_err("remap_pfn_range() fails with ret = %d\n",
+ ret);
+ return ret;
+ }
+ start += PAGE_SIZE;
+ vptr += PAGE_SIZE;
+ length -= PAGE_SIZE;
+ }
+ }
+
+ return 0;
+}
+
+static const struct file_operations seemp_logk_fops = {
+ .write = seemp_logk_write,
+ .open = seemp_logk_open,
+ .unlocked_ioctl = seemp_logk_ioctl,
+ .compat_ioctl = seemp_logk_ioctl,
+ .mmap = seemp_logk_mmap,
+};
+
+__init int seemp_logk_init(void)
+{
+ int ret;
+ int devno = 0;
+
+ num_sources = 0;
+ kmalloc_flag = 0;
+ block_apps = 0;
+ pmask = NULL;
+
+ if (kmalloc_flag && ring_sz > FOUR_MB) {
+ pr_err("kmalloc cannot allocate > 4MB\n");
+ return -ENOMEM;
+ }
+
+ ring_sz = ring_sz * SZ_1M;
+ if (ring_sz <= 0) {
+ pr_err("Too small a ring_sz=%d\n", ring_sz);
+ return -EINVAL;
+ }
+
+ slogk_dev = kmalloc(sizeof(*slogk_dev), GFP_KERNEL);
+ if (slogk_dev == NULL)
+ return -ENOMEM;
+
+ slogk_dev->ring_sz = ring_sz;
+ slogk_dev->blk_sz = sizeof(struct seemp_logk_blk);
+ /*initialize ping-pong buffers*/
+ ret = ringbuf_init(slogk_dev);
+ if (ret < 0) {
+ pr_err("Init Failed, ret = %d\n", ret);
+ goto pingpong_fail;
+ }
+
+ ret = alloc_chrdev_region(&devno, 0, seemp_LOGK_NUM_DEVS,
+ seemp_LOGK_DEV_NAME);
+ if (ret < 0) {
+ pr_err("alloc_chrdev_region failed with ret = %d\n",
+ ret);
+ goto register_fail;
+ }
+
+ slogk_dev->major = MAJOR(devno);
+
+ pr_debug("logk: major# = %d\n", slogk_dev->major);
+
+ cl = class_create(THIS_MODULE, seemp_LOGK_DEV_NAME);
+ if (cl == NULL) {
+ pr_err("class create failed");
+ goto cdev_fail;
+ }
+ if (device_create(cl, NULL, devno, NULL,
+ seemp_LOGK_DEV_NAME) == NULL) {
+ pr_err("device create failed");
+ goto class_destroy_fail;
+ }
+ cdev_init(&(slogk_dev->cdev), &seemp_logk_fops);
+
+ slogk_dev->cdev.owner = THIS_MODULE;
+ ret = cdev_add(&(slogk_dev->cdev), MKDEV(slogk_dev->major, 0), 1);
+ if (ret) {
+ pr_err("cdev_add failed with ret = %d", ret);
+ goto class_destroy_fail;
+ }
+
+ seemp_logk_attach();
+ mutex_init(&slogk_dev->lock);
+ init_waitqueue_head(&slogk_dev->readers_wq);
+ init_waitqueue_head(&slogk_dev->writers_wq);
+ rwlock_init(&filter_lock);
+ return 0;
+class_destroy_fail:
+ class_destroy(cl);
+cdev_fail:
+ unregister_chrdev_region(devno, seemp_LOGK_NUM_DEVS);
+register_fail:
+ ringbuf_cleanup(slogk_dev);
+pingpong_fail:
+ kfree(slogk_dev);
+ return -EPERM;
+}
+
+__exit void seemp_logk_cleanup(void)
+{
+ dev_t devno = MKDEV(slogk_dev->major, slogk_dev->minor);
+
+ seemp_logk_detach();
+
+ cdev_del(&slogk_dev->cdev);
+
+ unregister_chrdev_region(devno, seemp_LOGK_NUM_DEVS);
+ ringbuf_cleanup(slogk_dev);
+ kfree(slogk_dev);
+
+ if (pmask != NULL) {
+ kfree(pmask);
+ pmask = NULL;
+ }
+}
+
+module_init(seemp_logk_init);
+module_exit(seemp_logk_cleanup);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("seemp Observer");
+
diff --git a/drivers/platform/msm/seemp_core/seemp_logk.h b/drivers/platform/msm/seemp_core/seemp_logk.h
new file mode 100644
index 0000000..1a41d4c
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_logk.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2014-2015, 2017, 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.
+ */
+
+#ifndef __SEEMP_LOGK_H__
+#define __SEEMP_LOGK_H__
+
+#define OBSERVER_VERSION 0x01
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+#include <linux/vmalloc.h>
+#include <asm/ioctls.h>
+
+#define seemp_LOGK_NUM_DEVS 1
+#define seemp_LOGK_DEV_NAME "seemplog"
+
+/*
+ * The logcat driver on Android uses four 256k ring buffers
+ * here, we use two ring buffers of the same size.
+ * we think this is reasonable
+ */
+#define FULL_BUF_SIZE (64 * 1024 * 1024)
+#define HALF_BUF_SIZE (32 * 1024 * 1024)
+#define FULL_BLOCKS (8 * 1024)
+#define HALF_BLOCKS (4 * 1024)
+
+#define READER_NOT_READY 0
+#define READER_READY 1
+
+#define MAGIC 'z'
+
+#define SEEMP_CMD_RESERVE_RDBLKS _IOR(MAGIC, 1, int)
+#define SEEMP_CMD_RELEASE_RDBLKS _IO(MAGIC, 2)
+#define SEEMP_CMD_GET_RINGSZ _IOR(MAGIC, 3, int)
+#define SEEMP_CMD_GET_BLKSZ _IOR(MAGIC, 4, int)
+#define SEEMP_CMD_SET_MASK _IO(MAGIC, 5)
+#define SEEMP_CMD_SET_MAPPING _IO(MAGIC, 6)
+#define SEEMP_CMD_CHECK_FILTER _IOR(MAGIC, 7, int)
+
+struct read_range {
+ int start_idx;
+ int num;
+};
+
+struct seemp_logk_dev {
+ unsigned int major;
+ unsigned int minor;
+
+ struct cdev cdev;
+ struct class *cls;
+ /*the full buffer*/
+ struct seemp_logk_blk *ring;
+ /*an array of blks*/
+ unsigned int ring_sz;
+ unsigned int blk_sz;
+
+ int num_tot_blks;
+
+ int num_write_avail_blks;
+ int num_write_in_prog_blks;
+
+ int num_read_avail_blks;
+ int num_read_in_prog_blks;
+
+ int num_writers;
+
+ /*
+ * there is always one reader
+ * which is the observer daemon
+ * therefore there is no necessity
+ * for num_readers variable
+ */
+
+ /*
+ * read_idx and write_idx loop through from zero to ring_sz,
+ * and then back to zero in a circle, as they advance
+ * based on the reader's and writers' accesses
+ */
+ int read_idx;
+
+ int write_idx;
+
+ /*
+ * wait queues
+ * readers_wq: implement wait for readers
+ * writers_wq: implement wait for writers
+ *
+ * whether writers are blocked or not is driven by the policy:
+ * case 1: (best_effort_logging == 1)
+ * writers are not blocked, and
+ * when there is no mem in the ring to store logs,
+ * the logs are simply dropped.
+ * case 2: (best_effort_logging == 0)
+ * when there is no mem in the ring to store logs,
+ * the process gets blocked until there is space.
+ */
+ wait_queue_head_t readers_wq;
+ wait_queue_head_t writers_wq;
+
+ /*
+ * protects everything in the device
+ * including ring buffer and all the num_ variables
+ * spinlock_t lock;
+ */
+ struct mutex lock;
+};
+
+#define BLK_SIZE 256
+#define BLK_HDR_SIZE 64
+#define TS_SIZE 20
+#define BLK_MAX_MSG_SZ (BLK_SIZE - BLK_HDR_SIZE)
+
+struct blk_payload {
+ __u32 api_id; /* event API id */
+ char msg[BLK_MAX_MSG_SZ]; /* event parameters */
+} __packed;
+
+struct seemp_logk_blk {
+ __u8 status; /* bits: 0->valid/invalid; 1-7: unused as of now! */
+ __u16 len; /* length of the payload */
+ __u8 version; /* version number */
+ __s32 pid; /* generating process's pid */
+ __s32 uid; /* generating process's uid - app specific */
+ __s32 tid; /* generating process's tid */
+ __s32 sec; /* seconds since Epoch */
+ __s32 nsec; /* nanoseconds */
+ char ts[TS_SIZE]; /* Time Stamp */
+ char appname[TASK_COMM_LEN];
+ struct blk_payload payload;
+} __packed;
+
+
+extern unsigned int kmalloc_flag;
+
+struct seemp_source_mask {
+ __u32 hash;
+ bool isOn;
+};
+#endif
diff --git a/drivers/platform/msm/seemp_core/seemp_ringbuf.c b/drivers/platform/msm/seemp_core/seemp_ringbuf.c
new file mode 100644
index 0000000..4558051
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_ringbuf.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014-2015, 2017, 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.
+ */
+
+#define pr_fmt(fmt) "seemp: %s: " fmt, __func__
+
+#include "seemp_logk.h"
+#include "seemp_ringbuf.h"
+#include "seemp_event_encoder.h"
+
+/*initial function no need to hold ring_lock*/
+int ringbuf_init(struct seemp_logk_dev *sdev)
+{
+ char *buf;
+ unsigned long virt_addr;
+
+ if (kmalloc_flag) {
+ sdev->ring = kmalloc(sdev->ring_sz, GFP_KERNEL);
+ if (sdev->ring == NULL) {
+ pr_err("kmalloc failed, ring_sz= %d\n", sdev->ring_sz);
+ return -ENOMEM;
+ }
+
+ buf = (char *)sdev->ring;
+
+ /*reserve kmalloc memory as pages to make them remapable*/
+ for (virt_addr = (unsigned long)buf;
+ virt_addr < (unsigned long)buf + sdev->ring_sz;
+ virt_addr += PAGE_SIZE) {
+ SetPageReserved(virt_to_page((virt_addr)));
+ }
+ } else {
+ sdev->ring = vmalloc(sdev->ring_sz);
+ if (sdev->ring == NULL) {
+ pr_err("vmalloc failed, ring_sz = %d\n", sdev->ring_sz);
+ return -ENOMEM;
+ }
+ buf = (char *)sdev->ring;
+
+ /*reserve vmalloc memory as pages to make them remapable*/
+ for (virt_addr = (unsigned long)buf;
+ virt_addr < (unsigned long)buf + sdev->ring_sz;
+ virt_addr += PAGE_SIZE) {
+ SetPageReserved(vmalloc_to_page(
+ (unsigned long *) virt_addr));
+ }
+ }
+
+ memset(sdev->ring, 0, sdev->ring_sz);
+
+ sdev->num_tot_blks = (sdev->ring_sz / BLK_SIZE);
+ sdev->num_writers = 0;
+ sdev->write_idx = 0;
+ sdev->read_idx = 0;
+
+ sdev->num_write_avail_blks = sdev->num_tot_blks;
+ /*no. of blocks available for write*/
+ sdev->num_write_in_prog_blks = 0;
+ /*no. of blocks held by writers to perform writes*/
+
+ sdev->num_read_avail_blks = 0;
+ /*no. of blocks ready for read*/
+ sdev->num_read_in_prog_blks = 0;
+ /*no. of blocks held by the reader to perform read*/
+
+ return 0;
+}
+
+void ringbuf_cleanup(struct seemp_logk_dev *sdev)
+{
+ unsigned long virt_addr;
+
+ if (kmalloc_flag) {
+ for (virt_addr = (unsigned long)sdev->ring;
+ virt_addr < (unsigned long)sdev->ring + sdev->ring_sz;
+ virt_addr += PAGE_SIZE) {
+ /*clear all pages*/
+ ClearPageReserved(virt_to_page((unsigned long *)
+ virt_addr));
+ }
+ kfree(sdev->ring);
+ } else {
+ for (virt_addr = (unsigned long)sdev->ring;
+ virt_addr < (unsigned long)sdev->ring + sdev->ring_sz;
+ virt_addr += PAGE_SIZE) {
+ /*clear all pages*/
+ ClearPageReserved(vmalloc_to_page((unsigned long *)
+ virt_addr));
+ }
+ vfree(sdev->ring);
+ }
+}
+
+struct seemp_logk_blk *ringbuf_fetch_wr_block
+ (struct seemp_logk_dev *sdev)
+{
+ struct seemp_logk_blk *blk = NULL;
+ int idx;
+
+ mutex_lock(&sdev->lock);
+ if (sdev->num_write_avail_blks == 0) {
+ idx = -1;
+ mutex_unlock(&sdev->lock);
+ return blk;
+ }
+
+ idx = sdev->write_idx;
+ sdev->write_idx = (sdev->write_idx + 1) % sdev->num_tot_blks;
+ sdev->num_write_avail_blks--;
+ sdev->num_write_in_prog_blks++;
+ sdev->num_writers++;
+
+ blk = &sdev->ring[idx];
+ blk->status = 0x0;
+
+ mutex_unlock(&sdev->lock);
+ return blk;
+}
+
+void ringbuf_finish_writer(struct seemp_logk_dev *sdev,
+ struct seemp_logk_blk *blk)
+{
+ /* Encode seemp parameters in multi-threaded mode (before mutex lock) */
+ encode_seemp_params(blk);
+
+ /*
+ * finish writing...
+ * the calling process will no longer access this block.
+ */
+ mutex_lock(&sdev->lock);
+
+ sdev->num_writers--;
+ sdev->num_write_in_prog_blks--;
+ sdev->num_read_avail_blks++;
+
+ /*wake up any readers*/
+ if (sdev->num_writers == 0)
+ wake_up_interruptible(&sdev->readers_wq);
+
+ mutex_unlock(&sdev->lock);
+}
+
+int ringbuf_count_marked(struct seemp_logk_dev *sdev)
+{
+ int i;
+ unsigned int marked;
+
+ mutex_lock(&sdev->lock);
+ for (marked = 0, i = 0; i < sdev->num_tot_blks; i++)
+ if (sdev->ring[i].status & 0x1)
+ marked++;
+ mutex_unlock(&sdev->lock);
+
+ return marked;
+}
diff --git a/drivers/platform/msm/seemp_core/seemp_ringbuf.h b/drivers/platform/msm/seemp_core/seemp_ringbuf.h
new file mode 100644
index 0000000..3abdf77
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_ringbuf.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014-2015, 2017, 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.
+ */
+
+#ifndef __SEEMP_RINGBUF_H__
+#define __SEEMP_RINGBUF_H__
+
+/*
+ * This header exports pingpong's API
+ */
+
+int ringbuf_init(struct seemp_logk_dev *sdev);
+struct seemp_logk_blk *ringbuf_fetch_wr_block
+(struct seemp_logk_dev *sdev);
+void ringbuf_finish_writer(struct seemp_logk_dev *sdev,
+ struct seemp_logk_blk *blk);
+void ringbuf_cleanup(struct seemp_logk_dev *sdev);
+int ringbuf_count_marked(struct seemp_logk_dev *sdev);
+
+#endif
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
index c977d1b..bf5a526 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
@@ -24,6 +24,9 @@
#define NUM_LNODES 3
#define MAX_STR_CL 50
+#define MSM_BUS_MAS_ALC 144
+#define MSM_BUS_RSC_APPS 8000
+
struct bus_search_type {
struct list_head link;
struct list_head node_list;
@@ -38,6 +41,7 @@
static LIST_HEAD(input_list);
static LIST_HEAD(apply_list);
static LIST_HEAD(commit_list);
+static LIST_HEAD(late_init_clist);
static LIST_HEAD(query_list);
DEFINE_RT_MUTEX(msm_bus_adhoc_lock);
@@ -123,6 +127,9 @@
goto exit_bcm_add_bus_req;
}
+ if (cur_dev->node_info->bcm_req_idx != -1)
+ goto exit_bcm_add_bus_req;
+
if (!cur_dev->node_info->num_bcm_devs)
goto exit_bcm_add_bus_req;
@@ -179,8 +186,6 @@
cur_dev->node_info->bcm_req_idx = lnode_idx;
memset(lnode->lnode_ib, 0, sizeof(uint64_t) * NUM_CTX);
memset(lnode->lnode_ab, 0, sizeof(uint64_t) * NUM_CTX);
- MSM_BUS_ERR("%s: Added %d entry to bcm %d @ %d\n", __func__,
- lnode->bus_dev_id, bcm_dev->node_info->id, lnode_idx);
}
exit_bcm_add_bus_req:
@@ -316,7 +321,6 @@
MSM_BUS_ERR("%s: Can't find dest dev %d", __func__, dest);
goto exit_prune_path;
}
- MSM_BUS_ERR("%s: dest dev %d", __func__, dest);
lnode_hop = gen_lnode(dest_dev, search_dev_id, lnode_hop, cl_name);
bcm_add_bus_req(dest_dev);
@@ -520,7 +524,6 @@
max_ib = max(max_ib,
max(bcm_dev->lnode_list[i].lnode_ib[ACTIVE_CTX],
bcm_dev->lnode_list[i].lnode_ib[DUAL_CTX]));
-
max_ab = max(max_ab,
bcm_dev->lnode_list[i].lnode_ab[ACTIVE_CTX] +
bcm_dev->lnode_list[i].lnode_ab[DUAL_CTX]);
@@ -531,9 +534,14 @@
bcm_dev->lnode_list[i].lnode_ab[ctx]);
}
}
-
bcm_dev->node_bw[ctx].max_ab = max_ab;
bcm_dev->node_bw[ctx].max_ib = max_ib;
+
+ max_ab = msm_bus_div64(max_ab, bcm_dev->bcmdev->unit_size);
+ max_ib = msm_bus_div64(max_ib, bcm_dev->bcmdev->unit_size);
+
+ bcm_dev->node_vec[ctx].vec_a = max_ab;
+ bcm_dev->node_vec[ctx].vec_b = max_ib;
}
exit_bcm_update_bus_req:
return;
@@ -598,44 +606,81 @@
}
}
+ max_query_ab = msm_bus_div64(max_query_ab,
+ bcm_dev->bcmdev->unit_size);
+ max_query_ib = msm_bus_div64(max_query_ib,
+ bcm_dev->bcmdev->unit_size);
+
bcm_dev->node_bw[ctx].max_query_ab = max_query_ab;
bcm_dev->node_bw[ctx].max_query_ib = max_query_ib;
-
}
exit_bcm_query_bus_req:
return;
}
-
-
-int bcm_remove_handoff_req(struct device *dev, void *data)
+static void bcm_update_alc_req(struct msm_bus_node_device_type *dev, int ctx)
{
struct msm_bus_node_device_type *bcm_dev = NULL;
int i;
- uint64_t max_ib = 0;
- uint64_t max_ab = 0;
+ uint64_t max_alc = 0;
+
+ if (!dev || !to_msm_bus_node(dev->node_info->bus_device)) {
+ MSM_BUS_ERR("Bus node pointer is Invalid");
+ goto exit_bcm_update_alc_req;
+ }
+
+ for (i = 0; i < dev->num_lnodes; i++)
+ max_alc = max(max_alc, dev->lnode_list[i].alc_idx[ctx]);
+
+ dev->node_bw[ctx].max_alc = max_alc;
+
+ bcm_dev = to_msm_bus_node(dev->node_info->bcm_devs[0]);
+
+ if (ctx == ACTIVE_CTX) {
+ max_alc = max(max_alc,
+ max(dev->node_bw[ACTIVE_CTX].max_alc,
+ dev->node_bw[DUAL_CTX].max_alc));
+ } else {
+ max_alc = dev->node_bw[ctx].max_alc;
+ }
+
+ bcm_dev->node_bw[ctx].max_alc = max_alc;
+ bcm_dev->node_vec[ctx].vec_a = max_alc;
+ bcm_dev->node_vec[ctx].vec_b = 0;
+
+exit_bcm_update_alc_req:
+ return;
+}
+
+int bcm_remove_handoff_req(struct device *dev, void *data)
+{
+ struct msm_bus_node_device_type *bus_dev = NULL;
+ struct msm_bus_node_device_type *cur_bcm = NULL;
+ struct msm_bus_node_device_type *cur_rsc = NULL;
int ret = 0;
rt_mutex_lock(&msm_bus_adhoc_lock);
- bcm_dev = to_msm_bus_node(dev);
- if (!bcm_dev) {
- MSM_BUS_ERR("%s: Null device ptr", __func__);
- goto exit_bcm_remove_handoff_req;
- }
-
- if (!bcm_dev->node_info->is_bcm_dev)
+ bus_dev = to_msm_bus_node(dev);
+ if (bus_dev->node_info->is_bcm_dev ||
+ bus_dev->node_info->is_fab_dev ||
+ bus_dev->node_info->is_rsc_dev)
goto exit_bcm_remove_handoff_req;
- for (i = 0; i < bcm_dev->num_lnodes; i++) {
- max_ib = max(max_ib,
- bcm_dev->lnode_list[i].lnode_ib[0]);
- max_ab = max(max_ab,
- bcm_dev->lnode_list[i].lnode_ab[0]);
+ if (bus_dev->node_info->num_bcm_devs) {
+ cur_bcm = to_msm_bus_node(bus_dev->node_info->bcm_devs[0]);
+ if (cur_bcm->node_info->num_rsc_devs) {
+ cur_rsc =
+ to_msm_bus_node(cur_bcm->node_info->rsc_devs[0]);
+ if (cur_rsc->node_info->id != MSM_BUS_RSC_APPS)
+ goto exit_bcm_remove_handoff_req;
+ }
}
- bcm_dev->node_bw[0].max_ab = max_ab;
- bcm_dev->node_bw[0].max_ib = max_ib;
+ if (!bus_dev->dirty) {
+ list_add_tail(&bus_dev->link, &late_init_clist);
+ bus_dev->dirty = true;
+ }
exit_bcm_remove_handoff_req:
rt_mutex_unlock(&msm_bus_adhoc_lock);
@@ -684,7 +729,6 @@
sum_ab += bus_dev->lnode_list[i].lnode_query_ab[ctx];
}
- MSM_BUS_ERR("aggregate: query_ab:%llu\n", sum_ab);
bus_dev->node_bw[ctx].sum_query_ab = sum_ab;
bus_dev->node_bw[ctx].max_query_ib = max_ib;
@@ -766,6 +810,18 @@
INIT_LIST_HEAD(&commit_list);
}
+void commit_late_init_data(void)
+{
+ rt_mutex_lock(&msm_bus_adhoc_lock);
+
+ msm_bus_commit_data(&late_init_clist);
+ INIT_LIST_HEAD(&late_init_clist);
+
+ rt_mutex_unlock(&msm_bus_adhoc_lock);
+}
+
+
+
static void add_node_to_clist(struct msm_bus_node_device_type *node)
{
struct msm_bus_node_device_type *node_parent =
@@ -870,6 +926,63 @@
return ret;
}
+static int update_alc_vote(struct device *alc_dev, uint64_t act_req_fa_lat,
+ uint64_t act_req_idle_time, uint64_t slp_req_fa_lat,
+ uint64_t slp_req_idle_time, uint64_t cur_fa_lat,
+ uint64_t cur_idle_time, int idx, int ctx)
+{
+ struct link_node *lnode = NULL;
+ struct msm_bus_node_device_type *dev_info = NULL;
+ int curr_idx, i;
+ int ret = 0;
+
+ if (IS_ERR_OR_NULL(alc_dev)) {
+ MSM_BUS_ERR("%s: No source device", __func__);
+ ret = -ENODEV;
+ goto exit_update_alc_vote;
+ }
+
+ if (idx < 0) {
+ MSM_BUS_ERR("%s: Invalid lnode idx %d", __func__, idx);
+ ret = -ENXIO;
+ goto exit_update_alc_vote;
+ }
+
+ dev_info = to_msm_bus_node(alc_dev);
+ curr_idx = idx;
+
+ if (curr_idx >= dev_info->num_lnodes) {
+ MSM_BUS_ERR("%s: Invalid lnode Idx %d num lnodes %d",
+ __func__, curr_idx, dev_info->num_lnodes);
+ ret = -ENXIO;
+ goto exit_update_alc_vote;
+ }
+
+ lnode = &dev_info->lnode_list[curr_idx];
+ if (!lnode) {
+ MSM_BUS_ERR("%s: Invalid lnode ptr lnode %d",
+ __func__, curr_idx);
+ ret = -ENXIO;
+ goto exit_update_alc_vote;
+ }
+
+ /*
+ * Add aggregation and mapping logic once LUT is avail.
+ * Use default values for time being.
+ */
+ lnode->alc_idx[ACTIVE_CTX] = 12;
+ lnode->alc_idx[DUAL_CTX] = 0;
+
+ for (i = 0; i < NUM_CTX; i++)
+ bcm_update_alc_req(dev_info, i);
+
+ add_node_to_clist(dev_info);
+
+exit_update_alc_vote:
+ return ret;
+}
+
+
static int query_path(struct device *src_dev, int dest, uint64_t act_req_ib,
uint64_t act_req_bw, uint64_t slp_req_ib,
uint64_t slp_req_bw, uint64_t cur_ib, uint64_t cur_bw,
@@ -1160,6 +1273,40 @@
}
client->pdata = pdata;
+ if (pdata->alc) {
+ client->curr = -1;
+ lnode = kzalloc(sizeof(int), GFP_KERNEL);
+
+ if (ZERO_OR_NULL_PTR(lnode)) {
+ MSM_BUS_ERR("%s: Error allocating lnode!", __func__);
+ goto exit_lnode_malloc_fail;
+ }
+ client->src_pnode = lnode;
+
+ client->src_devs = kzalloc(sizeof(struct device *),
+ GFP_KERNEL);
+ if (IS_ERR_OR_NULL(client->src_devs)) {
+ MSM_BUS_ERR("%s: Error allocating src_dev!", __func__);
+ goto exit_src_dev_malloc_fail;
+ }
+ src = MSM_BUS_MAS_ALC;
+ dev = bus_find_device(&msm_bus_type, NULL,
+ (void *) &src,
+ msm_bus_device_match_adhoc);
+ if (IS_ERR_OR_NULL(dev)) {
+ MSM_BUS_ERR("%s:Failed to find alc device",
+ __func__);
+ goto exit_invalid_data;
+ }
+ gen_lnode(dev, MSM_BUS_MAS_ALC, 0, pdata->name);
+ bcm_add_bus_req(dev);
+
+ client->src_devs[0] = dev;
+
+ handle = gen_handle(client);
+ goto exit_register_client;
+ }
+
lnode = kcalloc(pdata->usecase->num_paths, sizeof(int), GFP_KERNEL);
if (ZERO_OR_NULL_PTR(lnode)) {
MSM_BUS_ERR("%s: Error allocating pathnode ptr!", __func__);
@@ -1293,6 +1440,58 @@
return ret;
}
+static int update_client_alc(struct msm_bus_client *client, bool log_trns,
+ unsigned int idx)
+{
+ int lnode, cur_idx;
+ uint64_t req_idle_time, req_fal, dual_idle_time, dual_fal,
+ cur_idle_time, cur_fal;
+ int ret = 0;
+ struct msm_bus_scale_pdata *pdata;
+ struct device *src_dev;
+
+ if (!client) {
+ MSM_BUS_ERR("Client handle Null");
+ ret = -ENXIO;
+ goto exit_update_client_alc;
+ }
+
+ pdata = client->pdata;
+ if (!pdata) {
+ MSM_BUS_ERR("Client pdata Null");
+ ret = -ENXIO;
+ goto exit_update_client_alc;
+ }
+
+ cur_idx = client->curr;
+ client->curr = idx;
+ req_fal = pdata->usecase_lat[idx].fal_ns;
+ req_idle_time = pdata->usecase_lat[idx].idle_t_ns;
+ lnode = client->src_pnode[0];
+ src_dev = client->src_devs[0];
+
+ if (pdata->active_only) {
+ dual_fal = 0;
+ dual_idle_time = 0;
+ } else {
+ dual_fal = req_fal;
+ dual_idle_time = req_idle_time;
+ }
+
+ ret = update_alc_vote(src_dev, req_fal, req_idle_time, dual_fal,
+ dual_idle_time, cur_fal, cur_idle_time, lnode,
+ pdata->active_only);
+
+ if (ret) {
+ MSM_BUS_ERR("%s: Update path failed! %d ctx %d\n",
+ __func__, ret, pdata->active_only);
+ goto exit_update_client_alc;
+ }
+ commit_data();
+exit_update_client_alc:
+ return ret;
+}
+
static int query_usecase(struct msm_bus_client *client, bool log_trns,
unsigned int idx,
struct msm_bus_tcs_usecase *tcs_usecase)
@@ -1483,8 +1682,13 @@
MSM_BUS_DBG("%s: cl: %u index: %d curr: %d num_paths: %d\n", __func__,
cl, index, client->curr, client->pdata->usecase->num_paths);
- msm_bus_dbg_client_data(client->pdata, index, cl);
- ret = update_client_paths(client, log_transaction, index);
+
+ if (pdata->alc)
+ ret = update_client_alc(client, log_transaction, index);
+ else {
+ msm_bus_dbg_client_data(client->pdata, index, cl);
+ ret = update_client_paths(client, log_transaction, index);
+ }
if (ret) {
pr_err("%s: Err updating path\n", __func__);
goto exit_update_request;
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_dbg.c b/drivers/soc/qcom/msm_bus/msm_bus_dbg.c
index 5908122..015edb3 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_dbg.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_dbg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, 2014-2016, The Linux Foundation. All rights
+/* Copyright (c) 2010-2012, 2014-2017, The Linux Foundation. All rights
* reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -439,7 +439,6 @@
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->clid == clid) {
- debugfs_remove(cldata->file);
list_del(&cldata->list);
kfree(cldata);
break;
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
index beb5c2b..4167480 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
@@ -45,6 +45,7 @@
static struct list_head bcm_query_list_inorder[VCD_MAX_CNT];
static struct msm_bus_node_device_type *cur_rsc;
+static bool init_time = true;
struct bcm_db {
uint32_t unit_size;
@@ -265,27 +266,23 @@
}
static int tcs_cmd_gen(struct msm_bus_node_device_type *cur_bcm,
- struct tcs_cmd *cmd, uint64_t ib,
- uint64_t ab, bool commit)
+ struct tcs_cmd *cmd, uint64_t vec_a,
+ uint64_t vec_b, bool commit)
{
int ret = 0;
bool valid = true;
- if (ib == 0 && ab == 0) {
+ if (vec_a == 0 && vec_b == 0)
valid = false;
- } else {
- do_div(ib, cur_bcm->bcmdev->unit_size);
- do_div(ab, cur_bcm->bcmdev->unit_size);
- }
- if (ib > BCM_TCS_CMD_VOTE_MASK)
- ib = BCM_TCS_CMD_VOTE_MASK;
+ if (vec_a > BCM_TCS_CMD_VOTE_MASK)
+ vec_a = BCM_TCS_CMD_VOTE_MASK;
- if (ab > BCM_TCS_CMD_VOTE_MASK)
- ab = BCM_TCS_CMD_VOTE_MASK;
+ if (vec_b > BCM_TCS_CMD_VOTE_MASK)
+ vec_b = BCM_TCS_CMD_VOTE_MASK;
cmd->addr = cur_bcm->bcmdev->addr;
- cmd->data = BCM_TCS_CMD(commit, valid, ab, ib);
+ cmd->data = BCM_TCS_CMD(commit, valid, vec_a, vec_b);
cmd->complete = commit;
return ret;
@@ -333,8 +330,8 @@
idx++;
}
tcs_cmd_gen(cur_bcm, &cmdlist_active[k],
- cur_bcm->node_bw[ACTIVE_CTX].max_ib,
- cur_bcm->node_bw[ACTIVE_CTX].max_ab, commit);
+ cur_bcm->node_vec[ACTIVE_CTX].vec_a,
+ cur_bcm->node_vec[ACTIVE_CTX].vec_b, commit);
k++;
last_tcs = k;
cur_bcm->updated = true;
@@ -352,10 +349,10 @@
continue;
list_for_each_entry(cur_bcm, &cur_bcm_clist[i], link) {
commit = false;
- if ((cur_bcm->node_bw[DUAL_CTX].max_ab ==
- cur_bcm->node_bw[ACTIVE_CTX].max_ab) &&
- (cur_bcm->node_bw[DUAL_CTX].max_ib ==
- cur_bcm->node_bw[ACTIVE_CTX].max_ib)) {
+ if ((cur_bcm->node_vec[DUAL_CTX].vec_a ==
+ cur_bcm->node_vec[ACTIVE_CTX].vec_a) &&
+ (cur_bcm->node_vec[DUAL_CTX].vec_b ==
+ cur_bcm->node_vec[ACTIVE_CTX].vec_b)) {
if (last_tcs != -1 &&
list_is_last(&cur_bcm->link,
&cur_bcm_clist[i])) {
@@ -378,11 +375,11 @@
}
tcs_cmd_gen(cur_bcm, &cmdlist_wake[k],
- cur_bcm->node_bw[ACTIVE_CTX].max_ib,
- cur_bcm->node_bw[ACTIVE_CTX].max_ab, commit);
+ cur_bcm->node_vec[ACTIVE_CTX].vec_a,
+ cur_bcm->node_vec[ACTIVE_CTX].vec_b, commit);
tcs_cmd_gen(cur_bcm, &cmdlist_sleep[k],
- cur_bcm->node_bw[DUAL_CTX].max_ib,
- cur_bcm->node_bw[DUAL_CTX].max_ab, commit);
+ cur_bcm->node_vec[DUAL_CTX].vec_a,
+ cur_bcm->node_vec[DUAL_CTX].vec_b, commit);
k++;
}
}
@@ -485,10 +482,11 @@
cur_bcm = to_msm_bus_node(cur_dev->node_info->bcm_devs[0]);
- if (cur_bcm->node_bw[DUAL_CTX].max_ab == 0 &&
- cur_bcm->node_bw[ACTIVE_CTX].max_ab == 0 &&
- cur_bcm->node_bw[DUAL_CTX].max_ib == 0 &&
- cur_bcm->node_bw[ACTIVE_CTX].max_ib == 0) {
+ if (cur_bcm->node_vec[DUAL_CTX].vec_a == 0 &&
+ cur_bcm->node_vec[ACTIVE_CTX].vec_a == 0 &&
+ cur_bcm->node_vec[DUAL_CTX].vec_b == 0 &&
+ cur_bcm->node_vec[ACTIVE_CTX].vec_b == 0 &&
+ init_time == false) {
cur_bcm->dirty = false;
list_del_init(&cur_bcm->link);
}
@@ -550,25 +548,31 @@
if (list_empty(&cur_bcm_clist[i]))
continue;
list_for_each_entry(cur_bcm, &cur_bcm_clist[i], link) {
- if ((cur_bcm->node_bw[DUAL_CTX].max_ab !=
- cur_bcm->node_bw[ACTIVE_CTX].max_ab) ||
- (cur_bcm->node_bw[DUAL_CTX].max_ib !=
- cur_bcm->node_bw[ACTIVE_CTX].max_ib)) {
+ if ((cur_bcm->node_vec[DUAL_CTX].vec_a !=
+ cur_bcm->node_vec[ACTIVE_CTX].vec_a) ||
+ (cur_bcm->node_vec[DUAL_CTX].vec_b !=
+ cur_bcm->node_vec[ACTIVE_CTX].vec_b)) {
cnt_sleep++;
cnt_wake++;
}
- if (!cur_bcm->updated)
- cnt_active++;
+ if (cur_bcm->updated ||
+ (cur_bcm->node_vec[DUAL_CTX].vec_a == 0 &&
+ cur_bcm->node_vec[ACTIVE_CTX].vec_a == 0 &&
+ cur_bcm->node_vec[DUAL_CTX].vec_b == 0 &&
+ cur_bcm->node_vec[ACTIVE_CTX].vec_b == 0 &&
+ init_time == true))
+ continue;
+ cnt_active++;
}
cnt_vcd++;
}
- MSM_BUS_ERR("%s: cmd_gen\n", __func__);
n_active = kcalloc(cnt_vcd+1, sizeof(int), GFP_KERNEL);
n_wake = kcalloc(cnt_vcd+1, sizeof(int), GFP_KERNEL);
n_sleep = kcalloc(cnt_vcd+1, sizeof(int), GFP_KERNEL);
- cmdlist_active = kcalloc(cnt_active, sizeof(struct tcs_cmd),
+ if (cnt_active)
+ cmdlist_active = kcalloc(cnt_active, sizeof(struct tcs_cmd),
GFP_KERNEL);
if (cnt_sleep && cnt_wake) {
cmdlist_wake = kcalloc(cnt_wake, sizeof(struct tcs_cmd),
@@ -1086,6 +1090,7 @@
node_info->name = pdata_node_info->name;
node_info->id = pdata_node_info->id;
+ node_info->bcm_req_idx = -1;
node_info->bus_device_id = pdata_node_info->bus_device_id;
node_info->mas_rpm_id = pdata_node_info->mas_rpm_id;
node_info->slv_rpm_id = pdata_node_info->slv_rpm_id;
@@ -1289,6 +1294,7 @@
bus_node->node_info = node_info;
bus_node->ap_owned = pdata->ap_owned;
+ bus_node->dirty = false;
bus_dev->of_node = pdata->of_node;
if (msm_bus_copy_node_info(pdata, bus_dev) < 0) {
@@ -1653,9 +1659,11 @@
int rc;
MSM_BUS_ERR("msm_bus_late_init: Remove handoff bw requests\n");
+ init_time = false;
rc = bus_for_each_dev(&msm_bus_type, NULL, NULL,
bcm_remove_handoff_req);
+ commit_late_init_data();
return rc;
}
subsys_initcall(msm_bus_device_init_driver);
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_of.c b/drivers/soc/qcom/msm_bus/msm_bus_of.c
index 856dcce..fd72ae6 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_of.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_of.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, 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
@@ -46,6 +46,7 @@
{
struct msm_bus_scale_pdata *pdata = NULL;
struct msm_bus_paths *usecase = NULL;
+ struct msm_bus_lat_vectors *usecase_lat = NULL;
int i = 0, j, ret, num_usecases = 0, num_paths, len;
const uint32_t *vec_arr = NULL;
bool mem_err = false;
@@ -85,6 +86,42 @@
pr_debug("Using dual context by default\n");
}
+ pdata->alc = of_property_read_bool(of_node, "qcom,msm-bus,alc-voter");
+
+ if (pdata->alc) {
+ usecase_lat = devm_kzalloc(&pdev->dev,
+ (sizeof(struct msm_bus_lat_vectors) *
+ pdata->num_usecases), GFP_KERNEL);
+ if (!usecase_lat) {
+ mem_err = true;
+ goto err;
+ }
+
+ vec_arr = of_get_property(of_node,
+ "qcom,msm-bus,vectors-alc", &len);
+ if (vec_arr == NULL) {
+ pr_err("Error: Lat vector array not found\n");
+ goto err;
+ }
+
+ if (len != num_usecases * sizeof(uint32_t) * 2) {
+ pr_err("Error: Length-error on getting vectors\n");
+ goto err;
+ }
+
+ for (i = 0; i < num_usecases; i++) {
+ int index = i * 2;
+
+ usecase_lat[i].fal_ns = (uint64_t)
+ KBTOB(be32_to_cpu(vec_arr[index]));
+ usecase_lat[i].idle_t_ns = (uint64_t)
+ KBTOB(be32_to_cpu(vec_arr[index + 1]));
+ }
+
+ pdata->usecase_lat = usecase_lat;
+ return pdata;
+ }
+
usecase = devm_kzalloc(&pdev->dev, (sizeof(struct msm_bus_paths) *
pdata->num_usecases), GFP_KERNEL);
if (!usecase) {
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_rpmh.h b/drivers/soc/qcom/msm_bus/msm_bus_rpmh.h
index f415735..fad7afa 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_rpmh.h
+++ b/drivers/soc/qcom/msm_bus/msm_bus_rpmh.h
@@ -29,6 +29,7 @@
uint64_t lnode_ab[NUM_CTX];
uint64_t lnode_query_ib[NUM_CTX];
uint64_t lnode_query_ab[NUM_CTX];
+ uint64_t alc_idx[NUM_CTX];
int next;
struct device *next_dev;
struct list_head link;
@@ -61,11 +62,17 @@
uint64_t sum_query_ab;
uint64_t max_query_ib;
uint64_t max_query_ab;
+ uint64_t max_alc;
uint64_t cur_clk_hz;
uint32_t util_used;
uint32_t vrail_used;
};
+struct nodevector {
+ uint64_t vec_a;
+ uint64_t vec_b;
+};
+
struct msm_bus_rsc_device_type {
struct rpmh_client *mbox;
struct list_head bcm_clist[VCD_MAX_CNT];
@@ -167,6 +174,7 @@
int num_lnodes;
struct link_node *lnode_list;
struct nodebw node_bw[NUM_CTX];
+ struct nodevector node_vec[NUM_CTX];
struct list_head link;
struct list_head query_link;
struct nodeclk clk[NUM_CTX];
@@ -193,6 +201,7 @@
int throttle_en, uint64_t lim_bw);
int msm_bus_commit_data(struct list_head *clist);
int bcm_remove_handoff_req(struct device *dev, void *data);
+void commit_late_init_data(void);
int msm_bus_query_gen(struct list_head *qlist,
struct msm_bus_tcs_usecase *tcs_usecase);
void *msm_bus_realloc_devmem(struct device *dev, void *p, size_t old_size,
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
index aeecf29..1635bab 100644
--- a/drivers/soc/qcom/rpmh.c
+++ b/drivers/soc/qcom/rpmh.c
@@ -37,14 +37,13 @@
.msg = { 0 }, \
.msg.state = s, \
.msg.is_complete = true, \
- .msg.payload = &name.cmd, \
- .msg.num_payload = 1, \
- .cmd = { 0 }, \
+ .msg.payload = name.cmd, \
+ .msg.num_payload = 0, \
+ .cmd = { { 0 } }, \
.waitq = q, \
.wait_count = c, \
.rc = rc, \
.bit = -1, \
- .free_cmd = NULL, \
}
struct rpmh_req {
@@ -56,13 +55,11 @@
struct rpmh_msg {
struct tcs_mbox_msg msg;
- /* A single command for our use here */
- struct tcs_cmd cmd;
+ struct tcs_cmd cmd[MAX_RPMH_PAYLOAD];
wait_queue_head_t *waitq;
atomic_t *wait_count;
struct rpmh_client *rc;
int bit;
- void *free_cmd;
int err; /* relay error from mbox for sync calls */
};
@@ -120,7 +117,6 @@
struct rpmh_mbox *rpm = rpm_msg->rc->rpmh;
atomic_t *wc = rpm_msg->wait_count;
wait_queue_head_t *waitq = rpm_msg->waitq;
- void *free = rpm_msg->free_cmd;
rpm_msg->err = r;
@@ -139,7 +135,7 @@
/*
* Copy the child object pointers before freeing up the parent,
* This way even if the parent (rpm_msg) object gets reused, we
- * can free up the child objects (free_cmd and wq/wc) parallely.
+ * can free up the child objects (wq/wc) parallely.
* If you free up the children before the parent, then we run
* into an issue that the stack allocated parent object may be
* invalid before we can check the ->bit value.
@@ -152,9 +148,6 @@
spin_unlock(&rpm->lock);
}
- /* Nobody should be needing the request anymore */
- kfree(free);
-
/* Signal the blocking thread we are done */
if (waitq) {
atomic_dec(wc);
@@ -254,6 +247,9 @@
ret = mbox_send_message(rc->chan, &rpm_msg->msg);
if (ret > 0)
ret = 0;
+ } else {
+ /* Clean up our call by spoofing tx_done */
+ rpmh_tx_done(&rc->client, &rpm_msg->msg, ret);
}
return ret;
@@ -285,10 +281,10 @@
if (!rpm_msg)
return -ENOMEM;
- rpm_msg->cmd.addr = addr;
- rpm_msg->cmd.data = data;
+ rpm_msg->cmd[0].addr = addr;
+ rpm_msg->cmd[0].data = data;
- rpm_msg->msg.payload = &rpm_msg->cmd;
+ rpm_msg->msg.payload = rpm_msg->cmd;
rpm_msg->msg.num_payload = 1;
return __rpmh_write(rc, state, rpm_msg);
@@ -325,8 +321,9 @@
if (rpmh_standalone)
return 0;
- rpm_msg.cmd.addr = addr;
- rpm_msg.cmd.data = data;
+ rpm_msg.cmd[0].addr = addr;
+ rpm_msg.cmd[0].data = data;
+ rpm_msg.msg.num_payload = 1;
ret = __rpmh_write(rc, state, &rpm_msg);
if (ret < 0)
@@ -341,29 +338,22 @@
EXPORT_SYMBOL(rpmh_write_single);
struct rpmh_msg *__get_rpmh_msg_async(struct rpmh_client *rc,
- enum rpmh_state state, struct tcs_cmd *cmd, int n, bool fast)
+ enum rpmh_state state, struct tcs_cmd *cmd, int n)
{
struct rpmh_msg *rpm_msg;
- struct tcs_cmd *tcs_cmd;
if (IS_ERR_OR_NULL(rc) || !cmd || n <= 0 || n > MAX_RPMH_PAYLOAD)
return ERR_PTR(-EINVAL);
- tcs_cmd = kcalloc(n, sizeof(*cmd), fast ? GFP_ATOMIC : GFP_KERNEL);
- if (!tcs_cmd)
- return ERR_PTR(-ENOMEM);
- memcpy(tcs_cmd, cmd, n * sizeof(*tcs_cmd));
-
rpm_msg = get_msg_from_pool(rc);
- if (!rpm_msg) {
- kfree(tcs_cmd);
+ if (!rpm_msg)
return ERR_PTR(-ENOMEM);
- }
+
+ memcpy(rpm_msg->cmd, cmd, n * sizeof(*cmd));
rpm_msg->msg.state = state;
- rpm_msg->msg.payload = tcs_cmd;
+ rpm_msg->msg.payload = rpm_msg->cmd;
rpm_msg->msg.num_payload = n;
- rpm_msg->free_cmd = tcs_cmd;
return rpm_msg;
}
@@ -389,8 +379,7 @@
if (rpmh_standalone)
return 0;
- rpm_msg = __get_rpmh_msg_async(rc, state, cmd, n, true);
-
+ rpm_msg = __get_rpmh_msg_async(rc, state, cmd, n);
if (IS_ERR(rpm_msg))
return PTR_ERR(rpm_msg);
@@ -430,7 +419,7 @@
if (rpmh_standalone)
return 0;
- rpm_msg.msg.payload = cmd;
+ memcpy(rpm_msg.cmd, cmd, n * sizeof(*cmd));
rpm_msg.msg.num_payload = n;
ret = __rpmh_write(rc, state, &rpm_msg);
@@ -502,7 +491,7 @@
/* Create async request batches */
for (i = 0; i < count; i++) {
- rpm_msg[i] = __get_rpmh_msg_async(rc, state, cmd, n[i], false);
+ rpm_msg[i] = __get_rpmh_msg_async(rc, state, cmd, n[i]);
if (IS_ERR_OR_NULL(rpm_msg[i]))
return PTR_ERR(rpm_msg[i]);
rpm_msg[i]->waitq = &waitq;
@@ -551,15 +540,16 @@
{
DEFINE_RPMH_MSG_ONSTACK(rc, 0, NULL, NULL, rpm_msg);
- if (IS_ERR_OR_NULL(rc))
+ if (IS_ERR_OR_NULL(rc) || n > MAX_RPMH_PAYLOAD)
return -EINVAL;
if (rpmh_standalone)
return 0;
- rpm_msg.msg.payload = cmd;
+ memcpy(rpm_msg.cmd, cmd, n * sizeof(*cmd));
rpm_msg.msg.num_payload = n;
rpm_msg.msg.is_control = true;
+ rpm_msg.msg.is_complete = false;
return mbox_send_controller_data(rc->chan, &rpm_msg.msg);
}
@@ -587,6 +577,7 @@
rpm = rc->rpmh;
rpm_msg.msg.invalidate = true;
+ rpm_msg.msg.is_complete = false;
spin_lock(&rpm->lock);
rpm->dirty = true;
@@ -621,8 +612,9 @@
if (rpmh_standalone)
return 0;
- rpm_msg.cmd.addr = addr;
- rpm_msg.cmd.data = 0;
+ rpm_msg.cmd[0].addr = addr;
+ rpm_msg.cmd[0].data = 0;
+ rpm_msg.msg.num_payload = 1;
rpm_msg.msg.is_read = true;
@@ -636,7 +628,7 @@
return ret;
/* Read the data back from the tcs_mbox_msg structrure */
- *resp = rpm_msg.cmd.data;
+ *resp = rpm_msg.cmd[0].data;
return rpm_msg.err;
}
@@ -655,8 +647,10 @@
/* Wake sets are always complete and sleep sets are not */
rpm_msg.msg.is_complete = (state == RPMH_WAKE_ONLY_STATE);
- rpm_msg.cmd.addr = addr;
- rpm_msg.cmd.data = data;
+ rpm_msg.cmd[0].addr = addr;
+ rpm_msg.cmd[0].data = data;
+ rpm_msg.msg.num_payload = 1;
+ rpm_msg.msg.is_complete = false;
return mbox_send_controller_data(rc->chan, &rpm_msg.msg);
}
diff --git a/drivers/soc/qcom/service-locator.c b/drivers/soc/qcom/service-locator.c
index b40d678..6a54048 100644
--- a/drivers/soc/qcom/service-locator.c
+++ b/drivers/soc/qcom/service-locator.c
@@ -24,7 +24,6 @@
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
-#include <linux/debugfs.h>
#include <soc/qcom/msm_qmi_interface.h>
#include <soc/qcom/service-locator.h>
@@ -441,140 +440,3 @@
return 0;
}
EXPORT_SYMBOL(find_subsys);
-
-static struct pd_qmi_client_data test_data;
-
-static int servloc_test_pdr_cb(struct notifier_block *this,
- unsigned long opcode, void *ptr)
-{
- int i, rc = 0;
- char subsys[QMI_SERVREG_LOC_NAME_LENGTH_V01];
- struct pd_qmi_client_data *return_data;
-
- return_data = (struct pd_qmi_client_data *)ptr;
-
- if (opcode) {
- pr_err("%s: Failed to get process domain!, opcode = %lu\n",
- __func__, opcode);
- return -EIO;
- }
-
- pr_err("Service Name: %s\tTotal Domains: %d\n",
- return_data->service_name, return_data->total_domains);
-
- for (i = 0; i < return_data->total_domains; i++) {
- pr_err("Instance ID: %d\t ",
- return_data->domain_list[i].instance_id);
- pr_err("Domain Name: %s\n",
- return_data->domain_list[i].name);
- rc = find_subsys(return_data->domain_list[i].name,
- subsys);
- if (rc < 0)
- pr_err("No valid subsys found for %s!\n",
- return_data->domain_list[i].name);
- else
- pr_err("Subsys: %s\n", subsys);
- }
- return 0;
-}
-
-static struct notifier_block pdr_service_nb = {
- .notifier_call = servloc_test_pdr_cb,
-};
-
-static ssize_t servloc_read(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- int rc = 0;
- char *node_name = filp->private_data;
-
- if (!strcmp(node_name, "test_servloc_get"))
- rc = get_service_location(test_data.client_name,
- test_data.service_name, &pdr_service_nb);
-
- return rc;
-}
-
-static ssize_t servloc_write(struct file *fp, const char __user *buf,
- size_t count, loff_t *unused)
-{
- char *node_name = fp->private_data;
-
- if (!buf)
- return -EIO;
- if (!strcmp(node_name, "service_name")) {
- snprintf(test_data.service_name, sizeof(test_data.service_name),
- "%.*s", (int) min((size_t)count - 1,
- (sizeof(test_data.service_name) - 1)), buf);
- } else {
- snprintf(test_data.client_name, sizeof(test_data.client_name),
- "%.*s", (int) min((size_t)count - 1,
- (sizeof(test_data.client_name) - 1)), buf);
- }
- return count;
-}
-
-static const struct file_operations servloc_fops = {
- .open = simple_open,
- .read = servloc_read,
- .write = servloc_write,
-};
-
-static struct dentry *servloc_base_dir;
-static struct dentry *test_servloc_file;
-
-static int __init servloc_debugfs_init(void)
-{
- servloc_base_dir = debugfs_create_dir("test_servloc", NULL);
- return !servloc_base_dir ? -ENOMEM : 0;
-}
-
-static void servloc_debugfs_exit(void)
-{
- debugfs_remove_recursive(servloc_base_dir);
-}
-
-static int servloc_debugfs_add(void)
-{
- int rc;
-
- if (!servloc_base_dir)
- return -ENOMEM;
-
- test_servloc_file = debugfs_create_file("client_name",
- 0644, servloc_base_dir,
- "client_name", &servloc_fops);
- rc = !test_servloc_file ? -ENOMEM : 0;
-
- if (rc == 0) {
- test_servloc_file = debugfs_create_file("service_name",
- 0644, servloc_base_dir,
- "service_name", &servloc_fops);
- rc = !test_servloc_file ? -ENOMEM : 0;
- }
-
- if (rc == 0) {
- test_servloc_file = debugfs_create_file("test_servloc_get",
- 0644, servloc_base_dir,
- "test_servloc_get", &servloc_fops);
- rc = !test_servloc_file ? -ENOMEM : 0;
- }
- return rc;
-}
-
-static int __init service_locator_init(void)
-{
- pr_debug("service_locator_status = %d\n", locator_status);
- if (servloc_debugfs_init())
- pr_err("Could not create test_servloc base directory!");
- if (servloc_debugfs_add())
- pr_err("Could not create test_servloc node entries!");
- return 0;
-}
-
-static void __exit service_locator_exit(void)
-{
- servloc_debugfs_exit();
-}
-module_init(service_locator_init);
-module_exit(service_locator_exit);
diff --git a/drivers/soc/qcom/service-notifier.c b/drivers/soc/qcom/service-notifier.c
index fca1c68..68592fe 100644
--- a/drivers/soc/qcom/service-notifier.c
+++ b/drivers/soc/qcom/service-notifier.c
@@ -21,7 +21,6 @@
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/err.h>
-#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <soc/qcom/subsystem_restart.h>
@@ -104,6 +103,7 @@
struct work_struct svc_exit;
struct work_struct svc_rcv_msg;
struct work_struct ind_ack;
+ struct work_struct qmi_handle_free;
struct workqueue_struct *svc_event_wq;
struct qmi_handle *clnt_handle;
struct notifier_block notifier;
@@ -123,6 +123,18 @@
static void root_service_service_arrive(struct work_struct *work);
static void root_service_exit_work(struct work_struct *work);
+static void free_qmi_handle(struct work_struct *work)
+{
+ struct qmi_client_info *data = container_of(work,
+ struct qmi_client_info, qmi_handle_free);
+
+ mutex_lock(&qmi_client_release_lock);
+ data->service_connected = false;
+ qmi_handle_destroy(data->clnt_handle);
+ data->clnt_handle = NULL;
+ mutex_unlock(&qmi_client_release_lock);
+}
+
static struct service_notif_info *_find_service_info(const char *service_path)
{
struct service_notif_info *service_notif;
@@ -426,11 +438,7 @@
* Destroy client handle and try connecting when
* service comes up again.
*/
- mutex_lock(&qmi_client_release_lock);
- data->service_connected = false;
- qmi_handle_destroy(data->clnt_handle);
- data->clnt_handle = NULL;
- mutex_unlock(&qmi_client_release_lock);
+ queue_work(data->svc_event_wq, &data->qmi_handle_free);
}
static void root_service_exit_work(struct work_struct *work)
@@ -486,7 +494,7 @@
info->subsys_state = ROOT_PD_SHUTDOWN;
break;
}
- queue_work(info->svc_event_wq, &info->svc_exit);
+ root_service_service_exit(info, info->subsys_state);
break;
default:
break;
@@ -561,6 +569,7 @@
INIT_WORK(&qmi_data->svc_exit, root_service_exit_work);
INIT_WORK(&qmi_data->svc_rcv_msg, root_service_clnt_recv_msg);
INIT_WORK(&qmi_data->ind_ack, send_ind_ack);
+ INIT_WORK(&qmi_data->qmi_handle_free, free_qmi_handle);
*curr_state = service_notif->curr_state =
SERVREG_NOTIF_SERVICE_STATE_UNINIT_V01;
@@ -742,179 +751,3 @@
&service_notif->service_notif_rcvr_list, nb);
}
EXPORT_SYMBOL(service_notif_unregister_notifier);
-
-struct service_notifier_test_data {
- char service_path[MAX_STRING_LEN];
- int instance_id;
- struct notifier_block nb;
- void *service_notif_handle;
-};
-
-static struct service_notifier_test_data test_data;
-
-static void print_service_provider_state(int notification, char *type)
-{
- if (notification == SERVREG_NOTIF_SERVICE_STATE_DOWN_V01)
- pr_info("%s: Service %s down!\n", type, test_data.service_path);
- else if (notification == SERVREG_NOTIF_SERVICE_STATE_UP_V01)
- pr_info("%s: Service %s up!\n", type, test_data.service_path);
- else if (notification == SERVREG_NOTIF_SERVICE_STATE_UNINIT_V01)
- pr_info("%s: Service %s state uninit!\n", type,
- test_data.service_path);
- else
- pr_info("%s: Service %s state Unknown 0x%x!\n", type,
- test_data.service_path, notification);
-}
-
-static int nb_callback(struct notifier_block *nb,
- unsigned long notification,
- void *data)
-{
- print_service_provider_state((int)notification, "Notification:");
- return 0;
-}
-
-static ssize_t show_service_path(struct seq_file *f, void *unused)
-{
- if (test_data.service_notif_handle)
- seq_printf(f, "Service Path: %s\n", test_data.service_path);
- else
- seq_puts(f, "No existing notifier\n");
- return 0;
-}
-
-
-static ssize_t set_service_notifier_register(struct file *fp,
- const char __user *buf,
- size_t count, loff_t *ppos)
-{
- int curr_state = INT_MAX, rc;
-
- if (!buf)
- return -EIO;
- if (test_data.service_notif_handle) {
- service_notif_unregister_notifier(
- test_data.service_notif_handle,
- &test_data.nb);
- test_data.service_notif_handle = NULL;
- pr_info("Unregistering existing notifier for %s\n",
- test_data.service_path);
- }
- rc = simple_write_to_buffer(test_data.service_path, MAX_STRING_LEN,
- ppos, buf, count - 1);
- if (rc != count - 1) {
- pr_err("Unable to read data into kernel buffer\n");
- goto err;
- }
- test_data.nb.notifier_call = nb_callback;
- test_data.service_notif_handle = service_notif_register_notifier(
- test_data.service_path,
- test_data.instance_id, &test_data.nb,
- &curr_state);
- if (!IS_ERR(test_data.service_notif_handle)) {
- pr_info("Notifier Registered for service %s\n",
- test_data.service_path);
- print_service_provider_state(curr_state, "Initial State");
- return count;
- }
-err:
- test_data.service_notif_handle = NULL;
- pr_err("Unable to register notifier for %s\n", test_data.service_path);
- return -EIO;
-}
-
-static int open_service_notifier_register(struct inode *inode, struct file *f)
-{
- return single_open(f, (void *) show_service_path,
- inode->i_private);
-}
-
-static const struct file_operations service_notifier_register_fops = {
- .open = open_service_notifier_register,
- .read = seq_read,
- .write = set_service_notifier_register,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static ssize_t show_service_notifier_id(struct seq_file *f, void *unused)
-{
- seq_printf(f, "Service instance ID: %d\n", test_data.instance_id);
- return 0;
-}
-
-static ssize_t set_service_notifier_id(struct file *fp,
- const char __user *buf,
- size_t count, loff_t *unused)
-{
- int val, rc;
- char kbuf[MAX_STRING_LEN];
-
- if (count > MAX_STRING_LEN) {
- rc = -EIO;
- goto err;
- }
- rc = copy_from_user(kbuf, buf, count);
- if (rc != 0) {
- rc = -EFAULT;
- goto err;
- }
-
- kbuf[count - 1] = '\0';
- rc = kstrtoint(kbuf, 0, &val);
- if (rc < 0)
- goto err;
-
- test_data.instance_id = val;
- return count;
-err:
- pr_err("Invalid input parameters: rc = %d\n", rc);
- return rc;
-}
-
-static int open_service_notifier_id(struct inode *inode, struct file *f)
-{
- return single_open(f, (void *) show_service_notifier_id,
- inode->i_private);
-}
-
-static const struct file_operations service_notifier_id_fops = {
- .open = open_service_notifier_id,
- .read = seq_read,
- .write = set_service_notifier_id,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static struct dentry *service_notifier_dir;
-static struct dentry *service_path_file;
-static struct dentry *service_id_file;
-
-static int __init service_notifier_init(void)
-{
- service_notifier_dir = debugfs_create_dir("service_notifier", NULL);
- if (service_notifier_dir) {
- service_path_file = debugfs_create_file("service_path",
- 0644, service_notifier_dir, NULL,
- &service_notifier_register_fops);
- if (!service_path_file)
- goto err;
- service_id_file = debugfs_create_file("service_id",
- 0644, service_notifier_dir, NULL,
- &service_notifier_id_fops);
- if (!service_id_file)
- goto err;
- }
- return 0;
-err:
- debugfs_remove_recursive(service_notifier_dir);
- return 0;
-}
-
-static void __exit service_notifier_exit(void)
-{
- debugfs_remove_recursive(service_notifier_dir);
- test_data.nb.notifier_call = nb_callback;
-}
-module_init(service_notifier_init);
-module_exit(service_notifier_exit);
diff --git a/drivers/soc/qcom/subsystem_restart.c b/drivers/soc/qcom/subsystem_restart.c
index c846d26..e7c2bb2 100644
--- a/drivers/soc/qcom/subsystem_restart.c
+++ b/drivers/soc/qcom/subsystem_restart.c
@@ -28,7 +28,6 @@
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/idr.h>
-#include <linux/debugfs.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/cdev.h>
@@ -149,7 +148,6 @@
* @restart_level: restart level (0 - panic, 1 - related, 2 - independent, etc.)
* @restart_order: order of other devices this devices restarts with
* @crash_count: number of times the device has crashed
- * @dentry: debugfs directory for this device
* @do_ramdump_on_put: ramdump on subsystem_put() if true
* @err_ready: completion variable to record error ready from subsystem
* @crashed: indicates if subsystem has crashed
@@ -171,9 +169,6 @@
int restart_level;
int crash_count;
struct subsys_soc_restart_order *restart_order;
-#ifdef CONFIG_DEBUG_FS
- struct dentry *dentry;
-#endif
bool do_ramdump_on_put;
struct cdev char_dev;
dev_t dev_no;
@@ -354,10 +349,11 @@
__ATTR_NULL,
};
-static struct bus_type subsys_bus_type = {
+struct bus_type subsys_bus_type = {
.name = "msm_subsys",
.dev_attrs = subsys_attrs,
};
+EXPORT_SYMBOL(subsys_bus_type);
static DEFINE_IDA(subsys_ida);
@@ -1172,87 +1168,6 @@
notify_each_subsys_device(&dev, 1, SUBSYS_PROXY_UNVOTE, NULL);
}
-#ifdef CONFIG_DEBUG_FS
-static ssize_t subsys_debugfs_read(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- int r;
- char buf[40];
- struct subsys_device *subsys = filp->private_data;
-
- r = snprintf(buf, sizeof(buf), "%d\n", subsys->count);
- return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
-}
-
-static ssize_t subsys_debugfs_write(struct file *filp,
- const char __user *ubuf, size_t cnt, loff_t *ppos)
-{
- struct subsys_device *subsys = filp->private_data;
- char buf[10];
- char *cmp;
-
- cnt = min(cnt, sizeof(buf) - 1);
- if (copy_from_user(&buf, ubuf, cnt))
- return -EFAULT;
- buf[cnt] = '\0';
- cmp = strstrip(buf);
-
- if (!strcmp(cmp, "restart")) {
- if (subsystem_restart_dev(subsys))
- return -EIO;
- } else if (!strcmp(cmp, "get")) {
- if (subsystem_get(subsys->desc->name))
- return -EIO;
- } else if (!strcmp(cmp, "put")) {
- subsystem_put(subsys);
- } else {
- return -EINVAL;
- }
-
- return cnt;
-}
-
-static const struct file_operations subsys_debugfs_fops = {
- .open = simple_open,
- .read = subsys_debugfs_read,
- .write = subsys_debugfs_write,
-};
-
-static struct dentry *subsys_base_dir;
-
-static int __init subsys_debugfs_init(void)
-{
- subsys_base_dir = debugfs_create_dir("msm_subsys", NULL);
- return !subsys_base_dir ? -ENOMEM : 0;
-}
-
-static void subsys_debugfs_exit(void)
-{
- debugfs_remove_recursive(subsys_base_dir);
-}
-
-static int subsys_debugfs_add(struct subsys_device *subsys)
-{
- if (!subsys_base_dir)
- return -ENOMEM;
-
- subsys->dentry = debugfs_create_file(subsys->desc->name,
- 0644, subsys_base_dir,
- subsys, &subsys_debugfs_fops);
- return !subsys->dentry ? -ENOMEM : 0;
-}
-
-static void subsys_debugfs_remove(struct subsys_device *subsys)
-{
- debugfs_remove(subsys->dentry);
-}
-#else
-static int __init subsys_debugfs_init(void) { return 0; };
-static void subsys_debugfs_exit(void) { }
-static int subsys_debugfs_add(struct subsys_device *subsys) { return 0; }
-static void subsys_debugfs_remove(struct subsys_device *subsys) { }
-#endif
-
static int subsys_device_open(struct inode *inode, struct file *file)
{
struct subsys_device *device, *subsys_dev = 0;
@@ -1690,17 +1605,8 @@
mutex_init(&subsys->track.lock);
- ret = subsys_debugfs_add(subsys);
- if (ret) {
- ida_simple_remove(&subsys_ida, subsys->id);
- wakeup_source_trash(&subsys->ssr_wlock);
- kfree(subsys);
- return ERR_PTR(ret);
- }
-
ret = device_register(&subsys->dev);
if (ret) {
- subsys_debugfs_remove(subsys);
put_device(&subsys->dev);
return ERR_PTR(ret);
}
@@ -1761,7 +1667,6 @@
if (ofnode)
subsys_remove_restart_order(ofnode);
err_register:
- subsys_debugfs_remove(subsys);
device_unregister(&subsys->dev);
return ERR_PTR(ret);
}
@@ -1790,7 +1695,6 @@
WARN_ON(subsys->count);
device_unregister(&subsys->dev);
mutex_unlock(&subsys->track.lock);
- subsys_debugfs_remove(subsys);
subsys_char_device_remove(subsys);
sysmon_notifier_unregister(subsys->desc);
if (subsys->desc->edge)
@@ -1830,9 +1734,6 @@
ret = bus_register(&subsys_bus_type);
if (ret)
goto err_bus;
- ret = subsys_debugfs_init();
- if (ret)
- goto err_debugfs;
char_class = class_create(THIS_MODULE, "subsys");
if (IS_ERR(char_class)) {
@@ -1851,8 +1752,6 @@
err_soc:
class_destroy(char_class);
err_class:
- subsys_debugfs_exit();
-err_debugfs:
bus_unregister(&subsys_bus_type);
err_bus:
destroy_workqueue(ssr_wq);
diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c
index 87b26445..9c3b6ff 100644
--- a/drivers/tty/serial/msm_geni_serial.c
+++ b/drivers/tty/serial/msm_geni_serial.c
@@ -256,6 +256,26 @@
geni_write_reg_nolog(irq_clear, uport->membase, SE_GENI_M_IRQ_CLEAR);
}
+static void msm_geni_serial_poll_cancel_rx(struct uart_port *uport)
+{
+ int done = 0;
+ unsigned int irq_clear = S_CMD_DONE_EN;
+
+ done = msm_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS,
+ S_CMD_DONE_EN);
+ if (!done) {
+ geni_cancel_s_cmd(uport->membase);
+ irq_clear |= S_CMD_CANCEL_EN;
+ if (!msm_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS,
+ S_CMD_CANCEL_EN)) {
+ geni_abort_s_cmd(uport->membase);
+ irq_clear |= S_CMD_ABORT_EN;
+ msm_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS,
+ S_CMD_ABORT_EN);
+ }
+ }
+ geni_write_reg_nolog(irq_clear, uport->membase, SE_GENI_S_IRQ_CLEAR);
+}
#ifdef CONFIG_CONSOLE_POLL
static int msm_geni_serial_get_char(struct uart_port *uport)
{
@@ -351,10 +371,15 @@
while (i < count) {
u32 chars_to_write = 0;
u32 avail_fifo_bytes = (port->tx_fifo_depth - port->tx_wm);
-
+ /*
+ * If the WM bit never set, then the Tx state machine is not
+ * in a valid state, so break, cancel/abort any existing
+ * command. Unfortunately the current data being written is
+ * lost.
+ */
while (!msm_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
M_TX_FIFO_WATERMARK_EN))
- cpu_relax();
+ break;
chars_to_write = min((unsigned int)(count - i),
avail_fifo_bytes);
if ((chars_to_write << 1) > avail_fifo_bytes)
@@ -485,7 +510,11 @@
{
unsigned int geni_s_irq_en;
unsigned int geni_m_irq_en;
+ unsigned int geni_status;
+ geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS);
+ if (geni_status & S_GENI_CMD_ACTIVE)
+ msm_geni_serial_poll_cancel_rx(uport);
geni_s_irq_en = geni_read_reg_nolog(uport->membase,
SE_GENI_S_IRQ_EN);
geni_m_irq_en = geni_read_reg_nolog(uport->membase,
@@ -1012,6 +1041,11 @@
if (!dev_port->port_setup)
msm_geni_serial_port_setup(uport);
+ /*
+ * Make an unconditional cancel on the main sequencer to reset
+ * it else we could end up in data loss scenarios.
+ */
+ msm_geni_serial_poll_cancel_tx(uport);
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -1088,6 +1122,11 @@
s_clk_cfg |= SER_CLK_EN;
s_clk_cfg |= (clk_div << CLK_DIV_SHFT);
+ /*
+ * Make an unconditional cancel on the main sequencer to reset
+ * it else we could end up in data loss scenarios.
+ */
+ msm_geni_serial_poll_cancel_tx(uport);
geni_serial_write_term_regs(uport, 0, tx_trans_cfg,
tx_parity_cfg, rx_trans_cfg, rx_parity_cfg, bits_per_char,
stop_bit, rx_stale, s_clk_cfg);
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index b9edb53..a0bc61f 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -435,7 +435,7 @@
dev_dbg(dev, "xhci-plat runtime suspend\n");
- return 0;
+ return xhci_suspend(xhci, true);
}
static int xhci_plat_runtime_resume(struct device *dev)
@@ -449,7 +449,7 @@
dev_dbg(dev, "xhci-plat runtime resume\n");
- ret = 0;
+ ret = xhci_resume(xhci, false);
pm_runtime_mark_last_busy(dev);
return ret;
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index e19e963..3ee2938 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -1426,6 +1426,7 @@
}
pd_phy_update_roles(pd->current_dr, pd->current_pr);
+ dual_role_instance_changed(pd->dual_role);
}
@@ -2665,11 +2666,17 @@
static int usbpd_dr_prop_writeable(struct dual_role_phy_instance *dual_role,
enum dual_role_property prop)
{
+ struct usbpd *pd = dual_role_get_drvdata(dual_role);
+
switch (prop) {
case DUAL_ROLE_PROP_MODE:
+ return 1;
case DUAL_ROLE_PROP_DR:
case DUAL_ROLE_PROP_PR:
- return 1;
+ if (pd)
+ return pd->current_state == PE_SNK_READY ||
+ pd->current_state == PE_SRC_READY;
+ break;
default:
break;
}
diff --git a/drivers/usb/phy/class-dual-role.c b/drivers/usb/phy/class-dual-role.c
index 51fcb54..9ef8895 100644
--- a/drivers/usb/phy/class-dual-role.c
+++ b/drivers/usb/phy/class-dual-role.c
@@ -70,15 +70,7 @@
return ret;
}
-static void dual_role_changed_work(struct work_struct *work)
-{
- struct dual_role_phy_instance *dual_role =
- container_of(work, struct dual_role_phy_instance,
- changed_work);
-
- dev_dbg(&dual_role->dev, "%s\n", __func__);
- kobject_uevent(&dual_role->dev.kobj, KOBJ_CHANGE);
-}
+static void dual_role_changed_work(struct work_struct *work);
void dual_role_instance_changed(struct dual_role_phy_instance *dual_role)
{
@@ -505,6 +497,17 @@
return ret;
}
+static void dual_role_changed_work(struct work_struct *work)
+{
+ struct dual_role_phy_instance *dual_role =
+ container_of(work, struct dual_role_phy_instance,
+ changed_work);
+
+ dev_dbg(&dual_role->dev, "%s\n", __func__);
+ sysfs_update_group(&dual_role->dev.kobj, &dual_role_attr_group);
+ kobject_uevent(&dual_role->dev.kobj, KOBJ_CHANGE);
+}
+
/******************* Module Init ***********************************/
static int __init dual_role_class_init(void)
diff --git a/include/dt-bindings/msm/msm-bus-ids.h b/include/dt-bindings/msm/msm-bus-ids.h
index 8135da9..be2210c 100644
--- a/include/dt-bindings/msm/msm-bus-ids.h
+++ b/include/dt-bindings/msm/msm-bus-ids.h
@@ -244,7 +244,8 @@
#define MSM_BUS_MASTER_PIMEM 141
#define MSM_BUS_MASTER_MEM_NOC_SNOC 142
#define MSM_BUS_MASTER_IPA_CORE 143
-#define MSM_BUS_MASTER_MASTER_LAST 144
+#define MSM_BUS_MASTER_ALC 144
+#define MSM_BUS_MASTER_MASTER_LAST 145
#define MSM_BUS_MASTER_LLCC_DISPLAY 20000
#define MSM_BUS_MASTER_MNOC_HF_MEM_NOC_DISPLAY 20001
diff --git a/include/linux/msm-bus.h b/include/linux/msm-bus.h
index 16e3bb2..26e948f 100644
--- a/include/linux/msm-bus.h
+++ b/include/linux/msm-bus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2017, 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,14 @@
struct msm_bus_vectors *vectors;
};
+struct msm_bus_lat_vectors {
+ uint64_t fal_ns; /* First Access Latency */
+ uint64_t idle_t_ns; /* Idle Time */
+};
+
struct msm_bus_scale_pdata {
struct msm_bus_paths *usecase;
+ struct msm_bus_lat_vectors *usecase_lat;
int num_usecases;
const char *name;
/*
@@ -66,6 +72,11 @@
* of the CPU state.
*/
unsigned int active_only;
+ /*
+ * If the ALC(Active Latency Client) flag is set to 1,
+ * use lat_usecases for latency voting.
+ */
+ unsigned int alc;
};
struct msm_bus_client_handle {
diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h
index 0de4da6..6b790c6 100644
--- a/include/linux/qcom-geni-se.h
+++ b/include/linux/qcom-geni-se.h
@@ -429,7 +429,7 @@
geni_write_reg(M_GENI_CMD_ABORT, base, SE_GENI_M_CMD_CTRL_REG);
}
-static inline void qcom_geni_abort_s_cmd(void __iomem *base)
+static inline void geni_abort_s_cmd(void __iomem *base)
{
geni_write_reg(S_GENI_CMD_ABORT, base, SE_GENI_S_CMD_CTRL_REG);
}
diff --git a/include/linux/seemp_instrumentation.h b/include/linux/seemp_instrumentation.h
new file mode 100644
index 0000000..2c050cb
--- /dev/null
+++ b/include/linux/seemp_instrumentation.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ */
+#ifndef __SEEMP_LOGK_STUB__
+#define __SEEMP_LOGK_STUB__
+
+#ifdef CONFIG_SEEMP_CORE
+#include <linux/kernel.h>
+
+#define MAX_BUF_SIZE 188
+
+#define SEEMP_LOGK_API_SIZE sizeof(int)
+
+/* Write: api_id + skip encoding byte + params */
+#define SEEMP_LOGK_RECORD(api_id, format, ...) do { \
+ *((int *)(buf - SEEMP_LOGK_API_SIZE)) = api_id; \
+ snprintf(buf + 1, MAX_BUF_SIZE - 1, format, ##__VA_ARGS__); \
+} while (0)
+
+extern void *(*seemp_logk_kernel_begin)(char **buf);
+extern void (*seemp_logk_kernel_end)(void *blck);
+
+static inline void *seemp_setup_buf(char **buf)
+{
+ void *blck;
+
+ if (seemp_logk_kernel_begin && seemp_logk_kernel_end) {
+ blck = seemp_logk_kernel_begin(buf);
+ if (!*buf) {
+ seemp_logk_kernel_end(blck);
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+ return blck;
+}
+/*
+ * NOTE: only sendto is going to be instrumented
+ * since send sys call internally calls sendto
+ * with 2 extra parameters
+ */
+static inline void seemp_logk_sendto(int fd, void __user *buff, size_t len,
+ unsigned int flags, struct sockaddr __user *addr, int addr_len)
+{
+ char *buf = NULL;
+ void *blck = NULL;
+
+ /*sets up buf and blck correctly*/
+ blck = seemp_setup_buf(&buf);
+ if (!blck)
+ return;
+
+ /*fill the buf*/
+ SEEMP_LOGK_RECORD(SEEMP_API_kernel__sendto, "len=%u,fd=%d",
+ (unsigned int)len, fd);
+
+ seemp_logk_kernel_end(blck);
+}
+
+/*
+ * NOTE: only recvfrom is going to be instrumented
+ * since recv sys call internally calls recvfrom
+ * with 2 extra parameters
+ */
+static inline void seemp_logk_recvfrom(int fd, void __user *ubuf,
+ size_t size, unsigned int flags, struct sockaddr __user *addr,
+ int __user *addr_len)
+{
+ char *buf = NULL;
+ void *blck = NULL;
+
+ /*sets up buf and blck correctly*/
+ blck = seemp_setup_buf(&buf);
+ if (!blck)
+ return;
+
+ /*fill the buf*/
+ SEEMP_LOGK_RECORD(SEEMP_API_kernel__recvfrom, "size=%u,fd=%d",
+ (unsigned int)size, fd);
+
+ seemp_logk_kernel_end(blck);
+}
+
+static inline void seemp_logk_oom_adjust_write(pid_t pid,
+ kuid_t uid, int oom_adj)
+{
+ char *buf = NULL;
+ void *blck = NULL;
+
+ /*sets up buf and blck correctly*/
+ blck = seemp_setup_buf(&buf);
+ if (!blck)
+ return;
+
+ /*fill the buf*/
+ SEEMP_LOGK_RECORD(SEEMP_API_kernel__oom_adjust_write,
+ "app_uid=%d,app_pid=%d,oom_adj=%d",
+ uid.val, pid, oom_adj);
+
+ seemp_logk_kernel_end(blck);
+}
+
+static inline void seemp_logk_oom_score_adj_write(pid_t pid, kuid_t uid,
+ int oom_adj_score)
+{
+ char *buf = NULL;
+ void *blck = NULL;
+
+ /*sets up buf and blck correctly*/
+ blck = seemp_setup_buf(&buf);
+ if (!blck)
+ return;
+
+ /*fill the buf*/
+ snprintf(buf, MAX_BUF_SIZE,
+ "-1|kernel|oom_score_adj_write|app_uid=%d,app_pid=%d,oom_adj=%d|--end",
+ uid.val, pid, oom_adj_score);
+
+ seemp_logk_kernel_end(blck);
+}
+
+#else
+static inline void seemp_logk_sendto(int fd, void __user *buff,
+ size_t len, unsigned int flags, struct sockaddr __user *addr,
+ int addr_len)
+{
+}
+
+static inline void seemp_logk_recvfrom
+ (int fd, void __user *ubuf, size_t size,
+ unsigned int flags, struct sockaddr __user *addr,
+ int __user *addr_len)
+{
+}
+
+static inline void seemp_logk_oom_adjust_write
+ (pid_t pid, kuid_t uid, int oom_adj)
+{
+}
+
+static inline void seemp_logk_oom_score_adj_write
+ (pid_t pid, kuid_t uid, int oom_adj_score)
+{
+}
+#endif
+#endif
diff --git a/include/soc/qcom/subsystem_restart.h b/include/soc/qcom/subsystem_restart.h
index 9ea0736..5478417 100644
--- a/include/soc/qcom/subsystem_restart.h
+++ b/include/soc/qcom/subsystem_restart.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, 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 <linux/interrupt.h>
struct subsys_device;
+extern struct bus_type subsys_bus_type;
enum {
RESET_SOC = 0,
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 33ba430..7c1899e 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -414,6 +414,8 @@
header-y += sdla.h
header-y += seccomp.h
header-y += securebits.h
+header-y += seemp_api.h
+header-y += seemp_param_id.h
header-y += selinux_netlink.h
header-y += sem.h
header-y += serial_core.h
diff --git a/include/uapi/linux/seemp_api.h b/include/uapi/linux/seemp_api.h
new file mode 100644
index 0000000..4dfc257
--- /dev/null
+++ b/include/uapi/linux/seemp_api.h
@@ -0,0 +1,395 @@
+#ifndef _SEEMP_API_H_
+#define _SEEMP_API_H_
+
+#define SEEMP_API_kernel__oom_adjust_write 0
+#define SEEMP_API_kernel__sendto 1
+#define SEEMP_API_kernel__recvfrom 2
+#define SEEMP_API_View__onTouchEvent 3
+#define SEEMP_API_View__onKeyDown 4
+#define SEEMP_API_View__onKeyUp 5
+#define SEEMP_API_View__onTrackBallEvent 6
+#define SEEMP_API_android_provider_Settings__get_ANDROID_ID_ 7
+#define SEEMP_API_TelephonyManager__getDeviceId 8
+#define SEEMP_API_TelephonyManager__getLine1Number 9
+#define SEEMP_API_Telephony__query 10
+#define SEEMP_API_CallerInfo__getCallerId 11
+#define SEEMP_API_CallerInfo__getCallerInfo 12
+#define SEEMP_API_ContentResolver__query 13
+#define SEEMP_API_AccountManagerService__getPassword 14
+#define SEEMP_API_AccountManagerService__getUserData 15
+#define SEEMP_API_AccountManagerService__addAccount 16
+#define SEEMP_API_AccountManagerService__removeAccount 17
+#define SEEMP_API_AccountManagerService__setPassword 18
+#define SEEMP_API_AccountManagerService__clearPassword 19
+#define SEEMP_API_AccountManagerService__setUserData 20
+#define SEEMP_API_AccountManagerService__editProperties 21
+#define SEEMP_API_AccountManager__getPassword 22
+#define SEEMP_API_AccountManager__getUserData 23
+#define SEEMP_API_AccountManager__addAccountExplicitly 24
+#define SEEMP_API_AccountManager__removeAccount 25
+#define SEEMP_API_AccountManager__setPassword 26
+#define SEEMP_API_AccountManager__clearPassword 27
+#define SEEMP_API_AccountManager__setUserData 28
+#define SEEMP_API_AccountManager__addAccount 29
+#define SEEMP_API_AccountManager__editProperties 30
+#define SEEMP_API_AccountManager__doWork 31
+#define SEEMP_API_Browser__getAllBookmarks 32
+#define SEEMP_API_Browser__getAllVisitedUrls 33
+#define SEEMP_API_Browser__getVisitedLike 34
+#define SEEMP_API_Browser__getVisitedHistory 35
+#define SEEMP_API_Browser__requestAllIcons 36
+#define SEEMP_API_ContentResolver__insert 37
+#define SEEMP_API_CalendarContract__insert 38
+#define SEEMP_API_CalendarContract__alarmExists 39
+#define SEEMP_API_CalendarContract__findNextAlarmTime 40
+#define SEEMP_API_CalendarContract__query 41
+#define SEEMP_API_LocationManager___requestLocationUpdates 42
+#define SEEMP_API_LocationManager__addGpsStatusListener 43
+#define SEEMP_API_LocationManager__addNmeaListener 44
+#define SEEMP_API_LocationManager__addProximityAlert 45
+#define SEEMP_API_LocationManager__getLastKnownLocation 46
+#define SEEMP_API_LocationManager__requestLocationUpdates 47
+#define SEEMP_API_LocationManager__sendExtraCommand 48
+#define SEEMP_API_TelephonyManager__getCellLocation 49
+#define SEEMP_API_TelephonyManager__getNeighboringCellInfo 50
+#define SEEMP_API_GeolocationService__registerForLocationUpdates 51
+#define SEEMP_API_GeolocationService__setEnableGps 52
+#define SEEMP_API_GeolocationService__start 53
+#define SEEMP_API_WebChromeClient__onGeolocationPermissionsShowPrompt 54
+#define SEEMP_API_WifiManager__getScanResults 55
+#define SEEMP_API_adB__enable 56
+#define SEEMP_API_adB__disable 57
+#define SEEMP_API_adB__startDiscovery 58
+#define SEEMP_API_adB__listenUsingInsecureRfcommWithServiceRecord 59
+#define SEEMP_API_adB__listenUsingSecureRfcommWithServiceRecord 60
+#define SEEMP_API_adB__getBondedDevices 61
+#define SEEMP_API_adB__getRemoteDevice 62
+#define SEEMP_API_adB__getState 63
+#define SEEMP_API_adB__getProfileConnectionState 64
+#define SEEMP_API_Camera__takePicture 65
+#define SEEMP_API_Camera__setPreviewCallback 66
+#define SEEMP_API_Camera__setPreviewCallbackWithBuffer 67
+#define SEEMP_API_Camera__setOneShotPreviewCallback 68
+#define SEEMP_API_android_media_MediaRecorder__start 69
+#define SEEMP_API_AudioRecord__startRecording 70
+#define SEEMP_API_AudioRecord__start 71
+#define SEEMP_API_SpeechRecognizer__startListening 72
+#define SEEMP_API_at_SmsManager__sendDataMessage 73
+#define SEEMP_API_at_SmsManager__sendMultipartTextMessage 74
+#define SEEMP_API_at_SmsManager__sendTextMessage 75
+#define SEEMP_API_at_gsm_SmsManager__sendDataMessage 76
+#define SEEMP_API_at_gsm_SmsManager__sendMultipartTextMessage 77
+#define SEEMP_API_at_gsm_SmsManager__sendTextMessage 78
+#define SEEMP_API_at_SmsManager__copyMessageToIcc 79
+#define SEEMP_API_at_SmsManager__deleteMessageFromIcc 80
+#define SEEMP_API_at_SmsManager__updateMessageOnIcc 81
+#define SEEMP_API_at_gsm_SmsManager__copyMessageToSim 82
+#define SEEMP_API_at_gsm_SmsManager__deleteMessageFromSim 83
+#define SEEMP_API_at_gsm_SmsManager__updateMessageOnSim 84
+#define SEEMP_API_at_gsm_SmsManager__getAllMessagesFromSim 85
+#define SEEMP_API_ContactsContract__getLookupUri 86
+#define SEEMP_API_ContactsContract__lookupContact 87
+#define SEEMP_API_ContactsContract__openContactPhotoInputStream 88
+#define SEEMP_API_ContactsContract__getContactLookupUri 89
+#define SEEMP_API_PackageManagerService__installPackage 90
+#define SEEMP_API_URL__openConnection 91
+#define SEEMP_API_URI__URI 92
+#define SEEMP_API_HttpGet__HttpGet 93
+#define SEEMP_API_HttpPut__HttpPut 94
+#define SEEMP_API_HttpPost__HttpPost 95
+#define SEEMP_API_apS__get_ACCELEROMETER_ROTATION_ 96
+#define SEEMP_API_apS__get_USER_ROTATION_ 97
+#define SEEMP_API_apS__get_ADB_ENABLED_ 98
+#define SEEMP_API_apS__get_DEBUG_APP_ 99
+#define SEEMP_API_apS__get_WAIT_FOR_DEBUGGER_ 100
+#define SEEMP_API_apS__get_AIRPLANE_MODE_ON_ 101
+#define SEEMP_API_apS__get_AIRPLANE_MODE_RADIOS_ 102
+#define SEEMP_API_apS__get_ALARM_ALERT_ 103
+#define SEEMP_API_apS__get_NEXT_ALARM_FORMATTED_ 104
+#define SEEMP_API_apS__get_ALWAYS_FINISH_ACTIVITIES_ 105
+#define SEEMP_API_apS__get_LOGGING_ID_ 106
+#define SEEMP_API_apS__get_ANIMATOR_DURATION_SCALE_ 107
+#define SEEMP_API_apS__get_WINDOW_ANIMATION_SCALE_ 108
+#define SEEMP_API_apS__get_FONT_SCALE_ 109
+#define SEEMP_API_apS__get_SCREEN_BRIGHTNESS_ 110
+#define SEEMP_API_apS__get_SCREEN_BRIGHTNESS_MODE_ 111
+#define SEEMP_API_apS__get_SCREEN_BRIGHTNESS_MODE_AUTOMATIC_ 112
+#define SEEMP_API_apS__get_SCREEN_BRIGHTNESS_MODE_MANUAL_ 113
+#define SEEMP_API_apS__get_SCREEN_OFF_TIMEOUT_ 114
+#define SEEMP_API_apS__get_DIM_SCREEN_ 115
+#define SEEMP_API_apS__get_TRANSITION_ANIMATION_SCALE_ 116
+#define SEEMP_API_apS__get_STAY_ON_WHILE_PLUGGED_IN_ 117
+#define SEEMP_API_apS__get_WALLPAPER_ACTIVITY_ 118
+#define SEEMP_API_apS__get_SHOW_PROCESSES_ 119
+#define SEEMP_API_apS__get_SHOW_WEB_SUGGESTIONS_ 120
+#define SEEMP_API_apS__get_SHOW_GTALK_SERVICE_STATUS_ 121
+#define SEEMP_API_apS__get_USE_GOOGLE_MAIL_ 122
+#define SEEMP_API_apS__get_AUTO_TIME_ 123
+#define SEEMP_API_apS__get_AUTO_TIME_ZONE_ 124
+#define SEEMP_API_apS__get_DATE_FORMAT_ 125
+#define SEEMP_API_apS__get_TIME_12_24_ 126
+#define SEEMP_API_apS__get_BLUETOOTH_DISCOVERABILITY_ 127
+#define SEEMP_API_apS__get_BLUETOOTH_DISCOVERABILITY_TIMEOUT_ 128
+#define SEEMP_API_apS__get_BLUETOOTH_ON_ 129
+#define SEEMP_API_apS__get_DEVICE_PROVISIONED_ 130
+#define SEEMP_API_apS__get_SETUP_WIZARD_HAS_RUN_ 131
+#define SEEMP_API_apS__get_DTMF_TONE_WHEN_DIALING_ 132
+#define SEEMP_API_apS__get_END_BUTTON_BEHAVIOR_ 133
+#define SEEMP_API_apS__get_RINGTONE_ 134
+#define SEEMP_API_apS__get_MODE_RINGER_ 135
+#define SEEMP_API_apS__get_INSTALL_NON_MARKET_APPS_ 136
+#define SEEMP_API_apS__get_LOCATION_PROVIDERS_ALLOWED_ 137
+#define SEEMP_API_apS__get_LOCK_PATTERN_ENABLED_ 138
+#define SEEMP_API_apS__get_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_ 139
+#define SEEMP_API_apS__get_LOCK_PATTERN_VISIBLE_ 140
+#define SEEMP_API_apS__get_NETWORK_PREFERENCE_ 141
+#define SEEMP_API_apS__get_DATA_ROAMING_ 142
+#define SEEMP_API_apS__get_HTTP_PROXY_ 143
+#define SEEMP_API_apS__get_PARENTAL_CONTROL_ENABLED_ 144
+#define SEEMP_API_apS__get_PARENTAL_CONTROL_LAST_UPDATE_ 145
+#define SEEMP_API_apS__get_PARENTAL_CONTROL_REDIRECT_URL_ 146
+#define SEEMP_API_apS__get_RADIO_BLUETOOTH_ 147
+#define SEEMP_API_apS__get_RADIO_CELL_ 148
+#define SEEMP_API_apS__get_RADIO_NFC_ 149
+#define SEEMP_API_apS__get_RADIO_WIFI_ 150
+#define SEEMP_API_apS__get_SYS_PROP_SETTING_VERSION_ 151
+#define SEEMP_API_apS__get_SETTINGS_CLASSNAME_ 152
+#define SEEMP_API_apS__get_TEXT_AUTO_CAPS_ 153
+#define SEEMP_API_apS__get_TEXT_AUTO_PUNCTUATE_ 154
+#define SEEMP_API_apS__get_TEXT_AUTO_REPLACE_ 155
+#define SEEMP_API_apS__get_TEXT_SHOW_PASSWORD_ 156
+#define SEEMP_API_apS__get_USB_MASS_STORAGE_ENABLED_ 157
+#define SEEMP_API_apS__get_VIBRATE_ON_ 158
+#define SEEMP_API_apS__get_HAPTIC_FEEDBACK_ENABLED_ 159
+#define SEEMP_API_apS__get_VOLUME_ALARM_ 160
+#define SEEMP_API_apS__get_VOLUME_BLUETOOTH_SCO_ 161
+#define SEEMP_API_apS__get_VOLUME_MUSIC_ 162
+#define SEEMP_API_apS__get_VOLUME_NOTIFICATION_ 163
+#define SEEMP_API_apS__get_VOLUME_RING_ 164
+#define SEEMP_API_apS__get_VOLUME_SYSTEM_ 165
+#define SEEMP_API_apS__get_VOLUME_VOICE_ 166
+#define SEEMP_API_apS__get_SOUND_EFFECTS_ENABLED_ 167
+#define SEEMP_API_apS__get_MODE_RINGER_STREAMS_AFFECTED_ 168
+#define SEEMP_API_apS__get_MUTE_STREAMS_AFFECTED_ 169
+#define SEEMP_API_apS__get_NOTIFICATION_SOUND_ 170
+#define SEEMP_API_apS__get_APPEND_FOR_LAST_AUDIBLE_ 171
+#define SEEMP_API_apS__get_WIFI_MAX_DHCP_RETRY_COUNT_ 172
+#define SEEMP_API_apS__get_WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS_ 173
+#define SEEMP_API_apS__get_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_ 174
+#define SEEMP_API_apS__get_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_ 175
+#define SEEMP_API_apS__get_WIFI_NUM_OPEN_NETWORKS_KEPT_ 176
+#define SEEMP_API_apS__get_WIFI_ON_ 177
+#define SEEMP_API_apS__get_WIFI_SLEEP_POLICY_ 178
+#define SEEMP_API_apS__get_WIFI_SLEEP_POLICY_DEFAULT_ 179
+#define SEEMP_API_apS__get_WIFI_SLEEP_POLICY_NEVER_ 180
+#define SEEMP_API_apS__get_WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED_ 181
+#define SEEMP_API_apS__get_WIFI_STATIC_DNS1_ 182
+#define SEEMP_API_apS__get_WIFI_STATIC_DNS2_ 183
+#define SEEMP_API_apS__get_WIFI_STATIC_GATEWAY_ 184
+#define SEEMP_API_apS__get_WIFI_STATIC_IP_ 185
+#define SEEMP_API_apS__get_WIFI_STATIC_NETMASK_ 186
+#define SEEMP_API_apS__get_WIFI_USE_STATIC_IP_ 187
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE_ 188
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_AP_COUNT_ 189
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_ 190
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_ 191
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_ 192
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_ 193
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_MAX_AP_CHECKS_ 194
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_ON_ 195
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_PING_COUNT_ 196
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_PING_DELAY_MS_ 197
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_PING_TIMEOUT_MS_ 198
+#define SEEMP_API_apS__put_ACCELEROMETER_ROTATION_ 199
+#define SEEMP_API_apS__put_USER_ROTATION_ 200
+#define SEEMP_API_apS__put_ADB_ENABLED_ 201
+#define SEEMP_API_apS__put_DEBUG_APP_ 202
+#define SEEMP_API_apS__put_WAIT_FOR_DEBUGGER_ 203
+#define SEEMP_API_apS__put_AIRPLANE_MODE_ON_ 204
+#define SEEMP_API_apS__put_AIRPLANE_MODE_RADIOS_ 205
+#define SEEMP_API_apS__put_ALARM_ALERT_ 206
+#define SEEMP_API_apS__put_NEXT_ALARM_FORMATTED_ 207
+#define SEEMP_API_apS__put_ALWAYS_FINISH_ACTIVITIES_ 208
+#define SEEMP_API_apS__put_ANDROID_ID_ 209
+#define SEEMP_API_apS__put_LOGGING_ID_ 210
+#define SEEMP_API_apS__put_ANIMATOR_DURATION_SCALE_ 211
+#define SEEMP_API_apS__put_WINDOW_ANIMATION_SCALE_ 212
+#define SEEMP_API_apS__put_FONT_SCALE_ 213
+#define SEEMP_API_apS__put_SCREEN_BRIGHTNESS_ 214
+#define SEEMP_API_apS__put_SCREEN_BRIGHTNESS_MODE_ 215
+#define SEEMP_API_apS__put_SCREEN_BRIGHTNESS_MODE_AUTOMATIC_ 216
+#define SEEMP_API_apS__put_SCREEN_BRIGHTNESS_MODE_MANUAL_ 217
+#define SEEMP_API_apS__put_SCREEN_OFF_TIMEOUT_ 218
+#define SEEMP_API_apS__put_DIM_SCREEN_ 219
+#define SEEMP_API_apS__put_TRANSITION_ANIMATION_SCALE_ 220
+#define SEEMP_API_apS__put_STAY_ON_WHILE_PLUGGED_IN_ 221
+#define SEEMP_API_apS__put_WALLPAPER_ACTIVITY_ 222
+#define SEEMP_API_apS__put_SHOW_PROCESSES_ 223
+#define SEEMP_API_apS__put_SHOW_WEB_SUGGESTIONS_ 224
+#define SEEMP_API_apS__put_SHOW_GTALK_SERVICE_STATUS_ 225
+#define SEEMP_API_apS__put_USE_GOOGLE_MAIL_ 226
+#define SEEMP_API_apS__put_AUTO_TIME_ 227
+#define SEEMP_API_apS__put_AUTO_TIME_ZONE_ 228
+#define SEEMP_API_apS__put_DATE_FORMAT_ 229
+#define SEEMP_API_apS__put_TIME_12_24_ 230
+#define SEEMP_API_apS__put_BLUETOOTH_DISCOVERABILITY_ 231
+#define SEEMP_API_apS__put_BLUETOOTH_DISCOVERABILITY_TIMEOUT_ 232
+#define SEEMP_API_apS__put_BLUETOOTH_ON_ 233
+#define SEEMP_API_apS__put_DEVICE_PROVISIONED_ 234
+#define SEEMP_API_apS__put_SETUP_WIZARD_HAS_RUN_ 235
+#define SEEMP_API_apS__put_DTMF_TONE_WHEN_DIALING_ 236
+#define SEEMP_API_apS__put_END_BUTTON_BEHAVIOR_ 237
+#define SEEMP_API_apS__put_RINGTONE_ 238
+#define SEEMP_API_apS__put_MODE_RINGER_ 239
+#define SEEMP_API_apS__put_INSTALL_NON_MARKET_APPS_ 240
+#define SEEMP_API_apS__put_LOCATION_PROVIDERS_ALLOWED_ 241
+#define SEEMP_API_apS__put_LOCK_PATTERN_ENABLED_ 242
+#define SEEMP_API_apS__put_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_ 243
+#define SEEMP_API_apS__put_LOCK_PATTERN_VISIBLE_ 244
+#define SEEMP_API_apS__put_NETWORK_PREFERENCE_ 245
+#define SEEMP_API_apS__put_DATA_ROAMING_ 246
+#define SEEMP_API_apS__put_HTTP_PROXY_ 247
+#define SEEMP_API_apS__put_PARENTAL_CONTROL_ENABLED_ 248
+#define SEEMP_API_apS__put_PARENTAL_CONTROL_LAST_UPDATE_ 249
+#define SEEMP_API_apS__put_PARENTAL_CONTROL_REDIRECT_URL_ 250
+#define SEEMP_API_apS__put_RADIO_BLUETOOTH_ 251
+#define SEEMP_API_apS__put_RADIO_CELL_ 252
+#define SEEMP_API_apS__put_RADIO_NFC_ 253
+#define SEEMP_API_apS__put_RADIO_WIFI_ 254
+#define SEEMP_API_apS__put_SYS_PROP_SETTING_VERSION_ 255
+#define SEEMP_API_apS__put_SETTINGS_CLASSNAME_ 256
+#define SEEMP_API_apS__put_TEXT_AUTO_CAPS_ 257
+#define SEEMP_API_apS__put_TEXT_AUTO_PUNCTUATE_ 258
+#define SEEMP_API_apS__put_TEXT_AUTO_REPLACE_ 259
+#define SEEMP_API_apS__put_TEXT_SHOW_PASSWORD_ 260
+#define SEEMP_API_apS__put_USB_MASS_STORAGE_ENABLED_ 261
+#define SEEMP_API_apS__put_VIBRATE_ON_ 262
+#define SEEMP_API_apS__put_HAPTIC_FEEDBACK_ENABLED_ 263
+#define SEEMP_API_apS__put_VOLUME_ALARM_ 264
+#define SEEMP_API_apS__put_VOLUME_BLUETOOTH_SCO_ 265
+#define SEEMP_API_apS__put_VOLUME_MUSIC_ 266
+#define SEEMP_API_apS__put_VOLUME_NOTIFICATION_ 267
+#define SEEMP_API_apS__put_VOLUME_RING_ 268
+#define SEEMP_API_apS__put_VOLUME_SYSTEM_ 269
+#define SEEMP_API_apS__put_VOLUME_VOICE_ 270
+#define SEEMP_API_apS__put_SOUND_EFFECTS_ENABLED_ 271
+#define SEEMP_API_apS__put_MODE_RINGER_STREAMS_AFFECTED_ 272
+#define SEEMP_API_apS__put_MUTE_STREAMS_AFFECTED_ 273
+#define SEEMP_API_apS__put_NOTIFICATION_SOUND_ 274
+#define SEEMP_API_apS__put_APPEND_FOR_LAST_AUDIBLE_ 275
+#define SEEMP_API_apS__put_WIFI_MAX_DHCP_RETRY_COUNT_ 276
+#define SEEMP_API_apS__put_WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS_ 277
+#define SEEMP_API_apS__put_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_ 278
+#define SEEMP_API_apS__put_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_ 279
+#define SEEMP_API_apS__put_WIFI_NUM_OPEN_NETWORKS_KEPT_ 280
+#define SEEMP_API_apS__put_WIFI_ON_ 281
+#define SEEMP_API_apS__put_WIFI_SLEEP_POLICY_ 282
+#define SEEMP_API_apS__put_WIFI_SLEEP_POLICY_DEFAULT_ 283
+#define SEEMP_API_apS__put_WIFI_SLEEP_POLICY_NEVER_ 284
+#define SEEMP_API_apS__put_WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED_ 285
+#define SEEMP_API_apS__put_WIFI_STATIC_DNS1_ 286
+#define SEEMP_API_apS__put_WIFI_STATIC_DNS2_ 287
+#define SEEMP_API_apS__put_WIFI_STATIC_GATEWAY_ 288
+#define SEEMP_API_apS__put_WIFI_STATIC_IP_ 289
+#define SEEMP_API_apS__put_WIFI_STATIC_NETMASK_ 290
+#define SEEMP_API_apS__put_WIFI_USE_STATIC_IP_ 291
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE_ 292
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_AP_COUNT_ 293
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_ 294
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_ 295
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_ 296
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_ 297
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_MAX_AP_CHECKS_ 298
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_ON_ 299
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_PING_COUNT_ 300
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_PING_DELAY_MS_ 301
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_PING_TIMEOUT_MS_ 302
+#define SEEMP_API_Poll__setCumulativeWifiRxMBytes 303
+#define SEEMP_API_Poll__setInstantaneousWifiRxMBytes 304
+#define SEEMP_API_Poll__setCumulativeWifiRxPackets 305
+#define SEEMP_API_Poll__setInstantaneousWifiRxPackets 306
+#define SEEMP_API_Poll__setCumulativeWifiTxMBytes 307
+#define SEEMP_API_Poll__setInstantaneousWifiTxMBytes 308
+#define SEEMP_API_Poll__setCumulativeWifiTxPackets 309
+#define SEEMP_API_Poll__setInstantaneousWifiTxPackets 310
+#define SEEMP_API_Poll__setCumulativeWifiRxTcpMBytes 311
+#define SEEMP_API_Poll__setInstantaneousWifiRxTcpMBytes 312
+#define SEEMP_API_Poll__setCumulativeWifiRxTcpPackets 313
+#define SEEMP_API_Poll__setInstantaneousWifiRxTcpPackets 314
+#define SEEMP_API_Poll__setCumulativeWifiRxUdpMBytes 315
+#define SEEMP_API_Poll__setInstantaneousWifiRxUdpMBytes 316
+#define SEEMP_API_Poll__setCumulativeWifiRxUdpPackets 317
+#define SEEMP_API_Poll__setInstantaneousWifiRxUdpPackets 318
+#define SEEMP_API_Poll__setCumulativeWifiRxOtherMBytes 319
+#define SEEMP_API_Poll__setInstantaneousWifiRxOtherMBytes 320
+#define SEEMP_API_Poll__setCumulativeWifiRxOtherPackets 321
+#define SEEMP_API_Poll__setInstantaneousWifiRxOtherPackets 322
+#define SEEMP_API_Poll__setCumulativeWifiTxTcpMBytes 323
+#define SEEMP_API_Poll__setInstantaneousWifiTxTcpMBytes 324
+#define SEEMP_API_Poll__setCumulativeWifiTxTcpPackets 325
+#define SEEMP_API_Poll__setInstantaneousWifiTxTcpPackets 326
+#define SEEMP_API_Poll__setCumulativeWifiTxUdpMBytes 327
+#define SEEMP_API_Poll__setInstantaneousWifiTxUdpMBytes 328
+#define SEEMP_API_Poll__setCumulativeWifiTxUdpPackets 329
+#define SEEMP_API_Poll__setInstantaneousWifiTxUdpPackets 330
+#define SEEMP_API_Poll__setCumulativeWifiTxOtherMBytes 331
+#define SEEMP_API_Poll__setInstantaneousWifiTxOtherMBytes 332
+#define SEEMP_API_Poll__setCumulativeWifiTxOtherPackets 333
+#define SEEMP_API_Poll__setInstantaneousWifiTxOtherPackets 334
+#define SEEMP_API_Poll__setCumulativeMobileRxMBytes 335
+#define SEEMP_API_Poll__setInstantaneousMobileRxMBytes 336
+#define SEEMP_API_Poll__setCumulativeMobileRxPackets 337
+#define SEEMP_API_Poll__setInstantaneousMobileRxPackets 338
+#define SEEMP_API_Poll__setCumulativeMobileTxMBytes 339
+#define SEEMP_API_Poll__setInstantaneousMobileTxMBytes 340
+#define SEEMP_API_Poll__setCumulativeMobileTxPackets 341
+#define SEEMP_API_Poll__setInstantaneousMobileTxPackets 342
+#define SEEMP_API_Poll__setCumulativeMobileRxTcpMBytes 343
+#define SEEMP_API_Poll__setInstantaneousMobileRxTcpMBytes 344
+#define SEEMP_API_Poll__setCumulativeMobileRxTcpPackets 345
+#define SEEMP_API_Poll__setInstantaneousMobileRxTcpPackets 346
+#define SEEMP_API_Poll__setCumulativeMobileRxUdpMBytes 347
+#define SEEMP_API_Poll__setInstantaneousMobileRxUdpMBytes 348
+#define SEEMP_API_Poll__setCumulativeMobileRxUdpPackets 349
+#define SEEMP_API_Poll__setInstantaneousMobileRxUdpPackets 350
+#define SEEMP_API_Poll__setCumulativeMobileRxOtherMBytes 351
+#define SEEMP_API_Poll__setInstantaneousMobileRxOtherMBytes 352
+#define SEEMP_API_Poll__setCumulativeMobileRxOtherPackets 353
+#define SEEMP_API_Poll__setInstantaneousMobileRxOtherPackets 354
+#define SEEMP_API_Poll__setCumulativeMobileTxTcpMBytes 355
+#define SEEMP_API_Poll__setInstantaneousMobileTxTcpMBytes 356
+#define SEEMP_API_Poll__setCumulativeMobileTxTcpPackets 357
+#define SEEMP_API_Poll__setInstantaneousMobileTxTcpPackets 358
+#define SEEMP_API_Poll__setCumulativeMobileTxUdpMBytes 359
+#define SEEMP_API_Poll__setInstantaneousMobileTxUdpMBytes 360
+#define SEEMP_API_Poll__setCumulativeMobileTxUdpPackets 361
+#define SEEMP_API_Poll__setInstantaneousMobileTxUdpPackets 362
+#define SEEMP_API_Poll__setCumulativeMobileTxOtherMBytes 363
+#define SEEMP_API_Poll__setInstantaneousMobileTxOtherMBytes 364
+#define SEEMP_API_Poll__setCumulativeMobileTxOtherPackets 365
+#define SEEMP_API_Poll__setInstantaneousMobileTxOtherPackets 366
+#define SEEMP_API_Poll__setNumSockets 367
+#define SEEMP_API_Poll__setNumTcpStateListen 368
+#define SEEMP_API_Poll__setNumTcpStateEstablished 369
+#define SEEMP_API_Poll__setNumLocalIp 370
+#define SEEMP_API_Poll__setNumLocalPort 371
+#define SEEMP_API_Poll__setNumRemoteIp 372
+#define SEEMP_API_Poll__setNumRemotePort 373
+#define SEEMP_API_Poll__setNumRemoteTuple 374
+#define SEEMP_API_Poll__setNumInode 375
+#define SEEMP_API_Instrumentation__startActivitySync 376
+#define SEEMP_API_Instrumentation__execStartActivity 377
+#define SEEMP_API_Instrumentation__execStartActivitiesAsUser 378
+#define SEEMP_API_Instrumentation__execStartActivityAsCaller 379
+#define SEEMP_API_Instrumentation__execStartActivityFromAppTask 380
+#define SEEMP_API_ah_SystemSensorManager__registerListenerImpl 381
+#define SEEMP_API_ah_SystemSensorManager__unregisterListenerImpl 382
+#define SEEMP_API_WindowManagerImpl__addView 383
+#define SEEMP_API_WindowManagerImpl__updateViewLayout 384
+#define SEEMP_API_ActivityManagerService__applyOomAdjLocked 385
+#define SEEMP_API_ProcessRecord__makeActive 386
+#define SEEMP_API_ProcessRecord__makeInactive 387
+#define SEEMP_API_TelephonyManager__getSimSerialNumber 388
+#define SEEMP_API_TelephonyManager__getSubscriberId 389
+
+#endif /* _SEEMP_API_H_*/
diff --git a/include/uapi/linux/seemp_param_id.h b/include/uapi/linux/seemp_param_id.h
new file mode 100644
index 0000000..8f1f05f
--- /dev/null
+++ b/include/uapi/linux/seemp_param_id.h
@@ -0,0 +1,90 @@
+#ifndef _PARAM_ID_H_
+#define _PARAM_ID_H_
+
+#define PARAM_ID_LEN 0
+#define PARAM_ID_OOM_ADJ 1
+#define PARAM_ID_APP_UID 2
+#define PARAM_ID_APP_PID 3
+#define PARAM_ID_VALUE 4
+#define PARAM_ID_SIZE 5
+#define PARAM_ID_FD 6
+#define PARAM_ID_RATE 7
+#define PARAM_ID_SENSOR 8
+#define PARAM_ID_WINDOW_TYPE 9
+#define PARAM_ID_WINDOW_FLAG 10
+#define NUM_PARAM_IDS 11
+
+static inline int param_id_index(const char *param, const char *end)
+{
+ int id = -1;
+ int len = ((end != NULL) ? (end - param) : (int)strlen(param));
+
+ if ((len == 3) && !memcmp(param, "len", 3))
+ id = 0;
+ else if ((len == 7) && !memcmp(param, "oom_adj", 7))
+ id = 1;
+ else if ((len == 7) && !memcmp(param, "app_uid", 7))
+ id = 2;
+ else if ((len == 7) && !memcmp(param, "app_pid", 7))
+ id = 3;
+ else if ((len == 5) && !memcmp(param, "value", 5))
+ id = 4;
+ else if ((len == 4) && !memcmp(param, "size", 4))
+ id = 5;
+ else if ((len == 2) && !memcmp(param, "fd", 2))
+ id = 6;
+ else if ((len == 4) && !memcmp(param, "rate", 4))
+ id = 7;
+ else if ((len == 6) && !memcmp(param, "sensor", 6))
+ id = 8;
+ else if ((len == 11) && !memcmp(param, "window_type", 11))
+ id = 9;
+ else if ((len == 11) && !memcmp(param, "window_flag", 11))
+ id = 10;
+
+ return id;
+}
+
+static inline const char *get_param_id_name(int id)
+{
+ const char *name = "?";
+
+ switch (id) {
+ case 0:
+ name = "len";
+ break;
+ case 1:
+ name = "oom_adj";
+ break;
+ case 2:
+ name = "app_uid";
+ break;
+ case 3:
+ name = "app_pid";
+ break;
+ case 4:
+ name = "value";
+ break;
+ case 5:
+ name = "size";
+ break;
+ case 6:
+ name = "fd";
+ break;
+ case 7:
+ name = "rate";
+ break;
+ case 8:
+ name = "sensor";
+ break;
+ case 9:
+ name = "window_type";
+ break;
+ case 10:
+ name = "window_flag";
+ break;
+ }
+ return name;
+}
+
+#endif /* _PARAM_ID_H_ */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 69df75d..1d203e1 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1122,8 +1122,9 @@
if (!switch_err) {
switch_err = switch_to_fair_policy();
- pr_err("Hotplug policy switch err. Task %s pid=%d\n",
- current->comm, current->pid);
+ if (switch_err)
+ pr_err("Hotplug policy switch err=%d Task %s pid=%d\n",
+ switch_err, current->comm, current->pid);
}
return err;
diff --git a/kernel/sched/core_ctl.c b/kernel/sched/core_ctl.c
index a58bdb0..1040a43 100644
--- a/kernel/sched/core_ctl.c
+++ b/kernel/sched/core_ctl.c
@@ -35,6 +35,7 @@
unsigned int busy_down_thres[MAX_CPUS_PER_CLUSTER];
unsigned int active_cpus;
unsigned int num_cpus;
+ unsigned int nr_isolated_cpus;
cpumask_t cpu_mask;
unsigned int need_cpus;
unsigned int task_thres;
@@ -264,6 +265,7 @@
ssize_t count = 0;
unsigned int cpu;
+ spin_lock_irq(&state_lock);
for_each_possible_cpu(cpu) {
c = &per_cpu(cpu_state, cpu);
cluster = c->cluster;
@@ -297,8 +299,12 @@
count += snprintf(buf + count, PAGE_SIZE - count,
"\tNeed CPUs: %u\n", cluster->need_cpus);
count += snprintf(buf + count, PAGE_SIZE - count,
+ "\tNr isolated CPUs: %u\n",
+ cluster->nr_isolated_cpus);
+ count += snprintf(buf + count, PAGE_SIZE - count,
"\tBoost: %u\n", (unsigned int) cluster->boost);
}
+ spin_unlock_irq(&state_lock);
return count;
}
@@ -531,7 +537,7 @@
unsigned int need)
{
return (need < cluster->active_cpus || (need > cluster->active_cpus &&
- sched_isolate_count(&cluster->cpu_mask, false)));
+ cluster->nr_isolated_cpus));
}
static bool eval_need(struct cluster_data *cluster)
@@ -541,9 +547,8 @@
unsigned int need_cpus = 0, last_need, thres_idx;
int ret = 0;
bool need_flag = false;
- unsigned int active_cpus;
unsigned int new_need;
- s64 now;
+ s64 now, elapsed;
if (unlikely(!cluster->inited))
return 0;
@@ -553,8 +558,8 @@
if (cluster->boost) {
need_cpus = cluster->max_cpus;
} else {
- active_cpus = get_active_cpu_count(cluster);
- thres_idx = active_cpus ? active_cpus - 1 : 0;
+ cluster->active_cpus = get_active_cpu_count(cluster);
+ thres_idx = cluster->active_cpus ? cluster->active_cpus - 1 : 0;
list_for_each_entry(c, &cluster->lru, sib) {
if (c->busy >= cluster->busy_up_thres[thres_idx])
c->is_busy = true;
@@ -570,17 +575,16 @@
last_need = cluster->need_cpus;
now = ktime_to_ms(ktime_get());
- if (new_need == last_need) {
- cluster->need_ts = now;
- spin_unlock_irqrestore(&state_lock, flags);
- return 0;
- }
-
- if (need_cpus > cluster->active_cpus) {
+ if (new_need > cluster->active_cpus) {
ret = 1;
- } else if (need_cpus < cluster->active_cpus) {
- s64 elapsed = now - cluster->need_ts;
+ } else {
+ if (new_need == last_need) {
+ cluster->need_ts = now;
+ spin_unlock_irqrestore(&state_lock, flags);
+ return 0;
+ }
+ elapsed = now - cluster->need_ts;
ret = elapsed >= cluster->offline_delay_ms;
}
@@ -588,7 +592,7 @@
cluster->need_ts = now;
cluster->need_cpus = new_need;
}
- trace_core_ctl_eval_need(cluster->first_cpu, last_need, need_cpus,
+ trace_core_ctl_eval_need(cluster->first_cpu, last_need, new_need,
ret && need_flag);
spin_unlock_irqrestore(&state_lock, flags);
@@ -724,6 +728,7 @@
struct cpu_data *c, *tmp;
unsigned long flags;
unsigned int num_cpus = cluster->num_cpus;
+ unsigned int nr_isolated = 0;
/*
* Protect against entry being removed (and added at tail) by other
@@ -748,12 +753,14 @@
if (!sched_isolate_cpu(c->cpu)) {
c->isolated_by_us = true;
move_cpu_lru(c);
+ nr_isolated++;
} else {
pr_debug("Unable to isolate CPU%u\n", c->cpu);
}
cluster->active_cpus = get_active_cpu_count(cluster);
spin_lock_irqsave(&state_lock, flags);
}
+ cluster->nr_isolated_cpus += nr_isolated;
spin_unlock_irqrestore(&state_lock, flags);
/*
@@ -763,6 +770,7 @@
if (cluster->active_cpus <= cluster->max_cpus)
return;
+ nr_isolated = 0;
num_cpus = cluster->num_cpus;
spin_lock_irqsave(&state_lock, flags);
list_for_each_entry_safe(c, tmp, &cluster->lru, sib) {
@@ -780,12 +788,14 @@
if (!sched_isolate_cpu(c->cpu)) {
c->isolated_by_us = true;
move_cpu_lru(c);
+ nr_isolated++;
} else {
pr_debug("Unable to isolate CPU%u\n", c->cpu);
}
cluster->active_cpus = get_active_cpu_count(cluster);
spin_lock_irqsave(&state_lock, flags);
}
+ cluster->nr_isolated_cpus += nr_isolated;
spin_unlock_irqrestore(&state_lock, flags);
}
@@ -796,6 +806,7 @@
struct cpu_data *c, *tmp;
unsigned long flags;
unsigned int num_cpus = cluster->num_cpus;
+ unsigned int nr_unisolated = 0;
/*
* Protect against entry being removed (and added at tail) by other
@@ -820,12 +831,14 @@
if (!sched_unisolate_cpu(c->cpu)) {
c->isolated_by_us = false;
move_cpu_lru(c);
+ nr_unisolated++;
} else {
pr_debug("Unable to unisolate CPU%u\n", c->cpu);
}
cluster->active_cpus = get_active_cpu_count(cluster);
spin_lock_irqsave(&state_lock, flags);
}
+ cluster->nr_isolated_cpus -= nr_unisolated;
spin_unlock_irqrestore(&state_lock, flags);
}
@@ -891,10 +904,11 @@
struct cpu_data *state = &per_cpu(cpu_state, cpu);
struct cluster_data *cluster = state->cluster;
unsigned int need;
- int ret = NOTIFY_OK;
+ bool do_wakeup, unisolated = false;
+ unsigned long flags;
if (unlikely(!cluster || !cluster->inited))
- return NOTIFY_OK;
+ return NOTIFY_DONE;
switch (action & ~CPU_TASKS_FROZEN) {
case CPU_ONLINE:
@@ -917,6 +931,7 @@
if (state->isolated_by_us) {
sched_unisolate_cpu_unlocked(cpu);
state->isolated_by_us = false;
+ unisolated = true;
}
/* Move a CPU to the end of the LRU when it goes offline. */
@@ -925,13 +940,20 @@
state->busy = 0;
cluster->active_cpus = get_active_cpu_count(cluster);
break;
+ default:
+ return NOTIFY_DONE;
}
need = apply_limits(cluster, cluster->need_cpus);
- if (adjustment_possible(cluster, need))
+ spin_lock_irqsave(&state_lock, flags);
+ if (unisolated)
+ cluster->nr_isolated_cpus--;
+ do_wakeup = adjustment_possible(cluster, need);
+ spin_unlock_irqrestore(&state_lock, flags);
+ if (do_wakeup)
wake_up_core_ctl_thread(cluster);
- return ret;
+ return NOTIFY_OK;
}
static struct notifier_block __refdata cpu_notifier = {
diff --git a/net/socket.c b/net/socket.c
index 40beb5a..a4fb472 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -89,6 +89,8 @@
#include <linux/magic.h>
#include <linux/slab.h>
#include <linux/xattr.h>
+#include <linux/seemp_api.h>
+#include <linux/seemp_instrumentation.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -1646,6 +1648,8 @@
struct iovec iov;
int fput_needed;
+ seemp_logk_sendto(fd, buff, len, flags, addr, addr_len);
+
err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
if (unlikely(err))
return err;