summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt67
-rw-r--r--Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt8
-rw-r--r--Documentation/devicetree/bindings/media/video/msm-cpp.txt4
-rw-r--r--Documentation/devicetree/bindings/pci/msm_pcie.txt3
-rw-r--r--arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi76
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi11
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmi8994.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi11
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi45
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi16
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi16
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi71
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi46
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts2
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts191
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi20
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi143
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-vidc.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt.dtsi8
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi23
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-rumi.dts5
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon.dtsi25
-rw-r--r--arch/arm/boot/dts/qcom/msmtriton-rumi.dts5
-rw-r--r--arch/arm/boot/dts/qcom/msmtriton.dtsi33
-rw-r--r--arch/arm/configs/msmcortex_defconfig1
-rw-r--r--arch/arm64/configs/msm-perf_defconfig1
-rw-r--r--arch/arm64/configs/msm_defconfig1
-rw-r--r--arch/arm64/configs/msmcortex-perf_defconfig1
-rw-r--r--arch/arm64/configs/msmcortex_defconfig1
-rw-r--r--drivers/clk/msm/clock-gpu-cobalt.c3
-rw-r--r--drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c2
-rw-r--r--drivers/clk/qcom/clk-alpha-pll.c8
-rw-r--r--drivers/clk/qcom/clk-alpha-pll.h1
-rw-r--r--drivers/cpufreq/qcom-cpufreq.c32
-rw-r--r--drivers/gpu/msm/a5xx_reg.h6
-rw-r--r--drivers/gpu/msm/adreno_a4xx_preempt.c2
-rw-r--r--drivers/gpu/msm/adreno_a5xx.c38
-rw-r--r--drivers/gpu/msm/adreno_a5xx.h1
-rw-r--r--drivers/gpu/msm/kgsl_sharedmem.c7
-rw-r--r--drivers/iio/adc/qcom-rradc.c19
-rw-r--r--drivers/iio/adc/qcom-tadc.c2
-rw-r--r--drivers/iommu/arm-smmu.c52
-rw-r--r--drivers/iommu/iommu-debug.c2
-rw-r--r--drivers/leds/leds-qpnp-flash-v2.c984
-rw-r--r--drivers/leds/leds-qpnp-flash.c3
-rw-r--r--drivers/leds/leds-qpnp-wled.c82
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c74
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c3
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h22
-rw-r--r--drivers/media/platform/msm/vidc/hfi_packetization.c27
-rw-r--r--drivers/media/platform/msm/vidc/msm_v4l2_vidc.c20
-rw-r--r--drivers/media/platform/msm/vidc/msm_venc.c42
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c4
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_debug.c2
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.c18
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.h3
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_api.h8
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_helper.h10
-rw-r--r--drivers/pci/host/pci-msm.c35
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msmfalcon.c229
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa.c6
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_uc.c8
-rw-r--r--drivers/power/qcom-charger/fg-core.h37
-rw-r--r--drivers/power/qcom-charger/fg-util.c76
-rw-r--r--drivers/power/qcom-charger/qpnp-fg-gen3.c303
-rw-r--r--drivers/power/qcom-charger/qpnp-smb2.c36
-rw-r--r--drivers/power/qcom-charger/smb-lib.c234
-rw-r--r--drivers/power/qcom-charger/smb-lib.h15
-rw-r--r--drivers/power/qcom-charger/smb-reg.h4
-rw-r--r--drivers/scsi/ufs/ufshcd.c129
-rw-r--r--drivers/scsi/ufs/ufshcd.h15
-rw-r--r--drivers/soc/qcom/glink.c1
-rw-r--r--drivers/soc/qcom/icnss.c46
-rw-r--r--drivers/soc/qcom/secure_buffer.c2
-rw-r--r--drivers/soc/qcom/wlan_firmware_service_v01.c62
-rw-r--r--drivers/soc/qcom/wlan_firmware_service_v01.h22
-rw-r--r--drivers/usb/gadget/function/f_mtp.c6
-rw-r--r--drivers/usb/host/xhci-plat.c4
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c12
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_layer.c12
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c45
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pipe.c5
-rw-r--r--include/linux/iommu.h1
-rw-r--r--include/linux/qdsp6v2/apr_tal.h2
-rw-r--r--include/uapi/linux/v4l2-controls.h9
-rw-r--r--kernel/sched/core.c4
-rw-r--r--kernel/sched/core_ctl.c1
-rw-r--r--net/netfilter/xt_IDLETIMER.c2
-rw-r--r--net/rmnet_data/rmnet_data_vnd.c1
-rw-r--r--sound/soc/codecs/wcd9335.c10
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c27
-rw-r--r--sound/soc/msm/qdsp6v2/q6voice.h2
-rw-r--r--sound/soc/soc-compress.c6
96 files changed, 2843 insertions, 886 deletions
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
index 8365762e520f..4808d1dda5c1 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
@@ -11,6 +11,8 @@ Main node:
Required properties:
- compatible : Should be "qcom,qpnp-flash-led-v2"
- reg : Base address and size for flash LED modules
+- qcom,pmic-revid : phandle of PMIC revid module. This is used to
+ identify the PMIC subtype.
Optional properties:
- interrupts : Specifies the interrupts associated with flash-led.
@@ -32,6 +34,18 @@ Optional properties:
- qcom,vph-droop-debounce-us : Integer property to specify VPH droop debounce time. It is only used
if qcom,vph-droop-det is specified. Valid values are 0, 8, 16 and 26.
Unit is uS.
+- qcom,led1n2-iclamp-low-ma : Integer property to specify current clamp low
+ level for mitigation. Unit is mA. Allowed
+ values are same as under qcom,max-current.
+- qcom,led1n2-iclamp-mid-ma : Integer property to specify current clamp mid
+ level for mitigation. Unit is mA. Allowed
+ values are same as under qcom,max-current.
+- qcom,led3-iclamp-low-ma : Integer property to specify current clamp low
+ level for mitigation. Unit is mA. Allowed
+ values are same as under qcom,max-current.
+- qcom,led3-iclamp-mid-ma : Integer property to specify current clamp mid
+ level for mitigation. Unit is mA. Allowed
+ values are same as under qcom,max-current.
- qcom,vled-max-uv : Integer property for flash current predictive mitigation.
Default value is 3500000 uV.
- qcom,ibatt-ocp-threshold-ua : Integer property for flash current predictive mitigation.
@@ -64,12 +78,47 @@ Optional properties:
- qcom,thermal-derate-current : Array of currrent limits for thermal mitigation. Required if
qcom,thermal-derate-en is specified. Unit is mA. Format is
qcom,thermal-derate-current = <OTST1_LIMIT, OTST2_LIMIT, OTST3_LIMIT>.
+- qcom,otst-ramp-back-up-dis : Boolean property to disable current ramp
+ backup after thermal derate trigger is
+ deasserted.
+- qcom,thermal-derate-slow : Integer property to specify slow ramping
+ down thermal rate. Unit is in uS. Allowed
+ values are: 128, 256, 512, 1024, 2048, 4096,
+ 8192 and 314592.
+- qcom,thermal-derate-fast : Integer property to specify fast ramping
+ down thermal rate. Unit is in uS. Allowed
+ values are: 32, 64, 96, 128, 256, 384 and
+ 512.
+- qcom,thermal-debounce : Integer property to specify thermal debounce
+ time. It is only used if qcom,thermal-derate-en
+ is specified. Unit is in uS. Allowed values
+ are: 0, 16, 32, 64.
+- qcom,thermal-hysteresis : Integer property to specify thermal derating
+ hysteresis. Unit is in deciDegC. It is only
+ used if qcom,thermal-derate-en is specified.
+ Allowed values are:
+ 0, 15, 30, 45 for pmicobalt.
+ 0, 20, 40, 60 for pm2falcon.
+- qcom,thermal-thrsh1 : Integer property to specify OTST1 threshold
+ for thermal mitigation. Unit is in Celsius.
+ Accepted values are:
+ 85, 79, 73, 67, 109, 103, 97, 91.
+- qcom,thermal-thrsh2 : Integer property to specify OTST2 threshold
+ for thermal mitigation. Unit is in Celsius.
+ Accepted values are:
+ 110, 104, 98, 92, 134, 128, 122, 116.
+- qcom,thermal-thrsh3 : Integer property to specify OTST3 threshold
+ for thermal mitigation. Unit is in Celsius.
+ Accepted values are:
+ 125, 119, 113, 107, 149, 143, 137, 131.
- qcom,hw-strobe-option : Integer type to specify hardware strobe option. Based on the specified
value, additional GPIO configuration may be required to provide strobing
support. Supported values are:
0: Flash strobe is used for LED1, LED2, LED3
1: Flash strobe is used for LED1, LED2 and GPIO10 is used for LED3
2: Flash strobe is used for LED1; GPIO9 is used for LED2; GPIO10 is used for LED3
+- switchX-supply : phandle of the regulator that needs to be used
+ as a supply for flash switch_X device.
Child node: Contains settings for each individual LED. Each LED channel needs a flash node and
torch node for itself, and an individual switch node to serve as an overall switch.
@@ -126,15 +175,6 @@ Optional properties:
be edge triggered. Otherwise, it is level triggered.
- qcom,hw-strobe-active-low : Boolean property to select strobe signal polarity. If defined, hw-strobe
signal polarity is set to active-low, else it is active-high.
-- reg<n> : reg<n> (<n> represents number. e.g. 0,1,2,..) subnode is to add support for
- multiple power sources. This subnode should only be specified for switch nodes.
- Required property inside regulator node:
- - regulator-name : Name of the regulator which has to be used for this
- switch node.
- Optional property inside regulator node:
- - max-voltage-uv : This specifies max voltage of regulator. Some switch
- or boost regulator does not need this property.
-
Example:
qcom,leds@d300 {
compatible = "qcom,qpnp-flash-led-v2";
@@ -160,6 +200,7 @@ Example:
qcom,hdrm-auto-mode;
qcom,isc-delay = <192>;
+ switch0-supply = <&pmicobalt_bob>;
pmi8998_flash0: qcom,flash_0 {
label = "flash";
@@ -254,10 +295,6 @@ Example:
qcom,led-mask = <3>;
qcom,default-led-trigger =
"switch0_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
pmi8998_switch1: qcom,led_switch_1 {
@@ -266,10 +303,6 @@ Example:
qcom,led-mask = <4>;
qcom,default-led-trigger =
"switch1_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
};
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt b/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt
index ebbcfe5b2fd0..07f3fd274658 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt
@@ -25,7 +25,11 @@ Optional properties for WLED:
- linux,default-trigger : trigger for the backlight. default is NONE.
- qcom,fdbk-output : string feedback current output for wled module. The accepted values
are "wled1", "wled2", "wled3", "wled4" and "auto". default is "auto".
-- qcom,vref-mv : maximum reference voltage in mv. default is 350.
+- qcom,vref-uv : maximum reference voltage in uV.
+ For pmi8994/8952/8996, supported values are from 300000 to 675000
+ with a step size of 25000, the default value is 350000.
+ For pmicobalt/pm2falcon, supported values are from 60000 to 397500
+ with a step size of 22500, the default value is 127500.
- qcom,switch-freq-khz : switch frequency in khz. default is 800.
- qcom,ovp-mv : Over voltage protection threshold in mV. Default is
29500. Supported values are:
@@ -94,7 +98,7 @@ Example:
linux,name = "wled";
linux,default-trigger = "bkl-trigger";
qcom,fdbk-output = "auto";
- qcom,vref-mv = <350>;
+ qcom,vref-uv = <350000>;
qcom,switch-freq-khz = <800>;
qcom,ovp-mv = <29500>;
qcom,ilim-ma = <980>;
diff --git a/Documentation/devicetree/bindings/media/video/msm-cpp.txt b/Documentation/devicetree/bindings/media/video/msm-cpp.txt
index 52abf409cb65..ade5fbe8cbd7 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cpp.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cpp.txt
@@ -26,6 +26,8 @@ Required properties:
and reset lines used by this controller.
- reset-names: reset signal name strings sorted in the same order as the resets
property.
+- qcom,src-clock-rates = This is an array which holds clock rates for cpp src
+ clocks. The maximum size for the array is 10.
Required properties of the child node:
- qcom,stripe-base = Base offset of stripes in cpp payload.
@@ -107,6 +109,8 @@ Example:
<0x24 0x10000000>,
<0x28 0x10000000>,
<0x2C 0x10000000>;
+ qcom,src-clock-rates = <100000000 200000000 384000000 404000000
+ 480000000 576000000 600000000>;
qcom,cpp-fw-payload-info {
qcom,stripe-base = <553>;
qcom,plane-base = <481>;
diff --git a/Documentation/devicetree/bindings/pci/msm_pcie.txt b/Documentation/devicetree/bindings/pci/msm_pcie.txt
index 21b6d99424c0..a50e0c2b2c35 100644
--- a/Documentation/devicetree/bindings/pci/msm_pcie.txt
+++ b/Documentation/devicetree/bindings/pci/msm_pcie.txt
@@ -93,6 +93,8 @@ Optional Properties:
and assign for each endpoint.
- qcom,ep-latency: The time (unit: ms) to wait for the PCIe endpoint to become
stable after power on, before de-assert the PERST to the endpoint.
+ - qcom,wr-halt-size: With base 2, this exponent determines the size of the
+ data that PCIe core will halt on for each write transaction.
- qcom,cpl-timeout: Completion timeout value. This value specifies the time range
which the root complex will send out a completion packet if there is no response
from the endpoint.
@@ -270,6 +272,7 @@ Example:
qcom,smmu-exist;
qcom,smmu-sid-base = <0x1480>;
qcom,ep-latency = <100>;
+ qcom,wr-halt-size = <0xa>; /* 1KB */
qcom,cpl-timeout = <0x2>;
iommus = <&anoc0_smmu>;
diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi b/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi
index 76126c21c43a..8bf98d83d381 100644
--- a/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi
+++ b/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi
@@ -18,44 +18,44 @@ qcom,qrd_msmcobalt_skuk_3000mah {
qcom,battery-type = "qrd_msmcobalt_skuk_300mah";
qcom,checksum = <0x0F19>;
qcom,fg-profile-data = [
- 05 B2 1F 6F
- FC A3 0A 6E
- FD DB 1D 8C
- 1D AE 12 C2
- 23 00 18 7E
- 52 B4 45 8D
- 00 00 00 55
- 00 00 00 0F
- C5 92 00 00
- CA A0 CD 95
- 00 0C 00 1F
- EC C3 F2 56
- F3 27 06 7B
- 12 FF 01 02
- 3A 21 DA 1C
- 40 40 09 1C
- 00 05 00 07
- 05 B4 1F AC
- FC EF 0A 57
- 00 2E 1D 6A
- 14 BA 0B 12
- 22 DC 19 40
- 53 03 45 79
- 00 00 00 53
- 00 00 00 0E
- CC 05 00 00
- CA 24 BB 3A
- 00 00 00 1C
- EC C3 F2 56
- F2 A2 06 A6
- 01 C7 06 96
- 1A CF EA 8B
- 33 08 33 BA
- 00 00 10 07
- 46 66 0C 3A
- 00 19 00 1C
- FA 0A 01 98
- 00 00 00 FF
+ 6F 1F B2 05
+ 6E 0A A3 FC
+ 8C 1D DB FD
+ C2 12 AE 1D
+ 7E 18 00 23
+ 8D 45 B4 52
+ 55 00 00 00
+ 0F 00 00 00
+ 00 00 92 C5
+ 95 CD A0 CA
+ 1F 00 0C 00
+ 56 F2 C3 EC
+ 7B 06 27 F3
+ 02 01 FF 12
+ 1C DA 21 3A
+ 1C 09 40 40
+ 07 00 05 00
+ AC 1F B4 05
+ 57 0A EF FC
+ 6A 1D 2E 00
+ 12 0B BA 14
+ 40 19 DC 22
+ 79 45 03 53
+ 53 00 00 00
+ 0E 00 00 00
+ 00 00 05 CC
+ 3A BB 24 CA
+ 1C 00 00 00
+ 56 F2 C3 EC
+ A6 06 A2 F2
+ 96 06 C7 01
+ 8B EA CF 1A
+ BA 33 08 33
+ 07 10 00 00
+ 3A 0C 66 46
+ 1C 00 19 00
+ 98 01 0A FA
+ FF 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
diff --git a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi
index 41589d02f6fc..79883db10d06 100644
--- a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi
@@ -234,7 +234,7 @@
linux,name = "wled";
linux,default-trigger = "bkl-trigger";
qcom,fdbk-output = "auto";
- qcom,vref-mv = <350>;
+ qcom,vref-uv = <127500>;
qcom,switch-freq-khz = <800>;
qcom,ovp-mv = <29600>;
qcom,ilim-ma = <970>;
@@ -269,6 +269,7 @@
qcom,thermal-derate-en;
qcom,thermal-derate-current = <200 500 1000>;
qcom,isc-delay = <192>;
+ qcom,pmic-revid = <&pm2falcon_revid>;
status = "disabled";
pm2falcon_flash0: qcom,flash_0 {
@@ -357,10 +358,6 @@
qcom,led-name = "led:switch_0";
qcom,led-mask = <3>;
qcom,default-led-trigger = "switch0_trigger";
- reg0 {
- regulator-name = "pmfalcon_bob";
- max-voltage-uv = <3600000>;
- };
};
pm2falcon_switch1: qcom,led_switch_1 {
@@ -368,10 +365,6 @@
qcom,led-name = "led:switch_1";
qcom,led-mask = <4>;
qcom,default-led-trigger = "switch1_trigger";
- reg0 {
- regulator-name = "pmfalcon_bob";
- max-voltage-uv = <3600000>;
- };
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi
index c46c0963ff56..c820d213165b 100644
--- a/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi
@@ -523,7 +523,7 @@
linux,name = "wled";
linux,default-trigger = "bkl-trigger";
qcom,fdbk-output = "auto";
- qcom,vref-mv = <350>;
+ qcom,vref-uv = <350000>;
qcom,switch-freq-khz = <800>;
qcom,ovp-mv = <29500>;
qcom,ilim-ma = <980>;
diff --git a/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi b/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi
index b88b0e28c948..62db712e6979 100644
--- a/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi
@@ -598,7 +598,7 @@
linux,name = "wled";
linux,default-trigger = "bkl-trigger";
qcom,fdbk-output = "auto";
- qcom,vref-mv = <350>;
+ qcom,vref-uv = <127500>;
qcom,switch-freq-khz = <800>;
qcom,ovp-mv = <29600>;
qcom,ilim-ma = <970>;
@@ -657,6 +657,7 @@
qcom,thermal-derate-en;
qcom,thermal-derate-current = <200 500 1000>;
qcom,isc-delay = <192>;
+ qcom,pmic-revid = <&pmicobalt_revid>;
pmicobalt_flash0: qcom,flash_0 {
label = "flash";
@@ -744,10 +745,6 @@
qcom,led-name = "led:switch_0";
qcom,led-mask = <3>;
qcom,default-led-trigger = "switch0_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
pmicobalt_switch1: qcom,led_switch_1 {
@@ -755,10 +752,6 @@
qcom,led-name = "led:switch_1";
qcom,led-mask = <4>;
qcom,default-led-trigger = "switch1_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi
index 27e537c9c702..6a0061e206ca 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi
@@ -422,6 +422,8 @@
qcom,msm-bus-vector-dyn-vote;
resets = <&clock_mmss CAMSS_MICRO_BCR>;
reset-names = "micro_iface_reset";
+ qcom,src-clock-rates = <100000000 200000000 576000000
+ 600000000>;
qcom,cpp-fw-payload-info {
qcom,stripe-base = <790>;
qcom,plane-base = <715>;
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi
index 32f616e1dc7a..ffb42576ffd3 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi
@@ -3088,3 +3088,48 @@
#include "msmcobalt-mdss-pll.dtsi"
#include "msmcobalt-blsp.dtsi"
#include "msmcobalt-audio.dtsi"
+
+
+/* GPU overrides */
+&msm_gpu {
+ qcom,initial-pwrlevel = <0>;
+
+ qcom,gpu-pwrlevels {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,gpu-pwrlevels";
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <332000000>;
+ qcom,bus-freq = <7>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <8>;
+ };
+
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <251000000>;
+ qcom,bus-freq = <4>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <5>;
+ };
+
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <171000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <1>;
+ qcom,bus-max = <4>;
+ };
+
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <27000000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+
+};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi
index 75de2d70028a..0cd6d0ab1f1d 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi
@@ -269,7 +269,7 @@
batt_i@3 {
reg = <3>;
qcom,channel = <3>;
- qcom,scale = <20000000>;
+ qcom,scale = <(-20000000)>;
};
batt_v@4 {
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi
index 1db1fc5cec46..15756d13d2e0 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi
@@ -194,3 +194,19 @@
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
};
+
+/{
+ qrd_batterydata: qcom,battery-data {
+ qcom,batt-id-range-pct = <15>;
+
+ #include "batterydata-qrd-skuk-4v4-3000mah.dtsi"
+ };
+};
+
+&pmicobalt_fg {
+ qcom,battery-data = <&qrd_batterydata>;
+};
+
+&pmicobalt_haptics {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi
index 5b8585a33de6..71fd5cc1383f 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi
@@ -128,3 +128,19 @@
qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrLeft";
};
};
+
+/{
+ qrd_batterydata: qcom,battery-data {
+ qcom,batt-id-range-pct = <15>;
+
+ #include "batterydata-qrd-skuk-4v4-3000mah.dtsi"
+ };
+};
+
+&pmicobalt_fg {
+ qcom,battery-data = <&qrd_batterydata>;
+};
+
+&pmicobalt_haptics {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi
index 1ba5905bcc36..32cf1663cf43 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi
@@ -1101,6 +1101,8 @@
qcom,cpr-aging-ref-corner = <6>;
qcom,cpr-aging-ro-scaling-factor = <2950>;
qcom,allow-aging-voltage-adjustment = <0>;
+ qcom,allow-aging-open-loop-voltage-adjustment =
+ <1>;
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi
index fcc4d6d8ee2d..a81287c36266 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi
@@ -116,5 +116,76 @@
0 256000000 0>;
status = "ok";
};
+
+ qcom,cpp@ca04000 {
+ cell-index = <0>;
+ compatible = "qcom,cpp";
+ reg = <0xca04000 0x100>,
+ <0xca80000 0x3000>,
+ <0xca18000 0x3000>,
+ <0xc8c36d4 0x4>;
+ reg-names = "cpp", "cpp_vbif", "cpp_hw", "camss_cpp";
+ interrupts = <0 294 0>;
+ interrupt-names = "cpp";
+ smmu-vdd-supply = <&gdsc_bimc_smmu>;
+ camss-vdd-supply = <&gdsc_camss_top>;
+ vdd-supply = <&gdsc_cpp>;
+ qcom,vdd-names = "smmu-vdd", "camss-vdd", "vdd";
+ clocks = <&clock_gcc clk_mmssnoc_axi_clk>,
+ <&clock_mmss clk_mmss_mnoc_ahb_clk>,
+ <&clock_mmss clk_mmss_camss_ahb_clk>,
+ <&clock_mmss clk_mmss_camss_top_ahb_clk>,
+ <&clock_mmss clk_cpp_clk_src>,
+ <&clock_mmss clk_mmss_camss_cpp_clk>,
+ <&clock_mmss clk_mmss_camss_cpp_ahb_clk>,
+ <&clock_mmss clk_mmss_camss_cpp_axi_clk>,
+ <&clock_mmss clk_mmss_camss_micro_ahb_clk>,
+ <&clock_mmss clk_mmss_bimc_smmu_axi_clk>,
+ <&clock_mmss clk_mmss_camss_cpp_vbif_ahb_clk>;
+ clock-names = "mmssnoc_axi_clk",
+ "mnoc_ahb_clk",
+ "camss_ahb_clk", "camss_top_ahb_clk",
+ "cpp_src_clk",
+ "cpp_core_clk", "camss_cpp_ahb_clk",
+ "camss_cpp_axi_clk", "micro_iface_clk",
+ "mmss_smmu_axi_clk", "cpp_vbif_ahb_clk";
+ qcom,clock-rates = <0 0 0 0 200000000 200000000 0 0 0 0 0>;
+ qcom,min-clock-rate = <200000000>;
+ qcom,bus-master = <1>;
+ qcom,vbif-qos-setting = <0x20 0x10000000>,
+ <0x24 0x10000000>,
+ <0x28 0x10000000>,
+ <0x2C 0x10000000>;
+ status = "ok";
+ qcom,msm-bus,name = "msm_camera_cpp";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <106 512 0 0>,
+ <106 512 0 0>;
+ qcom,msm-bus-vector-dyn-vote;
+ resets = <&clock_mmss CAMSS_MICRO_BCR>;
+ reset-names = "micro_iface_reset";
+ qcom,src-clock-rates = <100000000 200000000 384000000 404000000
+ 480000000 576000000 600000000>;
+ qcom,cpp-fw-payload-info {
+ qcom,stripe-base = <790>;
+ qcom,plane-base = <715>;
+ qcom,stripe-size = <63>;
+ qcom,plane-size = <25>;
+ qcom,fe-ptr-off = <11>;
+ qcom,we-ptr-off = <23>;
+ qcom,ref-fe-ptr-off = <17>;
+ qcom,ref-we-ptr-off = <36>;
+ qcom,we-meta-ptr-off = <42>;
+ qcom,fe-mmu-pf-ptr-off = <7>;
+ qcom,ref-fe-mmu-pf-ptr-off = <10>;
+ qcom,we-mmu-pf-ptr-off = <13>;
+ qcom,dup-we-mmu-pf-ptr-off = <18>;
+ qcom,ref-we-mmu-pf-ptr-off = <23>;
+ qcom,set-group-buffer-len = <135>;
+ qcom,dup-frame-indicator-off = <70>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi
index 02cc86212301..46ed1f219970 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi
@@ -750,7 +750,7 @@
&msm_gpu {
/* Updated chip ID */
qcom,chipid = <0x05040001>;
- qcom,initial-pwrlevel = <5>;
+ qcom,initial-pwrlevel = <0>;
qcom,gpu-pwrlevels {
#address-cells = <1>;
@@ -760,61 +760,29 @@
qcom,gpu-pwrlevel@0 {
reg = <0>;
- qcom,gpu-freq = <670000000>;
- qcom,bus-freq = <12>;
- qcom,bus-min = <11>;
- qcom,bus-max = <12>;
- };
-
- qcom,gpu-pwrlevel@1 {
- reg = <1>;
- qcom,gpu-freq = <596000000>;
- qcom,bus-freq = <11>;
- qcom,bus-min = <9>;
- qcom,bus-max = <12>;
- };
-
- qcom,gpu-pwrlevel@2 {
- reg = <2>;
- qcom,gpu-freq = <515000000>;
- qcom,bus-freq = <11>;
- qcom,bus-min = <9>;
- qcom,bus-max = <12>;
- };
-
- qcom,gpu-pwrlevel@3 {
- reg = <3>;
- qcom,gpu-freq = <414000000>;
- qcom,bus-freq = <9>;
- qcom,bus-min = <8>;
- qcom,bus-max = <11>;
- };
-
- qcom,gpu-pwrlevel@4 {
- reg = <4>;
qcom,gpu-freq = <342000000>;
qcom,bus-freq = <8>;
qcom,bus-min = <5>;
qcom,bus-max = <9>;
};
- qcom,gpu-pwrlevel@5 {
- reg = <5>;
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
qcom,gpu-freq = <257000000>;
qcom,bus-freq = <5>;
qcom,bus-min = <3>;
qcom,bus-max = <8>;
};
- qcom,gpu-pwrlevel@6 {
- reg = <6>;
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
qcom,gpu-freq = <180000000>;
qcom,bus-freq = <3>;
qcom,bus-min = <1>;
qcom,bus-max = <5>;
};
- qcom,gpu-pwrlevel@7 {
- reg = <7>;
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
qcom,gpu-freq = <27000000>;
qcom,bus-freq = <0>;
qcom,bus-min = <0>;
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts b/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts
index 78e810b816c9..581e9fef1aeb 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts
@@ -19,5 +19,5 @@
/ {
model = "Qualcomm Technologies, Inc. MSM COBALT V2 SKUK";
compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd";
- qcom,board-id = <0x01000b 0x80>;
+ qcom,board-id = <0x01000b 0x10>;
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts b/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts
index 69a5419503ac..e5ad123f52a7 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts
@@ -21,3 +21,194 @@
compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd";
qcom,board-id = <0x03000b 0x80>;
};
+
+&slim_aud {
+ tasha_codec {
+ /delete-property/cdc-vdd-buck-supply;
+ /delete-property/cdc-buck-sido-supply;
+ /delete-property/cdc-vdd-tx-h-supply;
+ /delete-property/cdc-vdd-rx-h-supply;
+ /delete-property/cdc-vddpx-1-supply;
+ };
+
+ tavil_codec {
+ /delete-property/cdc-vdd-buck-supply;
+ /delete-property/cdc-buck-sido-supply;
+ /delete-property/cdc-vdd-tx-h-supply;
+ /delete-property/cdc-vdd-rx-h-supply;
+ /delete-property/cdc-vddpx-1-supply;
+ };
+};
+
+&clock_gcc {
+ /delete-property/vdd_dig-supply;
+ /delete-property/vdd_dig_ao-supply;
+};
+
+&clock_mmss {
+ /delete-property/vdd_dig-supply;
+ /delete-property/vdd_mmsscc_mx-supply;
+};
+
+&clock_gpu {
+ /delete-property/vdd_dig-supply;
+};
+
+&clock_gfx {
+ /delete-property/vdd_mx-supply;
+ /delete-property/vdd_gpu_mx-supply;
+};
+
+&pcie0 {
+ /delete-property/vreg-1.8-supply;
+ /delete-property/vreg-0.9-supply;
+ /delete-property/vreg-cx-supply;
+};
+
+&qusb_phy0 {
+ /delete-property/vdd-supply;
+ /delete-property/vdda18-supply;
+ /delete-property/vdda33-supply;
+};
+
+&ssphy {
+ /delete-property/vdd-supply;
+ /delete-property/core-supply;
+};
+
+&usb3 {
+ /delete-property/extcon;
+};
+
+&mdss_dsi {
+ /delete-property/vdda-1p2-supply;
+ /delete-property/vdda-0p9-supply;
+};
+
+&mdss_dsi0 {
+ /delete-property/wqhd-vddio-supply;
+ /delete-property/lab-supply;
+ /delete-property/ibb-supply;
+};
+
+&mdss_dsi1 {
+ /delete-property/wqhd-vddio-supply;
+ /delete-property/lab-supply;
+ /delete-property/ibb-supply;
+};
+
+&mdss_hdmi_pll {
+ /delete-property/vdda-pll-supply;
+ /delete-property/vdda-phy-supply;
+};
+
+&mdss_dp_ctrl {
+ /delete-property/vdda-1p2-supply;
+ /delete-property/vdda-0p9-supply;
+ /delete-property/qcom,dp-usbpd-detection;
+};
+
+&apc0_cpr {
+ /* disable aging and closed-loop */
+ /delete-property/vdd-supply;
+ /delete-property/qcom,cpr-enable;
+ /delete-property/qcom,cpr-hw-closed-loop;
+ /delete-property/qcom,cpr-aging-ref-voltage;
+};
+
+&apc0_pwrcl_vreg {
+ /delete-property/qcom,cpr-aging-max-voltage-adjustment;
+ /delete-property/qcom,cpr-aging-ref-corner;
+ /delete-property/qcom,cpr-aging-ro-scaling-factor;
+ /delete-property/qcom,allow-aging-voltage-adjustment;
+ /delete-property/qcom,allow-aging-open-loop-voltage-adjustment;
+};
+
+&apc1_cpr {
+ /* disable aging and closed-loop */
+ /delete-property/vdd-supply;
+ /delete-property/qcom,cpr-enable;
+ /delete-property/qcom,cpr-hw-closed-loop;
+ /delete-property/qcom,cpr-aging-ref-voltage;
+};
+
+&apc1_perfcl_vreg {
+ /delete-property/qcom,cpr-aging-max-voltage-adjustment;
+ /delete-property/qcom,cpr-aging-ref-corner;
+ /delete-property/qcom,cpr-aging-ro-scaling-factor;
+ /delete-property/qcom,allow-aging-voltage-adjustment;
+ /delete-property/qcom,allow-aging-open-loop-voltage-adjustment;
+};
+
+&gfx_cpr {
+ reg = <0x05061000 0x4000>,
+ <0x00784000 0x1000>;
+ reg-names = "cpr_ctrl", "fuse_base";
+
+ /* disable aging and closed-loop */
+ /delete-property/vdd-supply;
+ /delete-property/qcom,cpr-enable;
+ /delete-property/qcom,cpr-aging-ref-voltage;
+ /delete-property/qcom,cpr-aging-allowed-reg-mask;
+ /delete-property/qcom,cpr-aging-allowed-reg-value;
+};
+
+&gfx_vreg {
+ /delete-property/qcom,cpr-aging-max-voltage-adjustment;
+ /delete-property/qcom,cpr-aging-ref-corner;
+ /delete-property/qcom,cpr-aging-ro-scaling-factor;
+ /delete-property/qcom,allow-aging-voltage-adjustment;
+ /delete-property/qcom,allow-aging-open-loop-voltage-adjustment;
+};
+
+&clock_audio {
+ /delete-property/qcom,audio-ref-clk-gpio;
+};
+
+&soc {
+ /delete-node/qcom,csid@ca30000;
+ /delete-node/qcom,csid@ca30400;
+ /delete-node/qcom,csid@ca30800;
+ /delete-node/qcom,csid@ca30c00;
+
+ /delete-node/qcom,lpass@17300000;
+ /delete-node/qcom,mss@4080000;
+ /delete-node/qcom,spss@1d00000;
+ /delete-node/qcom,bcl;
+ /delete-node/qcom,msm-thermal;
+ /delete-node/qcom,ssc@5c00000;
+ /delete-node/qcom,icnss@18800000;
+ /delete-node/qcom,wil6210;
+ /delete-node/qcom,rpm-smd;
+ /delete-node/qcom,spmi@800f000;
+
+
+ rpm_bus: qcom,rpm-smd {
+ compatible = "qcom,rpm-glink";
+ qcom,glink-edge = "rpm";
+ rpm-channel-name = "rpm_requests";
+ };
+
+ spmi_bus: qcom,spmi@800f000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0x800f000 0x1000>,
+ <0x8400000 0x1000000>,
+ <0x9400000 0x1000000>,
+ <0xa400000 0x220000>,
+ <0x800a000 0x3000>;
+ reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
+ interrupt-names = "periph_irq";
+ interrupts = <GIC_SPI 326 IRQ_TYPE_NONE>;
+ qcom,ee = <0>;
+ qcom,channel = <0>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ interrupt-controller;
+ #interrupt-cells = <4>;
+ cell-index = <0>;
+ };
+};
+
+#include "msm-pmfalcon.dtsi"
+#include "msm-pm2falcon.dtsi"
+#include "msmfalcon-regulator.dtsi"
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi
index fbb1e56b7090..b257281466a9 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi
@@ -20,9 +20,6 @@
};
&ufsphy1 {
- vdda-phy-supply = <&pmcobalt_l1>;
- vdda-pll-supply = <&pmcobalt_l2>;
- vddp-ref-clk-supply = <&pmcobalt_l26>;
vdda-phy-max-microamp = <51400>;
vdda-pll-max-microamp = <14600>;
vddp-ref-clk-max-microamp = <100>;
@@ -33,9 +30,6 @@
&ufs1 {
vdd-hba-supply = <&gdsc_ufs>;
vdd-hba-fixed-regulator;
- vcc-supply = <&pmcobalt_l20>;
- vccq-supply = <&pmcobalt_l26>;
- vccq2-supply = <&pmcobalt_s4>;
vcc-max-microamp = <750000>;
vccq-max-microamp = <560000>;
vccq2-max-microamp = <750000>;
@@ -71,11 +65,9 @@
};
&sdhc_2 {
- vdd-supply = <&pmcobalt_l21>;
qcom,vdd-voltage-level = <2950000 2960000>;
qcom,vdd-current-level = <200 800000>;
- vdd-io-supply = <&pmcobalt_l13>;
qcom,vdd-io-voltage-level = <1808000 2960000>;
qcom,vdd-io-current-level = <200 22000>;
@@ -91,15 +83,3 @@
status = "ok";
};
-
-/{
- qrd_batterydata: qcom,battery-data {
- qcom,batt-id-range-pct = <15>;
-
- #include "batterydata-qrd-skuk-4v4-3000mah.dtsi"
- };
-};
-
-&pmicobalt_fg {
- qcom,battery-data = <&qrd_batterydata>;
-};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi
index f09f4d8b3adb..93b586df5640 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi
@@ -205,6 +205,24 @@
};
};
+&devfreq_memlat_0 {
+ qcom,core-dev-table =
+ < 595200 3143 >,
+ < 1324800 4173 >,
+ < 1555200 5859 >,
+ < 1747200 5859 >,
+ < 1900800 7759 >;
+};
+
+&devfreq_memlat_4 {
+ qcom,core-dev-table =
+ < 576000 3143 >,
+ < 1132800 4173 >,
+ < 1344000 5859 >,
+ < 1728000 7759 >,
+ < 1958400 11863 >,
+ < 2208000 13763 >;
+};
&clock_gcc {
compatible = "qcom,gcc-cobalt-v2";
};
@@ -227,7 +245,8 @@
< 414000000 4 RPM_SMD_REGULATOR_LEVEL_SVS >,
< 515000000 5 RPM_SMD_REGULATOR_LEVEL_NOM >,
< 596000000 6 RPM_SMD_REGULATOR_LEVEL_NOM >,
- < 670000000 7 RPM_SMD_REGULATOR_LEVEL_TURBO >;
+ < 670000000 7 RPM_SMD_REGULATOR_LEVEL_TURBO >,
+ < 710000000 8 RPM_SMD_REGULATOR_LEVEL_TURBO >;
qcom,gfxfreq-mx-speedbin0 =
< 0 0 >,
< 180000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
@@ -236,7 +255,8 @@
< 414000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
< 515000000 RPM_SMD_REGULATOR_LEVEL_NOM >,
< 596000000 RPM_SMD_REGULATOR_LEVEL_NOM >,
- < 670000000 RPM_SMD_REGULATOR_LEVEL_TURBO >;
+ < 670000000 RPM_SMD_REGULATOR_LEVEL_TURBO >,
+ < 710000000 RPM_SMD_REGULATOR_LEVEL_TURBO >;
};
&mdss_mdp {
@@ -438,43 +458,43 @@
qcom,cpr-open-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>,
/* Speed bin 1 */
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>;
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>;
qcom,cpr-closed-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>,
/* Speed bin 1 */
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>;
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>;
qcom,allow-voltage-interpolation;
qcom,allow-quotient-interpolation;
@@ -483,8 +503,8 @@
qcom,cpr-aging-ref-corner = <22 22>;
qcom,cpr-aging-ro-scaling-factor = <1620>;
qcom,allow-aging-voltage-adjustment =
- <0 0 0 1 1 1 1 1>,
- <0 0 0 1 1 1 1 1>;
+ <0 0 0 0 1 1 1 1>,
+ <0 0 0 0 1 1 1 1>;
};
&apc1_cpr {
@@ -601,19 +621,19 @@
qcom,cpr-open-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- <8000 0 0 52000>,
- <8000 0 0 52000>,
- <8000 0 0 52000>,
- <(-7000) (-15000) (-15000) 37000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
<(-7000) (-15000) (-15000) 37000>,
<(-7000) (-15000) (-15000) 37000>,
<(-7000) (-15000) (-15000) 37000>,
<(-7000) (-15000) (-15000) 37000>,
/* Speed bin 1 */
- <8000 0 0 52000>,
- <8000 0 0 52000>,
- <8000 0 0 52000>,
- <(-7000) (-15000) (-15000) 37000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
<(-7000) (-15000) (-15000) 37000>,
<(-7000) (-15000) (-15000) 37000>,
<(-7000) (-15000) (-15000) 37000>,
@@ -621,19 +641,19 @@
qcom,cpr-closed-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- <0 0 0 50000>,
- <0 0 0 50000>,
- <0 0 0 50000>,
- <(-15000) (-15000) (-15000) 35000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
<(-15000) (-15000) (-15000) 35000>,
<(-15000) (-15000) (-15000) 35000>,
<(-15000) (-15000) (-15000) 35000>,
<(-15000) (-15000) (-15000) 35000>,
/* Speed bin 1 */
- <0 0 0 50000>,
- <0 0 0 50000>,
- <0 0 0 50000>,
- <(-15000) (-15000) (-15000) 35000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
<(-15000) (-15000) (-15000) 35000>,
<(-15000) (-15000) (-15000) 35000>,
<(-15000) (-15000) (-15000) 35000>,
@@ -646,8 +666,8 @@
qcom,cpr-aging-ref-corner = <30 26>;
qcom,cpr-aging-ro-scaling-factor = <1700>;
qcom,allow-aging-voltage-adjustment =
- <0 0 0 1 1 1 1 1>,
- <0 0 0 1 1 1 1 1>;
+ <0 0 0 0 1 1 1 1>,
+ <0 0 0 0 1 1 1 1>;
};
&pm8005_s1 {
@@ -728,7 +748,7 @@
qcom,cpr-open-loop-voltage-fuse-adjustment =
< 60000 0 0 0>,
< 60000 0 0 0>,
- < 45000 (-15000) (-15000) (-15000)>,
+ < 60000 0 0 0>,
< 45000 (-15000) (-15000) (-15000)>,
< 45000 (-15000) (-15000) (-15000)>,
< 45000 (-15000) (-15000) (-15000)>,
@@ -740,8 +760,8 @@
0 29000 11000 0>,
< 90000 38000 28000 8000
0 29000 11000 0>,
- < 75000 23000 13000 (-7000)
- (-15000) 14000 (-4000) (-15000)>,
+ < 90000 38000 28000 8000
+ 0 29000 11000 0>,
< 75000 23000 13000 (-7000)
(-15000) 14000 (-4000) (-15000)>,
< 75000 23000 13000 (-7000)
@@ -765,7 +785,7 @@
qcom,cpr-aging-max-voltage-adjustment = <15000>;
qcom,cpr-aging-ref-corner = <8>;
qcom,cpr-aging-ro-scaling-factor = <1620>;
- qcom,allow-aging-voltage-adjustment = <0 0 1 1 1 1 1 1>;
+ qcom,allow-aging-voltage-adjustment = <0 0 0 1 1 1 1 1>;
};
&qusb_phy0 {
@@ -909,13 +929,6 @@
qcom,gpu-pwrlevel@6 {
reg = <6>;
- qcom,gpu-freq = <180000000>;
- qcom,bus-freq = <3>;
- qcom,bus-min = <1>;
- qcom,bus-max = <5>;
- };
- qcom,gpu-pwrlevel@7 {
- reg = <7>;
qcom,gpu-freq = <27000000>;
qcom,bus-freq = <0>;
qcom,bus-min = <0>;
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-vidc.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-vidc.dtsi
index f17be7570742..a8655c2e88a0 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-vidc.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-vidc.dtsi
@@ -25,6 +25,7 @@
qcom,firmware-name = "venus";
qcom,never-unload-fw;
qcom,sw-power-collapse;
+ qcom,max-secure-instances = <5>;
qcom,debug-timeout;
qcom,reg-presets =
<0x80124 0x00000003>,
diff --git a/arch/arm/boot/dts/qcom/msmcobalt.dtsi b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
index 328ae458eb06..9b0d3f674032 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
@@ -611,7 +611,7 @@
< 13763 /* 1804 MHz */ >;
};
- qcom,arm-memlat-mon-0 {
+ devfreq_memlat_0: qcom,arm-memlat-mon-0 {
compatible = "qcom,arm-memlat-mon";
qcom,cpulist = <&CPU0 &CPU1 &CPU2 &CPU3>;
qcom,target-dev = <&memlat_cpu0>;
@@ -622,7 +622,7 @@
< 1881600 5859 >;
};
- qcom,arm-memlat-mon-4 {
+ devfreq_memlat_4: qcom,arm-memlat-mon-4 {
compatible = "qcom,arm-memlat-mon";
qcom,cpulist = <&CPU4 &CPU5 &CPU6 &CPU7>;
qcom,target-dev = <&memlat_cpu4>;
@@ -1568,6 +1568,10 @@
qcom,vreg-cx-voltage-level = <RPM_SMD_REGULATOR_LEVEL_BINNING
RPM_SMD_REGULATOR_LEVEL_SVS 0>;
+ qcom,l1-supported;
+ qcom,l1ss-supported;
+ qcom,aux-clk-sync;
+
qcom,ep-latency = <10>;
qcom,ep-wakeirq;
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi
index 75cf4de97672..cfe968a7310a 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi
@@ -142,6 +142,7 @@
};
rpm-regulator-ldoa2 {
+ status = "okay";
pmfalcon_l2: regulator-l2 {
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1010000>;
@@ -150,6 +151,7 @@
};
rpm-regulator-ldoa3 {
+ status = "okay";
pmfalcon_l3: regulator-l3 {
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1010000>;
@@ -159,6 +161,7 @@
/* TODO: remove if ADRASTEA CX/MX not voted from APPS */
rpm-regulator-ldoa5 {
+ status = "okay";
pmfalcon_l5: regulator-l5 {
regulator-min-microvolt = <525000>;
regulator-max-microvolt = <950000>;
@@ -167,6 +170,7 @@
};
rpm-regulator-ldoa6 {
+ status = "okay";
pmfalcon_l6: regulator-l6 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1370000>;
@@ -175,6 +179,7 @@
};
rpm-regulator-ldoa7 {
+ status = "okay";
pmfalcon_l7: regulator-l7 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
@@ -183,6 +188,7 @@
};
rpm-regulator-ldoa8 {
+ status = "okay";
pmfalcon_l8: regulator-l8 {
regulator-min-microvolt = <1750000>;
regulator-max-microvolt = <1900000>;
@@ -191,6 +197,7 @@
};
rpm-regulator-ldoa9 {
+ status = "okay";
pmfalcon_l9: regulator-l9 {
regulator-min-microvolt = <1750000>;
regulator-max-microvolt = <1900000>;
@@ -199,6 +206,7 @@
};
rpm-regulator-ldoa10 {
+ status = "okay";
pmfalcon_l10: regulator-l10 {
regulator-min-microvolt = <1780000>;
regulator-max-microvolt = <1950000>;
@@ -207,6 +215,7 @@
};
rpm-regulator-ldoa11 {
+ status = "okay";
pmfalcon_l11: regulator-l11 {
regulator-min-microvolt = <1780000>;
regulator-max-microvolt = <1950000>;
@@ -215,6 +224,7 @@
};
rpm-regulator-ldoa12 {
+ status = "okay";
pmfalcon_l12: regulator-l12 {
regulator-min-microvolt = <1780000>;
regulator-max-microvolt = <1950000>;
@@ -223,6 +233,7 @@
};
rpm-regulator-ldoa13 {
+ status = "okay";
pmfalcon_l13: regulator-l13 {
regulator-min-microvolt = <1780000>;
regulator-max-microvolt = <1950000>;
@@ -231,6 +242,7 @@
};
rpm-regulator-ldoa14 {
+ status = "okay";
pmfalcon_l14: regulator-l14 {
regulator-min-microvolt = <1710000>;
regulator-max-microvolt = <1900000>;
@@ -239,6 +251,7 @@
};
rpm-regulator-ldoa15 {
+ status = "okay";
pmfalcon_l15: regulator-l15 {
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <2950000>;
@@ -247,6 +260,7 @@
};
rpm-regulator-ldoa17 {
+ status = "okay";
pmfalcon_l17: regulator-l17 {
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <2950000>;
@@ -255,6 +269,7 @@
};
rpm-regulator-ldoa19 {
+ status = "okay";
pmfalcon_l19: regulator-l19 {
regulator-min-microvolt = <3200000>;
regulator-max-microvolt = <3400000>;
@@ -263,6 +278,7 @@
};
rpm-regulator-ldob1 {
+ status = "okay";
pm2falcon_l1: regulator-l1 {
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <925000>;
@@ -271,6 +287,7 @@
};
rpm-regulator-ldob2 {
+ status = "okay";
pm2falcon_l2: regulator-l2 {
regulator-min-microvolt = <350000>;
regulator-max-microvolt = <3100000>;
@@ -279,6 +296,7 @@
};
rpm-regulator-ldob3 {
+ status = "okay";
pm2falcon_l3: regulator-l3 {
regulator-min-microvolt = <1710000>;
regulator-max-microvolt = <3600000>;
@@ -287,6 +305,7 @@
};
rpm-regulator-ldob4 {
+ status = "okay";
pm2falcon_l4: regulator-l4 {
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <2950000>;
@@ -295,6 +314,7 @@
};
rpm-regulator-ldob5 {
+ status = "okay";
pm2falcon_l5: regulator-l5 {
regulator-min-microvolt = <1721000>;
regulator-max-microvolt = <3600000>;
@@ -303,6 +323,7 @@
};
rpm-regulator-ldob6 {
+ status = "okay";
pm2falcon_l6: regulator-l6 {
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <3300000>;
@@ -311,6 +332,7 @@
};
rpm-regulator-ldob7 {
+ status = "okay";
pm2falcon_l7: regulator-l7 {
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3125000>;
@@ -319,6 +341,7 @@
};
rpm-regulator-ldob8 {
+ status = "okay";
pm2falcon_l8: regulator-l8 {
regulator-min-microvolt = <3200000>;
regulator-max-microvolt = <3400000>;
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts
index 9d76681bab2d..c94ba0df3e6e 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts
+++ b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts
@@ -57,3 +57,8 @@
status = "ok";
};
+
+&clock_gcc {
+ compatible = "qcom,dummycc";
+ clock-output-names = "gcc_clocks";
+};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi
index b035bc3c0f14..473270d6e87d 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi
@@ -345,6 +345,31 @@
clock-names = "core", "iface";
};
+ slim_aud: slim@151c0000 {
+ cell-index = <1>;
+ compatible = "qcom,slim-ngd";
+ reg = <0x151c0000 0x2c000>,
+ <0x15180000 0x2e000>;
+ reg-names = "slimbus_physical", "slimbus_bam_physical";
+ interrupts = <0 163 0>, <0 164 0>;
+ interrupt-names = "slimbus_irq", "slimbus_bam_irq";
+ qcom,apps-ch-pipes = <0x7e0000>;
+ qcom,ea-pc = <0x260>;
+ status = "disabled";
+ };
+
+ slim_qca: slim@15240000 {
+ cell-index = <3>;
+ compatible = "qcom,slim-ngd";
+ reg = <0x15240000 0x2c000>,
+ <0x15200000 0x24000>;
+ reg-names = "slimbus_physical", "slimbus_bam_physical";
+ interrupts = <0 291 0>, <0 292 0>;
+ interrupt-names = "slimbus_irq", "slimbus_bam_irq";
+ qcom,apps-ch-pipes = <0x1800>;
+ status = "disabled";
+ };
+
timer@17920000 {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom/msmtriton-rumi.dts b/arch/arm/boot/dts/qcom/msmtriton-rumi.dts
index d3c62dbf99f2..0317c35d1f44 100644
--- a/arch/arm/boot/dts/qcom/msmtriton-rumi.dts
+++ b/arch/arm/boot/dts/qcom/msmtriton-rumi.dts
@@ -27,3 +27,8 @@
pinctrl-names = "default";
pinctrl-0 = <&uart_console_active>;
};
+
+&clock_gcc {
+ compatible = "qcom,dummycc";
+ clock-output-names = "gcc_clocks";
+};
diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi
index 49fa1ac7f192..06f296a49113 100644
--- a/arch/arm/boot/dts/qcom/msmtriton.dtsi
+++ b/arch/arm/boot/dts/qcom/msmtriton.dtsi
@@ -246,6 +246,32 @@
qcom,pipe-attr-ee;
};
+ qcom,memshare {
+ compatible = "qcom,memshare";
+
+ qcom,client_1 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x200000>;
+ qcom,client-id = <0>;
+ qcom,allocate-boot-time;
+ label = "modem";
+ };
+
+ qcom,client_2 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x300000>;
+ qcom,client-id = <2>;
+ label = "modem";
+ };
+
+ mem_client_3_size: qcom,client_3 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x0>;
+ qcom,client-id = <1>;
+ label = "modem";
+ };
+ };
+
tsens: tsens@10ad000 {
compatible = "qcom,msmtriton-tsens";
reg = <0x10ad000 0x2000>;
@@ -505,6 +531,13 @@
qcom,xprt = "smem";
};
+ rpm_bus: qcom,rpm-smd {
+ compatible = "qcom,rpm-glink";
+ qcom,glink-edge = "rpm";
+ rpm-channel-name = "rpm_requests";
+ rpm-standalone;
+ };
+
qcom,ipc_router {
compatible = "qcom,ipc_router";
qcom,node-id = <1>;
diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig
index f843a98ee130..f8743e760054 100644
--- a/arch/arm/configs/msmcortex_defconfig
+++ b/arch/arm/configs/msmcortex_defconfig
@@ -27,6 +27,7 @@ CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_ARCH_MMAP_RND_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig
index 5f8b02904d49..520a60c46106 100644
--- a/arch/arm64/configs/msm-perf_defconfig
+++ b/arch/arm64/configs/msm-perf_defconfig
@@ -32,6 +32,7 @@ CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig
index c1c0ae9da001..6249b604466b 100644
--- a/arch/arm64/configs/msm_defconfig
+++ b/arch/arm64/configs/msm_defconfig
@@ -29,6 +29,7 @@ CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig
index df65a3db12f5..3990bece1dd1 100644
--- a/arch/arm64/configs/msmcortex-perf_defconfig
+++ b/arch/arm64/configs/msmcortex-perf_defconfig
@@ -35,6 +35,7 @@ CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig
index 2f7dfa9216b1..15ca50859eca 100644
--- a/arch/arm64/configs/msmcortex_defconfig
+++ b/arch/arm64/configs/msmcortex_defconfig
@@ -34,6 +34,7 @@ CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
diff --git a/drivers/clk/msm/clock-gpu-cobalt.c b/drivers/clk/msm/clock-gpu-cobalt.c
index 9d93351a083e..7cec9be1f42c 100644
--- a/drivers/clk/msm/clock-gpu-cobalt.c
+++ b/drivers/clk/msm/clock-gpu-cobalt.c
@@ -173,6 +173,7 @@ static struct clk_freq_tbl ftbl_gfx3d_clk_src_v2[] = {
F_SLEW( 515000000, 1030000000, gpu_pll0_pll_out_even, 1, 0, 0),
F_SLEW( 596000000, 1192000000, gpu_pll0_pll_out_even, 1, 0, 0),
F_SLEW( 670000000, 1340000000, gpu_pll0_pll_out_even, 1, 0, 0),
+ F_SLEW( 710000000, 1420000000, gpu_pll0_pll_out_even, 1, 0, 0),
F_END
};
@@ -611,7 +612,7 @@ static void msm_gfxcc_hamster_fixup(void)
static void msm_gfxcc_cobalt_v2_fixup(void)
{
- gpu_pll0_pll.c.fmax[VDD_DIG_MIN] = 1340000500;
+ gpu_pll0_pll.c.fmax[VDD_DIG_MIN] = 1420000500;
gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_v2;
}
diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
index f23f32f7e37a..93bbcf5d40f5 100644
--- a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
+++ b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
@@ -275,7 +275,7 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate)
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00);
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_DIV_FRAC_START3_MODE0, 0xa0);
+ QSERDES_COM_DIV_FRAC_START3_MODE0, 0x0a);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_CMN_CONFIG, 0x12);
MDSS_PLL_REG_W(dp_res->pll_base,
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 1501c5da4a6c..085b9acfb9d5 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -221,8 +221,6 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
if (pll->flags & SUPPORTS_FSM_MODE)
clk_alpha_set_fsm_mode(pll);
-
- pll->inited = true;
}
static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
@@ -288,12 +286,6 @@ static int clk_alpha_pll_enable(struct clk_hw *hw)
u32 val, mask, off;
off = pll->offset;
-
- if (unlikely(!pll->inited)) {
- clk_alpha_pll_configure(pll, pll->clkr.regmap,
- pll->config);
- }
-
mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
if (ret)
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index 425cf3afef9e..9b1d3ee61cac 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -39,7 +39,6 @@ struct pll_vco {
struct clk_alpha_pll {
u32 offset;
struct pll_config *config;
- bool inited;
const struct pll_vco *vco_table;
size_t num_vco;
diff --git a/drivers/cpufreq/qcom-cpufreq.c b/drivers/cpufreq/qcom-cpufreq.c
index 82861b1dbe46..2aa7b783f276 100644
--- a/drivers/cpufreq/qcom-cpufreq.c
+++ b/drivers/cpufreq/qcom-cpufreq.c
@@ -3,7 +3,7 @@
* MSM architecture cpufreq driver
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2007-2016, The Linux Foundation. All rights reserved.
* Author: Mike A. Chan <mikechan@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -320,7 +320,7 @@ static struct cpufreq_driver msm_cpufreq_driver = {
static struct cpufreq_frequency_table *cpufreq_parse_dt(struct device *dev,
char *tbl_name, int cpu)
{
- int ret, nf, i;
+ int ret, nf, i, j;
u32 *data;
struct cpufreq_frequency_table *ftbl;
@@ -344,6 +344,7 @@ static struct cpufreq_frequency_table *cpufreq_parse_dt(struct device *dev,
if (!ftbl)
return ERR_PTR(-ENOMEM);
+ j = 0;
for (i = 0; i < nf; i++) {
unsigned long f;
@@ -353,29 +354,20 @@ static struct cpufreq_frequency_table *cpufreq_parse_dt(struct device *dev,
f /= 1000;
/*
- * Check if this is the last feasible frequency in the table.
+ * Don't repeat frequencies if they round up to the same clock
+ * frequency.
*
- * The table listing frequencies higher than what the HW can
- * support is not an error since the table might be shared
- * across CPUs in different speed bins. It's also not
- * sufficient to check if the rounded rate is lower than the
- * requested rate as it doesn't cover the following example:
- *
- * Table lists: 2.2 GHz and 2.5 GHz.
- * Rounded rate returns: 2.2 GHz and 2.3 GHz.
- *
- * In this case, we can CPUfreq to use 2.2 GHz and 2.3 GHz
- * instead of rejecting the 2.5 GHz table entry.
*/
- if (i > 0 && f <= ftbl[i-1].frequency)
- break;
+ if (j > 0 && f <= ftbl[j - 1].frequency)
+ continue;
- ftbl[i].driver_data = i;
- ftbl[i].frequency = f;
+ ftbl[j].driver_data = j;
+ ftbl[j].frequency = f;
+ j++;
}
- ftbl[i].driver_data = i;
- ftbl[i].frequency = CPUFREQ_TABLE_END;
+ ftbl[j].driver_data = j;
+ ftbl[j].frequency = CPUFREQ_TABLE_END;
devm_kfree(dev, data);
diff --git a/drivers/gpu/msm/a5xx_reg.h b/drivers/gpu/msm/a5xx_reg.h
index 436b6949c414..ef2861ca96dd 100644
--- a/drivers/gpu/msm/a5xx_reg.h
+++ b/drivers/gpu/msm/a5xx_reg.h
@@ -893,6 +893,11 @@
#define A5XX_GDPM_INT_MASK 0xB811
#define A5XX_GPMU_BEC_ENABLE 0xB9A0
+/* ISENSE registers */
+#define A5XX_GPU_CS_DECIMAL_ALIGN 0xC16A
+#define A5XX_GPU_CS_SENSOR_PARAM_CORE_1 0xC126
+#define A5XX_GPU_CS_SENSOR_PARAM_CORE_2 0xC127
+#define A5XX_GPU_CS_SW_OV_FUSE_EN 0xC168
#define A5XX_GPU_CS_SENSOR_GENERAL_STATUS 0xC41A
#define A5XX_GPU_CS_AMP_CALIBRATION_STATUS1_0 0xC41D
#define A5XX_GPU_CS_AMP_CALIBRATION_STATUS1_2 0xC41F
@@ -900,5 +905,6 @@
#define A5XX_GPU_CS_ENABLE_REG 0xC520
#define A5XX_GPU_CS_AMP_CALIBRATION_CONTROL1 0xC557
#define A5XX_GPU_CS_AMP_CALIBRATION_DONE 0xC565
+#define A5XX_GPU_CS_ENDPOINT_CALIBRATION_DONE 0xC556
#endif /* _A5XX_REG_H */
diff --git a/drivers/gpu/msm/adreno_a4xx_preempt.c b/drivers/gpu/msm/adreno_a4xx_preempt.c
index 4087ac60c89e..ef837dc4b7ea 100644
--- a/drivers/gpu/msm/adreno_a4xx_preempt.c
+++ b/drivers/gpu/msm/adreno_a4xx_preempt.c
@@ -146,6 +146,8 @@ static int a4xx_submit_preempt_token(struct adreno_ringbuffer *rb,
&ptname, PT_INFO_OFFSET(current_rb_ptname));
pt = kgsl_mmu_get_pt_from_ptname(&(device->mmu),
ptname);
+ if (IS_ERR_OR_NULL(pt))
+ return (pt == NULL) ? -ENOENT : PTR_ERR(pt);
/* set the ringbuffer for incoming RB */
pt_switch_sizedwords =
adreno_iommu_set_pt_generate_cmds(incoming_rb,
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index f652e955b07c..5dad7fd3bf4d 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -431,6 +431,43 @@ static int _poll_gdsc_status(struct adreno_device *adreno_dev,
return 0;
}
+static void a5xx_restore_isense_regs(struct adreno_device *adreno_dev)
+{
+ struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
+ unsigned int reg, i, ramp = GPMU_ISENSE_SAVE;
+ static unsigned int isense_regs[6] = {0xFFFF}, isense_reg_addr[] = {
+ A5XX_GPU_CS_DECIMAL_ALIGN,
+ A5XX_GPU_CS_SENSOR_PARAM_CORE_1,
+ A5XX_GPU_CS_SENSOR_PARAM_CORE_2,
+ A5XX_GPU_CS_SW_OV_FUSE_EN,
+ A5XX_GPU_CS_ENDPOINT_CALIBRATION_DONE,
+ A5XX_GPMU_TEMP_SENSOR_CONFIG};
+
+ if (!adreno_is_a540(adreno_dev))
+ return;
+
+ /* read signature */
+ kgsl_regread(device, ramp++, &reg);
+
+ if (reg == 0xBABEFACE) {
+ /* store memory locations in buffer */
+ for (i = 0; i < ARRAY_SIZE(isense_regs); i++)
+ kgsl_regread(device, ramp + i, isense_regs + i);
+
+ /* clear signature */
+ kgsl_regwrite(device, GPMU_ISENSE_SAVE, 0x0);
+ }
+
+ /* if we never stored memory locations - do nothing */
+ if (isense_regs[0] == 0xFFFF)
+ return;
+
+ /* restore registers from memory */
+ for (i = 0; i < ARRAY_SIZE(isense_reg_addr); i++)
+ kgsl_regwrite(device, isense_reg_addr[i], isense_regs[i]);
+
+}
+
/*
* a5xx_regulator_enable() - Enable any necessary HW regulators
* @adreno_dev: The adreno device pointer
@@ -480,6 +517,7 @@ static int a5xx_regulator_enable(struct adreno_device *adreno_dev)
kgsl_regrmw(device, A5XX_GPMU_GPMU_SP_CLOCK_CONTROL,
CNTL_IP_CLK_ENABLE, 1);
+ a5xx_restore_isense_regs(adreno_dev);
return 0;
}
diff --git a/drivers/gpu/msm/adreno_a5xx.h b/drivers/gpu/msm/adreno_a5xx.h
index e424e7a9f228..08fd16a83f30 100644
--- a/drivers/gpu/msm/adreno_a5xx.h
+++ b/drivers/gpu/msm/adreno_a5xx.h
@@ -228,6 +228,7 @@ void a5xx_hwcg_set(struct adreno_device *adreno_dev, bool on);
#define LM_SEQUENCE_ID 1
#define MAX_SEQUENCE_ID 3
+#define GPMU_ISENSE_SAVE (A5XX_GPMU_DATA_RAM_BASE + 200/4)
/* LM defaults */
#define LM_DEFAULT_LIMIT 6000
#define A530_DEFAULT_LEAKAGE 0x004E001A
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 72895c18119f..618e9e9a33a3 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -574,12 +574,11 @@ int kgsl_cache_range_op(struct kgsl_memdesc *memdesc, uint64_t offset,
void *addr = (memdesc->hostptr) ?
memdesc->hostptr : (void *) memdesc->useraddr;
- /* Make sure that size is non-zero */
- if (!size)
+ if (size == 0 || size > UINT_MAX)
return -EINVAL;
- /* Make sure that the offset + size isn't bigger than we can handle */
- if ((offset + size) > ULONG_MAX)
+ /* Make sure that the offset + size does not overflow */
+ if ((offset + size < offset) || (offset + size < size))
return -ERANGE;
/* Make sure the offset + size do not overflow the address */
diff --git a/drivers/iio/adc/qcom-rradc.c b/drivers/iio/adc/qcom-rradc.c
index ebb49230d4d7..e08de7a808eb 100644
--- a/drivers/iio/adc/qcom-rradc.c
+++ b/drivers/iio/adc/qcom-rradc.c
@@ -165,7 +165,8 @@
#define FG_ADC_RR_CHG_THRESHOLD_SCALE 4
#define FG_ADC_RR_VOLT_INPUT_FACTOR 8
-#define FG_ADC_RR_CURR_INPUT_FACTOR 2
+#define FG_ADC_RR_CURR_INPUT_FACTOR 2000
+#define FG_ADC_RR_CURR_USBIN_INPUT_FACTOR_MIL 1886
#define FG_ADC_SCALE_MILLI_FACTOR 1000
#define FG_ADC_KELVINMIL_CELSIUSMIL 273150
@@ -323,12 +324,20 @@ static int rradc_post_process_curr(struct rradc_chip *chip,
struct rradc_chan_prop *prop, u16 adc_code,
int *result_ua)
{
- int64_t ua = 0;
+ int64_t ua = 0, scale = 0;
- /* 0.5 V/A; 2.5V ADC full scale */
- ua = ((int64_t)adc_code * FG_ADC_RR_CURR_INPUT_FACTOR);
+ if (!prop)
+ return -EINVAL;
+
+ if (prop->channel == RR_ADC_USBIN_I)
+ scale = FG_ADC_RR_CURR_USBIN_INPUT_FACTOR_MIL;
+ else
+ scale = FG_ADC_RR_CURR_INPUT_FACTOR;
+
+ /* scale * V/A; 2.5V ADC full scale */
+ ua = ((int64_t)adc_code * scale);
ua *= (FG_ADC_RR_FS_VOLTAGE_MV * FG_ADC_SCALE_MILLI_FACTOR);
- ua = div64_s64(ua, FG_MAX_ADC_READINGS);
+ ua = div64_s64(ua, (FG_MAX_ADC_READINGS * 1000));
*result_ua = ua;
return 0;
diff --git a/drivers/iio/adc/qcom-tadc.c b/drivers/iio/adc/qcom-tadc.c
index 3cc2694f9a03..4a56847a43e7 100644
--- a/drivers/iio/adc/qcom-tadc.c
+++ b/drivers/iio/adc/qcom-tadc.c
@@ -398,7 +398,7 @@ static int tadc_do_conversion(struct tadc_chip *chip, u8 channels, s16 *adc)
}
for (i = 0; i < TADC_NUM_CH; i++)
- adc[i] = val[i * 2] | val[i * 2 + 1] << BITS_PER_BYTE;
+ adc[i] = (s16)(val[i * 2] | (u16)val[i * 2 + 1] << 8);
return jiffies_to_msecs(timeout - timeleft);
}
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index fda10abae58a..eac6d07e6097 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -528,6 +528,8 @@ static bool arm_smmu_is_static_cb(struct arm_smmu_device *smmu);
static bool arm_smmu_is_slave_side_secure(struct arm_smmu_domain *smmu_domain);
static bool arm_smmu_has_secure_vmid(struct arm_smmu_domain *smmu_domain);
+static int arm_smmu_enable_s1_translations(struct arm_smmu_domain *smmu_domain);
+
static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
{
return container_of(dom, struct arm_smmu_domain, domain);
@@ -1604,7 +1606,8 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
/* SCTLR */
reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_EAE_SBOP;
- if (!(smmu_domain->attributes & (1 << DOMAIN_ATTR_S1_BYPASS)) ||
+ if ((!(smmu_domain->attributes & (1 << DOMAIN_ATTR_S1_BYPASS)) &&
+ !(smmu_domain->attributes & (1 << DOMAIN_ATTR_EARLY_MAP))) ||
!stage1)
reg |= SCTLR_M;
if (stage1)
@@ -1651,7 +1654,7 @@ static void arm_smmu_secure_domain_unlock(struct arm_smmu_domain *smmu_domain)
static unsigned long arm_smmu_pgtbl_lock(struct arm_smmu_domain *smmu_domain)
{
- unsigned long flags;
+ unsigned long flags = 0;
if (arm_smmu_is_slave_side_secure(smmu_domain))
mutex_lock(&smmu_domain->pgtbl_mutex_lock);
@@ -3043,6 +3046,11 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
ret = 0;
break;
}
+ case DOMAIN_ATTR_EARLY_MAP:
+ *((int *)data) = !!(smmu_domain->attributes
+ & (1 << DOMAIN_ATTR_EARLY_MAP));
+ ret = 0;
+ break;
default:
ret = -ENODEV;
break;
@@ -3148,6 +3156,24 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
smmu_domain->attributes |= 1 << DOMAIN_ATTR_FAST;
ret = 0;
break;
+ case DOMAIN_ATTR_EARLY_MAP: {
+ int early_map = *((int *)data);
+
+ ret = 0;
+ if (early_map) {
+ smmu_domain->attributes |=
+ 1 << DOMAIN_ATTR_EARLY_MAP;
+ } else {
+ if (smmu_domain->smmu)
+ ret = arm_smmu_enable_s1_translations(
+ smmu_domain);
+
+ if (!ret)
+ smmu_domain->attributes &=
+ ~(1 << DOMAIN_ATTR_EARLY_MAP);
+ }
+ break;
+ }
default:
ret = -ENODEV;
break;
@@ -3158,6 +3184,28 @@ out_unlock:
return ret;
}
+
+static int arm_smmu_enable_s1_translations(struct arm_smmu_domain *smmu_domain)
+{
+ struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+ void __iomem *cb_base;
+ u32 reg;
+ int ret;
+
+ cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
+ ret = arm_smmu_enable_clocks(smmu);
+ if (ret)
+ return ret;
+
+ reg = readl_relaxed(cb_base + ARM_SMMU_CB_SCTLR);
+ reg |= SCTLR_M;
+
+ writel_relaxed(reg, cb_base + ARM_SMMU_CB_SCTLR);
+ arm_smmu_disable_clocks(smmu);
+ return ret;
+}
+
static int arm_smmu_dma_supported(struct iommu_domain *domain,
struct device *dev, u64 mask)
{
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index 3b54fd4a77e6..7b0c1ae5a48d 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -70,6 +70,8 @@ static const char *iommu_debug_attr_to_string(enum iommu_attr attr)
return "DOMAIN_ATTR_S1_BYPASS";
case DOMAIN_ATTR_FAST:
return "DOMAIN_ATTR_FAST";
+ case DOMAIN_ATTR_EARLY_MAP:
+ return "DOMAIN_ATTR_EARLY_MAP";
default:
return "Unknown attr!";
}
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index 51fd79f101c8..674ca6161af9 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -10,6 +10,8 @@
* GNU General Public License for more details.
*/
+#define pr_fmt(fmt) "flashv2: %s: " fmt, __func__
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -27,6 +29,8 @@
#include <linux/regulator/consumer.h>
#include <linux/leds-qpnp-flash.h>
#include <linux/leds-qpnp-flash-v2.h>
+#include <linux/qpnp/qpnp-revid.h>
+#include <linux/log2.h>
#include "leds.h"
#define FLASH_LED_REG_LED_STATUS1(base) (base + 0x08)
@@ -43,24 +47,28 @@
#define FLASH_LED_REG_HDRM_AUTO_MODE_CTRL(base) (base + 0x50)
#define FLASH_LED_REG_WARMUP_DELAY(base) (base + 0x51)
#define FLASH_LED_REG_ISC_DELAY(base) (base + 0x52)
+#define FLASH_LED_REG_THERMAL_RMP_DN_RATE(base) (base + 0x55)
#define FLASH_LED_REG_THERMAL_THRSH1(base) (base + 0x56)
#define FLASH_LED_REG_THERMAL_THRSH2(base) (base + 0x57)
#define FLASH_LED_REG_THERMAL_THRSH3(base) (base + 0x58)
+#define FLASH_LED_REG_THERMAL_HYSTERESIS(base) (base + 0x59)
+#define FLASH_LED_REG_THERMAL_DEBOUNCE(base) (base + 0x5A)
#define FLASH_LED_REG_VPH_DROOP_THRESHOLD(base) (base + 0x61)
#define FLASH_LED_REG_VPH_DROOP_DEBOUNCE(base) (base + 0x62)
#define FLASH_LED_REG_ILED_GRT_THRSH(base) (base + 0x67)
+#define FLASH_LED_REG_LED1N2_ICLAMP_LOW(base) (base + 0x68)
+#define FLASH_LED_REG_LED1N2_ICLAMP_MID(base) (base + 0x69)
+#define FLASH_LED_REG_LED3_ICLAMP_LOW(base) (base + 0x6A)
+#define FLASH_LED_REG_LED3_ICLAMP_MID(base) (base + 0x6B)
#define FLASH_LED_REG_MITIGATION_SEL(base) (base + 0x6E)
#define FLASH_LED_REG_MITIGATION_SW(base) (base + 0x6F)
#define FLASH_LED_REG_LMH_LEVEL(base) (base + 0x70)
#define FLASH_LED_REG_CURRENT_DERATE_EN(base) (base + 0x76)
-#define FLASH_LED_HDRM_MODE_PRGM_MASK GENMASK(7, 0)
#define FLASH_LED_HDRM_VOL_MASK GENMASK(7, 4)
#define FLASH_LED_CURRENT_MASK GENMASK(6, 0)
#define FLASH_LED_ENABLE_MASK GENMASK(2, 0)
#define FLASH_HW_STROBE_MASK GENMASK(2, 0)
-#define FLASH_LED_SAFETY_TMR_MASK GENMASK(7, 0)
-#define FLASH_LED_INT_RT_STS_MASK GENMASK(7, 0)
#define FLASH_LED_ISC_WARMUP_DELAY_MASK GENMASK(1, 0)
#define FLASH_LED_CURRENT_DERATE_EN_MASK GENMASK(2, 0)
#define FLASH_LED_VPH_DROOP_DEBOUNCE_MASK GENMASK(1, 0)
@@ -70,13 +78,19 @@
#define FLASH_LED_LMH_LEVEL_MASK GENMASK(1, 0)
#define FLASH_LED_VPH_DROOP_HYSTERESIS_MASK GENMASK(5, 4)
#define FLASH_LED_VPH_DROOP_THRESHOLD_MASK GENMASK(2, 0)
+#define FLASH_LED_THERMAL_HYSTERESIS_MASK GENMASK(1, 0)
+#define FLASH_LED_THERMAL_DEBOUNCE_MASK GENMASK(1, 0)
#define FLASH_LED_THERMAL_THRSH_MASK GENMASK(2, 0)
-#define FLASH_LED_THERMAL_OTST_MASK GENMASK(2, 0)
#define FLASH_LED_MOD_CTRL_MASK BIT(7)
#define FLASH_LED_HW_SW_STROBE_SEL_BIT BIT(2)
#define FLASH_LED_VPH_DROOP_FAULT_MASK BIT(4)
#define FLASH_LED_LMH_MITIGATION_EN_MASK BIT(0)
#define FLASH_LED_CHGR_MITIGATION_EN_MASK BIT(4)
+#define THERMAL_OTST1_RAMP_CTRL_MASK BIT(7)
+#define THERMAL_OTST1_RAMP_CTRL_SHIFT 7
+#define THERMAL_DERATE_SLOW_SHIFT 4
+#define THERMAL_DERATE_SLOW_MASK GENMASK(6, 4)
+#define THERMAL_DERATE_FAST_MASK GENMASK(2, 0)
#define VPH_DROOP_DEBOUNCE_US_TO_VAL(val_us) (val_us / 8)
#define VPH_DROOP_HYST_MV_TO_VAL(val_mv) (val_mv / 25)
@@ -85,17 +99,24 @@
#define MITIGATION_THRSH_MA_TO_VAL(val_ma) (val_ma / 100)
#define CURRENT_MA_TO_REG_VAL(curr_ma, ires_ua) ((curr_ma * 1000) / ires_ua - 1)
#define SAFETY_TMR_TO_REG_VAL(duration_ms) ((duration_ms / 10) - 1)
+#define THERMAL_HYST_TEMP_TO_VAL(val, divisor) (val / divisor)
#define FLASH_LED_ISC_WARMUP_DELAY_SHIFT 6
#define FLASH_LED_WARMUP_DELAY_DEFAULT 2
#define FLASH_LED_ISC_DELAY_DEFAULT 3
#define FLASH_LED_VPH_DROOP_DEBOUNCE_DEFAULT 2
+#define FLASH_LED_VPH_DROOP_HYST_SHIFT 4
#define FLASH_LED_VPH_DROOP_HYST_DEFAULT 2
#define FLASH_LED_VPH_DROOP_THRESH_DEFAULT 5
-#define FLASH_LED_VPH_DROOP_DEBOUNCE_MAX 3
-#define FLASH_LED_VPH_DROOP_HYST_MAX 3
+#define FLASH_LED_DEBOUNCE_MAX 3
+#define FLASH_LED_HYSTERESIS_MAX 3
#define FLASH_LED_VPH_DROOP_THRESH_MAX 7
+#define THERMAL_DERATE_SLOW_MAX 314592
+#define THERMAL_DERATE_FAST_MAX 512
+#define THERMAL_DEBOUNCE_TIME_MAX 64
+#define THERMAL_DERATE_HYSTERESIS_MAX 3
#define FLASH_LED_THERMAL_THRSH_MIN 3
+#define FLASH_LED_THERMAL_THRSH_MAX 7
#define FLASH_LED_THERMAL_OTST_LEVELS 3
#define FLASH_LED_VLED_MAX_DEFAULT_UV 3500000
#define FLASH_LED_IBATT_OCP_THRESH_DEFAULT_UA 4500000
@@ -173,18 +194,12 @@ struct flash_node_data {
bool led_on;
};
-struct flash_regulator_data {
- struct regulator *vreg;
- const char *reg_name;
- u32 max_volt_uv;
-};
struct flash_switch_data {
struct platform_device *pdev;
+ struct regulator *vreg;
struct led_classdev cdev;
- struct flash_regulator_data *reg_data;
int led_mask;
- int num_regulators;
bool regulator_on;
bool enabled;
};
@@ -193,28 +208,41 @@ struct flash_switch_data {
* Flash LED configuration read from device tree
*/
struct flash_led_platform_data {
- int *thermal_derate_current;
- int all_ramp_up_done_irq;
- int all_ramp_down_done_irq;
- int led_fault_irq;
- int ibatt_ocp_threshold_ua;
- int vled_max_uv;
- int rpara_uohm;
- int lmh_rbatt_threshold_uohm;
- int lmh_ocv_threshold_uv;
- u8 isc_delay;
- u8 warmup_delay;
- u8 current_derate_en_cfg;
- u8 vph_droop_threshold;
- u8 vph_droop_hysteresis;
- u8 vph_droop_debounce;
- u8 lmh_mitigation_sel;
- u8 chgr_mitigation_sel;
- u8 lmh_level;
- u8 iled_thrsh_val;
- u8 hw_strobe_option;
- bool hdrm_auto_mode_en;
- bool thermal_derate_en;
+ struct pmic_revid_data *pmic_rev_id;
+ int *thermal_derate_current;
+ int all_ramp_up_done_irq;
+ int all_ramp_down_done_irq;
+ int led_fault_irq;
+ int ibatt_ocp_threshold_ua;
+ int vled_max_uv;
+ int rpara_uohm;
+ int lmh_rbatt_threshold_uohm;
+ int lmh_ocv_threshold_uv;
+ int thermal_derate_slow;
+ int thermal_derate_fast;
+ int thermal_hysteresis;
+ int thermal_debounce;
+ int thermal_thrsh1;
+ int thermal_thrsh2;
+ int thermal_thrsh3;
+ u32 led1n2_iclamp_low_ma;
+ u32 led1n2_iclamp_mid_ma;
+ u32 led3_iclamp_low_ma;
+ u32 led3_iclamp_mid_ma;
+ u8 isc_delay;
+ u8 warmup_delay;
+ u8 current_derate_en_cfg;
+ u8 vph_droop_threshold;
+ u8 vph_droop_hysteresis;
+ u8 vph_droop_debounce;
+ u8 lmh_mitigation_sel;
+ u8 chgr_mitigation_sel;
+ u8 lmh_level;
+ u8 iled_thrsh_val;
+ u8 hw_strobe_option;
+ bool hdrm_auto_mode_en;
+ bool thermal_derate_en;
+ bool otst_ramp_bkup_en;
};
/*
@@ -237,22 +265,54 @@ struct qpnp_flash_led {
bool trigger_chgr;
};
-static int
-qpnp_flash_led_read(struct qpnp_flash_led *led, u16 addr, u8 *data)
+static int thermal_derate_slow_table[] = {
+ 128, 256, 512, 1024, 2048, 4096, 8192, 314592,
+};
+
+static int thermal_derate_fast_table[] = {
+ 32, 64, 96, 128, 256, 384, 512,
+};
+
+static int otst1_threshold_table[] = {
+ 85, 79, 73, 67, 109, 103, 97, 91,
+};
+
+static int otst2_threshold_table[] = {
+ 110, 104, 98, 92, 134, 128, 122, 116,
+};
+
+static int otst3_threshold_table[] = {
+ 125, 119, 113, 107, 149, 143, 137, 131,
+};
+
+static int qpnp_flash_led_read(struct qpnp_flash_led *led, u16 addr, u8 *data)
{
int rc;
uint val;
rc = regmap_read(led->regmap, addr, &val);
- if (rc < 0)
- dev_err(&led->pdev->dev, "Unable to read from 0x%04X rc = %d\n",
- addr, rc);
- else
- dev_dbg(&led->pdev->dev, "Read 0x%02X from addr 0x%04X\n",
- val, addr);
+ if (rc < 0) {
+ pr_err("Unable to read from 0x%04X rc = %d\n", addr, rc);
+ return rc;
+ }
+ pr_debug("Read 0x%02X from addr 0x%04X\n", val, addr);
*data = (u8)val;
- return rc;
+ return 0;
+}
+
+static int qpnp_flash_led_write(struct qpnp_flash_led *led, u16 addr, u8 data)
+{
+ int rc;
+
+ rc = regmap_write(led->regmap, addr, data);
+ if (rc < 0) {
+ pr_err("Unable to write to 0x%04X rc = %d\n", addr, rc);
+ return rc;
+ }
+
+ pr_debug("Wrote 0x%02X to addr 0x%04X\n", data, addr);
+ return 0;
}
static int
@@ -277,11 +337,10 @@ qpnp_flash_led_masked_write(struct qpnp_flash_led *led, u16 addr, u8 mask,
rc = regmap_update_bits(led->regmap, addr, mask, val);
if (rc < 0)
- dev_err(&led->pdev->dev, "Unable to update bits from 0x%04X, rc = %d\n",
- addr, rc);
+ pr_err("Unable to update bits from 0x%04X, rc = %d\n", addr,
+ rc);
else
- dev_dbg(&led->pdev->dev, "Wrote 0x%02X to addr 0x%04X\n",
- val, addr);
+ pr_debug("Wrote 0x%02X to addr 0x%04X\n", val, addr);
return rc;
}
@@ -295,13 +354,12 @@ led_brightness qpnp_flash_led_brightness_get(struct led_classdev *led_cdev)
static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
{
int rc, i, addr_offset;
- u8 val = 0;
+ u8 val = 0, mask;
for (i = 0; i < led->num_fnodes; i++) {
addr_offset = led->fnode[i].id;
- rc = qpnp_flash_led_masked_write(led,
+ rc = qpnp_flash_led_write(led,
FLASH_LED_REG_HDRM_PRGM(led->base + addr_offset),
- FLASH_LED_HDRM_MODE_PRGM_MASK,
led->fnode[i].hdrm_val);
if (rc < 0)
return rc;
@@ -309,9 +367,9 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
val |= 0x1 << led->fnode[i].id;
}
- rc = qpnp_flash_led_masked_write(led,
+ rc = qpnp_flash_led_write(led,
FLASH_LED_REG_HDRM_AUTO_MODE_CTRL(led->base),
- FLASH_LED_HDRM_MODE_PRGM_MASK, val);
+ val);
if (rc < 0)
return rc;
@@ -336,6 +394,70 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
if (rc < 0)
return rc;
+ val = (led->pdata->otst_ramp_bkup_en << THERMAL_OTST1_RAMP_CTRL_SHIFT);
+ mask = THERMAL_OTST1_RAMP_CTRL_MASK;
+ if (led->pdata->thermal_derate_slow >= 0) {
+ val |= (led->pdata->thermal_derate_slow <<
+ THERMAL_DERATE_SLOW_SHIFT);
+ mask |= THERMAL_DERATE_SLOW_MASK;
+ }
+
+ if (led->pdata->thermal_derate_fast >= 0) {
+ val |= led->pdata->thermal_derate_fast;
+ mask |= THERMAL_DERATE_FAST_MASK;
+ }
+
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_RMP_DN_RATE(led->base),
+ mask, val);
+ if (rc < 0)
+ return rc;
+
+ if (led->pdata->thermal_debounce >= 0) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_DEBOUNCE(led->base),
+ FLASH_LED_THERMAL_DEBOUNCE_MASK,
+ led->pdata->thermal_debounce);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->thermal_hysteresis >= 0) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_HYSTERESIS(led->base),
+ FLASH_LED_THERMAL_HYSTERESIS_MASK,
+ led->pdata->thermal_hysteresis);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->thermal_thrsh1 >= 0) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_THRSH1(led->base),
+ FLASH_LED_THERMAL_THRSH_MASK,
+ led->pdata->thermal_thrsh1);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->thermal_thrsh2 >= 0) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_THRSH2(led->base),
+ FLASH_LED_THERMAL_THRSH_MASK,
+ led->pdata->thermal_thrsh2);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->thermal_thrsh3 >= 0) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_THRSH3(led->base),
+ FLASH_LED_THERMAL_THRSH_MASK,
+ led->pdata->thermal_thrsh3);
+ if (rc < 0)
+ return rc;
+ }
+
rc = qpnp_flash_led_masked_write(led,
FLASH_LED_REG_VPH_DROOP_DEBOUNCE(led->base),
FLASH_LED_VPH_DROOP_DEBOUNCE_MASK,
@@ -385,6 +507,46 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
if (rc < 0)
return rc;
+ if (led->pdata->led1n2_iclamp_low_ma) {
+ val = CURRENT_MA_TO_REG_VAL(led->pdata->led1n2_iclamp_low_ma,
+ led->fnode[0].ires_ua);
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_LED1N2_ICLAMP_LOW(led->base),
+ FLASH_LED_CURRENT_MASK, val);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->led1n2_iclamp_mid_ma) {
+ val = CURRENT_MA_TO_REG_VAL(led->pdata->led1n2_iclamp_mid_ma,
+ led->fnode[0].ires_ua);
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_LED1N2_ICLAMP_MID(led->base),
+ FLASH_LED_CURRENT_MASK, val);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->led3_iclamp_low_ma) {
+ val = CURRENT_MA_TO_REG_VAL(led->pdata->led3_iclamp_low_ma,
+ led->fnode[3].ires_ua);
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_LED3_ICLAMP_LOW(led->base),
+ FLASH_LED_CURRENT_MASK, val);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->led3_iclamp_mid_ma) {
+ val = CURRENT_MA_TO_REG_VAL(led->pdata->led3_iclamp_mid_ma,
+ led->fnode[3].ires_ua);
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_LED3_ICLAMP_MID(led->base),
+ FLASH_LED_CURRENT_MASK, val);
+ if (rc < 0)
+ return rc;
+ }
+
return 0;
}
@@ -414,8 +576,7 @@ static int qpnp_flash_led_hw_strobe_enable(struct flash_node_data *fnode,
on ? fnode->hw_strobe_state_active :
fnode->hw_strobe_state_suspend);
if (rc < 0) {
- dev_err(&fnode->pdev->dev,
- "failed to change hw strobe pin state\n");
+ pr_err("failed to change hw strobe pin state\n");
return rc;
}
}
@@ -426,34 +587,27 @@ static int qpnp_flash_led_hw_strobe_enable(struct flash_node_data *fnode,
static int qpnp_flash_led_regulator_enable(struct qpnp_flash_led *led,
struct flash_switch_data *snode, bool on)
{
- int i, rc = 0;
+ int rc = 0;
+
+ if (!snode || !snode->vreg)
+ return 0;
if (snode->regulator_on == on)
return 0;
- if (on == false) {
- i = snode->num_regulators;
- goto out;
- }
+ if (on)
+ rc = regulator_enable(snode->vreg);
+ else
+ rc = regulator_disable(snode->vreg);
- for (i = 0; i < snode->num_regulators; i++) {
- rc = regulator_enable(snode->reg_data[i].vreg);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "regulator enable failed, rc=%d\n", rc);
- goto out;
- }
+ if (rc < 0) {
+ pr_err("regulator_%s failed, rc=%d\n",
+ on ? "enable" : "disable", rc);
+ return rc;
}
- snode->regulator_on = true;
-
- return rc;
-
-out:
- while (i--)
- regulator_disable(snode->reg_data[i].vreg);
- snode->regulator_on = false;
- return rc;
+ snode->regulator_on = on ? true : false;
+ return 0;
}
static int get_property_from_fg(struct qpnp_flash_led *led,
@@ -463,14 +617,13 @@ static int get_property_from_fg(struct qpnp_flash_led *led,
union power_supply_propval pval = {0, };
if (!led->bms_psy) {
- dev_err(&led->pdev->dev, "no bms psy found\n");
+ pr_err("no bms psy found\n");
return -EINVAL;
}
rc = power_supply_get_property(led->bms_psy, prop, &pval);
if (rc) {
- dev_err(&led->pdev->dev,
- "bms psy doesn't support reading prop %d rc = %d\n",
+ pr_err("bms psy doesn't support reading prop %d rc = %d\n",
prop, rc);
return rc;
}
@@ -532,8 +685,7 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
rc = get_property_from_fg(led, POWER_SUPPLY_PROP_RESISTANCE,
&rbatt_uohm);
if (rc < 0) {
- dev_err(&led->pdev->dev, "bms psy does not support resistance, rc=%d\n",
- rc);
+ pr_err("bms psy does not support resistance, rc=%d\n", rc);
return rc;
}
@@ -543,16 +695,14 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
rc = get_property_from_fg(led, POWER_SUPPLY_PROP_VOLTAGE_OCV, &ocv_uv);
if (rc < 0) {
- dev_err(&led->pdev->dev, "bms psy does not support OCV, rc=%d\n",
- rc);
+ pr_err("bms psy does not support OCV, rc=%d\n", rc);
return rc;
}
rc = get_property_from_fg(led, POWER_SUPPLY_PROP_CURRENT_NOW,
&ibat_now);
if (rc < 0) {
- dev_err(&led->pdev->dev, "bms psy does not support current, rc=%d\n",
- rc);
+ pr_err("bms psy does not support current, rc=%d\n", rc);
return rc;
}
@@ -571,8 +721,7 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
FLASH_LED_LMH_MITIGATION_EN_MASK,
FLASH_LED_LMH_MITIGATION_ENABLE);
if (rc < 0) {
- dev_err(&led->pdev->dev, "trigger lmh mitigation failed, rc=%d\n",
- rc);
+ pr_err("trigger lmh mitigation failed, rc=%d\n", rc);
return rc;
}
@@ -617,9 +766,8 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
* before collapsing the battery. (available power/ flash input voltage)
*/
avail_flash_ua = div64_s64(avail_flash_power_fw, vin_flash_uv * MCONV);
- dev_dbg(&led->pdev->dev, "avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n",
- avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm,
- led->trigger_lmh);
+ pr_debug("avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n",
+ avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm, led->trigger_lmh);
return min(FLASH_LED_MAX_TOTAL_CURRENT_MA,
(int)(div64_s64(avail_flash_ua, MCONV)));
}
@@ -761,8 +909,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
FLASH_LED_LMH_MITIGATION_EN_MASK,
FLASH_LED_LMH_MITIGATION_DISABLE);
if (rc < 0) {
- dev_err(&led->pdev->dev, "disable lmh mitigation failed, rc=%d\n",
- rc);
+ pr_err("disable lmh mitigation failed, rc=%d\n", rc);
return rc;
}
}
@@ -773,8 +920,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
FLASH_LED_CHGR_MITIGATION_EN_MASK,
FLASH_LED_CHGR_MITIGATION_DISABLE);
if (rc < 0) {
- dev_err(&led->pdev->dev, "disable chgr mitigation failed, rc=%d\n",
- rc);
+ pr_err("disable chgr mitigation failed, rc=%d\n", rc);
return rc;
}
}
@@ -806,8 +952,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
rc = pinctrl_select_state(led->fnode[i].pinctrl,
led->fnode[i].gpio_state_suspend);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "failed to disable GPIO, rc=%d\n", rc);
+ pr_err("failed to disable GPIO, rc=%d\n", rc);
return rc;
}
}
@@ -816,8 +961,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i],
led->pdata->hw_strobe_option, false);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to disable hw strobe, rc=%d\n",
+ pr_err("Unable to disable hw strobe, rc=%d\n",
rc);
return rc;
}
@@ -835,8 +979,8 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
u8 val, mask;
if (snode->enabled == on) {
- dev_warn(&led->pdev->dev, "Switch node is already %s!\n",
- on ? "enabled" : "disabled");
+ pr_debug("Switch node is already %s!\n",
+ on ? "enabled" : "disabled");
return 0;
}
@@ -886,9 +1030,9 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
if (rc < 0)
return rc;
- rc = qpnp_flash_led_masked_write(led,
+ rc = qpnp_flash_led_write(led,
FLASH_LED_REG_SAFETY_TMR(led->base + addr_offset),
- FLASH_LED_SAFETY_TMR_MASK, led->fnode[i].duration);
+ led->fnode[i].duration);
if (rc < 0)
return rc;
@@ -898,8 +1042,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
rc = pinctrl_select_state(led->fnode[i].pinctrl,
led->fnode[i].gpio_state_active);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "failed to enable GPIO\n");
+ pr_err("failed to enable GPIO rc=%d\n", rc);
return rc;
}
}
@@ -908,8 +1051,8 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i],
led->pdata->hw_strobe_option, true);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to enable hw strobe\n");
+ pr_err("Unable to enable hw strobe rc=%d\n",
+ rc);
return rc;
}
}
@@ -930,8 +1073,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
FLASH_LED_LMH_MITIGATION_EN_MASK,
FLASH_LED_LMH_MITIGATION_ENABLE);
if (rc < 0) {
- dev_err(&led->pdev->dev, "trigger lmh mitigation failed, rc=%d\n",
- rc);
+ pr_err("trigger lmh mitigation failed, rc=%d\n", rc);
return rc;
}
}
@@ -942,8 +1084,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
FLASH_LED_CHGR_MITIGATION_EN_MASK,
FLASH_LED_CHGR_MITIGATION_ENABLE);
if (rc < 0) {
- dev_err(&led->pdev->dev, "trigger chgr mitigation failed, rc=%d\n",
- rc);
+ pr_err("trigger chgr mitigation failed, rc=%d\n", rc);
return rc;
}
}
@@ -975,15 +1116,14 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
led = dev_get_drvdata(&snode->pdev->dev);
if (!(options & FLASH_LED_PREPARE_OPTIONS_MASK)) {
- dev_err(&led->pdev->dev, "Invalid options %d\n", options);
+ pr_err("Invalid options %d\n", options);
return -EINVAL;
}
if (options & ENABLE_REGULATOR) {
rc = qpnp_flash_led_regulator_enable(led, snode, true);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "enable regulator failed, rc=%d\n", rc);
+ pr_err("enable regulator failed, rc=%d\n", rc);
return rc;
}
}
@@ -991,8 +1131,7 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
if (options & DISABLE_REGULATOR) {
rc = qpnp_flash_led_regulator_enable(led, snode, false);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "disable regulator failed, rc=%d\n", rc);
+ pr_err("disable regulator failed, rc=%d\n", rc);
return rc;
}
}
@@ -1000,8 +1139,7 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
if (options & QUERY_MAX_CURRENT) {
rc = qpnp_flash_led_get_max_avail_current(led);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "query max current failed, rc=%d\n", rc);
+ pr_err("query max current failed, rc=%d\n", rc);
return rc;
}
*max_current = rc;
@@ -1041,8 +1179,7 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev,
if (snode) {
rc = qpnp_flash_led_switch_set(snode, value > 0);
if (rc < 0)
- dev_err(&led->pdev->dev,
- "Failed to set flash LED switch\n");
+ pr_err("Failed to set flash LED switch rc=%d\n", rc);
} else if (fnode) {
qpnp_flash_led_node_set(fnode, value);
}
@@ -1050,6 +1187,31 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev,
spin_unlock(&led->lock);
}
+/* sysfs show function for flash_max_current */
+static ssize_t qpnp_flash_led_max_current_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ struct flash_switch_data *snode;
+ struct qpnp_flash_led *led;
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+
+ snode = container_of(led_cdev, struct flash_switch_data, cdev);
+ led = dev_get_drvdata(&snode->pdev->dev);
+
+ rc = qpnp_flash_led_get_max_avail_current(led);
+ if (rc < 0)
+ pr_err("query max current failed, rc=%d\n", rc);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", rc);
+}
+
+/* sysfs attributes exported by flash_led */
+static struct device_attribute qpnp_flash_led_attrs[] = {
+ __ATTR(max_current, (S_IRUGO | S_IWUSR | S_IWGRP),
+ qpnp_flash_led_max_current_show, NULL),
+};
+
static int flash_led_psy_notifier_call(struct notifier_block *nb,
unsigned long ev, void *v)
{
@@ -1063,7 +1225,7 @@ static int flash_led_psy_notifier_call(struct notifier_block *nb,
if (!strcmp(psy->desc->name, "bms")) {
led->bms_psy = power_supply_get_by_name("bms");
if (!led->bms_psy)
- dev_err(&led->pdev->dev, "Failed to get bms power_supply\n");
+ pr_err("Failed to get bms power_supply\n");
else
power_supply_unreg_notifier(&led->nb);
}
@@ -1093,13 +1255,12 @@ static irqreturn_t qpnp_flash_led_irq_handler(int irq, void *_led)
int rc;
u8 irq_status, led_status1, led_status2;
- dev_dbg(&led->pdev->dev, "irq received, irq=%d\n", irq);
+ pr_debug("irq received, irq=%d\n", irq);
rc = qpnp_flash_led_read(led,
FLASH_LED_REG_INT_RT_STS(led->base), &irq_status);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Failed to read interrupt status reg, rc=%d\n",
- rc);
+ pr_err("Failed to read interrupt status reg, rc=%d\n", rc);
goto exit;
}
@@ -1118,29 +1279,27 @@ static irqreturn_t qpnp_flash_led_irq_handler(int irq, void *_led)
rc = qpnp_flash_led_read(led,
FLASH_LED_REG_LED_STATUS1(led->base), &led_status1);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Failed to read led_status1 reg, rc=%d\n",
- rc);
+ pr_err("Failed to read led_status1 reg, rc=%d\n", rc);
goto exit;
}
rc = qpnp_flash_led_read(led,
FLASH_LED_REG_LED_STATUS2(led->base), &led_status2);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Failed to read led_status2 reg, rc=%d\n",
- rc);
+ pr_err("Failed to read led_status2 reg, rc=%d\n", rc);
goto exit;
}
if (led_status1)
- dev_emerg(&led->pdev->dev, "led short/open fault detected! led_status1=%x\n",
- led_status1);
+ pr_emerg("led short/open fault detected! led_status1=%x\n",
+ led_status1);
if (led_status2 & FLASH_LED_VPH_DROOP_FAULT_MASK)
- dev_emerg(&led->pdev->dev, "led vph_droop fault detected!\n");
+ pr_emerg("led vph_droop fault detected!\n");
}
- dev_dbg(&led->pdev->dev, "irq handled, irq_type=%x, irq_status=%x\n",
- irq_type, irq_status);
+ pr_debug("irq handled, irq_type=%x, irq_status=%x\n", irq_type,
+ irq_status);
exit:
return IRQ_HANDLED;
@@ -1156,104 +1315,6 @@ int qpnp_flash_led_unregister_irq_notifier(struct notifier_block *nb)
return atomic_notifier_chain_unregister(&irq_notifier_list, nb);
}
-static int qpnp_flash_led_regulator_setup(struct qpnp_flash_led *led,
- struct flash_switch_data *snode, bool on)
-{
- int i, rc = 0;
-
- if (on == false) {
- i = snode->num_regulators;
- goto out;
- }
-
- for (i = 0; i < snode->num_regulators; i++) {
- snode->reg_data[i].vreg = regulator_get(snode->cdev.dev,
- snode->reg_data[i].reg_name);
- if (IS_ERR(snode->reg_data[i].vreg)) {
- rc = PTR_ERR(snode->reg_data[i].vreg);
- dev_err(&led->pdev->dev,
- "Failed to get regulator, rc=%d\n", rc);
- goto out;
- }
-
- if (regulator_count_voltages(snode->reg_data[i].vreg) > 0) {
- rc = regulator_set_voltage(snode->reg_data[i].vreg,
- snode->reg_data[i].max_volt_uv,
- snode->reg_data[i].max_volt_uv);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "regulator set voltage failed, rc=%d\n",
- rc);
- regulator_put(snode->reg_data[i].vreg);
- goto out;
- }
- }
- }
-
- return rc;
-
-out:
- while (i--) {
- if (regulator_count_voltages(snode->reg_data[i].vreg) > 0)
- regulator_set_voltage(snode->reg_data[i].vreg, 0,
- snode->reg_data[i].max_volt_uv);
-
- regulator_put(snode->reg_data[i].vreg);
- }
-
- return rc;
-}
-
-static int qpnp_flash_led_regulator_parse_dt(struct qpnp_flash_led *led,
- struct flash_switch_data *snode,
- struct device_node *node) {
-
- int i = 0, rc = 0, num_regs = 0;
- struct device_node *temp = NULL;
- const char *temp_string;
- u32 val;
-
- while ((temp = of_get_next_available_child(node, temp))) {
- if (of_find_property(temp, "regulator-name", NULL))
- num_regs++;
- }
- snode->num_regulators = num_regs;
-
- if (snode->num_regulators == 0)
- return 0;
-
- snode->reg_data = devm_kcalloc(&led->pdev->dev, snode->num_regulators,
- sizeof(*snode->reg_data),
- GFP_KERNEL);
- if (!snode->reg_data)
- return -ENOMEM;
-
- for_each_available_child_of_node(node, temp) {
- rc = of_property_read_string(temp, "regulator-name",
- &temp_string);
- if (!rc)
- snode->reg_data[i].reg_name = temp_string;
- else {
- dev_err(&led->pdev->dev,
- "Unable to read regulator name, rc=%d\n", rc);
- return rc;
- }
-
- rc = of_property_read_u32(temp, "max-voltage-uv", &val);
- if (!rc) {
- snode->reg_data[i].max_volt_uv = val;
- } else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read max voltage, rc=%d\n", rc);
- return rc;
- }
-
- i++;
- }
-
- return 0;
-}
-
static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
struct flash_node_data *fnode, struct device_node *node)
{
@@ -1268,7 +1329,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
rc = of_property_read_string(node, "qcom,led-name", &fnode->cdev.name);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Unable to read flash LED names\n");
+ pr_err("Unable to read flash LED names\n");
return rc;
}
@@ -1279,11 +1340,11 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
} else if (!strcmp(temp_string, "torch")) {
fnode->type = FLASH_LED_TYPE_TORCH;
} else {
- dev_err(&led->pdev->dev, "Wrong flash LED type\n");
+ pr_err("Wrong flash LED type\n");
return rc;
}
} else {
- dev_err(&led->pdev->dev, "Unable to read flash LED label\n");
+ pr_err("Unable to read flash LED label\n");
return rc;
}
@@ -1291,14 +1352,14 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
if (!rc) {
fnode->id = (u8)val;
} else {
- dev_err(&led->pdev->dev, "Unable to read flash LED ID\n");
+ pr_err("Unable to read flash LED ID\n");
return rc;
}
rc = of_property_read_string(node, "qcom,default-led-trigger",
&fnode->cdev.default_trigger);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Unable to read trigger name\n");
+ pr_err("Unable to read trigger name\n");
return rc;
}
@@ -1310,7 +1371,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->ires = FLASH_LED_IRES_BASE -
(val - FLASH_LED_IRES_MIN_UA) / FLASH_LED_IRES_DIVISOR;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to read current resolution\n");
+ pr_err("Unable to read current resolution rc=%d\n", rc);
return rc;
}
@@ -1321,8 +1382,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->max_current = val;
fnode->cdev.max_brightness = val;
} else {
- dev_err(&led->pdev->dev,
- "Unable to read max current, rc=%d\n", rc);
+ pr_err("Unable to read max current, rc=%d\n", rc);
return rc;
}
@@ -1330,8 +1390,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
if (!rc) {
if (val < FLASH_LED_MIN_CURRENT_MA ||
val > fnode->max_current)
- dev_warn(&led->pdev->dev,
- "Invalid operational current specified, capping it\n");
+ pr_warn("Invalid operational current specified, capping it\n");
if (val < FLASH_LED_MIN_CURRENT_MA)
val = FLASH_LED_MIN_CURRENT_MA;
if (val > fnode->max_current)
@@ -1339,8 +1398,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->current_ma = val;
fnode->cdev.brightness = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read operational current, rc=%d\n", rc);
+ pr_err("Unable to read operational current, rc=%d\n", rc);
return rc;
}
@@ -1351,13 +1409,11 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
FLASH_LED_SAFETY_TMR_ENABLE);
} else if (rc == -EINVAL) {
if (fnode->type == FLASH_LED_TYPE_FLASH) {
- dev_err(&led->pdev->dev,
- "Timer duration is required for flash LED\n");
+ pr_err("Timer duration is required for flash LED\n");
return rc;
}
} else {
- dev_err(&led->pdev->dev,
- "Unable to read timer duration\n");
+ pr_err("Unable to read timer duration\n");
return rc;
}
@@ -1369,7 +1425,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->hdrm_val = (val << FLASH_LED_HDRM_VOL_SHIFT) &
FLASH_LED_HDRM_VOL_MASK;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to read headroom voltage\n");
+ pr_err("Unable to read headroom voltage\n");
return rc;
}
@@ -1380,8 +1436,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
} else if (rc == -EINVAL) {
fnode->hdrm_val |= FLASH_LED_HDRM_VOL_HI_LO_WIN_DEFAULT_MV;
} else {
- dev_err(&led->pdev->dev,
- "Unable to read hdrm hi-lo window voltage\n");
+ pr_err("Unable to read hdrm hi-lo window voltage\n");
return rc;
}
@@ -1399,8 +1454,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->hw_strobe_gpio = of_get_named_gpio(node,
"qcom,hw-strobe-gpio", 0);
if (fnode->hw_strobe_gpio < 0) {
- dev_err(&led->pdev->dev,
- "Invalid gpio specified\n");
+ pr_err("Invalid gpio specified\n");
return fnode->hw_strobe_gpio;
}
gpio_direction_output(fnode->hw_strobe_gpio, 0);
@@ -1410,8 +1464,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
pinctrl_lookup_state(fnode->pinctrl,
"strobe_enable");
if (IS_ERR_OR_NULL(fnode->hw_strobe_state_active)) {
- dev_err(&led->pdev->dev,
- "No active pin for hardware strobe, rc=%ld\n",
+ pr_err("No active pin for hardware strobe, rc=%ld\n",
PTR_ERR(fnode->hw_strobe_state_active));
fnode->hw_strobe_state_active = NULL;
}
@@ -1420,8 +1473,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
pinctrl_lookup_state(fnode->pinctrl,
"strobe_disable");
if (IS_ERR_OR_NULL(fnode->hw_strobe_state_suspend)) {
- dev_err(&led->pdev->dev,
- "No suspend pin for hardware strobe, rc=%ld\n",
+ pr_err("No suspend pin for hardware strobe, rc=%ld\n",
PTR_ERR(fnode->hw_strobe_state_suspend)
);
fnode->hw_strobe_state_suspend = NULL;
@@ -1431,8 +1483,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
rc = led_classdev_register(&led->pdev->dev, &fnode->cdev);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Unable to register led node %d\n",
- fnode->id);
+ pr_err("Unable to register led node %d\n", fnode->id);
return rc;
}
@@ -1440,14 +1491,13 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->pinctrl = devm_pinctrl_get(fnode->cdev.dev);
if (IS_ERR_OR_NULL(fnode->pinctrl)) {
- dev_warn(&led->pdev->dev, "No pinctrl defined\n");
+ pr_debug("No pinctrl defined\n");
fnode->pinctrl = NULL;
} else {
fnode->gpio_state_active =
pinctrl_lookup_state(fnode->pinctrl, "led_enable");
if (IS_ERR_OR_NULL(fnode->gpio_state_active)) {
- dev_err(&led->pdev->dev,
- "Cannot lookup LED active state\n");
+ pr_err("Cannot lookup LED active state\n");
devm_pinctrl_put(fnode->pinctrl);
fnode->pinctrl = NULL;
return PTR_ERR(fnode->gpio_state_active);
@@ -1456,8 +1506,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->gpio_state_suspend =
pinctrl_lookup_state(fnode->pinctrl, "led_disable");
if (IS_ERR_OR_NULL(fnode->gpio_state_suspend)) {
- dev_err(&led->pdev->dev,
- "Cannot lookup LED disable state\n");
+ pr_err("Cannot lookup LED disable state\n");
devm_pinctrl_put(fnode->pinctrl);
fnode->pinctrl = NULL;
return PTR_ERR(fnode->gpio_state_suspend);
@@ -1471,46 +1520,48 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led,
struct flash_switch_data *snode,
struct device_node *node)
{
- int rc = 0;
+ int rc = 0, num;
+ char reg_name[16], reg_sup_name[16];
rc = of_property_read_string(node, "qcom,led-name", &snode->cdev.name);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Failed to read switch node name, rc=%d\n", rc);
+ pr_err("Failed to read switch node name, rc=%d\n", rc);
return rc;
}
+ rc = sscanf(snode->cdev.name, "led:switch_%d", &num);
+ if (!rc) {
+ pr_err("No number for switch device?\n");
+ return -EINVAL;
+ }
+
rc = of_property_read_string(node, "qcom,default-led-trigger",
&snode->cdev.default_trigger);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to read trigger name, rc=%d\n", rc);
+ pr_err("Unable to read trigger name, rc=%d\n", rc);
return rc;
}
rc = of_property_read_u32(node, "qcom,led-mask", &snode->led_mask);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Unable to read led mask rc=%d\n", rc);
+ pr_err("Unable to read led mask rc=%d\n", rc);
return rc;
}
if (snode->led_mask < 1 || snode->led_mask > 7) {
- dev_err(&led->pdev->dev, "Invalid value for led-mask\n");
+ pr_err("Invalid value for led-mask\n");
return -EINVAL;
}
- rc = qpnp_flash_led_regulator_parse_dt(led, snode, node);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to parse regulator data, rc=%d\n", rc);
- return rc;
- }
-
- if (snode->num_regulators) {
- rc = qpnp_flash_led_regulator_setup(led, snode, true);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to setup regulator, rc=%d\n", rc);
+ scnprintf(reg_name, sizeof(reg_name), "switch%d-supply", num);
+ if (of_find_property(led->pdev->dev.of_node, reg_name, NULL)) {
+ scnprintf(reg_sup_name, sizeof(reg_sup_name), "switch%d", num);
+ snode->vreg = devm_regulator_get(&led->pdev->dev, reg_sup_name);
+ if (IS_ERR_OR_NULL(snode->vreg)) {
+ rc = PTR_ERR(snode->vreg);
+ if (rc != -EPROBE_DEFER)
+ pr_err("Failed to get regulator, rc=%d\n", rc);
+ snode->vreg = NULL;
return rc;
}
}
@@ -1520,8 +1571,7 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led,
snode->cdev.brightness_get = qpnp_flash_led_brightness_get;
rc = led_classdev_register(&led->pdev->dev, &snode->cdev);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to register led switch node\n");
+ pr_err("Unable to register led switch node\n");
return rc;
}
@@ -1529,13 +1579,53 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led,
return 0;
}
+static int get_code_from_table(int *table, int len, int value)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (value == table[i])
+ break;
+ }
+
+ if (i == len) {
+ pr_err("Couldn't find %d from table\n", value);
+ return -ENODATA;
+ }
+
+ return i;
+}
+
static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
struct device_node *node)
{
+ struct device_node *revid_node;
int rc;
u32 val;
bool short_circuit_det, open_circuit_det, vph_droop_det;
+ revid_node = of_parse_phandle(node, "qcom,pmic-revid", 0);
+ if (!revid_node) {
+ pr_err("Missing qcom,pmic-revid property - driver failed\n");
+ return -EINVAL;
+ }
+
+ led->pdata->pmic_rev_id = get_revid_data(revid_node);
+ if (IS_ERR_OR_NULL(led->pdata->pmic_rev_id)) {
+ pr_err("Unable to get pmic_revid rc=%ld\n",
+ PTR_ERR(led->pdata->pmic_rev_id));
+ /*
+ * the revid peripheral must be registered, any failure
+ * here only indicates that the rev-id module has not
+ * probed yet.
+ */
+ return -EPROBE_DEFER;
+ }
+
+ pr_debug("PMIC subtype %d Digital major %d\n",
+ led->pdata->pmic_rev_id->pmic_subtype,
+ led->pdata->pmic_rev_id->rev4);
+
led->pdata->hdrm_auto_mode_en = of_property_read_bool(node,
"qcom,hdrm-auto-mode");
@@ -1545,8 +1635,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
led->pdata->isc_delay =
val >> FLASH_LED_ISC_WARMUP_DELAY_SHIFT;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read ISC delay, rc=%d\n", rc);
+ pr_err("Unable to read ISC delay, rc=%d\n", rc);
return rc;
}
@@ -1556,8 +1645,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
led->pdata->warmup_delay =
val >> FLASH_LED_ISC_WARMUP_DELAY_SHIFT;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read WARMUP delay, rc=%d\n", rc);
+ pr_err("Unable to read WARMUP delay, rc=%d\n", rc);
return rc;
}
@@ -1584,26 +1672,128 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
led->pdata->thermal_derate_current,
FLASH_LED_THERMAL_OTST_LEVELS);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Unable to read thermal current limits, rc=%d\n",
- rc);
+ pr_err("Unable to read thermal current limits, rc=%d\n",
+ rc);
return rc;
}
}
+ led->pdata->otst_ramp_bkup_en =
+ !of_property_read_bool(node, "qcom,otst-ramp-back-up-dis");
+
+ led->pdata->thermal_derate_slow = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-derate-slow", &val);
+ if (!rc) {
+ if (val < 0 || val > THERMAL_DERATE_SLOW_MAX) {
+ pr_err("Invalid thermal_derate_slow %d\n", val);
+ return -EINVAL;
+ }
+
+ led->pdata->thermal_derate_slow =
+ get_code_from_table(thermal_derate_slow_table,
+ ARRAY_SIZE(thermal_derate_slow_table), val);
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal derate slow, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_derate_fast = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-derate-fast", &val);
+ if (!rc) {
+ if (val < 0 || val > THERMAL_DERATE_FAST_MAX) {
+ pr_err("Invalid thermal_derate_fast %d\n", val);
+ return -EINVAL;
+ }
+
+ led->pdata->thermal_derate_fast =
+ get_code_from_table(thermal_derate_fast_table,
+ ARRAY_SIZE(thermal_derate_fast_table), val);
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal derate fast, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_debounce = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-debounce", &val);
+ if (!rc) {
+ if (val < 0 || val > THERMAL_DEBOUNCE_TIME_MAX) {
+ pr_err("Invalid thermal_debounce %d\n", val);
+ return -EINVAL;
+ }
+
+ if (val >= 0 && val < 16)
+ led->pdata->thermal_debounce = 0;
+ else
+ led->pdata->thermal_debounce = ilog2(val) - 3;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal debounce, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_hysteresis = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-hysteresis", &val);
+ if (!rc) {
+ if (led->pdata->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE)
+ val = THERMAL_HYST_TEMP_TO_VAL(val, 20);
+ else
+ val = THERMAL_HYST_TEMP_TO_VAL(val, 15);
+
+ if (val < 0 || val > THERMAL_DERATE_HYSTERESIS_MAX) {
+ pr_err("Invalid thermal_derate_hysteresis %d\n", val);
+ return -EINVAL;
+ }
+
+ led->pdata->thermal_hysteresis = val;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal hysteresis, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_thrsh1 = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-thrsh1", &val);
+ if (!rc) {
+ led->pdata->thermal_thrsh1 =
+ get_code_from_table(otst1_threshold_table,
+ ARRAY_SIZE(otst1_threshold_table), val);
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal thrsh1, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_thrsh2 = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-thrsh2", &val);
+ if (!rc) {
+ led->pdata->thermal_thrsh2 =
+ get_code_from_table(otst2_threshold_table,
+ ARRAY_SIZE(otst2_threshold_table), val);
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal thrsh2, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_thrsh3 = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-thrsh3", &val);
+ if (!rc) {
+ led->pdata->thermal_thrsh3 =
+ get_code_from_table(otst3_threshold_table,
+ ARRAY_SIZE(otst3_threshold_table), val);
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal thrsh3, rc=%d\n", rc);
+ return rc;
+ }
+
led->pdata->vph_droop_debounce = FLASH_LED_VPH_DROOP_DEBOUNCE_DEFAULT;
rc = of_property_read_u32(node, "qcom,vph-droop-debounce-us", &val);
if (!rc) {
led->pdata->vph_droop_debounce =
VPH_DROOP_DEBOUNCE_US_TO_VAL(val);
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read VPH droop debounce, rc=%d\n", rc);
+ pr_err("Unable to read VPH droop debounce, rc=%d\n", rc);
return rc;
}
- if (led->pdata->vph_droop_debounce > FLASH_LED_VPH_DROOP_DEBOUNCE_MAX) {
- dev_err(&led->pdev->dev,
- "Invalid VPH droop debounce specified");
+ if (led->pdata->vph_droop_debounce > FLASH_LED_DEBOUNCE_MAX) {
+ pr_err("Invalid VPH droop debounce specified\n");
return -EINVAL;
}
@@ -1613,14 +1803,12 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
led->pdata->vph_droop_threshold =
VPH_DROOP_THRESH_MV_TO_VAL(val);
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read VPH droop threshold, rc=%d\n", rc);
+ pr_err("Unable to read VPH droop threshold, rc=%d\n", rc);
return rc;
}
if (led->pdata->vph_droop_threshold > FLASH_LED_VPH_DROOP_THRESH_MAX) {
- dev_err(&led->pdev->dev,
- "Invalid VPH droop threshold specified");
+ pr_err("Invalid VPH droop threshold specified\n");
return -EINVAL;
}
@@ -1631,23 +1819,54 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
led->pdata->vph_droop_hysteresis =
VPH_DROOP_HYST_MV_TO_VAL(val);
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read VPH droop hysteresis, rc=%d\n", rc);
+ pr_err("Unable to read VPH droop hysteresis, rc=%d\n", rc);
return rc;
}
- if (led->pdata->vph_droop_hysteresis > FLASH_LED_VPH_DROOP_HYST_MAX) {
- dev_err(&led->pdev->dev,
- "Invalid VPH droop hysteresis specified");
+ if (led->pdata->vph_droop_hysteresis > FLASH_LED_HYSTERESIS_MAX) {
+ pr_err("Invalid VPH droop hysteresis specified\n");
return -EINVAL;
}
+ led->pdata->vph_droop_hysteresis <<= FLASH_LED_VPH_DROOP_HYST_SHIFT;
+
rc = of_property_read_u32(node, "qcom,hw-strobe-option", &val);
if (!rc) {
led->pdata->hw_strobe_option = (u8)val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to parse hw strobe option, rc=%d\n", rc);
+ pr_err("Unable to parse hw strobe option, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32(node, "qcom,led1n2-iclamp-low-ma", &val);
+ if (!rc) {
+ led->pdata->led1n2_iclamp_low_ma = val;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read led1n2_iclamp_low current, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32(node, "qcom,led1n2-iclamp-mid-ma", &val);
+ if (!rc) {
+ led->pdata->led1n2_iclamp_mid_ma = val;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read led1n2_iclamp_mid current, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32(node, "qcom,led3-iclamp-low-ma", &val);
+ if (!rc) {
+ led->pdata->led3_iclamp_low_ma = val;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read led3_iclamp_low current, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32(node, "qcom,led3-iclamp-mid-ma", &val);
+ if (!rc) {
+ led->pdata->led3_iclamp_mid_ma = val;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read led3_iclamp_mid current, rc=%d\n", rc);
return rc;
}
@@ -1656,8 +1875,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->vled_max_uv = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse vled_max voltage, rc=%d\n",
- rc);
+ pr_err("Unable to parse vled_max voltage, rc=%d\n", rc);
return rc;
}
@@ -1667,8 +1885,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->ibatt_ocp_threshold_ua = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse ibatt_ocp threshold, rc=%d\n",
- rc);
+ pr_err("Unable to parse ibatt_ocp threshold, rc=%d\n", rc);
return rc;
}
@@ -1677,8 +1894,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->rpara_uohm = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse rparasitic, rc=%d\n",
- rc);
+ pr_err("Unable to parse rparasitic, rc=%d\n", rc);
return rc;
}
@@ -1688,8 +1904,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->lmh_ocv_threshold_uv = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse lmh ocv threshold, rc=%d\n",
- rc);
+ pr_err("Unable to parse lmh ocv threshold, rc=%d\n", rc);
return rc;
}
@@ -1699,8 +1914,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->lmh_rbatt_threshold_uohm = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse lmh rbatt threshold, rc=%d\n",
- rc);
+ pr_err("Unable to parse lmh rbatt threshold, rc=%d\n", rc);
return rc;
}
@@ -1709,8 +1923,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->lmh_level = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse lmh_level, rc=%d\n",
- rc);
+ pr_err("Unable to parse lmh_level, rc=%d\n", rc);
return rc;
}
@@ -1719,13 +1932,12 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->lmh_mitigation_sel = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse lmh_mitigation_sel, rc=%d\n",
- rc);
+ pr_err("Unable to parse lmh_mitigation_sel, rc=%d\n", rc);
return rc;
}
if (led->pdata->lmh_mitigation_sel > FLASH_LED_MITIGATION_SEL_MAX) {
- dev_err(&led->pdev->dev, "Invalid lmh_mitigation_sel specified\n");
+ pr_err("Invalid lmh_mitigation_sel specified\n");
return -EINVAL;
}
@@ -1734,13 +1946,12 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->chgr_mitigation_sel = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse chgr_mitigation_sel, rc=%d\n",
- rc);
+ pr_err("Unable to parse chgr_mitigation_sel, rc=%d\n", rc);
return rc;
}
if (led->pdata->chgr_mitigation_sel > FLASH_LED_MITIGATION_SEL_MAX) {
- dev_err(&led->pdev->dev, "Invalid chgr_mitigation_sel specified\n");
+ pr_err("Invalid chgr_mitigation_sel specified\n");
return -EINVAL;
}
@@ -1751,30 +1962,29 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->iled_thrsh_val = MITIGATION_THRSH_MA_TO_VAL(val);
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse iled_thrsh_val, rc=%d\n",
- rc);
+ pr_err("Unable to parse iled_thrsh_val, rc=%d\n", rc);
return rc;
}
if (led->pdata->iled_thrsh_val > FLASH_LED_MITIGATION_THRSH_MAX) {
- dev_err(&led->pdev->dev, "Invalid iled_thrsh_val specified\n");
+ pr_err("Invalid iled_thrsh_val specified\n");
return -EINVAL;
}
led->pdata->all_ramp_up_done_irq =
of_irq_get_byname(node, "all-ramp-up-done-irq");
if (led->pdata->all_ramp_up_done_irq < 0)
- dev_dbg(&led->pdev->dev, "all-ramp-up-done-irq not used\n");
+ pr_debug("all-ramp-up-done-irq not used\n");
led->pdata->all_ramp_down_done_irq =
of_irq_get_byname(node, "all-ramp-down-done-irq");
if (led->pdata->all_ramp_down_done_irq < 0)
- dev_dbg(&led->pdev->dev, "all-ramp-down-done-irq not used\n");
+ pr_debug("all-ramp-down-done-irq not used\n");
led->pdata->led_fault_irq =
of_irq_get_byname(node, "led-fault-irq");
if (led->pdata->led_fault_irq < 0)
- dev_dbg(&led->pdev->dev, "led-fault-irq not used\n");
+ pr_debug("led-fault-irq not used\n");
return 0;
}
@@ -1785,18 +1995,18 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
struct device_node *node, *temp;
const char *temp_string;
unsigned int base;
- int rc, i = 0;
+ int rc, i = 0, j = 0;
node = pdev->dev.of_node;
if (!node) {
- dev_info(&pdev->dev, "No flash LED nodes defined\n");
+ pr_err("No flash LED nodes defined\n");
return -ENODEV;
}
rc = of_property_read_u32(node, "reg", &base);
if (rc < 0) {
- dev_err(&pdev->dev, "Couldn't find reg in node %s, rc = %d\n",
- node->full_name, rc);
+ pr_err("Couldn't find reg in node %s, rc = %d\n",
+ node->full_name, rc);
return rc;
}
@@ -1807,7 +2017,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
led->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!led->regmap) {
- dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
+ pr_err("Couldn't get parent's regmap\n");
return -EINVAL;
}
@@ -1820,16 +2030,14 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
rc = qpnp_flash_led_parse_common_dt(led, node);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Failed to parse common flash LED device tree\n");
+ pr_err("Failed to parse common flash LED device tree\n");
return rc;
}
for_each_available_child_of_node(node, temp) {
rc = of_property_read_string(temp, "label", &temp_string);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Failed to parse label, rc=%d\n", rc);
+ pr_err("Failed to parse label, rc=%d\n", rc);
return rc;
}
@@ -1839,14 +2047,13 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
!strcmp("torch", temp_string)) {
led->num_fnodes++;
} else {
- dev_err(&pdev->dev,
- "Invalid label for led node\n");
+ pr_err("Invalid label for led node\n");
return -EINVAL;
}
}
if (!led->num_fnodes) {
- dev_err(&pdev->dev, "No LED nodes defined\n");
+ pr_err("No LED nodes defined\n");
return -ECHILD;
}
@@ -1863,26 +2070,34 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
return -ENOMEM;
temp = NULL;
- for (i = 0; i < led->num_fnodes; i++) {
- temp = of_get_next_available_child(node, temp);
- rc = qpnp_flash_led_parse_each_led_dt(led,
- &led->fnode[i], temp);
+ i = 0;
+ j = 0;
+ for_each_available_child_of_node(node, temp) {
+ rc = of_property_read_string(temp, "label", &temp_string);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to parse flash node %d rc=%d\n", i, rc);
- goto error_led_register;
+ pr_err("Failed to parse label, rc=%d\n", rc);
+ return rc;
}
- }
- for (i = 0; i < led->num_snodes; i++) {
- temp = of_get_next_available_child(node, temp);
- rc = qpnp_flash_led_parse_and_register_switch(led,
- &led->snode[i], temp);
- if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to parse and register switch node, rc=%d\n",
- rc);
- goto error_switch_register;
+ if (!strcmp("flash", temp_string) ||
+ !strcmp("torch", temp_string)) {
+ rc = qpnp_flash_led_parse_each_led_dt(led,
+ &led->fnode[i++], temp);
+ if (rc < 0) {
+ pr_err("Unable to parse flash node %d rc=%d\n",
+ i, rc);
+ goto error_led_register;
+ }
+ }
+
+ if (!strcmp("switch", temp_string)) {
+ rc = qpnp_flash_led_parse_and_register_switch(led,
+ &led->snode[j++], temp);
+ if (rc < 0) {
+ pr_err("Unable to parse and register switch node, rc=%d\n",
+ rc);
+ goto error_switch_register;
+ }
}
}
@@ -1894,8 +2109,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
IRQF_ONESHOT,
"qpnp_flash_led_all_ramp_up_done_irq", led);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to request all_ramp_up_done(%d) IRQ(err:%d)\n",
+ pr_err("Unable to request all_ramp_up_done(%d) IRQ(err:%d)\n",
led->pdata->all_ramp_up_done_irq, rc);
goto error_switch_register;
}
@@ -1908,8 +2122,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
IRQF_ONESHOT,
"qpnp_flash_led_all_ramp_down_done_irq", led);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to request all_ramp_down_done(%d) IRQ(err:%d)\n",
+ pr_err("Unable to request all_ramp_down_done(%d) IRQ(err:%d)\n",
led->pdata->all_ramp_down_done_irq, rc);
goto error_switch_register;
}
@@ -1922,8 +2135,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
IRQF_ONESHOT,
"qpnp_flash_led_fault_irq", led);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to request led_fault(%d) IRQ(err:%d)\n",
+ pr_err("Unable to request led_fault(%d) IRQ(err:%d)\n",
led->pdata->led_fault_irq, rc);
goto error_switch_register;
}
@@ -1933,25 +2145,46 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
if (!led->bms_psy) {
rc = flash_led_psy_register_notifier(led);
if (rc < 0) {
- dev_err(&pdev->dev, "Couldn't register psy notifier, rc = %d\n",
- rc);
+ pr_err("Couldn't register psy notifier, rc = %d\n", rc);
goto error_switch_register;
}
}
rc = qpnp_flash_led_init_settings(led);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Failed to initialize flash LED, rc=%d\n", rc);
+ pr_err("Failed to initialize flash LED, rc=%d\n", rc);
goto unreg_notifier;
}
+ for (i = 0; i < led->num_snodes; i++) {
+ for (j = 0; j < ARRAY_SIZE(qpnp_flash_led_attrs); j++) {
+ rc = sysfs_create_file(&led->snode[i].cdev.dev->kobj,
+ &qpnp_flash_led_attrs[j].attr);
+ if (rc < 0) {
+ pr_err("sysfs creation failed, rc=%d\n", rc);
+ goto sysfs_fail;
+ }
+ }
+ }
+
spin_lock_init(&led->lock);
dev_set_drvdata(&pdev->dev, led);
return 0;
+sysfs_fail:
+ for (--j; j >= 0; j--)
+ sysfs_remove_file(&led->snode[i].cdev.dev->kobj,
+ &qpnp_flash_led_attrs[j].attr);
+
+ for (--i; i >= 0; i--) {
+ for (j = 0; j < ARRAY_SIZE(qpnp_flash_led_attrs); j++)
+ sysfs_remove_file(&led->snode[i].cdev.dev->kobj,
+ &qpnp_flash_led_attrs[j].attr);
+ }
+
+ i = led->num_snodes;
unreg_notifier:
power_supply_unreg_notifier(&led->nb);
error_switch_register:
@@ -1968,20 +2201,21 @@ error_led_register:
static int qpnp_flash_led_remove(struct platform_device *pdev)
{
struct qpnp_flash_led *led = dev_get_drvdata(&pdev->dev);
- int i;
+ int i, j;
for (i = 0; i < led->num_snodes; i++) {
- if (led->snode[i].num_regulators) {
- if (led->snode[i].regulator_on)
- qpnp_flash_led_regulator_enable(led,
- &led->snode[i], false);
- qpnp_flash_led_regulator_setup(led,
+ for (j = 0; j < ARRAY_SIZE(qpnp_flash_led_attrs); j++)
+ sysfs_remove_file(&led->snode[i].cdev.dev->kobj,
+ &qpnp_flash_led_attrs[j].attr);
+
+ if (led->snode[i].regulator_on)
+ qpnp_flash_led_regulator_enable(led,
&led->snode[i], false);
- }
}
while (i > 0)
led_classdev_unregister(&led->snode[--i].cdev);
+
i = led->num_fnodes;
while (i > 0)
led_classdev_unregister(&led->fnode[--i].cdev);
diff --git a/drivers/leds/leds-qpnp-flash.c b/drivers/leds/leds-qpnp-flash.c
index 95b4c42a5adb..98dfa56add51 100644
--- a/drivers/leds/leds-qpnp-flash.c
+++ b/drivers/leds/leds-qpnp-flash.c
@@ -82,7 +82,6 @@
#define FLASH_LED_HDRM_SNS_ENABLE_MASK 0x81
#define FLASH_MASK_MODULE_CONTRL_MASK 0xE0
#define FLASH_FOLLOW_OTST2_RB_MASK 0x08
-#define FLASH_PREPARE_OPTIONS_MASK 0x08
#define FLASH_LED_TRIGGER_DEFAULT "none"
#define FLASH_LED_HEADROOM_DEFAULT_MV 500
@@ -1172,7 +1171,7 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
flash_node = container_of(led_cdev, struct flash_node_data, cdev);
led = dev_get_drvdata(&flash_node->pdev->dev);
- if (!(options & FLASH_PREPARE_OPTIONS_MASK)) {
+ if (!(options & FLASH_LED_PREPARE_OPTIONS_MASK)) {
dev_err(&led->pdev->dev, "Invalid options %d\n", options);
return -EINVAL;
}
diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c
index 894c1d88b3ef..97cfa813f4ce 100644
--- a/drivers/leds/leds-qpnp-wled.c
+++ b/drivers/leds/leds-qpnp-wled.c
@@ -61,11 +61,7 @@
#define QPNP_WLED_EN_MASK 0x7F
#define QPNP_WLED_EN_SHIFT 7
#define QPNP_WLED_FDBK_OP_MASK 0xF8
-#define QPNP_WLED_VREF_MASK 0xF0
-#define QPNP_WLED_VREF_STEP_MV 25
-#define QPNP_WLED_VREF_MIN_MV 300
-#define QPNP_WLED_VREF_MAX_MV 675
-#define QPNP_WLED_DFLT_VREF_MV 350
+#define QPNP_WLED_VREF_MASK GENMASK(3, 0)
#define QPNP_WLED_VLOOP_COMP_RES_MASK 0xF0
#define QPNP_WLED_VLOOP_COMP_RES_OVERWRITE 0x80
@@ -275,6 +271,20 @@ static int qpnp_wled_ilim_settings_pmicobalt[NUM_SUPPORTED_ILIM_THRESHOLDS] = {
105, 280, 450, 620, 970, 1150, 1300, 1500,
};
+struct wled_vref_setting {
+ u32 min_uv;
+ u32 max_uv;
+ u32 step_uv;
+ u32 default_uv;
+};
+
+static struct wled_vref_setting vref_setting_pmi8994 = {
+ 300000, 675000, 25000, 350000,
+};
+static struct wled_vref_setting vref_setting_pmicobalt = {
+ 60000, 397500, 22500, 127500,
+};
+
/**
* qpnp_wled - wed data structure
* @ cdev - led class device
@@ -294,7 +304,7 @@ static int qpnp_wled_ilim_settings_pmicobalt[NUM_SUPPORTED_ILIM_THRESHOLDS] = {
* @ mod_freq_khz - modulator frequency in KHZ
* @ hyb_thres - threshold for hybrid dimming
* @ sync_dly_us - sync delay in us
- * @ vref_mv - ref voltage in mv
+ * @ vref_uv - ref voltage in uv
* @ vref_psm_mv - ref psm voltage in mv
* @ loop_comp_res_kohm - control to select the compensation resistor
* @ loop_ea_gm - control to select the gm for the gm stage in control loop
@@ -337,7 +347,7 @@ struct qpnp_wled {
u16 mod_freq_khz;
u16 hyb_thres;
u16 sync_dly_us;
- u16 vref_mv;
+ u32 vref_uv;
u16 vref_psm_mv;
u16 loop_comp_res_kohm;
u16 loop_ea_gm;
@@ -1248,6 +1258,35 @@ static int qpnp_wled_ilim_config(struct qpnp_wled *wled)
return rc;
}
+static int qpnp_wled_vref_config(struct qpnp_wled *wled)
+{
+
+ struct wled_vref_setting vref_setting;
+ int rc;
+ u8 reg = 0;
+
+ if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE ||
+ wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE)
+ vref_setting = vref_setting_pmicobalt;
+ else
+ vref_setting = vref_setting_pmi8994;
+
+ if (wled->vref_uv < vref_setting.min_uv)
+ wled->vref_uv = vref_setting.min_uv;
+ else if (wled->vref_uv > vref_setting.max_uv)
+ wled->vref_uv = vref_setting.max_uv;
+
+ reg |= DIV_ROUND_CLOSEST(wled->vref_uv - vref_setting.min_uv,
+ vref_setting.step_uv);
+
+ rc = qpnp_wled_masked_write_reg(wled, QPNP_WLED_VREF_MASK,
+ &reg, QPNP_WLED_VREF_REG(wled->ctrl_base));
+ if (rc)
+ pr_err("Write VREF_REG failed, rc=%d\n", rc);
+
+ return rc;
+}
+
/* Configure WLED registers */
static int qpnp_wled_config(struct qpnp_wled *wled)
{
@@ -1272,22 +1311,11 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
return rc;
/* Configure the VREF register */
- if (wled->vref_mv < QPNP_WLED_VREF_MIN_MV)
- wled->vref_mv = QPNP_WLED_VREF_MIN_MV;
- else if (wled->vref_mv > QPNP_WLED_VREF_MAX_MV)
- wled->vref_mv = QPNP_WLED_VREF_MAX_MV;
-
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_VREF_REG(wled->ctrl_base));
- if (rc < 0)
- return rc;
- reg &= QPNP_WLED_VREF_MASK;
- temp = wled->vref_mv - QPNP_WLED_VREF_MIN_MV;
- reg |= (temp / QPNP_WLED_VREF_STEP_MV);
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_VREF_REG(wled->ctrl_base));
- if (rc)
+ rc = qpnp_wled_vref_config(wled);
+ if (rc < 0) {
+ pr_err("Error in configuring wled vref, rc=%d\n", rc);
return rc;
+ }
/* Configure the ILIM register */
rc = qpnp_wled_ilim_config(wled);
@@ -1714,11 +1742,15 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled)
return rc;
}
- wled->vref_mv = QPNP_WLED_DFLT_VREF_MV;
+ if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE ||
+ wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE)
+ wled->vref_uv = vref_setting_pmicobalt.default_uv;
+ else
+ wled->vref_uv = vref_setting_pmi8994.default_uv;
rc = of_property_read_u32(pdev->dev.of_node,
- "qcom,vref-mv", &temp_val);
+ "qcom,vref-uv", &temp_val);
if (!rc) {
- wled->vref_mv = temp_val;
+ wled->vref_uv = temp_val;
} else if (rc != -EINVAL) {
dev_err(&pdev->dev, "Unable to read vref\n");
return rc;
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c
index 2c313016bc90..8213f736205a 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c
@@ -66,39 +66,72 @@ int msm_cpp_get_clock_index(struct cpp_device *cpp_dev, const char *clk_name)
return -EINVAL;
}
-static int cpp_get_clk_freq_tbl(struct clk *clk, struct cpp_hw_info *hw_info,
- uint32_t min_clk_rate)
+static int cpp_get_clk_freq_tbl_dt(struct cpp_device *cpp_dev)
{
- uint32_t i;
+ uint32_t i, count, min_clk_rate;
uint32_t idx = 0;
- signed long freq_tbl_entry = 0;
+ struct device_node *of_node;
+ uint32_t *rates;
+ int32_t rc = 0;
+ struct cpp_hw_info *hw_info;
- if ((clk == NULL) || (hw_info == NULL) || (clk->ops == NULL) ||
- (clk->ops->list_rate == NULL)) {
+ if (cpp_dev == NULL) {
pr_err("Bad parameter\n");
- return -EINVAL;
+ rc = -EINVAL;
+ goto err;
}
- for (i = 0; i < MAX_FREQ_TBL; i++) {
- freq_tbl_entry = clk->ops->list_rate(clk, i);
- pr_debug("entry=%ld\n", freq_tbl_entry);
- if (freq_tbl_entry >= 0) {
- if (freq_tbl_entry >= min_clk_rate) {
- hw_info->freq_tbl[idx++] = freq_tbl_entry;
- pr_debug("tbl[%d]=%ld\n", idx-1,
- freq_tbl_entry);
+ of_node = cpp_dev->pdev->dev.of_node;
+ min_clk_rate = cpp_dev->min_clk_rate;
+ hw_info = &cpp_dev->hw_info;
+
+ if ((hw_info == NULL) || (of_node == NULL)) {
+ pr_err("Invalid hw_info %p or ofnode %p\n", hw_info, of_node);
+ rc = -EINVAL;
+ goto err;
+
+ }
+ count = of_property_count_u32_elems(of_node, "qcom,src-clock-rates");
+ if ((count == 0) || (count > MAX_FREQ_TBL)) {
+ pr_err("Clock count is invalid\n");
+ rc = -EINVAL;
+ goto err;
+ }
+
+ rates = devm_kcalloc(&cpp_dev->pdev->dev, count, sizeof(uint32_t),
+ GFP_KERNEL);
+ if (!rates) {
+ rc = -ENOMEM;
+ goto err;
+ }
+
+ rc = of_property_read_u32_array(of_node, "qcom,src-clock-rates",
+ rates, count);
+ if (rc) {
+ rc = -EINVAL;
+ goto mem_free;
+ }
+
+ for (i = 0; i < count; i++) {
+ pr_debug("entry=%d\n", rates[i]);
+ if (rates[i] >= 0) {
+ if (rates[i] >= min_clk_rate) {
+ hw_info->freq_tbl[idx++] = rates[i];
+ pr_debug("tbl[%d]=%d\n", idx-1, rates[i]);
}
} else {
- pr_debug("freq table returned invalid entry/end %ld\n",
- freq_tbl_entry);
+ pr_debug("rate is invalid entry/end %d\n", rates[i]);
break;
}
}
- pr_debug("%s: idx %d", __func__, idx);
+ pr_debug("%s: idx %d\n", __func__, idx);
hw_info->freq_tbl_count = idx;
- return 0;
+mem_free:
+ devm_kfree(&cpp_dev->pdev->dev, rates);
+err:
+ return rc;
}
int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev)
@@ -147,8 +180,7 @@ int msm_update_freq_tbl(struct cpp_device *cpp_dev)
rc = msm_cpp_core_clk_idx;
return rc;
}
- rc = cpp_get_clk_freq_tbl(cpp_dev->cpp_clk[msm_cpp_core_clk_idx],
- &cpp_dev->hw_info, cpp_dev->min_clk_rate);
+ rc = cpp_get_clk_freq_tbl_dt(cpp_dev);
if (rc < 0) {
pr_err("%s: fail to get frequency table\n", __func__);
return rc;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index 925b8497273a..4e86a3ff820d 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -1502,7 +1502,8 @@ static void sde_hw_rotator_free_rotctx(struct sde_hw_rotator *rot,
ctx->q_id, ctx->timestamp,
atomic_read(&ctx->hwres->num_active));
- rot->rotCtx[ctx->q_id][sde_hw_rotator_get_regdma_ctxidx(ctx)] = NULL;
+ /* Clear rotator context from lookup purpose */
+ sde_hw_rotator_clr_ctx(ctx);
devm_kfree(&rot->pdev->dev, ctx);
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
index 91ac3d0371fa..7aecc3cee210 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
@@ -345,10 +345,32 @@ static inline void sde_hw_rotator_put_ctx(struct sde_hw_rotator_context *ctx)
{
struct sde_hw_rotator *rot = ctx->rot;
u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx);
+ unsigned long flags;
+ spin_lock_irqsave(&rot->rotisr_lock, flags);
rot->rotCtx[ctx->q_id][idx] = ctx;
+ spin_unlock_irqrestore(&rot->rotisr_lock, flags);
+
SDEROT_DBG("rotCtx[%d][%d] <== ctx:%p | session-id:%d\n",
ctx->q_id, idx, ctx, ctx->session_id);
}
+/**
+ * sde_hw_rotator_clr_ctx(): Clearing rotator context according to its
+ * timestamp.
+ */
+static inline void sde_hw_rotator_clr_ctx(struct sde_hw_rotator_context *ctx)
+{
+ struct sde_hw_rotator *rot = ctx->rot;
+ u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx);
+ unsigned long flags;
+
+ spin_lock_irqsave(&rot->rotisr_lock, flags);
+ rot->rotCtx[ctx->q_id][idx] = NULL;
+ spin_unlock_irqrestore(&rot->rotisr_lock, flags);
+
+ SDEROT_DBG("rotCtx[%d][%d] <== null | session-id:%d\n",
+ ctx->q_id, idx, ctx->session_id);
+}
+
#endif /*_SDE_ROTATOR_R3_INTERNAL_H */
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 0b44896bf6b3..7388dab92c34 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -2153,6 +2153,33 @@ int create_pkt_cmd_session_set_property(
pkt->size += sizeof(u32) + sizeof(*signal_info);
break;
}
+ case HAL_PARAM_VENC_IFRAMESIZE_TYPE:
+ {
+ enum hal_iframesize_type hal =
+ *(enum hal_iframesize_type *)pdata;
+ struct hfi_iframe_size *hfi = (struct hfi_iframe_size *)
+ &pkt->rg_property_data[1];
+
+ switch (hal) {
+ case HAL_IFRAMESIZE_TYPE_DEFAULT:
+ hfi->type = HFI_IFRAME_SIZE_DEFAULT;
+ break;
+ case HAL_IFRAMESIZE_TYPE_MEDIUM:
+ hfi->type = HFI_IFRAME_SIZE_MEDIUM;
+ break;
+ case HAL_IFRAMESIZE_TYPE_HUGE:
+ hfi->type = HFI_IFRAME_SIZE_HIGH;
+ break;
+ case HAL_IFRAMESIZE_TYPE_UNLIMITED:
+ hfi->type = HFI_IFRAME_SIZE_UNLIMITED;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+ pkt->rg_property_data[0] = HFI_PROPERTY_PARAM_VENC_IFRAMESIZE;
+ pkt->size += sizeof(u32) + sizeof(struct hfi_iframe_size);
+ break;
+ }
/* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */
case HAL_CONFIG_BUFFER_REQUIREMENTS:
case HAL_CONFIG_PRIORITY:
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index 3633d1fb3cd1..fbdccea56f67 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -36,7 +36,7 @@
struct msm_vidc_drv *vidc_driver;
-uint32_t msm_vidc_pwr_collapse_delay = 2000;
+uint32_t msm_vidc_pwr_collapse_delay = 3000;
static inline struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh)
{
@@ -138,12 +138,20 @@ int msm_v4l2_reqbufs(struct file *file, void *fh,
{
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
int rc = 0;
- if (!b->count)
+ if (!b->count) {
rc = msm_vidc_release_buffers(vidc_inst, b->type);
- if (rc)
- dprintk(VIDC_WARN,
- "Failed in %s for release output buffers\n", __func__);
- return msm_vidc_reqbufs((void *)vidc_inst, b);
+ if (rc)
+ dprintk(VIDC_WARN,
+ "Failed in %s for release output buffers\n",
+ __func__);
+ } else {
+ rc = msm_vidc_reqbufs((void *)vidc_inst, b);
+ if (rc)
+ dprintk(VIDC_WARN,
+ "Failed in %s for buffer requirements\n",
+ __func__);
+ }
+ return rc;
}
int msm_v4l2_prepare_buf(struct file *file, void *fh,
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 0931242a5ec4..4ec331d121d9 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -185,6 +185,13 @@ static const char *const timestamp_mode[] = {
"Ignore",
};
+static const char *const iframe_sizes[] = {
+ "Default",
+ "Medium",
+ "Huge",
+ "Unlimited"
+};
+
static struct msm_vidc_ctrl msm_venc_ctrls[] = {
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD,
@@ -1281,6 +1288,20 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
.step = 1,
.qmenu = NULL,
},
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE,
+ .name = "Bounds of I-frame size",
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT,
+ .maximum = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED,
+ .default_value = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT,
+ .menu_skip_mask = ~(
+ (1 << V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT) |
+ (1 << V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_MEDIUM) |
+ (1 << V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_HUGE) |
+ (1 << V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED)),
+ .qmenu = iframe_sizes,
+ },
};
@@ -2117,6 +2138,19 @@ static inline int venc_v4l2_to_hal(int id, int value)
default:
goto unknown_value;
}
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE:
+ switch (value) {
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT:
+ return HAL_IFRAMESIZE_TYPE_DEFAULT;
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_MEDIUM:
+ return HAL_IFRAMESIZE_TYPE_MEDIUM;
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_HUGE:
+ return HAL_IFRAMESIZE_TYPE_HUGE;
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED:
+ return HAL_IFRAMESIZE_TYPE_UNLIMITED;
+ default:
+ goto unknown_value;
+ }
}
unknown_value:
@@ -2159,6 +2193,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
int frameqp = 0;
int pic_order_cnt = 0;
struct hal_video_signal_info signal_info = {0};
+ enum hal_iframesize_type iframesize_type = HAL_IFRAMESIZE_TYPE_DEFAULT;
if (!inst || !inst->core || !inst->core->device) {
dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
@@ -3242,6 +3277,13 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
}
pdata = &enable;
break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE:
+ property_id = HAL_PARAM_VENC_IFRAMESIZE_TYPE;
+ iframesize_type = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE,
+ ctrl->val);
+ pdata = &iframesize_type;
+ break;
default:
dprintk(VIDC_ERR, "Unsupported index: %x\n", ctrl->id);
rc = -ENOTSUPP;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 93e32ef4ac35..c4d06b658b30 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -652,10 +652,6 @@ int output_buffer_cache_invalidate(struct msm_vidc_inst *inst,
return -EINVAL;
}
- if (binfo->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return 0;
-
-
for (i = 0; i < binfo->num_planes; i++) {
if (binfo->handle[i]) {
rc = msm_comm_smem_cache_operations(inst,
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index 011941c6d4eb..2e1df75cb248 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -24,7 +24,7 @@ EXPORT_SYMBOL(msm_vidc_debug_out);
int msm_vidc_fw_debug = 0x18;
int msm_vidc_fw_debug_mode = 1;
int msm_vidc_fw_low_power_mode = 1;
-int msm_vidc_hw_rsp_timeout = 1000;
+int msm_vidc_hw_rsp_timeout = 2000;
bool msm_vidc_fw_coverage = false;
bool msm_vidc_vpe_csc_601_to_709 = false;
bool msm_vidc_dec_dcvs_mode = true;
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index c87b6fc585c7..787ee43ccbd2 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -3407,10 +3407,12 @@ static int __response_handler(struct venus_hfi_device *device)
packets = device->response_pkt;
- raw_packet = kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_TEMPORARY);
+ raw_packet = device->raw_packet;
+
if (!raw_packet || !packets) {
- dprintk(VIDC_ERR, "%s: Failed to allocate memory\n", __func__);
- kfree(raw_packet);
+ dprintk(VIDC_ERR,
+ "%s: Invalid args : Res packet = %p, Raw packet = %p\n",
+ __func__, packets, raw_packet);
return 0;
}
@@ -3566,7 +3568,6 @@ static int __response_handler(struct venus_hfi_device *device)
exit:
__flush_debug_queue(device, raw_packet);
- kfree(raw_packet);
return packet_count;
}
@@ -4553,6 +4554,13 @@ static struct venus_hfi_device *__add_device(u32 device_id,
goto err_cleanup;
}
+ hdevice->raw_packet =
+ kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_TEMPORARY);
+ if (!hdevice->raw_packet) {
+ dprintk(VIDC_ERR, "failed to allocate raw packet\n");
+ goto err_cleanup;
+ }
+
rc = __init_regs_and_interrupts(hdevice, res);
if (rc)
goto err_cleanup;
@@ -4590,6 +4598,7 @@ err_cleanup:
if (hdevice->vidc_workq)
destroy_workqueue(hdevice->vidc_workq);
kfree(hdevice->response_pkt);
+ kfree(hdevice->raw_packet);
kfree(hdevice);
exit:
return NULL;
@@ -4631,6 +4640,7 @@ void venus_hfi_delete_device(void *device)
iounmap(dev->hal_data->register_base);
kfree(close->hal_data);
kfree(close->response_pkt);
+ kfree(close->raw_packet);
kfree(close);
break;
}
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.h b/drivers/media/platform/msm/vidc/venus_hfi.h
index 7cc71a470c2e..1d2ca88a3c1d 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.h
+++ b/drivers/media/platform/msm/vidc/venus_hfi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -247,6 +247,7 @@ struct venus_hfi_device {
struct hfi_packetization_ops *pkt_ops;
enum hfi_packetization_type packetization_type;
struct msm_vidc_cb_info *response_pkt;
+ u8 *raw_packet;
struct pm_qos_request qos;
unsigned int skip_pc_count;
struct msm_vidc_capability *sys_init_capabilities;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index aa566159c393..116ce12c8dba 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -242,6 +242,7 @@ enum hal_property {
HAL_PARAM_VENC_SESSION_QP_RANGE_PACKED,
HAL_PARAM_VENC_H264_TRANSFORM_8x8,
HAL_PARAM_VENC_VIDEO_SIGNAL_INFO,
+ HAL_PARAM_VENC_IFRAMESIZE_TYPE,
};
enum hal_domain {
@@ -1002,6 +1003,13 @@ struct hal_video_signal_info {
bool full_range;
};
+enum hal_iframesize_type {
+ HAL_IFRAMESIZE_TYPE_DEFAULT,
+ HAL_IFRAMESIZE_TYPE_MEDIUM,
+ HAL_IFRAMESIZE_TYPE_HUGE,
+ HAL_IFRAMESIZE_TYPE_UNLIMITED,
+};
+
enum vidc_resource_id {
VIDC_RESOURCE_NONE,
VIDC_RESOURCE_OCMEM,
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 5e5ef6abc303..bb9958b0a819 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -386,6 +386,8 @@ struct hfi_buffer_info {
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x031)
#define HFI_PROPERTY_PARAM_VENC_VQZIP_SEI_TYPE \
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x033)
+#define HFI_PROPERTY_PARAM_VENC_IFRAMESIZE \
+ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x034)
#define HFI_PROPERTY_CONFIG_VENC_COMMON_START \
(HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x6000)
@@ -888,6 +890,14 @@ struct hfi_aspect_ratio {
u32 aspect_height;
};
+#define HFI_IFRAME_SIZE_DEFAULT (HFI_COMMON_BASE + 0x1)
+#define HFI_IFRAME_SIZE_MEDIUM (HFI_COMMON_BASE + 0x2)
+#define HFI_IFRAME_SIZE_HIGH (HFI_COMMON_BASE + 0x3)
+#define HFI_IFRAME_SIZE_UNLIMITED (HFI_COMMON_BASE + 0x4)
+struct hfi_iframe_size {
+ u32 type;
+};
+
#define HFI_MVC_BUFFER_LAYOUT_TOP_BOTTOM (0)
#define HFI_MVC_BUFFER_LAYOUT_SIDEBYSIDE (1)
#define HFI_MVC_BUFFER_LAYOUT_SEQ (2)
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index ce0752d3b535..240bf2903308 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -619,6 +619,7 @@ struct msm_pcie_dev_t {
bool ext_ref_clk;
bool common_phy;
uint32_t ep_latency;
+ uint32_t wr_halt_size;
uint32_t cpl_timeout;
uint32_t current_bdf;
short current_short_bdf;
@@ -1976,6 +1977,8 @@ static void msm_pcie_show_status(struct msm_pcie_dev_t *dev)
dev->common_phy);
PCIE_DBG_FS(dev, "ep_latency: %dms\n",
dev->ep_latency);
+ PCIE_DBG_FS(dev, "wr_halt_size: 0x%x\n",
+ dev->wr_halt_size);
PCIE_DBG_FS(dev, "cpl_timeout: 0x%x\n",
dev->cpl_timeout);
PCIE_DBG_FS(dev, "current_bdf: 0x%x\n",
@@ -4495,8 +4498,19 @@ int msm_pcie_enable(struct msm_pcie_dev_t *dev, u32 options)
if (dev->use_msi) {
PCIE_DBG(dev, "RC%d: enable WR halt.\n", dev->rc_idx);
- msm_pcie_write_mask(dev->parf +
- PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT, 0, BIT(31));
+ val = dev->wr_halt_size ? dev->wr_halt_size :
+ readl_relaxed(dev->parf +
+ PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
+
+ msm_pcie_write_reg(dev->parf,
+ PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT,
+ BIT(31) | val);
+
+ PCIE_DBG(dev,
+ "RC%d: PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT: 0x%x.\n",
+ dev->rc_idx,
+ readl_relaxed(dev->parf +
+ PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT));
}
mutex_lock(&com_phy_lock);
@@ -5385,9 +5399,6 @@ static irqreturn_t handle_linkdown_irq(int irq, void *data)
dev->link_status = MSM_PCIE_LINK_DISABLED;
dev->shadow_en = false;
- pcie_phy_dump(dev);
- pcie_parf_dump(dev);
-
if (dev->linkdown_panic)
panic("User has chosen to panic on linkdown\n");
@@ -5696,7 +5707,7 @@ static int arch_setup_msi_irq_qgic(struct pci_dev *pdev,
irq_set_msi_desc(firstirq, desc);
msg.address_hi = 0;
msg.address_lo = dev->msi_gicm_addr;
- msg.data = dev->msi_gicm_base;
+ msg.data = dev->msi_gicm_base + (firstirq - dev->msi[0].num);
write_msi_msg(firstirq, &msg);
return 0;
@@ -6071,6 +6082,18 @@ static int msm_pcie_probe(struct platform_device *pdev)
PCIE_DBG(&msm_pcie_dev[rc_idx], "RC%d: ep-latency: 0x%x.\n",
rc_idx, msm_pcie_dev[rc_idx].ep_latency);
+ msm_pcie_dev[rc_idx].wr_halt_size = 0;
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,wr-halt-size",
+ &msm_pcie_dev[rc_idx].wr_halt_size);
+ if (ret)
+ PCIE_DBG(&msm_pcie_dev[rc_idx],
+ "RC%d: wr-halt-size not specified in dt. Use default value.\n",
+ rc_idx);
+ else
+ PCIE_DBG(&msm_pcie_dev[rc_idx], "RC%d: wr-halt-size: 0x%x.\n",
+ rc_idx, msm_pcie_dev[rc_idx].wr_halt_size);
+
msm_pcie_dev[rc_idx].cpl_timeout = 0;
ret = of_property_read_u32((&pdev->dev)->of_node,
"qcom,cpl-timeout",
diff --git a/drivers/pinctrl/qcom/pinctrl-msmfalcon.c b/drivers/pinctrl/qcom/pinctrl-msmfalcon.c
index 45db409eb7c1..3678f952fe0f 100644
--- a/drivers/pinctrl/qcom/pinctrl-msmfalcon.c
+++ b/drivers/pinctrl/qcom/pinctrl-msmfalcon.c
@@ -354,6 +354,8 @@ enum msmfalcon_functions {
msm_mux_blsp_i2c2,
msm_mux_phase_flag31,
msm_mux_blsp_spi3,
+ msm_mux_blsp_spi3_cs1,
+ msm_mux_blsp_spi3_cs2,
msm_mux_wlan1_adc1,
msm_mux_atest_usb13,
msm_mux_tgu_ch1,
@@ -380,7 +382,10 @@ enum msmfalcon_functions {
msm_mux_blsp_spi4,
msm_mux_pri_mi2s,
msm_mux_phase_flag26,
- msm_mux_qdss_cti,
+ msm_mux_qdss_cti0_a,
+ msm_mux_qdss_cti0_b,
+ msm_mux_qdss_cti1_a,
+ msm_mux_qdss_cti1_b,
msm_mux_DP_HOT,
msm_mux_pri_mi2s_ws,
msm_mux_phase_flag27,
@@ -402,7 +407,8 @@ enum msmfalcon_functions {
msm_mux_phase_flag13,
msm_mux_vsense_mode,
msm_mux_blsp_spi7,
- msm_mux_BLSP_UART,
+ msm_mux_blsp_uart6_a,
+ msm_mux_blsp_uart6_b,
msm_mux_sec_mi2s,
msm_mux_sndwire_clk,
msm_mux_phase_flag17,
@@ -415,13 +421,15 @@ enum msmfalcon_functions {
msm_mux_vfr_1,
msm_mux_phase_flag20,
msm_mux_NFC_INT,
- msm_mux_blsp_spi,
+ msm_mux_blsp_spi8_cs1,
+ msm_mux_blsp_spi8_cs2,
msm_mux_m_voc,
msm_mux_phase_flag21,
msm_mux_NFC_EN,
msm_mux_phase_flag22,
msm_mux_NFC_DWL,
- msm_mux_BLSP_I2C,
+ msm_mux_blsp_i2c8_a,
+ msm_mux_blsp_i2c8_b,
msm_mux_phase_flag23,
msm_mux_NFC_ESE,
msm_mux_pwr_modem,
@@ -519,10 +527,15 @@ enum msmfalcon_functions {
msm_mux_atest_char0,
msm_mux_US_EURO,
msm_mux_LCD_BACKLIGHT,
- msm_mux_blsp_spi8,
+ msm_mux_blsp_spi8_a,
+ msm_mux_blsp_spi8_b,
msm_mux_sp_cmu,
- msm_mux_NAV_PPS,
- msm_mux_GPS_TX,
+ msm_mux_nav_pps_a,
+ msm_mux_nav_pps_b,
+ msm_mux_nav_pps_c,
+ msm_mux_gps_tx_a,
+ msm_mux_gps_tx_b,
+ msm_mux_gps_tx_c,
msm_mux_adsp_ext,
msm_mux_TS_RESET,
msm_mux_ssc_irq,
@@ -560,16 +573,23 @@ static const char * const blsp_spi1_groups[] = {
"gpio0", "gpio1", "gpio2", "gpio3", "gpio46",
};
static const char * const gpio_groups[] = {
- "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio6", "gpio7", "gpio8",
- "gpio9", "gpio10", "gpio11", "gpio14", "gpio15", "gpio16", "gpio17",
- "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", "gpio23", "gpio24",
- "gpio25", "gpio32", "gpio33", "gpio34", "gpio35", "gpio36", "gpio37",
- "gpio38", "gpio39", "gpio57", "gpio58", "gpio59", "gpio61", "gpio65",
- "gpio81", "gpio82", "gpio83", "gpio84", "gpio85", "gpio86", "gpio87",
- "gpio88", "gpio89", "gpio90", "gpio91", "gpio92", "gpio93", "gpio94",
- "gpio95", "gpio96", "gpio97", "gpio98", "gpio99", "gpio100", "gpio101",
- "gpio102", "gpio103", "gpio104", "gpio105", "gpio106", "gpio107",
- "gpio108", "gpio109", "gpio110", "gpio111", "gpio112", "gpio113",
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+ "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+ "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
+ "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+ "gpio111", "gpio112", "gpio113",
};
static const char * const blsp_uim1_groups[] = {
"gpio0", "gpio1",
@@ -599,7 +619,13 @@ static const char * const phase_flag31_groups[] = {
"gpio6",
};
static const char * const blsp_spi3_groups[] = {
- "gpio8", "gpio9", "gpio10", "gpio11", "gpio30", "gpio65",
+ "gpio8", "gpio9", "gpio10", "gpio11",
+};
+static const char * const blsp_spi3_cs1_groups[] = {
+ "gpio30",
+};
+static const char * const blsp_spi3_cs2_groups[] = {
+ "gpio65",
};
static const char * const wlan1_adc1_groups[] = {
"gpio8",
@@ -679,9 +705,17 @@ static const char * const pri_mi2s_groups[] = {
static const char * const phase_flag26_groups[] = {
"gpio12",
};
-static const char * const qdss_cti_groups[] = {
- "gpio12", "gpio13", "gpio21", "gpio49", "gpio50", "gpio53", "gpio55",
- "gpio66",
+static const char * const qdss_cti0_a_groups[] = {
+ "gpio49", "gpio50",
+};
+static const char * const qdss_cti0_b_groups[] = {
+ "gpio13", "gpio21",
+};
+static const char * const qdss_cti1_a_groups[] = {
+ "gpio53", "gpio55",
+};
+static const char * const qdss_cti1_b_groups[] = {
+ "gpio12", "gpio66",
};
static const char * const DP_HOT_groups[] = {
"gpio13",
@@ -746,9 +780,11 @@ static const char * const vsense_mode_groups[] = {
static const char * const blsp_spi7_groups[] = {
"gpio24", "gpio25", "gpio26", "gpio27",
};
-static const char * const BLSP_UART_groups[] = {
- "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29", "gpio30",
- "gpio31",
+static const char * const blsp_uart6_a_groups[] = {
+ "gpio24", "gpio25", "gpio26", "gpio27",
+};
+static const char * const blsp_uart6_b_groups[] = {
+ "gpio28", "gpio29", "gpio30", "gpio31",
};
static const char * const sec_mi2s_groups[] = {
"gpio24", "gpio25", "gpio26", "gpio27", "gpio62",
@@ -786,9 +822,11 @@ static const char * const phase_flag20_groups[] = {
static const char * const NFC_INT_groups[] = {
"gpio28",
};
-static const char * const blsp_spi_groups[] = {
- "gpio28", "gpio29", "gpio30", "gpio31", "gpio40", "gpio41", "gpio44",
- "gpio52",
+static const char * const blsp_spi8_a_groups[] = {
+ "gpio28", "gpio29", "gpio30", "gpio31",
+};
+static const char * const blsp_spi8_b_groups[] = {
+ "gpio40", "gpio41", "gpio44", "gpio52",
};
static const char * const m_voc_groups[] = {
"gpio28",
@@ -805,8 +843,11 @@ static const char * const phase_flag22_groups[] = {
static const char * const NFC_DWL_groups[] = {
"gpio30",
};
-static const char * const BLSP_I2C_groups[] = {
- "gpio30", "gpio31", "gpio44", "gpio52",
+static const char * const blsp_i2c8_a_groups[] = {
+ "gpio30", "gpio31",
+};
+static const char * const blsp_i2c8_b_groups[] = {
+ "gpio44", "gpio52",
};
static const char * const phase_flag23_groups[] = {
"gpio30",
@@ -1099,17 +1140,32 @@ static const char * const US_EURO_groups[] = {
static const char * const LCD_BACKLIGHT_groups[] = {
"gpio64",
};
-static const char * const blsp_spi8_groups[] = {
- "gpio64", "gpio76",
+static const char * const blsp_spi8_cs1_groups[] = {
+ "gpio64",
+};
+static const char * const blsp_spi8_cs2_groups[] = {
+ "gpio76",
};
static const char * const sp_cmu_groups[] = {
"gpio64",
};
-static const char * const NAV_PPS_groups[] = {
- "gpio65", "gpio65", "gpio80", "gpio80", "gpio98", "gpio98",
+static const char * const nav_pps_a_groups[] = {
+ "gpio65",
};
-static const char * const GPS_TX_groups[] = {
- "gpio65", "gpio80", "gpio98",
+static const char * const nav_pps_b_groups[] = {
+ "gpio98",
+};
+static const char * const nav_pps_c_groups[] = {
+ "gpio80",
+};
+static const char * const gps_tx_a_groups[] = {
+ "gpio65",
+};
+static const char * const gps_tx_b_groups[] = {
+ "gpio98",
+};
+static const char * const gps_tx_c_groups[] = {
+ "gpio80",
};
static const char * const adsp_ext_groups[] = {
"gpio65",
@@ -1216,6 +1272,8 @@ static const struct msm_function msmfalcon_functions[] = {
FUNCTION(blsp_i2c2),
FUNCTION(phase_flag31),
FUNCTION(blsp_spi3),
+ FUNCTION(blsp_spi3_cs1),
+ FUNCTION(blsp_spi3_cs2),
FUNCTION(wlan1_adc1),
FUNCTION(atest_usb13),
FUNCTION(tgu_ch1),
@@ -1242,7 +1300,10 @@ static const struct msm_function msmfalcon_functions[] = {
FUNCTION(blsp_spi4),
FUNCTION(pri_mi2s),
FUNCTION(phase_flag26),
- FUNCTION(qdss_cti),
+ FUNCTION(qdss_cti0_a),
+ FUNCTION(qdss_cti0_b),
+ FUNCTION(qdss_cti1_a),
+ FUNCTION(qdss_cti1_b),
FUNCTION(DP_HOT),
FUNCTION(pri_mi2s_ws),
FUNCTION(phase_flag27),
@@ -1264,7 +1325,8 @@ static const struct msm_function msmfalcon_functions[] = {
FUNCTION(phase_flag13),
FUNCTION(vsense_mode),
FUNCTION(blsp_spi7),
- FUNCTION(BLSP_UART),
+ FUNCTION(blsp_uart6_a),
+ FUNCTION(blsp_uart6_b),
FUNCTION(sec_mi2s),
FUNCTION(sndwire_clk),
FUNCTION(phase_flag17),
@@ -1277,13 +1339,15 @@ static const struct msm_function msmfalcon_functions[] = {
FUNCTION(vfr_1),
FUNCTION(phase_flag20),
FUNCTION(NFC_INT),
- FUNCTION(blsp_spi),
+ FUNCTION(blsp_spi8_cs1),
+ FUNCTION(blsp_spi8_cs2),
FUNCTION(m_voc),
FUNCTION(phase_flag21),
FUNCTION(NFC_EN),
FUNCTION(phase_flag22),
FUNCTION(NFC_DWL),
- FUNCTION(BLSP_I2C),
+ FUNCTION(blsp_i2c8_a),
+ FUNCTION(blsp_i2c8_b),
FUNCTION(phase_flag23),
FUNCTION(NFC_ESE),
FUNCTION(pwr_modem),
@@ -1381,10 +1445,15 @@ static const struct msm_function msmfalcon_functions[] = {
FUNCTION(atest_char0),
FUNCTION(US_EURO),
FUNCTION(LCD_BACKLIGHT),
- FUNCTION(blsp_spi8),
+ FUNCTION(blsp_spi8_a),
+ FUNCTION(blsp_spi8_b),
FUNCTION(sp_cmu),
- FUNCTION(NAV_PPS),
- FUNCTION(GPS_TX),
+ FUNCTION(nav_pps_a),
+ FUNCTION(nav_pps_b),
+ FUNCTION(nav_pps_c),
+ FUNCTION(gps_tx_a),
+ FUNCTION(gps_tx_b),
+ FUNCTION(gps_tx_c),
FUNCTION(adsp_ext),
FUNCTION(TS_RESET),
FUNCTION(ssc_irq),
@@ -1441,10 +1510,10 @@ static const struct msm_pingroup msmfalcon_groups[] = {
atest_usb11, bimc_dte1, NA),
PINGROUP(11, NORTH, blsp_spi3, blsp_i2c3, NA, dbg_out, wlan2_adc0,
atest_usb10, bimc_dte0, NA, NA),
- PINGROUP(12, NORTH, blsp_spi4, pri_mi2s, NA, phase_flag26, qdss_cti,
+ PINGROUP(12, NORTH, blsp_spi4, pri_mi2s, NA, phase_flag26, qdss_cti1_b,
NA, NA, NA, NA),
PINGROUP(13, NORTH, blsp_spi4, DP_HOT, pri_mi2s_ws, NA, NA,
- phase_flag27, qdss_cti, NA, NA),
+ phase_flag27, qdss_cti0_b, NA, NA),
PINGROUP(14, NORTH, blsp_spi4, blsp_i2c4, pri_mi2s, NA, phase_flag28,
NA, NA, NA, NA),
PINGROUP(15, NORTH, blsp_spi4, blsp_i2c4, pri_mi2s, NA, NA, NA, NA, NA,
@@ -1460,27 +1529,27 @@ static const struct msm_pingroup msmfalcon_groups[] = {
PINGROUP(20, SOUTH, blsp_spi6, blsp_uart2, blsp_uim6, NA, NA, NA, NA,
NA, NA),
PINGROUP(21, SOUTH, blsp_spi6, blsp_uart2, blsp_uim6, NA, phase_flag11,
- qdss_cti, vsense_data0, NA, NA),
+ qdss_cti0_b, vsense_data0, NA, NA),
PINGROUP(22, CENTER, blsp_spi6, blsp_uart2, blsp_i2c6, NA,
phase_flag12, vsense_data1, NA, NA, NA),
PINGROUP(23, CENTER, blsp_spi6, blsp_uart2, blsp_i2c6, NA,
phase_flag13, vsense_mode, NA, NA, NA),
- PINGROUP(24, NORTH, blsp_spi7, BLSP_UART, sec_mi2s, sndwire_clk, NA,
+ PINGROUP(24, NORTH, blsp_spi7, blsp_uart6_a, sec_mi2s, sndwire_clk, NA,
NA, phase_flag17, vsense_clkout, NA),
- PINGROUP(25, NORTH, blsp_spi7, BLSP_UART, sec_mi2s, sndwire_data, NA,
+ PINGROUP(25, NORTH, blsp_spi7, blsp_uart6_a, sec_mi2s, sndwire_data, NA,
NA, phase_flag18, NA, NA),
- PINGROUP(26, NORTH, blsp_spi7, BLSP_UART, blsp_i2c7, sec_mi2s, NA,
+ PINGROUP(26, NORTH, blsp_spi7, blsp_uart6_a, blsp_i2c7, sec_mi2s, NA,
phase_flag19, NA, NA, NA),
- PINGROUP(27, NORTH, blsp_spi7, BLSP_UART, blsp_i2c7, vfr_1, sec_mi2s,
+ PINGROUP(27, NORTH, blsp_spi7, blsp_uart6_a, blsp_i2c7, vfr_1, sec_mi2s,
NA, phase_flag20, NA, NA),
- PINGROUP(28, CENTER, blsp_spi, BLSP_UART, m_voc, NA, phase_flag21, NA,
- NA, NA, NA),
- PINGROUP(29, CENTER, blsp_spi, BLSP_UART, NA, NA, phase_flag22, NA, NA,
- NA, NA),
- PINGROUP(30, CENTER, blsp_spi, BLSP_UART, BLSP_I2C, blsp_spi3, NA,
- phase_flag23, NA, NA, NA),
- PINGROUP(31, CENTER, blsp_spi, BLSP_UART, BLSP_I2C, pwr_modem, NA,
- phase_flag24, qdss_gpio, NA, NA),
+ PINGROUP(28, CENTER, blsp_spi8_a, blsp_uart6_b, m_voc, NA, phase_flag21,
+ NA, NA, NA, NA),
+ PINGROUP(29, CENTER, blsp_spi8_a, blsp_uart6_b, NA, NA, phase_flag22,
+ NA, NA, NA, NA),
+ PINGROUP(30, CENTER, blsp_spi8_a, blsp_uart6_b, blsp_i2c8_a,
+ blsp_spi3_cs1, NA, phase_flag23, NA, NA, NA),
+ PINGROUP(31, CENTER, blsp_spi8_a, blsp_uart6_b, blsp_i2c8_a, pwr_modem,
+ NA, phase_flag24, qdss_gpio, NA, NA),
PINGROUP(32, SOUTH, cam_mclk, pwr_nav, NA, NA, qdss_gpio0, NA, NA, NA,
NA),
PINGROUP(33, SOUTH, cam_mclk, qspi_data0, pwr_crypto, NA, NA,
@@ -1495,30 +1564,35 @@ static const struct msm_pingroup msmfalcon_groups[] = {
atest_usb23, NA, NA, NA),
PINGROUP(38, SOUTH, cci_i2c, NA, NA, qdss_gpio6, NA, NA, NA, NA, NA),
PINGROUP(39, SOUTH, cci_i2c, NA, NA, qdss_gpio7, NA, NA, NA, NA, NA),
- PINGROUP(40, SOUTH, CCI_TIMER0, NA, blsp_spi, NA, NA, NA, NA, NA, NA),
- PINGROUP(41, SOUTH, CCI_TIMER1, NA, blsp_spi, NA, NA, NA, NA, NA, NA),
+ PINGROUP(40, SOUTH, CCI_TIMER0, NA, blsp_spi8_b, NA, NA, NA, NA, NA,
+ NA),
+ PINGROUP(41, SOUTH, CCI_TIMER1, NA, blsp_spi8_b, NA, NA, NA, NA, NA,
+ NA),
PINGROUP(42, SOUTH, mdss_vsync0, mdss_vsync1, mdss_vsync2, mdss_vsync3,
NA, NA, qdss_gpio9, NA, NA),
PINGROUP(43, SOUTH, CCI_TIMER3, CCI_ASYNC, qspi_cs, NA, NA,
qdss_gpio10, NA, NA, NA),
- PINGROUP(44, SOUTH, CCI_TIMER4, CCI_ASYNC, blsp_spi, BLSP_I2C, NA, NA,
- qdss_gpio11, NA, NA),
+ PINGROUP(44, SOUTH, CCI_TIMER4, CCI_ASYNC, blsp_spi8_b, blsp_i2c8_b, NA,
+ NA, qdss_gpio11, NA, NA),
PINGROUP(45, SOUTH, cci_async, NA, NA, qdss_gpio12, NA, NA, NA, NA, NA),
PINGROUP(46, SOUTH, blsp_spi1, NA, NA, qdss_gpio13, NA, NA, NA, NA, NA),
PINGROUP(47, SOUTH, qspi_clk, NA, phase_flag30, qdss_gpio14, NA, NA,
NA, NA, NA),
PINGROUP(48, SOUTH, NA, phase_flag1, qdss_gpio15, NA, NA, NA, NA, NA,
NA),
- PINGROUP(49, SOUTH, NA, phase_flag2, qdss_cti, NA, NA, NA, NA, NA, NA),
- PINGROUP(50, SOUTH, qspi_cs, NA, phase_flag9, qdss_cti, NA, NA, NA, NA,
+ PINGROUP(49, SOUTH, NA, phase_flag2, qdss_cti0_a, NA, NA, NA, NA, NA,
NA),
+ PINGROUP(50, SOUTH, qspi_cs, NA, phase_flag9, qdss_cti0_a, NA, NA, NA,
+ NA, NA),
PINGROUP(51, SOUTH, qspi_data3, NA, phase_flag15, qdss_gpio8, NA, NA,
NA, NA, NA),
- PINGROUP(52, SOUTH, CCI_TIMER2, blsp_spi, BLSP_I2C, NA, phase_flag16,
- qdss_gpio, NA, NA, NA),
- PINGROUP(53, NORTH, NA, phase_flag6, qdss_cti, NA, NA, NA, NA, NA, NA),
+ PINGROUP(52, SOUTH, CCI_TIMER2, blsp_spi8_b, blsp_i2c8_b, NA,
+ phase_flag16, qdss_gpio, NA, NA, NA),
+ PINGROUP(53, NORTH, NA, phase_flag6, qdss_cti1_a, NA, NA, NA, NA, NA,
+ NA),
PINGROUP(54, NORTH, NA, NA, phase_flag29, NA, NA, NA, NA, NA, NA),
- PINGROUP(55, SOUTH, NA, phase_flag25, qdss_cti, NA, NA, NA, NA, NA, NA),
+ PINGROUP(55, SOUTH, NA, phase_flag25, qdss_cti1_a, NA, NA, NA, NA, NA,
+ NA),
PINGROUP(56, SOUTH, NA, phase_flag10, qdss_gpio3, NA, atest_usb20, NA,
NA, NA, NA),
PINGROUP(57, SOUTH, gcc_gp1, NA, phase_flag4, atest_usb22, NA, NA, NA,
@@ -1533,11 +1607,11 @@ static const struct msm_pingroup msmfalcon_groups[] = {
PINGROUP(62, NORTH, sec_mi2s, audio_ref, MDP_VSYNC, cri_trng, NA, NA,
atest_char0, NA, NA),
PINGROUP(63, NORTH, NA, NA, NA, qdss_gpio1, NA, NA, NA, NA, NA),
- PINGROUP(64, SOUTH, blsp_spi8, sp_cmu, NA, NA, qdss_gpio2, NA, NA, NA,
- NA),
- PINGROUP(65, SOUTH, NA, NAV_PPS, NAV_PPS, GPS_TX, blsp_spi3, adsp_ext,
- NA, NA, NA),
- PINGROUP(66, NORTH, NA, NA, qdss_cti, NA, NA, NA, NA, NA, NA),
+ PINGROUP(64, SOUTH, blsp_spi8_cs1, sp_cmu, NA, NA, qdss_gpio2, NA, NA,
+ NA, NA),
+ PINGROUP(65, SOUTH, NA, nav_pps_a, nav_pps_a, gps_tx_a, blsp_spi3_cs2,
+ adsp_ext, NA, NA, NA),
+ PINGROUP(66, NORTH, NA, NA, qdss_cti1_b, NA, NA, NA, NA, NA, NA),
PINGROUP(67, NORTH, NA, NA, qdss_gpio0, NA, NA, NA, NA, NA, NA),
PINGROUP(68, NORTH, isense_dbg, NA, phase_flag0, qdss_gpio, NA, NA, NA,
NA, NA),
@@ -1550,12 +1624,13 @@ static const struct msm_pingroup msmfalcon_groups[] = {
PINGROUP(73, NORTH, NA, NA, qdss_gpio15, NA, NA, NA, NA, NA, NA),
PINGROUP(74, NORTH, mdp_vsync, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(75, NORTH, NA, NA, qdss_gpio8, NA, NA, NA, NA, NA, NA),
- PINGROUP(76, NORTH, blsp_spi8, NA, NA, NA, qdss_gpio9, NA, NA, NA, NA),
+ PINGROUP(76, NORTH, blsp_spi8_cs2, NA, NA, NA, qdss_gpio9, NA, NA, NA,
+ NA),
PINGROUP(77, NORTH, NA, NA, qdss_gpio10, NA, NA, NA, NA, NA, NA),
PINGROUP(78, NORTH, gcc_gp1, NA, qdss_gpio13, NA, NA, NA, NA, NA, NA),
PINGROUP(79, SOUTH, NA, NA, qdss_gpio11, NA, NA, NA, NA, NA, NA),
- PINGROUP(80, SOUTH, NAV_PPS, NAV_PPS, GPS_TX, NA, NA, qdss_gpio12, NA,
- NA, NA),
+ PINGROUP(80, SOUTH, nav_pps_b, nav_pps_b, gps_tx_c, NA, NA, qdss_gpio12,
+ NA, NA, NA),
PINGROUP(81, CENTER, mss_lte, gcc_gp2, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(82, CENTER, mss_lte, gcc_gp3, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(83, SOUTH, uim2_data, NA, NA, NA, NA, NA, NA, NA, NA),
@@ -1573,8 +1648,8 @@ static const struct msm_pingroup msmfalcon_groups[] = {
PINGROUP(95, SOUTH, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(96, SOUTH, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(97, SOUTH, NA, ldo_en, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(98, SOUTH, NA, NAV_PPS, NAV_PPS, GPS_TX, ldo_update, NA, NA,
- NA, NA),
+ PINGROUP(98, SOUTH, NA, nav_pps_c, nav_pps_c, gps_tx_b, ldo_update, NA,
+ NA, NA, NA),
PINGROUP(99, SOUTH, qlink_request, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(100, SOUTH, qlink_enable, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(101, SOUTH, NA, NA, NA, NA, NA, NA, NA, NA, NA),
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c
index 804c89dc9533..73add50cf224 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c
@@ -4907,20 +4907,16 @@ int ipa_iommu_map(struct iommu_domain *domain,
IPADBG("domain =0x%p iova 0x%lx\n", domain, iova);
IPADBG("paddr =0x%pa size 0x%x\n", &paddr, (u32)size);
- /* make sure no overlapping */
+ /* Checking the address overlapping */
if (domain == ipa2_get_smmu_domain()) {
if (iova >= ap_cb->va_start && iova < ap_cb->va_end) {
IPAERR("iommu AP overlap addr 0x%lx\n", iova);
- ipa_assert();
- return -EFAULT;
}
} else if (domain == ipa2_get_wlan_smmu_domain()) {
/* wlan is one time map */
} else if (domain == ipa2_get_uc_smmu_domain()) {
if (iova >= uc_cb->va_start && iova < uc_cb->va_end) {
IPAERR("iommu uC overlap addr 0x%lx\n", iova);
- ipa_assert();
- return -EFAULT;
}
} else {
IPAERR("Unexpected domain 0x%p\n", domain);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c
index cb47773e8a39..21ce28204069 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c
@@ -585,7 +585,9 @@ send_cmd:
if (ipa3_ctx->uc_ctx.uc_status != expected_status) {
if (ipa3_ctx->uc_ctx.uc_status ==
- IPA_HW_PROD_DISABLE_CMD_GSI_STOP_FAILURE) {
+ IPA_HW_PROD_DISABLE_CMD_GSI_STOP_FAILURE ||
+ ipa3_ctx->uc_ctx.uc_status ==
+ IPA_HW_CONS_DISABLE_CMD_GSI_STOP_FAILURE) {
retries++;
if (retries == IPA_GSI_CHANNEL_STOP_MAX_RETRY) {
IPAERR("Failed after %d tries\n", retries);
@@ -594,7 +596,9 @@ send_cmd:
return -EFAULT;
}
IPA3_UC_UNLOCK(flags);
- ipa3_inject_dma_task_for_gsi();
+ if (ipa3_ctx->uc_ctx.uc_status ==
+ IPA_HW_PROD_DISABLE_CMD_GSI_STOP_FAILURE)
+ ipa3_inject_dma_task_for_gsi();
/* sleep for short period to flush IPA */
usleep_range(IPA_GSI_CHANNEL_STOP_SLEEP_MIN_USEC,
IPA_GSI_CHANNEL_STOP_SLEEP_MAX_USEC);
diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/qcom-charger/fg-core.h
index 3f67f49377b4..d612016b1b79 100644
--- a/drivers/power/qcom-charger/fg-core.h
+++ b/drivers/power/qcom-charger/fg-core.h
@@ -74,6 +74,7 @@ enum fg_debug_flag {
FG_BUS_WRITE = BIT(5), /* Show REGMAP writes */
FG_BUS_READ = BIT(6), /* Show REGMAP reads */
FG_CAP_LEARN = BIT(7), /* Show capacity learning */
+ FG_TTF = BIT(8), /* Show time to full */
};
/* SRAM access */
@@ -128,6 +129,7 @@ enum {
*/
enum fg_sram_param_id {
FG_SRAM_BATT_SOC = 0,
+ FG_SRAM_FULL_SOC,
FG_SRAM_VOLTAGE_PRED,
FG_SRAM_OCV,
FG_SRAM_RSLOW,
@@ -250,6 +252,29 @@ struct fg_irq_info {
int irq;
};
+struct fg_circ_buf {
+ int arr[20];
+ int size;
+ int head;
+};
+
+struct fg_pt {
+ s32 x;
+ s32 y;
+};
+
+static const struct fg_pt fg_ln_table[] = {
+ { 1000, 0 },
+ { 2000, 693 },
+ { 4000, 1386 },
+ { 6000, 1792 },
+ { 8000, 2079 },
+ { 16000, 2773 },
+ { 32000, 3466 },
+ { 64000, 4159 },
+ { 128000, 4852 },
+};
+
struct fg_chip {
struct device *dev;
struct pmic_revid_data *pmic_rev_id;
@@ -275,12 +300,15 @@ struct fg_chip {
struct fg_cap_learning cl;
struct mutex bus_lock;
struct mutex sram_rw_lock;
+ struct mutex batt_avg_lock;
u32 batt_soc_base;
u32 batt_info_base;
u32 mem_if_base;
int batt_id_kohms;
- int status;
+ int charge_status;
+ int prev_charge_status;
int charge_done;
+ int charge_type;
int last_soc;
int last_batt_temp;
int health;
@@ -297,6 +325,9 @@ struct fg_chip {
struct delayed_work profile_load_work;
struct work_struct status_change_work;
struct work_struct cycle_count_work;
+ struct delayed_work batt_avg_work;
+ struct fg_circ_buf ibatt_circ_buf;
+ struct fg_circ_buf vbatt_circ_buf;
};
/* Debugfs data structures are below */
@@ -348,4 +379,8 @@ extern void fill_string(char *str, size_t str_len, u8 *buf, int buf_len);
extern int64_t twos_compliment_extend(int64_t val, int s_bit_pos);
extern s64 fg_float_decode(u16 val);
extern bool is_input_present(struct fg_chip *chip);
+extern void fg_circ_buf_add(struct fg_circ_buf *, int);
+extern void fg_circ_buf_clr(struct fg_circ_buf *);
+extern int fg_circ_buf_avg(struct fg_circ_buf *, int *);
+extern int fg_lerp(const struct fg_pt *, size_t, s32, s32 *);
#endif
diff --git a/drivers/power/qcom-charger/fg-util.c b/drivers/power/qcom-charger/fg-util.c
index 0e3c7dbb5731..405d875ea7df 100644
--- a/drivers/power/qcom-charger/fg-util.c
+++ b/drivers/power/qcom-charger/fg-util.c
@@ -14,6 +14,82 @@
#include "fg-core.h"
+void fg_circ_buf_add(struct fg_circ_buf *buf, int val)
+{
+ buf->arr[buf->head] = val;
+ buf->head = (buf->head + 1) % ARRAY_SIZE(buf->arr);
+ buf->size = min(++buf->size, (int)ARRAY_SIZE(buf->arr));
+}
+
+void fg_circ_buf_clr(struct fg_circ_buf *buf)
+{
+ memset(buf, 0, sizeof(*buf));
+}
+
+int fg_circ_buf_avg(struct fg_circ_buf *buf, int *avg)
+{
+ s64 result = 0;
+ int i;
+
+ if (buf->size == 0)
+ return -ENODATA;
+
+ for (i = 0; i < buf->size; i++)
+ result += buf->arr[i];
+
+ *avg = div_s64(result, buf->size);
+ return 0;
+}
+
+int fg_lerp(const struct fg_pt *pts, size_t tablesize, s32 input, s32 *output)
+{
+ int i;
+ s64 temp;
+
+ if (pts == NULL) {
+ pr_err("Table is NULL\n");
+ return -EINVAL;
+ }
+
+ if (tablesize < 1) {
+ pr_err("Table has no entries\n");
+ return -ENOENT;
+ }
+
+ if (tablesize == 1) {
+ *output = pts[0].y;
+ return 0;
+ }
+
+ if (pts[0].x > pts[1].x) {
+ pr_err("Table is not in acending order\n");
+ return -EINVAL;
+ }
+
+ if (input <= pts[0].x) {
+ *output = pts[0].y;
+ return 0;
+ }
+
+ if (input >= pts[tablesize - 1].x) {
+ *output = pts[tablesize - 1].y;
+ return 0;
+ }
+
+ for (i = 1; i < tablesize; i++) {
+ if (input >= pts[i].x)
+ continue;
+
+ temp = (s64)(pts[i].y - pts[i - 1].y) *
+ (s64)(input - pts[i - 1].x);
+ temp = div_s64(temp, pts[i].x - pts[i - 1].x);
+ *output = temp + pts[i - 1].y;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
static struct fg_dbgfs dbgfs_data = {
.help_msg = {
.data =
diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/qcom-charger/qpnp-fg-gen3.c
index dfbf1adc5a38..100153280d9e 100644
--- a/drivers/power/qcom-charger/qpnp-fg-gen3.c
+++ b/drivers/power/qcom-charger/qpnp-fg-gen3.c
@@ -146,6 +146,8 @@ static void fg_encode_default(struct fg_sram_param *sp,
static struct fg_sram_param pmicobalt_v1_sram_params[] = {
PARAM(BATT_SOC, BATT_SOC_WORD, BATT_SOC_OFFSET, 4, 1, 1, 0, NULL,
fg_decode_default),
+ PARAM(FULL_SOC, FULL_SOC_WORD, FULL_SOC_OFFSET, 2, 1, 1, 0, NULL,
+ fg_decode_default),
PARAM(VOLTAGE_PRED, VOLTAGE_PRED_WORD, VOLTAGE_PRED_OFFSET, 2, 244141,
1000, 0, NULL, fg_decode_voltage_15b),
PARAM(OCV, OCV_WORD, OCV_OFFSET, 2, 244141, 1000, 0, NULL,
@@ -198,6 +200,8 @@ static struct fg_sram_param pmicobalt_v1_sram_params[] = {
static struct fg_sram_param pmicobalt_v2_sram_params[] = {
PARAM(BATT_SOC, BATT_SOC_WORD, BATT_SOC_OFFSET, 4, 1, 1, 0, NULL,
fg_decode_default),
+ PARAM(FULL_SOC, FULL_SOC_WORD, FULL_SOC_OFFSET, 2, 1, 1, 0, NULL,
+ fg_decode_default),
PARAM(VOLTAGE_PRED, VOLTAGE_PRED_WORD, VOLTAGE_PRED_OFFSET, 2, 244141,
1000, 0, NULL, fg_decode_voltage_15b),
PARAM(OCV, OCV_WORD, OCV_OFFSET, 2, 244141, 1000, 0, NULL,
@@ -1196,11 +1200,11 @@ static void fg_cap_learning_update(struct fg_chip *chip)
batt_soc = (u32)batt_soc >> 24;
fg_dbg(chip, FG_CAP_LEARN, "Chg_status: %d cl_active: %d batt_soc: %d\n",
- chip->status, chip->cl.active, batt_soc);
+ chip->charge_status, chip->cl.active, batt_soc);
/* Initialize the starting point of learning capacity */
if (!chip->cl.active) {
- if (chip->status == POWER_SUPPLY_STATUS_CHARGING) {
+ if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING) {
rc = fg_cap_learning_begin(chip, batt_soc);
chip->cl.active = (rc == 0);
}
@@ -1216,7 +1220,7 @@ static void fg_cap_learning_update(struct fg_chip *chip)
chip->cl.init_cc_uah = 0;
}
- if (chip->status == POWER_SUPPLY_STATUS_NOT_CHARGING) {
+ if (chip->charge_status == POWER_SUPPLY_STATUS_NOT_CHARGING) {
fg_dbg(chip, FG_CAP_LEARN, "Capacity learning aborted @ battery SOC %d\n",
batt_soc);
chip->cl.active = false;
@@ -1246,7 +1250,7 @@ static int fg_adjust_ki_coeff_dischg(struct fg_chip *chip)
return rc;
}
- if (chip->status == POWER_SUPPLY_STATUS_DISCHARGING) {
+ if (chip->charge_status == POWER_SUPPLY_STATUS_DISCHARGING) {
for (i = KI_COEFF_SOC_LEVELS - 1; i >= 0; i--) {
if (msoc < chip->dt.ki_coeff_soc[i]) {
ki_coeff_med = chip->dt.ki_coeff_med_dischg[i];
@@ -1320,7 +1324,7 @@ static int fg_charge_full_update(struct fg_chip *chip)
}
fg_dbg(chip, FG_STATUS, "msoc: %d health: %d status: %d\n", msoc,
- chip->health, chip->status);
+ chip->health, chip->charge_status);
if (chip->charge_done) {
if (msoc >= 99 && chip->health == POWER_SUPPLY_HEALTH_GOOD)
chip->charge_full = true;
@@ -1438,10 +1442,11 @@ static int fg_esr_fcc_config(struct fg_chip *chip)
parallel_en = prop.intval;
}
- fg_dbg(chip, FG_POWER_SUPPLY, "status: %d parallel_en: %d esr_fcc_ctrl_en: %d\n",
- chip->status, parallel_en, chip->esr_fcc_ctrl_en);
+ fg_dbg(chip, FG_POWER_SUPPLY, "charge_status: %d parallel_en: %d esr_fcc_ctrl_en: %d\n",
+ chip->charge_status, parallel_en, chip->esr_fcc_ctrl_en);
- if (chip->status == POWER_SUPPLY_STATUS_CHARGING && parallel_en) {
+ if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING &&
+ parallel_en) {
if (chip->esr_fcc_ctrl_en)
return 0;
@@ -1487,6 +1492,21 @@ static int fg_esr_fcc_config(struct fg_chip *chip)
return 0;
}
+static void fg_batt_avg_update(struct fg_chip *chip)
+{
+ if (chip->charge_status == chip->prev_charge_status)
+ return;
+
+ cancel_delayed_work_sync(&chip->batt_avg_work);
+ fg_circ_buf_clr(&chip->ibatt_circ_buf);
+ fg_circ_buf_clr(&chip->vbatt_circ_buf);
+
+ if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING ||
+ chip->charge_status == POWER_SUPPLY_STATUS_DISCHARGING)
+ schedule_delayed_work(&chip->batt_avg_work,
+ msecs_to_jiffies(2000));
+}
+
static void status_change_work(struct work_struct *work)
{
struct fg_chip *chip = container_of(work,
@@ -1506,7 +1526,16 @@ static void status_change_work(struct work_struct *work)
goto out;
}
- chip->status = prop.intval;
+ chip->prev_charge_status = chip->charge_status;
+ chip->charge_status = prop.intval;
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_CHARGE_TYPE, &prop);
+ if (rc < 0) {
+ pr_err("Error in getting charge type, rc=%d\n", rc);
+ goto out;
+ }
+
+ chip->charge_type = prop.intval;
rc = power_supply_get_property(chip->batt_psy,
POWER_SUPPLY_PROP_CHARGE_DONE, &prop);
if (rc < 0) {
@@ -1515,9 +1544,6 @@ static void status_change_work(struct work_struct *work)
}
chip->charge_done = prop.intval;
- fg_dbg(chip, FG_POWER_SUPPLY, "curr_status:%d charge_done: %d\n",
- chip->status, chip->charge_done);
-
if (chip->cyc_ctr.en)
schedule_work(&chip->cycle_count_work);
@@ -1538,7 +1564,12 @@ static void status_change_work(struct work_struct *work)
rc = fg_esr_fcc_config(chip);
if (rc < 0)
pr_err("Error in adjusting FCC for ESR, rc=%d\n", rc);
+
+ fg_batt_avg_update(chip);
+
out:
+ fg_dbg(chip, FG_POWER_SUPPLY, "charge_status:%d charge_type:%d charge_done:%d\n",
+ chip->charge_status, chip->charge_type, chip->charge_done);
pm_relax(chip->dev);
}
@@ -1625,7 +1656,7 @@ static void cycle_count_work(struct work_struct *work)
/* We need only the most significant byte here */
batt_soc = (u32)batt_soc >> 24;
- if (chip->status == POWER_SUPPLY_STATUS_CHARGING) {
+ if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING) {
/* Find out which bucket the SOC falls in */
bucket = batt_soc / BUCKET_SOC_PCT;
pr_debug("batt_soc: %d bucket: %d\n", batt_soc, bucket);
@@ -1942,6 +1973,229 @@ static struct kernel_param_ops fg_restart_ops = {
module_param_cb(restart, &fg_restart_ops, &fg_restart, 0644);
+#define BATT_AVG_POLL_PERIOD_MS 10000
+static void batt_avg_work(struct work_struct *work)
+{
+ struct fg_chip *chip = container_of(work, struct fg_chip,
+ batt_avg_work.work);
+ int rc, ibatt_now, vbatt_now;
+
+ mutex_lock(&chip->batt_avg_lock);
+ rc = fg_get_battery_current(chip, &ibatt_now);
+ if (rc < 0) {
+ pr_err("failed to get battery current, rc=%d\n", rc);
+ goto reschedule;
+ }
+
+ rc = fg_get_battery_voltage(chip, &vbatt_now);
+ if (rc < 0) {
+ pr_err("failed to get battery voltage, rc=%d\n", rc);
+ goto reschedule;
+ }
+
+ fg_circ_buf_add(&chip->ibatt_circ_buf, ibatt_now);
+ fg_circ_buf_add(&chip->vbatt_circ_buf, vbatt_now);
+
+reschedule:
+ mutex_unlock(&chip->batt_avg_lock);
+ schedule_delayed_work(&chip->batt_avg_work,
+ msecs_to_jiffies(BATT_AVG_POLL_PERIOD_MS));
+}
+
+#define DECI_TAU_SCALE 13
+#define HOURS_TO_SECONDS 3600
+#define OCV_SLOPE_UV 10869
+#define MILLI_UNIT 1000
+#define MICRO_UNIT 1000000
+static int fg_get_time_to_full(struct fg_chip *chip, int *val)
+{
+ int rc, ibatt_avg, vbatt_avg, rbatt, msoc, ocv_cc2cv, full_soc,
+ act_cap_uah;
+ s32 i_cc2cv, soc_cc2cv, ln_val;
+ s64 t_predicted_cc = 0, t_predicted_cv = 0;
+
+ if (chip->bp.float_volt_uv <= 0) {
+ pr_err("battery profile is not loaded\n");
+ return -ENODATA;
+ }
+
+ if (!is_charger_available(chip)) {
+ fg_dbg(chip, FG_TTF, "charger is not available\n");
+ return -ENODATA;
+ }
+
+ if (chip->charge_status == POWER_SUPPLY_STATUS_FULL) {
+ *val = 0;
+ return 0;
+ }
+
+ mutex_lock(&chip->batt_avg_lock);
+ rc = fg_circ_buf_avg(&chip->ibatt_circ_buf, &ibatt_avg);
+ if (rc < 0) {
+ /* try to get instantaneous current */
+ rc = fg_get_battery_current(chip, &ibatt_avg);
+ if (rc < 0) {
+ mutex_unlock(&chip->batt_avg_lock);
+ pr_err("failed to get battery current, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ rc = fg_circ_buf_avg(&chip->vbatt_circ_buf, &vbatt_avg);
+ if (rc < 0) {
+ /* try to get instantaneous voltage */
+ rc = fg_get_battery_voltage(chip, &vbatt_avg);
+ if (rc < 0) {
+ mutex_unlock(&chip->batt_avg_lock);
+ pr_err("failed to get battery voltage, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ mutex_unlock(&chip->batt_avg_lock);
+ fg_dbg(chip, FG_TTF, "vbatt_avg=%d\n", vbatt_avg);
+
+ /* clamp ibatt_avg to -150mA */
+ if (ibatt_avg > -150000)
+ ibatt_avg = -150000;
+ fg_dbg(chip, FG_TTF, "ibatt_avg=%d\n", ibatt_avg);
+
+ /* reverse polarity to be consistent with unsigned current settings */
+ ibatt_avg = abs(ibatt_avg);
+
+ /* estimated battery current at the CC to CV transition */
+ i_cc2cv = div_s64((s64)ibatt_avg * vbatt_avg, chip->bp.float_volt_uv);
+ fg_dbg(chip, FG_TTF, "i_cc2cv=%d\n", i_cc2cv);
+
+ rc = fg_get_battery_resistance(chip, &rbatt);
+ if (rc < 0) {
+ pr_err("failed to get battery resistance rc=%d\n", rc);
+ return rc;
+ }
+
+ /* clamp rbatt to 50mOhms */
+ if (rbatt < 50000)
+ rbatt = 50000;
+
+ fg_dbg(chip, FG_TTF, "rbatt=%d\n", rbatt);
+
+ rc = fg_get_sram_prop(chip, FG_SRAM_ACT_BATT_CAP, &act_cap_uah);
+ if (rc < 0) {
+ pr_err("failed to get ACT_BATT_CAP rc=%d\n", rc);
+ return rc;
+ }
+ act_cap_uah *= MILLI_UNIT;
+ fg_dbg(chip, FG_TTF, "actual_capacity_uah=%d\n", act_cap_uah);
+
+ rc = fg_get_prop_capacity(chip, &msoc);
+ if (rc < 0) {
+ pr_err("failed to get msoc rc=%d\n", rc);
+ return rc;
+ }
+ fg_dbg(chip, FG_TTF, "msoc=%d\n", msoc);
+
+ rc = fg_get_sram_prop(chip, FG_SRAM_FULL_SOC, &full_soc);
+ if (rc < 0) {
+ pr_err("failed to get full soc rc=%d\n", rc);
+ return rc;
+ }
+ full_soc = DIV_ROUND_CLOSEST(((u16)full_soc >> 8) * FULL_CAPACITY,
+ FULL_SOC_RAW);
+ fg_dbg(chip, FG_TTF, "full_soc=%d\n", full_soc);
+
+ /* if we are already in CV state then we can skip estimating CC */
+ if (chip->charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER)
+ goto skip_cc_estimate;
+
+ /* if the charger is current limited then use power approximation */
+ if (ibatt_avg > chip->bp.fastchg_curr_ma * MILLI_UNIT - 50000)
+ ocv_cc2cv = div_s64((s64)rbatt * ibatt_avg, MICRO_UNIT);
+ else
+ ocv_cc2cv = div_s64((s64)rbatt * i_cc2cv, MICRO_UNIT);
+ ocv_cc2cv = chip->bp.float_volt_uv - ocv_cc2cv;
+ fg_dbg(chip, FG_TTF, "ocv_cc2cv=%d\n", ocv_cc2cv);
+
+ soc_cc2cv = div_s64(chip->bp.float_volt_uv - ocv_cc2cv, OCV_SLOPE_UV);
+ /* estimated SOC at the CC to CV transition */
+ soc_cc2cv = 100 - soc_cc2cv;
+ fg_dbg(chip, FG_TTF, "soc_cc2cv=%d\n", soc_cc2cv);
+
+ /* the esimated SOC may be lower than the current SOC */
+ if (soc_cc2cv - msoc <= 0)
+ goto skip_cc_estimate;
+
+ t_predicted_cc = div_s64((s64)full_soc * act_cap_uah, 100);
+ t_predicted_cc = div_s64(t_predicted_cc * (soc_cc2cv - msoc), 100);
+ t_predicted_cc *= HOURS_TO_SECONDS;
+ t_predicted_cc = div_s64(t_predicted_cc, (ibatt_avg + i_cc2cv) / 2);
+
+skip_cc_estimate:
+ fg_dbg(chip, FG_TTF, "t_predicted_cc=%lld\n", t_predicted_cc);
+
+ /* CV estimate starts here */
+ if (chip->charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER)
+ ln_val = ibatt_avg / abs(chip->dt.sys_term_curr_ma);
+ else
+ ln_val = i_cc2cv / abs(chip->dt.sys_term_curr_ma);
+
+ fg_dbg(chip, FG_TTF, "ln_in=%d\n", ln_val);
+ rc = fg_lerp(fg_ln_table, ARRAY_SIZE(fg_ln_table), ln_val, &ln_val);
+ fg_dbg(chip, FG_TTF, "ln_out=%d\n", ln_val);
+ t_predicted_cv = div_s64((s64)act_cap_uah * rbatt, MICRO_UNIT);
+ t_predicted_cv = div_s64(t_predicted_cv * DECI_TAU_SCALE, 10);
+ t_predicted_cv = div_s64(t_predicted_cv * ln_val, MILLI_UNIT);
+ t_predicted_cv = div_s64(t_predicted_cv * HOURS_TO_SECONDS, MICRO_UNIT);
+ fg_dbg(chip, FG_TTF, "t_predicted_cv=%lld\n", t_predicted_cv);
+ *val = t_predicted_cc + t_predicted_cv;
+ return 0;
+}
+
+#define CENTI_ICORRECT_C0 105
+#define CENTI_ICORRECT_C1 20
+static int fg_get_time_to_empty(struct fg_chip *chip, int *val)
+{
+ int rc, ibatt_avg, msoc, act_cap_uah;
+ s32 divisor;
+ s64 t_predicted;
+
+ rc = fg_circ_buf_avg(&chip->ibatt_circ_buf, &ibatt_avg);
+ if (rc < 0) {
+ /* try to get instantaneous current */
+ rc = fg_get_battery_current(chip, &ibatt_avg);
+ if (rc < 0) {
+ pr_err("failed to get battery current, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ /* clamp ibatt_avg to 150mA */
+ if (ibatt_avg < 150000)
+ ibatt_avg = 150000;
+
+ rc = fg_get_sram_prop(chip, FG_SRAM_ACT_BATT_CAP, &act_cap_uah);
+ if (rc < 0) {
+ pr_err("Error in getting ACT_BATT_CAP, rc=%d\n", rc);
+ return rc;
+ }
+ act_cap_uah *= MILLI_UNIT;
+
+ rc = fg_get_prop_capacity(chip, &msoc);
+ if (rc < 0) {
+ pr_err("Error in getting capacity, rc=%d\n", rc);
+ return rc;
+ }
+
+ t_predicted = div_s64((s64)msoc * act_cap_uah, 100);
+ t_predicted *= HOURS_TO_SECONDS;
+ divisor = CENTI_ICORRECT_C0 * 100 + CENTI_ICORRECT_C1 * msoc;
+ divisor = div_s64((s64)divisor * ibatt_avg, 10000);
+ if (divisor > 0)
+ t_predicted = div_s64(t_predicted, divisor);
+
+ *val = t_predicted;
+ return 0;
+}
+
/* PSY CALLBACKS STAY HERE */
static int fg_psy_get_property(struct power_supply *psy,
@@ -2003,11 +2257,22 @@ static int fg_psy_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_CHARGE_COUNTER:
rc = fg_get_cc_soc_sw(chip, &pval->intval);
break;
+ case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
+ rc = fg_get_time_to_full(chip, &pval->intval);
+ break;
+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
+ rc = fg_get_time_to_empty(chip, &pval->intval);
+ break;
default:
+ pr_err("unsupported property %d\n", psp);
+ rc = -EINVAL;
break;
}
- return rc;
+ if (rc < 0)
+ return -ENODATA;
+
+ return 0;
}
static int fg_psy_set_property(struct power_supply *psy,
@@ -2090,6 +2355,8 @@ static enum power_supply_property fg_psy_props[] = {
POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_COUNTER,
+ POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
};
static const struct power_supply_desc fg_psy_desc = {
@@ -2964,6 +3231,8 @@ static int fg_gen3_probe(struct platform_device *pdev)
chip->dev = &pdev->dev;
chip->debug_mask = &fg_gen3_debug_mask;
chip->irqs = fg_irqs;
+ chip->charge_status = -EINVAL;
+ chip->prev_charge_status = -EINVAL;
chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
if (!chip->regmap) {
dev_err(chip->dev, "Parent regmap is unavailable\n");
@@ -2988,11 +3257,13 @@ static int fg_gen3_probe(struct platform_device *pdev)
mutex_init(&chip->sram_rw_lock);
mutex_init(&chip->cyc_ctr.lock);
mutex_init(&chip->cl.lock);
+ mutex_init(&chip->batt_avg_lock);
init_completion(&chip->soc_update);
init_completion(&chip->soc_ready);
INIT_DELAYED_WORK(&chip->profile_load_work, profile_load_work);
INIT_WORK(&chip->status_change_work, status_change_work);
INIT_WORK(&chip->cycle_count_work, cycle_count_work);
+ INIT_DELAYED_WORK(&chip->batt_avg_work, batt_avg_work);
rc = fg_memif_init(chip);
if (rc < 0) {
@@ -3085,6 +3356,7 @@ static int fg_gen3_suspend(struct device *dev)
}
}
+ cancel_delayed_work_sync(&chip->batt_avg_work);
return 0;
}
@@ -3103,6 +3375,9 @@ static int fg_gen3_resume(struct device *dev)
}
}
+ fg_circ_buf_clr(&chip->ibatt_circ_buf);
+ fg_circ_buf_clr(&chip->vbatt_circ_buf);
+ schedule_delayed_work(&chip->batt_avg_work, 0);
return 0;
}
diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c
index a00ad8343a88..6968ab2ab11c 100644
--- a/drivers/power/qcom-charger/qpnp-smb2.c
+++ b/drivers/power/qcom-charger/qpnp-smb2.c
@@ -1049,6 +1049,7 @@ static int smb2_init_hw(struct smb2 *chip)
{
struct smb_charger *chg = &chip->chg;
int rc;
+ u8 stat;
if (chip->dt.no_battery)
chg->fake_capacity = 50;
@@ -1069,6 +1070,21 @@ static int smb2_init_hw(struct smb2 *chip)
chg->otg_cl_ua = chip->dt.otg_cl_ua;
+ rc = smblib_read(chg, APSD_RESULT_STATUS_REG, &stat);
+ if (rc < 0) {
+ pr_err("Couldn't read APSD_RESULT_STATUS rc=%d\n", rc);
+ return rc;
+ }
+
+ /* clear the ICL override if it is set */
+ if (stat & ICL_OVERRIDE_LATCH_BIT) {
+ rc = smblib_write(chg, CMD_APSD_REG, ICL_OVERRIDE_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't disable ICL override rc=%d\n", rc);
+ return rc;
+ }
+ }
+
/* votes must be cast before configuring software control */
vote(chg->pl_disable_votable,
PL_INDIRECT_VOTER, true, 0);
@@ -1161,6 +1177,15 @@ static int smb2_init_hw(struct smb2 *chip)
return rc;
}
+ /* increase VCONN softstart */
+ rc = smblib_masked_write(chg, TYPE_C_CFG_2_REG,
+ VCONN_SOFTSTART_CFG_MASK, VCONN_SOFTSTART_CFG_MASK);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't increase VCONN softstart rc=%d\n",
+ rc);
+ return rc;
+ }
+
rc = smblib_masked_write(chg, QNOVO_PT_ENABLE_CMD_REG,
QNOVO_PT_ENABLE_CMD_BIT, QNOVO_PT_ENABLE_CMD_BIT);
if (rc < 0) {
@@ -1183,13 +1208,12 @@ static int smb2_init_hw(struct smb2 *chip)
return rc;
}
- /* configure PMI stat output to enable and disable parallel charging */
+ /* disable SW STAT override */
rc = smblib_masked_write(chg, STAT_CFG_REG,
- STAT_PARALLEL_CFG_BIT | STAT_SW_OVERRIDE_CFG_BIT,
- STAT_PARALLEL_CFG_BIT);
+ STAT_SW_OVERRIDE_CFG_BIT, 0);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure signal for parallel rc=%d\n", rc);
+ dev_err(chg->dev, "Couldn't disable SW STAT override rc=%d\n",
+ rc);
return rc;
}
@@ -1287,6 +1311,8 @@ static int smb2_setup_wa_flags(struct smb2 *chip)
chip->chg.wa_flags |= BOOST_BACK_WA;
if (pmic_rev_id->rev4 == PMICOBALT_V1P1_REV4) /* PMI rev 1.1 */
chg->wa_flags |= QC_CHARGER_DETECTION_WA_BIT;
+ if (pmic_rev_id->rev4 == PMICOBALT_V2P0_REV4) /* PMI rev 2.0 */
+ chg->wa_flags |= TYPEC_CC2_REMOVAL_WA_BIT;
break;
default:
pr_err("PMIC subtype %d not supported\n",
diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c
index 144169ea4930..6aae7d49271f 100644
--- a/drivers/power/qcom-charger/smb-lib.c
+++ b/drivers/power/qcom-charger/smb-lib.c
@@ -1464,21 +1464,17 @@ int smblib_set_prop_system_temp_level(struct smb_charger *chg,
int smblib_get_prop_dc_present(struct smb_charger *chg,
union power_supply_propval *val)
{
- int rc = 0;
+ int rc;
u8 stat;
- rc = smblib_read(chg, DC_INT_RT_STS_REG, &stat);
+ rc = smblib_read(chg, DCIN_BASE + INT_RT_STS_OFFSET, &stat);
if (rc < 0) {
- smblib_err(chg, "Couldn't read DC_INT_RT_STS_REG rc=%d\n",
- rc);
+ smblib_err(chg, "Couldn't read DCIN_RT_STS rc=%d\n", rc);
return rc;
}
- smblib_dbg(chg, PR_REGISTER, "DC_INT_RT_STS_REG = 0x%02x\n",
- stat);
val->intval = (bool)(stat & DCIN_PLUGIN_RT_STS_BIT);
-
- return rc;
+ return 0;
}
int smblib_get_prop_dc_online(struct smb_charger *chg,
@@ -1534,20 +1530,17 @@ int smblib_set_prop_dc_current_max(struct smb_charger *chg,
int smblib_get_prop_usb_present(struct smb_charger *chg,
union power_supply_propval *val)
{
- int rc = 0;
+ int rc;
u8 stat;
- rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat);
+ rc = smblib_read(chg, USBIN_BASE + INT_RT_STS_OFFSET, &stat);
if (rc < 0) {
- smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc);
+ smblib_err(chg, "Couldn't read USBIN_RT_STS rc=%d\n", rc);
return rc;
}
- smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_4 = 0x%02x\n",
- stat);
-
- val->intval = (bool)(stat & CC_ATTACHED_BIT);
- return rc;
+ val->intval = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT);
+ return 0;
}
int smblib_get_prop_usb_online(struct smb_charger *chg,
@@ -2129,6 +2122,100 @@ int smblib_reg_block_restore(struct smb_charger *chg,
return rc;
}
+static struct reg_info cc2_detach_settings[] = {
+ {
+ .reg = TYPE_C_CFG_2_REG,
+ .mask = TYPE_C_UFP_MODE_BIT | EN_TRY_SOURCE_MODE_BIT,
+ .val = TYPE_C_UFP_MODE_BIT,
+ .desc = "TYPE_C_CFG_2_REG",
+ },
+ {
+ .reg = TYPE_C_CFG_3_REG,
+ .mask = EN_TRYSINK_MODE_BIT,
+ .val = 0,
+ .desc = "TYPE_C_CFG_3_REG",
+ },
+ {
+ .reg = TAPER_TIMER_SEL_CFG_REG,
+ .mask = TYPEC_SPARE_CFG_BIT,
+ .val = TYPEC_SPARE_CFG_BIT,
+ .desc = "TAPER_TIMER_SEL_CFG_REG",
+ },
+ {
+ .reg = TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
+ .mask = VCONN_EN_ORIENTATION_BIT,
+ .val = 0,
+ .desc = "TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG",
+ },
+ {
+ .reg = MISC_CFG_REG,
+ .mask = TCC_DEBOUNCE_20MS_BIT,
+ .val = TCC_DEBOUNCE_20MS_BIT,
+ .desc = "Tccdebounce time"
+ },
+ {
+ },
+};
+
+static int smblib_cc2_sink_removal_enter(struct smb_charger *chg)
+{
+ int rc = 0;
+ union power_supply_propval cc2_val = {0, };
+
+ if ((chg->wa_flags & TYPEC_CC2_REMOVAL_WA_BIT) == 0)
+ return rc;
+
+ if (chg->cc2_sink_detach_flag != CC2_SINK_NONE)
+ return rc;
+
+ rc = smblib_get_prop_typec_cc_orientation(chg, &cc2_val);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't get cc orientation rc=%d\n", rc);
+ return rc;
+ }
+ if (cc2_val.intval == 1)
+ return rc;
+
+ rc = smblib_get_prop_typec_mode(chg, &cc2_val);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't get prop typec mode rc=%d\n", rc);
+ return rc;
+ }
+
+ switch (cc2_val.intval) {
+ case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT:
+ smblib_reg_block_update(chg, cc2_detach_settings);
+ chg->cc2_sink_detach_flag = CC2_SINK_STD;
+ schedule_work(&chg->rdstd_cc2_detach_work);
+ break;
+ case POWER_SUPPLY_TYPEC_SOURCE_MEDIUM:
+ case POWER_SUPPLY_TYPEC_SOURCE_HIGH:
+ chg->cc2_sink_detach_flag = CC2_SINK_MEDIUM_HIGH;
+ break;
+ default:
+ break;
+ }
+
+ return rc;
+}
+
+static int smblib_cc2_sink_removal_exit(struct smb_charger *chg)
+{
+ int rc = 0;
+
+ if ((chg->wa_flags & TYPEC_CC2_REMOVAL_WA_BIT) == 0)
+ return rc;
+
+ if (chg->cc2_sink_detach_flag == CC2_SINK_STD) {
+ cancel_work_sync(&chg->rdstd_cc2_detach_work);
+ smblib_reg_block_restore(chg, cc2_detach_settings);
+ }
+
+ chg->cc2_sink_detach_flag = CC2_SINK_NONE;
+
+ return rc;
+}
+
int smblib_set_prop_pd_in_hard_reset(struct smb_charger *chg,
const union power_supply_propval *val)
{
@@ -2137,9 +2224,24 @@ int smblib_set_prop_pd_in_hard_reset(struct smb_charger *chg,
rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
EXIT_SNK_BASED_ON_CC_BIT,
(val->intval) ? EXIT_SNK_BASED_ON_CC_BIT : 0);
+ if (rc < 0) {
+ smblib_err(chg, "Could not set EXIT_SNK_BASED_ON_CC rc=%d\n",
+ rc);
+ return rc;
+ }
vote(chg->apsd_disable_votable, PD_HARD_RESET_VOTER, val->intval, 0);
+ if (val->intval)
+ rc = smblib_cc2_sink_removal_enter(chg);
+ else
+ rc = smblib_cc2_sink_removal_exit(chg);
+
+ if (rc < 0) {
+ smblib_err(chg, "Could not detect cc2 removal rc=%d\n", rc);
+ return rc;
+ }
+
return rc;
}
@@ -2310,6 +2412,7 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
struct smb_charger *chg = irq_data->parent_data;
int rc;
u8 stat;
+ bool vbus_rising;
rc = smblib_read(chg, USBIN_BASE + INT_RT_STS_OFFSET, &stat);
if (rc < 0) {
@@ -2317,9 +2420,9 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
return IRQ_HANDLED;
}
- chg->vbus_present = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT);
+ vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT);
smblib_set_opt_freq_buck(chg,
- chg->vbus_present ? FSW_600HZ_FOR_5V : FSW_1MHZ_FOR_REMOVAL);
+ vbus_rising ? FSW_600HZ_FOR_5V : FSW_1MHZ_FOR_REMOVAL);
/* fetch the DPDM regulator */
if (!chg->dpdm_reg && of_get_property(chg->dev->of_node,
@@ -2332,7 +2435,7 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
}
}
- if (chg->vbus_present) {
+ if (vbus_rising) {
if (chg->dpdm_reg && !regulator_is_enabled(chg->dpdm_reg)) {
smblib_dbg(chg, PR_MISC, "enabling DPDM regulator\n");
rc = regulator_enable(chg->dpdm_reg);
@@ -2359,7 +2462,7 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
power_supply_changed(chg->usb_psy);
smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s %s\n",
- irq_data->name, chg->vbus_present ? "attached" : "detached");
+ irq_data->name, vbus_rising ? "attached" : "detached");
return IRQ_HANDLED;
}
@@ -2726,6 +2829,24 @@ static void smblib_handle_typec_debounce_done(struct smb_charger *chg,
if (rc < 0)
smblib_err(chg, "Couldn't get prop typec mode rc=%d\n", rc);
+ /*
+ * HW BUG - after cable is removed, medium or high rd reading
+ * falls to std. Use it for signal of typec cc detachment in
+ * software WA.
+ */
+ if (chg->cc2_sink_detach_flag == CC2_SINK_MEDIUM_HIGH
+ && pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) {
+
+ chg->cc2_sink_detach_flag = CC2_SINK_WA_DONE;
+
+ rc = smblib_masked_write(chg,
+ TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
+ EXIT_SNK_BASED_ON_CC_BIT, 0);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't get prop typec mode rc=%d\n",
+ rc);
+ }
+
smblib_dbg(chg, PR_INTERRUPT, "IRQ: debounce-done %s; Type-C %s detected\n",
rising ? "rising" : "falling",
smblib_typec_mode_name[pval.intval]);
@@ -2739,6 +2860,10 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data)
u8 stat;
bool debounce_done, sink_attached, legacy_cable;
+ /* WA - not when PD hard_reset WIP on cc2 in sink mode */
+ if (chg->cc2_sink_detach_flag == CC2_SINK_STD)
+ return IRQ_HANDLED;
+
rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat);
if (rc < 0) {
smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc);
@@ -2923,6 +3048,74 @@ static void clear_hdc_work(struct work_struct *work)
chg->is_hdc = 0;
}
+static void rdstd_cc2_detach_work(struct work_struct *work)
+{
+ int rc;
+ u8 stat;
+ struct smb_irq_data irq_data = {NULL, "cc2-removal-workaround"};
+ struct smb_charger *chg = container_of(work, struct smb_charger,
+ rdstd_cc2_detach_work);
+
+ /*
+ * WA steps -
+ * 1. Enable both UFP and DFP, wait for 10ms.
+ * 2. Disable DFP, wait for 30ms.
+ * 3. Removal detected if both TYPEC_DEBOUNCE_DONE_STATUS
+ * and TIMER_STAGE bits are gone, otherwise repeat all by
+ * work rescheduling.
+ * Note, work will be cancelled when pd_hard_reset is 0.
+ */
+
+ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
+ UFP_EN_CMD_BIT | DFP_EN_CMD_BIT,
+ UFP_EN_CMD_BIT | DFP_EN_CMD_BIT);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't write TYPE_C_CTRL_REG rc=%d\n", rc);
+ return;
+ }
+
+ usleep_range(10000, 11000);
+
+ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
+ UFP_EN_CMD_BIT | DFP_EN_CMD_BIT,
+ UFP_EN_CMD_BIT);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't write TYPE_C_CTRL_REG rc=%d\n", rc);
+ return;
+ }
+
+ usleep_range(30000, 31000);
+
+ rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n",
+ rc);
+ return;
+ }
+ if (stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT)
+ goto rerun;
+
+ rc = smblib_read(chg, TYPE_C_STATUS_5_REG, &stat);
+ if (rc < 0) {
+ smblib_err(chg,
+ "Couldn't read TYPE_C_STATUS_5_REG rc=%d\n", rc);
+ return;
+ }
+ if (stat & TIMER_STAGE_2_BIT)
+ goto rerun;
+
+ /* Bingo, cc2 removal detected */
+ smblib_reg_block_restore(chg, cc2_detach_settings);
+ chg->cc2_sink_detach_flag = CC2_SINK_WA_DONE;
+ irq_data.parent_data = chg;
+ smblib_handle_usb_typec_change(0, &irq_data);
+
+ return;
+
+rerun:
+ schedule_work(&chg->rdstd_cc2_detach_work);
+}
+
static int smblib_create_votables(struct smb_charger *chg)
{
int rc = 0;
@@ -3105,6 +3298,7 @@ int smblib_init(struct smb_charger *chg)
mutex_init(&chg->write_lock);
INIT_WORK(&chg->bms_update_work, bms_update_work);
INIT_WORK(&chg->pl_detect_work, smblib_pl_detect_work);
+ INIT_WORK(&chg->rdstd_cc2_detach_work, rdstd_cc2_detach_work);
INIT_DELAYED_WORK(&chg->hvdcp_detect_work, smblib_hvdcp_detect_work);
INIT_DELAYED_WORK(&chg->pl_taper_work, smblib_pl_taper_work);
INIT_DELAYED_WORK(&chg->step_soc_req_work, step_soc_req_work);
diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/qcom-charger/smb-lib.h
index 2809ddadbd90..a0237412ee8b 100644
--- a/drivers/power/qcom-charger/smb-lib.h
+++ b/drivers/power/qcom-charger/smb-lib.h
@@ -54,9 +54,17 @@ enum smb_mode {
NUM_MODES,
};
+enum cc2_sink_type {
+ CC2_SINK_NONE = 0,
+ CC2_SINK_STD,
+ CC2_SINK_MEDIUM_HIGH,
+ CC2_SINK_WA_DONE,
+};
+
enum {
- QC_CHARGER_DETECTION_WA_BIT = BIT(0),
- BOOST_BACK_WA = BIT(1),
+ QC_CHARGER_DETECTION_WA_BIT = BIT(0),
+ BOOST_BACK_WA = BIT(1),
+ TYPEC_CC2_REMOVAL_WA_BIT = BIT(2),
};
struct smb_regulator {
@@ -177,6 +185,7 @@ struct smb_charger {
/* work */
struct work_struct bms_update_work;
struct work_struct pl_detect_work;
+ struct work_struct rdstd_cc2_detach_work;
struct delayed_work hvdcp_detect_work;
struct delayed_work ps_change_timeout_work;
struct delayed_work pl_taper_work;
@@ -187,7 +196,6 @@ struct smb_charger {
int voltage_min_uv;
int voltage_max_uv;
int pd_active;
- bool vbus_present;
bool system_suspend_supported;
int system_temp_level;
@@ -205,6 +213,7 @@ struct smb_charger {
/* workaround flag */
u32 wa_flags;
+ enum cc2_sink_type cc2_sink_detach_flag;
};
int smblib_read(struct smb_charger *chg, u16 addr, u8 *val);
diff --git a/drivers/power/qcom-charger/smb-reg.h b/drivers/power/qcom-charger/smb-reg.h
index 2aed4cf294a2..c2a2b0c86d73 100644
--- a/drivers/power/qcom-charger/smb-reg.h
+++ b/drivers/power/qcom-charger/smb-reg.h
@@ -705,9 +705,6 @@ enum {
#define WIPWR_RANGE_STATUS_REG (DCIN_BASE + 0x08)
#define WIPWR_RANGE_STATUS_MASK GENMASK(4, 0)
-#define DC_INT_RT_STS_REG (DCIN_BASE + 0x10)
-#define DCIN_PLUGIN_RT_STS_BIT BIT(4)
-
/* DCIN Interrupt Bits */
#define WIPWR_VOLTAGE_RANGE_RT_STS_BIT BIT(7)
#define DCIN_ICL_CHANGE_RT_STS_BIT BIT(6)
@@ -905,6 +902,7 @@ enum {
#define MISC_CFG_REG (MISC_BASE + 0x52)
#define GSM_PA_ON_ADJ_SEL_BIT BIT(0)
+#define TCC_DEBOUNCE_20MS_BIT BIT(5)
#define SNARL_BARK_BITE_WD_CFG_REG (MISC_BASE + 0x53)
#define BITE_WDOG_DISABLE_CHARGING_CFG_BIT BIT(7)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 862d56e78086..19a8aacf98d0 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2633,6 +2633,65 @@ static inline u16 ufshcd_upiu_wlun_to_scsi_wlun(u8 upiu_wlun_id)
}
/**
+ * ufshcd_get_write_lock - synchronize between shutdown, scaling &
+ * arrival of requests
+ * @hba: ufs host
+ *
+ * Lock is predominantly held by shutdown context thus, ensuring
+ * that no requests from any other context may sneak through.
+ */
+static void ufshcd_get_write_lock(struct ufs_hba *hba)
+{
+ down_write(&hba->lock);
+ hba->issuing_task = current;
+}
+
+/**
+ * ufshcd_get_read_lock - synchronize between shutdown, scaling &
+ * arrival of requests
+ * @hba: ufs host
+ *
+ * Returns 1 if acquired, < 0 on contention
+ *
+ * After shutdown's initiated, allow requests only from shutdown
+ * context. The sync between scaling & issue is maintained
+ * as is and this restructuring syncs shutdown with these too.
+ */
+static int ufshcd_get_read_lock(struct ufs_hba *hba)
+{
+ int err = 0;
+
+ err = down_read_trylock(&hba->lock);
+ if (err > 0)
+ goto out;
+ if (hba->issuing_task == current)
+ return 0;
+ else if (!ufshcd_is_shutdown_ongoing(hba))
+ return -EAGAIN;
+ else
+ return -EPERM;
+
+out:
+ hba->issuing_task = current;
+ return err;
+}
+
+/**
+ * ufshcd_put_read_lock - synchronize between shutdown, scaling &
+ * arrival of requests
+ * @hba: ufs host
+ *
+ * Returns none
+ */
+static inline void ufshcd_put_read_lock(struct ufs_hba *hba)
+{
+ if (!ufshcd_is_shutdown_ongoing(hba)) {
+ hba->issuing_task = NULL;
+ up_read(&hba->lock);
+ }
+}
+
+/**
* ufshcd_queuecommand - main entry point for SCSI requests
* @cmd: command from SCSI Midlayer
* @done: call back function
@@ -2657,8 +2716,16 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
BUG();
}
- if (!down_read_trylock(&hba->clk_scaling_lock))
- return SCSI_MLQUEUE_HOST_BUSY;
+ err = ufshcd_get_read_lock(hba);
+ if (unlikely(err < 0)) {
+ if (err == -EPERM) {
+ set_host_byte(cmd, DID_ERROR);
+ cmd->scsi_done(cmd);
+ return 0;
+ }
+ if (err == -EAGAIN)
+ return SCSI_MLQUEUE_HOST_BUSY;
+ }
spin_lock_irqsave(hba->host->host_lock, flags);
@@ -2798,7 +2865,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
out_unlock:
spin_unlock_irqrestore(hba->host->host_lock, flags);
out:
- up_read(&hba->clk_scaling_lock);
+ ufshcd_put_read_lock(hba);
return err;
}
@@ -2990,7 +3057,12 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
struct completion wait;
unsigned long flags;
- down_read(&hba->clk_scaling_lock);
+ /*
+ * May get invoked from shutdown and IOCTL contexts.
+ * In shutdown context, it comes in with lock acquired.
+ */
+ if (!ufshcd_is_shutdown_ongoing(hba))
+ down_read(&hba->lock);
/*
* Get free slot, sleep if slots are unavailable.
@@ -3023,7 +3095,8 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
out_put_tag:
ufshcd_put_dev_cmd_tag(hba, tag);
wake_up(&hba->dev_cmd.tag_wq);
- up_read(&hba->clk_scaling_lock);
+ if (!ufshcd_is_shutdown_ongoing(hba))
+ up_read(&hba->lock);
return err;
}
@@ -8654,11 +8727,37 @@ static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba)
*/
int ufshcd_shutdown(struct ufs_hba *hba)
{
- /*
- * TODO: This function should send the power down notification to
- * UFS device and then power off the UFS link. But we need to be sure
- * that there will not be any new UFS requests issued after this.
+ int ret = 0;
+
+ if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba))
+ goto out;
+
+ pm_runtime_get_sync(hba->dev);
+ ufshcd_hold_all(hba);
+ /**
+ * (1) Acquire the lock to stop any more requests
+ * (2) Set state to shutting down
+ * (3) Suspend clock scaling
+ * (4) Wait for all issued requests to complete
*/
+ ufshcd_get_write_lock(hba);
+ ufshcd_mark_shutdown_ongoing(hba);
+ ufshcd_scsi_block_requests(hba);
+ ufshcd_suspend_clkscaling(hba);
+ ret = ufshcd_wait_for_doorbell_clr(hba, U64_MAX);
+ if (ret)
+ dev_err(hba->dev, "%s: waiting for DB clear: failed: %d\n",
+ __func__, ret);
+ /* Requests may have errored out above, let it be handled */
+ flush_work(&hba->eh_work);
+ /* reqs issued from contexts other than shutdown will fail from now */
+ ufshcd_scsi_unblock_requests(hba);
+ ufshcd_release_all(hba);
+ ret = ufshcd_suspend(hba, UFS_SHUTDOWN_PM);
+out:
+ if (ret)
+ dev_err(hba->dev, "%s failed, err %d\n", __func__, ret);
+ /* allow force shutdown even in case of errors */
return 0;
}
EXPORT_SYMBOL(ufshcd_shutdown);
@@ -8843,10 +8942,10 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba)
* clock scaling is in progress
*/
ufshcd_scsi_block_requests(hba);
- down_write(&hba->clk_scaling_lock);
+ down_write(&hba->lock);
if (ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US)) {
ret = -EBUSY;
- up_write(&hba->clk_scaling_lock);
+ up_write(&hba->lock);
ufshcd_scsi_unblock_requests(hba);
}
@@ -8855,7 +8954,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba)
static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba)
{
- up_write(&hba->clk_scaling_lock);
+ up_write(&hba->lock);
ufshcd_scsi_unblock_requests(hba);
}
@@ -9038,6 +9137,10 @@ static void ufshcd_clk_scaling_resume_work(struct work_struct *work)
clk_scaling.resume_work);
unsigned long irq_flags;
+ /* Let's not resume scaling if shutdown is ongoing */
+ if (ufshcd_is_shutdown_ongoing(hba))
+ return;
+
spin_lock_irqsave(hba->host->host_lock, irq_flags);
if (!hba->clk_scaling.is_suspended) {
spin_unlock_irqrestore(hba->host->host_lock, irq_flags);
@@ -9250,7 +9353,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
/* Initialize mutex for device management commands */
mutex_init(&hba->dev_cmd.lock);
- init_rwsem(&hba->clk_scaling_lock);
+ init_rwsem(&hba->lock);
/* Initialize device management tag acquire wait queue */
init_waitqueue_head(&hba->dev_cmd.tag_wq);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index c0714b7bea72..74fe46cf34fe 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -895,7 +895,10 @@ struct ufs_hba {
enum bkops_status urgent_bkops_lvl;
bool is_urgent_bkops_lvl_checked;
- struct rw_semaphore clk_scaling_lock;
+ /* sync b/w diff contexts */
+ struct rw_semaphore lock;
+ struct task_struct *issuing_task;
+ unsigned long shutdown_in_prog;
struct reset_control *core_reset;
/* If set, don't gate device ref_clk during clock gating */
@@ -904,6 +907,16 @@ struct ufs_hba {
int scsi_block_reqs_cnt;
};
+static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba)
+{
+ set_bit(0, &hba->shutdown_in_prog);
+}
+
+static inline bool ufshcd_is_shutdown_ongoing(struct ufs_hba *hba)
+{
+ return !!(test_bit(0, &hba->shutdown_in_prog));
+}
+
/* Returns true if clocks can be gated. Otherwise false */
static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba)
{
diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c
index 9cfca014c8ad..382245eb90b6 100644
--- a/drivers/soc/qcom/glink.c
+++ b/drivers/soc/qcom/glink.c
@@ -3948,7 +3948,6 @@ int glink_core_register_transport(struct glink_transport_if *if_ptr,
xprt_ptr->edge, xprt_ptr->name);
if (IS_ERR_OR_NULL(xprt_ptr->tx_task)) {
GLINK_ERR("%s: unable to run thread\n", __func__);
- glink_core_deinit_xprt_qos_cfg(xprt_ptr);
kfree(xprt_ptr);
return -ENOMEM;
}
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index feeed645fc47..6215636b0f46 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -45,6 +45,7 @@
#include <soc/qcom/service-locator.h>
#include <soc/qcom/service-notifier.h>
#include <soc/qcom/socinfo.h>
+#include <soc/qcom/ramdump.h>
#include "wlan_firmware_service_v01.h"
@@ -439,6 +440,7 @@ static struct icnss_priv {
struct wlfw_rf_board_info_s_v01 board_info;
struct wlfw_soc_info_s_v01 soc_info;
struct wlfw_fw_version_info_s_v01 fw_version_info;
+ char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1];
u32 pwr_pin_result;
u32 phy_io_pin_result;
u32 rf_pin_result;
@@ -463,6 +465,7 @@ static struct icnss_priv {
struct qpnp_vadc_chip *vadc_dev;
uint64_t vph_pwr;
atomic_t pm_count;
+ struct ramdump_device *msa0_dump_dev;
} *penv;
static void icnss_hw_write_reg(void *base, u32 offset, u32 val)
@@ -1971,12 +1974,16 @@ static int wlfw_cap_send_sync_msg(void)
penv->soc_info = resp.soc_info;
if (resp.fw_version_info_valid)
penv->fw_version_info = resp.fw_version_info;
+ if (resp.fw_build_id_valid)
+ strlcpy(penv->fw_build_id, resp.fw_build_id,
+ QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1);
- icnss_pr_dbg("Capability, chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s",
+ icnss_pr_dbg("Capability, chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s, fw_build_id: %s",
penv->chip_info.chip_id, penv->chip_info.chip_family,
penv->board_info.board_id, penv->soc_info.soc_id,
penv->fw_version_info.fw_version,
- penv->fw_version_info.fw_build_timestamp);
+ penv->fw_version_info.fw_build_timestamp,
+ penv->fw_build_id);
return 0;
@@ -2657,8 +2664,6 @@ static int icnss_driver_event_pd_service_down(struct icnss_priv *priv,
out:
ret = icnss_hw_power_off(priv);
- icnss_remove_msa_permissions(priv);
-
kfree(data);
return ret;
@@ -2763,6 +2768,16 @@ static int icnss_qmi_wlfw_clnt_svc_event_notify(struct notifier_block *this,
return ret;
}
+static int icnss_msa0_ramdump(struct icnss_priv *priv)
+{
+ struct ramdump_segment segment;
+
+ memset(&segment, 0, sizeof(segment));
+ segment.v_address = priv->msa_va;
+ segment.size = priv->msa_mem_size;
+ return do_ramdump(priv->msa0_dump_dev, &segment, 1);
+}
+
static struct notifier_block wlfw_clnt_nb = {
.notifier_call = icnss_qmi_wlfw_clnt_svc_event_notify,
};
@@ -2778,9 +2793,19 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
icnss_pr_dbg("Modem-Notify: event %lu\n", code);
+ if (code == SUBSYS_AFTER_SHUTDOWN) {
+ icnss_remove_msa_permissions(priv);
+ icnss_pr_info("Collecting msa0 segment dump\n");
+ icnss_msa0_ramdump(priv);
+ return NOTIFY_OK;
+ }
+
if (code != SUBSYS_BEFORE_SHUTDOWN)
return NOTIFY_OK;
+ if (test_bit(ICNSS_PDR_ENABLED, &priv->state))
+ return NOTIFY_OK;
+
icnss_pr_info("Modem went down, state: %lx\n", priv->state);
event_data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -2936,8 +2961,6 @@ static int icnss_get_service_location_notify(struct notifier_block *nb,
set_bit(ICNSS_PDR_ENABLED, &priv->state);
- icnss_modem_ssr_unregister_notifier(priv);
-
icnss_pr_dbg("PD restart enabled, state: 0x%lx\n", priv->state);
return NOTIFY_OK;
@@ -3000,6 +3023,11 @@ static int icnss_enable_recovery(struct icnss_priv *priv)
goto enable_pdr;
}
+ priv->msa0_dump_dev = create_ramdump_device("wcss_msa0",
+ &priv->pdev->dev);
+ if (!priv->msa0_dump_dev)
+ return -ENOMEM;
+
icnss_modem_ssr_register_notifier(priv);
if (test_bit(SSR_ONLY, &quirks)) {
icnss_pr_dbg("PDR disabled through module parameter\n");
@@ -3929,6 +3957,8 @@ static int icnss_stats_show_capability(struct seq_file *s,
priv->fw_version_info.fw_version);
seq_printf(s, "Firmware Build Timestamp: %s\n",
priv->fw_version_info.fw_build_timestamp);
+ seq_printf(s, "Firmware Build ID: %s\n",
+ priv->fw_build_id);
}
return 0;
@@ -4511,6 +4541,8 @@ static int icnss_remove(struct platform_device *pdev)
icnss_modem_ssr_unregister_notifier(penv);
+ destroy_ramdump_device(penv->msa0_dump_dev);
+
icnss_pdr_unregister_notifier(penv);
qmi_svc_event_notifier_unregister(WLFW_SERVICE_ID_V01,
@@ -4522,6 +4554,8 @@ static int icnss_remove(struct platform_device *pdev)
icnss_hw_power_off(penv);
+ icnss_remove_msa_permissions(penv);
+
dev_set_drvdata(&pdev->dev, NULL);
return 0;
diff --git a/drivers/soc/qcom/secure_buffer.c b/drivers/soc/qcom/secure_buffer.c
index afe6b2309e27..95d50fe01ee1 100644
--- a/drivers/soc/qcom/secure_buffer.c
+++ b/drivers/soc/qcom/secure_buffer.c
@@ -260,7 +260,7 @@ int hyp_assign_table(struct sg_table *table,
int *dest_vmids, int *dest_perms,
int dest_nelems)
{
- int ret;
+ int ret = 0;
struct scm_desc desc = {0};
u32 *source_vm_copy;
size_t source_vm_copy_size;
diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.c b/drivers/soc/qcom/wlan_firmware_service_v01.c
index f5f7ae8c9901..3e00d6c9d153 100644
--- a/drivers/soc/qcom/wlan_firmware_service_v01.c
+++ b/drivers/soc/qcom/wlan_firmware_service_v01.c
@@ -766,6 +766,24 @@ struct elem_info wlfw_cap_resp_msg_v01_ei[] = {
.ei_array = wlfw_fw_version_info_s_v01_ei,
},
{
+ .data_type = QMI_OPT_FLAG,
+ .elem_len = 1,
+ .elem_size = sizeof(uint8_t),
+ .is_array = NO_ARRAY,
+ .tlv_type = 0x14,
+ .offset = offsetof(struct wlfw_cap_resp_msg_v01,
+ fw_build_id_valid),
+ },
+ {
+ .data_type = QMI_STRING,
+ .elem_len = QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1,
+ .elem_size = sizeof(char),
+ .is_array = NO_ARRAY,
+ .tlv_type = 0x14,
+ .offset = offsetof(struct wlfw_cap_resp_msg_v01,
+ fw_build_id),
+ },
+ {
.data_type = QMI_EOTI,
.is_array = NO_ARRAY,
.is_array = QMI_COMMON_TLV_TYPE,
@@ -1588,3 +1606,47 @@ struct elem_info wlfw_vbatt_resp_msg_v01_ei[] = {
.is_array = QMI_COMMON_TLV_TYPE,
},
};
+
+struct elem_info wlfw_mac_addr_req_msg_v01_ei[] = {
+ {
+ .data_type = QMI_OPT_FLAG,
+ .elem_len = 1,
+ .elem_size = sizeof(uint8_t),
+ .is_array = NO_ARRAY,
+ .tlv_type = 0x10,
+ .offset = offsetof(struct wlfw_mac_addr_req_msg_v01,
+ mac_addr_valid),
+ },
+ {
+ .data_type = QMI_UNSIGNED_1_BYTE,
+ .elem_len = QMI_WLFW_MAC_ADDR_SIZE_V01,
+ .elem_size = sizeof(uint8_t),
+ .is_array = STATIC_ARRAY,
+ .tlv_type = 0x10,
+ .offset = offsetof(struct wlfw_mac_addr_req_msg_v01,
+ mac_addr),
+ },
+ {
+ .data_type = QMI_EOTI,
+ .is_array = NO_ARRAY,
+ .is_array = QMI_COMMON_TLV_TYPE,
+ },
+};
+
+struct elem_info wlfw_mac_addr_resp_msg_v01_ei[] = {
+ {
+ .data_type = QMI_STRUCT,
+ .elem_len = 1,
+ .elem_size = sizeof(struct qmi_response_type_v01),
+ .is_array = NO_ARRAY,
+ .tlv_type = 0x02,
+ .offset = offsetof(struct wlfw_mac_addr_resp_msg_v01,
+ resp),
+ .ei_array = get_qmi_response_type_v01_ei(),
+ },
+ {
+ .data_type = QMI_EOTI,
+ .is_array = NO_ARRAY,
+ .is_array = QMI_COMMON_TLV_TYPE,
+ },
+};
diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.h b/drivers/soc/qcom/wlan_firmware_service_v01.h
index 29bdfb23480a..47b315fce94c 100644
--- a/drivers/soc/qcom/wlan_firmware_service_v01.h
+++ b/drivers/soc/qcom/wlan_firmware_service_v01.h
@@ -24,6 +24,7 @@
#define QMI_WLFW_CAL_DOWNLOAD_RESP_V01 0x0027
#define QMI_WLFW_INI_RESP_V01 0x002F
#define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026
+#define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033
#define QMI_WLFW_INITIATE_CAL_DOWNLOAD_IND_V01 0x0028
#define QMI_WLFW_MSA_READY_IND_V01 0x002B
#define QMI_WLFW_ATHDIAG_WRITE_RESP_V01 0x0031
@@ -43,6 +44,7 @@
#define QMI_WLFW_CAP_RESP_V01 0x0024
#define QMI_WLFW_ATHDIAG_READ_RESP_V01 0x0030
#define QMI_WLFW_VBATT_REQ_V01 0x0032
+#define QMI_WLFW_MAC_ADDR_REQ_V01 0x0033
#define QMI_WLFW_VBATT_RESP_V01 0x0032
#define QMI_WLFW_MSA_INFO_REQ_V01 0x002D
#define QMI_WLFW_CAL_DOWNLOAD_REQ_V01 0x0027
@@ -57,6 +59,8 @@
#define QMI_WLFW_MAX_TIMESTAMP_LEN_V01 32
#define QMI_WLFW_MAX_STR_LEN_V01 16
#define QMI_WLFW_MAX_NUM_SHADOW_REG_V01 24
+#define QMI_WLFW_MAC_ADDR_SIZE_V01 6
+#define QMI_WLFW_MAX_BUILD_ID_LEN_V01 128
#define QMI_WLFW_MAX_NUM_SVC_V01 24
enum wlfw_driver_mode_enum_v01 {
@@ -99,6 +103,7 @@ enum wlfw_pipedir_enum_v01 {
#define QMI_WLFW_ALREADY_REGISTERED_V01 ((uint64_t)0x01ULL)
#define QMI_WLFW_FW_READY_V01 ((uint64_t)0x02ULL)
+#define QMI_WLFW_MSA_READY_V01 ((uint64_t)0x04ULL)
struct wlfw_ce_tgt_pipe_cfg_s_v01 {
uint32_t pipe_num;
@@ -243,8 +248,10 @@ struct wlfw_cap_resp_msg_v01 {
struct wlfw_soc_info_s_v01 soc_info;
uint8_t fw_version_info_valid;
struct wlfw_fw_version_info_s_v01 fw_version_info;
+ uint8_t fw_build_id_valid;
+ char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1];
};
-#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 72
+#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 203
extern struct elem_info wlfw_cap_resp_msg_v01_ei[];
struct wlfw_bdf_download_req_msg_v01 {
@@ -428,4 +435,17 @@ struct wlfw_vbatt_resp_msg_v01 {
#define WLFW_VBATT_RESP_MSG_V01_MAX_MSG_LEN 7
extern struct elem_info wlfw_vbatt_resp_msg_v01_ei[];
+struct wlfw_mac_addr_req_msg_v01 {
+ uint8_t mac_addr_valid;
+ uint8_t mac_addr[QMI_WLFW_MAC_ADDR_SIZE_V01];
+};
+#define WLFW_MAC_ADDR_REQ_MSG_V01_MAX_MSG_LEN 9
+extern struct elem_info wlfw_mac_addr_req_msg_v01_ei[];
+
+struct wlfw_mac_addr_resp_msg_v01 {
+ struct qmi_response_type_v01 resp;
+};
+#define WLFW_MAC_ADDR_RESP_MSG_V01_MAX_MSG_LEN 7
+extern struct elem_info wlfw_mac_addr_resp_msg_v01_ei[];
+
#endif
diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c
index ea0f433f989c..33f7304eac84 100644
--- a/drivers/usb/gadget/function/f_mtp.c
+++ b/drivers/usb/gadget/function/f_mtp.c
@@ -43,6 +43,7 @@
#include "configfs.h"
#define MTP_RX_BUFFER_INIT_SIZE 1048576
+#define MTP_TX_BUFFER_INIT_SIZE 1048576
#define MTP_BULK_BUFFER_SIZE 16384
#define INTR_BUFFER_SIZE 28
#define MAX_INST_NAME_LEN 40
@@ -81,7 +82,7 @@
unsigned int mtp_rx_req_len = MTP_RX_BUFFER_INIT_SIZE;
module_param(mtp_rx_req_len, uint, S_IRUGO | S_IWUSR);
-unsigned int mtp_tx_req_len = MTP_BULK_BUFFER_SIZE;
+unsigned int mtp_tx_req_len = MTP_TX_BUFFER_INIT_SIZE;
module_param(mtp_tx_req_len, uint, S_IRUGO | S_IWUSR);
unsigned int mtp_tx_reqs = MTP_TX_REQ_MAX;
@@ -551,9 +552,6 @@ static int mtp_create_bulk_endpoints(struct mtp_dev *dev,
dev->ep_intr = ep;
retry_tx_alloc:
- if (mtp_tx_req_len > MTP_BULK_BUFFER_SIZE)
- mtp_tx_reqs = 4;
-
/* now allocate requests for our endpoints */
for (i = 0; i < mtp_tx_reqs; i++) {
req = mtp_request_new(dev->ep_in, mtp_tx_req_len);
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 084dbbc81a6d..c025dccdd8f1 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -332,7 +332,7 @@ static int xhci_plat_runtime_suspend(struct device *dev)
dev_dbg(dev, "xhci-plat runtime suspend\n");
- return xhci_suspend(xhci, true);
+ return 0;
}
static int xhci_plat_runtime_resume(struct device *dev)
@@ -346,7 +346,7 @@ static int xhci_plat_runtime_resume(struct device *dev)
dev_dbg(dev, "xhci-plat runtime resume\n");
- ret = xhci_resume(xhci, false);
+ ret = 0;
pm_runtime_mark_last_busy(dev);
return ret;
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index e396dfff60ef..b64518194926 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -514,7 +514,7 @@ char mdss_dp_gen_link_clk(struct mdss_panel_info *pinfo, char lane_cnt)
{
const u32 encoding_factx10 = 8;
const u32 ln_to_link_ratio = 10;
- u32 min_link_rate;
+ u32 min_link_rate, reminder = 0;
char calc_link_rate = 0;
pr_debug("clk_rate=%llu, bpp= %d, lane_cnt=%d\n",
@@ -531,9 +531,15 @@ char mdss_dp_gen_link_clk(struct mdss_panel_info *pinfo, char lane_cnt)
(lane_cnt * encoding_factx10));
min_link_rate /= ln_to_link_ratio;
min_link_rate = (min_link_rate * pinfo->bpp);
- min_link_rate = (u32)div_u64(min_link_rate * 10,
- DP_LINK_RATE_MULTIPLIER);
+ min_link_rate = (u32)div_u64_rem(min_link_rate * 10,
+ DP_LINK_RATE_MULTIPLIER, &reminder);
+ /*
+ * To avoid any fractional values,
+ * increment the min_link_rate
+ */
+ if (reminder)
+ min_link_rate += 1;
pr_debug("min_link_rate = %d\n", min_link_rate);
if (min_link_rate <= DP_LINK_RATE_162)
diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c
index 20fcc26bb4bf..036e4e39efda 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_layer.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c
@@ -2470,16 +2470,20 @@ validate_exit:
mutex_lock(&mdp5_data->list_lock);
list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) {
if (IS_ERR_VALUE(ret)) {
- if ((pipe->ndx & rec_release_ndx[0]) ||
- (pipe->ndx & rec_release_ndx[1])) {
+ if (((pipe->ndx & rec_release_ndx[0]) &&
+ (pipe->multirect.num == 0)) ||
+ ((pipe->ndx & rec_release_ndx[1]) &&
+ (pipe->multirect.num == 1))) {
mdss_mdp_smp_unreserve(pipe);
pipe->params_changed = 0;
pipe->dirty = true;
if (!list_empty(&pipe->list))
list_del_init(&pipe->list);
mdss_mdp_pipe_destroy(pipe);
- } else if ((pipe->ndx & rec_destroy_ndx[0]) ||
- (pipe->ndx & rec_destroy_ndx[1])) {
+ } else if (((pipe->ndx & rec_destroy_ndx[0]) &&
+ (pipe->multirect.num == 0)) ||
+ ((pipe->ndx & rec_destroy_ndx[1]) &&
+ (pipe->multirect.num == 1))) {
/*
* cleanup/destroy list pipes should move back
* to destroy list. Next/current kickoff cycle
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 664850a1a617..946e33033ab7 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -2120,8 +2120,10 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd)
int ret = 0;
int sd_in_pipe = 0;
int sc_in_pipe = 0;
+ u64 pipes_flags = 0;
list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
+ pipes_flags |= pipe->flags;
if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) {
sd_in_pipe = 1;
pr_debug("Secure pipe: %u : %16llx\n",
@@ -2133,34 +2135,54 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd)
}
}
- if ((!sd_in_pipe && !mdp5_data->sd_enabled) ||
- (sd_in_pipe && mdp5_data->sd_enabled) ||
- (!sc_in_pipe && !mdp5_data->sc_enabled) ||
+ MDSS_XLOG(sd_in_pipe, sc_in_pipe, pipes_flags,
+ mdp5_data->sc_enabled, mdp5_data->sd_enabled);
+ pr_debug("sd:%d sd_in_pipe:%d sc:%d sc_in_pipe:%d flags:0x%llx\n",
+ mdp5_data->sd_enabled, sd_in_pipe,
+ mdp5_data->sc_enabled, sc_in_pipe, pipes_flags);
+
+ /*
+ * Return early in only two conditions:
+ * 1. All the features are already disabled and state remains
+ * disabled for the pipes.
+ * 2. One of the features is already enabled and state remains
+ * enabled for the pipes.
+ */
+ if (!sd_in_pipe && !mdp5_data->sd_enabled &&
+ !sc_in_pipe && !mdp5_data->sc_enabled)
+ return ret;
+ else if ((sd_in_pipe && mdp5_data->sd_enabled) ||
(sc_in_pipe && mdp5_data->sc_enabled))
return ret;
/* Secure Display */
if (!mdp5_data->sd_enabled && sd_in_pipe) {
if (!mdss_get_sd_client_cnt()) {
+ MDSS_XLOG(0x11);
/*wait for ping pong done */
if (ctl->ops.wait_pingpong)
mdss_mdp_display_wait4pingpong(ctl, true);
ret = mdss_mdp_secure_session_ctrl(1,
MDP_SECURE_DISPLAY_OVERLAY_SESSION);
- if (ret)
+ if (ret) {
+ pr_err("secure display enable fail:%d", ret);
return ret;
+ }
}
mdp5_data->sd_enabled = 1;
mdss_update_sd_client(mdp5_data->mdata, true);
} else if (mdp5_data->sd_enabled && !sd_in_pipe) {
/* disable the secure display on last client */
if (mdss_get_sd_client_cnt() == 1) {
+ MDSS_XLOG(0x22);
if (ctl->ops.wait_pingpong)
mdss_mdp_display_wait4pingpong(ctl, true);
ret = mdss_mdp_secure_session_ctrl(0,
MDP_SECURE_DISPLAY_OVERLAY_SESSION);
- if (ret)
+ if (ret) {
+ pr_err("secure display disable fail:%d\n", ret);
return ret;
+ }
}
mdss_update_sd_client(mdp5_data->mdata, false);
mdp5_data->sd_enabled = 0;
@@ -2169,29 +2191,36 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd)
/* Secure Camera */
if (!mdp5_data->sc_enabled && sc_in_pipe) {
if (!mdss_get_sc_client_cnt()) {
+ MDSS_XLOG(0x33);
if (ctl->ops.wait_pingpong)
mdss_mdp_display_wait4pingpong(ctl, true);
ret = mdss_mdp_secure_session_ctrl(1,
MDP_SECURE_CAMERA_OVERLAY_SESSION);
- if (ret)
+ if (ret) {
+ pr_err("secure camera enable fail:%d\n", ret);
return ret;
+ }
}
mdp5_data->sc_enabled = 1;
mdss_update_sc_client(mdp5_data->mdata, true);
} else if (mdp5_data->sc_enabled && !sc_in_pipe) {
/* disable the secure camera on last client */
if (mdss_get_sc_client_cnt() == 1) {
+ MDSS_XLOG(0x44);
if (ctl->ops.wait_pingpong)
mdss_mdp_display_wait4pingpong(ctl, true);
ret = mdss_mdp_secure_session_ctrl(0,
MDP_SECURE_CAMERA_OVERLAY_SESSION);
- if (ret)
+ if (ret) {
+ pr_err("secure camera disable fail:%d\n", ret);
return ret;
+ }
}
mdss_update_sc_client(mdp5_data->mdata, false);
mdp5_data->sc_enabled = 0;
}
+ MDSS_XLOG(ret);
return ret;
}
@@ -5430,6 +5459,7 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
mdss_mdp_overlay_kickoff(mfd, NULL);
}
+ctl_stop:
/*
* If retire fences are still active wait for a vsync time
* for retire fence to be updated.
@@ -5460,7 +5490,6 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
flush_work(&mdp5_data->retire_work);
}
-ctl_stop:
mutex_lock(&mdp5_data->ov_lock);
/* set the correct pipe_mapped before ctl_stop */
mdss_mdp_mixer_update_pipe_map(mdp5_data->ctl,
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
index e370a80ad998..bcf5309993b9 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
@@ -1340,10 +1340,11 @@ static struct mdss_mdp_pipe *__pipe_lookup(struct mdss_mdp_pipe *pipe_list,
bool (*cmp)(struct mdss_mdp_pipe *, void *), void *data)
{
struct mdss_mdp_pipe *pipe;
- int i, j;
+ int i, j, max_rects;
for (i = 0, pipe = pipe_list; i < count; i++) {
- for (j = 0; j < pipe->multirect.max_rects; j++, pipe++)
+ max_rects = pipe->multirect.max_rects;
+ for (j = 0; j < max_rects; j++, pipe++)
if ((rect_num == pipe->multirect.num) &&
cmp(pipe, data))
return pipe;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c34a68ce901a..d33e10784b23 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -133,6 +133,7 @@ enum iommu_attr {
DOMAIN_ATTR_S1_BYPASS,
DOMAIN_ATTR_FAST,
DOMAIN_ATTR_PGTBL_INFO,
+ DOMAIN_ATTR_EARLY_MAP,
DOMAIN_ATTR_MAX,
};
diff --git a/include/linux/qdsp6v2/apr_tal.h b/include/linux/qdsp6v2/apr_tal.h
index ee8b2f5a8b5b..c2c49dd748de 100644
--- a/include/linux/qdsp6v2/apr_tal.h
+++ b/include/linux/qdsp6v2/apr_tal.h
@@ -32,7 +32,7 @@
#if defined(CONFIG_MSM_QDSP6_APRV2_GLINK) || \
defined(CONFIG_MSM_QDSP6_APRV3_GLINK)
#define APR_MAX_BUF 512
-#define APR_NUM_OF_TX_BUF 20
+#define APR_NUM_OF_TX_BUF 30
#else
#define APR_MAX_BUF 8092
#endif
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 643c68f4c449..8fdf57504ab6 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -1199,6 +1199,15 @@ enum v4l2_cid_mpeg_vidc_video_full_range {
#define V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS \
(V4L2_CID_MPEG_MSM_VIDC_BASE + 97)
+#define V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 98)
+enum v4l2_mpeg_vidc_video_venc_iframesize_type {
+ V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT,
+ V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_MEDIUM,
+ V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_HUGE,
+ V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED,
+};
+
/* Camera class control IDs */
#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 862eb8fd3860..84563da000cf 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5537,8 +5537,8 @@ static void migrate_tasks(struct rq *dead_rq, bool migrate_pinned_tasks)
* interferred since we don't stop all CPUs. Ignore warning for
* this case.
*/
- if (WARN_ON((task_rq(next) != rq || !task_on_rq_queued(next)) &&
- migrate_pinned_tasks)) {
+ if (task_rq(next) != rq || !task_on_rq_queued(next)) {
+ WARN_ON(migrate_pinned_tasks);
raw_spin_unlock(&next->pi_lock);
continue;
}
diff --git a/kernel/sched/core_ctl.c b/kernel/sched/core_ctl.c
index ecf6c568f0b5..9b21a09ec4ba 100644
--- a/kernel/sched/core_ctl.c
+++ b/kernel/sched/core_ctl.c
@@ -687,6 +687,7 @@ int core_ctl_set_boost(bool boost)
return ret;
}
+EXPORT_SYMBOL(core_ctl_set_boost);
void core_ctl_check(u64 wallclock)
{
diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c
index dda332d821e4..456a1dff692d 100644
--- a/net/netfilter/xt_IDLETIMER.c
+++ b/net/netfilter/xt_IDLETIMER.c
@@ -460,9 +460,9 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par)
list_del(&info->timer->entry);
del_timer_sync(&info->timer->timer);
- cancel_work_sync(&info->timer->work);
sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr);
unregister_pm_notifier(&info->timer->pm_nb);
+ cancel_work_sync(&info->timer->work);
kfree(info->timer->attr.attr.name);
kfree(info->timer);
} else {
diff --git a/net/rmnet_data/rmnet_data_vnd.c b/net/rmnet_data/rmnet_data_vnd.c
index 4e3a205551e0..2999e2c15fdb 100644
--- a/net/rmnet_data/rmnet_data_vnd.c
+++ b/net/rmnet_data/rmnet_data_vnd.c
@@ -180,6 +180,7 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
rmnet_vnd_add_qos_header(skb,
dev,
dev_conf->qos_version);
+ skb_orphan(skb);
rmnet_egress_handler(skb, &dev_conf->local_ep);
} else {
dev->stats.tx_dropped++;
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index 393b8b4b8084..06e00fdfe6a1 100644
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -11820,7 +11820,7 @@ static struct snd_soc_dai_driver tasha_dai[] = {
.capture = {
.stream_name = "AIF1 Capture",
.rates = WCD9335_RATES_MASK,
- .formats = TASHA_FORMATS,
+ .formats = TASHA_FORMATS_S16_S24_LE,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
@@ -11848,7 +11848,7 @@ static struct snd_soc_dai_driver tasha_dai[] = {
.capture = {
.stream_name = "AIF2 Capture",
.rates = WCD9335_RATES_MASK,
- .formats = TASHA_FORMATS,
+ .formats = TASHA_FORMATS_S16_S24_LE,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
@@ -11876,7 +11876,7 @@ static struct snd_soc_dai_driver tasha_dai[] = {
.capture = {
.stream_name = "AIF3 Capture",
.rates = WCD9335_RATES_MASK,
- .formats = TASHA_FORMATS,
+ .formats = TASHA_FORMATS_S16_S24_LE,
.rate_max = 48000,
.rate_min = 8000,
.channels_min = 1,
@@ -11977,7 +11977,7 @@ static struct snd_soc_dai_driver tasha_i2s_dai[] = {
.capture = {
.stream_name = "AIF1 Capture",
.rates = WCD9335_RATES_MASK,
- .formats = TASHA_FORMATS,
+ .formats = TASHA_FORMATS_S16_S24_LE,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
@@ -12005,7 +12005,7 @@ static struct snd_soc_dai_driver tasha_i2s_dai[] = {
.capture = {
.stream_name = "AIF2 Capture",
.rates = WCD9335_RATES_MASK,
- .formats = TASHA_FORMATS,
+ .formats = TASHA_FORMATS_S16_S24_LE,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 2874a334dfdd..22e14f431bb3 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -3015,7 +3015,8 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac,
int dir)
{
struct audio_buffer *buf_circ;
- int bytes_to_alloc, rc, len;
+ int bytes_to_alloc, rc;
+ size_t len;
buf_circ = kzalloc(sizeof(struct audio_buffer), GFP_KERNEL);
@@ -3034,7 +3035,7 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac,
rc = msm_audio_ion_alloc("audio_client", &buf_circ->client,
&buf_circ->handle, bytes_to_alloc,
(ion_phys_addr_t *)&buf_circ->phys,
- (size_t *)&len, &buf_circ->data);
+ &len, &buf_circ->data);
if (rc) {
pr_err("%s: Audio ION alloc is failed, rc = %d\n", __func__,
@@ -3076,7 +3077,8 @@ int q6asm_set_shared_pos_buff(struct audio_client *ac,
int dir)
{
struct audio_buffer *buf_pos = &ac->shared_pos_buf;
- int len, rc;
+ int rc;
+ size_t len;
int bytes_to_alloc = sizeof(struct asm_shared_position_buffer);
mutex_lock(&ac->cmd_lock);
@@ -3085,7 +3087,7 @@ int q6asm_set_shared_pos_buff(struct audio_client *ac,
rc = msm_audio_ion_alloc("audio_client", &buf_pos->client,
&buf_pos->handle, bytes_to_alloc,
- (ion_phys_addr_t *)&buf_pos->phys, (size_t *)&len,
+ (ion_phys_addr_t *)&buf_pos->phys, &len,
&buf_pos->data);
if (rc) {
@@ -5848,7 +5850,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
struct asm_buffer_node *buffer_node = NULL;
int rc = 0;
int i = 0;
- int cmd_size = 0;
+ uint32_t cmd_size = 0;
uint32_t bufcnt_t;
uint32_t bufsz_t;
@@ -5870,10 +5872,25 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
bufsz_t = PAGE_ALIGN(bufsz_t);
}
+ if (bufcnt_t > (UINT_MAX
+ - sizeof(struct avs_cmd_shared_mem_map_regions))
+ / sizeof(struct avs_shared_map_region_payload)) {
+ pr_err("%s: Unsigned Integer Overflow. bufcnt_t = %u\n",
+ __func__, bufcnt_t);
+ return -EINVAL;
+ }
+
cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions)
+ (sizeof(struct avs_shared_map_region_payload)
* bufcnt_t);
+
+ if (bufcnt > (UINT_MAX / sizeof(struct asm_buffer_node))) {
+ pr_err("%s: Unsigned Integer Overflow. bufcnt = %u\n",
+ __func__, bufcnt);
+ return -EINVAL;
+ }
+
buffer_node = kzalloc(sizeof(struct asm_buffer_node) * bufcnt,
GFP_KERNEL);
if (!buffer_node) {
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index 3b3e728f88f2..834fe7c05306 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -142,7 +142,7 @@ struct share_mem_buf {
struct mem_map_table {
dma_addr_t phys;
void *data;
- uint32_t size; /* size of buffer */
+ size_t size; /* size of buffer */
struct ion_handle *handle;
struct ion_client *client;
};
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index f4ceb5f5c678..eb894d073c07 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -68,7 +68,8 @@ out:
static int soc_compr_open_fe(struct snd_compr_stream *cstream)
{
struct snd_soc_pcm_runtime *fe = cstream->private_data;
- struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
+ struct snd_pcm_substream *fe_substream =
+ fe->pcm->streams[cstream->direction].substream;
struct snd_soc_platform *platform = fe->platform;
struct snd_soc_dpcm *dpcm;
struct snd_soc_dapm_widget_list *list;
@@ -443,7 +444,8 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
struct snd_compr_params *params)
{
struct snd_soc_pcm_runtime *fe = cstream->private_data;
- struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
+ struct snd_pcm_substream *fe_substream =
+ fe->pcm->streams[cstream->direction].substream;
struct snd_soc_platform *platform = fe->platform;
struct snd_soc_pcm_runtime *be_list[DPCM_MAX_BE_USERS];
struct snd_soc_dpcm *dpcm;