Merge "ARM: dts: msm: Split system low power mode state id for sdxpoorwills"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt b/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt
index 53ad68e..cf13d34 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt
@@ -33,6 +33,7 @@
- qcom,ipi-ping : (boolean) send keep alive ping to other cpus if present
- qcom,wakeup-enable : (boolean) enable non secure watchdog to freeze / unfreeze
automatically across suspend / resume path.
+- qcom,scandump-size : size of scan dump memory region.
Example:
diff --git a/Documentation/devicetree/bindings/bt-fm/fm.txt b/Documentation/devicetree/bindings/bt-fm/fm.txt
new file mode 100644
index 0000000..ed73e5d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/bt-fm/fm.txt
@@ -0,0 +1,29 @@
+Qti radio iris device
+
+-FM RX playback with no RDS
+
+ FM samples is filtered by external RF chips at baseband, then send to Riva-FM core through serial link.
+ FM signal is demodulated then audio L/R samples are stored inside memory.
+ FM Rx received samples data is connected to external audio codec.
+
+-Audio playback to FM TX
+
+ Used to play audio source to FM TX.
+ FM TX module will read the audio samples from memory then modulated samples will be send through serial interface to external RF chip.
+
+-RX playback with RDS
+
+ FM Rx receive audio data along with RDS.
+
+-FM TX with RDS
+
+ Used to send RDS messages to external FM receiver.
+
+Required Properties:
+- compatible: "qcom,iris_fm"
+
+Example:
+ qcom,iris-fm {
+ compatible = "qcom,iris_fm";
+ };
+
diff --git a/Documentation/devicetree/bindings/display/bridge/lt9611.txt b/Documentation/devicetree/bindings/display/bridge/lt9611.txt
index 61688b5..419be2d 100644
--- a/Documentation/devicetree/bindings/display/bridge/lt9611.txt
+++ b/Documentation/devicetree/bindings/display/bridge/lt9611.txt
@@ -8,7 +8,7 @@
- lt,reset-gpio Main reset gpio mapping
- Optional properties:
+Optional properties:
- lt,hdmi-ps-gpio: gpio mapping for HDMI PS
- lt,hdmi-en-gpio: gpio mapping for HDMI EN
@@ -29,6 +29,7 @@
-- lt,supply-post-off-sleep: time to sleep (ms) after turning off
- lt,non-pluggable: Boolean to indicate if display is non pluggable.
+ - lt,preferred-mode: Preferred display mode.
- lt,customize-modes: Customized modes when it's non-pluggable display.
e.g. lt,customize-mode-id@0
-- lt,mode-h-active: Horizontal active pixels for this mode.
@@ -66,6 +67,8 @@
lt,reset-gpio = <&tlmm 134 0x0>;
lt,hdmi-ps-gpio = <&tlmm 136 0x0>;
lt,hdmi-en-gpio = <&tlmm 137 0x0>;
+ lt,non-pluggable;
+ lt,preferred-mode = "1920x1080";
vcc-supply = <&pm660l_l6>;
vdd-supply = <&pm660_l11>;
diff --git a/Documentation/devicetree/bindings/display/msm/sde.txt b/Documentation/devicetree/bindings/display/msm/sde.txt
index 4b4c274..0589165 100644
--- a/Documentation/devicetree/bindings/display/msm/sde.txt
+++ b/Documentation/devicetree/bindings/display/msm/sde.txt
@@ -78,6 +78,8 @@
Optional properties:
- clock-rate: List of clock rates in Hz.
- clock-max-rate: List of maximum clock rate in Hz that this device supports.
+- connectors: Specifies the connector components.
+- bridges: Specifies the bridge components.
- qcom,platform-supply-entries: A node that lists the elements of the supply. There
can be more than one instance of this binding,
in which case the entry would be appended with
diff --git a/Documentation/devicetree/bindings/input/qpnp-power-on.txt b/Documentation/devicetree/bindings/input/qpnp-power-on.txt
index 33d0236..0f1d9e1 100644
--- a/Documentation/devicetree/bindings/input/qpnp-power-on.txt
+++ b/Documentation/devicetree/bindings/input/qpnp-power-on.txt
@@ -112,6 +112,9 @@
trigger during system shutdown case.
- qcom,ps-hold-hard-reset-disable Boolean property to disable PS_HOLD
POFF trigger during system hard reset case.
+- qcom,use-legacy-hard-reset-offset Boolean property to support legacy
+ hard-reset offset of the PON_RB_SPARE register for
+ some (PON gen2) platforms.
All the below properties are in the sub-node section (properties of the child
node).
diff --git a/Documentation/devicetree/bindings/input/touchscreen/focaltech_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/focaltech_ts.txt
index 4a1b751..0174e3d 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/focaltech_ts.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/focaltech_ts.txt
@@ -30,6 +30,7 @@
- focaltech,keys : array of key code.
- focaltech,key-y-coord : y coordinate for the keys.
- focaltech,key-x-coords : array of x coordinates for the keys.
+ - focaltech,wakeup-gestures-en : enable wakeup gestures.
Example:
i2c@f9923000{
diff --git a/Documentation/devicetree/bindings/pil/pil-blackghost.txt b/Documentation/devicetree/bindings/pil/pil-blackghost.txt
new file mode 100644
index 0000000..66cde5c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pil/pil-blackghost.txt
@@ -0,0 +1,33 @@
+Qualcomm Technologies Inc Blackghost(BG) PIL driver:
+
+Blackghost(BG) PIL driver provide interface to load and boot Blackghost(BG)
+SOC. Blackghost(BG) SOC is an external SOC which communicate to MSM via
+SPI. The PIL driver loads firmware into memory and invoke secure app via
+qseecom to transfer and handshake the boot process. Once Blackghost(BG) SOC
+is booted it raises ready interrupt which is handled by BG PIL driver, and
+this event is informed to other MSM drivers, other remote subsystem via
+notifier framework. The PIL driver also handles interrupt for the BG SOC
+crash upon arrival of which it reset and initiates ramdump collection for BG
+SOC.
+
+Required properties:
+- compatible: Must be "qcom,PIL-blackghost"
+- qcom,firmware-name: Base name of the firmware image.
+- qcom,bg2ap-status-gpio: GPIO used by the blackghost to indicate status to the apps.
+- qcom,bg2ap-errfatal-gpio: GPIO used by the blackghost to indicate software error to the apps.
+- qcom,ap2bg-status-gpio: GPIO used by the apps to indicate its status to blackghost.
+- qcom,ap2bg-errfatal-gpio: GPIO used by the apps to indicate blackghost about apps reset.
+
+Example:
+
+ qcom,blackghost {
+ compatible = "qcom,pil-blackghost";
+ qcom,firmware-name = "bgelf";
+
+ /* GPIO inputs from blackghost */
+ qcom,bg2ap-status-gpio = <&msm_gpio 97 0>;
+ qcom,bg2ap-errfatal-gpio = <&msm_gpio 95 0>;
+ /* GPIO output to blackghost */
+ qcom,ap2bg-status-gpio = <&msm_gpio 17 0>;
+ qcom,ap2bg-errfatal-gpio = <&msm_gpio 23 0>;
+ };
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
index 5034e9f..392ee7b 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
@@ -380,7 +380,7 @@
Value type: <u32>
Definition: Value in micro percentage for low temperature ESR tight
filter. If this is not specified, then a default value of
- 48829 (4.88 %) will be used. Lowest possible value is 1954
+ 30000 (3 %) will be used. Lowest possible value is 1954
(0.19 %).
- qcom,fg-esr-broad-lt-filter-micro-pct
@@ -388,9 +388,35 @@
Value type: <u32>
Definition: Value in micro percentage for low temperature ESR broad
filter. If this is not specified, then a default value of
- 148438 (14.84 %) will be used. Lowest possible value is
+ 30000 (3 %) will be used. Lowest possible value is
1954 (0.19 %).
+- qcom,fg-esr-rt-filter-switch-temp
+ Usage: optional
+ Value type: <u32>
+ Definition: Battery temperature threshold below which ESR relax
+ filter coefficients will be applied after a certain
+ number of delta battery temperature interrupts firing in
+ an interval of time. This will be applied only when Qnovo
+ is enabled. If this is not specified, then the default
+ value used will be -100. Unit is in decidegC.
+
+- qcom,fg-esr-tight-rt-filter-micro-pct
+ Usage: optional
+ Value type: <u32>
+ Definition: Value in micro percentage for relax temperature ESR tight
+ filter. If this is not specified, then a default value of
+ 5860 will be used. Lowest possible value is 1954 (0.19 %).
+ This will be applied only if Qnovo is enabled.
+
+- qcom,fg-esr-broad-rt-filter-micro-pct
+ Usage: optional
+ Value type: <u32>
+ Definition: Value in micro percentage for relax temperature ESR broad
+ filter. If this is not specified, then a default value of
+ 156250 will be used. Lowest possible value is 1954 (0.19 %).
+ This will be applied only if Qnovo is enabled.
+
- qcom,fg-auto-recharge-soc
Usage: optional
Value type: <empty>
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index f56516c..f42fcd4 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -131,7 +131,7 @@
KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
-CHECKFLAGS += -D__arm__
+CHECKFLAGS += -D__arm__ -m32
#Default value
head-y := arch/arm/kernel/head$(MMUEXT).o
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 29151fc..b4bc69f 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -4,6 +4,10 @@
sdxpoorwills-mtp.dtb \
sdxpoorwills-cdp-256.dtb \
sdxpoorwills-mtp-256.dtb \
+ sdxpoorwills-dualwifi-cdp.dtb \
+ sdxpoorwills-dualwifi-mtp.dtb \
+ sdxpoorwills-pcie-ep-cdp-256.dtb \
+ sdxpoorwills-pcie-ep-mtp-256.dtb \
sdxpoorwills-pcie-ep-cdp.dtb \
sdxpoorwills-pcie-ep-mtp.dtb
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
index ad1e6ca..b4e91ab 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
@@ -35,6 +35,14 @@
};
/*BCMs*/
+ bcm_acv: bcm-acv {
+ cell-id = <MSM_BUS_BCM_ACV>;
+ label = "ACV";
+ qcom,bcm-name = "ACV";
+ qcom,rscs = <&rsc_apps>;
+ qcom,bcm-dev;
+ };
+
bcm_alc: bcm-alc {
cell-id = <MSM_BUS_BCM_ALC>;
label = "ALC";
@@ -564,6 +572,15 @@
qcom,prio = <0>;
};
+ mas_alc: mas-alc {
+ cell-id = <MSM_BUS_MASTER_ALC>;
+ label = "mas-alc";
+ qcom,buswidth = <1>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_mc_virt>;
+ qcom,bcms = <&bcm_alc>;
+ };
+
/*Internal nodes*/
/*Slaves*/
@@ -583,7 +600,7 @@
qcom,buswidth = <4>;
qcom,agg-ports = <1>;
qcom,bus-dev = <&fab_mc_virt>;
- qcom,bcms = <&bcm_mc0>;
+ qcom,bcms = <&bcm_mc0>, <&bcm_acv>;
};
slv_qns_llcc:slv-qns-llcc {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dts
new file mode 100644
index 0000000..6909ef5
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dts
@@ -0,0 +1,30 @@
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "sdxpoorwills-dualwifi-cdp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDXPOORWILLS DUAL-WIFI CDP";
+ compatible = "qcom,sdxpoorwills-cdp",
+ "qcom,sdxpoorwills", "qcom,cdp";
+ qcom,board-id = <1 0x105>;
+};
+
+&cnss_pcie {
+ qcom,is-dual-wifi-enabled;
+};
+
+&cnss_sdio {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dtsi
new file mode 100644
index 0000000..8a7b771
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dtsi
@@ -0,0 +1,13 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "sdxpoorwills-cdp.dtsi"
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dts
new file mode 100644
index 0000000..5fd7042
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dts
@@ -0,0 +1,30 @@
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "sdxpoorwills-dualwifi-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDXPOORWILLS DUAL-WIFI MTP";
+ compatible = "qcom,sdxpoorwills-mtp",
+ "qcom,sdxpoorwills", "qcom,mtp";
+ qcom,board-id = <8 0x104>;
+};
+
+&cnss_pcie {
+ qcom,is-dual-wifi-enabled;
+};
+
+&cnss_sdio {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dtsi
new file mode 100644
index 0000000..4a2ece8c
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dtsi
@@ -0,0 +1,13 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "sdxpoorwills-mtp.dtsi"
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dts
new file mode 100644
index 0000000..cbbf585
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dts
@@ -0,0 +1,22 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "sdxpoorwills-pcie-ep-cdp-256.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDXPOORWILLS(M) PCIE-EP CDP";
+ compatible = "qcom,sdxpoorwills-cdp",
+ "qcom,sdxpoorwills", "qcom,cdp";
+ qcom,board-id = <1 0x1>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dtsi
new file mode 100644
index 0000000..518d8a1
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dtsi
@@ -0,0 +1,34 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "sdxpoorwills-cdp.dtsi"
+
+&vbus_detect {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+ extcon = <&vbus_detect>;
+};
+
+&pcie_ep {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "disabled";
+};
+
+&mhi_device {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dts
index 52eaba3..2a2e496 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dts
@@ -12,32 +12,12 @@
/dts-v1/;
-#include "sdxpoorwills-cdp.dtsi"
+#include "sdxpoorwills-pcie-ep-cdp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDXPOORWILLS PCIE-EP CDP";
compatible = "qcom,sdxpoorwills-cdp",
"qcom,sdxpoorwills", "qcom,cdp";
- qcom,board-id = <1 0x1>, <1 0x101>;
+ qcom,board-id = <1 0x106>;
};
-&vbus_detect {
- status = "okay";
-};
-
-&usb {
- status = "okay";
- extcon = <&vbus_detect>;
-};
-
-&pcie_ep {
- status = "okay";
-};
-
-&pcie0 {
- status = "disabled";
-};
-
-&mhi_device {
- status = "okay";
-};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dtsi
new file mode 100644
index 0000000..518d8a1
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dtsi
@@ -0,0 +1,34 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "sdxpoorwills-cdp.dtsi"
+
+&vbus_detect {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+ extcon = <&vbus_detect>;
+};
+
+&pcie_ep {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "disabled";
+};
+
+&mhi_device {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dts
new file mode 100644
index 0000000..6b6aab5
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dts
@@ -0,0 +1,22 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "sdxpoorwills-pcie-ep-mtp-256.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDXPOORWILLS(M) PCIE-EP MTP";
+ compatible = "qcom,sdxpoorwills-mtp",
+ "qcom,sdxpoorwills", "qcom,mtp";
+ qcom,board-id = <8 0x1>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dtsi
new file mode 100644
index 0000000..eb544e6
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dtsi
@@ -0,0 +1,34 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "sdxpoorwills-mtp.dtsi"
+
+&vbus_detect {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+ extcon = <&vbus_detect>;
+};
+
+&pcie_ep {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "disabled";
+};
+
+&mhi_device {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dts
index b68e401..8c22348 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dts
@@ -12,32 +12,11 @@
/dts-v1/;
-#include "sdxpoorwills-mtp.dtsi"
+#include "sdxpoorwills-pcie-ep-mtp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDXPOORWILLS PCIE-EP MTP";
compatible = "qcom,sdxpoorwills-mtp",
"qcom,sdxpoorwills", "qcom,mtp";
- qcom,board-id = <8 0x1>, <8 0x101>;
-};
-
-&vbus_detect {
- status = "okay";
-};
-
-&usb {
- status = "okay";
- extcon = <&vbus_detect>;
-};
-
-&pcie_ep {
- status = "okay";
-};
-
-&pcie0 {
- status = "disabled";
-};
-
-&mhi_device {
- status = "okay";
+ qcom,board-id = <8 0x105>;
};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dtsi
new file mode 100644
index 0000000..eb544e6
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dtsi
@@ -0,0 +1,34 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "sdxpoorwills-mtp.dtsi"
+
+&vbus_detect {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+ extcon = <&vbus_detect>;
+};
+
+&pcie_ep {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "disabled";
+};
+
+&mhi_device {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index b125e08..6e9bdd5 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -43,6 +43,16 @@
label = "sbl_mem";
};
+ flex_sec_apps_mem: flex_sec_apps_regions@8fcfd000 {
+ no-map;
+ reg = <0x8fcfd000 0x3000>;
+ };
+
+ access_control_mem: access_control_mem@8fc80000 {
+ no-map;
+ reg = <0x8fc80000 0x40000>;
+ };
+
hyp_region: hyp_region@8fc00000 {
no-map;
reg = <0x8fc00000 0x80000>;
@@ -823,6 +833,8 @@
qcom,mhi-event-ring-id-limits = <9 10>; /* start and end */
qcom,modem-cfg-emb-pipe-flt;
qcom,use-ipa-pm;
+ qcom,arm-smmu;
+ qcom,smmu-fast-map;
qcom,bandwidth-vote-for-ipa;
qcom,msm-bus,name = "ipa";
qcom,msm-bus,num-cases = <5>;
@@ -964,6 +976,32 @@
compatible = "qcom,smp2pgpio-map-ipa-1-in";
gpios = <&smp2pgpio_ipa_1_in 0 0>;
};
+
+ ipa_smmu_ap: ipa_smmu_ap {
+ compatible = "qcom,ipa-smmu-ap-cb";
+ qcom,smmu-s1-bypass;
+ iommus = <&apps_smmu 0x5E0 0x0>;
+ qcom,iova-mapping = <0x20000000 0x40000000>;
+ qcom,additional-mapping =
+ /* modem tables in IMEM */
+ <0x14686000 0x14686000 0x3000>;
+ };
+
+ ipa_smmu_wlan: ipa_smmu_wlan {
+ compatible = "qcom,ipa-smmu-wlan-cb";
+ qcom,smmu-s1-bypass;
+ iommus = <&apps_smmu 0x5E1 0x0>;
+ qcom,additional-mapping =
+ /* ipa-uc ram */
+ <0x1E60000 0x1E60000 0xA000>;
+ };
+
+ ipa_smmu_uc: ipa_smmu_uc {
+ compatible = "qcom,ipa-smmu-uc-cb";
+ qcom,smmu-s1-bypass;
+ iommus = <&apps_smmu 0x5E2 0x0>;
+ qcom,iova-mapping = <0x40000000 0x20000000>;
+ };
};
qmp_aop: qcom,qmp-aop@c300000 {
@@ -1142,12 +1180,12 @@
<0x36000 0x100>,
<0x3900000 0x300000>;
reg-names = "emac-base", "rgmii-base", "tlmm-central-base";
- interrupts = <0 62 4>, <0 60 4>,
- <0 45 4>, <0 49 4>,
- <0 50 4>, <0 51 4>,
- <0 52 4>, <0 53 4>,
- <0 54 4>, <0 55 4>,
- <0 56 4>, <0 57 4>;
+ interrupts-extended = <&pdc 0 62 4>, <&pdc 0 60 4>,
+ <&tlmm 84 2>, <&pdc 0 49 4>,
+ <&pdc 0 50 4>, <&pdc 0 51 4>,
+ <&pdc 0 52 4>, <&pdc 0 53 4>,
+ <&pdc 0 54 4>, <&pdc 0 55 4>,
+ <&pdc 0 56 4>, <&pdc 0 57 4>;
interrupt-names = "sbd-intr", "lpi-intr",
"wol-intr", "tx-ch0-intr",
"tx-ch1-intr", "tx-ch2-intr",
diff --git a/arch/arm/configs/msm8909w-perf_defconfig b/arch/arm/configs/msm8909w-perf_defconfig
index 7c10cdd..0c04f9c 100644
--- a/arch/arm/configs/msm8909w-perf_defconfig
+++ b/arch/arm/configs/msm8909w-perf_defconfig
@@ -259,6 +259,10 @@
CONFIG_KEYBOARD_GPIO=y
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y
+CONFIG_TOUCHSCREEN_FTS=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_UINPUT=y
@@ -421,10 +425,13 @@
CONFIG_MSM_GLINK_PKT=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
CONFIG_MSM_EVENT_TIMER=y
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_MSM_BAM_DMUX=y
+CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_IIO=y
CONFIG_QCOM_SPMI_IADC=y
CONFIG_QCOM_SPMI_VADC=y
diff --git a/arch/arm/configs/msm8909w_defconfig b/arch/arm/configs/msm8909w_defconfig
index 7c10cdd..0c04f9c 100644
--- a/arch/arm/configs/msm8909w_defconfig
+++ b/arch/arm/configs/msm8909w_defconfig
@@ -259,6 +259,10 @@
CONFIG_KEYBOARD_GPIO=y
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y
+CONFIG_TOUCHSCREEN_FTS=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_UINPUT=y
@@ -421,10 +425,13 @@
CONFIG_MSM_GLINK_PKT=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
CONFIG_MSM_EVENT_TIMER=y
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_MSM_BAM_DMUX=y
+CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_IIO=y
CONFIG_QCOM_SPMI_IADC=y
CONFIG_QCOM_SPMI_VADC=y
diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig
index 722845e..9a88cb6 100644
--- a/arch/arm/configs/msm8953-perf_defconfig
+++ b/arch/arm/configs/msm8953-perf_defconfig
@@ -51,6 +51,7 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8953=y
CONFIG_ARCH_MSM8937=y
+CONFIG_ARCH_MSM8917=y
CONFIG_ARCH_SDM450=y
# CONFIG_VDSO is not set
CONFIG_SMP=y
@@ -291,6 +292,9 @@
# CONFIG_SERIO_SERPORT is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_SMD=y
CONFIG_DIAG_CHAR=y
CONFIG_DIAG_USES_SMD=y
@@ -300,6 +304,7 @@
CONFIG_MSM_ADSPRPC=y
CONFIG_MSM_RDBG=m
CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MSM_V2=y
CONFIG_SPI=y
CONFIG_SPI_QUP=y
CONFIG_SPI_SPIDEV=y
@@ -385,6 +390,8 @@
CONFIG_MSM_JPEGDMA=y
CONFIG_MSM_VIDC_3X_V4L2=y
CONFIG_MSM_VIDC_3X_GOVERNORS=y
+CONFIG_RADIO_IRIS=y
+CONFIG_RADIO_IRIS_TRANSPORT=y
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
CONFIG_FB_MSM=y
@@ -505,6 +512,7 @@
CONFIG_QPNP_COINCELL=y
CONFIG_QPNP_REVID=y
CONFIG_USB_BAM=y
+CONFIG_MSM_RMNET_BAM=y
CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_MAILBOX=y
@@ -545,6 +553,7 @@
CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
CONFIG_QCOM_BIMC_BWMON=y
CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
+CONFIG_DEVFREQ_SIMPLE_DEV=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_SPDM_SCM=y
CONFIG_DEVFREQ_SPDM=y
diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig
index 26d9717..102b148 100644
--- a/arch/arm/configs/msm8953_defconfig
+++ b/arch/arm/configs/msm8953_defconfig
@@ -57,6 +57,7 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8953=y
CONFIG_ARCH_MSM8937=y
+CONFIG_ARCH_MSM8917=y
CONFIG_ARCH_SDM450=y
# CONFIG_VDSO is not set
CONFIG_SMP=y
@@ -300,8 +301,11 @@
# CONFIG_SERIO_SERPORT is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_SMD=y
CONFIG_DIAG_CHAR=y
CONFIG_DIAG_USES_SMD=y
@@ -311,6 +315,7 @@
CONFIG_MSM_ADSPRPC=y
CONFIG_MSM_RDBG=m
CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MSM_V2=y
CONFIG_SPI=y
CONFIG_SPI_QUP=y
CONFIG_SPI_SPIDEV=y
@@ -396,6 +401,8 @@
CONFIG_MSM_JPEGDMA=y
CONFIG_MSM_VIDC_3X_V4L2=y
CONFIG_MSM_VIDC_3X_GOVERNORS=y
+CONFIG_RADIO_IRIS=y
+CONFIG_RADIO_IRIS_TRANSPORT=y
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
CONFIG_FB_VIRTUAL=y
@@ -519,6 +526,7 @@
CONFIG_QPNP_REVID=y
CONFIG_USB_BAM=y
CONFIG_MSM_EXT_DISPLAY=y
+CONFIG_MSM_RMNET_BAM=y
CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_MAILBOX=y
@@ -565,6 +573,7 @@
CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
CONFIG_QCOM_BIMC_BWMON=y
CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
+CONFIG_DEVFREQ_SIMPLE_DEV=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_SPDM_SCM=y
CONFIG_DEVFREQ_SPDM=y
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index 32ff446..8d8e6d1 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -194,6 +194,7 @@
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_SMSC is not set
# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_AT803X_PHY=y
CONFIG_PPP=y
CONFIG_PPP_ASYNC=y
CONFIG_USB_USBNET=y
@@ -321,6 +322,7 @@
CONFIG_ION_MSM=y
CONFIG_GSI=y
CONFIG_IPA3=y
+CONFIG_IPA_WDI_UNIFIED_API=y
CONFIG_RMNET_IPA3=y
CONFIG_ECM_IPA=y
CONFIG_RNDIS_IPA=y
@@ -366,6 +368,7 @@
CONFIG_MSM_PIL_SSR_GENERIC=y
CONFIG_QCOM_COMMAND_DB=y
CONFIG_MSM_PM=y
+CONFIG_QCOM_DCC_V2=y
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_EXTCON_QCOM_SPMI_MISC=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index a6063c8..f786337 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -186,6 +186,7 @@
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_SMSC is not set
# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_AT803X_PHY=y
CONFIG_PPP=y
CONFIG_PPP_ASYNC=y
CONFIG_USB_USBNET=y
@@ -326,6 +327,7 @@
CONFIG_ION_MSM=y
CONFIG_GSI=y
CONFIG_IPA3=y
+CONFIG_IPA_WDI_UNIFIED_API=y
CONFIG_RMNET_IPA3=y
CONFIG_ECM_IPA=y
CONFIG_RNDIS_IPA=y
@@ -371,6 +373,7 @@
CONFIG_MSM_PIL_SSR_GENERIC=y
CONFIG_QCOM_COMMAND_DB=y
CONFIG_MSM_PM=y
+CONFIG_QCOM_DCC_V2=y
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index cc75e7f..a92f511 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -165,6 +165,15 @@
This enables support for the MSM8937 chipset. If you do not
wish to build a kernel that runs on this chipset, say 'N' here.
+config ARCH_MSM8917
+ bool "Enable Support for Qualcomm Technologies Inc. MSM8917"
+ depends on ARCH_QCOM
+ select CPU_FREQ_QCOM
+ select COMMON_CLK_MSM
+ help
+ This enables support for the MSM8917 chipset. If you do not
+ wish to build a kernel that runs on this chipset, say 'N' here.
+
config ARCH_SDM450
bool "Enable Support for Qualcomm Technologies Inc. SDM450"
depends on ARCH_QCOM
diff --git a/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi b/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi
index 211e28c..c9996f8 100644
--- a/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi
@@ -326,6 +326,10 @@
};
};
+ qcom,power-on@800 {
+ qcom,use-legacy-hard-reset-offset;
+ };
+
pm660_rradc: rradc@4500 {
compatible = "qcom,rradc";
reg = <0x4500 0x100>;
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 8675d09..fb167a6 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -143,7 +143,27 @@
qcs605-mtp-overlay.dtbo \
qcs605-360camera-overlay.dtbo \
qcs605-external-codec-mtp-overlay.dtbo \
- qcs605-lc-mtp-overlay.dtbo
+ qcs605-lc-mtp-overlay.dtbo \
+ sdm710-cdp-overlay.dtbo \
+ sdm710-mtp-overlay.dtbo \
+ sdm710-qrd-overlay.dtbo \
+ sdm710-qrd-sku2-overlay.dtbo \
+ sdm710-pm660a-cdp-overlay.dtbo \
+ sdm710-pm660a-mtp-overlay.dtbo \
+ sdm710-external-codec-cdp-overlay.dtbo \
+ sdm710-external-codec-mtp-overlay.dtbo \
+ sdm710-external-codec-pm660a-cdp-overlay.dtbo \
+ sdm710-external-codec-pm660a-mtp-overlay.dtbo \
+ sdm710-usbc-cdp-overlay.dtbo \
+ sdm710-usbc-mtp-overlay.dtbo \
+ sdm710-usbc-pm660a-cdp-overlay.dtbo \
+ sdm710-usbc-pm660a-mtp-overlay.dtbo \
+ sdm710-usbc-external-codec-cdp-overlay.dtbo \
+ sdm710-usbc-external-codec-mtp-overlay.dtbo \
+ sdm710-usbc-external-codec-pm660a-cdp-overlay.dtbo \
+ sdm710-usbc-external-codec-pm660a-mtp-overlay.dtbo \
+ sdm710-tasha-codec-cdp-overlay.dtbo \
+ sdm710-pm660a-tasha-codec-cdp-overlay.dtbo
sdm670-cdp-overlay.dtbo-base := sdm670.dtb
sdm670-mtp-overlay.dtbo-base := sdm670.dtb
@@ -175,6 +195,26 @@
qcs605-external-codec-mtp-overlay.dtbo-base := qcs605.dtb
qcs605-lc-mtp-overlay.dtbo-base := qcs605-lc.dtb
qcs605-360camera-overlay.dtbo-base := qcs605.dtb
+sdm710-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-qrd-overlay.dtbo-base := sdm710.dtb
+sdm710-qrd-sku2-overlay.dtbo-base := sdm710.dtb
+sdm710-pm660a-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-pm660a-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-external-codec-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-external-codec-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-external-codec-pm660a-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-external-codec-pm660a-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-pm660a-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-pm660a-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-external-codec-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-external-codec-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-external-codec-pm660a-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-external-codec-pm660a-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-tasha-codec-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-pm660a-tasha-codec-cdp-overlay.dtbo-base := sdm710.dtb
else
dtb-$(CONFIG_ARCH_SDM670) += sdm670-rumi.dtb \
@@ -206,7 +246,27 @@
qcs605-mtp.dtb \
qcs605-cdp.dtb \
qcs605-external-codec-mtp.dtb \
- qcs605-lc-mtp.dtb
+ qcs605-lc-mtp.dtb \
+ sdm710-mtp.dtb \
+ sdm710-cdp.dtb \
+ sdm710-qrd.dtb \
+ sdm710-qrd-sku2.dtb \
+ sdm710-pm660a-mtp.dtb \
+ sdm710-pm660a-cdp.dtb \
+ sdm710-external-codec-cdp.dtb \
+ sdm710-external-codec-mtp.dtb \
+ sdm710-external-codec-pm660a-cdp.dtb \
+ sdm710-external-codec-pm660a-mtp.dtb \
+ sdm710-usbc-cdp.dtb \
+ sdm710-usbc-external-codec-cdp.dtb \
+ sdm710-usbc-external-codec-mtp.dtb \
+ sdm710-usbc-external-codec-pm660a-cdp.dtb \
+ sdm710-usbc-external-codec-pm660a-mtp.dtb \
+ sdm710-usbc-mtp.dtb \
+ sdm710-usbc-pm660a-cdp.dtb \
+ sdm710-usbc-pm660a-mtp.dtb \
+ sdm710-tasha-codec-cdp.dtb \
+ sdm710-pm660a-tasha-codec-cdp.dtb
endif
ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y)
@@ -306,7 +366,9 @@
dtb-$(CONFIG_ARCH_MSM8917) += msm8917-pmi8950-mtp.dtb
-dtb-$(CONFIG_ARCH_MSM8909) += msm8909w-bg-wtp-v2.dtb
+dtb-$(CONFIG_ARCH_MSM8909) += msm8909w-bg-wtp-v2.dtb \
+ apq8009w-bg-wtp-v2.dtb \
+ apq8009w-bg-alpha.dtb
dtb-$(CONFIG_ARCH_SDM450) += sdm450-rcm.dtb \
sdm450-cdp.dtb \
diff --git a/arch/arm64/boot/dts/qcom/apq8009w-bg-alpha.dts b/arch/arm64/boot/dts/qcom/apq8009w-bg-alpha.dts
new file mode 100644
index 0000000..57a28d0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8009w-bg-alpha.dts
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "msm8909-mtp.dtsi"
+#include "msm8909w.dtsi"
+#include "8909w-pm660.dtsi"
+#include "apq8009w-bg-memory.dtsi"
+#include "msm8909-audio-bg_codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. APQ8009W-PM660 BG Alpha";
+ compatible = "qcom,apq8009-mtp", "qcom,apq8009", "qcom,mtp";
+ qcom,msm-id = <265 0>,
+ <301 0>;
+ qcom,board-id = <8 0x113>;
+ qcom,pmic-id = <0x0001001b 0x0 0x0 0x0>,
+ <0x0001011b 0x0 0x0 0x0>;
+};
+
+&soc {
+ i2c@78b9000 { /* BLSP1 QUP5 */
+ focaltech@38 {
+ compatible = "focaltech,fts";
+ reg = <0x38>;
+ interrupt-parent = <&msm_gpio>;
+ interrupts = <98 0x2008>;
+ vdd-supply = <&pm660_l18>;
+ vcc-i2c-supply = <&pm660_l13>;
+ focaltech,irq-gpio = <&msm_gpio 98 0x2008>;
+ focaltech,reset-gpio = <&msm_gpio 16 0x00>;/**/
+ focaltech,max-touch-number = <5>;
+ focaltech,display-coords = <0 0 390 390>;/**/
+ focaltech,wakeup-gestures-en;
+ };
+
+ /delete-node/ it7260@46;
+ /delete-node/ synaptics@20;
+ };
+
+ qcom,blackghost {
+ compatible = "qcom,pil-blackghost";
+
+ qcom,firmware-name = "bg-wear";
+ /* GPIO inputs from blackghost */
+ qcom,bg2ap-status-gpio = <&msm_gpio 97 0>;
+ qcom,bg2ap-errfatal-gpio = <&msm_gpio 95 0>;
+ /* GPIO output to blackghost */
+ qcom,ap2bg-status-gpio = <&msm_gpio 17 0>;
+ qcom,ap2bg-errfatal-gpio = <&msm_gpio 23 0>;
+ };
+
+ qcom,msm-ssc-sensors {
+ compatible = "qcom,msm-ssc-sensors";
+ };
+
+ qcom,glink-bgcom-xprt-bg {
+ compatible = "qcom,glink-bgcom-xprt";
+ label = "bg";
+ qcom,qos-config = <&glink_qos_bg>;
+ qcom,ramp-time = <0x10>,
+ <0x20>,
+ <0x30>,
+ <0x40>;
+ };
+
+ glink_qos_bg: qcom,glink-qos-config-bg {
+ compatible = "qcom,glink-qos-config";
+ qcom,flow-info = <0x80 0x0>,
+ <0x70 0x1>,
+ <0x60 0x2>,
+ <0x50 0x3>;
+ qcom,mtu-size = <0x800>;
+ qcom,tput-stats-cycle = <0xa>;
+ };
+
+ qcom,glink_pkt {
+ compatible = "qcom,glinkpkt";
+
+ qcom,glinkpkt-bg-daemon {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "bg-daemon";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon";
+ };
+
+ qcom,glinkpkt-bg-display-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "display-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_display_ctrl";
+ };
+
+ qcom,glinkpkt-bg-display-data {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "display-data";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_display_data";
+ };
+
+ qcom,glinkpkt-bg-rsb-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "RSB_CTRL";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
+ };
+ };
+
+ spi@78B8000 { /* BLSP1 QUP4 */
+ status = "ok";
+ qcom,bg-spi {
+ compatible = "qcom,bg-spi";
+ reg = <0>;
+ spi-max-frequency = <16000000>;
+ interrupt-parent = <&msm_gpio>;
+ qcom,irq-gpio = <&msm_gpio 110 1>;
+ };
+ };
+
+ qcom,bg-rsb {
+ compatible = "qcom,bg-rsb";
+ vdd-ldo1-supply = <&pm660_l11>;
+ vdd-ldo2-supply = <&pm660_l15>;
+ };
+
+ qcom,bg-daemon {
+ compatible = "qcom,bg-daemon";
+ qcom,bg-reset-gpio = <&pm660_gpios 5 0>;
+ ssr-reg1-supply = <&pm660_l3>;
+ ssr-reg2-supply = <&pm660_l9>;
+ };
+};
+
+&i2c_1 {
+ status = "okay";
+ nq@28 {
+ compatible = "qcom,nq-nci";
+ reg = <0x28>;
+ qcom,nq-irq = <&msm_gpio 50 0x00>;
+ qcom,nq-ven = <&msm_gpio 36 0x00>;
+ qcom,nq-firm = <&msm_gpio 38 0x00>;
+ qcom,nq-esepwr = <&msm_gpio 49 0x00>;
+ qcom,nq-clkreq = <&pm660_gpios 4 0x00>;
+ qcom,clk-src = "BBCLK3";
+ interrupt-parent = <&msm_gpio>;
+ interrupts = <50 0>;
+ interrupt-names = "nfc_irq";
+ pinctrl-names = "nfc_active","nfc_suspend";
+ pinctrl-0 = <&nfcw_int_active &nfcw_disable_active>;
+ pinctrl-1 = <&nfcw_int_suspend &nfcw_disable_suspend>;
+ clock-names = "ref_clk";
+ };
+};
+
+&spi_0 {
+ status = "disabled";
+};
+
+&i2c_3 {
+ status = "disabled";
+};
+
+&i2c_4 {
+ status = "disabled";
+};
+
+&i2c_2 {
+ status = "disabled";
+};
+
+&sdc1_clk_off {
+ config {
+ pins = "sdc1_clk";
+ bias-disable; /* NO pull */
+ drive-strength = <2>; /* 2 MA */
+ output-low;
+ };
+};
+
+&sdc1_cmd_off {
+ config {
+ pins = "sdc1_cmd";
+ bias-disable; /* NO pull */
+ drive-strength = <2>; /* 2 MA */
+ output-low;
+ };
+};
+
+&sdc1_data_off {
+ config {
+ pins = "sdc1_data";
+ bias-disable; /* NO pull */
+ drive-strength = <2>; /* 2 MA */
+ output-low;
+ };
+};
+
+&sdhc_2 {
+ status = "disabled";
+};
+
+&audio_codec_mtp {
+ status = "disabled";
+};
+
+&audio_codec_bg {
+ status = "ok";
+};
+
+&bg_cdc {
+ status = "ok";
+ vdd-spkr-supply = <&pm660_l11>;
+};
+
+&blsp1_uart1 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_sleep>;
+};
+
+/* Pinctrl dt nodes for interrupt and reset gpio for Synaptics controller */
+&ts_int_active {
+ mux {
+ pins = "gpio98";
+ };
+
+ config {
+ pins = "gpio98";
+ };
+};
+
+&ts_int_suspend {
+ mux {
+ pins = "gpio98";
+ };
+
+ config {
+ pins = "gpio98";
+ };
+};
+
+&ts_reset_active {
+ mux {
+ pins = "gpio16";
+ };
+
+ config {
+ pins = "gpio16";
+ };
+};
+
+&ts_reset_suspend {
+ mux {
+ pins = "gpio16";
+ };
+
+ config {
+ pins = "gpio16";
+ };
+};
+
+&ts_release {
+ mux {
+ pins = "gpio98", "gpio16";
+ };
+
+ config {
+ pins = "gpio98", "gpio16";
+ };
+};
+
+&pm660_charger {
+ qcom,micro-usb;
+};
+
+&spi4_cs0_active {
+ mux {
+ pins = "gpio14";
+ function = "blsp_spi4";
+ };
+ config {
+ pins = "gpio14";
+ drive-strength = <2>;
+ bias-disable; /* No PULL */
+ output-high;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8009w-bg-memory.dtsi b/arch/arm64/boot/dts/qcom/apq8009w-bg-memory.dtsi
new file mode 100644
index 0000000..d41a792
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8009w-bg-memory.dtsi
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&external_image_mem {
+ reg = <0x0 0x87b00000 0x0 0x0500000>;
+};
+
+&modem_adsp_mem {
+ reg = <0x0 0x88000000 0x0 0x02300000>;
+};
+
+&peripheral_mem {
+ reg = <0x0 0x8a300000 0x0 0x0600000>;
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8009w-bg-wtp-v2.dts b/arch/arm64/boot/dts/qcom/apq8009w-bg-wtp-v2.dts
new file mode 100644
index 0000000..454ba81
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8009w-bg-wtp-v2.dts
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "msm8909-mtp.dtsi"
+#include "msm8909w.dtsi"
+#include "8909w-pm660.dtsi"
+#include "apq8009w-bg-memory.dtsi"
+#include "msm8909-audio-bg_codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. APQ8009W-PM660 BLACKGHOST WTP";
+ compatible = "qcom,apq8009-mtp", "qcom,apq8009", "qcom,mtp";
+ qcom,msm-id = <265 0>,
+ <301 0>;
+ qcom,board-id = <8 0x10f>;
+ qcom,pmic-id = <0x0001001b 0x0 0x0 0x0>,
+ <0x0001011b 0x0 0x0 0x0>;
+};
+
+&soc {
+ i2c@78b9000 { /* BLSP1 QUP5 */
+ synaptics@20 {
+ compatible = "synaptics,dsx-i2c";
+ reg = <0x20>;
+ interrupt-parent = <&msm_gpio>;
+ interrupts = <98 0x2008>;
+ vdd_ana-supply = <&pm660_l18>;
+ vcc_i2c-supply = <&pm660_l13>;
+ synaptics,pwr-reg-name = "vdd_ana";
+ synaptics,bus-reg-name = "vcc_i2c";
+ pinctrl-names = "pmx_ts_active", "pmx_ts_suspend",
+ "pmx_ts_release";
+ pinctrl-0 = <&ts_int_active &ts_reset_active>;
+ pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
+ pinctrl-2 = <&ts_release>;
+ synaptics,irq-gpio = <&msm_gpio 98 0x2008>;
+ synaptics,irq-on-state = <0>;
+ synaptics,irq-flags = <0x2008>;
+ synaptics,power-delay-ms = <200>;
+ synaptics,reset-delay-ms = <200>;
+ synaptics,max-y-for-2d = <389>;
+ synaptics,bus-lpm-cur-uA = <450>;
+ synaptics,do-not-disable-regulators;
+ synaptics,wakeup-gestures-en;
+ synaptics,resume-in-workqueue;
+ synaptics,x-flip;
+ synaptics,y-flip;
+ /delete-property/ synaptics,reset-gpio;
+ /delete-property/ synaptics,display-coords;
+ /delete-property/ synaptics,panel-coords;
+ /delete-property/ synaptics,power-down;
+ /delete-property/ synaptics,disable-gpios;
+ /delete-property/ synaptics,is_wake;
+ };
+
+ /delete-node/ it7260@46;
+ };
+
+ qcom,blackghost {
+ compatible = "qcom,pil-blackghost";
+
+ qcom,firmware-name = "bg-wear";
+ /* GPIO inputs from blackghost */
+ qcom,bg2ap-status-gpio = <&msm_gpio 97 0>;
+ qcom,bg2ap-errfatal-gpio = <&msm_gpio 95 0>;
+ /* GPIO output to blackghost */
+ qcom,ap2bg-status-gpio = <&msm_gpio 17 0>;
+ qcom,ap2bg-errfatal-gpio = <&msm_gpio 23 0>;
+ };
+
+ qcom,msm-ssc-sensors {
+ compatible = "qcom,msm-ssc-sensors";
+ };
+
+ qcom,glink-bgcom-xprt-bg {
+ compatible = "qcom,glink-bgcom-xprt";
+ label = "bg";
+ qcom,qos-config = <&glink_qos_bg>;
+ qcom,ramp-time = <0x10>,
+ <0x20>,
+ <0x30>,
+ <0x40>;
+ };
+
+ glink_qos_bg: qcom,glink-qos-config-bg {
+ compatible = "qcom,glink-qos-config";
+ qcom,flow-info = <0x80 0x0>,
+ <0x70 0x1>,
+ <0x60 0x2>,
+ <0x50 0x3>;
+ qcom,mtu-size = <0x800>;
+ qcom,tput-stats-cycle = <0xa>;
+ };
+
+ qcom,glink_pkt {
+ compatible = "qcom,glinkpkt";
+
+ qcom,glinkpkt-bg-daemon {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "bg-daemon";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon";
+ };
+
+ qcom,glinkpkt-bg-display-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "display-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_display_ctrl";
+ };
+
+ qcom,glinkpkt-bg-display-data {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "display-data";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_display_data";
+ };
+
+ qcom,glinkpkt-bg-rsb-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "RSB_CTRL";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
+ };
+ };
+
+ spi@78B8000 { /* BLSP1 QUP4 */
+ status = "ok";
+ qcom,bg-spi {
+ compatible = "qcom,bg-spi";
+ reg = <0>;
+ spi-max-frequency = <16000000>;
+ interrupt-parent = <&msm_gpio>;
+ qcom,irq-gpio = <&msm_gpio 110 1>;
+ };
+ };
+
+ qcom,bg-rsb {
+ compatible = "qcom,bg-rsb";
+ vdd-ldo1-supply = <&pm660_l11>;
+ vdd-ldo2-supply = <&pm660_l15>;
+ };
+
+ qcom,bg-daemon {
+ compatible = "qcom,bg-daemon";
+ qcom,bg-reset-gpio = <&pm660_gpios 5 0>;
+ ssr-reg1-supply = <&pm660_l3>;
+ ssr-reg2-supply = <&pm660_l9>;
+ };
+};
+
+&i2c_1 {
+ status = "okay";
+ nq@28 {
+ compatible = "qcom,nq-nci";
+ reg = <0x28>;
+ qcom,nq-irq = <&msm_gpio 50 0x00>;
+ qcom,nq-ven = <&msm_gpio 36 0x00>;
+ qcom,nq-firm = <&msm_gpio 38 0x00>;
+ qcom,nq-esepwr = <&msm_gpio 49 0x00>;
+ qcom,nq-clkreq = <&pm660_gpios 4 0x00>;
+ qcom,clk-src = "BBCLK3";
+ interrupt-parent = <&msm_gpio>;
+ interrupts = <50 0>;
+ interrupt-names = "nfc_irq";
+ pinctrl-names = "nfc_active","nfc_suspend";
+ pinctrl-0 = <&nfcw_int_active &nfcw_disable_active>;
+ pinctrl-1 = <&nfcw_int_suspend &nfcw_disable_suspend>;
+ clock-names = "ref_clk";
+ };
+};
+
+&spi_0 {
+ status = "disabled";
+};
+
+&i2c_3 {
+ status = "disabled";
+};
+
+&i2c_4 {
+ status = "disabled";
+};
+
+&i2c_2 {
+ status = "disabled";
+};
+
+&sdc1_clk_off {
+ config {
+ pins = "sdc1_clk";
+ bias-disable; /* NO pull */
+ drive-strength = <2>; /* 2 MA */
+ output-low;
+ };
+};
+
+&sdc1_cmd_off {
+ config {
+ pins = "sdc1_cmd";
+ bias-disable; /* NO pull */
+ drive-strength = <2>; /* 2 MA */
+ output-low;
+ };
+};
+
+&sdc1_data_off {
+ config {
+ pins = "sdc1_data";
+ bias-disable; /* NO pull */
+ drive-strength = <2>; /* 2 MA */
+ output-low;
+ };
+};
+
+&sdhc_2 {
+ status = "disabled";
+};
+
+&audio_codec_mtp {
+ status = "disabled";
+};
+
+&audio_codec_bg {
+ status = "ok";
+};
+
+&bg_cdc {
+ status = "ok";
+ vdd-spkr-supply = <&pm660_l11>;
+};
+
+&blsp1_uart1 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_sleep>;
+};
+
+/* Pinctrl dt nodes for interrupt and reset gpio for Synaptics controller */
+&ts_int_active {
+ mux {
+ pins = "gpio98";
+ };
+
+ config {
+ pins = "gpio98";
+ };
+};
+
+&ts_int_suspend {
+ mux {
+ pins = "gpio98";
+ };
+
+ config {
+ pins = "gpio98";
+ /delete-property/ bias-pull-down;
+ bias-disable; /* No PULL */
+ };
+};
+
+&ts_reset_active {
+ mux {
+ pins = "gpio16";
+ };
+
+ config {
+ pins = "gpio16";
+ };
+};
+
+&ts_reset_suspend {
+ mux {
+ pins = "gpio16";
+ };
+
+ config {
+ pins = "gpio16";
+ };
+};
+
+&ts_release {
+ mux {
+ pins = "gpio98", "gpio16";
+ };
+
+ config {
+ pins = "gpio98", "gpio16";
+ };
+};
+
+&spi4_cs0_active {
+ mux {
+ pins = "gpio14";
+ function = "blsp_spi4";
+ };
+ config {
+ pins = "gpio14";
+ drive-strength = <2>;
+ bias-disable; /* No PULL */
+ output-high;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
index 76b1fa2..f2d4ef3 100644
--- a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
@@ -344,47 +344,54 @@
};
&pmi8950_gpios {
- gpio@c000 { /* GPIO_1 */
- status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmi_gpio1_default>;
+ pmi_gpio1_default: pmi8950_gpio1 {
+ pins = "gpio1";
+ function = "normal";
+ input-enable;
+ power-source = <0>;
+ status = "okay";
};
};
&pmi8950_mpps {
- mpp@a200 { /* MPP_3 */
- qcom,mode = <1>; /* Digital output */
- qcom,output-type = <0>; /* CMOS logic */
- qcom,vin-sel = <2>; /* 1.8V */
- qcom,src-sel = <0>; /* Constant */
- qcom,master-en = <1>; /* Enable GPIO */
- qcom,invert = <0>;
- status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ext_fet_wled_pwr_en_default>;
+ ext_fet_wled_pwr_en_default: pmi8950_mpp3 {
+ pins = "mpp3"; /* MPP_3 */
+ function = "digital"; /* Digital */
+ output-high; /* Output */
+ drive-strength = <2>; /* 1.8 mA */
+ power-source = <1>;
+ bias-disable = <0>; /* no pull */
+ status = "okay";
};
};
&pm8953_gpios {
- gpio@c000 { /* GPIO_1 */
- status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pm_gpio1_div_clk2_default>;
+ pm_gpio1_div_clk2_default: pm8953_gpio1 {
+ pins = "gpio1";
+ function = "normal";
+ output-high;
+ power-source = <1>;
+ status = "okay";
};
};
&pm8953_mpps {
- mpp@a000 { /* MPP_1 */ /* VDD_PX */
- status = "disabled";
- };
- mpp@a100 { /* MPP_2 */
- status = "disabled";
- };
- mpp@a200 { /* MPP_3 */
- status = "disabled";
- };
-
- mpp@a300 { /* MPP_4 */ /* WLED_PWM_CTRL */
- qcom,mode = <1>; /* Digital output */
- qcom,output-type = <0>; /* CMOS logic */
- qcom,vin-sel = <0>; /* VPH_PWR */
- qcom,src-sel = <4>; /* DTEST1 */
- qcom,master-en = <1>; /* Enable GPIO */
- qcom,invert = <0>;
- status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pm_mpp4_wled_pwm_ctrl_default>;
+ pm_mpp4_wled_pwm_ctrl_default: pm8953_mpp4 {
+ pins = "mpp4"; /* WLED_PWM_CTRL */
+ function = "digital"; /* Digital */
+ output-high; /* Output */
+ drive-strength = <2>; /* 1.8 mA */
+ power-source = <0>; /* VPH_PWR */
+ qcom,dtest = <1>; /* DTEST1 */
+ bias-disable = <0>; /* no pull */
+ status = "okay";
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-8909.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-8909.dtsi
new file mode 100644
index 0000000..a601b5f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-8909.dtsi
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <dt-bindings/clock/msm-clocks-8909.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+&soc {
+
+ apps_iommu: qcom,iommu@1e00000 {
+ compatible = "qcom,qsmmu-v500";
+ reg = <0x1e00000 0x40000>,
+ <0x1ef2000 0x20>;
+ reg-names = "base", "tcu-base";
+ #iommu-cells = <2>;
+ qcom,tz-device-id = "APPS";
+ qcom,skip-init;
+ qcom,enable-static-cb;
+ qcom,use-3-lvl-tables;
+ qcom,disable-atos;
+ #global-interrupts = <0>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+ ranges;
+ interrupts =
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks =
+ <&clock_gcc clk_gcc_smmu_cfg_clk>,
+ <&clock_gcc clk_gcc_apss_tcu_clk>;
+ clock-names = "iface_clk", "core_clk";
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8909.dtsi b/arch/arm64/boot/dts/qcom/msm8909.dtsi
index 7b38370..5e56c49 100644
--- a/arch/arm64/boot/dts/qcom/msm8909.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909.dtsi
@@ -334,7 +334,7 @@
compatible = "qcom,gcc-mdss-8909";
clocks = <&mdss_dsi0_pll clk_dsi_pll0_pixel_clk_src>,
<&mdss_dsi0_pll clk_dsi_pll0_byte_clk_src>;
- clock-names = "pixel_src", "byte_src";
+ clock-names = "pclk0_src", "byte0_src";
#clock-cells = <1>;
};
@@ -1363,6 +1363,7 @@
qcom,scm_core_clk_src-freq = <80000000>;
qcom,pas-id = <9>;
+ qcom,mas-crypto = <&mas_crypto>;
qcom,proxy-timeout-ms = <100>;
qcom,firmware-name = "venus";
memory-region = <&venus_qseecom_mem>;
@@ -1792,6 +1793,7 @@
qcom,sysmon-id = <6>;
qcom,ssctl-instance-id = <0x13>;
qcom,firmware-name = "wcnss";
+ qcom,mas-crypto = <&mas_crypto>;
/* GPIO inputs from wcnss */
qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_4_in 0 0>;
@@ -1835,6 +1837,7 @@
qcom,pil-self-auth;
qcom,sysmon-id = <0>;
qcom,ssctl-instance-id = <0x12>;
+ qcom,reset-clk;
/* GPIO inputs from mss */
qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
diff --git a/arch/arm64/boot/dts/qcom/msm8909w-bg-wtp-v2.dts b/arch/arm64/boot/dts/qcom/msm8909w-bg-wtp-v2.dts
index 8bcbe68..24266e8 100644
--- a/arch/arm64/boot/dts/qcom/msm8909w-bg-wtp-v2.dts
+++ b/arch/arm64/boot/dts/qcom/msm8909w-bg-wtp-v2.dts
@@ -18,6 +18,7 @@
#include "msm8909w-bg-memory.dtsi"
#include "8909w-pm660.dtsi"
#include "msm8909-audio-bg_codec.dtsi"
+#include "msm-arm-smmu-8909.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM8909W-PM660 BLACKGHOST WTP";
diff --git a/arch/arm64/boot/dts/qcom/msm8917-gpu.dtsi b/arch/arm64/boot/dts/qcom/msm8917-gpu.dtsi
new file mode 100644
index 0000000..3b12ba4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8917-gpu.dtsi
@@ -0,0 +1,184 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&soc {
+ msm_bus: qcom,kgsl-busmon {
+ label = "kgsl-busmon";
+ compatible = "qcom,kgsl-busmon";
+ };
+
+ /* Bus governor */
+ gpubw: qcom,gpubw {
+ compatible = "qcom,devbw";
+ governor = "bw_vbif";
+ qcom,src-dst-ports = <26 512>;
+ /*
+ * Need to configure 2x Clock as BIMC
+ * Internally Divides by 2 for Gen1 DDR PHY.
+ */
+ qcom,active-only;
+ qcom,bw-tbl =
+ < 0 >, /* Off */
+ < 769 >, /* 1. DDR:100.80 MHz BIMC: 201.60 MHz */
+ < 1611 >, /* 2. DDR:211.20 MHz BIMC: 422.40 MHz */
+ < 2270 >, /* 3. DDR:297.60 MHz BIMC: 595.20 MHz */
+ < 2929 >, /* 4. DDR:384.00 MHz BIMC: 768.00 MHz */
+ < 4248 >, /* 5. DDR:556.80 MHz BIMC: 1113.60 MHz */
+ < 4541 >, /* 6. DDR:595.20 MHz BIMC: 1190.40 MHz */
+ < 5126 >, /* 7. DDR:672.00 MHz BIMC: 1344.00 MHz */
+ < 5639 >; /* 8. DDR:739.20 MHz BIMC: 1478.40 MHz */
+ };
+
+ msm_gpu: qcom,kgsl-3d0@1c00000 {
+ label = "kgsl-3d0";
+ compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d";
+ reg = <0x1c00000 0x10000
+ 0x1c10000 0x10000
+ 0x00a0000 0x06fff>;
+ reg-names = "kgsl_3d0_reg_memory" , "kgsl_3d0_shader_memory",
+ "qfprom_memory";
+ interrupts = <0 33 0>;
+ interrupt-names = "kgsl_3d0_irq";
+ qcom,id = <0>;
+
+ qcom,chipid = <0x03000620>;
+
+ qcom,initial-pwrlevel = <3>;
+
+ qcom,idle-timeout = <80>; //msecs
+ qcom,strtstp-sleepwake;
+ qcom,gpu-bimc-interface-clk-freq = <400000000>; //In Hz
+
+ clocks = <&clock_gcc clk_gcc_oxili_gfx3d_clk>,
+ <&clock_gcc clk_gcc_oxili_ahb_clk>,
+ <&clock_gcc clk_gcc_bimc_gfx_clk>,
+ <&clock_gcc clk_gcc_bimc_gpu_clk>,
+ <&clock_gcc clk_gcc_gtcu_ahb_clk>,
+ <&clock_gcc clk_gcc_gfx_tcu_clk>,
+ <&clock_gcc clk_gcc_gfx_tbu_clk>,
+ <&clock_gcc clk_bimc_gpu_clk>;
+
+ clock-names = "core_clk", "iface_clk", "mem_iface_clk",
+ "alt_mem_iface_clk", "gtcu_iface_clk",
+ "gtcu_clk", "gtbu_clk", "bimc_gpu_clk";
+
+ /* Bus Scale Settings */
+ qcom,gpubw-dev = <&gpubw>;
+ qcom,bus-control;
+ qcom,bus-width = <16>;
+ qcom,msm-bus,name = "grp3d";
+ qcom,msm-bus,num-cases = <9>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <26 512 0 0>, /* off */
+ <26 512 0 806400>, /* 1. 100.80 MHz */
+ <26 512 0 1689600>, /* 2. 211.20 MHz */
+ <26 512 0 2380800>, /* 3. 297.60 MHz */
+ <26 512 0 3072000>, /* 4. 384.00 MHz */
+ <26 512 0 4454400>, /* 5. 556.80 MHz */
+ <26 512 0 4761600>, /* 6. 595.20 MHz */
+ <26 512 0 5376000>, /* 7. 672.00 MHz */
+ <26 512 0 5913600>; /* 8. 739.20 MHz */
+
+ /* GDSC regulator names */
+ regulator-names = "vdd";
+ /* GDSC oxili regulators */
+ vdd-supply = <&gdsc_oxili_gx>;
+
+ /* CPU latency parameter */
+ qcom,pm-qos-active-latency = <651>;
+
+ /* Power levels */
+ qcom,gpu-pwrlevels {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,gpu-pwrlevels";
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <598000000>;
+ qcom,bus-freq = <7>;
+ qcom,bus-min = <7>;
+ qcom,bus-max = <7>;
+ };
+
+ /* NOM+ */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <523200000>;
+ qcom,bus-freq = <6>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <7>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <484800000>;
+ qcom,bus-freq = <5>;
+ qcom,bus-min = <4>;
+ qcom,bus-max = <6>;
+ };
+
+ /* SVS+ */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <400000000>;
+ qcom,bus-freq = <4>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <5>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <270000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <1>;
+ qcom,bus-max = <3>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+};
+
+ kgsl_msm_iommu: qcom,kgsl-iommu@1f00000 {
+ compatible = "qcom,kgsl-smmu-v2";
+ reg = <0x1f00000 0x10000>;
+ /*
+ * The gpu can only program a single context bank
+ * at this fixed offset.
+ */
+ qcom,protect = <0xa000 0x1000>;
+ clocks = <&clock_gcc clk_gcc_smmu_cfg_clk>,
+ <&clock_gcc clk_gcc_gfx_tcu_clk>,
+ <&clock_gcc clk_gcc_gtcu_ahb_clk>,
+ <&clock_gcc clk_gcc_gfx_tbu_clk>;
+ clock-names = "scfg_clk", "gtcu_clk", "gtcu_iface_clk",
+ "gtbu_clk";
+ qcom,retention;
+ gfx3d_user: gfx3d_user {
+ compatible = "qcom,smmu-kgsl-cb";
+ iommus = <&gfx_iommu 0>;
+ qcom,gpu-offset = <0xa000>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8917.dtsi b/arch/arm64/boot/dts/qcom/msm8917.dtsi
index a85d6d2..a315ade 100644
--- a/arch/arm64/boot/dts/qcom/msm8917.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917.dtsi
@@ -165,6 +165,7 @@
#include "msm8917-mdss.dtsi"
#include "msm8917-mdss-pll.dtsi"
#include "msm-arm-smmu-8917.dtsi"
+#include "msm8917-gpu.dtsi"
&soc {
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/msm8937-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8937-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..d134dd1
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8937-camera-sensor-mtp.dtsi
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2015-2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&cci {
+ actuator0: qcom,actuator@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8937_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ actuator1: qcom,actuator@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8937_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ eeprom0: qcom,eeprom@0 {
+ cell-index = <0>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <0>;
+ reg = <0x0>;
+ cam_vana-supply = <&pm8937_l22>;
+ cam_vio-supply = <&pm8937_l6>;
+ cam_vaf-supply = <&pm8937_l17>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_reset
+ &cam_sensor_rear_standby
+ &cam_sensor_rear_vdig>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep
+ &cam_sensor_rear_reset_sleep
+ &cam_sensor_rear_standby_sleep
+ &cam_sensor_rear_vdig_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 36 0>,
+ <&tlmm 35 0>,
+ <&tlmm 62 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vdig = <3>;
+ qcom,gpio-req-tbl-num = <0 1 2 3>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VDIG";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom1: qcom,eeprom@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ qcom,eeprom-name = "sunny_8865";
+ compatible = "qcom,eeprom";
+ qcom,slave-addr = <0x6c>;
+ qcom,cci-master = <0>;
+ qcom,num-blocks = <8>;
+
+ qcom,page0 = <1 0x0100 2 0x01 1 1>;
+ qcom,poll0 = <0 0x0 2 0x0 1 0>;
+ qcom,mem0 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page1 = <1 0x5002 2 0x00 1 0>;
+ qcom,poll1 = <0 0x0 2 0x0 1 0>;
+ qcom,mem1 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
+ qcom,poll2 = <0 0x0 2 0x0 1 0>;
+ qcom,mem2 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page3 = <1 0x3d88 2 0x70 1 0>;
+ qcom,poll3 = <0 0x0 2 0x0 1 0>;
+ qcom,mem3 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page4 = <1 0x3d89 2 0x10 1 0>;
+ qcom,poll4 = <0 0x0 2 0x0 1 0>;
+ qcom,mem4 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
+ qcom,poll5 = <0 0x0 2 0x0 1 0>;
+ qcom,mem5 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
+ qcom,poll6 = <0 0x0 2 0x0 1 0>;
+ qcom,mem6 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page7 = <1 0x3d81 2 0x01 1 10>;
+ qcom,poll7 = <0 0x0 2 0x0 1 1>;
+ qcom,mem7 = <1536 0x7010 2 0 1 0>;
+
+ cam_vdig-supply = <&pm8937_l23>;
+ cam_vana-supply = <&pm8937_l22>;
+ cam_vio-supply = <&pm8937_l6>;
+ cam_vaf-supply = <&pm8937_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
+ "sensor_vreg",
+ "sensor_gpio", "sensor_gpio" , "sensor_clk";
+ qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
+ "sensor_gpio_reset", "sensor_gpio_standby",
+ "sensor_cam_mclk";
+ qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
+ qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <270>;
+ qcom,led-flash-src = <&led_flash0>;
+ qcom,eeprom-src = <&eeprom0>;
+ qcom,actuator-src = <&actuator0>;
+ cam_vana-supply = <&pm8937_l22>;
+ cam_vio-supply = <&pm8937_l6>;
+ cam_vaf-supply = <&pm8937_l17>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_reset
+ &cam_sensor_rear_standby
+ &cam_sensor_rear_vdig>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep
+ &cam_sensor_rear_reset_sleep
+ &cam_sensor_rear_standby_sleep
+ &cam_sensor_rear_vdig_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 36 0>,
+ <&tlmm 35 0>,
+ <&tlmm 62 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vdig = <3>;
+ qcom,gpio-req-tbl-num = <0 1 2 3>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VDIG";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ cam_vdig-supply = <&pm8937_l23>;
+ cam_vana-supply = <&pm8937_l22>;
+ cam_vio-supply = <&pm8937_l6>;
+ cam_vaf-supply = <&pm8937_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 38 0>,
+ <&tlmm 50 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ qcom,sensor-position = <0x100>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <1>;
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@2 {
+ cell-index = <2>;
+ compatible = "qcom,camera";
+ reg = <0x02>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ qcom,eeprom-src = <&eeprom1>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vdig-supply = <&pm8937_l23>;
+ cam_vana-supply = <&pm8937_l22>;
+ cam_vio-supply = <&pm8937_l6>;
+ cam_vaf-supply = <&pm8937_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8937-camera.dtsi b/arch/arm64/boot/dts/qcom/msm8937-camera.dtsi
new file mode 100644
index 0000000..b5f467e
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8937-camera.dtsi
@@ -0,0 +1,536 @@
+/*
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&soc {
+ qcom,msm-cam@1b00000 {
+ compatible = "qcom,msm-cam";
+ reg = <0x1b00000 0x40000>;
+ reg-names = "msm-cam";
+ status = "ok";
+ bus-vectors = "suspend", "svs", "nominal", "turbo";
+ qcom,bus-votes = <0 160000000 320000000 320000000>;
+ };
+
+ qcom,csiphy@1b34000 {
+ status = "ok";
+ cell-index = <0>;
+ compatible = "qcom,csiphy-v3.4.2", "qcom,csiphy";
+ reg = <0x1b34000 0x1000>,
+ <0x1b00030 0x4>;
+ reg-names = "csiphy", "csiphy_clk_mux";
+ interrupts = <0 78 0>;
+ interrupt-names = "csiphy";
+ clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+ <&clock_gcc clk_csi0phytimer_clk_src>,
+ <&clock_gcc clk_gcc_camss_csi0phytimer_clk>,
+ <&clock_gcc clk_camss_top_ahb_clk_src>,
+ <&clock_gcc clk_gcc_camss_ahb_clk>;
+ clock-names = "camss_top_ahb_clk", "ispif_ahb_clk",
+ "csiphy_timer_src_clk", "csiphy_timer_clk",
+ "camss_ahb_src", "camss_ahb_clk";
+ qcom,clock-rates = <0 61540000 200000000 0 0 0>;
+ };
+
+ qcom,csiphy@1b35000 {
+ status = "ok";
+ cell-index = <1>;
+ compatible = "qcom,csiphy-v3.4.2", "qcom,csiphy";
+ reg = <0x1b35000 0x1000>,
+ <0x1b00038 0x4>;
+ reg-names = "csiphy", "csiphy_clk_mux";
+ interrupts = <0 79 0>;
+ interrupt-names = "csiphy";
+ clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+ <&clock_gcc clk_csi1phytimer_clk_src>,
+ <&clock_gcc clk_gcc_camss_csi1phytimer_clk>,
+ <&clock_gcc clk_camss_top_ahb_clk_src>,
+ <&clock_gcc clk_gcc_camss_ahb_clk>;
+ clock-names = "camss_top_ahb_clk", "ispif_ahb_clk",
+ "csiphy_timer_src_clk", "csiphy_timer_clk",
+ "camss_ahb_src", "camss_ahb_clk";
+ qcom,clock-rates = <0 61540000 200000000 0 0 0>;
+ };
+
+ qcom,csid@1b30000 {
+ status = "ok";
+ cell-index = <0>;
+ compatible = "qcom,csid-v3.4.2", "qcom,csid";
+ reg = <0x1b30000 0x400>;
+ reg-names = "csid";
+ interrupts = <0 51 0>;
+ interrupt-names = "csid";
+ qcom,csi-vdd-voltage = <1200000>;
+ qcom,mipi-csi-vdd-supply = <&pm8937_l2>;
+ clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_csi0_ahb_clk>,
+ <&clock_gcc clk_csi0_clk_src>,
+ <&clock_gcc clk_gcc_camss_csi0phy_clk>,
+ <&clock_gcc clk_gcc_camss_csi0_clk>,
+ <&clock_gcc clk_gcc_camss_csi0pix_clk>,
+ <&clock_gcc clk_gcc_camss_csi0rdi_clk>,
+ <&clock_gcc clk_gcc_camss_ahb_clk>;
+ clock-names = "camss_top_ahb_clk",
+ "ispif_ahb_clk", "csi_ahb_clk", "csi_src_clk",
+ "csi0_phy_clk",
+ "csi_clk", "csi_pix_clk",
+ "csi_rdi_clk", "camss_ahb_clk";
+ qcom,clock-rates = <0 61540000 0 200000000 0 0 0 0 0>;
+ };
+
+ qcom,csid@1b30400 {
+ status = "ok";
+ cell-index = <1>;
+ compatible = "qcom,csid-v3.4.2", "qcom,csid";
+ reg = <0x1b30400 0x400>;
+ reg-names = "csid";
+ interrupts = <0 52 0>;
+ interrupt-names = "csid";
+ qcom,csi-vdd-voltage = <1200000>;
+ qcom,mipi-csi-vdd-supply = <&pm8937_l2>;
+ clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_csi1_ahb_clk>,
+ <&clock_gcc clk_csi1_clk_src>,
+ <&clock_gcc clk_gcc_camss_csi1phy_clk>,
+ <&clock_gcc clk_gcc_camss_csi1_clk>,
+ <&clock_gcc clk_gcc_camss_csi1pix_clk>,
+ <&clock_gcc clk_gcc_camss_csi1rdi_clk>,
+ <&clock_gcc clk_gcc_camss_ahb_clk>;
+ clock-names = "camss_top_ahb_clk",
+ "ispif_ahb_clk", "csi_ahb_clk", "csi_src_clk",
+ "csi1_phy_clk",
+ "csi_clk", "csi_pix_clk",
+ "csi_rdi_clk", "camss_ahb_clk";
+ qcom,clock-rates = <0 61540000 0 200000000 0 0 0 0 0>;
+ };
+
+ qcom,csid@1b30800 {
+ status = "ok";
+ cell-index = <2>;
+ compatible = "qcom,csid-v3.4.2", "qcom,csid";
+ reg = <0x1b30800 0x400>;
+ reg-names = "csid";
+ interrupts = <0 153 0>;
+ interrupt-names = "csid";
+ qcom,csi-vdd-voltage = <1200000>;
+ qcom,mipi-csi-vdd-supply = <&pm8937_l2>;
+ clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_csi2_ahb_clk>,
+ <&clock_gcc clk_csi2_clk_src>,
+ <&clock_gcc clk_gcc_camss_csi2phy_clk>,
+ <&clock_gcc clk_gcc_camss_csi2_clk>,
+ <&clock_gcc clk_gcc_camss_csi2pix_clk>,
+ <&clock_gcc clk_gcc_camss_csi2rdi_clk>,
+ <&clock_gcc clk_gcc_camss_ahb_clk>;
+ clock-names = "camss_top_ahb_clk",
+ "ispif_ahb_clk", "csi_ahb_clk", "csi_src_clk",
+ "csi2_phy_clk",
+ "csi_clk", "csi_pix_clk",
+ "csi_rdi_clk", "camss_ahb_clk";
+ qcom,clock-rates = <0 61540000 0 200000000 0 0 0 0 0>;
+ };
+
+ qcom,ispif@1b31000 {
+ cell-index = <0>;
+ compatible = "qcom,ispif-v3.0", "qcom,ispif";
+ reg = <0x1b31000 0x500>,
+ <0x1b00020 0x10>;
+ reg-names = "ispif", "csi_clk_mux";
+ interrupts = <0 55 0>;
+ interrupt-names = "ispif";
+ qcom,num-isps = <0x2>;
+ vfe0-vdd-supply = <&gdsc_vfe>;
+ vfe1-vdd-supply = <&gdsc_vfe1>;
+ qcom,vdd-names = "vfe0-vdd", "vfe1-vdd";
+ clocks = <&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+ <&clock_gcc clk_camss_top_ahb_clk_src>,
+ <&clock_gcc clk_csi0_clk_src>,
+ <&clock_gcc clk_gcc_camss_csi0_clk>,
+ <&clock_gcc clk_gcc_camss_csi0rdi_clk>,
+ <&clock_gcc clk_gcc_camss_csi0pix_clk>,
+ <&clock_gcc clk_csi1_clk_src>,
+ <&clock_gcc clk_gcc_camss_csi1_clk>,
+ <&clock_gcc clk_gcc_camss_csi1rdi_clk>,
+ <&clock_gcc clk_gcc_camss_csi1pix_clk>,
+ <&clock_gcc clk_csi2_clk_src>,
+ <&clock_gcc clk_gcc_camss_csi2_clk>,
+ <&clock_gcc clk_gcc_camss_csi2rdi_clk>,
+ <&clock_gcc clk_gcc_camss_csi2pix_clk>,
+ <&clock_gcc clk_vfe0_clk_src>,
+ <&clock_gcc clk_gcc_camss_vfe0_clk>,
+ <&clock_gcc clk_gcc_camss_csi_vfe0_clk>,
+ <&clock_gcc clk_vfe1_clk_src>,
+ <&clock_gcc clk_gcc_camss_vfe1_clk>,
+ <&clock_gcc clk_gcc_camss_csi_vfe1_clk>;
+ clock-names = "ispif_ahb_clk",
+ "camss_ahb_clk", "camss_top_ahb_clk",
+ "camss_ahb_src",
+ "csi0_src_clk", "csi0_clk",
+ "csi0_rdi_clk", "csi0_pix_clk",
+ "csi1_src_clk", "csi1_clk",
+ "csi1_rdi_clk", "csi1_pix_clk",
+ "csi2_src_clk", "csi2_clk",
+ "csi2_rdi_clk", "csi2_pix_clk",
+ "vfe0_clk_src", "camss_vfe_vfe0_clk",
+ "camss_csi_vfe0_clk", "vfe1_clk_src",
+ "camss_vfe_vfe1_clk", "camss_csi_vfe1_clk";
+ qcom,clock-rates = <61540000 0 0 0
+ 200000000 0 0 0
+ 200000000 0 0 0
+ 200000000 0 0 0
+ 0 0 0
+ 0 0 0>;
+ qcom,clock-cntl-support;
+ qcom,clock-control = "SET_RATE","NO_SET_RATE", "NO_SET_RATE",
+ "NO_SET_RATE", "SET_RATE", "NO_SET_RATE",
+ "NO_SET_RATE", "NO_SET_RATE", "SET_RATE",
+ "NO_SET_RATE", "NO_SET_RATE", "NO_SET_RATE",
+ "SET_RATE", "NO_SET_RATE", "NO_SET_RATE",
+ "NO_SET_RATE", "INIT_RATE", "NO_SET_RATE",
+ "NO_SET_RATE", "INIT_RATE", "NO_SET_RATE",
+ "NO_SET_RATE";
+ };
+
+ vfe0: qcom,vfe0@1b10000 {
+ cell-index = <0>;
+ compatible = "qcom,vfe40";
+ reg = <0x1b10000 0x1000>,
+ <0x1b40000 0x200>;
+ reg-names = "vfe", "vfe_vbif";
+ interrupts = <0 57 0>;
+ interrupt-names = "vfe";
+ vdd-supply = <&gdsc_vfe>;
+ clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_ahb_clk>,
+ <&clock_gcc clk_vfe0_clk_src>,
+ <&clock_gcc clk_gcc_camss_vfe0_clk>,
+ <&clock_gcc clk_gcc_camss_csi_vfe0_clk>,
+ <&clock_gcc clk_gcc_camss_vfe_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_vfe_axi_clk>,
+ <&clock_gcc clk_gcc_camss_ispif_ahb_clk>;
+ clock-names = "camss_top_ahb_clk", "camss_ahb_clk",
+ "vfe_clk_src", "camss_vfe_vfe_clk",
+ "camss_csi_vfe_clk", "iface_clk",
+ "bus_clk", "iface_ahb_clk";
+ qcom,clock-rates = <0 0 266670000 0 0 0 0 0>;
+ qos-entries = <8>;
+ qos-regs = <0x2c4 0x2c8 0x2cc 0x2d0 0x2d4 0x2d8
+ 0x2dc 0x2e0>;
+ qos-settings = <0xaa55aa55
+ 0xaa55aa55 0xaa55aa55
+ 0xaa55aa55 0xaa55aa55
+ 0xaa55aa55 0xaa55aa55
+ 0xaa55aa55>;
+ vbif-entries = <1>;
+ vbif-regs = <0x124>;
+ vbif-settings = <0x3>;
+ ds-entries = <17>;
+ ds-regs = <0x988 0x98c 0x990 0x994 0x998
+ 0x99c 0x9a0 0x9a4 0x9a8 0x9ac 0x9b0
+ 0x9b4 0x9b8 0x9bc 0x9c0 0x9c4 0x9c8>;
+ ds-settings = <0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0x00000110>;
+ max-clk-nominal = <400000000>;
+ max-clk-turbo = <432000000>;
+ };
+
+ vfe1: qcom,vfe1@1b14000 {
+ cell-index = <1>;
+ compatible = "qcom,vfe40";
+ reg = <0x1b14000 0x1000>,
+ <0x1ba0000 0x200>;
+ reg-names = "vfe", "vfe_vbif";
+ interrupts = <0 29 0>;
+ interrupt-names = "vfe";
+ vdd-supply = <&gdsc_vfe1>;
+ clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_ahb_clk>,
+ <&clock_gcc clk_vfe1_clk_src>,
+ <&clock_gcc clk_gcc_camss_vfe1_clk>,
+ <&clock_gcc clk_gcc_camss_csi_vfe1_clk>,
+ <&clock_gcc clk_gcc_camss_vfe1_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_vfe1_axi_clk>,
+ <&clock_gcc clk_gcc_camss_ispif_ahb_clk>;
+ clock-names = "camss_top_ahb_clk" , "camss_ahb_clk",
+ "vfe_clk_src", "camss_vfe_vfe_clk",
+ "camss_csi_vfe_clk", "iface_clk",
+ "bus_clk", "iface_ahb_clk";
+ qcom,clock-rates = <0 0 266670000 0 0 0 0 0>;
+ qos-entries = <8>;
+ qos-regs = <0x2c4 0x2c8 0x2cc 0x2d0 0x2d4 0x2d8
+ 0x2dc 0x2e0>;
+ qos-settings = <0xaa55aa55
+ 0xaa55aa55 0xaa55aa55
+ 0xaa55aa55 0xaa55aa55
+ 0xaa55aa55 0xaa55aa55
+ 0xaa55aa55>;
+ vbif-entries = <1>;
+ vbif-regs = <0x124>;
+ vbif-settings = <0x3>;
+ ds-entries = <17>;
+ ds-regs = <0x988 0x98c 0x990 0x994 0x998
+ 0x99c 0x9a0 0x9a4 0x9a8 0x9ac 0x9b0
+ 0x9b4 0x9b8 0x9bc 0x9c0 0x9c4 0x9c8>;
+ ds-settings = <0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0xcccc1111
+ 0xcccc1111 0x00000110>;
+ max-clk-nominal = <400000000>;
+ max-clk-turbo = <432000000>;
+ };
+
+ qcom,vfe {
+ compatible = "qcom,vfe";
+ num_child = <2>;
+ };
+
+ qcom,cam_smmu {
+ status = "ok";
+ compatible = "qcom,msm-cam-smmu";
+ msm_cam_smmu_cb1: msm_cam_smmu_cb1 {
+ compatible = "qcom,msm-cam-smmu-cb";
+ iommus = <&apps_iommu 0x400 0x00>,
+ <&apps_iommu 0x2400 0x00>;
+ label = "vfe";
+ qcom,scratch-buf-support;
+ };
+
+ msm_cam_smmu_cb2: msm_cam_smmu_cb2 {
+ compatible = "qcom,msm-cam-smmu-cb";
+ label = "vfe_secure";
+ qcom,secure-context;
+ };
+
+ msm_cam_smmu_cb3: msm_cam_smmu_cb3 {
+ compatible = "qcom,msm-cam-smmu-cb";
+ iommus = <&apps_iommu 0x1c00 0x00>;
+ label = "cpp";
+ };
+
+ msm_cam_smmu_cb4: msm_cam_smmu_cb4 {
+ compatible = "qcom,msm-cam-smmu-cb";
+ iommus = <&apps_iommu 0x1800 0x00>;
+ label = "jpeg_enc0";
+ };
+ };
+
+ qcom,jpeg@1b1c000 {
+ status = "ok";
+ cell-index = <0>;
+ compatible = "qcom,jpeg";
+ reg = <0x1b1c000 0x400>,
+ <0x1b60000 0xc30>;
+ reg-names = "jpeg_hw", "jpeg_vbif";
+ interrupts = <0 59 0>;
+ interrupt-names = "jpeg";
+ vdd-supply = <&gdsc_jpeg>;
+ qcom,vdd-names = "vdd";
+ clock-names = "core_clk", "iface_clk", "bus_clk0",
+ "camss_top_ahb_clk", "camss_ahb_clk";
+ clocks = <&clock_gcc clk_gcc_camss_jpeg0_clk>,
+ <&clock_gcc clk_gcc_camss_jpeg_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_jpeg_axi_clk>,
+ <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_ahb_clk>;
+ qcom,clock-rates = <266670000 0 0 0 0>;
+ qcom,qos-reg-settings = <0x28 0x0000555e>,
+ <0xc8 0x00005555>;
+ qcom,vbif-reg-settings = <0xc0 0x10101000>,
+ <0xb0 0x10100010>;
+ qcom,msm-bus,name = "msm_camera_jpeg0";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps = <62 512 0 0>,
+ <62 512 800000 800000>;
+ };
+
+ qcom,irqrouter@1b00000 {
+ status = "ok";
+ cell-index = <0>;
+ compatible = "qcom,irqrouter";
+ reg = <0x1b00000 0x100>;
+ reg-names = "irqrouter";
+ };
+
+ qcom,cpp@1b04000 {
+ status = "ok";
+ cell-index = <0>;
+ compatible = "qcom,cpp";
+ reg = <0x1b04000 0x100>,
+ <0x1b80000 0x200>,
+ <0x1b18000 0x018>,
+ <0x1858078 0x4>;
+ reg-names = "cpp", "cpp_vbif", "cpp_hw", "camss_cpp";
+ interrupts = <0 49 0>;
+ interrupt-names = "cpp";
+ vdd-supply = <&gdsc_cpp>;
+ qcom,vdd-names = "vdd";
+ clocks = <&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+ <&clock_gcc clk_cpp_clk_src>,
+ <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_cpp_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_cpp_axi_clk>,
+ <&clock_gcc clk_gcc_camss_cpp_clk>,
+ <&clock_gcc clk_gcc_camss_micro_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_ahb_clk>;
+ clock-names = "ispif_ahb_clk", "cpp_core_clk",
+ "camss_top_ahb_clk", "camss_vfe_cpp_ahb_clk",
+ "camss_vfe_cpp_axi_clk", "camss_vfe_cpp_clk",
+ "micro_iface_clk", "camss_ahb_clk";
+ qcom,clock-rates = <61540000 180000000 0 0 0 180000000 0 0>;
+ qcom,min-clock-rate = <133000000>;
+ resets = <&clock_gcc GCC_CAMSS_MICRO_BCR>;
+ reset-names = "micro_iface_reset";
+ qcom,bus-master = <1>;
+ 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;
+ qcom,micro-reset;
+ qcom,cpp-fw-payload-info {
+ qcom,stripe-base = <156>;
+ qcom,plane-base = <141>;
+ qcom,stripe-size = <27>;
+ qcom,plane-size = <5>;
+ qcom,fe-ptr-off = <5>;
+ qcom,we-ptr-off = <11>;
+ };
+ };
+
+ cci: qcom,cci@1b0c000 {
+ status = "ok";
+ cell-index = <0>;
+ compatible = "qcom,cci";
+ reg = <0x1b0c000 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "cci";
+ interrupts = <0 50 0>;
+ interrupt-names = "cci";
+ clocks = <&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+ <&clock_gcc clk_cci_clk_src>,
+ <&clock_gcc clk_gcc_camss_cci_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_cci_clk>,
+ <&clock_gcc clk_gcc_camss_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_top_ahb_clk>;
+ clock-names = "ispif_ahb_clk", "cci_src_clk",
+ "cci_ahb_clk", "camss_cci_clk",
+ "camss_ahb_clk", "camss_top_ahb_clk";
+ qcom,clock-rates = <61540000 19200000 0 0 0 0>,
+ <61540000 37500000 0 0 0 0>;
+ pinctrl-names = "cci_default", "cci_suspend";
+ pinctrl-0 = <&cci0_active &cci1_active>;
+ pinctrl-1 = <&cci0_suspend &cci1_suspend>;
+ gpios = <&tlmm 29 0>,
+ <&tlmm 30 0>,
+ <&tlmm 31 0>,
+ <&tlmm 32 0>;
+ qcom,gpio-tbl-num = <0 1 2 3>;
+ qcom,gpio-tbl-flags = <1 1 1 1>;
+ qcom,gpio-tbl-label = "CCI_I2C_DATA0",
+ "CCI_I2C_CLK0",
+ "CCI_I2C_DATA1",
+ "CCI_I2C_CLK1";
+ i2c_freq_100Khz: qcom,i2c_standard_mode {
+ status = "disabled";
+ };
+ i2c_freq_400Khz: qcom,i2c_fast_mode {
+ status = "disabled";
+ };
+ i2c_freq_custom: qcom,i2c_custom_mode {
+ status = "disabled";
+ };
+
+ i2c_freq_1Mhz: qcom,i2c_fast_plus_mode {
+ status = "disabled";
+ };
+
+ };
+};
+
+&i2c_freq_100Khz {
+ qcom,hw-thigh = <78>;
+ qcom,hw-tlow = <114>;
+ qcom,hw-tsu-sto = <28>;
+ qcom,hw-tsu-sta = <28>;
+ qcom,hw-thd-dat = <10>;
+ qcom,hw-thd-sta = <77>;
+ qcom,hw-tbuf = <118>;
+ qcom,hw-scl-stretch-en = <0>;
+ qcom,hw-trdhld = <6>;
+ qcom,hw-tsp = <1>;
+};
+
+&i2c_freq_400Khz {
+ qcom,hw-thigh = <20>;
+ qcom,hw-tlow = <28>;
+ qcom,hw-tsu-sto = <21>;
+ qcom,hw-tsu-sta = <21>;
+ qcom,hw-thd-dat = <13>;
+ qcom,hw-thd-sta = <18>;
+ qcom,hw-tbuf = <32>;
+ qcom,hw-scl-stretch-en = <0>;
+ qcom,hw-trdhld = <6>;
+ qcom,hw-tsp = <3>;
+ status = "ok";
+};
+
+&i2c_freq_custom {
+ qcom,hw-thigh = <15>;
+ qcom,hw-tlow = <28>;
+ qcom,hw-tsu-sto = <21>;
+ qcom,hw-tsu-sta = <21>;
+ qcom,hw-thd-dat = <13>;
+ qcom,hw-thd-sta = <18>;
+ qcom,hw-tbuf = <25>;
+ qcom,hw-scl-stretch-en = <1>;
+ qcom,hw-trdhld = <6>;
+ qcom,hw-tsp = <3>;
+ status = "ok";
+};
+
+&i2c_freq_1Mhz {
+ qcom,hw-thigh = <16>;
+ qcom,hw-tlow = <22>;
+ qcom,hw-tsu-sto = <17>;
+ qcom,hw-tsu-sta = <18>;
+ qcom,hw-thd-dat = <16>;
+ qcom,hw-thd-sta = <15>;
+ qcom,hw-tbuf = <19>;
+ qcom,hw-scl-stretch-en = <1>;
+ qcom,hw-trdhld = <3>;
+ qcom,hw-tsp = <3>;
+ qcom,cci-clk-src = <37500000>;
+ status = "ok";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi b/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi
index f72fda9..ec92805 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi
@@ -58,7 +58,7 @@
reg = <0x100>;
enable-method = "psci";
efficiency = <1126>;
- sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
#cooling-cells = <2>;
L2_1: l2-cache {
@@ -83,7 +83,7 @@
reg = <0x101>;
enable-method = "psci";
efficiency = <1126>;
- sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
#cooling-cells = <2>;
L1_I_101: l1-icache {
@@ -102,7 +102,7 @@
reg = <0x102>;
enable-method = "psci";
efficiency = <1126>;
- sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
#cooling-cells = <2>;
L1_I_102: l1-icache {
@@ -121,7 +121,7 @@
reg = <0x103>;
enable-method = "psci";
efficiency = <1126>;
- sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
#cooling-cells = <2>;
L1_I_103: l1-icache {
@@ -140,7 +140,7 @@
reg = <0x0>;
enable-method = "psci";
efficiency = <1024>;
- sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
+ sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
next-level-cache = <&L2_0>;
#cooling-cells = <2>;
L2_0: l2-cache {
@@ -164,7 +164,7 @@
reg = <0x1>;
enable-method = "psci";
efficiency = <1024>;
- sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
+ sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
next-level-cache = <&L2_0>;
#cooling-cells = <2>;
L1_I_1: l1-icache {
@@ -183,7 +183,7 @@
reg = <0x2>;
enable-method = "psci";
efficiency = <1024>;
- sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
+ sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
next-level-cache = <&L2_0>;
#cooling-cells = <2>;
L1_I_2: l1-icache {
@@ -202,7 +202,7 @@
reg = <0x3>;
enable-method = "psci";
efficiency = <1024>;
- sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
+ sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
next-level-cache = <&L2_0>;
#cooling-cells = <2>;
L1_I_3: l1-icache {
@@ -245,11 +245,11 @@
};
CLUSTER_COST_0: cluster-cost0 {
busy-cost-data = <
- 500000 19
- 800000 29
- 900000 36
- 1000000 46
- 1100000 55
+ 700000 85
+ 1000000 126
+ 1100000 152
+ 1250000 197
+ 1400000 239
>;
idle-cost-data = <
4 3 2 1
@@ -257,11 +257,11 @@
};
CLUSTER_COST_1: cluster-cost1 {
busy-cost-data = <
- 700000 85
- 1000000 126
- 1100000 152
- 1250000 197
- 1400000 239
+ 500000 19
+ 800000 29
+ 900000 36
+ 1000000 46
+ 1100000 55
>;
idle-cost-data = <
4 3 2 1
diff --git a/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi b/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi
index a6918b9..fbe5ce7 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi
@@ -28,13 +28,13 @@
&soc {
qcom,csid@1b30000 {
- /delete-property/ qcom,mipi-csi-vdd-supply;
+ qcom,mipi-csi-vdd-supply = <&pm8953_l2>;
};
qcom,csid@1b30400 {
- /delete-property/ qcom,mipi-csi-vdd-supply;
+ qcom,mipi-csi-vdd-supply = <&pm8953_l2>;
};
qcom,csid@1b30800 {
- /delete-property/ qcom,mipi-csi-vdd-supply;
+ qcom,mipi-csi-vdd-supply = <&pm8953_l2>;
};
mem_acc_vreg_corner: regulator@01946004 {
diff --git a/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi
index 8d18bdd..bca8912 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi
@@ -20,7 +20,8 @@
#include "dsi-panel-r69006-1080p-video.dtsi"
#include "dsi-adv7533-1080p.dtsi"
#include "dsi-adv7533-720p.dtsi"
-
+#include "dsi-panel-hx8399c-fhd-plus-video.dtsi"
+#include "dsi-panel-hx8399c-hd-plus-video.dtsi"
&soc {
dsi_panel_pwr_supply: dsi_panel_pwr_supply {
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi
index 01192af..42f1b5c 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi
@@ -11,6 +11,8 @@
* GNU General Public License for more details.
*/
+#include "msm8937-camera-sensor-mtp.dtsi"
+
#include "msm8937-pinctrl.dtsi"
&blsp1_uart2 {
status = "ok";
diff --git a/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi
index 1b273ef..87dd30e 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi
@@ -15,7 +15,7 @@
tlmm: pinctrl@1000000 {
compatible = "qcom,msm8937-pinctrl";
reg = <0x1000000 0x300000>;
- interrupts = <0 208 0>;
+ interrupts-extended = <&wakegic GIC_SPI 208 IRQ_TYPE_NONE>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -1376,29 +1376,57 @@
};
};
- cam_sensor_rear_default: cam_sensor_rear_default {
- /* RESET, STANDBY */
+ cam_sensor_rear_reset: cam_sensor_rear_reset {
+ /* RESET */
mux {
- pins = "gpio36", "gpio35";
+ pins = "gpio36";
function = "gpio";
};
config {
- pins = "gpio36","gpio35";
+ pins = "gpio36";
bias-disable; /* No PULL */
drive-strength = <2>; /* 2 MA */
};
};
- cam_sensor_rear_sleep: cam_sensor_rear_sleep {
- /* RESET, STANDBY */
+ cam_sensor_rear_reset_sleep: cam_sensor_rear_reset_sleep {
+ /* RESET */
mux {
- pins = "gpio36","gpio35";
+ pins = "gpio36";
function = "gpio";
};
config {
- pins = "gpio36","gpio35";
+ pins = "gpio36";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear_standby: cam_sensor_rear_standby {
+ /* STANDBY */
+ mux {
+ pins = "gpio35";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio35";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear_standby_sleep: cam_sensor_rear_standby_sleep {
+ /* STANDBY */
+ mux {
+ pins = "gpio35";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio35";
bias-disable; /* No PULL */
drive-strength = <2>; /* 2 MA */
};
@@ -1432,6 +1460,34 @@
};
};
+ cam_sensor_rear_vana: cam_sensor_rear_vana {
+ /* VANA */
+ mux {
+ pins = "gpio35";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio35";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear_vana_sleep: cam_sensor_rear_vana_sleep {
+ /* VANA */
+ mux {
+ pins = "gpio35";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio35";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
cam_sensor_mclk1_default: cam_sensor_mclk1_default {
/* MCLK1 */
mux {
diff --git a/arch/arm64/boot/dts/qcom/msm8937.dtsi b/arch/arm64/boot/dts/qcom/msm8937.dtsi
index 3518473..8f769fe 100644
--- a/arch/arm64/boot/dts/qcom/msm8937.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937.dtsi
@@ -889,6 +889,10 @@
};
};
+ qcom,iris-fm {
+ compatible = "qcom,iris_fm";
+ };
+
rpm_bus: qcom,rpm-smd {
compatible = "qcom,rpm-smd";
rpm-channel-name = "rpm_requests";
@@ -991,6 +995,7 @@
qcom,ipi-ping;
qcom,wakeup-enable;
status = "okay";
+ qcom,scandump-size = <0x40000>;
};
spmi_bus: qcom,spmi@200f000 {
@@ -1052,10 +1057,20 @@
reg = <0x6b0 32>;
};
+ kaslr_offset@6d0 {
+ compatible = "qcom,msm-imem-kaslr_offset";
+ reg = <0x6d0 12>;
+ };
+
pil@94c {
compatible = "qcom,msm-imem-pil";
reg = <0x94c 200>;
};
+
+ diag_dload@c8 {
+ compatible = "qcom,msm-imem-diag-dload";
+ reg = <0xc8 200>;
+ };
};
qcom,memshare {
@@ -1722,6 +1737,7 @@
#include "msm8937-regulator.dtsi"
#include "pm8937.dtsi"
#include "msm8937-audio.dtsi"
+#include "msm8937-camera.dtsi"
#include "msm-gdsc-8916.dtsi"
#include "msm8937-coresight.dtsi"
#include "msm8937-thermal.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi b/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
index 2845e36..196a526 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
@@ -25,6 +25,7 @@
arm,buffer-size = <0x100000>;
arm,sg-enable;
+ qcom,force-reg-dump;
coresight-name = "coresight-tmc-etr";
coresight-csr = <&csr>;
@@ -53,6 +54,7 @@
coresight-csr = <&csr>;
arm,default-sink;
+ qcom,force-reg-dump;
coresight-ctis = <&cti0 &cti8>;
clocks = <&clock_gcc clk_qdss_clk>,
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index 005444c..50ee0e8 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -26,7 +26,7 @@
interrupt-parent = <&wakegic>;
chosen {
- bootargs = "kpti=0";
+ bootargs = "core_ctl_disable_cpumask=0-7 kpti=0";
};
firmware: firmware {
@@ -1187,6 +1187,10 @@
};
};
+ qcom,iris-fm {
+ compatible = "qcom,iris_fm";
+ };
+
rpm_bus: qcom,rpm-smd {
compatible = "qcom,rpm-smd";
rpm-channel-name = "rpm_requests";
diff --git a/arch/arm64/boot/dts/qcom/pm8937.dtsi b/arch/arm64/boot/dts/qcom/pm8937.dtsi
index cd1bddb..18a3270c 100644
--- a/arch/arm64/boot/dts/qcom/pm8937.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8937.dtsi
@@ -35,6 +35,7 @@
"resin-bark", "kpdpwr-resin-bark";
qcom,pon-dbc-delay = <15625>;
qcom,system-reset;
+ qcom,store-hard-reset-reason;
qcom,pon_1 {
qcom,pon-type = <0>;
diff --git a/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi b/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
index 5d7d0b8..aa316ba 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
@@ -47,9 +47,14 @@
status = "disabled";
};
+&mdss_mdp {
+ bridges = <<9611>;
+};
+
&qupv3_se9_i2c {
status = "okay";
- lt9611@3b {
+
+ lt9611: lt,lt9611@3b {
compatible = "lt,lt9611";
reg = <0x3b>;
interrupt-parent = <&tlmm>;
@@ -60,6 +65,7 @@
lt,hdmi-ps-gpio = <&tlmm 136 0x0>;
lt,hdmi-en-gpio = <&tlmm 137 0x0>;
lt,non-pluggable;
+ lt,preferred-mode = "1920x1080";
vcc-supply = <&pm660l_l6>;
vdd-supply = <&pm660_l11>;
@@ -101,6 +107,21 @@
lt,mode-refresh-rate = <60>;
lt,mode-clock-in-khz = <148500>;
};
+
+ lt,customize-mode-id@1 {
+ lt,mode-h-active = <3840>;
+ lt,mode-h-front-porch = <176>;
+ lt,mode-h-pulse-width = <88>;
+ lt,mode-h-back-porch = <296>;
+ lt,mode-h-active-high;
+ lt,mode-v-active = <2160>;
+ lt,mode-v-front-porch = <8>;
+ lt,mode-v-pulse-width = <10>;
+ lt,mode-v-back-porch = <72>;
+ lt,mode-v-active-high;
+ lt,mode-refresh-rate = <30>;
+ lt,mode-clock-in-khz = <297000>;
+ };
};
ports {
diff --git a/arch/arm64/boot/dts/qcom/qcs605-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/qcs605-cdp-overlay.dts
index 1429880..a479175 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/qcs605-cdp-overlay.dts
@@ -46,7 +46,7 @@
eeprom-src = <&eeprom_rear_aux>;
cam_vio-supply = <&camera_vio_ldo>;
cam_vana-supply = <&camera_vana_ldo>;
- cam_vdig-supply = <&camera_ldo>;
+ cam_vdig-supply = <&camera_rear_ldo>;
cam_clk-supply = <&titan_top_gdsc>;
regulator-names = "cam_vdig", "cam_vio", "cam_vana",
"cam_clk";
diff --git a/arch/arm64/boot/dts/qcom/qcs605-cdp.dts b/arch/arm64/boot/dts/qcom/qcs605-cdp.dts
index 6c6012e..92453d4 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/qcs605-cdp.dts
@@ -40,7 +40,7 @@
eeprom-src = <&eeprom_rear_aux>;
cam_vio-supply = <&camera_vio_ldo>;
cam_vana-supply = <&camera_vana_ldo>;
- cam_vdig-supply = <&camera_ldo>;
+ cam_vdig-supply = <&camera_rear_ldo>;
cam_clk-supply = <&titan_top_gdsc>;
regulator-names = "cam_vdig", "cam_vio", "cam_vana",
"cam_clk";
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..a2841bf
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-camera-sensor-mtp.dtsi
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&cam_cci {
+ qcom,cam-res-mgr {
+ compatible = "qcom,cam-res-mgr";
+ status = "ok";
+ };
+
+ qcom,cam-sensor@0 {
+ cell-index = <0>;
+ compatible = "qcom,cam-sensor";
+ reg = <0x0>;
+ csiphy-sd-index = <0>;
+ sensor-position-roll = <270>;
+ sensor-position-pitch = <0>;
+ sensor-position-yaw = <180>;
+ cam_vio-supply = <&pm660_l11>;
+ cam_vana-supply = <&pm660_l15>;
+ cam_vdig-supply = <&pm660_l5>;
+ cam_clk-supply = <&titan_top_gdsc>;
+ regulator-names = "cam_vio", "cam_vana", "cam_vdig",
+ "cam_clk";
+ rgltr-cntrl-support;
+ rgltr-min-voltage = <1800000 2900000 1200000 0>;
+ rgltr-max-voltage = <1800000 2900000 1200000 0>;
+ rgltr-load-current = <0 80000 105000 0>;
+ gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_active
+ &cam_sensor_rear_active>;
+ pinctrl-1 = <&cam_sensor_mclk0_suspend
+ &cam_sensor_rear_suspend>;
+ gpios = <&tlmm 13 0>,
+ <&tlmm 30 0>;
+ gpio-reset = <1>;
+ gpio-req-tbl-num = <0 1>;
+ gpio-req-tbl-flags = <1 0>;
+ gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0";
+ sensor-mode = <0>;
+ cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
+ clock-names = "cam_clk";
+ clock-cntl-level = "turbo";
+ clock-rates = <24000000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi
index f592c0e..1ae339e 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi
@@ -11,6 +11,7 @@
*/
#include "qcs605-lc-pmic-overlay.dtsi"
+#include "qcs605-lc-camera-sensor-mtp.dtsi"
&qupv3_se9_2uart {
status = "disabled";
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-sde-display.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-sde-display.dtsi
new file mode 100644
index 0000000..654f3a1
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-sde-display.dtsi
@@ -0,0 +1,73 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <dt-bindings/clock/mdss-10nm-pll-clk.h>
+
+&soc {
+ ext_dsi_bridge_display: qcom,dsi-display@0 {
+ compatible = "qcom,dsi-display";
+ label = "ext_dsi_bridge_display";
+ qcom,display-type = "primary";
+
+ qcom,dsi-ctrl = <&mdss_dsi0>;
+ qcom,dsi-phy = <&mdss_dsi_phy0>;
+ clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
+ <&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+ clock-names = "src_byte_clk", "src_pixel_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ ext_dsi_out: endpoint {
+ };
+ };
+ };
+ };
+
+ sde_wb: qcom,wb-display@0 {
+ compatible = "qcom,wb-display";
+ cell-index = <0>;
+ label = "wb_display";
+ };
+
+ ext_disp: qcom,msm-ext-disp {
+ compatible = "qcom,msm-ext-disp";
+
+ ext_disp_audio_codec: qcom,msm-ext-disp-audio-codec-rx {
+ compatible = "qcom,msm-ext-disp-audio-codec-rx";
+ };
+ };
+};
+
+&mdss_dsi0 {
+ vdda-1p2-supply = <&pm660_l2>;
+};
+
+&mdss_dsi1 {
+ vdda-1p2-supply = <&pm660_l2>;
+};
+
+&mdss_dsi_phy0 {
+ vdda-0p9-supply = <&pm660_l6>;
+};
+
+&mdss_dsi_phy1 {
+ vdda-0p9-supply = <&pm660_l6>;
+};
+
+&sde_dp {
+ vdda-0p9-supply = <&pm660_l6>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc.dtsi
index 2af6610..94ee398 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-lc.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc.dtsi
@@ -14,6 +14,7 @@
#include "qcs605.dtsi"
#include "pm8005.dtsi"
#include "qcs605-pm660-pm8005-regulator.dtsi"
+#include "qcs605-lc-sde-display.dtsi"
/ {
model = "Qualcomm Technologies, Inc. QCS605 SoC";
@@ -134,6 +135,13 @@
/delete-node/ qcom,pm660l@3;
};
+&icnss {
+ /delete-property/ vdd-3.3-ch0-supply;
+ vdd-0.8-cx-mx-supply = <&pm660_l1>;
+ vdd-1.8-xo-supply = <&pm660_l9>;
+ vdd-1.3-rfa-supply = <&pm660_l3>;
+};
+
&thermal_zones {
pm660l_tz {
/delete-property/ thermal-sensors;
@@ -201,24 +209,147 @@
&clock_gfx {
/delete-property/ vdd_gfx-supply;
- vdd_gfx-supply = <&pm8005_s2>;
+ vdd_gfx-supply = <&pm8005_s3_level>;
};
&gpu_gx_gdsc {
/delete-property/ parent-supply;
- parent-supply = <&pm8005_s2>;
+ parent-supply = <&pm8005_s3_level>;
};
-&mdss_dsi_phy0 {
- /delete-property/ vdda-0p9-supply;
-};
-
-&mdss_dsi_phy1 {
- /delete-property/ vdda-0p9-supply;
+&mdss_mdp {
+ connectors = <&sde_rscc &sde_wb>;
+ bridges = <<9611>;
};
&sde_dp {
- /delete-property/ vdda-0p9-supply;
+ status = "disabled";
+};
+
+&tlmm {
+ lt9611_vcc_eldo_default: lt9611_vcc_eldo_default {
+ mux {
+ pins = "gpio53";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio53";
+ drive-strength = <8>;
+ bias-disable = <0>;
+ output-low;
+ };
+ };
+};
+
+&soc {
+ lt9611_vcc_eldo: lt9611-gpio-regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "lt9611_vcc_eldo";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <233>;
+ gpio = <&tlmm 53 0>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pintctrl-0 = <<9611_vcc_eldo_default>;
+ };
+};
+
+&qupv3_se9_i2c {
+ status = "okay";
+
+ lt9611: lt,lt9611@3b {
+ compatible = "lt,lt9611";
+ reg = <0x3b>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <96 0>;
+ interrupt-names = "lt_irq";
+ lt,irq-gpio = <&tlmm 96 0x0>;
+ lt,reset-gpio = <&tlmm 95 0x0>;
+ lt,non-pluggable;
+ lt,preferred-mode = "1920x1080";
+
+ vdd-supply = <&pm660_l12>;
+ vcc-supply = <<9611_vcc_eldo>;
+ lt,supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ lt,supply-entry@0 {
+ reg = <0>;
+ lt,supply-name = "vdd";
+ lt,supply-min-voltage = <1800000>;
+ lt,supply-max-voltage = <1800000>;
+ lt,supply-enable-load = <200000>;
+ lt,supply-post-on-sleep = <50>;
+ };
+
+ lt,supply-entry@1 {
+ reg = <1>;
+ lt,supply-name = "vcc";
+ lt,supply-min-voltage = <3300000>;
+ lt,supply-max-voltage = <3300000>;
+ lt,supply-post-on-sleep = <50>;
+ };
+ };
+
+ lt,customize-modes {
+ lt,customize-mode-id@0 {
+ lt,mode-h-active = <1920>;
+ lt,mode-h-front-porch = <88>;
+ lt,mode-h-pulse-width = <44>;
+ lt,mode-h-back-porch = <148>;
+ lt,mode-h-active-high;
+ lt,mode-v-active = <1080>;
+ lt,mode-v-front-porch = <4>;
+ lt,mode-v-pulse-width = <5>;
+ lt,mode-v-back-porch = <36>;
+ lt,mode-v-active-high;
+ lt,mode-refresh-rate = <60>;
+ lt,mode-clock-in-khz = <148500>;
+ };
+
+ lt,customize-mode-id@1 {
+ lt,mode-h-active = <3840>;
+ lt,mode-h-front-porch = <176>;
+ lt,mode-h-pulse-width = <88>;
+ lt,mode-h-back-porch = <296>;
+ lt,mode-h-active-high;
+ lt,mode-v-active = <2160>;
+ lt,mode-v-front-porch = <8>;
+ lt,mode-v-pulse-width = <10>;
+ lt,mode-v-back-porch = <72>;
+ lt,mode-v-active-high;
+ lt,mode-refresh-rate = <30>;
+ lt,mode-clock-in-khz = <297000>;
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ lt9611_in: endpoint {
+ remote-endpoint = <&ext_dsi_out>;
+ };
+ };
+ };
+ };
+};
+
+&soc {
+ qcom,dsi-display@0 {
+ qcom,dsi-display-active;
+
+ ports {
+ port@0 {
+ endpoint {
+ remote-endpoint = <<9611_in>;
+ };
+ };
+ };
+ };
};
&qusb_phy0 {
diff --git a/arch/arm64/boot/dts/qcom/sda845-svr.dtsi b/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
index 51dbe74..ce62781 100644
--- a/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
+++ b/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
@@ -325,7 +325,7 @@
};
&adsp_mem {
- size = <0 0xc800000>;
+ size = <0 0x12c00000>;
};
&qupv3_se9_2uart {
diff --git a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
index d2a8f3e..80f7007 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
@@ -13,16 +13,13 @@
/ {
/delete-node/ cpus;
+ /delete-node/ energy-costs;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu-map {
-
cluster0 {
- };
-
- cluster1 {
core0 {
cpu = <&CPU0>;
};
@@ -44,6 +41,8 @@
reg = <0x100>;
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
#cooling-cells = <2>;
L2_1: l2-cache {
@@ -68,6 +67,8 @@
reg = <0x101>;
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
#cooling-cells = <2>;
L1_I_101: l1-icache {
@@ -86,6 +87,8 @@
reg = <0x102>;
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
#cooling-cells = <2>;
L1_I_102: l1-icache {
@@ -104,6 +107,8 @@
reg = <0x103>;
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
#cooling-cells = <2>;
L1_I_103: l1-icache {
@@ -118,4 +123,34 @@
};
+ energy_costs: energy-costs {
+ compatible = "sched-energy";
+
+ CPU_COST_0: core-cost0 {
+ busy-cost-data = <
+ 800000 137
+ 1001600 165
+ 1305600 207
+ 1497600 256
+ 1708800 327
+ 1958400 445
+ >;
+ idle-cost-data = <
+ 100 80 60 40
+ >;
+ };
+ CLUSTER_COST_0: cluster-cost0 {
+ busy-cost-data = <
+ 800000 49
+ 1001600 53
+ 1305600 61
+ 1497600 71
+ 1708800 85
+ 1958400 110
+ >;
+ idle-cost-data = <
+ 4 3 2 1
+ >;
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/sdm429.dtsi b/arch/arm64/boot/dts/qcom/sdm429.dtsi
index f31eb6e..a4d2a80 100644
--- a/arch/arm64/boot/dts/qcom/sdm429.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429.dtsi
@@ -20,8 +20,6 @@
};
&soc {
- /delete-node/ qcom,spm@b1d2000;
- /delete-node/ qcom,lpm-levels;
/delete-node/ etm@619c000;
/delete-node/ etm@619d000;
/delete-node/ etm@619e000;
@@ -30,6 +28,16 @@
/delete-node/ cti@61b9000;
/delete-node/ cti@61ba000;
/delete-node/ cti@61bb000;
+
+ qcom,spm@b1d2000 {
+ qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>;
+ };
+
+ qcom,lpm-levels {
+ qcom,pm-cluster@0 {
+ /delete-node/qcom,pm-cluster@1;
+ };
+ };
};
&funnel_apss {
diff --git a/arch/arm64/boot/dts/qcom/sdm439-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm439-audio.dtsi
index fae43ba..f6751d2 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-audio.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-audio.dtsi
@@ -13,6 +13,7 @@
&soc {
int_codec: sound {
+ qcom,model = "sdm439-snd-card-mtp";
qcom,msm-hs-micbias-type = "internal";
asoc-codec = <&stub_codec>, <&msm_digital_codec>,
diff --git a/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-cdp.dtsi
new file mode 100644
index 0000000..5e2c740
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-cdp.dtsi
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2015-2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&cci {
+ actuator0: qcom,actuator@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ actuator1: qcom,actuator@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ eeprom0: qcom,eeprom@0 {
+ cell-index = <0>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <0>;
+ reg = <0x0>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ cam_vdig-supply = <&pm8953_l3>;
+ qcom,cam-vreg-name = "cam_vana",
+ "cam_vio", "cam_vdig", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000 0 1200000 2850000>;
+ qcom,cam-vreg-max-voltage = <2800000 0 1200000 2850000>;
+ qcom,cam-vreg-op-mode = <80000 0 200000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_reset
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep
+ &cam_sensor_rear_reset_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 36 0>,
+ <&tlmm 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_VANA";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom1: qcom,eeprom@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ qcom,eeprom-name = "sunny_8865";
+ compatible = "qcom,eeprom";
+ qcom,slave-addr = <0x6c>;
+ qcom,cci-master = <0>;
+ qcom,num-blocks = <8>;
+
+ qcom,page0 = <1 0x0100 2 0x01 1 1>;
+ qcom,poll0 = <0 0x0 2 0x0 1 0>;
+ qcom,mem0 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page1 = <1 0x5002 2 0x00 1 0>;
+ qcom,poll1 = <0 0x0 2 0x0 1 0>;
+ qcom,mem1 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
+ qcom,poll2 = <0 0x0 2 0x0 1 0>;
+ qcom,mem2 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page3 = <1 0x3d88 2 0x70 1 0>;
+ qcom,poll3 = <0 0x0 2 0x0 1 0>;
+ qcom,mem3 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page4 = <1 0x3d89 2 0x10 1 0>;
+ qcom,poll4 = <0 0x0 2 0x0 1 0>;
+ qcom,mem4 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
+ qcom,poll5 = <0 0x0 2 0x0 1 0>;
+ qcom,mem5 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
+ qcom,poll6 = <0 0x0 2 0x0 1 0>;
+ qcom,mem6 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page7 = <1 0x3d81 2 0x01 1 10>;
+ qcom,poll7 = <0 0x0 2 0x0 1 1>;
+ qcom,mem7 = <1536 0x7010 2 0 1 0>;
+
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
+ "sensor_vreg",
+ "sensor_gpio", "sensor_gpio" , "sensor_clk";
+ qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
+ "sensor_gpio_reset", "sensor_gpio_standby",
+ "sensor_cam_mclk";
+ qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
+ qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <270>;
+ qcom,led-flash-src = <&led_flash0>;
+ qcom,eeprom-src = <&eeprom0>;
+ qcom,actuator-src = <&actuator0>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ cam_vdig-supply = <&pm8953_l3>;
+ qcom,cam-vreg-name = "cam_vana",
+ "cam_vio", "cam_vdig", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000 0 1200000 2850000>;
+ qcom,cam-vreg-max-voltage = <2800000 0 1200000 2850000>;
+ qcom,cam-vreg-op-mode = <80000 0 200000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_reset
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep
+ &cam_sensor_rear_reset_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 36 0>,
+ <&tlmm 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_VANA";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ cam_vdig-supply = <&pm8953_l3>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 38 0>,
+ <&tlmm 50 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ qcom,sensor-position = <0x100>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <1>;
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@2 {
+ cell-index = <2>;
+ compatible = "qcom,camera";
+ reg = <0x02>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ qcom,eeprom-src = <&eeprom1>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..5e2c740
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-mtp.dtsi
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2015-2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&cci {
+ actuator0: qcom,actuator@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ actuator1: qcom,actuator@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ eeprom0: qcom,eeprom@0 {
+ cell-index = <0>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <0>;
+ reg = <0x0>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ cam_vdig-supply = <&pm8953_l3>;
+ qcom,cam-vreg-name = "cam_vana",
+ "cam_vio", "cam_vdig", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000 0 1200000 2850000>;
+ qcom,cam-vreg-max-voltage = <2800000 0 1200000 2850000>;
+ qcom,cam-vreg-op-mode = <80000 0 200000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_reset
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep
+ &cam_sensor_rear_reset_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 36 0>,
+ <&tlmm 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_VANA";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom1: qcom,eeprom@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ qcom,eeprom-name = "sunny_8865";
+ compatible = "qcom,eeprom";
+ qcom,slave-addr = <0x6c>;
+ qcom,cci-master = <0>;
+ qcom,num-blocks = <8>;
+
+ qcom,page0 = <1 0x0100 2 0x01 1 1>;
+ qcom,poll0 = <0 0x0 2 0x0 1 0>;
+ qcom,mem0 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page1 = <1 0x5002 2 0x00 1 0>;
+ qcom,poll1 = <0 0x0 2 0x0 1 0>;
+ qcom,mem1 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
+ qcom,poll2 = <0 0x0 2 0x0 1 0>;
+ qcom,mem2 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page3 = <1 0x3d88 2 0x70 1 0>;
+ qcom,poll3 = <0 0x0 2 0x0 1 0>;
+ qcom,mem3 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page4 = <1 0x3d89 2 0x10 1 0>;
+ qcom,poll4 = <0 0x0 2 0x0 1 0>;
+ qcom,mem4 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
+ qcom,poll5 = <0 0x0 2 0x0 1 0>;
+ qcom,mem5 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
+ qcom,poll6 = <0 0x0 2 0x0 1 0>;
+ qcom,mem6 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page7 = <1 0x3d81 2 0x01 1 10>;
+ qcom,poll7 = <0 0x0 2 0x0 1 1>;
+ qcom,mem7 = <1536 0x7010 2 0 1 0>;
+
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
+ "sensor_vreg",
+ "sensor_gpio", "sensor_gpio" , "sensor_clk";
+ qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
+ "sensor_gpio_reset", "sensor_gpio_standby",
+ "sensor_cam_mclk";
+ qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
+ qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <270>;
+ qcom,led-flash-src = <&led_flash0>;
+ qcom,eeprom-src = <&eeprom0>;
+ qcom,actuator-src = <&actuator0>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ cam_vdig-supply = <&pm8953_l3>;
+ qcom,cam-vreg-name = "cam_vana",
+ "cam_vio", "cam_vdig", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000 0 1200000 2850000>;
+ qcom,cam-vreg-max-voltage = <2800000 0 1200000 2850000>;
+ qcom,cam-vreg-op-mode = <80000 0 200000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_reset
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep
+ &cam_sensor_rear_reset_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 36 0>,
+ <&tlmm 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_VANA";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ cam_vdig-supply = <&pm8953_l3>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 38 0>,
+ <&tlmm 50 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ qcom,sensor-position = <0x100>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <1>;
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@2 {
+ cell-index = <2>;
+ compatible = "qcom,camera";
+ reg = <0x02>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ qcom,eeprom-src = <&eeprom1>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi
index 5512297..83a4651 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi
@@ -11,6 +11,8 @@
* GNU General Public License for more details.
*/
+#include "sdm439-camera-sensor-cdp.dtsi"
+
&blsp1_uart2 {
status = "ok";
};
@@ -63,3 +65,106 @@
status = "ok";
};
+
+&soc {
+ gpio_keys {
+ compatible = "gpio-keys";
+ input-name = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_key_active>;
+
+ camera_focus {
+ label = "camera_focus";
+ gpios = <&tlmm 128 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x210>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ gpio-key,wakeup;
+ };
+
+ camera_snapshot {
+ label = "camera_snapshot";
+ gpios = <&tlmm 127 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x2fe>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ gpio-key,wakeup;
+ };
+
+ vol_up {
+ label = "volume_up";
+ gpios = <&tlmm 91 0x1>;
+ linux,input-type = <1>;
+ linux,code = <115>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&pm8953_gpios {
+ bklt_en {
+ bklt_en_default: bklt_en_default {
+ pins = "gpio4";
+ function = "normal";
+ power-source = <0>;
+ output-high;
+ };
+ };
+};
+
+&pm8953_pwm {
+ status = "ok";
+};
+
+#include "msm8937-mdss-panels.dtsi"
+
+&mdss_mdp {
+ qcom,mdss-pref-prim-intf = "dsi";
+};
+
+&mdss_dsi {
+ hw-config = "single_dsi";
+};
+
+&mdss_dsi0 {
+ qcom,dsi-pref-prim-pan = <&dsi_hx8399c_truly_vid>;
+ pinctrl-names = "mdss_default", "mdss_sleep";
+ pinctrl-0 = <&mdss_dsi_active &mdss_te_active &bklt_en_default>;
+ pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
+
+ qcom,platform-bklight-en-gpio = <&pm8953_gpios 4 0>;
+ qcom,platform-te-gpio = <&tlmm 24 0>;
+ qcom,platform-reset-gpio = <&tlmm 61 0>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+
+};
+
+&dsi_hx8399c_truly_vid {
+ qcom,mdss-dsi-panel-timings =
+ [f3 3a 26 00 6c 6e 2c 3e 2f 03 04 00];
+ qcom,mdss-dsi-t-clk-post = <0x02>;
+ qcom,mdss-dsi-t-clk-pre = <0x2d>;
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+ qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+ qcom,mdss-dsi-bl-pmic-bank-select = <0>;
+ qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>;
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
+};
+
+
+&dsi_hx8399c_hd_vid {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+ qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+ qcom,mdss-dsi-bl-pmic-bank-select = <0>;
+ qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi
index 5512297..17218a8 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi
@@ -11,6 +11,8 @@
* GNU General Public License for more details.
*/
+#include "sdm439-camera-sensor-mtp.dtsi"
+
&blsp1_uart2 {
status = "ok";
};
@@ -63,3 +65,105 @@
status = "ok";
};
+
+&soc {
+ gpio_keys {
+ compatible = "gpio-keys";
+ input-name = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_key_active>;
+
+ camera_focus {
+ label = "camera_focus";
+ gpios = <&tlmm 128 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x210>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ gpio-key,wakeup;
+ };
+
+ camera_snapshot {
+ label = "camera_snapshot";
+ gpios = <&tlmm 127 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x2fe>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ gpio-key,wakeup;
+ };
+
+ vol_up {
+ label = "volume_up";
+ gpios = <&tlmm 91 0x1>;
+ linux,input-type = <1>;
+ linux,code = <115>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ gpio-key,wakeup;
+ };
+ };
+};
+
+#include "msm8937-mdss-panels.dtsi"
+
+&pm8953_gpios {
+ bklt_en {
+ bklt_en_default: bklt_en_default {
+ pins = "gpio4";
+ function = "normal";
+ power-source = <0>;
+ output-high;
+ };
+ };
+};
+
+&pm8953_pwm {
+ status = "ok";
+};
+
+&mdss_mdp {
+ qcom,mdss-pref-prim-intf = "dsi";
+};
+
+&mdss_dsi {
+ hw-config = "single_dsi";
+};
+
+&mdss_dsi0 {
+ qcom,dsi-pref-prim-pan = <&dsi_hx8399c_truly_vid>;
+ pinctrl-names = "mdss_default", "mdss_sleep";
+ pinctrl-0 = <&mdss_dsi_active &mdss_te_active &bklt_en_default>;
+ pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
+
+ qcom,platform-bklight-en-gpio = <&pm8953_gpios 4 0>;
+ qcom,platform-te-gpio = <&tlmm 24 0>;
+ qcom,platform-reset-gpio = <&tlmm 61 0>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+
+};
+
+&dsi_hx8399c_truly_vid {
+ qcom,mdss-dsi-panel-timings =
+ [f3 3a 26 00 6c 6e 2c 3e 2f 03 04 00];
+ qcom,mdss-dsi-t-clk-post = <0x02>;
+ qcom,mdss-dsi-t-clk-pre = <0x2d>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+ qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+ qcom,mdss-dsi-bl-pmic-bank-select = <0>;
+ qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>;
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
+};
+
+&dsi_hx8399c_hd_vid {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+ qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+ qcom,mdss-dsi-bl-pmic-bank-select = <0>;
+ qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi b/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi
index 1c0a1fc..3c8a298 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi
@@ -125,8 +125,8 @@
};
&mdss_dsi {
- /delete-property/ vdda-supply;
- /delete-property/ vddio-supply;
+ vdda-supply = <&pm8953_l2>; /*1.2V*/
+ vddio-supply = <&pm8953_l6>; /*1.8V*/
};
&usb_otg {
@@ -137,21 +137,22 @@
};
&mdss_dsi0_pll {
- /delete-property/ vddio-supply;
+ vddio-supply = <&pm8953_l6>;
};
&mdss_dsi1_pll {
- /delete-property/ vddio-supply;
+ vddio-supply = <&pm8953_l6>;
};
&mdss_dsi0 {
- /delete-property/ vdd-supply;
- /delete-property/ vddio-supply;
+ vdd-supply = <&pm8953_l17>;
+ vddio-supply = <&pm8953_l6>;
};
&mdss_dsi1 {
- /delete-property/ vdd-supply;
- /delete-property/ vddio-supply;
+ status = "disabled";
+ vdd-supply = <&pm8953_l17>;
+ vddio-supply = <&pm8953_l6>;
};
&int_codec {
@@ -266,3 +267,33 @@
/delete-node/ case_therm;
};
+&pil_mss {
+ vdd_mss-supply = <&pm8953_s1>;
+ vdd_cx-supply = <&pm8953_s2_level>;
+ vdd_cx-voltage = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ vdd_mx-supply = <&pm8953_s7_level_ao>;
+ vdd_mx-uV = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ vdd_pll-supply = <&pm8953_l7>;
+};
+
+&soc {
+ qcom,lpass@c200000 {
+ vdd_cx-supply = <&pm8953_s2_level>;
+ };
+
+ qcom,pronto@a21b000 {
+ vdd_pronto_pll-supply = <&pm8953_l7>;
+ };
+
+ qcom,wcnss-wlan@0a000000 {
+ qcom,pronto-vddmx-supply = <&pm8953_s7_level_ao>;
+ qcom,pronto-vddcx-supply = <&pm8953_s2_level>;
+ qcom,pronto-vddpx-supply = <&pm8953_l5>;
+ qcom,iris-vddxo-supply = <&pm8953_l7>;
+ qcom,iris-vddrfa-supply = <&pm8953_l19>;
+ qcom,iris-vddpa-supply = <&pm8953_l9>;
+ qcom,iris-vdddig-supply = <&pm8953_l5>;
+ qcom,wcnss-adc_tm = <&pm8953_adc_tm>;
+ };
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi
index 5512297..24748dd 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi
@@ -40,6 +40,24 @@
status = "ok";
};
+&int_codec {
+ status = "okay";
+ qcom,model = "sdm439-sku1-snd-card";
+ qcom,msm-micbias1-ext-cap;
+ qcom,msm-micbias2-ext-cap;
+ qcom,msm-mbhc-hphl-swh = <1>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+ qcom,msm-hs-micbias-type = "external";
+};
+
+&wsa881x_i2c_f {
+ status = "okay";
+};
+
+&wsa881x_i2c_45 {
+ status = "okay";
+};
+
&sdhc_2 {
/* device core power supply */
vdd-supply = <&pm8953_l11>;
@@ -63,3 +81,22 @@
status = "ok";
};
+
+&soc {
+ gpio_keys {
+ compatible = "gpio-keys";
+ input-name = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_key_active>;
+
+ vol_up {
+ label = "volume_up";
+ gpios = <&tlmm 91 0x1>;
+ linux,input-type = <1>;
+ linux,code = <115>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ gpio-key,wakeup;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
index f9bef43..08c9e4f 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
@@ -174,7 +174,7 @@
qcom,hpm-min-load = <10000>;
status = "okay";
pm8953_l4: regulator-l4 {
- compatible = "qcom,rpm-smd-regulator-resource";
+ compatible = "qcom,rpm-smd-regulator";
regulator-name = "pm8953_l4";
qcom,set = <3>;
regulator-min-microvolt = <1800000>;
@@ -291,7 +291,7 @@
qcom,hpm-min-load = <5000>;
status = "okay";
pm8953_l14: regulator-l14 {
- compatible = "qcom,rpm-smd-regulator-resource";
+ compatible = "qcom,rpm-smd-regulator";
regulator-name = "pm8953_l14";
qcom,set = <3>;
regulator-min-microvolt = <1800000>;
@@ -309,7 +309,7 @@
qcom,hpm-min-load = <5000>;
status = "okay";
pm8953_l15: regulator-l15 {
- compatible = "qcom,rpm-smd-regulator-resource";
+ compatible = "qcom,rpm-smd-regulator";
regulator-name = "pm8953_l15";
qcom,set = <3>;
regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/qcom/sdm439.dtsi b/arch/arm64/boot/dts/qcom/sdm439.dtsi
index 13bcf1b..422a95f 100644
--- a/arch/arm64/boot/dts/qcom/sdm439.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439.dtsi
@@ -32,3 +32,58 @@
/delete-property/ qcom,mipi-csi-vdd-supply;
};
};
+
+&energy_costs {
+ compatible = "sched-energy";
+
+ CPU_COST_0: core-cost0 {
+ busy-cost-data = <
+ 8000000 137
+ 1001600 165
+ 1305600 207
+ 1497600 256
+ 1708800 327
+ 1958400 445
+ >;
+ idle-cost-data = <
+ 100 80 60 40
+ >;
+ };
+ CPU_COST_1: core-cost1 {
+ busy-cost-data = <
+ 8000000 45
+ 1001600 56
+ 1171200 71
+ 1305600 89
+ 1459200 120
+ >;
+ idle-cost-data = <
+ 40 20 10 8
+ >;
+ };
+ CLUSTER_COST_0: cluster-cost0 {
+ busy-cost-data = <
+ 8000000 49
+ 1001600 53
+ 1305600 61
+ 1497600 71
+ 1708800 85
+ 1958400 110
+ >;
+ idle-cost-data = <
+ 4 3 2 1
+ >;
+ };
+ CLUSTER_COST_1: cluster-cost1 {
+ busy-cost-data = <
+ 8000000 9
+ 1001600 10
+ 1171200 13
+ 1305600 15
+ 1459200 20
+ >;
+ idle-cost-data = <
+ 4 3 2 1
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm632-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm632-regulator.dtsi
index ed7ec2a..060b8996 100644
--- a/arch/arm64/boot/dts/qcom/sdm632-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm632-regulator.dtsi
@@ -13,6 +13,42 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
+&pm8953_s3 {
+ regulator-min-microvolt = <984000>;
+ regulator-max-microvolt = <1240000>;
+ qcom,init-voltage = <984000>;
+};
+
+&pm8953_s4 {
+ regulator-min-microvolt = <1036000>;
+ regulator-max-microvolt = <2040000>;
+ qcom,init-voltage = <1036000>;
+};
+
+&pm8953_l1 {
+ regulator-min-microvolt = <975000>;
+ regulator-max-microvolt = <1050000>;
+ qcom,init-voltage = <975000>;
+};
+
+&pm8953_l2 {
+ regulator-min-microvolt = <975000>;
+ regulator-max-microvolt = <1175000>;
+ qcom,init-voltage = <975000>;
+};
+
+&pm8953_l10 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+ qcom,init-voltage = <2800000>;
+};
+
+&pm8953_l22 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ qcom,init-voltage = <2800000>;
+};
+
&rpm_bus {
rpm-regulator-ldoc1 {
status = "okay";
@@ -150,7 +186,7 @@
qcom,cpr-corner-fmax-map = <1 2 3 4 7>;
qcom,cpr-voltage-ceiling =
- <720000 720000 790000 865000 920000
+ <720000 790000 865000 865000 920000
990000 1065000>;
qcom,cpr-voltage-floor =
@@ -162,7 +198,7 @@
qcom,corner-frequencies =
<614400000 883200000 1036800000
1363200000 1536000000 1670400000
- 1785600000>;
+ 1804800000>;
qcom,cpr-ro-scaling-factor =
<3600 3600 3830 2430 2520 2700 1790 1760
@@ -200,7 +236,7 @@
qcom,cpr-corner-fmax-map = <1 2 5>;
qcom,cpr-voltage-ceiling =
- <790000 865000 920000 990000 1065000>;
+ <865000 865000 920000 990000 1065000>;
qcom,cpr-voltage-floor =
<500000 500000 500000 500000 500000>;
@@ -209,7 +245,7 @@
qcom,corner-frequencies =
<1094400000 1401600000 1555200000
- 1785600000 1996200000>;
+ 1804800000 2016000000>;
qcom,cpr-ro-scaling-factor =
<3600 3600 3830 2430 2520 2700 1790 1760
diff --git a/arch/arm64/boot/dts/qcom/sdm632.dtsi b/arch/arm64/boot/dts/qcom/sdm632.dtsi
index f1fe11d..813b89d 100644
--- a/arch/arm64/boot/dts/qcom/sdm632.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm632.dtsi
@@ -22,6 +22,10 @@
compatible = "qcom,sdm632";
qcom,msm-id = <349 0x0>;
qcom,msm-name = "SDM632";
+
+ chosen {
+ /delete-property/ bootargs;
+ };
};
&clock_gcc_mdss {
@@ -788,42 +792,40 @@
&clock_cpu {
/delete-property/ vdd-cl-supply;
- status = "disabled";
compatible = "qcom,cpu-clock-sdm632";
reg = <0xb114000 0x68>,
<0xb014000 0x68>,
- <0xb016000 0x8>,
- <0xb116000 0x8>,
- <0xb1d0000 0x8>,
<0xb011050 0x8>,
<0xb111050 0x8>,
<0xb1d1050 0x8>,
- <0x00a412c 0x8>;
+ <0xb011050 0x8>,
+ <0xb111050 0x8>,
+ <0x00a4124 0x8>;
reg-names = "rcgwr-c0-base", "rcgwr-c1-base",
- "apcs-c1-pll-base", "apcs-c0-pll-base",
- "apcs-cci-pll-base", "apcs-c1-rcg-base",
- "apcs-c0-rcg-base", "apcs-cci-rcg-base",
- "efuse";
+ "apcs-c1-rcg-base", "apcs-c0-rcg-base",
+ "apcs-cci-rcg-base", "c1-mux",
+ "c0-mux", "efuse";
qcom,num-clusters = <2>;
+ vdd-c0-supply = <&apc0_pwrcl_vreg>;
+ vdd-c1-supply = <&apc1_perfcl_vreg>;
+ vdd-cci-supply = <&apc0_pwrcl_vreg>;
clocks = <&clock_gcc clk_xo_a_clk_src>;
clock-names = "xo_a";
qcom,speed0-bin-v0-c0 =
< 0 0>,
< 614400000 1>,
< 883200000 2>,
- < 1036200000 3>,
+ < 1036800000 3>,
< 1363200000 4>,
- < 1563000000 5>,
+ < 1536000000 5>,
< 1670400000 6>,
< 1785600000 7>;
qcom,speed0-bin-v0-c1 =
< 0 0>,
- < 633600000 1>,
- < 902400000 2>,
- < 1094400000 3>,
- < 1401600000 4>,
- < 1555200000 5>,
- < 1785600000 6>;
+ < 1094400000 1>,
+ < 1401600000 2>,
+ < 1555200000 3>,
+ < 1785600000 4>;
qcom,speed0-bin-v0-cci =
< 0 0>,
< 307200000 1>,
@@ -844,9 +846,9 @@
"cpu0_clk",
"cpu4_clk";
clocks =
- <&clock_cpu clk_a53_cci_clk >,
- <&clock_cpu clk_a53_pwr_clk >,
- <&clock_cpu clk_a53_perf_clk >;
+ <&clock_cpu clk_cci_clk >,
+ <&clock_cpu clk_pwr_clk >,
+ <&clock_cpu clk_perf_clk >;
qcom,governor-per-policy;
@@ -871,7 +873,7 @@
cci_cache: qcom,cci {
compatible = "devfreq-simple-dev";
clock-names = "devfreq_clk";
- clocks = <&clock_cpu clk_a53_cci_clk >;
+ clocks = <&clock_cpu clk_cci_clk >;
governor = "cpufreq";
freq-tbl-khz =
< 307200 >,
diff --git a/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
index f6ce559..e86117d 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
@@ -63,6 +63,7 @@
qcom,gpu-quirk-hfi-use-reg;
qcom,gpu-quirk-limit-uche-gbif-rw;
+ qcom,gpu-quirk-secvid-set-once;
/* <HZ/12> */
qcom,idle-timeout = <80>;
@@ -147,12 +148,14 @@
qcom,gpu-quirk-hfi-use-reg;
qcom,gpu-quirk-limit-uche-gbif-rw;
qcom,gpu-quirk-mmu-secure-cb-alt;
+ qcom,gpu-quirk-secvid-set-once;
};
qcom,soc-hw-revision-1 {
qcom,soc-hw-revision = <1>;
qcom,chipid = <0x06010501>;
qcom,gpu-quirk-hfi-use-reg;
+ qcom,gpu-quirk-secvid-set-once;
};
};
@@ -357,7 +360,7 @@
reg = <0>;
qcom,gpu-freq = <700000000>;
qcom,bus-freq = <11>;
- qcom,bus-min = <8>;
+ qcom,bus-min = <9>;
qcom,bus-max = <11>;
};
@@ -365,7 +368,7 @@
qcom,gpu-pwrlevel@1 {
reg = <1>;
qcom,gpu-freq = <650000000>;
- qcom,bus-freq = <11>;
+ qcom,bus-freq = <10>;
qcom,bus-min = <8>;
qcom,bus-max = <11>;
};
@@ -374,27 +377,27 @@
qcom,gpu-pwrlevel@2 {
reg = <2>;
qcom,gpu-freq = <565000000>;
- qcom,bus-freq = <11>;
+ qcom,bus-freq = <9>;
qcom,bus-min = <8>;
- qcom,bus-max = <11>;
+ qcom,bus-max = <10>;
};
/* SVS_L1 */
qcom,gpu-pwrlevel@3 {
reg = <3>;
qcom,gpu-freq = <430000000>;
- qcom,bus-freq = <11>;
- qcom,bus-min = <8>;
- qcom,bus-max = <11>;
+ qcom,bus-freq = <8>;
+ qcom,bus-min = <7>;
+ qcom,bus-max = <10>;
};
/* SVS */
qcom,gpu-pwrlevel@4 {
reg = <4>;
qcom,gpu-freq = <355000000>;
- qcom,bus-freq = <8>;
+ qcom,bus-freq = <7>;
qcom,bus-min = <5>;
- qcom,bus-max = <9>;
+ qcom,bus-max = <8>;
};
/* LOW SVS */
@@ -403,7 +406,7 @@
qcom,gpu-freq = <267000000>;
qcom,bus-freq = <6>;
qcom,bus-min = <4>;
- qcom,bus-max = <8>;
+ qcom,bus-max = <7>;
};
/* MIN SVS */
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 152b760..4d4e918 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -2469,6 +2469,7 @@
compatible = "qcom,msm-fastrpc-compute";
qcom,adsp-remoteheap-vmid = <22 37>;
qcom,fastrpc-adsp-audio-pdr;
+ qcom,fastrpc-adsp-sensors-pdr;
qcom,msm_fastrpc_compute_cb1 {
compatible = "qcom,msm-fastrpc-compute-cb";
@@ -2543,6 +2544,7 @@
label = "adsprpc-smd";
iommus = <&apps_smmu 0x1806 0x0>;
dma-coherent;
+ shared-cb;
};
};
@@ -2561,7 +2563,7 @@
qca,bt-vdd-ldo-current-level = <1>; /* LPM/PFM */
};
- qcom,icnss@18800000 {
+ icnss: qcom,icnss@18800000 {
compatible = "qcom,icnss";
reg = <0x18800000 0x800000>,
<0xa0000000 0x10000000>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-cdp-overlay.dts
new file mode 100644
index 0000000..a61d714
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-cdp-overlay.dts
@@ -0,0 +1,34 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm710-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-cdp.dts
new file mode 100644
index 0000000..a39ee9e
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-cdp.dts
@@ -0,0 +1,27 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp-overlay.dts
new file mode 100644
index 0000000..c64e623
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp-overlay.dts
@@ -0,0 +1,37 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L Ext. Audio Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <1 1>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
+&tavil_snd {
+ qcom,us-euro-gpios = <&tavil_us_euro_sw>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp.dts
new file mode 100644
index 0000000..0b4c3af
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp.dts
@@ -0,0 +1,31 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM 710 PM660 + PM660L Ext. Audio Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,board-id = <1 1>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
+&tavil_snd {
+ qcom,us-euro-gpios = <&tavil_us_euro_sw>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp-overlay.dts
new file mode 100644
index 0000000..058a3f1
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L Ext. Audio Codec MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <8 1>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp.dts
new file mode 100644
index 0000000..3920d78
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp.dts
@@ -0,0 +1,27 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM 710 PM660 + PM660L Ext. Audio Codec MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,board-id = <8 1>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp-overlay.dts
new file mode 100644
index 0000000..408a376
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp-overlay.dts
@@ -0,0 +1,38 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A Ext. Audio Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <1 1>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&tavil_snd {
+ qcom,us-euro-gpios = <&tavil_us_euro_sw>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp.dts
new file mode 100644
index 0000000..1257c64
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp.dts
@@ -0,0 +1,32 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM 710 PM660 + PM660A Ext. Audio Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,board-id = <1 1>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&tavil_snd {
+ qcom,us-euro-gpios = <&tavil_us_euro_sw>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp-overlay.dts
new file mode 100644
index 0000000..9a41edd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp-overlay.dts
@@ -0,0 +1,34 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A Ext. Audio Codec MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <8 1>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp.dts
new file mode 100644
index 0000000..e519095
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp.dts
@@ -0,0 +1,28 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM 710 PM660 + PM660A Ext. Audio Codec MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,board-id = <8 1>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-mtp-overlay.dts
new file mode 100644
index 0000000..aa8ba6a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-mtp.dts
new file mode 100644
index 0000000..c081d00
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-mtp.dts
@@ -0,0 +1,27 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp-overlay.dts
new file mode 100644
index 0000000..66afaad
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp-overlay.dts
@@ -0,0 +1,74 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&dsi_dual_nt35597_truly_video_display {
+ /delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_panel_pwr_supply_labibb_amoled {
+ qcom,panel-supply-entry@2 {
+ reg = <2>;
+ qcom,supply-name = "lab";
+ qcom,supply-min-voltage = <4600000>;
+ qcom,supply-max-voltage = <6100000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+
+ qcom,panel-supply-entry@3 {
+ reg = <3>;
+ qcom,supply-name = "ibb";
+ qcom,supply-min-voltage = <4000000>;
+ qcom,supply-max-voltage = <6300000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+
+ qcom,panel-supply-entry@4 {
+ reg = <4>;
+ qcom,supply-name = "oledb";
+ qcom,supply-min-voltage = <5000000>;
+ qcom,supply-max-voltage = <8100000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+};
+
+&dsi_rm67195_amoled_fhd_cmd_display {
+ qcom,dsi-display-active;
+ lab-supply = <&lab_regulator>;
+ ibb-supply = <&ibb_regulator>;
+ oledb-supply = <&pm660a_oledb>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp.dts
new file mode 100644
index 0000000..2786717
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp.dts
@@ -0,0 +1,68 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&dsi_dual_nt35597_truly_video_display {
+ /delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_panel_pwr_supply_labibb_amoled {
+ qcom,panel-supply-entry@2 {
+ reg = <2>;
+ qcom,supply-name = "lab";
+ qcom,supply-min-voltage = <4600000>;
+ qcom,supply-max-voltage = <6100000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+
+ qcom,panel-supply-entry@3 {
+ reg = <3>;
+ qcom,supply-name = "ibb";
+ qcom,supply-min-voltage = <4000000>;
+ qcom,supply-max-voltage = <6300000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+
+ qcom,panel-supply-entry@4 {
+ reg = <4>;
+ qcom,supply-name = "oledb";
+ qcom,supply-min-voltage = <5000000>;
+ qcom,supply-max-voltage = <8100000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+};
+
+&dsi_rm67195_amoled_fhd_cmd_display {
+ qcom,dsi-display-active;
+ lab-supply = <&lab_regulator>;
+ ibb-supply = <&ibb_regulator>;
+ oledb-supply = <&pm660a_oledb>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp-overlay.dts
new file mode 100644
index 0000000..d9b055d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp-overlay.dts
@@ -0,0 +1,34 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp.dts
new file mode 100644
index 0000000..97bbf2b
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp.dts
@@ -0,0 +1,28 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp-overlay.dts
new file mode 100644
index 0000000..7e9eaa7
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp-overlay.dts
@@ -0,0 +1,74 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-tasha-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A + Tasha Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <1 5>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&dsi_dual_nt35597_truly_video_display {
+ /delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_panel_pwr_supply_labibb_amoled {
+ qcom,panel-supply-entry@2 {
+ reg = <2>;
+ qcom,supply-name = "lab";
+ qcom,supply-min-voltage = <4600000>;
+ qcom,supply-max-voltage = <6100000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+
+ qcom,panel-supply-entry@3 {
+ reg = <3>;
+ qcom,supply-name = "ibb";
+ qcom,supply-min-voltage = <4000000>;
+ qcom,supply-max-voltage = <6300000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+
+ qcom,panel-supply-entry@4 {
+ reg = <4>;
+ qcom,supply-name = "oledb";
+ qcom,supply-min-voltage = <5000000>;
+ qcom,supply-max-voltage = <8100000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+};
+
+&dsi_rm67195_amoled_fhd_cmd_display {
+ qcom,dsi-display-active;
+ lab-supply = <&lab_regulator>;
+ ibb-supply = <&ibb_regulator>;
+ oledb-supply = <&pm660a_oledb>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp.dts
new file mode 100644
index 0000000..f7c654d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp.dts
@@ -0,0 +1,68 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-tasha-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A Tasha Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,board-id = <1 5>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&dsi_dual_nt35597_truly_video_display {
+ /delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_panel_pwr_supply_labibb_amoled {
+ qcom,panel-supply-entry@2 {
+ reg = <2>;
+ qcom,supply-name = "lab";
+ qcom,supply-min-voltage = <4600000>;
+ qcom,supply-max-voltage = <6100000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+
+ qcom,panel-supply-entry@3 {
+ reg = <3>;
+ qcom,supply-name = "ibb";
+ qcom,supply-min-voltage = <4000000>;
+ qcom,supply-max-voltage = <6300000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+
+ qcom,panel-supply-entry@4 {
+ reg = <4>;
+ qcom,supply-name = "oledb";
+ qcom,supply-min-voltage = <5000000>;
+ qcom,supply-max-voltage = <8100000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+};
+
+&dsi_rm67195_amoled_fhd_cmd_display {
+ qcom,dsi-display-active;
+ lab-supply = <&lab_regulator>;
+ ibb-supply = <&ibb_regulator>;
+ oledb-supply = <&pm660a_oledb>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-qrd-overlay.dts
new file mode 100644
index 0000000..803616d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-qrd-overlay.dts
@@ -0,0 +1,32 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-qrd.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L QRD";
+ compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <0x0002000b 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2-overlay.dts
new file mode 100644
index 0000000..ab3ce4d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2-overlay.dts
@@ -0,0 +1,51 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-qrd.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L QRD SKU2";
+ compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <0x0012000b 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
+&dsi_dual_nt36850_truly_cmd_display {
+ /delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_hx8399_truly_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
+&dsi_hx8399_truly_cmd_display {
+ qcom,dsi-display-active;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2.dts b/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2.dts
new file mode 100644
index 0000000..76b2862
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2.dts
@@ -0,0 +1,45 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-qrd.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L QRD SKU2";
+ compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+ qcom,board-id = <0x0012000b 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
+&dsi_dual_nt36850_truly_cmd_display {
+ /delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_hx8399_truly_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
+&dsi_hx8399_truly_cmd_display {
+ qcom,dsi-display-active;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-qrd.dts b/arch/arm64/boot/dts/qcom/sdm710-qrd.dts
new file mode 100644
index 0000000..e3cb7cc
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-qrd.dts
@@ -0,0 +1,26 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-qrd.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L QRD";
+ compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+ qcom,board-id = <0x0002000b 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp-overlay.dts
new file mode 100644
index 0000000..1632ebf
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp-overlay.dts
@@ -0,0 +1,33 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "sdm670-tasha-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L Tasha Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <1 5>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp.dts
new file mode 100644
index 0000000..456e3d2
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp.dts
@@ -0,0 +1,27 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "sdm670-tasha-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L Tasha Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,board-id = <1 5>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp-overlay.dts
new file mode 100644
index 0000000..fe05472
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp-overlay.dts
@@ -0,0 +1,34 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L, USB-C Audio, CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <1 2>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp.dts
new file mode 100644
index 0000000..ac7f59a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp.dts
@@ -0,0 +1,26 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L, USB-C Audio, CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,board-id = <1 2>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp-overlay.dts
new file mode 100644
index 0000000..846bee4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp-overlay.dts
@@ -0,0 +1,34 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660L, USB-C Audio, Ext. Audio Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <1 3>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp.dts
new file mode 100644
index 0000000..b3b8254
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp.dts
@@ -0,0 +1,28 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM 710 PM660+PM660L, USB-C Audio, Ext. Audio Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,board-id = <1 3>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp-overlay.dts
new file mode 100644
index 0000000..bfc9a7f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660L, USB-C Audio, Ext. Audio Codec MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <8 3>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp.dts
new file mode 100644
index 0000000..011e6ae
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp.dts
@@ -0,0 +1,28 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM 710 PM660+PM660L, USB-C Audio, Ext. Audio Codec MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,board-id = <8 3>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp-overlay.dts
new file mode 100644
index 0000000..f8642bb
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp-overlay.dts
@@ -0,0 +1,36 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660A, USB-C Audio, Ext. Audio Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <1 3>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp.dts
new file mode 100644
index 0000000..6e9d9d9
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp.dts
@@ -0,0 +1,29 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM 710 PM660+PM660A, USB-C Audio, Ext. Audio Codec CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,board-id = <1 3>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp-overlay.dts
new file mode 100644
index 0000000..c820950
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp-overlay.dts
@@ -0,0 +1,35 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660A, USB-C Audio, Ext. Audio Codec MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <8 3>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp.dts
new file mode 100644
index 0000000..11e7243
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp.dts
@@ -0,0 +1,29 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM 710 PM660+PM660A, USB-C Audio, Ext. Audio Codec MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,board-id = <8 3>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp-overlay.dts
new file mode 100644
index 0000000..a40ab83
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L, USB-C Audio, MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <8 2>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp.dts
new file mode 100644
index 0000000..1c8ab48
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp.dts
@@ -0,0 +1,27 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L, USB-C Audio, MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,board-id = <8 2>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp-overlay.dts
new file mode 100644
index 0000000..df4c2b9
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp-overlay.dts
@@ -0,0 +1,35 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A, USB-C Audio, CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <1 2>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp.dts
new file mode 100644
index 0000000..2f484b5
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp.dts
@@ -0,0 +1,28 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A, USB-C Audio, CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,board-id = <1 2>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp-overlay.dts
new file mode 100644
index 0000000..35f9570
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp-overlay.dts
@@ -0,0 +1,34 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A, USB-C Audio, MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,msm-id = <360 0x0>;
+ qcom,board-id = <8 2>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp.dts
new file mode 100644
index 0000000..f71b77a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp.dts
@@ -0,0 +1,28 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A, USB-C Audio, MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,board-id = <8 2>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710.dts b/arch/arm64/boot/dts/qcom/sdm710.dts
new file mode 100644
index 0000000..da971a3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710.dts
@@ -0,0 +1,21 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "sdm710.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710 SoC";
+ compatible = "qcom,sdm670";
+ qcom,board-id = <0 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710.dtsi b/arch/arm64/boot/dts/qcom/sdm710.dtsi
new file mode 100644
index 0000000..4a051b0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710.dtsi
@@ -0,0 +1,26 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "sdm670.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM710";
+ compatible = "qcom,sdm670";
+ qcom,msm-id = <360 0x0>;
+};
+
+&msm_gpu {
+ qcom,chipid = <0x06010500>;
+ /delete-property/qcom,gpu-quirk-limit-uche-gbif-rw;
+ /delete-property/qcom,soc-hw-rev-efuse;
+ /delete-node/qcom,soc-hw-revisions;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
index 8d4d7df..6e0bb861 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
@@ -562,6 +562,7 @@
&dsi_dual_nt35597_truly_cmd {
qcom,mdss-dsi-t-clk-post = <0x0D>;
qcom,mdss-dsi-t-clk-pre = <0x2D>;
+ qcom,ulps-enabled;
qcom,esd-check-enabled;
qcom,mdss-dsi-panel-status-check-mode = "reg_read";
qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a];
@@ -576,6 +577,8 @@
qcom,display-topology = <2 0 2>,
<1 0 2>;
qcom,default-topology-index = <0>;
+ qcom,partial-update-enabled = "single_roi";
+ qcom,panel-roi-alignment = <720 128 720 128 1440 128>;
};
};
};
@@ -829,6 +832,7 @@
&dsi_dual_nt35597_cmd {
qcom,mdss-dsi-t-clk-post = <0x0d>;
qcom,mdss-dsi-t-clk-pre = <0x2d>;
+ qcom,ulps-enabled;
qcom,mdss-dsi-display-timings {
timing@0 {
qcom,mdss-dsi-panel-timings = [00 1c 08 07 23 22 07 07
@@ -836,6 +840,8 @@
qcom,display-topology = <2 0 2>,
<1 0 2>;
qcom,default-topology-index = <0>;
+ qcom,partial-update-enabled = "single_roi";
+ qcom,panel-roi-alignment = <720 128 720 128 1440 128>;
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index aa16a77..82e55c4 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -2641,7 +2641,7 @@
<0 432 0>;
interrupt-names = "ipa-irq", "gsi-irq";
qcom,ipa-hw-ver = <13>; /* IPA core version = IPAv3.5.1 */
- qcom,ipa-hw-mode = <1>;
+ qcom,ipa-hw-mode = <0>;
qcom,ee = <0>;
qcom,use-ipa-tethering-bridge;
qcom,modem-cfg-emb-pipe-flt;
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index f5410c1..64c1e0b 100644
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -53,6 +53,7 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8953=y
CONFIG_ARCH_MSM8937=y
+CONFIG_ARCH_MSM8917=y
CONFIG_ARCH_SDM450=y
CONFIG_ARCH_SDM632=y
CONFIG_ARCH_SDM429=y
@@ -293,6 +294,8 @@
# CONFIG_SERIO_SERPORT is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_SMD=y
CONFIG_DIAG_CHAR=y
@@ -395,6 +398,8 @@
CONFIG_MSM_VIDC_3X_GOVERNORS=y
CONFIG_MSM_SDE_ROTATOR=y
CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
+CONFIG_RADIO_IRIS=y
+CONFIG_RADIO_IRIS_TRANSPORT=y
CONFIG_QCOM_KGSL=y
CONFIG_DRM=y
CONFIG_DRM_SDE_EVTLOG_DEBUG=y
@@ -517,6 +522,7 @@
CONFIG_QPNP_COINCELL=y
CONFIG_QPNP_REVID=y
CONFIG_USB_BAM=y
+CONFIG_MSM_RMNET_BAM=y
CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_MAILBOX=y
@@ -558,6 +564,7 @@
CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
CONFIG_QCOM_BIMC_BWMON=y
CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
+CONFIG_DEVFREQ_SIMPLE_DEV=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_SPDM_SCM=y
CONFIG_DEVFREQ_SPDM=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index b9f4d9d..a287b1c 100644
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -57,6 +57,7 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8953=y
CONFIG_ARCH_MSM8937=y
+CONFIG_ARCH_MSM8917=y
CONFIG_ARCH_SDM450=y
CONFIG_ARCH_SDM632=y
CONFIG_ARCH_SDM429=y
@@ -303,6 +304,8 @@
# CONFIG_SERIO_SERPORT is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_MSM_HS=y
@@ -407,6 +410,8 @@
CONFIG_MSM_VIDC_3X_GOVERNORS=y
CONFIG_MSM_SDE_ROTATOR=y
CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
+CONFIG_RADIO_IRIS=y
+CONFIG_RADIO_IRIS_TRANSPORT=y
CONFIG_QCOM_KGSL=y
CONFIG_DRM=y
CONFIG_DRM_SDE_EVTLOG_DEBUG=y
@@ -531,6 +536,7 @@
CONFIG_QPNP_COINCELL=y
CONFIG_QPNP_REVID=y
CONFIG_USB_BAM=y
+CONFIG_MSM_RMNET_BAM=y
CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_MAILBOX=y
diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c b/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c
index 20b8e34..7121261 100644
--- a/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c
+++ b/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c
@@ -424,8 +424,8 @@
pdb->in.pll_ip_trim = 4; /* 4, reg: 0x0404 */
pdb->in.pll_cpcset_cur = 1; /* 1, reg: 0x04f0, bit 0 - 2 */
pdb->in.pll_cpmset_cur = 1; /* 1, reg: 0x04f0, bit 3 - 5 */
- pdb->in.pll_icpmset = 4; /* 4, reg: 0x04fc, bit 3 - 5 */
- pdb->in.pll_icpcset = 4; /* 4, reg: 0x04fc, bit 0 - 2 */
+ pdb->in.pll_icpmset = 7; /* 7, reg: 0x04fc, bit 3 - 5 */
+ pdb->in.pll_icpcset = 7; /* 7, reg: 0x04fc, bit 0 - 2 */
pdb->in.pll_icpmset_p = 0; /* 0, reg: 0x04f4, bit 0 - 2 */
pdb->in.pll_icpmset_m = 0; /* 0, reg: 0x04f4, bit 3 - 5 */
pdb->in.pll_icpcset_p = 0; /* 0, reg: 0x04f8, bit 0 - 2 */
diff --git a/drivers/gpu/drm/bridge/lt9611.c b/drivers/gpu/drm/bridge/lt9611.c
index 887dd6f..dd2d54f 100644
--- a/drivers/gpu/drm/bridge/lt9611.c
+++ b/drivers/gpu/drm/bridge/lt9611.c
@@ -24,6 +24,7 @@
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
+#include <linux/component.h>
#include <linux/of_gpio.h>
#include <linux/of_graph.h>
#include <linux/of_irq.h>
@@ -1687,6 +1688,22 @@
return 0;
}
+static void lt9611_set_preferred_mode(struct drm_connector *connector)
+{
+ struct lt9611 *pdata = connector_to_lt9611(connector);
+ struct drm_display_mode *mode;
+ const char *string;
+
+ /* use specified mode as preferred */
+ if (!of_property_read_string(pdata->dev->of_node,
+ "lt,preferred-mode", &string)) {
+ list_for_each_entry(mode, &connector->probed_modes, head) {
+ if (!strcmp(mode->name, string))
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+ }
+ }
+}
+
static int lt9611_connector_get_modes(struct drm_connector *connector)
{
struct lt9611 *pdata = connector_to_lt9611(connector);
@@ -1719,12 +1736,11 @@
pdata->hdmi_mode = drm_detect_hdmi_monitor(edid);
pr_debug("hdmi_mode = %d\n", pdata->hdmi_mode);
- /* TODO: this should not be hard coded */
- drm_set_preferred_mode(connector, 1920, 1080);
-
kfree(edid);
}
+ lt9611_set_preferred_mode(connector);
+
return count;
}
@@ -1997,6 +2013,20 @@
sysfs_remove_group(&dev->kobj, <9611_sysfs_attr_grp);
}
+static int lt9611_bind(struct device *dev, struct device *master, void *data)
+{
+ return 0;
+}
+
+static void lt9611_unbind(struct device *dev, struct device *master, void *data)
+{
+}
+
+static const struct component_ops lt9611_comp_ops = {
+ .bind = lt9611_bind,
+ .unbind = lt9611_unbind,
+};
+
static int lt9611_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -2078,6 +2108,10 @@
drm_bridge_add(&pdata->bridge);
+ ret = component_add(&client->dev, <9611_comp_ops);
+ if (ret)
+ pr_err("component add failed, rc=%d\n", ret);
+
return ret;
err_sysfs_init:
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c
index 189a5c3..434d383 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c
@@ -1078,12 +1078,7 @@
struct dsi_clk_mngr *mngr;
struct dsi_link_clks *l_clks;
- if (!client) {
- pr_err("%s: Invalid arg\n", __func__);
- return -EINVAL;
- }
mngr = c->mngr;
-
mutex_lock(&mngr->clk_mutex);
l_clks = mngr->link_clks;
@@ -1133,8 +1128,6 @@
mutex_lock(&dsi_mngr_clk_mutex);
rc = dsi_display_link_clk_force_update(handle);
- if (rc && (rc != -EAGAIN))
- pr_err("%s: failed set clk state, rc = %d\n", __func__, rc);
mutex_unlock(&dsi_mngr_clk_mutex);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index c9e8a01..1ab1de6 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -1333,6 +1333,9 @@
u32 dlen, diff, rlen = msg->rx_len;
unsigned char *buff;
char cmd;
+ struct dsi_cmd_desc *of_cmd;
+
+ of_cmd = container_of(msg, struct dsi_cmd_desc, msg);
if (msg->rx_len <= 2) {
short_resp = true;
@@ -1366,6 +1369,13 @@
pr_err("Message transmission failed, rc=%d\n", rc);
goto error;
}
+ /*
+ * wait before reading rdbk_data register, if any delay is
+ * required after sending the read command.
+ */
+ if (of_cmd && of_cmd->post_wait_ms)
+ usleep_range(of_cmd->post_wait_ms * 1000,
+ ((of_cmd->post_wait_ms * 1000) + 10));
dlen = dsi_ctrl->hw.ops.get_cmd_read_data(&dsi_ctrl->hw,
buff, total_bytes_read,
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
index f0e7ba6..c1af52f 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
@@ -1487,7 +1487,7 @@
rc = readl_poll_timeout(ctrl->base + DSI_STATUS, val,
!(val & cmd_mode_mdp_busy_mask), sleep_us, timeout_us);
if (rc)
- pr_err("%s: waiting failed, ret=%d\n", __func__, rc);
+ pr_err("%s: timed out waiting for idle\n", __func__);
return rc;
}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 12ca46e..5e5a3ee 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -349,7 +349,7 @@
static void dsi_display_register_te_irq(struct dsi_display *display)
{
- int rc;
+ int rc = 0;
struct platform_device *pdev;
struct device *dev;
@@ -365,18 +365,31 @@
return;
}
+ if (!gpio_is_valid(display->disp_te_gpio)) {
+ rc = -EINVAL;
+ goto error;
+ }
+
+ init_completion(&display->esd_te_gate);
+
rc = devm_request_irq(dev, gpio_to_irq(display->disp_te_gpio),
dsi_display_panel_te_irq_handler, IRQF_TRIGGER_FALLING,
"TE_GPIO", display);
if (rc) {
pr_err("TE request_irq failed for ESD rc:%d\n", rc);
- return;
+ goto error;
}
- init_completion(&display->esd_te_gate);
-
disable_irq(gpio_to_irq(display->disp_te_gpio));
display->is_te_irq_enabled = false;
+
+ return;
+
+error:
+ /* disable the TE based ESD check */
+ pr_warn("Unable to register for TE IRQ\n");
+ if (display->panel->esd_config.status_mode == ESD_MODE_PANEL_TE)
+ display->panel->esd_config.esd_enabled = false;
}
static bool dsi_display_is_te_based_esd(struct dsi_display *display)
@@ -555,14 +568,14 @@
lenp = config->status_valid_params ?: config->status_cmds_rlen;
count = config->status_cmd.count;
cmds = config->status_cmd.cmds;
- if (cmds->last_command) {
- cmds->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;
- flags |= DSI_CTRL_CMD_LAST_COMMAND;
- }
flags |= (DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_READ);
for (i = 0; i < count; ++i) {
memset(config->status_buf, 0x0, SZ_4K);
+ if (cmds[i].last_command) {
+ cmds[i].msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;
+ flags |= DSI_CTRL_CMD_LAST_COMMAND;
+ }
cmds[i].msg.rx_buf = config->status_buf;
cmds[i].msg.rx_len = config->status_cmds_rlen[i];
rc = dsi_ctrl_cmd_transfer(ctrl->ctrl, &cmds[i].msg, flags);
@@ -646,7 +659,7 @@
rc = dsi_display_validate_status(ctrl, display->panel);
if (rc <= 0) {
- pr_err("[%s] read status failed on master,rc=%d\n",
+ pr_err("[%s] read status failed on slave,rc=%d\n",
display->name, rc);
goto exit;
}
@@ -4079,11 +4092,6 @@
{
int rc = 0;
- if (!display || !display->panel) {
- pr_err("Invalid params\n");
- return -EINVAL;
- }
-
rc = dsi_display_link_clk_force_update_ctrl(display->dsi_clk_handle);
if (!rc) {
@@ -4091,8 +4099,6 @@
display->cached_clk_rate);
atomic_set(&display->clkrate_change_pending, 0);
- } else if (rc == -EAGAIN) {
- pr_info("Clock is disabled, update it next time\n");
} else {
pr_err("Failed to configure dsi bit clock '%d'. rc = %d\n",
display->cached_clk_rate, rc);
@@ -4108,7 +4114,7 @@
int i;
pr_debug("%s:bit rate:%d\n", __func__, bit_clk_rate);
- if (!display || !display->panel) {
+ if (!display->panel) {
pr_err("Invalid params\n");
return -EINVAL;
}
@@ -4187,11 +4193,6 @@
struct dsi_display_ctrl *m_ctrl;
struct dsi_ctrl *ctrl;
- if (!dev) {
- pr_err("Invalid device\n");
- return -EINVAL;
- }
-
display = dev_get_drvdata(dev);
if (!display) {
pr_err("Invalid display\n");
@@ -4207,7 +4208,7 @@
byte_clk_rate * 8;
rc = snprintf(buf, PAGE_SIZE, "%d\n", display->cached_clk_rate);
- pr_info("%s: read dsi clk rate %d\n", __func__,
+ pr_debug("%s: read dsi clk rate %d\n", __func__,
display->cached_clk_rate);
mutex_unlock(&display->display_lock);
@@ -4222,11 +4223,6 @@
int clk_rate;
struct dsi_display *display;
- if (!dev) {
- pr_err("Invalid device\n");
- return -EINVAL;
- }
-
display = dev_get_drvdata(dev);
if (!display) {
pr_err("Invalid display\n");
@@ -6030,11 +6026,8 @@
int ret = 0;
ret = dsi_ctrl_wait_for_cmd_mode_mdp_idle(ctrl);
- if (ret) {
- pr_info("Failed to wait for cmd engine not to be busy sending data from MDP, rc: %d\n",
- ret);
+ if (ret)
goto wait_failure;
- }
}
/*
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index d5437d0..15fff53 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1806,6 +1806,27 @@
return ret;
}
+static int add_bridge_components(struct device *dev,
+ struct component_match **matchptr)
+{
+ struct device_node *node;
+
+ if (of_device_is_compatible(dev->of_node, "qcom,sde-kms")) {
+ struct device_node *np = dev->of_node;
+ unsigned int i;
+
+ for (i = 0; ; i++) {
+ node = of_parse_phandle(np, "bridges", i);
+ if (!node)
+ break;
+
+ component_match_add(dev, matchptr, compare_of, node);
+ }
+ }
+
+ return 0;
+}
+
struct msm_gem_address_space *
msm_gem_smmu_address_space_get(struct drm_device *dev,
unsigned int domain)
@@ -1897,6 +1918,10 @@
if (ret)
return ret;
+ ret = add_bridge_components(&pdev->dev, &match);
+ if (ret)
+ return ret;
+
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
return component_master_add_with_match(&pdev->dev, &msm_drm_ops, match);
}
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index f908e7f..db0c1d4 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -414,6 +414,10 @@
if (!c_conn)
return;
+ /* Return if there is no change in ESD status check condition */
+ if (en == c_conn->esd_status_check)
+ return;
+
sde_connector_get_info(connector, &info);
if (c_conn->ops.check_status &&
(info.capabilities & MSM_DISPLAY_ESD_ENABLED)) {
@@ -430,9 +434,11 @@
/* Schedule ESD status check */
schedule_delayed_work(&c_conn->status_work,
msecs_to_jiffies(interval));
+ c_conn->esd_status_check = true;
} else {
/* Cancel any pending ESD status check */
cancel_delayed_work_sync(&c_conn->status_work);
+ c_conn->esd_status_check = false;
}
}
}
@@ -482,11 +488,12 @@
}
c_conn->last_panel_power_mode = mode;
- if (mode != SDE_MODE_DPMS_ON) {
- mutex_unlock(&c_conn->lock);
+ mutex_unlock(&c_conn->lock);
+ if (mode != SDE_MODE_DPMS_ON)
sde_connector_schedule_status_work(connector, false);
- mutex_lock(&c_conn->lock);
- }
+ else
+ sde_connector_schedule_status_work(connector, true);
+ mutex_lock(&c_conn->lock);
return rc;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.h b/drivers/gpu/drm/msm/sde/sde_connector.h
index 1495622..101fc01 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.h
+++ b/drivers/gpu/drm/msm/sde/sde_connector.h
@@ -356,6 +356,8 @@
u32 force_panel_dead;
u32 esd_status_interval;
+ bool esd_status_check;
+
bool bl_scale_dirty;
u32 bl_scale;
u32 bl_scale_ad;
diff --git a/drivers/gpu/drm/msm/sde/sde_formats.c b/drivers/gpu/drm/msm/sde/sde_formats.c
index d09054e..719b8c1 100644
--- a/drivers/gpu/drm/msm/sde/sde_formats.c
+++ b/drivers/gpu/drm/msm/sde/sde_formats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -275,97 +275,97 @@
INTERLEAVED_RGB_FMT(ARGB1555,
COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
- C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+ C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
true, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(ABGR1555,
COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
- C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+ C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
true, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(RGBA5551,
COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
- C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
true, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(BGRA5551,
COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
- C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+ C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
true, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(XRGB1555,
COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
- C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+ C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
false, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(XBGR1555,
COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
- C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+ C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
false, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(RGBX5551,
COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
- C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
false, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(BGRX5551,
COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
- C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+ C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
false, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(ARGB4444,
COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
- C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+ C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
true, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(ABGR4444,
COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
- C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+ C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
true, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(RGBA4444,
COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
- C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
true, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(BGRA4444,
COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
- C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+ C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
true, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(XRGB4444,
COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
- C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+ C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
false, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(XBGR4444,
COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
- C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+ C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
false, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(RGBX4444,
COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
- C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
false, 2, 0,
SDE_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(BGRX4444,
COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
- C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+ C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
false, 2, 0,
SDE_FETCH_LINEAR, 1),
diff --git a/drivers/gpu/drm/msm/sde_rsc.c b/drivers/gpu/drm/msm/sde_rsc.c
index ca4f0da..8179b10 100644
--- a/drivers/gpu/drm/msm/sde_rsc.c
+++ b/drivers/gpu/drm/msm/sde_rsc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, 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
@@ -882,23 +882,22 @@
int sde_rsc_client_vote(struct sde_rsc_client *caller_client,
u32 bus_id, u64 ab_vote, u64 ib_vote)
{
- int rc = 0;
+ int rc = 0, rsc_index;
struct sde_rsc_priv *rsc;
- if (!caller_client) {
- pr_err("invalid client for ab/ib vote\n");
- return -EINVAL;
- } else if (caller_client->rsc_index >= MAX_RSC_COUNT) {
+ if (caller_client && caller_client->rsc_index >= MAX_RSC_COUNT) {
pr_err("invalid rsc index\n");
return -EINVAL;
}
- rsc = rsc_prv_list[caller_client->rsc_index];
+ rsc_index = caller_client ? caller_client->rsc_index : SDE_RSC_INDEX;
+ rsc = rsc_prv_list[rsc_index];
if (!rsc)
return -EINVAL;
pr_debug("client:%s ab:%llu ib:%llu\n",
- caller_client->name, ab_vote, ib_vote);
+ caller_client ? caller_client->name : "unknown",
+ ab_vote, ib_vote);
mutex_lock(&rsc->client_lock);
rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
diff --git a/drivers/gpu/drm/msm/sde_rsc_hw.c b/drivers/gpu/drm/msm/sde_rsc_hw.c
index d40b0ad..5049758 100644
--- a/drivers/gpu/drm/msm/sde_rsc_hw.c
+++ b/drivers/gpu/drm/msm/sde_rsc_hw.c
@@ -405,6 +405,9 @@
if (rc)
pr_err("vdd reg is not enabled yet\n");
+ dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0,
+ 0x3, rsc->debug_mode);
+
rsc_event_trigger(rsc, SDE_RSC_EVENT_POST_CORE_RESTORE);
return rc;
@@ -477,19 +480,33 @@
if (seq_busy && (current_mode == SDE_RSC_MODE_0_VAL ||
current_mode == SDE_RSC_MODE_1_VAL)) {
- dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_LO,
- 0xffffffff, rsc->debug_mode);
dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_HI,
+ 0xffffff, rsc->debug_mode);
+ dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_LO,
0xffffffff, rsc->debug_mode);
/* unstick f1 qtimer */
wmb();
- dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_LO,
- 0x0, rsc->debug_mode);
dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_HI,
0x0, rsc->debug_mode);
+ dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_LO,
+ 0x0, rsc->debug_mode);
/* manually trigger f1 qtimer interrupt */
wmb();
+
+ dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_HI,
+ 0xffffff, rsc->debug_mode);
+ dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_LO,
+ 0xffffffff, rsc->debug_mode);
+ /* unstick f0 qtimer */
+ wmb();
+
+ dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_HI,
+ 0x0, rsc->debug_mode);
+ dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_LO,
+ 0x0, rsc->debug_mode);
+ /* manually trigger f0 qtimer interrupt */
+ wmb();
}
}
@@ -506,6 +523,8 @@
return rc;
}
+ dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0,
+ 0x7, rsc->debug_mode);
rsc_event_trigger(rsc, SDE_RSC_EVENT_PRE_CORE_PC);
for (i = 0; i <= MAX_MODE2_ENTRY_TRY; i++) {
diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h
index 2aff383..1fb76dd 100644
--- a/drivers/gpu/msm/adreno-gpulist.h
+++ b/drivers/gpu/msm/adreno-gpulist.h
@@ -379,4 +379,22 @@
.gpmu_major = 0x1,
.gpmu_minor = 0x003,
},
+ {
+ .gpurev = ADRENO_REV_A616,
+ .core = 6,
+ .major = 1,
+ .minor = 6,
+ .patchid = ANY_ID,
+ .features = ADRENO_64BIT | ADRENO_RPMH | ADRENO_PREEMPTION |
+ ADRENO_GPMU | ADRENO_CONTENT_PROTECTION | ADRENO_IFPC,
+ .sqefw_name = "a630_sqe.fw",
+ .zap_name = "a615_zap",
+ .gpudev = &adreno_a6xx_gpudev,
+ .gmem_size = SZ_512K,
+ .num_protected_regs = 0x20,
+ .busy_mask = 0xFFFFFFFE,
+ .gpmufw_name = "a630_gmu.bin",
+ .gpmu_major = 0x1,
+ .gpmu_minor = 0x003,
+ },
};
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 8785d62..9ca22fd 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -211,6 +211,7 @@
ADRENO_REV_A530 = 530,
ADRENO_REV_A540 = 540,
ADRENO_REV_A615 = 615,
+ ADRENO_REV_A616 = 616,
ADRENO_REV_A630 = 630,
};
@@ -1251,6 +1252,7 @@
}
ADRENO_TARGET(a615, ADRENO_REV_A615)
+ADRENO_TARGET(a616, ADRENO_REV_A616)
ADRENO_TARGET(a630, ADRENO_REV_A630)
static inline int adreno_is_a630v1(struct adreno_device *adreno_dev)
@@ -1878,7 +1880,7 @@
static inline bool adreno_has_gbif(struct adreno_device *adreno_dev)
{
- if (adreno_is_a615(adreno_dev))
+ if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev))
return true;
else
return false;
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index daf314d..7096d7c 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -61,6 +61,7 @@
static const struct adreno_vbif_platform a6xx_vbif_platforms[] = {
{ adreno_is_a630, a630_vbif },
{ adreno_is_a615, a615_gbif },
+ { adreno_is_a616, a615_gbif },
};
@@ -251,6 +252,7 @@
} a6xx_hwcg_registers[] = {
{adreno_is_a630, a630_hwcg_regs, ARRAY_SIZE(a630_hwcg_regs)},
{adreno_is_a615, a615_hwcg_regs, ARRAY_SIZE(a615_hwcg_regs)},
+ {adreno_is_a616, a615_hwcg_regs, ARRAY_SIZE(a615_hwcg_regs)},
};
static struct a6xx_protected_regs {
@@ -499,7 +501,7 @@
static inline unsigned int
__get_rbbm_clock_cntl_on(struct adreno_device *adreno_dev)
{
- if (adreno_is_a615(adreno_dev))
+ if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev))
return 0x8AA8AA82;
else
return 0x8AA8AA02;
@@ -508,7 +510,7 @@
static inline unsigned int
__get_gmu_ao_cgc_mode_cntl(struct adreno_device *adreno_dev)
{
- if (adreno_is_a615(adreno_dev))
+ if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev))
return 0x00000222;
else
return 0x00020202;
@@ -517,7 +519,7 @@
static inline unsigned int
__get_gmu_ao_cgc_delay_cntl(struct adreno_device *adreno_dev)
{
- if (adreno_is_a615(adreno_dev))
+ if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev))
return 0x00000111;
else
return 0x00010111;
@@ -526,7 +528,7 @@
static inline unsigned int
__get_gmu_ao_cgc_hyst_cntl(struct adreno_device *adreno_dev)
{
- if (adreno_is_a615(adreno_dev))
+ if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev))
return 0x00000555;
else
return 0x00005555;
@@ -643,7 +645,7 @@
+ sizeof(a6xx_ifpc_pwrup_reglist), a6xx_pwrup_reglist,
sizeof(a6xx_pwrup_reglist));
- if (adreno_is_a615(adreno_dev)) {
+ if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev)) {
for (i = 0; i < ARRAY_SIZE(a615_pwrup_reglist); i++) {
r = &a615_pwrup_reglist[i];
kgsl_regread(KGSL_DEVICE(adreno_dev),
@@ -3587,6 +3589,7 @@
void (*func)(struct adreno_device *adreno_dev);
} a6xx_efuse_funcs[] = {
{ adreno_is_a615, a6xx_efuse_speed_bin },
+ { adreno_is_a616, a6xx_efuse_speed_bin },
};
static void a6xx_check_features(struct adreno_device *adreno_dev)
diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c
index afd1be5..7376a38 100644
--- a/drivers/gpu/msm/adreno_a6xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c
@@ -1169,7 +1169,8 @@
block_id = block->block_id;
/* GMU_GX data is read using the GMU_CX block id on A630 */
- if ((adreno_is_a630(adreno_dev) || adreno_is_a615(adreno_dev)) &&
+ if ((adreno_is_a630(adreno_dev) || adreno_is_a615(adreno_dev) ||
+ adreno_is_a616(adreno_dev)) &&
(block_id == A6XX_DBGBUS_GMU_GX))
block_id = A6XX_DBGBUS_GMU_CX;
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index a9c2252..3702893 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2018, 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
@@ -716,6 +716,18 @@
align = (memdesc->flags & KGSL_MEMALIGN_MASK) >> KGSL_MEMALIGN_SHIFT;
+ /*
+ * As 1MB is the max supported page size, use the alignment
+ * corresponding to 1MB page to make sure higher order pages
+ * are used if possible for a given memory size. Also, we
+ * don't need to update alignment in memdesc flags in case
+ * higher order page is used, as memdesc flags represent the
+ * virtual alignment specified by the user which is anyways
+ * getting satisfied.
+ */
+ if (align < ilog2(SZ_1M))
+ align = ilog2(SZ_1M);
+
page_size = kgsl_get_page_size(size, align);
/*
diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c
index 59ca208..1f38574 100644
--- a/drivers/hwmon/qpnp-adc-voltage.c
+++ b/drivers/hwmon/qpnp-adc-voltage.c
@@ -109,7 +109,7 @@
#define QPNP_VADC_CONV_TIME_MIN 1000
#define QPNP_VADC_CONV_TIME_MAX 1100
#define QPNP_ADC_COMPLETION_TIMEOUT HZ
-#define QPNP_VADC_ERR_COUNT 50
+#define QPNP_VADC_ERR_COUNT 20
#define QPNP_OP_MODE_SHIFT 3
#define QPNP_VADC_THR_LSB_MASK(val) (val & 0xff)
@@ -277,42 +277,6 @@
return -EINVAL;
}
-static int32_t qpnp_vadc_warm_rst_configure(struct qpnp_vadc_chip *vadc)
-{
- int rc = 0;
- u8 data = 0, buf = 0;
-
- buf = QPNP_VADC_ACCESS_DATA;
- rc = qpnp_vadc_write_reg(vadc, QPNP_VADC_ACCESS, &buf, 1);
- if (rc < 0) {
- pr_err("VADC write access failed\n");
- return rc;
- }
-
- rc = qpnp_vadc_read_reg(vadc, QPNP_VADC_PERH_RESET_CTL3, &data, 1);
- if (rc < 0) {
- pr_err("VADC perh reset ctl3 read failed\n");
- return rc;
- }
-
- buf = QPNP_VADC_ACCESS_DATA;
- rc = qpnp_vadc_write_reg(vadc, QPNP_VADC_ACCESS, &buf, 1);
- if (rc < 0) {
- pr_err("VADC write access failed\n");
- return rc;
- }
-
- data |= QPNP_FOLLOW_WARM_RB;
-
- rc = qpnp_vadc_write_reg(vadc, QPNP_VADC_PERH_RESET_CTL3, &data, 1);
- if (rc < 0) {
- pr_err("VADC perh reset ctl3 write failed\n");
- return rc;
- }
-
- return 0;
-}
-
static int32_t qpnp_vadc_mode_select(struct qpnp_vadc_chip *vadc, u8 mode_ctl)
{
int rc;
@@ -422,20 +386,7 @@
static int qpnp_vadc_hc_read_data(struct qpnp_vadc_chip *vadc, int *data)
{
int rc = 0;
- u8 buf = 0, rslt_lsb = 0, rslt_msb = 0;
-
- /* Set hold bit */
- rc = qpnp_vadc_read_reg(vadc, QPNP_VADC_HC1_DATA_HOLD_CTL, &buf, 1);
- if (rc) {
- pr_err("debug register dump failed\n");
- return rc;
- }
- buf |= QPNP_VADC_HC1_DATA_HOLD_CTL_FIELD;
- rc = qpnp_vadc_write_reg(vadc, QPNP_VADC_HC1_DATA_HOLD_CTL, &buf, 1);
- if (rc) {
- pr_err("debug register dump failed\n");
- return rc;
- }
+ u8 rslt_lsb = 0, rslt_msb = 0;
rc = qpnp_vadc_read_reg(vadc, QPNP_VADC_HC1_DATA0, &rslt_lsb, 1);
if (rc < 0) {
@@ -462,11 +413,6 @@
return rc;
}
- /* De-assert hold bit */
- buf &= ~QPNP_VADC_HC1_DATA_HOLD_CTL_FIELD;
- rc = qpnp_vadc_write_reg(vadc, QPNP_VADC_HC1_DATA_HOLD_CTL, &buf, 1);
- if (rc)
- pr_err("de-asserting hold bit failed\n");
return rc;
}
@@ -2757,12 +2703,6 @@
goto err_setup;
}
- rc = qpnp_vadc_warm_rst_configure(vadc);
- if (rc < 0) {
- pr_err("Setting perp reset on warm reset failed %d\n", rc);
- goto err_setup;
- }
-
INIT_WORK(&vadc->trigger_completion_work, qpnp_vadc_work);
vadc->vadc_recalib_check = of_property_read_bool(node,
diff --git a/drivers/hwtracing/coresight/coresight-byte-cntr.c b/drivers/hwtracing/coresight/coresight-byte-cntr.c
index 5173770..9fa3e0f 100644
--- a/drivers/hwtracing/coresight/coresight-byte-cntr.c
+++ b/drivers/hwtracing/coresight/coresight-byte-cntr.c
@@ -162,7 +162,7 @@
goto err0;
}
- if (tmcdrvdata->mem_type == TMC_ETR_MEM_TYPE_CONTIG)
+ if (tmcdrvdata->memtype == TMC_ETR_MEM_TYPE_CONTIG)
tmc_etr_read_bytes(byte_cntr_data, ppos,
byte_cntr_data->block_size, &len,
&bufp);
@@ -172,7 +172,7 @@
} else {
if (!atomic_read(&byte_cntr_data->irq_cnt)) {
- if (tmcdrvdata->mem_type == TMC_ETR_MEM_TYPE_CONTIG)
+ if (tmcdrvdata->memtype == TMC_ETR_MEM_TYPE_CONTIG)
tmc_etr_flush_bytes(ppos,
byte_cntr_data->block_size,
&len);
@@ -184,7 +184,7 @@
if (!len)
goto err0;
} else {
- if (tmcdrvdata->mem_type == TMC_ETR_MEM_TYPE_CONTIG)
+ if (tmcdrvdata->memtype == TMC_ETR_MEM_TYPE_CONTIG)
tmc_etr_read_bytes(byte_cntr_data, ppos,
byte_cntr_data->block_size,
&len, &bufp);
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c
index 6597fd6..c9c22d0 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.c
+++ b/drivers/hwtracing/coresight/coresight-tmc.c
@@ -28,10 +28,13 @@
#include <linux/of.h>
#include <linux/coresight.h>
#include <linux/amba/bus.h>
+#include <soc/qcom/memory_dump.h>
#include "coresight-priv.h"
#include "coresight-tmc.h"
+#define TMC_REG_DUMP_MAGIC 0x42445953
+
void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
{
/* Ensure formatter, unformatter and hardware fifo are empty */
@@ -61,11 +64,85 @@
tmc_wait_for_tmcready(drvdata);
}
+static void __tmc_reg_dump(struct tmc_drvdata *drvdata)
+{
+ struct dump_vaddr_entry *dump_entry;
+ struct msm_dump_data *dump_data;
+ uint32_t *reg_buf;
+
+ if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
+ dump_entry = get_msm_dump_ptr(MSM_DUMP_DATA_TMC_ETR_REG);
+ dev_dbg(drvdata->dev, "%s: TMC ETR dump entry ptr is %pK\n",
+ __func__, dump_entry);
+ } else if (drvdata->config_type == TMC_CONFIG_TYPE_ETB ||
+ drvdata->config_type == TMC_CONFIG_TYPE_ETF) {
+ dump_entry = get_msm_dump_ptr(MSM_DUMP_DATA_TMC_ETF_REG);
+ dev_dbg(drvdata->dev, "%s: TMC ETF dump entry ptr is %pK\n",
+ __func__, dump_entry);
+ } else
+ return;
+
+ if (dump_entry == NULL)
+ return;
+
+ reg_buf = (uint32_t *)(dump_entry->dump_vaddr);
+ dump_data = dump_entry->dump_data_vaddr;
+
+ if (reg_buf == NULL || dump_data == NULL)
+ return;
+
+ dev_dbg(drvdata->dev, "%s: TMC dump reg ptr is %pK, dump_data is %pK\n",
+ __func__, reg_buf, dump_data);
+
+ reg_buf[1] = readl_relaxed(drvdata->base + TMC_RSZ);
+ reg_buf[3] = readl_relaxed(drvdata->base + TMC_STS);
+ reg_buf[5] = readl_relaxed(drvdata->base + TMC_RRP);
+ reg_buf[6] = readl_relaxed(drvdata->base + TMC_RWP);
+ reg_buf[7] = readl_relaxed(drvdata->base + TMC_TRG);
+ reg_buf[8] = readl_relaxed(drvdata->base + TMC_CTL);
+ reg_buf[10] = readl_relaxed(drvdata->base + TMC_MODE);
+ reg_buf[11] = readl_relaxed(drvdata->base + TMC_LBUFLEVEL);
+ reg_buf[12] = readl_relaxed(drvdata->base + TMC_CBUFLEVEL);
+ reg_buf[13] = readl_relaxed(drvdata->base + TMC_BUFWM);
+ if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
+ reg_buf[14] = readl_relaxed(drvdata->base + TMC_RRPHI);
+ reg_buf[15] = readl_relaxed(drvdata->base + TMC_RWPHI);
+ reg_buf[68] = readl_relaxed(drvdata->base + TMC_AXICTL);
+ reg_buf[70] = readl_relaxed(drvdata->base + TMC_DBALO);
+ reg_buf[71] = readl_relaxed(drvdata->base + TMC_DBAHI);
+ }
+ reg_buf[192] = readl_relaxed(drvdata->base + TMC_FFSR);
+ reg_buf[193] = readl_relaxed(drvdata->base + TMC_FFCR);
+ reg_buf[194] = readl_relaxed(drvdata->base + TMC_PSCR);
+ reg_buf[1000] = readl_relaxed(drvdata->base + CORESIGHT_CLAIMSET);
+ reg_buf[1001] = readl_relaxed(drvdata->base + CORESIGHT_CLAIMCLR);
+ reg_buf[1005] = readl_relaxed(drvdata->base + CORESIGHT_LSR);
+ reg_buf[1006] = readl_relaxed(drvdata->base + CORESIGHT_AUTHSTATUS);
+ reg_buf[1010] = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
+ reg_buf[1011] = readl_relaxed(drvdata->base + CORESIGHT_DEVTYPE);
+ reg_buf[1012] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR4);
+ reg_buf[1013] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR5);
+ reg_buf[1014] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR6);
+ reg_buf[1015] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR7);
+ reg_buf[1016] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR0);
+ reg_buf[1017] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR1);
+ reg_buf[1018] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR2);
+ reg_buf[1019] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR3);
+ reg_buf[1020] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR0);
+ reg_buf[1021] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR1);
+ reg_buf[1022] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR2);
+ reg_buf[1023] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR3);
+
+ dump_data->magic = TMC_REG_DUMP_MAGIC;
+}
+
void tmc_enable_hw(struct tmc_drvdata *drvdata)
{
drvdata->enable = true;
drvdata->sticky_enable = true;
writel_relaxed(TMC_CTL_CAPT_EN, drvdata->base + TMC_CTL);
+ if (drvdata->force_reg_dump)
+ __tmc_reg_dump(drvdata);
}
void tmc_disable_hw(struct tmc_drvdata *drvdata)
@@ -626,6 +703,8 @@
return -EPROBE_DEFER;
}
}
+ if (of_property_read_bool(drvdata->dev->of_node, "qcom,force-reg-dump"))
+ drvdata->force_reg_dump = true;
desc.pdata = pdata;
desc.dev = dev;
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 0a271e5..2372be6 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -192,6 +192,7 @@
struct coresight_csr *csr;
const char *csr_name;
struct byte_cntr *byte_cntr;
+ bool force_reg_dump;
};
/* Generic functions */
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 0bc9439..7cdb459 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -3898,6 +3898,8 @@
static int tpdm_datasets_alloc(struct tpdm_drvdata *drvdata)
{
+ struct dump_vaddr_entry *dump_entry;
+
if (test_bit(TPDM_DS_GPR, drvdata->datasets)) {
drvdata->gpr = devm_kzalloc(drvdata->dev, sizeof(*drvdata->gpr),
GFP_KERNEL);
@@ -3939,10 +3941,13 @@
return -ENOMEM;
if (of_property_read_bool(drvdata->dev->of_node,
- "qcom,dump-enable"))
- drvdata->cmb->mcmb->mcmb_msr_dump_ptr =
- (uint32_t *)get_msm_dump_ptr(
- MSM_DUMP_DATA_TPDM_SWAO_MCMB);
+ "qcom,dump-enable")) {
+ dump_entry = get_msm_dump_ptr(
+ MSM_DUMP_DATA_TPDM_SWAO_MCMB);
+ if (dump_entry)
+ drvdata->cmb->mcmb->mcmb_msr_dump_ptr =
+ (uint32_t *)(dump_entry->dump_vaddr);
+ }
}
return 0;
}
diff --git a/drivers/input/misc/qpnp-power-on.c b/drivers/input/misc/qpnp-power-on.c
index 5fa0d4b..36d07c5 100644
--- a/drivers/input/misc/qpnp-power-on.c
+++ b/drivers/input/misc/qpnp-power-on.c
@@ -229,6 +229,7 @@
bool kpdpwr_dbc_enable;
bool resin_pon_reset;
ktime_t kpdpwr_last_release_time;
+ bool legacy_hard_reset_offset;
};
static int pon_ship_mode_en;
@@ -353,7 +354,7 @@
if (!pon->store_hard_reset_reason)
return 0;
- if (is_pon_gen2(pon))
+ if (is_pon_gen2(pon) && !pon->legacy_hard_reset_offset)
rc = qpnp_pon_masked_write(pon, QPNP_PON_SOFT_RB_SPARE(pon),
GENMASK(7, 1), (reason << 1));
else
@@ -2524,6 +2525,9 @@
pon->store_hard_reset_reason = of_property_read_bool(pdev->dev.of_node,
"qcom,store-hard-reset-reason");
+ pon->legacy_hard_reset_offset = of_property_read_bool(pdev->dev.of_node,
+ "qcom,use-legacy-hard-reset-offset");
+
qpnp_pon_debugfs_init(pdev);
return 0;
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_config.h b/drivers/input/touchscreen/focaltech_touch/focaltech_config.h
index 157f0df..5ab6bda 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_config.h
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_config.h
@@ -121,7 +121,7 @@
* Gesture function enable
* default: disable
*/
-#define FTS_GESTURE_EN 0
+#define FTS_GESTURE_EN 1
/*
* ESD check & protection
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
index 27bb390..b3d7322 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
@@ -648,7 +648,7 @@
#if FTS_GESTURE_EN
u8 state;
- if (data->suspended) {
+ if (data->suspended && data->pdata->wakeup_gestures_en) {
fts_i2c_read_reg(data->client, FTS_REG_GESTURE_EN, &state);
if (state == 1) {
fts_gesture_readdata(data->client);
@@ -989,6 +989,8 @@
pdata->max_touch_number = FTS_MAX_POINTS;
}
+ pdata->wakeup_gestures_en = of_property_read_bool(np,
+ "focaltech,wakeup-gestures-en");
FTS_FUNC_EXIT();
return 0;
@@ -1310,15 +1312,17 @@
#endif
#if FTS_GESTURE_EN
- retval = fts_gesture_suspend(data->client);
- if (retval == 0) {
- /* Enter into gesture mode(suspend) */
- retval = enable_irq_wake(fts_wq_data->client->irq);
- if (retval)
- FTS_ERROR("%s: set_irq_wake failed", __func__);
- data->suspended = true;
- FTS_FUNC_EXIT();
- return 0;
+ if (data->pdata->wakeup_gestures_en) {
+ retval = fts_gesture_suspend(data->client);
+ if (retval == 0) {
+ /* Enter into gesture mode(suspend) */
+ retval = enable_irq_wake(fts_wq_data->client->irq);
+ if (retval)
+ FTS_ERROR("%s: set_irq_wake failed", __func__);
+ data->suspended = true;
+ FTS_FUNC_EXIT();
+ return 0;
+ }
}
#endif
@@ -1376,15 +1380,18 @@
#endif
#if FTS_GESTURE_EN
- if (fts_gesture_resume(data->client) == 0) {
- int err;
+ if (data->pdata->wakeup_gestures_en) {
+ if (fts_gesture_resume(data->client) == 0) {
+ int err;
- err = disable_irq_wake(data->client->irq);
- if (err)
- FTS_ERROR("%s: disable_irq_wake failed", __func__);
- data->suspended = false;
- FTS_FUNC_EXIT();
- return 0;
+ err = disable_irq_wake(data->client->irq);
+ if (err)
+ FTS_ERROR("%s: disable_irq_wake failed",
+ __func__);
+ data->suspended = false;
+ FTS_FUNC_EXIT();
+ return 0;
+ }
}
#endif
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.h b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h
index 52b4ffe..a3c64f9 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.h
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h
@@ -97,10 +97,10 @@
#define FTS_TOUCH_UP 1
#define FTS_TOUCH_CONTACT 2
-#define FTS_SYSFS_ECHO_ON(buf) ((strnicmp(buf, "1", 1) == 0) || \
- (strnicmp(buf, "on", 2) == 0))
-#define FTS_SYSFS_ECHO_OFF(buf) ((strnicmp(buf, "0", 1) == 0) || \
- (strnicmp(buf, "off", 3) == 0))
+#define FTS_SYSFS_ECHO_ON(buf) ((strncasecmp(buf, "1", 1) == 0) || \
+ (strncasecmp(buf, "on", 2) == 0))
+#define FTS_SYSFS_ECHO_OFF(buf) ((strncasecmp(buf, "0", 1) == 0) || \
+ (strncasecmp(buf, "off", 3) == 0))
/*****************************************************************************
* Private enumerations, structures and unions using typedef
@@ -122,6 +122,7 @@
u32 x_min;
u32 y_min;
u32 max_touch_number;
+ bool wakeup_gestures_en;
};
struct ts_event {
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_test.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_test.c
index 2041369..aa4c9cf 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_test.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_test.c
@@ -34,7 +34,6 @@
*****************************************************************************/
#include "../focaltech_core.h"
#include "../focaltech_flash.h"
-#include <linux/wakelock.h>
#include <linux/timer.h>
/*****************************************************************************
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c b/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
index b3bb39e..d24cd8a 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
@@ -69,6 +69,9 @@
#define FTS_GESTRUE_POINTS 255
#define FTS_GESTRUE_POINTS_HEADER 8
+#define GESTURE_SMALL_AREA 0x25 /* TP Coverage < 50% */
+#define GESTURE_LARGE_AREA 0x26 /* TP Coverage > 50% */
+
/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
@@ -423,11 +426,21 @@
return ret;
}
- /* FW recognize gesture */
- if (fts_gesture_fw()) {
- memcpy(fts_gesture_data.header, buf, FTS_GESTRUE_POINTS_HEADER);
- gestrue_id = buf[0];
- pointnum = buf[1];
+ memcpy(fts_gesture_data.header, buf, FTS_GESTRUE_POINTS_HEADER);
+ gestrue_id = buf[0];
+ pointnum = buf[1];
+
+ if (gestrue_id == GESTURE_SMALL_AREA) {
+ FTS_INFO("[GESTURE] Wakeup gesture.");
+ input_report_key(fts_input_dev, KEY_POWER, 1);
+ input_sync(fts_input_dev);
+ input_report_key(fts_input_dev, KEY_POWER, 0);
+ input_sync(fts_input_dev);
+
+ } else if (gestrue_id == GESTURE_LARGE_AREA) {
+ FTS_INFO("[GESTURE] Large object detected.");
+ } else if (fts_gesture_fw()) {
+ /* FW recognize gesture */
read_bytes = ((int)pointnum) * 4 + 2;
buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
FTS_DEBUG("[GESTURE]PointNum=%d", pointnum);
@@ -448,12 +461,13 @@
| (((s16) buf[3 + (4 * i + 2)]) & 0xFF);
}
- FTS_FUNC_EXIT();
- return 0;
+
+ } else {
+ FTS_ERROR("[GESTURE]IC 0x%x need lib to support gestures.",
+ chip_types.chip_idh);
}
- FTS_ERROR("[GESTURE]IC 0x%x need gesture lib to support gestures.",
- chip_types.chip_idh);
+ FTS_FUNC_EXIT();
return 0;
}
diff --git a/drivers/irqchip/qcom/mpm.c b/drivers/irqchip/qcom/mpm.c
index 72bd7fd..a8b8b9b 100644
--- a/drivers/irqchip/qcom/mpm.c
+++ b/drivers/irqchip/qcom/mpm.c
@@ -162,13 +162,26 @@
}
}
-static inline void msm_mpm_set_type(struct irq_data *d,
+static void msm_mpm_program_set_type(bool set, unsigned int reg,
+ unsigned int index, unsigned int mask)
+{
+ u32 type;
+
+ type = msm_mpm_read(reg, index);
+ if (set)
+ type = ENABLE_TYPE(type, mask);
+ else
+ type = CLEAR_TYPE(type, mask);
+
+ msm_mpm_write(reg, index, type);
+}
+
+static void msm_mpm_set_type(struct irq_data *d,
unsigned int flowtype)
{
int mpm_pin[MAX_MPM_PIN_PER_IRQ] = {-1, -1};
unsigned long flags;
int i = 0;
- u32 type;
unsigned int index, mask;
unsigned int reg = 0;
@@ -180,24 +193,24 @@
index = mpm_pin[i]/32;
mask = mpm_pin[i]%32;
- if (flowtype & IRQ_TYPE_LEVEL_HIGH)
- reg = MPM_REG_FALLING_EDGE;
-
- if (flowtype & IRQ_TYPE_EDGE_RISING)
- reg = MPM_REG_RISING_EDGE;
-
- if (flowtype & IRQ_TYPE_EDGE_FALLING)
- reg = MPM_REG_POLARITY;
-
spin_lock_irqsave(&mpm_lock, flags);
- type = msm_mpm_read(reg, index);
-
- if (flowtype)
- type = ENABLE_TYPE(type, mask);
+ reg = MPM_REG_RISING_EDGE;
+ if (flowtype & IRQ_TYPE_EDGE_RISING)
+ msm_mpm_program_set_type(1, reg, index, mask);
else
- type = CLEAR_TYPE(type, mask);
+ msm_mpm_program_set_type(0, reg, index, mask);
- msm_mpm_write(reg, index, type);
+ reg = MPM_REG_FALLING_EDGE;
+ if (flowtype & IRQ_TYPE_EDGE_FALLING)
+ msm_mpm_program_set_type(1, reg, index, mask);
+ else
+ msm_mpm_program_set_type(0, reg, index, mask);
+
+ reg = MPM_REG_POLARITY;
+ if (flowtype & IRQ_TYPE_LEVEL_HIGH)
+ msm_mpm_program_set_type(1, reg, index, mask);
+ else
+ msm_mpm_program_set_type(0, reg, index, mask);
spin_unlock_irqrestore(&mpm_lock, flags);
}
}
@@ -512,6 +525,8 @@
IRQCHIP_STATE_PENDING, true);
}
+
+ msm_mpm_write(MPM_REG_STATUS, i, 0);
}
return IRQ_HANDLED;
}
diff --git a/drivers/mailbox/msm_qmp.c b/drivers/mailbox/msm_qmp.c
index d6e41ae..9e898b8 100644
--- a/drivers/mailbox/msm_qmp.c
+++ b/drivers/mailbox/msm_qmp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -893,7 +893,7 @@
mdev->name);
ret = devm_request_irq(&pdev->dev, mdev->rx_irq_line, qmp_irq_handler,
- IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND | IRQF_SHARED,
+ IRQF_TRIGGER_RISING | IRQF_SHARED,
edge_node->name, mdev);
if (ret < 0) {
qmp_mbox_remove(pdev);
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
index 85e9058..b4f83f7 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
@@ -535,10 +535,9 @@
CAM_SYNC_STATE_SIGNALED_ERROR);
if (rc == -EALREADY) {
CAM_ERR(CAM_CTXT,
- "Req: %llu already signalled, sync_id:%d",
- req->request_id,
- req->out_map_entries[i].
- sync_id);
+ "Req: %llu already signalled, sync_id:%d",
+ req->request_id,
+ req->out_map_entries[i].sync_id);
break;
}
}
@@ -629,6 +628,7 @@
struct cam_ctx_request *req = NULL;
struct cam_hw_flush_args flush_args;
uint32_t i;
+ int32_t sync_id = 0;
int rc = 0;
CAM_DBG(CAM_CTXT, "[%s] E: NRT flush req", ctx->dev_name);
@@ -683,20 +683,20 @@
if (req) {
if (flush_args.num_req_pending || flush_args.num_req_active) {
- for (i = 0; i < req->num_out_map_entries; i++)
- if (req->out_map_entries[i].sync_id != -1) {
- rc = cam_sync_signal(
- req->out_map_entries[i].sync_id,
+ for (i = 0; i < req->num_out_map_entries; i++) {
+ sync_id =
+ req->out_map_entries[i].sync_id;
+ if (sync_id != -1) {
+ rc = cam_sync_signal(sync_id,
CAM_SYNC_STATE_SIGNALED_ERROR);
if (rc == -EALREADY) {
CAM_ERR(CAM_CTXT,
- "Req: %llu already signalled, sync_id:%d",
- req->request_id,
- req->out_map_entries[i].
- sync_id);
+ "Req: %llu already signalled, sync_id:%d",
+ req->request_id, sync_id);
break;
}
}
+ }
if (flush_args.num_req_active) {
spin_lock(&ctx->lock);
list_add_tail(&req->list, &ctx->free_req_list);
diff --git a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c
index e7de207..5e4ff0d 100644
--- a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c
+++ b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c
@@ -873,6 +873,7 @@
if (!CAM_CPAS_CLIENT_VALID(client_indx))
return -EINVAL;
+ mutex_lock(&cpas_hw->hw_mutex);
mutex_lock(&cpas_core->client_mutex[client_indx]);
if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) {
@@ -892,6 +893,7 @@
unlock_client:
mutex_unlock(&cpas_core->client_mutex[client_indx]);
+ mutex_unlock(&cpas_hw->hw_mutex);
return rc;
}
@@ -907,6 +909,7 @@
struct cam_axi_vote *axi_vote;
enum cam_vote_level applied_level = CAM_SVS_VOTE;
int rc;
+ struct cam_cpas_private_soc *soc_private = NULL;
if (!hw_priv || !start_args) {
CAM_ERR(CAM_CPAS, "Invalid arguments %pK %pK",
@@ -922,6 +925,8 @@
cpas_hw = (struct cam_hw_info *)hw_priv;
cpas_core = (struct cam_cpas *) cpas_hw->core_info;
+ soc_private = (struct cam_cpas_private_soc *)
+ cpas_hw->soc_info.soc_private;
cmd_hw_start = (struct cam_cpas_hw_cmd_start *)start_args;
client_indx = CAM_CPAS_GET_CLIENT_IDX(cmd_hw_start->client_handle);
ahb_vote = cmd_hw_start->ahb_vote;
@@ -1005,8 +1010,9 @@
cpas_client->started = true;
cpas_core->streamon_clients++;
- CAM_DBG(CAM_CPAS, "client_indx=%d, streamon_clients=%d",
- client_indx, cpas_core->streamon_clients);
+ CAM_DBG(CAM_CPAS, "client=%s, streamon_clients=%d",
+ soc_private->client_name[client_indx],
+ cpas_core->streamon_clients);
done:
mutex_unlock(&cpas_core->client_mutex[client_indx]);
mutex_unlock(&cpas_hw->hw_mutex);
@@ -1028,6 +1034,7 @@
struct cam_cpas_client *cpas_client;
struct cam_ahb_vote ahb_vote;
struct cam_axi_vote axi_vote;
+ struct cam_cpas_private_soc *soc_private = NULL;
int rc = 0;
long result;
@@ -1045,6 +1052,8 @@
cpas_hw = (struct cam_hw_info *)hw_priv;
cpas_core = (struct cam_cpas *) cpas_hw->core_info;
+ soc_private = (struct cam_cpas_private_soc *)
+ cpas_hw->soc_info.soc_private;
cmd_hw_stop = (struct cam_cpas_hw_cmd_stop *)stop_args;
client_indx = CAM_CPAS_GET_CLIENT_IDX(cmd_hw_stop->client_handle);
@@ -1054,8 +1063,9 @@
mutex_lock(&cpas_hw->hw_mutex);
mutex_lock(&cpas_core->client_mutex[client_indx]);
- CAM_DBG(CAM_CPAS, "client_indx=%d, streamon_clients=%d",
- client_indx, cpas_core->streamon_clients);
+ CAM_DBG(CAM_CPAS, "client=%s, streamon_clients=%d",
+ soc_private->client_name[client_indx],
+ cpas_core->streamon_clients);
if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) {
CAM_ERR(CAM_CPAS, "Client %d is not started", client_indx);
diff --git a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_session_defs.h b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_session_defs.h
index 7b2cb8b..69e6ccf 100644
--- a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_session_defs.h
+++ b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_session_defs.h
@@ -261,8 +261,8 @@
};
struct frame_buffer {
- uint32_t buffer_ptr[MAX_NUM_OF_IMAGE_PLANES];
- uint32_t meta_buffer_ptr[MAX_NUM_OF_IMAGE_PLANES];
+ uint32_t buf_ptr[MAX_NUM_OF_IMAGE_PLANES];
+ uint32_t meta_buf_ptr[MAX_NUM_OF_IMAGE_PLANES];
} __packed;
struct bps_frame_process_data {
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_dev.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_dev.c
index 0e36ec0..feb0bd8 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_dev.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -33,6 +33,40 @@
};
EXPORT_SYMBOL(cam_bps_hw_info);
+static bool cam_bps_cpas_cb(uint32_t client_handle, void *userdata,
+ struct cam_cpas_irq_data *irq_data)
+{
+ bool error_handled = false;
+
+ if (!irq_data)
+ return error_handled;
+
+ switch (irq_data->irq_type) {
+ case CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR:
+ CAM_ERR_RATE_LIMIT(CAM_ICP,
+ "IPE/BPS UBWC Decode error type=%d status=%x thr_err=%d, fcl_err=%d, len_md_err=%d, format_err=%d",
+ irq_data->irq_type,
+ irq_data->u.dec_err.decerr_status.value,
+ irq_data->u.dec_err.decerr_status.thr_err,
+ irq_data->u.dec_err.decerr_status.fcl_err,
+ irq_data->u.dec_err.decerr_status.len_md_err,
+ irq_data->u.dec_err.decerr_status.format_err);
+ error_handled = true;
+ break;
+ case CAM_CAMNOC_IRQ_IPE_BPS_UBWC_ENCODE_ERROR:
+ CAM_ERR_RATE_LIMIT(CAM_ICP,
+ "IPE/BPS UBWC Encode error type=%d status=%x",
+ irq_data->irq_type,
+ irq_data->u.enc_err.encerr_status.value);
+ error_handled = true;
+ break;
+ default:
+ break;
+ }
+
+ return error_handled;
+}
+
int cam_bps_register_cpas(struct cam_hw_soc_info *soc_info,
struct cam_bps_device_core_info *core_info,
uint32_t hw_idx)
@@ -42,7 +76,7 @@
cpas_register_params.dev = &soc_info->pdev->dev;
memcpy(cpas_register_params.identifier, "bps", sizeof("bps"));
- cpas_register_params.cam_cpas_client_cb = NULL;
+ cpas_register_params.cam_cpas_client_cb = cam_bps_cpas_cb;
cpas_register_params.cell_index = hw_idx;
cpas_register_params.userdata = NULL;
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index c6c9b85..9ed71d2 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -308,8 +308,9 @@
ctx_data = &hw_mgr->ctx_data[i];
mutex_lock(&ctx_data->ctx_mutex);
if ((ctx_data->state == CAM_ICP_CTX_STATE_ACQUIRED) &&
- (ICP_DEV_TYPE_TO_CLK_TYPE(ctx_data->
- icp_dev_acquire_info->dev_type) == clk_info->hw_type)) {
+ (ICP_DEV_TYPE_TO_CLK_TYPE(
+ ctx_data->icp_dev_acquire_info->dev_type)
+ == clk_info->hw_type)) {
busy = cam_icp_frame_pending(ctx_data);
if (busy) {
mutex_unlock(&ctx_data->ctx_mutex);
@@ -2994,6 +2995,8 @@
uint64_t cpu_addr = 0;
struct ipe_frame_process_data *frame_process_data = NULL;
struct bps_frame_process_data *bps_frame_process_data = NULL;
+ struct frame_set *ipe_set = NULL;
+ struct frame_buffer *bps_bufs = NULL;
cmd_desc = (struct cam_cmd_buf_desc *)
((uint32_t *) &packet->payload + packet->cmd_buf_offset/4);
@@ -3042,14 +3045,11 @@
frame_process_data->cdm_buffer_addr = 0;
frame_process_data->cdm_prog_base = 0;
for (i = 0; i < frame_process_data->frames_in_batch; i++) {
+ ipe_set = &frame_process_data->framesets[i];
for (j = 0; j < IPE_IO_IMAGES_MAX; j++) {
for (k = 0; k < MAX_NUM_OF_IMAGE_PLANES; k++) {
- frame_process_data->
- framesets[i].buffers[j].
- buffer_ptr[k] = 0;
- frame_process_data->
- framesets[i].buffers[j].
- meta_buffer_ptr[k] = 0;
+ ipe_set->buffers[j].buf_ptr[k] = 0;
+ ipe_set->buffers[j].meta_buf_ptr[k] = 0;
}
}
}
@@ -3066,11 +3066,10 @@
bps_frame_process_data->strip_lib_out_addr = 0;
bps_frame_process_data->cdm_prog_addr = 0;
for (i = 0; i < BPS_IO_IMAGES_MAX; i++) {
+ bps_bufs = &bps_frame_process_data->buffers[i];
for (j = 0; j < MAX_NUM_OF_IMAGE_PLANES; j++) {
- bps_frame_process_data->
- buffers[i].buffer_ptr[j] = 0;
- bps_frame_process_data->
- buffers[i].meta_buffer_ptr[j] = 0;
+ bps_bufs->buf_ptr[j] = 0;
+ bps_bufs->meta_buf_ptr[j] = 0;
}
}
}
@@ -4028,8 +4027,8 @@
CAM_ERR(CAM_ICP, "read num bps devices failed");
goto num_bps_failed;
}
- icp_hw_mgr.devices[CAM_ICP_DEV_BPS] = kzalloc(
- sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL);
+ icp_hw_mgr.devices[CAM_ICP_DEV_BPS] = kcalloc(num_dev,
+ sizeof(struct cam_hw_intf *), GFP_KERNEL);
if (!icp_hw_mgr.devices[CAM_ICP_DEV_BPS]) {
rc = -ENOMEM;
goto num_bps_failed;
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
index 8753bbb..1106453 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
@@ -26,6 +26,97 @@
static const char isp_dev_name[] = "isp";
+#define INC_STATE_MONITOR_HEAD(head) \
+ (atomic64_add_return(1, head) % \
+ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES)
+
+static void __cam_isp_ctx_update_state_monitor_array(
+ struct cam_isp_context *ctx_isp,
+ enum cam_isp_state_change_trigger trigger_type,
+ uint32_t req_id)
+{
+ int iterator = 0;
+
+ iterator = INC_STATE_MONITOR_HEAD(&ctx_isp->state_monitor_head);
+ ctx_isp->cam_isp_ctx_state_monitor[iterator].curr_state =
+ ctx_isp->substate_activated;
+ ctx_isp->cam_isp_ctx_state_monitor[iterator].trigger =
+ trigger_type;
+ ctx_isp->cam_isp_ctx_state_monitor[iterator].req_id =
+ req_id;
+ ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp =
+ jiffies_to_msecs(jiffies);
+}
+
+static const char *__cam_isp_ctx_substate_val_to_type(
+ uint32_t type)
+{
+ switch (type) {
+ case CAM_ISP_CTX_ACTIVATED_SOF:
+ return "SOF";
+ case CAM_ISP_CTX_ACTIVATED_APPLIED:
+ return "APPLIED";
+ case CAM_ISP_CTX_ACTIVATED_EPOCH:
+ return "EPOCH";
+ case CAM_ISP_CTX_ACTIVATED_BUBBLE:
+ return "BUBBLE";
+ case CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED:
+ return "BUBBLE_APPLIED";
+ case CAM_ISP_CTX_ACTIVATED_HALT:
+ return "HALT";
+ default:
+ return "CAM_ISP_CTX_INVALID_STATE";
+ }
+}
+
+static const char *__cam_isp_hw_evt_val_to_type(
+ uint32_t evt_id)
+{
+ switch (evt_id) {
+ case CAM_ISP_STATE_CHANGE_TRIGGER_ERROR:
+ return "ERROR";
+ case CAM_ISP_STATE_CHANGE_TRIGGER_SOF:
+ return "SOF";
+ case CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE:
+ return "REG_UPDATE";
+ case CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH:
+ return "EPOCH";
+ case CAM_ISP_STATE_CHANGE_TRIGGER_EOF:
+ return "EOF";
+ case CAM_ISP_STATE_CHANGE_TRIGGER_DONE:
+ return "DONE";
+ default:
+ return "CAM_ISP_EVENT_INVALID";
+ }
+}
+
+static void __cam_isp_ctx_dump_state_monitor_array(
+ struct cam_isp_context *ctx_isp)
+{
+ int i = 0;
+ uint64_t state_head = 0;
+ uint64_t index;
+
+ state_head = atomic64_read(&ctx_isp->state_monitor_head);
+ CAM_ERR_RATE_LIMIT(CAM_ISP,
+ "Dumping state information for preceding requests");
+
+ for (i = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES - 1; i >= 0;
+ i--) {
+ index = (((state_head - i) +
+ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) %
+ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES);
+ CAM_ERR_RATE_LIMIT(CAM_ISP,
+ "time[0x%llx] req_id[%u] state[%s] evt_type[%s]",
+ ctx_isp->cam_isp_ctx_state_monitor[index].evt_time_stamp,
+ ctx_isp->cam_isp_ctx_state_monitor[index].req_id,
+ __cam_isp_ctx_substate_val_to_type(
+ ctx_isp->cam_isp_ctx_state_monitor[index].curr_state),
+ __cam_isp_hw_evt_val_to_type(
+ ctx_isp->cam_isp_ctx_state_monitor[index].trigger));
+ }
+}
+
static int __cam_isp_ctx_enqueue_request_in_order(
struct cam_context *ctx, struct cam_ctx_request *req)
{
@@ -134,46 +225,46 @@
return rc;
}
-static const char *__cam_isp_resource_handle_id_to_type
- (uint32_t resource_handle)
+static const char *__cam_isp_resource_handle_id_to_type(
+ uint32_t resource_handle)
{
switch (resource_handle) {
case CAM_ISP_IFE_OUT_RES_FULL:
- return "CAM_ISP_IFE_OUT_RES_FULL";
+ return "FULL";
case CAM_ISP_IFE_OUT_RES_DS4:
- return "CAM_ISP_IFE_OUT_RES_DS4";
+ return "DS4";
case CAM_ISP_IFE_OUT_RES_DS16:
- return "CAM_ISP_IFE_OUT_RES_DS16";
+ return "DS16";
case CAM_ISP_IFE_OUT_RES_RAW_DUMP:
- return "CAM_ISP_IFE_OUT_RES_RAW_DUMP";
+ return "RAW_DUMP";
case CAM_ISP_IFE_OUT_RES_FD:
- return "CAM_ISP_IFE_OUT_RES_FD";
+ return "FD";
case CAM_ISP_IFE_OUT_RES_PDAF:
- return "CAM_ISP_IFE_OUT_RES_PDAF";
+ return "PDAF";
case CAM_ISP_IFE_OUT_RES_RDI_0:
- return "CAM_ISP_IFE_OUT_RES_RDI_0";
+ return "RDI_0";
case CAM_ISP_IFE_OUT_RES_RDI_1:
- return "CAM_ISP_IFE_OUT_RES_RDI_1";
+ return "RDI_1";
case CAM_ISP_IFE_OUT_RES_RDI_2:
- return "CAM_ISP_IFE_OUT_RES_RDI_2";
+ return "RDI_2";
case CAM_ISP_IFE_OUT_RES_RDI_3:
- return "CAM_ISP_IFE_OUT_RES_RDI_3";
+ return "RDI_3";
case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE:
- return "CAM_ISP_IFE_OUT_RES_STATS_HDR_BE";
+ return "STATS_HDR_BE";
case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST:
- return "CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST";
+ return "STATS_HDR_BHIST";
case CAM_ISP_IFE_OUT_RES_STATS_TL_BG:
- return "CAM_ISP_IFE_OUT_RES_STATS_TL_BG";
+ return "STATS_TL_BG";
case CAM_ISP_IFE_OUT_RES_STATS_BF:
- return "CAM_ISP_IFE_OUT_RES_STATS_BF";
+ return "STATS_BF";
case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG:
- return "CAM_ISP_IFE_OUT_RES_STATS_AWB_BG";
+ return "STATS_AWB_BG";
case CAM_ISP_IFE_OUT_RES_STATS_BHIST:
- return "CAM_ISP_IFE_OUT_RES_STATS_BHIST";
+ return "STATS_BHIST";
case CAM_ISP_IFE_OUT_RES_STATS_RS:
- return "CAM_ISP_IFE_OUT_RES_STATS_RS";
+ return "STATS_RS";
case CAM_ISP_IFE_OUT_RES_STATS_CS:
- return "CAM_ISP_IFE_OUT_RES_STATS_CS";
+ return "STATS_CS";
default:
return "CAM_ISP_Invalid_Resource_Type";
}
@@ -350,6 +441,9 @@
}
end:
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
+ ctx_isp->base->req_list->request_id);
return rc;
}
@@ -510,6 +604,11 @@
{
int rc = 0;
struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
+ struct cam_ctx_request *req;
+ struct cam_context *ctx = ctx_isp->base;
+
+ req = list_last_entry(&ctx->pending_req_list,
+ struct cam_ctx_request, list);
if (!evt_data) {
CAM_ERR(CAM_ISP, "in valid sof event data");
@@ -518,6 +617,8 @@
ctx_isp->frame_id++;
ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id);
CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
@@ -528,11 +629,11 @@
void *evt_data)
{
int rc = 0;
- struct cam_ctx_request *req;
+ struct cam_ctx_request *req = NULL;
struct cam_isp_ctx_req *req_isp;
struct cam_context *ctx = ctx_isp->base;
- if (ctx->state != CAM_CTX_ACTIVATED) {
+ if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) {
CAM_DBG(CAM_ISP, "invalid RUP");
goto end;
}
@@ -560,6 +661,11 @@
CAM_ISP_CTX_ACTIVATED_EPOCH;
}
}
+ if (req != NULL) {
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE,
+ req->request_id);
+ }
end:
return rc;
}
@@ -627,6 +733,15 @@
CAM_DBG(CAM_ISP, "next substate %d",
ctx_isp->substate_activated);
end:
+ if (request_id == 0) {
+ req = list_last_entry(&ctx->active_req_list,
+ struct cam_ctx_request, list);
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id);
+ } else {
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, request_id);
+ }
return 0;
}
@@ -649,6 +764,7 @@
int rc = 0;
struct cam_context *ctx = ctx_isp->base;
struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
+ struct cam_ctx_request *req;
if (!evt_data) {
CAM_ERR(CAM_ISP, "in valid sof event data");
@@ -663,6 +779,10 @@
else
CAM_DBG(CAM_ISP, "Still need to wait for the buf done");
+ req = list_last_entry(&ctx->active_req_list,
+ struct cam_ctx_request, list);
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_STATE_CHANGE_TRIGGER_SOF, ctx->req_list->request_id);
CAM_DBG(CAM_ISP, "next substate %d",
ctx_isp->substate_activated);
@@ -761,6 +881,10 @@
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
end:
+ req = list_last_entry(&ctx->active_req_list, struct cam_ctx_request,
+ list);
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id);
return 0;
}
@@ -772,6 +896,9 @@
(struct cam_isp_hw_done_event_data *) evt_data;
rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1);
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
+ ctx_isp->base->req_list->request_id);
return rc;
}
@@ -786,6 +913,7 @@
struct cam_isp_ctx_req *req_isp = NULL;
struct cam_req_mgr_error_notify notify;
uint64_t error_request_id;
+ struct cam_hw_fence_map_entry *fence_map_out = NULL;
struct cam_context *ctx = ctx_isp->base;
struct cam_isp_hw_error_event_data *error_event_data =
@@ -814,18 +942,18 @@
if (!req_isp->bubble_report) {
for (i = 0; i < req_isp->num_fence_map_out;
i++) {
+ fence_map_out =
+ &req_isp->fence_map_out[i];
CAM_ERR(CAM_ISP, "req %llu, Sync fd %x",
- req->request_id,
- req_isp->fence_map_out[i].
- sync_id);
+ req->request_id,
+ req_isp->fence_map_out[i].sync_id);
if (req_isp->fence_map_out[i].sync_id
!= -1) {
rc = cam_sync_signal(
- req_isp->fence_map_out[i].
- sync_id,
+ fence_map_out->sync_id,
CAM_SYNC_STATE_SIGNALED_ERROR);
- req_isp->fence_map_out[i].
- sync_id = -1;
+ fence_map_out->sync_id =
+ -1;
}
}
list_del_init(&req->list);
@@ -893,6 +1021,14 @@
rc = -EFAULT;
}
+
+ list_del_init(&req->list);
+ list_add(&req->list, &ctx->pending_req_list);
+ /* might need to check if active list is empty */
+ if (req != NULL) {
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, req->request_id);
+ }
CAM_DBG(CAM_ISP, "Exit");
return rc;
}
@@ -1013,7 +1149,7 @@
struct cam_ctx_request *active_req;
struct cam_isp_ctx_req *req_isp;
struct cam_isp_ctx_req *active_req_isp;
- struct cam_isp_context *ctx_isp;
+ struct cam_isp_context *ctx_isp = NULL;
struct cam_hw_config_args cfg;
if (list_empty(&ctx->pending_req_list)) {
@@ -1087,6 +1223,11 @@
spin_unlock_bh(&ctx->lock);
}
end:
+ if (ctx_isp != NULL) {
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_STATE_CHANGE_TRIGGER_SOF,
+ ctx->req_list->request_id);
+ }
return rc;
}
@@ -2390,16 +2531,16 @@
struct cam_req_mgr_apply_request *apply)
{
int rc = 0;
+ struct cam_ctx_ops *ctx_ops = NULL;
struct cam_isp_context *ctx_isp =
(struct cam_isp_context *) ctx->ctx_priv;
trace_cam_apply_req("ISP", apply->request_id);
CAM_DBG(CAM_ISP, "Enter: apply req in Substate %d request _id:%lld",
ctx_isp->substate_activated, apply->request_id);
- if (ctx_isp->substate_machine[ctx_isp->substate_activated].
- crm_ops.apply_req) {
- rc = ctx_isp->substate_machine[ctx_isp->substate_activated].
- crm_ops.apply_req(ctx, apply);
+ ctx_ops = &ctx_isp->substate_machine[ctx_isp->substate_activated];
+ if (ctx_ops->crm_ops.apply_req) {
+ rc = ctx_ops->crm_ops.apply_req(ctx, apply);
} else {
CAM_ERR_RATE_LIMIT(CAM_ISP,
"No handle function in activated substate %d",
@@ -2420,6 +2561,7 @@
uint32_t evt_id, void *evt_data)
{
int rc = 0;
+ struct cam_isp_ctx_irq_ops *irq_ops = NULL;
struct cam_context *ctx = (struct cam_context *)context;
struct cam_isp_context *ctx_isp =
(struct cam_isp_context *)ctx->ctx_priv;
@@ -2431,13 +2573,13 @@
CAM_DBG(CAM_ISP, "Enter: State %d, Substate %d, evt id %d",
ctx->state, ctx_isp->substate_activated, evt_id);
- if (ctx_isp->substate_machine_irq[ctx_isp->substate_activated].
- irq_ops[evt_id]) {
- rc = ctx_isp->substate_machine_irq[ctx_isp->substate_activated].
- irq_ops[evt_id](ctx_isp, evt_data);
+ irq_ops = &ctx_isp->substate_machine_irq[ctx_isp->substate_activated];
+ if (irq_ops->irq_ops[evt_id]) {
+ rc = irq_ops->irq_ops[evt_id](ctx_isp, evt_data);
} else {
CAM_DBG(CAM_ISP, "No handle function for substate %d",
ctx_isp->substate_activated);
+ __cam_isp_ctx_dump_state_monitor_array(ctx_isp);
}
CAM_DBG(CAM_ISP, "Exit: State %d Substate %d",
ctx->state, ctx_isp->substate_activated);
@@ -2551,6 +2693,12 @@
ctx_base->state_machine = cam_isp_ctx_top_state_machine;
ctx_base->ctx_priv = ctx;
+ /* initializing current state for error logging */
+ for (i = 0; i < CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES; i++) {
+ ctx->cam_isp_ctx_state_monitor[i].curr_state =
+ CAM_ISP_CTX_ACTIVATED_MAX;
+ }
+ atomic64_set(&ctx->state_monitor_head, -1);
err:
return rc;
}
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
index 38ea58d..1eae89f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
@@ -28,11 +28,16 @@
#define CAM_ISP_CTX_RES_MAX 20
/*
- * Maxiimum configuration entry size - This is based on the
+ * Maximum configuration entry size - This is based on the
* worst case DUAL IFE use case plus some margin.
*/
#define CAM_ISP_CTX_CFG_MAX 22
+/*
+ * Maximum entries in state monitoring array for error logging
+ */
+#define CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES 20
+
/* forward declaration */
struct cam_isp_context;
@@ -56,6 +61,19 @@
CAM_ISP_CTX_ACTIVATED_MAX,
};
+/**
+ * enum cam_isp_state_change_trigger - Different types of ISP events
+ *
+ */
+enum cam_isp_state_change_trigger {
+ CAM_ISP_STATE_CHANGE_TRIGGER_ERROR,
+ CAM_ISP_STATE_CHANGE_TRIGGER_SOF,
+ CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE,
+ CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH,
+ CAM_ISP_STATE_CHANGE_TRIGGER_EOF,
+ CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
+ CAM_ISP_STATE_CHANGE_TRIGGER_MAX
+};
/**
* struct cam_isp_ctx_irq_ops - Function table for handling IRQ callbacks
@@ -101,23 +119,44 @@
};
/**
- * struct cam_isp_context - ISP context object
+ * struct cam_isp_context_state_monitor - ISP context state
+ * monitoring for
+ * debug purposes
*
- * @base: Common context object pointer
- * @frame_id: Frame id tracking for the isp context
- * @substate_actiavted: Current substate for the activated state.
- * @substate_machine: ISP substate machine for external interface
- * @substate_machine_irq: ISP substate machine for irq handling
- * @req_base: Common request object storage
- * @req_isp: ISP private request object storage
- * @hw_ctx: HW object returned by the acquire device command
- * @sof_timestamp_val: Captured time stamp value at sof hw event
- * @active_req_cnt: Counter for the active request
- * @reported_req_id: Last reported request id
- * @subscribe_event: The irq event mask that CRM subscribes to, IFE will
- * invoke CRM cb at those event.
- * @last_applied_req_id: Last applied request id
- * @frame_skip_count: Number of frame to skip before change state
+ *@curr_state: Current sub state that received req
+ *@req_type: Event type of incoming req
+ *@req_id: Request id
+ *@evt_time_stamp Current time stamp
+ *
+ */
+struct cam_isp_context_state_monitor {
+ enum cam_isp_ctx_activated_substate curr_state;
+ enum cam_isp_state_change_trigger trigger;
+ uint32_t req_id;
+ int64_t frame_id;
+ uint64_t evt_time_stamp;
+};
+
+/**
+ * struct cam_isp_context - ISP context object
+ *
+ * @base: Common context object pointer
+ * @frame_id: Frame id tracking for the isp context
+ * @substate_actiavted: Current substate for the activated state.
+ * @substate_machine: ISP substate machine for external interface
+ * @substate_machine_irq: ISP substate machine for irq handling
+ * @req_base: Common request object storage
+ * @req_isp: ISP private request object storage
+ * @hw_ctx: HW object returned by the acquire device command
+ * @sof_timestamp_val: Captured time stamp value at sof hw event
+ * @active_req_cnt: Counter for the active request
+ * @reported_req_id: Last reported request id
+ * @subscribe_event: The irq event mask that CRM subscribes to, IFE
+ * will invoke CRM cb at those event.
+ * @last_applied_req_id: Last applied request id
+ * @frame_skip_count: Number of frame to skip before change state
+ * @state_monitor_head: Write index to the state monitoring array
+ * @cam_isp_ctx_state_monitor: State monitoring array
*
*/
struct cam_isp_context {
@@ -138,6 +177,9 @@
uint32_t subscribe_event;
int64_t last_applied_req_id;
uint32_t frame_skip_count;
+ atomic64_t state_monitor_head;
+ struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[
+ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES];
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index 4628172..6e140e2 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -1809,7 +1809,6 @@
if (cam_cdm_stream_off(ctx->cdm_handle))
CAM_ERR(CAM_ISP, "CDM stream off failed %d",
ctx->cdm_handle);
- cam_tasklet_stop(ctx->common.tasklet_info);
CAM_DBG(CAM_ISP, "Going to stop IFE Mux");
@@ -1831,6 +1830,8 @@
}
}
+ cam_tasklet_stop(ctx->common.tasklet_info);
+
/*
* If Context does not have PIX resources and has only RDI resource
* then take the first base index.
@@ -4031,6 +4032,8 @@
int rc = -EFAULT;
int i, j;
struct cam_iommu_handle cdm_handles;
+ struct cam_ife_hw_mgr_ctx *ctx_pool;
+ struct cam_ife_hw_mgr_res *res_list_ife_out;
CAM_DBG(CAM_ISP, "Enter");
@@ -4135,9 +4138,10 @@
INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_cid);
INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_csid);
INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_src);
+ ctx_pool = &g_ife_hw_mgr.ctx_pool[i];
for (j = 0; j < CAM_IFE_HW_OUT_RES_MAX; j++) {
- INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].
- res_list_ife_out[j].list);
+ res_list_ife_out = &ctx_pool->res_list_ife_out[j];
+ INIT_LIST_HEAD(&res_list_ife_out->list);
}
/* init context pool */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
index 3606af9..1d38f3b 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -414,6 +414,8 @@
struct cam_ife_hw_mgr_res *hw_mgr_res;
struct cam_isp_hw_get_cmd_update update_buf;
struct cam_isp_hw_get_wm_update wm_update;
+ struct cam_hw_fence_map_entry *out_map_entries;
+ struct cam_hw_fence_map_entry *in_map_entries;
uint32_t kmd_buf_remain_size;
uint32_t i, j, num_out_buf, num_in_buf;
uint32_t res_id_out, res_id_in, plane_id;
@@ -458,14 +460,15 @@
CAM_DBG(CAM_ISP,
"configure output io with fill fence %d",
fill_fence);
+ out_map_entries =
+ &prepare->out_map_entries[num_out_buf];
if (fill_fence) {
if (num_out_buf <
prepare->max_out_map_entries) {
- prepare->out_map_entries[num_out_buf].
- resource_handle =
- io_cfg[i].resource_type;
- prepare->out_map_entries[num_out_buf].
- sync_id = io_cfg[i].fence;
+ out_map_entries->resource_handle =
+ io_cfg[i].resource_type;
+ out_map_entries->sync_id =
+ io_cfg[i].fence;
num_out_buf++;
} else {
CAM_ERR(CAM_ISP, "ln_out:%d max_ln:%d",
@@ -486,14 +489,14 @@
CAM_DBG(CAM_ISP,
"configure input io with fill fence %d",
fill_fence);
+ in_map_entries =
+ &prepare->in_map_entries[num_in_buf];
if (fill_fence) {
if (num_in_buf < prepare->max_in_map_entries) {
- prepare->in_map_entries[num_in_buf].
- resource_handle =
- io_cfg[i].resource_type;
- prepare->in_map_entries[num_in_buf].
- sync_id =
- io_cfg[i].fence;
+ in_map_entries->resource_handle =
+ io_cfg[i].resource_type;
+ in_map_entries->sync_id =
+ io_cfg[i].fence;
num_in_buf++;
} else {
CAM_ERR(CAM_ISP, "ln_in:%d imax_ln:%d",
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
index 24df4ce..feb79cc 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
@@ -336,9 +336,11 @@
int cam_irq_controller_enable_irq(void *irq_controller, uint32_t handle)
{
- struct cam_irq_controller *controller = irq_controller;
- struct cam_irq_evt_handler *evt_handler = NULL;
- struct cam_irq_evt_handler *evt_handler_temp;
+ struct cam_irq_controller *controller = irq_controller;
+ struct cam_irq_evt_handler *evt_handler = NULL;
+ struct cam_irq_evt_handler *evt_handler_temp;
+ struct cam_irq_register_obj *irq_register = NULL;
+ enum cam_irq_priority_level priority;
unsigned long flags = 0;
unsigned int i;
uint32_t irq_mask;
@@ -369,14 +371,14 @@
return rc;
}
+ priority = evt_handler->priority;
for (i = 0; i < controller->num_registers; i++) {
- controller->irq_register_arr[i].
- top_half_enable_mask[evt_handler->priority] |=
+ irq_register = &controller->irq_register_arr[i];
+ irq_register->top_half_enable_mask[priority] |=
evt_handler->evt_bit_mask_arr[i];
irq_mask = cam_io_r_mb(controller->mem_base +
- controller->irq_register_arr[i].
- mask_reg_offset);
+ irq_register->mask_reg_offset);
irq_mask |= evt_handler->evt_bit_mask_arr[i];
cam_io_w_mb(irq_mask, controller->mem_base +
@@ -390,9 +392,11 @@
int cam_irq_controller_disable_irq(void *irq_controller, uint32_t handle)
{
- struct cam_irq_controller *controller = irq_controller;
- struct cam_irq_evt_handler *evt_handler = NULL;
- struct cam_irq_evt_handler *evt_handler_temp;
+ struct cam_irq_controller *controller = irq_controller;
+ struct cam_irq_evt_handler *evt_handler = NULL;
+ struct cam_irq_evt_handler *evt_handler_temp;
+ struct cam_irq_register_obj *irq_register;
+ enum cam_irq_priority_level priority;
unsigned long flags = 0;
unsigned int i;
uint32_t irq_mask;
@@ -423,31 +427,27 @@
return rc;
}
+ priority = evt_handler->priority;
for (i = 0; i < controller->num_registers; i++) {
- controller->irq_register_arr[i].
- top_half_enable_mask[evt_handler->priority] &=
+ irq_register = &controller->irq_register_arr[i];
+ irq_register->top_half_enable_mask[priority] &=
~(evt_handler->evt_bit_mask_arr[i]);
irq_mask = cam_io_r_mb(controller->mem_base +
- controller->irq_register_arr[i].
- mask_reg_offset);
+ irq_register->mask_reg_offset);
CAM_DBG(CAM_ISP, "irq_mask 0x%x before disable 0x%x",
- controller->irq_register_arr[i].mask_reg_offset,
- irq_mask);
+ irq_register->mask_reg_offset, irq_mask);
irq_mask &= ~(evt_handler->evt_bit_mask_arr[i]);
cam_io_w_mb(irq_mask, controller->mem_base +
- controller->irq_register_arr[i].
- mask_reg_offset);
+ irq_register->mask_reg_offset);
CAM_DBG(CAM_ISP, "irq_mask 0x%x after disable 0x%x",
- controller->irq_register_arr[i].mask_reg_offset,
- irq_mask);
+ irq_register->mask_reg_offset, irq_mask);
/* Clear the IRQ bits of this handler */
cam_io_w_mb(evt_handler->evt_bit_mask_arr[i],
controller->mem_base +
- controller->irq_register_arr[i].
- clear_reg_offset);
+ irq_register->clear_reg_offset);
if (controller->global_clear_offset)
cam_io_w_mb(
@@ -464,9 +464,11 @@
int cam_irq_controller_unsubscribe_irq(void *irq_controller,
uint32_t handle)
{
- struct cam_irq_controller *controller = irq_controller;
- struct cam_irq_evt_handler *evt_handler = NULL;
- struct cam_irq_evt_handler *evt_handler_temp;
+ struct cam_irq_controller *controller = irq_controller;
+ struct cam_irq_evt_handler *evt_handler = NULL;
+ struct cam_irq_evt_handler *evt_handler_temp;
+ struct cam_irq_register_obj *irq_register;
+ enum cam_irq_priority_level priority;
uint32_t i;
uint32_t found = 0;
uint32_t irq_mask;
@@ -490,26 +492,24 @@
}
}
+ priority = evt_handler->priority;
if (found) {
for (i = 0; i < controller->num_registers; i++) {
- controller->irq_register_arr[i].
- top_half_enable_mask[evt_handler->priority] &=
+ irq_register = &controller->irq_register_arr[i];
+ irq_register->top_half_enable_mask[priority] &=
~(evt_handler->evt_bit_mask_arr[i]);
irq_mask = cam_io_r_mb(controller->mem_base +
- controller->irq_register_arr[i].
- mask_reg_offset);
+ irq_register->mask_reg_offset);
irq_mask &= ~(evt_handler->evt_bit_mask_arr[i]);
cam_io_w_mb(irq_mask, controller->mem_base +
- controller->irq_register_arr[i].
- mask_reg_offset);
+ irq_register->mask_reg_offset);
/* Clear the IRQ bits of this handler */
cam_io_w_mb(evt_handler->evt_bit_mask_arr[i],
controller->mem_base +
- controller->irq_register_arr[i].
- clear_reg_offset);
+ irq_register->clear_reg_offset);
if (controller->global_clear_offset)
cam_io_w_mb(
controller->global_clear_bitmask,
@@ -642,7 +642,8 @@
irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv)
{
- struct cam_irq_controller *controller = priv;
+ struct cam_irq_controller *controller = priv;
+ struct cam_irq_register_obj *irq_register;
bool need_th_processing[CAM_IRQ_PRIORITY_MAX] = {false};
int i;
int j;
@@ -654,6 +655,7 @@
controller, controller->name, &controller->lock);
spin_lock(&controller->lock);
for (i = 0; i < controller->num_registers; i++) {
+ irq_register = &controller->irq_register_arr[i];
controller->irq_status_arr[i] = cam_io_r_mb(
controller->mem_base +
controller->irq_register_arr[i].status_reg_offset);
@@ -664,8 +666,7 @@
controller->irq_register_arr[i].status_reg_offset,
controller->irq_status_arr[i]);
for (j = 0; j < CAM_IRQ_PRIORITY_MAX; j++) {
- if (controller->irq_register_arr[i].
- top_half_enable_mask[j] &
+ if (irq_register->top_half_enable_mask[j] &
controller->irq_status_arr[i])
need_th_processing[j] = true;
CAM_DBG(CAM_ISP,
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index 328aaaf..34f8c41 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -356,6 +356,8 @@
struct cam_ife_csid_reg_offset *csid_reg;
int rc = 0;
uint32_t val = 0, i;
+ uint32_t status;
+
soc_info = &csid_hw->hw_info->soc_info;
csid_reg = csid_hw->csid_info->csid_reg;
@@ -370,8 +372,6 @@
CAM_DBG(CAM_ISP, "CSID:%d Csid reset",
csid_hw->hw_intf->hw_idx);
- init_completion(&csid_hw->csid_top_complete);
-
/* Mask all interrupts */
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
@@ -417,21 +417,19 @@
cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[i]->csid_rdi_cfg0_addr);
- /* perform the top CSID HW reset */
- cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
+ /* perform the top CSID HW and SW registers reset */
+ cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb_sw_all,
soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_rst_strobes_addr);
- CAM_DBG(CAM_ISP, " Waiting for reset complete from irq handler");
- rc = wait_for_completion_timeout(&csid_hw->csid_top_complete,
- msecs_to_jiffies(IFE_CSID_TIMEOUT));
- if (rc <= 0) {
- CAM_ERR(CAM_ISP, "CSID:%d reset completion in fail rc = %d",
- csid_hw->hw_intf->hw_idx, rc);
- if (rc == 0)
- rc = -ETIMEDOUT;
- } else {
- rc = 0;
+ rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
+ csid_reg->cmn_reg->csid_top_irq_status_addr,
+ status, (status & 0x1) == 0x1,
+ CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
+ csid_hw->hw_intf->hw_idx, rc);
+ rc = -ETIMEDOUT;
}
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
@@ -858,6 +856,11 @@
path_data->height = reserve->in_port->height;
path_data->start_line = reserve->in_port->line_start;
path_data->end_line = reserve->in_port->line_stop;
+ path_data->crop_enable = true;
+ CAM_DBG(CAM_ISP, "Res id: %d height:%d line_start %d line_stop %d",
+ reserve->res_id, reserve->in_port->height,
+ reserve->in_port->line_start, reserve->in_port->line_stop);
+
if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
path_data->dt = CAM_IFE_CSID_TPG_DT_VAL;
path_data->vc = CAM_IFE_CSID_TPG_VC_VAL;
@@ -867,7 +870,6 @@
}
if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
- path_data->crop_enable = 1;
path_data->start_pixel = reserve->in_port->left_start;
path_data->end_pixel = reserve->in_port->left_stop;
path_data->width = reserve->in_port->left_width;
@@ -878,7 +880,6 @@
csid_hw->hw_intf->hw_idx, path_data->start_line,
path_data->end_line);
} else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) {
- path_data->crop_enable = 1;
path_data->start_pixel = reserve->in_port->right_start;
path_data->end_pixel = reserve->in_port->right_stop;
path_data->width = reserve->in_port->right_width;
@@ -889,9 +890,13 @@
csid_hw->hw_intf->hw_idx, path_data->start_line,
path_data->end_line);
} else {
- path_data->crop_enable = 0;
path_data->width = reserve->in_port->left_width;
path_data->start_pixel = reserve->in_port->left_start;
+ path_data->end_pixel = reserve->in_port->left_stop;
+ CAM_DBG(CAM_ISP, "Res id: %d left width %d start: %d stop:%d",
+ reserve->res_id, reserve->in_port->left_width,
+ reserve->in_port->left_start,
+ reserve->in_port->left_stop);
}
CAM_DBG(CAM_ISP, "Res %d width %d height %d", reserve->res_id,
@@ -907,7 +912,7 @@
int rc = 0;
struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
- uint32_t i, status, val;
+ uint32_t i, val;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
@@ -936,42 +941,10 @@
goto err;
}
-
- CAM_DBG(CAM_ISP, "CSID:%d enable top irq interrupt",
- csid_hw->hw_intf->hw_idx);
-
csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP;
- /* Enable the top IRQ interrupt */
- cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
- csid_reg->cmn_reg->csid_top_irq_mask_addr);
-
+ /* Reset CSID top */
rc = cam_ife_csid_global_reset(csid_hw);
if (rc) {
- CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
- csid_hw->hw_intf->hw_idx, rc);
- rc = -ETIMEDOUT;
- goto disable_soc;
- }
-
- /*
- * Reset the SW registers
- * SW register reset also reset the mask irq, so poll the irq status
- * to check the reset complete.
- */
- CAM_DBG(CAM_ISP, "CSID:%d Reset Software registers",
- csid_hw->hw_intf->hw_idx);
-
- cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb_sw_all,
- soc_info->reg_map[0].mem_base +
- csid_reg->cmn_reg->csid_rst_strobes_addr);
-
- rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
- csid_reg->cmn_reg->csid_top_irq_status_addr,
- status, (status & 0x1) == 0x1,
- CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
- if (rc < 0) {
- CAM_ERR(CAM_ISP, "software register reset timeout.....");
- rc = -ETIMEDOUT;
goto disable_soc;
}
@@ -1065,6 +1038,7 @@
int rc = 0;
uint32_t val = 0;
struct cam_hw_soc_info *soc_info;
+ struct cam_ife_csid_reg_offset *csid_reg = NULL;
csid_hw->tpg_start_cnt++;
if (csid_hw->tpg_start_cnt == 1) {
@@ -1109,10 +1083,10 @@
}
/* Enable the IFE force clock on for dual isp case */
+ csid_reg = csid_hw->csid_info->csid_reg;
if (csid_hw->tpg_cfg.usage_type) {
rc = cam_ife_csid_enable_ife_force_clock_on(soc_info,
- csid_hw->csid_info->csid_reg->tpg_reg->
- tpg_cpas_ife_reg_offset);
+ csid_reg->tpg_reg->tpg_cpas_ife_reg_offset);
if (rc)
return rc;
}
@@ -1122,10 +1096,9 @@
val |= (0x80 << 8);
val |= (((csid_hw->csi2_rx_cfg.lane_num - 1) & 0x3) << 4);
val |= 7;
- cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
- csid_hw->csid_info->csid_reg->tpg_reg->
- csid_tpg_ctrl_addr);
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+ csid_reg->tpg_reg->csid_tpg_ctrl_addr);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base + 0x600);
CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val);
}
@@ -1138,6 +1111,7 @@
{
int rc = 0;
struct cam_hw_soc_info *soc_info;
+ struct cam_ife_csid_reg_offset *csid_reg = NULL;
if (csid_hw->tpg_start_cnt)
csid_hw->tpg_start_cnt--;
@@ -1146,6 +1120,7 @@
return 0;
soc_info = &csid_hw->hw_info->soc_info;
+ csid_reg = csid_hw->csid_info->csid_reg;
/* disable the TPG */
if (!csid_hw->tpg_start_cnt) {
@@ -1155,8 +1130,7 @@
/* Disable the IFE force clock on for dual isp case */
if (csid_hw->tpg_cfg.usage_type)
rc = cam_ife_csid_disable_ife_force_clock_on(soc_info,
- csid_hw->csid_info->csid_reg->tpg_reg->
- tpg_cpas_ife_reg_offset);
+ csid_reg->tpg_reg->tpg_cpas_ife_reg_offset);
/*stop the TPG */
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
@@ -1669,6 +1643,10 @@
if (rc)
return rc;
+ /* if path decode format is payload only then RDI crop is not applied */
+ if (path_format == 0xF)
+ path_data->crop_enable = 0;
+
/*
* RDI path config and enable the time stamp capture
* Enable the measurement blocks
@@ -1905,6 +1883,7 @@
struct cam_isp_resource_node *res;
struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
+ struct cam_ife_csid_rdi_reg_offset *rdi_reg;
uint32_t time_32, id;
time_stamp = (struct cam_csid_get_time_stamp_args *)cmd_args;
@@ -1937,15 +1916,14 @@
time_stamp->time_stamp_val |= time_32;
} else {
id = res->res_id;
+ rdi_reg = csid_reg->rdi_reg[id];
time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->rdi_reg[id]->
- csid_rdi_timestamp_curr1_sof_addr);
+ rdi_reg->csid_rdi_timestamp_curr1_sof_addr);
time_stamp->time_stamp_val = time_32;
time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->rdi_reg[id]->
- csid_rdi_timestamp_curr0_sof_addr);
+ rdi_reg->csid_rdi_timestamp_curr0_sof_addr);
time_stamp->time_stamp_val |= time_32;
}
@@ -2171,6 +2149,7 @@
struct cam_ife_csid_reg_offset *csid_reg =
csid_hw->csid_info->csid_reg;
+ init_completion(&csid_hw->csid_top_complete);
cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
csid_hw->hw_info->soc_info.reg_map[0].mem_base +
csid_reg->cmn_reg->csid_rst_strobes_addr);
@@ -2490,6 +2469,7 @@
struct cam_ife_csid_hw *csid_hw;
struct cam_hw_soc_info *soc_info;
struct cam_ife_csid_reg_offset *csid_reg;
+ struct cam_ife_csid_csi2_rx_reg_offset *csi2_reg;
uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0;
uint32_t irq_status_rdi[4] = {0, 0, 0, 0};
uint32_t val;
@@ -2505,6 +2485,7 @@
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
+ csi2_reg = csid_reg->csi2_reg;
/* read */
irq_status_top = cam_io_r_mb(soc_info->reg_map[0].mem_base +
@@ -2653,19 +2634,16 @@
CAM_ERR(CAM_ISP, "CSID:%d LONG_PKT_CAPTURED",
csid_hw->hw_intf->hw_idx);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->csi2_reg->
- csid_csi2_rx_captured_long_pkt_0_addr);
+ csi2_reg->csid_csi2_rx_captured_long_pkt_0_addr);
CAM_ERR(CAM_ISP, "CSID:%d long packet VC :%d DT:%d WC:%d",
csid_hw->hw_intf->hw_idx,
(val >> 22), ((val >> 16) & 0x3F), (val & 0xFFFF));
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->csi2_reg->
- csid_csi2_rx_captured_long_pkt_1_addr);
+ csi2_reg->csid_csi2_rx_captured_long_pkt_1_addr);
CAM_ERR(CAM_ISP, "CSID:%d long packet ECC :%d",
csid_hw->hw_intf->hw_idx, val);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->csi2_reg->
- csid_csi2_rx_captured_long_pkt_ftr_addr);
+ csi2_reg->csid_csi2_rx_captured_long_pkt_ftr_addr);
CAM_ERR(CAM_ISP, "CSID:%d long pkt cal CRC:%d expected CRC:%d",
csid_hw->hw_intf->hw_idx, (val >> 16), (val & 0xFFFF));
}
@@ -2674,14 +2652,12 @@
CAM_ERR(CAM_ISP, "CSID:%d SHORT_PKT_CAPTURED",
csid_hw->hw_intf->hw_idx);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->csi2_reg->
- csid_csi2_rx_captured_short_pkt_0_addr);
+ csi2_reg->csid_csi2_rx_captured_short_pkt_0_addr);
CAM_ERR(CAM_ISP, "CSID:%d short pkt VC :%d DT:%d LC:%d",
csid_hw->hw_intf->hw_idx,
(val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->csi2_reg->
- csid_csi2_rx_captured_short_pkt_1_addr);
+ csi2_reg->csid_csi2_rx_captured_short_pkt_1_addr);
CAM_ERR(CAM_ISP, "CSID:%d short packet ECC :%d",
csid_hw->hw_intf->hw_idx, val);
}
@@ -2691,8 +2667,7 @@
CAM_ERR(CAM_ISP, "CSID:%d CPHY_PKT_HDR_CAPTURED",
csid_hw->hw_intf->hw_idx);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->csi2_reg->
- csid_csi2_rx_captured_cphy_pkt_hdr_addr);
+ csi2_reg->csid_csi2_rx_captured_cphy_pkt_hdr_addr);
CAM_ERR(CAM_ISP, "CSID:%d cphy packet VC :%d DT:%d WC:%d",
csid_hw->hw_intf->hw_idx,
(val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
index 2c4fe9d..fd38a96 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
@@ -32,17 +32,17 @@
};
static uint32_t camif_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
- 0x0003FD1F,
+ 0x00000017,
0x00000000,
};
static uint32_t camif_irq_err_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
- 0x00000000,
+ 0x0003FC00,
0x0FFF7EBC,
};
static uint32_t rdi_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
- 0x780000e0,
+ 0x780001e0,
0x00000000,
};
@@ -89,9 +89,10 @@
spin_lock_irqsave(&vfe_core_info->spin_lock, flags);
(*evt_payload)->error_type = 0;
list_add_tail(&(*evt_payload)->list, &vfe_core_info->free_payload_list);
+ *evt_payload = NULL;
spin_unlock_irqrestore(&vfe_core_info->spin_lock, flags);
- *evt_payload = NULL;
+
return 0;
}
@@ -156,6 +157,7 @@
struct cam_vfe_irq_handler_priv *handler_priv;
struct cam_vfe_top_irq_evt_payload *evt_payload;
struct cam_vfe_hw_core_info *core_info;
+ bool error_flag = false;
CAM_DBG(CAM_ISP, "IRQ status_0 = %x, IRQ status_1 = %x",
th_payload->evt_status_arr[0], th_payload->evt_status_arr[1]);
@@ -166,14 +168,20 @@
* need to handle overflow condition here, otherwise irq storm
* will block everything
*/
-
- if (th_payload->evt_status_arr[1]) {
- CAM_ERR(CAM_ISP, "IRQ status_1: %x, Masking all interrupts",
+ if (th_payload->evt_status_arr[1] ||
+ (th_payload->evt_status_arr[0] & camif_irq_err_reg_mask[0])) {
+ CAM_ERR(CAM_ISP,
+ "Encountered Error: vfe:%d: Irq_status0=0x%x Status1=0x%x",
+ handler_priv->core_index, th_payload->evt_status_arr[0],
th_payload->evt_status_arr[1]);
+ CAM_ERR(CAM_ISP,
+ "Stopping further IRQ processing from this HW index=%d",
+ handler_priv->core_index);
cam_irq_controller_disable_irq(core_info->vfe_irq_controller,
core_info->irq_err_handle);
cam_irq_controller_clear_and_mask(evt_id,
core_info->vfe_irq_controller);
+ error_flag = true;
}
rc = cam_vfe_get_evt_payload(handler_priv->core_info, &evt_payload);
@@ -200,7 +208,9 @@
irq_reg_offset[i]);
}
- CAM_DBG(CAM_ISP, "Violation status = %x", evt_payload->irq_reg_val[2]);
+ if (error_flag)
+ CAM_INFO(CAM_ISP, "Violation status = %x",
+ evt_payload->irq_reg_val[2]);
th_payload->evt_payload_priv = evt_payload;
@@ -291,6 +301,8 @@
struct cam_vfe_hw_core_info *core_info = NULL;
struct cam_isp_resource_node *isp_res = NULL;
int rc = 0;
+ uint32_t reset_core_args =
+ CAM_VFE_HW_RESET_HW_AND_REG;
CAM_DBG(CAM_ISP, "Enter");
if (!hw_priv) {
@@ -327,6 +339,8 @@
CAM_ERR(CAM_ISP, "deinit failed");
}
+ rc = cam_vfe_reset(hw_priv, &reset_core_args, sizeof(uint32_t));
+
/* Turn OFF Regulators, Clocks and other SOC resources */
CAM_DBG(CAM_ISP, "Disable SOC resource");
rc = cam_vfe_disable_soc_resources(soc_info);
@@ -373,7 +387,7 @@
reinit_completion(&vfe_hw->hw_complete);
- CAM_DBG(CAM_ISP, "calling RESET");
+ CAM_DBG(CAM_ISP, "calling RESET on vfe %d", soc_info->index);
core_info->vfe_top->hw_ops.reset(core_info->vfe_top->top_priv,
reset_core_args, arg_size);
CAM_DBG(CAM_ISP, "waiting for vfe reset complete");
@@ -416,23 +430,6 @@
CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
- /*
- * need to handle non-recoverable condition here, otherwise irq storm
- * will block everything.
- */
- if (th_payload->evt_status_arr[0] & 0x3FC00) {
- CAM_ERR(CAM_ISP,
- "Encountered Error Irq_status0=0x%x Status1=0x%x",
- th_payload->evt_status_arr[0],
- th_payload->evt_status_arr[1]);
- CAM_ERR(CAM_ISP,
- "Stopping further IRQ processing from this HW index=%d",
- handler_priv->core_index);
- cam_io_w(0, handler_priv->mem_base + 0x60);
- cam_io_w(0, handler_priv->mem_base + 0x5C);
- return 0;
- }
-
rc = cam_vfe_get_evt_payload(handler_priv->core_info, &evt_payload);
if (rc) {
CAM_ERR_RATE_LIMIT(CAM_ISP,
@@ -705,6 +702,7 @@
case CAM_ISP_HW_CMD_GET_BUF_UPDATE:
case CAM_ISP_HW_CMD_GET_HFR_UPDATE:
case CAM_ISP_HW_CMD_STRIPE_UPDATE:
+ case CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ:
rc = core_info->vfe_bus->hw_ops.process_cmd(
core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
arg_size);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
index ed728f5..969b75a 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
@@ -2291,6 +2291,7 @@
struct cam_buf_io_cfg *io_cfg;
struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
+ struct cam_vfe_bus_ver2_reg_offset_ubwc_client *ubwc_client = NULL;
uint32_t *reg_val_pair;
uint32_t i, j, size = 0;
uint32_t frame_inc = 0, ubwc_bw_limit = 0, camera_hw_version, val;
@@ -2326,7 +2327,7 @@
}
wm_data = vfe_out_data->wm_res[i]->res_priv;
-
+ ubwc_client = wm_data->hw_regs->ubwc_regs;
/* update width register */
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->buffer_width_cfg,
@@ -2398,9 +2399,8 @@
* update offset value.
*/
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair,
- j,
- wm_data->hw_regs->ubwc_regs->
- h_init, wm_data->offset);
+ j, ubwc_client->h_init,
+ wm_data->offset);
wm_data->h_init = wm_data->offset;
}
} else if (wm_data->h_init !=
@@ -2428,8 +2428,7 @@
io_cfg->planes[i].meta_stride ||
!wm_data->init_cfg_done) {
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
- wm_data->hw_regs->ubwc_regs->
- meta_stride,
+ ubwc_client->meta_stride,
io_cfg->planes[i].meta_stride);
wm_data->ubwc_meta_stride =
io_cfg->planes[i].meta_stride;
@@ -2453,8 +2452,7 @@
io_cfg->planes[i].meta_offset ||
!wm_data->init_cfg_done) {
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
- wm_data->hw_regs->ubwc_regs->
- meta_offset,
+ ubwc_client->meta_offset,
io_cfg->planes[i].meta_offset);
wm_data->ubwc_meta_offset =
io_cfg->planes[i].meta_offset;
@@ -2849,7 +2847,7 @@
case CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ:
bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
if (bus_priv->error_irq_handle) {
- CAM_INFO(CAM_ISP, "Mask off bus error irq handler");
+ CAM_DBG(CAM_ISP, "Mask off bus error irq handler");
rc = cam_irq_controller_unsubscribe_irq(
bus_priv->common_data.bus_irq_controller,
bus_priv->error_irq_handle);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
index 976e6d2..5d6045b 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
@@ -275,7 +275,7 @@
}
if (hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
+ CAM_DBG(CAM_ISP,
"VFE:%d Not ready to set clocks yet :%d",
res->hw_intf->hw_idx,
hw_info->hw_state);
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
index 32f11a7..f172a79 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
@@ -145,8 +145,7 @@
}
rc = cam_mem_get_cpu_buf(
- p_cfg_req->hw_cfg_args.
- hw_update_entries[CAM_JPEG_PARAM].handle,
+ p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].handle,
(uint64_t *)&kaddr, &cmd_buf_len);
if (rc) {
CAM_ERR(CAM_JPEG, "unable to get info for cmd buf: %x %d",
@@ -157,20 +156,20 @@
cmd_buf_kaddr = (uint32_t *)kaddr;
cmd_buf_kaddr =
- (cmd_buf_kaddr + (p_cfg_req->hw_cfg_args.
- hw_update_entries[CAM_JPEG_PARAM].offset / sizeof(uint32_t)));
+ (cmd_buf_kaddr +
+ (p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset
+ / sizeof(uint32_t)));
p_params = (struct cam_jpeg_config_inout_param_info *)cmd_buf_kaddr;
p_params->output_size = task_data->result_size;
CAM_DBG(CAM_JPEG, "Encoded Size %d", task_data->result_size);
- buf_data.num_handles = p_cfg_req->
- hw_cfg_args.num_out_map_entries;
+ buf_data.num_handles =
+ p_cfg_req->hw_cfg_args.num_out_map_entries;
for (i = 0; i < buf_data.num_handles; i++) {
buf_data.resource_handle[i] =
- p_cfg_req->hw_cfg_args.
- out_map_entries[i].resource_handle;
+ p_cfg_req->hw_cfg_args.out_map_entries[i].resource_handle;
}
buf_data.request_id =
(uint64_t)p_cfg_req->hw_cfg_args.priv;
@@ -267,8 +266,8 @@
uint32_t *ch_base_iova_addr;
size_t ch_base_len;
- rc = cam_mem_get_cpu_buf(config_args->
- hw_update_entries[CAM_JPEG_CHBASE].handle,
+ rc = cam_mem_get_cpu_buf(
+ config_args->hw_update_entries[CAM_JPEG_CHBASE].handle,
&iova_addr, &ch_base_len);
if (rc) {
CAM_ERR(CAM_JPEG,
@@ -285,10 +284,10 @@
dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
mem_cam_base = hw_mgr->cdm_reg_map[dev_type][0]->mem_cam_base;
- size = hw_mgr->cdm_info[dev_type][0].cdm_ops->
- cdm_required_size_changebase();
- hw_mgr->cdm_info[dev_type][0].cdm_ops->
- cdm_write_changebase(ch_base_iova_addr, mem_cam_base);
+ size =
+ hw_mgr->cdm_info[dev_type][0].cdm_ops->cdm_required_size_changebase();
+ hw_mgr->cdm_info[dev_type][0].cdm_ops->cdm_write_changebase(
+ ch_base_iova_addr, mem_cam_base);
cdm_cmd = ctx_data->cdm_cmd;
cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle =
@@ -322,6 +321,7 @@
struct cam_jpeg_set_irq_cb irq_cb;
struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL;
struct cam_hw_done_event_data buf_data;
+ struct cam_hw_config_args *hw_cfg_args = NULL;
if (!hw_mgr || !task_data) {
CAM_ERR(CAM_JPEG, "Invalid arguments %pK %pK",
@@ -444,8 +444,8 @@
for (i = CAM_JPEG_CFG; i < (config_args->num_hw_update_entries - 1);
i++) {
cmd = (config_args->hw_update_entries + i);
- cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].
- bl_addr.mem_handle = cmd->handle;
+ cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle
+ = cmd->handle;
cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].offset =
cmd->offset;
cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].len =
@@ -456,8 +456,7 @@
}
rc = cam_cdm_submit_bls(
- hw_mgr->cdm_info[dev_type][0].cdm_handle,
- cdm_cmd);
+ hw_mgr->cdm_info[dev_type][0].cdm_handle, cdm_cmd);
if (rc) {
CAM_ERR(CAM_JPEG, "Failed to apply the configs %d", rc);
goto end_callcb;
@@ -483,15 +482,14 @@
end_callcb:
mutex_unlock(&hw_mgr->hw_mgr_mutex);
if (p_cfg_req) {
- buf_data.num_handles = p_cfg_req->
- hw_cfg_args.num_out_map_entries;
+ hw_cfg_args = &p_cfg_req->hw_cfg_args;
+ buf_data.num_handles =
+ hw_cfg_args->num_out_map_entries;
for (i = 0; i < buf_data.num_handles; i++) {
buf_data.resource_handle[i] =
- p_cfg_req->hw_cfg_args.
- out_map_entries[i].resource_handle;
+ hw_cfg_args->out_map_entries[i].resource_handle;
}
- buf_data.request_id =
- (uint64_t)p_cfg_req->hw_cfg_args.priv;
+ buf_data.request_id = (uint64_t)p_cfg_req->hw_cfg_args.priv;
ctx_data->ctxt_event_cb(ctx_data->context_priv, 0, &buf_data);
}
@@ -753,8 +751,8 @@
p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
if (hw_mgr->device_in_use[dev_type][0] == true &&
p_cfg_req != NULL) {
- if ((struct cam_jpeg_hw_ctx_data *)p_cfg_req->
- hw_cfg_args.ctxt_to_hw_map == ctx_data) {
+ if ((struct cam_jpeg_hw_ctx_data *)
+ p_cfg_req->hw_cfg_args.ctxt_to_hw_map == ctx_data) {
/* stop reset Unregister CB and deinit */
irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb;
irq_cb.data = NULL;
@@ -811,8 +809,8 @@
list_for_each_entry_safe(cfg_req, req_temp,
&hw_mgr->hw_config_req_list, list) {
- if ((cfg_req) && ((struct cam_jpeg_hw_ctx_data *)cfg_req->
- hw_cfg_args.ctxt_to_hw_map != ctx_data))
+ if ((cfg_req) && ((struct cam_jpeg_hw_ctx_data *)
+ cfg_req->hw_cfg_args.ctxt_to_hw_map != ctx_data))
continue;
list_del_init(&cfg_req->list);
@@ -1091,8 +1089,8 @@
hw_mgr->cdm_info[dev_type][0].ref_cnt++;
}
- size = hw_mgr->cdm_info[dev_type][0].
- cdm_ops->cdm_required_size_changebase();
+ size =
+ hw_mgr->cdm_info[dev_type][0].cdm_ops->cdm_required_size_changebase();
if (hw_mgr->cdm_info[dev_type][0].ref_cnt == 1)
if (cam_cdm_stream_on(
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c
index 2d343dd..bc6dce9 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -47,9 +47,8 @@
}
soc_info = &jpeg_dma_dev->soc_info;
- core_info =
- (struct cam_jpeg_dma_device_core_info *)jpeg_dma_dev->
- core_info;
+ core_info = (struct cam_jpeg_dma_device_core_info *)
+ jpeg_dma_dev->core_info;
if (!soc_info || !core_info) {
CAM_ERR(CAM_JPEG, "soc_info = %pK core_info = %pK",
@@ -159,9 +158,8 @@
return -EINVAL;
}
- core_info =
- (struct cam_jpeg_dma_device_core_info *)jpeg_dma_dev->
- core_info;
+ core_info = (struct cam_jpeg_dma_device_core_info *)
+ jpeg_dma_dev->core_info;
switch (cmd_type) {
case CAM_JPEG_CMD_SET_IRQ_CB:
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c
index 05ae7cc..ef10406 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -153,8 +153,8 @@
rc = -ENOMEM;
goto error_alloc_core;
}
- core_info = (struct cam_jpeg_dma_device_core_info *)jpeg_dma_dev->
- core_info;
+ core_info = (struct cam_jpeg_dma_device_core_info *)
+ jpeg_dma_dev->core_info;
match_dev = of_match_device(pdev->dev.driver->of_match_table,
&pdev->dev);
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
index 934b911..9fa691b 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -58,9 +58,8 @@
}
soc_info = &jpeg_enc_dev->soc_info;
- core_info =
- (struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
- core_info;
+ core_info = (struct cam_jpeg_enc_device_core_info *)
+ jpeg_enc_dev->core_info;
if (!soc_info || !core_info) {
CAM_ERR(CAM_JPEG, "soc_info = %pK core_info = %pK",
@@ -168,9 +167,8 @@
return IRQ_HANDLED;
}
soc_info = &jpeg_enc_dev->soc_info;
- core_info =
- (struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
- core_info;
+ core_info = (struct cam_jpeg_enc_device_core_info *)
+ jpeg_enc_dev->core_info;
hw_info = core_info->jpeg_enc_hw_info;
mem_base = soc_info->reg_map[0].mem_base;
@@ -188,8 +186,7 @@
spin_lock(&jpeg_enc_dev->hw_lock);
if (core_info->core_state == CAM_JPEG_ENC_CORE_READY) {
encoded_size = cam_io_r_mb(mem_base +
- core_info->jpeg_enc_hw_info->reg_offset.
- encode_size);
+ core_info->jpeg_enc_hw_info->reg_offset.encode_size);
if (core_info->irq_cb.jpeg_hw_mgr_cb) {
core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
encoded_size,
@@ -263,9 +260,8 @@
}
/* maskdisable.clrirq.maskenable.resetcmd */
soc_info = &jpeg_enc_dev->soc_info;
- core_info =
- (struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
- core_info;
+ core_info = (struct cam_jpeg_enc_device_core_info *)
+ jpeg_enc_dev->core_info;
hw_info = core_info->jpeg_enc_hw_info;
mem_base = soc_info->reg_map[0].mem_base;
@@ -348,9 +344,8 @@
return -EINVAL;
}
soc_info = &jpeg_enc_dev->soc_info;
- core_info =
- (struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
- core_info;
+ core_info = (struct cam_jpeg_enc_device_core_info *)
+ jpeg_enc_dev->core_info;
hw_info = core_info->jpeg_enc_hw_info;
mem_base = soc_info->reg_map[0].mem_base;
@@ -398,9 +393,8 @@
return -EINVAL;
}
- core_info =
- (struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
- core_info;
+ core_info = (struct cam_jpeg_enc_device_core_info *)
+ jpeg_enc_dev->core_info;
switch (cmd_type) {
case CAM_JPEG_CMD_SET_IRQ_CB:
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c
index 2180448..d1eb526 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -152,8 +152,8 @@
rc = -ENOMEM;
goto error_alloc_core;
}
- core_info = (struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
- core_info;
+ core_info = (struct cam_jpeg_enc_device_core_info *)
+ jpeg_enc_dev->core_info;
match_dev = of_match_device(pdev->dev.driver->of_match_table,
&pdev->dev);
diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
index 20b8586..898997a 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -391,13 +391,14 @@
work_data = (struct cam_lrme_mgr_work_data *)data;
hw_device = work_data->hw_device;
- rc = cam_lrme_mgr_util_get_frame_req(&hw_device->
- frame_pending_list_high, &frame_req, &hw_device->high_req_lock);
+ rc = cam_lrme_mgr_util_get_frame_req(
+ &hw_device->frame_pending_list_high, &frame_req,
+ &hw_device->high_req_lock);
if (!frame_req) {
- rc = cam_lrme_mgr_util_get_frame_req(&hw_device->
- frame_pending_list_normal, &frame_req,
- &hw_device->normal_req_lock);
+ rc = cam_lrme_mgr_util_get_frame_req(
+ &hw_device->frame_pending_list_normal, &frame_req,
+ &hw_device->normal_req_lock);
if (frame_req)
req_prio = 1;
}
diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c
index 21e66a2..6f98354 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c
+++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c
@@ -449,8 +449,8 @@
cb_args.cb_type = CAM_LRME_CB_PUT_FRAME;
cb_args.frame_req = req_submit;
if (lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb)
- lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(lrme_core->
- hw_mgr_cb.data, &cb_args);
+ lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(
+ lrme_core->hw_mgr_cb.data, &cb_args);
} else if (req_submit) {
submit_args.frame_req = req_submit;
submit_args.hw_update_entries = req_submit->hw_update_entries;
@@ -468,8 +468,8 @@
cb_args.cb_type = CAM_LRME_CB_PUT_FRAME;
cb_args.frame_req = req_proc;
if (lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb)
- lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(lrme_core->
- hw_mgr_cb.data, &cb_args);
+ lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(
+ lrme_core->hw_mgr_cb.data, &cb_args);
} else if (req_proc) {
submit_args.frame_req = req_proc;
submit_args.hw_update_entries = req_proc->hw_update_entries;
@@ -511,8 +511,8 @@
cb_args.cb_type = CAM_LRME_CB_PUT_FRAME;
cb_args.frame_req = req_submit;
if (lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb)
- lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(lrme_core->
- hw_mgr_cb.data, &cb_args);
+ lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(
+ lrme_core->hw_mgr_cb.data, &cb_args);
} else if (req_submit) {
submit_args.frame_req = req_submit;
submit_args.hw_update_entries = req_submit->hw_update_entries;
@@ -530,8 +530,8 @@
cb_args.cb_type = CAM_LRME_CB_PUT_FRAME;
cb_args.frame_req = req_proc;
if (lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb)
- lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(lrme_core->
- hw_mgr_cb.data, &cb_args);
+ lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(
+ lrme_core->hw_mgr_cb.data, &cb_args);
} else if (req_proc) {
submit_args.frame_req = req_proc;
submit_args.hw_update_entries = req_proc->hw_update_entries;
@@ -745,8 +745,8 @@
}
if (lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb) {
- lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(lrme_core->
- hw_mgr_cb.data, &cb_args);
+ lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(
+ lrme_core->hw_mgr_cb.data, &cb_args);
} else {
CAM_ERR(CAM_LRME, "No hw mgr cb");
rc = -EINVAL;
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
index e66d21d..aaba481 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
@@ -1684,8 +1684,8 @@
evt_data.u.error = err_info->error;
if (device->ops &&
device->ops->process_evt)
- rc = device->ops->
- process_evt(&evt_data);
+ rc = device->ops->process_evt(
+ &evt_data);
}
}
/* Bring processing pointer to bubbled req id */
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
index 079f5bb..9f26635 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -193,16 +193,12 @@
for (i = 0; i < size; i++) {
rc = camera_io_dev_poll(
io_master_info,
- i2c_list->i2c_settings.
- reg_setting[i].reg_addr,
- i2c_list->i2c_settings.
- reg_setting[i].reg_data,
- i2c_list->i2c_settings.
- reg_setting[i].data_mask,
+ i2c_list->i2c_settings.reg_setting[i].reg_addr,
+ i2c_list->i2c_settings.reg_setting[i].reg_data,
+ i2c_list->i2c_settings.reg_setting[i].data_mask,
i2c_list->i2c_settings.addr_type,
- i2c_list->i2c_settings.data_type,
- i2c_list->i2c_settings.
- reg_setting[i].delay);
+ i2c_list->i2c_settings.data_type,
+ i2c_list->i2c_settings.reg_setting[i].delay);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR,
"i2c poll apply setting Fail: %d", rc);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
index b975418..fe69fcb 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
@@ -94,8 +94,8 @@
CAM_DBG(CAM_CCI, "CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d len %d max %d",
read_val, len,
cci_dev->cci_i2c_queue_info[master][queue].max_queue_size);
- if ((read_val + len + 1) > cci_dev->
- cci_i2c_queue_info[master][queue].max_queue_size) {
+ if ((read_val + len + 1) >
+ cci_dev->cci_i2c_queue_info[master][queue].max_queue_size) {
uint32_t reg_val = 0;
uint32_t report_val = CCI_I2C_REPORT_CMD | (1 << 8);
@@ -113,16 +113,18 @@
CAM_DBG(CAM_CCI, "CCI_QUEUE_START_ADDR");
spin_lock_irqsave(
&cci_dev->cci_master_info[master].lock_q[queue], flags);
- atomic_set(&cci_dev->cci_master_info[master].
- done_pending[queue], 1);
+ atomic_set(
+ &cci_dev->cci_master_info[master].done_pending[queue],
+ 1);
cam_io_w_mb(reg_val, base +
CCI_QUEUE_START_ADDR);
CAM_DBG(CAM_CCI, "wait_for_completion_timeout");
atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1);
spin_unlock_irqrestore(
&cci_dev->cci_master_info[master].lock_q[queue], flags);
- rc = wait_for_completion_timeout(&cci_dev->
- cci_master_info[master].report_q[queue], CCI_TIMEOUT);
+ rc = wait_for_completion_timeout(
+ &cci_dev->cci_master_info[master].report_q[queue],
+ CCI_TIMEOUT);
if (rc <= 0) {
CAM_ERR(CAM_CCI, "Wait_for_completion_timeout: rc: %d",
rc);
@@ -244,8 +246,8 @@
return -EINVAL;
}
- rc = wait_for_completion_timeout(&cci_dev->
- cci_master_info[master].report_q[queue], CCI_TIMEOUT);
+ rc = wait_for_completion_timeout(
+ &cci_dev->cci_master_info[master].report_q[queue], CCI_TIMEOUT);
CAM_DBG(CAM_CCI, "wait DONE_for_completion_timeout");
if (rc <= 0) {
@@ -338,8 +340,9 @@
return rc;
}
} else {
- atomic_set(&cci_dev->cci_master_info[master].
- done_pending[queue], 1);
+ atomic_set(
+ &cci_dev->cci_master_info[master].done_pending[queue],
+ 1);
spin_unlock_irqrestore(
&cci_dev->cci_master_info[master].lock_q[queue], flags);
rc = cam_cci_wait(cci_dev, master, queue);
@@ -376,9 +379,8 @@
CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
CAM_DBG(CAM_CCI, "CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d max %d", read_val,
cci_dev->cci_i2c_queue_info[master][queue].max_queue_size);
- return (cci_dev->
- cci_i2c_queue_info[master][queue].max_queue_size) -
- read_val;
+ return ((cci_dev->cci_i2c_queue_info[master][queue].max_queue_size) -
+ read_val);
}
static void cam_cci_process_half_q(struct cci_device *cci_dev,
@@ -414,8 +416,9 @@
spin_lock_irqsave(&cci_dev->cci_master_info[master].lock_q[queue],
flags);
if (atomic_read(&cci_dev->cci_master_info[master].q_free[queue]) == 1) {
- atomic_set(&cci_dev->cci_master_info[master].
- done_pending[queue], 1);
+ atomic_set(
+ &cci_dev->cci_master_info[master].done_pending[queue],
+ 1);
spin_unlock_irqrestore(
&cci_dev->cci_master_info[master].lock_q[queue], flags);
rc = cam_cci_wait(cci_dev, master, queue);
@@ -682,8 +685,8 @@
spin_unlock_irqrestore(&cci_dev->cci_master_info[master].lock_q[queue],
flags);
- max_queue_size = cci_dev->cci_i2c_queue_info[master][queue].
- max_queue_size;
+ max_queue_size =
+ cci_dev->cci_i2c_queue_info[master][queue].max_queue_size;
if (c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ)
queue_size = max_queue_size;
@@ -993,8 +996,8 @@
cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR);
CAM_DBG(CAM_CCI, "wait_for_completion_timeout");
- rc = wait_for_completion_timeout(&cci_dev->
- cci_master_info[master].reset_complete, CCI_TIMEOUT);
+ rc = wait_for_completion_timeout(
+ &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT);
if (rc <= 0) {
#ifdef DUMP_CCI_REGISTERS
cam_cci_dump_registers(cci_dev, master, queue);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c
index 8fb2468..fb37526 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c
@@ -74,14 +74,14 @@
if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) {
cci_dev->cci_master_info[MASTER_0].reset_pending =
FALSE;
- complete(&cci_dev->cci_master_info[MASTER_0].
- reset_complete);
+ complete(
+ &cci_dev->cci_master_info[MASTER_0].reset_complete);
}
if (cci_dev->cci_master_info[MASTER_1].reset_pending == TRUE) {
cci_dev->cci_master_info[MASTER_1].reset_pending =
FALSE;
- complete(&cci_dev->cci_master_info[MASTER_1].
- reset_complete);
+ complete(
+ &cci_dev->cci_master_info[MASTER_1].reset_complete);
}
}
if (irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) {
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c
index 14737f9..295259d 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c
@@ -53,11 +53,11 @@
mutex_lock(&cci_dev->cci_master_info[master].mutex);
flush_workqueue(cci_dev->write_wq[master]);
/* Re-initialize the completion */
- reinit_completion(&cci_dev->
- cci_master_info[master].reset_complete);
+ reinit_completion(
+ &cci_dev->cci_master_info[master].reset_complete);
for (i = 0; i < NUM_QUEUES; i++)
- reinit_completion(&cci_dev->
- cci_master_info[master].report_q[i]);
+ reinit_completion(
+ &cci_dev->cci_master_info[master].report_q[i]);
/* Set reset pending flag to TRUE */
cci_dev->cci_master_info[master].reset_pending = TRUE;
/* Set proper mask to RESET CMD address */
@@ -69,8 +69,7 @@
base + CCI_RESET_CMD_ADDR);
/* wait for reset done irq */
rc = wait_for_completion_timeout(
- &cci_dev->cci_master_info[master].
- reset_complete,
+ &cci_dev->cci_master_info[master].reset_complete,
CCI_TIMEOUT);
if (rc <= 0)
CAM_ERR(CAM_CCI, "wait failed %d", rc);
@@ -94,8 +93,8 @@
/* Re-initialize the completion */
reinit_completion(&cci_dev->cci_master_info[master].reset_complete);
for (i = 0; i < NUM_QUEUES; i++)
- reinit_completion(&cci_dev->cci_master_info[master].
- report_q[i]);
+ reinit_completion(
+ &cci_dev->cci_master_info[master].report_q[i]);
/* Enable Regulators and IRQ*/
rc = cam_soc_util_enable_platform_resource(soc_info, true,
@@ -116,19 +115,15 @@
for (i = 0; i < NUM_MASTERS; i++) {
for (j = 0; j < NUM_QUEUES; j++) {
if (j == QUEUE_0)
- cci_dev->cci_i2c_queue_info[i][j].
- max_queue_size =
- CCI_I2C_QUEUE_0_SIZE;
+ cci_dev->cci_i2c_queue_info[i][j].max_queue_size
+ = CCI_I2C_QUEUE_0_SIZE;
else
- cci_dev->cci_i2c_queue_info[i][j].
- max_queue_size =
- CCI_I2C_QUEUE_1_SIZE;
+ cci_dev->cci_i2c_queue_info[i][j].max_queue_size
+ = CCI_I2C_QUEUE_1_SIZE;
- CAM_DBG(CAM_CCI, "CCI Master[%d] :: Q0 : %d Q1 : %d", i
- , cci_dev->cci_i2c_queue_info[i][j].
- max_queue_size,
- cci_dev->cci_i2c_queue_info[i][j].
- max_queue_size);
+ CAM_DBG(CAM_CCI, "CCI Master[%d] :: Q0 : %d Q1 : %d", i,
+ cci_dev->cci_i2c_queue_info[i][j].max_queue_size,
+ cci_dev->cci_i2c_queue_info[i][j].max_queue_size);
}
}
@@ -191,13 +186,13 @@
for (i = 0; i < NUM_MASTERS; i++) {
new_cci_dev->cci_master_info[i].status = 0;
mutex_init(&new_cci_dev->cci_master_info[i].mutex);
- init_completion(&new_cci_dev->
- cci_master_info[i].reset_complete);
+ init_completion(
+ &new_cci_dev->cci_master_info[i].reset_complete);
for (j = 0; j < NUM_QUEUES; j++) {
mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]);
- init_completion(&new_cci_dev->
- cci_master_info[i].report_q[j]);
+ init_completion(
+ &new_cci_dev->cci_master_info[i].report_q[j]);
spin_lock_init(
&new_cci_dev->cci_master_info[i].lock_q[j]);
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
index 4f30f56..e978a40 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
@@ -64,16 +64,14 @@
for (i = 0; i < size; i++) {
cam_io_w_mb(
- csiphy_dev->ctrl_reg->
- csiphy_reset_reg[i].reg_data,
+ csiphy_dev->ctrl_reg->csiphy_reset_reg[i].reg_data,
base +
- csiphy_dev->ctrl_reg->
- csiphy_reset_reg[i].reg_addr);
+ csiphy_dev->ctrl_reg->csiphy_reset_reg[i].reg_addr);
usleep_range(csiphy_dev->ctrl_reg->
csiphy_reset_reg[i].delay * 1000,
- csiphy_dev->ctrl_reg->
- csiphy_reset_reg[i].delay * 1000 + 10);
+ csiphy_dev->ctrl_reg->csiphy_reset_reg[i].delay * 1000
+ + 10);
}
}
@@ -150,11 +148,10 @@
csiphy_dev->soc_info.reg_map[0].mem_base;
for (i = 0; i < csiphy_dev->num_irq_registers; i++)
- cam_io_w_mb(csiphy_dev->ctrl_reg->
- csiphy_irq_reg[i].reg_data,
+ cam_io_w_mb(
+ csiphy_dev->ctrl_reg->csiphy_irq_reg[i].reg_data,
csiphybase +
- csiphy_dev->ctrl_reg->
- csiphy_irq_reg[i].reg_addr);
+ csiphy_dev->ctrl_reg->csiphy_irq_reg[i].reg_addr);
}
void cam_csiphy_cphy_irq_disable(struct csiphy_device *csiphy_dev)
@@ -164,10 +161,8 @@
csiphy_dev->soc_info.reg_map[0].mem_base;
for (i = 0; i < csiphy_dev->num_irq_registers; i++)
- cam_io_w_mb(0x0,
- csiphybase +
- csiphy_dev->ctrl_reg->
- csiphy_irq_reg[i].reg_addr);
+ cam_io_w_mb(0x0, csiphybase +
+ csiphy_dev->ctrl_reg->csiphy_irq_reg[i].reg_addr);
}
irqreturn_t cam_csiphy_irq(int irq_num, void *data)
@@ -177,6 +172,7 @@
struct csiphy_device *csiphy_dev =
(struct csiphy_device *)data;
struct cam_hw_soc_info *soc_info = NULL;
+ struct csiphy_reg_parms_t *csiphy_reg = NULL;
void __iomem *base = NULL;
if (!csiphy_dev) {
@@ -186,30 +182,24 @@
soc_info = &csiphy_dev->soc_info;
base = csiphy_dev->soc_info.reg_map[0].mem_base;
+ csiphy_reg = &csiphy_dev->ctrl_reg->csiphy_reg;
for (i = 0; i < csiphy_dev->num_irq_registers; i++) {
- irq = cam_io_r(
- base +
- csiphy_dev->ctrl_reg->csiphy_reg.
- mipi_csiphy_interrupt_status0_addr + 0x4*i);
- cam_io_w_mb(irq,
- base +
- csiphy_dev->ctrl_reg->csiphy_reg.
- mipi_csiphy_interrupt_clear0_addr + 0x4*i);
+ irq = cam_io_r(base +
+ csiphy_reg->mipi_csiphy_interrupt_status0_addr +
+ (0x4 * i));
+ cam_io_w_mb(irq, base +
+ csiphy_reg->mipi_csiphy_interrupt_clear0_addr +
+ (0x4 * i));
CAM_ERR_RATE_LIMIT(CAM_CSIPHY,
"CSIPHY%d_IRQ_STATUS_ADDR%d = 0x%x",
soc_info->index, i, irq);
- cam_io_w_mb(0x0,
- base +
- csiphy_dev->ctrl_reg->csiphy_reg.
- mipi_csiphy_interrupt_clear0_addr + 0x4*i);
+ cam_io_w_mb(0x0, base +
+ csiphy_reg->mipi_csiphy_interrupt_clear0_addr +
+ (0x4 * i));
}
- cam_io_w_mb(0x1, base +
- csiphy_dev->ctrl_reg->
- csiphy_reg.mipi_csiphy_glbl_irq_cmd_addr);
- cam_io_w_mb(0x0, base +
- csiphy_dev->ctrl_reg->
- csiphy_reg.mipi_csiphy_glbl_irq_cmd_addr);
+ cam_io_w_mb(0x1, base + csiphy_reg->mipi_csiphy_glbl_irq_cmd_addr);
+ cam_io_w_mb(0x0, base + csiphy_reg->mipi_csiphy_glbl_irq_cmd_addr);
return IRQ_HANDLED;
}
@@ -222,6 +212,7 @@
uint8_t lane_cnt, lane_pos = 0;
uint16_t settle_cnt = 0;
void __iomem *csiphybase;
+ struct csiphy_reg_t *csiphy_common_reg = NULL;
struct csiphy_reg_t (*reg_array)[MAX_SETTINGS_PER_LANE];
lane_cnt = csiphy_dev->csiphy_info.lane_cnt;
@@ -240,8 +231,8 @@
reg_array =
csiphy_dev->ctrl_reg->csiphy_2ph_reg;
csiphy_dev->num_irq_registers = 11;
- cfg_size = csiphy_dev->ctrl_reg->csiphy_reg.
- csiphy_2ph_config_array_size;
+ cfg_size =
+ csiphy_dev->ctrl_reg->csiphy_reg.csiphy_2ph_config_array_size;
lane_mask = csiphy_dev->csiphy_info.lane_mask & 0x1f;
for (i = 0; i < MAX_DPHY_DATA_LN; i++) {
@@ -262,8 +253,8 @@
reg_array =
csiphy_dev->ctrl_reg->csiphy_3ph_reg;
csiphy_dev->num_irq_registers = 11;
- cfg_size = csiphy_dev->ctrl_reg->csiphy_reg.
- csiphy_3ph_config_array_size;
+ cfg_size =
+ csiphy_dev->ctrl_reg->csiphy_reg.csiphy_3ph_config_array_size;
lane_mask = csiphy_dev->csiphy_info.lane_mask & 0x7;
mask = lane_mask;
@@ -276,32 +267,24 @@
}
size = csiphy_dev->ctrl_reg->csiphy_reg.csiphy_common_array_size;
-
for (i = 0; i < size; i++) {
- switch (csiphy_dev->ctrl_reg->
- csiphy_common_reg[i].csiphy_param_type) {
- case CSIPHY_LANE_ENABLE:
+ csiphy_common_reg = &csiphy_dev->ctrl_reg->csiphy_common_reg[i];
+ switch (csiphy_common_reg->csiphy_param_type) {
+ case CSIPHY_LANE_ENABLE:
cam_io_w_mb(lane_enable,
csiphybase +
- csiphy_dev->ctrl_reg->
- csiphy_common_reg[i].reg_addr);
- usleep_range(csiphy_dev->ctrl_reg->
- csiphy_common_reg[i].delay*1000,
- csiphy_dev->ctrl_reg->
- csiphy_common_reg[i].delay*1000 + 10);
+ csiphy_common_reg->reg_addr);
+ usleep_range(csiphy_common_reg->delay * 1000,
+ csiphy_common_reg->delay * 1000 + 10);
break;
- case CSIPHY_DEFAULT_PARAMS:
- cam_io_w_mb(csiphy_dev->ctrl_reg->
- csiphy_common_reg[i].reg_data,
+ case CSIPHY_DEFAULT_PARAMS:
+ cam_io_w_mb(csiphy_common_reg->reg_data,
csiphybase +
- csiphy_dev->ctrl_reg->
- csiphy_common_reg[i].reg_addr);
- usleep_range(csiphy_dev->ctrl_reg->
- csiphy_common_reg[i].delay*1000,
- csiphy_dev->ctrl_reg->
- csiphy_common_reg[i].delay*1000 + 10);
+ csiphy_common_reg->reg_addr);
+ usleep_range(csiphy_common_reg->delay * 1000,
+ csiphy_common_reg->delay * 1000 + 10);
break;
- default:
+ default:
break;
}
}
@@ -317,8 +300,8 @@
if (csiphy_dev->csiphy_info.combo_mode == 1 &&
(lane_pos >= 3))
settle_cnt =
- (csiphy_dev->csiphy_info.
- settle_time_combo_sensor / 200000000);
+ (csiphy_dev->csiphy_info.settle_time_combo_sensor /
+ 200000000);
for (i = 0; i < cfg_size; i++) {
switch (reg_array[lane_pos][i].csiphy_param_type) {
case CSIPHY_LANE_ENABLE:
@@ -400,6 +383,7 @@
csiphy_dev->ref_count = 0;
csiphy_dev->is_acquired_dev_combo_mode = 0;
csiphy_dev->acquire_count = 0;
+ csiphy_dev->start_dev_count = 0;
csiphy_dev->csiphy_state = CAM_CSIPHY_INIT;
}
@@ -445,6 +429,7 @@
{
struct csiphy_device *csiphy_dev =
(struct csiphy_device *)phy_dev;
+ struct intf_params *bridge_intf = NULL;
struct cam_control *cmd = (struct cam_control *)arg;
int32_t rc = 0;
@@ -523,11 +508,10 @@
csiphy_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
- csiphy_dev->bridge_intf.
- device_hdl[csiphy_acq_params.combo_mode] =
- csiphy_acq_dev.device_handle;
- csiphy_dev->bridge_intf.
- session_hdl[csiphy_acq_params.combo_mode] =
+ bridge_intf = &csiphy_dev->bridge_intf;
+ bridge_intf->device_hdl[csiphy_acq_params.combo_mode]
+ = csiphy_acq_dev.device_handle;
+ bridge_intf->session_hdl[csiphy_acq_params.combo_mode] =
csiphy_acq_dev.session_handle;
if (copy_to_user((void __user *)cmd->handle,
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
index e7110b8..9b74826 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
@@ -284,8 +284,8 @@
for (i = 0; i < flash_data->cmn_attr.count; i++)
flash_data->led_current_ma[i] = 0;
} else {
- fctrl->flash_init_setting.cmn_attr.
- is_settings_valid = false;
+ fctrl->flash_init_setting.cmn_attr.is_settings_valid
+ = false;
}
} else {
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
@@ -513,7 +513,7 @@
uint64_t generic_ptr;
uint32_t *cmd_buf = NULL;
uint32_t *offset = NULL;
- uint32_t frame_offset = 0;
+ uint32_t frm_offset = 0;
size_t len_of_buffer;
struct cam_control *ioctl_ctrl = NULL;
struct cam_packet *csl_packet = NULL;
@@ -525,6 +525,7 @@
struct cam_flash_set_rer *flash_rer_info = NULL;
struct cam_flash_set_on_off *flash_operation_info = NULL;
struct cam_flash_query_curr *flash_query_info = NULL;
+ struct cam_flash_frame_setting *flash_data = NULL;
if (!fctrl || !arg) {
CAM_ERR(CAM_FLASH, "fctrl/arg is NULL");
@@ -616,25 +617,19 @@
case CAM_FLASH_PACKET_OPCODE_SET_OPS: {
offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
csl_packet->cmd_buf_offset);
- frame_offset = csl_packet->header.request_id %
+ frm_offset = csl_packet->header.request_id %
MAX_PER_FRAME_ARRAY;
- if (fctrl->per_frame[frame_offset].cmn_attr.is_settings_valid
- == true) {
- fctrl->per_frame[frame_offset].cmn_attr.request_id = 0;
- fctrl->per_frame[frame_offset].
- cmn_attr.is_settings_valid = false;
- for (i = 0;
- i < fctrl->per_frame[frame_offset].cmn_attr.count;
- i++) {
- fctrl->per_frame[frame_offset].
- led_current_ma[i] = 0;
- }
+ flash_data = &fctrl->per_frame[frm_offset];
+
+ if (flash_data->cmn_attr.is_settings_valid == true) {
+ flash_data->cmn_attr.request_id = 0;
+ flash_data->cmn_attr.is_settings_valid = false;
+ for (i = 0; i < flash_data->cmn_attr.count; i++)
+ flash_data->led_current_ma[i] = 0;
}
- fctrl->per_frame[frame_offset].cmn_attr.request_id =
- csl_packet->header.request_id;
- fctrl->per_frame[frame_offset].cmn_attr.is_settings_valid =
- true;
+ flash_data->cmn_attr.request_id = csl_packet->header.request_id;
+ flash_data->cmn_attr.is_settings_valid = true;
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle,
(uint64_t *)&generic_ptr, &len_of_buffer);
@@ -655,8 +650,7 @@
CAM_FLASH_STATE_ACQUIRE)) {
CAM_WARN(CAM_FLASH,
"Rxed Flash fire ops without linking");
- fctrl->per_frame[frame_offset].
- cmn_attr.is_settings_valid = false;
+ flash_data->cmn_attr.is_settings_valid = false;
return 0;
}
@@ -668,16 +662,12 @@
return -EINVAL;
}
- fctrl->per_frame[frame_offset].opcode =
- flash_operation_info->opcode;
- fctrl->per_frame[frame_offset].cmn_attr.count =
+ flash_data->opcode = flash_operation_info->opcode;
+ flash_data->cmn_attr.count =
flash_operation_info->count;
- for (i = 0;
- i < flash_operation_info->count; i++)
- fctrl->per_frame[frame_offset].
- led_current_ma[i]
- = flash_operation_info->
- led_current_ma[i];
+ for (i = 0; i < flash_operation_info->count; i++)
+ flash_data->led_current_ma[i]
+ = flash_operation_info->led_current_ma[i];
}
break;
default:
@@ -782,8 +772,10 @@
(fctrl->flash_state == CAM_FLASH_STATE_ACQUIRE)) {
CAM_WARN(CAM_FLASH,
"Rxed NOP packets without linking");
- fctrl->per_frame[frame_offset].
- cmn_attr.is_settings_valid = false;
+ frm_offset = csl_packet->header.request_id %
+ MAX_PER_FRAME_ARRAY;
+ fctrl->per_frame[frm_offset].cmn_attr.is_settings_valid
+ = false;
return 0;
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
index 3a0a6d6..fbdaee7 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
@@ -233,17 +233,13 @@
size = i2c_list->i2c_settings.size;
for (i = 0; i < size; i++) {
rc = camera_io_dev_poll(
- &(o_ctrl->io_master_info),
- i2c_list->i2c_settings.
- reg_setting[i].reg_addr,
- i2c_list->i2c_settings.
- reg_setting[i].reg_data,
- i2c_list->i2c_settings.
- reg_setting[i].data_mask,
- i2c_list->i2c_settings.addr_type,
- i2c_list->i2c_settings.data_type,
- i2c_list->i2c_settings.
- reg_setting[i].delay);
+ &(o_ctrl->io_master_info),
+ i2c_list->i2c_settings.reg_setting[i].reg_addr,
+ i2c_list->i2c_settings.reg_setting[i].reg_data,
+ i2c_list->i2c_settings.reg_setting[i].data_mask,
+ i2c_list->i2c_settings.addr_type,
+ i2c_list->i2c_settings.data_type,
+ i2c_list->i2c_settings.reg_setting[i].delay);
if (rc < 0) {
CAM_ERR(CAM_OIS,
"i2c poll apply setting Fail");
@@ -529,8 +525,8 @@
return rc;
}
} else if ((o_ctrl->is_ois_calib != 0) &&
- (o_ctrl->i2c_calib_data.
- is_settings_valid == 0)) {
+ (o_ctrl->i2c_calib_data.is_settings_valid ==
+ 0)) {
CAM_DBG(CAM_OIS,
"Received calib settings");
i2c_reg_settings = &(o_ctrl->i2c_calib_data);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
index 5a1b67c..b3f3a35 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
@@ -190,9 +190,8 @@
}
i2c_reg_settings =
- &i2c_data->
- per_frame[csl_packet->header.request_id %
- MAX_PER_FRAME_ARRAY];
+ &i2c_data->per_frame[csl_packet->header.request_id %
+ MAX_PER_FRAME_ARRAY];
CAM_DBG(CAM_SENSOR, "Received Packet: %lld req: %lld",
csl_packet->header.request_id % MAX_PER_FRAME_ARRAY,
csl_packet->header.request_id);
@@ -290,16 +289,12 @@
for (i = 0; i < size; i++) {
rc = camera_io_dev_poll(
io_master_info,
- i2c_list->i2c_settings.
- reg_setting[i].reg_addr,
- i2c_list->i2c_settings.
- reg_setting[i].reg_data,
- i2c_list->i2c_settings.
- reg_setting[i].data_mask,
+ i2c_list->i2c_settings.reg_setting[i].reg_addr,
+ i2c_list->i2c_settings.reg_setting[i].reg_data,
+ i2c_list->i2c_settings.reg_setting[i].data_mask,
i2c_list->i2c_settings.addr_type,
- i2c_list->i2c_settings.data_type,
- i2c_list->i2c_settings.
- reg_setting[i].delay);
+ i2c_list->i2c_settings.data_type,
+ i2c_list->i2c_settings.reg_setting[i].delay);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"i2c poll apply setting Fail: %d", rc);
@@ -1104,9 +1099,9 @@
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
if ((del_req_id >
- s_ctrl->i2c_data.per_frame[i].request_id) &&
- (s_ctrl->i2c_data.per_frame[i].
- is_settings_valid == 1)) {
+ s_ctrl->i2c_data.per_frame[i].request_id) && (
+ s_ctrl->i2c_data.per_frame[i].is_settings_valid
+ == 1)) {
s_ctrl->i2c_data.per_frame[i].request_id = 0;
rc = delete_request(
&(s_ctrl->i2c_data.per_frame[i]));
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
index f9b846b..ac60dc8 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
@@ -93,12 +93,10 @@
list_entry(list_ptr, struct i2c_settings_list, list);
if (generic_op_code ==
CAMERA_SENSOR_WAIT_OP_HW_UCND)
- i2c_list->i2c_settings.
- reg_setting[offset - 1].delay =
+ i2c_list->i2c_settings.reg_setting[offset - 1].delay =
cmd_uncond_wait->delay;
else
- i2c_list->i2c_settings.delay =
- cmd_uncond_wait->delay;
+ i2c_list->i2c_settings.delay = cmd_uncond_wait->delay;
(*cmd_buf) +=
sizeof(
struct cam_cmd_unconditional_wait) / sizeof(uint32_t);
@@ -182,14 +180,10 @@
for (cnt = 0; cnt < (cam_cmd_i2c_random_wr->header.count);
cnt++) {
i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
- cam_cmd_i2c_random_wr->
- random_wr_payload[cnt].reg_addr;
- i2c_list->i2c_settings.
- reg_setting[cnt].reg_data =
- cam_cmd_i2c_random_wr->
- random_wr_payload[cnt].reg_data;
- i2c_list->i2c_settings.
- reg_setting[cnt].data_mask = 0;
+ cam_cmd_i2c_random_wr->random_wr_payload[cnt].reg_addr;
+ i2c_list->i2c_settings.reg_setting[cnt].reg_data =
+ cam_cmd_i2c_random_wr->random_wr_payload[cnt].reg_data;
+ i2c_list->i2c_settings.reg_setting[cnt].data_mask = 0;
}
*offset = cnt;
*list = &(i2c_list->list);
@@ -237,14 +231,10 @@
for (cnt = 0; cnt < (cam_cmd_i2c_continuous_wr->header.count);
cnt++) {
i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
- cam_cmd_i2c_continuous_wr->
- reg_addr;
- i2c_list->i2c_settings.
- reg_setting[cnt].reg_data =
- cam_cmd_i2c_continuous_wr->
- data_read[cnt].reg_data;
- i2c_list->i2c_settings.
- reg_setting[cnt].data_mask = 0;
+ cam_cmd_i2c_continuous_wr->reg_addr;
+ i2c_list->i2c_settings.reg_setting[cnt].reg_data =
+ cam_cmd_i2c_continuous_wr->data_read[cnt].reg_data;
+ i2c_list->i2c_settings.reg_setting[cnt].data_mask = 0;
}
*offset = cnt;
*list = &(i2c_list->list);
@@ -642,6 +632,7 @@
{
int32_t rc = 0, tot_size = 0, last_cmd_type = 0;
int32_t i = 0, pwr_up = 0, pwr_down = 0;
+ struct cam_sensor_power_setting *pwr_settings;
void *ptr = cmd_buf, *scr;
struct cam_cmd_power *pwr_cmd = (struct cam_cmd_power *)cmd_buf;
struct common_header *cmm_hdr = (struct common_header *)cmd_buf;
@@ -684,14 +675,10 @@
CAM_WARN(CAM_SENSOR, "Un expected Command");
for (i = 0; i < pwr_cmd->count; i++, pwr_up++) {
- power_info->
- power_setting[pwr_up].seq_type =
- pwr_cmd->power_settings[i].
- power_seq_type;
- power_info->
- power_setting[pwr_up].config_val =
- pwr_cmd->power_settings[i].
- config_val_low;
+ power_info->power_setting[pwr_up].seq_type =
+ pwr_cmd->power_settings[i].power_seq_type;
+ power_info->power_setting[pwr_up].config_val =
+ pwr_cmd->power_settings[i].config_val_low;
power_info->power_setting[pwr_up].delay = 0;
if (i) {
scr = scr +
@@ -708,13 +695,9 @@
goto free_power_down_settings;
}
CAM_DBG(CAM_SENSOR,
- "Seq Type[%d]: %d Config_val: %ld",
- pwr_up,
- power_info->
- power_setting[pwr_up].seq_type,
- power_info->
- power_setting[pwr_up].
- config_val);
+ "Seq Type[%d]: %d Config_val: %ld", pwr_up,
+ power_info->power_setting[pwr_up].seq_type,
+ power_info->power_setting[pwr_up].config_val);
}
last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_UP;
ptr = (void *) scr;
@@ -722,32 +705,38 @@
} else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) {
struct cam_cmd_unconditional_wait *wait_cmd =
(struct cam_cmd_unconditional_wait *)ptr;
- if (wait_cmd->op_code ==
- CAMERA_SENSOR_WAIT_OP_SW_UCND) {
- if (last_cmd_type ==
- CAMERA_SENSOR_CMD_TYPE_PWR_UP) {
- if (pwr_up > 0)
- power_info->
- power_setting
- [pwr_up - 1].delay +=
- wait_cmd->delay;
- else
- CAM_ERR(CAM_SENSOR,
- "Delay is expected only after valid power up setting");
- } else if (last_cmd_type ==
- CAMERA_SENSOR_CMD_TYPE_PWR_DOWN) {
- if (pwr_down > 0)
- power_info->
- power_down_setting
- [pwr_down - 1].delay +=
- wait_cmd->delay;
- else
- CAM_ERR(CAM_SENSOR,
- "Delay is expected only after valid power up setting");
+ if ((wait_cmd->op_code ==
+ CAMERA_SENSOR_WAIT_OP_SW_UCND) &&
+ (last_cmd_type ==
+ CAMERA_SENSOR_CMD_TYPE_PWR_UP)) {
+ if (pwr_up > 0) {
+ pwr_settings =
+ &power_info->power_setting[pwr_up - 1];
+ pwr_settings->delay +=
+ wait_cmd->delay;
+ } else {
+ CAM_ERR(CAM_SENSOR,
+ "Delay is expected only after valid power up setting");
}
- } else
+ } else if ((wait_cmd->op_code ==
+ CAMERA_SENSOR_WAIT_OP_SW_UCND) &&
+ (last_cmd_type ==
+ CAMERA_SENSOR_CMD_TYPE_PWR_DOWN)) {
+ if (pwr_down > 0) {
+ pwr_settings =
+ &power_info->power_down_setting[
+ pwr_down - 1];
+ pwr_settings->delay +=
+ wait_cmd->delay;
+ } else {
+ CAM_ERR(CAM_SENSOR,
+ "Delay is expected only after valid power up setting");
+ }
+ } else {
CAM_DBG(CAM_SENSOR, "Invalid op code: %d",
wait_cmd->op_code);
+ }
+
tot_size = tot_size +
sizeof(struct cam_cmd_unconditional_wait);
if (tot_size > cmd_length) {
@@ -776,18 +765,14 @@
CAM_ERR(CAM_SENSOR, "Invalid Command");
for (i = 0; i < pwr_cmd->count; i++, pwr_down++) {
- power_info->
- power_down_setting[pwr_down].
- seq_type =
- pwr_cmd->power_settings[i].
- power_seq_type;
- power_info->
- power_down_setting[pwr_down].
- config_val =
- pwr_cmd->power_settings[i].
- config_val_low;
- power_info->
- power_down_setting[pwr_down].delay = 0;
+ pwr_settings =
+ &power_info->power_down_setting[pwr_down];
+ pwr_settings->seq_type =
+ pwr_cmd->power_settings[i].power_seq_type;
+ pwr_settings->config_val =
+ pwr_cmd->power_settings[i].config_val_low;
+ power_info->power_down_setting[pwr_down].delay
+ = 0;
if (i) {
scr = scr +
sizeof(
@@ -805,13 +790,8 @@
}
CAM_DBG(CAM_SENSOR,
"Seq Type[%d]: %d Config_val: %ld",
- pwr_down,
- power_info->
- power_down_setting[pwr_down].
- seq_type,
- power_info->
- power_down_setting[pwr_down].
- config_val);
+ pwr_down, pwr_settings->seq_type,
+ pwr_settings->config_val);
}
last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_DOWN;
ptr = (void *) scr;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index fda45cb..691b492 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -26,6 +26,7 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
#include <media/videobuf2-core.h>
+#include <media/msmb_generic_buf_mgr.h>
#include "msm.h"
#include "msm_buf_mgr.h"
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
index e350096..e458b4df 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -167,6 +167,33 @@
return ret;
}
+static int32_t msm_buf_mngr_buf_error(struct msm_buf_mngr_device *buf_mngr_dev,
+ struct msm_buf_mngr_info *buf_info)
+{
+ unsigned long flags;
+ struct msm_get_bufs *bufs, *save;
+ int32_t ret = -EINVAL;
+
+ spin_lock_irqsave(&buf_mngr_dev->buf_q_spinlock, flags);
+ list_for_each_entry_safe(bufs, save, &buf_mngr_dev->buf_qhead, entry) {
+ if ((bufs->session_id == buf_info->session_id) &&
+ (bufs->stream_id == buf_info->stream_id) &&
+ (bufs->index == buf_info->index)) {
+ ret = buf_mngr_dev->vb2_ops.buf_error
+ (bufs->vb2_v4l2_buf,
+ buf_info->session_id,
+ buf_info->stream_id,
+ buf_info->frame_id,
+ &buf_info->timestamp,
+ buf_info->reserved);
+ list_del_init(&bufs->entry);
+ kfree(bufs);
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&buf_mngr_dev->buf_q_spinlock, flags);
+ return ret;
+}
static int32_t msm_buf_mngr_put_buf(struct msm_buf_mngr_device *buf_mngr_dev,
struct msm_buf_mngr_info *buf_info)
@@ -478,6 +505,9 @@
case VIDIOC_MSM_BUF_MNGR_BUF_DONE:
rc = msm_buf_mngr_buf_done(msm_buf_mngr_dev, argp);
break;
+ case VIDIOC_MSM_BUF_MNGR_BUF_ERROR:
+ rc = msm_buf_mngr_buf_error(msm_buf_mngr_dev, argp);
+ break;
case VIDIOC_MSM_BUF_MNGR_PUT_BUF:
rc = msm_buf_mngr_put_buf(msm_buf_mngr_dev, argp);
break;
@@ -576,6 +606,7 @@
case VIDIOC_MSM_BUF_MNGR_GET_BUF:
case VIDIOC_MSM_BUF_MNGR_BUF_DONE:
case VIDIOC_MSM_BUF_MNGR_PUT_BUF:
+ case VIDIOC_MSM_BUF_MNGR_BUF_ERROR:
rc = msm_cam_buf_mgr_ops(cmd, argp);
break;
case VIDIOC_MSM_BUF_MNGR_INIT:
@@ -724,6 +755,9 @@
case VIDIOC_MSM_BUF_MNGR_BUF_DONE32:
cmd = VIDIOC_MSM_BUF_MNGR_BUF_DONE;
break;
+ case VIDIOC_MSM_BUF_MNGR_BUF_ERROR32:
+ cmd = VIDIOC_MSM_BUF_MNGR_BUF_ERROR;
+ break;
case VIDIOC_MSM_BUF_MNGR_PUT_BUF32:
cmd = VIDIOC_MSM_BUF_MNGR_PUT_BUF;
break;
@@ -742,6 +776,7 @@
switch (cmd) {
case VIDIOC_MSM_BUF_MNGR_GET_BUF:
case VIDIOC_MSM_BUF_MNGR_BUF_DONE:
+ case VIDIOC_MSM_BUF_MNGR_BUF_ERROR:
case VIDIOC_MSM_BUF_MNGR_FLUSH:
case VIDIOC_MSM_BUF_MNGR_PUT_BUF: {
struct msm_buf_mngr_info32_t buf_info32;
diff --git a/drivers/media/platform/msm/camera_v2/msm_sd.h b/drivers/media/platform/msm/camera_v2/msm_sd.h
index f45c0d7..64cb785 100644
--- a/drivers/media/platform/msm/camera_v2/msm_sd.h
+++ b/drivers/media/platform/msm/camera_v2/msm_sd.h
@@ -81,6 +81,9 @@
unsigned int stream_id, uint32_t sequence, struct timeval *ts,
uint32_t reserved);
int (*flush_buf)(int session_id, unsigned int stream_id);
+ int (*buf_error)(struct vb2_v4l2_buffer *vb2_v4l2_buf, int session_id,
+ unsigned int stream_id, uint32_t sequence, struct timeval *ts,
+ uint32_t reserved);
};
#define MSM_SD_NOTIFY_GET_SD 0x00000001
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index 87e0172..6e528a6 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -461,6 +461,69 @@
return rc;
}
+static int msm_vb2_buf_error(struct vb2_v4l2_buffer *vb, int session_id,
+ unsigned int stream_id, uint32_t sequence,
+ struct timeval *ts, uint32_t buf_type)
+{
+ unsigned long flags, rl_flags;
+ struct msm_vb2_buffer *msm_vb2;
+ struct msm_stream *stream;
+ struct msm_session *session;
+ struct vb2_v4l2_buffer *vb2_v4l2_buf = NULL;
+ int rc = 0;
+
+ session = msm_get_session(session_id);
+ if (IS_ERR_OR_NULL(session))
+ return -EINVAL;
+
+ read_lock_irqsave(&session->stream_rwlock, rl_flags);
+
+ stream = msm_get_stream(session, stream_id);
+ if (IS_ERR_OR_NULL(stream)) {
+ read_unlock_irqrestore(&session->stream_rwlock, rl_flags);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&stream->stream_lock, flags);
+ if (vb) {
+ list_for_each_entry(msm_vb2, &(stream->queued_list), list) {
+ vb2_v4l2_buf = &(msm_vb2->vb2_v4l2_buf);
+ if (vb2_v4l2_buf == vb)
+ break;
+ }
+ if (vb2_v4l2_buf != vb) {
+ pr_err("VB buffer is INVALID ses_id=%d, str_id=%d, vb=%pK\n",
+ session_id, stream_id, vb);
+ spin_unlock_irqrestore(&stream->stream_lock, flags);
+ read_unlock_irqrestore(&session->stream_rwlock,
+ rl_flags);
+ return -EINVAL;
+ }
+ msm_vb2 =
+ container_of(vb2_v4l2_buf, struct msm_vb2_buffer,
+ vb2_v4l2_buf);
+ /* put buf before buf done */
+ if (msm_vb2->in_freeq) {
+ vb2_v4l2_buf->sequence = sequence;
+ vb2_v4l2_buf->timecode.type = buf_type;
+ vb2_v4l2_buf->vb2_buf.timestamp =
+ (ts->tv_sec * 1000000 + ts->tv_usec) * 1000;
+ vb2_buffer_done(&vb2_v4l2_buf->vb2_buf,
+ VB2_BUF_STATE_ERROR);
+ msm_vb2->in_freeq = 0;
+ rc = 0;
+ } else
+ rc = -EINVAL;
+ } else {
+ pr_err(" VB buffer is NULL for ses_id=%d, str_id=%d\n",
+ session_id, stream_id);
+ rc = -EINVAL;
+ }
+ spin_unlock_irqrestore(&stream->stream_lock, flags);
+ read_unlock_irqrestore(&session->stream_rwlock, rl_flags);
+ return rc;
+}
+
long msm_vb2_return_buf_by_idx(int session_id, unsigned int stream_id,
uint32_t index)
{
@@ -559,6 +622,7 @@
req->put_buf = msm_vb2_put_buf;
req->buf_done = msm_vb2_buf_done;
req->flush_buf = msm_vb2_flush_buf;
+ req->buf_error = msm_vb2_buf_error;
return 0;
}
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 70bb3f2..1ad2f257 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -1617,6 +1617,7 @@
case VIDIOC_MSM_BUF_MNGR_PUT_BUF:
case VIDIOC_MSM_BUF_MNGR_BUF_DONE:
case VIDIOC_MSM_BUF_MNGR_GET_BUF:
+ case VIDIOC_MSM_BUF_MNGR_BUF_ERROR:
default: {
struct msm_buf_mngr_info *buff_mgr_info =
(struct msm_buf_mngr_info *)arg;
@@ -3604,7 +3605,7 @@
break;
}
buff_mgr_info.frame_id = frame_info.frame_id;
- rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_BUF_DONE,
+ rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_BUF_ERROR,
0x0, &buff_mgr_info);
if (rc < 0) {
pr_err("error in buf done\n");
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index cef5396..97f5ca2 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -1501,6 +1501,8 @@
data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
data_done.output_done.flags1 = pkt->flags;
+ data_done.output_done.input_tag = pkt->input_tag;
+ data_done.output_done.output_tag = pkt->output_tag;
data_done.output_done.mark_target = pkt->mark_target;
data_done.output_done.mark_data = pkt->mark_data;
data_done.output_done.stats = pkt->stats;
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 192f36f2..3d29ed4 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -499,3 +499,25 @@
endif # V4L_RADIO_ISA_DRIVERS
endif # RADIO_ADAPTERS
+
+config RADIO_IRIS
+ tristate "QTI IRIS FM support"
+ depends on VIDEO_V4L2
+ ---help---
+ Say Y here if you want to use the QTI FM chip (IRIS).
+ This FM chip uses SMD interface
+
+ To compile this driver as a module, choose M here: the
+ module will be called radio-iris.
+
+
+config RADIO_IRIS_TRANSPORT
+ tristate "QTI IRIS Transport"
+ depends on RADIO_IRIS
+ ---help---
+ Say Y here if you want to use the QTI FM chip (IRIS).
+ with SMD as transport.
+
+ To compile this driver as a module, choose M here: the
+ module will be called radio-iris-transport.
+
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 120e791..efda39b 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -33,6 +33,8 @@
obj-$(CONFIG_RADIO_WL128X) += wl128x/
obj-$(CONFIG_RADIO_TEA575X) += tea575x.o
obj-$(CONFIG_USB_RAREMONO) += radio-raremono.o
+obj-$(CONFIG_RADIO_IRIS) += radio-iris.o
+obj-$(CONFIG_RADIO_IRIS_TRANSPORT) += radio-iris-transport.o
shark2-objs := radio-shark2.o radio-tea5777.o
diff --git a/drivers/media/radio/radio-iris-transport.c b/drivers/media/radio/radio-iris-transport.c
new file mode 100644
index 0000000..98afd19
--- /dev/null
+++ b/drivers/media/radio/radio-iris-transport.c
@@ -0,0 +1,274 @@
+/*
+ * QTI's FM Shared Memory Transport Driver
+ *
+ * FM HCI_SMD ( FM HCI Shared Memory Driver) is QTI's Shared memory driver
+ * for the HCI protocol. This file is based on drivers/bluetooth/hci_vhci.c
+ *
+ * Copyright (c) 2000-2001, 2011-2012, 2014-2015 The Linux Foundation.
+ * All rights reserved.
+ *
+ * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
+ * Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/skbuff.h>
+#include <linux/workqueue.h>
+#include <soc/qcom/smd.h>
+#include <media/radio-iris.h>
+#include <linux/uaccess.h>
+
+struct radio_data {
+ struct radio_hci_dev *hdev;
+ struct tasklet_struct rx_task;
+ struct smd_channel *fm_channel;
+};
+struct radio_data hs;
+DEFINE_MUTEX(fm_smd_enable);
+static int fmsmd_set;
+static bool chan_opened;
+static int hcismd_fm_set_enable(const char *val, struct kernel_param *kp);
+module_param_call(fmsmd_set, hcismd_fm_set_enable, NULL, &fmsmd_set, 0644);
+static struct work_struct *reset_worker;
+static void radio_hci_smd_deregister(void);
+static void radio_hci_smd_exit(void);
+
+static void radio_hci_smd_destruct(struct radio_hci_dev *hdev)
+{
+ radio_hci_unregister_dev();
+}
+
+
+static void radio_hci_smd_recv_event(unsigned long temp)
+{
+ int len;
+ int rc;
+ struct sk_buff *skb;
+ unsigned char *buf;
+ struct radio_data *hsmd = &hs;
+
+ len = smd_read_avail(hsmd->fm_channel);
+
+ while (len) {
+ skb = alloc_skb(len, GFP_ATOMIC);
+ if (!skb) {
+ FMDERR("Memory not allocated for the socket\n");
+ return;
+ }
+
+ buf = kmalloc(len, GFP_ATOMIC);
+ if (!buf) {
+ kfree_skb(skb);
+ return;
+ }
+
+ rc = smd_read(hsmd->fm_channel, (void *)buf, len);
+
+ memcpy(skb_put(skb, len), buf, len);
+
+ skb_orphan(skb);
+ skb->dev = (struct net_device *)hs.hdev;
+
+ rc = radio_hci_recv_frame(skb);
+
+ kfree(buf);
+ len = smd_read_avail(hsmd->fm_channel);
+ }
+}
+
+static int radio_hci_smd_send_frame(struct sk_buff *skb)
+{
+ int len = 0;
+
+ FMDBG("skb %pK\n", skb);
+
+ len = smd_write(hs.fm_channel, skb->data, skb->len);
+ if (len < skb->len) {
+ FMDERR("Failed to write Data %d\n", len);
+ kfree_skb(skb);
+ return -ENODEV;
+ }
+ kfree_skb(skb);
+ return 0;
+}
+
+
+static void send_disable_event(struct work_struct *worker)
+{
+ struct sk_buff *skb;
+ unsigned char buf[6] = { 0x0f, 0x04, 0x01, 0x02, 0x4c, 0x00 };
+ int len = sizeof(buf);
+
+ skb = alloc_skb(len, GFP_ATOMIC);
+ if (!skb) {
+ FMDERR("Memory not allocated for the socket\n");
+ kfree(worker);
+ return;
+ }
+
+ FMDBG("FM INSERT DISABLE Rx Event\n");
+
+ memcpy(skb_put(skb, len), buf, len);
+
+ skb_orphan(skb);
+ skb->dev = (struct net_device *)hs.hdev;
+
+ radio_hci_recv_frame(skb);
+ kfree(worker);
+}
+
+static void radio_hci_smd_notify_cmd(void *data, unsigned int event)
+{
+ struct radio_hci_dev *hdev = (struct radio_hci_dev *)data;
+
+ FMDBG("data %p event %u\n", data, event);
+
+ if (!hdev) {
+ FMDERR("Frame for unknown HCI device (hdev=NULL)\n");
+ return;
+ }
+
+ switch (event) {
+ case SMD_EVENT_DATA:
+ tasklet_schedule(&hs.rx_task);
+ break;
+ case SMD_EVENT_OPEN:
+ break;
+ case SMD_EVENT_CLOSE:
+ reset_worker = kzalloc(sizeof(*reset_worker), GFP_ATOMIC);
+ if (reset_worker) {
+ INIT_WORK(reset_worker, send_disable_event);
+ schedule_work(reset_worker);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static int radio_hci_smd_register_dev(struct radio_data *hsmd)
+{
+ struct radio_hci_dev *hdev;
+ int rc;
+
+ FMDBG("hsmd: %pK\n", hsmd);
+
+ if (hsmd == NULL)
+ return -ENODEV;
+
+ hdev = kmalloc(sizeof(struct radio_hci_dev), GFP_KERNEL);
+ if (hdev == NULL)
+ return -ENODEV;
+
+ tasklet_init(&hsmd->rx_task, radio_hci_smd_recv_event,
+ (unsigned long) hsmd);
+ hdev->send = radio_hci_smd_send_frame;
+ hdev->destruct = radio_hci_smd_destruct;
+ hdev->close_smd = radio_hci_smd_exit;
+
+ /* Open the SMD Channel and device and register the callback function */
+ rc = smd_named_open_on_edge("APPS_FM", SMD_APPS_WCNSS,
+ &hsmd->fm_channel, hdev, radio_hci_smd_notify_cmd);
+
+ if (rc < 0) {
+ FMDERR("Cannot open the command channel\n");
+ hsmd->hdev = NULL;
+ kfree(hdev);
+ return -ENODEV;
+ }
+
+ smd_disable_read_intr(hsmd->fm_channel);
+
+ if (radio_hci_register_dev(hdev) < 0) {
+ FMDERR("Can't register HCI device\n");
+ smd_close(hsmd->fm_channel);
+ hsmd->hdev = NULL;
+ kfree(hdev);
+ return -ENODEV;
+ }
+
+ hsmd->hdev = hdev;
+ return 0;
+}
+
+static void radio_hci_smd_deregister(void)
+{
+ radio_hci_unregister_dev();
+ kfree(hs.hdev);
+ hs.hdev = NULL;
+
+ smd_close(hs.fm_channel);
+ hs.fm_channel = 0;
+ fmsmd_set = 0;
+}
+
+static int radio_hci_smd_init(void)
+{
+ int ret;
+
+ if (chan_opened) {
+ FMDBG("Channel is already opened\n");
+ return 0;
+ }
+
+ /* this should be called with fm_smd_enable lock held */
+ ret = radio_hci_smd_register_dev(&hs);
+ if (ret < 0) {
+ FMDERR("Failed to register smd device\n");
+ chan_opened = false;
+ return ret;
+ }
+ chan_opened = true;
+ return ret;
+}
+
+static void radio_hci_smd_exit(void)
+{
+ if (!chan_opened) {
+ FMDBG("Channel already closed\n");
+ return;
+ }
+
+ /* this should be called with fm_smd_enable lock held */
+ radio_hci_smd_deregister();
+ chan_opened = false;
+}
+
+static int hcismd_fm_set_enable(const char *val, struct kernel_param *kp)
+{
+ int ret = 0;
+
+ mutex_lock(&fm_smd_enable);
+ ret = param_set_int(val, kp);
+ if (ret)
+ goto done;
+ switch (fmsmd_set) {
+
+ case 1:
+ radio_hci_smd_init();
+ break;
+ case 0:
+ radio_hci_smd_exit();
+ break;
+ default:
+ ret = -EFAULT;
+ }
+done:
+ mutex_unlock(&fm_smd_enable);
+ return ret;
+}
+MODULE_DESCRIPTION("FM SMD driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
new file mode 100644
index 0000000..7671049
--- /dev/null
+++ b/drivers/media/radio/radio-iris.c
@@ -0,0 +1,5646 @@
+/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved
+ *
+ * program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define DRIVER_NAME "radio-iris"
+#define DRIVER_CARD "QTI FM Radio Transceiver"
+#define DRIVER_DESC "Driver for QTI FM Radio Transceiver "
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/kfifo.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/version.h>
+#include <linux/videodev2.h>
+#include <linux/mutex.h>
+#include <linux/unistd.h>
+#include <linux/atomic.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/radio-iris.h>
+#include <asm/unaligned.h>
+
+static unsigned int rds_buf = 100;
+static int oda_agt;
+static int grp_mask;
+static int rt_plus_carrier = -1;
+static int ert_carrier = -1;
+static unsigned char ert_buf[256];
+static unsigned char ert_len;
+static unsigned char c_byt_pair_index;
+static char utf_8_flag;
+static char rt_ert_flag;
+static char formatting_dir;
+static unsigned char sig_blend = CTRL_ON;
+static DEFINE_MUTEX(iris_fm);
+
+module_param(rds_buf, uint, 0000);
+MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
+
+module_param(sig_blend, byte, 0200 | 0400 | 0040 | 0004);
+MODULE_PARM_DESC(sig_blend, "signal blending switch: 0:OFF 1:ON");
+
+static void radio_hci_cmd_task(unsigned long arg);
+static void radio_hci_rx_task(unsigned long arg);
+static struct video_device *video_get_dev(void);
+static DEFINE_RWLOCK(hci_task_lock);
+
+typedef int (*radio_hci_request_func)(struct radio_hci_dev *hdev,
+ int (*req)(struct radio_hci_dev *hdev, unsigned long param),
+ unsigned long param, unsigned long timeout_msecs);
+
+struct iris_device {
+ struct device *dev;
+ struct kfifo data_buf[IRIS_BUF_MAX];
+
+ int pending_xfrs[IRIS_XFR_MAX];
+ int xfr_bytes_left;
+ int xfr_in_progress;
+ struct completion sync_xfr_start;
+ int tune_req;
+ unsigned int mode;
+ bool is_fm_closing;
+
+ __u16 pi;
+ __u8 pty;
+ __u8 ps_repeatcount;
+ __u8 prev_trans_rds;
+ __u8 af_jump_bit;
+ struct video_device *videodev;
+ struct v4l2_device v4l2_dev;
+
+ struct mutex lock;
+ spinlock_t buf_lock[IRIS_BUF_MAX];
+ wait_queue_head_t event_queue;
+ wait_queue_head_t read_queue;
+
+ struct radio_hci_dev *fm_hdev;
+
+ struct v4l2_capability g_cap;
+ struct v4l2_control *g_ctl;
+
+ struct hci_fm_mute_mode_req mute_mode;
+ struct hci_fm_stereo_mode_req stereo_mode;
+ struct hci_fm_station_rsp fm_st_rsp;
+ struct hci_fm_search_station_req srch_st;
+ struct hci_fm_search_rds_station_req srch_rds;
+ struct hci_fm_search_station_list_req srch_st_list;
+ struct hci_fm_recv_conf_req recv_conf;
+ struct hci_fm_trans_conf_req_struct trans_conf;
+ struct hci_fm_rds_grp_req rds_grp;
+ unsigned char g_search_mode;
+ unsigned char power_mode;
+ int search_on;
+ unsigned int tone_freq;
+ unsigned char spur_table_size;
+ unsigned char g_scan_time;
+ unsigned int g_antenna;
+ unsigned int g_rds_grp_proc_ps;
+ unsigned char event_mask;
+ enum iris_region_t region;
+ struct hci_fm_dbg_param_rsp st_dbg_param;
+ struct hci_ev_srch_list_compl srch_st_result;
+ struct hci_fm_riva_poke riva_data_req;
+ struct hci_fm_ssbi_req ssbi_data_accs;
+ struct hci_fm_ssbi_peek ssbi_peek_reg;
+ struct hci_fm_sig_threshold_rsp sig_th;
+ struct hci_fm_ch_det_threshold ch_det_threshold;
+ struct hci_fm_data_rd_rsp default_data;
+ struct hci_fm_spur_data spur_data;
+ unsigned char is_station_valid;
+ struct hci_fm_blend_table blend_tbl;
+};
+
+static struct video_device *priv_videodev;
+static int iris_do_calibration(struct iris_device *radio);
+static void hci_buff_ert(struct iris_device *radio,
+ struct rds_grp_data *rds_buf);
+static void hci_ev_rt_plus(struct iris_device *radio,
+ struct rds_grp_data rds_buf);
+static void hci_ev_ert(struct iris_device *radio);
+static int update_spur_table(struct iris_device *radio);
+static int initialise_recv(struct iris_device *radio);
+static int initialise_trans(struct iris_device *radio);
+static int is_enable_rx_possible(struct iris_device *radio);
+static int is_enable_tx_possible(struct iris_device *radio);
+
+static struct v4l2_queryctrl iris_v4l2_queryctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 15,
+ .step = 1,
+ .default_value = 15,
+ },
+ {
+ .id = V4L2_CID_AUDIO_BALANCE,
+ .flags = V4L2_CTRL_FLAG_DISABLED,
+ },
+ {
+ .id = V4L2_CID_AUDIO_BASS,
+ .flags = V4L2_CTRL_FLAG_DISABLED,
+ },
+ {
+ .id = V4L2_CID_AUDIO_TREBLE,
+ .flags = V4L2_CTRL_FLAG_DISABLED,
+ },
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_AUDIO_LOUDNESS,
+ .flags = V4L2_CTRL_FLAG_DISABLED,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SRCHMODE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Search mode",
+ .minimum = 0,
+ .maximum = 7,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SCANDWELL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Search dwell time",
+ .minimum = 0,
+ .maximum = 7,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SRCHON,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Search on/off",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_STATE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "radio 0ff/rx/tx/reset",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+ .default_value = 1,
+
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_REGION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "radio standard",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SIGNAL_TH,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Signal Threshold",
+ .minimum = 0x80,
+ .maximum = 0x7F,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SRCH_PTY,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Search PTY",
+ .minimum = 0,
+ .maximum = 31,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SRCH_PI,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Search PI",
+ .minimum = 0,
+ .maximum = 0xFF,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SRCH_CNT,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Preset num",
+ .minimum = 0,
+ .maximum = 12,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_EMPHASIS,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Emphasis",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_RDS_STD,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "RDS standard",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SPACING,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Channel spacing",
+ .minimum = 0,
+ .maximum = 2,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_RDSON,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "RDS on/off",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "RDS group mask",
+ .minimum = 0,
+ .maximum = 0xFFFFFFFF,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "RDS processing",
+ .minimum = 0,
+ .maximum = 0xFF,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_RDSD_BUF,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "RDS data groups to buffer",
+ .minimum = 1,
+ .maximum = 21,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_PSALL,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "pass all ps strings",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_LP_MODE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Low power mode",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_ANTENNA,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "headset/internal",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Set PS REPEATCOUNT",
+ .minimum = 0,
+ .maximum = 15,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_PS_NAME,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Stop PS NAME",
+ .minimum = 0,
+ .maximum = 1,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_RT,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Stop RT",
+ .minimum = 0,
+ .maximum = 1,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SOFT_MUTE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Soft Mute",
+ .minimum = 0,
+ .maximum = 1,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_ADDR,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Riva addr",
+ .minimum = 0x3180000,
+ .maximum = 0x31E0004,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_LEN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Data len",
+ .minimum = 0,
+ .maximum = 0xFF,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_RIVA_PEEK,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Riva peek",
+ .minimum = 0,
+ .maximum = 1,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_RIVA_POKE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Riva poke",
+ .minimum = 0x3180000,
+ .maximum = 0x31E0004,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SSBI_ACCS_ADDR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Ssbi addr",
+ .minimum = 0x280,
+ .maximum = 0x37F,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SSBI_PEEK,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Ssbi peek",
+ .minimum = 0,
+ .maximum = 0x37F,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SSBI_POKE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "ssbi poke",
+ .minimum = 0x01,
+ .maximum = 0xFF,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_HLSI,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "set hlsi",
+ .minimum = 0,
+ .maximum = 2,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_RDS_GRP_COUNTERS,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "RDS grp",
+ .minimum = 0,
+ .maximum = 1,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SET_NOTCH_FILTER,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Notch filter",
+ .minimum = 0,
+ .maximum = 2,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_READ_DEFAULT,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Read default",
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_WRITE_DEFAULT,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Write default",
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_SET_CALIBRATION,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "SET Calibration",
+ .minimum = 0,
+ .maximum = 1,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_DO_CALIBRATION,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "SET Calibration",
+ .minimum = 0,
+ .maximum = 1,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_IRIS_GET_SINR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "GET SINR",
+ .minimum = -128,
+ .maximum = 127,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_INTF_HIGH_THRESHOLD,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Intf High Threshold",
+ .minimum = 0,
+ .maximum = 0xFF,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_INTF_LOW_THRESHOLD,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Intf low Threshold",
+ .minimum = 0,
+ .maximum = 0xFF,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_SINR_THRESHOLD,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "SINR Threshold",
+ .minimum = -128,
+ .maximum = 127,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_PRIVATE_SINR_SAMPLES,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "SINR samples",
+ .minimum = 1,
+ .maximum = 0xFF,
+ .default_value = 0,
+ },
+};
+
+static void iris_q_event(struct iris_device *radio,
+ enum iris_evt_t event)
+{
+ struct kfifo *data_b;
+ unsigned char evt = event;
+
+ FMDBG("radio %pK event %d", radio, event);
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+
+ data_b = &radio->data_buf[IRIS_BUF_EVENTS];
+ if (kfifo_in_locked(data_b, &evt, 1, &radio->buf_lock[IRIS_BUF_EVENTS]))
+ wake_up_interruptible(&radio->event_queue);
+}
+
+static int hci_send_frame(struct sk_buff *skb)
+{
+ struct radio_hci_dev *hdev;
+
+ FMDBG("skb %pK", skb);
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return -EINVAL;
+ }
+ hdev = (struct radio_hci_dev *) skb->dev;
+ if (unlikely(!hdev)) {
+ kfree_skb(skb);
+ return -ENODEV;
+ }
+
+ __net_timestamp(skb);
+
+ skb_orphan(skb);
+ return hdev->send(skb);
+}
+
+static void radio_hci_cmd_task(unsigned long arg)
+{
+ struct radio_hci_dev *hdev = (struct radio_hci_dev *) arg;
+ struct sk_buff *skb;
+
+ FMDBG("hdev %pK", hdev);
+
+ if (unlikely(hdev == NULL)) {
+ FMDERR("%s, HCI Device is null\n", __func__);
+ return;
+ }
+ if (!(atomic_read(&hdev->cmd_cnt))
+ && time_after(jiffies, hdev->cmd_last_tx + HZ)) {
+ FMDERR("%s command tx timeout\n", hdev->name);
+ atomic_set(&hdev->cmd_cnt, 1);
+ }
+
+ skb = skb_dequeue(&hdev->cmd_q);
+ if (atomic_read(&hdev->cmd_cnt) && skb) {
+ kfree_skb(hdev->sent_cmd);
+ hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
+ if (hdev->sent_cmd) {
+ atomic_dec(&hdev->cmd_cnt);
+ hci_send_frame(skb);
+ hdev->cmd_last_tx = jiffies;
+ } else {
+ skb_queue_head(&hdev->cmd_q, skb);
+ tasklet_schedule(&hdev->cmd_task);
+ }
+ }
+
+}
+
+static void radio_hci_rx_task(unsigned long arg)
+{
+ struct radio_hci_dev *hdev = (struct radio_hci_dev *) arg;
+ struct sk_buff *skb;
+
+ FMDBG("hdev %pK", hdev);
+
+ if (unlikely(hdev == NULL)) {
+ FMDERR("%s, HCI Device is null\n", __func__);
+ return;
+ }
+ read_lock(&hci_task_lock);
+
+ skb = skb_dequeue(&hdev->rx_q);
+ radio_hci_event_packet(hdev, skb);
+
+ read_unlock(&hci_task_lock);
+}
+
+int radio_hci_register_dev(struct radio_hci_dev *hdev)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ FMDBG("radio %pK", radio);
+
+ if (!radio) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+
+ if (!hdev) {
+ FMDERR("hdev is null\n");
+ return -EINVAL;
+ }
+
+ hdev->flags = 0;
+
+ tasklet_init(&hdev->cmd_task, radio_hci_cmd_task, (unsigned long)
+ hdev);
+ tasklet_init(&hdev->rx_task, radio_hci_rx_task, (unsigned long)
+ hdev);
+
+ init_waitqueue_head(&hdev->req_wait_q);
+
+ skb_queue_head_init(&hdev->rx_q);
+ skb_queue_head_init(&hdev->cmd_q);
+ skb_queue_head_init(&hdev->raw_q);
+
+
+ radio->fm_hdev = hdev;
+
+ return 0;
+}
+EXPORT_SYMBOL(radio_hci_register_dev);
+
+int radio_hci_unregister_dev(void)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ struct radio_hci_dev *hdev = NULL;
+
+ if (!radio) {
+ FMDERR("radio is null\n");
+ return -EINVAL;
+ }
+ hdev = radio->fm_hdev;
+ if (!hdev) {
+ FMDERR("hdev is null\n");
+ return -EINVAL;
+ }
+
+ tasklet_kill(&hdev->rx_task);
+ tasklet_kill(&hdev->cmd_task);
+ skb_queue_purge(&hdev->rx_q);
+ skb_queue_purge(&hdev->cmd_q);
+ skb_queue_purge(&hdev->raw_q);
+
+ radio->fm_hdev = NULL;
+ return 0;
+}
+EXPORT_SYMBOL(radio_hci_unregister_dev);
+
+int radio_hci_recv_frame(struct sk_buff *skb)
+{
+ struct radio_hci_dev *hdev;
+
+ FMDBG("hdev %pK", skb);
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return -EINVAL;
+ }
+ hdev = (struct radio_hci_dev *) skb->dev;
+ if (unlikely(!hdev)) {
+ FMDERR("%s hdev is null while receiving frame\n", hdev->name);
+ kfree_skb(skb);
+ return -ENXIO;
+ }
+
+ __net_timestamp(skb);
+
+ radio_hci_event_packet(hdev, skb);
+ kfree_skb(skb);
+ return 0;
+}
+EXPORT_SYMBOL(radio_hci_recv_frame);
+
+int radio_hci_send_cmd(struct radio_hci_dev *hdev, __u16 opcode, __u32 plen,
+ void *param)
+{
+ int len = RADIO_HCI_COMMAND_HDR_SIZE + plen;
+ struct radio_hci_command_hdr *hdr;
+ struct sk_buff *skb;
+ int ret = 0;
+
+ FMDBG("hdev %pK opcode %u len %u", hdev, opcode, plen);
+
+ if (unlikely(hdev == NULL)) {
+ FMDERR("%s, hci device is null\n", __func__);
+ return -EINVAL;
+ }
+ skb = alloc_skb(len, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ hdr = (struct radio_hci_command_hdr *) skb_put(skb,
+ RADIO_HCI_COMMAND_HDR_SIZE);
+ hdr->opcode = cpu_to_le16(opcode);
+ hdr->plen = plen;
+
+ if (plen)
+ memcpy(skb_put(skb, plen), param, plen);
+
+ skb->dev = (void *) hdev;
+
+ ret = hci_send_frame(skb);
+
+ return ret;
+}
+EXPORT_SYMBOL(radio_hci_send_cmd);
+
+static int hci_fm_enable_recv_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_ENABLE_RECV_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_tone_generator(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ __u16 opcode = 0;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+ HCI_FM_SET_INTERNAL_TONE_GENRATOR);
+ return radio_hci_send_cmd(hdev, opcode,
+ sizeof(radio->tone_freq), &radio->tone_freq);
+}
+
+static int hci_fm_enable_trans_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_ENABLE_TRANS_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_disable_recv_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_DISABLE_RECV_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_disable_trans_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_DISABLE_TRANS_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_get_fm_recv_conf_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_RECV_CONF_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_get_fm_trans_conf_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_TRANS_CONF_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+static int hci_set_fm_recv_conf_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ struct hci_fm_recv_conf_req *recv_conf_req =
+ (struct hci_fm_recv_conf_req *) param;
+
+ if (recv_conf_req == NULL) {
+ FMDERR("%s, recv conf is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_RECV_CONF_REQ);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*recv_conf_req)),
+ recv_conf_req);
+}
+
+static int hci_set_fm_trans_conf_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ struct hci_fm_trans_conf_req_struct *trans_conf_req =
+ (struct hci_fm_trans_conf_req_struct *) param;
+
+ if (trans_conf_req == NULL) {
+ FMDERR("%s, tx conf is null\n", __func__);
+ return -EINVAL;
+ }
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_TRANS_CONF_REQ);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*trans_conf_req)),
+ trans_conf_req);
+}
+
+static int hci_fm_get_station_param_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_STATION_PARAM_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_set_fm_mute_mode_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_mute_mode_req *mute_mode_req =
+ (struct hci_fm_mute_mode_req *) param;
+
+ if (mute_mode_req == NULL) {
+ FMDERR("%s, mute mode is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_MUTE_MODE_REQ);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*mute_mode_req)),
+ mute_mode_req);
+}
+
+
+static int hci_trans_ps_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_tx_ps *tx_ps_req =
+ (struct hci_fm_tx_ps *) param;
+
+ if (tx_ps_req == NULL) {
+ FMDERR("%s, tx ps req is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_RDS_PS_REQ);
+
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*tx_ps_req)),
+ tx_ps_req);
+}
+
+static int hci_trans_rt_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_tx_rt *tx_rt_req =
+ (struct hci_fm_tx_rt *) param;
+
+ if (tx_rt_req == NULL) {
+ FMDERR("%s, tx rt req is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_RDS_RT_REQ);
+
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*tx_rt_req)),
+ tx_rt_req);
+}
+
+static int hci_set_fm_stereo_mode_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_stereo_mode_req *stereo_mode_req =
+ (struct hci_fm_stereo_mode_req *) param;
+
+ if (stereo_mode_req == NULL) {
+ FMDERR("%s, stere mode req is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_STEREO_MODE_REQ);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*stereo_mode_req)),
+ stereo_mode_req);
+}
+
+static int hci_fm_set_antenna_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ __u8 antenna = param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_ANTENNA);
+ return radio_hci_send_cmd(hdev, opcode, sizeof(antenna), &antenna);
+}
+
+static int hci_fm_set_sig_threshold_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ __u8 sig_threshold = param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_SIGNAL_THRESHOLD);
+ return radio_hci_send_cmd(hdev, opcode, sizeof(sig_threshold),
+ &sig_threshold);
+}
+
+static int hci_fm_set_event_mask(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ u16 opcode = 0;
+ u8 event_mask = param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_EVENT_MASK);
+ return radio_hci_send_cmd(hdev, opcode, sizeof(event_mask),
+ &event_mask);
+}
+static int hci_fm_get_sig_threshold_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_SIGNAL_THRESHOLD);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_get_program_service_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_PROGRAM_SERVICE_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_get_radio_text_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_RADIO_TEXT_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_get_af_list_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_AF_LIST_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_search_stations_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_search_station_req *srch_stations =
+ (struct hci_fm_search_station_req *) param;
+
+ if (srch_stations == NULL) {
+ FMDERR("%s, search station param is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_SEARCH_STATIONS);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_stations)),
+ srch_stations);
+}
+
+static int hci_fm_srch_rds_stations_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_search_rds_station_req *srch_stations =
+ (struct hci_fm_search_rds_station_req *) param;
+
+ if (srch_stations == NULL) {
+ FMDERR("%s, rds stations param is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_SEARCH_RDS_STATIONS);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_stations)),
+ srch_stations);
+}
+
+static int hci_fm_srch_station_list_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_search_station_list_req *srch_list =
+ (struct hci_fm_search_station_list_req *) param;
+
+ if (srch_list == NULL) {
+ FMDERR("%s, search list param is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_SEARCH_STATIONS_LIST);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_list)),
+ srch_list);
+}
+
+static int hci_fm_cancel_search_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_CANCEL_SEARCH);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_rds_grp_mask_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ struct hci_fm_rds_grp_req *fm_grp_mask =
+ (struct hci_fm_rds_grp_req *)param;
+
+ if (fm_grp_mask == NULL) {
+ FMDERR("%s, grp mask param is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_RDS_GRP);
+ return radio_hci_send_cmd(hdev, opcode, sizeof(*fm_grp_mask),
+ fm_grp_mask);
+}
+
+static int hci_fm_rds_grp_process_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ __u32 fm_grps_process = param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_RDS_GRP_PROCESS);
+ return radio_hci_send_cmd(hdev, opcode, sizeof(fm_grps_process),
+ &fm_grps_process);
+}
+
+static int hci_fm_tune_station_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ __u32 tune_freq = param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+ HCI_OCF_FM_TUNE_STATION_REQ);
+ return radio_hci_send_cmd(hdev, opcode, sizeof(tune_freq), &tune_freq);
+}
+
+static int hci_def_data_read_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_def_data_rd_req *def_data_rd =
+ (struct hci_fm_def_data_rd_req *) param;
+
+ if (def_data_rd == NULL) {
+ FMDERR("%s, def data read param is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+ HCI_OCF_FM_DEFAULT_DATA_READ);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*def_data_rd)),
+ def_data_rd);
+}
+
+static int hci_def_data_write_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_def_data_wr_req *def_data_wr =
+ (struct hci_fm_def_data_wr_req *) param;
+
+ if (def_data_wr == NULL) {
+ FMDERR("%s, def data write param is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+ HCI_OCF_FM_DEFAULT_DATA_WRITE);
+
+ return radio_hci_send_cmd(hdev, opcode, (def_data_wr->length+2),
+ def_data_wr);
+}
+
+static int hci_set_notch_filter_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ __u8 notch_filter_val = param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_EN_NOTCH_CTRL);
+ return radio_hci_send_cmd(hdev, opcode, sizeof(notch_filter_val),
+ ¬ch_filter_val);
+}
+
+static int hci_fm_reset_req(struct radio_hci_dev *hdev, unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+ HCI_OCF_FM_RESET);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_get_feature_lists_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_FEATURE_LIST);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_do_calibration_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ __u8 mode = param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+ HCI_OCF_FM_DO_CALIBRATION);
+ return radio_hci_send_cmd(hdev, opcode, sizeof(mode), &mode);
+}
+
+static int hci_read_grp_counters_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ __u8 reset_counters = param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_STATUS_PARAMETERS_CMD_REQ,
+ HCI_OCF_FM_READ_GRP_COUNTERS);
+ return radio_hci_send_cmd(hdev, opcode, sizeof(reset_counters),
+ &reset_counters);
+}
+
+static int hci_peek_data_req(struct radio_hci_dev *hdev, unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_riva_data *peek_data = (struct hci_fm_riva_data *)param;
+
+ if (peek_data == NULL) {
+ FMDERR("%s, peek data param is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+ HCI_OCF_FM_PEEK_DATA);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*peek_data)),
+ peek_data);
+}
+
+static int hci_poke_data_req(struct radio_hci_dev *hdev, unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_riva_poke *poke_data = (struct hci_fm_riva_poke *) param;
+
+ if (poke_data == NULL) {
+ FMDERR("%s, poke data param is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+ HCI_OCF_FM_POKE_DATA);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*poke_data)),
+ poke_data);
+}
+
+static int hci_ssbi_peek_reg_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_ssbi_peek *ssbi_peek = (struct hci_fm_ssbi_peek *) param;
+
+ if (ssbi_peek == NULL) {
+ FMDERR("%s, ssbi peek param is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+ HCI_OCF_FM_SSBI_PEEK_REG);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*ssbi_peek)),
+ ssbi_peek);
+}
+
+static int hci_ssbi_poke_reg_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_ssbi_req *ssbi_poke = (struct hci_fm_ssbi_req *) param;
+
+ if (ssbi_poke == NULL) {
+ FMDERR("%s, ssbi poke param is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+ HCI_OCF_FM_SSBI_POKE_REG);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*ssbi_poke)),
+ ssbi_poke);
+}
+
+static int hci_fm_get_station_dbg_param_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+ HCI_OCF_FM_STATION_DBG_PARAM);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_set_ch_det_th(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ struct hci_fm_ch_det_threshold *ch_det_th =
+ (struct hci_fm_ch_det_threshold *) param;
+ u16 opcode;
+
+ if (ch_det_th == NULL) {
+ FMDERR("%s, channel det thrshld is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_CH_DET_THRESHOLD);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*ch_det_th)),
+ ch_det_th);
+}
+
+static int hci_fm_get_ch_det_th(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ u16 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_CH_DET_THRESHOLD);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_get_blend_tbl(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ u16 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_BLND_TBL);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_set_blend_tbl(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ struct hci_fm_blend_table *blnd_tbl =
+ (struct hci_fm_blend_table *) param;
+ u16 opcode;
+
+ if (blnd_tbl == NULL) {
+ FMDERR("%s, blend tbl is null\n", __func__);
+ return -EINVAL;
+ }
+ opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_BLND_TBL);
+ return radio_hci_send_cmd(hdev, opcode,
+ sizeof(struct hci_fm_blend_table), blnd_tbl);
+}
+
+static int radio_hci_err(__u32 code)
+{
+ switch (code) {
+ case 0:
+ return 0;
+ case 0x01:
+ return -EBADRQC;
+ case 0x02:
+ return -ENOTCONN;
+ case 0x03:
+ return -EIO;
+ case 0x07:
+ return -ENOMEM;
+ case 0x0c:
+ return -EBUSY;
+ case 0x11:
+ return -EOPNOTSUPP;
+ case 0x12:
+ return -EINVAL;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int __radio_hci_request(struct radio_hci_dev *hdev,
+ int (*req)(struct radio_hci_dev *hdev,
+ unsigned long param),
+ unsigned long param, unsigned long timeout_msecs,
+ bool interruptible)
+{
+ int err = 0;
+ DECLARE_WAITQUEUE(wait, current);
+
+ if (unlikely(hdev == NULL)) {
+ FMDERR("%s, hci dev is null\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&iris_fm);
+ hdev->req_status = HCI_REQ_PEND;
+
+ add_wait_queue(&hdev->req_wait_q, &wait);
+ if (interruptible)
+ set_current_state(TASK_INTERRUPTIBLE);
+ else
+ set_current_state(TASK_UNINTERRUPTIBLE);
+
+ err = req(hdev, param);
+
+ schedule_timeout(msecs_to_jiffies(timeout_msecs));
+
+ remove_wait_queue(&hdev->req_wait_q, &wait);
+
+ if (interruptible && signal_pending(current)) {
+ mutex_unlock(&iris_fm);
+ return -EINTR;
+ }
+
+ switch (hdev->req_status) {
+ case HCI_REQ_DONE:
+ case HCI_REQ_STATUS:
+ err = radio_hci_err(hdev->req_result);
+ break;
+ default:
+ err = -ETIMEDOUT;
+ break;
+ }
+
+ hdev->req_status = hdev->req_result = 0;
+ mutex_unlock(&iris_fm);
+
+ return err;
+}
+
+static inline int radio_hci_request_interruptible(struct radio_hci_dev *hdev,
+ int (*req)(struct
+ radio_hci_dev * hdev, unsigned long param),
+ unsigned long param, unsigned long timeout_msecs)
+{
+ int ret = 0;
+
+ ret = __radio_hci_request(hdev, req, param, timeout_msecs, true);
+
+ return ret;
+}
+
+static inline int radio_hci_request_uninterruptible(struct radio_hci_dev *hdev,
+ int (*req)(struct
+ radio_hci_dev * hdev, unsigned long param),
+ unsigned long param, unsigned long timeout_msecs)
+{
+ int ret = 0;
+
+ ret = __radio_hci_request(hdev, req, param, timeout_msecs, false);
+
+ return ret;
+}
+
+static inline int radio_hci_request(struct radio_hci_dev *hdev,
+ int (*req)(struct
+ radio_hci_dev * hdev, unsigned long param),
+ unsigned long param, unsigned long timeout_msecs)
+{
+ return radio_hci_request_interruptible(hdev, req, param, timeout_msecs);
+}
+
+static inline int hci_conf_event_mask(__u8 *arg,
+ struct radio_hci_dev *hdev)
+{
+ u8 event_mask;
+
+ if (arg == NULL) {
+ FMDERR("%s, arg is null\n", __func__);
+ return -EINVAL;
+ }
+ event_mask = *arg;
+ return radio_hci_request(hdev, hci_fm_set_event_mask,
+ event_mask, RADIO_HCI_TIMEOUT);
+}
+static int hci_set_fm_recv_conf(struct hci_fm_recv_conf_req *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_recv_conf_req *set_recv_conf = arg;
+
+ ret = radio_hci_request(hdev, hci_set_fm_recv_conf_req, (unsigned
+ long)set_recv_conf, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_set_fm_trans_conf(struct hci_fm_trans_conf_req_struct *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_trans_conf_req_struct *set_trans_conf = arg;
+
+ ret = radio_hci_request(hdev, hci_set_fm_trans_conf_req, (unsigned
+ long)set_trans_conf, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_fm_tune_station(__u32 *arg, struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ __u32 tune_freq;
+
+ if (arg == NULL) {
+ FMDERR("%s, arg is null\n", __func__);
+ return -EINVAL;
+ }
+ tune_freq = *arg;
+ ret = radio_hci_request(hdev, hci_fm_tune_station_req, tune_freq,
+ RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_set_fm_mute_mode(struct hci_fm_mute_mode_req *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_mute_mode_req *set_mute_conf = arg;
+
+ ret = radio_hci_request(hdev, hci_set_fm_mute_mode_req, (unsigned
+ long)set_mute_conf, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_set_fm_stereo_mode(struct hci_fm_stereo_mode_req *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_stereo_mode_req *set_stereo_conf = arg;
+
+ ret = radio_hci_request(hdev, hci_set_fm_stereo_mode_req, (unsigned
+ long)set_stereo_conf, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_fm_set_antenna(__u8 *arg, struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ __u8 antenna;
+
+ if (arg == NULL) {
+ FMDERR("%s, arg is null\n", __func__);
+ return -EINVAL;
+ }
+ antenna = *arg;
+ ret = radio_hci_request(hdev, hci_fm_set_antenna_req, antenna,
+ RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_fm_set_signal_threshold(__u8 *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ __u8 sig_threshold;
+
+ if (arg == NULL) {
+ FMDERR("%s, arg is null\n", __func__);
+ return -EINVAL;
+ }
+ sig_threshold = *arg;
+ ret = radio_hci_request(hdev, hci_fm_set_sig_threshold_req,
+ sig_threshold, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_fm_search_stations(struct hci_fm_search_station_req *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_search_station_req *srch_stations = arg;
+
+ ret = radio_hci_request(hdev, hci_fm_search_stations_req, (unsigned
+ long)srch_stations, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_fm_search_rds_stations(struct hci_fm_search_rds_station_req *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_search_rds_station_req *srch_stations = arg;
+
+ ret = radio_hci_request(hdev, hci_fm_srch_rds_stations_req, (unsigned
+ long)srch_stations, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_fm_search_station_list
+ (struct hci_fm_search_station_list_req *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_search_station_list_req *srch_list = arg;
+
+ ret = radio_hci_request(hdev, hci_fm_srch_station_list_req, (unsigned
+ long)srch_list, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_fm_rds_grp(struct hci_fm_rds_grp_req *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_rds_grp_req *fm_grp_mask = arg;
+
+ ret = radio_hci_request(hdev, hci_fm_rds_grp_mask_req, (unsigned
+ long)fm_grp_mask, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_fm_rds_grps_process(__u32 *arg, struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ __u32 fm_grps_process;
+
+ if (arg == NULL) {
+ FMDERR("%s, arg is null\n", __func__);
+ return -EINVAL;
+ }
+ fm_grps_process = *arg;
+ ret = radio_hci_request(hdev, hci_fm_rds_grp_process_req,
+ fm_grps_process, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+int hci_def_data_read(struct hci_fm_def_data_rd_req *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_def_data_rd_req *def_data_rd = arg;
+
+ ret = radio_hci_request(hdev, hci_def_data_read_req, (unsigned
+ long)def_data_rd, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+int hci_def_data_write(struct hci_fm_def_data_wr_req *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_def_data_wr_req *def_data_wr = arg;
+
+ ret = radio_hci_request(hdev, hci_def_data_write_req, (unsigned
+ long)def_data_wr, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+int hci_fm_do_calibration(__u8 *arg, struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ __u8 mode;
+
+ if (arg == NULL) {
+ FMDERR("%s, arg is null\n", __func__);
+ return -EINVAL;
+ }
+ mode = *arg;
+ ret = radio_hci_request(hdev, hci_fm_do_calibration_req, mode,
+ RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_read_grp_counters(__u8 *arg, struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ __u8 reset_counters;
+
+ if (arg == NULL) {
+ FMDERR("%s, arg is null\n", __func__);
+ return -EINVAL;
+ }
+ reset_counters = *arg;
+ ret = radio_hci_request(hdev, hci_read_grp_counters_req,
+ reset_counters, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_set_notch_filter(__u8 *arg, struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ __u8 notch_filter;
+
+ if (arg == NULL) {
+ FMDERR("%s, arg is null\n", __func__);
+ return -EINVAL;
+ }
+
+ notch_filter = *arg;
+ ret = radio_hci_request(hdev, hci_set_notch_filter_req,
+ notch_filter, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_peek_data(struct hci_fm_riva_data *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_riva_data *peek_data = arg;
+
+ ret = radio_hci_request(hdev, hci_peek_data_req, (unsigned
+ long)peek_data, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_poke_data(struct hci_fm_riva_poke *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_riva_poke *poke_data = arg;
+
+ ret = radio_hci_request(hdev, hci_poke_data_req, (unsigned
+ long)poke_data, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_ssbi_peek_reg(struct hci_fm_ssbi_peek *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_ssbi_peek *ssbi_peek_reg = arg;
+
+ ret = radio_hci_request(hdev, hci_ssbi_peek_reg_req, (unsigned
+ long)ssbi_peek_reg, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_ssbi_poke_reg(struct hci_fm_ssbi_req *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_ssbi_req *ssbi_poke_reg = arg;
+
+ ret = radio_hci_request(hdev, hci_ssbi_poke_reg_req, (unsigned
+ long)ssbi_poke_reg, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
+static int hci_set_ch_det_thresholds_req(struct hci_fm_ch_det_threshold *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_ch_det_threshold *ch_det_threshold = arg;
+
+ ret = radio_hci_request(hdev, hci_fm_set_ch_det_th,
+ (unsigned long)ch_det_threshold, RADIO_HCI_TIMEOUT);
+ return ret;
+}
+
+static int hci_fm_set_cal_req_proc(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ u16 opcode = 0;
+ struct hci_fm_set_cal_req_proc *cal_req =
+ (struct hci_fm_set_cal_req_proc *)param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_CALIBRATION);
+ return radio_hci_send_cmd(hdev, opcode,
+ sizeof(struct hci_fm_set_cal_req_proc), cal_req);
+}
+
+static int hci_fm_do_cal_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ u16 opcode = 0;
+ u8 cal_mode = param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+ HCI_OCF_FM_DO_CALIBRATION);
+ return radio_hci_send_cmd(hdev, opcode, sizeof(cal_mode),
+ &cal_mode);
+
+}
+
+static int hci_fm_set_spur_tbl_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ u16 opcode = 0, len = 0;
+ struct hci_fm_set_spur_table_req *spur_req =
+ (struct hci_fm_set_spur_table_req *)param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_SPUR_TABLE);
+ if (spur_req->no_of_freqs_entries > ENTRIES_EACH_CMD)
+ len = (ENTRIES_EACH_CMD * SPUR_DATA_LEN)
+ + SPUR_DATA_INDEX;
+ else
+ len = (spur_req->no_of_freqs_entries * SPUR_DATA_LEN)
+ + SPUR_DATA_INDEX;
+
+ return radio_hci_send_cmd(hdev, opcode, len, spur_req);
+}
+
+static int hci_fm_get_spur_tbl_data(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ u16 opcode = 0;
+ unsigned int spur_freq = (unsigned int)param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+ HCI_OCF_FM_GET_SPUR_TABLE);
+ return radio_hci_send_cmd(hdev, opcode, sizeof(int), &spur_freq);
+}
+
+static int hci_set_blend_tbl_req(struct hci_fm_blend_table *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_blend_table *blend_tbl = arg;
+
+ ret = radio_hci_request(hdev, hci_fm_set_blend_tbl,
+ (unsigned long)blend_tbl, RADIO_HCI_TIMEOUT);
+ return ret;
+}
+
+static int hci_cmd_internal(unsigned int cmd, struct radio_hci_dev *hdev,
+ bool interruptible)
+{
+ int ret = 0;
+ unsigned long arg = 0;
+ radio_hci_request_func radio_hci_request;
+
+ FMDBG("hdev %pK cmd 0x%x", hdev, cmd);
+
+ if (!hdev)
+ return -ENODEV;
+
+ radio_hci_request = interruptible ? radio_hci_request_interruptible :
+ radio_hci_request_uninterruptible;
+
+ switch (cmd) {
+ case HCI_FM_ENABLE_RECV_CMD:
+ ret = radio_hci_request(hdev, hci_fm_enable_recv_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_DISABLE_RECV_CMD:
+ ret = radio_hci_request(hdev, hci_fm_disable_recv_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_GET_RECV_CONF_CMD:
+ ret = radio_hci_request(hdev, hci_get_fm_recv_conf_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_GET_STATION_PARAM_CMD:
+ ret = radio_hci_request(hdev,
+ hci_fm_get_station_param_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_GET_SIGNAL_TH_CMD:
+ ret = radio_hci_request(hdev,
+ hci_fm_get_sig_threshold_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_GET_PROGRAM_SERVICE_CMD:
+ ret = radio_hci_request(hdev,
+ hci_fm_get_program_service_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_GET_RADIO_TEXT_CMD:
+ ret = radio_hci_request(hdev, hci_fm_get_radio_text_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_GET_AF_LIST_CMD:
+ ret = radio_hci_request(hdev, hci_fm_get_af_list_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_CANCEL_SEARCH_CMD:
+ ret = radio_hci_request(hdev, hci_fm_cancel_search_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_RESET_CMD:
+ ret = radio_hci_request(hdev, hci_fm_reset_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_GET_FEATURES_CMD:
+ ret = radio_hci_request(hdev,
+ hci_fm_get_feature_lists_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_STATION_DBG_PARAM_CMD:
+ ret = radio_hci_request(hdev,
+ hci_fm_get_station_dbg_param_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_ENABLE_TRANS_CMD:
+ ret = radio_hci_request(hdev, hci_fm_enable_trans_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_DISABLE_TRANS_CMD:
+ ret = radio_hci_request(hdev, hci_fm_disable_trans_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+
+ case HCI_FM_GET_TX_CONFIG:
+ ret = radio_hci_request(hdev, hci_get_fm_trans_conf_req, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+ case HCI_FM_GET_DET_CH_TH_CMD:
+ ret = radio_hci_request(hdev, hci_fm_get_ch_det_th, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+ case HCI_FM_GET_BLND_TBL_CMD:
+ ret = radio_hci_request(hdev, hci_fm_get_blend_tbl, arg,
+ RADIO_HCI_TIMEOUT);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+
+static int hci_cmd(unsigned int cmd, struct radio_hci_dev *hdev)
+{
+ return hci_cmd_internal(cmd, hdev, true);
+}
+
+static int hci_cmd_uninterruptible(unsigned int cmd, struct radio_hci_dev *hdev)
+{
+ return hci_cmd_internal(cmd, hdev, false);
+}
+
+static void radio_hci_req_complete(struct radio_hci_dev *hdev, int result)
+{
+
+ if (unlikely(hdev == NULL)) {
+ FMDERR("%s, hci device is null\n", __func__);
+ return;
+ }
+ hdev->req_result = result;
+ hdev->req_status = HCI_REQ_DONE;
+ wake_up(&hdev->req_wait_q);
+}
+
+static void radio_hci_status_complete(struct radio_hci_dev *hdev, int result)
+{
+ if (unlikely(hdev == NULL)) {
+ FMDERR("%s, hci device is null\n", __func__);
+ return;
+ }
+ hdev->req_result = result;
+ hdev->req_status = HCI_REQ_STATUS;
+ wake_up(&hdev->req_wait_q);
+}
+
+static void hci_cc_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+ __u8 status;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ status = *((__u8 *) skb->data);
+
+ radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_fm_disable_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ __u8 status;
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ FMDBG("hdev %pK skb %p", hdev, skb);
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null");
+ return;
+ }
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ status = *((__u8 *) skb->data);
+ if ((radio->mode == FM_TURNING_OFF) && (status == 0)) {
+ if (!radio->is_fm_closing)
+ iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
+ radio_hci_req_complete(hdev, status);
+ radio->mode = FM_OFF;
+ } else if (radio->mode == FM_CALIB) {
+ radio_hci_req_complete(hdev, status);
+ } else if ((radio->mode == FM_RECV) || (radio->mode == FM_TRANS)) {
+ iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
+ radio->mode = FM_OFF;
+ } else if ((radio->mode == FM_TURNING_OFF) && (status != 0)) {
+ radio_hci_req_complete(hdev, status);
+ }
+}
+
+static void hci_cc_conf_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_fm_conf_rsp *rsp;
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null");
+ return;
+ }
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ rsp = (struct hci_fm_conf_rsp *)skb->data;
+ if (!rsp->status)
+ radio->recv_conf = rsp->recv_conf_rsp;
+ radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_fm_trans_get_conf_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_fm_get_trans_conf_rsp *rsp;
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ rsp = (struct hci_fm_get_trans_conf_rsp *)skb->data;
+ if (!rsp->status)
+ memcpy((void *)&radio->trans_conf,
+ (void *)&rsp->trans_conf_rsp,
+ sizeof(rsp->trans_conf_rsp));
+
+ radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_fm_enable_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_fm_conf_rsp *rsp;
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ FMDBG("hdev %pK skb %p", hdev, skb);
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ rsp = (struct hci_fm_conf_rsp *)skb->data;
+ if (rsp->status) {
+ radio_hci_req_complete(hdev, rsp->status);
+ return;
+ }
+
+ radio_hci_req_complete(hdev, rsp->status);
+}
+
+
+static void hci_cc_fm_trans_set_conf_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_fm_conf_rsp *rsp;
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ rsp = (struct hci_fm_conf_rsp *)skb->data;
+ if (!rsp->status)
+ iris_q_event(radio, HCI_EV_CMD_COMPLETE);
+
+ radio_hci_req_complete(hdev, rsp->status);
+}
+
+
+static void hci_cc_sig_threshold_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_fm_sig_threshold_rsp *rsp;
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ rsp = (struct hci_fm_sig_threshold_rsp *)skb->data;
+ if (!rsp->status)
+ memcpy(&radio->sig_th, rsp,
+ sizeof(struct hci_fm_sig_threshold_rsp));
+ radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_station_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ struct hci_fm_station_rsp *rsp;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ rsp = (struct hci_fm_station_rsp *)skb->data;
+ radio->fm_st_rsp = *(rsp);
+
+ /* Tune is always successful */
+ radio_hci_req_complete(hdev, 0);
+}
+
+static void hci_cc_prg_srv_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_fm_prgm_srv_rsp *rsp;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ rsp = (struct hci_fm_prgm_srv_rsp *)skb->data;
+
+ radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_rd_txt_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_fm_radio_txt_rsp *rsp;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ rsp = (struct hci_fm_radio_txt_rsp *)skb->data;
+ radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_af_list_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_fm_af_list_rsp *rsp;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ rsp = (struct hci_fm_af_list_rsp *)skb->data;
+ radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_feature_list_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct v4l2_capability *v4l_cap;
+ struct hci_fm_feature_list_rsp *rsp;
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ rsp = (struct hci_fm_feature_list_rsp *)skb->data;
+ v4l_cap = &radio->g_cap;
+
+ if (!rsp->status)
+ v4l_cap->capabilities = (rsp->feature_mask & 0x000002) |
+ (rsp->feature_mask & 0x000001);
+
+ radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_dbg_param_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ struct hci_fm_dbg_param_rsp *rsp;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ rsp = (struct hci_fm_dbg_param_rsp *)skb->data;
+ radio->st_dbg_param = *(rsp);
+ radio_hci_req_complete(hdev, radio->st_dbg_param.status);
+}
+
+static void iris_q_evt_data(struct iris_device *radio,
+ char *data, int len, int event)
+{
+ struct kfifo *data_b;
+
+ FMDBG("radio %pK data %p len %d event %d", radio, data, len, event);
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+ data_b = &radio->data_buf[event];
+ if (kfifo_in_locked(data_b, data, len, &radio->buf_lock[event]))
+ wake_up_interruptible(&radio->event_queue);
+}
+
+static void hci_cc_riva_peek_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ __u8 status;
+ int len;
+ char *data;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ status = *((__u8 *) skb->data);
+ if (!status) {
+ len = skb->data[RIVA_PEEK_LEN_OFSET] + RIVA_PEEK_PARAM;
+ data = kmalloc(len, GFP_ATOMIC);
+
+ if (data != NULL) {
+ memcpy(data, &skb->data[PEEK_DATA_OFSET], len);
+ iris_q_evt_data(radio, data, len, IRIS_BUF_PEEK);
+ kfree(data);
+ }
+ }
+
+ radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_riva_read_default_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ __u8 status;
+ __u8 len;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ status = *((__u8 *) skb->data);
+ if (!status) {
+ len = skb->data[1];
+ memset(&radio->default_data, 0,
+ sizeof(struct hci_fm_data_rd_rsp));
+ memcpy(&radio->default_data, &skb->data[0], len+2);
+ iris_q_evt_data(radio, &skb->data[0], len+2,
+ IRIS_BUF_RD_DEFAULT);
+ }
+ radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_get_spur_tbl(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ __u8 status;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ status = *((__u8 *) skb->data);
+ if (!status) {
+ iris_q_evt_data(radio, &skb->data[1], SPUR_DATA_LEN,
+ IRIS_BUF_SPUR);
+ iris_q_event(radio, IRIS_EVT_SPUR_TBL);
+ }
+ radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_ssbi_peek_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ __u8 status;
+ char *data;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ status = *((__u8 *) skb->data);
+ if (!status) {
+ data = kmalloc(SSBI_PEEK_LEN, GFP_ATOMIC);
+ if (data != NULL) {
+ data[0] = skb->data[PEEK_DATA_OFSET];
+ iris_q_evt_data(radio, data, SSBI_PEEK_LEN,
+ IRIS_BUF_SSBI_PEEK);
+ kfree(data);
+ }
+ }
+
+ radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_rds_grp_cntrs_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ __u8 status;
+ char *data;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ status = *((__u8 *) skb->data);
+ if (!status) {
+ data = kmalloc(RDS_GRP_CNTR_LEN, GFP_ATOMIC);
+ if (data != NULL) {
+ memcpy(data, &skb->data[1], RDS_GRP_CNTR_LEN);
+ iris_q_evt_data(radio, data, RDS_GRP_CNTR_LEN,
+ IRIS_BUF_RDS_CNTRS);
+ kfree(data);
+ }
+ }
+ radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_do_calibration_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ static struct hci_cc_do_calibration_rsp rsp;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ rsp.status = skb->data[0];
+ rsp.mode = skb->data[CALIB_MODE_OFSET];
+
+ if (!rsp.status) {
+ if (rsp.mode == PROCS_CALIB_MODE) {
+ memcpy(&rsp.data[0], &skb->data[CALIB_DATA_OFSET],
+ PROCS_CALIB_SIZE);
+ iris_q_evt_data(radio, rsp.data, PROCS_CALIB_SIZE,
+ IRIS_BUF_CAL_DATA);
+ }
+ }
+ radio_hci_req_complete(hdev, rsp.status);
+}
+
+static void hci_cc_get_ch_det_threshold_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ u8 status;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ status = skb->data[0];
+ if (!status)
+ memcpy(&radio->ch_det_threshold, &skb->data[1],
+ sizeof(struct hci_fm_ch_det_threshold));
+
+ radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_get_blend_tbl_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ u8 status;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ status = skb->data[0];
+ if (!status)
+ memcpy(&radio->blend_tbl, &skb->data[1],
+ sizeof(struct hci_fm_blend_table));
+
+ radio_hci_req_complete(hdev, status);
+}
+
+static inline void hci_cmd_complete_event(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_ev_cmd_complete *cmd_compl_ev;
+ __u16 opcode;
+
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ cmd_compl_ev = (struct hci_ev_cmd_complete *)skb->data;
+ skb_pull(skb, sizeof(*cmd_compl_ev));
+
+ opcode = __le16_to_cpu(cmd_compl_ev->cmd_opcode);
+
+ FMDBG("opcode 0x%x", opcode);
+ switch (opcode) {
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_ENABLE_RECV_REQ):
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_ENABLE_TRANS_REQ):
+ hci_cc_fm_enable_rsp(hdev, skb);
+ break;
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_RECV_CONF_REQ):
+ hci_cc_conf_rsp(hdev, skb);
+ break;
+
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_DISABLE_RECV_REQ):
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_DISABLE_TRANS_REQ):
+ hci_cc_fm_disable_rsp(hdev, skb);
+ break;
+
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_RECV_CONF_REQ):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_MUTE_MODE_REQ):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_STEREO_MODE_REQ):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_ANTENNA):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_SIGNAL_THRESHOLD):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_CANCEL_SEARCH):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_GRP):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_GRP_PROCESS):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_WAN_AVD_CTRL):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_NOTCH_CTRL):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_CH_DET_THRESHOLD):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_BLND_TBL):
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_RT_REQ):
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_PS_REQ):
+ case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_WRITE):
+ hci_cc_rsp(hdev, skb);
+ break;
+ case hci_common_cmd_op_pack(HCI_OCF_FM_RESET):
+ case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_SSBI_POKE_REG):
+ case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_POKE_DATA):
+ case hci_diagnostic_cmd_op_pack(HCI_FM_SET_INTERNAL_TONE_GENRATOR):
+ case hci_common_cmd_op_pack(HCI_OCF_FM_SET_CALIBRATION):
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_EVENT_MASK):
+ case hci_common_cmd_op_pack(HCI_OCF_FM_SET_SPUR_TABLE):
+ hci_cc_rsp(hdev, skb);
+ break;
+ case hci_common_cmd_op_pack(HCI_OCF_FM_GET_SPUR_TABLE):
+ hci_cc_get_spur_tbl(hdev, skb);
+ break;
+ case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_SSBI_PEEK_REG):
+ hci_cc_ssbi_peek_rsp(hdev, skb);
+ break;
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_SIGNAL_THRESHOLD):
+ hci_cc_sig_threshold_rsp(hdev, skb);
+ break;
+
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_STATION_PARAM_REQ):
+ hci_cc_station_rsp(hdev, skb);
+ break;
+
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_PROGRAM_SERVICE_REQ):
+ hci_cc_prg_srv_rsp(hdev, skb);
+ break;
+
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_RADIO_TEXT_REQ):
+ hci_cc_rd_txt_rsp(hdev, skb);
+ break;
+
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_AF_LIST_REQ):
+ hci_cc_af_list_rsp(hdev, skb);
+ break;
+
+ case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_READ):
+ hci_cc_riva_read_default_rsp(hdev, skb);
+ break;
+
+ case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_PEEK_DATA):
+ hci_cc_riva_peek_rsp(hdev, skb);
+ break;
+
+ case hci_common_cmd_op_pack(HCI_OCF_FM_GET_FEATURE_LIST):
+ hci_cc_feature_list_rsp(hdev, skb);
+ break;
+
+ case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_STATION_DBG_PARAM):
+ hci_cc_dbg_param_rsp(hdev, skb);
+ break;
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_SET_TRANS_CONF_REQ):
+ hci_cc_fm_trans_set_conf_rsp(hdev, skb);
+ break;
+
+ case hci_status_param_op_pack(HCI_OCF_FM_READ_GRP_COUNTERS):
+ hci_cc_rds_grp_cntrs_rsp(hdev, skb);
+ break;
+ case hci_common_cmd_op_pack(HCI_OCF_FM_DO_CALIBRATION):
+ hci_cc_do_calibration_rsp(hdev, skb);
+ break;
+
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_GET_TRANS_CONF_REQ):
+ hci_cc_fm_trans_get_conf_rsp(hdev, skb);
+ break;
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_CH_DET_THRESHOLD):
+ hci_cc_get_ch_det_threshold_rsp(hdev, skb);
+ break;
+ case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_BLND_TBL):
+ hci_cc_get_blend_tbl_rsp(hdev, skb);
+ break;
+ default:
+ FMDERR("%s opcode 0x%x\n", hdev->name, opcode);
+ break;
+ }
+
+}
+
+static inline void hci_cmd_status_event(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_ev_cmd_status *ev = (void *) skb->data;
+
+ radio_hci_status_complete(hdev, ev->status);
+}
+
+static inline void hci_ev_tune_status(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ int i;
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+ memcpy(&radio->fm_st_rsp.station_rsp, &skb->data[0],
+ sizeof(struct hci_ev_tune_status));
+ iris_q_event(radio, IRIS_EVT_TUNE_SUCC);
+
+ for (i = 0; i < IRIS_BUF_MAX; i++) {
+ if (i >= IRIS_BUF_RT_RDS)
+ kfifo_reset(&radio->data_buf[i]);
+ }
+ if (radio->fm_st_rsp.station_rsp.serv_avble)
+ iris_q_event(radio, IRIS_EVT_ABOVE_TH);
+ else
+ iris_q_event(radio, IRIS_EVT_BELOW_TH);
+
+ if (radio->fm_st_rsp.station_rsp.stereo_prg)
+ iris_q_event(radio, IRIS_EVT_STEREO);
+ else if (radio->fm_st_rsp.station_rsp.stereo_prg == 0)
+ iris_q_event(radio, IRIS_EVT_MONO);
+
+ if (radio->fm_st_rsp.station_rsp.rds_sync_status)
+ iris_q_event(radio, IRIS_EVT_RDS_AVAIL);
+ else
+ iris_q_event(radio, IRIS_EVT_RDS_NOT_AVAIL);
+}
+
+static inline void hci_ev_search_compl(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ radio->search_on = 0;
+ iris_q_event(radio, IRIS_EVT_SEEK_COMPLETE);
+}
+
+static inline void hci_ev_srch_st_list_compl(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ struct hci_ev_srch_list_compl *ev;
+ int cnt;
+ int stn_num;
+ int rel_freq;
+ int abs_freq;
+ int len;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
+ if (!ev)
+ return;
+
+ ev->num_stations_found = skb->data[STN_NUM_OFFSET];
+ len = ev->num_stations_found * PARAMS_PER_STATION + STN_FREQ_OFFSET;
+
+ for (cnt = STN_FREQ_OFFSET, stn_num = 0;
+ (cnt < len) && (stn_num < ev->num_stations_found)
+ && (stn_num < ARRAY_SIZE(ev->rel_freq));
+ cnt += PARAMS_PER_STATION, stn_num++) {
+ abs_freq = *((int *)&skb->data[cnt]);
+ rel_freq = abs_freq - radio->recv_conf.band_low_limit;
+ rel_freq = (rel_freq * 20) / KHZ_TO_MHZ;
+
+ ev->rel_freq[stn_num].rel_freq_lsb = GET_LSB(rel_freq);
+ ev->rel_freq[stn_num].rel_freq_msb = GET_MSB(rel_freq);
+ }
+
+ len = ev->num_stations_found * 2 + sizeof(ev->num_stations_found);
+ iris_q_event(radio, IRIS_EVT_NEW_SRCH_LIST);
+ iris_q_evt_data(radio, (char *)ev, len, IRIS_BUF_SRCH_LIST);
+ kfree(ev);
+}
+
+static inline void hci_ev_search_next(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ iris_q_event(radio, IRIS_EVT_SCAN_NEXT);
+}
+
+static inline void hci_ev_stereo_status(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ __u8 st_status;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ st_status = *((__u8 *) skb->data);
+ if (st_status)
+ iris_q_event(radio, IRIS_EVT_STEREO);
+ else
+ iris_q_event(radio, IRIS_EVT_MONO);
+}
+
+static void hci_ev_raw_rds_group_data(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio;
+ unsigned char blocknum, index;
+ struct rds_grp_data temp;
+ unsigned int mask_bit;
+ unsigned short int aid, agt, gtc;
+ unsigned short int carrier;
+
+ radio = video_get_drvdata(video_get_dev());
+ index = RDSGRP_DATA_OFFSET;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return;
+ }
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ for (blocknum = 0; blocknum < RDS_BLOCKS_NUM; blocknum++) {
+ temp.rdsBlk[blocknum].rdsLsb =
+ (skb->data[index]);
+ temp.rdsBlk[blocknum].rdsMsb =
+ (skb->data[index+1]);
+ index = index + 2;
+ }
+
+ aid = AID(temp.rdsBlk[3].rdsLsb, temp.rdsBlk[3].rdsMsb);
+ gtc = GTC(temp.rdsBlk[1].rdsMsb);
+ agt = AGT(temp.rdsBlk[1].rdsLsb);
+
+ if (gtc == GRP_3A) {
+ switch (aid) {
+ case ERT_AID:
+ /* calculate the grp mask for RDS grp
+ * which will contain actual eRT text
+ *
+ * Bit Pos 0 1 2 3 4 5 6 7
+ * Grp Type 0A 0B 1A 1B 2A 2B 3A 3B
+ *
+ * similarly for rest grps
+ */
+ mask_bit = (((agt >> 1) << 1) + (agt & 1));
+ oda_agt = (1 << mask_bit);
+ utf_8_flag = (temp.rdsBlk[2].rdsLsb & 1);
+ formatting_dir = EXTRACT_BIT(temp.rdsBlk[2].rdsLsb,
+ ERT_FORMAT_DIR_BIT);
+ if (ert_carrier != agt)
+ iris_q_event(radio, IRIS_EVT_NEW_ODA);
+ ert_carrier = agt;
+ break;
+ case RT_PLUS_AID:
+ /* calculate the grp mask for RDS grp
+ * which will contain actual eRT text
+ *
+ * Bit Pos 0 1 2 3 4 5 6 7
+ * Grp Type 0A 0B 1A 1B 2A 2B 3A 3B
+ *
+ * similarly for rest grps
+ */
+ mask_bit = (((agt >> 1) << 1) + (agt & 1));
+ oda_agt = (1 << mask_bit);
+ /*Extract 5th bit of MSB (b7b6b5b4b3b2b1b0)*/
+ rt_ert_flag = EXTRACT_BIT(temp.rdsBlk[2].rdsMsb,
+ RT_ERT_FLAG_BIT);
+ if (rt_plus_carrier != agt)
+ iris_q_event(radio, IRIS_EVT_NEW_ODA);
+ rt_plus_carrier = agt;
+ break;
+ default:
+ oda_agt = 0;
+ break;
+ }
+ } else {
+ carrier = gtc;
+ if (carrier == rt_plus_carrier)
+ hci_ev_rt_plus(radio, temp);
+ else if (carrier == ert_carrier)
+ hci_buff_ert(radio, &temp);
+ }
+}
+
+static void hci_buff_ert(struct iris_device *radio,
+ struct rds_grp_data *rds_buf)
+{
+ int i;
+ unsigned short int info_byte = 0;
+ unsigned short int byte_pair_index;
+
+ if (rds_buf == NULL) {
+ FMDERR("%s, rds buffer is null\n", __func__);
+ return;
+ }
+ byte_pair_index = AGT(rds_buf->rdsBlk[1].rdsLsb);
+ if (byte_pair_index == 0) {
+ c_byt_pair_index = 0;
+ ert_len = 0;
+ }
+ if (c_byt_pair_index == byte_pair_index) {
+ c_byt_pair_index++;
+ for (i = 2; i <= 3; i++) {
+ info_byte = rds_buf->rdsBlk[i].rdsLsb;
+ info_byte |= (rds_buf->rdsBlk[i].rdsMsb << 8);
+ ert_buf[ert_len++] = rds_buf->rdsBlk[i].rdsMsb;
+ ert_buf[ert_len++] = rds_buf->rdsBlk[i].rdsLsb;
+ if ((utf_8_flag == 0)
+ && (info_byte == CARRIAGE_RETURN)) {
+ ert_len -= 2;
+ break;
+ } else if ((utf_8_flag == 1)
+ &&
+ (rds_buf->rdsBlk[i].rdsMsb
+ == CARRIAGE_RETURN)) {
+ info_byte = CARRIAGE_RETURN;
+ ert_len -= 2;
+ break;
+ } else if ((utf_8_flag == 1)
+ &&
+ (rds_buf->rdsBlk[i].rdsLsb
+ == CARRIAGE_RETURN)) {
+ info_byte = CARRIAGE_RETURN;
+ ert_len--;
+ break;
+ }
+ }
+ if ((byte_pair_index == MAX_ERT_SEGMENT) ||
+ (info_byte == CARRIAGE_RETURN)) {
+ hci_ev_ert(radio);
+ c_byt_pair_index = 0;
+ ert_len = 0;
+ }
+ } else {
+ ert_len = 0;
+ c_byt_pair_index = 0;
+ }
+}
+static void hci_ev_ert(struct iris_device *radio)
+
+{
+ char *data = NULL;
+
+ if (ert_len <= 0)
+ return;
+ data = kmalloc((ert_len + 3), GFP_ATOMIC);
+ if (data != NULL) {
+ data[0] = ert_len;
+ data[1] = utf_8_flag;
+ data[2] = formatting_dir;
+ memcpy((data + 3), ert_buf, ert_len);
+ iris_q_evt_data(radio, data, (ert_len + 3), IRIS_BUF_ERT);
+ iris_q_event(radio, IRIS_EVT_NEW_ERT);
+ kfree(data);
+ }
+}
+
+static void hci_ev_rt_plus(struct iris_device *radio,
+ struct rds_grp_data rds_buf)
+{
+ char tag_type1, tag_type2;
+ char *data = NULL;
+ int len = 0;
+ unsigned short int agt;
+
+ agt = AGT(rds_buf.rdsBlk[1].rdsLsb);
+ /*right most 3 bits of Lsb of block 2
+ * and left most 3 bits of Msb of block 3
+ */
+ tag_type1 = (((agt & TAG1_MSB_MASK) << TAG1_MSB_OFFSET) |
+ (rds_buf.rdsBlk[2].rdsMsb >> TAG1_LSB_OFFSET));
+
+ /*right most 1 bit of lsb of 3rd block
+ * and left most 5 bits of Msb of 4th block
+ */
+ tag_type2 = (((rds_buf.rdsBlk[2].rdsLsb & TAG2_MSB_MASK)
+ << TAG2_MSB_OFFSET) |
+ (rds_buf.rdsBlk[3].rdsMsb >> TAG2_LSB_OFFSET));
+
+ if (tag_type1 != DUMMY_CLASS)
+ len += RT_PLUS_LEN_1_TAG;
+ if (tag_type2 != DUMMY_CLASS)
+ len += RT_PLUS_LEN_1_TAG;
+
+ if (len != 0) {
+ len += 2;
+ data = kmalloc(len, GFP_ATOMIC);
+ } else {
+ FMDERR("Len is zero\n");
+ return;
+ }
+ if (data != NULL) {
+ data[0] = len;
+ len = 1;
+ data[len++] = rt_ert_flag;
+ if (tag_type1 != DUMMY_CLASS) {
+ data[len++] = tag_type1;
+ /*start position of tag1
+ *right most 5 bits of msb of 3rd block
+ *and left most bit of lsb of 3rd block
+ */
+ data[len++] = (((rds_buf.rdsBlk[2].rdsMsb &
+ TAG1_POS_MSB_MASK)
+ << TAG1_POS_MSB_OFFSET)
+ |
+ (rds_buf.rdsBlk[2].rdsLsb >>
+ TAG1_POS_LSB_OFFSET));
+ /*length of tag1
+ *left most 6 bits of lsb of 3rd block
+ */
+ data[len++] = ((rds_buf.rdsBlk[2].rdsLsb
+ >> TAG1_LEN_OFFSET)
+ &
+ TAG1_LEN_MASK) + 1;
+ }
+ if (tag_type2 != DUMMY_CLASS) {
+ data[len++] = tag_type2;
+ /*start position of tag2
+ *right most 3 bit of msb of 4th block
+ *and left most 3 bits of lsb of 4th block
+ */
+ data[len++] = (((rds_buf.rdsBlk[3].rdsMsb
+ & TAG2_POS_MSB_MASK)
+ << TAG2_POS_MSB_OFFSET)
+ |
+ (rds_buf.rdsBlk[3].rdsLsb
+ >> TAG2_POS_LSB_OFFSET));
+ /*length of tag2
+ *right most 5 bits of lsb of 4th block
+ */
+ data[len++] = (rds_buf.rdsBlk[3].rdsLsb
+ & TAG2_LEN_MASK) + 1;
+ }
+ iris_q_evt_data(radio, data, len, IRIS_BUF_RT_PLUS);
+ iris_q_event(radio, IRIS_EVT_NEW_RT_PLUS);
+ kfree(data);
+ }
+}
+
+static inline void hci_ev_program_service(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ int len;
+ char *data;
+
+ len = (skb->data[RDS_PS_LENGTH_OFFSET] * RDS_STRING) + RDS_OFFSET;
+ iris_q_event(radio, IRIS_EVT_NEW_PS_RDS);
+ data = kmalloc(len, GFP_ATOMIC);
+ if (!data)
+ return;
+
+ data[0] = skb->data[RDS_PS_LENGTH_OFFSET];
+ data[1] = skb->data[RDS_PTYPE];
+ data[2] = skb->data[RDS_PID_LOWER];
+ data[3] = skb->data[RDS_PID_HIGHER];
+ data[4] = 0;
+
+ memcpy(data+RDS_OFFSET, &skb->data[RDS_PS_DATA_OFFSET], len-RDS_OFFSET);
+
+ iris_q_evt_data(radio, data, len, IRIS_BUF_PS_RDS);
+
+ kfree(data);
+}
+
+
+static inline void hci_ev_radio_text(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ int len = 0;
+ char *data;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ iris_q_event(radio, IRIS_EVT_NEW_RT_RDS);
+
+ while ((skb->data[len+RDS_OFFSET] != 0x0d) && (len < MAX_RT_LENGTH))
+ len++;
+ data = kmalloc(len+RDS_OFFSET, GFP_ATOMIC);
+ if (!data)
+ return;
+
+ data[0] = len;
+ data[1] = skb->data[RDS_PTYPE];
+ data[2] = skb->data[RDS_PID_LOWER];
+ data[3] = skb->data[RDS_PID_HIGHER];
+ data[4] = skb->data[RT_A_B_FLAG_OFFSET];
+
+ memcpy(data+RDS_OFFSET, &skb->data[RDS_OFFSET], len);
+ data[len+RDS_OFFSET] = 0x00;
+
+ iris_q_evt_data(radio, data, len+RDS_OFFSET, IRIS_BUF_RT_RDS);
+
+ kfree(data);
+}
+
+static void hci_ev_af_list(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ struct hci_ev_af_list ev;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ ev.tune_freq = *((int *) &skb->data[0]);
+ ev.pi_code = *((__le16 *) &skb->data[PI_CODE_OFFSET]);
+ ev.af_size = skb->data[AF_SIZE_OFFSET];
+ if (ev.af_size > AF_LIST_MAX) {
+ FMDERR("AF list size received more than available size\n");
+ return;
+ }
+ memcpy(&ev.af_list[0], &skb->data[AF_LIST_OFFSET],
+ ev.af_size * sizeof(int));
+ iris_q_event(radio, IRIS_EVT_NEW_AF_LIST);
+ iris_q_evt_data(radio, (char *)&ev, (7 + ev.af_size * sizeof(int)),
+ IRIS_BUF_AF_LIST);
+}
+
+static void hci_ev_rds_lock_status(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ __u8 rds_status;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+
+ rds_status = skb->data[0];
+
+ if (rds_status)
+ iris_q_event(radio, IRIS_EVT_RDS_AVAIL);
+ else
+ iris_q_event(radio, IRIS_EVT_RDS_NOT_AVAIL);
+}
+
+static void hci_ev_service_available(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ u8 serv_avble;
+
+ if (unlikely(skb == NULL)) {
+ FMDERR("%s, socket buffer is null\n", __func__);
+ return;
+ }
+ serv_avble = skb->data[0];
+ if (serv_avble)
+ iris_q_event(radio, IRIS_EVT_ABOVE_TH);
+ else
+ iris_q_event(radio, IRIS_EVT_BELOW_TH);
+}
+
+static void hci_ev_rds_grp_complete(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ iris_q_event(radio, IRIS_EVT_TXRDSDONE);
+}
+
+void radio_hci_event_packet(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+ struct radio_hci_event_hdr *hdr;
+ u8 event;
+
+ if (skb == NULL) {
+ FMDERR("Socket buffer is NULL\n");
+ return;
+ }
+
+ hdr = (void *) skb->data;
+ event = hdr->evt;
+
+ skb_pull(skb, RADIO_HCI_EVENT_HDR_SIZE);
+
+ FMDBG("event 0x%x", event);
+ switch (event) {
+ case HCI_EV_TUNE_STATUS:
+ hci_ev_tune_status(hdev, skb);
+ break;
+ case HCI_EV_SEARCH_PROGRESS:
+ case HCI_EV_SEARCH_RDS_PROGRESS:
+ case HCI_EV_SEARCH_LIST_PROGRESS:
+ hci_ev_search_next(hdev, skb);
+ break;
+ case HCI_EV_STEREO_STATUS:
+ hci_ev_stereo_status(hdev, skb);
+ break;
+ case HCI_EV_RDS_LOCK_STATUS:
+ hci_ev_rds_lock_status(hdev, skb);
+ break;
+ case HCI_EV_SERVICE_AVAILABLE:
+ hci_ev_service_available(hdev, skb);
+ break;
+ case HCI_EV_RDS_RX_DATA:
+ hci_ev_raw_rds_group_data(hdev, skb);
+ break;
+ case HCI_EV_PROGRAM_SERVICE:
+ hci_ev_program_service(hdev, skb);
+ break;
+ case HCI_EV_RADIO_TEXT:
+ hci_ev_radio_text(hdev, skb);
+ break;
+ case HCI_EV_FM_AF_LIST:
+ hci_ev_af_list(hdev, skb);
+ break;
+ case HCI_EV_TX_RDS_GRP_COMPL:
+ hci_ev_rds_grp_complete(hdev, skb);
+ break;
+ case HCI_EV_TX_RDS_CONT_GRP_COMPL:
+ break;
+
+ case HCI_EV_CMD_COMPLETE:
+ hci_cmd_complete_event(hdev, skb);
+ break;
+
+ case HCI_EV_CMD_STATUS:
+ hci_cmd_status_event(hdev, skb);
+ break;
+
+ case HCI_EV_SEARCH_COMPLETE:
+ case HCI_EV_SEARCH_RDS_COMPLETE:
+ hci_ev_search_compl(hdev, skb);
+ break;
+
+ case HCI_EV_SEARCH_LIST_COMPLETE:
+ hci_ev_srch_st_list_compl(hdev, skb);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+ * fops/IOCTL helper functions
+ */
+
+static int iris_search(struct iris_device *radio, int on, int dir)
+{
+ int retval = 0;
+ enum search_t srch;
+ int saved_val;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+
+ srch = radio->g_search_mode & SRCH_MODE;
+ saved_val = radio->search_on;
+ radio->search_on = on;
+ if (on) {
+ switch (srch) {
+ case SCAN_FOR_STRONG:
+ case SCAN_FOR_WEAK:
+ radio->srch_st_list.srch_list_dir = dir;
+ radio->srch_st_list.srch_list_mode = srch;
+ retval = hci_fm_search_station_list(
+ &radio->srch_st_list, radio->fm_hdev);
+ break;
+ case RDS_SEEK_PTY:
+ case RDS_SCAN_PTY:
+ case RDS_SEEK_PI:
+ srch = srch - SEARCH_RDS_STNS_MODE_OFFSET;
+ radio->srch_rds.srch_station.srch_mode = srch;
+ radio->srch_rds.srch_station.srch_dir = dir;
+ radio->srch_rds.srch_station.scan_time =
+ radio->g_scan_time;
+ retval = hci_fm_search_rds_stations(&radio->srch_rds,
+ radio->fm_hdev);
+ break;
+ default:
+ radio->srch_st.srch_mode = srch;
+ radio->srch_st.scan_time = radio->g_scan_time;
+ radio->srch_st.srch_dir = dir;
+ retval = hci_fm_search_stations(
+ &radio->srch_st, radio->fm_hdev);
+ break;
+ }
+
+ } else {
+ retval = hci_cmd(HCI_FM_CANCEL_SEARCH_CMD, radio->fm_hdev);
+ }
+
+ if (retval < 0)
+ radio->search_on = saved_val;
+ return retval;
+}
+
+static int set_low_power_mode(struct iris_device *radio, int power_mode)
+{
+
+ int rds_grps_proc = 0x00;
+ int retval = 0;
+ struct hci_fm_rds_grp_req grp_3a;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+
+ FMDBG("power mode old 0x%x new 0x%x", radio->power_mode, power_mode);
+ if (radio->power_mode != power_mode) {
+
+ if (power_mode) {
+ memcpy(&grp_3a, &radio->rds_grp,
+ sizeof(struct hci_fm_rds_grp_req));
+ /* Disable 3A group */
+ grp_3a.rds_grp_enable_mask &= ~FM_RDS_3A_GRP;
+ retval = hci_fm_rds_grp(&grp_3a, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("error in disable 3A group mask\n");
+ radio->event_mask = 0x00;
+ if (radio->af_jump_bit)
+ rds_grps_proc = 0x00 | AF_JUMP_ENABLE;
+ else
+ rds_grps_proc = 0x00;
+ retval = hci_fm_rds_grps_process(
+ &rds_grps_proc,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Disable RDS failed\n");
+ return retval;
+ }
+ retval = hci_conf_event_mask(&radio->event_mask,
+ radio->fm_hdev);
+ } else {
+ /* Enable RDS group to normal */
+ retval = hci_fm_rds_grp(&radio->rds_grp,
+ radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("error in enable 3A group mask\n");
+ radio->event_mask = SIG_LEVEL_INTR |
+ RDS_SYNC_INTR | AUDIO_CTRL_INTR;
+ retval = hci_conf_event_mask(&radio->event_mask,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Enable Async events failed\n");
+ return retval;
+ }
+ retval = hci_fm_rds_grps_process(
+ &radio->g_rds_grp_proc_ps,
+ radio->fm_hdev);
+ }
+ radio->power_mode = power_mode;
+ }
+ return retval;
+}
+static int iris_recv_set_region(struct iris_device *radio, int req_region)
+{
+ int retval;
+ int saved_val;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+ saved_val = radio->region;
+ radio->region = req_region;
+
+ retval = hci_set_fm_recv_conf(
+ &radio->recv_conf,
+ radio->fm_hdev);
+
+ if (retval < 0)
+ radio->region = saved_val;
+
+ return retval;
+}
+
+
+static int iris_trans_set_region(struct iris_device *radio, int req_region)
+{
+ int retval;
+ int saved_val;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+
+ saved_val = radio->region;
+ radio->region = req_region;
+
+ retval = hci_set_fm_trans_conf(
+ &radio->trans_conf,
+ radio->fm_hdev);
+
+ if (retval < 0)
+ radio->region = saved_val;
+ return retval;
+}
+
+
+static int iris_set_freq(struct iris_device *radio, unsigned int freq)
+{
+
+ int retval;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+ retval = hci_fm_tune_station(&freq, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("Error while setting the frequency : %d\n", retval);
+ return retval;
+}
+
+
+static int iris_vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ unsigned char i;
+ int retval = -EINVAL;
+
+ if (qc == NULL) {
+ FMDERR("%s, query ctrl is null\n", __func__);
+ return retval;
+ }
+ for (i = 0; i < ARRAY_SIZE(iris_v4l2_queryctrl); i++) {
+ if (qc->id && qc->id == iris_v4l2_queryctrl[i].id) {
+ memcpy(qc, &(iris_v4l2_queryctrl[i]), sizeof(*qc));
+ retval = 0;
+ break;
+ }
+ }
+
+ return retval;
+}
+
+static int iris_do_calibration(struct iris_device *radio)
+{
+ char cal_mode = 0x00;
+ int retval = 0x00;
+
+ FMDBG("radio %pK", radio);
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+
+ cal_mode = PROCS_CALIB_MODE;
+ radio->mode = FM_CALIB;
+ retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Enable failed before calibration %x\n", retval);
+ radio->mode = FM_OFF;
+ return retval;
+ }
+ retval = radio_hci_request(radio->fm_hdev, hci_fm_do_cal_req,
+ (unsigned long)cal_mode, RADIO_HCI_TIMEOUT);
+ if (retval < 0) {
+ FMDERR("Do Process calibration failed %x\n", retval);
+ radio->mode = FM_RECV;
+ return retval;
+ }
+ retval = hci_cmd(HCI_FM_DISABLE_RECV_CMD,
+ radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("Disable Failed after calibration %d\n", retval);
+
+ return retval;
+}
+static int iris_vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ int retval = 0;
+ int cf0;
+ struct hci_fm_def_data_rd_req rd;
+ int lsb, msb;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ retval = -EINVAL;
+ goto end;
+ }
+
+ if (ctrl == NULL) {
+ FMDERR("%s, v4l2 ctrl is null\n", __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+
+ FMDBG("id 0x%x", ctrl->id);
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ if (is_valid_hard_mute(radio->mute_mode.hard_mute))
+ ctrl->value = radio->mute_mode.hard_mute;
+ else
+ retval = -EINVAL;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
+ if (is_valid_srch_mode(radio->g_search_mode))
+ ctrl->value = radio->g_search_mode;
+ else
+ retval = -EINVAL;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
+ if (is_valid_scan_dwell_prd(radio->g_scan_time))
+ ctrl->value = radio->g_scan_time;
+ else
+ retval = -EINVAL;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SRCHON:
+ ctrl->value = radio->search_on;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_STATE:
+ if (is_valid_fm_state(radio->mode))
+ ctrl->value = radio->mode;
+ else
+ retval = -EINVAL;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_IOVERC:
+ retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+ if (retval < 0)
+ return retval;
+ ctrl->value = radio->st_dbg_param.io_verc;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_INTDET:
+ retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+ if (retval == 0)
+ ctrl->value = radio->st_dbg_param.in_det_out;
+ else
+ retval = -EINVAL;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_REGION:
+ ctrl->value = radio->region;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
+ retval = hci_cmd(HCI_FM_GET_SIGNAL_TH_CMD, radio->fm_hdev);
+ if ((retval == 0) &&
+ is_valid_sig_th(radio->sig_th.sig_threshold))
+ ctrl->value = radio->sig_th.sig_threshold;
+ else
+ retval = -EINVAL;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
+ if (is_valid_pty(radio->srch_rds.srch_pty))
+ ctrl->value = radio->srch_rds.srch_pty;
+ else
+ retval = -EINVAL;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
+ if (is_valid_pi(radio->srch_rds.srch_pi))
+ ctrl->value = radio->srch_rds.srch_pi;
+ else
+ retval = -EINVAL;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
+ if (is_valid_srch_station_cnt(
+ radio->srch_st_result.num_stations_found))
+ ctrl->value = radio->srch_st_result.num_stations_found;
+ else
+ retval = -EINVAL;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
+ if (radio->mode == FM_RECV) {
+ retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+ radio->fm_hdev);
+ if ((retval == 0) &&
+ is_valid_emphasis(radio->recv_conf.emphasis))
+ ctrl->value = radio->recv_conf.emphasis;
+ else
+ retval = -EINVAL;
+ } else if (radio->mode == FM_TRANS) {
+ retval = hci_cmd(HCI_FM_GET_TX_CONFIG,
+ radio->fm_hdev);
+ if ((retval == 0) &&
+ is_valid_emphasis(radio->trans_conf.emphasis))
+ ctrl->value = radio->trans_conf.emphasis;
+ else
+ retval = -EINVAL;
+ } else {
+ retval = -EINVAL;
+ FMDERR("Error in radio mode %d\n", retval);
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RDS_STD:
+ if (radio->mode == FM_RECV) {
+ retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+ radio->fm_hdev);
+ if ((retval == 0) &&
+ is_valid_rds_std(radio->recv_conf.rds_std))
+ ctrl->value = radio->recv_conf.rds_std;
+ else
+ retval = -EINVAL;
+ } else if (radio->mode == FM_TRANS) {
+ retval = hci_cmd(HCI_FM_GET_TX_CONFIG,
+ radio->fm_hdev);
+ if ((retval == 0) &&
+ is_valid_rds_std(radio->trans_conf.rds_std))
+ ctrl->value = radio->trans_conf.rds_std;
+ else
+ retval = -EINVAL;
+ } else {
+ retval = -EINVAL;
+ FMDERR("Error in radio mode %d\n", retval);
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SPACING:
+ if (radio->mode == FM_RECV) {
+ retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+ radio->fm_hdev);
+ if ((retval == 0) &&
+ is_valid_chan_spacing(
+ radio->recv_conf.ch_spacing))
+ ctrl->value = radio->recv_conf.ch_spacing;
+ else
+ retval = -EINVAL;
+ } else {
+ retval = -EINVAL;
+ FMDERR("Error in radio mode %d\n", retval);
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RDSON:
+ if (radio->mode == FM_RECV) {
+ retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+ radio->fm_hdev);
+ if ((retval == 0) &&
+ is_valid_rds_std(radio->recv_conf.rds_std))
+ ctrl->value = radio->recv_conf.rds_std;
+ else
+ retval = -EINVAL;
+ } else {
+ retval = -EINVAL;
+ FMDERR("Error in radio mode %d\n", retval);
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
+ ctrl->value = radio->rds_grp.rds_grp_enable_mask;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
+ case V4L2_CID_PRIVATE_IRIS_PSALL:
+ ctrl->value = radio->g_rds_grp_proc_ps;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
+ ctrl->value = radio->rds_grp.rds_buf_size;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_LP_MODE:
+ ctrl->value = radio->power_mode;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_ANTENNA:
+ ctrl->value = radio->g_antenna;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SOFT_MUTE:
+ retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+ if ((retval == 0) &&
+ is_valid_soft_mute(radio->mute_mode.soft_mute))
+ ctrl->value = radio->mute_mode.soft_mute;
+ else
+ retval = -EINVAL;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_DO_CALIBRATION:
+ retval = iris_do_calibration(radio);
+ break;
+ case V4L2_CID_PRIVATE_IRIS_GET_SINR:
+ if (radio->mode == FM_RECV) {
+ retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD,
+ radio->fm_hdev);
+ if (retval == 0)
+ ctrl->value = radio->fm_st_rsp.station_rsp.sinr;
+ } else
+ retval = -EINVAL;
+ break;
+ case V4L2_CID_PRIVATE_INTF_HIGH_THRESHOLD:
+ retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+ if (retval == 0)
+ ctrl->value = radio->ch_det_threshold.high_th;
+ break;
+ case V4L2_CID_PRIVATE_INTF_LOW_THRESHOLD:
+ retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+ if (retval == 0)
+ ctrl->value = radio->ch_det_threshold.low_th;
+ break;
+ case V4L2_CID_PRIVATE_SINR_THRESHOLD:
+ retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+ if (retval == 0)
+ ctrl->value = radio->ch_det_threshold.sinr;
+ break;
+ case V4L2_CID_PRIVATE_SINR_SAMPLES:
+ retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+ if (retval == 0)
+ ctrl->value = radio->ch_det_threshold.sinr_samples;
+ break;
+ case V4L2_CID_PRIVATE_VALID_CHANNEL:
+ ctrl->value = radio->is_station_valid;
+ break;
+ case V4L2_CID_PRIVATE_AF_RMSSI_TH:
+ rd.mode = FM_RDS_CNFG_MODE;
+ rd.length = FM_RDS_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval == 0) {
+ lsb = radio->default_data.data[AF_RMSSI_TH_LSB_OFFSET];
+ msb = radio->default_data.data[AF_RMSSI_TH_MSB_OFFSET];
+ ctrl->value = ((msb << 8) | lsb);
+ }
+ break;
+ case V4L2_CID_PRIVATE_AF_RMSSI_SAMPLES:
+ rd.mode = FM_RDS_CNFG_MODE;
+ rd.length = FM_RDS_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval == 0)
+ ctrl->value =
+ radio->default_data.data[AF_RMSSI_SAMPLES_OFFSET];
+ break;
+ case V4L2_CID_PRIVATE_GOOD_CH_RMSSI_TH:
+ rd.mode = FM_RX_CONFG_MODE;
+ rd.length = FM_RX_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval == 0) {
+ ctrl->value =
+ radio->default_data.data[GD_CH_RMSSI_TH_OFFSET];
+ if (ctrl->value > MAX_GD_CH_RMSSI_TH)
+ ctrl->value -= 256;
+ }
+ break;
+ case V4L2_CID_PRIVATE_SRCHALGOTYPE:
+ rd.mode = FM_RX_CONFG_MODE;
+ rd.length = FM_RX_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval == 0)
+ ctrl->value =
+ radio->default_data.data[SRCH_ALGO_TYPE_OFFSET];
+ break;
+ case V4L2_CID_PRIVATE_SINRFIRSTSTAGE:
+ rd.mode = FM_RX_CONFG_MODE;
+ rd.length = FM_RX_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval == 0) {
+ ctrl->value =
+ radio->default_data.data[SINRFIRSTSTAGE_OFFSET];
+ if (ctrl->value > MAX_SINR_FIRSTSTAGE)
+ ctrl->value -= 256;
+ }
+ break;
+ case V4L2_CID_PRIVATE_RMSSIFIRSTSTAGE:
+ rd.mode = FM_RX_CONFG_MODE;
+ rd.length = FM_RX_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval == 0) {
+ ctrl->value =
+ radio->default_data.data[RMSSIFIRSTSTAGE_OFFSET];
+ if (ctrl->value > MAX_RMSSI_FIRSTSTAGE)
+ ctrl->value -= 256;
+ }
+ break;
+ case V4L2_CID_PRIVATE_CF0TH12:
+ rd.mode = FM_RX_CONFG_MODE;
+ rd.length = FM_RX_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval == 0) {
+ ctrl->value =
+ radio->default_data.data[CF0TH12_BYTE1_OFFSET];
+ cf0 = radio->default_data.data[CF0TH12_BYTE2_OFFSET];
+ ctrl->value |= (cf0 << 8);
+ cf0 = radio->default_data.data[CF0TH12_BYTE3_OFFSET];
+ ctrl->value |= (cf0 << 16);
+ cf0 = radio->default_data.data[CF0TH12_BYTE4_OFFSET];
+ if (cf0 > 127)
+ cf0 -= 256;
+ ctrl->value |= (cf0 << 24);
+ }
+ break;
+ case V4L2_CID_PRIVATE_BLEND_SINRHI:
+ retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Failed to get blend table %d", retval);
+ goto end;
+ }
+ ctrl->value = radio->blend_tbl.scBlendSinrHi;
+ break;
+ case V4L2_CID_PRIVATE_BLEND_RMSSIHI:
+ retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Failed to get blend table %d", retval);
+ goto end;
+ }
+ ctrl->value = radio->blend_tbl.scBlendRmssiHi;
+ break;
+ default:
+ retval = -EINVAL;
+ break;
+ }
+
+end:
+ if (retval > 0)
+ retval = -EINVAL;
+ if (ctrl != NULL && retval < 0)
+ FMDERR("get control failed: %d, ret: %d\n", ctrl->id, retval);
+
+ return retval;
+}
+
+static int iris_vidioc_g_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *ctrl)
+{
+ int retval = 0;
+ char *data = NULL;
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ struct hci_fm_def_data_rd_req default_data_rd;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ retval = -EINVAL;
+ goto end;
+ }
+
+ if ((ctrl == NULL) || (ctrl->count == 0)
+ || (ctrl->controls == NULL)) {
+ FMDERR("%s, invalid v4l2 ctrl\n", __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+
+ FMDBG("0x%x", ctrl->controls[0].id);
+ switch ((ctrl->controls[0]).id) {
+ case V4L2_CID_PRIVATE_IRIS_READ_DEFAULT:
+ data = (ctrl->controls[0]).string;
+ memset(&default_data_rd, 0, sizeof(default_data_rd));
+ if (copy_from_user(&default_data_rd.mode, data,
+ sizeof(default_data_rd))) {
+ retval = -EFAULT;
+ goto end;
+ }
+ retval = hci_def_data_read(&default_data_rd, radio->fm_hdev);
+ break;
+ default:
+ retval = -EINVAL;
+ break;
+ }
+
+end:
+ if (retval > 0)
+ retval = -EINVAL;
+
+ return retval;
+}
+
+static int iris_vidioc_s_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *ctrl)
+{
+ int retval = 0;
+ size_t bytes_to_copy;
+ struct hci_fm_tx_ps tx_ps;
+ struct hci_fm_tx_rt tx_rt;
+ struct hci_fm_def_data_wr_req default_data;
+ struct hci_fm_set_cal_req_proc proc_cal_req;
+ struct hci_fm_set_spur_table_req spur_tbl_req;
+ char *spur_data;
+ char tmp_buf[2];
+
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ char *data = NULL;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null");
+ retval = -EINVAL;
+ goto end;
+ }
+
+ if ((ctrl == NULL) || (ctrl->count == 0)
+ || (ctrl->controls == NULL)) {
+ FMDERR("%s, invalid v4l2 ctrl\n", __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+
+ FMDBG("0x%x\n", ctrl->controls[0].id);
+ switch ((ctrl->controls[0]).id) {
+ case V4L2_CID_RDS_TX_PS_NAME:
+ FMDBG("In V4L2_CID_RDS_TX_PS_NAME\n");
+ /*Pass a sample PS string */
+
+ memset(tx_ps.ps_data, 0, MAX_PS_LENGTH);
+ bytes_to_copy = min_t(size_t, ctrl->controls[0].size,
+ MAX_PS_LENGTH);
+ data = (ctrl->controls[0]).string;
+
+ if (copy_from_user(tx_ps.ps_data,
+ data, bytes_to_copy)) {
+ FMDERR("%s: copy from user for tx ps name failed\n",
+ __func__);
+ retval = -EFAULT;
+ goto end;
+ } else {
+ tx_ps.ps_control = 0x01;
+ tx_ps.pi = radio->pi;
+ tx_ps.pty = radio->pty;
+ tx_ps.ps_repeatcount = radio->ps_repeatcount;
+ tx_ps.ps_num = (bytes_to_copy / PS_STRING_LEN);
+
+ retval = radio_hci_request(radio->fm_hdev,
+ hci_trans_ps_req,
+ (unsigned long)&tx_ps,
+ RADIO_HCI_TIMEOUT);
+ }
+ break;
+ case V4L2_CID_RDS_TX_RADIO_TEXT:
+ bytes_to_copy =
+ min_t(size_t, (ctrl->controls[0]).size, MAX_RT_LENGTH);
+ data = (ctrl->controls[0]).string;
+
+ memset(tx_rt.rt_data, 0, MAX_RT_LENGTH);
+
+ if (copy_from_user(tx_rt.rt_data,
+ data, bytes_to_copy)) {
+ FMDERR("%s: copy from user for tx rt failed\n",
+ __func__);
+ retval = -EFAULT;
+ goto end;
+ } else {
+ tx_rt.rt_control = 0x01;
+ tx_rt.pi = radio->pi;
+ tx_rt.pty = radio->pty;
+ tx_rt.rt_len = bytes_to_copy;
+
+ retval = radio_hci_request(radio->fm_hdev,
+ hci_trans_rt_req,
+ (unsigned long)&tx_rt,
+ RADIO_HCI_TIMEOUT);
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_WRITE_DEFAULT:
+ data = (ctrl->controls[0]).string;
+ memset(&default_data, 0, sizeof(default_data));
+ /*
+ * Check if length of the 'FM Default Data' to be sent
+ * is within the maximum 'FM Default Data' packet limit.
+ * Max. 'FM Default Data' packet length is 251 bytes:
+ * 1 byte - XFR Mode
+ * 1 byte - length of the default data
+ * 249 bytes - actual data to be configured
+ */
+ if (ctrl->controls[0].size > (DEFAULT_DATA_SIZE + 2)) {
+ pr_err("%s: Default data buffer overflow\n", __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+
+ /* copy only 'size' bytes of data as requested by user */
+ retval = copy_from_user(&default_data, data,
+ ctrl->controls[0].size);
+ if (retval > 0) {
+ FMDERR("Failed to copy %d bytes data\n", retval);
+ retval = -EFAULT;
+ goto end;
+ }
+ FMDBG("XFR Mode\t: 0x%x", default_data.mode);
+ FMDBG("XFR Data Length\t: %d\n", default_data.length);
+ /*
+ * Check if the 'length' of the actual XFR data to be configured
+ * is valid or not. Length of actual XFR data should be always
+ * 2 bytes less than the total length of the 'FM Default Data'.
+ * Length of 'FM Default Data' DEF_DATA_LEN: (1+1+XFR Data Size)
+ * Length of 'Actual XFR Data' XFR_DATA_LEN: (DEF_DATA_LEN - 2)
+ */
+ if (default_data.length != (ctrl->controls[0].size - 2)) {
+ FMDERR("Invalid 'length' parameter\n");
+ retval = -EINVAL;
+ goto end;
+ }
+ retval = hci_def_data_write(&default_data, radio->fm_hdev);
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SET_CALIBRATION:
+ data = (ctrl->controls[0]).string;
+ bytes_to_copy = (ctrl->controls[0]).size;
+ if (bytes_to_copy < PROCS_CALIB_SIZE) {
+ FMDERR("data is less than required size\n");
+ retval = -EFAULT;
+ goto end;
+ }
+ memset(proc_cal_req.data, 0, PROCS_CALIB_SIZE);
+ proc_cal_req.mode = PROCS_CALIB_MODE;
+ if (copy_from_user(&proc_cal_req.data[0],
+ data, sizeof(proc_cal_req.data))) {
+ retval = -EFAULT;
+ goto end;
+ }
+ retval = radio_hci_request(radio->fm_hdev,
+ hci_fm_set_cal_req_proc,
+ (unsigned long)&proc_cal_req,
+ RADIO_HCI_TIMEOUT);
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SET_SPURTABLE:
+ memset(&spur_tbl_req, 0, sizeof(spur_tbl_req));
+ data = (ctrl->controls[0]).string;
+ if (copy_from_user(&bytes_to_copy, &((ctrl->controls[0]).size),
+ sizeof(bytes_to_copy))) {
+ retval = -EFAULT;
+ goto end;
+ }
+ if (copy_from_user(&tmp_buf[0], &data[0],
+ sizeof(tmp_buf))) {
+ retval = -EFAULT;
+ goto end;
+ }
+ spur_tbl_req.mode = tmp_buf[0];
+ spur_tbl_req.no_of_freqs_entries = tmp_buf[1];
+
+ if (((spur_tbl_req.no_of_freqs_entries * SPUR_DATA_LEN) !=
+ bytes_to_copy - 2) ||
+ ((spur_tbl_req.no_of_freqs_entries * SPUR_DATA_LEN) >
+ 2 * FM_SPUR_TBL_SIZE)) {
+ FMDERR("Invalid data len: data[1] = %d, bytes = %zu\n",
+ spur_tbl_req.no_of_freqs_entries,
+ bytes_to_copy);
+ retval = -EINVAL;
+ goto end;
+ }
+ spur_data =
+ kmalloc((spur_tbl_req.no_of_freqs_entries * SPUR_DATA_LEN)
+ + 2, GFP_ATOMIC);
+ if (!spur_data) {
+ retval = -EFAULT;
+ goto end;
+ }
+ if (copy_from_user(spur_data,
+ &data[2], (bytes_to_copy - 2))) {
+ kfree(spur_data);
+ retval = -EFAULT;
+ goto end;
+ }
+
+ if (spur_tbl_req.no_of_freqs_entries <= ENTRIES_EACH_CMD) {
+ memcpy(&spur_tbl_req.spur_data[0], spur_data,
+ (spur_tbl_req.no_of_freqs_entries *
+ SPUR_DATA_LEN));
+ retval = radio_hci_request(radio->fm_hdev,
+ hci_fm_set_spur_tbl_req,
+ (unsigned long)&spur_tbl_req,
+ RADIO_HCI_TIMEOUT);
+ } else {
+ memcpy(&spur_tbl_req.spur_data[0], spur_data,
+ (ENTRIES_EACH_CMD * SPUR_DATA_LEN));
+ retval = radio_hci_request(radio->fm_hdev,
+ hci_fm_set_spur_tbl_req,
+ (unsigned long)&spur_tbl_req,
+ RADIO_HCI_TIMEOUT);
+ if (retval < 0) {
+ FMDERR("Spur command failed to execute\n");
+ kfree(spur_data);
+ goto end;
+ }
+ spur_tbl_req.mode = 0x02;/* 02-Continue mode */
+ spur_tbl_req.no_of_freqs_entries =
+ spur_tbl_req.no_of_freqs_entries
+ - ENTRIES_EACH_CMD;
+ memcpy(&spur_tbl_req.spur_data[0],
+ &spur_data[ENTRIES_EACH_CMD * SPUR_DATA_LEN],
+ (spur_tbl_req.no_of_freqs_entries * SPUR_DATA_LEN));
+ retval = radio_hci_request(radio->fm_hdev,
+ hci_fm_set_spur_tbl_req,
+ (unsigned long)&spur_tbl_req,
+ RADIO_HCI_TIMEOUT);
+ }
+ kfree(spur_data);
+ break;
+ default:
+ FMDBG("Shouldn't reach here\n");
+ retval = -EINVAL;
+ goto end;
+ }
+
+end:
+ if (retval > 0)
+ retval = -EINVAL;
+
+ return retval;
+}
+
+static int iris_vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ int retval = 0;
+ unsigned int rds_grps_proc = 0;
+ __u8 temp_val = 0;
+ int saved_val;
+ unsigned long arg = 0;
+ struct hci_fm_tx_ps tx_ps = {0};
+ struct hci_fm_tx_rt tx_rt = {0};
+ struct hci_fm_def_data_rd_req rd;
+ struct hci_fm_def_data_wr_req wrd;
+ char sinr_th, sinr;
+ __u8 intf_det_low_th, intf_det_high_th, intf_det_out;
+ unsigned int spur_freq;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ retval = -EINVAL;
+ goto end;
+ }
+
+ if (ctrl == NULL) {
+ FMDERR("%s, v4l2 ctrl is null\n", __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+
+ FMDBG("id 0x%x", ctrl->id);
+ switch (ctrl->id) {
+ case V4L2_CID_PRIVATE_IRIS_TX_TONE:
+ if (!is_valid_tone(ctrl->value)) {
+ retval = -EINVAL;
+ FMDERR("%s: tone value is not valid\n", __func__);
+ goto end;
+ }
+ saved_val = radio->tone_freq;
+ radio->tone_freq = ctrl->value;
+ retval = radio_hci_request(radio->fm_hdev,
+ hci_fm_tone_generator, arg,
+ RADIO_HCI_TIMEOUT);
+ if (retval < 0) {
+ FMDERR("Error while setting the tone %d\n", retval);
+ radio->tone_freq = saved_val;
+ }
+ break;
+ case V4L2_CID_AUDIO_VOLUME:
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ if (!is_valid_hard_mute(ctrl->value)) {
+ retval = -EINVAL;
+ FMDERR("%s: hard mute value is not valid\n", __func__);
+ goto end;
+ }
+ saved_val = radio->mute_mode.hard_mute;
+ radio->mute_mode.hard_mute = ctrl->value;
+ retval = hci_set_fm_mute_mode(
+ &radio->mute_mode,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error while set FM hard mute %d\n",
+ retval);
+ radio->mute_mode.hard_mute = saved_val;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
+ if (is_valid_srch_mode(ctrl->value)) {
+ radio->g_search_mode = ctrl->value;
+ } else {
+ FMDERR("%s: srch mode is not valid\n", __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
+ if (is_valid_scan_dwell_prd(ctrl->value)) {
+ radio->g_scan_time = ctrl->value;
+ } else {
+ FMDERR("%s: scandwell period is not valid\n", __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SRCHON:
+ iris_search(radio, ctrl->value, SRCH_DIR_UP);
+ break;
+ case V4L2_CID_PRIVATE_IRIS_STATE:
+ switch (ctrl->value) {
+ case FM_RECV:
+ if (radio->mode != FM_OFF) {
+ FMDERR("FM mode is not off %d\n", radio->mode);
+ retval = -EINVAL;
+ goto end;
+ }
+ if (is_enable_rx_possible(radio) != 0) {
+ FMDERR("%s: fm is not in proper state\n",
+ __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ radio->mode = FM_RECV_TURNING_ON;
+ retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Enabling RECV FM fail %d\n", retval);
+ radio->mode = FM_OFF;
+ goto end;
+ } else {
+ retval = initialise_recv(radio);
+ if (retval < 0) {
+ FMDERR("Error while initialising\n");
+ FMDERR("radio %d\n", retval);
+ hci_cmd(HCI_FM_DISABLE_RECV_CMD,
+ radio->fm_hdev);
+ radio->mode = FM_OFF;
+ goto end;
+ }
+ }
+ if (radio->mode == FM_RECV_TURNING_ON) {
+ radio->mode = FM_RECV;
+ iris_q_event(radio, IRIS_EVT_RADIO_READY);
+ }
+ break;
+ case FM_TRANS:
+ if (is_enable_tx_possible(radio) != 0) {
+ retval = -EINVAL;
+ goto end;
+ }
+ radio->mode = FM_TRANS_TURNING_ON;
+ retval = hci_cmd(HCI_FM_ENABLE_TRANS_CMD,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Enabling TRANS FM fail %d\n", retval);
+ radio->mode = FM_OFF;
+ goto end;
+ } else {
+ retval = initialise_trans(radio);
+ if (retval < 0) {
+ FMDERR("Error while initialising\n");
+ FMDERR("radio %d\n", retval);
+ hci_cmd(HCI_FM_DISABLE_TRANS_CMD,
+ radio->fm_hdev);
+ radio->mode = FM_OFF;
+ goto end;
+ }
+ }
+ if (radio->mode == FM_TRANS_TURNING_ON) {
+ radio->mode = FM_TRANS;
+ iris_q_event(radio, IRIS_EVT_RADIO_READY);
+ }
+ break;
+ case FM_OFF:
+ radio->spur_table_size = 0;
+ switch (radio->mode) {
+ case FM_RECV:
+ radio->mode = FM_TURNING_OFF;
+ retval = hci_cmd(HCI_FM_DISABLE_RECV_CMD,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Err on disable recv FM\n");
+ FMDERR("%d\n", retval);
+ radio->mode = FM_RECV;
+ goto end;
+ }
+ break;
+ case FM_TRANS:
+ radio->mode = FM_TURNING_OFF;
+ retval = hci_cmd(HCI_FM_DISABLE_TRANS_CMD,
+ radio->fm_hdev);
+
+ if (retval < 0) {
+ FMDERR("Err disabling trans FM\n");
+ FMDERR("%d\n", retval);
+ radio->mode = FM_TRANS;
+ goto end;
+ }
+ break;
+ default:
+ retval = -EINVAL;
+ }
+ break;
+ default:
+ retval = -EINVAL;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_REGION:
+ if (radio->mode == FM_RECV) {
+ retval = iris_recv_set_region(radio, ctrl->value);
+ } else {
+ if (radio->mode == FM_TRANS) {
+ retval = iris_trans_set_region(radio,
+ ctrl->value);
+ } else {
+ FMDERR("%s: fm is not in proper state\n",
+ __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
+ if (!is_valid_sig_th(ctrl->value)) {
+ retval = -EINVAL;
+ FMDERR("%s: sig threshold is not valid\n", __func__);
+ goto end;
+ }
+ temp_val = ctrl->value;
+ retval = hci_fm_set_signal_threshold(
+ &temp_val,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error while setting signal threshold\n");
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
+ if (is_valid_pty(ctrl->value)) {
+ radio->srch_rds.srch_pty = ctrl->value;
+ radio->srch_st_list.srch_pty = ctrl->value;
+ } else {
+ FMDERR("%s: pty is not valid\n", __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
+ if (is_valid_pi(ctrl->value)) {
+ radio->srch_rds.srch_pi = ctrl->value;
+ } else {
+ retval = -EINVAL;
+ FMDERR("%s: Pi is not valid\n", __func__);
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
+ if (is_valid_srch_station_cnt(ctrl->value)) {
+ radio->srch_st_list.srch_list_max = ctrl->value;
+ } else {
+ retval = -EINVAL;
+ FMDERR("%s: srch station count is not valid\n",
+ __func__);
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SPACING:
+ if (!is_valid_chan_spacing(ctrl->value)) {
+ retval = -EINVAL;
+ FMDERR("%s: channel spacing is not valid\n", __func__);
+ goto end;
+ }
+ if (radio->mode == FM_RECV) {
+ saved_val = radio->recv_conf.ch_spacing;
+ radio->recv_conf.ch_spacing = ctrl->value;
+ retval = hci_set_fm_recv_conf(
+ &radio->recv_conf,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error in setting channel spacing\n");
+ radio->recv_conf.ch_spacing = saved_val;
+ goto end;
+ }
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
+ if (!is_valid_emphasis(ctrl->value)) {
+ retval = -EINVAL;
+ FMDERR("%s, emphasis is not valid\n", __func__);
+ goto end;
+ }
+ switch (radio->mode) {
+ case FM_RECV:
+ saved_val = radio->recv_conf.emphasis;
+ radio->recv_conf.emphasis = ctrl->value;
+ retval = hci_set_fm_recv_conf(
+ &radio->recv_conf,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error in setting emphasis\n");
+ radio->recv_conf.emphasis = saved_val;
+ goto end;
+ }
+ break;
+ case FM_TRANS:
+ saved_val = radio->trans_conf.emphasis;
+ radio->trans_conf.emphasis = ctrl->value;
+ retval = hci_set_fm_trans_conf(
+ &radio->trans_conf,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error in setting emphasis\n");
+ radio->trans_conf.emphasis = saved_val;
+ goto end;
+ }
+ break;
+ default:
+ retval = -EINVAL;
+ FMDERR("FM mode is unknown %d\n", radio->mode);
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RDS_STD:
+ if (!is_valid_rds_std(ctrl->value)) {
+ retval = -EINVAL;
+ FMDERR("%s: rds std is not valid\n", __func__);
+ goto end;
+ }
+ switch (radio->mode) {
+ case FM_RECV:
+ saved_val = radio->recv_conf.rds_std;
+ radio->recv_conf.rds_std = ctrl->value;
+ retval = hci_set_fm_recv_conf(
+ &radio->recv_conf,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error in rds_std\n");
+ radio->recv_conf.rds_std = saved_val;
+ goto end;
+ }
+ break;
+ case FM_TRANS:
+ saved_val = radio->trans_conf.rds_std;
+ radio->trans_conf.rds_std = ctrl->value;
+ retval = hci_set_fm_trans_conf(
+ &radio->trans_conf,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error in rds_Std\n");
+ radio->trans_conf.rds_std = saved_val;
+ goto end;
+ }
+ break;
+ default:
+ retval = -EINVAL;
+ FMDERR("%s: fm is not in proper state\n", __func__);
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RDSON:
+ if (!is_valid_rds_std(ctrl->value)) {
+ retval = -EINVAL;
+ FMDERR("%s: rds std is not valid\n", __func__);
+ goto end;
+ }
+ switch (radio->mode) {
+ case FM_RECV:
+ saved_val = radio->recv_conf.rds_std;
+ radio->recv_conf.rds_std = ctrl->value;
+ retval = hci_set_fm_recv_conf(
+ &radio->recv_conf,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error in rds_std\n");
+ radio->recv_conf.rds_std = saved_val;
+ goto end;
+ }
+ break;
+ case FM_TRANS:
+ saved_val = radio->trans_conf.rds_std;
+ radio->trans_conf.rds_std = ctrl->value;
+ retval = hci_set_fm_trans_conf(
+ &radio->trans_conf,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error in rds_Std\n");
+ radio->trans_conf.rds_std = saved_val;
+ goto end;
+ }
+ break;
+ default:
+ retval = -EINVAL;
+ FMDERR("%s: fm is not in proper state\n", __func__);
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
+ saved_val = radio->rds_grp.rds_grp_enable_mask;
+ grp_mask = (grp_mask | oda_agt | ctrl->value);
+ radio->rds_grp.rds_grp_enable_mask = grp_mask;
+ radio->rds_grp.rds_buf_size = 1;
+ radio->rds_grp.en_rds_change_filter = 0;
+ retval = hci_fm_rds_grp(&radio->rds_grp, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("error in setting group mask\n");
+ radio->rds_grp.rds_grp_enable_mask = saved_val;
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
+ saved_val = radio->g_rds_grp_proc_ps;
+ radio->g_rds_grp_proc_ps |= ctrl->value;
+ retval = hci_fm_rds_grps_process(
+ &radio->g_rds_grp_proc_ps,
+ radio->fm_hdev);
+ if (retval < 0) {
+ radio->g_rds_grp_proc_ps = saved_val;
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
+ radio->rds_grp.rds_buf_size = ctrl->value;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_PSALL:
+ saved_val = radio->g_rds_grp_proc_ps;
+ rds_grps_proc = (ctrl->value << RDS_PS_SIMPLE_OFFSET);
+ radio->g_rds_grp_proc_ps |= rds_grps_proc;
+ retval = hci_fm_rds_grps_process(
+ &radio->g_rds_grp_proc_ps,
+ radio->fm_hdev);
+ if (retval < 0) {
+ radio->g_rds_grp_proc_ps = saved_val;
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_AF_JUMP:
+ saved_val = radio->g_rds_grp_proc_ps;
+ /*Clear the current AF jump settings*/
+ radio->g_rds_grp_proc_ps &= ~(1 << RDS_AF_JUMP_OFFSET);
+ radio->af_jump_bit = ctrl->value;
+ rds_grps_proc = 0x00;
+ rds_grps_proc = (ctrl->value << RDS_AF_JUMP_OFFSET);
+ radio->g_rds_grp_proc_ps |= rds_grps_proc;
+ retval = hci_fm_rds_grps_process(
+ &radio->g_rds_grp_proc_ps,
+ radio->fm_hdev);
+ if (retval < 0) {
+ radio->g_rds_grp_proc_ps = saved_val;
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_LP_MODE:
+ set_low_power_mode(radio, ctrl->value);
+ break;
+ case V4L2_CID_PRIVATE_IRIS_ANTENNA:
+ if (!is_valid_antenna(ctrl->value)) {
+ retval = -EINVAL;
+ FMDERR("%s: antenna type is not valid\n", __func__);
+ goto end;
+ }
+ temp_val = ctrl->value;
+ retval = hci_fm_set_antenna(&temp_val, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Set Antenna failed retval = %x\n", retval);
+ goto end;
+ }
+ radio->g_antenna = ctrl->value;
+ break;
+ case V4L2_CID_RDS_TX_PTY:
+ if (is_valid_pty(ctrl->value)) {
+ radio->pty = ctrl->value;
+ } else {
+ retval = -EINVAL;
+ FMDERR("%s: pty is not valid\n", __func__);
+ goto end;
+ }
+ break;
+ case V4L2_CID_RDS_TX_PI:
+ if (is_valid_pi(ctrl->value)) {
+ radio->pi = ctrl->value;
+ } else {
+ retval = -EINVAL;
+ FMDERR("%s: pi is not valid\n", __func__);
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_PS_NAME:
+ tx_ps.ps_control = 0x00;
+ retval = radio_hci_request(radio->fm_hdev, hci_trans_ps_req,
+ (unsigned long)&tx_ps, RADIO_HCI_TIMEOUT);
+ break;
+ case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_RT:
+ tx_rt.rt_control = 0x00;
+ retval = radio_hci_request(radio->fm_hdev, hci_trans_rt_req,
+ (unsigned long)&tx_rt, RADIO_HCI_TIMEOUT);
+ break;
+ case V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT:
+ if (is_valid_ps_repeat_cnt(ctrl->value)) {
+ radio->ps_repeatcount = ctrl->value;
+ } else {
+ retval = -EINVAL;
+ FMDERR("%s: ps repeat count is not valid\n", __func__);
+ goto end;
+ }
+ break;
+ case V4L2_CID_TUNE_POWER_LEVEL:
+ if (ctrl->value > FM_TX_PWR_LVL_MAX)
+ ctrl->value = FM_TX_PWR_LVL_MAX;
+ if (ctrl->value < FM_TX_PWR_LVL_0)
+ ctrl->value = FM_TX_PWR_LVL_0;
+ rd.mode = FM_TX_PHY_CFG_MODE;
+ rd.length = FM_TX_PHY_CFG_LEN;
+ rd.param_len = 0x00;
+ rd.param = 0x00;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Default data read failed for PHY_CFG %d\n",
+ retval);
+ goto end;
+ }
+ memset(&wrd, 0, sizeof(wrd));
+ wrd.mode = FM_TX_PHY_CFG_MODE;
+ wrd.length = FM_TX_PHY_CFG_LEN;
+ memcpy(&wrd.data, &radio->default_data.data,
+ radio->default_data.ret_data_len);
+ wrd.data[FM_TX_PWR_GAIN_OFFSET] =
+ (ctrl->value) * FM_TX_PWR_LVL_STEP_SIZE;
+ retval = hci_def_data_write(&wrd, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("Default write failed for PHY_TXGAIN %d\n",
+ retval);
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SOFT_MUTE:
+ if (!is_valid_soft_mute(ctrl->value)) {
+ retval = -EINVAL;
+ FMDERR("%s: soft mute is not valid\n", __func__);
+ goto end;
+ }
+ saved_val = radio->mute_mode.soft_mute;
+ radio->mute_mode.soft_mute = ctrl->value;
+ retval = hci_set_fm_mute_mode(
+ &radio->mute_mode,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error while setting FM soft mute %d\n",
+ retval);
+ radio->mute_mode.soft_mute = saved_val;
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_ADDR:
+ radio->riva_data_req.cmd_params.start_addr = ctrl->value;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_LEN:
+ if (is_valid_peek_len(ctrl->value)) {
+ radio->riva_data_req.cmd_params.length = ctrl->value;
+ } else {
+ retval = -EINVAL;
+ FMDERR("%s: riva access len is not valid\n", __func__);
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RIVA_POKE:
+ if (radio->riva_data_req.cmd_params.length <=
+ MAX_RIVA_PEEK_RSP_SIZE) {
+#ifdef CONFIG_COMPAT
+ retval = copy_from_user(
+ radio->riva_data_req.data,
+ (void *)(__s64)ctrl->value,
+ radio->riva_data_req.cmd_params.length);
+#else
+ retval = copy_from_user(
+ radio->riva_data_req.data,
+ (void *)ctrl->value,
+ radio->riva_data_req.cmd_params.length);
+#endif
+ if (retval != 0) {
+ retval = -retval;
+ goto end;
+ }
+ radio->riva_data_req.cmd_params.subopcode =
+ RIVA_POKE_OPCODE;
+ retval = hci_poke_data(
+ &radio->riva_data_req,
+ radio->fm_hdev);
+ } else {
+ FMDERR("Can not copy into driver buffer\n");
+ retval = -EINVAL;
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SSBI_ACCS_ADDR:
+ radio->ssbi_data_accs.start_addr = ctrl->value;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SSBI_POKE:
+ radio->ssbi_data_accs.data = ctrl->value;
+ retval = hci_ssbi_poke_reg(&radio->ssbi_data_accs,
+ radio->fm_hdev);
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RIVA_PEEK:
+ radio->riva_data_req.cmd_params.subopcode = RIVA_PEEK_OPCODE;
+ ctrl->value = hci_peek_data(&radio->riva_data_req.cmd_params,
+ radio->fm_hdev);
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SSBI_PEEK:
+ radio->ssbi_peek_reg.start_address = ctrl->value;
+ hci_ssbi_peek_reg(&radio->ssbi_peek_reg, radio->fm_hdev);
+ break;
+ case V4L2_CID_PRIVATE_IRIS_RDS_GRP_COUNTERS:
+ if (is_valid_reset_cntr(ctrl->value)) {
+ temp_val = ctrl->value;
+ hci_read_grp_counters(&temp_val, radio->fm_hdev);
+ } else {
+ FMDERR("%s: reset counter value is not valid\n",
+ __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_IRIS_HLSI:
+ if (!is_valid_hlsi(ctrl->value)) {
+ FMDERR("%s: hlsi value is not valid\n", __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+ radio->fm_hdev);
+ if (retval)
+ goto end;
+ saved_val = radio->recv_conf.hlsi;
+ radio->recv_conf.hlsi = ctrl->value;
+ retval = hci_set_fm_recv_conf(
+ &radio->recv_conf,
+ radio->fm_hdev);
+ if (retval < 0)
+ radio->recv_conf.hlsi = saved_val;
+ break;
+ case V4L2_CID_PRIVATE_IRIS_SET_NOTCH_FILTER:
+ if (is_valid_notch_filter(ctrl->value)) {
+ temp_val = ctrl->value;
+ retval = hci_set_notch_filter(&temp_val,
+ radio->fm_hdev);
+ } else {
+ FMDERR("%s: notch filter is not valid\n", __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_INTF_HIGH_THRESHOLD:
+ if (!is_valid_intf_det_hgh_th(ctrl->value)) {
+ FMDERR("%s: intf high threshold is not valid\n",
+ __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Fail to get chnl det thresholds %d\n", retval);
+ goto end;
+ }
+ saved_val = radio->ch_det_threshold.high_th;
+ radio->ch_det_threshold.high_th = ctrl->value;
+ retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Failed to set High det threshold %d\n", retval);
+ radio->ch_det_threshold.high_th = saved_val;
+ goto end;
+ }
+ break;
+
+ case V4L2_CID_PRIVATE_INTF_LOW_THRESHOLD:
+ if (!is_valid_intf_det_low_th(ctrl->value)) {
+ FMDERR("%s: intf det low threshold is not valid\n",
+ __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Fail to get chnl det thresholds %d\n", retval);
+ goto end;
+ }
+ saved_val = radio->ch_det_threshold.low_th;
+ radio->ch_det_threshold.low_th = ctrl->value;
+ retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Fail to Set Low det threshold %d\n", retval);
+ radio->ch_det_threshold.low_th = saved_val;
+ goto end;
+ }
+ break;
+
+ case V4L2_CID_PRIVATE_SINR_THRESHOLD:
+ if (!is_valid_sinr_th(ctrl->value)) {
+ FMDERR("%s: sinr threshold is not valid\n", __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Fail to get chnl det thresholds %d\n", retval);
+ goto end;
+ }
+ saved_val = radio->ch_det_threshold.sinr;
+ radio->ch_det_threshold.sinr = ctrl->value;
+ retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Fail to set SINR threshold %d\n", retval);
+ radio->ch_det_threshold.sinr = saved_val;
+ goto end;
+ }
+ break;
+
+ case V4L2_CID_PRIVATE_SINR_SAMPLES:
+ if (!is_valid_sinr_samples(ctrl->value)) {
+ FMDERR("%s: sinr samples count is not valid\n",
+ __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Fail to get chnl det thresholds %d\n", retval);
+ goto end;
+ }
+ saved_val = radio->ch_det_threshold.sinr_samples;
+ radio->ch_det_threshold.sinr_samples = ctrl->value;
+ retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Fail to set SINR samples %d\n", retval);
+ radio->ch_det_threshold.sinr_samples = saved_val;
+ goto end;
+ }
+ break;
+
+ case V4L2_CID_PRIVATE_IRIS_SRCH_ALGORITHM:
+ case V4L2_CID_PRIVATE_IRIS_SET_AUDIO_PATH:
+ /*
+ * These private controls are place holders to keep the
+ * driver compatible with changes done in the frameworks
+ * which are specific to TAVARUA.
+ */
+ retval = 0;
+ break;
+ case V4L2_CID_PRIVATE_SPUR_FREQ:
+ if (radio->spur_table_size >= MAX_SPUR_FREQ_LIMIT) {
+ FMDERR("%s: Spur Table Full\n", __func__);
+ retval = -1;
+ } else
+ radio->spur_data.freq[radio->spur_table_size] =
+ ctrl->value;
+ break;
+ case V4L2_CID_PRIVATE_SPUR_FREQ_RMSSI:
+ if (radio->spur_table_size >= MAX_SPUR_FREQ_LIMIT) {
+ FMDERR("%s: Spur Table Full\n", __func__);
+ retval = -1;
+ } else
+ radio->spur_data.rmssi[radio->spur_table_size] =
+ ctrl->value;
+ break;
+ case V4L2_CID_PRIVATE_SPUR_SELECTION:
+ if (radio->spur_table_size >= MAX_SPUR_FREQ_LIMIT) {
+ FMDERR("%s: Spur Table Full\n", __func__);
+ retval = -1;
+ } else {
+ radio->spur_data.enable[radio->spur_table_size] =
+ ctrl->value;
+ radio->spur_table_size++;
+ }
+ break;
+ case V4L2_CID_PRIVATE_UPDATE_SPUR_TABLE:
+ update_spur_table(radio);
+ break;
+ case V4L2_CID_PRIVATE_VALID_CHANNEL:
+ retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("%s: Failed to determine channel validity\n",
+ __func__);
+ goto end;
+ } else {
+ sinr_th = radio->ch_det_threshold.sinr;
+ intf_det_low_th = radio->ch_det_threshold.low_th;
+ intf_det_high_th = radio->ch_det_threshold.high_th;
+ }
+ if (!is_valid_sinr_th(sinr_th) ||
+ !is_valid_intf_det_low_th(intf_det_low_th) ||
+ !is_valid_intf_det_hgh_th(intf_det_high_th)) {
+ retval = -EINVAL;
+ goto end;
+ }
+ retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("%s: Failed to determine channel validity\n",
+ __func__);
+ goto end;
+ } else
+ sinr = radio->fm_st_rsp.station_rsp.sinr;
+
+ retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("%s: Failed to determine channel validity\n",
+ __func__);
+ goto end;
+ } else
+ intf_det_out = radio->st_dbg_param.in_det_out;
+
+ if ((sinr >= sinr_th) && (intf_det_out >= intf_det_low_th) &&
+ (intf_det_out <= intf_det_high_th))
+ radio->is_station_valid = VALID_CHANNEL;
+ else
+ radio->is_station_valid = INVALID_CHANNEL;
+ break;
+ case V4L2_CID_PRIVATE_AF_RMSSI_TH:
+ rd.mode = FM_RDS_CNFG_MODE;
+ rd.length = FM_RDS_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("default data read failed %x\n", retval);
+ goto end;
+ }
+ wrd.mode = FM_RDS_CNFG_MODE;
+ wrd.length = FM_RDS_CNFG_LEN;
+ memcpy(&wrd.data, &radio->default_data.data,
+ radio->default_data.ret_data_len);
+ wrd.data[AF_RMSSI_TH_LSB_OFFSET] = ((ctrl->value) & 255);
+ wrd.data[AF_RMSSI_TH_MSB_OFFSET] = ((ctrl->value) >> 8);
+ retval = hci_def_data_write(&wrd, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("set AF jump RMSSI threshold failed\n");
+ break;
+ case V4L2_CID_PRIVATE_AF_RMSSI_SAMPLES:
+ rd.mode = FM_RDS_CNFG_MODE;
+ rd.length = FM_RDS_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("default data read failed %x\n", retval);
+ goto end;
+ }
+ wrd.mode = FM_RDS_CNFG_MODE;
+ wrd.length = FM_RDS_CNFG_LEN;
+ memcpy(&wrd.data, &radio->default_data.data,
+ radio->default_data.ret_data_len);
+ wrd.data[AF_RMSSI_SAMPLES_OFFSET] = ctrl->value;
+ retval = hci_def_data_write(&wrd, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("set AF jump RMSSI Samples failed\n");
+ break;
+ case V4L2_CID_PRIVATE_GOOD_CH_RMSSI_TH:
+ rd.mode = FM_RX_CONFG_MODE;
+ rd.length = FM_RX_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("default data read failed %x\n", retval);
+ goto end;
+ }
+ wrd.mode = FM_RX_CONFG_MODE;
+ wrd.length = FM_RX_CNFG_LEN;
+ memcpy(&wrd.data, &radio->default_data.data,
+ radio->default_data.ret_data_len);
+ wrd.data[GD_CH_RMSSI_TH_OFFSET] = ctrl->value;
+ retval = hci_def_data_write(&wrd, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("set good channel RMSSI th failed\n");
+ break;
+ case V4L2_CID_PRIVATE_SRCHALGOTYPE:
+ rd.mode = FM_RX_CONFG_MODE;
+ rd.length = FM_RX_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("default data read failed %x\n", retval);
+ goto end;
+ }
+ wrd.mode = FM_RX_CONFG_MODE;
+ wrd.length = FM_RX_CNFG_LEN;
+ memcpy(&wrd.data, &radio->default_data.data,
+ radio->default_data.ret_data_len);
+ wrd.data[SRCH_ALGO_TYPE_OFFSET] = ctrl->value;
+ retval = hci_def_data_write(&wrd, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("set Search Algo Type failed\n");
+ break;
+ case V4L2_CID_PRIVATE_SINRFIRSTSTAGE:
+ rd.mode = FM_RX_CONFG_MODE;
+ rd.length = FM_RX_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("default data read failed %x\n", retval);
+ goto end;
+ }
+ wrd.mode = FM_RX_CONFG_MODE;
+ wrd.length = FM_RX_CNFG_LEN;
+ memcpy(&wrd.data, &radio->default_data.data,
+ radio->default_data.ret_data_len);
+ wrd.data[SINRFIRSTSTAGE_OFFSET] = ctrl->value;
+ retval = hci_def_data_write(&wrd, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("set SINR First Stage failed\n");
+ break;
+ case V4L2_CID_PRIVATE_RMSSIFIRSTSTAGE:
+ rd.mode = FM_RX_CONFG_MODE;
+ rd.length = FM_RX_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("default data read failed %x\n", retval);
+ goto end;
+ }
+ wrd.mode = FM_RX_CONFG_MODE;
+ wrd.length = FM_RX_CNFG_LEN;
+ memcpy(&wrd.data, &radio->default_data.data,
+ radio->default_data.ret_data_len);
+ wrd.data[RMSSIFIRSTSTAGE_OFFSET] = ctrl->value;
+ retval = hci_def_data_write(&wrd, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("set RMSSI First Stage failed\n");
+ break;
+ case V4L2_CID_PRIVATE_CF0TH12:
+ rd.mode = FM_RX_CONFG_MODE;
+ rd.length = FM_RX_CNFG_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("default data read failed %x\n", retval);
+ goto end;
+ }
+ wrd.mode = FM_RX_CONFG_MODE;
+ wrd.length = FM_RX_CNFG_LEN;
+ memcpy(&wrd.data, &radio->default_data.data,
+ radio->default_data.ret_data_len);
+ wrd.data[CF0TH12_BYTE1_OFFSET] = (ctrl->value & 255);
+ wrd.data[CF0TH12_BYTE2_OFFSET] = ((ctrl->value >> 8) & 255);
+ wrd.data[CF0TH12_BYTE3_OFFSET] = ((ctrl->value >> 16) & 255);
+ wrd.data[CF0TH12_BYTE4_OFFSET] = ((ctrl->value >> 24) & 255);
+ retval = hci_def_data_write(&wrd, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("set CF0 Threshold failed\n");
+ break;
+ case V4L2_CID_PRIVATE_RXREPEATCOUNT:
+ rd.mode = RDS_PS0_XFR_MODE;
+ rd.length = RDS_PS0_LEN;
+ rd.param_len = 0;
+ rd.param = 0;
+
+ retval = hci_def_data_read(&rd, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("default data read failed for PS0 %x\n", retval);
+ goto end;
+ }
+ wrd.mode = RDS_PS0_XFR_MODE;
+ wrd.length = RDS_PS0_LEN;
+ memcpy(&wrd.data, &radio->default_data.data,
+ radio->default_data.ret_data_len);
+ wrd.data[RX_REPEATE_BYTE_OFFSET] = ctrl->value;
+
+ retval = hci_def_data_write(&wrd, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("set RxRePeat count failed\n");
+ break;
+ case V4L2_CID_PRIVATE_IRIS_GET_SPUR_TBL:
+ spur_freq = ctrl->value;
+ retval = radio_hci_request(radio->fm_hdev,
+ hci_fm_get_spur_tbl_data,
+ (unsigned long)spur_freq,
+ RADIO_HCI_TIMEOUT);
+ if (retval < 0)
+ FMDERR("get Spur data failed\n");
+ break;
+ case V4L2_CID_PRIVATE_BLEND_SINRHI:
+ if (!is_valid_blend_value(ctrl->value)) {
+ FMDERR("%s: blend sinr count is not valid\n",
+ __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Failed to get blend table %d\n", retval);
+ goto end;
+ }
+ radio->blend_tbl.scBlendSinrHi = ctrl->value;
+ retval = hci_set_blend_tbl_req(&radio->blend_tbl,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Failed to set blend table %d\n", retval);
+ goto end;
+ }
+ break;
+ case V4L2_CID_PRIVATE_BLEND_RMSSIHI:
+ if (!is_valid_blend_value(ctrl->value)) {
+ FMDERR("%s: blend rmssi count is not valid\n",
+ __func__);
+ retval = -EINVAL;
+ goto end;
+ }
+ retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Failed to get blend table %d\n", retval);
+ goto end;
+ }
+ radio->blend_tbl.scBlendRmssiHi = ctrl->value;
+ retval = hci_set_blend_tbl_req(&radio->blend_tbl,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Failed to set blend table %d\n", retval);
+ goto end;
+ }
+ break;
+ default:
+ retval = -EINVAL;
+ break;
+ }
+
+end:
+ if (retval > 0)
+ retval = -EINVAL;
+
+ return retval;
+}
+
+static int update_spur_table(struct iris_device *radio)
+{
+ struct hci_fm_def_data_wr_req default_data;
+ int len = 0, index = 0, offset = 0, i = 0;
+ int retval = 0, temp = 0, cnt = 0;
+
+ memset(&default_data, 0, sizeof(default_data));
+
+ /* Pass the mode of SPUR_CLK */
+ default_data.mode = CKK_SPUR;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+ temp = radio->spur_table_size;
+ for (cnt = 0; cnt < (temp / 5); cnt++) {
+ offset = 0;
+ /*
+ * Program the spur entries in spur table in following order:
+ * Spur index
+ * Length of the spur data
+ * Spur Data:
+ * MSB of the spur frequency
+ * LSB of the spur frequency
+ * Enable/Disable the spur frequency
+ * RMSSI value of the spur frequency
+ */
+ default_data.data[offset++] = ENTRY_0 + cnt;
+ for (i = 0; i < SPUR_ENTRIES_PER_ID; i++) {
+ default_data.data[offset++] = GET_FREQ(COMPUTE_SPUR(
+ radio->spur_data.freq[index]), 0);
+ default_data.data[offset++] = GET_FREQ(COMPUTE_SPUR(
+ radio->spur_data.freq[index]), 1);
+ default_data.data[offset++] =
+ radio->spur_data.enable[index];
+ default_data.data[offset++] =
+ radio->spur_data.rmssi[index];
+ index++;
+ }
+ len = (SPUR_ENTRIES_PER_ID * SPUR_DATA_SIZE);
+ default_data.length = (len + 1);
+ retval = hci_def_data_write(&default_data, radio->fm_hdev);
+ if (retval < 0) {
+ FMDBG("%s: Failed to configure entries for ID : %d\n",
+ __func__, default_data.data[0]);
+ return retval;
+ }
+ }
+
+ /* Compute balance SPUR frequencies to be programmed */
+ temp %= SPUR_ENTRIES_PER_ID;
+ if (temp > 0) {
+ offset = 0;
+ default_data.data[offset++] = (radio->spur_table_size / 5);
+ for (i = 0; i < temp; i++) {
+ default_data.data[offset++] = GET_FREQ(COMPUTE_SPUR(
+ radio->spur_data.freq[index]), 0);
+ default_data.data[offset++] = GET_FREQ(COMPUTE_SPUR(
+ radio->spur_data.freq[index]), 1);
+ default_data.data[offset++] =
+ radio->spur_data.enable[index];
+ default_data.data[offset++] =
+ radio->spur_data.rmssi[index];
+ index++;
+ }
+ len = (temp * SPUR_DATA_SIZE);
+ default_data.length = (len + 1);
+ retval = hci_def_data_write(&default_data, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("%s: Failed to configure entries for ID : %d\n",
+ __func__, default_data.data[0]);
+ return retval;
+ }
+ }
+
+ return retval;
+}
+
+static int iris_vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *tuner)
+{
+ int retval;
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+ if (tuner == NULL) {
+ FMDERR("%s, tuner is null\n", __func__);
+ return -EINVAL;
+ }
+ if (tuner->index > 0) {
+ FMDERR("Invalid Tuner Index\n");
+ return -EINVAL;
+ }
+ if (radio->mode == FM_RECV) {
+ retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Failed to Get station params\n");
+ return retval;
+ }
+ tuner->type = V4L2_TUNER_RADIO;
+ tuner->rangelow =
+ radio->recv_conf.band_low_limit * TUNE_PARAM;
+ tuner->rangehigh =
+ radio->recv_conf.band_high_limit * TUNE_PARAM;
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ tuner->capability = V4L2_TUNER_CAP_LOW;
+ tuner->signal = radio->fm_st_rsp.station_rsp.rssi;
+ tuner->audmode = radio->fm_st_rsp.station_rsp.stereo_prg;
+ tuner->afc = 0;
+ } else if (radio->mode == FM_TRANS) {
+ retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("get Tx config failed %d\n", retval);
+ return retval;
+ }
+ tuner->type = V4L2_TUNER_RADIO;
+ tuner->rangelow =
+ radio->trans_conf.band_low_limit * TUNE_PARAM;
+ tuner->rangehigh =
+ radio->trans_conf.band_high_limit * TUNE_PARAM;
+ } else
+ return -EINVAL;
+ return 0;
+}
+
+static int iris_vidioc_s_tuner(struct file *file, void *priv,
+ const struct v4l2_tuner *tuner)
+{
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ int retval = 0;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+
+ if (tuner == NULL) {
+ FMDERR("%s, tuner is null\n", __func__);
+ return -EINVAL;
+ }
+
+ if (tuner->index > 0)
+ return -EINVAL;
+
+ if (radio->mode == FM_RECV) {
+ radio->recv_conf.band_low_limit = tuner->rangelow / TUNE_PARAM;
+ radio->recv_conf.band_high_limit =
+ tuner->rangehigh / TUNE_PARAM;
+ if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
+ radio->stereo_mode.stereo_mode = 0x01;
+ retval = hci_set_fm_stereo_mode(
+ &radio->stereo_mode,
+ radio->fm_hdev);
+ } else {
+ radio->stereo_mode.stereo_mode = 0x00;
+ retval = hci_set_fm_stereo_mode(
+ &radio->stereo_mode,
+ radio->fm_hdev);
+ }
+ if (retval < 0)
+ FMDERR(": set tuner failed with %d\n", retval);
+ return retval;
+ } else if (radio->mode == FM_TRANS) {
+ radio->trans_conf.band_low_limit = tuner->rangelow / TUNE_PARAM;
+ radio->trans_conf.band_high_limit =
+ tuner->rangehigh / TUNE_PARAM;
+ } else
+ return -EINVAL;
+
+ return retval;
+}
+
+static int iris_vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *freq)
+{
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+
+ if ((freq != NULL) && (radio != NULL)) {
+ freq->frequency =
+ radio->fm_st_rsp.station_rsp.station_freq * TUNE_PARAM;
+ } else
+ return -EINVAL;
+ return 0;
+}
+
+static int iris_vidioc_s_frequency(struct file *file, void *priv,
+ const struct v4l2_frequency *freq)
+{
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ int retval = -1;
+ u32 f;
+
+ if (freq == NULL) {
+ FMDERR("%s, v4l2 freq is null\n", __func__);
+ return -EINVAL;
+ }
+ f = (freq->frequency / TUNE_PARAM);
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+ if (freq->type != V4L2_TUNER_RADIO)
+ return -EINVAL;
+
+ /* We turn off RDS prior to tuning to a new station.
+ * because of a bug in SoC which prevents tuning
+ * during RDS transmission.
+ */
+ if (radio->mode == FM_TRANS
+ && (radio->trans_conf.rds_std == 0 ||
+ radio->trans_conf.rds_std == 1)) {
+ radio->prev_trans_rds = radio->trans_conf.rds_std;
+ radio->trans_conf.rds_std = 2;
+ hci_set_fm_trans_conf(&radio->trans_conf,
+ radio->fm_hdev);
+ }
+
+ retval = iris_set_freq(radio, f);
+
+ if (radio->mode == FM_TRANS
+ && radio->trans_conf.rds_std == 2
+ && (radio->prev_trans_rds == 1
+ || radio->prev_trans_rds == 0)) {
+ radio->trans_conf.rds_std = radio->prev_trans_rds;
+ hci_set_fm_trans_conf(&radio->trans_conf,
+ radio->fm_hdev);
+ }
+
+ if (retval < 0)
+ FMDERR(" set frequency failed with %d\n", retval);
+ return retval;
+}
+
+static int iris_fops_release(struct file *file)
+{
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ int retval = 0;
+
+ FMDBG("radio %pK", radio);
+
+ if (radio == NULL)
+ return -EINVAL;
+
+ FMDBG("state %d", radio->mode);
+ mutex_lock(&radio->lock);
+
+ if (radio->mode == FM_OFF)
+ goto end;
+
+ if (radio->mode == FM_RECV) {
+ radio->is_fm_closing = true;
+ radio->mode = FM_TURNING_OFF;
+ retval = hci_cmd_uninterruptible(HCI_FM_DISABLE_RECV_CMD,
+ radio->fm_hdev);
+ radio->mode = FM_OFF;
+ radio->is_fm_closing = false;
+ } else if (radio->mode == FM_TRANS) {
+ radio->is_fm_closing = true;
+ radio->mode = FM_TURNING_OFF;
+ retval = hci_cmd_uninterruptible(HCI_FM_DISABLE_TRANS_CMD,
+ radio->fm_hdev);
+ radio->mode = FM_OFF;
+ radio->is_fm_closing = false;
+ } else if (radio->mode == FM_CALIB) {
+ radio->mode = FM_OFF;
+ mutex_unlock(&radio->lock);
+ return retval;
+ }
+end:
+ FMDBG("mode %d", radio->mode);
+ mutex_lock(&fm_smd_enable);
+ if (radio->fm_hdev != NULL)
+ radio->fm_hdev->close_smd();
+ mutex_unlock(&fm_smd_enable);
+
+ mutex_unlock(&radio->lock);
+
+ if (retval < 0)
+ FMDERR("Err on disable FM %d\n", retval);
+
+ FMDBG("ret %d", retval);
+ return retval;
+}
+
+static int iris_vidioc_dqbuf(struct file *file, void *priv,
+ struct v4l2_buffer *buffer)
+{
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ enum iris_buf_t buf_type = -1;
+ unsigned char buf_fifo[STD_BUF_SIZE] = {0};
+ struct kfifo *data_fifo = NULL;
+ unsigned char *buf = NULL;
+ unsigned int len = 0, retval = -1;
+
+ FMDBG("buffer %pK", buffer);
+
+ if ((radio == NULL) || (buffer == NULL)) {
+ FMDERR("radio/buffer is NULL\n");
+ return -ENXIO;
+ }
+ buf_type = buffer->index;
+ buf = (unsigned char *)buffer->m.userptr;
+ len = buffer->length;
+
+ if ((buf_type < IRIS_BUF_MAX) && (buf_type >= 0)) {
+ data_fifo = &radio->data_buf[buf_type];
+ if (buf_type == IRIS_BUF_EVENTS)
+ if (wait_event_interruptible(radio->event_queue,
+ kfifo_len(data_fifo)) < 0)
+ return -EINTR;
+ } else {
+ FMDERR("invalid buffer type\n");
+ return -EINVAL;
+ }
+ if (len <= STD_BUF_SIZE) {
+ buffer->bytesused = kfifo_out_locked(data_fifo, &buf_fifo[0],
+ len, &radio->buf_lock[buf_type]);
+ } else {
+ FMDERR("kfifo_out_locked can not use len more than 128\n");
+ return -EINVAL;
+ }
+ retval = copy_to_user(buf, &buf_fifo[0], buffer->bytesused);
+ if (retval > 0) {
+ FMDERR("Failed to copy %d bytes of data\n", retval);
+ return -EAGAIN;
+ }
+
+ return retval;
+}
+
+static int iris_vidioc_g_fmt_type_private(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ return 0;
+
+}
+
+static int iris_vidioc_s_hw_freq_seek(struct file *file, void *priv,
+ const struct v4l2_hw_freq_seek *seek)
+{
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ int dir;
+
+ if (seek == NULL) {
+ FMDERR("%s, v4l2_hw_freq_seek is null\n", __func__);
+ return -EINVAL;
+ }
+ if (seek->seek_upward)
+ dir = SRCH_DIR_UP;
+ else
+ dir = SRCH_DIR_DOWN;
+ return iris_search(radio, CTRL_ON, dir);
+}
+
+static int iris_vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *capability)
+{
+ struct iris_device *radio;
+
+ FMDBG("caps %pK", capability);
+
+ radio = video_get_drvdata(video_devdata(file));
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+ if (capability == NULL) {
+ FMDERR("%s, capability struct is null\n", __func__);
+ return -EINVAL;
+ }
+ strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
+ strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
+
+ strlcpy(radio->g_cap.driver, DRIVER_NAME, sizeof(radio->g_cap.driver));
+ strlcpy(radio->g_cap.card, DRIVER_CARD, sizeof(radio->g_cap.card));
+
+ radio->g_cap.capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ capability->capabilities = radio->g_cap.capabilities;
+ return 0;
+}
+
+static int initialise_recv(struct iris_device *radio)
+{
+ int retval;
+
+ FMDBG("radio %pK", radio);
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+
+ radio->mute_mode.soft_mute = CTRL_ON;
+ retval = hci_set_fm_mute_mode(&radio->mute_mode,
+ radio->fm_hdev);
+
+ if (retval < 0) {
+ FMDERR("Failed to enable Smute\n");
+ return retval;
+ }
+
+ radio->stereo_mode.stereo_mode = CTRL_OFF;
+ radio->stereo_mode.sig_blend = sig_blend;
+ radio->stereo_mode.intf_blend = CTRL_ON;
+ radio->stereo_mode.most_switch = CTRL_ON;
+ retval = hci_set_fm_stereo_mode(&radio->stereo_mode,
+ radio->fm_hdev);
+
+ if (retval < 0) {
+ FMDERR("Failed to set stereo mode\n");
+ return retval;
+ }
+
+ radio->event_mask = SIG_LEVEL_INTR | RDS_SYNC_INTR | AUDIO_CTRL_INTR;
+ retval = hci_conf_event_mask(&radio->event_mask, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Enable Async events failed\n");
+ return retval;
+ }
+
+ retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("Failed to get the Recv Config\n");
+ return retval;
+}
+
+static int initialise_trans(struct iris_device *radio)
+{
+
+ int retval;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null");
+ return -EINVAL;
+ }
+
+ retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("get frequency failed %d\n", retval);
+
+ return retval;
+}
+
+static int is_enable_rx_possible(struct iris_device *radio)
+{
+ int retval = 1;
+
+ if (unlikely(radio == NULL)) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+
+ if (radio->mode == FM_OFF || radio->mode == FM_RECV)
+ retval = 0;
+
+ return retval;
+}
+
+static int is_enable_tx_possible(struct iris_device *radio)
+{
+ int retval = 1;
+
+ if (radio->mode == FM_OFF || radio->mode == FM_TRANS)
+ retval = 0;
+
+ return retval;
+}
+
+static const struct v4l2_ioctl_ops iris_ioctl_ops = {
+ .vidioc_querycap = iris_vidioc_querycap,
+ .vidioc_queryctrl = iris_vidioc_queryctrl,
+ .vidioc_g_ctrl = iris_vidioc_g_ctrl,
+ .vidioc_s_ctrl = iris_vidioc_s_ctrl,
+ .vidioc_g_tuner = iris_vidioc_g_tuner,
+ .vidioc_s_tuner = iris_vidioc_s_tuner,
+ .vidioc_g_frequency = iris_vidioc_g_frequency,
+ .vidioc_s_frequency = iris_vidioc_s_frequency,
+ .vidioc_s_hw_freq_seek = iris_vidioc_s_hw_freq_seek,
+ .vidioc_dqbuf = iris_vidioc_dqbuf,
+ .vidioc_g_fmt_type_private = iris_vidioc_g_fmt_type_private,
+ .vidioc_s_ext_ctrls = iris_vidioc_s_ext_ctrls,
+ .vidioc_g_ext_ctrls = iris_vidioc_g_ext_ctrls,
+};
+
+static const struct v4l2_file_operations iris_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = video_ioctl2,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl32 = v4l2_compat_ioctl32,
+#endif
+ .release = iris_fops_release,
+};
+
+static struct video_device iris_viddev_template = {
+ .fops = &iris_fops,
+ .ioctl_ops = &iris_ioctl_ops,
+ .name = DRIVER_NAME,
+ .release = video_device_release,
+};
+
+static struct video_device *video_get_dev(void)
+{
+ return priv_videodev;
+}
+
+static int iris_probe(struct platform_device *pdev)
+{
+ struct iris_device *radio;
+ int retval;
+ int radio_nr = -1;
+ int i;
+
+ FMDBG("pdev %pK", pdev);
+
+ if (!pdev) {
+ FMDERR(": pdev is null\n");
+ return -ENOMEM;
+ }
+
+ radio = kzalloc(sizeof(struct iris_device), GFP_KERNEL);
+ if (!radio)
+ return -ENOMEM;
+
+ radio->dev = &pdev->dev;
+ platform_set_drvdata(pdev, radio);
+
+ radio->videodev = video_device_alloc();
+ if (!radio->videodev) {
+ kfree(radio);
+ return -ENOMEM;
+ }
+
+ memcpy(radio->videodev, &iris_viddev_template,
+ sizeof(iris_viddev_template));
+ strlcpy(radio->v4l2_dev.name, DRIVER_NAME,
+ sizeof(radio->v4l2_dev.name));
+ retval = v4l2_device_register(NULL, &radio->v4l2_dev);
+ if (retval)
+ return -EINVAL;
+ radio->videodev->v4l2_dev = &radio->v4l2_dev;
+
+ for (i = 0; i < IRIS_BUF_MAX; i++) {
+ int kfifo_alloc_rc = 0;
+
+ spin_lock_init(&radio->buf_lock[i]);
+
+ if ((i == IRIS_BUF_RAW_RDS) || (i == IRIS_BUF_PEEK))
+ kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
+ rds_buf*3, GFP_KERNEL);
+ else if ((i == IRIS_BUF_CAL_DATA) || (i == IRIS_BUF_RT_RDS))
+ kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
+ STD_BUF_SIZE*2, GFP_KERNEL);
+ else
+ kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
+ STD_BUF_SIZE, GFP_KERNEL);
+
+ if (kfifo_alloc_rc != 0) {
+ FMDERR("failed allocating buffers %d\n",
+ kfifo_alloc_rc);
+ for (; i > -1; i--)
+ kfifo_free(&radio->data_buf[i]);
+ video_device_release(radio->videodev);
+ kfree(radio);
+ return -ENOMEM;
+ }
+ }
+
+ mutex_init(&radio->lock);
+ init_completion(&radio->sync_xfr_start);
+ radio->tune_req = 0;
+ radio->prev_trans_rds = 2;
+ radio->is_fm_closing = false;
+ init_waitqueue_head(&radio->event_queue);
+ init_waitqueue_head(&radio->read_queue);
+
+ video_set_drvdata(radio->videodev, radio);
+
+ if (video_get_drvdata(radio->videodev) == NULL)
+ FMDERR(": video_get_drvdata failed\n");
+
+ retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
+ radio_nr);
+ if (retval) {
+ FMDERR(": Could not register video device\n");
+ video_device_release(radio->videodev);
+ for (; i > -1; i--)
+ kfifo_free(&radio->data_buf[i]);
+ kfree(radio);
+ return retval;
+ }
+ priv_videodev = kzalloc(sizeof(struct video_device),
+ GFP_KERNEL);
+ if (priv_videodev != NULL) {
+ memcpy(priv_videodev, radio->videodev,
+ sizeof(struct video_device));
+ } else {
+ video_unregister_device(radio->videodev);
+ video_device_release(radio->videodev);
+ for (; i > -1; i--)
+ kfifo_free(&radio->data_buf[i]);
+ kfree(radio);
+ }
+ return 0;
+}
+
+
+static int iris_remove(struct platform_device *pdev)
+{
+ int i;
+ struct iris_device *radio = platform_get_drvdata(pdev);
+
+ if (radio == NULL) {
+ FMDERR(":radio is null\n");
+ return -EINVAL;
+ }
+ video_unregister_device(radio->videodev);
+
+ for (i = 0; i < IRIS_BUF_MAX; i++)
+ kfifo_free(&radio->data_buf[i]);
+
+ kfree(radio);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id iris_fm_match[] = {
+ {.compatible = "qcom,iris_fm"},
+ {}
+};
+
+static struct platform_driver iris_driver = {
+ .probe = iris_probe,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "iris_fm",
+ .of_match_table = iris_fm_match,
+ },
+ .remove = iris_remove,
+};
+
+static int __init iris_radio_init(void)
+{
+ return platform_driver_register(&iris_driver);
+}
+module_init(iris_radio_init);
+
+static void __exit iris_radio_exit(void)
+{
+ platform_driver_unregister(&iris_driver);
+}
+module_exit(iris_radio_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 8be561a..9f98e4d 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -710,7 +710,11 @@
SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings);
SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap);
SET_VALID_IOCTL(ops, VIDIOC_G_EDID, vidioc_g_edid);
+ } else {
+ /* ioctls valid for radio */
+ SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
}
+
if (is_tx && (is_radio || is_sdr)) {
/* radio transmitter only ioctls */
SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index e2e23ff..d4ee140 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -982,6 +982,9 @@
if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
return 0;
break;
+ case V4L2_BUF_TYPE_PRIVATE:
+ if (ops->vidioc_g_fmt_type_private)
+ return 0;
default:
break;
}
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 831b64d..47094d5 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -158,6 +158,8 @@
#define DDR_CONFIG_PRG_RCLK_DLY_MASK 0x1FF
#define DDR_CONFIG_PRG_RCLK_DLY 115
#define DDR_CONFIG_2_POR_VAL 0x80040873
+#define DLL_USR_CTL_POR_VAL 0x10800
+#define ENABLE_DLL_LOCK_STATUS (1 << 26)
/* 512 descriptors */
#define SDHCI_MSM_MAX_SEGMENTS (1 << 9)
@@ -200,6 +202,7 @@
u32 CORE_DLL_CONFIG_2;
u32 CORE_DDR_CONFIG;
u32 CORE_DDR_CONFIG_2;
+ u32 CORE_DLL_USR_CTL; /* Present on SDCC5.1 onwards */
};
struct sdhci_msm_offset sdhci_msm_offset_mci_removed = {
@@ -229,6 +232,7 @@
.CORE_DLL_CONFIG_2 = 0x254,
.CORE_DDR_CONFIG = 0x258,
.CORE_DDR_CONFIG_2 = 0x25C,
+ .CORE_DLL_USR_CTL = 0x388,
};
struct sdhci_msm_offset sdhci_msm_offset_mci_present = {
@@ -795,6 +799,15 @@
msm_host_offset->CORE_DLL_CONFIG_2);
}
+ /*
+ * Configure DLL user control register to enable DLL status
+ * This setting is applicable to SDCC v5.1 onwards only
+ */
+ if (msm_host->need_dll_user_ctl) {
+ writel_relaxed(DLL_USR_CTL_POR_VAL | ENABLE_DLL_LOCK_STATUS,
+ host->ioaddr + msm_host_offset->CORE_DLL_USR_CTL);
+ }
+
/* Set DLL_EN bit to 1. */
writel_relaxed((readl_relaxed(host->ioaddr +
msm_host_offset->CORE_DLL_CONFIG) | CORE_DLL_EN),
@@ -4563,6 +4576,10 @@
msm_host->ice_hci_support = true;
host->cdr_support = true;
}
+
+ if ((major == 1) && (minor >= 0x71))
+ msm_host->need_dll_user_ctl = true;
+
}
#ifdef CONFIG_MMC_CQ_HCI
diff --git a/drivers/mmc/host/sdhci-msm.h b/drivers/mmc/host/sdhci-msm.h
index 1888945..27c4f23 100644
--- a/drivers/mmc/host/sdhci-msm.h
+++ b/drivers/mmc/host/sdhci-msm.h
@@ -257,6 +257,7 @@
struct sdhci_msm_regs_restore regs_restore;
int soc_min_rev;
struct workqueue_struct *pm_qos_wq;
+ bool need_dll_user_ctl;
};
extern char *saved_command_line;
diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c
index 90be113..795b905 100644
--- a/drivers/net/wireless/cnss2/pci.c
+++ b/drivers/net/wireless/cnss2/pci.c
@@ -865,13 +865,15 @@
goto out;
}
- num_vectors = pci_enable_msi_range(pci_dev,
- msi_config->total_vectors,
- msi_config->total_vectors);
+ num_vectors = pci_alloc_irq_vectors(pci_dev,
+ msi_config->total_vectors,
+ msi_config->total_vectors,
+ PCI_IRQ_MSI);
if (num_vectors != msi_config->total_vectors) {
cnss_pr_err("Failed to get enough MSI vectors (%d), available vectors = %d",
msi_config->total_vectors, num_vectors);
- ret = -EINVAL;
+ if (num_vectors >= 0)
+ ret = -EINVAL;
goto reset_msi_config;
}
@@ -879,7 +881,7 @@
if (!msi_desc) {
cnss_pr_err("msi_desc is NULL!\n");
ret = -EINVAL;
- goto disable_msi;
+ goto free_msi_vector;
}
pci_priv->msi_ep_base_data = msi_desc->msg.data;
@@ -892,8 +894,8 @@
return 0;
-disable_msi:
- pci_disable_msi(pci_priv->pci_dev);
+free_msi_vector:
+ pci_free_irq_vectors(pci_priv->pci_dev);
reset_msi_config:
pci_priv->msi_config = NULL;
out:
@@ -902,7 +904,7 @@
static void cnss_pci_disable_msi(struct cnss_pci_data *pci_priv)
{
- pci_disable_msi(pci_priv->pci_dev);
+ pci_free_irq_vectors(pci_priv->pci_dev);
}
int cnss_get_user_msi_assignment(struct device *dev, char *user_name,
@@ -946,8 +948,12 @@
int cnss_get_msi_irq(struct device *dev, unsigned int vector)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
+ int irq_num;
- return pci_dev->irq + vector;
+ irq_num = pci_irq_vector(pci_dev, vector);
+ cnss_pr_dbg("Get IRQ number %d for vector index %d\n", irq_num, vector);
+
+ return irq_num;
}
EXPORT_SYMBOL(cnss_get_msi_irq);
diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig
index 782ce62..5b34bbcd 100644
--- a/drivers/platform/msm/Kconfig
+++ b/drivers/platform/msm/Kconfig
@@ -47,6 +47,16 @@
Kernel and user-space processes can call the IPA driver
to configure IPA core.
+config IPA_WDI_UNIFIED_API
+ bool "IPA WDI unified API support"
+ depends on IPA3
+ help
+ This driver supports IPA WDI unified API.
+ WDI is the interface between IPA micro controller and WLAN chipset.
+ It is designed to support IPA HW accelerating path for WLAN use case.
+ The IPA WDI unified API supports all WDI versions through a unified
+ interface.
+
config RMNET_IPA3
tristate "IPA3 RMNET WWAN Network Device"
depends on IPA3 && MSM_QMI_INTERFACE
@@ -214,4 +224,14 @@
External Display driver was added to support the communication
between external display driver and its counterparts.
+config MSM_RMNET_BAM
+ bool "RMNET BAM Driver"
+ depends on MSM_BAM_DMUX
+ default n
+ help
+ Implements RMNET over BAM interface.
+ RMNET provides a virtual ethernet interface
+ for routing IP packets within the MSM using
+ BAM as a physical transport.
+
endmenu
diff --git a/drivers/platform/msm/Makefile b/drivers/platform/msm/Makefile
index d0f0216f..06ff2ca 100644
--- a/drivers/platform/msm/Makefile
+++ b/drivers/platform/msm/Makefile
@@ -7,6 +7,7 @@
obj-$(CONFIG_SPS) += sps/
obj-$(CONFIG_QPNP_COINCELL) += qpnp-coincell.o
obj-$(CONFIG_QPNP_REVID) += qpnp-revid.o
+obj-$(CONFIG_MSM_RMNET_BAM) += msm_rmnet_bam.o
obj-$(CONFIG_GPIO_USB_DETECT) += gpio-usbdetect.o
obj-$(CONFIG_EP_PCIE) += ep_pcie/
obj-$(CONFIG_MSM_MHI_DEV) += mhi_dev/
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 754c1f4..62bb8f9 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -269,6 +269,9 @@
ipa3_transport_release_resource);
static void ipa_gsi_notify_cb(struct gsi_per_notify *notify);
+static int ipa3_attach_to_smmu(void);
+static int ipa3_alloc_pkt_init(void);
+
static void ipa3_load_ipa_fw(struct work_struct *work);
static DECLARE_WORK(ipa3_fw_loading_work, ipa3_load_ipa_fw);
@@ -277,15 +280,12 @@
ipa_dec_clients_disable_clks_on_wq);
static struct ipa3_plat_drv_res ipa3_res = {0, };
-struct msm_bus_scale_pdata *ipa3_bus_scale_table;
static struct clk *ipa3_clk;
struct ipa3_context *ipa3_ctx;
-static struct device *master_dev;
-struct platform_device *ipa3_pdev;
static struct {
- bool present;
+ bool present[IPA_SMMU_CB_MAX];
bool arm_smmu;
bool fast_map;
bool s1_bypass_arr[IPA_SMMU_CB_MAX];
@@ -508,42 +508,19 @@
}
/**
- * ipa3_get_smmu_ctx()- Return the wlan smmu context
+ * ipa3_get_smmu_ctx()- Return smmu context for the given cb_type
*
* Return value: pointer to smmu context address
*/
-struct ipa_smmu_cb_ctx *ipa3_get_smmu_ctx(void)
+struct ipa_smmu_cb_ctx *ipa3_get_smmu_ctx(enum ipa_smmu_cb_type cb_type)
{
- return &smmu_cb[IPA_SMMU_CB_AP];
-}
-
-/**
- * ipa3_get_wlan_smmu_ctx()- Return the wlan smmu context
- *
- * Return value: pointer to smmu context address
- */
-struct ipa_smmu_cb_ctx *ipa3_get_wlan_smmu_ctx(void)
-{
- return &smmu_cb[IPA_SMMU_CB_WLAN];
-}
-
-/**
- * ipa3_get_uc_smmu_ctx()- Return the uc smmu context
- *
- * Return value: pointer to smmu context address
- */
-struct ipa_smmu_cb_ctx *ipa3_get_uc_smmu_ctx(void)
-{
- return &smmu_cb[IPA_SMMU_CB_UC];
+ return &smmu_cb[cb_type];
}
static int ipa3_open(struct inode *inode, struct file *filp)
{
- struct ipa3_context *ctx = NULL;
-
IPADBG_LOW("ENTER\n");
- ctx = container_of(inode->i_cdev, struct ipa3_context, cdev);
- filp->private_data = ctx;
+ filp->private_data = ipa3_ctx;
return 0;
}
@@ -3509,6 +3486,11 @@
*/
void ipa3_enable_clks(void)
{
+ if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_NORMAL) {
+ IPAERR("not supported in this mode\n");
+ return;
+ }
+
IPADBG("enabling IPA clocks and bus voting\n");
if (msm_bus_scale_client_update_request(ipa3_ctx->ipa_bus_hdl,
@@ -3540,6 +3522,11 @@
*/
void ipa3_disable_clks(void)
{
+ if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_NORMAL) {
+ IPAERR("not supported in this mode\n");
+ return;
+ }
+
IPADBG("disabling IPA clocks and bus voting\n");
ipa3_ctx->ctrl->ipa3_disable_clks();
@@ -3870,6 +3857,11 @@
if (!ipa3_ctx->enable_clock_scaling)
return 0;
+ if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_NORMAL) {
+ IPAERR("not supported in this mode\n");
+ return 0;
+ }
+
IPADBG_LOW("idx = %d\n", idx);
if (idx <= 0 || idx >= ipa3_ctx->ctrl->msm_bus_data_ptr->num_usecases) {
@@ -3921,6 +3913,11 @@
enum ipa_voltage_level needed_voltage;
u32 clk_rate;
+ if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_NORMAL) {
+ IPAERR("not supported in this mode\n");
+ return 0;
+ }
+
IPADBG_LOW("floor_voltage=%d, bandwidth_mbps=%u",
floor_voltage, bandwidth_mbps);
@@ -4177,7 +4174,7 @@
/*register IPA IRQ handler*/
result = ipa3_interrupts_init(ipa3_res.ipa_irq, 0,
- master_dev);
+ &ipa3_ctx->master_pdev->dev);
if (result) {
IPAERR("ipa interrupts initialization failed\n");
return -ENODEV;
@@ -4195,7 +4192,7 @@
return 0;
fail_add_interrupt_handler:
- free_irq(ipa3_res.ipa_irq, master_dev);
+ free_irq(ipa3_res.ipa_irq, &ipa3_ctx->master_pdev->dev);
return result;
}
@@ -4411,6 +4408,78 @@
if (ipa3_ctx->ipa_hw_type != IPA_HW_v4_0)
ipa3_proxy_clk_vote();
+ /* SMMU was already attached if used, safe to do allocations */
+ if (ipahal_init(ipa3_ctx->ipa_hw_type, ipa3_ctx->mmio,
+ ipa3_ctx->pdev)) {
+ IPAERR("fail to init ipahal\n");
+ result = -EFAULT;
+ goto fail_ipahal;
+ }
+
+ result = ipa3_init_hw();
+ if (result) {
+ IPAERR(":error initializing HW\n");
+ result = -ENODEV;
+ goto fail_init_hw;
+ }
+ IPADBG("IPA HW initialization sequence completed");
+
+ ipa3_ctx->ipa_num_pipes = ipa3_get_num_pipes();
+ if (ipa3_ctx->ipa_num_pipes > IPA3_MAX_NUM_PIPES) {
+ IPAERR("IPA has more pipes then supported has %d, max %d\n",
+ ipa3_ctx->ipa_num_pipes, IPA3_MAX_NUM_PIPES);
+ result = -ENODEV;
+ goto fail_init_hw;
+ }
+
+ ipa3_ctx->ctrl->ipa_sram_read_settings();
+ IPADBG("SRAM, size: 0x%x, restricted bytes: 0x%x\n",
+ ipa3_ctx->smem_sz, ipa3_ctx->smem_restricted_bytes);
+
+ IPADBG("hdr_lcl=%u ip4_rt_hash=%u ip4_rt_nonhash=%u\n",
+ ipa3_ctx->hdr_tbl_lcl, ipa3_ctx->ip4_rt_tbl_hash_lcl,
+ ipa3_ctx->ip4_rt_tbl_nhash_lcl);
+
+ IPADBG("ip6_rt_hash=%u ip6_rt_nonhash=%u\n",
+ ipa3_ctx->ip6_rt_tbl_hash_lcl, ipa3_ctx->ip6_rt_tbl_nhash_lcl);
+
+ IPADBG("ip4_flt_hash=%u ip4_flt_nonhash=%u\n",
+ ipa3_ctx->ip4_flt_tbl_hash_lcl,
+ ipa3_ctx->ip4_flt_tbl_nhash_lcl);
+
+ IPADBG("ip6_flt_hash=%u ip6_flt_nonhash=%u\n",
+ ipa3_ctx->ip6_flt_tbl_hash_lcl,
+ ipa3_ctx->ip6_flt_tbl_nhash_lcl);
+
+ if (ipa3_ctx->smem_reqd_sz > ipa3_ctx->smem_sz) {
+ IPAERR("SW expect more core memory, needed %d, avail %d\n",
+ ipa3_ctx->smem_reqd_sz, ipa3_ctx->smem_sz);
+ result = -ENOMEM;
+ goto fail_init_hw;
+ }
+
+ result = ipa3_allocate_dma_task_for_gsi();
+ if (result) {
+ IPAERR("failed to allocate dma task\n");
+ goto fail_dma_task;
+ }
+
+ if (ipa3_nat_ipv6ct_init_devices()) {
+ IPAERR("unable to init NAT and IPv6CT devices\n");
+ result = -ENODEV;
+ goto fail_nat_ipv6ct_init_dev;
+ }
+
+ result = ipa3_alloc_pkt_init();
+ if (result) {
+ IPAERR("Failed to alloc pkt_init payload\n");
+ result = -ENODEV;
+ goto fail_allok_pkt_init;
+ }
+
+ if (ipa3_ctx->ipa_hw_type >= IPA_HW_v3_5)
+ ipa3_enable_dcd();
+
/*
* indication whether working in MHI config or non MHI config is given
* in ipa3_write which is launched before ipa3_post_init. i.e. from
@@ -4563,6 +4632,15 @@
fail_register_device:
ipa3_destroy_flt_tbl_idrs();
ipa3_proxy_clk_unvote();
+fail_allok_pkt_init:
+ ipa3_nat_ipv6ct_destroy_devices();
+fail_nat_ipv6ct_init_dev:
+ ipa3_free_dma_task_for_gsi();
+fail_dma_task:
+fail_init_hw:
+ ipahal_destroy();
+fail_ipahal:
+
return result;
}
@@ -4573,7 +4651,7 @@
IPADBG("Manual FW loading process initiated\n");
- result = request_firmware(&fw, IPA_FWS_PATH, ipa3_ctx->dev);
+ result = request_firmware(&fw, IPA_FWS_PATH, ipa3_ctx->cdev.dev);
if (result < 0) {
IPAERR("request_firmware failed, error %d\n", result);
return result;
@@ -4629,6 +4707,12 @@
IPADBG("Entry\n");
+ result = ipa3_attach_to_smmu();
+ if (result) {
+ IPAERR("IPA attach to smmu failed %d\n", result);
+ return;
+ }
+
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
if (ipa3_is_msm_device() || (ipa3_ctx->ipa_hw_type >= IPA_HW_v3_5))
@@ -4644,7 +4728,7 @@
}
pr_info("IPA FW loaded successfully\n");
- result = ipa3_post_init(&ipa3_res, ipa3_ctx->dev);
+ result = ipa3_post_init(&ipa3_res, ipa3_ctx->cdev.dev);
if (result)
IPAERR("IPA post init failed %d\n", result);
}
@@ -4867,12 +4951,13 @@
* Configure GSI registers (in GSI case)
*/
static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
- struct device *ipa_dev)
+ struct platform_device *ipa_pdev)
{
int result = 0;
int i;
struct ipa3_rt_tbl_set *rset;
struct ipa_active_client_logging_info log_info;
+ struct cdev *cdev;
IPADBG("IPA Driver initialization started\n");
@@ -4887,8 +4972,8 @@
if (ipa3_ctx->logbuf == NULL)
IPAERR("failed to create IPC log, continue...\n");
- ipa3_ctx->pdev = ipa_dev;
- ipa3_ctx->uc_pdev = ipa_dev;
+ /* ipa3_ctx->pdev and ipa3_ctx->uc_pdev will be set in the smmu probes*/
+ ipa3_ctx->master_pdev = ipa_pdev;
ipa3_ctx->smmu_present = smmu_info.present;
if (!ipa3_ctx->smmu_present) {
for (i = 0; i < IPA_SMMU_CB_MAX; i++)
@@ -4917,6 +5002,10 @@
ipa3_ctx->ipa3_active_clients_logging.log_rdy = false;
ipa3_ctx->mhi_evid_limits[0] = resource_p->mhi_evid_limits[0];
ipa3_ctx->mhi_evid_limits[1] = resource_p->mhi_evid_limits[1];
+
+ WARN(ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_NORMAL,
+ "Non NORMAL IPA HW mode, is this emulation platform ?");
+
if (resource_p->ipa_tz_unlock_reg) {
ipa3_ctx->ipa_tz_unlock_reg_num =
resource_p->ipa_tz_unlock_reg_num;
@@ -4961,31 +5050,36 @@
goto fail_bind;
}
- result = ipa3_init_mem_partition(master_dev->of_node);
+ result = ipa3_init_mem_partition(ipa3_ctx->master_pdev->dev.of_node);
if (result) {
IPAERR(":ipa3_init_mem_partition failed!\n");
result = -ENODEV;
goto fail_init_mem_partition;
}
- if (ipa3_bus_scale_table) {
+ if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_VIRTUAL) {
+ ipa3_ctx->ctrl->msm_bus_data_ptr =
+ msm_bus_cl_get_pdata(ipa3_ctx->master_pdev);
+ if (ipa3_ctx->ctrl->msm_bus_data_ptr == NULL) {
+ IPAERR("failed to get bus scaling\n");
+ goto fail_bus_reg;
+ }
IPADBG("Use bus scaling info from device tree #usecases=%d\n",
- ipa3_bus_scale_table->num_usecases);
- ipa3_ctx->ctrl->msm_bus_data_ptr = ipa3_bus_scale_table;
- }
+ ipa3_ctx->ctrl->msm_bus_data_ptr->num_usecases);
- /* get BUS handle */
- ipa3_ctx->ipa_bus_hdl =
- msm_bus_scale_register_client(
- ipa3_ctx->ctrl->msm_bus_data_ptr);
- if (!ipa3_ctx->ipa_bus_hdl) {
- IPAERR("fail to register with bus mgr!\n");
- result = -ENODEV;
- goto fail_bus_reg;
+ /* get BUS handle */
+ ipa3_ctx->ipa_bus_hdl =
+ msm_bus_scale_register_client(
+ ipa3_ctx->ctrl->msm_bus_data_ptr);
+ if (!ipa3_ctx->ipa_bus_hdl) {
+ IPAERR("fail to register with bus mgr!\n");
+ result = -ENODEV;
+ goto fail_bus_reg;
+ }
}
/* get IPA clocks */
- result = ipa3_get_clks(master_dev);
+ result = ipa3_get_clks(&ipa3_ctx->master_pdev->dev);
if (result)
goto fail_clk;
@@ -5013,55 +5107,6 @@
goto fail_remap;
}
- if (ipahal_init(ipa3_ctx->ipa_hw_type, ipa3_ctx->mmio,
- ipa3_ctx->pdev)) {
- IPAERR("fail to init ipahal\n");
- result = -EFAULT;
- goto fail_ipahal;
- }
-
- result = ipa3_init_hw();
- if (result) {
- IPAERR(":error initializing HW.\n");
- result = -ENODEV;
- goto fail_init_hw;
- }
- IPADBG("IPA HW initialization sequence completed");
-
- ipa3_ctx->ipa_num_pipes = ipa3_get_num_pipes();
- if (ipa3_ctx->ipa_num_pipes > IPA3_MAX_NUM_PIPES) {
- IPAERR("IPA has more pipes then supported! has %d, max %d\n",
- ipa3_ctx->ipa_num_pipes, IPA3_MAX_NUM_PIPES);
- result = -ENODEV;
- goto fail_init_hw;
- }
-
- ipa3_ctx->ctrl->ipa_sram_read_settings();
- IPADBG("SRAM, size: 0x%x, restricted bytes: 0x%x\n",
- ipa3_ctx->smem_sz, ipa3_ctx->smem_restricted_bytes);
-
- IPADBG("hdr_lcl=%u ip4_rt_hash=%u ip4_rt_nonhash=%u\n",
- ipa3_ctx->hdr_tbl_lcl, ipa3_ctx->ip4_rt_tbl_hash_lcl,
- ipa3_ctx->ip4_rt_tbl_nhash_lcl);
-
- IPADBG("ip6_rt_hash=%u ip6_rt_nonhash=%u\n",
- ipa3_ctx->ip6_rt_tbl_hash_lcl, ipa3_ctx->ip6_rt_tbl_nhash_lcl);
-
- IPADBG("ip4_flt_hash=%u ip4_flt_nonhash=%u\n",
- ipa3_ctx->ip4_flt_tbl_hash_lcl,
- ipa3_ctx->ip4_flt_tbl_nhash_lcl);
-
- IPADBG("ip6_flt_hash=%u ip6_flt_nonhash=%u\n",
- ipa3_ctx->ip6_flt_tbl_hash_lcl,
- ipa3_ctx->ip6_flt_tbl_nhash_lcl);
-
- if (ipa3_ctx->smem_reqd_sz > ipa3_ctx->smem_sz) {
- IPAERR("SW expect more core memory, needed %d, avail %d\n",
- ipa3_ctx->smem_reqd_sz, ipa3_ctx->smem_sz);
- result = -ENOMEM;
- goto fail_init_hw;
- }
-
mutex_init(&ipa3_ctx->ipa3_active_clients.mutex);
IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log_info, "PROXY_CLK_VOTE");
@@ -5160,13 +5205,6 @@
goto fail_rx_pkt_wrapper_cache;
}
- /* allocate memory for DMA_TASK workaround */
- result = ipa3_allocate_dma_task_for_gsi();
- if (result) {
- IPAERR("failed to allocate dma task\n");
- goto fail_dma_task;
- }
-
/* init the various list heads */
INIT_LIST_HEAD(&ipa3_ctx->hdr_tbl.head_hdr_entry_list);
for (i = 0; i < IPA_HDR_BIN_MAX; i++) {
@@ -5210,29 +5248,23 @@
spin_lock_init(&ipa3_ctx->wc_memb.ipa_tx_mul_spinlock);
INIT_LIST_HEAD(&ipa3_ctx->wc_memb.wlan_comm_desc_list);
- ipa3_ctx->class = class_create(THIS_MODULE, DRV_NAME);
+ ipa3_ctx->cdev.class = class_create(THIS_MODULE, DRV_NAME);
- result = alloc_chrdev_region(&ipa3_ctx->dev_num, 0, 1, DRV_NAME);
+ result = alloc_chrdev_region(&ipa3_ctx->cdev.dev_num, 0, 1, DRV_NAME);
if (result) {
IPAERR("alloc_chrdev_region err.\n");
result = -ENODEV;
goto fail_alloc_chrdev_region;
}
- ipa3_ctx->dev = device_create(ipa3_ctx->class, NULL, ipa3_ctx->dev_num,
- ipa3_ctx, DRV_NAME);
- if (IS_ERR(ipa3_ctx->dev)) {
+ ipa3_ctx->cdev.dev = device_create(ipa3_ctx->cdev.class, NULL,
+ ipa3_ctx->cdev.dev_num, ipa3_ctx, DRV_NAME);
+ if (IS_ERR(ipa3_ctx->cdev.dev)) {
IPAERR(":device_create err.\n");
result = -ENODEV;
goto fail_device_create;
}
- if (ipa3_nat_ipv6ct_init_devices()) {
- IPAERR("unable to init NAT and IPv6CT devices\n");
- result = -ENODEV;
- goto fail_nat_ipv6ct_init_dev;
- }
-
/* Create a wakeup source. */
wakeup_source_init(&ipa3_ctx->w_lock, "IPA_WS");
spin_lock_init(&ipa3_ctx->wakelock_ref_cnt.spinlock);
@@ -5263,16 +5295,6 @@
}
}
- result = ipa3_alloc_pkt_init();
- if (result) {
- IPAERR("Failed to alloc pkt_init payload\n");
- result = -ENODEV;
- goto fail_allok_pkt_init;
- }
-
- if (ipa3_ctx->ipa_hw_type >= IPA_HW_v3_5)
- ipa3_enable_dcd();
-
INIT_LIST_HEAD(&ipa3_ctx->ipa_ready_cb_list);
init_completion(&ipa3_ctx->init_completion_obj);
@@ -5301,19 +5323,20 @@
}
}
- cdev_init(&ipa3_ctx->cdev, &ipa3_drv_fops);
- ipa3_ctx->cdev.owner = THIS_MODULE;
- ipa3_ctx->cdev.ops = &ipa3_drv_fops; /* from LDD3 */
+ cdev = &ipa3_ctx->cdev.cdev;
+ cdev_init(cdev, &ipa3_drv_fops);
+ cdev->owner = THIS_MODULE;
+ cdev->ops = &ipa3_drv_fops; /* from LDD3 */
- result = cdev_add(&ipa3_ctx->cdev, ipa3_ctx->dev_num, 1);
+ result = cdev_add(cdev, ipa3_ctx->cdev.dev_num, 1);
if (result) {
IPAERR(":cdev_add err=%d\n", -result);
result = -ENODEV;
goto fail_cdev_add;
}
IPADBG("ipa cdev added successful. major:%d minor:%d\n",
- MAJOR(ipa3_ctx->dev_num),
- MINOR(ipa3_ctx->dev_num));
+ MAJOR(ipa3_ctx->cdev.dev_num),
+ MINOR(ipa3_ctx->cdev.dev_num));
/*
* for IPA 4.0 offline charge is not needed and we need to prevent
* power collapse until IPA uC is loaded.
@@ -5328,7 +5351,6 @@
fail_gsi_pre_fw_load_init:
ipa3_dma_shutdown();
fail_ipa_dma_setup:
-fail_allok_pkt_init:
if (ipa3_ctx->use_ipa_pm)
ipa_pm_destroy();
else
@@ -5337,11 +5359,9 @@
if (!ipa3_ctx->use_ipa_pm)
ipa_rm_exit();
fail_ipa_rm_init:
- ipa3_nat_ipv6ct_destroy_devices();
-fail_nat_ipv6ct_init_dev:
- device_destroy(ipa3_ctx->class, ipa3_ctx->dev_num);
+ device_destroy(ipa3_ctx->cdev.class, ipa3_ctx->cdev.dev_num);
fail_device_create:
- unregister_chrdev_region(ipa3_ctx->dev_num, 1);
+ unregister_chrdev_region(ipa3_ctx->cdev.dev_num, 1);
fail_alloc_chrdev_region:
idr_destroy(&ipa3_ctx->ipa_idr);
rset = &ipa3_ctx->reap_rt_tbl_set[IPA_IP_v6];
@@ -5350,8 +5370,6 @@
idr_destroy(&rset->rule_ids);
idr_destroy(&ipa3_ctx->rt_tbl_set[IPA_IP_v6].rule_ids);
idr_destroy(&ipa3_ctx->rt_tbl_set[IPA_IP_v4].rule_ids);
- ipa3_free_dma_task_for_gsi();
-fail_dma_task:
kmem_cache_destroy(ipa3_ctx->rx_pkt_wrapper_cache);
fail_rx_pkt_wrapper_cache:
kmem_cache_destroy(ipa3_ctx->tx_pkt_wrapper_cache);
@@ -5374,8 +5392,6 @@
fail_create_transport_wq:
destroy_workqueue(ipa3_ctx->power_mgmt_wq);
fail_init_hw:
- ipahal_destroy();
-fail_ipahal:
iounmap(ipa3_ctx->mmio);
fail_remap:
ipa3_disable_clks();
@@ -5385,12 +5401,11 @@
clk_put(ipa3_clk);
ipa3_clk = NULL;
fail_clk:
- msm_bus_scale_unregister_client(ipa3_ctx->ipa_bus_hdl);
+ if (ipa3_ctx->ipa_bus_hdl)
+ msm_bus_scale_unregister_client(ipa3_ctx->ipa_bus_hdl);
fail_bus_reg:
- if (ipa3_bus_scale_table) {
- msm_bus_cl_clear_pdata(ipa3_bus_scale_table);
- ipa3_bus_scale_table = NULL;
- }
+ if (ipa3_ctx->ctrl->msm_bus_data_ptr)
+ msm_bus_cl_clear_pdata(ipa3_ctx->ctrl->msm_bus_data_ptr);
fail_init_mem_partition:
fail_bind:
kfree(ipa3_ctx->ctrl);
@@ -5777,7 +5792,7 @@
static int ipa_smmu_wlan_cb_probe(struct device *dev)
{
- struct ipa_smmu_cb_ctx *cb = ipa3_get_wlan_smmu_ctx();
+ struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN);
int atomic_ctx = 1;
int fast = 1;
int bypass = 1;
@@ -5788,6 +5803,11 @@
IPADBG("sub pdev=%p\n", dev);
+ if (!smmu_info.present[IPA_SMMU_CB_WLAN]) {
+ IPAERR("WLAN SMMU is disabled\n");
+ return 0;
+ }
+
cb->dev = dev;
cb->iommu = iommu_domain_alloc(dev->bus);
if (!cb->iommu) {
@@ -5797,7 +5817,8 @@
}
cb->valid = true;
- if (of_property_read_bool(dev->of_node, "qcom,smmu-s1-bypass")) {
+ if (of_property_read_bool(dev->of_node, "qcom,smmu-s1-bypass") ||
+ ipa3_ctx->ipa_config_is_mhi) {
smmu_info.s1_bypass_arr[IPA_SMMU_CB_WLAN] = true;
ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_WLAN] = true;
@@ -5877,7 +5898,7 @@
static int ipa_smmu_uc_cb_probe(struct device *dev)
{
- struct ipa_smmu_cb_ctx *cb = ipa3_get_uc_smmu_ctx();
+ struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
int atomic_ctx = 1;
int bypass = 1;
int fast = 1;
@@ -5886,6 +5907,11 @@
IPADBG("UC CB PROBE sub pdev=%p\n", dev);
+ if (!smmu_info.present[IPA_SMMU_CB_UC]) {
+ IPAERR("UC SMMU is disabled\n");
+ return 0;
+ }
+
ret = of_property_read_u32_array(dev->of_node, "qcom,iova-mapping",
iova_ap_mapping, 2);
if (ret) {
@@ -5925,7 +5951,8 @@
IPADBG("UC CB PROBE sub pdev=%p set attribute\n", dev);
- if (of_property_read_bool(dev->of_node, "qcom,smmu-s1-bypass")) {
+ if (of_property_read_bool(dev->of_node, "qcom,smmu-s1-bypass") ||
+ ipa3_ctx->ipa_config_is_mhi) {
smmu_info.s1_bypass_arr[IPA_SMMU_CB_UC] = true;
ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_UC] = true;
@@ -5985,7 +6012,7 @@
static int ipa_smmu_ap_cb_probe(struct device *dev)
{
- struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx();
+ struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP);
int result;
int atomic_ctx = 1;
int fast = 1;
@@ -5999,6 +6026,11 @@
IPADBG("AP CB probe: sub pdev=%p\n", dev);
+ if (!smmu_info.present[IPA_SMMU_CB_AP]) {
+ IPAERR("AP SMMU is disabled");
+ return 0;
+ }
+
result = of_property_read_u32_array(dev->of_node, "qcom,iova-mapping",
iova_ap_mapping, 2);
if (result) {
@@ -6036,8 +6068,9 @@
cb->valid = true;
if (of_property_read_bool(dev->of_node,
- "qcom,smmu-s1-bypass")) {
+ "qcom,smmu-s1-bypass") || ipa3_ctx->ipa_config_is_mhi) {
smmu_info.s1_bypass_arr[IPA_SMMU_CB_AP] = true;
+ ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_AP] = true;
if (iommu_domain_set_attr(cb->mapping->domain,
DOMAIN_ATTR_S1_BYPASS,
&bypass)) {
@@ -6049,6 +6082,7 @@
IPADBG("AP/USB SMMU S1 BYPASS\n");
} else {
smmu_info.s1_bypass_arr[IPA_SMMU_CB_AP] = false;
+ ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_AP] = false;
if (iommu_domain_set_attr(cb->mapping->domain,
DOMAIN_ATTR_ATOMIC,
&atomic_ctx)) {
@@ -6138,24 +6172,49 @@
}
- smmu_info.present = true;
-
- if (!ipa3_bus_scale_table)
- ipa3_bus_scale_table = msm_bus_cl_get_pdata(ipa3_pdev);
-
- /* Proceed to real initialization */
- result = ipa3_pre_init(&ipa3_res, dev);
- if (result) {
- IPAERR("ipa_init failed\n");
- arm_iommu_detach_device(cb->dev);
- arm_iommu_release_mapping(cb->mapping);
- cb->valid = false;
- return result;
- }
+ smmu_info.present[IPA_SMMU_CB_AP] = true;
+ ipa3_ctx->pdev = dev;
return result;
}
+static int ipa_smmu_cb_probe(struct device *dev, enum ipa_smmu_cb_type cb_type)
+{
+ switch (cb_type) {
+ case IPA_SMMU_CB_AP:
+ return ipa_smmu_ap_cb_probe(dev);
+ case IPA_SMMU_CB_WLAN:
+ return ipa_smmu_wlan_cb_probe(dev);
+ case IPA_SMMU_CB_UC:
+ return ipa_smmu_uc_cb_probe(dev);
+ case IPA_SMMU_CB_MAX:
+ IPAERR("Invalid cb_type\n");
+ }
+ return 0;
+}
+
+static int ipa3_attach_to_smmu(void)
+{
+ struct ipa_smmu_cb_ctx *cb;
+ int i, result;
+
+ ipa3_ctx->pdev = &ipa3_ctx->master_pdev->dev;
+ ipa3_ctx->uc_pdev = &ipa3_ctx->master_pdev->dev;
+
+ if (smmu_info.arm_smmu) {
+ IPADBG("smmu is enabled\n");
+ for (i = 0; i < IPA_SMMU_CB_MAX; i++) {
+ cb = ipa3_get_smmu_ctx(i);
+ result = ipa_smmu_cb_probe(cb->dev, i);
+ if (result)
+ IPAERR("probe failed for cb %d\n", i);
+ }
+ } else {
+ IPADBG("smmu is disabled\n");
+ }
+ return 0;
+}
+
static irqreturn_t ipa3_smp2p_modem_clk_query_isr(int irq, void *ctxt)
{
ipa3_freeze_clock_vote_and_notify_modem();
@@ -6226,18 +6285,34 @@
{
int result;
struct device *dev = &pdev_p->dev;
+ struct ipa_smmu_cb_ctx *cb;
IPADBG("IPA driver probing started\n");
IPADBG("dev->of_node->name = %s\n", dev->of_node->name);
- if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-ap-cb"))
- return ipa_smmu_ap_cb_probe(dev);
+ if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-ap-cb")) {
+ cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP);
+ cb->dev = dev;
+ smmu_info.present[IPA_SMMU_CB_AP] = true;
- if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-wlan-cb"))
- return ipa_smmu_wlan_cb_probe(dev);
+ return 0;
+ }
- if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-uc-cb"))
- return ipa_smmu_uc_cb_probe(dev);
+ if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-wlan-cb")) {
+ cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN);
+ cb->dev = dev;
+ smmu_info.present[IPA_SMMU_CB_WLAN] = true;
+
+ return 0;
+ }
+
+ if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-uc-cb")) {
+ cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
+ cb->dev = dev;
+ smmu_info.present[IPA_SMMU_CB_UC] = true;
+
+ return 0;
+ }
if (of_device_is_compatible(dev->of_node,
"qcom,smp2pgpio-map-ipa-1-in"))
@@ -6247,10 +6322,6 @@
"qcom,smp2pgpio-map-ipa-1-out"))
return ipa3_smp2p_probe(dev);
- master_dev = dev;
- if (!ipa3_pdev)
- ipa3_pdev = pdev_p;
-
result = get_ipa_dts_configuration(pdev_p, &ipa3_res);
if (result) {
IPAERR("IPA dts parsing failed\n");
@@ -6292,15 +6363,13 @@
return -EOPNOTSUPP;
}
}
+ }
- if (!ipa3_bus_scale_table)
- ipa3_bus_scale_table = msm_bus_cl_get_pdata(pdev_p);
- /* Proceed to real initialization */
- result = ipa3_pre_init(&ipa3_res, dev);
- if (result) {
- IPAERR("ipa3_init failed\n");
- return result;
- }
+ /* Proceed to real initialization */
+ result = ipa3_pre_init(&ipa3_res, pdev_p);
+ if (result) {
+ IPAERR("ipa3_init failed\n");
+ return result;
}
result = of_platform_populate(pdev_p->dev.of_node,
@@ -6448,8 +6517,8 @@
int ipa3_iommu_map(struct iommu_domain *domain,
unsigned long iova, phys_addr_t paddr, size_t size, int prot)
{
- struct ipa_smmu_cb_ctx *ap_cb = ipa3_get_smmu_ctx();
- struct ipa_smmu_cb_ctx *uc_cb = ipa3_get_uc_smmu_ctx();
+ struct ipa_smmu_cb_ctx *ap_cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP);
+ struct ipa_smmu_cb_ctx *uc_cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
IPADBG("domain =0x%p iova 0x%lx\n", domain, iova);
IPADBG("paddr =0x%pa size 0x%x\n", &paddr, (u32)size);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index d0db35a..fd81f49 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -1161,11 +1161,22 @@
};
/**
- * struct ipa3_context - IPA context
+ * struct ipa3_char_device_context - IPA character device
* @class: pointer to the struct class
* @dev_num: device number
* @dev: the dev_t of the device
* @cdev: cdev of the device
+ */
+struct ipa3_char_device_context {
+ struct class *class;
+ dev_t dev_num;
+ struct device *dev;
+ struct cdev cdev;
+};
+
+/**
+ * struct ipa3_context - IPA context
+ * @cdev: cdev context
* @ep: list of all end points
* @skip_ep_cfg_shadow: state to update filter table correctly across
power-save
@@ -1251,10 +1262,7 @@
* IPA context - holds all relevant info about IPA driver and its state
*/
struct ipa3_context {
- struct class *class;
- dev_t dev_num;
- struct device *dev;
- struct cdev cdev;
+ struct ipa3_char_device_context cdev;
struct ipa3_ep_context ep[IPA3_MAX_NUM_PIPES];
bool skip_ep_cfg_shadow[IPA3_MAX_NUM_PIPES];
u32 ep_flt_bitmap;
@@ -1336,6 +1344,7 @@
u32 ipa_bus_hdl;
struct ipa3_controller *ctrl;
struct idr ipa_idr;
+ struct platform_device *master_pdev;
struct device *pdev;
struct device *uc_pdev;
spinlock_t idr_lock;
@@ -2278,9 +2287,7 @@
int ipa_reset_all_flt_rt_stats(enum ipa_ip_type ip, bool filtering);
u32 ipa3_get_num_pipes(void);
-struct ipa_smmu_cb_ctx *ipa3_get_smmu_ctx(void);
-struct ipa_smmu_cb_ctx *ipa3_get_wlan_smmu_ctx(void);
-struct ipa_smmu_cb_ctx *ipa3_get_uc_smmu_ctx(void);
+struct ipa_smmu_cb_ctx *ipa3_get_smmu_ctx(enum ipa_smmu_cb_type);
struct iommu_domain *ipa3_get_smmu_domain(void);
struct iommu_domain *ipa3_get_uc_smmu_domain(void);
struct iommu_domain *ipa3_get_wlan_smmu_domain(void);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
index ec777bc..13d2511 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
@@ -495,7 +495,7 @@
static int ipa_create_uc_smmu_mapping_pa(phys_addr_t pa, size_t len,
bool device, unsigned long *iova)
{
- struct ipa_smmu_cb_ctx *cb = ipa3_get_uc_smmu_ctx();
+ struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
unsigned long va = roundup(cb->next_addr, PAGE_SIZE);
int prot = IOMMU_READ | IOMMU_WRITE;
size_t true_len = roundup(len + pa - rounddown(pa, PAGE_SIZE),
@@ -524,7 +524,7 @@
static int ipa_create_uc_smmu_mapping_sgt(struct sg_table *sgt,
unsigned long *iova)
{
- struct ipa_smmu_cb_ctx *cb = ipa3_get_uc_smmu_ctx();
+ struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
unsigned long va = roundup(cb->next_addr, PAGE_SIZE);
int prot = IOMMU_READ | IOMMU_WRITE;
int ret;
@@ -573,7 +573,7 @@
static void ipa_release_uc_smmu_mappings(enum ipa_client_type client)
{
- struct ipa_smmu_cb_ctx *cb = ipa3_get_uc_smmu_ctx();
+ struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
int i;
int j;
int start;
@@ -1810,7 +1810,7 @@
int ipa3_create_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info)
{
- struct ipa_smmu_cb_ctx *cb = ipa3_get_wlan_smmu_ctx();
+ struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN);
int i;
int ret = 0;
int prot = IOMMU_READ | IOMMU_WRITE;
@@ -1846,7 +1846,7 @@
int ipa3_release_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info)
{
- struct ipa_smmu_cb_ctx *cb = ipa3_get_wlan_smmu_ctx();
+ struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN);
int i;
int ret = 0;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 5ea78b9..d26679a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -1477,53 +1477,6 @@
{ 31, 31, 8, 8, IPA_EE_AP } },
};
-static struct msm_bus_vectors ipa_init_vectors_v3_0[] = {
- {
- .src = MSM_BUS_MASTER_IPA,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 0,
- .ib = 0,
- },
- {
- .src = MSM_BUS_MASTER_IPA,
- .dst = MSM_BUS_SLAVE_OCIMEM,
- .ab = 0,
- .ib = 0,
- },
-};
-
-static struct msm_bus_vectors ipa_nominal_perf_vectors_v3_0[] = {
- {
- .src = MSM_BUS_MASTER_IPA,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 100000000,
- .ib = 1300000000,
- },
- {
- .src = MSM_BUS_MASTER_IPA,
- .dst = MSM_BUS_SLAVE_OCIMEM,
- .ab = 100000000,
- .ib = 1300000000,
- },
-};
-
-static struct msm_bus_paths ipa_usecases_v3_0[] = {
- {
- .num_paths = ARRAY_SIZE(ipa_init_vectors_v3_0),
- .vectors = ipa_init_vectors_v3_0,
- },
- {
- .num_paths = ARRAY_SIZE(ipa_nominal_perf_vectors_v3_0),
- .vectors = ipa_nominal_perf_vectors_v3_0,
- },
-};
-
-static struct msm_bus_scale_pdata ipa_bus_client_pdata_v3_0 = {
- .usecase = ipa_usecases_v3_0,
- .num_usecases = ARRAY_SIZE(ipa_usecases_v3_0),
- .name = "ipa",
-};
-
/**
* ipa3_get_clients_from_rm_resource() - get IPA clients which are related to an
* IPA_RM resource
@@ -3786,7 +3739,6 @@
ctrl->ipa3_commit_hdr = __ipa_commit_hdr_v3_0;
ctrl->ipa3_enable_clks = _ipa_enable_clks_v3_0;
ctrl->ipa3_disable_clks = _ipa_disable_clks_v3_0;
- ctrl->msm_bus_data_ptr = &ipa_bus_client_pdata_v3_0;
ctrl->clock_scaling_bw_threshold_svs =
IPA_V3_0_BW_THRESHOLD_SVS_MBPS;
ctrl->clock_scaling_bw_threshold_nominal =
diff --git a/drivers/platform/msm/msm_rmnet_bam.c b/drivers/platform/msm/msm_rmnet_bam.c
new file mode 100644
index 0000000..8d59af0
--- /dev/null
+++ b/drivers/platform/msm/msm_rmnet_bam.c
@@ -0,0 +1,945 @@
+/* Copyright (c) 2011-2016, 2018 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * RMNET BAM Module.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/msm_rmnet.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+
+#include <net/pkt_sched.h>
+
+#include <soc/qcom/bam_dmux.h>
+
+/* Debug message support */
+static int msm_rmnet_bam_debug_mask;
+module_param_named(debug_enable, msm_rmnet_bam_debug_mask, int, 0664);
+ /* S_IRUGO | S_IWUSR | S_IWGRP */
+
+static unsigned long int msm_rmnet_bam_headroom_check_failure;
+module_param(msm_rmnet_bam_headroom_check_failure, ulong, 0444); /*S_IRUGO*/
+MODULE_PARM_DESC(msm_rmnet_bam_headroom_check_failure,
+ "Number of packets with insufficient headroom");
+
+/* Packet threshold. */
+static unsigned int pkt_threshold = 1;
+module_param(pkt_threshold, uint, 0664); /* S_IRUGO | S_IWUSR | S_IWGRP */
+
+#define DEBUG_MASK_LVL0 (1U << 0)
+#define DEBUG_MASK_LVL1 (1U << 1)
+#define DEBUG_MASK_LVL2 (1U << 2)
+
+#define DBG(m, x...) do { \
+ if (msm_rmnet_bam_debug_mask & m) \
+ pr_info(x); \
+} while (0)
+#define DBG0(x...) DBG(DEBUG_MASK_LVL0, x)
+#define DBG1(x...) DBG(DEBUG_MASK_LVL1, x)
+#define DBG2(x...) DBG(DEBUG_MASK_LVL2, x)
+
+/* allow larger frames */
+#define RMNET_DATA_LEN 2000
+
+#define RMNET_BAM_DRIVER_NAME "rmnet_bam"
+
+#define DEVICE_ID_INVALID -1
+
+#define DEVICE_INACTIVE 2
+#define DEVICE_ACTIVE 1
+#define DEVICE_UNINITIALIZED 0
+
+#define HEADROOM_FOR_BAM 8 /* for mux header */
+#define HEADROOM_FOR_QOS 8
+#define TAILROOM 8 /* for padding by mux layer */
+
+struct rmnet_private {
+ struct net_device_stats stats;
+ uint32_t ch_id;
+#ifdef CONFIG_MSM_RMNET_DEBUG
+ ktime_t last_packet;
+ unsigned long wakeups_xmit;
+ unsigned long wakeups_rcv;
+ unsigned long timeout_us;
+#endif
+ struct sk_buff *waiting_for_ul_skb;
+ spinlock_t lock;
+ spinlock_t tx_queue_lock;
+ struct tasklet_struct tsklt;
+ u32 operation_mode; /* IOCTL specified mode (protocol, QoS header) */
+ uint8_t device_up;
+ uint8_t in_reset;
+};
+
+struct rmnet_free_bam_work {
+ struct work_struct work;
+ uint32_t ch_id;
+};
+
+#ifdef CONFIG_MSM_RMNET_DEBUG
+static unsigned long timeout_us;
+
+/* Returns 1 if packet caused rmnet to wakeup, 0 otherwise. */
+static int rmnet_cause_wakeup(struct rmnet_private *p)
+{
+ int ret = 0;
+ ktime_t now;
+
+ if (p->timeout_us == 0) /* Check if disabled */
+ return 0;
+
+ /* Use real (wall) time. */
+ now = ktime_get_real();
+
+ if (ktime_us_delta(now, p->last_packet) > p->timeout_us)
+ ret = 1;
+
+ p->last_packet = now;
+ return ret;
+}
+
+static ssize_t wakeups_xmit_show(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmnet_private *p = netdev_priv(to_net_dev(d));
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", p->wakeups_xmit);
+}
+
+DEVICE_ATTR(wakeups_xmit, 0444, wakeups_xmit_show, NULL);
+
+static ssize_t wakeups_rcv_show(struct device *d, struct device_attribute *attr,
+ char *buf)
+{
+ struct rmnet_private *p = netdev_priv(to_net_dev(d));
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", p->wakeups_rcv);
+}
+
+DEVICE_ATTR(wakeups_rcv, 0444, wakeups_rcv_show, NULL);
+
+/* Set timeout in us. */
+static ssize_t timeout_store(struct device *d, struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+ struct rmnet_private *p = netdev_priv(to_net_dev(d));
+ int ret;
+
+ ret = kstrtoul(buf, 0, &timeout_us);
+ if (ret < 0)
+ return n;
+ p->timeout_us = timeout_us;
+ return n;
+}
+
+static ssize_t timeout_show(struct device *d, struct device_attribute *attr,
+ char *buf)
+{
+ struct rmnet_private *p = netdev_priv(to_net_dev(d));
+
+ p = netdev_priv(to_net_dev(d));
+ return snprintf(buf, PAGE_SIZE, "%lu\n", timeout_us);
+}
+
+DEVICE_ATTR(timeout, 0664, timeout_show, timeout_store);
+#endif
+
+
+/* Forward declaration */
+static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+static struct platform_driver bam_rmnet_drivers[BAM_DMUX_NUM_CHANNELS];
+
+static struct net_device *netdevs[BAM_DMUX_NUM_CHANNELS];
+
+static __be16 rmnet_ip_type_trans(struct sk_buff *skb, struct net_device *dev)
+{
+ __be16 protocol = 0;
+
+ skb->dev = dev;
+
+ /* Determine L3 protocol */
+ switch (skb->data[0] & 0xf0) {
+ case 0x40:
+ protocol = htons(ETH_P_IP);
+ break;
+ case 0x60:
+ protocol = htons(ETH_P_IPV6);
+ break;
+ default:
+ protocol = htons(ETH_P_MAP);
+ }
+ return protocol;
+}
+
+static int count_this_packet(void *_hdr, int len)
+{
+ struct ethhdr *hdr = _hdr;
+
+ if (len >= ETH_HLEN && hdr->h_proto == htons(ETH_P_ARP))
+ return 0;
+
+ return 1;
+}
+
+/* Rx Callback, Called in Work Queue context */
+static void bam_recv_notify(void *dev, struct sk_buff *skb)
+{
+ struct rmnet_private *p = netdev_priv(dev);
+ unsigned long flags;
+ u32 opmode;
+
+ if (skb) {
+ skb->dev = dev;
+ /* Handle Rx frame format */
+ spin_lock_irqsave(&p->lock, flags);
+ opmode = p->operation_mode;
+ spin_unlock_irqrestore(&p->lock, flags);
+
+ if (RMNET_IS_MODE_IP(opmode)) {
+ /* Driver in IP mode */
+ skb->protocol = rmnet_ip_type_trans(skb, dev);
+ } else {
+ /* Driver in Ethernet mode */
+ skb->protocol = eth_type_trans(skb, dev);
+ }
+ if (RMNET_IS_MODE_IP(opmode) ||
+ count_this_packet(skb->data, skb->len)) {
+#ifdef CONFIG_MSM_RMNET_DEBUG
+ p->wakeups_rcv += rmnet_cause_wakeup(p);
+#endif
+ p->stats.rx_packets++;
+ p->stats.rx_bytes += skb->len;
+ }
+ DBG1("[%s] Rx packet #%lu len=%d\n",
+ ((struct net_device *)dev)->name,
+ p->stats.rx_packets, skb->len);
+
+ /* Deliver to network stack */
+ if (pkt_threshold == 1) {
+ netif_rx_ni(skb);
+ } else {
+ /* For every nth packet, use netif_rx_ni(). */
+ if (p->stats.rx_packets % pkt_threshold == 0)
+ netif_rx_ni(skb);
+ else
+ netif_rx(skb);
+ }
+ } else
+ pr_err("[%s] %s: No skb received",
+ ((struct net_device *)dev)->name, __func__);
+}
+
+static struct sk_buff *_rmnet_add_headroom(struct sk_buff **skb,
+ struct net_device *dev)
+{
+ struct sk_buff *skbn;
+
+ if (skb_headroom(*skb) < dev->needed_headroom) {
+ msm_rmnet_bam_headroom_check_failure++;
+ skbn = skb_realloc_headroom(*skb, dev->needed_headroom);
+ kfree_skb(*skb);
+ *skb = skbn;
+ } else {
+ skbn = *skb;
+ }
+
+ return skbn;
+}
+
+static int _rmnet_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct rmnet_private *p = netdev_priv(dev);
+ int bam_ret;
+ struct QMI_QOS_HDR_S *qmih;
+ u32 opmode;
+ unsigned long flags;
+
+ if (unlikely(!_rmnet_add_headroom(&skb, dev))) {
+ dev->stats.tx_dropped++;
+ return NETDEV_TX_OK;
+ }
+ /* For QoS mode, prepend QMI header and assign flow ID from skb->mark */
+ spin_lock_irqsave(&p->lock, flags);
+ opmode = p->operation_mode;
+ spin_unlock_irqrestore(&p->lock, flags);
+
+ if (RMNET_IS_MODE_QOS(opmode)) {
+ qmih = (struct QMI_QOS_HDR_S *)
+ skb_push(skb, sizeof(struct QMI_QOS_HDR_S));
+ qmih->version = 1;
+ qmih->flags = 0;
+ qmih->flow_id = skb->mark;
+ }
+
+ //Mayank dev->trans_start = jiffies;
+ /* if write() succeeds, skb access is unsafe in this process */
+ bam_ret = msm_bam_dmux_write(p->ch_id, skb);
+
+ if (bam_ret != 0 && bam_ret != -EAGAIN && bam_ret != -EFAULT) {
+ pr_err("[%s] %s: write returned error %d",
+ dev->name, __func__, bam_ret);
+ if (RMNET_IS_MODE_QOS(opmode))
+ skb_pull(skb, sizeof(struct QMI_QOS_HDR_S));
+ return -EPERM;
+ }
+
+ return bam_ret;
+}
+
+static void bam_write_done(void *dev, struct sk_buff *skb)
+{
+ struct rmnet_private *p = netdev_priv(dev);
+ u32 opmode = p->operation_mode;
+ unsigned long flags;
+
+ DBG1("%s: write complete\n", __func__);
+ if (RMNET_IS_MODE_IP(opmode) ||
+ count_this_packet(skb->data, skb->len)) {
+ p->stats.tx_packets++;
+ p->stats.tx_bytes += skb->len;
+#ifdef CONFIG_MSM_RMNET_DEBUG
+ p->wakeups_xmit += rmnet_cause_wakeup(p);
+#endif
+ }
+ DBG1("[%s] Tx packet #%lu len=%d mark=0x%x\n",
+ ((struct net_device *)(dev))->name, p->stats.tx_packets,
+ skb->len, skb->mark);
+ dev_kfree_skb_any(skb);
+
+ spin_lock_irqsave(&p->tx_queue_lock, flags);
+ if (netif_queue_stopped(dev) &&
+ msm_bam_dmux_is_ch_low(p->ch_id)) {
+ DBG0("%s: Low WM hit, waking queue=%pK\n",
+ __func__, skb);
+ netif_wake_queue(dev);
+ }
+ spin_unlock_irqrestore(&p->tx_queue_lock, flags);
+}
+
+static void bam_notify(void *dev, int event, unsigned long data)
+{
+ struct rmnet_private *p = netdev_priv(dev);
+ unsigned long flags;
+
+ switch (event) {
+ case BAM_DMUX_RECEIVE:
+ bam_recv_notify(dev, (struct sk_buff *)(data));
+ break;
+ case BAM_DMUX_WRITE_DONE:
+ bam_write_done(dev, (struct sk_buff *)(data));
+ break;
+ case BAM_DMUX_UL_CONNECTED:
+ spin_lock_irqsave(&p->lock, flags);
+ if (p->waiting_for_ul_skb != NULL) {
+ struct sk_buff *skb;
+ int ret;
+
+ skb = p->waiting_for_ul_skb;
+ p->waiting_for_ul_skb = NULL;
+ spin_unlock_irqrestore(&p->lock, flags);
+ ret = _rmnet_xmit(skb, dev);
+ if (ret) {
+ pr_err("%s: error %d dropping delayed TX SKB %pK\n",
+ __func__, ret, skb);
+ dev_kfree_skb_any(skb);
+ }
+ netif_wake_queue(dev);
+ } else {
+ spin_unlock_irqrestore(&p->lock, flags);
+ }
+ break;
+ case BAM_DMUX_UL_DISCONNECTED:
+ break;
+ }
+}
+
+static int __rmnet_open(struct net_device *dev)
+{
+ int r;
+ struct rmnet_private *p = netdev_priv(dev);
+
+ DBG0("[%s] __rmnet_open()\n", dev->name);
+
+ if (p->device_up == DEVICE_UNINITIALIZED) {
+ r = msm_bam_dmux_open(p->ch_id, dev, bam_notify);
+ if (r < 0) {
+ DBG0("%s: ch=%d failed with rc %d\n",
+ __func__, p->ch_id, r);
+ return -ENODEV;
+ }
+ }
+
+ p->device_up = DEVICE_ACTIVE;
+ return 0;
+}
+
+static int rmnet_open(struct net_device *dev)
+{
+ int rc = 0;
+
+ DBG0("[%s] rmnet_open()\n", dev->name);
+
+ rc = __rmnet_open(dev);
+
+ if (rc == 0)
+ netif_start_queue(dev);
+
+ return rc;
+}
+
+
+static int __rmnet_close(struct net_device *dev)
+{
+ struct rmnet_private *p = netdev_priv(dev);
+ int rc = 0;
+
+ if (p->device_up == DEVICE_ACTIVE) {
+ /* do not close rmnet port once up, this causes
+ * remote side to hang if tried to open again
+ */
+ p->device_up = DEVICE_INACTIVE;
+ return rc;
+ } else
+ return -EBADF;
+}
+
+
+static int rmnet_stop(struct net_device *dev)
+{
+ DBG0("[%s] rmnet_stop()\n", dev->name);
+
+ __rmnet_close(dev);
+ netif_stop_queue(dev);
+
+ return 0;
+}
+
+static int rmnet_change_mtu(struct net_device *dev, int new_mtu)
+{
+ if (0 > new_mtu || RMNET_DATA_LEN < new_mtu)
+ return -EINVAL;
+
+ DBG0("[%s] MTU change: old=%d new=%d\n",
+ dev->name, dev->mtu, new_mtu);
+ dev->mtu = new_mtu;
+
+ return 0;
+}
+
+static int rmnet_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct rmnet_private *p = netdev_priv(dev);
+ unsigned long flags;
+ int awake;
+ int ret = 0;
+
+ if (netif_queue_stopped(dev)) {
+ pr_err("[%s]debug: rmnet_xmit called when netif_queue is stopped\n",
+ dev->name);
+ return NETDEV_TX_BUSY;
+ }
+
+ spin_lock_irqsave(&p->lock, flags);
+ awake = msm_bam_dmux_ul_power_vote();
+ if (!awake) {
+ /* send SKB once wakeup is complete */
+ netif_stop_queue(dev);
+ p->waiting_for_ul_skb = skb;
+ spin_unlock_irqrestore(&p->lock, flags);
+ ret = 0;
+ goto exit;
+ }
+ spin_unlock_irqrestore(&p->lock, flags);
+
+ ret = _rmnet_xmit(skb, dev);
+ if (ret == -EPERM) {
+ ret = NETDEV_TX_BUSY;
+ goto exit;
+ }
+
+ /*
+ * detected SSR a bit early. shut some things down now, and leave
+ * the rest to the main ssr handling code when that happens later
+ */
+ if (ret == -EFAULT) {
+ netif_carrier_off(dev);
+ dev_kfree_skb_any(skb);
+ ret = 0;
+ goto exit;
+ }
+
+ if (ret == -EAGAIN) {
+ /*
+ * This should not happen
+ * EAGAIN means we attempted to overflow the high watermark
+ * Clearly the queue is not stopped like it should be, so
+ * stop it and return BUSY to the TCP/IP framework. It will
+ * retry this packet with the queue is restarted which happens
+ * in the write_done callback when the low watermark is hit.
+ */
+ netif_stop_queue(dev);
+ ret = NETDEV_TX_BUSY;
+ goto exit;
+ }
+
+ spin_lock_irqsave(&p->tx_queue_lock, flags);
+ if (msm_bam_dmux_is_ch_full(p->ch_id)) {
+ netif_stop_queue(dev);
+ DBG0("%s: High WM hit, stopping queue=%pK\n", __func__, skb);
+ }
+ spin_unlock_irqrestore(&p->tx_queue_lock, flags);
+
+exit:
+ msm_bam_dmux_ul_power_unvote();
+ return ret;
+}
+
+static struct net_device_stats *rmnet_get_stats(struct net_device *dev)
+{
+ struct rmnet_private *p = netdev_priv(dev);
+
+ return &p->stats;
+}
+
+static void rmnet_tx_timeout(struct net_device *dev)
+{
+ pr_warn("[%s] rmnet_tx_timeout()\n", dev->name);
+}
+
+static const struct net_device_ops rmnet_ops_ether = {
+ .ndo_open = rmnet_open,
+ .ndo_stop = rmnet_stop,
+ .ndo_start_xmit = rmnet_xmit,
+ .ndo_get_stats = rmnet_get_stats,
+ .ndo_tx_timeout = rmnet_tx_timeout,
+ .ndo_do_ioctl = rmnet_ioctl,
+ .ndo_change_mtu = rmnet_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static const struct net_device_ops rmnet_ops_ip = {
+ .ndo_open = rmnet_open,
+ .ndo_stop = rmnet_stop,
+ .ndo_start_xmit = rmnet_xmit,
+ .ndo_get_stats = rmnet_get_stats,
+ .ndo_tx_timeout = rmnet_tx_timeout,
+ .ndo_do_ioctl = rmnet_ioctl,
+ .ndo_change_mtu = rmnet_change_mtu,
+ .ndo_set_mac_address = NULL,
+ .ndo_validate_addr = NULL,
+};
+
+static void _rmnet_free_bam_later(struct work_struct *work)
+{
+ struct rmnet_free_bam_work *fwork;
+
+ fwork = container_of(work, struct rmnet_free_bam_work, work);
+
+ DBG0("%s: unregister_netdev, done\n", __func__);
+
+ if (bam_rmnet_drivers[fwork->ch_id].remove) {
+ platform_driver_unregister(&bam_rmnet_drivers[fwork->ch_id]);
+ bam_rmnet_drivers[fwork->ch_id].remove = NULL;
+ }
+
+ DBG0("%s: free_netdev, done\n", __func__);
+
+ kfree(work);
+}
+
+static int rmnet_ioctl_extended(struct net_device *dev, struct ifreq *ifr)
+{
+ struct rmnet_ioctl_extended_s ext_cmd;
+ int rc = 0;
+ struct rmnet_private *p = netdev_priv(dev);
+ struct rmnet_free_bam_work *work;
+
+ rc = copy_from_user(&ext_cmd, ifr->ifr_ifru.ifru_data,
+ sizeof(ext_cmd));
+
+ if (rc) {
+ pr_err("%s: copy_from_user failed ,error %d\n", __func__, rc);
+ return -EFAULT;
+ }
+
+ switch (ext_cmd.extended_ioctl) {
+ case RMNET_IOCTL_SET_MRU:
+ /* Transport MRU is fixed, so do nothing */
+ break;
+ case RMNET_IOCTL_GET_EPID:
+ ext_cmd.u.data = p->ch_id;
+ break;
+ case RMNET_IOCTL_GET_SUPPORTED_FEATURES:
+ ext_cmd.u.data = 0;
+ break;
+ case RMNET_IOCTL_GET_DRIVER_NAME:
+ strlcpy(ext_cmd.u.if_name, RMNET_BAM_DRIVER_NAME,
+ sizeof(ext_cmd.u.if_name));
+ break;
+ case RMNET_IOCTL_DEREGISTER_DEV:
+ work = kmalloc(sizeof(*work), GFP_KERNEL);
+ if (!work)
+ break;
+ INIT_WORK(&work->work, _rmnet_free_bam_later);
+
+ work->ch_id = p->ch_id;
+ schedule_work(&work->work);
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
+
+ rc = copy_to_user(ifr->ifr_ifru.ifru_data, &ext_cmd, sizeof(ext_cmd));
+
+ if (rc)
+ pr_err("%s: copy_to_user failed, error %d\n", __func__, rc);
+
+ return rc ? -EFAULT : 0;
+}
+
+static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct rmnet_private *p = netdev_priv(dev);
+ u32 old_opmode = p->operation_mode;
+ unsigned long flags;
+ int prev_mtu = dev->mtu;
+ int rc = 0;
+ struct rmnet_ioctl_data_s ioctl_data;
+
+ /* Process IOCTL command */
+ switch (cmd) {
+ case RMNET_IOCTL_SET_LLP_ETHERNET: /* Set Ethernet protocol */
+ /* Perform Ethernet config only if in IP mode currently*/
+ if (p->operation_mode & RMNET_MODE_LLP_IP) {
+ ether_setup(dev);
+ random_ether_addr(dev->dev_addr);
+ dev->mtu = prev_mtu;
+
+ dev->netdev_ops = &rmnet_ops_ether;
+ spin_lock_irqsave(&p->lock, flags);
+ p->operation_mode &= ~RMNET_MODE_LLP_IP;
+ p->operation_mode |= RMNET_MODE_LLP_ETH;
+ spin_unlock_irqrestore(&p->lock, flags);
+ DBG0("[%s] rmnet_ioctl():set Ethernet protocol mode\n",
+ dev->name);
+ }
+ break;
+
+ case RMNET_IOCTL_SET_LLP_IP: /* Set RAWIP protocol */
+ /* Perform IP config only if in Ethernet mode currently*/
+ if (p->operation_mode & RMNET_MODE_LLP_ETH) {
+
+ /* Undo config done in ether_setup() */
+ dev->header_ops = NULL; /* No header */
+ dev->type = ARPHRD_RAWIP;
+ dev->hard_header_len = 0;
+ dev->mtu = prev_mtu;
+ dev->addr_len = 0;
+ dev->flags &= ~(IFF_BROADCAST|
+ IFF_MULTICAST);
+
+ dev->needed_headroom = HEADROOM_FOR_BAM +
+ HEADROOM_FOR_QOS;
+ dev->needed_tailroom = TAILROOM;
+ dev->netdev_ops = &rmnet_ops_ip;
+ spin_lock_irqsave(&p->lock, flags);
+ p->operation_mode &= ~RMNET_MODE_LLP_ETH;
+ p->operation_mode |= RMNET_MODE_LLP_IP;
+ spin_unlock_irqrestore(&p->lock, flags);
+ DBG0("[%s] rmnet_ioctl(): set IP protocol mode\n",
+ dev->name);
+ }
+ break;
+
+ case RMNET_IOCTL_GET_LLP: /* Get link protocol state */
+ ioctl_data.u.operation_mode = (p->operation_mode &
+ (RMNET_MODE_LLP_ETH|RMNET_MODE_LLP_IP));
+ if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
+ sizeof(struct rmnet_ioctl_data_s)))
+ rc = -EFAULT;
+ break;
+
+ case RMNET_IOCTL_SET_QOS_ENABLE: /* Set QoS header enabled */
+ spin_lock_irqsave(&p->lock, flags);
+ p->operation_mode |= RMNET_MODE_QOS;
+ spin_unlock_irqrestore(&p->lock, flags);
+ DBG0("[%s] rmnet_ioctl(): set QMI QOS header enable\n",
+ dev->name);
+ break;
+
+ case RMNET_IOCTL_SET_QOS_DISABLE: /* Set QoS header disabled */
+ spin_lock_irqsave(&p->lock, flags);
+ p->operation_mode &= ~RMNET_MODE_QOS;
+ spin_unlock_irqrestore(&p->lock, flags);
+ DBG0("[%s] rmnet_ioctl(): set QMI QOS header disable\n",
+ dev->name);
+ break;
+
+ case RMNET_IOCTL_FLOW_ENABLE:
+ if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
+ sizeof(struct rmnet_ioctl_data_s))) {
+ rc = -EFAULT;
+ break;
+ }
+ tc_qdisc_flow_control(dev, ioctl_data.u.tcm_handle, 1);
+ DBG0("[%s] rmnet_ioctl(): enabled flow\n", dev->name);
+ break;
+
+ case RMNET_IOCTL_FLOW_DISABLE:
+ if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
+ sizeof(struct rmnet_ioctl_data_s))) {
+ rc = -EFAULT;
+ break;
+ }
+ tc_qdisc_flow_control(dev, ioctl_data.u.tcm_handle, 0);
+ DBG0("[%s] rmnet_ioctl(): disabled flow\n", dev->name);
+ break;
+
+ case RMNET_IOCTL_GET_QOS: /* Get QoS header state */
+ ioctl_data.u.operation_mode = (p->operation_mode
+ & RMNET_MODE_QOS);
+ if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
+ sizeof(struct rmnet_ioctl_data_s)))
+ rc = -EFAULT;
+ break;
+
+ case RMNET_IOCTL_GET_OPMODE: /* Get operation mode */
+ ioctl_data.u.operation_mode = p->operation_mode;
+ if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
+ sizeof(struct rmnet_ioctl_data_s)))
+ rc = -EFAULT;
+ break;
+
+ case RMNET_IOCTL_OPEN: /* Open transport port */
+ rc = __rmnet_open(dev);
+ DBG0("[%s] rmnet_ioctl(): open transport port\n",
+ dev->name);
+ break;
+
+ case RMNET_IOCTL_CLOSE: /* Close transport port */
+ rc = __rmnet_close(dev);
+ DBG0("[%s] rmnet_ioctl(): close transport port\n",
+ dev->name);
+ break;
+
+ case RMNET_IOCTL_EXTENDED: /* Extended IOCTL's */
+ rc = rmnet_ioctl_extended(dev, ifr);
+ break;
+
+ default:
+ pr_err("[%s] error: rmnet_ioct called for unsupported cmd[%x]\n",
+ dev->name, cmd);
+ return -EINVAL;
+ }
+
+ DBG2("[%s] %s: cmd=0x%x opmode old=0x%08x new=0x%08x\n",
+ dev->name, __func__, cmd, old_opmode, p->operation_mode);
+ return rc;
+}
+
+static void rmnet_setup(struct net_device *dev)
+{
+ /* Using Ethernet mode by default */
+ dev->netdev_ops = &rmnet_ops_ether;
+ ether_setup(dev);
+
+ /* set this after calling ether_setup */
+ dev->mtu = RMNET_DATA_LEN;
+ dev->needed_headroom = HEADROOM_FOR_BAM + HEADROOM_FOR_QOS;
+ dev->needed_tailroom = TAILROOM;
+ random_ether_addr(dev->dev_addr);
+
+ dev->watchdog_timeo = 1000; /* 10 seconds? */
+}
+
+
+#ifdef CONFIG_MSM_RMNET_DEBUG
+static int rmnet_debug_init(struct net_device *dev)
+{
+
+ struct device *d;
+ struct rmnet_private *p;
+ int err = 0;
+
+ d = &(dev->dev);
+ p = netdev_priv(dev);
+ p->timeout_us = 0;
+ p->wakeups_xmit = p->wakeups_rcv = 0;
+ err = device_create_file(d, &dev_attr_timeout);
+ if (err)
+ return err;
+ err = device_create_file(d, &dev_attr_wakeups_xmit);
+ if (err)
+ return err;
+ err = device_create_file(d, &dev_attr_wakeups_rcv);
+ return err;
+}
+#else
+static int rmnet_debug_init(struct net_device *dev)
+{
+ return 0;
+}
+#endif
+
+static int bam_rmnet_probe(struct platform_device *pdev)
+{
+ int i, ret;
+ struct rmnet_private *p;
+ struct device *d;
+ char name[BAM_DMUX_CH_NAME_MAX_LEN];
+ struct net_device *dev;
+ const char *dev_name;
+
+ for (i = 0; i < BAM_DMUX_NUM_CHANNELS; ++i) {
+ scnprintf(name, BAM_DMUX_CH_NAME_MAX_LEN, "bam_dmux_ch_%d", i);
+ if (!strcmp(pdev->name, name))
+ break;
+ }
+
+ if (((i > BAM_DMUX_DATA_RMNET_7) && (i < BAM_DMUX_DATA_REV_RMNET_0)) ||
+ (i >= BAM_DMUX_NUM_CHANNELS)) {
+ pr_err("%s: wrong netdev %s\n", __func__, pdev->name);
+ return -ENODEV;
+ }
+
+ if (i <= BAM_DMUX_DATA_RMNET_7)
+ dev_name = "rmnet%d";
+ else
+ dev_name = "rev_rmnet%d";
+
+ dev = alloc_netdev(sizeof(*p), dev_name, NET_NAME_ENUM, rmnet_setup);
+ if (!dev) {
+ pr_err("%s: no memory for netdev %d\n", __func__, i);
+ return -ENOMEM;
+ }
+
+ netdevs[i] = dev;
+ d = &(dev->dev);
+ p = netdev_priv(dev);
+ /* Initial config uses Ethernet */
+ p->operation_mode = RMNET_MODE_LLP_ETH;
+ p->ch_id = i;
+ p->waiting_for_ul_skb = NULL;
+ p->device_up = DEVICE_UNINITIALIZED;
+ spin_lock_init(&p->lock);
+ spin_lock_init(&p->tx_queue_lock);
+
+ ret = register_netdev(dev);
+ if (ret) {
+ pr_err("%s: unable to register netdev %d rc=%d\n",
+ __func__, i, ret);
+ netdevs[i] = NULL;
+ free_netdev(dev);
+ return ret;
+ }
+
+ rmnet_debug_init(dev);
+
+ return 0;
+}
+
+static int bam_rmnet_remove(struct platform_device *pdev)
+{
+ int i;
+ struct rmnet_private *p;
+ char name[BAM_DMUX_CH_NAME_MAX_LEN];
+
+ for (i = 0; i < BAM_DMUX_NUM_CHANNELS; ++i) {
+ scnprintf(name, BAM_DMUX_CH_NAME_MAX_LEN, "bam_dmux_ch_%d", i);
+ if (!strcmp(pdev->name, name))
+ break;
+ }
+
+ if (((i > BAM_DMUX_DATA_RMNET_7) && (i < BAM_DMUX_DATA_REV_RMNET_0)) ||
+ (i >= BAM_DMUX_NUM_CHANNELS)) {
+ pr_err("%s: wrong netdev %s\n", __func__, pdev->name);
+ return -ENODEV;
+ }
+
+ p = netdev_priv(netdevs[i]);
+ if (p->waiting_for_ul_skb != NULL) {
+ dev_kfree_skb_any(p->waiting_for_ul_skb);
+ p->waiting_for_ul_skb = NULL;
+ }
+ msm_bam_dmux_close(p->ch_id);
+ netif_carrier_off(netdevs[i]);
+ netif_stop_queue(netdevs[i]);
+
+ unregister_netdev(netdevs[i]);
+ free_netdev(netdevs[i]);
+
+ return 0;
+}
+
+#ifdef CONFIG_MSM_RMNET_DEBUG
+static void rmnet_clear_timeout_us(void)
+{
+ timeout_us = 0;
+}
+#else
+static void rmnet_clear_timeout_us(void)
+{
+ ; /*Do Nothing*/
+}
+#endif /* CONFIG_MSM_RMNET_DEBUG */
+
+static int __init rmnet_init(void)
+{
+ unsigned int n;
+ char *tempname;
+
+ rmnet_clear_timeout_us();
+
+ n = 0;
+ while (n <= BAM_DMUX_DATA_REV_RMNET_8) {
+ if ((n > BAM_DMUX_DATA_RMNET_7) &&
+ (n < BAM_DMUX_DATA_REV_RMNET_0)) {
+ n++;
+ continue;
+ }
+ bam_rmnet_drivers[n].probe = bam_rmnet_probe;
+ bam_rmnet_drivers[n].remove = bam_rmnet_remove;
+ tempname = kmalloc(BAM_DMUX_CH_NAME_MAX_LEN, GFP_KERNEL);
+ if (tempname == NULL) {
+ netdevs[n] = NULL;
+ return -ENOMEM;
+ }
+ scnprintf(tempname, BAM_DMUX_CH_NAME_MAX_LEN, "bam_dmux_ch_%d",
+ n);
+ bam_rmnet_drivers[n].driver.name = tempname;
+ bam_rmnet_drivers[n].driver.owner = THIS_MODULE;
+ platform_driver_register(&bam_rmnet_drivers[n]);
+ n++;
+ }
+
+ return 0;
+}
+
+module_init(rmnet_init);
+MODULE_DESCRIPTION("MSM RMNET BAM TRANSPORT");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 6314270..b4cd640 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -2729,12 +2729,12 @@
if (bam_type == CI_CTRL)
msm_hw_bam_disable(0);
- /* Enable usb irq here which is disabled in function drivers
- * during disconnect after BAM reset.
- */
- if (bam_type == CI_CTRL)
- msm_usb_irq_disable(false);
}
+ /* Enable usb irq here which is disabled in function drivers
+ * during disconnect after BAM reset.
+ */
+ if (!ctx->pipes_enabled_per_bam && (bam_type == CI_CTRL))
+ msm_usb_irq_disable(false);
/* This function is directly called by USB Transport drivers
* to disconnect pipes. Drop runtime usage count here. For
* IPA, caller takes care of it
@@ -3136,6 +3136,7 @@
&& bam_type == CI_CTRL) {
pr_debug("Register and enable HSUSB BAM\n");
props.options |= SPS_BAM_OPT_ENABLE_AT_BOOT;
+ props.options |= SPS_BAM_FORCE_RESET;
}
dev = &ctx->usb_bam_pdev->dev;
@@ -3406,6 +3407,127 @@
}
EXPORT_SYMBOL(usb_bam_get_bam_type);
+/*
+ * This function makes sure ipa endpoints are disabled for both USB->IPA
+ * and IPA->USB pipes before USB bam reset. USB BAM reset is required to
+ * to avoid EP flush issues while disabling USB endpoints on disconnect.
+ */
+int msm_do_bam_disable_enable(enum usb_ctrl bam)
+{
+ struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam];
+ struct sps_pipe *pipe;
+ u32 timeout = 10, pipe_empty;
+ int ret = 0, i;
+ struct sps_connect *sps_connection;
+ struct usb_bam_sps_type usb_bam_sps = ctx->usb_bam_sps;
+ struct usb_bam_pipe_connect *pipe_connect;
+ int qdss_idx;
+ struct msm_usb_bam_data *usb_bam_data;
+
+ if (!ctx->usb_bam_pdev)
+ return 0;
+
+ usb_bam_data = ctx->usb_bam_data;
+ if ((bam != CI_CTRL) || !usb_bam_data->enable_hsusb_bam_on_boot)
+ return 0;
+
+ if (!ctx->pipes_enabled_per_bam || info[bam].pipes_suspended)
+ return 0;
+
+ if (in_interrupt()) {
+ pr_err("%s:API called in interrupt context\n", __func__);
+ return 0;
+ }
+
+ mutex_lock(&info[bam].suspend_resume_mutex);
+ log_event_dbg("%s: Perform USB BAM reset\n", __func__);
+ /* Get QDSS pipe index to avoid pipe reset */
+ qdss_idx = usb_bam_get_connection_idx(qdss_usb_bam_type, QDSS_P_BAM,
+ PEER_PERIPHERAL_TO_USB, USB_BAM_DEVICE, 0);
+
+ for (i = 0; i < ctx->max_connections; i++) {
+ pipe_connect = &ctx->usb_bam_connections[i];
+ if (pipe_connect->enabled &&
+ (pipe_connect->dir == PEER_PERIPHERAL_TO_USB) &&
+ (qdss_idx != i)) {
+ /* Call to disable IPA producer endpoint */
+ ipa_disable_endpoint(pipe_connect->ipa_clnt_hdl);
+ sps_pipe_reset(ctx->h_bam,
+ pipe_connect->dst_pipe_index);
+ }
+ }
+
+ for (i = 0; i < ctx->max_connections; i++) {
+ pipe_connect = &ctx->usb_bam_connections[i];
+ if (pipe_connect->enabled &&
+ (pipe_connect->dir == USB_TO_PEER_PERIPHERAL) &&
+ (qdss_idx != i)) {
+ pipe = ctx->usb_bam_sps.sps_pipes[i];
+ sps_connection = &usb_bam_sps.sps_connections[i];
+ timeout = 10;
+ /*
+ * On some platforms, there is a chance that flow
+ * control is disabled from IPA side, due to this IPA
+ * core may not consume data from USB. Hence notify IPA
+ * to enable flow control and then check sps pipe is
+ * empty or not before processing USB->IPA disconnect.
+ */
+ ipa_clear_endpoint_delay(pipe_connect->ipa_clnt_hdl);
+
+ /* Make sure pipes are empty before disconnecting it */
+ while (1) {
+ ret = sps_is_pipe_empty(pipe, &pipe_empty);
+ if (ret) {
+ log_event_err("%s: pipeempty fail %d\n",
+ __func__, ret);
+ goto err;
+ }
+ if (pipe_empty || !--timeout)
+ break;
+
+ /* Check again */
+ usleep_range(1000, 2000);
+ }
+ if (!pipe_empty) {
+ log_event_dbg("%s: Inject ZLT\n", __func__);
+ sps_pipe_inject_zlt(sps_connection->destination,
+ sps_connection->dest_pipe_index);
+
+ timeout = 0;
+ while (1) {
+ ret = sps_is_pipe_empty(pipe,
+ &pipe_empty);
+ if (ret)
+ goto err;
+
+ if (pipe_empty)
+ break;
+
+ timeout++;
+ /* Check again */
+ usleep_range(1000, 2000);
+ }
+ }
+ /* Call to disable IPA consumer endpoint */
+ ipa_disable_endpoint(pipe_connect->ipa_clnt_hdl);
+ sps_pipe_reset(ctx->h_bam,
+ pipe_connect->src_pipe_index);
+ }
+ }
+
+ /* Perform USB BAM reset */
+ msm_hw_bam_disable(1);
+ sps_device_reset(ctx->h_bam);
+ msm_hw_bam_disable(0);
+ log_event_dbg("%s: USB BAM reset done\n", __func__);
+ ret = 0;
+
+err:
+ mutex_unlock(&info[bam].suspend_resume_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(msm_do_bam_disable_enable);
+
bool msm_usb_bam_enable(enum usb_ctrl bam, bool bam_enable)
{
struct msm_usb_bam_data *usb_bam_data;
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index 35c8bb9..03bfd48 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -328,6 +328,7 @@
POWER_SUPPLY_ATTR(batt_full_current),
POWER_SUPPLY_ATTR(recharge_soc),
POWER_SUPPLY_ATTR(toggle_stat),
+ POWER_SUPPLY_ATTR(allow_hvdcp3),
/* Local extensions of type int64_t */
POWER_SUPPLY_ATTR(charge_counter_ext),
/* Properties of type `const char *' */
diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h
index 76bb974..4bd6c4f 100644
--- a/drivers/power/supply/qcom/fg-core.h
+++ b/drivers/power/supply/qcom/fg-core.h
@@ -13,6 +13,7 @@
#ifndef __FG_CORE_H__
#define __FG_CORE_H__
+#include <linux/alarmtimer.h>
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
@@ -249,6 +250,12 @@
SLOPE_LIMIT_NUM_COEFFS,
};
+enum esr_filter_status {
+ ROOM_TEMP = 1,
+ LOW_TEMP,
+ RELAX_TEMP,
+};
+
enum esr_timer_config {
TIMER_RETRY = 0,
TIMER_MAX,
@@ -296,6 +303,9 @@
int esr_broad_flt_upct;
int esr_tight_lt_flt_upct;
int esr_broad_lt_flt_upct;
+ int esr_flt_rt_switch_temp;
+ int esr_tight_rt_flt_upct;
+ int esr_broad_rt_flt_upct;
int slope_limit_temp;
int esr_pulse_thresh_ma;
int esr_meas_curr_ma;
@@ -434,6 +444,7 @@
struct mutex sram_rw_lock;
struct mutex charge_full_lock;
struct mutex qnovo_esr_ctrl_lock;
+ spinlock_t suspend_lock;
u32 batt_soc_base;
u32 batt_info_base;
u32 mem_if_base;
@@ -453,8 +464,10 @@
int delta_soc;
int last_msoc;
int last_recharge_volt_mv;
+ int delta_temp_irq_count;
int esr_timer_charging_default[NUM_ESR_TIMERS];
enum slope_limit_status slope_limit_sts;
+ enum esr_filter_status esr_flt_sts;
bool profile_available;
bool profile_loaded;
enum prof_load_status profile_load_status;
@@ -470,6 +483,7 @@
bool use_ima_single_mode;
bool use_dma;
bool qnovo_enable;
+ bool suspended;
struct completion soc_update;
struct completion soc_ready;
struct delayed_work profile_load_work;
@@ -477,6 +491,9 @@
struct delayed_work ttf_work;
struct delayed_work sram_dump_work;
struct delayed_work pl_enable_work;
+ struct work_struct esr_filter_work;
+ struct alarm esr_filter_alarm;
+ ktime_t last_delta_temp_time;
};
/* Debugfs data structures are below */
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index 420f2fd..5a9b8f6 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -2205,10 +2205,66 @@
return 0;
}
-static int fg_esr_filter_config(struct fg_chip *chip, int batt_temp)
+static int __fg_esr_filter_config(struct fg_chip *chip,
+ enum esr_filter_status esr_flt_sts)
{
- u8 esr_tight_lt_flt, esr_broad_lt_flt;
- bool cold_temp = false;
+ u8 esr_tight_flt, esr_broad_flt;
+ int esr_tight_flt_upct, esr_broad_flt_upct;
+ int rc;
+
+ if (esr_flt_sts == chip->esr_flt_sts)
+ return 0;
+
+ if (esr_flt_sts == ROOM_TEMP) {
+ esr_tight_flt_upct = chip->dt.esr_tight_flt_upct;
+ esr_broad_flt_upct = chip->dt.esr_broad_flt_upct;
+ } else if (esr_flt_sts == LOW_TEMP) {
+ esr_tight_flt_upct = chip->dt.esr_tight_lt_flt_upct;
+ esr_broad_flt_upct = chip->dt.esr_broad_lt_flt_upct;
+ } else if (esr_flt_sts == RELAX_TEMP) {
+ esr_tight_flt_upct = chip->dt.esr_tight_rt_flt_upct;
+ esr_broad_flt_upct = chip->dt.esr_broad_rt_flt_upct;
+ } else {
+ pr_err("Unknown esr filter config\n");
+ return 0;
+ }
+
+ fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER, esr_tight_flt_upct,
+ &esr_tight_flt);
+ rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_word,
+ chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_byte,
+ &esr_tight_flt,
+ chip->sp[FG_SRAM_ESR_TIGHT_FILTER].len, FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in writing ESR LT tight filter, rc=%d\n", rc);
+ return rc;
+ }
+
+ fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER, esr_broad_flt_upct,
+ &esr_broad_flt);
+ rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_word,
+ chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_byte,
+ &esr_broad_flt,
+ chip->sp[FG_SRAM_ESR_BROAD_FILTER].len, FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in writing ESR LT broad filter, rc=%d\n", rc);
+ return rc;
+ }
+
+ chip->esr_flt_sts = esr_flt_sts;
+ fg_dbg(chip, FG_STATUS, "applied ESR filter %d values\n", esr_flt_sts);
+ return 0;
+}
+
+#define DT_IRQ_COUNT 3
+#define DELTA_TEMP_IRQ_TIME_MS 300000
+#define ESR_FILTER_ALARM_TIME_MS 900000
+static int fg_esr_filter_config(struct fg_chip *chip, int batt_temp,
+ bool override)
+{
+ enum esr_filter_status esr_flt_sts = ROOM_TEMP;
+ bool qnovo_en, input_present, count_temp_irq = false;
+ s64 time_ms;
int rc;
/*
@@ -2218,6 +2274,47 @@
if (batt_temp < -210)
return 0;
+ qnovo_en = is_qnovo_en(chip);
+ input_present = is_input_present(chip);
+
+ /*
+ * If Qnovo is enabled, after hitting a lower battery temperature of
+ * say 6 C, count the delta battery temperature interrupts for a
+ * certain period of time when the battery temperature increases.
+ * Switch to relaxed filter coefficients once the temperature increase
+ * is qualified so that ESR accuracy can be improved.
+ */
+ if (qnovo_en && !override) {
+ if (input_present) {
+ if (chip->esr_flt_sts == RELAX_TEMP) {
+ /* do nothing */
+ return 0;
+ }
+
+ count_temp_irq = true;
+ if (chip->delta_temp_irq_count) {
+ /* Don't count when temperature is dropping. */
+ if (batt_temp <= chip->last_batt_temp)
+ count_temp_irq = false;
+ } else {
+ /*
+ * Starting point for counting. Check if the
+ * temperature is qualified.
+ */
+ if (batt_temp > chip->dt.esr_flt_rt_switch_temp)
+ count_temp_irq = false;
+ else
+ chip->last_delta_temp_time =
+ ktime_get();
+ }
+ } else {
+ chip->delta_temp_irq_count = 0;
+ rc = alarm_try_to_cancel(&chip->esr_filter_alarm);
+ if (rc < 0)
+ pr_err("Couldn't cancel esr_filter_alarm\n");
+ }
+ }
+
/*
* If battery temperature is lesser than 10 C (default), then apply the
* ESR low temperature tight and broad filter values to ESR room
@@ -2225,47 +2322,82 @@
* than 10 C, then apply back the room temperature ESR filter
* coefficients to ESR room temperature tight and broad filters.
*/
- if (batt_temp > chip->dt.esr_flt_switch_temp
- && chip->esr_flt_cold_temp_en) {
- fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER,
- chip->dt.esr_tight_flt_upct, &esr_tight_lt_flt);
- fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER,
- chip->dt.esr_broad_flt_upct, &esr_broad_lt_flt);
- } else if (batt_temp <= chip->dt.esr_flt_switch_temp
- && !chip->esr_flt_cold_temp_en) {
- fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER,
- chip->dt.esr_tight_lt_flt_upct, &esr_tight_lt_flt);
- fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER,
- chip->dt.esr_broad_lt_flt_upct, &esr_broad_lt_flt);
- cold_temp = true;
- } else {
- return 0;
+ if (batt_temp > chip->dt.esr_flt_switch_temp)
+ esr_flt_sts = ROOM_TEMP;
+ else
+ esr_flt_sts = LOW_TEMP;
+
+ if (count_temp_irq) {
+ time_ms = ktime_ms_delta(ktime_get(),
+ chip->last_delta_temp_time);
+ chip->delta_temp_irq_count++;
+ fg_dbg(chip, FG_STATUS, "dt_irq_count: %d\n",
+ chip->delta_temp_irq_count);
+
+ if (chip->delta_temp_irq_count >= DT_IRQ_COUNT
+ && time_ms <= DELTA_TEMP_IRQ_TIME_MS) {
+ fg_dbg(chip, FG_STATUS, "%d interrupts in %lld ms\n",
+ chip->delta_temp_irq_count, time_ms);
+ esr_flt_sts = RELAX_TEMP;
+ }
}
- rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_word,
- chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_byte,
- &esr_tight_lt_flt,
- chip->sp[FG_SRAM_ESR_TIGHT_FILTER].len, FG_IMA_DEFAULT);
- if (rc < 0) {
- pr_err("Error in writing ESR LT tight filter, rc=%d\n", rc);
+ rc = __fg_esr_filter_config(chip, esr_flt_sts);
+ if (rc < 0)
return rc;
- }
- rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_word,
- chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_byte,
- &esr_broad_lt_flt,
- chip->sp[FG_SRAM_ESR_BROAD_FILTER].len, FG_IMA_DEFAULT);
- if (rc < 0) {
- pr_err("Error in writing ESR LT broad filter, rc=%d\n", rc);
- return rc;
- }
+ if (esr_flt_sts == RELAX_TEMP)
+ alarm_start_relative(&chip->esr_filter_alarm,
+ ms_to_ktime(ESR_FILTER_ALARM_TIME_MS));
- chip->esr_flt_cold_temp_en = cold_temp;
- fg_dbg(chip, FG_STATUS, "applied %s ESR filter values\n",
- cold_temp ? "cold" : "normal");
return 0;
}
+#define FG_ESR_FILTER_RESTART_MS 60000
+static void esr_filter_work(struct work_struct *work)
+{
+ struct fg_chip *chip = container_of(work,
+ struct fg_chip, esr_filter_work);
+ int rc, batt_temp;
+
+ rc = fg_get_battery_temp(chip, &batt_temp);
+ if (rc < 0) {
+ pr_err("Error in getting batt_temp\n");
+ alarm_start_relative(&chip->esr_filter_alarm,
+ ms_to_ktime(FG_ESR_FILTER_RESTART_MS));
+ goto out;
+ }
+
+ rc = fg_esr_filter_config(chip, batt_temp, true);
+ if (rc < 0) {
+ pr_err("Error in configuring ESR filter rc:%d\n", rc);
+ alarm_start_relative(&chip->esr_filter_alarm,
+ ms_to_ktime(FG_ESR_FILTER_RESTART_MS));
+ }
+
+out:
+ chip->delta_temp_irq_count = 0;
+ pm_relax(chip->dev);
+}
+
+static enum alarmtimer_restart fg_esr_filter_alarm_cb(struct alarm *alarm,
+ ktime_t now)
+{
+ struct fg_chip *chip = container_of(alarm, struct fg_chip,
+ esr_filter_alarm);
+
+ fg_dbg(chip, FG_STATUS, "ESR filter alarm triggered %lld\n",
+ ktime_to_ms(now));
+ /*
+ * We cannot vote for awake votable here as that takes a mutex lock
+ * and this is executed in an atomic context.
+ */
+ pm_stay_awake(chip->dev);
+ schedule_work(&chip->esr_filter_work);
+
+ return ALARMTIMER_NORESTART;
+}
+
static int fg_esr_fcc_config(struct fg_chip *chip)
{
union power_supply_propval prop = {0, };
@@ -3891,6 +4023,14 @@
struct power_supply *psy = data;
struct fg_chip *chip = container_of(nb, struct fg_chip, nb);
+ spin_lock(&chip->suspend_lock);
+ if (chip->suspended) {
+ /* Return if we are still suspended */
+ spin_unlock(&chip->suspend_lock);
+ return NOTIFY_OK;
+ }
+ spin_unlock(&chip->suspend_lock);
+
if (event != PSY_EVENT_PROP_CHANGED)
return NOTIFY_OK;
@@ -4385,14 +4525,14 @@
union power_supply_propval prop = {0, };
int rc, batt_temp;
- fg_dbg(chip, FG_IRQ, "irq %d triggered\n", irq);
rc = fg_get_battery_temp(chip, &batt_temp);
if (rc < 0) {
pr_err("Error in getting batt_temp\n");
return IRQ_HANDLED;
}
+ fg_dbg(chip, FG_IRQ, "irq %d triggered bat_temp: %d\n", irq, batt_temp);
- rc = fg_esr_filter_config(chip, batt_temp);
+ rc = fg_esr_filter_config(chip, batt_temp, false);
if (rc < 0)
pr_err("Error in configuring ESR filter rc:%d\n", rc);
@@ -4793,8 +4933,11 @@
#define DEFAULT_ESR_FLT_TEMP_DECIDEGC 100
#define DEFAULT_ESR_TIGHT_FLT_UPCT 3907
#define DEFAULT_ESR_BROAD_FLT_UPCT 99610
-#define DEFAULT_ESR_TIGHT_LT_FLT_UPCT 48829
-#define DEFAULT_ESR_BROAD_LT_FLT_UPCT 148438
+#define DEFAULT_ESR_TIGHT_LT_FLT_UPCT 30000
+#define DEFAULT_ESR_BROAD_LT_FLT_UPCT 30000
+#define DEFAULT_ESR_FLT_RT_DECIDEGC 60
+#define DEFAULT_ESR_TIGHT_RT_FLT_UPCT 5860
+#define DEFAULT_ESR_BROAD_RT_FLT_UPCT 156250
#define DEFAULT_ESR_CLAMP_MOHMS 20
#define DEFAULT_ESR_PULSE_THRESH_MA 110
#define DEFAULT_ESR_MEAS_CURR_MA 120
@@ -5128,6 +5271,27 @@
else
chip->dt.esr_broad_lt_flt_upct = temp;
+ rc = of_property_read_u32(node, "qcom,fg-esr-rt-filter-switch-temp",
+ &temp);
+ if (rc < 0)
+ chip->dt.esr_flt_rt_switch_temp = DEFAULT_ESR_FLT_RT_DECIDEGC;
+ else
+ chip->dt.esr_flt_rt_switch_temp = temp;
+
+ rc = of_property_read_u32(node, "qcom,fg-esr-tight-rt-filter-micro-pct",
+ &temp);
+ if (rc < 0)
+ chip->dt.esr_tight_rt_flt_upct = DEFAULT_ESR_TIGHT_RT_FLT_UPCT;
+ else
+ chip->dt.esr_tight_rt_flt_upct = temp;
+
+ rc = of_property_read_u32(node, "qcom,fg-esr-broad-rt-filter-micro-pct",
+ &temp);
+ if (rc < 0)
+ chip->dt.esr_broad_rt_flt_upct = DEFAULT_ESR_BROAD_RT_FLT_UPCT;
+ else
+ chip->dt.esr_broad_rt_flt_upct = temp;
+
rc = fg_parse_slope_limit_coefficients(chip);
if (rc < 0)
pr_err("Error in parsing slope limit coeffs, rc=%d\n", rc);
@@ -5173,6 +5337,7 @@
devm_free_irq(chip->dev, fg_irqs[i].irq, chip);
}
+ alarm_try_to_cancel(&chip->esr_filter_alarm);
power_supply_unreg_notifier(&chip->nb);
debugfs_remove_recursive(chip->dfs_root);
if (chip->awake_votable)
@@ -5285,6 +5450,7 @@
mutex_init(&chip->ttf.lock);
mutex_init(&chip->charge_full_lock);
mutex_init(&chip->qnovo_esr_ctrl_lock);
+ spin_lock_init(&chip->suspend_lock);
init_completion(&chip->soc_update);
init_completion(&chip->soc_ready);
INIT_DELAYED_WORK(&chip->profile_load_work, profile_load_work);
@@ -5292,6 +5458,9 @@
INIT_WORK(&chip->status_change_work, status_change_work);
INIT_DELAYED_WORK(&chip->ttf_work, ttf_work);
INIT_DELAYED_WORK(&chip->sram_dump_work, sram_dump_work);
+ INIT_WORK(&chip->esr_filter_work, esr_filter_work);
+ alarm_init(&chip->esr_filter_alarm, ALARM_BOOTTIME,
+ fg_esr_filter_alarm_cb);
rc = fg_memif_init(chip);
if (rc < 0) {
@@ -5363,7 +5532,7 @@
if (!rc) {
pr_info("battery SOC:%d voltage: %duV temp: %d\n",
msoc, volt_uv, batt_temp);
- rc = fg_esr_filter_config(chip, batt_temp);
+ rc = fg_esr_filter_config(chip, batt_temp, false);
if (rc < 0)
pr_err("Error in configuring ESR filter rc:%d\n", rc);
}
@@ -5383,6 +5552,10 @@
struct fg_chip *chip = dev_get_drvdata(dev);
int rc;
+ spin_lock(&chip->suspend_lock);
+ chip->suspended = true;
+ spin_unlock(&chip->suspend_lock);
+
rc = fg_esr_timer_config(chip, true);
if (rc < 0)
pr_err("Error in configuring ESR timer, rc=%d\n", rc);
@@ -5406,6 +5579,16 @@
if (fg_sram_dump)
schedule_delayed_work(&chip->sram_dump_work,
msecs_to_jiffies(fg_sram_dump_period_ms));
+
+ if (!work_pending(&chip->status_change_work)) {
+ pm_stay_awake(chip->dev);
+ schedule_work(&chip->status_change_work);
+ }
+
+ spin_lock(&chip->suspend_lock);
+ chip->suspended = false;
+ spin_unlock(&chip->suspend_lock);
+
return 0;
}
diff --git a/drivers/power/supply/qcom/qpnp-smbcharger.c b/drivers/power/supply/qcom/qpnp-smbcharger.c
index f9c755c..403b670 100644
--- a/drivers/power/supply/qcom/qpnp-smbcharger.c
+++ b/drivers/power/supply/qcom/qpnp-smbcharger.c
@@ -144,6 +144,7 @@
bool vbat_above_headroom;
bool force_aicl_rerun;
bool hvdcp3_supported;
+ bool allow_hvdcp3_detection;
bool restricted_charging;
bool skip_usb_suspend_for_fake_battery;
bool hvdcp_not_supported;
@@ -5021,6 +5022,30 @@
return 0;
}
+static void smbchg_handle_hvdcp3_disable(struct smbchg_chip *chip)
+{
+ enum power_supply_type usb_supply_type;
+ char *usb_type_name = "NULL";
+
+ if (chip->allow_hvdcp3_detection)
+ return;
+
+ chip->pulse_cnt = 0;
+
+ if (is_hvdcp_present(chip)) {
+ smbchg_change_usb_supply_type(chip,
+ POWER_SUPPLY_TYPE_USB_HVDCP);
+ } else if (is_usb_present(chip)) {
+ read_usb_type(chip, &usb_type_name, &usb_supply_type);
+ smbchg_change_usb_supply_type(chip, usb_supply_type);
+ if (usb_supply_type == POWER_SUPPLY_TYPE_USB_DCP)
+ schedule_delayed_work(&chip->hvdcp_det_work,
+ msecs_to_jiffies(HVDCP_NOTIFY_MS));
+ } else {
+ smbchg_change_usb_supply_type(chip, POWER_SUPPLY_TYPE_UNKNOWN);
+ }
+}
+
static int smbchg_prepare_for_pulsing(struct smbchg_chip *chip)
{
int rc = 0;
@@ -5241,6 +5266,9 @@
pr_smb(PR_MISC, "HVDCP removed\n");
update_usb_status(chip, 0, 0);
}
+
+ smbchg_handle_hvdcp3_disable(chip);
+
return rc;
}
@@ -5425,6 +5453,8 @@
if (rc < 0)
pr_err("Couldn't retract HVDCP ICL vote rc=%d\n", rc);
+ smbchg_handle_hvdcp3_disable(chip);
+
return rc;
}
@@ -5713,6 +5743,7 @@
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED,
POWER_SUPPLY_PROP_RERUN_AICL,
POWER_SUPPLY_PROP_RESTRICTED_CHARGING,
+ POWER_SUPPLY_PROP_ALLOW_HVDCP3,
};
static int smbchg_battery_set_property(struct power_supply *psy,
@@ -5790,6 +5821,12 @@
if (chip->typec_psy)
update_typec_otg_status(chip, val->intval, false);
break;
+ case POWER_SUPPLY_PROP_ALLOW_HVDCP3:
+ if (chip->allow_hvdcp3_detection != val->intval) {
+ chip->allow_hvdcp3_detection = !!val->intval;
+ power_supply_changed(chip->batt_psy);
+ }
+ break;
default:
return -EINVAL;
}
@@ -5813,6 +5850,7 @@
case POWER_SUPPLY_PROP_DP_DM:
case POWER_SUPPLY_PROP_RERUN_AICL:
case POWER_SUPPLY_PROP_RESTRICTED_CHARGING:
+ case POWER_SUPPLY_PROP_ALLOW_HVDCP3:
rc = 1;
break;
default:
@@ -5913,6 +5951,9 @@
case POWER_SUPPLY_PROP_INPUT_CURRENT_NOW:
val->intval = smbchg_get_iusb(chip);
break;
+ case POWER_SUPPLY_PROP_ALLOW_HVDCP3:
+ val->intval = chip->allow_hvdcp3_detection;
+ break;
default:
return -EINVAL;
}
@@ -8247,6 +8288,7 @@
goto out;
}
}
+ chip->allow_hvdcp3_detection = true;
if (chip->cfg_chg_led_support &&
chip->schg_version == QPNP_SCHG_LITE) {
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 609005cc..7e1aa5d 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -3524,6 +3524,11 @@
chg->chg_freq.freq_removal);
if (vbus_rising) {
+ if (smblib_get_prop_dfp_mode(chg) != POWER_SUPPLY_TYPEC_NONE) {
+ chg->fake_usb_insertion = true;
+ return;
+ }
+
rc = smblib_request_dpdm(chg, true);
if (rc < 0)
smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc);
@@ -3537,6 +3542,11 @@
!chg->pd_active)
pr_err("APSD disabled on vbus rising without PD\n");
} else {
+ if (chg->fake_usb_insertion) {
+ chg->fake_usb_insertion = false;
+ return;
+ }
+
if (chg->wa_flags & BOOST_BACK_WA) {
data = chg->irq_info[SWITCH_POWER_OK_IRQ].irq_data;
if (data) {
@@ -3899,6 +3909,9 @@
int rc = 0;
u8 stat;
+ if (chg->fake_usb_insertion)
+ return IRQ_HANDLED;
+
rc = smblib_read(chg, APSD_STATUS_REG, &stat);
if (rc < 0) {
smblib_err(chg, "Couldn't read APSD_STATUS rc=%d\n", rc);
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index 141fa82..b9d1992 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -358,6 +358,7 @@
bool try_sink_active;
int boost_current_ua;
int temp_speed_reading_count;
+ bool fake_usb_insertion;
/* extcon for VBUS / ID notification to USB for uUSB */
struct extcon_dev *extcon;
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 8811386..46c8268 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -2636,48 +2636,6 @@
kfree(testbus);
}
-void ufs_qcom_read_custom_testbus(struct ufs_hba *hba)
-{
- struct ufs_qcom_host *host = ufshcd_get_variant(hba);
-
- host->testbus.select_major = TSTBUS_UTP_HCI;
- host->testbus.select_minor = 5;
- ufs_qcom_testbus_config(host);
- hba->tb_ah8_ctrl_0 = ufshcd_readl(hba, UFS_TEST_BUS);
-
- host->testbus.select_major = TSTBUS_UNIPRO;
- host->testbus.select_minor = 33;
- ufs_qcom_testbus_config(host);
- hba->tb_dme = ufshcd_readl(hba, UFS_TEST_BUS);
-
- host->testbus.select_major = TSTBUS_UNIPRO;
- host->testbus.select_minor = 37;
- ufs_qcom_testbus_config(host);
- hba->tb_pa_power_ctrl = ufshcd_readl(hba, UFS_TEST_BUS);
-
- host->testbus.select_major = TSTBUS_UNIPRO;
- host->testbus.select_minor = 55;
- ufs_qcom_testbus_config(host);
- hba->tb_pa_attr_1 = ufshcd_readl(hba, UFS_TEST_BUS);
-
- host->testbus.select_major = TSTBUS_UNIPRO;
- host->testbus.select_minor = 56;
- ufs_qcom_testbus_config(host);
- hba->tb_pa_attr_2 = ufshcd_readl(hba, UFS_TEST_BUS);
-}
-
-int ufs_qcom_read_pa_vs_status_reg1(struct ufs_hba *hba, u32 *pa_vs_status_reg1)
-{
- int err;
-
- err = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_VS_STATUS_REG1),
- pa_vs_status_reg1);
- if (err)
- dev_err(hba->dev, "%s: couldn't read PA_VS_STATUS_REG1 %d\n",
- __func__, err);
- return err;
-}
-
static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba, bool no_sleep)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
diff --git a/drivers/scsi/ufs/ufs-qcom.h b/drivers/scsi/ufs/ufs-qcom.h
index 1c48a85..a03ecb0 100644
--- a/drivers/scsi/ufs/ufs-qcom.h
+++ b/drivers/scsi/ufs/ufs-qcom.h
@@ -161,7 +161,6 @@
/* QUniPro Vendor specific attributes */
#define PA_VS_CONFIG_REG1 0x9000
-#define PA_VS_STATUS_REG1 0x9001
#define SAVECONFIGTIME_MODE_MASK 0x6000
#define PA_VS_CLK_CFG_REG 0x9004
@@ -397,9 +396,6 @@
void ufs_qcom_print_hw_debug_reg_all(struct ufs_hba *hba, void *priv,
void (*print_fn)(struct ufs_hba *hba, int offset, int num_regs,
char *str, void *priv));
-void ufs_qcom_read_custom_testbus(struct ufs_hba *hba);
-int ufs_qcom_read_pa_vs_status_reg1(struct ufs_hba *hba,
- u32 *pa_vs_status_reg1);
static inline bool ufs_qcom_cap_qunipro(struct ufs_qcom_host *host)
{
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index f3e79e3..d427fb3 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -54,8 +54,6 @@
#ifdef CONFIG_DEBUG_FS
-static u32 pa_vs_status_reg1;
-
static int ufshcd_tag_req_type(struct request *rq)
{
int rq_type = TS_WRITE;
@@ -630,23 +628,6 @@
entry->tag = tag;
entry->tstamp = ktime_get();
entry->outstanding_reqs = hba->outstanding_reqs;
- if (!strcmp(cmd_type, "custom")) {
- ufs_qcom_read_custom_testbus(hba);
- entry->tb_ah8_ctrl_0 = hba->tb_ah8_ctrl_0;
- entry->tb_dme = hba->tb_dme;
- entry->tb_pa_power_ctrl = hba->tb_pa_power_ctrl;
- entry->tb_pa_attr_1 = hba->tb_pa_attr_1;
- entry->tb_pa_attr_2 = hba->tb_pa_attr_2;
- entry->pa_vs_status_reg1 = pa_vs_status_reg1;
- pa_vs_status_reg1 = 0;
- } else {
- entry->tb_ah8_ctrl_0 = 0;
- entry->tb_dme = 0;
- entry->tb_pa_power_ctrl = 0;
- entry->tb_pa_attr_1 = 0;
- entry->tb_pa_attr_2 = 0;
- entry->pa_vs_status_reg1 = 0;
- }
entry->seq_num = hba->cmd_log.seq_num;
hba->cmd_log.seq_num++;
hba->cmd_log.pos =
@@ -686,14 +667,11 @@
pos = (pos + 1) % UFSHCD_MAX_CMD_LOGGING;
if (ktime_to_us(p->tstamp)) {
- pr_err("%s: %s: seq_no=%u lun=0x%x cmd_id=0x%02x lba=0x%llx txfer_len=%d tag=%u, doorbell=0x%x outstanding=0x%x idn=%d ah8_ctrl_0=0x%x dme=0x%x pa_power_ctrl=0x%x pa_attr_1=0x%x pa_attr_2=0x%x pa_vs_status_reg1=0x%x time=%lld us\n",
+ pr_err("%s: %s: seq_no=%u lun=0x%x cmd_id=0x%02x lba=0x%llx txfer_len=%d tag=%u, doorbell=0x%x outstanding=0x%x idn=%d time=%lld us\n",
p->cmd_type, p->str, p->seq_num,
p->lun, p->cmd_id, (unsigned long long)p->lba,
p->transfer_len, p->tag, p->doorbell,
p->outstanding_reqs, p->idn,
- p->tb_ah8_ctrl_0, p->tb_dme,
- p->tb_pa_power_ctrl, p->tb_pa_attr_1,
- p->tb_pa_attr_2, p->pa_vs_status_reg1,
ktime_to_us(p->tstamp));
usleep_range(1000, 1100);
}
@@ -10235,7 +10213,6 @@
if (ret)
goto out;
- ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
ufshcd_custom_cmd_log(hba, "waited-for-DB-clear");
/* scale down the gear before scaling down clocks */
@@ -10243,7 +10220,6 @@
ret = ufshcd_scale_gear(hba, false);
if (ret)
goto clk_scaling_unprepare;
- ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
ufshcd_custom_cmd_log(hba, "Gear-scaled-down");
}
@@ -10257,14 +10233,12 @@
if (ret)
/* link will be bad state so no need to scale_up_gear */
return ret;
- ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
ufshcd_custom_cmd_log(hba, "Hibern8-entered");
}
ret = ufshcd_scale_clks(hba, scale_up);
if (ret)
goto scale_up_gear;
- ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
ufshcd_custom_cmd_log(hba, "Clk-freq-switched");
if (ufshcd_is_auto_hibern8_supported(hba)) {
@@ -10272,7 +10246,6 @@
if (ret)
/* link will be bad state so no need to scale_up_gear */
return ret;
- ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
ufshcd_custom_cmd_log(hba, "Hibern8-Exited");
}
@@ -10283,7 +10256,6 @@
ufshcd_scale_clks(hba, false);
goto clk_scaling_unprepare;
}
- ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
ufshcd_custom_cmd_log(hba, "Gear-scaled-up");
}
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index a6b47aa..6e329c0 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -686,12 +686,6 @@
u32 seq_num;
unsigned int tag;
ktime_t tstamp;
- u32 tb_ah8_ctrl_0;
- u32 tb_dme;
- u32 tb_pa_power_ctrl;
- u32 tb_pa_attr_1;
- u32 tb_pa_attr_2;
- u32 pa_vs_status_reg1;
};
struct ufshcd_cmd_log {
@@ -1001,13 +995,6 @@
struct io_latency_state io_lat_write;
struct ufs_desc_size desc_size;
bool restore_needed;
-
- /* Custom test bus data */
- u32 tb_ah8_ctrl_0;
- u32 tb_dme;
- u32 tb_pa_power_ctrl;
- u32 tb_pa_attr_1;
- u32 tb_pa_attr_2;
};
static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba)
diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c
index d9cd0fa..baebb25 100644
--- a/drivers/soc/qcom/glink_smem_native_xprt.c
+++ b/drivers/soc/qcom/glink_smem_native_xprt.c
@@ -2548,7 +2548,7 @@
einfo->irq_line = irq_line;
rc = request_irq(irq_line, irq_handler,
- IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND | IRQF_SHARED,
+ IRQF_TRIGGER_RISING | IRQF_SHARED,
node->name, einfo);
if (rc < 0) {
pr_err("%s: request_irq on %d failed: %d\n", __func__, irq_line,
diff --git a/drivers/soc/qcom/memory_dump_v2.c b/drivers/soc/qcom/memory_dump_v2.c
index b76fe86..5912ff2 100644
--- a/drivers/soc/qcom/memory_dump_v2.c
+++ b/drivers/soc/qcom/memory_dump_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, 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
@@ -39,15 +39,6 @@
struct msm_dump_table *table;
};
-struct dump_vaddr_entry {
- uint32_t id;
- void *dump_vaddr;
-};
-
-struct msm_mem_dump_vaddr_tbl {
- uint8_t num_node;
- struct dump_vaddr_entry *entries;
-};
static struct msm_memory_dump memdump;
static struct msm_mem_dump_vaddr_tbl vaddr_tbl;
@@ -156,7 +147,7 @@
}
EXPORT_SYMBOL(msm_dump_data_register);
-void *get_msm_dump_ptr(enum msm_dump_data_ids id)
+struct dump_vaddr_entry *get_msm_dump_ptr(enum msm_dump_data_ids id)
{
int i;
@@ -174,7 +165,7 @@
if (i == vaddr_tbl.num_node)
return NULL;
- return (void *)vaddr_tbl.entries[i].dump_vaddr;
+ return &vaddr_tbl.entries[i];
}
EXPORT_SYMBOL(get_msm_dump_ptr);
@@ -333,6 +324,7 @@
} else if (vaddr_tbl.entries) {
vaddr_tbl.entries[i].id = id;
vaddr_tbl.entries[i].dump_vaddr = dump_vaddr;
+ vaddr_tbl.entries[i].dump_data_vaddr = dump_data;
i++;
}
}
diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c
index 3b6c0bd..360dbcf 100644
--- a/drivers/soc/qcom/peripheral-loader.c
+++ b/drivers/soc/qcom/peripheral-loader.c
@@ -141,28 +141,50 @@
static int pil_do_minidump(struct pil_desc *desc, void *ramdump_dev)
{
- struct md_ss_region __iomem *region_info;
+ struct md_ss_region __iomem *region_info_ss;
+ struct md_ss_region __iomem *region_info_pdr;
struct ramdump_segment *ramdump_segs, *s;
struct pil_priv *priv = desc->priv;
- void __iomem *subsys_segtable_base;
+ void __iomem *subsys_segtable_base_ss;
+ void __iomem *subsys_segtable_base_pdr;
u64 ss_region_ptr = 0;
- void __iomem *offset;
- int ss_mdump_seg_cnt;
+ void __iomem *offset_ss;
+ void __iomem *offset_pdr;
+ int ss_mdump_seg_cnt_ss = 0, ss_mdump_seg_cnt_pdr = 0, total_segs;
int ss_valid_seg_cnt;
int ret, i;
- ss_region_ptr = desc->minidump->md_ss_smem_regions_baseptr;
if (!ramdump_dev)
return -ENODEV;
- ss_mdump_seg_cnt = desc->minidump->ss_region_count;
- subsys_segtable_base =
+
+ ss_region_ptr = desc->minidump_ss->md_ss_smem_regions_baseptr;
+ ss_mdump_seg_cnt_ss = desc->minidump_ss->ss_region_count;
+ subsys_segtable_base_ss =
ioremap((unsigned long)ss_region_ptr,
- ss_mdump_seg_cnt * sizeof(struct md_ss_region));
- region_info = (struct md_ss_region __iomem *)subsys_segtable_base;
- if (!region_info)
+ ss_mdump_seg_cnt_ss * sizeof(struct md_ss_region));
+ region_info_ss =
+ (struct md_ss_region __iomem *)subsys_segtable_base_ss;
+ if (!region_info_ss)
return -EINVAL;
- pr_info("Minidump : Segments in minidump 0x%x\n", ss_mdump_seg_cnt);
- ramdump_segs = kcalloc(ss_mdump_seg_cnt,
+ pr_info("Minidump : SS Segments in minidump 0x%x\n",
+ ss_mdump_seg_cnt_ss);
+
+ if (desc->minidump_pdr &&
+ (desc->minidump_pdr->md_ss_enable_status == MD_SS_ENABLED)) {
+ ss_region_ptr = desc->minidump_pdr->md_ss_smem_regions_baseptr;
+ ss_mdump_seg_cnt_pdr = desc->minidump_pdr->ss_region_count;
+ subsys_segtable_base_pdr =
+ ioremap((unsigned long)ss_region_ptr,
+ ss_mdump_seg_cnt_pdr * sizeof(struct md_ss_region));
+ region_info_pdr =
+ (struct md_ss_region __iomem *)subsys_segtable_base_pdr;
+ if (!region_info_pdr)
+ return -EINVAL;
+ pr_info("Minidump : PDR Segments in minidump 0x%x\n",
+ ss_mdump_seg_cnt_pdr);
+ }
+ total_segs = ss_mdump_seg_cnt_ss + ss_mdump_seg_cnt_pdr;
+ ramdump_segs = kcalloc(total_segs,
sizeof(*ramdump_segs), GFP_KERNEL);
if (!ramdump_segs)
return -ENOMEM;
@@ -172,24 +194,47 @@
(priv->region_end - priv->region_start));
s = ramdump_segs;
- ss_valid_seg_cnt = ss_mdump_seg_cnt;
- for (i = 0; i < ss_mdump_seg_cnt; i++) {
- memcpy(&offset, ®ion_info, sizeof(region_info));
- offset = offset + sizeof(region_info->name) +
- sizeof(region_info->seq_num);
- if (__raw_readl(offset) == MD_REGION_VALID) {
- memcpy(&s->name, ®ion_info, sizeof(region_info));
- offset = offset + sizeof(region_info->md_valid);
- s->address = __raw_readl(offset);
- offset = offset +
- sizeof(region_info->region_base_address);
- s->size = __raw_readl(offset);
+ ss_valid_seg_cnt = total_segs;
+ for (i = 0; i < ss_mdump_seg_cnt_ss; i++) {
+ memcpy(&offset_ss, ®ion_info_ss, sizeof(region_info_ss));
+ offset_ss = offset_ss + sizeof(region_info_ss->name) +
+ sizeof(region_info_ss->seq_num);
+ if (__raw_readl(offset_ss) == MD_REGION_VALID) {
+ memcpy(&s->name, ®ion_info_ss,
+ sizeof(region_info_ss));
+ offset_ss = offset_ss +
+ sizeof(region_info_ss->md_valid);
+ s->address = __raw_readl(offset_ss);
+ offset_ss = offset_ss +
+ sizeof(region_info_ss->region_base_address);
+ s->size = __raw_readl(offset_ss);
pr_info("Minidump : Dumping segment %s with address 0x%lx and size 0x%x\n",
s->name, s->address, (unsigned int)s->size);
} else
ss_valid_seg_cnt--;
s++;
- region_info++;
+ region_info_ss++;
+ }
+
+ for (i = 0; i < ss_mdump_seg_cnt_pdr; i++) {
+ memcpy(&offset_pdr, ®ion_info_pdr, sizeof(region_info_pdr));
+ offset_pdr = offset_pdr + sizeof(region_info_pdr->name) +
+ sizeof(region_info_pdr->seq_num);
+ if (__raw_readl(offset_pdr) == MD_REGION_VALID) {
+ memcpy(&s->name, ®ion_info_pdr,
+ sizeof(region_info_pdr));
+ offset_pdr = offset_pdr +
+ sizeof(region_info_pdr->md_valid);
+ s->address = __raw_readl(offset_pdr);
+ offset_pdr = offset_pdr +
+ sizeof(region_info_pdr->region_base_address);
+ s->size = __raw_readl(offset_pdr);
+ pr_info("Minidump : Dumping segment %s with address 0x%lx and size 0x%x\n",
+ s->name, s->address, (unsigned int)s->size);
+ } else
+ ss_valid_seg_cnt--;
+ s++;
+ region_info_pdr++;
}
ret = do_minidump(ramdump_dev, ramdump_segs, ss_valid_seg_cnt);
kfree(ramdump_segs);
@@ -219,27 +264,27 @@
struct pil_seg *seg;
int count = 0, ret;
- if (desc->minidump) {
+ if (desc->minidump_ss) {
pr_info("Minidump : md_ss_toc->md_ss_toc_init is 0x%x\n",
- (unsigned int)desc->minidump->md_ss_toc_init);
+ (unsigned int)desc->minidump_ss->md_ss_toc_init);
pr_info("Minidump : md_ss_toc->md_ss_enable_status is 0x%x\n",
- (unsigned int)desc->minidump->md_ss_enable_status);
+ (unsigned int)desc->minidump_ss->md_ss_enable_status);
pr_info("Minidump : md_ss_toc->encryption_status is 0x%x\n",
- (unsigned int)desc->minidump->encryption_status);
+ (unsigned int)desc->minidump_ss->encryption_status);
pr_info("Minidump : md_ss_toc->ss_region_count is 0x%x\n",
- (unsigned int)desc->minidump->ss_region_count);
+ (unsigned int)desc->minidump_ss->ss_region_count);
pr_info("Minidump : md_ss_toc->md_ss_smem_regions_baseptr is 0x%x\n",
(unsigned int)
- desc->minidump->md_ss_smem_regions_baseptr);
+ desc->minidump_ss->md_ss_smem_regions_baseptr);
/**
* Collect minidump if SS ToC is valid and segment table
* is initialized in memory and encryption status is set.
*/
- if ((desc->minidump->md_ss_smem_regions_baseptr != 0) &&
- (desc->minidump->md_ss_toc_init == true) &&
- (desc->minidump->md_ss_enable_status ==
+ if ((desc->minidump_ss->md_ss_smem_regions_baseptr != 0) &&
+ (desc->minidump_ss->md_ss_toc_init == true) &&
+ (desc->minidump_ss->md_ss_enable_status ==
MD_SS_ENABLED)) {
- if (desc->minidump->encryption_status ==
+ if (desc->minidump_ss->encryption_status ==
MD_SS_ENCR_DONE) {
pr_info("Minidump : Dumping for %s\n",
desc->name);
@@ -1184,9 +1229,15 @@
else {
if (g_md_toc && g_md_toc->md_toc_init == true) {
ss_toc_addr = &g_md_toc->md_ss_toc[desc->minidump_id];
- pr_debug("Minidump : ss_toc_addr is %pa and desc->minidump_id is %d\n",
+ pr_debug("Minidump : ss_toc_addr for ss is %pa and desc->minidump_id is %d\n",
&ss_toc_addr, desc->minidump_id);
- memcpy(&desc->minidump, &ss_toc_addr,
+ memcpy(&desc->minidump_ss, &ss_toc_addr,
+ sizeof(ss_toc_addr));
+ ss_toc_addr =
+ &g_md_toc->md_ss_toc[desc->minidump_id + 1];
+ pr_debug("Minidump : ss_toc_addr for pdr is %pa and desc->minidump_id is %d\n",
+ &ss_toc_addr, desc->minidump_id);
+ memcpy(&desc->minidump_pdr, &ss_toc_addr,
sizeof(ss_toc_addr));
}
}
diff --git a/drivers/soc/qcom/peripheral-loader.h b/drivers/soc/qcom/peripheral-loader.h
index 78c00fe..6ea6b2a 100644
--- a/drivers/soc/qcom/peripheral-loader.h
+++ b/drivers/soc/qcom/peripheral-loader.h
@@ -64,7 +64,8 @@
bool signal_aop;
struct mbox_client cl;
struct mbox_chan *mbox;
- struct md_ss_toc *minidump;
+ struct md_ss_toc *minidump_ss;
+ struct md_ss_toc *minidump_pdr;
int minidump_id;
};
diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c
index 80dd2f7..6283477 100644
--- a/drivers/soc/qcom/pil-msa.c
+++ b/drivers/soc/qcom/pil-msa.c
@@ -582,7 +582,7 @@
if (ret)
goto err_clks;
- if (!pil->minidump || !pil->modem_ssr) {
+ if (!pil->minidump_ss || !pil->modem_ssr) {
/* Save state of modem debug register before full reset */
debug_val = readl_relaxed(drv->reg_base + QDSP6SS_DBG_CFG);
}
@@ -595,7 +595,7 @@
if (ret)
goto err_restart;
- if (!pil->minidump || !pil->modem_ssr) {
+ if (!pil->minidump_ss || !pil->modem_ssr) {
writel_relaxed(debug_val, drv->reg_base + QDSP6SS_DBG_CFG);
if (modem_dbg_cfg)
writel_relaxed(modem_dbg_cfg,
@@ -799,8 +799,13 @@
struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc);
int ret;
- if (!pil->minidump)
+ if (!pil->minidump_ss)
return 0;
+ if (pil->minidump_ss) {
+ if (pil->minidump_ss->md_ss_enable_status != MD_SS_ENABLED)
+ return 0;
+ }
+
/*
* Bring subsystem out of reset and enable required
* regulators and clocks.
@@ -809,7 +814,7 @@
if (ret)
return ret;
- if (pil->minidump) {
+ if (pil->minidump_ss) {
writel_relaxed(0x1, drv->reg_base + QDSP6SS_NMI_CFG);
/* Let write complete before proceeding */
mb();
@@ -832,7 +837,7 @@
*/
pr_info("Minidump: waiting encryption to complete\n");
msleep(10000);
- if (pil->minidump) {
+ if (pil->minidump_ss) {
writel_relaxed(0x2, drv->reg_base + QDSP6SS_NMI_CFG);
/* Let write complete before proceeding */
mb();
diff --git a/drivers/soc/qcom/rpmh_master_stat.c b/drivers/soc/qcom/rpmh_master_stat.c
index bc665fd..e696d4d 100644
--- a/drivers/soc/qcom/rpmh_master_stat.c
+++ b/drivers/soc/qcom/rpmh_master_stat.c
@@ -23,6 +23,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/uaccess.h>
+#include <asm/arch_timer.h>
#include <soc/qcom/smem.h>
#include "rpmh_master_stat.h"
@@ -102,6 +103,17 @@
struct msm_rpmh_master_stats *record,
const char *name)
{
+ /*
+ * If a master is in sleep when reading the sleep stats from SMEM
+ * adjust the accumulated sleep duration to show actual sleep time.
+ * This ensures that the displayed stats are real when used for
+ * the purpose of computing battery utilization.
+ */
+ if (record->last_entered > record->last_exited)
+ record->accumulated_duration +=
+ (arch_counter_get_cntvct()
+ - record->last_entered);
+
return snprintf(prvbuf, length, "%s\n\tVersion:0x%x\n"
"\tSleep Count:0x%x\n"
"\tSleep Last Entered At:0x%llx\n"
diff --git a/drivers/soc/qcom/scm.c b/drivers/soc/qcom/scm.c
index fec6f17..a64ddae 100644
--- a/drivers/soc/qcom/scm.c
+++ b/drivers/soc/qcom/scm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2018, 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
@@ -635,28 +635,7 @@
return 0;
}
-/**
- * scm_call2() - Invoke a syscall in the secure world
- * @fn_id: The function ID for this syscall
- * @desc: Descriptor structure containing arguments and return values
- *
- * Sends a command to the SCM and waits for the command to finish processing.
- * This should *only* be called in pre-emptible context.
- *
- * A note on cache maintenance:
- * Note that any buffers that are expected to be accessed by the secure world
- * must be flushed before invoking scm_call and invalidated in the cache
- * immediately after scm_call returns. An important point that must be noted
- * is that on ARMV8 architectures, invalidation actually also causes a dirty
- * cache line to be cleaned (flushed + unset-dirty-bit). Therefore it is of
- * paramount importance that the buffer be flushed before invoking scm_call2,
- * even if you don't care about the contents of that buffer.
- *
- * Note that cache maintenance on the argument buffer (desc->args) is taken care
- * of by scm_call2; however, callers are responsible for any other cached
- * buffers passed over to the secure world.
-*/
-int scm_call2(u32 fn_id, struct scm_desc *desc)
+static int __scm_call2(u32 fn_id, struct scm_desc *desc, bool retry)
{
int arglen = desc->arginfo & 0xf;
int ret, retry_count = 0;
@@ -670,7 +649,6 @@
return ret;
x0 = fn_id | scm_version_mask;
-
do {
mutex_lock(&scm_lock);
@@ -700,13 +678,15 @@
mutex_unlock(&scm_lmh_lock);
mutex_unlock(&scm_lock);
+ if (!retry)
+ goto out;
if (ret == SCM_V2_EBUSY)
msleep(SCM_EBUSY_WAIT_MS);
if (retry_count == 33)
pr_warn("scm: secure world has been busy for 1 second!\n");
- } while (ret == SCM_V2_EBUSY && (retry_count++ < SCM_EBUSY_MAX_RETRY));
-
+ } while (ret == SCM_V2_EBUSY && (retry_count++ < SCM_EBUSY_MAX_RETRY));
+out:
if (ret < 0)
pr_err("scm_call failed: func id %#llx, ret: %d, syscall returns: %#llx, %#llx, %#llx\n",
x0, ret, desc->ret[0], desc->ret[1], desc->ret[2]);
@@ -717,9 +697,47 @@
return scm_remap_error(ret);
return 0;
}
+
+/**
+ * scm_call2() - Invoke a syscall in the secure world
+ * @fn_id: The function ID for this syscall
+ * @desc: Descriptor structure containing arguments and return values
+ *
+ * Sends a command to the SCM and waits for the command to finish processing.
+ * This should *only* be called in pre-emptible context.
+ *
+ * A note on cache maintenance:
+ * Note that any buffers that are expected to be accessed by the secure world
+ * must be flushed before invoking scm_call and invalidated in the cache
+ * immediately after scm_call returns. An important point that must be noted
+ * is that on ARMV8 architectures, invalidation actually also causes a dirty
+ * cache line to be cleaned (flushed + unset-dirty-bit). Therefore it is of
+ * paramount importance that the buffer be flushed before invoking scm_call2,
+ * even if you don't care about the contents of that buffer.
+ *
+ * Note that cache maintenance on the argument buffer (desc->args) is taken care
+ * of by scm_call2; however, callers are responsible for any other cached
+ * buffers passed over to the secure world.
+ */
+int scm_call2(u32 fn_id, struct scm_desc *desc)
+{
+ return __scm_call2(fn_id, desc, true);
+}
EXPORT_SYMBOL(scm_call2);
/**
+ * scm_call2_noretry() - Invoke a syscall in the secure world
+ *
+ * Similar to scm_call2 except that there is no retry mechanism
+ * implemented.
+ */
+int scm_call2_noretry(u32 fn_id, struct scm_desc *desc)
+{
+ return __scm_call2(fn_id, desc, false);
+}
+EXPORT_SYMBOL(scm_call2_noretry);
+
+/**
* scm_call2_atomic() - Invoke a syscall in the secure world
*
* Similar to scm_call2 except that this can be invoked in atomic context.
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 8713f73..d8fcf5f 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -570,6 +570,7 @@
/* sdxpoorwills ID */
[334] = {SDX_CPU_SDXPOORWILLS, "SDXPOORWILLS"},
+ [335] = {SDX_CPU_SDXPOORWILLS, "SDXPOORWILLS"},
/* 9650 IDs */
[279] = {MSM_CPU_9650, "MDM9650"},
diff --git a/drivers/soc/qcom/watchdog_v2.c b/drivers/soc/qcom/watchdog_v2.c
index 5630dc0..b924bc8 100644
--- a/drivers/soc/qcom/watchdog_v2.c
+++ b/drivers/soc/qcom/watchdog_v2.c
@@ -93,6 +93,7 @@
bool timer_expired;
bool user_pet_complete;
+ unsigned int scandump_size;
};
/*
@@ -581,6 +582,41 @@
return;
}
+static void register_scan_dump(struct msm_watchdog_data *wdog_dd)
+{
+ static void *dump_addr;
+ int ret;
+ struct msm_dump_entry dump_entry;
+ struct msm_dump_data *dump_data;
+
+ if (!wdog_dd->scandump_size)
+ return;
+
+ dump_data = kzalloc(sizeof(struct msm_dump_data), GFP_KERNEL);
+ if (!dump_data)
+ return;
+ dump_addr = kzalloc(wdog_dd->scandump_size, GFP_KERNEL);
+ if (!dump_addr)
+ goto err0;
+
+ dump_data->addr = virt_to_phys(dump_addr);
+ dump_data->len = wdog_dd->scandump_size;
+ strlcpy(dump_data->name, "KSCANDUMP", sizeof(dump_data->name));
+
+ dump_entry.id = MSM_DUMP_DATA_SCANDUMP;
+ dump_entry.addr = virt_to_phys(dump_data);
+ ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry);
+ if (ret) {
+ pr_err("Registering scandump region failed\n");
+ goto err1;
+ }
+ return;
+err1:
+ kfree(dump_addr);
+err0:
+ kfree(dump_data);
+}
+
static void configure_scandump(struct msm_watchdog_data *wdog_dd)
{
int ret;
@@ -624,6 +660,8 @@
devm_kfree(wdog_dd->dev, cpu_data);
}
}
+
+ register_scan_dump(wdog_dd);
}
static int init_watchdog_sysfs(struct msm_watchdog_data *wdog_dd)
@@ -805,6 +843,11 @@
pdata->wakeup_irq_enable = of_property_read_bool(node,
"qcom,wakeup-enable");
+ if (of_property_read_u32(node, "qcom,scandump-size",
+ &pdata->scandump_size))
+ dev_info(&pdev->dev,
+ "No need to allocate memory for scandumps\n");
+
pdata->irq_ppi = irq_is_percpu(pdata->bark_irq);
dump_pdata(pdata);
return 0;
diff --git a/drivers/soc/qcom/wcnss/wcnss_vreg.c b/drivers/soc/qcom/wcnss/wcnss_vreg.c
index 29bc834..9d24ce1 100644
--- a/drivers/soc/qcom/wcnss/wcnss_vreg.c
+++ b/drivers/soc/qcom/wcnss/wcnss_vreg.c
@@ -193,27 +193,6 @@
}
}
-void wcnss_free_regulator(void)
-{
- int vreg_i;
-
- /* Free pronto voltage regulators from device node */
- for (vreg_i = 0; vreg_i < PRONTO_REGULATORS; vreg_i++) {
- if (pronto_vregs[vreg_i].state) {
- regulator_put(pronto_vregs[vreg_i].regulator);
- pronto_vregs[vreg_i].state = VREG_NULL_CONFIG;
- }
- }
-
- /* Free IRIS voltage regulators from device node */
- for (vreg_i = 0; vreg_i < IRIS_REGULATORS; vreg_i++) {
- if (iris_vregs[vreg_i].state) {
- regulator_put(iris_vregs[vreg_i].regulator);
- iris_vregs[vreg_i].state = VREG_NULL_CONFIG;
- }
- }
-}
-
static int
wcnss_dt_parse_vreg_level(struct device *dev, int index,
const char *current_vreg_name, const char *vreg_name,
@@ -256,13 +235,14 @@
/* Parse pronto voltage regulators from device node */
for (vreg_i = 0; vreg_i < PRONTO_REGULATORS; vreg_i++) {
pronto_vregs[vreg_i].regulator =
- regulator_get(dev, pronto_vregs[vreg_i].name);
+ devm_regulator_get_optional(dev,
+ pronto_vregs[vreg_i].name);
if (IS_ERR(pronto_vregs[vreg_i].regulator)) {
if (pronto_vregs[vreg_i].required) {
rc = PTR_ERR(pronto_vregs[vreg_i].regulator);
dev_err(dev, "regulator get of %s failed (%d)\n",
pronto_vregs[vreg_i].name, rc);
- goto wcnss_vreg_get_err;
+ return rc;
} else {
dev_dbg(dev, "Skip optional regulator configuration: %s\n",
pronto_vregs[vreg_i].name);
@@ -270,27 +250,28 @@
}
}
- pronto_vregs[vreg_i].state |= VREG_GET_REGULATOR_MASK;
rc = wcnss_dt_parse_vreg_level(dev, vreg_i,
pronto_vregs[vreg_i].curr,
pronto_vregs[vreg_i].volt,
wlan_config->pronto_vlevel);
if (rc) {
dev_err(dev, "error reading voltage-level property\n");
- goto wcnss_vreg_get_err;
+ return rc;
}
+ pronto_vregs[vreg_i].state |= VREG_GET_REGULATOR_MASK;
}
/* Parse iris voltage regulators from device node */
for (vreg_i = 0; vreg_i < IRIS_REGULATORS; vreg_i++) {
iris_vregs[vreg_i].regulator =
- regulator_get(dev, iris_vregs[vreg_i].name);
+ devm_regulator_get_optional(dev,
+ iris_vregs[vreg_i].name);
if (IS_ERR(iris_vregs[vreg_i].regulator)) {
if (iris_vregs[vreg_i].required) {
rc = PTR_ERR(iris_vregs[vreg_i].regulator);
dev_err(dev, "regulator get of %s failed (%d)\n",
iris_vregs[vreg_i].name, rc);
- goto wcnss_vreg_get_err;
+ return rc;
} else {
dev_dbg(dev, "Skip optional regulator configuration: %s\n",
iris_vregs[vreg_i].name);
@@ -298,22 +279,18 @@
}
}
- iris_vregs[vreg_i].state |= VREG_GET_REGULATOR_MASK;
rc = wcnss_dt_parse_vreg_level(dev, vreg_i,
iris_vregs[vreg_i].curr,
iris_vregs[vreg_i].volt,
wlan_config->iris_vlevel);
if (rc) {
dev_err(dev, "error reading voltage-level property\n");
- goto wcnss_vreg_get_err;
+ return rc;
}
+ iris_vregs[vreg_i].state |= VREG_GET_REGULATOR_MASK;
}
return 0;
-
-wcnss_vreg_get_err:
- wcnss_free_regulator();
- return rc;
}
void wcnss_iris_reset(u32 reg, void __iomem *pmu_conf_reg)
diff --git a/drivers/soc/qcom/wcnss/wcnss_wlan.c b/drivers/soc/qcom/wcnss/wcnss_wlan.c
index 6d5ee04..481dbd0 100644
--- a/drivers/soc/qcom/wcnss/wcnss_wlan.c
+++ b/drivers/soc/qcom/wcnss/wcnss_wlan.c
@@ -3524,7 +3524,6 @@
static int
wcnss_wlan_remove(struct platform_device *pdev)
{
- wcnss_free_regulator();
if (penv->wcnss_notif_hdle)
subsys_notif_unregister_notifier(penv->wcnss_notif_hdle, &wnb);
wcnss_cdev_unregister(pdev);
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index 6a3c06f..5c0022e 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -2232,6 +2232,71 @@
static int qpnp_adc_tm_read_status(struct qpnp_adc_tm_chip *chip)
{
+ int rc = 0, sensor_notify_num = 0, i = 0, sensor_num = 0;
+ unsigned long flags;
+
+ if (qpnp_adc_tm_is_valid(chip))
+ return -ENODEV;
+
+ mutex_lock(&chip->adc->adc_lock);
+
+ rc = qpnp_adc_tm_req_sts_check(chip);
+ if (rc) {
+ pr_err("adc-tm-tm req sts check failed with %d\n", rc);
+ goto fail;
+ }
+
+ if (chip->th_info.adc_tm_high_enable) {
+ spin_lock_irqsave(&chip->th_info.adc_tm_high_lock, flags);
+ sensor_notify_num = chip->th_info.adc_tm_high_enable;
+ chip->th_info.adc_tm_high_enable = 0;
+ spin_unlock_irqrestore(&chip->th_info.adc_tm_high_lock, flags);
+ while (i < chip->max_channels_available) {
+ if ((sensor_notify_num & 0x1) == 1) {
+ sensor_num = i;
+ rc = qpnp_adc_tm_disable_rearm_high_thresholds(
+ chip, sensor_num);
+ if (rc < 0) {
+ pr_err("rearm threshold failed\n");
+ goto fail;
+ }
+ }
+ sensor_notify_num >>= 1;
+ i++;
+ }
+ }
+
+ if (chip->th_info.adc_tm_low_enable) {
+ spin_lock_irqsave(&chip->th_info.adc_tm_low_lock, flags);
+ sensor_notify_num = chip->th_info.adc_tm_low_enable;
+ chip->th_info.adc_tm_low_enable = 0;
+ spin_unlock_irqrestore(&chip->th_info.adc_tm_low_lock, flags);
+ i = 0;
+ while (i < chip->max_channels_available) {
+ if ((sensor_notify_num & 0x1) == 1) {
+ sensor_num = i;
+ rc = qpnp_adc_tm_disable_rearm_low_thresholds(
+ chip, sensor_num);
+ if (rc < 0) {
+ pr_err("rearm threshold failed\n");
+ goto fail;
+ }
+ }
+ sensor_notify_num >>= 1;
+ i++;
+ }
+ }
+
+fail:
+ mutex_unlock(&chip->adc->adc_lock);
+ if (rc < 0)
+ atomic_dec(&chip->wq_cnt);
+
+ return rc;
+}
+
+static int qpnp_adc_tm_hc_read_status(struct qpnp_adc_tm_chip *chip)
+{
int rc = 0, sensor_num = 0;
if (qpnp_adc_tm_is_valid(chip))
@@ -2300,9 +2365,15 @@
pr_debug("thr:0x%x\n", chip->th_info.adc_tm_high_enable);
- rc = qpnp_adc_tm_read_status(chip);
- if (rc < 0)
- pr_err("adc-tm high thr work failed\n");
+ if (!chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_read_status(chip);
+ if (rc < 0)
+ pr_err("adc-tm high thr work failed\n");
+ } else {
+ rc = qpnp_adc_tm_hc_read_status(chip);
+ if (rc < 0)
+ pr_err("adc-tm-hc high thr work failed\n");
+ }
}
static irqreturn_t qpnp_adc_tm_high_thr_isr(int irq, void *data)
@@ -2406,9 +2477,15 @@
pr_debug("thr:0x%x\n", chip->th_info.adc_tm_low_enable);
- rc = qpnp_adc_tm_read_status(chip);
- if (rc < 0)
- pr_err("adc-tm low thr work failed\n");
+ if (!chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_read_status(chip);
+ if (rc < 0)
+ pr_err("adc-tm low thr work failed\n");
+ } else {
+ rc = qpnp_adc_tm_hc_read_status(chip);
+ if (rc < 0)
+ pr_err("adc-tm-hc low thr work failed\n");
+ }
}
static irqreturn_t qpnp_adc_tm_low_thr_isr(int irq, void *data)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index d1a63da..2095579 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -405,7 +405,7 @@
evt = dwc->ev_buf;
dwc3_trace(trace_dwc3_core,
- "Event buf %p dma %08llx length %d\n",
+ "Event buf %pK dma %08llx length %d\n",
evt->buf, (unsigned long long) evt->dma,
evt->length);
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index ded62f1..defb438 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -792,7 +792,7 @@
list_add_tail(&req_complete->list_item, &mdwc->req_complete_list);
request->complete = dwc3_msm_req_complete_func;
- dev_vdbg(dwc->dev, "%s: queing request %p to ep %s length %d\n",
+ dev_vdbg(dwc->dev, "%s: queing request %pK to ep %s length %d\n",
__func__, request, ep->name, request->length);
size = dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTSIZ(0));
dbm_event_buffer_config(mdwc->dbm,
@@ -992,7 +992,7 @@
dev_dbg(mdwc->dev, "Failed to get GSI DBL address MSB\n");
offset = dwc3_trb_dma_offset(dep, &dep->trb_pool[num_trbs-1]);
- dev_dbg(mdwc->dev, "Writing link TRB addr: %pa to %p (%x) for ep:%s\n",
+ dev_dbg(mdwc->dev, "Writing link TRB addr: %pa to %pK (%x) for ep:%s\n",
&offset, gsi_dbl_address_lsb, request->db_reg_phs_addr_lsb,
ep->name);
@@ -1959,7 +1959,7 @@
if (!evt)
break;
- dev_dbg(mdwc->dev, "Evt buf %p dma %08llx length %d\n",
+ dev_dbg(mdwc->dev, "Evt buf %pK dma %08llx length %d\n",
evt->buf, (unsigned long long) evt->dma,
evt->length);
memset(evt->buf, 0, evt->length);
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 8cf49fa..381ad49 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -240,7 +240,7 @@
spin_lock_irqsave(&dwc->lock, flags);
if (!dep->endpoint.desc) {
dwc3_trace(trace_dwc3_ep0,
- "trying to queue request %p to disabled %s",
+ "trying to queue request %pK to disabled %s",
request, dep->name);
ret = -ESHUTDOWN;
goto out;
@@ -265,7 +265,7 @@
}
dwc3_trace(trace_dwc3_ep0,
- "queueing request %p to %s length %d state '%s'",
+ "queueing request %pK to %s length %d state '%s'",
request, dep->name, request->length,
dwc3_ep0_state_string(dwc->ep0state));
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index f90d0c9..3c38ee1 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -937,7 +937,7 @@
struct usb_gadget *gadget = &dwc->gadget;
enum usb_device_speed speed = gadget->speed;
- dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s",
+ dwc3_trace(trace_dwc3_gadget, "%s: req %pK dma %08llx length %d%s%s",
dep->name, req, (unsigned long long) dma,
length, chain ? " chain" : "");
@@ -1293,7 +1293,7 @@
if (!dep->endpoint.desc) {
dwc3_trace(trace_dwc3_gadget,
- "trying to queue request %p to disabled %s",
+ "trying to queue request %pK to disabled %s",
&req->request, dep->endpoint.name);
return -ESHUTDOWN;
}
@@ -1432,13 +1432,13 @@
spin_lock_irqsave(&dwc->lock, flags);
if (!dep->endpoint.desc) {
- dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
+ dev_dbg(dwc->dev, "trying to queue request %pK to disabled %s\n",
request, ep->name);
ret = -ESHUTDOWN;
goto out;
}
- if (WARN(req->dep != dep, "request %p belongs to '%s'\n",
+ if (WARN(req->dep != dep, "request %pK belongs to '%s'\n",
request, req->dep->name)) {
ret = -EINVAL;
goto out;
diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
index 1f75b58..bc2a8bc 100644
--- a/drivers/usb/dwc3/io.h
+++ b/drivers/usb/dwc3/io.h
@@ -40,7 +40,7 @@
* documentation, so we revert it back to the proper addresses, the
* same way they are described on SNPS documentation
*/
- dwc3_trace(trace_dwc3_readl, "addr %p value %08x",
+ dwc3_trace(trace_dwc3_readl, "addr %pK value %08x",
base - DWC3_GLOBALS_REGS_START + offset, value);
return value;
@@ -60,7 +60,7 @@
* documentation, so we revert it back to the proper addresses, the
* same way they are described on SNPS documentation
*/
- dwc3_trace(trace_dwc3_writel, "addr %p value %08x",
+ dwc3_trace(trace_dwc3_writel, "addr %pK value %08x",
base - DWC3_GLOBALS_REGS_START + offset, value);
}
diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h
index 88f5fb8..d9873ad 100644
--- a/drivers/usb/dwc3/trace.h
+++ b/drivers/usb/dwc3/trace.h
@@ -137,7 +137,7 @@
__entry->short_not_ok = req->request.short_not_ok;
__entry->no_interrupt = req->request.no_interrupt;
),
- TP_printk("%s: req %p length %u/%u %s%s%s ==> %d",
+ TP_printk("%s: req %pK length %u/%u %s%s%s ==> %d",
__get_str(name), __entry->req, __entry->actual, __entry->length,
__entry->zero ? "Z" : "z",
__entry->short_not_ok ? "S" : "s",
@@ -253,7 +253,7 @@
__entry->size = trb->size;
__entry->ctrl = trb->ctrl;
),
- TP_printk("%s: %d/%d trb %p buf %08x%08x size %d ctrl %08x (%c%c%c%c:%c%c:%s)",
+ TP_printk("%s: %d/%d trb %pK buf %08x%08x size %d ctrl %08x (%c%c%c%c:%c%c:%s)",
__get_str(name), __entry->queued, __entry->allocated,
__entry->trb, __entry->bph, __entry->bpl,
__entry->size, __entry->ctrl,
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index f6fc30a..ab2c623 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -20,6 +20,7 @@
#include <linux/usb/composite.h>
#include <linux/usb/otg.h>
+#include <linux/usb/msm_hsusb.h>
#include <asm/unaligned.h>
#include "u_os_desc.h"
@@ -856,6 +857,11 @@
DBG(cdev, "reset config\n");
+ if (!cdev->config) {
+ pr_err("%s:cdev->config is already NULL\n", __func__);
+ return;
+ }
+
list_for_each_entry(f, &cdev->config->functions, list) {
if (f->disable)
f->disable(f);
@@ -1120,8 +1126,14 @@
spin_lock_irqsave(&cdev->lock, flags);
- if (cdev->config == config)
+ if (cdev->config == config) {
+ if (cdev->gadget->is_chipidea && !cdev->suspended) {
+ spin_unlock_irqrestore(&cdev->lock, flags);
+ msm_do_bam_disable_enable(CI_CTRL);
+ spin_lock_irqsave(&cdev->lock, flags);
+ }
reset_config(cdev);
+ }
spin_unlock_irqrestore(&cdev->lock, flags);
@@ -2161,8 +2173,14 @@
* disconnect callbacks?
*/
spin_lock_irqsave(&cdev->lock, flags);
- if (cdev->config)
+ if (cdev->config) {
+ if (gadget->is_chipidea && !cdev->suspended) {
+ spin_unlock_irqrestore(&cdev->lock, flags);
+ msm_do_bam_disable_enable(CI_CTRL);
+ spin_lock_irqsave(&cdev->lock, flags);
+ }
reset_config(cdev);
+ }
if (cdev->driver->disconnect)
cdev->driver->disconnect(cdev);
if (cdev->delayed_status != 0) {
diff --git a/drivers/usb/gadget/function/f_audio_source.c b/drivers/usb/gadget/function/f_audio_source.c
index aaa15da..3f60bf7 100644
--- a/drivers/usb/gadget/function/f_audio_source.c
+++ b/drivers/usb/gadget/function/f_audio_source.c
@@ -337,14 +337,15 @@
/*--------------------------------------------------------------------------*/
-static struct usb_request *audio_request_new(struct usb_ep *ep, int buffer_size)
+static struct usb_request *audio_request_new(struct usb_ep *ep, int buffer_size,
+ size_t extra_buf_alloc)
{
struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL);
if (!req)
return NULL;
- req->buf = kmalloc(buffer_size, GFP_KERNEL);
+ req->buf = kmalloc(buffer_size + extra_buf_alloc, GFP_KERNEL);
if (!req->buf) {
usb_ep_free_request(ep, req);
return NULL;
@@ -748,7 +749,8 @@
f->ss_descriptors = ss_audio_desc;
for (i = 0, status = 0; i < IN_EP_REQ_COUNT && status == 0; i++) {
- req = audio_request_new(ep, IN_EP_MAX_PACKET_SIZE);
+ req = audio_request_new(ep, IN_EP_MAX_PACKET_SIZE,
+ cdev->gadget->extra_buf_alloc);
if (req) {
req->context = audio;
req->complete = audio_data_complete;
diff --git a/drivers/usb/gadget/function/f_ccid.c b/drivers/usb/gadget/function/f_ccid.c
index dbf72ab..76b181a 100644
--- a/drivers/usb/gadget/function/f_ccid.c
+++ b/drivers/usb/gadget/function/f_ccid.c
@@ -337,7 +337,8 @@
}
static struct usb_request *
-ccid_request_alloc(struct usb_ep *ep, size_t len, gfp_t kmalloc_flags)
+ccid_request_alloc(struct usb_ep *ep, size_t len, size_t extra_buf_alloc,
+ gfp_t kmalloc_flags)
{
struct usb_request *req;
@@ -345,7 +346,7 @@
if (req != NULL) {
req->length = len;
- req->buf = kmalloc(len, kmalloc_flags);
+ req->buf = kmalloc(len + extra_buf_alloc, kmalloc_flags);
if (req->buf == NULL) {
usb_ep_free_request(ep, req);
req = NULL;
@@ -467,7 +468,8 @@
int i;
ccid_dev->notify_req = ccid_request_alloc(ccid_dev->notify,
- sizeof(struct usb_ccid_notification), GFP_ATOMIC);
+ sizeof(struct usb_ccid_notification),
+ cdev->gadget->extra_buf_alloc, GFP_ATOMIC);
if (IS_ERR(ccid_dev->notify_req)) {
pr_err("%s: unable to allocate memory for notify req\n",
__func__);
@@ -478,7 +480,7 @@
/* now allocate requests for our endpoints */
req = ccid_request_alloc(ccid_dev->out, BULK_OUT_BUFFER_SIZE,
- GFP_ATOMIC);
+ 0, GFP_ATOMIC);
if (IS_ERR(req)) {
pr_err("%s: unable to allocate memory for out req\n",
__func__);
@@ -491,7 +493,7 @@
for (i = 0; i < TX_REQ_MAX; i++) {
req = ccid_request_alloc(ccid_dev->in, BULK_IN_BUFFER_SIZE,
- GFP_ATOMIC);
+ cdev->gadget->extra_buf_alloc, GFP_ATOMIC);
if (IS_ERR(req)) {
pr_err("%s: unable to allocate memory for in req\n",
__func__);
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c
index 25b2cdd..1979156 100644
--- a/drivers/usb/gadget/function/f_midi.c
+++ b/drivers/usb/gadget/function/f_midi.c
@@ -218,9 +218,23 @@
};
static inline struct usb_request *midi_alloc_ep_req(struct usb_ep *ep,
- unsigned length)
+ unsigned int length, size_t extra_buf_alloc)
{
- return alloc_ep_req(ep, length);
+ struct usb_request *req;
+
+ req = usb_ep_alloc_request(ep, GFP_ATOMIC);
+ if (!req)
+ return NULL;
+
+ req->length = usb_endpoint_dir_out(ep->desc) ?
+ usb_ep_align(ep, length) : length;
+ req->buf = kmalloc(req->length + extra_buf_alloc, GFP_ATOMIC);
+ if (!req->buf) {
+ usb_ep_free_request(ep, req);
+ return NULL;
+ }
+
+ return req;
}
static const uint8_t f_midi_cin_length[] = {
@@ -374,7 +388,8 @@
/* pre-allocate write usb requests to use on f_midi_transmit. */
while (kfifo_avail(&midi->in_req_fifo)) {
struct usb_request *req =
- midi_alloc_ep_req(midi->in_ep, midi->buflen);
+ midi_alloc_ep_req(midi->in_ep, midi->buflen,
+ midi->gadget->extra_buf_alloc);
if (req == NULL)
return -ENOMEM;
@@ -388,7 +403,7 @@
/* allocate a bunch of read buffers and queue them all at once. */
for (i = 0; i < midi->qlen && err == 0; i++) {
struct usb_request *req =
- midi_alloc_ep_req(midi->out_ep, midi->buflen);
+ midi_alloc_ep_req(midi->out_ep, midi->buflen, 0);
if (req == NULL)
return -ENOMEM;
diff --git a/drivers/usb/gadget/function/u_qdss.c b/drivers/usb/gadget/function/u_qdss.c
index d445e51..6e60258 100644
--- a/drivers/usb/gadget/function/u_qdss.c
+++ b/drivers/usb/gadget/function/u_qdss.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -20,6 +20,7 @@
{
struct usb_request *req = NULL;
struct f_qdss *qdss = data_ep->driver_data;
+ struct usb_gadget *gadget = qdss->gadget;
u32 sps_params = 0;
pr_debug("send_sps_req\n");
@@ -30,9 +31,17 @@
return -ENOMEM;
}
- req->length = 32*1024;
- sps_params = MSM_SPS_MODE | MSM_DISABLE_WB |
- qdss->bam_info.usb_bam_pipe_idx;
+ if (!gadget->is_chipidea) {
+ req->length = 32*1024;
+ sps_params = MSM_SPS_MODE | MSM_DISABLE_WB |
+ qdss->bam_info.usb_bam_pipe_idx;
+ } else {
+ /* non DWC3 BAM requires req->length to be 0 */
+ req->length = 0;
+ sps_params = (MSM_SPS_MODE | qdss->bam_info.usb_bam_pipe_idx |
+ MSM_VENDOR_ID) & ~MSM_IS_FINITE_TRANSFER;
+ }
+
req->udc_priv = sps_params;
qdss->endless_req = req;
@@ -107,10 +116,12 @@
NULL, bam_info.data_fifo, NULL);
alloc_sps_req(qdss->port.data);
- msm_data_fifo_config(qdss->port.data,
- bam_info.data_fifo->iova,
- bam_info.data_fifo->size,
- bam_info.usb_bam_pipe_idx);
+ if (!gadget->is_chipidea)
+ msm_data_fifo_config(qdss->port.data,
+ bam_info.data_fifo->iova,
+ bam_info.data_fifo->size,
+ bam_info.usb_bam_pipe_idx);
+
init_data(qdss->port.data);
res = usb_bam_connect(usb_bam_type, idx,
@@ -132,8 +143,14 @@
static int init_data(struct usb_ep *ep)
{
struct f_qdss *qdss = ep->driver_data;
+ struct usb_gadget *gadget = qdss->gadget;
int res = 0;
+ if (gadget->is_chipidea) {
+ pr_debug("QDSS is used with non DWC3 core\n");
+ return res;
+ }
+
pr_debug("init_data\n");
res = msm_ep_config(ep, qdss->endless_req);
@@ -145,8 +162,13 @@
int uninit_data(struct usb_ep *ep)
{
+ struct f_qdss *qdss = ep->driver_data;
+ struct usb_gadget *gadget = qdss->gadget;
int res = 0;
+ if (gadget->is_chipidea)
+ return res;
+
pr_err("uninit_data\n");
res = msm_ep_unconfig(ep);
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 3ff6468..73ab200 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -89,7 +89,7 @@
static void __maybe_unused
dbg_qtd(const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
{
- ehci_dbg(ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
+ ehci_dbg(ehci, "%s td %pK n%08x %08x t%08x p0=%08x\n", label, qtd,
hc32_to_cpup(ehci, &qtd->hw_next),
hc32_to_cpup(ehci, &qtd->hw_alt_next),
hc32_to_cpup(ehci, &qtd->hw_token),
@@ -107,7 +107,7 @@
{
struct ehci_qh_hw *hw = qh->hw;
- ehci_dbg(ehci, "%s qh %p n%08x info %x %x qtd %x\n", label,
+ ehci_dbg(ehci, "%s qh %pK n%08x info %x %x qtd %x\n", label,
qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
dbg_qtd("overlay", ehci, (struct ehci_qtd *) &hw->hw_qtd_next);
}
@@ -115,7 +115,7 @@
static void __maybe_unused
dbg_itd(const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd)
{
- ehci_dbg(ehci, "%s [%d] itd %p, next %08x, urb %p\n",
+ ehci_dbg(ehci, "%s [%d] itd %pK, next %08x, urb %p\n",
label, itd->frame, itd, hc32_to_cpu(ehci, itd->hw_next),
itd->urb);
ehci_dbg(ehci,
@@ -146,7 +146,7 @@
static void __maybe_unused
dbg_sitd(const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd)
{
- ehci_dbg(ehci, "%s [%d] sitd %p, next %08x, urb %p\n",
+ ehci_dbg(ehci, "%s [%d] sitd %pK, next %08x, urb %p\n",
label, sitd->frame, sitd, hc32_to_cpu(ehci, sitd->hw_next),
sitd->urb);
ehci_dbg(ehci,
@@ -406,7 +406,7 @@
scratch = hc32_to_cpup(ehci, &hw->hw_info1);
hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &hw->hw_current) : 0;
temp = scnprintf(next, size,
- "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)"
+ "qh/%pK dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)"
" [cur %08x next %08x buf[0] %08x]",
qh, scratch & 0x007f,
speed_char (scratch),
@@ -454,7 +454,7 @@
break;
}
temp = scnprintf(next, size,
- "\n\t%p%c%s len=%d %08x urb %p"
+ "\n\t%pK%c%s len=%d %08x urb %pK"
" [td %08x buf[0] %08x]",
td, mark, type,
(scratch >> 16) & 0x7fff,
@@ -674,7 +674,7 @@
switch (hc32_to_cpu(ehci, tag)) {
case Q_TYPE_QH:
hw = p.qh->hw;
- temp = scnprintf(next, size, " qh%d-%04x/%p",
+ temp = scnprintf(next, size, " qh%d-%04x/%pK",
p.qh->ps.period,
hc32_to_cpup(ehci,
&hw->hw_info2)
@@ -709,21 +709,21 @@
p = p.qh->qh_next;
break;
case Q_TYPE_FSTN:
- temp = scnprintf(next, size,
- " fstn-%8x/%p", p.fstn->hw_prev,
+ temp = scnprintf (next, size,
+ " fstn-%8x/%pK", p.fstn->hw_prev,
p.fstn);
tag = Q_NEXT_TYPE(ehci, p.fstn->hw_next);
p = p.fstn->fstn_next;
break;
case Q_TYPE_ITD:
- temp = scnprintf(next, size,
- " itd/%p", p.itd);
+ temp = scnprintf (next, size,
+ " itd/%pK", p.itd);
tag = Q_NEXT_TYPE(ehci, p.itd->hw_next);
p = p.itd->itd_next;
break;
case Q_TYPE_SITD:
- temp = scnprintf(next, size,
- " sitd%d-%04x/%p",
+ temp = scnprintf (next, size,
+ " sitd%d-%04x/%pK",
p.sitd->stream->ps.period,
hc32_to_cpup(ehci, &p.sitd->hw_uframe)
& 0x0000ffff,
@@ -895,7 +895,7 @@
}
if (!list_empty(&ehci->async_unlink)) {
- temp = scnprintf(next, size, "async unlink qh %p\n",
+ temp = scnprintf(next, size, "async unlink qh %pK\n",
list_first_entry(&ehci->async_unlink,
struct ehci_qh, unlink_node));
size -= temp;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 0630648..142fe51 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1017,7 +1017,7 @@
/* caller was supposed to have unlinked any requests;
* that's not our job. just leak this memory.
*/
- ehci_err (ehci, "qh %p (#%02x) state %d%s\n",
+ ehci_err (ehci, "qh %pK (#%02x) state %d%s\n",
qh, ep->desc.bEndpointAddress, qh->qh_state,
list_empty (&qh->qtd_list) ? "" : "(has tds)");
break;
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index eca3710..484d9d7 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -268,7 +268,7 @@
#ifdef EHCI_URB_TRACE
ehci_dbg (ehci,
- "%s %s urb %p ep%d%s status %d len %d/%d\n",
+ "%s %s urb %pK ep%d%s status %d len %d/%d\n",
__func__, urb->dev->devpath, urb,
usb_pipeendpoint (urb->pipe),
usb_pipein (urb->pipe) ? "in" : "out",
@@ -354,7 +354,7 @@
/* Report Data Buffer Error: non-fatal but useful */
if (token & QTD_STS_DBE)
ehci_dbg(ehci,
- "detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
+ "detected DataBufferErr for urb %pK ep%d%s len %d, qtd %pK [qh %pK]\n",
urb,
usb_endpoint_num(&urb->ep->desc),
usb_endpoint_dir_in(&urb->ep->desc) ? "in" : "out",
@@ -933,7 +933,7 @@
}
break;
default:
- ehci_dbg(ehci, "bogus dev %p speed %d\n", urb->dev,
+ ehci_dbg(ehci, "bogus dev %pK speed %d\n", urb->dev,
urb->dev->speed);
done:
qh_destroy(ehci, qh);
@@ -1121,7 +1121,7 @@
struct ehci_qtd *qtd;
qtd = list_entry(qtd_list->next, struct ehci_qtd, qtd_list);
ehci_dbg(ehci,
- "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
+ "%s %s urb %pK ep%d%s len %d, qtd %pK [qh %pK]\n",
__func__, urb->dev->devpath, urb,
epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
urb->transfer_buffer_length,
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 1dfe54f..414e122 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -549,7 +549,7 @@
unsigned period = qh->ps.period;
dev_dbg(&qh->ps.udev->dev,
- "link qh%d-%04x/%p start %d [%d/%d us]\n",
+ "link qh%d-%04x/%pK start %d [%d/%d us]\n",
period, hc32_to_cpup(ehci, &qh->hw->hw_info2)
& (QH_CMASK | QH_SMASK),
qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs);
@@ -642,7 +642,7 @@
: (qh->ps.usecs * 8);
dev_dbg(&qh->ps.udev->dev,
- "unlink qh%d-%04x/%p start %d [%d/%d us]\n",
+ "unlink qh%d-%04x/%pK start %d [%d/%d us]\n",
qh->ps.period,
hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK),
qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs);
@@ -752,7 +752,7 @@
* FIXME kill the now-dysfunctional queued urbs
*/
else {
- ehci_err(ehci, "can't reschedule qh %p, err %d\n",
+ ehci_err(ehci, "can't reschedule qh %pK, err %d\n",
qh, rc);
}
}
@@ -870,7 +870,7 @@
/* reuse the previous schedule slots, if we can */
if (qh->ps.phase != NO_FRAME) {
- ehci_dbg(ehci, "reused qh %p schedule\n", qh);
+ ehci_dbg(ehci, "reused qh %pK schedule\n", qh);
return 0;
}
@@ -1550,7 +1550,7 @@
/* no room in the schedule */
if (!done) {
- ehci_dbg(ehci, "iso sched full %p", urb);
+ ehci_dbg(ehci, "iso sched full %pK", urb);
status = -ENOSPC;
goto fail;
}
@@ -1604,7 +1604,7 @@
/* Is the schedule about to wrap around? */
if (unlikely(!empty && start < period)) {
- ehci_dbg(ehci, "request %p would overflow (%u-%u < %u mod %u)\n",
+ ehci_dbg(ehci, "request %pK would overflow (%u-%u < %u mod %u)\n",
urb, stream->next_uframe, base, period, mod);
status = -EFBIG;
goto fail;
@@ -1633,7 +1633,7 @@
/* How many uframes and packets do we need to skip? */
skip = (now2 - start + period - 1) & -period;
if (skip >= span) { /* Entirely in the past? */
- ehci_dbg(ehci, "iso underrun %p (%u+%u < %u) [%u]\n",
+ ehci_dbg(ehci, "iso underrun %pK (%u+%u < %u) [%u]\n",
urb, start + base, span - period, now2 + base,
base);
@@ -1660,7 +1660,7 @@
use_start:
/* Tried to schedule too far into the future? */
if (unlikely(start + span - period >= mod + wrap)) {
- ehci_dbg(ehci, "request %p would overflow (%u+%u >= %u)\n",
+ ehci_dbg(ehci, "request %pK would overflow (%u+%u >= %u)\n",
urb, start, span - period, mod + wrap);
status = -EFBIG;
goto fail;
@@ -1956,7 +1956,7 @@
#ifdef EHCI_URB_TRACE
ehci_dbg(ehci,
- "%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n",
+ "%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%pK]\n",
__func__, urb->dev->devpath, urb,
usb_pipeendpoint(urb->pipe),
usb_pipein(urb->pipe) ? "in" : "out",
@@ -2336,8 +2336,8 @@
}
#ifdef EHCI_URB_TRACE
- ehci_dbg(ehci,
- "submit %p dev%s ep%d%s-iso len %d\n",
+ ehci_dbg (ehci,
+ "submit %pK dev%s ep%d%s-iso len %d\n",
urb, urb->dev->devpath,
usb_pipeendpoint(urb->pipe),
usb_pipein(urb->pipe) ? "in" : "out",
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index c3eded3..5617622 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -256,7 +256,7 @@
{
u32 tmp = hc32_to_cpup (ohci, &td->hwINFO);
- ohci_dbg (ohci, "%s td %p%s; urb %p index %d; hw next td %08x\n",
+ ohci_dbg (ohci, "%s td %pK%s; urb %pK index %d; hw next td %08x\n",
label, td,
(tmp & TD_DONE) ? " (DONE)" : "",
td->urb, td->index,
@@ -314,7 +314,7 @@
u32 tmp = hc32_to_cpu (ohci, ed->hwINFO);
char *type = "";
- ohci_dbg (ohci, "%s, ed %p state 0x%x type %s; next ed %08x\n",
+ ohci_dbg (ohci, "%s, ed %pK state 0x%x type %s; next ed %08x\n",
label,
ed, ed->state, edstring (ed->type),
hc32_to_cpup (ohci, &ed->hwNextED));
@@ -415,7 +415,7 @@
struct td *td;
temp = scnprintf (buf, size,
- "ed/%p %cs dev%d ep%d%s max %d %08x%s%s %s",
+ "ed/%pK %cs dev%d ep%d%s max %d %08x%s%s %s",
ed,
(info & ED_LOWSPEED) ? 'l' : 'f',
info & 0x7f,
@@ -437,7 +437,7 @@
cbp = hc32_to_cpup (ohci, &td->hwCBP);
be = hc32_to_cpup (ohci, &td->hwBE);
temp = scnprintf (buf, size,
- "\n\ttd %p %s %d cc=%x urb %p (%08x)",
+ "\n\ttd %pK %s %d cc=%x urb %pK (%08x)",
td,
({ char *pid;
switch (info & TD_DP) {
@@ -516,7 +516,7 @@
next += temp;
do {
- temp = scnprintf (next, size, " ed%d/%p",
+ temp = scnprintf (next, size, " ed%d/%pK",
ed->interval, ed);
size -= temp;
next += temp;
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index f6c7a27..5635a33 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -279,7 +279,7 @@
ed->interval);
if (urb_priv->td_cnt >= urb_priv->length) {
++urb_priv->td_cnt; /* Mark it */
- ohci_dbg(ohci, "iso underrun %p (%u+%u < %u)\n",
+ ohci_dbg(ohci, "iso underrun %pK (%u+%u < %u)\n",
urb, frame, length,
next);
}
@@ -387,7 +387,7 @@
/* caller was supposed to have unlinked any requests;
* that's not our job. can't recover; must leak ed.
*/
- ohci_err (ohci, "leak ed %p (#%02x) state %d%s\n",
+ ohci_err (ohci, "leak ed %pK (#%02x) state %d%s\n",
ed, ep->desc.bEndpointAddress, ed->state,
list_empty (&ed->td_list) ? "" : " (has tds)");
td_free (ohci, ed->dummy);
@@ -1028,7 +1028,7 @@
case ED_UNLINK:
break;
default:
- ohci_dbg(ohci, "bogus ed %p state %d\n",
+ ohci_dbg(ohci, "bogus ed %pK state %d\n",
ed, ed->state);
}
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
index c9e315c..99576f3 100644
--- a/drivers/usb/host/ohci-mem.c
+++ b/drivers/usb/host/ohci-mem.c
@@ -109,7 +109,7 @@
if (*prev)
*prev = td->td_hash;
else if ((td->hwINFO & cpu_to_hc32(hc, TD_DONE)) != 0)
- ohci_dbg (hc, "no hash for td %p\n", td);
+ ohci_dbg (hc, "no hash for td %pK\n", td);
dma_pool_free (hc->td_cache, td, td->td_dma);
}
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 641fed6..4365dc3 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -143,7 +143,7 @@
{
unsigned i;
- ohci_dbg(ohci, "link %sed %p branch %d [%dus.], interval %d\n",
+ ohci_dbg(ohci, "link %sed %pK branch %d [%dus.], interval %d\n",
(ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "",
ed, ed->branch, ed->load, ed->interval);
@@ -287,7 +287,7 @@
}
ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval;
- ohci_dbg(ohci, "unlink %sed %p branch %d [%dus.], interval %d\n",
+ ohci_dbg(ohci, "unlink %sed %pK branch %d [%dus.], interval %d\n",
(ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "",
ed, ed->branch, ed->load, ed->interval);
}
@@ -787,7 +787,7 @@
if (cc != TD_CC_NOERROR)
ohci_dbg(ohci,
- "urb %p iso td %p (%d) len %d cc %d\n",
+ "urb %pK iso td %pK (%d) len %d cc %d\n",
urb, td, 1 + td->index, dlen, cc);
/* BULK, INT, CONTROL ... drivers see aggregate length/status,
@@ -819,7 +819,7 @@
if (cc != TD_CC_NOERROR && cc < 0x0E)
ohci_dbg(ohci,
- "urb %p td %p (%d) cc %d, len=%d/%d\n",
+ "urb %pK td %pK (%d) cc %d, len=%d/%d\n",
urb, td, 1 + td->index, cc,
urb->actual_length,
urb->transfer_buffer_length);
@@ -885,7 +885,7 @@
/* fallthrough */
default:
ohci_dbg (ohci,
- "urb %p path %s ep%d%s %08x cc %d --> status %d\n",
+ "urb %pK path %s ep%d%s %08x cc %d --> status %d\n",
urb, urb->dev->devpath,
usb_pipeendpoint (urb->pipe),
usb_pipein (urb->pipe) ? "in" : "out",
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index 9c6635d..dcb6efa 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -47,7 +47,7 @@
u32 status, token;
status = td_status(uhci, td);
- out += sprintf(out, "%*s[%p] link (%08x) ", space, "", td,
+ out += sprintf(out, "%*s[%pK] link (%08x) ", space, "", td,
hc32_to_cpu(uhci, td->link));
out += sprintf(out, "e%d %s%s%s%s%s%s%s%s%s%sLength=%x ",
((status >> 27) & 3),
@@ -105,9 +105,9 @@
char *ptype;
- out += sprintf(out, "urb_priv [%p] ", urbp);
- out += sprintf(out, "urb [%p] ", urbp->urb);
- out += sprintf(out, "qh [%p] ", urbp->qh);
+ out += sprintf(out, "urb_priv [%pK] ", urbp);
+ out += sprintf(out, "urb [%pK] ", urbp->urb);
+ out += sprintf(out, "qh [%pK] ", urbp->qh);
out += sprintf(out, "Dev=%d ", usb_pipedevice(urbp->urb->pipe));
out += sprintf(out, "EP=%x(%s) ", usb_pipeendpoint(urbp->urb->pipe),
(usb_pipein(urbp->urb->pipe) ? "IN" : "OUT"));
@@ -177,13 +177,13 @@
default: qtype = "Skel" ; break;
}
- out += sprintf(out, "%*s[%p] %s QH link (%08x) element (%08x)\n",
+ out += sprintf(out, "%*s[%pK] %s QH link (%08x) element (%08x)\n",
space, "", qh, qtype,
hc32_to_cpu(uhci, qh->link),
hc32_to_cpu(uhci, element));
if (qh->type == USB_ENDPOINT_XFER_ISOC)
out += sprintf(out,
- "%*s period %d phase %d load %d us, frame %x desc [%p]\n",
+ "%*s period %d phase %d load %d us, frame %x desc [%pK]\n",
space, "", qh->period, qh->phase, qh->load,
qh->iso_frame, qh->iso_packet_desc);
else if (qh->type == USB_ENDPOINT_XFER_INT)
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index c17ea15..11c9d7b 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -124,9 +124,9 @@
static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
{
if (!list_empty(&td->list))
- dev_WARN(uhci_dev(uhci), "td %p still in list!\n", td);
+ dev_WARN(uhci_dev(uhci), "td %pK still in list!\n", td);
if (!list_empty(&td->fl_list))
- dev_WARN(uhci_dev(uhci), "td %p still in fl_list!\n", td);
+ dev_WARN(uhci_dev(uhci), "td %pK still in fl_list!\n", td);
dma_pool_free(uhci->td_pool, td, td->dma_handle);
}
@@ -293,7 +293,7 @@
{
WARN_ON(qh->state != QH_STATE_IDLE && qh->udev);
if (!list_empty(&qh->queue))
- dev_WARN(uhci_dev(uhci), "qh %p list not empty!\n", qh);
+ dev_WARN(uhci_dev(uhci), "qh %pK list not empty!\n", qh);
list_del(&qh->node);
if (qh->udev) {
@@ -743,7 +743,7 @@
struct uhci_td *td, *tmp;
if (!list_empty(&urbp->node))
- dev_WARN(uhci_dev(uhci), "urb %p still on QH's list!\n",
+ dev_WARN(uhci_dev(uhci), "urb %pK still on QH's list!\n",
urbp->urb);
list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
@@ -1316,7 +1316,7 @@
else if (!uhci_frame_before_eq(next,
frame + (urb->number_of_packets - 1) *
qh->period))
- dev_dbg(uhci_dev(uhci), "iso underrun %p (%u+%u < %u)\n",
+ dev_dbg(uhci_dev(uhci), "iso underrun %pK (%u+%u < %u)\n",
urb, frame,
(urb->number_of_packets - 1) *
qh->period,
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index 3425154..a190c97 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -30,10 +30,10 @@
{
u32 temp;
- xhci_dbg(xhci, "// xHCI capability registers at %p:\n",
+ xhci_dbg(xhci, "// xHCI capability registers at %pK:\n",
xhci->cap_regs);
temp = readl(&xhci->cap_regs->hc_capbase);
- xhci_dbg(xhci, "// @%p = 0x%x (CAPLENGTH AND HCIVERSION)\n",
+ xhci_dbg(xhci, "// @%pK = 0x%x (CAPLENGTH AND HCIVERSION)\n",
&xhci->cap_regs->hc_capbase, temp);
xhci_dbg(xhci, "// CAPLENGTH: 0x%x\n",
(unsigned int) HC_LENGTH(temp));
@@ -42,17 +42,17 @@
(unsigned int) HC_VERSION(temp));
#endif
- xhci_dbg(xhci, "// xHCI operational registers at %p:\n", xhci->op_regs);
+ xhci_dbg(xhci, "// xHCI operational registers at %pK:\n", xhci->op_regs);
temp = readl(&xhci->cap_regs->run_regs_off);
- xhci_dbg(xhci, "// @%p = 0x%x RTSOFF\n",
+ xhci_dbg(xhci, "// @%pK = 0x%x RTSOFF\n",
&xhci->cap_regs->run_regs_off,
(unsigned int) temp & RTSOFF_MASK);
- xhci_dbg(xhci, "// xHCI runtime registers at %p:\n", xhci->run_regs);
+ xhci_dbg(xhci, "// xHCI runtime registers at %pK:\n", xhci->run_regs);
temp = readl(&xhci->cap_regs->db_off);
- xhci_dbg(xhci, "// @%p = 0x%x DBOFF\n", &xhci->cap_regs->db_off, temp);
- xhci_dbg(xhci, "// Doorbell array at %p:\n", xhci->dba);
+ xhci_dbg(xhci, "// @%pK = 0x%x DBOFF\n", &xhci->cap_regs->db_off, temp);
+ xhci_dbg(xhci, "// Doorbell array at %pK:\n", xhci->dba);
}
static void xhci_print_cap_regs(struct xhci_hcd *xhci)
@@ -60,7 +60,7 @@
u32 temp;
u32 hci_version;
- xhci_dbg(xhci, "xHCI capability registers at %p:\n", xhci->cap_regs);
+ xhci_dbg(xhci, "xHCI capability registers at %pK:\n", xhci->cap_regs);
temp = readl(&xhci->cap_regs->hc_capbase);
hci_version = HC_VERSION(temp);
@@ -157,7 +157,7 @@
static void xhci_print_op_regs(struct xhci_hcd *xhci)
{
- xhci_dbg(xhci, "xHCI operational registers at %p:\n", xhci->op_regs);
+ xhci_dbg(xhci, "xHCI operational registers at %pK:\n", xhci->op_regs);
xhci_print_command_reg(xhci);
xhci_print_status(xhci);
}
@@ -178,7 +178,7 @@
addr = &xhci->op_regs->port_status_base;
for (i = 0; i < ports; i++) {
for (j = 0; j < NUM_PORT_REGS; ++j) {
- xhci_dbg(xhci, "%p port %s reg = 0x%x\n",
+ xhci_dbg(xhci, "%pK port %s reg = 0x%x\n",
addr, names[j],
(unsigned int) readl(addr));
addr++;
@@ -198,35 +198,35 @@
if (temp == XHCI_INIT_VALUE)
return;
- xhci_dbg(xhci, " %p: ir_set[%i]\n", ir_set, set_num);
+ xhci_dbg(xhci, " %pK: ir_set[%i]\n", ir_set, set_num);
- xhci_dbg(xhci, " %p: ir_set.pending = 0x%x\n", addr,
+ xhci_dbg(xhci, " %pK: ir_set.pending = 0x%x\n", addr,
(unsigned int)temp);
addr = &ir_set->irq_control;
temp = readl(addr);
- xhci_dbg(xhci, " %p: ir_set.control = 0x%x\n", addr,
+ xhci_dbg(xhci, " %pK: ir_set.control = 0x%x\n", addr,
(unsigned int)temp);
addr = &ir_set->erst_size;
temp = readl(addr);
- xhci_dbg(xhci, " %p: ir_set.erst_size = 0x%x\n", addr,
+ xhci_dbg(xhci, " %pK: ir_set.erst_size = 0x%x\n", addr,
(unsigned int)temp);
addr = &ir_set->rsvd;
temp = readl(addr);
if (temp != XHCI_INIT_VALUE)
- xhci_dbg(xhci, " WARN: %p: ir_set.rsvd = 0x%x\n",
+ xhci_dbg(xhci, " WARN: %pK: ir_set.rsvd = 0x%x\n",
addr, (unsigned int)temp);
addr = &ir_set->erst_base;
temp_64 = xhci_read_64(xhci, addr);
- xhci_dbg(xhci, " %p: ir_set.erst_base = @%08llx\n",
+ xhci_dbg(xhci, " %pK: ir_set.erst_base = @%08llx\n",
addr, temp_64);
addr = &ir_set->erst_dequeue;
temp_64 = xhci_read_64(xhci, addr);
- xhci_dbg(xhci, " %p: ir_set.erst_dequeue = @%08llx\n",
+ xhci_dbg(xhci, " %pK: ir_set.erst_dequeue = @%08llx\n",
addr, temp_64);
}
@@ -235,15 +235,15 @@
u32 temp;
int i;
- xhci_dbg(xhci, "xHCI runtime registers at %p:\n", xhci->run_regs);
+ xhci_dbg(xhci, "xHCI runtime registers at %pK:\n", xhci->run_regs);
temp = readl(&xhci->run_regs->microframe_index);
- xhci_dbg(xhci, " %p: Microframe index = 0x%x\n",
+ xhci_dbg(xhci, " %pK: Microframe index = 0x%x\n",
&xhci->run_regs->microframe_index,
(unsigned int) temp);
for (i = 0; i < 7; ++i) {
temp = readl(&xhci->run_regs->rsvd[i]);
if (temp != XHCI_INIT_VALUE)
- xhci_dbg(xhci, " WARN: %p: Rsvd[%i] = 0x%x\n",
+ xhci_dbg(xhci, " WARN: %pK: Rsvd[%i] = 0x%x\n",
&xhci->run_regs->rsvd[i],
i, (unsigned int) temp);
}
@@ -345,13 +345,13 @@
void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring)
{
- xhci_dbg(xhci, "Ring deq = %p (virt), 0x%llx (dma)\n",
+ xhci_dbg(xhci, "Ring deq = %pK (virt), 0x%llx (dma)\n",
ring->dequeue,
(unsigned long long)xhci_trb_virt_to_dma(ring->deq_seg,
ring->dequeue));
xhci_dbg(xhci, "Ring deq updated %u times\n",
ring->deq_updates);
- xhci_dbg(xhci, "Ring enq = %p (virt), 0x%llx (dma)\n",
+ xhci_dbg(xhci, "Ring enq = %pK (virt), 0x%llx (dma)\n",
ring->enqueue,
(unsigned long long)xhci_trb_virt_to_dma(ring->enq_seg,
ring->enqueue));
@@ -441,7 +441,7 @@
{
int i;
for (i = 0; i < 4; ++i) {
- xhci_dbg(xhci, "@%p (virt) @%08llx "
+ xhci_dbg(xhci, "@%pK (virt) @%08llx "
"(dma) %#08llx - rsvd64[%d]\n",
&ctx[4 + i], (unsigned long long)dma,
ctx[4 + i], i);
@@ -480,24 +480,24 @@
int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
xhci_dbg(xhci, "Slot Context:\n");
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - dev_info\n",
&slot_ctx->dev_info,
(unsigned long long)dma, slot_ctx->dev_info);
dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - dev_info2\n",
&slot_ctx->dev_info2,
(unsigned long long)dma, slot_ctx->dev_info2);
dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - tt_info\n",
&slot_ctx->tt_info,
(unsigned long long)dma, slot_ctx->tt_info);
dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - dev_state\n",
&slot_ctx->dev_state,
(unsigned long long)dma, slot_ctx->dev_state);
dma += field_size;
for (i = 0; i < 4; ++i) {
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
&slot_ctx->reserved[i], (unsigned long long)dma,
slot_ctx->reserved[i], i);
dma += field_size;
@@ -528,24 +528,24 @@
xhci_dbg(xhci, "%s Endpoint %02d Context (ep_index %02d):\n",
usb_endpoint_out(epaddr) ? "OUT" : "IN",
epaddr & USB_ENDPOINT_NUMBER_MASK, i);
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - ep_info\n",
&ep_ctx->ep_info,
(unsigned long long)dma, ep_ctx->ep_info);
dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - ep_info2\n",
&ep_ctx->ep_info2,
(unsigned long long)dma, ep_ctx->ep_info2);
dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08llx - deq\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08llx - deq\n",
&ep_ctx->deq,
(unsigned long long)dma, ep_ctx->deq);
dma += 2*field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - tx_info\n",
&ep_ctx->tx_info,
(unsigned long long)dma, ep_ctx->tx_info);
dma += field_size;
for (j = 0; j < 3; ++j) {
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
&ep_ctx->reserved[j],
(unsigned long long)dma,
ep_ctx->reserved[j], j);
@@ -575,16 +575,16 @@
return;
}
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - drop flags\n",
&ctrl_ctx->drop_flags, (unsigned long long)dma,
ctrl_ctx->drop_flags);
dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - add flags\n",
&ctrl_ctx->add_flags, (unsigned long long)dma,
ctrl_ctx->add_flags);
dma += field_size;
for (i = 0; i < 6; ++i) {
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd2[%d]\n",
+ xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - rsvd2[%d]\n",
&ctrl_ctx->rsvd2[i], (unsigned long long)dma,
ctrl_ctx->rsvd2[i], i);
dma += field_size;
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 2911b72..588e053 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1077,7 +1077,7 @@
/* Point to output device context in dcbaa. */
xhci->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(dev->out_ctx->dma);
- xhci_dbg(xhci, "Set slot id %d dcbaa entry %p to 0x%llx\n",
+ xhci_dbg(xhci, "Set slot id %d dcbaa entry %pK to 0x%llx\n",
slot_id,
&xhci->dcbaa->dev_context_ptrs[slot_id],
le64_to_cpu(xhci->dcbaa->dev_context_ptrs[slot_id]));
@@ -1251,7 +1251,7 @@
if (udev->tt->multi)
slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
}
- xhci_dbg(xhci, "udev->tt = %p\n", udev->tt);
+ xhci_dbg(xhci, "udev->tt = %pK\n", udev->tt);
xhci_dbg(xhci, "udev->ttport = 0x%x\n", udev->ttport);
/* Step 4 - ring already allocated */
@@ -2101,15 +2101,15 @@
if (seg != result_seg) {
xhci_warn(xhci, "WARN: %s TRB math test %d failed!\n",
test_name, test_number);
- xhci_warn(xhci, "Tested TRB math w/ seg %p and "
+ xhci_warn(xhci, "Tested TRB math w/ seg %pK and "
"input DMA 0x%llx\n",
input_seg,
(unsigned long long) input_dma);
- xhci_warn(xhci, "starting TRB %p (0x%llx DMA), "
- "ending TRB %p (0x%llx DMA)\n",
+ xhci_warn(xhci, "starting TRB %pK (0x%llx DMA), "
+ "ending TRB %pK (0x%llx DMA)\n",
start_trb, start_dma,
end_trb, end_dma);
- xhci_warn(xhci, "Expected seg %p, got seg %p\n",
+ xhci_warn(xhci, "Expected seg %pK, got seg %pK\n",
result_seg, seg);
trb_in_td(xhci, input_seg, start_trb, end_trb, input_dma,
true);
@@ -2258,7 +2258,7 @@
rhub = &xhci->usb2_rhub;
} else {
xhci_warn(xhci, "Ignoring unknown port speed, "
- "Ext Cap %p, revision = 0x%x\n",
+ "Ext Cap %pK, revision = 0x%x\n",
addr, major_revision);
/* Ignoring port protocol we can't understand. FIXME */
return;
@@ -2273,7 +2273,7 @@
port_offset = XHCI_EXT_PORT_OFF(temp);
port_count = XHCI_EXT_PORT_COUNT(temp);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
- "Ext Cap %p, port offset = %u, "
+ "Ext Cap %pK, port offset = %u, "
"count = %u, revision = 0x%x",
addr, port_offset, port_count, major_revision);
/* Port count includes the current port offset */
@@ -2335,7 +2335,7 @@
for (i = port_offset; i < (port_offset + port_count); i++) {
/* Duplicate entry. Ignore the port if the revisions differ. */
if (xhci->port_array[i] != 0) {
- xhci_warn(xhci, "Duplicate port entry, Ext Cap %p,"
+ xhci_warn(xhci, "Duplicate port entry, Ext Cap %pK,"
" port %u\n", addr, i);
xhci_warn(xhci, "Port was marked as USB %u, "
"duplicated as USB %u\n",
@@ -2470,7 +2470,7 @@
NUM_PORT_REGS*i;
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"USB 2.0 port at index %u, "
- "addr = %p", i,
+ "addr = %pK", i,
xhci->usb2_ports[port_index]);
port_index++;
if (port_index == xhci->num_usb2_ports)
@@ -2491,7 +2491,7 @@
NUM_PORT_REGS*i;
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"USB 3.0 port at index %u, "
- "addr = %p", i,
+ "addr = %pK", i,
xhci->usb3_ports[port_index]);
port_index++;
if (port_index == xhci->num_usb3_ports)
@@ -2531,7 +2531,7 @@
erst->num_entries = ERST_NUM_SEGS;
erst->erst_dma_addr = dma;
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
- "intr# %d: num segs = %i, virt addr = %p, dma addr = 0x%llx",
+ "intr# %d: num segs = %i, virt addr = %pK, dma addr = 0x%llx",
intr_num,
erst->num_entries,
erst->entries,
@@ -2603,7 +2603,7 @@
|| !xhci->sec_event_ring || !xhci->sec_erst ||
intr_num >= xhci->max_interrupters) {
xhci_err(xhci,
- "%s:state %x ir_set %p evt_ring %p erst %p intr# %d\n",
+ "%s:state %x ir_set %pK evt_ring %pK erst %pK intr# %d\n",
__func__, xhci->xhc_state, xhci->sec_ir_set,
xhci->sec_event_ring, xhci->sec_erst, intr_num);
return -EINVAL;
@@ -2730,7 +2730,7 @@
memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa));
xhci->dcbaa->dma = dma;
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
- "// Device context base array address = 0x%llx (DMA), %p (virt)",
+ "// Device context base array address = 0x%llx (DMA), %pK (virt)",
(unsigned long long)xhci->dcbaa->dma, xhci->dcbaa);
xhci_write_64(xhci, dma, &xhci->op_regs->dcbaa_ptr);
@@ -2771,7 +2771,7 @@
if (!xhci->cmd_ring)
goto fail;
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
- "Allocated command ring at %p", xhci->cmd_ring);
+ "Allocated command ring at %pK", xhci->cmd_ring);
xhci_dbg_trace(xhci, trace_xhci_dbg_init, "First segment DMA is 0x%llx",
(unsigned long long)xhci->cmd_ring->first_seg->dma);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 7020b9e..f7c753f 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -290,7 +290,7 @@
i_cmd->status = COMP_CMD_STOP;
- xhci_dbg(xhci, "Turn aborted command %p to no-op\n",
+ xhci_dbg(xhci, "Turn aborted command %pK to no-op\n",
i_cmd->command_trb);
/* get cycle state from the original cmd trb */
cycle_state = le32_to_cpu(
@@ -555,7 +555,7 @@
"Cycle state = 0x%x", state->new_cycle_state);
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
- "New dequeue segment = %p (virtual)",
+ "New dequeue segment = %pK (virtual)",
state->new_deq_seg);
addr = xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr);
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
@@ -590,8 +590,8 @@
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"Cancel (unchain) link TRB");
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
- "Address = %p (0x%llx dma); "
- "in seg %p (0x%llx dma)",
+ "Address = %pK (0x%llx dma); "
+ "in seg %pK (0x%llx dma)",
cur_trb,
(unsigned long long)xhci_trb_virt_to_dma(cur_seg, cur_trb),
cur_seg,
@@ -752,7 +752,7 @@
* short, don't muck with the stream ID after
* submission.
*/
- xhci_warn(xhci, "WARN Cancelled URB %p "
+ xhci_warn(xhci, "WARN Cancelled URB %pK "
"has invalid stream ID %u.\n",
cur_td->urb,
cur_td->urb->stream_id);
@@ -1096,7 +1096,7 @@
ep_ring, ep_index);
} else {
xhci_warn(xhci, "Mismatch between completed Set TR Deq Ptr command & xHCI internal state.\n");
- xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n",
+ xhci_warn(xhci, "ep deq seg = %pK, deq ptr = %pK\n",
ep->queued_deq_seg, ep->queued_deq_ptr);
}
}
@@ -2621,7 +2621,7 @@
URB_SHORT_NOT_OK)) ||
(status != 0 &&
!usb_endpoint_xfer_isoc(&urb->ep->desc)))
- xhci_dbg(xhci, "Giveback URB %p, len = %d, "
+ xhci_dbg(xhci, "Giveback URB %pK, len = %d, "
"expected = %d, status = %d\n",
urb, urb->actual_length,
urb->transfer_buffer_length,
@@ -4182,7 +4182,7 @@
int ret;
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
- "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), new deq ptr = %p (0x%llx dma), new cycle = %u",
+ "Set TR Deq Ptr cmd, new deq seg = %pK (0x%llx dma), new deq ptr = %pK (0x%llx dma), new cycle = %u",
deq_state->new_deq_seg,
(unsigned long long)deq_state->new_deq_seg->dma,
deq_state->new_deq_ptr,
@@ -4194,7 +4194,7 @@
deq_state->new_deq_ptr);
if (addr == 0) {
xhci_warn(xhci, "WARN Cannot submit Set TR Deq Ptr\n");
- xhci_warn(xhci, "WARN deq seg = %p, deq pt = %p\n",
+ xhci_warn(xhci, "WARN deq seg = %pK, deq pt = %pK\n",
deq_state->new_deq_seg, deq_state->new_deq_ptr);
return;
}
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index 59c0565..4ef95ac 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -103,7 +103,7 @@
((HCC_64BYTE_CONTEXT(xhci->hcc_params) + 1) * 32) *
((ctx->type == XHCI_CTX_TYPE_INPUT) + ep_num + 1));
),
- TP_printk("\nctx_64=%d, ctx_type=%u, ctx_dma=@%llx, ctx_va=@%p",
+ TP_printk("\nctx_64=%d, ctx_type=%u, ctx_dma=@%llx, ctx_va=@%pK",
__entry->ctx_64, __entry->ctx_type,
(unsigned long long) __entry->ctx_dma, __entry->ctx_va
)
@@ -134,7 +134,7 @@
memcpy(__get_dynamic_array(trb), trb_va,
sizeof(struct xhci_generic_trb));
),
- TP_printk("\ntrb_dma=@%llx, trb_va=@%p, status=%08x, flags=%08x",
+ TP_printk("\ntrb_dma=@%llx, trb_va=@%pK, status=%08x, flags=%08x",
(unsigned long long) __entry->dma, __entry->va,
__entry->status, __entry->flags
)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 84ace86..fe2bbfb 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -690,7 +690,7 @@
temp = readl(&xhci->ir_set->irq_pending);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
- "// Enabling event ring interrupter %p by writing 0x%x to irq_pending",
+ "// Enabling event ring interrupter %pK by writing 0x%x to irq_pending",
xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp));
writel(ER_IRQ_ENABLE(temp), &xhci->ir_set->irq_pending);
xhci_print_ir_set(xhci, 0);
@@ -1496,7 +1496,7 @@
exit:
return ret;
dying:
- xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
+ xhci_dbg(xhci, "Ep 0x%x: URB %pK submitted for "
"non-responsive xHCI host.\n",
urb->ep->desc.bEndpointAddress, urb);
ret = -ESHUTDOWN;
@@ -1591,7 +1591,7 @@
i = urb_priv->td_cnt;
if (i < urb_priv->length)
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
- "Cancel URB %p, dev %s, ep 0x%x, "
+ "Cancel URB %pK, dev %s, ep 0x%x, "
"starting at offset 0x%llx",
urb, urb->dev->devpath,
urb->ep->desc.bEndpointAddress,
@@ -1659,7 +1659,7 @@
if (xhci->xhc_state & XHCI_STATE_DYING)
return -ENODEV;
- xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+ xhci_dbg(xhci, "%s called for udev %pK\n", __func__, udev);
drop_flag = xhci_get_endpoint_flag(&ep->desc);
if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) {
xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n",
@@ -1687,7 +1687,7 @@
xhci_get_endpoint_flag(&ep->desc)) {
/* Do not warn when called after a usb_device_reset */
if (xhci->devs[udev->slot_id]->eps[ep_index].ring != NULL)
- xhci_warn(xhci, "xHCI %s called with disabled ep %p\n",
+ xhci_warn(xhci, "xHCI %s called with disabled ep %pK\n",
__func__, ep);
return 0;
}
@@ -1782,7 +1782,7 @@
* ignore this request.
*/
if (le32_to_cpu(ctrl_ctx->add_flags) & added_ctxs) {
- xhci_warn(xhci, "xHCI %s called with enabled ep %p\n",
+ xhci_warn(xhci, "xHCI %s called with enabled ep %pK\n",
__func__, ep);
return 0;
}
@@ -2772,7 +2772,7 @@
(xhci->xhc_state & XHCI_STATE_REMOVING))
return -ENODEV;
- xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+ xhci_dbg(xhci, "%s called for udev %pK\n", __func__, udev);
virt_dev = xhci->devs[udev->slot_id];
command = xhci_alloc_command(xhci, false, true, GFP_KERNEL);
@@ -2869,7 +2869,7 @@
return;
xhci = hcd_to_xhci(hcd);
- xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+ xhci_dbg(xhci, "%s called for udev %pK\n", __func__, udev);
virt_dev = xhci->devs[udev->slot_id];
/* Free any rings allocated for added endpoints */
for (i = 0; i < 31; ++i) {
@@ -2922,7 +2922,7 @@
if (addr == 0) {
xhci_warn(xhci, "WARN Cannot submit config ep after "
"reset ep command\n");
- xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n",
+ xhci_warn(xhci, "WARN deq seg = %pK, deq ptr = %pK\n",
deq_state->new_deq_seg,
deq_state->new_deq_ptr);
return;
@@ -3949,7 +3949,7 @@
xhci_dbg_trace(xhci, trace_xhci_dbg_address,
"Op regs DCBAA ptr = %#016llx", temp_64);
xhci_dbg_trace(xhci, trace_xhci_dbg_address,
- "Slot ID %d dcbaa entry @%p = %#016llx",
+ "Slot ID %d dcbaa entry @%pK = %#016llx",
udev->slot_id,
&xhci->dcbaa->dev_context_ptrs[udev->slot_id],
(unsigned long long)
diff --git a/drivers/usb/phy/phy-msm-snps-hs.c b/drivers/usb/phy/phy-msm-snps-hs.c
index a259790..28a9bf1 100644
--- a/drivers/usb/phy/phy-msm-snps-hs.c
+++ b/drivers/usb/phy/phy-msm-snps-hs.c
@@ -69,6 +69,9 @@
#define REFCLK_SEL_MASK (0x3 << 0)
#define REFCLK_SEL_DEFAULT (0x2 << 0)
+#define USB2PHY_USB_PHY_RTUNE_SEL (0xb4)
+#define RTUNE_SEL BIT(0)
+
#define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */
#define USB_HSPHY_3P3_VOL_MAX 3300000 /* uV */
#define USB_HSPHY_3P3_HPM_LOAD 16000 /* uA */
@@ -390,6 +393,9 @@
hsusb_phy_write_seq(phy->base, phy->param_override_seq,
phy->param_override_seq_cnt, 0);
+ msm_usb_write_readback(phy->base, USB2PHY_USB_PHY_RTUNE_SEL,
+ RTUNE_SEL, RTUNE_SEL);
+
msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2,
VREGBYPASS, VREGBYPASS);
diff --git a/drivers/video/fbdev/msm/mdp3.c b/drivers/video/fbdev/msm/mdp3.c
index 5cf439c..00183f8 100644
--- a/drivers/video/fbdev/msm/mdp3.c
+++ b/drivers/video/fbdev/msm/mdp3.c
@@ -44,7 +44,6 @@
#include <linux/msm-bus.h>
#include <linux/msm-bus-board.h>
-#include <linux/qcom_iommu.h>
#include <linux/msm_dma_iommu_mapping.h>
@@ -116,39 +115,14 @@
[MDP3_IOMMU_DOMAIN_UNSECURE] = {
.domain_type = MDP3_IOMMU_DOMAIN_UNSECURE,
.client_name = "mdp_ns",
- .partitions = {
- {
- .start = SZ_128K,
- .size = SZ_1G - SZ_128K,
- },
- },
.npartitions = 1,
+ .domain_idx = MDP3_IOMMU_DOMAIN_UNSECURE,
},
[MDP3_IOMMU_DOMAIN_SECURE] = {
.domain_type = MDP3_IOMMU_DOMAIN_SECURE,
.client_name = "mdp_secure",
- .partitions = {
- {
- .start = SZ_1G,
- .size = SZ_1G,
- },
- },
.npartitions = 1,
- },
-};
-
-struct mdp3_iommu_ctx_map mdp3_iommu_contexts[MDP3_IOMMU_CTX_MAX] = {
- [MDP3_IOMMU_CTX_MDP_0] = {
- .ctx_type = MDP3_IOMMU_CTX_MDP_0,
- .domain = &mdp3_iommu_domains[MDP3_IOMMU_DOMAIN_UNSECURE],
- .ctx_name = "mdp_0",
- .attached = 0,
- },
- [MDP3_IOMMU_CTX_MDP_1] = {
- .ctx_type = MDP3_IOMMU_CTX_MDP_1,
- .domain = &mdp3_iommu_domains[MDP3_IOMMU_DOMAIN_SECURE],
- .ctx_name = "mdp_1",
- .attached = 0,
+ .domain_idx = MDP3_IOMMU_DOMAIN_SECURE,
},
};
@@ -785,7 +759,7 @@
ret = devm_request_irq(&mdp3_res->pdev->dev,
mdp3_hw->irq_info->irq,
mdp3_irq_handler,
- IRQF_DISABLED, "MDP", mdp3_res);
+ 0, "MDP", mdp3_res);
if (ret) {
pr_err("mdp request_irq() failed!\n");
return ret;
@@ -795,7 +769,6 @@
return 0;
}
-
static int mdp3_get_iommu_domain(u32 type)
{
if (type >= MDSS_IOMMU_MAX_DOMAIN)
@@ -807,155 +780,6 @@
return mdp3_res->domains[type].domain_idx;
}
-int mdp3_iommu_attach(int context)
-{
- int rc = 0;
- struct mdp3_iommu_ctx_map *context_map;
- struct mdp3_iommu_domain_map *domain_map;
-
- if (context >= MDP3_IOMMU_CTX_MAX)
- return -EINVAL;
-
- context_map = mdp3_res->iommu_contexts + context;
- if (context_map->attached) {
- pr_warn("mdp iommu already attached\n");
- return 0;
- }
-
- domain_map = context_map->domain;
-
- rc = iommu_attach_device(domain_map->domain, context_map->ctx);
- if (rc) {
- pr_err("mpd3 iommu attach failed\n");
- return -EINVAL;
- }
-
- context_map->attached = true;
- return 0;
-}
-
-int mdp3_iommu_dettach(int context)
-{
- struct mdp3_iommu_ctx_map *context_map;
- struct mdp3_iommu_domain_map *domain_map;
-
- if (!mdp3_res->iommu_contexts ||
- context >= MDP3_IOMMU_CTX_MAX)
- return -EINVAL;
-
- context_map = mdp3_res->iommu_contexts + context;
- if (!context_map->attached) {
- pr_warn("mdp iommu not attached\n");
- return 0;
- }
-
- domain_map = context_map->domain;
- iommu_detach_device(domain_map->domain, context_map->ctx);
- context_map->attached = false;
-
- return 0;
-}
-
-int mdp3_iommu_domain_init(void)
-{
- struct msm_iova_layout layout;
- int i;
-
- if (mdp3_res->domains) {
- pr_warn("iommu domain already initialized\n");
- return 0;
- }
-
- for (i = 0; i < MDP3_IOMMU_DOMAIN_MAX; i++) {
- int domain_idx;
-
- layout.client_name = mdp3_iommu_domains[i].client_name;
- layout.partitions = mdp3_iommu_domains[i].partitions;
- layout.npartitions = mdp3_iommu_domains[i].npartitions;
- layout.is_secure = (i == MDP3_IOMMU_DOMAIN_SECURE);
-
- domain_idx = msm_register_domain(&layout);
- if (IS_ERR_VALUE(domain_idx))
- return -EINVAL;
-
- mdp3_iommu_domains[i].domain_idx = domain_idx;
- mdp3_iommu_domains[i].domain = msm_get_iommu_domain(domain_idx);
- if (IS_ERR_OR_NULL(mdp3_iommu_domains[i].domain)) {
- pr_err("unable to get iommu domain(%d)\n",
- domain_idx);
- if (!mdp3_iommu_domains[i].domain)
- return -EINVAL;
- else
- return PTR_ERR(mdp3_iommu_domains[i].domain);
- }
- }
-
- mdp3_res->domains = mdp3_iommu_domains;
-
- return 0;
-}
-
-int mdp3_iommu_context_init(void)
-{
- int i;
-
- if (mdp3_res->iommu_contexts) {
- pr_warn("iommu context already initialized\n");
- return 0;
- }
-
- for (i = 0; i < MDP3_IOMMU_CTX_MAX; i++) {
- mdp3_iommu_contexts[i].ctx =
- msm_iommu_get_ctx(mdp3_iommu_contexts[i].ctx_name);
-
- if (IS_ERR_OR_NULL(mdp3_iommu_contexts[i].ctx)) {
- pr_warn("unable to get iommu ctx(%s)\n",
- mdp3_iommu_contexts[i].ctx_name);
- if (!mdp3_iommu_contexts[i].ctx)
- return -EINVAL;
- else
- return PTR_ERR(mdp3_iommu_contexts[i].ctx);
- }
- }
-
- mdp3_res->iommu_contexts = mdp3_iommu_contexts;
-
- return 0;
-}
-
-int mdp3_iommu_init(void)
-{
- int ret;
-
- mutex_init(&mdp3_res->iommu_lock);
-
- ret = mdp3_iommu_domain_init();
- if (ret) {
- pr_err("mdp3 iommu domain init fails\n");
- return ret;
- }
-
- ret = mdp3_iommu_context_init();
- if (ret) {
- pr_err("mdp3 iommu context init fails\n");
- return ret;
- }
- return ret;
-}
-
-void mdp3_iommu_deinit(void)
-{
- int i;
-
- if (!mdp3_res->domains)
- return;
-
- for (i = 0; i < MDP3_IOMMU_DOMAIN_MAX; i++) {
- if (!IS_ERR_OR_NULL(mdp3_res->domains[i].domain))
- msm_unregister_domain(mdp3_res->domains[i].domain);
- }
-}
-
static int mdp3_check_version(void)
{
int rc;
@@ -1151,11 +975,9 @@
mdp3_res->ion_client = NULL;
return -EINVAL;
}
+ mutex_init(&mdp3_res->iommu_lock);
- rc = mdp3_iommu_init();
- if (rc)
- return rc;
-
+ mdp3_res->domains = mdp3_iommu_domains;
mdp3_res->bus_handle = mdp3_bus_handle;
rc = mdp3_bus_scale_register();
if (rc) {
@@ -1171,18 +993,20 @@
static void mdp3_res_deinit(void)
{
struct mdss_hw *mdp3_hw;
- int i;
+ int rc = 0;
mdp3_hw = &mdp3_res->mdp3_hw;
mdp3_bus_scale_unregister();
-
mutex_lock(&mdp3_res->iommu_lock);
- for (i = 0; i < MDP3_IOMMU_CTX_MAX; i++)
- mdp3_iommu_dettach(i);
+ if (mdp3_res->iommu_ref_cnt) {
+ mdp3_res->iommu_ref_cnt--;
+ if (mdp3_res->iommu_ref_cnt == 0)
+ rc = mdss_smmu_detach(mdss_res);
+ } else {
+ pr_err("iommu ref count %d\n", mdp3_res->iommu_ref_cnt);
+ }
mutex_unlock(&mdp3_res->iommu_lock);
- mdp3_iommu_deinit();
-
if (!IS_ERR_OR_NULL(mdp3_res->ion_client))
ion_client_destroy(mdp3_res->ion_client);
@@ -1503,317 +1327,6 @@
mdp3_batfet_ctrl(enable);
}
-static void mdp3_iommu_heap_unmap_iommu(struct mdp3_iommu_meta *meta)
-{
- unsigned int domain_num;
- unsigned int partition_num = 0;
- struct iommu_domain *domain;
-
- domain_num = (mdp3_res->domains +
- MDP3_IOMMU_DOMAIN_UNSECURE)->domain_idx;
- domain = msm_get_iommu_domain(domain_num);
-
- if (!domain) {
- pr_err("Could not get domain %d. Corruption?\n", domain_num);
- return;
- }
-
- iommu_unmap_range(domain, meta->iova_addr, meta->mapped_size);
- msm_free_iova_address(meta->iova_addr, domain_num, partition_num,
- meta->mapped_size);
-}
-
-static void mdp3_iommu_meta_destroy(struct kref *kref)
-{
- struct mdp3_iommu_meta *meta =
- container_of(kref, struct mdp3_iommu_meta, ref);
-
- rb_erase(&meta->node, &mdp3_res->iommu_root);
- mdp3_iommu_heap_unmap_iommu(meta);
- dma_buf_put(meta->dbuf);
- kfree(meta);
-}
-
-
-static void mdp3_iommu_meta_put(struct mdp3_iommu_meta *meta)
-{
- /* Need to lock here to prevent race against map/unmap */
- mutex_lock(&mdp3_res->iommu_lock);
- kref_put(&meta->ref, mdp3_iommu_meta_destroy);
- mutex_unlock(&mdp3_res->iommu_lock);
-}
-
-static struct mdp3_iommu_meta *mdp3_iommu_meta_lookup(struct sg_table *table)
-{
- struct rb_root *root = &mdp3_res->iommu_root;
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
- struct mdp3_iommu_meta *entry = NULL;
-
- while (*p) {
- parent = *p;
- entry = rb_entry(parent, struct mdp3_iommu_meta, node);
-
- if (table < entry->table)
- p = &(*p)->rb_left;
- else if (table > entry->table)
- p = &(*p)->rb_right;
- else
- return entry;
- }
- return NULL;
-}
-
-void mdp3_unmap_iommu(struct ion_client *client, struct ion_handle *handle)
-{
- struct mdp3_iommu_meta *meta;
- struct sg_table *table;
-
- table = ion_sg_table(client, handle);
-
- mutex_lock(&mdp3_res->iommu_lock);
- meta = mdp3_iommu_meta_lookup(table);
- if (!meta) {
- WARN(1, "%s: buffer was never mapped for %pK\n", __func__,
- handle);
- mutex_unlock(&mdp3_res->iommu_lock);
- return;
- }
- mutex_unlock(&mdp3_res->iommu_lock);
-
- mdp3_iommu_meta_put(meta);
-}
-
-static void mdp3_iommu_meta_add(struct mdp3_iommu_meta *meta)
-{
- struct rb_root *root = &mdp3_res->iommu_root;
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
- struct mdp3_iommu_meta *entry;
-
- while (*p) {
- parent = *p;
- entry = rb_entry(parent, struct mdp3_iommu_meta, node);
-
- if (meta->table < entry->table) {
- p = &(*p)->rb_left;
- } else if (meta->table > entry->table) {
- p = &(*p)->rb_right;
- } else {
- pr_err("%s: handle %pK already exists\n", __func__,
- entry->handle);
- WARN_ON(1);
- }
- }
-
- rb_link_node(&meta->node, parent, p);
- rb_insert_color(&meta->node, root);
-}
-
-static int mdp3_iommu_map_iommu(struct mdp3_iommu_meta *meta,
- unsigned long align, unsigned long iova_length,
- unsigned int padding, unsigned long flags)
-{
- struct iommu_domain *domain;
- int ret = 0;
- unsigned long size;
- unsigned long unmap_size;
- struct sg_table *table;
- int prot = IOMMU_WRITE | IOMMU_READ;
- unsigned int domain_num = (mdp3_res->domains +
- MDP3_IOMMU_DOMAIN_UNSECURE)->domain_idx;
- unsigned int partition_num = 0;
-
- size = meta->size;
- table = meta->table;
-
- /* Use the biggest alignment to allow bigger IOMMU mappings.
- * Use the first entry since the first entry will always be the
- * biggest entry. To take advantage of bigger mapping sizes both the
- * VA and PA addresses have to be aligned to the biggest size.
- */
- if (table->sgl->length > align)
- align = table->sgl->length;
-
- ret = msm_allocate_iova_address(domain_num, partition_num,
- meta->mapped_size, align,
- (unsigned long *)&meta->iova_addr);
-
- if (ret)
- goto out;
-
- domain = msm_get_iommu_domain(domain_num);
-
- if (!domain) {
- ret = -ENOMEM;
- goto out1;
- }
-
- /* Adding padding to before buffer */
- if (padding) {
- unsigned long phys_addr = sg_phys(table->sgl);
-
- ret = msm_iommu_map_extra(domain, meta->iova_addr, phys_addr,
- padding, SZ_4K, prot);
- if (ret)
- goto out1;
- }
-
- /* Mapping actual buffer */
- ret = iommu_map_range(domain, meta->iova_addr + padding,
- table->sgl, size, prot);
- if (ret) {
- pr_err("%s: could not map %pa in domain %pK\n",
- __func__, &meta->iova_addr, domain);
- unmap_size = padding;
- goto out2;
- }
-
- /* Adding padding to end of buffer */
- if (padding) {
- unsigned long phys_addr = sg_phys(table->sgl);
- unsigned long extra_iova_addr = meta->iova_addr +
- padding + size;
- ret = msm_iommu_map_extra(domain, extra_iova_addr, phys_addr,
- padding, SZ_4K, prot);
- if (ret) {
- unmap_size = padding + size;
- goto out2;
- }
- }
- return ret;
-
-out2:
- iommu_unmap_range(domain, meta->iova_addr, unmap_size);
-out1:
- msm_free_iova_address(meta->iova_addr, domain_num, partition_num,
- iova_length);
-
-out:
- return ret;
-}
-
-static struct mdp3_iommu_meta *mdp3_iommu_meta_create(struct ion_client *client,
- struct ion_handle *handle, struct sg_table *table, unsigned long size,
- unsigned long align, unsigned long iova_length, unsigned int padding,
- unsigned long flags, dma_addr_t *iova)
-{
- struct mdp3_iommu_meta *meta;
- int ret;
-
- meta = kzalloc(sizeof(*meta), GFP_KERNEL);
-
- if (!meta)
- return ERR_PTR(-ENOMEM);
-
- meta->handle = handle;
- meta->table = table;
- meta->size = size;
- meta->mapped_size = iova_length;
- meta->dbuf = ion_share_dma_buf(client, handle);
- kref_init(&meta->ref);
-
- ret = mdp3_iommu_map_iommu(meta,
- align, iova_length, padding, flags);
- if (ret < 0) {
- pr_err("%s: Unable to map buffer\n", __func__);
- goto out;
- }
-
- *iova = meta->iova_addr;
- mdp3_iommu_meta_add(meta);
-
- return meta;
-out:
- kfree(meta);
- return ERR_PTR(ret);
-}
-
-/*
- * PPP hw reads in tiles of 16 which might be outside mapped region
- * need to map buffers ourseleve to add extra padding
- */
-int mdp3_self_map_iommu(struct ion_client *client, struct ion_handle *handle,
- unsigned long align, unsigned long padding, dma_addr_t *iova,
- unsigned long *buffer_size, unsigned long flags,
- unsigned long iommu_flags)
-{
- struct mdp3_iommu_meta *iommu_meta = NULL;
- struct sg_table *table;
- struct scatterlist *sg;
- unsigned long size = 0, iova_length = 0;
- int ret = 0;
- int i;
-
- table = ion_sg_table(client, handle);
- if (IS_ERR_OR_NULL(table))
- return PTR_ERR(table);
-
- for_each_sg(table->sgl, sg, table->nents, i)
- size += sg->length;
-
- padding = PAGE_ALIGN(padding);
-
- /* Adding 16 lines padding before and after buffer */
- iova_length = size + 2 * padding;
-
- if (size & ~PAGE_MASK) {
- pr_debug("%s: buffer size %lx is not aligned to %lx",
- __func__, size, PAGE_SIZE);
- ret = -EINVAL;
- goto out;
- }
-
- if (iova_length & ~PAGE_MASK) {
- pr_debug("%s: iova_length %lx is not aligned to %lx",
- __func__, iova_length, PAGE_SIZE);
- ret = -EINVAL;
- goto out;
- }
-
- mutex_lock(&mdp3_res->iommu_lock);
- iommu_meta = mdp3_iommu_meta_lookup(table);
-
- if (!iommu_meta) {
- iommu_meta = mdp3_iommu_meta_create(client, handle, table, size,
- align, iova_length, padding, flags, iova);
- if (!IS_ERR_OR_NULL(iommu_meta)) {
- iommu_meta->flags = iommu_flags;
- ret = 0;
- } else {
- ret = PTR_ERR(iommu_meta);
- goto out_unlock;
- }
- } else {
- if (iommu_meta->flags != iommu_flags) {
- pr_err("%s: hndl %pK already mapped with diff flag\n",
- __func__, handle);
- ret = -EINVAL;
- goto out_unlock;
- } else if (iommu_meta->mapped_size != iova_length) {
- pr_err("%s: hndl %pK already mapped with diff len\n",
- __func__, handle);
- ret = -EINVAL;
- goto out_unlock;
- } else {
- kref_get(&iommu_meta->ref);
- *iova = iommu_meta->iova_addr;
- }
- }
- WARN_ON(iommu_meta->size != size);
- mutex_unlock(&mdp3_res->iommu_lock);
-
- *iova = *iova + padding;
- *buffer_size = size;
- return ret;
-
-out_unlock:
- mutex_unlock(&mdp3_res->iommu_lock);
-out:
- mdp3_iommu_meta_put(iommu_meta);
- return ret;
-}
-
int mdp3_put_img(struct mdp3_img_data *data, int client)
{
struct ion_client *iclient = mdp3_res->ion_client;
@@ -1877,10 +1390,10 @@
img->memory_id);
return -EINVAL;
}
- if (MAJOR(f.file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
- fb_num = MINOR(f.file->f_dentry->d_inode->i_rdev);
+ if (MAJOR(f.file->f_path.dentry->d_inode->i_rdev) == FB_MAJOR) {
+ fb_num = MINOR(f.file->f_path.dentry->d_inode->i_rdev);
ret = mdss_fb_get_phys_info(&data->addr,
- &data->len, fb_num);
+ &data->len, fb_num);
if (ret) {
pr_err("mdss_fb_get_phys_info() failed\n");
fdput(f);
@@ -2155,29 +1668,6 @@
return rc;
}
-void mdp3_free(struct msm_fb_data_type *mfd)
-{
- size_t size = 0;
- int dom;
- unsigned long phys;
-
- if (!mfd->iova || !mfd->fbi->screen_base) {
- pr_info("no fbmem allocated\n");
- return;
- }
-
- size = mfd->fbi->fix.smem_len;
- phys = mfd->fbi->fix.smem_start;
- dom = mdp3_res->domains[MDP3_IOMMU_DOMAIN_UNSECURE].domain_idx;
- iommu_unmap(mdp3_res->domains[MDP3_IOMMU_DOMAIN_UNSECURE].domain,
- phys, size);
- msm_iommu_unmap_contig_buffer(mfd->iova, dom, 0, size);
-
- mfd->fbi->screen_base = NULL;
- mfd->fbi->fix.smem_start = 0;
- mfd->iova = 0;
-}
-
void mdp3_release_splash_memory(struct msm_fb_data_type *mfd)
{
/* Give back the reserved memory to the system */
@@ -2188,7 +1678,6 @@
mdp3_res->splash_mem_addr,
mdp3_res->splash_mem_size);
}
- mdp3_free(mfd);
pr_debug("mdp3_release_splash_memory\n");
memblock_free(mdp3_res->splash_mem_addr,
mdp3_res->splash_mem_size);
@@ -3056,8 +2545,7 @@
#define mdp3_resume NULL
#endif
-
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
static int mdp3_runtime_resume(struct device *dev)
{
bool device_on = true;
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c
index 1ce1878..4a844e9 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.c
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.c
@@ -22,13 +22,13 @@
#include <linux/delay.h>
#include <linux/dma-buf.h>
#include <linux/pm_runtime.h>
-#include <linux/sw_sync.h>
#include <linux/iommu.h>
#include "mdp3_ctrl.h"
#include "mdp3.h"
#include "mdp3_ppp.h"
#include "mdss_smmu.h"
+#include "mdss_sync.h"
#define VSYNC_EXPIRE_TICK 4
@@ -233,7 +233,7 @@
mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex);
if (mdp3_session->retire_cnt > 0) {
- sw_sync_timeline_inc(mdp3_session->vsync_timeline, val);
+ mdss_inc_timeline(mfd->mdp_sync_pt_data.timeline_retire, val);
mdp3_session->retire_cnt -= min(val, mdp3_session->retire_cnt);
}
mutex_unlock(&mfd->mdp_sync_pt_data.sync_mutex);
@@ -1737,9 +1737,10 @@
}
break;
case metadata_op_get_ion_fd:
- if (mfd->fb_ion_handle) {
+ if (mfd->fb_ion_handle && mfd->fb_ion_client) {
metadata->data.fbmem_ionfd =
- dma_buf_fd(mfd->fbmem_buf, 0);
+ ion_share_dma_buf_fd(mfd->fb_ion_client,
+ mfd->fb_ion_handle);
if (metadata->data.fbmem_ionfd < 0)
pr_err("fd allocation failed. fd = %d\n",
metadata->data.fbmem_ionfd);
@@ -2116,7 +2117,7 @@
static int mdp3_histo_ioctl(struct msm_fb_data_type *mfd, u32 cmd,
void __user *argp)
{
- int ret = -ENOTSUP;
+ int ret = -ENOTSUPP;
struct mdp_histogram_data hist;
struct mdp_histogram_start_req hist_req;
u32 block;
@@ -2820,8 +2821,8 @@
mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
snprintf(name, sizeof(name), "mdss_fb%d_retire", mfd->index);
- mdp3_session->vsync_timeline = sw_sync_timeline_create(name);
- if (mdp3_session->vsync_timeline == NULL) {
+ mfd->mdp_sync_pt_data.timeline_retire = mdss_create_timeline(name);
+ if (mfd->mdp_sync_pt_data.timeline_retire == NULL) {
pr_err("cannot vsync create time line");
return -ENOMEM;
}
@@ -2874,8 +2875,9 @@
mutex_init(&mdp3_session->lock);
INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off);
- init_kthread_worker(&mdp3_session->worker);
- init_kthread_work(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done);
+ kthread_init_worker(&mdp3_session->worker);
+ kthread_init_work(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done);
+
mdp3_session->thread = kthread_run(kthread_worker_fn,
&mdp3_session->worker,
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.h b/drivers/video/fbdev/msm/mdp3_ctrl.h
index 2cc3421..b7b667b 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.h
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.h
@@ -79,7 +79,7 @@
int (*wait_for_dma_done)(struct mdp3_session_data *session);
/* For retire fence */
- struct sw_sync_timeline *vsync_timeline;
+ struct mdss_timeline *vsync_timeline;
int retire_cnt;
struct work_struct retire_work;
};
diff --git a/drivers/video/fbdev/msm/mdp3_layer.c b/drivers/video/fbdev/msm/mdp3_layer.c
index 6c45395..0078466 100644
--- a/drivers/video/fbdev/msm/mdp3_layer.c
+++ b/drivers/video/fbdev/msm/mdp3_layer.c
@@ -21,8 +21,6 @@
#include <linux/delay.h>
#include <linux/msm_mdp.h>
#include <linux/memblock.h>
-#include <linux/sync.h>
-#include <linux/sw_sync.h>
#include <linux/file.h>
#include <soc/qcom/event_timer.h>
@@ -31,17 +29,18 @@
#include "mdp3_ppp.h"
#include "mdp3_ctrl.h"
#include "mdss_fb.h"
+#include "mdss_sync.h"
enum {
MDP3_RELEASE_FENCE = 0,
MDP3_RETIRE_FENCE,
};
-static struct sync_fence *__mdp3_create_fence(struct msm_fb_data_type *mfd,
+static struct mdss_fence *__mdp3_create_fence(struct msm_fb_data_type *mfd,
struct msm_sync_pt_data *sync_pt_data, u32 fence_type,
int *fence_fd, int value)
{
- struct sync_fence *sync_fence = NULL;
+ struct mdss_fence *sync_fence = NULL;
char fence_name[32];
struct mdp3_session_data *mdp3_session;
@@ -56,38 +55,42 @@
if ((fence_type == MDP3_RETIRE_FENCE) &&
(mfd->panel.type == MIPI_CMD_PANEL)) {
- if (mdp3_session->vsync_timeline) {
- value = mdp3_session->vsync_timeline->value + 1 +
- mdp3_session->retire_cnt++;
- sync_fence = mdss_fb_sync_get_fence(
- mdp3_session->vsync_timeline,
+ if (sync_pt_data->timeline_retire) {
+ value = sync_pt_data->timeline_retire->value + 1 +
+ mdp3_session->retire_cnt++;
+ sync_fence = mdss_fb_sync_get_fence(
+ sync_pt_data->timeline_retire,
fence_name, value);
+
} else {
return ERR_PTR(-EPERM);
}
} else {
- sync_fence = mdss_fb_sync_get_fence(sync_pt_data->timeline,
- fence_name, value);
- }
+ if (fence_type == MDP3_RETIRE_FENCE)
+ sync_fence = mdss_fb_sync_get_fence(
+ sync_pt_data->timeline_retire,
+ fence_name, value);
+ else
+ sync_fence = mdss_fb_sync_get_fence(
+ sync_pt_data->timeline,
+ fence_name, value);
+ }
if (IS_ERR_OR_NULL(sync_fence)) {
pr_err("%s: unable to retrieve release fence\n", fence_name);
goto end;
}
- /* get fence fd */
- *fence_fd = get_unused_fd_flags(0);
+ *fence_fd = mdss_get_sync_fence_fd(sync_fence);
if (*fence_fd < 0) {
pr_err("%s: get_unused_fd_flags failed error:0x%x\n",
fence_name, *fence_fd);
- sync_fence_put(sync_fence);
- sync_fence = NULL;
- goto end;
+ mdss_put_sync_fence(sync_fence);
+ sync_fence = NULL;
+ goto end;
}
-
- sync_fence_install(sync_fence, *fence_fd);
+ pr_debug("%s:val=%d\n", mdss_get_sync_fence_name(sync_fence), value);
end:
-
return sync_fence;
}
@@ -101,7 +104,7 @@
static int __mdp3_handle_buffer_fences(struct msm_fb_data_type *mfd,
struct mdp_layer_commit_v1 *commit, struct mdp_input_layer *layer_list)
{
- struct sync_fence *fence, *release_fence, *retire_fence;
+ struct mdss_fence *fence, *release_fence, *retire_fence;
struct msm_sync_pt_data *sync_pt_data = NULL;
struct mdp_input_layer *layer;
int value;
@@ -127,7 +130,7 @@
if (layer->buffer.fence < 0)
continue;
- fence = sync_fence_fdget(layer->buffer.fence);
+ fence = mdss_get_fd_sync_fence(layer->buffer.fence);
if (!fence) {
pr_err("%s: sync fence get failed! fd=%d\n",
sync_pt_data->fence_name, layer->buffer.fence);
@@ -142,7 +145,7 @@
if (ret)
goto sync_fence_err;
- value = sync_pt_data->timeline_value + sync_pt_data->threshold +
+ value = sync_pt_data->threshold +
atomic_read(&sync_pt_data->commit_cnt);
release_fence = __mdp3_create_fence(mfd, sync_pt_data,
@@ -166,13 +169,13 @@
retire_fence_err:
put_unused_fd(commit->release_fence);
- sync_fence_put(release_fence);
+ mdss_put_sync_fence(release_fence);
release_fence_err:
commit->retire_fence = -1;
commit->release_fence = -1;
sync_fence_err:
for (i = 0; i < sync_pt_data->acq_fen_cnt; i++)
- sync_fence_put(sync_pt_data->acq_fen[i]);
+ mdss_put_sync_fence(sync_pt_data->acq_fen[i]);
sync_pt_data->acq_fen_cnt = 0;
mutex_unlock(&sync_pt_data->sync_mutex);
diff --git a/drivers/video/fbdev/msm/mdp3_ppp.c b/drivers/video/fbdev/msm/mdp3_ppp.c
index 3b72b2d..612cccc 100644
--- a/drivers/video/fbdev/msm/mdp3_ppp.c
+++ b/drivers/video/fbdev/msm/mdp3_ppp.c
@@ -20,8 +20,6 @@
#include <linux/uaccess.h>
#include <linux/sched.h>
#include <linux/mutex.h>
-#include <linux/sync.h>
-#include <linux/sw_sync.h>
#include "linux/proc_fs.h"
#include <linux/delay.h>
@@ -30,6 +28,7 @@
#include "mdp3_hwio.h"
#include "mdp3.h"
#include "mdss_debug.h"
+#include "mdss_sync.h"
#define MDP_IS_IMGTYPE_BAD(x) ((x) >= MDP_IMGTYPE_LIMIT)
#define MDP_RELEASE_BW_TIMEOUT 50
@@ -76,12 +75,12 @@
struct mdp_blit_req req_list[MAX_LIST_WINDOW];
struct mdp3_img_data src_data[MAX_LIST_WINDOW];
struct mdp3_img_data dst_data[MAX_LIST_WINDOW];
- struct sync_fence *acq_fen[MDP_MAX_FENCE_FD];
+ struct mdss_fence *acq_fen[MDP_MAX_FENCE_FD];
u32 acq_fen_cnt;
int cur_rel_fen_fd;
struct sync_pt *cur_rel_sync_pt;
- struct sync_fence *cur_rel_fence;
- struct sync_fence *last_rel_fence;
+ struct mdss_fence *cur_rel_fence;
+ struct mdss_fence *last_rel_fence;
};
struct blit_req_queue {
@@ -104,7 +103,8 @@
struct task_struct *blit_thread;
struct blit_req_queue req_q;
- struct sw_sync_timeline *timeline;
+ struct mdss_timeline *timeline;
+
int timeline_value;
struct timer_list free_bw_timer;
@@ -1188,19 +1188,19 @@
ATRACE_BEGIN(__func__);
/* buf sync */
for (i = 0; i < req->acq_fen_cnt; i++) {
- ret = sync_fence_wait(req->acq_fen[i],
+ ret = mdss_wait_sync_fence(req->acq_fen[i],
WAIT_FENCE_FINAL_TIMEOUT);
if (ret < 0) {
pr_err("%s: sync_fence_wait failed! ret = %x\n",
__func__, ret);
break;
}
- sync_fence_put(req->acq_fen[i]);
+ mdss_put_sync_fence(req->acq_fen[i]);
}
ATRACE_END(__func__);
if (ret < 0) {
while (i < req->acq_fen_cnt) {
- sync_fence_put(req->acq_fen[i]);
+ mdss_put_sync_fence(req->acq_fen[i]);
i++;
}
}
@@ -1209,7 +1209,7 @@
void mdp3_ppp_signal_timeline(struct blit_req_list *req)
{
- sw_sync_timeline_inc(ppp_stat->timeline, 1);
+ mdss_inc_timeline(ppp_stat->timeline, 1);
MDSS_XLOG(ppp_stat->timeline->value, ppp_stat->timeline_value);
req->last_rel_fence = req->cur_rel_fence;
req->cur_rel_fence = 0;
@@ -1221,12 +1221,12 @@
int i;
put_unused_fd(req->cur_rel_fen_fd);
- sync_fence_put(req->cur_rel_fence);
+ mdss_put_sync_fence(req->cur_rel_fence);
req->cur_rel_fence = NULL;
req->cur_rel_fen_fd = 0;
ppp_stat->timeline_value--;
for (i = 0; i < req->acq_fen_cnt; i++)
- sync_fence_put(req->acq_fen[i]);
+ mdss_put_sync_fence(req->acq_fen[i]);
req->acq_fen_cnt = 0;
}
@@ -1235,7 +1235,7 @@
{
int i, fence_cnt = 0, ret = 0;
int acq_fen_fd[MDP_MAX_FENCE_FD];
- struct sync_fence *fence;
+ struct mdss_fence *fence;
if ((buf_sync->acq_fen_fd_cnt > MDP_MAX_FENCE_FD) ||
(ppp_stat->timeline == NULL))
@@ -1249,7 +1249,7 @@
return ret;
}
for (i = 0; i < buf_sync->acq_fen_fd_cnt; i++) {
- fence = sync_fence_fdget(acq_fen_fd[i]);
+ fence = mdss_get_fd_sync_fence(acq_fen_fd[i]);
if (fence == NULL) {
pr_info("%s: null fence! i=%d fd=%d\n", __func__, i,
acq_fen_fd[i]);
@@ -1265,19 +1265,12 @@
if (buf_sync->flags & MDP_BUF_SYNC_FLAG_WAIT)
mdp3_ppp_wait_for_fence(req);
- req->cur_rel_sync_pt = sw_sync_pt_create(ppp_stat->timeline,
- ppp_stat->timeline_value++);
MDSS_XLOG(ppp_stat->timeline_value);
- if (req->cur_rel_sync_pt == NULL) {
- pr_err("%s: cannot create sync point\n", __func__);
- ret = -ENOMEM;
- goto buf_sync_err_2;
- }
+
/* create fence */
- req->cur_rel_fence = sync_fence_create("ppp-fence",
- req->cur_rel_sync_pt);
+ req->cur_rel_fence = mdss_get_sync_fence(ppp_stat->timeline,
+ "ppp_fence", NULL, ppp_stat->timeline_value++);
if (req->cur_rel_fence == NULL) {
- sync_pt_free(req->cur_rel_sync_pt);
req->cur_rel_sync_pt = NULL;
pr_err("%s: cannot create fence\n", __func__);
ret = -ENOMEM;
@@ -1289,7 +1282,7 @@
ppp_stat->timeline_value--;
buf_sync_err_1:
for (i = 0; i < fence_cnt; i++)
- sync_fence_put(req->acq_fen[i]);
+ mdss_put_sync_fence(req->acq_fen[i]);
req->acq_fen_cnt = 0;
return ret;
}
@@ -1586,7 +1579,7 @@
{
struct blit_req_list *req;
struct blit_req_queue *req_q = &ppp_stat->req_q;
- struct sync_fence *fence = NULL;
+ struct mdss_fence *fence = NULL;
int count, rc, idx, i;
count = req_list_header->count;
@@ -1642,13 +1635,8 @@
}
if (async) {
- req->cur_rel_fen_fd = get_unused_fd_flags(0);
- if (req->cur_rel_fen_fd < 0) {
- pr_err("%s: get_unused_fd_flags failed\n", __func__);
- rc = -ENOMEM;
- goto parse_err_1;
- }
- sync_fence_install(req->cur_rel_fence, req->cur_rel_fen_fd);
+ req->cur_rel_fen_fd = mdss_get_sync_fence_fd(
+ req->cur_rel_fence);
rc = copy_to_user(req_list_header->sync.rel_fen_fd,
&req->cur_rel_fen_fd, sizeof(int));
if (rc) {
@@ -1664,12 +1652,12 @@
kthread_queue_work(&ppp_stat->kworker, &ppp_stat->blit_work);
if (!async) {
/* wait for release fence */
- rc = sync_fence_wait(fence,
+ rc = mdss_wait_sync_fence(fence,
5 * MSEC_PER_SEC);
if (rc < 0)
pr_err("%s: sync blit! rc = %x\n", __func__, rc);
- sync_fence_put(fence);
+ mdss_put_sync_fence(fence);
fence = NULL;
}
return 0;
@@ -1697,15 +1685,15 @@
return -ENOMEM;
/*Setup sync_pt timeline for ppp*/
- ppp_stat->timeline = sw_sync_timeline_create(timeline_name);
+ ppp_stat->timeline = mdss_create_timeline(timeline_name);
if (ppp_stat->timeline == NULL) {
pr_err("%s: cannot create time line\n", __func__);
return -ENOMEM;
}
ppp_stat->timeline_value = 1;
- init_kthread_worker(&ppp_stat->kworker);
- init_kthread_work(&ppp_stat->blit_work, mdp3_ppp_blit_handler);
+ kthread_init_worker(&ppp_stat->kworker);
+ kthread_init_work(&ppp_stat->blit_work, mdp3_ppp_blit_handler);
ppp_stat->blit_thread = kthread_run(kthread_worker_fn,
&ppp_stat->kworker,
"mdp3_ppp");
diff --git a/drivers/video/fbdev/msm/mdp3_ppp_hwio.c b/drivers/video/fbdev/msm/mdp3_ppp_hwio.c
index 6f077e2..ec806cf 100644
--- a/drivers/video/fbdev/msm/mdp3_ppp_hwio.c
+++ b/drivers/video/fbdev/msm/mdp3_ppp_hwio.c
@@ -41,7 +41,7 @@
LAYER_MAX,
};
-static long long mdp_do_div(long long num, long long den)
+static long long mdp_do_div(uint64_t num, uint64_t den)
{
do_div(num, den);
return num;
diff --git a/drivers/video/fbdev/msm/mdss_debug_xlog.c b/drivers/video/fbdev/msm/mdss_debug_xlog.c
index 49684f4..a651b55 100644
--- a/drivers/video/fbdev/msm/mdss_debug_xlog.c
+++ b/drivers/video/fbdev/msm/mdss_debug_xlog.c
@@ -683,6 +683,11 @@
if (__mdss_xlog_dump_calc_range()) {
len = mdss_xlog_dump_entry(xlog_buf, MDSS_XLOG_BUF_MAX);
+ if (len < 0 || len > count) {
+ pr_err("len is more than the size of user buffer\n");
+ return 0;
+ }
+
if (copy_to_user(buff, xlog_buf, len))
return -EFAULT;
*ppos += len;
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index d70c1e8..6bb0960 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -743,7 +743,7 @@
if (blen < 0)
return 0;
- if (copy_to_user(buf, buffer, blen))
+ if (copy_to_user(buf, buffer, min(count, (size_t)blen+1)))
return -EFAULT;
*ppos += blen;
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 25d70f00..27299d10 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -3221,7 +3221,6 @@
mfd->msm_fb_backup.info = *info;
mfd->msm_fb_backup.disp_commit = *disp_commit;
- atomic_inc(&mfd->mdp_sync_pt_data.commit_cnt);
atomic_inc(&mfd->commits_pending);
atomic_inc(&mfd->kickoff_pending);
wake_up_all(&mfd->commit_wait_q);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 5088117..344d6ef 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -76,13 +76,15 @@
u64 result = val;
if (val) {
- u64 temp = -1UL;
+ u64 temp = U64_MAX;
do_div(temp, val);
if (temp > numer) {
/* no overflow, so we can do the operation*/
result = (val * (u64)numer);
do_div(result, denom);
+ } else {
+ pr_warn("Overflow, skip fudge factor\n");
}
}
return result;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 05f52a5..80708aa 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -2913,6 +2913,11 @@
}
}
+ if (!data) {
+ atomic_inc(&mfd->mdp_sync_pt_data.commit_cnt);
+ MDSS_XLOG(atomic_read(&mfd->mdp_sync_pt_data.commit_cnt));
+ }
+
/*
* Setup pipe in solid fill before unstaging,
* to ensure no fetches are happening after dettach or reattach.
diff --git a/drivers/video/fbdev/msm/mdss_sync.c b/drivers/video/fbdev/msm/mdss_sync.c
index 6308162..8fe9461 100644
--- a/drivers/video/fbdev/msm/mdss_sync.c
+++ b/drivers/video/fbdev/msm/mdss_sync.c
@@ -218,6 +218,7 @@
spin_lock(&tl->list_lock);
if (list_empty(&tl->fence_list_head)) {
pr_debug("fence list is empty\n");
+ tl->value += 1;
spin_unlock(&tl->list_lock);
return 0;
}
diff --git a/include/linux/ipc_logging.h b/include/linux/ipc_logging.h
index 780a82d..5bc8b6a 100644
--- a/include/linux/ipc_logging.h
+++ b/include/linux/ipc_logging.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2018 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
@@ -124,6 +124,13 @@
*/
int ipc_log_string(void *ilctxt, const char *fmt, ...) __printf(2, 3);
+/*
+ * ipc_log_ctrl_all - disable/enable logging in all clients
+ *
+ * @ Data specified using format specifiers
+ */
+void ipc_log_ctrl_all(bool disable);
+
/**
* ipc_log_extract - Reads and deserializes log
*
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 7c69d6c..629907a 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -279,6 +279,7 @@
POWER_SUPPLY_PROP_BATT_FULL_CURRENT,
POWER_SUPPLY_PROP_RECHARGE_SOC,
POWER_SUPPLY_PROP_TOGGLE_STAT,
+ POWER_SUPPLY_PROP_ALLOW_HVDCP3,
/* Local extensions of type int64_t */
POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT,
/* Properties of type `const char *' */
diff --git a/include/linux/usb_bam.h b/include/linux/usb_bam.h
index e5d4c04..fc0647a 100644
--- a/include/linux/usb_bam.h
+++ b/include/linux/usb_bam.h
@@ -438,6 +438,7 @@
bool msm_bam_hsic_lpm_ok(void);
bool msm_bam_hsic_host_pipe_empty(void);
bool msm_usb_bam_enable(enum usb_ctrl ctrl, bool bam_enable);
+int msm_do_bam_disable_enable(enum usb_ctrl ctrl);
#else
static inline int usb_bam_connect(enum usb_ctrl bam, u8 idx, u32 *bam_pipe_idx,
unsigned long iova)
@@ -543,6 +544,7 @@
static inline bool msm_bam_hsic_host_pipe_empty(void) { return true; }
static inline bool msm_usb_bam_enable(enum usb_ctrl ctrl, bool bam_enable)
{ return true; }
+int msm_do_bam_disable_enable(enum usb_ctrl ctrl) { return true; }
#endif
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 47fb288..b37f8df 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -132,7 +132,6 @@
bool wcnss_cbc_complete(void);
int wcnss_device_is_shutdown(void);
void wcnss_riva_dump_pmic_regs(void);
-void wcnss_free_regulator(void);
int wcnss_xo_auto_detect_enabled(void);
u32 wcnss_get_wlan_rx_buff_count(void);
int wcnss_wlan_iris_xo_mode(void);
diff --git a/include/media/msmb_generic_buf_mgr.h b/include/media/msmb_generic_buf_mgr.h
index b3e1a02..95cfcad7 100644
--- a/include/media/msmb_generic_buf_mgr.h
+++ b/include/media/msmb_generic_buf_mgr.h
@@ -43,6 +43,8 @@
#define VIDIOC_MSM_BUF_MNGR_FLUSH32 \
_IOWR('V', BASE_VIDIOC_PRIVATE + 39, struct msm_buf_mngr_info32_t)
+#define VIDIOC_MSM_BUF_MNGR_BUF_ERROR32 \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 41, struct msm_buf_mngr_info32_t)
#endif
#endif
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index 22888b0..aab92ad 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -34,6 +34,9 @@
#include <linux/mutex.h>
#include <linux/atomic.h>
+#define RDS_PS_SIMPLE_OFFSET 2
+extern struct mutex fm_smd_enable;
+
struct radio_hci_dev {
char name[8];
unsigned long flags;
@@ -75,7 +78,7 @@
};
int radio_hci_register_dev(struct radio_hci_dev *hdev);
-int radio_hci_unregister_dev(struct radio_hci_dev *hdev);
+int radio_hci_unregister_dev(void);
int radio_hci_recv_frame(struct sk_buff *skb);
int radio_hci_send_cmd(struct radio_hci_dev *hdev, __u16 opcode, __u32 plen,
void *param);
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 574ff2a..916f1dc 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -331,7 +331,8 @@
struct v4l2_format *f);
int (*vidioc_g_fmt_sdr_out)(struct file *file, void *fh,
struct v4l2_format *f);
-
+ int (*vidioc_g_fmt_type_private)(struct file *file, void *fh,
+ struct v4l2_format *f);
/* VIDIOC_S_FMT handlers */
int (*vidioc_s_fmt_vid_cap)(struct file *file, void *fh,
struct v4l2_format *f);
diff --git a/include/soc/qcom/memory_dump.h b/include/soc/qcom/memory_dump.h
index 5bc50b5..a962a16 100644
--- a/include/soc/qcom/memory_dump.h
+++ b/include/soc/qcom/memory_dump.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2014-2018, 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
@@ -87,7 +87,8 @@
MSM_DUMP_DATA_POWER_REGS = 0xED,
MSM_DUMP_DATA_TMC_ETF = 0xF0,
MSM_DUMP_DATA_TPDM_SWAO_MCMB = 0xF2,
- MSM_DUMP_DATA_TMC_REG = 0x100,
+ MSM_DUMP_DATA_TMC_ETR_REG = 0x100,
+ MSM_DUMP_DATA_TMC_ETF_REG = 0x101,
MSM_DUMP_DATA_LOG_BUF = 0x110,
MSM_DUMP_DATA_LOG_BUF_FIRST_IDX = 0x111,
MSM_DUMP_DATA_SCANDUMP_PER_CPU = 0x130,
@@ -121,11 +122,22 @@
uint64_t addr;
};
+struct dump_vaddr_entry {
+ uint32_t id;
+ void *dump_vaddr;
+ struct msm_dump_data *dump_data_vaddr;
+};
+
+struct msm_mem_dump_vaddr_tbl {
+ uint8_t num_node;
+ struct dump_vaddr_entry *entries;
+};
+
#ifdef CONFIG_QCOM_MEMORY_DUMP_V2
extern int msm_dump_data_register(enum msm_dump_table_ids id,
struct msm_dump_entry *entry);
-extern void *get_msm_dump_ptr(enum msm_dump_data_ids id);
+extern struct dump_vaddr_entry *get_msm_dump_ptr(enum msm_dump_data_ids id);
#else
static inline int msm_dump_data_register(enum msm_dump_table_ids id,
struct msm_dump_entry *entry)
diff --git a/include/soc/qcom/scm.h b/include/soc/qcom/scm.h
index 63698cf..fa64d5d 100644
--- a/include/soc/qcom/scm.h
+++ b/include/soc/qcom/scm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2018, 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
@@ -100,6 +100,8 @@
extern int scm_call2(u32 cmd_id, struct scm_desc *desc);
+extern int scm_call2_noretry(u32 cmd_id, struct scm_desc *desc);
+
extern int scm_call2_atomic(u32 cmd_id, struct scm_desc *desc);
extern int scm_call_noalloc(u32 svc_id, u32 cmd_id, const void *cmd_buf,
@@ -149,6 +151,11 @@
return 0;
}
+static inline int scm_call2_noretry(u32 cmd_id, struct scm_desc *desc)
+{
+ return 0;
+}
+
static inline int scm_call2_atomic(u32 cmd_id, struct scm_desc *desc)
{
return 0;
diff --git a/include/trace/events/trace_msm_pil_event.h b/include/trace/events/trace_msm_pil_event.h
index 4795dc5..072bbbb 100644
--- a/include/trace/events/trace_msm_pil_event.h
+++ b/include/trace/events/trace_msm_pil_event.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -40,6 +40,7 @@
__get_str(fw_name))
);
+#ifdef CONFIG_MSM_PIL
TRACE_EVENT(pil_notif,
TP_PROTO(const char *event_name, unsigned long code,
@@ -64,6 +65,9 @@
__entry->code,
__get_str(fw_name))
);
+#else
+#define trace_pil_notif(event_name, code, fw_name) do { } while (0)
+#endif
TRACE_EVENT(pil_func,
diff --git a/include/uapi/media/msmb_generic_buf_mgr.h b/include/uapi/media/msmb_generic_buf_mgr.h
index 2961cae..8dad9ae 100644
--- a/include/uapi/media/msmb_generic_buf_mgr.h
+++ b/include/uapi/media/msmb_generic_buf_mgr.h
@@ -62,5 +62,7 @@
_IOWR('V', BASE_VIDIOC_PRIVATE + 40, \
struct msm_camera_private_ioctl_arg)
+#define VIDIOC_MSM_BUF_MNGR_BUF_ERROR \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 41, struct msm_buf_mngr_info)
#endif
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index 53974cc..895c63f 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -246,7 +246,7 @@
if (unlikely(!sysctl_sched_use_walt_cpu_util))
return;
- WARN_ON(curr_ws < last_ws);
+ BUG_ON(curr_ws < last_ws);
if (curr_ws <= last_ws)
return;
diff --git a/kernel/trace/ipc_logging.c b/kernel/trace/ipc_logging.c
index ec9bde7..68a9ad7 100644
--- a/kernel/trace/ipc_logging.c
+++ b/kernel/trace/ipc_logging.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 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
@@ -295,6 +295,8 @@
return;
}
+ if (ilctxt->disabled)
+ return;
read_lock_irqsave(&context_list_lock_lha1, flags);
spin_lock(&ilctxt->context_lock_lhb1);
while (ilctxt->write_avail <= ectxt->offset)
@@ -508,11 +510,14 @@
{
struct encode_context ectxt;
int avail_size, data_size, hdr_size = sizeof(struct tsv_header);
+ struct ipc_log_context *ctxt = (struct ipc_log_context *)ilctxt;
va_list arg_list;
if (!ilctxt)
return -EINVAL;
+ if (ctxt->disabled)
+ return -EBUSY;
msg_encode_start(&ectxt, TSV_TYPE_STRING);
tsv_timestamp_write(&ectxt);
tsv_qtimer_write(&ectxt);
@@ -529,6 +534,32 @@
}
EXPORT_SYMBOL(ipc_log_string);
+/*
+ * ipc_log_ctrl_all - disable/enable logging in all clients
+ *
+ * @ Data specified using format specifiers
+ */
+void ipc_log_ctrl_all(bool disable)
+{
+ struct ipc_log_context *ctxt = NULL;
+ unsigned long flags;
+
+ read_lock_irqsave(&context_list_lock_lha1, flags);
+ list_for_each_entry(ctxt, &ipc_log_context_list, list) {
+ if (disable) {
+ ipc_log_string(ctxt,
+ "LOGGING DISABLED FOR ALL CLIENTS!!\n");
+ ctxt->disabled = disable;
+ } else {
+ ctxt->disabled = disable;
+ ipc_log_string(ctxt,
+ "LOGGING ENABLED FOR ALL CLIENTS!!\n");
+ }
+ }
+ read_unlock_irqrestore(&context_list_lock_lha1, flags);
+}
+EXPORT_SYMBOL(ipc_log_ctrl_all);
+
/**
* ipc_log_extract - Reads and deserializes log
*
diff --git a/kernel/trace/ipc_logging_debug.c b/kernel/trace/ipc_logging_debug.c
index d733724..7a4c630 100644
--- a/kernel/trace/ipc_logging_debug.c
+++ b/kernel/trace/ipc_logging_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015,2017-2018 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
@@ -113,6 +113,83 @@
return bsize;
}
+static ssize_t debug_write_ctrl(struct file *file, const char __user *buff,
+ size_t count, loff_t *ppos)
+{
+ struct ipc_log_context *ilctxt;
+ struct dentry *d = file->f_path.dentry;
+ int bsize = 1;
+ int srcu_idx;
+ int r;
+ char local_buf[3];
+
+ r = debugfs_use_file_start(d, &srcu_idx);
+ if (!r) {
+ ilctxt = file->private_data;
+ r = kref_get_unless_zero(&ilctxt->refcount) ? 0 : -EIO;
+ }
+ debugfs_use_file_finish(srcu_idx);
+ if (r)
+ return r;
+
+ if (copy_from_user(local_buf, buff, bsize)) {
+ count = -EFAULT;
+ goto done;
+ }
+
+ if (*local_buf == '1') {
+ ipc_log_string(ilctxt, "LOGGING DISABLED FOR THIS CLIENT!!\n");
+ ilctxt->disabled = true;
+ } else if (*local_buf == '0') {
+ ilctxt->disabled = false;
+ ipc_log_string(ilctxt, "LOGGING ENABLED FOR THIS CLIENT!!\n");
+ }
+
+done:
+ ipc_log_context_put(ilctxt);
+ return count;
+}
+
+
+static ssize_t debug_write_ctrl_all(struct file *file, const char __user *buff,
+ size_t count, loff_t *ppos)
+{
+ int bsize = 1;
+ char local_buf[3];
+
+ if (copy_from_user(local_buf, buff, bsize))
+ return -EFAULT;
+ if (*local_buf == '1')
+ ipc_log_ctrl_all(true);
+ else if (*local_buf == '0')
+ ipc_log_ctrl_all(false);
+ return count;
+}
+
+static ssize_t debug_read_ctrl(struct file *file, char __user *buff,
+ size_t count, loff_t *ppos)
+{
+ struct ipc_log_context *ilctxt;
+ struct dentry *d = file->f_path.dentry;
+ int bsize = 2;
+ int srcu_idx;
+ int r;
+
+ r = debugfs_use_file_start(d, &srcu_idx);
+ if (!r) {
+ ilctxt = file->private_data;
+ r = kref_get_unless_zero(&ilctxt->refcount) ? 0 : -EIO;
+ }
+ debugfs_use_file_finish(srcu_idx);
+ if (r)
+ return r;
+
+ bsize = simple_read_from_buffer(buff, count, ppos,
+ ilctxt->disabled?"1\n":"0\n", bsize);
+ ipc_log_context_put(ilctxt);
+ return bsize;
+}
+
static ssize_t debug_read(struct file *file, char __user *buff,
size_t count, loff_t *ppos)
{
@@ -141,6 +218,16 @@
.open = debug_open,
};
+static const struct file_operations debug_ops_ctrl = {
+ .read = debug_read_ctrl,
+ .write = debug_write_ctrl,
+ .open = debug_open,
+};
+
+static const struct file_operations debug_ops_ctrl_all = {
+ .write = debug_write_ctrl_all,
+};
+
static void debug_create(const char *name, mode_t mode,
struct dentry *dent,
struct ipc_log_context *ilctxt,
@@ -176,6 +263,9 @@
pr_err("%s: unable to create debugfs %ld\n",
__func__, PTR_ERR(root_dent));
root_dent = NULL;
+ } else {
+ debug_create("ctrl_all", 0444, root_dent,
+ NULL, &debug_ops_ctrl_all);
}
}
mutex_unlock(&ipc_log_debugfs_init_lock);
@@ -195,6 +285,8 @@
ctxt, &debug_ops);
debug_create("log_cont", 0444, ctxt->dent,
ctxt, &debug_ops_cont);
+ debug_create("log_disable", 0444, ctxt->dent,
+ ctxt, &debug_ops_ctrl);
}
}
add_deserialization_func((void *)ctxt,
diff --git a/kernel/trace/ipc_logging_private.h b/kernel/trace/ipc_logging_private.h
index 47c41e9..bb91dce 100644
--- a/kernel/trace/ipc_logging_private.h
+++ b/kernel/trace/ipc_logging_private.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 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
@@ -121,6 +121,7 @@
struct completion read_avail;
struct kref refcount;
bool destroyed;
+ bool disabled;
};
struct dfunc_info {
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 9b59170..1d4429d 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -1589,8 +1589,7 @@
}
/*
- * Stop the automatic memory scanning thread. This function must be called
- * with the scan_mutex held.
+ * Stop the automatic memory scanning thread.
*/
static void stop_scan_thread(void)
{
@@ -1853,12 +1852,15 @@
{
stop_scan_thread();
+ mutex_lock(&scan_mutex);
/*
- * Once the scan thread has stopped, it is safe to no longer track
- * object freeing. Ordering of the scan thread stopping and the memory
- * accesses below is guaranteed by the kthread_stop() function.
+ * Once it is made sure that kmemleak_scan has stopped, it is safe to no
+ * longer track object freeing. Ordering of the scan thread stopping and
+ * the memory accesses below is guaranteed by the kthread_stop()
+ * function.
*/
kmemleak_free_enabled = 0;
+ mutex_unlock(&scan_mutex);
if (!kmemleak_found_leaks)
__kmemleak_do_cleanup();
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 7fe91b1..eb4cc00 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -1202,9 +1202,12 @@
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
-country QA:
+country QA: DFS-ETSI
(2402 - 2482 @ 40), (20)
- (5735 - 5835 @ 80), (30)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5730 @ 80), (20), DFS
+ (5735 - 5875 @ 80), (20)
country RE: DFS-ETSI
(2402 - 2482 @ 40), (20)