Merge "arm/dt: msm8610: Adjust lpm settings for SDHC1 & SDHC2 devices"
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
new file mode 100644
index 0000000..6508329
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -0,0 +1,78 @@
+* ARM CPUs binding description
+
+The device tree allows to describe the layout of CPUs in a system through
+the "cpus" node, which in turn contains a number of subnodes (ie "cpu")
+defining properties for every cpu.
+
+Bindings for CPU nodes follow the ePAPR standard, available from:
+
+http://devicetree.org
+
+For the ARM architecture every CPU node must contain the following properties:
+
+- device_type: must be "cpu"
+- reg: property matching the CPU MPIDR[23:0] register bits
+ reg[31:24] bits must be set to 0
+- compatible: should be one of:
+ "arm,arm1020"
+ "arm,arm1020e"
+ "arm,arm1022"
+ "arm,arm1026"
+ "arm,arm720"
+ "arm,arm740"
+ "arm,arm7tdmi"
+ "arm,arm920"
+ "arm,arm922"
+ "arm,arm925"
+ "arm,arm926"
+ "arm,arm940"
+ "arm,arm946"
+ "arm,arm9tdmi"
+ "arm,cortex-a5"
+ "arm,cortex-a7"
+ "arm,cortex-a8"
+ "arm,cortex-a9"
+ "arm,cortex-a15"
+ "arm,arm1136"
+ "arm,arm1156"
+ "arm,arm1176"
+ "arm,arm11mpcore"
+ "faraday,fa526"
+ "intel,sa110"
+ "intel,sa1100"
+ "marvell,feroceon"
+ "marvell,mohawk"
+ "marvell,xsc3"
+ "marvell,xscale"
+ "qcom,krait"
+
+Example:
+
+ cpus {
+ #size-cells = <0>;
+ #address-cells = <1>;
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x0>;
+ };
+
+ CPU1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x1>;
+ };
+
+ CPU2: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x100>;
+ };
+
+ CPU3: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x101>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
index 23498e5..6ef2b77 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
@@ -24,6 +24,8 @@
Optional properties
+- qcom,freq-control-mask: The cpu mask that will be used to determine if a
+ core can be used for freq control.
- qcom,core-limit-temp: Threshold temperature to start shutting down cores
in degC
- qcom,core-temp-hysterisis: Degrees C below which the cores will be brought
@@ -77,6 +79,7 @@
qcom,limit-temp = <60>;
qcom,temp-hysteresis = <10>;
qcom,freq-step = <2>;
+ qcom,freq-control-mask = <0xf>
qcom,core-limit-temp = <90>;
qcom,core-temp-hysterisis = <10>;
qcom,core-control-mask = <7>;
diff --git a/Documentation/devicetree/bindings/arm/msm/pm_snoc_client.txt b/Documentation/devicetree/bindings/arm/msm/pm_snoc_client.txt
new file mode 100644
index 0000000..4f7111f
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/pm_snoc_client.txt
@@ -0,0 +1,35 @@
+* MSM PM SNOC client
+
+MSM PM SNOC client device is used to setup a bus request for 100 Mhz for the
+SNOC bus when the Apps cores are active. This bus request helps mitigate the
+exit latency from power collapse in cases where there aren't any active bus
+requests for SNOC.
+
+This device is dependent on the pm-8x60 device, which configures the low power
+mode of respective cores.
+
+The required properties of this device are:
+
+- compatible: qcom,pm-snoc-client
+- qcom,msm-bus,name: String representing the client-name
+- qcom,msm-bus,num-cases: Total number of usecases
+- qcom,msm-bus,active-only: Boolean context flag for requests in active or
+ dual (active & sleep) contex
+- qcom,msm-bus,num-paths: Total number of master-slave pairs
+- qcom,msm-bus,vectors-KBps: Arrays of unsigned integers representing:
+ master-id, slave-id, arbitrated bandwidth
+ in KBps, instantaneous bandwidth in KBps
+
+
+Example:
+ qcom,pm-snoc-client {
+ compatible = "qcom,pm-snoc-client";
+ qcom,msm-bus,name = "ocimem_snoc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors =
+ <22 512 0 0>,
+ <22 512 320000 3200000>;
+ };
+
diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt
index 436dfc7..052feeb 100644
--- a/Documentation/devicetree/bindings/gpu/adreno.txt
+++ b/Documentation/devicetree/bindings/gpu/adreno.txt
@@ -72,6 +72,20 @@
This is used to override faulty hardware readings.
- qcom,strtstp-sleepwake: Boolean. Enables use of GPU SLUMBER instead of SLEEP for power savings
+The following properties are optional as collecting data via coresight might
+not be supported for every chipset. The documentation for coresight
+properties can be found in:
+Documentation/devicetree/bindings/coresight/coresight.txt
+
+- coresight-id Unique integer identifier for the bus.
+- coresight-name Unique descriptive name of the bus.
+- coresight-nr-inports Number of input ports on the bus.
+- coresight-outports List of output port numbers on the bus.
+- coresight-child-list List of phandles pointing to the children of this
+ component.
+- coresight-child-ports List of input port numbers of the children.
+
+
Example of A330 GPU in MSM8974:
/ {
diff --git a/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt b/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
index 706ffe6..c7c6415 100644
--- a/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
+++ b/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
@@ -13,6 +13,7 @@
- qcom,iommu-pmu-event-classes: List of event classes supported.
- qcom,needs-alt-core-clk : boolean to enable the secondary core clock for
access to the IOMMU configuration registers
+- Bus scaling properties: See msm_bus.txt
- List of sub nodes, one for each of the translation context banks supported.
Required properties for each sub-node:
diff --git a/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt b/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
index 56f4767..ed45979 100644
--- a/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
+++ b/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
@@ -21,6 +21,7 @@
- qcom,iommu-pmu-ngroups: Number of Performance Monitor Unit (PMU) groups.
- qcom,iommu-pmu-ncounters: Number of PMU counters per group.
- qcom,iommu-pmu-event-classes: List of event classes supported.
+- Bus scaling properties: See msm_bus.txt
- List of sub nodes, one for each of the translation context banks supported.
Each sub node has the following required properties:
diff --git a/Documentation/devicetree/bindings/media/video/msm-cci.txt b/Documentation/devicetree/bindings/media/video/msm-cci.txt
index 7616505..1836867 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cci.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cci.txt
@@ -51,6 +51,9 @@
- qcom,sensor-name : should contain unique sensor name to differentiate from
other sensor
- "s5k3l1yx"
+- qcom,vdd-cx-supply : should contain regulator from which cx voltage is
+ supplied
+- qcom,vdd-cx-name : should contain names of cx regulator
- cam_vdig-supply : should contain regulator from which digital voltage is
supplied
- cam_vana-supply : should contain regulator from which analog voltage is
@@ -191,6 +194,8 @@
qcom,led-flash-src = <&led_flash0>;
qcom,mount-angle = <90>;
qcom,sensor-name = "s5k3l1yx";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
diff --git a/Documentation/devicetree/bindings/regulator/gdsc-regulator.txt b/Documentation/devicetree/bindings/regulator/gdsc-regulator.txt
index f2cfe34..daa68b3 100644
--- a/Documentation/devicetree/bindings/regulator/gdsc-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/gdsc-regulator.txt
@@ -15,6 +15,8 @@
- qcom,retain-mems: Presence denotes a hardware requirement to leave the
forced memory retention signals in the core's clock
branch control register asserted.
+ - qcom,retain-logic: Presence denotes a requirement to leave power to the
+ core's logic enabled.
Example:
gdsc_oxili_gx: qcom,gdsc@fd8c4024 {
diff --git a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
index 8ce31d9..b0d6b4d 100644
--- a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
@@ -40,6 +40,8 @@
DATA GPIO PAD.
- qcom,phy-sof-workaround : If present then HSIC PHY has h/w BUGs related to
SOFs. Software workarounds are required for the same.
+- hsic,consider-ipa-handshake: If present then hsic low power mode is
+ depend on suitable handshake with the IPA peer.
- Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for
below optional properties:
@@ -71,6 +73,7 @@
hsic,ignore-cal-pad-config;
hsic,strobe-pad-offset = <0x2050>;
hsic,data-pad-offset = <0x2054>;
+ hsic,consider-ipa-handshake;
qcom,msm-bus,name = "hsic";
qcom,msm-bus,num-cases = <2>;
diff --git a/arch/arm/boot/dts/apq8074-v1.dtsi b/arch/arm/boot/dts/apq8074-v1.dtsi
new file mode 100644
index 0000000..c4e7b7c
--- /dev/null
+++ b/arch/arm/boot/dts/apq8074-v1.dtsi
@@ -0,0 +1,48 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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.
+ */
+
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm8974.dtsi file.
+ */
+
+/include/ "msm8974-v1.dtsi"
+
+&soc {
+ qcom,qseecom@a700000 {
+ compatible = "qcom,qseecom";
+ reg = <0x0a700000 0x500000>;
+ reg-names = "secapp-region";
+ qcom,disk-encrypt-pipe-pair = <2>;
+ qcom,hlos-ce-hw-instance = <1>;
+ qcom,qsee-ce-hw-instance = <0>;
+ qcom,msm-bus,name = "qseecom-noc";
+ qcom,msm-bus,num-cases = <4>;
+ qcom,msm-bus,active-only = <0>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <55 512 0 0>,
+ <55 512 3936000 393600>,
+ <55 512 3936000 393600>,
+ <55 512 3936000 393600>;
+ };
+};
+
+&memory_hole {
+ qcom,memblock-remove = <0x0a700000 0x5800000>; /* Address and size of the hole */
+};
+
+&qseecom {
+ status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/apq8084-smp2p.dtsi b/arch/arm/boot/dts/apq8084-smp2p.dtsi
new file mode 100644
index 0000000..b1d21ff
--- /dev/null
+++ b/arch/arm/boot/dts/apq8084-smp2p.dtsi
@@ -0,0 +1,82 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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,smp2p-adsp {
+ compatible = "qcom,smp2p";
+ reg = <0xf9011008 0x4>;
+ qcom,remote-pid = <2>;
+ qcom,irq-bitmask = <0x400>;
+ interrupts = <0 158 1>;
+ };
+
+ smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <7>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_7_in {
+ compatible = "qcom,smp2pgpio_test_smp2p_7_in";
+ gpios = <&smp2pgpio_smp2p_7_in 0 0>;
+ };
+
+ smp2pgpio_smp2p_7_out: qcom,smp2pgpio-smp2p-7-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <7>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_7_out {
+ compatible = "qcom,smp2pgpio_test_smp2p_7_out";
+ gpios = <&smp2pgpio_smp2p_7_out 0 0>;
+ };
+
+ smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <2>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_2_in {
+ compatible = "qcom,smp2pgpio_test_smp2p_2_in";
+ gpios = <&smp2pgpio_smp2p_2_in 0 0>;
+ };
+
+ smp2pgpio_smp2p_2_out: qcom,smp2pgpio-smp2p-2-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_2_out {
+ compatible = "qcom,smp2pgpio_test_smp2p_2_out";
+ gpios = <&smp2pgpio_smp2p_2_out 0 0>;
+ };
+};
diff --git a/arch/arm/boot/dts/apq8084.dtsi b/arch/arm/boot/dts/apq8084.dtsi
index 7a1bbef..c74e59d 100644
--- a/arch/arm/boot/dts/apq8084.dtsi
+++ b/arch/arm/boot/dts/apq8084.dtsi
@@ -20,6 +20,7 @@
};
/include/ "apq8084-ion.dtsi"
+/include/ "apq8084-smp2p.dtsi"
&soc {
#address-cells = <1>;
@@ -201,6 +202,51 @@
};
};
+
+ memory_hole: qcom,msm-mem-hole {
+ compatible = "qcom,msm-mem-hole";
+ qcom,memblock-remove = <0x0dc00000 0x2000000>; /* Address and Size of Hole */
+ };
+
+ qcom,ipc-spinlock@fd484000 {
+ compatible = "qcom,ipc-spinlock-sfpb";
+ reg = <0xfd484000 0x400>;
+ qcom,num-locks = <8>;
+ };
+
+ qcom,smem@fa00000 {
+ compatible = "qcom,smem";
+ reg = <0xfa00000 0x200000>,
+ <0xf9011000 0x1000>,
+ <0xfc428000 0x4000>;
+ reg-names = "smem", "irq-reg-base", "aux-mem1";
+
+ qcom,smd-adsp {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <1>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x100>;
+ qcom,pil-string = "adsp";
+ interrupts = <0 156 1>;
+ };
+
+ qcom,smsm-adsp {
+ compatible = "qcom,smsm";
+ qcom,smsm-edge = <1>;
+ qcom,smsm-irq-offset = <0x8>;
+ qcom,smsm-irq-bitmask = <0x200>;
+ interrupts = <0 157 1>;
+ };
+
+ qcom,smd-rpm {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <15>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x1>;
+ interrupts = <0 168 1>;
+ qcom,irq-no-suspend;
+ };
+ };
};
/include/ "msm-pma8084.dtsi"
diff --git a/arch/arm/boot/dts/msm-gdsc.dtsi b/arch/arm/boot/dts/msm-gdsc.dtsi
index d4c5061..78234e8 100644
--- a/arch/arm/boot/dts/msm-gdsc.dtsi
+++ b/arch/arm/boot/dts/msm-gdsc.dtsi
@@ -11,8 +11,6 @@
* GNU General Public License for more details.
*/
-/include/ "skeleton.dtsi"
-
&soc {
gdsc_venus: qcom,gdsc@fd8c1024 {
compatible = "qcom,gdsc";
diff --git a/arch/arm/boot/dts/msm-iommu-v0.dtsi b/arch/arm/boot/dts/msm-iommu-v0.dtsi
index 35829a7..65075e5 100644
--- a/arch/arm/boot/dts/msm-iommu-v0.dtsi
+++ b/arch/arm/boot/dts/msm-iommu-v0.dtsi
@@ -27,6 +27,13 @@
0x10
0x12
0x80>;
+ qcom,msm-bus,name = "lpass_ebi";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <11 512 0 0>,
+ <11 512 0 1000>;
status = "disabled";
lpass_q6_fw: qcom,iommu-ctx@fd000000 {
@@ -78,6 +85,14 @@
0x10
0x12
0x80>;
+ qcom,msm-bus,name = "copss_ebi";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <88 512 0 0>,
+ <88 512 0 1000>;
+
status = "disabled";
qcom,iommu-ctx@fd010000 {
@@ -161,6 +176,13 @@
0x10
0x12
0x80>;
+ qcom,msm-bus,name = "mdpe_ebi";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <92 512 0 0>,
+ <92 512 0 1000>;
status = "disabled";
qcom,iommu-ctx@fd860000 {
@@ -196,6 +218,13 @@
0x10
0x12
0x80>;
+ qcom,msm-bus,name = "mdps_ebi";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <22 512 0 0>,
+ <22 512 0 1000>;
status = "disabled";
qcom,iommu-ctx@fd870000 {
@@ -232,6 +261,13 @@
0x10
0x12
0x80>;
+ qcom,msm-bus,name = "gfx_ebi";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <26 512 0 0>,
+ <26 512 0 1000>;
status = "disabled";
qcom,iommu-ctx@fd880000 {
@@ -277,6 +313,13 @@
0x10
0x12
0x80>;
+ qcom,msm-bus,name = "vfe_ebi";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <29 512 0 0>,
+ <29 512 0 1000>;
status = "disabled";
qcom,iommu-ctx@fd890000 {
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 9d77312..17cda51 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -869,6 +869,7 @@
qcom,limit-temp = <60>;
qcom,temp-hysteresis = <10>;
qcom,freq-step = <2>;
+ qcom,freq-control-mask = <0xf>;
};
spi_0: spi@f9923000 { /* BLSP1 QUP1 */
diff --git a/arch/arm/boot/dts/msm8610-bus.dtsi b/arch/arm/boot/dts/msm8610-bus.dtsi
index 2e7ba25..7ed914e 100644
--- a/arch/arm/boot/dts/msm8610-bus.dtsi
+++ b/arch/arm/boot/dts/msm8610-bus.dtsi
@@ -29,11 +29,13 @@
qcom,masterp = <2>;
qcom,tier = <2>;
qcom,hw-sel = "NoC";
- qcom,perm-mode = "Bypass";
- qcom,mode = "Bypass";
+ qcom,perm-mode = "Fixed";
+ qcom,mode = "Fixed";
qcom,qport = <0>;
qcom,ws = <10000>;
qcom,mas-hw-id = <8>;
+ qcom,prio1 = <2>;
+ qcom,prio0 = <2>;
};
mas-vfe {
@@ -47,6 +49,8 @@
qcom,ws = <10000>;
qcom,qport = <2>;
qcom,mas-hw-id = <11>;
+ qcom,prio1 = <2>;
+ qcom,prio0 = <2>;
};
mas-mdpe {
@@ -55,11 +59,13 @@
qcom,masterp = <4>;
qcom,tier = <2>;
qcom,hw-sel = "NoC";
- qcom,perm-mode = "Bypass";
- qcom,mode = "Bypass";
+ qcom,perm-mode = "Fixed";
+ qcom,mode = "Fixed";
qcom,ws = <10000>;
qcom,qport = <7>;
qcom,mas-hw-id = <11>;
+ qcom,prio1 = <2>;
+ qcom,prio0 = <2>;
};
fab-bimc {
@@ -67,7 +73,7 @@
label = "fab-bimc";
qcom,gateway;
qcom,slavep = <16>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <16>;
};
@@ -77,7 +83,7 @@
label = "slv-camera-cfg";
qcom,slavep = <0>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <3>;
};
@@ -87,7 +93,7 @@
label = "slv-display-cfg";
qcom,slavep = <1>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <4>;
};
@@ -97,7 +103,7 @@
label = "slv-cpr-cfg";
qcom,slavep = <3>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <6>;
};
@@ -107,7 +113,7 @@
label = "slv-cpr-xpu-cfg";
qcom,slavep = <4>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <7>;
};
@@ -117,7 +123,7 @@
label = "slv-misc-cfg";
qcom,slavep = <6>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <8>;
};
@@ -127,7 +133,7 @@
label = "slv-misc-xpu-cfg";
qcom,slavep = <7>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <9>;
};
@@ -137,7 +143,7 @@
label = "slv-gfx3d-cfg";
qcom,slavep = <9>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <11>;
};
@@ -147,7 +153,7 @@
label = "slv-mmss-clk-cfg";
qcom,slavep = <11>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <12>;
};
@@ -157,7 +163,7 @@
label = "slv-mmss-clk-xpu-cfg";
qcom,slavep = <12>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <13>;
};
@@ -167,7 +173,7 @@
label = "slv-mnoc-mpu-cfg";
qcom,slavep = <13>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <14>;
};
@@ -177,7 +183,7 @@
label = "slv-onoc-mpu-cfg";
qcom,slavep = <14>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <15>;
};
@@ -187,7 +193,7 @@
label = "slv-service-mnoc";
qcom,slavep = <18>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <17>;
};
@@ -197,7 +203,7 @@
label = "slv-dsi-cfg";
qcom,slavep = <19>;
qcom,tier = <2>;
- qcom,buswidth = <16>;
+ qcom,buswidth = <8>;
qcom,hw-sel = "NoC";
qcom,slv-hw-id = <19>;
};
@@ -272,8 +278,8 @@
qcom,mas-hw-id = <29>;
qcom,slv-hw-id = <28>;
qcom,mode = "Fixed";
- qcom,prio-rd = <2>;
- qcom,prio-wr = <2>;
+ qcom,prio0 = <2>;
+ qcom,prio1 = <2>;
};
fab-ovnoc {
@@ -291,6 +297,9 @@
qcom,masterp = <5>;
qcom,tier = <2>;
qcom,mas-hw-id = <23>;
+ qcom,hw-sel = "NoC";
+ qcom,prio0 = <1>;
+ qcom,prio1 = <1>;
};
mas-mss {
@@ -899,6 +908,7 @@
qcom,mas-hw-id = <0>;
qcom,prio-rd = <1>;
qcom,prio-wr = <1>;
+ qcom,prio-lvl = <1>;
};
mas-mss-proc {
@@ -943,8 +953,8 @@
qcom,qport = <4>;
qcom,mas-hw-id = <25>;
qcom,mode = "Fixed";
- qcom,prio-rd = <1>;
- qcom,prio-wr = <1>;
+ qcom,prio0 = <1>;
+ qcom,prio1 = <1>;
};
mas-gfx3d {
@@ -952,13 +962,11 @@
label = "mas-gfx3d";
qcom,masterp = <5>;
qcom,tier = <2>;
- qcom,hw-sel = "NoC";
- qcom,perm-mode = "Bypass";
- qcom,mode = "Bypass";
+ qcom,hw-sel = "BIMC";
+ qcom,perm-mode = "Fixed";
+ qcom,mode = "Fixed";
qcom,ws = <10000>;
qcom,qport = <5>;
- qcom,prio-rd = <1>;
- qcom,prio-wr = <1>;
qcom,mas-hw-id = <6>;
};
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 9dbd71d..ca3e7ca 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -736,6 +736,7 @@
qcom,limit-temp = <60>;
qcom,temp-hysteresis = <10>;
qcom,freq-step = <2>;
+ qcom,freq-control-mask = <0xf>;
};
qcom,ipc-spinlock@fd484000 {
@@ -812,6 +813,43 @@
compatible = "qcom,tz-log";
reg = <0x0fe805720 0x1000>;
};
+
+ qcom,qcrypto@fd404000 {
+ compatible = "qcom,qcrypto";
+ reg = <0xfd400000 0x20000>,
+ <0xfd404000 0x8000>;
+ reg-names = "crypto-base","crypto-bam-base";
+ interrupts = <0 207 0>;
+ qcom,bam-pipe-pair = <2>;
+ qcom,ce-hw-instance = <1>;
+ qcom,ce-hw-shared;
+ qcom,msm-bus,name = "qcrypto-noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only = <0>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <55 512 0 0>,
+ <55 512 393600 3936000>;
+ };
+
+ qcom,qcedev@fd400000 {
+ compatible = "qcom,qcedev";
+ reg = <0xfd400000 0x20000>,
+ <0xfd404000 0x8000>;
+ reg-names = "crypto-base","crypto-bam-base";
+ interrupts = <0 207 0>;
+ qcom,bam-pipe-pair = <1>;
+ qcom,ce-hw-instance = <1>;
+ qcom,ce-hw-shared;
+ qcom,msm-bus,name = "qcedev-noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only = <0>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <55 512 0 0>,
+ <55 512 393600 3936000>;
+ };
+
};
&gdsc_vfe {
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi
index efd9c32..4a9820d 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi
@@ -36,6 +36,8 @@
qcom,actuator-src = <&actuator0>;
qcom,mount-angle = <90>;
qcom,sensor-name = "s5k3l1yx";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
@@ -77,6 +79,8 @@
qcom,mount-angle = <90>;
qcom,sensor-name = "imx135";
qcom,actuator-src = <&actuator1>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
@@ -118,6 +122,8 @@
qcom,csid-sd-index = <2>;
qcom,mount-angle = <90>;
qcom,sensor-name = "ov2720";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
@@ -153,6 +159,8 @@
qcom,csid-sd-index = <0>;
qcom,mount-angle = <0>;
qcom,sensor-name = "mt9m114";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
index 9cbd45c..f61b83a 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
@@ -37,6 +37,8 @@
qcom,led-flash-src = <&led_flash0>;
qcom,mount-angle = <270>;
qcom,sensor-name = "s5k3l1yx";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
@@ -78,6 +80,8 @@
qcom,mount-angle = <270>;
qcom,sensor-name = "imx135";
qcom,actuator-src = <&actuator1>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
@@ -119,6 +123,8 @@
qcom,csid-sd-index = <2>;
qcom,mount-angle = <90>;
qcom,sensor-name = "ov2720";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
@@ -154,6 +160,8 @@
qcom,csid-sd-index = <0>;
qcom,mount-angle = <0>;
qcom,sensor-name = "mt9m114";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
index e9d3d75..e0b572e 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
@@ -36,6 +36,8 @@
qcom,csid-sd-index = <0>;
qcom,mount-angle = <0>;
qcom,sensor-name = "s5k3l1yx";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs2>;
@@ -73,6 +75,8 @@
qcom,csid-sd-index = <0>;
qcom,mount-angle = <0>;
qcom,sensor-name = "imx135";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
qcom,actuator-src = <&actuator1>;
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
@@ -115,6 +119,8 @@
qcom,csid-sd-index = <0>;
qcom,mount-angle = <180>;
qcom,sensor-name = "ov2720";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs2>;
@@ -149,6 +155,8 @@
qcom,csiphy-sd-index = <1>;
qcom,csid-sd-index = <0>;
qcom,mount-angle = <0>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
qcom,sensor-name = "mt9m114";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
index 68af4a6..6ad6213 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
@@ -37,6 +37,8 @@
qcom,led-flash-src = <&led_flash0>;
qcom,mount-angle = <90>;
qcom,sensor-name = "s5k3l1yx";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
@@ -77,6 +79,8 @@
qcom,csid-sd-index = <0>;
qcom,mount-angle = <90>;
qcom,sensor-name = "imx135";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
qcom,actuator-src = <&actuator1>;
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
@@ -120,6 +124,8 @@
qcom,csid-sd-index = <2>;
qcom,mount-angle = <90>;
qcom,sensor-name = "ov2720";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
@@ -155,6 +161,8 @@
qcom,csid-sd-index = <0>;
qcom,mount-angle = <0>;
qcom,sensor-name = "mt9m114";
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
cam_vio-supply = <&pm8941_lvs3>;
diff --git a/arch/arm/boot/dts/msm8974-gpu.dtsi b/arch/arm/boot/dts/msm8974-gpu.dtsi
index 669097e..5172a5a 100644
--- a/arch/arm/boot/dts/msm8974-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpu.dtsi
@@ -51,6 +51,14 @@
/* IOMMU Data */
iommu = <&kgsl_iommu>;
+ /* Trace bus */
+ coresight-id = <67>;
+ coresight-name = "coresight-gfx";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_mmss>;
+ coresight-child-ports = <7>;
+
qcom,gpu-pwrlevels {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/msm8974-ion.dtsi b/arch/arm/boot/dts/msm8974-ion.dtsi
index ee8152d..63f6d59 100644
--- a/arch/arm/boot/dts/msm8974-ion.dtsi
+++ b/arch/arm/boot/dts/msm8974-ion.dtsi
@@ -53,7 +53,7 @@
reg = <28>;
qcom,heap-align = <0x1000>;
qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
- qcom,memory-reservation-size = <0x314000>;
+ qcom,memory-reservation-size = <0x614000>;
};
};
};
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index 04f2eb6..c2dae28 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -727,8 +727,10 @@
&slim_msm {
taiko_codec {
+ qcom,cdc-micbias1-ext-cap;
qcom,cdc-micbias2-ext-cap;
qcom,cdc-micbias3-ext-cap;
+ qcom,cdc-micbias4-ext-cap;
/*
* Liquid has external spkrdrv supply. Give a dummy supply to
diff --git a/arch/arm/boot/dts/msm8974-v2-pm.dtsi b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
index 29dce2a..d3a0bc8 100644
--- a/arch/arm/boot/dts/msm8974-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
@@ -190,9 +190,9 @@
qcom,irqs-detectable;
qcom,gpio-detectable;
qcom,latency-us = <1>;
- qcom,ss-power = <784>;
- qcom,energy-overhead = <190000>;
- qcom,time-overhead = <100>;
+ qcom,ss-power = <715>;
+ qcom,energy-overhead = <17700>;
+ qcom,time-overhead = <2>;
};
qcom,lpm-level@1 {
@@ -206,10 +206,10 @@
qcom,vdd-dig-lower-bound = <4>; /* NORMAL */
qcom,irqs-detectable;
qcom,gpio-detectable;
- qcom,latency-us = <75>;
- qcom,ss-power = <735>;
- qcom,energy-overhead = <77341>;
- qcom,time-overhead = <105>;
+ qcom,latency-us = <35>;
+ qcom,ss-power = <542>;
+ qcom,energy-overhead = <34920>;
+ qcom,time-overhead = <40>;
};
@@ -224,10 +224,10 @@
qcom,vdd-dig-lower-bound = <4>; /* NORMAL */
qcom,irqs-detectable;
qcom,gpio-detectable;
- qcom,latency-us = <95>;
- qcom,ss-power = <725>;
- qcom,energy-overhead = <99500>;
- qcom,time-overhead = <130>;
+ qcom,latency-us = <300>;
+ qcom,ss-power = <476>;
+ qcom,energy-overhead = <225300>;
+ qcom,time-overhead = <350>;
};
qcom,lpm-level@3 {
@@ -241,10 +241,10 @@
qcom,vdd-dig-lower-bound = <4>; /* NORMAL */
qcom,irqs-detectable;
qcom,gpio-detectable;
- qcom,latency-us = <2000>;
- qcom,ss-power = <138>;
- qcom,energy-overhead = <1208400>;
- qcom,time-overhead = <3200>;
+ qcom,latency-us = <2817>;
+ qcom,ss-power = <163>;
+ qcom,energy-overhead = <1577736>;
+ qcom,time-overhead = <5067>;
};
qcom,lpm-level@4 {
@@ -258,44 +258,29 @@
qcom,vdd-dig-lower-bound = <3>; /* SVS SOC */
qcom,irqs-detectable;
qcom,gpio-detectable;
- qcom,latency-us = <3000>;
- qcom,ss-power = <110>;
- qcom,energy-overhead = <1250300>;
- qcom,time-overhead = <3500>;
+ qcom,latency-us = <3922>;
+ qcom,ss-power = <83>;
+ qcom,energy-overhead = <2274420>;
+ qcom,time-overhead = <6605>;
};
qcom,lpm-level@5 {
reg = <0x5>;
qcom,mode = "pc";
qcom,xo = "xo_off";
- qcom,l2 = "l2_cache_gdhs";
- qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
- qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
- qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
- qcom,vdd-dig-lower-bound = <4>; /* NORMAL */
- qcom,latency-us = <3000>;
- qcom,ss-power = <68>;
- qcom,energy-overhead = <1350200>;
- qcom,time-overhead = <4000>;
- };
-
- qcom,lpm-level@6 {
- reg = <0x6>;
- qcom,mode = "pc";
- qcom,xo = "xo_off";
qcom,l2 = "l2_cache_pc";
qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
qcom,vdd-dig-lower-bound = <4>; /* NORMAL */
- qcom,latency-us = <10300>;
- qcom,ss-power = <63>;
- qcom,energy-overhead = <2128000>;
- qcom,time-overhead = <18200>;
+ qcom,latency-us = <4922>;
+ qcom,ss-power = <68>;
+ qcom,energy-overhead = <2568180>;
+ qcom,time-overhead = <8812>;
};
- qcom,lpm-level@7 {
- reg = <0x7>;
+ qcom,lpm-level@6 {
+ reg = <0x6>;
qcom,mode= "pc";
qcom,xo = "xo_off";
qcom,l2 = "l2_cache_pc";
@@ -303,14 +288,14 @@
qcom,vdd-mem-lower-bound = <950000>; /* SVS SOC */
qcom,vdd-dig-upper-bound = <4>; /* NORMAL */
qcom,vdd-dig-lower-bound = <3>; /* SVS SOC */
- qcom,latency-us = <18000>;
- qcom,ss-power = <10>;
- qcom,energy-overhead = <3202600>;
- qcom,time-overhead = <27000>;
+ qcom,latency-us = <5890>;
+ qcom,ss-power = <60>;
+ qcom,energy-overhead = <2675900>;
+ qcom,time-overhead = <10140>;
};
- qcom,lpm-level@8 {
- reg = <0x8>;
+ qcom,lpm-level@7 {
+ reg = <0x7>;
qcom,mode= "pc";
qcom,xo = "xo_off";
qcom,l2 = "l2_cache_pc";
@@ -318,10 +303,10 @@
qcom,vdd-mem-lower-bound = <675000>; /* RETENTION */
qcom,vdd-dig-upper-bound = <3>; /* SVS SOC */
qcom,vdd-dig-lower-bound = <1>; /* RETENTION */
- qcom,latency-us = <20000>;
- qcom,ss-power = <2>;
- qcom,energy-overhead = <4252000>;
- qcom,time-overhead = <32000>;
+ qcom,latency-us = <8500>;
+ qcom,ss-power = <18>;
+ qcom,energy-overhead = <3286600>;
+ qcom,time-overhead = <15760>;
};
};
@@ -428,6 +413,17 @@
qcom,pc-mode = "tz_l2_int";
qcom,use-sync-timer;
+ qcom,pm-snoc-client {
+ compatible = "qcom,pm-snoc-client";
+ qcom,msm-bus,name = "ocimem_snoc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,vectors-KBps =
+ <54 585 0 0>,
+ <54 585 0 800000>;
+ };
+
qcom,cpu-sleep-status@f9088008{
compatible = "qcom,cpu-sleep-status";
reg = <0xf9088008 0x100>;
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index a4a3efe..e2dd3fd 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1419,6 +1419,7 @@
qcom,limit-temp = <60>;
qcom,temp-hysteresis = <10>;
qcom,freq-step = <2>;
+ qcom,freq-control-mask = <0xf>;
qcom,core-limit-temp = <80>;
qcom,core-temp-hysteresis = <10>;
qcom,core-control-mask = <0xe>;
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 6e258b5..ca09370 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -190,6 +190,7 @@
<85 512 40000 640000>;
qcom,pool-64-bit-align;
qcom,enable-hbm;
+ hsic,consider-ipa-handshake;
};
qcom,usbbam@f9a44000 {
diff --git a/arch/arm/boot/dts/msmsamarium-ion.dtsi b/arch/arm/boot/dts/msmsamarium-ion.dtsi
new file mode 100644
index 0000000..ea954b8
--- /dev/null
+++ b/arch/arm/boot/dts/msmsamarium-ion.dtsi
@@ -0,0 +1,31 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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,ion {
+ compatible = "qcom,msm-ion";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,ion-heap@30 { /* SYSTEM HEAP */
+ reg = <30>;
+ };
+
+ qcom,ion-heap@21 { /* SYSTEM CONTIG HEAP */
+ reg = <21>;
+ };
+
+ qcom,ion-heap@25 { /* IOMMU HEAP */
+ reg = <25>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/msmsamarium-sim.dts b/arch/arm/boot/dts/msmsamarium-sim.dts
new file mode 100644
index 0000000..2774f7f
--- /dev/null
+++ b/arch/arm/boot/dts/msmsamarium-sim.dts
@@ -0,0 +1,25 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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/ "msmsamarium.dtsi"
+
+/ {
+ model = "Qualcomm MSM SAMARIUM SIM";
+ compatible = "qcom,msmsamarium-sim", "qcom,msmsamarium", "qcom,sim";
+ qcom,msm-id = <195 0 0>;
+};
+
+&uartblsp0dm2{
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/msmsamarium.dtsi b/arch/arm/boot/dts/msmsamarium.dtsi
new file mode 100644
index 0000000..9d9ff87
--- /dev/null
+++ b/arch/arm/boot/dts/msmsamarium.dtsi
@@ -0,0 +1,66 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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/ "skeleton.dtsi"
+
+/ {
+ model = "Qualcomm MSM SAMARIUM";
+ compatible = "qcom,msmsamarium";
+ interrupt-parent = <&intc>;
+ soc: soc { };
+};
+
+/include/ "msmsamarium-ion.dtsi"
+
+&soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ intc: interrupt-controller@f9000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xf9000000 0x1000>,
+ <0xf9002000 0x1000>;
+ };
+
+ msmgpio: gpio@fd510000 {
+ compatible = "qcom,msm-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0xfd510000 0x4000>;
+ ngpio = <145>;
+ interrupts = <0 208 0>;
+ qcom,direct-connect-irqs = <8>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 2 0 1 3 0>;
+ clock-frequency = <19200000>;
+ };
+
+ uartblsp0dm2: serial@f991f000 {
+ compatible = "qcom,msm-lsuart-v14";
+ reg = <0xf991f000 0x1000>;
+ interrupts = <0 109 0>;
+ status = "disabled";
+ };
+
+ qcom,msm-imem@fe805000 {
+ compatible = "qcom,msm-imem";
+ reg = <0xfe805000 0x1000>; /* Address and size of IMEM */
+ };
+};
diff --git a/arch/arm/configs/apq8084_defconfig b/arch/arm/configs/apq8084_defconfig
index a1fa53c..c0084bf 100644
--- a/arch/arm/configs/apq8084_defconfig
+++ b/arch/arm/configs/apq8084_defconfig
@@ -43,6 +43,8 @@
# CONFIG_MSM_PROC_COMM is not set
CONFIG_MSM_SMD=y
CONFIG_MSM_SMD_PKG4=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
CONFIG_MSM_IPC_LOGGING=y
CONFIG_MSM_IPC_ROUTER=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
index 07a15d9..7bf54ce 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -291,6 +291,10 @@
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_MSM8226=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index b385669..d6a1d6b 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -217,6 +217,8 @@
CONFIG_INPUT_EVBUG=m
CONFIG_KEYBOARD_GPIO=y
CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_GEN_VKEYS=y
CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
@@ -295,6 +297,10 @@
CONFIG_SND_SOC=y
CONFIG_SND_SOC_MSM8226=y
CONFIG_SND_SOC_MSM8X10=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
@@ -359,4 +365,4 @@
# CONFIG_CRYPTO_HW is not set
CONFIG_CRC_CCITT=y
CONFIG_QPNP_VIBRATOR=y
-CONFIG_QSEECOM=y
\ No newline at end of file
+CONFIG_QSEECOM=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index 5e38ef1..0325613 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -216,6 +216,7 @@
CONFIG_KEYBOARD_GPIO=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_GEN_VKEYS=y
CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
@@ -293,6 +294,10 @@
CONFIG_SND_SOC=y
CONFIG_SND_SOC_MSM8226=y
CONFIG_SND_SOC_MSM8X10=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 8036a44..091cdd9 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -37,6 +37,7 @@
CONFIG_DEFAULT_ROW=y
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8974=y
+CONFIG_ARCH_MSMSAMARIUM=y
CONFIG_MSM_KRAIT_TBB_ABORT_HANDLER=y
# CONFIG_MSM_STACKED_MEMORY is not set
CONFIG_CPU_HAS_L2_PMU=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 2a1215d..ba246e5 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -108,12 +108,15 @@
CONFIG_NF_CT_NETLINK=y
CONFIG_NETFILTER_XT_MARK=y
CONFIG_NETFILTER_XT_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
CONFIG_NETFILTER_XT_MATCH_DSCP=y
CONFIG_NETFILTER_XT_MATCH_ESP=y
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
CONFIG_IP_SET=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index be0daf3..108a68f 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -304,6 +304,8 @@
select ARM_HAS_SG_CHAIN
select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
select ARCH_WANT_KMAP_ATOMIC_FLUSH
+ select MEMORY_HOLE_CARVEOUT
+ select DONT_MAP_HOLE_AFTER_MEMBANK0
config ARCH_MPQ8092
bool "MPQ8092"
@@ -509,6 +511,26 @@
select MSM_RPM_LOG
select MSM_RPM_STATS_LOG
select ARCH_WANT_KMAP_ATOMIC_FLUSH
+
+config ARCH_MSMSAMARIUM
+ bool "MSMSAMARIUM"
+ select ARCH_MSM_KRAITMP
+ select GPIO_MSM_V3
+ select ARM_GIC
+ select CPU_V7
+ select MSM_SCM
+ select MSM_GPIOMUX
+ select MULTI_IRQ_HANDLER
+ select MSM_SPM_V2
+ select MSM_L2_SPM
+ select MSM_NATIVE_RESTART
+ select MSM_RESTART_V2
+ select MSM_PM8X60 if PM
+ select MAY_HAVE_SPARSE_IRQ
+ select SPARSE_IRQ
+ select ARM_HAS_SG_CHAIN
+ select MSM_RUN_QUEUE_STATS
+ select ARCH_WANT_KMAP_ATOMIC_FLUSH
endmenu
choice
@@ -1111,6 +1133,7 @@
default "0x00000000" if ARCH_MPQ8092
default "0x00000000" if ARCH_MSM8226
default "0x00000000" if ARCH_MSM8610
+ default "0x00000000" if ARCH_MSMSAMARIUM
default "0x10000000" if ARCH_FSM9XXX
default "0x00000000" if ARCH_FSM9900
default "0x00200000" if ARCH_MSM9625
@@ -1284,6 +1307,14 @@
help
Say Y here if you want the debug print routines to direct
their output to the serial port on FSM9900 devices.
+
+ config DEBUG_MSMSAMARIUM_UART
+ bool "Kernel low-level debugging messages via MSM SAMARIUM UART"
+ depends on ARCH_MSMSAMARIUM
+ select MSM_HAS_DEBUG_UART_HS_V14
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the serial port on MSM SAMARIUM devices.
endchoice
choice
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index b8a2b2d..fa3344d 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -122,6 +122,7 @@
ifndef CONFIG_ARCH_APQ8084
ifndef CONFIG_ARCH_MSMKRYPTON
ifndef CONFIG_ARCH_FSM9900
+ifndef CONFIG_ARCH_MSMSAMARIUM
obj-y += nand_partitions.o
endif
endif
@@ -134,6 +135,7 @@
endif
endif
endif
+endif
obj-$(CONFIG_MSM_SDIO_TTY) += sdio_tty.o
obj-$(CONFIG_MSM_SMD_TTY) += smd_tty.o
obj-$(CONFIG_MSM_SMD_QMI) += smd_qmi.o
@@ -310,10 +312,12 @@
obj-$(CONFIG_ARCH_MSM8610) += gdsc.o
obj-$(CONFIG_ARCH_MSM8974) += krait-regulator.o
obj-$(CONFIG_ARCH_MSMKRYPTON) += board-krypton.o board-krypton-gpiomux.o
+obj-$(CONFIG_ARCH_MSMSAMARIUM) += board-samarium.o board-samarium-gpiomux.o
obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
obj-$(CONFIG_ARCH_MSM9625) += clock-local2.o clock-pll.o clock-9625.o clock-rpm.o clock-voter.o acpuclock-9625.o acpuclock-cortex.o
obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o acpuclock-8930ab.o
obj-$(CONFIG_ARCH_MPQ8092) += board-8092.o board-8092-gpiomux.o
+obj-$(CONFIG_ARCH_MPQ8092) += clock-8092.o
obj-$(CONFIG_ARCH_MSM8226) += board-8226.o board-8226-gpiomux.o
obj-$(CONFIG_ARCH_MSM8226) += clock-local2.o clock-pll.o clock-8226.o clock-rpm.o clock-voter.o clock-mdss-8226.o
obj-$(CONFIG_ARCH_MSM8226) += acpuclock-8226.o acpuclock-cortex.o
@@ -376,6 +380,7 @@
obj-$(CONFIG_ARCH_MSM8974) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MSM9625) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MSMKRYPTON) += gpiomux-v2.o gpiomux.o
+obj-$(CONFIG_ARCH_MSMSAMARIUM) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MPQ8092) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MSM8226) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MSM8610) += gpiomux-v2.o gpiomux.o
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index 07969e0..b40c70a 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -105,3 +105,7 @@
zreladdr-$(CONFIG_ARCH_MSM8610) := 0x00008000
dtb-$(CONFIG_ARCH_MSM8610) += msm8610-rumi.dtb
dtb-$(CONFIG_ARCH_MSM8610) += msm8610-sim.dtb
+
+# MSMSAMARIUM
+ zreladdr-$(CONFIG_ARCH_MSMSAMARIUM) := 0x00008000
+ dtb-$(CONFIG_ARCH_MSMSAMARIUM) += msmsamarium-sim.dtb
diff --git a/arch/arm/mach-msm/board-8084.c b/arch/arm/mach-msm/board-8084.c
index 500c302..67c05ba 100644
--- a/arch/arm/mach-msm/board-8084.c
+++ b/arch/arm/mach-msm/board-8084.c
@@ -31,6 +31,7 @@
#include "clock.h"
#include "devices.h"
#include "platsmp.h"
+#include "modem_notifier.h"
static struct memtype_reserve apq8084_reserve_table[] __initdata = {
[MEMTYPE_SMI] = {
@@ -82,6 +83,7 @@
*/
void __init apq8084_add_drivers(void)
{
+ msm_init_modem_notifier_list();
msm_smd_init();
msm_clock_init(&msm8084_clock_init_data);
}
diff --git a/arch/arm/mach-msm/board-8092.c b/arch/arm/mach-msm/board-8092.c
index cd95bf3..ab5cc3a 100644
--- a/arch/arm/mach-msm/board-8092.c
+++ b/arch/arm/mach-msm/board-8092.c
@@ -35,21 +35,6 @@
#include "clock.h"
#include "platsmp.h"
-static struct clk_lookup msm_clocks_dummy[] = {
- CLK_DUMMY("core_clk", BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
- CLK_DUMMY("iface_clk", BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
- CLK_DUMMY("core_clk", SDC1_CLK, "msm_sdcc.1", OFF),
- CLK_DUMMY("iface_clk", SDC1_P_CLK, "msm_sdcc.1", OFF),
- CLK_DUMMY("core_clk", SDC2_CLK, "msm_sdcc.2", OFF),
- CLK_DUMMY("iface_clk", SDC2_P_CLK, "msm_sdcc.2", OFF),
-
-};
-
-struct clock_init_data mpq8092_clock_init_data __initdata = {
- .table = msm_clocks_dummy,
- .size = ARRAY_SIZE(msm_clocks_dummy),
-};
-
static struct memtype_reserve mpq8092_reserve_table[] __initdata = {
[MEMTYPE_SMI] = {
},
diff --git a/arch/arm/mach-msm/clock-8084.c b/arch/arm/mach-msm/clock-8084.c
index 424b694..b7f9fd7 100644
--- a/arch/arm/mach-msm/clock-8084.c
+++ b/arch/arm/mach-msm/clock-8084.c
@@ -325,7 +325,9 @@
CLK_DUMMY("", mmss_mmssnoc_ahb_clk.c, "", OFF),
CLK_DUMMY("", mmss_mmssnoc_axi_clk.c, "", OFF),
CLK_DUMMY("", mmss_s0_axi_clk.c, "", OFF),
- CLK_DUMMY("", ocmemcx_ocmemnoc_clk.c, "", OFF),
+ CLK_DUMMY("core_clk", ocmemgx_core_clk.c, "fdd00000.qcom,ocmem", OFF),
+ CLK_DUMMY("iface_clk", ocmemcx_ocmemnoc_clk.c,
+ "fdd00000.qcom,ocmem", OFF),
CLK_DUMMY("", oxili_ocmemgx_clk.c, "", OFF),
CLK_DUMMY("", oxili_gfx3d_clk.c, "", OFF),
CLK_DUMMY("", oxili_rbbmtimer_clk.c, "", OFF),
diff --git a/arch/arm/mach-msm/clock-8092.c b/arch/arm/mach-msm/clock-8092.c
new file mode 100644
index 0000000..a8520e6
--- /dev/null
+++ b/arch/arm/mach-msm/clock-8092.c
@@ -0,0 +1,323 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/rpm-regulator-smd.h>
+#include <mach/socinfo.h>
+#include <mach/rpm-smd.h>
+
+#include "clock-local2.h"
+#include "clock-pll.h"
+#include "clock-rpm.h"
+#include "clock-voter.h"
+#include "clock.h"
+
+/*
+ * Drivers need to fill in the clock names and device names for the clocks
+ * they need to control.
+ */
+static struct clk_lookup msm_clocks_8092[] = {
+ CLK_DUMMY("core_clk", BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
+ CLK_DUMMY("iface_clk", BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
+ CLK_DUMMY("core_clk", SDC1_CLK, "msm_sdcc.1", OFF),
+ CLK_DUMMY("iface_clk", SDC1_P_CLK, "msm_sdcc.1", OFF),
+ CLK_DUMMY("core_clk", SDC2_CLK, "msm_sdcc.2", OFF),
+ CLK_DUMMY("iface_clk", SDC2_P_CLK, "msm_sdcc.2", OFF),
+ CLK_DUMMY("", usb30_master_clk_src.c, "", OFF),
+ CLK_DUMMY("", tsif_ref_clk_src.c, "", OFF),
+ CLK_DUMMY("", ce1_clk_src.c, "", OFF),
+ CLK_DUMMY("", ce2_clk_src.c, "", OFF),
+ CLK_DUMMY("", ce3_clk_src.c, "", OFF),
+ CLK_DUMMY("", geni_ser_clk_src.c, "", OFF),
+ CLK_DUMMY("", gmac_125m_clk_src.c, "", OFF),
+ CLK_DUMMY("", gmac_core_clk_src.c, "", OFF),
+ CLK_DUMMY("", gmac_sys_25m_clk_src.c, "", OFF),
+ CLK_DUMMY("", gp1_clk_src.c, "", OFF),
+ CLK_DUMMY("", gp2_clk_src.c, "", OFF),
+ CLK_DUMMY("", gp3_clk_src.c, "", OFF),
+ CLK_DUMMY("", pcie_aux_clk_src.c, "", OFF),
+ CLK_DUMMY("", pcie_pipe_clk_src.c, "", OFF),
+ CLK_DUMMY("", pdm2_clk_src.c, "", OFF),
+ CLK_DUMMY("", pwm_clk_src.c, "", OFF),
+ CLK_DUMMY("", sata_asic0_clk_src.c, "", OFF),
+ CLK_DUMMY("", sata_pmalive_clk_src.c, "", OFF),
+ CLK_DUMMY("", sata_rx_clk_src.c, "", OFF),
+ CLK_DUMMY("", sata_rx_oob_clk_src.c, "", OFF),
+ CLK_DUMMY("", sdcc1_apps_clk_src.c, "", OFF),
+ CLK_DUMMY("", sdcc2_apps_clk_src.c, "", OFF),
+ CLK_DUMMY("", usb30_mock_utmi_clk_src.c, "", OFF),
+ CLK_DUMMY("", usb_hs_system_clk_src.c, "", OFF),
+ CLK_DUMMY("", usb_hs2_system_clk_src.c, "", OFF),
+ CLK_DUMMY("", usb_hsic_clk_src.c, "", OFF),
+ CLK_DUMMY("", usb_hsic_io_cal_clk_src.c, "", OFF),
+ CLK_DUMMY("", usb_hsic_system_clk_src.c, "", OFF),
+ CLK_DUMMY("", gcc_bam_dma_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_bcss_cfg_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_bimc_gfx_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_bimc_kpss_axi_mstr_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_bimc_sysnoc_axi_mstr_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup1_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup1_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup2_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup2_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup3_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup3_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup4_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup4_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup5_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup5_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup6_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_qup6_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_uart1_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_uart2_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_uart3_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_uart4_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_uart5_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp1_uart6_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup1_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup1_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup2_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup2_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup3_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup3_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup4_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup4_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup5_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup5_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup6_i2c_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_qup6_spi_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_uart1_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_uart2_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_uart3_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_uart4_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_uart5_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_blsp2_uart6_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_boot_rom_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_ce1_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_ce1_axi_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_ce1_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_ce2_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_ce2_axi_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_ce2_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_ce3_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_ce3_axi_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_ce3_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_xo_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_xo_div4_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_geni_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_geni_ser_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_gmac_125m_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_gmac_axi_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_gmac_cfg_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_gmac_core_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_gmac_rx_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_gmac_sys_25m_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_gmac_sys_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_gp1_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_gp2_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_gp3_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_klm_core_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_klm_s_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_lpass_q6_axi_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sys_noc_lpass_mport_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sys_noc_lpass_sway_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_mmss_a5ss_axi_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_mmss_bimc_gfx_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_pcie_axi_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_pcie_axi_mstr_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_pcie_cfg_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_pcie_pipe_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_pcie_sleep_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_pdm2_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_pdm_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_prng_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_pwm_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_pwm_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sata_asic0_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sata_axi_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sata_cfg_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sata_pmalive_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sata_rx_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sata_rx_oob_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sdcc1_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sdcc1_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sdcc2_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sdcc2_apps_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_spss_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_sys_noc_usb3_axi_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb2a_phy_sleep_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb2b_phy_sleep_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb2c_phy_sleep_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb30_master_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb30_mock_utmi_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb30_sleep_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb_hs_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb_hs_system_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb_hs2_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb_hs2_system_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb_hsic_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb_hsic_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb_hsic_io_cal_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_usb_hsic_system_clk.c, "", OFF),
+ /* MMSS Clock Dummy */
+ CLK_DUMMY("", axi_clk_src.c, "", OFF),
+ CLK_DUMMY("", mmpll0_pll_clk_src.c, "", OFF),
+ CLK_DUMMY("", mmpll1_pll_clk_src.c, "", OFF),
+ CLK_DUMMY("", mmpll2_pll_clk_src.c, "", OFF),
+ CLK_DUMMY("", mmpll3_pll_clk_src.c, "", OFF),
+ CLK_DUMMY("", mmpll6_pll_clk_src.c, "", OFF),
+ CLK_DUMMY("", vcodec0_clk_src.c, "", OFF),
+ CLK_DUMMY("", extpclk_clk_src.c, "", OFF),
+ CLK_DUMMY("", lvds_clk_src.c, "", OFF),
+ CLK_DUMMY("", mdp_clk_src.c, "", OFF),
+ CLK_DUMMY("", vbyone_clk_src.c, "", OFF),
+ CLK_DUMMY("", gfx3d_clk_src.c, "", OFF),
+ CLK_DUMMY("", vp_clk_src.c, "", OFF),
+ CLK_DUMMY("", jpeg2_clk_src.c, "", OFF),
+ CLK_DUMMY("", hdmi_clk_src.c, "", OFF),
+ CLK_DUMMY("", vbyone_symbol_clk_src.c, "", OFF),
+ CLK_DUMMY("", mmss_spdm_axi_div_clk.c, "", OFF),
+ CLK_DUMMY("", mmss_spdm_gfx3d_div_clk.c, "", OFF),
+ CLK_DUMMY("", mmss_spdm_jpeg2_div_clk.c, "", OFF),
+ CLK_DUMMY("", mmss_spdm_mdp_div_clk.c, "", OFF),
+ CLK_DUMMY("", mmss_spdm_vcodec0_div_clk.c, "", OFF),
+ CLK_DUMMY("", afe_pixel_clk_src.c, "", OFF),
+ CLK_DUMMY("", cfg_clk_src.c, "", OFF),
+ CLK_DUMMY("", hdmi_bus_clk_src.c, "", OFF),
+ CLK_DUMMY("", hdmi_rx_clk_src.c, "", OFF),
+ CLK_DUMMY("", md_clk_src.c, "", OFF),
+ CLK_DUMMY("", ttl_clk_src.c, "", OFF),
+ CLK_DUMMY("", vafe_ext_clk_src.c, "", OFF),
+ CLK_DUMMY("", vcap_vp_clk_src.c, "", OFF),
+ CLK_DUMMY("", gproc_clk_src.c, "", OFF),
+ CLK_DUMMY("", hdmc_frcf_clk_src.c, "", OFF),
+ CLK_DUMMY("", kproc_clk_src.c, "", OFF),
+ CLK_DUMMY("", maple_clk_src.c, "", OFF),
+ CLK_DUMMY("", preproc_clk_src.c, "", OFF),
+ CLK_DUMMY("", sdmc_frcs_clk_src.c, "", OFF),
+ CLK_DUMMY("", sdme_frcf_clk_src.c, "", OFF),
+ CLK_DUMMY("", sdme_vproc_clk_src.c, "", OFF),
+ CLK_DUMMY("", vdp_clk_src.c, "", OFF),
+ CLK_DUMMY("", vpu_bus_clk_src.c, "", OFF),
+ CLK_DUMMY("", vpu_frc_xin_clk_src.c, "", OFF),
+ CLK_DUMMY("", vpu_vdp_xin_clk_src.c, "", OFF),
+ CLK_DUMMY("", avsync_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", avsync_extpclk_clk.c, "", OFF),
+ CLK_DUMMY("", avsync_lvds_clk.c, "", OFF),
+ CLK_DUMMY("", avsync_vbyone_clk.c, "", OFF),
+ CLK_DUMMY("", avsync_vp_clk.c, "", OFF),
+ CLK_DUMMY("", camss_jpeg_jpeg2_clk.c, "", OFF),
+ CLK_DUMMY("", camss_jpeg_jpeg_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", camss_jpeg_jpeg_axi_clk.c, "", OFF),
+ CLK_DUMMY("", camss_micro_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", camss_top_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", mdss_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", mdss_axi_clk.c, "", OFF),
+ CLK_DUMMY("", mdss_extpclk_clk.c, "", OFF),
+ CLK_DUMMY("", mdss_hdmi_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", mdss_hdmi_clk.c, "", OFF),
+ CLK_DUMMY("", mdss_lvds_clk.c, "", OFF),
+ CLK_DUMMY("", mdss_mdp_clk.c, "", OFF),
+ CLK_DUMMY("", mdss_mdp_lut_clk.c, "", OFF),
+ CLK_DUMMY("", mdss_vbyone_clk.c, "", OFF),
+ CLK_DUMMY("", mdss_vbyone_symbol_clk.c, "", OFF),
+ CLK_DUMMY("", mmss_misc_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", mmss_mmssnoc_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", mmss_mmssnoc_axi_clk.c, "", OFF),
+ CLK_DUMMY("", mmss_s0_axi_clk.c, "", OFF),
+ CLK_DUMMY("", ocmemcx_ocmemnoc_clk.c, "", OFF),
+ CLK_DUMMY("", oxili_ocmemgx_clk.c, "", OFF),
+ CLK_DUMMY("", oxili_gfx3d_clk.c, "", OFF),
+ CLK_DUMMY("", oxilicx_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", bcss_mmss_ifdemod_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_afe_pixel_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_audio_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_axi_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_cfg_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_hdmi_bus_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_hdmi_rx_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_md_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_ttl_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_ttl_debug_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_vafe_ext_clk.c, "", OFF),
+ CLK_DUMMY("", vcap_vp_clk.c, "", OFF),
+ CLK_DUMMY("", venus0_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", venus0_axi_clk.c, "", OFF),
+ CLK_DUMMY("", venus0_core0_vcodec_clk.c, "", OFF),
+ CLK_DUMMY("", venus0_core1_vcodec_clk.c, "", OFF),
+ CLK_DUMMY("", venus0_ocmemnoc_clk.c, "", OFF),
+ CLK_DUMMY("", venus0_vcodec0_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_axi_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_bus_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_cxo_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_frc_xin_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_gproc_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_hdmc_frcf_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_kproc_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_maple_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_preproc_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_sdmc_frcs_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_sdme_frcf_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_sdme_frcs_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_sdme_vproc_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_sleep_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_vdp_clk.c, "", OFF),
+ CLK_DUMMY("", vpu_vdp_xin_clk.c, "", OFF),
+ /* BCSS broadcast */
+ CLK_DUMMY("", bcc_dem_core_b_clk_src.c, "", OFF),
+ CLK_DUMMY("", adc_01_clk_src.c, "", OFF),
+ CLK_DUMMY("", bcc_adc_0_in_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_dem_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_klm_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_lnb_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_tsc_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_tspp2_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_vbif_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_bcss_ahb_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_dem_atv_rxfe_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_dem_atv_rxfe_resamp_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_dem_core_clk_src.c, "", OFF),
+ CLK_DUMMY("", bcc_dem_core_div2_clk_src.c, "", OFF),
+ CLK_DUMMY("", bcc_dem_core_x2_b_clk_src.c, "", OFF),
+ CLK_DUMMY("", bcc_dem_core_x2_pre_cgf_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_tsc_ci_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_tsc_cicam_ts_clk_src.c, "", OFF),
+ CLK_DUMMY("", bcc_tsc_par_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_tsc_ser_clk_src.c, "", OFF),
+ CLK_DUMMY("", bcc_tspp2_clk_src.c, "", OFF),
+ CLK_DUMMY("", dig_dem_core_b_div2_clk.c, "", OFF),
+ CLK_DUMMY("", atv_x5_pre_cgc_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_albacore_cvbs_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_atv_x1_clk.c, "", OFF),
+ CLK_DUMMY("", nidaq_out_clk.c, "", OFF),
+ CLK_DUMMY("", gcc_bcss_axi_clk.c, "", OFF),
+ CLK_DUMMY("", bcc_lnb_core_clk.c, "", OFF),
+};
+
+struct clock_init_data mpq8092_clock_init_data __initdata = {
+ .table = msm_clocks_8092,
+ .size = ARRAY_SIZE(msm_clocks_8092),
+};
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index f3de05a..1f0d328 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -3271,7 +3271,8 @@
CLK_LOOKUP("byte_clk", mdss_byte0_clk.c, "fd922800.qcom,mdss_dsi"),
CLK_LOOKUP("core_clk", mdss_esc0_clk.c, "fd922800.qcom,mdss_dsi"),
CLK_LOOKUP("pixel_clk", mdss_pclk0_clk.c, "fd922800.qcom,mdss_dsi"),
- CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdss_dsi_clk_ctrl"),
+ CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd922800.qcom,mdss_dsi"),
+ CLK_LOOKUP("bus_clk", mdss_axi_clk.c, "fd922800.qcom,mdss_dsi"),
CLK_LOOKUP("core_clk", mdss_mdp_clk.c, "fd900000.qcom,mdss_mdp"),
CLK_LOOKUP("lut_clk", mdss_mdp_lut_clk.c, "fd900000.qcom,mdss_mdp"),
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index 340f1ef..1034516 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -509,7 +509,6 @@
static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc_clk.c, LONG_MAX);
static DEFINE_CLK_VOTER(pnoc_iommu_clk, &pnoc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(pnoc_qseecom_clk, &pnoc_clk.c, LONG_MAX);
static DEFINE_CLK_MEASURE(apc0_m_clk);
static DEFINE_CLK_MEASURE(apc1_m_clk);
@@ -1546,6 +1545,7 @@
F_END,
};
+static struct branch_clk mmss_mmssnoc_axi_clk;
static struct rcg_clk axi_clk_src = {
.cmd_rcgr_reg = AXI_CMD_RCGR,
.set_rate = set_rate_hid,
@@ -1557,6 +1557,7 @@
.ops = &clk_ops_rcg,
VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
CLK_INIT(axi_clk_src.c),
+ .depends = &mmss_mmssnoc_axi_clk.c
},
};
@@ -2320,7 +2321,6 @@
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
- .parent = &axi_clk_src.c,
.dbg_name = "mmss_mmssnoc_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(mmss_mmssnoc_axi_clk.c),
@@ -2336,7 +2336,6 @@
.dbg_name = "mmss_s0_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(mmss_s0_axi_clk.c),
- .depends = &mmss_mmssnoc_axi_clk.c,
},
};
@@ -2764,7 +2763,6 @@
CLK_LOOKUP("core_clk", gcc_blsp1_uart2_apps_clk.c, "f991e000.serial"),
CLK_LOOKUP("dfab_clk", pnoc_sps_clk.c, "msm_sps"),
- CLK_LOOKUP("bus_clk", pnoc_qseecom_clk.c, "qseecom"),
CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
CLK_LOOKUP("bus_clk", pnoc_clk.c, ""),
@@ -3232,10 +3230,6 @@
/* Maintain the max nominal frequency on the MMSSNOC AHB bus. */
clk_set_rate(&mmssnoc_ahb_a_clk.c, 40000000);
clk_prepare_enable(&mmssnoc_ahb_a_clk.c);
-
- /* TODO: Remove this once the bus driver is in place */
- clk_set_rate(&axi_clk_src.c, 200000000);
- clk_prepare_enable(&mmss_s0_axi_clk.c);
}
struct clock_init_data msm8610_clock_init_data __initdata = {
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 4a16b42..c74f713 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -4891,6 +4891,10 @@
CLK_LOOKUP("byte_clk", mdss_byte1_clk.c, "fd922e00.qcom,mdss_dsi"),
CLK_LOOKUP("core_clk", mdss_esc0_clk.c, "fd922800.qcom,mdss_dsi"),
CLK_LOOKUP("core_clk", mdss_esc1_clk.c, "fd922e00.qcom,mdss_dsi"),
+ CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd922800.qcom,mdss_dsi"),
+ CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd922e00.qcom,mdss_dsi"),
+ CLK_LOOKUP("bus_clk", mdss_axi_clk.c, "fd922800.qcom,mdss_dsi"),
+ CLK_LOOKUP("bus_clk", mdss_axi_clk.c, "fd922e00.qcom,mdss_dsi"),
CLK_LOOKUP("pixel_clk", mdss_pclk0_clk.c, "fd922800.qcom,mdss_dsi"),
CLK_LOOKUP("pixel_clk", mdss_pclk1_clk.c, "fd922e00.qcom,mdss_dsi"),
CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd922100.qcom,hdmi_tx"),
@@ -5097,7 +5101,6 @@
CLK_LOOKUP("core_clk", camss_vfe_vfe_axi_clk.c, "fda44000.qcom,iommu"),
CLK_LOOKUP("alt_core_clk", camss_top_ahb_clk.c, "fda44000.qcom,iommu"),
CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdp.0"),
- CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdss_dsi_clk_ctrl"),
CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd923400.qcom,mdss_edp"),
CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd928000.qcom,iommu"),
CLK_LOOKUP("core_clk", mdss_axi_clk.c, "fd928000.qcom,iommu"),
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index 674ef77..2a65d2f 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -54,6 +54,7 @@
extern struct clock_init_data msm8226_clock_init_data;
extern struct clock_init_data msm8226_rumi_clock_init_data;
extern struct clock_init_data msm8084_clock_init_data;
+extern struct clock_init_data mpq8092_clock_init_data;
int msm_clock_init(struct clock_init_data *data);
int find_vdd_level(struct clk *clk, unsigned long rate);
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index bf89321..483d8b3 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -1270,6 +1270,7 @@
LPASS_SCSS_GP_HIGH_IRQ,
SPS_MTI_31,
A2_BAM_IRQ,
+ USB1_HS_BAM_IRQ,
};
struct msm_mpm_device_data msm9615_mpm_dev_data __initdata = {
diff --git a/arch/arm/mach-msm/gdsc.c b/arch/arm/mach-msm/gdsc.c
index 30a034e..1701262 100644
--- a/arch/arm/mach-msm/gdsc.c
+++ b/arch/arm/mach-msm/gdsc.c
@@ -48,6 +48,7 @@
struct clk **clocks;
int clock_count;
bool toggle_mems;
+ bool retain_logic;
};
static int gdsc_is_enabled(struct regulator_dev *rdev)
@@ -96,16 +97,20 @@
{
struct gdsc *sc = rdev_get_drvdata(rdev);
uint32_t regval;
- int i, ret;
+ int i, ret = 0;
- regval = readl_relaxed(sc->gdscr);
- regval |= SW_COLLAPSE_MASK;
- writel_relaxed(regval, sc->gdscr);
+ if (!sc->retain_logic) {
+ regval = readl_relaxed(sc->gdscr);
+ regval |= SW_COLLAPSE_MASK;
+ writel_relaxed(regval, sc->gdscr);
- ret = readl_tight_poll_timeout(sc->gdscr, regval,
- !(regval & PWR_ON_MASK), TIMEOUT_US);
- if (ret)
- dev_err(&rdev->dev, "%s disable timed out\n", sc->rdesc.name);
+ ret = readl_tight_poll_timeout(sc->gdscr, regval,
+ !(regval & PWR_ON_MASK),
+ TIMEOUT_US);
+ if (ret)
+ dev_err(&rdev->dev, "%s disable timed out\n",
+ sc->rdesc.name);
+ }
if (sc->toggle_mems) {
for (i = 0; i < sc->clock_count; i++) {
@@ -214,6 +219,8 @@
}
}
sc->toggle_mems = !retain_mems;
+ sc->retain_logic = of_property_read_bool(pdev->dev.of_node,
+ "qcom,retain-logic");
sc->rdev = regulator_register(&sc->rdesc, &pdev->dev, init_data, sc,
pdev->dev.of_node);
diff --git a/arch/arm/mach-msm/include/mach/camera2.h b/arch/arm/mach-msm/include/mach/camera2.h
index 248c9b0..3e7e5fd 100644
--- a/arch/arm/mach-msm/include/mach/camera2.h
+++ b/arch/arm/mach-msm/include/mach/camera2.h
@@ -79,6 +79,7 @@
struct msm_camera_i2c_conf *i2c_conf;
struct msm_sensor_info_t *sensor_info;
struct msm_sensor_init_params *sensor_init_params;
+ const char *misc_regulator;
};
enum msm_camera_i2c_cmd_type {
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 23d204a..decf9bb 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -98,6 +98,7 @@
* @halt_enabled: Set to 1 if IOMMU halt is supported in the IOMMU, 0 otherwise.
* @asid: List of ASID and their usage count (index is ASID value).
* @ctx_attach_count: Count of how many context are attached.
+ * @bus_client : Bus client needed to vote for bus bandwidth.
*
* A msm_iommu_drvdata holds the global driver data about a single piece
* of an IOMMU hardware instance.
@@ -121,12 +122,14 @@
int halt_enabled;
int *asid;
unsigned int ctx_attach_count;
+ unsigned int bus_client;
};
/**
* struct iommu_access_ops - Callbacks for accessing IOMMU
* @iommu_power_on: Turn on power to unit
* @iommu_power_off: Turn off power to unit
+ * @iommu_bus_vote: Vote for bus bandwidth
* @iommu_clk_on: Turn on clks to unit
* @iommu_clk_off: Turn off clks to unit
* @iommu_lock_initialize: Initialize the remote lock
@@ -136,6 +139,8 @@
struct iommu_access_ops {
int (*iommu_power_on)(struct msm_iommu_drvdata *);
void (*iommu_power_off)(struct msm_iommu_drvdata *);
+ int (*iommu_bus_vote)(struct msm_iommu_drvdata *drvdata,
+ unsigned int vote);
int (*iommu_clk_on)(struct msm_iommu_drvdata *);
void (*iommu_clk_off)(struct msm_iommu_drvdata *);
void * (*iommu_lock_initialize)(void);
diff --git a/arch/arm/mach-msm/include/mach/kgsl.h b/arch/arm/mach-msm/include/mach/kgsl.h
index 349dbe7..2216183 100644
--- a/arch/arm/mach-msm/include/mach/kgsl.h
+++ b/arch/arm/mach-msm/include/mach/kgsl.h
@@ -89,6 +89,8 @@
struct kgsl_device_iommu_data *iommu_data;
int iommu_count;
struct msm_dcvs_core_info *core_info;
+ struct coresight_device *csdev;
+ struct coresight_platform_data *coresight_pdata;
unsigned int chipid;
};
diff --git a/arch/arm/mach-msm/include/mach/ocmem_priv.h b/arch/arm/mach-msm/include/mach/ocmem_priv.h
index 8539dcc..6f83c53 100644
--- a/arch/arm/mach-msm/include/mach/ocmem_priv.h
+++ b/arch/arm/mach-msm/include/mach/ocmem_priv.h
@@ -42,7 +42,7 @@
struct ocmem_zone;
struct ocmem_zone_ops {
- unsigned long (*allocate) (struct ocmem_zone *, unsigned long);
+ int (*allocate) (struct ocmem_zone *, unsigned long, unsigned long *);
int (*free) (struct ocmem_zone *, unsigned long, unsigned long);
};
@@ -197,9 +197,9 @@
int zone_active(int);
unsigned long offset_to_phys(unsigned long);
unsigned long phys_to_offset(unsigned long);
-unsigned long allocate_head(struct ocmem_zone *, unsigned long);
+int allocate_head(struct ocmem_zone *, unsigned long, unsigned long *);
int free_head(struct ocmem_zone *, unsigned long, unsigned long);
-unsigned long allocate_tail(struct ocmem_zone *, unsigned long);
+int allocate_tail(struct ocmem_zone *, unsigned long, unsigned long *);
int free_tail(struct ocmem_zone *, unsigned long, unsigned long);
int ocmem_notifier_init(void);
diff --git a/arch/arm/mach-msm/include/mach/usb_bam.h b/arch/arm/mach-msm/include/mach/usb_bam.h
index 5ecc63b..bc76f56 100644
--- a/arch/arm/mach-msm/include/mach/usb_bam.h
+++ b/arch/arm/mach-msm/include/mach/usb_bam.h
@@ -126,6 +126,7 @@
struct sps_mem_buffer desc_mem_buf;
struct usb_bam_event_info event;
bool enabled;
+ bool suspended;
int ipa_clnt_hdl;
void *priv;
int (*activity_notify)(void *priv);
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index f4ac37e..12f5a8e 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -570,12 +570,14 @@
goto out;
}
ctx = msm_iommu_get_ctx(name);
- if (!ctx) {
- pr_err("Unable to find context %s\n", name);
- ret_val = -EINVAL;
+ if (IS_ERR(ctx)) {
+ ret_val = PTR_ERR(ctx);
goto out;
}
- iommu_group_add_device(group, ctx);
+
+ ret_val = iommu_group_add_device(group, ctx);
+ if (ret_val)
+ goto out;
}
out:
return ret_val;
@@ -590,7 +592,7 @@
struct msm_iova_layout l;
struct msm_iova_partition *part = 0;
struct iommu_domain *domain = 0;
- unsigned int *addr_array;
+ unsigned int *addr_array = 0;
unsigned int array_size;
int domain_no;
int secure_domain;
@@ -661,11 +663,46 @@
iommu_group_set_iommudata(group, domain, NULL);
free_mem:
+ kfree(addr_array);
kfree(part);
out:
return ret_val;
}
+static int __msm_group_get_domain(struct device *dev, void *data)
+{
+ struct msm_iommu_data_entry *list_entry;
+ struct list_head *dev_list = data;
+ int ret_val = 0;
+
+ list_entry = kmalloc(sizeof(*list_entry), GFP_KERNEL);
+ if (list_entry) {
+ list_entry->data = dev;
+ list_add(&list_entry->list, dev_list);
+ } else {
+ ret_val = -ENOMEM;
+ }
+
+ return ret_val;
+}
+
+static void __msm_iommu_group_remove_device(struct iommu_group *grp)
+{
+ struct msm_iommu_data_entry *tmp;
+ struct msm_iommu_data_entry *list_entry;
+ struct list_head dev_list;
+
+ INIT_LIST_HEAD(&dev_list);
+ iommu_group_for_each_dev(grp, &dev_list, __msm_group_get_domain);
+
+ list_for_each_entry_safe(list_entry, tmp, &dev_list, list) {
+ iommu_group_remove_device(list_entry->data);
+ list_del(&list_entry->list);
+ kfree(list_entry);
+ }
+}
+
+
static int iommu_domain_parse_dt(const struct device_node *dt_node)
{
struct device_node *node;
@@ -674,13 +711,30 @@
int ret_val = 0;
struct iommu_group *group = 0;
const char *name;
+ struct msm_iommu_data_entry *grp_list_entry;
+ struct msm_iommu_data_entry *tmp;
+ struct list_head iommu_group_list;
+ INIT_LIST_HEAD(&iommu_group_list);
for_each_child_of_node(dt_node, node) {
group = iommu_group_alloc();
if (IS_ERR(group)) {
ret_val = PTR_ERR(group);
- goto out;
+ group = 0;
+ goto free_group;
}
+
+ /* This is only needed to clean up memory if something fails */
+ grp_list_entry = kmalloc(sizeof(*grp_list_entry),
+ GFP_KERNEL);
+ if (grp_list_entry) {
+ grp_list_entry->data = group;
+ list_add(&grp_list_entry->list, &iommu_group_list);
+ } else {
+ ret_val = -ENOMEM;
+ goto free_group;
+ }
+
if (of_property_read_string(node, "label", &name)) {
ret_val = -EINVAL;
goto free_group;
@@ -696,7 +750,6 @@
ret_val = find_and_add_contexts(group, node, num_contexts);
if (ret_val) {
- ret_val = -EINVAL;
goto free_group;
}
ret_val = create_and_add_domain(group, node, name);
@@ -704,9 +757,33 @@
ret_val = -EINVAL;
goto free_group;
}
+
+ /* Remove reference to the group that is taken when the group
+ * is allocated. This will ensure that when all the devices in
+ * the group are removed the group will be released.
+ */
+ iommu_group_put(group);
}
+
+ list_for_each_entry_safe(grp_list_entry, tmp, &iommu_group_list, list) {
+ list_del(&grp_list_entry->list);
+ kfree(grp_list_entry);
+ }
+ goto out;
+
free_group:
- /* No iommu_group_free() function */
+ list_for_each_entry_safe(grp_list_entry, tmp, &iommu_group_list, list) {
+ struct iommu_domain *d;
+
+ d = iommu_group_get_iommudata(grp_list_entry->data);
+ if (d)
+ msm_unregister_domain(d);
+
+ __msm_iommu_group_remove_device(grp_list_entry->data);
+ list_del(&grp_list_entry->list);
+ kfree(grp_list_entry);
+ }
+ iommu_group_put(group);
out:
return ret_val;
}
diff --git a/arch/arm/mach-msm/ipc_logging.c b/arch/arm/mach-msm/ipc_logging.c
index 1260a1a..280f237 100644
--- a/arch/arm/mach-msm/ipc_logging.c
+++ b/arch/arm/mach-msm/ipc_logging.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -32,7 +32,7 @@
#include "ipc_logging.h"
static LIST_HEAD(ipc_log_context_list);
-DEFINE_SPINLOCK(ipc_log_context_list_lock);
+DEFINE_RWLOCK(ipc_log_context_list_lock);
static atomic_t next_log_id = ATOMIC_INIT(0);
static struct ipc_log_page *get_first_page(struct ipc_log_context *ilctxt)
@@ -140,7 +140,7 @@
return;
}
- spin_lock_irqsave(&ipc_log_context_list_lock, flags);
+ read_lock_irqsave(&ipc_log_context_list_lock, flags);
spin_lock(&ilctxt->ipc_log_context_lock);
while (ilctxt->write_avail < ectxt->offset)
msg_read(ilctxt, NULL);
@@ -165,7 +165,7 @@
ilctxt->write_avail -= ectxt->offset;
complete(&ilctxt->read_avail);
spin_unlock(&ilctxt->ipc_log_context_lock);
- spin_unlock_irqrestore(&ipc_log_context_list_lock, flags);
+ read_unlock_irqrestore(&ipc_log_context_list_lock, flags);
}
EXPORT_SYMBOL(ipc_log_write);
@@ -471,13 +471,13 @@
if (!df_info)
return -ENOSPC;
- spin_lock_irqsave(&ipc_log_context_list_lock, flags);
+ read_lock_irqsave(&ipc_log_context_list_lock, flags);
spin_lock(&ilctxt->ipc_log_context_lock);
df_info->type = type;
df_info->dfunc = dfunc;
list_add_tail(&df_info->list, &ilctxt->dfunc_info_list);
spin_unlock(&ilctxt->ipc_log_context_lock);
- spin_unlock_irqrestore(&ipc_log_context_list_lock, flags);
+ read_unlock_irqrestore(&ipc_log_context_list_lock, flags);
return 0;
}
EXPORT_SYMBOL(add_deserialization_func);
@@ -528,9 +528,9 @@
create_ctx_debugfs(ctxt, mod_name);
- spin_lock_irqsave(&ipc_log_context_list_lock, flags);
+ write_lock_irqsave(&ipc_log_context_list_lock, flags);
list_add_tail(&ctxt->list, &ipc_log_context_list);
- spin_unlock_irqrestore(&ipc_log_context_list_lock, flags);
+ write_unlock_irqrestore(&ipc_log_context_list_lock, flags);
return (void *)ctxt;
release_ipc_log_context:
diff --git a/arch/arm/mach-msm/ipc_logging.h b/arch/arm/mach-msm/ipc_logging.h
index 0eb82a5..36b4171 100644
--- a/arch/arm/mach-msm/ipc_logging.h
+++ b/arch/arm/mach-msm/ipc_logging.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -65,7 +65,7 @@
#define IS_MSG_TYPE(x) (((x) > TSV_TYPE_MSG_START) && \
((x) < TSV_TYPE_MSG_END))
-extern spinlock_t ipc_log_context_list_lock;
+extern rwlock_t ipc_log_context_list_lock;
extern int msg_read(struct ipc_log_context *ilctxt,
struct encode_context *ectxt);
diff --git a/arch/arm/mach-msm/ipc_logging_debug.c b/arch/arm/mach-msm/ipc_logging_debug.c
index ff947ef..246fb99 100644
--- a/arch/arm/mach-msm/ipc_logging_debug.c
+++ b/arch/arm/mach-msm/ipc_logging_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -62,7 +62,7 @@
dctxt.output_format = OUTPUT_DEBUGFS;
dctxt.buff = buff;
dctxt.size = size;
- spin_lock_irqsave(&ipc_log_context_list_lock, flags);
+ read_lock_irqsave(&ipc_log_context_list_lock, flags);
spin_lock(&ilctxt->ipc_log_context_lock);
while (dctxt.size >= MAX_MSG_DECODED_SIZE &&
!is_ilctxt_empty(ilctxt)) {
@@ -70,19 +70,19 @@
deserialize_func = get_deserialization_func(ilctxt,
ectxt.hdr.type);
spin_unlock(&ilctxt->ipc_log_context_lock);
- spin_unlock_irqrestore(&ipc_log_context_list_lock, flags);
+ read_unlock_irqrestore(&ipc_log_context_list_lock, flags);
if (deserialize_func)
deserialize_func(&ectxt, &dctxt);
else
pr_err("%s: unknown message 0x%x\n",
__func__, ectxt.hdr.type);
- spin_lock_irqsave(&ipc_log_context_list_lock, flags);
+ read_lock_irqsave(&ipc_log_context_list_lock, flags);
spin_lock(&ilctxt->ipc_log_context_lock);
}
if ((size - dctxt.size) == 0)
init_completion(&ilctxt->read_avail);
spin_unlock(&ilctxt->ipc_log_context_lock);
- spin_unlock_irqrestore(&ipc_log_context_list_lock, flags);
+ read_unlock_irqrestore(&ipc_log_context_list_lock, flags);
return size - dctxt.size;
}
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index c620419..f95ef3b 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -476,23 +476,44 @@
kfree(skb_head);
}
+static int post_pkt_to_port(struct msm_ipc_port *port_ptr,
+ struct rr_packet *pkt, int clone)
+{
+ struct rr_packet *temp_pkt = pkt;
+
+ if (unlikely(!port_ptr || !pkt))
+ return -EINVAL;
+
+ if (clone) {
+ temp_pkt = clone_pkt(pkt);
+ if (!temp_pkt) {
+ pr_err("%s: Error cloning packet for port %08x:%08x\n",
+ __func__, port_ptr->this_port.node_id,
+ port_ptr->this_port.port_id);
+ return -ENOMEM;
+ }
+ }
+
+ mutex_lock(&port_ptr->port_rx_q_lock);
+ wake_lock(&port_ptr->port_rx_wake_lock);
+ list_add_tail(&temp_pkt->list, &port_ptr->port_rx_q);
+ wake_up(&port_ptr->port_rx_wait_q);
+ if (port_ptr->notify)
+ port_ptr->notify(MSM_IPC_ROUTER_READ_CB, port_ptr->priv);
+ mutex_unlock(&port_ptr->port_rx_q_lock);
+ return 0;
+}
+
static int post_control_ports(struct rr_packet *pkt)
{
struct msm_ipc_port *port_ptr;
- struct rr_packet *cloned_pkt;
if (!pkt)
return -EINVAL;
mutex_lock(&control_ports_lock);
- list_for_each_entry(port_ptr, &control_ports, list) {
- mutex_lock(&port_ptr->port_rx_q_lock);
- cloned_pkt = clone_pkt(pkt);
- wake_lock(&port_ptr->port_rx_wake_lock);
- list_add_tail(&cloned_pkt->list, &port_ptr->port_rx_q);
- wake_up(&port_ptr->port_rx_wait_q);
- mutex_unlock(&port_ptr->port_rx_q_lock);
- }
+ list_for_each_entry(port_ptr, &control_ports, list)
+ post_pkt_to_port(port_ptr, pkt, 1);
mutex_unlock(&control_ports_lock);
return 0;
}
@@ -736,27 +757,14 @@
{
struct msm_ipc_resume_tx_port *rtx_port, *tmp_rtx_port;
struct msm_ipc_port *local_port;
- struct rr_packet *cloned_pkt;
list_for_each_entry_safe(rtx_port, tmp_rtx_port,
&rport_ptr->resume_tx_port_list, list) {
mutex_lock(&local_ports_lock);
local_port =
msm_ipc_router_lookup_local_port(rtx_port->port_id);
- if (local_port) {
- cloned_pkt = clone_pkt(pkt);
- if (cloned_pkt) {
- mutex_lock(&local_port->port_rx_q_lock);
- list_add_tail(&cloned_pkt->list,
- &local_port->port_rx_q);
- wake_up(&local_port->port_rx_wait_q);
- mutex_unlock(&local_port->port_rx_q_lock);
- } else {
- pr_err("%s: Clone_pkt failed for %08x:%08x\n",
- __func__, local_port->this_port.node_id,
- local_port->this_port.port_id);
- }
- }
+ if (local_port)
+ post_pkt_to_port(local_port, pkt, 1);
mutex_unlock(&local_ports_lock);
list_del(&rtx_port->list);
kfree(rtx_port);
@@ -1646,16 +1654,157 @@
return rc;
}
+static int process_resume_tx_msg(union rr_control_msg *msg,
+ struct rr_packet *pkt)
+{
+ struct msm_ipc_router_remote_port *rport_ptr;
+
+ RR("o RESUME_TX id=%d:%08x\n", msg->cli.node_id, msg->cli.port_id);
+
+ rport_ptr = msm_ipc_router_lookup_remote_port(msg->cli.node_id,
+ msg->cli.port_id);
+ if (!rport_ptr) {
+ pr_err("%s: Unable to resume client\n", __func__);
+ return -ENODEV;
+ }
+ mutex_lock(&rport_ptr->quota_lock);
+ rport_ptr->tx_quota_cnt = 0;
+ post_resume_tx(rport_ptr, pkt);
+ mutex_unlock(&rport_ptr->quota_lock);
+ return 0;
+}
+
+static int process_new_server_msg(struct msm_ipc_router_xprt_info *xprt_info,
+ union rr_control_msg *msg, struct rr_packet *pkt)
+{
+ struct msm_ipc_routing_table_entry *rt_entry;
+ struct msm_ipc_server *server;
+ struct msm_ipc_router_remote_port *rport_ptr;
+
+ if (msg->srv.instance == 0) {
+ pr_err("%s: Server %08x create rejected, version = 0\n",
+ __func__, msg->srv.service);
+ return -EINVAL;
+ }
+
+ RR("o NEW_SERVER id=%d:%08x service=%08x:%08x\n", msg->srv.node_id,
+ msg->srv.port_id, msg->srv.service, msg->srv.instance);
+ /*
+ * Find the entry from Routing Table corresponding to Node ID.
+ * Under SSR, an entry will be found. When the subsystem hosting
+ * service is not adjacent, an entry will not be found and hence
+ * allocate an entry. Update the entry with the Node ID that it
+ * corresponds to and the XPRT through which it can be reached.
+ */
+ mutex_lock(&routing_table_lock);
+ rt_entry = lookup_routing_table(msg->srv.node_id);
+ if (!rt_entry) {
+ rt_entry = alloc_routing_table_entry(msg->srv.node_id);
+ if (!rt_entry) {
+ mutex_unlock(&routing_table_lock);
+ pr_err("%s: rt_entry allocation failed\n", __func__);
+ return -ENOMEM;
+ }
+ mutex_lock(&rt_entry->lock);
+ rt_entry->neighbor_node_id = xprt_info->remote_node_id;
+ rt_entry->xprt_info = xprt_info;
+ mutex_unlock(&rt_entry->lock);
+ add_routing_table_entry(rt_entry);
+ }
+ mutex_unlock(&routing_table_lock);
+
+ /*
+ * If the service does not exist already in the database, create and
+ * store the service info. Create a remote port structure in which
+ * the service is hosted and cache the security rule for the service
+ * in that remote port structure.
+ */
+ mutex_lock(&server_list_lock);
+ server = msm_ipc_router_lookup_server(msg->srv.service,
+ msg->srv.instance, msg->srv.node_id, msg->srv.port_id);
+ if (!server) {
+ server = msm_ipc_router_create_server(
+ msg->srv.service, msg->srv.instance,
+ msg->srv.node_id, msg->srv.port_id, xprt_info);
+ if (!server) {
+ mutex_unlock(&server_list_lock);
+ pr_err("%s: Server Create failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ if (!msm_ipc_router_lookup_remote_port(
+ msg->srv.node_id, msg->srv.port_id)) {
+ rport_ptr = msm_ipc_router_create_remote_port(
+ msg->srv.node_id, msg->srv.port_id);
+ if (!rport_ptr) {
+ mutex_unlock(&server_list_lock);
+ return -ENOMEM;
+ }
+ rport_ptr->sec_rule = msm_ipc_get_security_rule(
+ msg->srv.service,
+ msg->srv.instance);
+ }
+ }
+ mutex_unlock(&server_list_lock);
+
+ /*
+ * Relay the new server message to other subsystems that do not belong
+ * to the cluster from which this message is received. Notify the
+ * local clients waiting for this service.
+ */
+ relay_msg(xprt_info, pkt);
+ post_control_ports(pkt);
+ return 0;
+}
+
+static int process_rmv_server_msg(struct msm_ipc_router_xprt_info *xprt_info,
+ union rr_control_msg *msg, struct rr_packet *pkt)
+{
+ struct msm_ipc_server *server;
+
+ RR("o REMOVE_SERVER service=%08x:%d\n",
+ msg->srv.service, msg->srv.instance);
+ mutex_lock(&server_list_lock);
+ server = msm_ipc_router_lookup_server(msg->srv.service,
+ msg->srv.instance, msg->srv.node_id, msg->srv.port_id);
+ if (server) {
+ msm_ipc_router_destroy_server(server, msg->srv.node_id,
+ msg->srv.port_id);
+ /*
+ * Relay the new server message to other subsystems that do not
+ * belong to the cluster from which this message is received.
+ * Notify the local clients communicating with the service.
+ */
+ relay_msg(xprt_info, pkt);
+ post_control_ports(pkt);
+ }
+ mutex_unlock(&server_list_lock);
+ return 0;
+}
+
+static int process_rmv_client_msg(struct msm_ipc_router_xprt_info *xprt_info,
+ union rr_control_msg *msg, struct rr_packet *pkt)
+{
+ struct msm_ipc_router_remote_port *rport_ptr;
+
+ RR("o REMOVE_CLIENT id=%d:%08x\n", msg->cli.node_id, msg->cli.port_id);
+ rport_ptr = msm_ipc_router_lookup_remote_port(msg->cli.node_id,
+ msg->cli.port_id);
+ if (rport_ptr)
+ msm_ipc_router_destroy_remote_port(rport_ptr);
+
+ relay_msg(xprt_info, pkt);
+ post_control_ports(pkt);
+ return 0;
+}
+
static int process_control_msg(struct msm_ipc_router_xprt_info *xprt_info,
struct rr_packet *pkt)
{
union rr_control_msg *msg;
- struct msm_ipc_router_remote_port *rport_ptr;
int rc = 0;
struct sk_buff *temp_ptr;
struct rr_header *hdr;
- struct msm_ipc_server *server;
- struct msm_ipc_routing_table_entry *rt_entry;
if (pkt->length != (IPC_ROUTER_HDR_SIZE + sizeof(*msg))) {
pr_err("%s: r2r msg size %d != %d\n", __func__, pkt->length,
@@ -1679,115 +1828,17 @@
case IPC_ROUTER_CTRL_CMD_HELLO:
rc = process_hello_msg(xprt_info, hdr);
break;
-
case IPC_ROUTER_CTRL_CMD_RESUME_TX:
- RR("o RESUME_TX id=%d:%08x\n",
- msg->cli.node_id, msg->cli.port_id);
-
- rport_ptr = msm_ipc_router_lookup_remote_port(msg->cli.node_id,
- msg->cli.port_id);
- if (!rport_ptr) {
- pr_err("%s: Unable to resume client\n", __func__);
- break;
- }
- mutex_lock(&rport_ptr->quota_lock);
- rport_ptr->tx_quota_cnt = 0;
- post_resume_tx(rport_ptr, pkt);
- mutex_unlock(&rport_ptr->quota_lock);
+ rc = process_resume_tx_msg(msg, pkt);
break;
-
case IPC_ROUTER_CTRL_CMD_NEW_SERVER:
- if (msg->srv.instance == 0) {
- pr_err(
- "rpcrouter: Server create rejected, version = 0, "
- "service = %08x\n", msg->srv.service);
- break;
- }
-
- RR("o NEW_SERVER id=%d:%08x service=%08x:%08x\n",
- msg->srv.node_id, msg->srv.port_id,
- msg->srv.service, msg->srv.instance);
-
- mutex_lock(&routing_table_lock);
- rt_entry = lookup_routing_table(msg->srv.node_id);
- if (!rt_entry) {
- rt_entry = alloc_routing_table_entry(msg->srv.node_id);
- if (!rt_entry) {
- mutex_unlock(&routing_table_lock);
- pr_err("%s: rt_entry allocation failed\n",
- __func__);
- return -ENOMEM;
- }
- mutex_lock(&rt_entry->lock);
- rt_entry->neighbor_node_id = xprt_info->remote_node_id;
- rt_entry->xprt_info = xprt_info;
- mutex_unlock(&rt_entry->lock);
- add_routing_table_entry(rt_entry);
- }
- mutex_unlock(&routing_table_lock);
-
- mutex_lock(&server_list_lock);
- server = msm_ipc_router_lookup_server(msg->srv.service,
- msg->srv.instance,
- msg->srv.node_id,
- msg->srv.port_id);
- if (!server) {
- server = msm_ipc_router_create_server(
- msg->srv.service, msg->srv.instance,
- msg->srv.node_id, msg->srv.port_id, xprt_info);
- if (!server) {
- mutex_unlock(&server_list_lock);
- pr_err("%s: Server Create failed\n", __func__);
- return -ENOMEM;
- }
-
- if (!msm_ipc_router_lookup_remote_port(
- msg->srv.node_id, msg->srv.port_id)) {
- rport_ptr = msm_ipc_router_create_remote_port(
- msg->srv.node_id, msg->srv.port_id);
- if (!rport_ptr)
- pr_err("%s: Remote port create "
- "failed\n", __func__);
- else
- rport_ptr->sec_rule =
- msm_ipc_get_security_rule(
- msg->srv.service,
- msg->srv.instance);
- }
- wake_up(&newserver_wait);
- }
- mutex_unlock(&server_list_lock);
-
- relay_msg(xprt_info, pkt);
- post_control_ports(pkt);
+ rc = process_new_server_msg(xprt_info, msg, pkt);
break;
case IPC_ROUTER_CTRL_CMD_REMOVE_SERVER:
- RR("o REMOVE_SERVER service=%08x:%d\n",
- msg->srv.service, msg->srv.instance);
- mutex_lock(&server_list_lock);
- server = msm_ipc_router_lookup_server(msg->srv.service,
- msg->srv.instance,
- msg->srv.node_id,
- msg->srv.port_id);
- if (server) {
- msm_ipc_router_destroy_server(server,
- msg->srv.node_id,
- msg->srv.port_id);
- relay_msg(xprt_info, pkt);
- post_control_ports(pkt);
- }
- mutex_unlock(&server_list_lock);
+ rc = process_rmv_server_msg(xprt_info, msg, pkt);
break;
case IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT:
- RR("o REMOVE_CLIENT id=%d:%08x\n",
- msg->cli.node_id, msg->cli.port_id);
- rport_ptr = msm_ipc_router_lookup_remote_port(msg->cli.node_id,
- msg->cli.port_id);
- if (rport_ptr)
- msm_ipc_router_destroy_remote_port(rport_ptr);
-
- relay_msg(xprt_info, pkt);
- post_control_ports(pkt);
+ rc = process_rmv_client_msg(xprt_info, msg, pkt);
break;
case IPC_ROUTER_CTRL_CMD_PING:
/* No action needed for ping messages received */
@@ -1901,14 +1952,7 @@
}
}
- mutex_lock(&port_ptr->port_rx_q_lock);
- wake_lock(&port_ptr->port_rx_wake_lock);
- list_add_tail(&pkt->list, &port_ptr->port_rx_q);
- wake_up(&port_ptr->port_rx_wait_q);
- if (port_ptr->notify)
- port_ptr->notify(MSM_IPC_ROUTER_READ_CB,
- port_ptr->priv);
- mutex_unlock(&port_ptr->port_rx_q_lock);
+ post_pkt_to_port(port_ptr, pkt, 0);
mutex_unlock(&local_ports_lock);
process_done:
@@ -2082,12 +2126,8 @@
return -ENODEV;
}
- mutex_lock(&port_ptr->port_rx_q_lock);
- wake_lock(&port_ptr->port_rx_wake_lock);
- list_add_tail(&pkt->list, &port_ptr->port_rx_q);
ret_len = pkt->length;
- wake_up(&port_ptr->port_rx_wait_q);
- mutex_unlock(&port_ptr->port_rx_q_lock);
+ post_pkt_to_port(port_ptr, pkt, 0);
update_comm_mode_info(&src->mode_info, NULL);
mutex_unlock(&local_ports_lock);
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
index f05b381..d531aaa 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
@@ -1460,7 +1460,7 @@
* boundary in future
*/
wmb();
- set_qos_mode(binfo->base, mas_index, 0, 1, 1);
+ set_qos_mode(binfo->base, mas_index, 1, 1, 1);
break;
case BIMC_QOS_MODE_BYPASS:
diff --git a/arch/arm/mach-msm/ocmem_allocator.c b/arch/arm/mach-msm/ocmem_allocator.c
index 203bb60..a0ff9f9 100644
--- a/arch/arm/mach-msm/ocmem_allocator.c
+++ b/arch/arm/mach-msm/ocmem_allocator.c
@@ -36,24 +36,22 @@
reserve: Enable libgenpool to simulate tail allocations
*/
-unsigned long allocate_head(struct ocmem_zone *z, unsigned long size)
+int allocate_head(struct ocmem_zone *z, unsigned long size,
+ unsigned long *offset)
{
+ *offset = gen_pool_alloc(z->z_pool, size);
- unsigned long offset;
-
- offset = gen_pool_alloc(z->z_pool, size);
-
- if (!offset)
+ if (!(*offset))
return -ENOMEM;
z->z_head += size;
z->z_free -= size;
- return offset;
+ return 0;
}
-unsigned long allocate_tail(struct ocmem_zone *z, unsigned long size)
+int allocate_tail(struct ocmem_zone *z, unsigned long size,
+ unsigned long *offset)
{
- unsigned long offset;
unsigned long reserve;
unsigned long head;
@@ -63,17 +61,17 @@
reserve = z->z_tail - z->z_head - size;
if (reserve) {
head = gen_pool_alloc(z->z_pool, reserve);
- offset = gen_pool_alloc(z->z_pool, size);
+ *offset = gen_pool_alloc(z->z_pool, size);
gen_pool_free(z->z_pool, head, reserve);
} else
- offset = gen_pool_alloc(z->z_pool, size);
+ *offset = gen_pool_alloc(z->z_pool, size);
- if (!offset)
+ if (!(*offset))
return -ENOMEM;
z->z_tail -= size;
z->z_free -= size;
- return offset;
+ return 0;
}
int free_head(struct ocmem_zone *z, unsigned long offset,
diff --git a/arch/arm/mach-msm/ocmem_sched.c b/arch/arm/mach-msm/ocmem_sched.c
index a14b960..21c4e1e 100644
--- a/arch/arm/mach-msm/ocmem_sched.c
+++ b/arch/arm/mach-msm/ocmem_sched.c
@@ -724,6 +724,7 @@
bool retry;
struct ocmem_region *spanned_r = NULL;
struct ocmem_region *overlap_r = NULL;
+ int rc = 0;
struct ocmem_req *matched_req = NULL;
struct ocmem_region *matched_region = NULL;
@@ -767,9 +768,10 @@
if (overlap_r == NULL) {
/* no conflicting regions, schedule this region */
zone->z_ops->free(zone, curr_start, curr_sz);
- alloc_addr = zone->z_ops->allocate(zone, curr_sz + growth_sz);
+ rc = zone->z_ops->allocate(zone, curr_sz + growth_sz,
+ &alloc_addr);
- if (alloc_addr < 0) {
+ if (rc) {
pr_err("ocmem: zone allocation operation failed\n");
goto internal_error;
}
@@ -933,6 +935,7 @@
struct ocmem_region *matched_region = NULL;
struct ocmem_region *region = NULL;
unsigned long alloc_addr = 0x0;
+ int rc = 0;
struct ocmem_zone *zone = get_zone(owner);
@@ -957,9 +960,9 @@
goto internal_error;
}
- alloc_addr = zone->z_ops->allocate(zone, new_sz);
+ rc = zone->z_ops->allocate(zone, new_sz, &alloc_addr);
- if (alloc_addr < 0) {
+ if (rc) {
pr_err("Zone Allocation operation failed\n");
goto internal_error;
}
@@ -1032,6 +1035,7 @@
enum client_prio prio = req->prio;
unsigned long alloc_addr = 0x0;
bool retry;
+ int rc = 0;
struct ocmem_region *spanned_r = NULL;
struct ocmem_region *overlap_r = NULL;
@@ -1078,9 +1082,9 @@
if (overlap_r == NULL) {
/* no conflicting regions, schedule this region */
- alloc_addr = zone->z_ops->allocate(zone, sz);
+ rc = zone->z_ops->allocate(zone, sz, &alloc_addr);
- if (alloc_addr < 0) {
+ if (rc) {
pr_err("Zone Allocation operation failed\n");
goto internal_error;
}
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index afb2b84..5e44a4e 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -36,6 +36,7 @@
#include <mach/scm.h>
#include <mach/socinfo.h>
#include <mach/msm-krait-l2-accessors.h>
+#include <mach/msm_bus.h>
#include <asm/cacheflush.h>
#include <asm/hardware/gic.h>
#include <asm/pgtable.h>
@@ -854,8 +855,10 @@
time = ktime_to_ns(ktime_get());
if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
+ int64_t ns = msm_pm_timer_enter_idle();
notify_rpm = true;
- sleep_delay = (uint32_t)msm_pm_timer_enter_idle();
+ do_div(ns, NSEC_PER_SEC / SCLK_HZ);
+ sleep_delay = (uint32_t)ns;
if (sleep_delay == 0) /* 0 would mean infinite time */
sleep_delay = 1;
@@ -1110,6 +1113,36 @@
.enter = msm_pm_enter,
.valid = suspend_valid_only_mem,
};
+
+static int __devinit msm_pm_snoc_client_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+ static struct msm_bus_scale_pdata *msm_pm_bus_pdata;
+ static uint32_t msm_pm_bus_client;
+
+ msm_pm_bus_pdata = msm_bus_cl_get_pdata(pdev);
+
+ if (msm_pm_bus_pdata) {
+ msm_pm_bus_client =
+ msm_bus_scale_register_client(msm_pm_bus_pdata);
+
+ if (!msm_pm_bus_client) {
+ pr_err("%s: Failed to register SNOC client",
+ __func__);
+ rc = -ENXIO;
+ goto snoc_cl_probe_done;
+ }
+
+ rc = msm_bus_scale_client_update_request(msm_pm_bus_client, 1);
+
+ if (rc)
+ pr_err("%s: Error setting bus rate", __func__);
+ }
+
+snoc_cl_probe_done:
+ return rc;
+}
+
static int __devinit msm_cpu_status_probe(struct platform_device *pdev)
{
struct msm_pm_sleep_status_data *pdata;
@@ -1198,6 +1231,21 @@
},
};
+static struct of_device_id msm_snoc_clnt_match_tbl[] = {
+ {.compatible = "qcom,pm-snoc-client"},
+ {},
+};
+
+static struct platform_driver msm_cpu_pm_snoc_client_driver = {
+ .probe = msm_pm_snoc_client_probe,
+ .driver = {
+ .name = "pm_snoc_client",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_snoc_clnt_match_tbl,
+ },
+};
+
+
static int __init msm_pm_setup_saved_state(void)
{
pgd_t *pc_pgd;
@@ -1538,6 +1586,14 @@
return rc;
}
+ rc = platform_driver_register(&msm_cpu_pm_snoc_client_driver);
+
+ if (rc) {
+ pr_err("%s(): failed to register driver %s\n", __func__,
+ msm_cpu_pm_snoc_client_driver.driver.name);
+ return rc;
+ }
+
return platform_driver_register(&msm_pm_8x60_driver);
}
device_initcall(msm_pm_8x60_init);
diff --git a/arch/arm/mach-msm/spm-regulator.c b/arch/arm/mach-msm/spm-regulator.c
index 00817c0..244a779 100644
--- a/arch/arm/mach-msm/spm-regulator.c
+++ b/arch/arm/mach-msm/spm-regulator.c
@@ -42,17 +42,40 @@
static const struct voltage_range fts2_range0 = {0, 350000, 1275000, 5000};
static const struct voltage_range fts2_range1 = {0, 700000, 2040000, 10000};
-/* Specifies the PMIC internal slew rate in uV/us. */
-#define QPNP_FTS2_SLEW_RATE 6000
-
#define QPNP_FTS2_REG_TYPE 0x04
#define QPNP_FTS2_REG_SUBTYPE 0x05
#define QPNP_FTS2_REG_VOLTAGE_RANGE 0x40
#define QPNP_FTS2_REG_VOLTAGE_SETPOINT 0x41
+#define QPNP_FTS2_REG_MODE 0x45
+#define QPNP_FTS2_REG_STEP_CTRL 0x61
#define QPNP_FTS2_TYPE 0x1C
#define QPNP_FTS2_SUBTYPE 0x08
+#define QPNP_FTS2_MODE_PWM 0x80
+#define QPNP_FTS2_MODE_AUTO 0x40
+
+#define QPNP_FTS2_STEP_CTRL_STEP_MASK 0x18
+#define QPNP_FTS2_STEP_CTRL_STEP_SHIFT 3
+#define QPNP_FTS2_STEP_CTRL_DELAY_MASK 0x07
+#define QPNP_FTS2_STEP_CTRL_DELAY_SHIFT 0
+
+/* Clock rate in kHz of the FTS2 regulator reference clock. */
+#define QPNP_FTS2_CLOCK_RATE 19200
+
+/* Time to delay in us to ensure that a mode change has completed. */
+#define QPNP_FTS2_MODE_CHANGE_DELAY 50
+
+/* Minimum time in us that it takes to complete a single SPMI write. */
+#define QPNP_SPMI_WRITE_MIN_DELAY 8
+
+/*
+ * The ratio QPNP_FTS2_STEP_MARGIN_NUM/QPNP_FTS2_STEP_MARGIN_DEN is use to
+ * adjust the step rate in order to account for oscillator variance.
+ */
+#define QPNP_FTS2_STEP_MARGIN_NUM 4
+#define QPNP_FTS2_STEP_MARGIN_DEN 5
+
struct spm_vreg {
struct regulator_desc rdesc;
struct regulator_dev *rdev;
@@ -64,8 +87,23 @@
unsigned last_set_vlevel;
bool online;
u16 spmi_base_addr;
+ u8 init_mode;
+ int step_rate;
};
+static int qpnp_fts2_set_mode(struct spm_vreg *vreg, u8 mode)
+{
+ int rc;
+
+ rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
+ vreg->spmi_base_addr + QPNP_FTS2_REG_MODE, &mode, 1);
+ if (rc)
+ dev_err(&vreg->spmi_dev->dev, "%s: could not write to mode register, rc=%d\n",
+ __func__, rc);
+
+ return rc;
+}
+
static int _spm_regulator_set_voltage(struct regulator_dev *rdev)
{
struct spm_vreg *vreg = rdev_get_drvdata(rdev);
@@ -74,6 +112,14 @@
if (vreg->vlevel == vreg->last_set_vlevel)
return 0;
+ if (!(vreg->init_mode & QPNP_FTS2_MODE_PWM)
+ && vreg->uV > vreg->last_set_uV) {
+ /* Switch to PWM mode so that voltage ramping is fast. */
+ rc = qpnp_fts2_set_mode(vreg, QPNP_FTS2_MODE_PWM);
+ if (rc)
+ return rc;
+ }
+
rc = msm_spm_apcs_set_vdd(vreg->vlevel);
if (rc) {
pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->rdesc.name, rc);
@@ -81,10 +127,21 @@
}
if (vreg->uV > vreg->last_set_uV) {
- /* Wait for voltage to stabalize. */
+ /* Wait for voltage stepping to complete. */
udelay(DIV_ROUND_UP(vreg->uV - vreg->last_set_uV,
- QPNP_FTS2_SLEW_RATE));
+ vreg->step_rate));
}
+
+ if (!(vreg->init_mode & QPNP_FTS2_MODE_PWM)
+ && vreg->uV > vreg->last_set_uV) {
+ /* Wait for mode transition to complete. */
+ udelay(QPNP_FTS2_MODE_CHANGE_DELAY - QPNP_SPMI_WRITE_MIN_DELAY);
+ /* Switch to AUTO mode so that power consumption is lowered. */
+ rc = qpnp_fts2_set_mode(vreg, QPNP_FTS2_MODE_AUTO);
+ if (rc)
+ return rc;
+ }
+
vreg->last_set_uV = vreg->uV;
vreg->last_set_vlevel = vreg->vlevel;
@@ -254,6 +311,51 @@
return rc;
}
+static int qpnp_fts2_init_mode(struct spm_vreg *vreg)
+{
+ int rc;
+
+ rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
+ vreg->spmi_base_addr + QPNP_FTS2_REG_MODE, &vreg->init_mode, 1);
+ if (rc)
+ dev_err(&vreg->spmi_dev->dev, "%s: could not read mode register, rc=%d\n",
+ __func__, rc);
+
+ return rc;
+}
+
+static int qpnp_fts2_init_step_rate(struct spm_vreg *vreg)
+{
+ int rc;
+ u8 reg = 0;
+ int step, delay;
+
+ rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
+ vreg->spmi_base_addr + QPNP_FTS2_REG_STEP_CTRL, ®, 1);
+ if (rc) {
+ dev_err(&vreg->spmi_dev->dev, "%s: could not read stepping control register, rc=%d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ step = (reg & QPNP_FTS2_STEP_CTRL_STEP_MASK)
+ >> QPNP_FTS2_STEP_CTRL_STEP_SHIFT;
+ delay = (reg & QPNP_FTS2_STEP_CTRL_DELAY_MASK)
+ >> QPNP_FTS2_STEP_CTRL_DELAY_SHIFT;
+
+ /* step_rate has units of uV/us. */
+ vreg->step_rate = QPNP_FTS2_CLOCK_RATE * vreg->range->step_uV
+ * (1 << step);
+ vreg->step_rate /= 1000 * (8 << delay);
+ vreg->step_rate = vreg->step_rate * QPNP_FTS2_STEP_MARGIN_NUM
+ / QPNP_FTS2_STEP_MARGIN_DEN;
+
+ /* Ensure that the stepping rate is greater than 0. */
+ vreg->step_rate = max(vreg->step_rate, 1);
+
+ return rc;
+}
+
static int __devinit spm_regulator_probe(struct spmi_device *spmi)
{
struct device_node *node = spmi->dev.of_node;
@@ -299,6 +401,14 @@
if (rc)
return rc;
+ rc = qpnp_fts2_init_mode(vreg);
+ if (rc)
+ return rc;
+
+ rc = qpnp_fts2_init_step_rate(vreg);
+ if (rc)
+ return rc;
+
init_data = of_get_regulator_init_data(&spmi->dev, node);
if (!init_data) {
dev_err(&spmi->dev, "%s: unable to allocate memory\n",
@@ -334,8 +444,12 @@
dev_set_drvdata(&spmi->dev, vreg);
- pr_info("name=%s, range=%d\n", vreg->rdesc.name,
- (vreg->range == &fts2_range0) ? 0 : 1);
+ pr_info("name=%s, range=%s, voltage=%d uV, mode=%s, step rate=%d uV/us\n",
+ vreg->rdesc.name, vreg->range == &fts2_range0 ? "LV" : "MV",
+ vreg->uV,
+ vreg->init_mode & QPNP_FTS2_MODE_PWM ? "PWM" :
+ (vreg->init_mode & QPNP_FTS2_MODE_AUTO ? "AUTO" : "PFM"),
+ vreg->step_rate);
return rc;
}
diff --git a/block/blk-core.c b/block/blk-core.c
index 2b6595c..153240e 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1086,7 +1086,7 @@
* urgent requests. We want to be able to track this
* down.
*/
- pr_err("%s(): requeueing an URGENT request", __func__);
+ pr_debug("%s(): requeueing an URGENT request", __func__);
WARN_ON(!q->dispatched_urgent);
q->dispatched_urgent = false;
}
@@ -1123,7 +1123,7 @@
* urgent requests. We want to be able to track this
* down.
*/
- pr_err("%s(): reinserting an URGENT request", __func__);
+ pr_debug("%s(): reinserting an URGENT request", __func__);
WARN_ON(!q->dispatched_urgent);
q->dispatched_urgent = false;
}
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 51578e0..e98fff2 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -26,10 +26,13 @@
#include <linux/msm_ion.h>
#include <mach/msm_smd.h>
#include <mach/ion.h>
+#include <mach/iommu_domains.h>
#include <linux/scatterlist.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/iommu.h>
#ifndef ION_ADSPRPC_HEAP_ID
#define ION_ADSPRPC_HEAP_ID ION_AUDIO_HEAP_ID
@@ -53,6 +56,8 @@
} while (0)
+#define IS_CACHE_ALIGNED(x) (((x) & ((L1_CACHE_BYTES)-1)) == 0)
+
static inline uint32_t buf_page_start(void *buf)
{
uint32_t start = (uint32_t) buf & PAGE_MASK;
@@ -84,8 +89,9 @@
{
struct vm_area_struct *vma;
uint32_t start = buf_page_start(addr);
+ uint32_t end = buf_page_start((void *)((uint32_t)addr + sz - 1));
uint32_t len = nr_pages << PAGE_SHIFT;
- unsigned long pfn;
+ unsigned long pfn, pfnend;
int n = -1, err = 0;
VERIFY(err, 0 != access_ok(access ? VERIFY_WRITE : VERIFY_READ,
@@ -102,6 +108,12 @@
VERIFY(err, 0 == follow_pfn(vma, start, &pfn));
if (err)
goto bail;
+ VERIFY(err, 0 == follow_pfn(vma, end, &pfnend));
+ if (err)
+ goto bail;
+ VERIFY(err, (pfn + nr_pages - 1) == pfnend);
+ if (err)
+ goto bail;
VERIFY(err, nr_elems > 0);
if (err)
goto bail;
@@ -124,6 +136,13 @@
int last;
};
+struct fastrpc_smmu {
+ struct iommu_group *group;
+ struct iommu_domain *domain;
+ int domain_id;
+ bool enabled;
+};
+
struct fastrpc_apps {
smd_channel_t *chan;
struct smq_context_list clst;
@@ -132,6 +151,7 @@
struct cdev cdev;
struct class *class;
struct device *dev;
+ struct fastrpc_smmu smmu;
dev_t dev_no;
spinlock_t wrlock;
spinlock_t hlock;
@@ -172,7 +192,12 @@
{
struct fastrpc_apps *me = &gfa;
- if (buf->handle) {
+ if (!IS_ERR_OR_NULL(buf->handle)) {
+ if (me->smmu.enabled && buf->phys) {
+ ion_unmap_iommu(me->iclient, buf->handle,
+ me->smmu.domain_id, 0);
+ buf->phys = 0;
+ }
if (buf->virt) {
ion_unmap_kernel(me->iclient, buf->handle);
buf->virt = 0;
@@ -185,7 +210,7 @@
static void free_map(struct fastrpc_mmap *map)
{
struct fastrpc_apps *me = &gfa;
- if (map->handle) {
+ if (!IS_ERR_OR_NULL(map->handle)) {
if (map->virt) {
ion_unmap_kernel(me->iclient, map->handle);
map->virt = 0;
@@ -197,26 +222,39 @@
static int alloc_mem(struct fastrpc_buf *buf)
{
+ struct fastrpc_apps *me = &gfa;
struct ion_client *clnt = gfa.iclient;
struct sg_table *sg;
int err = 0;
+ unsigned int heap;
+ unsigned long len;
buf->handle = 0;
buf->virt = 0;
- buf->handle = ion_alloc(clnt, buf->size, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID), 0);
+ heap = me->smmu.enabled ? ION_HEAP(ION_IOMMU_HEAP_ID) :
+ ION_HEAP(ION_ADSP_HEAP_ID) | ION_HEAP(ION_AUDIO_HEAP_ID);
+ buf->handle = ion_alloc(clnt, buf->size, SZ_4K, heap, 0);
VERIFY(err, 0 == IS_ERR_OR_NULL(buf->handle));
if (err)
goto bail;
VERIFY(err, 0 != (buf->virt = ion_map_kernel(clnt, buf->handle)));
if (err)
goto bail;
- VERIFY(err, 0 != (sg = ion_sg_table(clnt, buf->handle)));
- if (err)
- goto bail;
- VERIFY(err, 1 == sg->nents);
- if (err)
- goto bail;
- buf->phys = sg_dma_address(sg->sgl);
+ if (me->smmu.enabled) {
+ len = buf->size;
+ VERIFY(err, 0 == ion_map_iommu(clnt, buf->handle,
+ me->smmu.domain_id, 0, SZ_4K, 0,
+ &buf->phys, &len, 0, 0));
+ if (err)
+ goto bail;
+ } else {
+ VERIFY(err, 0 != (sg = ion_sg_table(clnt, buf->handle)));
+ if (err)
+ goto bail;
+ VERIFY(err, 1 == sg->nents);
+ if (err)
+ goto bail;
+ buf->phys = sg_dma_address(sg->sgl);
+ }
bail:
if (err && !IS_ERR_OR_NULL(buf->handle))
free_mem(buf);
@@ -481,6 +519,28 @@
return err;
}
+static void inv_args_pre(uint32_t sc, remote_arg_t *rpra)
+{
+ int i, inbufs, outbufs;
+ uint32_t end;
+
+ inbufs = REMOTE_SCALARS_INBUFS(sc);
+ outbufs = REMOTE_SCALARS_OUTBUFS(sc);
+ for (i = inbufs; i < inbufs + outbufs; ++i) {
+ if (!rpra[i].buf.len)
+ continue;
+ if (buf_page_start(rpra) == buf_page_start(rpra[i].buf.pv))
+ continue;
+ if (!IS_CACHE_ALIGNED((uint32_t)rpra[i].buf.pv))
+ dmac_flush_range(rpra[i].buf.pv,
+ (char *)rpra[i].buf.pv + 1);
+ end = (uint32_t)rpra[i].buf.pv + rpra[i].buf.len;
+ if (!IS_CACHE_ALIGNED(end))
+ dmac_flush_range((char *)end,
+ (char *)end + 1);
+ }
+}
+
static void inv_args(uint32_t sc, remote_arg_t *rpra, int used)
{
int i, inbufs, outbufs;
@@ -572,6 +632,8 @@
{
int err = 0;
struct fastrpc_apps *me = &gfa;
+ struct device_node *node;
+ bool enabled = 0;
if (me->chan == 0) {
int i;
@@ -588,6 +650,22 @@
VERIFY(err, 0 == IS_ERR_OR_NULL(me->iclient));
if (err)
goto ion_bail;
+ node = of_find_compatible_node(NULL, NULL,
+ "qcom,msm-audio-ion");
+ if (node)
+ enabled = of_property_read_bool(node,
+ "qcom,smmu-enabled");
+ if (enabled)
+ me->smmu.group = iommu_group_find("lpass_audio");
+ if (me->smmu.group)
+ me->smmu.domain = iommu_group_get_iommudata(
+ me->smmu.group);
+ if (!IS_ERR_OR_NULL(me->smmu.domain)) {
+ me->smmu.domain_id = msm_find_domain_no(
+ me->smmu.domain);
+ if (me->smmu.domain_id >= 0)
+ me->smmu.enabled = enabled;
+ }
VERIFY(err, 0 == smd_named_open_on_edge(FASTRPC_SMD_GUID,
SMD_APPS_QDSP, &me->chan,
me, smd_event_handler));
@@ -704,6 +782,12 @@
sc = invoke->sc;
obuf.handle = 0;
+ if (me->smmu.enabled) {
+ VERIFY(err, 0 == iommu_attach_group(me->smmu.domain,
+ me->smmu.group));
+ if (err)
+ return err;
+ }
if (REMOTE_SCALARS_LENGTH(sc)) {
VERIFY(err, 0 == get_dev(me, &dev));
if (err)
@@ -720,6 +804,7 @@
}
context_list_alloc_ctx(&me->clst, &ctx);
+ inv_args_pre(sc, rpra);
VERIFY(err, 0 == fastrpc_invoke_send(me, kernel, invoke->handle, sc,
ctx, &obuf));
if (err)
@@ -743,6 +828,8 @@
}
context_free(ctx);
+ if (me->smmu.enabled)
+ iommu_detach_group(me->smmu.domain, me->smmu.group);
for (i = 0, b = abufs; i < nbufs; ++i, ++b)
free_mem(b);
@@ -1093,6 +1180,7 @@
struct fastrpc_apps *me = &gfa;
int err = 0;
+ memset(me, 0, sizeof(*me));
VERIFY(err, 0 == fastrpc_init());
if (err)
goto fastrpc_bail;
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index f76d41a..9c2c8b1 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -689,9 +689,15 @@
int len, int type)
{
driver->pkt_length = len;
- if (entry.process_id != NON_APPS_PROC && type != MODEM_DATA) {
- diag_update_pkt_buffer(buf);
- diag_update_sleeping_process(entry.process_id, PKT_TYPE);
+
+ /* If the process_id corresponds to an apps process */
+ if (entry.process_id != NON_APPS_PROC) {
+ /* If the message is to be sent to the apps process */
+ if (type != MODEM_DATA) {
+ diag_update_pkt_buffer(buf);
+ diag_update_sleeping_process(entry.process_id,
+ PKT_TYPE);
+ }
} else {
if (len > 0) {
if (entry.client_id < NUM_SMD_DATA_CHANNELS) {
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index a506aa8..7b01432 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -4,6 +4,7 @@
* Copyright (C) 2001 Russell King
* (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
* Jun Nakajima <jun.nakajima@intel.com>
+ * (c) 2013 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -124,6 +125,14 @@
static DEFINE_PER_CPU(struct dbs_work_struct, dbs_refresh_work);
+struct dbs_sync_work_struct {
+ struct work_struct work;
+ unsigned int src_cpu;
+ unsigned int targ_cpu;
+};
+
+static DEFINE_PER_CPU(struct dbs_sync_work_struct, dbs_sync_work);
+
static struct dbs_tuners {
unsigned int sampling_rate;
unsigned int up_threshold;
@@ -1020,6 +1029,92 @@
return;
}
+static int dbs_migration_notify(struct notifier_block *nb,
+ unsigned long target_cpu, void *arg)
+{
+ struct dbs_sync_work_struct *sync_work =
+ &per_cpu(dbs_sync_work, target_cpu);
+ sync_work->src_cpu = (unsigned int)arg;
+
+ queue_work_on(target_cpu, input_wq,
+ &per_cpu(dbs_sync_work, target_cpu).work);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block dbs_migration_nb = {
+ .notifier_call = dbs_migration_notify,
+};
+
+void dbs_synchronize(struct work_struct *work)
+{
+ struct cpufreq_policy *policy;
+ struct cpu_dbs_info_s *this_dbs_info, *src_dbs_info;
+ struct dbs_sync_work_struct *dbs_work;
+ unsigned int cpu, src_cpu;
+ unsigned int src_freq, src_max_load;
+ int delay;
+
+ dbs_work = container_of(work, struct dbs_sync_work_struct, work);
+ cpu = dbs_work->targ_cpu;
+ src_cpu = dbs_work->src_cpu;
+
+ get_online_cpus();
+
+ /* Getting source cpu info */
+ src_dbs_info = &per_cpu(od_cpu_dbs_info, src_cpu);
+ if (src_dbs_info != NULL && src_dbs_info->cur_policy != NULL) {
+ src_freq = src_dbs_info->cur_policy->cur;
+ src_max_load = src_dbs_info->max_load;
+ } else {
+ src_freq = dbs_tuners_ins.sync_freq;
+ src_max_load = 0;
+ }
+
+ if (lock_policy_rwsem_write(cpu) < 0)
+ goto bail_acq_sema_failed;
+
+ this_dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
+ policy = this_dbs_info->cur_policy;
+ if (!policy) {
+ /* CPU not using ondemand governor */
+ goto bail_incorrect_governor;
+ }
+
+ delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+
+ if (policy->cur < src_freq) {
+
+ /* Cancelling the next ondemand sample */
+ cancel_delayed_work_sync(&this_dbs_info->work);
+
+ /*
+ * Arch specific cpufreq driver may fail.
+ * Don't update governor frequency upon failure.
+ */
+ if (__cpufreq_driver_target(policy, src_freq,
+ CPUFREQ_RELATION_L) >= 0) {
+ policy->cur = src_freq;
+ if (src_max_load > this_dbs_info->max_load) {
+ this_dbs_info->max_load = src_max_load;
+ this_dbs_info->prev_load = src_max_load;
+ }
+ }
+
+ /* Rescheduling the next ondemand sample */
+ mutex_lock(&this_dbs_info->timer_mutex);
+ schedule_delayed_work_on(cpu, &this_dbs_info->work,
+ delay);
+ mutex_unlock(&this_dbs_info->timer_mutex);
+ }
+bail_incorrect_governor:
+ unlock_policy_rwsem_write(cpu);
+
+bail_acq_sema_failed:
+ put_online_cpus();
+ return;
+}
+
static void dbs_input_event(struct input_handle *handle, unsigned int type,
unsigned int code, int value)
{
@@ -1148,6 +1243,9 @@
if (dbs_tuners_ins.sync_freq == 0)
dbs_tuners_ins.sync_freq = policy->min;
+
+ atomic_notifier_chain_register(&migration_notifier_head,
+ &dbs_migration_nb);
}
if (!cpu)
rc = input_register_handler(&dbs_input_handler);
@@ -1171,9 +1269,14 @@
this_dbs_info->cur_policy = NULL;
if (!cpu)
input_unregister_handler(&dbs_input_handler);
- if (!dbs_enable)
+ if (!dbs_enable) {
sysfs_remove_group(cpufreq_global_kobject,
&dbs_attr_group);
+ atomic_notifier_chain_unregister(
+ &migration_notifier_head,
+ &dbs_migration_nb);
+ }
+
mutex_unlock(&dbs_mutex);
break;
@@ -1232,10 +1335,17 @@
&per_cpu(od_cpu_dbs_info, i);
struct dbs_work_struct *dbs_work =
&per_cpu(dbs_refresh_work, i);
+ struct dbs_sync_work_struct *dbs_sync =
+ &per_cpu(dbs_sync_work, i);
mutex_init(&this_dbs_info->timer_mutex);
INIT_WORK(&dbs_work->work, dbs_refresh_callback);
dbs_work->cpu = i;
+
+ INIT_WORK(&dbs_sync->work, dbs_synchronize);
+ dbs_sync->src_cpu = 0;
+ dbs_sync->targ_cpu = i;
+
}
return cpufreq_register_governor(&cpufreq_gov_ondemand);
diff --git a/drivers/crypto/msm/qce.h b/drivers/crypto/msm/qce.h
index 51a74b6..cf75e93 100644
--- a/drivers/crypto/msm/qce.h
+++ b/drivers/crypto/msm/qce.h
@@ -32,6 +32,8 @@
#define SHA256_DIGESTSIZE 32
#define SHA1_DIGESTSIZE 20
+#define AES_CE_BLOCK_SIZE 16
+
/* key size in bytes */
#define HMAC_KEY_SIZE (SHA1_DIGESTSIZE) /* hmac-sha1 */
#define SHA_HMAC_KEY_SIZE 64
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index a09bb42..9870648 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1650,6 +1650,10 @@
__func__);
goto error;
}
+ if (req->byteoffset >= AES_CE_BLOCK_SIZE) {
+ pr_err("%s: Invalid byte offset\n", __func__);
+ goto error;
+ }
}
/* Ensure zer ivlen for ECB mode */
if (req->ivlen > 0) {
diff --git a/drivers/gpu/ion/ion_cma_heap.c b/drivers/gpu/ion/ion_cma_heap.c
index 193f4d4..e7f7836 100644
--- a/drivers/gpu/ion/ion_cma_heap.c
+++ b/drivers/gpu/ion/ion_cma_heap.c
@@ -115,6 +115,7 @@
dev_dbg(dev, "Release buffer %p\n", buffer);
/* release memory */
dma_free_coherent(dev, buffer->size, info->cpu_addr, info->handle);
+ sg_free_table(info->table);
/* release sg table */
kfree(info->table);
kfree(info);
diff --git a/drivers/gpu/ion/ion_cma_secure_heap.c b/drivers/gpu/ion/ion_cma_secure_heap.c
index e1b3eea..b3960b2 100644
--- a/drivers/gpu/ion/ion_cma_secure_heap.c
+++ b/drivers/gpu/ion/ion_cma_secure_heap.c
@@ -154,6 +154,7 @@
dev_dbg(dev, "Release buffer %p\n", buffer);
/* release memory */
dma_free_coherent(dev, buffer->size, info->cpu_addr, info->handle);
+ sg_free_table(info->table);
/* release sg table */
kfree(info->table);
kfree(info);
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index bc9bddd..b1c1c5d 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -42,6 +42,7 @@
*/
struct ion_iommu_priv_data {
struct page **pages;
+ unsigned int pages_uses_vmalloc;
int nrpages;
unsigned long size;
};
@@ -118,6 +119,7 @@
unsigned int npages_to_vmap, total_pages, num_large_pages = 0;
unsigned long size_remaining = PAGE_ALIGN(size);
unsigned int max_order = ION_IS_CACHED(flags) ? 0 : orders[0];
+ unsigned int page_tbl_size;
data = kmalloc(sizeof(*data), GFP_KERNEL);
if (!data)
@@ -139,8 +141,24 @@
data->size = PFN_ALIGN(size);
data->nrpages = data->size >> PAGE_SHIFT;
- data->pages = kzalloc(sizeof(struct page *)*data->nrpages,
- GFP_KERNEL);
+ data->pages_uses_vmalloc = 0;
+ page_tbl_size = sizeof(struct page *) * data->nrpages;
+
+ if (page_tbl_size > SZ_8K) {
+ /*
+ * Do fallback to ensure we have a balance between
+ * performance and availability.
+ */
+ data->pages = kmalloc(page_tbl_size,
+ __GFP_COMP | __GFP_NORETRY |
+ __GFP_NO_KSWAPD | __GFP_NOWARN);
+ if (!data->pages) {
+ data->pages = vmalloc(page_tbl_size);
+ data->pages_uses_vmalloc = 1;
+ }
+ } else {
+ data->pages = kmalloc(page_tbl_size, GFP_KERNEL);
+ }
if (!data->pages) {
ret = -ENOMEM;
goto err_free_data;
@@ -222,7 +240,10 @@
kfree(buffer->sg_table);
buffer->sg_table = 0;
err1:
- kfree(data->pages);
+ if (data->pages_uses_vmalloc)
+ vfree(data->pages);
+ else
+ kfree(data->pages);
err_free_data:
kfree(data);
@@ -253,7 +274,10 @@
sg_free_table(table);
kfree(table);
table = 0;
- kfree(data->pages);
+ if (data->pages_uses_vmalloc)
+ vfree(data->pages);
+ else
+ kfree(data->pages);
kfree(data);
}
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index 3441afa..fc66328 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -25,6 +25,7 @@
adreno_drawctxt.o \
adreno_postmortem.o \
adreno_snapshot.o \
+ adreno_coresight.o \
adreno_a2xx.o \
adreno_a2xx_trace.o \
adreno_a2xx_snapshot.o \
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 5f435f3..0c398c4 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -165,8 +165,16 @@
#define A3XX_RBBM_PERFCTR_PWR_0_HI 0x0EB
#define A3XX_RBBM_PERFCTR_PWR_1_LO 0x0EC
#define A3XX_RBBM_PERFCTR_PWR_1_HI 0x0ED
-#define A3XX_RBBM_DEBUG_BUS_CTL 0x111
-#define A3XX_RBBM_DEBUG_BUS_DATA_STATUS 0x112
+#define A3XX_RBBM_DEBUG_BUS_CTL 0x111
+#define A3XX_RBBM_DEBUG_BUS_DATA_STATUS 0x112
+#define A3XX_RBBM_DEBUG_BUS_STB_CTL0 0x11B
+#define A3XX_RBBM_DEBUG_BUS_STB_CTL1 0x11C
+#define A3XX_RBBM_INT_TRACE_BUS_CTL 0x11D
+#define A3XX_RBBM_EXT_TRACE_BUS_CTL 0x11E
+#define A3XX_RBBM_EXT_TRACE_STOP_CNT 0x11F
+#define A3XX_RBBM_EXT_TRACE_START_CNT 0x120
+#define A3XX_RBBM_EXT_TRACE_PERIOD_CNT 0x121
+#define A3XX_RBBM_EXT_TRACE_CMD 0x122
/* Following two are same as on A2XX, just in a different place */
#define A3XX_CP_PFP_UCODE_ADDR 0x1C9
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index a4f60f9..aad2882 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -18,6 +18,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/delay.h>
+#include <linux/of_coresight.h>
#include <mach/socinfo.h>
#include <mach/msm_bus_board.h>
@@ -1522,6 +1523,9 @@
if (ret)
goto err;
+ pdata->coresight_pdata = of_get_coresight_platform_data(&pdev->dev,
+ pdev->dev.of_node);
+
pdev->dev.platform_data = pdata;
return 0;
@@ -1595,6 +1599,7 @@
adreno_probe(struct platform_device *pdev)
{
struct kgsl_device *device;
+ struct kgsl_device_platform_data *pdata = NULL;
struct adreno_device *adreno_dev;
int status = -EINVAL;
bool is_dt;
@@ -1625,6 +1630,10 @@
kgsl_pwrscale_attach_policy(device, ADRENO_DEFAULT_PWRSCALE_POLICY);
device->flags &= ~KGSL_FLAGS_SOFT_RESET;
+ pdata = kgsl_device_get_drvdata(device);
+
+ adreno_coresight_init(pdev);
+
return 0;
error_close_rb:
@@ -1643,6 +1652,8 @@
device = (struct kgsl_device *)pdev->id_entry->driver_data;
adreno_dev = ADRENO_DEVICE(device);
+ adreno_coresight_remove(pdev);
+
kgsl_pwrscale_detach_policy(device);
kgsl_pwrscale_close(device);
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index fa892b9..77b654b 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -80,6 +80,15 @@
ADRENO_REV_A305B = 335,
};
+enum coresight_debug_reg {
+ DEBUG_BUS_CTL,
+ TRACE_STOP_CNT,
+ TRACE_START_CNT,
+ TRACE_PERIOD_CNT,
+ TRACE_CMD,
+ TRACE_BUS_CTL,
+};
+
struct adreno_gpudev;
struct adreno_device {
@@ -187,6 +196,10 @@
uint64_t (*perfcounter_read)(struct adreno_device *adreno_dev,
unsigned int group, unsigned int counter,
unsigned int offset);
+ int (*coresight_enable) (struct kgsl_device *device);
+ void (*coresight_disable) (struct kgsl_device *device);
+ void (*coresight_config_debug_reg) (struct kgsl_device *device,
+ int debug_reg, unsigned int val);
};
/*
@@ -269,6 +282,10 @@
extern unsigned int ft_detect_regs[];
extern const unsigned int ft_detect_regs_count;
+int adreno_coresight_enable(struct coresight_device *csdev);
+void adreno_coresight_disable(struct coresight_device *csdev);
+void adreno_coresight_remove(struct platform_device *pdev);
+int adreno_coresight_init(struct platform_device *pdev);
int adreno_idle(struct kgsl_device *device);
void adreno_regread(struct kgsl_device *device, unsigned int offsetwords,
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index a4b3121..1cdc87a 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -3235,6 +3235,108 @@
adreno_dev->gpu_cycles = 0;
}
+/**
+ * a3xx_coresight_enable() - Enables debugging through coresight
+ * debug bus for adreno a3xx devices.
+ * @device: Pointer to GPU device structure
+ */
+int a3xx_coresight_enable(struct kgsl_device *device)
+{
+ mutex_lock(&device->mutex);
+ if (!kgsl_active_count_get(device)) {
+ adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_CTL, 0x0001093F);
+ adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_STB_CTL0,
+ 0x00000000);
+ adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_STB_CTL1,
+ 0xFFFFFFFE);
+ adreno_regwrite(device, A3XX_RBBM_INT_TRACE_BUS_CTL,
+ 0x00201111);
+ adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_BUS_CTL,
+ 0x89100010);
+ adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_STOP_CNT,
+ 0x00017fff);
+ adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_START_CNT,
+ 0x0001000f);
+ adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_PERIOD_CNT ,
+ 0x0001ffff);
+ adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_CMD,
+ 0x00000001);
+ kgsl_active_count_put(device);
+ }
+ mutex_unlock(&device->mutex);
+ return 0;
+}
+
+/**
+ * a3xx_coresight_disable() - Disables debugging through coresight
+ * debug bus for adreno a3xx devices.
+ * @device: Pointer to GPU device structure
+ */
+void a3xx_coresight_disable(struct kgsl_device *device)
+{
+ mutex_lock(&device->mutex);
+ if (!kgsl_active_count_get(device)) {
+ adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_CTL, 0x0);
+ adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_STB_CTL0, 0x0);
+ adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_STB_CTL1, 0x0);
+ adreno_regwrite(device, A3XX_RBBM_INT_TRACE_BUS_CTL, 0x0);
+ adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_BUS_CTL, 0x0);
+ adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_STOP_CNT, 0x0);
+ adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_START_CNT, 0x0);
+ adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_PERIOD_CNT , 0x0);
+ adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_CMD, 0x0);
+ kgsl_active_count_put(device);
+ }
+ mutex_unlock(&device->mutex);
+}
+
+static void a3xx_coresight_write_reg(struct kgsl_device *device,
+ unsigned int wordoffset, unsigned int val)
+{
+ mutex_lock(&device->mutex);
+ if (!kgsl_active_count_get(device)) {
+ adreno_regwrite(device, wordoffset, val);
+ kgsl_active_count_put(device);
+ }
+ mutex_unlock(&device->mutex);
+}
+
+void a3xx_coresight_config_debug_reg(struct kgsl_device *device,
+ int debug_reg, unsigned int val)
+{
+ switch (debug_reg) {
+
+ case DEBUG_BUS_CTL:
+ a3xx_coresight_write_reg(device, A3XX_RBBM_DEBUG_BUS_CTL, val);
+ break;
+
+ case TRACE_STOP_CNT:
+ a3xx_coresight_write_reg(device, A3XX_RBBM_EXT_TRACE_STOP_CNT,
+ val);
+ break;
+
+ case TRACE_START_CNT:
+ a3xx_coresight_write_reg(device, A3XX_RBBM_EXT_TRACE_START_CNT,
+ val);
+ break;
+
+ case TRACE_PERIOD_CNT:
+ a3xx_coresight_write_reg(device, A3XX_RBBM_EXT_TRACE_PERIOD_CNT,
+ val);
+ break;
+
+ case TRACE_CMD:
+ a3xx_coresight_write_reg(device, A3XX_RBBM_EXT_TRACE_CMD, val);
+ break;
+
+ case TRACE_BUS_CTL:
+ a3xx_coresight_write_reg(device, A3XX_RBBM_EXT_TRACE_BUS_CTL,
+ val);
+ break;
+ }
+
+}
+
/*
* Define the available perfcounter groups - these get used by
* adreno_perfcounter_get and adreno_perfcounter_put
@@ -3381,4 +3483,7 @@
.snapshot = a3xx_snapshot,
.perfcounter_enable = a3xx_perfcounter_enable,
.perfcounter_read = a3xx_perfcounter_read,
+ .coresight_enable = a3xx_coresight_enable,
+ .coresight_disable = a3xx_coresight_disable,
+ .coresight_config_debug_reg = a3xx_coresight_config_debug_reg,
};
diff --git a/drivers/gpu/msm/adreno_coresight.c b/drivers/gpu/msm/adreno_coresight.c
new file mode 100644
index 0000000..e18568d
--- /dev/null
+++ b/drivers/gpu/msm/adreno_coresight.c
@@ -0,0 +1,219 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/of_coresight.h>
+#include <linux/coresight.h>
+#include <linux/memory_alloc.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include "kgsl.h"
+#include "kgsl_device.h"
+#include "adreno.h"
+
+struct coresight_attr {
+ struct device_attribute attr;
+ int regname;
+};
+
+#define CORESIGHT_CREATE_REG_ATTR(_attrname, _regname) \
+ struct coresight_attr coresight_attr_##_attrname = \
+ { __ATTR(_attrname, S_IRUGO | S_IWUSR, gfx_show_reg, gfx_store_reg),\
+ _regname}
+
+/**
+ * adreno_coresight_enable() - Generic function to enable coresight debugging
+ * @csdev: Pointer to coresight's device struct
+ *
+ * This is a generic function to enable coresight debug bus on adreno
+ * devices. This should be used in all cases of enabling
+ * coresight debug bus for adreno devices. This function in turn calls
+ * the adreno device specific function through gpudev hook.
+ * This function is registered as the coresight enable function
+ * with coresight driver. It should only be called through coresight driver
+ * as that would ensure that the necessary setup required to be done
+ * on coresight driver's part is also done.
+ */
+int adreno_coresight_enable(struct coresight_device *csdev)
+{
+ struct kgsl_device *device = dev_get_drvdata(csdev->dev.parent);
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+ /* Check if coresight compatible device, return error otherwise */
+ if (adreno_dev->gpudev->coresight_enable)
+ return adreno_dev->gpudev->coresight_enable(device);
+ else
+ return -ENODEV;
+}
+
+/**
+ * adreno_coresight_disable() - Generic function to disable coresight debugging
+ * @csdev: Pointer to coresight's device struct
+ *
+ * This is a generic function to disable coresight debug bus on adreno
+ * devices. This should be used in all cases of disabling
+ * coresight debug bus for adreno devices. This function in turn calls
+ * the adreno device specific function through the gpudev hook.
+ * This function is registered as the coresight disable function
+ * with coresight driver. It should only be called through coresight driver
+ * as that would ensure that the necessary setup required to be done on
+ * coresight driver's part is also done.
+ */
+void adreno_coresight_disable(struct coresight_device *csdev)
+{
+ struct kgsl_device *device = dev_get_drvdata(csdev->dev.parent);
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+ /* Check if coresight compatible device, bail otherwise */
+ if (adreno_dev->gpudev->coresight_disable)
+ return adreno_dev->gpudev->coresight_disable(device);
+}
+
+static const struct coresight_ops_source adreno_coresight_ops_source = {
+ .enable = adreno_coresight_enable,
+ .disable = adreno_coresight_disable,
+};
+
+static const struct coresight_ops adreno_coresight_cs_ops = {
+ .source_ops = &adreno_coresight_ops_source,
+};
+
+void adreno_coresight_remove(struct platform_device *pdev)
+{
+ struct kgsl_device_platform_data *pdata = pdev->dev.platform_data;
+ coresight_unregister(pdata->csdev);
+}
+
+static ssize_t coresight_read_reg(struct kgsl_device *device,
+ unsigned int offset, char *buf)
+{
+ unsigned int regval = 0;
+
+ mutex_lock(&device->mutex);
+ if (!kgsl_active_count_get(device)) {
+ adreno_regread(device, offset, ®val);
+ kgsl_active_count_put(device);
+ }
+ mutex_unlock(&device->mutex);
+ return snprintf(buf, PAGE_SIZE, "0x%X", regval);
+}
+
+static inline unsigned int coresight_convert_reg(const char *buf)
+{
+ long regval = 0;
+ int rv = 0;
+
+ rv = kstrtoul(buf, 16, ®val);
+ if (!rv)
+ return (unsigned int)regval;
+ else
+ return rv;
+}
+
+static ssize_t gfx_show_reg(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct kgsl_device *device = dev_get_drvdata(dev->parent);
+ struct coresight_attr *csight_attr = container_of(attr,
+ struct coresight_attr, attr);
+ return coresight_read_reg(device, csight_attr->regname, buf);
+}
+
+static ssize_t gfx_store_reg(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct kgsl_device *device = dev_get_drvdata(dev->parent);
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct coresight_attr *csight_attr = container_of(attr,
+ struct coresight_attr, attr);
+ unsigned int regval = 0;
+
+ regval = coresight_convert_reg(buf);
+
+ if (adreno_dev->gpudev->coresight_config_debug_reg)
+ adreno_dev->gpudev->coresight_config_debug_reg(device,
+ csight_attr->regname, regval);
+ return size;
+}
+
+CORESIGHT_CREATE_REG_ATTR(config_debug_bus, DEBUG_BUS_CTL);
+CORESIGHT_CREATE_REG_ATTR(config_trace_stop_cnt, TRACE_STOP_CNT);
+CORESIGHT_CREATE_REG_ATTR(config_trace_start_cnt, TRACE_START_CNT);
+CORESIGHT_CREATE_REG_ATTR(config_trace_period_cnt, TRACE_PERIOD_CNT);
+CORESIGHT_CREATE_REG_ATTR(config_trace_cmd, TRACE_CMD);
+CORESIGHT_CREATE_REG_ATTR(config_trace_bus_ctl, TRACE_BUS_CTL);
+
+static struct attribute *gfx_attrs[] = {
+ &coresight_attr_config_debug_bus.attr.attr,
+ &coresight_attr_config_trace_start_cnt.attr.attr,
+ &coresight_attr_config_trace_stop_cnt.attr.attr,
+ &coresight_attr_config_trace_period_cnt.attr.attr,
+ &coresight_attr_config_trace_cmd.attr.attr,
+ &coresight_attr_config_trace_bus_ctl.attr.attr,
+ NULL,
+};
+
+static struct attribute_group gfx_attr_grp = {
+ .attrs = gfx_attrs,
+};
+
+static const struct attribute_group *gfx_attr_grps[] = {
+ &gfx_attr_grp,
+ NULL,
+};
+
+int adreno_coresight_init(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct kgsl_device_platform_data *pdata = pdev->dev.platform_data;
+ struct device *dev = &pdev->dev;
+ struct coresight_desc *desc;
+
+ if (IS_ERR_OR_NULL(pdata->coresight_pdata))
+ return -ENODATA;
+
+
+ desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+
+ desc->type = CORESIGHT_DEV_TYPE_SOURCE;
+ desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_BUS;
+ desc->ops = &adreno_coresight_cs_ops;
+ desc->pdata = pdata->coresight_pdata;
+ desc->dev = &pdev->dev;
+ desc->owner = THIS_MODULE;
+ desc->groups = gfx_attr_grps;
+ pdata->csdev = coresight_register(desc);
+ if (IS_ERR(pdata->csdev)) {
+ ret = PTR_ERR(pdata->csdev);
+ goto err;
+ }
+
+ return 0;
+
+err:
+ devm_kfree(dev, desc);
+ return ret;
+}
+
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index b9bc432..4071b37 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -598,7 +598,7 @@
gfp_mask |= __GFP_COMP | __GFP_NORETRY |
__GFP_NO_KSWAPD | __GFP_NOWARN;
else
- gfp_mask |= GFP_KERNEL | __GFP_NORETRY;
+ gfp_mask |= GFP_KERNEL;
page = alloc_pages(gfp_mask, get_order(page_size));
diff --git a/drivers/iommu/msm_iommu-v0.c b/drivers/iommu/msm_iommu-v0.c
index 06f4a0f..10fa5b1 100644
--- a/drivers/iommu/msm_iommu-v0.c
+++ b/drivers/iommu/msm_iommu-v0.c
@@ -32,6 +32,7 @@
#include <mach/msm_iommu_priv.h>
#include <mach/iommu.h>
#include <mach/msm_smem.h>
+#include <mach/msm_bus.h>
#define MRC(reg, processor, op1, crn, crm, op2) \
__asm__ __volatile__ ( \
@@ -135,6 +136,20 @@
return msm_iommu_remote_lock.lock;
}
+static int apply_bus_vote(struct msm_iommu_drvdata *drvdata, unsigned int vote)
+{
+ int ret = 0;
+
+ if (drvdata->bus_client) {
+ ret = msm_bus_scale_client_update_request(drvdata->bus_client,
+ vote);
+ if (ret)
+ pr_err("%s: Failed to vote for bus: %d\n", __func__,
+ vote);
+ }
+ return ret;
+}
+
static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
{
int ret;
@@ -202,6 +217,7 @@
struct iommu_access_ops iommu_access_ops_v0 = {
.iommu_power_on = __enable_regulators,
.iommu_power_off = __disable_regulators,
+ .iommu_bus_vote = apply_bus_vote,
.iommu_clk_on = __enable_clocks,
.iommu_clk_off = __disable_clocks,
.iommu_lock_initialize = _iommu_lock_initialize,
@@ -506,6 +522,11 @@
goto unlock;
}
+ ret = apply_bus_vote(iommu_drvdata, 1);
+
+ if (ret)
+ goto unlock;
+
ret = __enable_clocks(iommu_drvdata);
if (ret)
goto unlock;
@@ -572,6 +593,9 @@
msm_iommu_remote_spin_unlock();
__disable_clocks(iommu_drvdata);
+
+ apply_bus_vote(iommu_drvdata, 0);
+
list_del_init(&ctx_drvdata->attached_elm);
ctx_drvdata->attached_domain = NULL;
unlock:
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index 8e68beb..f90bf6c 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -32,6 +32,7 @@
#include <mach/iommu.h>
#include <mach/msm_iommu_priv.h>
#include <mach/iommu_perfmon.h>
+#include <mach/msm_bus.h>
#include "msm_iommu_pagetable.h"
/* bitmap of the page sizes currently supported */
@@ -62,6 +63,20 @@
regulator_disable(drvdata->gdsc);
}
+static int apply_bus_vote(struct msm_iommu_drvdata *drvdata, unsigned int vote)
+{
+ int ret = 0;
+
+ if (drvdata->bus_client) {
+ ret = msm_bus_scale_client_update_request(drvdata->bus_client,
+ vote);
+ if (ret)
+ pr_err("%s: Failed to vote for bus: %d\n", __func__,
+ vote);
+ }
+ return ret;
+}
+
static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
{
int ret;
@@ -116,6 +131,7 @@
struct iommu_access_ops iommu_access_ops_v1 = {
.iommu_power_on = __enable_regulators,
.iommu_power_off = __disable_regulators,
+ .iommu_bus_vote = apply_bus_vote,
.iommu_clk_on = __enable_clocks,
.iommu_clk_off = __disable_clocks,
.iommu_lock_acquire = _iommu_lock_acquire,
@@ -513,6 +529,10 @@
if (ret)
goto fail;
+ ret = apply_bus_vote(iommu_drvdata, 1);
+ if (ret)
+ goto fail;
+
ret = __enable_clocks(iommu_drvdata);
if (ret) {
__disable_regulators(iommu_drvdata);
@@ -602,6 +622,8 @@
__disable_clocks(iommu_drvdata);
+ apply_bus_vote(iommu_drvdata, 0);
+
__disable_regulators(iommu_drvdata);
list_del_init(&ctx_drvdata->attached_elm);
diff --git a/drivers/iommu/msm_iommu_dev-v0.c b/drivers/iommu/msm_iommu_dev-v0.c
index 059216e..4ee65d8 100644
--- a/drivers/iommu/msm_iommu_dev-v0.c
+++ b/drivers/iommu/msm_iommu_dev-v0.c
@@ -30,10 +30,13 @@
#include <mach/iommu_perfmon.h>
#include <mach/iommu_hw-v0.h>
#include <mach/iommu.h>
+#include <mach/msm_bus.h>
static DEFINE_MUTEX(iommu_list_lock);
static LIST_HEAD(iommu_list);
+static struct of_device_id msm_iommu_v0_ctx_match_table[];
+
void msm_iommu_add_drv(struct msm_iommu_drvdata *drv)
{
mutex_lock(&iommu_list_lock);
@@ -77,10 +80,13 @@
}
mutex_unlock(&iommu_list_lock);
- if (!dev || !dev_get_drvdata(dev))
- pr_err("Could not find context <%s>\n", ctx_name);
put_device(dev);
+ if (!dev || !dev_get_drvdata(dev)) {
+ pr_debug("Could not find context <%s>\n", ctx_name);
+ dev = ERR_PTR(-EPROBE_DEFER);
+ }
+
return dev;
}
EXPORT_SYMBOL(msm_iommu_get_ctx);
@@ -128,74 +134,24 @@
mb();
}
-static int msm_iommu_parse_dt(struct platform_device *pdev,
- struct msm_iommu_drvdata *drvdata,
- int *needs_alt_core_clk)
-{
-#ifdef CONFIG_OF_DEVICE
- struct device_node *child;
- struct resource *r;
- u32 glb_offset = 0;
- int ret;
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r) {
- pr_err("%s: Missing property reg\n", __func__);
- return -EINVAL;
- }
- drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
- if (!drvdata->base) {
- pr_err("%s: Unable to ioremap %pr\n", __func__, r);
- return -ENOMEM;
- }
- drvdata->glb_base = drvdata->base;
-
- if (!of_property_read_u32(pdev->dev.of_node, "qcom,glb-offset",
- &glb_offset)) {
- drvdata->glb_base += glb_offset;
- } else {
- pr_err("%s: Missing property qcom,glb-offset\n", __func__);
- return -EINVAL;
- }
-
- for_each_child_of_node(pdev->dev.of_node, child) {
- drvdata->ncb++;
- if (!of_platform_device_create(child, NULL, &pdev->dev))
- pr_err("Failed to create %s device\n", child->name);
- }
-
- ret = of_property_read_string(pdev->dev.of_node, "label",
- &drvdata->name);
- if (ret) {
- pr_err("%s: Missing property label\n", __func__);
- return -EINVAL;
- }
-
- *needs_alt_core_clk = of_property_read_bool(pdev->dev.of_node,
- "qcom,needs-alt-core-clk");
-
- drvdata->sec_id = -1;
- drvdata->ttbr_split = 0;
-#endif
- return 0;
-}
-
static int __get_clocks(struct platform_device *pdev,
struct msm_iommu_drvdata *drvdata,
int needs_alt_core_clk)
{
int ret = 0;
- drvdata->pclk = clk_get(&pdev->dev, "iface_clk");
+ drvdata->pclk = devm_clk_get(&pdev->dev, "iface_clk");
if (IS_ERR(drvdata->pclk)) {
ret = PTR_ERR(drvdata->pclk);
drvdata->pclk = NULL;
- pr_err("Unable to get %s clock for %s IOMMU device\n",
- dev_name(&pdev->dev), drvdata->name);
+ if (ret != -EPROBE_DEFER) {
+ pr_err("Unable to get %s clock for %s IOMMU device\n",
+ dev_name(&pdev->dev), drvdata->name);
+ }
goto fail;
}
- drvdata->clk = clk_get(&pdev->dev, "core_clk");
+ drvdata->clk = devm_clk_get(&pdev->dev, "core_clk");
if (!IS_ERR(drvdata->clk)) {
if (clk_get_rate(drvdata->clk) == 0) {
@@ -208,8 +164,10 @@
if (needs_alt_core_clk) {
drvdata->aclk = devm_clk_get(&pdev->dev, "alt_core_clk");
- if (IS_ERR(drvdata->aclk))
- return PTR_ERR(drvdata->aclk);
+ if (IS_ERR(drvdata->aclk)) {
+ ret = PTR_ERR(drvdata->aclk);
+ goto fail;
+ }
}
if (drvdata->aclk && clk_get_rate(drvdata->aclk) == 0) {
@@ -222,15 +180,127 @@
return ret;
}
-static void __put_clocks(struct msm_iommu_drvdata *drvdata)
+#ifdef CONFIG_OF_DEVICE
+
+static int __get_bus_vote_client(struct platform_device *pdev,
+ struct msm_iommu_drvdata *drvdata)
{
- if (drvdata->aclk)
- clk_put(drvdata->aclk);
- if (drvdata->clk)
- clk_put(drvdata->clk);
- clk_put(drvdata->pclk);
+ int ret = 0;
+ struct msm_bus_scale_pdata *bs_table;
+ const char *dummy;
+
+ /* Check whether bus scaling has been specified for this node */
+ ret = of_property_read_string(pdev->dev.of_node, "qcom,msm-bus,name",
+ &dummy);
+ if (ret)
+ return 0;
+
+ bs_table = msm_bus_cl_get_pdata(pdev);
+
+ if (bs_table) {
+ drvdata->bus_client = msm_bus_scale_register_client(bs_table);
+ if (IS_ERR(&drvdata->bus_client)) {
+ pr_err("%s(): Bus client register failed.\n", __func__);
+ ret = -EINVAL;
+ }
+ }
+ return ret;
}
+static void __put_bus_vote_client(struct msm_iommu_drvdata *drvdata)
+{
+ msm_bus_scale_unregister_client(drvdata->bus_client);
+ drvdata->bus_client = 0;
+}
+
+static int msm_iommu_parse_dt(struct platform_device *pdev,
+ struct msm_iommu_drvdata *drvdata)
+{
+ struct device_node *child;
+ struct resource *r;
+ u32 glb_offset = 0;
+ int ret = 0;
+ int needs_alt_core_clk;
+
+ ret = __get_bus_vote_client(pdev, drvdata);
+
+ if (ret)
+ goto fail;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ pr_err("%s: Missing property reg\n", __func__);
+ ret = -EINVAL;
+ goto fail;
+ }
+ drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
+ if (!drvdata->base) {
+ pr_err("%s: Unable to ioremap %pr\n", __func__, r);
+ ret = -ENOMEM;
+ goto fail;
+ }
+ drvdata->glb_base = drvdata->base;
+
+ if (!of_property_read_u32(pdev->dev.of_node, "qcom,glb-offset",
+ &glb_offset)) {
+ drvdata->glb_base += glb_offset;
+ } else {
+ pr_err("%s: Missing property qcom,glb-offset\n", __func__);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ for_each_child_of_node(pdev->dev.of_node, child)
+ drvdata->ncb++;
+
+ ret = of_property_read_string(pdev->dev.of_node, "label",
+ &drvdata->name);
+ if (ret) {
+ pr_err("%s: Missing property label\n", __func__);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ needs_alt_core_clk = of_property_read_bool(pdev->dev.of_node,
+ "qcom,needs-alt-core-clk");
+
+ ret = __get_clocks(pdev, drvdata, needs_alt_core_clk);
+
+ if (ret)
+ goto fail;
+
+ drvdata->sec_id = -1;
+ drvdata->ttbr_split = 0;
+
+ ret = of_platform_populate(pdev->dev.of_node,
+ msm_iommu_v0_ctx_match_table,
+ NULL, &pdev->dev);
+ if (ret) {
+ pr_err("Failed to create iommu context device\n");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ __put_bus_vote_client(drvdata);
+ return ret;
+}
+
+#else
+static int msm_iommu_parse_dt(struct platform_device *pdev,
+ struct msm_iommu_drvdata *drvdata)
+{
+ return 0;
+}
+
+static void __put_bus_vote_client(struct msm_iommu_drvdata *drvdata)
+{
+
+}
+
+#endif
+
/*
* Do a basic check of the IOMMU by performing an ATS operation
* on context bank 0.
@@ -322,23 +392,27 @@
struct msm_iommu_drvdata *drvdata;
struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
int ret;
- int needs_alt_core_clk = 0;
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata) {
ret = -ENOMEM;
- goto fail;
+ goto fail_mem;
}
if (pdev->dev.of_node) {
- ret = msm_iommu_parse_dt(pdev, drvdata, &needs_alt_core_clk);
+ ret = msm_iommu_parse_dt(pdev, drvdata);
if (ret)
goto fail;
} else if (pdev->dev.platform_data) {
struct resource *r, *r2;
resource_size_t len;
+ ret = __get_clocks(pdev, drvdata, 0);
+
+ if (ret)
+ goto fail;
+
r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"physbase");
@@ -349,7 +423,8 @@
len = resource_size(r);
- r2 = request_mem_region(r->start, len, r->name);
+ r2 = devm_request_mem_region(&pdev->dev, r->start,
+ len, r->name);
if (!r2) {
pr_err("Could not request memory region: %pr\n", r);
ret = -EBUSY;
@@ -379,11 +454,6 @@
drvdata->dev = &pdev->dev;
- ret = __get_clocks(pdev, drvdata, needs_alt_core_clk);
-
- if (ret)
- goto fail;
-
iommu_access_ops_v0.iommu_clk_on(drvdata);
msm_iommu_reset(drvdata->base, drvdata->glb_base, drvdata->ncb);
@@ -392,14 +462,14 @@
if (ret)
goto fail_clk;
+ iommu_access_ops_v0.iommu_clk_off(drvdata);
+
pr_info("device %s mapped at %p, with %d ctx banks\n",
drvdata->name, drvdata->base, drvdata->ncb);
msm_iommu_add_drv(drvdata);
platform_set_drvdata(pdev, drvdata);
- iommu_access_ops_v0.iommu_clk_off(drvdata);
-
pmon_info = msm_iommu_pm_alloc(&pdev->dev);
if (pmon_info != NULL) {
ret = msm_iommu_pmon_parse_dt(pdev, pmon_info);
@@ -428,8 +498,9 @@
fail_clk:
iommu_access_ops_v0.iommu_clk_off(drvdata);
- __put_clocks(drvdata);
fail:
+ __put_bus_vote_client(drvdata);
+fail_mem:
return ret;
}
@@ -437,12 +508,13 @@
{
struct msm_iommu_drvdata *drv = NULL;
+ msm_iommu_pm_iommu_unregister(&pdev->dev);
+ msm_iommu_pm_free(&pdev->dev);
+
drv = platform_get_drvdata(pdev);
if (drv) {
+ __put_bus_vote_client(drv);
msm_iommu_remove_drv(drv);
- if (drv->clk)
- clk_put(drv->clk);
- clk_put(drv->pclk);
platform_set_drvdata(pdev, NULL);
}
return 0;
@@ -458,26 +530,28 @@
irq = platform_get_irq(pdev, 0);
if (irq > 0) {
- ret = request_threaded_irq(irq, NULL,
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
msm_iommu_fault_handler,
IRQF_ONESHOT | IRQF_SHARED,
"msm_iommu_nonsecure_irq", ctx_drvdata);
if (ret) {
pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
- return ret;
+ goto out;
}
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
pr_err("Could not find reg property for context bank\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
ret = of_address_to_resource(pdev->dev.parent->of_node, 0, &rp);
if (ret) {
pr_err("of_address_to_resource failed\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
/* Calculate the context bank number using the base addresses. CB0
@@ -488,29 +562,34 @@
if (of_property_read_string(pdev->dev.of_node, "label",
&ctx_drvdata->name)) {
pr_err("Could not find label property\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
if (!of_get_property(pdev->dev.of_node, "qcom,iommu-ctx-mids",
&nmid_array_size)) {
pr_err("Could not find iommu-ctx-mids property\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
if (nmid_array_size >= sizeof(ctx_drvdata->sids)) {
pr_err("Too many mids defined - array size: %u, mids size: %u\n",
nmid_array_size, sizeof(ctx_drvdata->sids));
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
nmid = nmid_array_size / sizeof(*ctx_drvdata->sids);
if (of_property_read_u32_array(pdev->dev.of_node, "qcom,iommu-ctx-mids",
ctx_drvdata->sids, nmid)) {
pr_err("Could not find iommu-ctx-mids property\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
ctx_drvdata->nsid = nmid;
- return 0;
+out:
+ return ret;
}
static void __program_m2v_tables(struct msm_iommu_drvdata *drvdata,
@@ -560,7 +639,7 @@
drvdata = dev_get_drvdata(pdev->dev.parent);
if (!drvdata) {
- ret = -ENODEV;
+ ret = -EPROBE_DEFER;
goto fail;
}
@@ -578,8 +657,10 @@
if (pdev->dev.of_node) {
ret = msm_iommu_ctx_parse_dt(pdev, ctx_drvdata);
- if (ret)
+ if (ret) {
+ platform_set_drvdata(pdev, NULL);
goto fail;
+ }
} else if (pdev->dev.platform_data) {
struct msm_iommu_ctx_dev *c = pdev->dev.platform_data;
@@ -601,7 +682,8 @@
goto fail;
}
- ret = request_threaded_irq(irq, NULL, msm_iommu_fault_handler,
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+ msm_iommu_fault_handler,
IRQF_ONESHOT | IRQF_SHARED,
"msm_iommu_nonsecure_irq", ctx_drvdata);
@@ -647,15 +729,15 @@
.remove = __devexit_p(msm_iommu_remove),
};
-static struct of_device_id msm_iommu_ctx_match_table[] = {
- { .name = "qcom,iommu-ctx", },
+static struct of_device_id msm_iommu_v0_ctx_match_table[] = {
+ { .compatible = "qcom,msm-smmu-v0-ctx", },
{}
};
static struct platform_driver msm_iommu_ctx_driver = {
.driver = {
.name = "msm_iommu_ctx",
- .of_match_table = msm_iommu_ctx_match_table,
+ .of_match_table = msm_iommu_v0_ctx_match_table,
},
.probe = msm_iommu_ctx_probe,
.remove = __devexit_p(msm_iommu_ctx_remove),
diff --git a/drivers/iommu/msm_iommu_dev-v1.c b/drivers/iommu/msm_iommu_dev-v1.c
index 418a086..c0e05f4 100644
--- a/drivers/iommu/msm_iommu_dev-v1.c
+++ b/drivers/iommu/msm_iommu_dev-v1.c
@@ -28,6 +28,9 @@
#include <mach/iommu_hw-v1.h>
#include <mach/iommu.h>
#include <mach/iommu_perfmon.h>
+#include <mach/msm_bus.h>
+
+static struct of_device_id msm_iommu_v1_ctx_match_table[];
static int msm_iommu_parse_bfb_settings(struct platform_device *pdev,
struct msm_iommu_drvdata *drvdata)
@@ -84,6 +87,36 @@
return 0;
}
+static int __get_bus_vote_client(struct platform_device *pdev,
+ struct msm_iommu_drvdata *drvdata)
+{
+ int ret = 0;
+ struct msm_bus_scale_pdata *bs_table;
+ const char *dummy;
+
+ /* Check whether bus scaling has been specified for this node */
+ ret = of_property_read_string(pdev->dev.of_node, "qcom,msm-bus,name",
+ &dummy);
+ if (ret)
+ return 0;
+
+ bs_table = msm_bus_cl_get_pdata(pdev);
+
+ if (bs_table) {
+ drvdata->bus_client = msm_bus_scale_register_client(bs_table);
+ if (IS_ERR(&drvdata->bus_client)) {
+ pr_err("%s(): Bus client register failed.\n", __func__);
+ ret = -EINVAL;
+ }
+ }
+ return ret;
+}
+
+static void __put_bus_vote_client(struct msm_iommu_drvdata *drvdata)
+{
+ msm_bus_scale_unregister_client(drvdata->bus_client);
+}
+
static int msm_iommu_parse_dt(struct platform_device *pdev,
struct msm_iommu_drvdata *drvdata)
{
@@ -92,17 +125,18 @@
struct resource *r;
drvdata->dev = &pdev->dev;
- msm_iommu_add_drv(drvdata);
+
+ ret = __get_bus_vote_client(pdev, drvdata);
+
+ if (ret)
+ goto fail;
ret = msm_iommu_parse_bfb_settings(pdev, drvdata);
if (ret)
goto fail;
- for_each_child_of_node(pdev->dev.of_node, child) {
+ for_each_child_of_node(pdev->dev.of_node, child)
drvdata->ncb++;
- if (!of_platform_device_create(child, NULL, &pdev->dev))
- pr_err("Failed to create %s device\n", child->name);
- }
drvdata->asid = devm_kzalloc(&pdev->dev, drvdata->ncb * sizeof(int),
GFP_KERNEL);
@@ -137,8 +171,15 @@
drvdata->halt_enabled = of_property_read_bool(pdev->dev.of_node,
"qcom,iommu-enable-halt");
- return 0;
+ ret = of_platform_populate(pdev->dev.of_node,
+ msm_iommu_v1_ctx_match_table,
+ NULL, &pdev->dev);
+ if (ret)
+ pr_err("Failed to create iommu context device\n");
+
+ msm_iommu_add_drv(drvdata);
fail:
+ __put_bus_vote_client(drvdata);
return ret;
}
@@ -224,7 +265,7 @@
drvdata->gdsc = devm_regulator_get(&pdev->dev, "vdd");
if (IS_ERR(drvdata->gdsc))
- return -EINVAL;
+ return PTR_ERR(drvdata->gdsc);
drvdata->alt_gdsc = devm_regulator_get(&pdev->dev, "qcom,alt-vdd");
if (IS_ERR(drvdata->alt_gdsc))
@@ -301,10 +342,8 @@
drv = platform_get_drvdata(pdev);
if (drv) {
+ __put_bus_vote_client(drv);
msm_iommu_remove_drv(drv);
- if (drv->clk)
- clk_put(drv->clk);
- clk_put(drv->pclk);
platform_set_drvdata(pdev, NULL);
}
return 0;
@@ -314,7 +353,7 @@
struct msm_iommu_ctx_drvdata *ctx_drvdata)
{
struct resource *r, rp;
- int irq, ret;
+ int irq = 0, ret = 0;
u32 nsid;
ctx_drvdata->secure_context = of_property_read_bool(pdev->dev.of_node,
@@ -323,25 +362,27 @@
if (!ctx_drvdata->secure_context) {
irq = platform_get_irq(pdev, 0);
if (irq > 0) {
- ret = request_threaded_irq(irq, NULL,
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
msm_iommu_fault_handler_v2,
IRQF_ONESHOT | IRQF_SHARED,
"msm_iommu_nonsecure_irq", pdev);
if (ret) {
pr_err("Request IRQ %d failed with ret=%d\n",
irq, ret);
- return ret;
+ goto out;
}
}
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r)
- return -EINVAL;
+ if (!r) {
+ ret = -EINVAL;
+ goto out;
+ }
ret = of_address_to_resource(pdev->dev.parent->of_node, 0, &rp);
if (ret)
- return -EINVAL;
+ goto out;
/* Calculate the context bank number using the base addresses. The
* first 8 pages belong to the global address space which is followed
@@ -354,21 +395,26 @@
&ctx_drvdata->name))
ctx_drvdata->name = dev_name(&pdev->dev);
- if (!of_get_property(pdev->dev.of_node, "qcom,iommu-ctx-sids", &nsid))
- return -EINVAL;
-
- if (nsid >= sizeof(ctx_drvdata->sids))
- return -EINVAL;
+ if (!of_get_property(pdev->dev.of_node, "qcom,iommu-ctx-sids", &nsid)) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (nsid >= sizeof(ctx_drvdata->sids)) {
+ ret = -EINVAL;
+ goto out;
+ }
if (of_property_read_u32_array(pdev->dev.of_node, "qcom,iommu-ctx-sids",
ctx_drvdata->sids,
nsid / sizeof(*ctx_drvdata->sids))) {
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
ctx_drvdata->nsid = nsid;
ctx_drvdata->asid = -1;
- return 0;
+out:
+ return ret;
}
static int __devinit msm_iommu_ctx_probe(struct platform_device *pdev)
@@ -386,12 +432,14 @@
ctx_drvdata->pdev = pdev;
INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
- platform_set_drvdata(pdev, ctx_drvdata);
ret = msm_iommu_ctx_parse_dt(pdev, ctx_drvdata);
- if (!ret)
+ if (!ret) {
+ platform_set_drvdata(pdev, ctx_drvdata);
+
dev_info(&pdev->dev, "context %s using bank %d\n",
ctx_drvdata->name, ctx_drvdata->num);
+ }
return ret;
}
@@ -416,15 +464,15 @@
.remove = __devexit_p(msm_iommu_remove),
};
-static struct of_device_id msm_iommu_ctx_match_table[] = {
- { .name = "qcom,iommu-ctx", },
+static struct of_device_id msm_iommu_v1_ctx_match_table[] = {
+ { .compatible = "qcom,msm-smmu-v1-ctx", },
{}
};
static struct platform_driver msm_iommu_ctx_driver = {
.driver = {
.name = "msm_iommu_ctx_v1",
- .of_match_table = msm_iommu_ctx_match_table,
+ .of_match_table = msm_iommu_v1_ctx_match_table,
},
.probe = msm_iommu_ctx_probe,
.remove = __devexit_p(msm_iommu_ctx_remove),
diff --git a/drivers/iommu/msm_iommu_perfmon.c b/drivers/iommu/msm_iommu_perfmon.c
index a11d794..958c6ca 100644
--- a/drivers/iommu/msm_iommu_perfmon.c
+++ b/drivers/iommu/msm_iommu_perfmon.c
@@ -257,6 +257,7 @@
dev_get_drvdata(iommu->iommu_dev);
iommu->ops->iommu_power_on(iommu_drvdata);
+ iommu->ops->iommu_bus_vote(iommu_drvdata, 1);
iommu->ops->iommu_clk_on(iommu_drvdata);
/* Reset counters in HW */
@@ -311,6 +312,7 @@
iommu->ops->iommu_lock_release();
iommu->ops->iommu_clk_off(iommu_drvdata);
+ iommu->ops->iommu_bus_vote(iommu_drvdata, 0);
iommu->ops->iommu_power_off(iommu_drvdata);
pr_info("%s: TLB performance monitoring turned OFF\n",
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 8caa9dd..b8c3c44 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -1577,9 +1577,11 @@
if (pktsize == 192) {
if (leadingbytes)
- memcpy(timestamp, &buf[p], TIMESTAMP_LEN);
+ memcpy(timestamp, &demux->tsbuf[p],
+ TIMESTAMP_LEN);
else
- memcpy(timestamp, &buf[188], TIMESTAMP_LEN);
+ memcpy(timestamp, &demux->tsbuf[188],
+ TIMESTAMP_LEN);
} else {
memset(timestamp, 0, TIMESTAMP_LEN);
}
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
index 4579cee..08fa7dd 100644
--- a/drivers/media/platform/msm/camera_v2/camera/camera.c
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -539,7 +539,6 @@
rc = msm_create_session(pvdev->vdev->num, pvdev->vdev);
if (rc < 0)
goto session_fail;
-
rc = msm_create_command_ack_q(pvdev->vdev->num, 0);
if (rc < 0)
goto command_ack_q_fail;
@@ -611,6 +610,7 @@
/* Donot wait, imaging server may have crashed */
msm_post_event(&event, -1);
+ msm_delete_command_ack_q(pvdev->vdev->num, 0);
/* This should take care of both normal close
* and application crashes */
@@ -622,7 +622,6 @@
/* Donot wait, imaging server may have crashed */
msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
-
msm_delete_command_ack_q(pvdev->vdev->num,
sp->stream_id);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
index b31b3f1..ff9c9b8 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
@@ -121,6 +121,7 @@
vfe_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE;
vfe_dev->subdev.sd.entity.name = pdev->name;
+ vfe_dev->subdev.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x2;
rc = msm_sd_register(&vfe_dev->subdev);
if (rc != 0) {
pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index dd8db03..ee205c0 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -389,6 +389,11 @@
rc = msm_isp_update_axi_stream(vfe_dev, arg);
mutex_unlock(&vfe_dev->core_mutex);
break;
+ case MSM_SD_SHUTDOWN:
+ while (vfe_dev->vfe_open_cnt != 0)
+ msm_isp_close_node(sd, NULL);
+ break;
+
default:
pr_err("%s: Invalid ISP command\n", __func__);
rc = -EINVAL;
@@ -912,11 +917,10 @@
rc = vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev);
if (rc <= 0)
- pr_err("%s: halt timeout\n", __func__);
+ pr_err("%s: halt timeout rc=%ld\n", __func__, rc);
vfe_dev->buf_mgr->ops->buf_mgr_deinit(vfe_dev->buf_mgr);
vfe_dev->hw_info->vfe_ops.core_ops.release_hw(vfe_dev);
-
vfe_dev->vfe_open_cnt--;
mutex_unlock(&vfe_dev->core_mutex);
mutex_unlock(&vfe_dev->realtime_mutex);
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index a95eda7..dc1bcc3 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -91,7 +91,6 @@
BUG_ON(!ispif);
memset(ispif->sof_count, 0, sizeof(ispif->sof_count));
-
for (i = 0; i < ispif->vfe_info.num_vfe; i++) {
msm_camera_io_w(1 << PIX0_LINE_BUF_EN_BIT,
@@ -105,9 +104,13 @@
ISPIF_VFE_m_IRQ_CLEAR_1(i));
msm_camera_io_w(0xFFFFFFFF, ispif->base +
ISPIF_VFE_m_IRQ_CLEAR_2(i));
+
msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INPUT_SEL(i));
- msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
- msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
+
+ msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
+ ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
+ msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
+ ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
msm_camera_io_w(0, ispif->base +
ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
@@ -905,6 +908,12 @@
switch (cmd) {
case VIDIOC_MSM_ISPIF_CFG:
return msm_ispif_cmd(sd, arg);
+ case MSM_SD_SHUTDOWN: {
+ struct ispif_device *ispif =
+ (struct ispif_device *)v4l2_get_subdevdata(sd);
+ msm_ispif_release(ispif);
+ return 0;
+ }
default:
pr_err("%s: invalid cmd 0x%x received\n", __func__, cmd);
return -ENOIOCTLCMD;
@@ -986,6 +995,7 @@
ispif->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
ispif->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ISPIF;
ispif->msm_sd.sd.entity.name = pdev->name;
+ ispif->msm_sd.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x1;
rc = msm_sd_register(&ispif->msm_sd);
if (rc) {
pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
index c805c3d..3cc21a7 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
@@ -91,4 +91,6 @@
#define ISPIF_IRQ_GLOBAL_CLEAR_CMD 0x1
+#define ISPIF_STOP_INTF_IMMEDIATELY 0xAAAAAAAA
+
#endif /* __MSM_ISPIF_HWREG_V2_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index be9f613..5581723 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -31,6 +31,7 @@
#include "msm_sd.h"
static struct v4l2_device *msm_v4l2_dev;
+static struct list_head ordered_sd_list;
static struct msm_queue_head *msm_session_q;
@@ -301,6 +302,20 @@
return rc;
}
+static void msm_add_sd_in_position(struct msm_sd_subdev *msm_subdev,
+ struct list_head *sd_list)
+{
+ struct msm_sd_subdev *temp_sd;
+
+ list_for_each_entry(temp_sd, sd_list, list) {
+ if (msm_subdev->close_seq < temp_sd->close_seq) {
+ list_add_tail(&msm_subdev->list, &temp_sd->list);
+ return;
+ }
+ }
+ list_add_tail(&msm_subdev->list, sd_list);
+}
+
int msm_sd_register(struct msm_sd_subdev *msm_subdev)
{
if (WARN_ON(!msm_subdev))
@@ -309,6 +324,7 @@
if (WARN_ON(!msm_v4l2_dev) || WARN_ON(!msm_v4l2_dev->dev))
return -EIO;
+ msm_add_sd_in_position(msm_subdev, &ordered_sd_list);
return __msm_sd_register_subdev(&msm_subdev->sd);
}
@@ -397,66 +413,40 @@
spin_lock_irqsave(&(session->command_ack_q.lock), flags);
list_del_init(&cmd_ack->list);
+ kzfree(cmd_ack);
session->command_ack_q.len--;
spin_unlock_irqrestore(&(session->command_ack_q.lock), flags);
}
-static inline int __msm_v4l2_subdev_shutdown(struct v4l2_subdev *sd)
-{
- return 0;
-}
-
-static void msm_sd_try_shutdown(void)
-{
- unsigned long flags;
- struct v4l2_subdev *sd;
-
- /* release all subdev's resource */
- spin_lock_irqsave(&msm_v4l2_dev->lock, flags);
- if (!list_empty(&msm_v4l2_dev->subdevs)) {
- list_for_each_entry(sd, &msm_v4l2_dev->subdevs, list)
- __msm_v4l2_subdev_shutdown(sd);
- }
- spin_unlock_irqrestore(&msm_v4l2_dev->lock, flags);
-}
-
-static inline int __msm_sd_close_session_streams(struct v4l2_subdev *sd,
+static inline int __msm_sd_close_subdevs(struct msm_sd_subdev *msm_sd,
struct msm_sd_close_ioctl *sd_close)
{
+ struct v4l2_subdev *sd;
+ sd = &msm_sd->sd;
+ pr_debug("%s: Shutting down subdev %s", __func__, sd->name);
+
+ v4l2_subdev_call(sd, core, ioctl, MSM_SD_SHUTDOWN, sd_close);
+ v4l2_subdev_call(sd, core, s_power, 0);
+
return 0;
}
static inline int __msm_destroy_session_streams(void *d1, void *d2)
{
struct msm_stream *stream = d1;
- struct msm_sd_close_ioctl *sd_close = d2;
- struct v4l2_subdev *sd;
- unsigned long flags;
- sd_close->stream = stream->stream_id;
-
- spin_lock_irqsave(&msm_v4l2_dev->lock, flags);
- if (!list_empty(&msm_v4l2_dev->subdevs))
- list_for_each_entry(sd, &msm_v4l2_dev->subdevs, list)
- __msm_sd_close_session_streams(sd, sd_close);
- spin_unlock_irqrestore(&msm_v4l2_dev->lock, flags);
INIT_LIST_HEAD(&stream->queued_list);
return 0;
}
static void msm_destroy_session_streams(struct msm_session *session)
{
- struct msm_sd_close_ioctl sd_close;
- /* to ensure error handling purpose, it needs to detach all subdevs
- * which are being connected to streams */
if (!session)
return;
- sd_close.session = session->session_id;
-
msm_queue_traverse_action(&session->stream_q, struct msm_stream, list,
- __msm_destroy_session_streams, &sd_close);
+ __msm_destroy_session_streams, NULL);
msm_queue_drain(&session->stream_q, struct msm_stream, list);
}
@@ -694,16 +684,13 @@
struct msm_v4l2_event_data *event_data =
(struct msm_v4l2_event_data *)&event.u.data[0];
struct msm_session *session = d1;
- mutex_lock(&session->lock);
+
event.type = MSM_CAMERA_V4L2_EVENT_TYPE;
event.id = MSM_CAMERA_MSM_NOTIFY;
event_data->command = MSM_CAMERA_PRIV_SHUTDOWN;
v4l2_event_queue(session->event_q.vdev, &event);
- msm_destroy_session_streams(session);
- msm_remove_session_cmd_ack_q(session);
- mutex_unlock(&session->lock);
return 0;
}
@@ -712,22 +699,23 @@
int rc = 0;
unsigned long flags;
struct msm_video_device *pvdev = video_drvdata(filep);
+ struct msm_sd_close_ioctl sd_close;
+ struct msm_sd_subdev *msm_sd;
- /* 1st thing 1st, send v4l2_event to HAL immediately,
- * to ensure error handling purpose, it needs to detach all subdevs
- * which are being connected to streams */
+ /*stop all hardware blocks immediately*/
+ if (!list_empty(&msm_v4l2_dev->subdevs))
+ list_for_each_entry(msm_sd, &ordered_sd_list, list)
+ __msm_sd_close_subdevs(msm_sd, &sd_close);
+
+ /* send v4l2_event to HAL next*/
msm_queue_traverse_action(msm_session_q, struct msm_session, list,
__msm_close_destry_session_notify_apps, NULL);
- msm_queue_drain(msm_session_q, struct msm_session, list);
-
spin_lock_irqsave(&msm_eventq_lock, flags);
msm_eventq = NULL;
spin_unlock_irqrestore(&msm_eventq_lock, flags);
v4l2_fh_release(filep);
- msm_sd_try_shutdown();
-
spin_lock_irqsave(&msm_pid_lock, flags);
put_pid(msm_pid);
msm_pid = NULL;
@@ -754,7 +742,6 @@
int rc;
unsigned long flags;
struct msm_video_device *pvdev = video_drvdata(filep);
-
BUG_ON(!pvdev);
/* !!! only ONE open is allowed !!! */
@@ -990,7 +977,7 @@
msm_init_queue(msm_session_q);
spin_lock_init(&msm_eventq_lock);
spin_lock_init(&msm_pid_lock);
-
+ INIT_LIST_HEAD(&ordered_sd_list);
goto probe_end;
v4l2_fail:
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 b0ff832..895f452 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
@@ -161,6 +161,7 @@
msm_buf_mngr_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
msm_buf_mngr_dev->subdev.sd.entity.group_id =
MSM_CAMERA_SUBDEV_BUF_MNGR;
+ msm_buf_mngr_dev->subdev.close_seq = MSM_SD_CLOSE_4TH_CATEGORY;
rc = msm_sd_register(&msm_buf_mngr_dev->subdev);
if (rc != 0) {
pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
diff --git a/drivers/media/platform/msm/camera_v2/msm_sd.h b/drivers/media/platform/msm/camera_v2/msm_sd.h
index 958e030..7c1519d 100644
--- a/drivers/media/platform/msm/camera_v2/msm_sd.h
+++ b/drivers/media/platform/msm/camera_v2/msm_sd.h
@@ -50,10 +50,12 @@
#define MSM_SD_CLOSE_1ST_CATEGORY 0x00010000
#define MSM_SD_CLOSE_2ND_CATEGORY 0x00020000
#define MSM_SD_CLOSE_3RD_CATEGORY 0x00030000
+#define MSM_SD_CLOSE_4TH_CATEGORY 0x00040000
struct msm_sd_subdev {
struct v4l2_subdev sd;
int close_seq;
+ struct list_head list;
};
struct msm_sd_req_sd {
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 5a174f5..4dd3f3d 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
@@ -43,6 +43,9 @@
#define CONFIG_MSM_CPP_DBG 0
+/* dump the frame command before writing to the hardware */
+#define MSM_CPP_DUMP_FRM_CMD 0
+
#if CONFIG_MSM_CPP_DBG
#define CPP_DBG(fmt, args...) pr_err(fmt, ##args)
#else
@@ -208,7 +211,6 @@
pr_err("ION import failed\n");
goto QUEUE_BUFF_ERROR1;
}
-
rc = ion_map_iommu(cpp_dev->client, buff->map_info.ion_handle,
cpp_dev->domain_num, 0, SZ_4K, 0,
(unsigned long *)&buff->map_info.phy_addr,
@@ -237,6 +239,7 @@
static void msm_cpp_dequeue_buffer_info(struct cpp_device *cpp_dev,
struct msm_cpp_buffer_map_list_t *buff)
{
+
ion_unmap_iommu(cpp_dev->client, buff->map_info.ion_handle,
cpp_dev->domain_num, 0);
ion_free(cpp_dev->client, buff->map_info.ion_handle);
@@ -390,6 +393,8 @@
pr_err("Queue not free sessionid: %d, streamid: %d\n",
cpp_dev->buff_queue[i].session_id,
cpp_dev->buff_queue[i].stream_id);
+ msm_cpp_dequeue_buff_info_list
+ (cpp_dev, &cpp_dev->buff_queue[i]);
msm_cpp_free_buff_queue_entry(cpp_dev,
cpp_dev->buff_queue[i].session_id,
cpp_dev->buff_queue[i].stream_id);
@@ -821,9 +826,16 @@
{
uint32_t i;
struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+
mutex_lock(&cpp_dev->mutex);
+
+ if (cpp_dev->cpp_open_cnt == 0) {
+ mutex_unlock(&cpp_dev->mutex);
+ return 0;
+ }
+
for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
- if (cpp_dev->cpp_subscribe_list[i].vfh == &fh->vfh) {
+ if (cpp_dev->cpp_subscribe_list[i].active == 1) {
cpp_dev->cpp_subscribe_list[i].active = 0;
cpp_dev->cpp_subscribe_list[i].vfh = NULL;
break;
@@ -835,7 +847,6 @@
return -ENODEV;
}
- CPP_DBG("close %d %p\n", i, &fh->vfh);
cpp_dev->cpp_open_cnt--;
if (cpp_dev->cpp_open_cnt == 0) {
msm_camera_io_w(0x0, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL);
@@ -843,6 +854,7 @@
cpp_release_hardware(cpp_dev);
cpp_dev->state = CPP_STATE_OFF;
}
+
mutex_unlock(&cpp_dev->mutex);
return 0;
}
@@ -888,8 +900,7 @@
event_qcmd->command = processed_frame;
CPP_DBG("fid %d\n", processed_frame->frame_id);
msm_enqueue(&cpp_dev->eventData_q, &event_qcmd->list_eventdata);
-
- if (!processed_frame->output_buffer_info.processed_divert) {
+ if (!processed_frame->output_buffer_info[0].processed_divert) {
memset(&buff_mgr_info, 0 ,
sizeof(struct msm_buf_mngr_info));
buff_mgr_info.session_id =
@@ -899,7 +910,7 @@
buff_mgr_info.frame_id = processed_frame->frame_id;
buff_mgr_info.timestamp = processed_frame->timestamp;
buff_mgr_info.index =
- processed_frame->output_buffer_info.index;
+ processed_frame->output_buffer_info[0].index;
rc = msm_cpp_buffer_ops(cpp_dev,
VIDIOC_MSM_BUF_MNGR_BUF_DONE,
&buff_mgr_info);
@@ -908,6 +919,28 @@
rc = -EINVAL;
}
}
+
+ if (processed_frame->duplicate_output &&
+ !processed_frame->
+ output_buffer_info[1].processed_divert) {
+ memset(&buff_mgr_info, 0 ,
+ sizeof(struct msm_buf_mngr_info));
+ buff_mgr_info.session_id =
+ ((processed_frame->duplicate_identity >> 16) & 0xFFFF);
+ buff_mgr_info.stream_id =
+ (processed_frame->duplicate_identity & 0xFFFF);
+ buff_mgr_info.frame_id = processed_frame->frame_id;
+ buff_mgr_info.timestamp = processed_frame->timestamp;
+ buff_mgr_info.index =
+ processed_frame->output_buffer_info[1].index;
+ rc = msm_cpp_buffer_ops(cpp_dev,
+ VIDIOC_MSM_BUF_MNGR_BUF_DONE,
+ &buff_mgr_info);
+ if (rc < 0) {
+ pr_err("error putting buffer\n");
+ rc = -EINVAL;
+ }
+ }
v4l2_evt.id = processed_frame->inst_id;
v4l2_evt.type = V4L2_EVENT_CPP_FRAME_DONE;
v4l2_event_queue(cpp_dev->msm_sd.sd.devnode, &v4l2_evt);
@@ -915,6 +948,23 @@
return rc;
}
+#if MSM_CPP_DUMP_FRM_CMD
+static int msm_cpp_dump_frame_cmd(uint32_t *cmd, int32_t len)
+{
+ int i;
+ pr_err("%s: -------- cpp frame cmd msg start --------", __func__);
+ for (i = 0; i < len; i++)
+ pr_err("%s: msg[%03d] = 0x%08x", __func__, i, cmd[i]);
+ pr_err("%s: --------- cpp frame cmd msg end ---------", __func__);
+ return 0;
+}
+#else
+static int msm_cpp_dump_frame_cmd(uint32_t *cmd, int32_t len)
+{
+ return 0;
+}
+#endif
+
static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev,
struct msm_queue_cmd *frame_qcmd)
{
@@ -927,6 +977,8 @@
msm_enqueue(&cpp_dev->processing_q,
&frame_qcmd->list_frame);
msm_cpp_write(0x6, cpp_dev->base);
+ msm_cpp_dump_frame_cmd(process_frame->cpp_cmd_msg,
+ process_frame->msg_len);
for (i = 0; i < process_frame->msg_len; i++)
msm_cpp_write(process_frame->cpp_cmd_msg[i],
cpp_dev->base);
@@ -951,7 +1003,7 @@
struct msm_cpp_frame_info_t *new_frame =
kzalloc(sizeof(struct msm_cpp_frame_info_t), GFP_KERNEL);
uint32_t *cpp_frame_msg;
- unsigned long in_phyaddr, out_phyaddr;
+ unsigned long in_phyaddr, out_phyaddr0, out_phyaddr1;
uint16_t num_stripes = 0;
struct msm_buf_mngr_info buff_mgr_info;
struct msm_cpp_frame_info_t *u_frame_info =
@@ -1001,7 +1053,7 @@
goto ERROR2;
}
- memset(&new_frame->output_buffer_info, 0,
+ memset(&new_frame->output_buffer_info[0], 0,
sizeof(struct msm_cpp_buffer_info_t));
memset(&buff_mgr_info, 0, sizeof(struct msm_buf_mngr_info));
buff_mgr_info.session_id = ((new_frame->identity >> 16) & 0xFFFF);
@@ -1013,17 +1065,49 @@
pr_debug("error getting buffer rc:%d\n", rc);
goto ERROR2;
}
-
- new_frame->output_buffer_info.index = buff_mgr_info.index;
- out_phyaddr = msm_cpp_fetch_buffer_info(cpp_dev,
- &new_frame->output_buffer_info,
+ new_frame->output_buffer_info[0].index = buff_mgr_info.index;
+ out_phyaddr0 = msm_cpp_fetch_buffer_info(cpp_dev,
+ &new_frame->output_buffer_info[0],
((new_frame->identity >> 16) & 0xFFFF),
(new_frame->identity & 0xFFFF));
- if (!out_phyaddr) {
+ if (!out_phyaddr0) {
pr_err("error gettting output physical address\n");
rc = -EINVAL;
goto ERROR3;
}
+ out_phyaddr1 = out_phyaddr0;
+
+ /* get buffer for duplicate output */
+ if (new_frame->duplicate_output) {
+ CPP_DBG("duplication enabled, dup_id=0x%x",
+ new_frame->duplicate_identity);
+ memset(&new_frame->output_buffer_info[1], 0,
+ sizeof(struct msm_cpp_buffer_info_t));
+ memset(&buff_mgr_info, 0, sizeof(struct msm_buf_mngr_info));
+ buff_mgr_info.session_id =
+ ((new_frame->duplicate_identity >> 16) & 0xFFFF);
+ buff_mgr_info.stream_id =
+ (new_frame->duplicate_identity & 0xFFFF);
+ rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_GET_BUF,
+ &buff_mgr_info);
+ if (rc < 0) {
+ rc = -EAGAIN;
+ pr_err("error getting buffer rc:%d\n", rc);
+ goto ERROR2;
+ }
+ new_frame->output_buffer_info[1].index = buff_mgr_info.index;
+ out_phyaddr1 = msm_cpp_fetch_buffer_info(cpp_dev,
+ &new_frame->output_buffer_info[1],
+ ((new_frame->duplicate_identity >> 16) & 0xFFFF),
+ (new_frame->duplicate_identity & 0xFFFF));
+ if (!out_phyaddr1) {
+ pr_err("error gettting output physical address\n");
+ rc = -EINVAL;
+ goto ERROR3;
+ }
+ /* set duplicate enable bit */
+ cpp_frame_msg[5] |= 0x1;
+ }
num_stripes = ((cpp_frame_msg[12] >> 20) & 0x3FF) +
((cpp_frame_msg[12] >> 10) & 0x3FF) +
@@ -1031,10 +1115,10 @@
for (i = 0; i < num_stripes; i++) {
cpp_frame_msg[133 + i * 27] += (uint32_t) in_phyaddr;
- cpp_frame_msg[139 + i * 27] += (uint32_t) out_phyaddr;
- cpp_frame_msg[140 + i * 27] += (uint32_t) out_phyaddr;
- cpp_frame_msg[141 + i * 27] += (uint32_t) out_phyaddr;
- cpp_frame_msg[142 + i * 27] += (uint32_t) out_phyaddr;
+ cpp_frame_msg[139 + i * 27] += (uint32_t) out_phyaddr0;
+ cpp_frame_msg[140 + i * 27] += (uint32_t) out_phyaddr1;
+ cpp_frame_msg[141 + i * 27] += (uint32_t) out_phyaddr0;
+ cpp_frame_msg[142 + i * 27] += (uint32_t) out_phyaddr1;
}
frame_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
@@ -1245,6 +1329,13 @@
kfree(event_qcmd);
break;
}
+ case MSM_SD_SHUTDOWN: {
+ mutex_unlock(&cpp_dev->mutex);
+ while (cpp_dev->cpp_open_cnt != 0)
+ cpp_close_node(sd, NULL);
+ rc = 0;
+ break;
+ }
}
mutex_unlock(&cpp_dev->mutex);
CPP_DBG("X\n");
@@ -1446,6 +1537,7 @@
cpp_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
cpp_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CPP;
cpp_dev->msm_sd.sd.entity.name = pdev->name;
+ cpp_dev->msm_sd.close_seq = MSM_SD_CLOSE_3RD_CATEGORY;
msm_sd_register(&cpp_dev->msm_sd);
msm_cpp_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner;
msm_cpp_v4l2_subdev_fops.open = v4l2_subdev_fops.open;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index e1b978f..b115738 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -629,6 +629,9 @@
return msm_actuator_get_subdev_id(a_ctrl, argp);
case VIDIOC_MSM_ACTUATOR_CFG:
return msm_actuator_config(a_ctrl, argp);
+ case MSM_SD_SHUTDOWN:
+ msm_actuator_close(sd, NULL);
+ return 0;
default:
return -ENOIOCTLCMD;
}
@@ -710,6 +713,7 @@
media_entity_init(&act_ctrl_t->msm_sd.sd.entity, 0, NULL, 0);
act_ctrl_t->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
act_ctrl_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
+ act_ctrl_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
msm_sd_register(&act_ctrl_t->msm_sd);
CDBG("succeeded\n");
CDBG("Exit\n");
@@ -780,6 +784,7 @@
media_entity_init(&msm_actuator_t->msm_sd.sd.entity, 0, NULL, 0);
msm_actuator_t->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
msm_actuator_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
+ msm_actuator_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
msm_sd_register(&msm_actuator_t->msm_sd);
CDBG("Exit\n");
return rc;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index 3409b3e..f3da41c 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -773,6 +773,12 @@
case VIDIOC_MSM_CCI_CFG:
rc = msm_cci_config(sd, arg);
break;
+ case MSM_SD_SHUTDOWN: {
+ struct msm_camera_cci_ctrl ctrl_cmd;
+ ctrl_cmd.cmd = MSM_CCI_RELEASE;
+ rc = msm_cci_config(sd, &ctrl_cmd);
+ break;
+ }
default:
rc = -ENOIOCTLCMD;
}
@@ -1007,6 +1013,7 @@
goto cci_release_mem;
}
disable_irq(new_cci_dev->irq->start);
+ new_cci_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x6;
msm_sd_register(&new_cci_dev->msm_sd);
new_cci_dev->pdev = pdev;
msm_cci_init_cci_params(new_cci_dev);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
index 33eaa69..4db6855 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
@@ -460,6 +460,7 @@
rc = msm_csid_cmd(csid_dev, arg);
break;
case VIDIOC_MSM_CSID_RELEASE:
+ case MSM_SD_SHUTDOWN:
rc = msm_csid_release(csid_dev);
break;
default:
@@ -552,6 +553,7 @@
media_entity_init(&new_csid_dev->msm_sd.sd.entity, 0, NULL, 0);
new_csid_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
new_csid_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CSID;
+ new_csid_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x5;
msm_sd_register(&new_csid_dev->msm_sd);
rc = request_irq(new_csid_dev->irq->start, msm_csid_irq,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
index 7d3a1fc..429d151 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
@@ -570,6 +570,7 @@
rc = msm_csiphy_cmd(csiphy_dev, arg);
break;
case VIDIOC_MSM_CSIPHY_RELEASE:
+ case MSM_SD_SHUTDOWN:
rc = msm_csiphy_release(csiphy_dev, arg);
break;
default:
@@ -665,7 +666,7 @@
media_entity_init(&new_csiphy_dev->msm_sd.sd.entity, 0, NULL, 0);
new_csiphy_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
new_csiphy_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CSIPHY;
-
+ new_csiphy_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x4;
msm_sd_register(&new_csiphy_dev->msm_sd);
new_csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
return 0;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
index 9119a13..044fd31 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
@@ -81,6 +81,7 @@
media_entity_init(&fctrl->msm_sd.sd.entity, 0, NULL, 0);
fctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
fctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_LED_FLASH;
+ fctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1;
msm_sd_register(&fctrl->msm_sd);
CDBG("probe success\n");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
index 7c639d1..d56a5252 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
@@ -16,6 +16,9 @@
#include "msm_cci.h"
#include "msm_camera_io_util.h"
#include "msm_camera_i2c_mux.h"
+#include <mach/rpm-regulator.h>
+#include <mach/rpm-regulator-smd.h>
+#include <linux/regulator/consumer.h>
#undef CDBG
#ifdef CONFIG_MSMB_CAMERA_DEBUG
@@ -774,7 +777,17 @@
sensordata->slave_info->sensor_id_reg_addr = id_info[1];
sensordata->slave_info->sensor_id = id_info[2];
+ rc = of_property_read_string(of_node, "qcom,vdd-cx-name",
+ &sensordata->misc_regulator);
+ CDBG("%s qcom,misc_regulator %s, rc %d\n", __func__,
+ sensordata->misc_regulator, rc);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto ERROR9;
+ }
+
kfree(gpio_array);
+
return rc;
ERROR9:
@@ -799,6 +812,41 @@
return rc;
}
+static void msm_sensor_misc_regulator(
+ struct msm_sensor_ctrl_t *sctrl, uint32_t enable)
+{
+ int32_t rc = 0;
+ if (enable) {
+ sctrl->misc_regulator = (void *)rpm_regulator_get(
+ &sctrl->pdev->dev, sctrl->sensordata->misc_regulator);
+ if (sctrl->misc_regulator) {
+ rc = rpm_regulator_set_mode(sctrl->misc_regulator,
+ RPM_REGULATOR_MODE_HPM);
+ if (rc < 0) {
+ pr_err("%s: Failed to set for rpm regulator on %s: %d\n",
+ __func__,
+ sctrl->sensordata->misc_regulator, rc);
+ rpm_regulator_put(sctrl->misc_regulator);
+ }
+ } else {
+ pr_err("%s: Failed to vote for rpm regulator on %s: %d\n",
+ __func__,
+ sctrl->sensordata->misc_regulator, rc);
+ }
+ } else {
+ if (sctrl->misc_regulator) {
+ rc = rpm_regulator_set_mode(
+ (struct rpm_regulator *)sctrl->misc_regulator,
+ RPM_REGULATOR_MODE_AUTO);
+ if (rc < 0)
+ pr_err("%s: Failed to set for rpm regulator on %s: %d\n",
+ __func__,
+ sctrl->sensordata->misc_regulator, rc);
+ rpm_regulator_put(sctrl->misc_regulator);
+ }
+ }
+}
+
int32_t msm_sensor_free_sensor_data(struct msm_sensor_ctrl_t *s_ctrl)
{
if (!s_ctrl->pdev)
@@ -1002,6 +1050,7 @@
struct msm_sensor_power_setting_array *power_setting_array = NULL;
struct msm_sensor_power_setting *power_setting = NULL;
struct msm_camera_sensor_board_info *data = s_ctrl->sensordata;
+ s_ctrl->stop_setting_valid = 0;
CDBG("%s:%d\n", __func__, __LINE__);
power_setting_array = &s_ctrl->power_setting_array;
@@ -1101,9 +1150,13 @@
static void msm_sensor_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
{
- s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table(
- s_ctrl->sensor_i2c_client, &s_ctrl->stop_setting);
- kfree(s_ctrl->stop_setting.reg_setting);
+ mutex_lock(s_ctrl->msm_sensor_mutex);
+ if (s_ctrl->sensor_state == MSM_SENSOR_POWER_UP) {
+ s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table(
+ s_ctrl->sensor_i2c_client, &s_ctrl->stop_setting);
+ kfree(s_ctrl->stop_setting.reg_setting);
+ }
+ mutex_unlock(s_ctrl->msm_sensor_mutex);
return;
}
@@ -1120,6 +1173,7 @@
case VIDIOC_MSM_SENSOR_CFG:
return s_ctrl->func_tbl->sensor_config(s_ctrl, argp);
case VIDIOC_MSM_SENSOR_RELEASE:
+ case MSM_SD_SHUTDOWN:
msm_sensor_stop_stream(s_ctrl);
return 0;
default:
@@ -1234,6 +1288,13 @@
struct msm_camera_i2c_reg_setting conf_array;
struct msm_camera_i2c_reg_array *reg_setting = NULL;
+ if (s_ctrl->sensor_state != MSM_SENSOR_POWER_UP) {
+ pr_err("%s:%d failed: invalid state %d\n", __func__,
+ __LINE__, s_ctrl->sensor_state);
+ rc = -EFAULT;
+ break;
+ }
+
if (copy_from_user(&conf_array,
(void *)cdata->cfg.setting,
sizeof(struct msm_camera_i2c_reg_setting))) {
@@ -1268,6 +1329,13 @@
struct msm_camera_i2c_seq_reg_setting conf_array;
struct msm_camera_i2c_seq_reg_array *reg_setting = NULL;
+ if (s_ctrl->sensor_state != MSM_SENSOR_POWER_UP) {
+ pr_err("%s:%d failed: invalid state %d\n", __func__,
+ __LINE__, s_ctrl->sensor_state);
+ rc = -EFAULT;
+ break;
+ }
+
if (copy_from_user(&conf_array,
(void *)cdata->cfg.setting,
sizeof(struct msm_camera_i2c_seq_reg_setting))) {
@@ -1302,18 +1370,54 @@
}
case CFG_POWER_UP:
- if (s_ctrl->func_tbl->sensor_power_up)
- rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
- else
+ if (s_ctrl->sensor_state != MSM_SENSOR_POWER_DOWN) {
+ pr_err("%s:%d failed: invalid state %d\n", __func__,
+ __LINE__, s_ctrl->sensor_state);
rc = -EFAULT;
+ break;
+ }
+ if (s_ctrl->func_tbl->sensor_power_up) {
+ if (s_ctrl->sensordata->misc_regulator)
+ msm_sensor_misc_regulator(s_ctrl, 1);
+
+ rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+ if (rc < 0) {
+ pr_err("%s:%d failed rc %ld\n", __func__,
+ __LINE__, rc);
+ break;
+ }
+ s_ctrl->sensor_state = MSM_SENSOR_POWER_UP;
+ pr_err("%s:%d sensor state %d\n", __func__, __LINE__,
+ s_ctrl->sensor_state);
+ } else {
+ rc = -EFAULT;
+ }
break;
case CFG_POWER_DOWN:
- if (s_ctrl->func_tbl->sensor_power_down)
+ if (s_ctrl->sensor_state != MSM_SENSOR_POWER_UP) {
+ pr_err("%s:%d failed: invalid state %d\n", __func__,
+ __LINE__, s_ctrl->sensor_state);
+ rc = -EFAULT;
+ break;
+ }
+ if (s_ctrl->func_tbl->sensor_power_down) {
+ if (s_ctrl->sensordata->misc_regulator)
+ msm_sensor_misc_regulator(s_ctrl, 0);
+
rc = s_ctrl->func_tbl->sensor_power_down(
s_ctrl);
- else
+ if (rc < 0) {
+ pr_err("%s:%d failed rc %ld\n", __func__,
+ __LINE__, rc);
+ break;
+ }
+ s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
+ pr_err("%s:%d sensor state %d\n", __func__, __LINE__,
+ s_ctrl->sensor_state);
+ } else {
rc = -EFAULT;
+ }
break;
case CFG_SET_STOP_STREAM_SETTING: {
@@ -1327,6 +1431,7 @@
rc = -EFAULT;
break;
}
+ s_ctrl->stop_setting_valid = 1;
reg_setting = stop_setting->reg_setting;
stop_setting->reg_setting = kzalloc(stop_setting->size *
@@ -1364,8 +1469,10 @@
int rc = 0;
struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
mutex_lock(s_ctrl->msm_sensor_mutex);
- if (!on)
- rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+ if (!on && s_ctrl->sensor_state == MSM_SENSOR_POWER_UP) {
+ s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+ s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
+ }
if (s_ctrl->free_power_setting == true) {
kfree(s_ctrl->power_setting_array.power_setting);
s_ctrl->free_power_setting = false;
@@ -1505,6 +1612,7 @@
rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id);
CDBG("%s rc %d session_id %d\n", __func__, rc, session_id);
s_ctrl->sensordata->sensor_info->session_id = session_id;
+ s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
msm_sd_register(&s_ctrl->msm_sd);
CDBG("%s:%d\n", __func__, __LINE__);
@@ -1596,6 +1704,7 @@
&session_id);
CDBG("%s rc %d session_id %d\n", __func__, rc, session_id);
s_ctrl->sensordata->sensor_info->session_id = session_id;
+ s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
msm_sd_register(&s_ctrl->msm_sd);
CDBG("%s:%d\n", __func__, __LINE__);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
index 6c36e47d..fe11a56 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
@@ -37,6 +37,11 @@
struct msm_sensor_ctrl_t;
+enum msm_sensor_state_t {
+ MSM_SENSOR_POWER_DOWN,
+ MSM_SENSOR_POWER_UP,
+};
+
struct msm_sensor_fn_t {
int (*sensor_config) (struct msm_sensor_ctrl_t *, void __user *);
int (*sensor_power_down)
@@ -62,9 +67,12 @@
struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
struct msm_sensor_fn_t *func_tbl;
struct msm_camera_i2c_reg_setting stop_setting;
+ bool stop_setting_valid;
bool free_power_setting;
struct msm_cam_clk_info *clk_info;
uint16_t clk_info_size;
+ void *misc_regulator;
+ enum msm_sensor_state_t sensor_state;
};
int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 20cb08d..c3cfe76 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -787,11 +787,10 @@
if (*num_buffers > VIDEO_MAX_FRAME) {
dprintk(VIDC_ERR,
- "Failed : No of slices requested = %d"\
- " Max supported slices = %d",
- *num_buffers, VIDEO_MAX_FRAME);
- rc = -EINVAL;
- break;
+ "Changing buffers requested, from %d to max"\
+ " supported (%d) best effort encoding\n",
+ *num_buffers, VIDEO_MAX_FRAME);
+ *num_buffers = VIDEO_MAX_FRAME;
}
ctrl = v4l2_ctrl_find(&inst->ctrl_handler,
V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA);
diff --git a/drivers/media/platform/msm/vidc/q6_hfi.c b/drivers/media/platform/msm/vidc/q6_hfi.c
index 123b654..577b2b5 100644
--- a/drivers/media/platform/msm/vidc/q6_hfi.c
+++ b/drivers/media/platform/msm/vidc/q6_hfi.c
@@ -362,17 +362,18 @@
void q6_hfi_delete_device(void *device)
{
- struct q6_hfi_device *close, *dev;
+ struct q6_hfi_device *close, *tmp, *dev;
if (device) {
q6_hfi_deinit_resources(device);
dev = (struct q6_hfi_device *) device;
- list_for_each_entry(close, &hal_ctxt.dev_head, list) {
+ list_for_each_entry_safe(close, tmp, &hal_ctxt.dev_head, list) {
if (close->device_id == dev->device_id) {
hal_ctxt.dev_count--;
list_del(&close->list);
destroy_workqueue(close->vidc_workq);
kfree(close);
+ break;
}
}
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 74733c2..bc5adc11 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -2953,12 +2953,12 @@
void venus_hfi_delete_device(void *device)
{
- struct venus_hfi_device *close, *dev;
+ struct venus_hfi_device *close, *tmp, *dev;
if (device) {
venus_hfi_deinit_resources(device);
dev = (struct venus_hfi_device *) device;
- list_for_each_entry(close, &hal_ctxt.dev_head, list) {
+ list_for_each_entry_safe(close, tmp, &hal_ctxt.dev_head, list) {
if (close->hal_data->irq == dev->hal_data->irq) {
hal_ctxt.dev_count--;
free_irq(dev->hal_data->irq, close);
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index f139b21..9bc77be 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -278,63 +278,24 @@
svc->sb_virt = (char *) ion_map_kernel(qseecom.ion_clnt, svc->ihandle);
svc->sb_phys = pa;
- if (qseecom.qseos_version == QSEOS_VERSION_14) {
- req.qsee_cmd_id = QSEOS_REGISTER_LISTENER;
- req.listener_id = svc->svc.listener_id;
- req.sb_len = svc->sb_length;
- req.sb_ptr = (void *)svc->sb_phys;
+ req.qsee_cmd_id = QSEOS_REGISTER_LISTENER;
+ req.listener_id = svc->svc.listener_id;
+ req.sb_len = svc->sb_length;
+ req.sb_ptr = (void *)svc->sb_phys;
- resp.result = QSEOS_RESULT_INCOMPLETE;
+ resp.result = QSEOS_RESULT_INCOMPLETE;
- ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+ ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
sizeof(req), &resp, sizeof(resp));
- if (ret) {
- pr_err("qseecom_scm_call failed with err: %d\n", ret);
- return -EINVAL;
- }
+ if (ret) {
+ pr_err("qseecom_scm_call failed with err: %d\n", ret);
+ return -EINVAL;
+ }
- if (resp.result != QSEOS_RESULT_SUCCESS) {
- pr_err("Error SB registration req: resp.result = %d\n",
- resp.result);
- return -EPERM;
- }
- } else {
- struct qseecom_command cmd;
- struct qseecom_response resp;
- struct qse_pr_init_sb_req_s sb_init_req;
- struct qse_pr_init_sb_rsp_s sb_init_rsp;
-
- svc->sb_reg_req = kzalloc((sizeof(sb_init_req) +
- sizeof(sb_init_rsp)), GFP_KERNEL);
-
- sb_init_req.pr_cmd = TZ_SCHED_CMD_ID_REGISTER_LISTENER;
- sb_init_req.listener_id = svc->svc.listener_id;
- sb_init_req.sb_len = svc->sb_length;
- sb_init_req.sb_ptr = svc->sb_phys;
-
- memcpy(svc->sb_reg_req, &sb_init_req, sizeof(sb_init_req));
-
- /* It will always be a new cmd from this method */
- cmd.cmd_type = TZ_SCHED_CMD_NEW;
- cmd.sb_in_cmd_addr = (u8 *)(virt_to_phys(svc->sb_reg_req));
- cmd.sb_in_cmd_len = sizeof(sb_init_req);
-
- resp.cmd_status = TZ_SCHED_STATUS_INCOMPLETE;
-
- ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &cmd, sizeof(cmd)
- , &resp, sizeof(resp));
-
- if (ret) {
- pr_err("qseecom_scm_call failed with err: %d\n", ret);
- return -EINVAL;
- }
-
- if (resp.cmd_status != TZ_SCHED_STATUS_COMPLETE) {
- pr_err("SB registration fail resp.cmd_status %d\n",
- resp.cmd_status);
- return -EINVAL;
- }
- memset(svc->sb_virt, 0, svc->sb_length);
+ if (resp.result != QSEOS_RESULT_SUCCESS) {
+ pr_err("Error SB registration req: resp.result = %d\n",
+ resp.result);
+ return -EPERM;
}
return 0;
}
@@ -396,56 +357,24 @@
struct qseecom_command_scm_resp resp;
struct ion_handle *ihandle = NULL; /* Retrieve phy addr */
- if (qseecom.qseos_version == QSEOS_VERSION_14) {
- req.qsee_cmd_id = QSEOS_DEREGISTER_LISTENER;
- req.listener_id = data->listener.id;
- resp.result = QSEOS_RESULT_INCOMPLETE;
+ req.qsee_cmd_id = QSEOS_DEREGISTER_LISTENER;
+ req.listener_id = data->listener.id;
+ resp.result = QSEOS_RESULT_INCOMPLETE;
- ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+ ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
sizeof(req), &resp, sizeof(resp));
- if (ret) {
- pr_err("scm_call() failed with err: %d (lstnr id=%d)\n",
- ret, data->listener.id);
- return ret;
- }
-
- if (resp.result != QSEOS_RESULT_SUCCESS) {
- pr_err("Failed resp.result=%d,(lstnr id=%d)\n",
- resp.result, data->listener.id);
- return -EPERM;
- }
- } else {
- struct qse_pr_init_sb_req_s sb_init_req;
- struct qseecom_command cmd;
- struct qseecom_response resp;
- struct qseecom_registered_listener_list *svc;
-
- svc = __qseecom_find_svc(data->listener.id);
- sb_init_req.pr_cmd = TZ_SCHED_CMD_ID_REGISTER_LISTENER;
- sb_init_req.listener_id = data->listener.id;
- sb_init_req.sb_len = 0;
- sb_init_req.sb_ptr = 0;
-
- memcpy(svc->sb_reg_req, &sb_init_req, sizeof(sb_init_req));
-
- /* It will always be a new cmd from this method */
- cmd.cmd_type = TZ_SCHED_CMD_NEW;
- cmd.sb_in_cmd_addr = (u8 *)(virt_to_phys(svc->sb_reg_req));
- cmd.sb_in_cmd_len = sizeof(sb_init_req);
- resp.cmd_status = TZ_SCHED_STATUS_INCOMPLETE;
-
- ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &cmd, sizeof(cmd),
- &resp, sizeof(resp));
- if (ret) {
- pr_err("qseecom_scm_call failed with err: %d\n", ret);
- return ret;
- }
- kzfree(svc->sb_reg_req);
- if (resp.cmd_status != TZ_SCHED_STATUS_COMPLETE) {
- pr_err("Error with SB initialization\n");
- return -EPERM;
- }
+ if (ret) {
+ pr_err("scm_call() failed with err: %d (lstnr id=%d)\n",
+ ret, data->listener.id);
+ return ret;
}
+
+ if (resp.result != QSEOS_RESULT_SUCCESS) {
+ pr_err("Failed resp.result=%d,(lstnr id=%d)\n",
+ resp.result, data->listener.id);
+ return -EPERM;
+ }
+
data->abort = 1;
spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags);
list_for_each_entry(ptr_svc, &qseecom.registered_listener_list_head,
@@ -830,8 +759,7 @@
bool unload = false;
bool found_app = false;
- if ((qseecom.qseos_version == QSEOS_VERSION_14) &&
- (data->client.app_id > 0)) {
+ if (data->client.app_id > 0) {
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
list_for_each_entry(ptr_app, &qseecom.registered_app_list_head,
list) {
@@ -857,7 +785,7 @@
}
}
- if ((unload) && (qseecom.qseos_version == QSEOS_VERSION_14)) {
+ if (unload) {
struct qseecom_unload_app_ireq req;
__qseecom_cleanup_app(data);
@@ -890,19 +818,6 @@
}
}
}
-
- if (qseecom.qseos_version == QSEOS_VERSION_13) {
- data->abort = 1;
- wake_up_all(&qseecom.send_resp_wq);
- while (atomic_read(&data->ioctl_count) > 0) {
- if (wait_event_freezable(data->abort_wq,
- atomic_read(&data->ioctl_count) <= 0)) {
- pr_err("Interrupted from abort\n");
- ret = -ERESTARTSYS;
- break;
- }
- }
- }
qseecom_unmap_ion_allocated_memory(data);
data->released = true;
return ret;
@@ -914,98 +829,6 @@
return data->client.sb_phys + (virt - data->client.user_virt_sb_base);
}
-static int __qseecom_send_cmd_legacy(struct qseecom_dev_handle *data,
- struct qseecom_send_cmd_req *req)
-{
- int ret = 0;
- unsigned long flags;
- u32 reqd_len_sb_in = 0;
- struct qseecom_command cmd;
- struct qseecom_response resp;
-
-
- if (req->cmd_req_buf == NULL || req->resp_buf == NULL) {
- pr_err("cmd buffer or response buffer is null\n");
- return -EINVAL;
- }
-
- if (req->cmd_req_len <= 0 ||
- req->resp_len <= 0 ||
- req->cmd_req_len > data->client.sb_length ||
- req->resp_len > data->client.sb_length) {
- pr_err("cmd buffer length or "
- "response buffer length not valid\n");
- return -EINVAL;
- }
-
- reqd_len_sb_in = req->cmd_req_len + req->resp_len;
- if (reqd_len_sb_in > data->client.sb_length) {
- pr_debug("Not enough memory to fit cmd_buf and "
- "resp_buf. Required: %u, Available: %u\n",
- reqd_len_sb_in, data->client.sb_length);
- return -ENOMEM;
- }
- cmd.cmd_type = TZ_SCHED_CMD_NEW;
- cmd.sb_in_cmd_addr = (u8 *) data->client.sb_phys;
- cmd.sb_in_cmd_len = req->cmd_req_len;
-
- resp.cmd_status = TZ_SCHED_STATUS_INCOMPLETE;
- resp.sb_in_rsp_addr = (u8 *)data->client.sb_phys + req->cmd_req_len;
- resp.sb_in_rsp_len = req->resp_len;
-
- ret = scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *)&cmd,
- sizeof(cmd), &resp, sizeof(resp));
-
- if (ret) {
- pr_err("qseecom_scm_call_legacy failed with err: %d\n", ret);
- return ret;
- }
-
- while (resp.cmd_status != TZ_SCHED_STATUS_COMPLETE) {
- /*
- * If cmd is incomplete, get the callback cmd out from SB out
- * and put it on the list
- */
- struct qseecom_registered_listener_list *ptr_svc = NULL;
- /*
- * We don't know which service can handle the command. so we
- * wake up all blocking services and let them figure out if
- * they can handle the given command.
- */
- spin_lock_irqsave(&qseecom.registered_listener_list_lock,
- flags);
- list_for_each_entry(ptr_svc,
- &qseecom.registered_listener_list_head, list) {
- ptr_svc->rcv_req_flag = 1;
- wake_up_interruptible(&ptr_svc->rcv_req_wq);
- }
- spin_unlock_irqrestore(&qseecom.registered_listener_list_lock,
- flags);
-
- pr_debug("waking up rcv_req_wq and "
- "waiting for send_resp_wq\n");
- if (wait_event_freezable(qseecom.send_resp_wq,
- __qseecom_listener_has_sent_rsp(data))) {
- pr_warning("qseecom Interrupted: exiting send_cmd loop\n");
- return -ERESTARTSYS;
- }
-
- if (data->abort) {
- pr_err("Aborting driver\n");
- return -ENODEV;
- }
- qseecom.send_resp_flag = 0;
- cmd.cmd_type = TZ_SCHED_CMD_PENDING;
- ret = scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *)&cmd,
- sizeof(cmd), &resp, sizeof(resp));
- if (ret) {
- pr_err("qseecom_scm_call failed with err: %d\n", ret);
- return ret;
- }
- }
- return ret;
-}
-
int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr,
struct qseecom_send_svc_cmd_req *req_ptr,
struct qseecom_client_send_service_ireq *send_svc_ireq_ptr)
@@ -1171,10 +994,8 @@
pr_err("copy_from_user failed\n");
return ret;
}
- if (qseecom.qseos_version == QSEOS_VERSION_14)
- ret = __qseecom_send_cmd(data, &req);
- else
- ret = __qseecom_send_cmd_legacy(data, &req);
+ ret = __qseecom_send_cmd(data, &req);
+
if (ret)
return ret;
@@ -1289,12 +1110,9 @@
ret = __qseecom_update_with_phy_addr(&req);
if (ret)
return ret;
- if (qseecom.qseos_version == QSEOS_VERSION_14)
- ret = __qseecom_send_cmd(data, &send_cmd_req);
- else
- ret = __qseecom_send_cmd_legacy(data, &send_cmd_req);
- __qseecom_send_cmd_req_clean_up(&req);
+ ret = __qseecom_send_cmd(data, &send_cmd_req);
+ __qseecom_send_cmd_req_clean_up(&req);
if (ret)
return ret;
@@ -1333,12 +1151,7 @@
return -ENODEV;
}
this_lstnr->rcv_req_flag = 0;
- if (qseecom.qseos_version == QSEOS_VERSION_13) {
- if (*((uint32_t *)this_lstnr->sb_virt) != 0)
- break;
- } else {
- break;
- }
+ break;
}
return ret;
}
@@ -1636,11 +1449,6 @@
uint32_t len;
ion_phys_addr_t pa;
- if (qseecom.qseos_version == QSEOS_VERSION_13) {
- pr_err("This functionality is UNSUPPORTED in version 1.3\n");
- return -EINVAL;
- }
-
*handle = kzalloc(sizeof(struct qseecom_handle), GFP_KERNEL);
if (!(*handle)) {
pr_err("failed to allocate memory for kernel client handle\n");
@@ -1791,10 +1599,6 @@
unsigned long flags = 0;
bool found_handle = false;
- if (qseecom.qseos_version == QSEOS_VERSION_13) {
- pr_err("This functionality is UNSUPPORTED in version 1.3\n");
- return -EINVAL;
- }
if ((handle == NULL) || (*handle == NULL)) {
pr_err("Handle is not initialized\n");
return -EINVAL;
@@ -1835,11 +1639,6 @@
struct qseecom_send_cmd_req req = {0, 0, 0, 0};
struct qseecom_dev_handle *data;
- if (qseecom.qseos_version == QSEOS_VERSION_13) {
- pr_err("This functionality is UNSUPPORTED in version 1.3\n");
- return -EINVAL;
- }
-
if (handle == NULL) {
pr_err("Handle is not initialized\n");
return -EINVAL;
@@ -2419,12 +2218,13 @@
case QSEOS_RESULT_SUCCESS:
break;
case QSEOS_RESULT_FAIL_KEY_ID_EXISTS:
+ pr_debug("process_incomplete_cmd return Key ID exists.\n");
break;
case QSEOS_RESULT_INCOMPLETE:
ret = __qseecom_process_incomplete_cmd(data, &resp);
if (ret) {
if (resp.result == QSEOS_RESULT_FAIL_KEY_ID_EXISTS) {
- pr_warn("process_incomplete_cmd return Key ID exits.\n");
+ pr_debug("process_incomplete_cmd return Key ID exists.\n");
ret = 0;
} else {
pr_err("process_incomplete_cmd FAILED, resp.result %d\n",
@@ -2503,9 +2303,8 @@
return -EFAULT;
}
- if (qseecom.qsee.instance == qseecom.ce_drv.instance)
- __qseecom_enable_clk(CLK_QSEE);
- else
+ __qseecom_enable_clk(CLK_QSEE);
+ if (qseecom.qsee.instance != qseecom.ce_drv.instance)
__qseecom_enable_clk(CLK_CE_DRV);
memcpy(ireq.key_id, set_key_para->key_id, QSEECOM_KEY_ID_SIZE);
@@ -2529,6 +2328,9 @@
&resp, sizeof(struct qseecom_command_scm_resp));
if (ret) {
pr_err("scm call to set QSEOS_PIPE_ENC key failed : %d\n", ret);
+ __qseecom_disable_clk(CLK_QSEE);
+ if (qseecom.qsee.instance != qseecom.ce_drv.instance)
+ __qseecom_disable_clk(CLK_CE_DRV);
return ret;
}
@@ -2548,9 +2350,8 @@
break;
}
- if (qseecom.qsee.instance == qseecom.ce_drv.instance)
- __qseecom_disable_clk(CLK_QSEE);
- else
+ __qseecom_disable_clk(CLK_QSEE);
+ if (qseecom.qsee.instance != qseecom.ce_drv.instance)
__qseecom_disable_clk(CLK_CE_DRV);
return ret;
@@ -2866,11 +2667,6 @@
}
case QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ: {
data->released = true;
- if (qseecom.qseos_version == QSEOS_VERSION_13) {
- pr_err("Loading External elf image unsupported in rev 0x13\n");
- ret = -EINVAL;
- break;
- }
mutex_lock(&app_access_lock);
atomic_inc(&data->ioctl_count);
ret = qseecom_load_external_elf(data, argp);
@@ -2882,11 +2678,6 @@
}
case QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ: {
data->released = true;
- if (qseecom.qseos_version == QSEOS_VERSION_13) {
- pr_err("Unloading External elf image unsupported in rev 0x13\n");
- ret = -EINVAL;
- break;
- }
mutex_lock(&app_access_lock);
atomic_inc(&data->ioctl_count);
ret = qseecom_unload_external_elf(data);
@@ -2990,23 +2781,7 @@
data->released = false;
init_waitqueue_head(&data->abort_wq);
atomic_set(&data->ioctl_count, 0);
- if (qseecom.qseos_version == QSEOS_VERSION_13) {
- int pil_error;
- mutex_lock(&pil_access_lock);
- if (pil_ref_cnt == 0) {
- pil = subsystem_get("tzapps");
- if (IS_ERR(pil)) {
- pr_err("Playready PIL image load failed\n");
- pil_error = PTR_ERR(pil);
- pil = NULL;
- pr_debug("tzapps image load FAILED\n");
- mutex_unlock(&pil_access_lock);
- return pil_error;
- }
- }
- pil_ref_cnt++;
- mutex_unlock(&pil_access_lock);
- }
+
return ret;
}
@@ -3044,13 +2819,6 @@
if (data->perf_enabled == true)
qsee_disable_clock_vote(data, CLK_DFAB);
- if (qseecom.qseos_version == QSEOS_VERSION_13) {
- mutex_lock(&pil_access_lock);
- if (pil_ref_cnt == 1)
- subsystem_put(pil);
- pil_ref_cnt--;
- mutex_unlock(&pil_access_lock);
- }
kfree(data);
return ret;
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 89730b0..d850782 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -2137,7 +2137,7 @@
int ret = 0, dead = 0;
u32 vdd_max_current;
u16 host_version;
- u32 pwr;
+ u32 pwr, irq_status, irq_ctl;
pr_debug("%s: Enter %s\n", dev_name(&pdev->dev), __func__);
msm_host = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_msm_host),
@@ -2265,6 +2265,27 @@
writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE));
/*
+ * CORE_SW_RST above may trigger power irq if previous status of PWRCTL
+ * was either BUS_ON or IO_HIGH_V. So before we enable the power irq
+ * interrupt in GIC (by registering the interrupt handler), we need to
+ * ensure that any pending power irq interrupt status is acknowledged
+ * otherwise power irq interrupt handler would be fired prematurely.
+ */
+ irq_status = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS);
+ writel_relaxed(irq_status, (msm_host->core_mem + CORE_PWRCTL_CLEAR));
+ irq_ctl = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_CTL);
+ if (irq_status & (CORE_PWRCTL_BUS_ON | CORE_PWRCTL_BUS_OFF))
+ irq_ctl |= CORE_PWRCTL_BUS_SUCCESS;
+ if (irq_status & (CORE_PWRCTL_IO_HIGH | CORE_PWRCTL_IO_LOW))
+ irq_ctl |= CORE_PWRCTL_IO_SUCCESS;
+ writel_relaxed(irq_ctl, (msm_host->core_mem + CORE_PWRCTL_CTL));
+ /*
+ * Ensure that above writes are propogated before interrupt enablement
+ * in GIC.
+ */
+ mb();
+
+ /*
* Following are the deviations from SDHC spec v3.0 -
* 1. Card detection is handled using separate GPIO.
* 2. Bus power control is handled by interacting with PMIC.
diff --git a/drivers/platform/msm/ipa/ipa_client.c b/drivers/platform/msm/ipa/ipa_client.c
index a95eafe..d707648 100644
--- a/drivers/platform/msm/ipa/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_client.c
@@ -13,6 +13,9 @@
#include <linux/delay.h>
#include "ipa_i.h"
+#define IPA_A2_HOLB_TMR_EN 0x1
+#define IPA_A2_HOLB_TMR_DEFAULT_VAL 0xff
+
static void ipa_enable_data_path(u32 clnt_hdl)
{
if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_VIRTUAL) {
@@ -175,6 +178,38 @@
return 0;
}
+static void ipa_program_holb(struct ipa_ep_context *ep, int ipa_ep_idx)
+{
+ u32 hol_en;
+ u32 hol_tmr;
+
+ if (IPA_CLIENT_IS_PROD(ep->client))
+ return;
+
+ switch (ep->client) {
+ case IPA_CLIENT_HSIC1_CONS:
+ case IPA_CLIENT_HSIC2_CONS:
+ case IPA_CLIENT_HSIC3_CONS:
+ case IPA_CLIENT_HSIC4_CONS:
+ hol_en = ipa_ctx->hol_en;
+ hol_tmr = ipa_ctx->hol_timer;
+ break;
+ case IPA_CLIENT_A2_TETHERED_CONS:
+ case IPA_CLIENT_A2_EMBEDDED_CONS:
+ hol_en = IPA_A2_HOLB_TMR_EN;
+ hol_tmr = IPA_A2_HOLB_TMR_DEFAULT_VAL;
+ break;
+ default:
+ return;
+ }
+
+ IPADBG("disable holb for ep=%d tmr=%d\n", ipa_ep_idx, hol_tmr);
+ ipa_write_reg(ipa_ctx->mmio,
+ IPA_ENDP_INIT_HOL_BLOCK_EN_n_OFST(ipa_ep_idx), hol_en);
+ ipa_write_reg(ipa_ctx->mmio,
+ IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_OFST(ipa_ep_idx), hol_tmr);
+}
+
/**
* ipa_connect() - low-level IPA client connect
* @in: [in] input parameters from client
@@ -290,21 +325,7 @@
memcpy(&sps->desc, &ep->connect.desc, sizeof(struct sps_mem_buffer));
memcpy(&sps->data, &ep->connect.data, sizeof(struct sps_mem_buffer));
- if (in->client == IPA_CLIENT_HSIC1_CONS ||
- in->client == IPA_CLIENT_HSIC2_CONS ||
- in->client == IPA_CLIENT_HSIC3_CONS ||
- in->client == IPA_CLIENT_HSIC4_CONS ||
- in->client == IPA_CLIENT_A2_TETHERED_CONS ||
- in->client == IPA_CLIENT_A2_EMBEDDED_CONS) {
- IPADBG("disable holb for ep=%d tmr=%d\n", ipa_ep_idx,
- ipa_ctx->hol_timer);
- ipa_write_reg(ipa_ctx->mmio,
- IPA_ENDP_INIT_HOL_BLOCK_EN_n_OFST(ipa_ep_idx),
- ipa_ctx->hol_en);
- ipa_write_reg(ipa_ctx->mmio,
- IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_OFST(ipa_ep_idx),
- ipa_ctx->hol_timer);
- }
+ ipa_program_holb(ep, ipa_ep_idx);
IPADBG("client %d (ep: %d) connected\n", in->client, ipa_ep_idx);
diff --git a/drivers/platform/msm/qpnp-pwm.c b/drivers/platform/msm/qpnp-pwm.c
index 442d18f..be62408 100644
--- a/drivers/platform/msm/qpnp-pwm.c
+++ b/drivers/platform/msm/qpnp-pwm.c
@@ -914,7 +914,7 @@
static inline int qpnp_enable_pwm_mode(struct qpnp_pwm_config *pwm_conf)
{
- if (pwm_conf->channel_id >= QPNP_GPLED_LPG_CHANNEL_RANGE_START ||
+ if (pwm_conf->channel_id >= QPNP_GPLED_LPG_CHANNEL_RANGE_START &&
pwm_conf->channel_id <= QPNP_GPLED_LPG_CHANNEL_RANGE_END)
return QPNP_ENABLE_PWM_MODE_GPLED_CHANNEL;
return QPNP_ENABLE_PWM_MODE;
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index 23c346a..81d80e6 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -1583,10 +1583,7 @@
for (i = 0; i < transfer->iovec_count; i++) {
u32 flags = iovec->flags;
- if (iovec->addr == 0) {
- SPS_ERR("sps:%s:iovec address is invalid.\n", __func__);
- return SPS_ERROR;
- } else if (iovec->size > SPS_IOVEC_MAX_SIZE) {
+ if (iovec->size > SPS_IOVEC_MAX_SIZE) {
SPS_ERR("sps:%s:iovec size is invalid.\n", __func__);
return SPS_ERROR;
}
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index fc85dba..af5442a 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -133,11 +133,11 @@
enum ipa_rm_event cur_prod_state[MAX_BAMS];
enum ipa_rm_event cur_cons_state[MAX_BAMS];
- int lpm_wait_handshake;
+ bool lpm_wait_handshake[MAX_BAMS];
int connect_complete;
bool lpm_wait_pipes;
int bus_suspend;
- bool in_lpm;
+ bool in_lpm[MAX_BAMS];
int (*wake_cb)(void *);
void *wake_param;
@@ -169,8 +169,31 @@
static struct usb_bam_pipe_connect *usb_bam_connections;
static struct usb_bam_ctx_type ctx;
+static struct device *hsic_host_dev;
+
static int __usb_bam_register_wake_cb(u8 idx, int (*callback)(void *user),
void *param, bool trigger_cb_per_pipe);
+static void wait_for_prod_release(enum usb_bam cur_bam);
+static void wait_for_cons_release(enum usb_bam cur_bam);
+
+void msm_bam_set_hsic_host_dev(struct device *dev)
+{
+ if (dev) {
+ /* Hold the device until allowing lpm */
+ info.in_lpm[HSIC_BAM] = false;
+ pr_debug("%s: Getting hsic device %x\n", __func__,
+ (int)dev);
+ pm_runtime_get(dev);
+ } else if (hsic_host_dev) {
+ pr_debug("%s: Putting hsic device %x\n", __func__,
+ (int)hsic_host_dev);
+ /* Just free previous device*/
+ info.in_lpm[HSIC_BAM] = true;
+ pm_runtime_put(hsic_host_dev);
+ }
+
+ hsic_host_dev = dev;
+}
static int get_bam_type_from_core_name(const char *name)
{
@@ -209,6 +232,8 @@
struct sps_pipe *pipe = NULL;
int i;
+ pr_debug("%s: enter\n", __func__);
+
/*
* Since we configure global incativity timer for all pipes
* and not per each pipe, it is enough to use some pipe
@@ -217,14 +242,15 @@
*/
for (i = 0; i < ctx.max_connections; i++) {
pipe_connect = &usb_bam_connections[i];
- if (pipe_connect->bam_type == bam) {
+ if (pipe_connect->bam_type == bam &&
+ pipe_connect->enabled) {
pipe = ctx.usb_bam_sps.sps_pipes[i];
break;
}
}
if (!pipe) {
- pr_err("%s: Bam %s has no pipes\n", __func__,
+ pr_warning("%s: Bam %s has no connected pipes\n", __func__,
bam_enable_strings[bam]);
return;
}
@@ -540,16 +566,6 @@
goto error;
}
- spin_lock(&usb_bam_lock);
-
- /* Set global inactivity timer upon first pipe connection */
- if (ctx.pipes_enabled_per_bam[pipe_connect->bam_type] == 0 &&
- ctx.inactivity_timer_ms[pipe_connect->bam_type] &&
- pipe_connect->inactivity_notify)
- usb_bam_set_inactivity_timer(pipe_connect->bam_type);
-
- spin_unlock(&usb_bam_lock);
-
return 0;
error:
@@ -622,7 +638,7 @@
BUG_ON(trans == NULL);
pr_debug("%s: Going to LPM\n", __func__);
spin_lock(&usb_bam_ipa_handshake_info_lock);
- info.lpm_wait_handshake = false;
+ info.lpm_wait_handshake[HSUSB_BAM] = false;
info.lpm_wait_pipes = 0;
if (disconnect)
pm_runtime_put_noidle(trans->dev);
@@ -813,8 +829,40 @@
return;
}
+static void usb_bam_resume_hsic_host(void)
+{
+ int i;
+ struct usb_bam_pipe_connect *pipe_iter;
+
+ spin_lock(&usb_bam_lock);
+
+ /* Exit from "full suspend" in case of hsic host */
+ if (hsic_host_dev && info.in_lpm[HSIC_BAM]) {
+ pr_debug("%s: Getting hsic device %x\n", __func__,
+ (int)hsic_host_dev);
+ pm_runtime_get(hsic_host_dev);
+ info.in_lpm[HSIC_BAM] = false;
+
+ for (i = 0; i < ctx.max_connections; i++) {
+ pipe_iter = &usb_bam_connections[i];
+ if (pipe_iter->bam_type == HSIC_BAM &&
+ pipe_iter->enabled &&
+ pipe_iter->suspended) {
+ spin_unlock(&usb_bam_lock);
+ ipa_resume(pipe_iter->ipa_clnt_hdl);
+ pipe_iter->suspended = false;
+ spin_lock(&usb_bam_lock);
+ }
+ }
+ }
+
+ spin_unlock(&usb_bam_lock);
+}
+
static int cons_request_resource(enum usb_bam cur_bam)
{
+ int ret = -EINPROGRESS;
+
pr_debug("%s: Request %s_CONS resource\n",
__func__, bam_enable_strings[cur_bam]);
@@ -823,29 +871,44 @@
complete_all(&info.cons_avail[cur_bam]);
spin_lock(&usb_bam_lock);
- if (ctx.pipes_enabled_per_bam[cur_bam] && info.connect_complete &&
- !info.bus_suspend && !info.prod_stopped) {
- spin_unlock(&usb_bam_lock);
- spin_unlock(&usb_bam_ipa_handshake_info_lock);
- pr_debug("%s: ACK on cons_request", __func__);
- return 0;
+
+ switch (cur_bam) {
+ case HSUSB_BAM:
+ if (ctx.pipes_enabled_per_bam[HSUSB_BAM] &&
+ info.connect_complete &&
+ !info.cons_stopped && !info.prod_stopped) {
+ pr_debug("%s: ACK on cons_request", __func__);
+ ret = 0;
+ } else if (ctx.pipes_enabled_per_bam[HSUSB_BAM] &&
+ info.connect_complete && info.bus_suspend) {
+ info.bus_suspend = 0;
+ if (info.wake_cb)
+ info.wake_cb(info.wake_param);
+ }
+
+ break;
+ case HSIC_BAM:
+ usb_bam_resume_hsic_host();
+
+ /*
+ * Return sucess if there are pipes connected
+ * and not in lpm
+ */
+ if (ctx.pipes_enabled_per_bam[cur_bam] &&
+ !info.in_lpm[cur_bam])
+ ret = 0;
+ break;
+ case SSUSB_BAM:
+ default:
+ break;
}
- /* A2 wakeup from LPM */
- if (cur_bam == HSUSB_BAM && ctx.pipes_enabled_per_bam[cur_bam] &&
- info.connect_complete && info.bus_suspend) {
- info.bus_suspend = 0;
- spin_unlock(&usb_bam_lock);
- spin_unlock(&usb_bam_ipa_handshake_info_lock);
- if (info.wake_cb)
- info.wake_cb(info.wake_param);
- } else {
- spin_unlock(&usb_bam_lock);
- spin_unlock(&usb_bam_ipa_handshake_info_lock);
- }
+ spin_unlock(&usb_bam_ipa_handshake_info_lock);
+ spin_unlock(&usb_bam_lock);
- pr_debug("%s: EINPROGRESS on cons_request", __func__);
- return -EINPROGRESS;
+ if (ret == -EINPROGRESS)
+ pr_debug("%s: EINPROGRESS on cons_request", __func__);
+ return ret;
}
static int usb_cons_request_resource(void)
@@ -934,7 +997,7 @@
}
}
-static void wait_for_prod_granted(enum usb_bam cur_bam)
+static void wait_for_prod_granted(enum usb_bam cur_bam, bool start_cons)
{
int ret;
@@ -948,7 +1011,8 @@
__func__);
init_completion(&info.prod_avail[cur_bam]);
- init_completion(&info.cons_avail[cur_bam]);
+ if (start_cons)
+ init_completion(&info.cons_avail[cur_bam]);
ret = ipa_rm_request_resource(ipa_rm_resource_prod[cur_bam]);
if (!ret) {
@@ -1129,7 +1193,7 @@
}
spin_lock(&usb_bam_ipa_handshake_info_lock);
- info.lpm_wait_handshake = true;
+ info.lpm_wait_handshake[HSUSB_BAM] = true;
spin_unlock(&usb_bam_ipa_handshake_info_lock);
wait_for_prod_release(HSUSB_BAM);
@@ -1156,10 +1220,10 @@
mutex_unlock(&info.suspend_resume_mutex);
return;
}
- info.lpm_wait_handshake = true;
+ info.lpm_wait_handshake[HSUSB_BAM] = true;
spin_unlock(&usb_bam_ipa_handshake_info_lock);
- wait_for_prod_granted(HSUSB_BAM);
+ wait_for_prod_granted(HSUSB_BAM, true);
wait_for_cons_granted(HSUSB_BAM);
if (info.cons_stopped) {
ipa_resume_pipes();
@@ -1213,13 +1277,115 @@
if (cur_bam != HSUSB_BAM)
return;
- info.in_lpm = false;
+ info.in_lpm[HSUSB_BAM] = false;
spin_lock(&usb_bam_ipa_handshake_info_lock);
info.bus_suspend = 0;
spin_unlock(&usb_bam_ipa_handshake_info_lock);
queue_work(ctx.usb_bam_wq, &info.resume_work);
}
+void msm_bam_wait_for_hsic_prod_granted(void)
+{
+ ctx.is_bam_inactivity[HSIC_BAM] = false;
+
+ /* Get back to resume state including wakeup ipa */
+ usb_bam_resume_hsic_host();
+
+ /* Ensure getting the producer resource */
+ wait_for_prod_granted(HSIC_BAM, false);
+}
+
+void msm_bam_hsic_notify_on_resume(void)
+{
+ /*
+ * This function is called to notify the usb bam driver
+ * that the hsic core and hsic bam hw are fully resumed
+ * and clocked on. Therefore we can now set the inactivity
+ * timer to the hsic bam hw.
+ */
+ if (ctx.inactivity_timer_ms[HSIC_BAM])
+ usb_bam_set_inactivity_timer(HSIC_BAM);
+}
+
+bool msm_bam_hsic_lpm_ok(void)
+{
+ int i;
+ struct usb_bam_pipe_connect *pipe_iter;
+
+ if (hsic_host_dev) {
+
+ pr_debug("%s: Starting hsic full suspend sequence\n",
+ __func__);
+
+ info.lpm_wait_handshake[HSIC_BAM] = true;
+
+ wait_for_prod_release(HSIC_BAM);
+ pr_debug("%s: complete wait on hsic producer s=%d\n",
+ __func__, info.cur_prod_state[HSIC_BAM]);
+
+ wait_for_cons_release(HSIC_BAM);
+ pr_debug("%s: complete wait on hsic consumer s=%d\n",
+ __func__, info.cur_cons_state[HSIC_BAM]);
+
+ info.lpm_wait_handshake[HSIC_BAM] = false;
+
+ /*
+ * Start low power mode by releasing the device
+ * only in case that indeed the resources were released
+ * and we are still in inactivity state (wake event
+ * have not been occured while we were waiting to the
+ * resources release)
+ */
+ spin_lock(&usb_bam_lock);
+
+ pr_debug("%s: goto lpm?, inactivity=%d\n",
+ __func__, ctx.is_bam_inactivity[HSIC_BAM]);
+
+ if (info.cur_cons_state[HSIC_BAM] ==
+ IPA_RM_RESOURCE_RELEASED &&
+ info.cur_prod_state[HSIC_BAM] ==
+ IPA_RM_RESOURCE_RELEASED &&
+ ctx.is_bam_inactivity[HSIC_BAM] && info.in_lpm[HSIC_BAM]) {
+
+ /* HSIC host will go now to lpm */
+ pr_debug("%s: vote for suspend hsic %x\n",
+ __func__, (int)hsic_host_dev);
+
+ for (i = 0; i < ctx.max_connections; i++) {
+ pipe_iter =
+ &usb_bam_connections[i];
+ if (pipe_iter->bam_type == HSIC_BAM &&
+ pipe_iter->enabled &&
+ !pipe_iter->suspended) {
+ spin_unlock(&usb_bam_lock);
+ ipa_suspend(
+ pipe_iter->ipa_clnt_hdl);
+ pipe_iter->suspended = true;
+ spin_lock(&usb_bam_lock);
+ }
+ }
+
+ spin_unlock(&usb_bam_lock);
+ return true;
+ }
+
+ /* We not allow lpm, therefore renew our vote here */
+ if (info.in_lpm[HSIC_BAM]) {
+ pr_debug("%s: Getting hsic device %x\n", __func__,
+ (int)hsic_host_dev);
+ pm_runtime_get(hsic_host_dev);
+ info.in_lpm[HSIC_BAM] = false;
+ spin_unlock(&usb_bam_lock);
+ wait_for_prod_granted(HSIC_BAM, false);
+ } else
+ spin_unlock(&usb_bam_lock);
+
+ return false;
+ }
+
+ return true;
+}
+
int usb_bam_connect_ipa(struct usb_bam_connect_ipa_params *ipa_params)
{
u8 idx;
@@ -1255,52 +1421,77 @@
}
pr_debug("%s: enter", __func__);
- mutex_lock(&info.suspend_resume_mutex);
- spin_lock(&usb_bam_lock);
- if (ctx.pipes_enabled_per_bam[cur_bam] == 0) {
- spin_unlock(&usb_bam_lock);
- if (cur_bam == HSUSB_BAM) {
+ if (cur_bam == HSUSB_BAM) {
+ mutex_lock(&info.suspend_resume_mutex);
+
+ spin_lock(&usb_bam_lock);
+ if (ctx.pipes_enabled_per_bam[HSUSB_BAM] == 0) {
+ spin_unlock(&usb_bam_lock);
spin_lock(&usb_bam_ipa_handshake_info_lock);
- info.lpm_wait_handshake = 1;
+ info.lpm_wait_handshake[HSUSB_BAM] = true;
info.connect_complete = 0;
info.lpm_wait_pipes = 1;
info.bus_suspend = 0;
info.cons_stopped = 0;
info.prod_stopped = 0;
spin_unlock(&usb_bam_ipa_handshake_info_lock);
- }
- usb_bam_resume_core(cur_bam);
- } else
- spin_unlock(&usb_bam_lock);
+ usb_bam_resume_core(cur_bam);
+ } else
+ spin_unlock(&usb_bam_lock);
+ }
/* Check if BAM requires RESET before connect and reset first pipe */
spin_lock(&usb_bam_lock);
if ((pdata->reset_on_connect[cur_bam] == true) &&
- (ctx.pipes_enabled_per_bam[cur_bam] == 0))
- sps_device_reset(ctx.h_bam[cur_bam]);
+ (ctx.pipes_enabled_per_bam[cur_bam] == 0)) {
+ spin_unlock(&usb_bam_lock);
+ sps_device_reset(ctx.h_bam[cur_bam]);
+
+ /* On re-connect assume out from lpm for HSIC BAM */
+ if (cur_bam == HSIC_BAM && hsic_host_dev &&
+ info.in_lpm[HSIC_BAM]) {
+ pr_debug("%s: Getting hsic device %x\n",
+ __func__, (int)hsic_host_dev);
+ pm_runtime_get(hsic_host_dev);
+ }
+
+ /* On re-connect assume out from lpm for all BAMs */
+ info.in_lpm[cur_bam] = false;
+ } else
spin_unlock(&usb_bam_lock);
if (ipa_params->dir == USB_TO_PEER_PERIPHERAL) {
pr_debug("%s: Starting connect sequence\n", __func__);
- wait_for_prod_granted(cur_bam);
+ wait_for_prod_granted(cur_bam, true);
}
ret = connect_pipe_ipa(idx, ipa_params);
if (ret) {
pr_err("%s: pipe connection failure\n", __func__);
- mutex_unlock(&info.suspend_resume_mutex);
+ if (cur_bam == HSUSB_BAM)
+ mutex_unlock(&info.suspend_resume_mutex);
return ret;
}
spin_lock(&usb_bam_lock);
pipe_connect->enabled = 1;
+ pipe_connect->suspended = 0;
+
+ /* Set global inactivity timer upon first pipe connection */
+ if (ctx.pipes_enabled_per_bam[pipe_connect->bam_type] == 0 &&
+ ctx.inactivity_timer_ms[pipe_connect->bam_type] &&
+ pipe_connect->inactivity_notify)
+ usb_bam_set_inactivity_timer(pipe_connect->bam_type);
+
ctx.pipes_enabled_per_bam[cur_bam] += 1;
spin_unlock(&usb_bam_lock);
if (ipa_params->dir == PEER_PERIPHERAL_TO_USB && cur_bam == HSUSB_BAM)
wait_for_cons_granted(cur_bam);
- mutex_unlock(&info.suspend_resume_mutex);
+ if (cur_bam == HSUSB_BAM)
+ mutex_unlock(&info.suspend_resume_mutex);
+
pr_debug("%s: done", __func__);
return 0;
@@ -1337,7 +1528,7 @@
container_of(w, struct usb_bam_event_info, event_w);
struct usb_bam_pipe_connect *pipe_connect =
container_of(event_info, struct usb_bam_pipe_connect, event);
- struct usb_bam_pipe_connect *pipe_connect_iter;
+ struct usb_bam_pipe_connect *pipe_iter;
int (*callback)(void *priv);
void *param = NULL;
@@ -1347,8 +1538,33 @@
pr_debug("%s recieved USB_BAM_EVENT_WAKEUP\n", __func__);
+ /*
+ * Make sure the PROD resource is granted before
+ * wakeup hsic host class driver (done by the callback below)
+ */
+ if (pipe_connect->peer_bam == IPA_P_BAM &&
+ pipe_connect->bam_type == HSIC_BAM &&
+ info.cur_prod_state[HSIC_BAM] != IPA_RM_RESOURCE_GRANTED) {
+ wait_for_prod_granted(HSIC_BAM, false);
+ }
+
+ /*
+ * Check if need to resume the hsic host.
+ * On one hand, since we got the wakeup interrupt
+ * the hsic bam clocks are already enabled, so no need
+ * to actualluy resume the hardware... However, we still need
+ * to update the usb bam driver state (to set in_lpm=false),
+ * and to wake ipa (ipa_resume) and to hold again the hsic host
+ * device again to avoid it going to low poer mode next time
+ * until we complete releasing the hsic consumer and producer
+ * resources against the ipa resource manager.
+ */
+ if (pipe_connect->bam_type == HSIC_BAM)
+ usb_bam_resume_hsic_host();
+
/* Notify about wakeup / activity of the bam */
- event_info->callback(event_info->param);
+ if (event_info->callback)
+ event_info->callback(event_info->param);
/*
* Reset inactivity timer counter if this pipe's bam
@@ -1359,12 +1575,14 @@
usb_bam_set_inactivity_timer(pipe_connect->bam_type);
spin_unlock(&usb_bam_lock);
- /* A2 wakeup not from LPM (CONS was up) */
- wait_for_prod_granted(pipe_connect->bam_type);
- if (info.start) {
- pr_debug("%s: Enqueue PROD transfer", __func__);
- info.start(info.start_stop_param,
- USB_TO_PEER_PERIPHERAL);
+ if (pipe_connect->bam_type == HSUSB_BAM) {
+ /* A2 wakeup not from LPM (CONS was up) */
+ wait_for_prod_granted(pipe_connect->bam_type, true);
+ if (info.start) {
+ pr_debug("%s: Enqueue PROD transfer", __func__);
+ info.start(info.start_stop_param,
+ USB_TO_PEER_PERIPHERAL);
+ }
}
break;
@@ -1389,21 +1607,34 @@
*/
spin_lock(&usb_bam_lock);
for (i = 0; i < ctx.max_connections; i++) {
- pipe_connect_iter = &usb_bam_connections[i];
- if (pipe_connect_iter->bam_type ==
+ pipe_iter = &usb_bam_connections[i];
+ if (pipe_iter->bam_type ==
pipe_connect->bam_type &&
- pipe_connect_iter->dir ==
+ pipe_iter->dir ==
PEER_PERIPHERAL_TO_USB &&
- pipe_connect_iter->enabled) {
+ pipe_iter->enabled) {
+ pr_debug("%s: Register wakeup on pipe %x\n",
+ __func__, (int)pipe_iter);
__usb_bam_register_wake_cb(i,
- pipe_connect_iter->activity_notify,
- pipe_connect_iter->priv,
+ pipe_iter->activity_notify,
+ pipe_iter->priv,
false);
}
}
spin_unlock(&usb_bam_lock);
- /* Notify about the inactivity */
+ /*
+ * Allow to go to lpm for now. Actual state will be checked
+ * in msm_bam_hsic_lpm_ok() just before going to lpm.
+ */
+ if (hsic_host_dev) {
+ pr_debug("%s: Putting hsic device %x\n", __func__,
+ (int)hsic_host_dev);
+ pm_runtime_put(hsic_host_dev);
+ info.in_lpm[HSIC_BAM] = true;
+ }
+
+ /* Notify about the inactivity to the USB class driver */
if (callback)
callback(param);
@@ -1422,13 +1653,14 @@
container_of(event_info,
struct usb_bam_pipe_connect,
event);
+ enum usb_bam bam = pipe_connect->bam_type;
spin_lock(&usb_bam_lock);
if (event_info->type == USB_BAM_EVENT_WAKEUP_PIPE)
queue_work(ctx.usb_bam_wq, &event_info->event_w);
else if (event_info->type == USB_BAM_EVENT_WAKEUP &&
- ctx.is_bam_inactivity[pipe_connect->bam_type]) {
+ ctx.is_bam_inactivity[bam]) {
/*
* Sps wake event is per pipe, so usb_bam_wake_cb is
@@ -1437,7 +1669,23 @@
* Therefore, the first pipe that awaked will be considered
* as global bam wake event.
*/
- ctx.is_bam_inactivity[pipe_connect->bam_type] = false;
+ ctx.is_bam_inactivity[bam] = false;
+
+ /*
+ * In case that this wakeup event occured while we are
+ * waiting to release of the resurces in order to get into
+ * low power mode, just cancle the waiting.
+ */
+ if (info.lpm_wait_handshake[bam]) {
+ pr_debug("%s: cancel waiting for lpm\n", __func__);
+ if (info.cur_prod_state[bam] !=
+ IPA_RM_RESOURCE_RELEASED)
+ complete_all(&info.prod_released[bam]);
+ if (info.cur_cons_state[bam] !=
+ IPA_RM_RESOURCE_RELEASED)
+ complete_all(&info.cons_released[bam]);
+ }
+
queue_work(ctx.usb_bam_wq, &event_info->event_w);
}
@@ -1687,6 +1935,10 @@
idx = ipa_params->dst_idx;
pipe_connect = &usb_bam_connections[idx];
+ pipe_connect->activity_notify = NULL;
+ pipe_connect->inactivity_notify = NULL;
+ pipe_connect->priv = NULL;
+
/* Do the release handshake with the A2 via RM */
cur_bam = pipe_connect->bam_type;
info.lpm_wait_pipes = 1;
@@ -1716,6 +1968,11 @@
if (ipa_params->cons_clnt_hdl) {
idx = ipa_params->src_idx;
pipe_connect = &usb_bam_connections[idx];
+
+ pipe_connect->activity_notify = NULL;
+ pipe_connect->inactivity_notify = NULL;
+ pipe_connect->priv = NULL;
+
cur_bam = pipe_connect->bam_type;
wait_for_cons_release(cur_bam);
/* close IPA -> USB pipe */
@@ -1839,9 +2096,11 @@
/*
* Notify inactivity once, Since it is global
- * for all pipes on bam.
+ * for all pipes on bam. Notify only if we have
+ * connected pipes.
*/
- if (pipe_connect->bam_type == bam) {
+ if (pipe_connect->bam_type == bam &&
+ pipe_connect->enabled) {
event_info = &pipe_connect->event;
event_info->type = USB_BAM_EVENT_INACTIVITY;
event_info->param = pipe_connect->priv;
@@ -2073,6 +2332,7 @@
props.num_pipes = pdata->usb_bam_num_pipes;
props.callback = usb_bam_sps_events;
props.user = bam_enable_strings[bam_idx];
+ props.options = SPS_BAM_OPT_IRQ_WAKEUP;
/*
* HSUSB and HSIC Cores don't support RESET ACK signal to BAMs
@@ -2190,7 +2450,8 @@
/* Apply new timer setting if bam has running pipes */
if (ctx.inactivity_timer_ms[bam] != timer_d) {
ctx.inactivity_timer_ms[bam] = timer_d;
- if (ctx.pipes_enabled_per_bam[bam] > 0)
+ if (ctx.pipes_enabled_per_bam[bam] > 0 &&
+ !info.in_lpm[bam])
usb_bam_set_inactivity_timer(bam);
}
@@ -2263,6 +2524,7 @@
complete(&info.prod_released[i]);
info.cur_prod_state[i] = IPA_RM_RESOURCE_RELEASED;
info.cur_cons_state[i] = IPA_RM_RESOURCE_RELEASED;
+ info.lpm_wait_handshake[i] = false;
}
INIT_WORK(&info.resume_work, usb_bam_finish_resume);
@@ -2360,12 +2622,12 @@
bool msm_bam_lpm_ok(void)
{
spin_lock(&usb_bam_ipa_handshake_info_lock);
- if (info.lpm_wait_handshake || info.lpm_wait_pipes) {
+ if (info.lpm_wait_handshake[HSUSB_BAM] || info.lpm_wait_pipes) {
spin_unlock(&usb_bam_ipa_handshake_info_lock);
pr_err("%s: Scheduling LPM for later\n", __func__);
return 0;
} else {
- info.in_lpm = 1;
+ info.in_lpm[HSUSB_BAM] = true;
spin_unlock(&usb_bam_ipa_handshake_info_lock);
pr_err("%s: Going to LPM now\n", __func__);
return 1;
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 10a9fcc..24825ea 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -184,6 +184,11 @@
/* Workaround flags */
#define CHG_FLAGS_VCP_WA BIT(0)
+struct qpnp_chg_irq {
+ unsigned int irq;
+ unsigned long disabled;
+};
+
/**
* struct qpnp_chg_chip - device information
* @dev: device pointer to access the parent
@@ -242,14 +247,14 @@
u16 boost_base;
u16 misc_base;
u16 freq_base;
- unsigned int usbin_valid_irq;
- unsigned int dcin_valid_irq;
- unsigned int chg_gone_irq;
- unsigned int chg_fastchg_irq;
- unsigned int chg_trklchg_irq;
- unsigned int chg_failed_irq;
- unsigned int chg_vbatdet_lo_irq;
- unsigned int batt_pres_irq;
+ struct qpnp_chg_irq usbin_valid;
+ struct qpnp_chg_irq dcin_valid;
+ struct qpnp_chg_irq chg_gone;
+ struct qpnp_chg_irq chg_fastchg;
+ struct qpnp_chg_irq chg_trklchg;
+ struct qpnp_chg_irq chg_failed;
+ struct qpnp_chg_irq chg_vbatdet_lo;
+ struct qpnp_chg_irq batt_pres;
bool bat_is_cool;
bool bat_is_warm;
bool chg_done;
@@ -292,6 +297,7 @@
struct wake_lock eoc_wake_lock;
};
+
static struct of_device_id qpnp_charger_match_table[] = {
{ .compatible = QPNP_CHARGER_DEV_NAME, },
{}
@@ -379,6 +385,24 @@
return 0;
}
+static void
+qpnp_chg_enable_irq(struct qpnp_chg_irq *irq)
+{
+ if (__test_and_clear_bit(0, &irq->disabled)) {
+ pr_debug("number = %d\n", irq->irq);
+ enable_irq(irq->irq);
+ }
+}
+
+static void
+qpnp_chg_disable_irq(struct qpnp_chg_irq *irq)
+{
+ if (!__test_and_set_bit(0, &irq->disabled)) {
+ pr_debug("number = %d\n", irq->irq);
+ disable_irq_nosync(irq->irq);
+ }
+}
+
#define USB_OTG_EN_BIT BIT(0)
static int
qpnp_chg_is_otg_en_set(struct qpnp_chg_chip *chip)
@@ -674,7 +698,7 @@
schedule_delayed_work(&chip->eoc_work,
msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
wake_lock(&chip->eoc_wake_lock);
- disable_irq_nosync(chip->chg_vbatdet_lo_irq);
+ qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
} else {
qpnp_chg_charge_en(chip, !chip->charging_disabled);
}
@@ -832,7 +856,7 @@
power_supply_changed(chip->usb_psy);
if (chip->dc_chgpth_base)
power_supply_changed(&chip->dc_psy);
- enable_irq(chip->chg_vbatdet_lo_irq);
+ qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
return IRQ_HANDLED;
}
@@ -1129,7 +1153,6 @@
get_prop_capacity(struct qpnp_chg_chip *chip)
{
union power_supply_propval ret = {0,};
- bool usb_online, dc_online;
if (chip->use_default_batt_values || !get_prop_batt_present(chip))
return DEFAULT_CAPACITY;
@@ -1138,11 +1161,8 @@
chip->bms_psy->get_property(chip->bms_psy,
POWER_SUPPLY_PROP_CAPACITY, &ret);
if (ret.intval == 0) {
- usb_online = chip->usb_psy->get_property(chip->usb_psy,
- POWER_SUPPLY_PROP_ONLINE, &ret);
- dc_online = chip->dc_psy.get_property(&chip->dc_psy,
- POWER_SUPPLY_PROP_ONLINE, &ret);
- if (!usb_online && !dc_online)
+ if (!qpnp_chg_is_usb_chg_plugged_in(chip)
+ && !qpnp_chg_is_usb_chg_plugged_in(chip))
pr_warn_ratelimited("Battery 0, CHG absent\n");
}
return ret.intval;
@@ -1555,7 +1575,7 @@
qpnp_chg_charge_en(chip, 0);
chip->chg_done = true;
power_supply_changed(&chip->batt_psy);
- enable_irq(chip->chg_vbatdet_lo_irq);
+ qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
goto stop_eoc;
} else {
count += 1;
@@ -1564,7 +1584,7 @@
} else if ((!(chg_sts & VBAT_DET_LOW_IRQ)) && (vbat_mv <
(chip->max_voltage_mv - chip->resume_delta_mv))) {
pr_debug("woke up too early\n");
- enable_irq(chip->chg_vbatdet_lo_irq);
+ qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
goto stop_eoc;
}
} else {
@@ -1721,157 +1741,157 @@
case SMBB_CHGR_SUBTYPE:
case SMBBP_CHGR_SUBTYPE:
case SMBCL_CHGR_SUBTYPE:
- chip->chg_fastchg_irq = spmi_get_irq_byname(spmi,
+ chip->chg_fastchg.irq = spmi_get_irq_byname(spmi,
spmi_resource, "fast-chg-on");
- if (chip->chg_fastchg_irq < 0) {
+ if (chip->chg_fastchg.irq < 0) {
pr_err("Unable to get fast-chg-on irq\n");
return rc;
}
- chip->chg_trklchg_irq = spmi_get_irq_byname(spmi,
+ chip->chg_trklchg.irq = spmi_get_irq_byname(spmi,
spmi_resource, "trkl-chg-on");
- if (chip->chg_trklchg_irq < 0) {
+ if (chip->chg_trklchg.irq < 0) {
pr_err("Unable to get trkl-chg-on irq\n");
return rc;
}
- chip->chg_failed_irq = spmi_get_irq_byname(spmi,
+ chip->chg_failed.irq = spmi_get_irq_byname(spmi,
spmi_resource, "chg-failed");
- if (chip->chg_failed_irq < 0) {
+ if (chip->chg_failed.irq < 0) {
pr_err("Unable to get chg_failed irq\n");
return rc;
}
- chip->chg_vbatdet_lo_irq = spmi_get_irq_byname(spmi,
+ chip->chg_vbatdet_lo.irq = spmi_get_irq_byname(spmi,
spmi_resource, "vbat-det-lo");
- if (chip->chg_vbatdet_lo_irq < 0) {
+ if (chip->chg_vbatdet_lo.irq < 0) {
pr_err("Unable to get fast-chg-on irq\n");
return rc;
}
- rc |= devm_request_irq(chip->dev, chip->chg_failed_irq,
+ rc |= devm_request_irq(chip->dev, chip->chg_failed.irq,
qpnp_chg_chgr_chg_failed_irq_handler,
IRQF_TRIGGER_RISING, "chg-failed", chip);
if (rc < 0) {
pr_err("Can't request %d chg-failed: %d\n",
- chip->chg_failed_irq, rc);
+ chip->chg_failed.irq, rc);
return rc;
}
- rc |= devm_request_irq(chip->dev, chip->chg_fastchg_irq,
+ rc |= devm_request_irq(chip->dev, chip->chg_fastchg.irq,
qpnp_chg_chgr_chg_fastchg_irq_handler,
IRQF_TRIGGER_RISING,
"fast-chg-on", chip);
if (rc < 0) {
pr_err("Can't request %d fast-chg-on: %d\n",
- chip->chg_fastchg_irq, rc);
+ chip->chg_fastchg.irq, rc);
return rc;
}
- rc |= devm_request_irq(chip->dev, chip->chg_trklchg_irq,
+ rc |= devm_request_irq(chip->dev, chip->chg_trklchg.irq,
qpnp_chg_chgr_chg_trklchg_irq_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
"trkl-chg-on", chip);
if (rc < 0) {
pr_err("Can't request %d trkl-chg-on: %d\n",
- chip->chg_trklchg_irq, rc);
+ chip->chg_trklchg.irq, rc);
return rc;
}
rc |= devm_request_irq(chip->dev,
- chip->chg_vbatdet_lo_irq,
+ chip->chg_vbatdet_lo.irq,
qpnp_chg_vbatdet_lo_irq_handler,
IRQF_TRIGGER_RISING,
"vbat-det-lo", chip);
if (rc < 0) {
pr_err("Can't request %d vbat-det-lo: %d\n",
- chip->chg_vbatdet_lo_irq, rc);
+ chip->chg_vbatdet_lo.irq, rc);
return rc;
}
- enable_irq_wake(chip->chg_fastchg_irq);
- enable_irq_wake(chip->chg_trklchg_irq);
- enable_irq_wake(chip->chg_failed_irq);
- disable_irq_nosync(chip->chg_vbatdet_lo_irq);
- enable_irq_wake(chip->chg_vbatdet_lo_irq);
+ enable_irq_wake(chip->chg_trklchg.irq);
+ enable_irq_wake(chip->chg_failed.irq);
+ qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
+ enable_irq_wake(chip->chg_vbatdet_lo.irq);
break;
case SMBB_BAT_IF_SUBTYPE:
case SMBBP_BAT_IF_SUBTYPE:
case SMBCL_BAT_IF_SUBTYPE:
- chip->batt_pres_irq = spmi_get_irq_byname(spmi,
+ chip->batt_pres.irq = spmi_get_irq_byname(spmi,
spmi_resource, "batt-pres");
- if (chip->batt_pres_irq < 0) {
+ if (chip->batt_pres.irq < 0) {
pr_err("Unable to get batt-pres irq\n");
return rc;
}
- rc = devm_request_irq(chip->dev, chip->batt_pres_irq,
+ rc = devm_request_irq(chip->dev, chip->batt_pres.irq,
qpnp_chg_bat_if_batt_pres_irq_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
"batt-pres", chip);
if (rc < 0) {
pr_err("Can't request %d batt-pres irq: %d\n",
- chip->batt_pres_irq, rc);
+ chip->batt_pres.irq, rc);
return rc;
}
- enable_irq_wake(chip->batt_pres_irq);
+ enable_irq_wake(chip->batt_pres.irq);
break;
case SMBB_USB_CHGPTH_SUBTYPE:
case SMBBP_USB_CHGPTH_SUBTYPE:
case SMBCL_USB_CHGPTH_SUBTYPE:
- chip->usbin_valid_irq = spmi_get_irq_byname(spmi,
+ chip->usbin_valid.irq = spmi_get_irq_byname(spmi,
spmi_resource, "usbin-valid");
- if (chip->usbin_valid_irq < 0) {
+ if (chip->usbin_valid.irq < 0) {
pr_err("Unable to get usbin irq\n");
return rc;
}
- rc = devm_request_irq(chip->dev, chip->usbin_valid_irq,
+ rc = devm_request_irq(chip->dev, chip->usbin_valid.irq,
qpnp_chg_usb_usbin_valid_irq_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
"usbin-valid", chip);
if (rc < 0) {
pr_err("Can't request %d usbin-valid: %d\n",
- chip->usbin_valid_irq, rc);
+ chip->usbin_valid.irq, rc);
return rc;
}
- chip->chg_gone_irq = spmi_get_irq_byname(spmi,
+ chip->chg_gone.irq = spmi_get_irq_byname(spmi,
spmi_resource, "chg-gone");
- if (chip->chg_gone_irq < 0) {
+ if (chip->chg_gone.irq < 0) {
pr_err("Unable to get chg-gone irq\n");
return rc;
}
- rc = devm_request_irq(chip->dev, chip->chg_gone_irq,
+ rc = devm_request_irq(chip->dev, chip->chg_gone.irq,
qpnp_chg_usb_chg_gone_irq_handler,
IRQF_TRIGGER_RISING,
"chg-gone", chip);
if (rc < 0) {
pr_err("Can't request %d chg-gone: %d\n",
- chip->chg_gone_irq, rc);
+ chip->chg_gone.irq, rc);
return rc;
}
- enable_irq_wake(chip->usbin_valid_irq);
- enable_irq_wake(chip->chg_gone_irq);
+
+ enable_irq_wake(chip->usbin_valid.irq);
+ enable_irq_wake(chip->chg_gone.irq);
break;
case SMBB_DC_CHGPTH_SUBTYPE:
- chip->dcin_valid_irq = spmi_get_irq_byname(spmi,
+ chip->dcin_valid.irq = spmi_get_irq_byname(spmi,
spmi_resource, "dcin-valid");
- if (chip->dcin_valid_irq < 0) {
+ if (chip->dcin_valid.irq < 0) {
pr_err("Unable to get dcin irq\n");
return -rc;
}
- rc = devm_request_irq(chip->dev, chip->dcin_valid_irq,
+ rc = devm_request_irq(chip->dev, chip->dcin_valid.irq,
qpnp_chg_dc_dcin_valid_irq_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
"dcin-valid", chip);
if (rc < 0) {
pr_err("Can't request %d dcin-valid: %d\n",
- chip->dcin_valid_irq, rc);
+ chip->dcin_valid.irq, rc);
return rc;
}
- enable_irq_wake(chip->dcin_valid_irq);
+ enable_irq_wake(chip->dcin_valid.irq);
break;
}
}
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c8fdc6b..b7762e1 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -725,8 +725,7 @@
bool sdev_lookup = true;
if (!hba || !query || !response) {
- dev_err(hba->dev,
- "%s: NULL pointer hba = %p, query = %p response = %p\n",
+ pr_err("%s: NULL pointer hba = %p, query = %p response = %p\n",
__func__, hba, query, response);
return -EINVAL;
}
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 814817b..ab59864 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -596,7 +596,14 @@
pr_info("%s: Max frequency reset for cpu%d\n",
KBUILD_MODNAME, cpu);
- ret = cpufreq_update_policy(cpu);
+ if (cpu_online(cpu)) {
+ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+ if (!policy)
+ return ret;
+ ret = cpufreq_driver_target(policy, policy->cur,
+ CPUFREQ_RELATION_H);
+ cpufreq_cpu_put(policy);
+ }
return ret;
}
@@ -748,14 +755,56 @@
return ret;
}
+static void __cpuinit do_freq_control(long temp)
+{
+ int ret = 0;
+ int cpu = 0;
+ uint32_t max_freq = limited_max_freq;
+
+ if (temp >= msm_thermal_info.limit_temp_degC) {
+ if (limit_idx == limit_idx_low)
+ return;
+
+ limit_idx -= msm_thermal_info.freq_step;
+ if (limit_idx < limit_idx_low)
+ limit_idx = limit_idx_low;
+ max_freq = table[limit_idx].frequency;
+ } else if (temp < msm_thermal_info.limit_temp_degC -
+ msm_thermal_info.temp_hysteresis_degC) {
+ if (limit_idx == limit_idx_high)
+ return;
+
+ limit_idx += msm_thermal_info.freq_step;
+ if (limit_idx >= limit_idx_high) {
+ limit_idx = limit_idx_high;
+ max_freq = MSM_CPUFREQ_NO_LIMIT;
+ } else
+ max_freq = table[limit_idx].frequency;
+ }
+
+ if (max_freq == limited_max_freq)
+ return;
+
+ /* Update new limits */
+ for_each_possible_cpu(cpu) {
+ if (!(msm_thermal_info.freq_control_mask & BIT(cpu)))
+ continue;
+ ret = update_cpu_max_freq(cpu, max_freq);
+ if (ret)
+ pr_debug(
+ "%s: Unable to limit cpu%d max freq to %d\n",
+ KBUILD_MODNAME, cpu, max_freq);
+ }
+
+}
+
static void __cpuinit check_temp(struct work_struct *work)
{
static int limit_init;
struct tsens_device tsens_dev;
long temp = 0;
- uint32_t max_freq = limited_max_freq;
- int cpu = 0;
int ret = 0;
+
tsens_dev.sensor_num = msm_thermal_info.sensor_id;
ret = tsens_get_temp(&tsens_dev, &temp);
if (ret) {
@@ -775,38 +824,7 @@
do_core_control(temp);
do_vdd_restriction();
do_psm();
-
- if (temp >= msm_thermal_info.limit_temp_degC) {
- if (limit_idx == limit_idx_low)
- goto reschedule;
-
- limit_idx -= msm_thermal_info.freq_step;
- if (limit_idx < limit_idx_low)
- limit_idx = limit_idx_low;
- max_freq = table[limit_idx].frequency;
- } else if (temp < msm_thermal_info.limit_temp_degC -
- msm_thermal_info.temp_hysteresis_degC) {
- if (limit_idx == limit_idx_high)
- goto reschedule;
-
- limit_idx += msm_thermal_info.freq_step;
- if (limit_idx >= limit_idx_high) {
- limit_idx = limit_idx_high;
- max_freq = MSM_CPUFREQ_NO_LIMIT;
- } else
- max_freq = table[limit_idx].frequency;
- }
- if (max_freq == limited_max_freq)
- goto reschedule;
-
- /* Update new limits */
- for_each_possible_cpu(cpu) {
- ret = update_cpu_max_freq(cpu, max_freq);
- if (ret)
- pr_debug(
- "%s: Unable to limit cpu%d max freq to %d\n",
- KBUILD_MODNAME, cpu, max_freq);
- }
+ do_freq_control(temp);
reschedule:
if (enabled)
@@ -1599,6 +1617,9 @@
if (ret)
goto fail;
+ key = "qcom,freq-control-mask";
+ ret = of_property_read_u32(node, key, &data.freq_control_mask);
+
key = "qcom,core-limit-temp";
ret = of_property_read_u32(node, key, &data.core_limit_temp_degC);
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 80e9e87..678627a 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -3793,9 +3793,7 @@
pm_runtime_no_callbacks(&udc->gadget.dev);
pm_runtime_enable(&udc->gadget.dev);
- retval = register_trace_usb_daytona_invalid_access(dump_usb_info,
- NULL);
- if (retval)
+ if (register_trace_usb_daytona_invalid_access(dump_usb_info, NULL))
pr_err("Registering trace failed\n");
_udc = udc;
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 87a3fd5..2f35315 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -728,12 +728,18 @@
rc = -EINTR;
break;
}
- if (common->thread_wakeup_needed)
+ spin_lock_irq(&common->lock);
+ if (common->thread_wakeup_needed) {
+ spin_unlock_irq(&common->lock);
break;
+ }
+ spin_unlock_irq(&common->lock);
schedule();
}
__set_current_state(TASK_RUNNING);
+ spin_lock_irq(&common->lock);
common->thread_wakeup_needed = 0;
+ spin_unlock_irq(&common->lock);
return rc;
}
@@ -796,12 +802,17 @@
curlun->file_length - file_offset);
/* Wait for the next buffer to become available */
+ spin_lock_irq(&common->lock);
bh = common->next_buffhd_to_fill;
while (bh->state != BUF_STATE_EMPTY) {
+ spin_unlock_irq(&common->lock);
rc = sleep_thread(common);
if (rc)
return rc;
+
+ spin_lock_irq(&common->lock);
}
+ spin_unlock_irq(&common->lock);
/*
* If we were asked to read past the end of file,
@@ -813,8 +824,10 @@
curlun->sense_data_info =
file_offset >> curlun->blkbits;
curlun->info_valid = 1;
+ spin_lock_irq(&common->lock);
bh->inreq->length = 0;
bh->state = BUF_STATE_FULL;
+ spin_unlock_irq(&common->lock);
break;
}
@@ -854,8 +867,10 @@
* equal to the buffer size, which is divisible by the
* bulk-in maxpacket size.
*/
+ spin_lock_irq(&common->lock);
bh->inreq->length = nread;
bh->state = BUF_STATE_FULL;
+ spin_unlock_irq(&common->lock);
/* If an error occurred, report it and its position */
if (nread < amount) {
@@ -1814,12 +1829,17 @@
u32 sd, sdinfo = 0;
/* Wait for the next buffer to become available */
+ spin_lock_irq(&common->lock);
bh = common->next_buffhd_to_fill;
while (bh->state != BUF_STATE_EMPTY) {
+ spin_unlock_irq(&common->lock);
rc = sleep_thread(common);
if (rc)
return rc;
+
+ spin_lock_irq(&common->lock);
}
+ spin_unlock_irq(&common->lock);
if (curlun) {
sd = curlun->sense_data;
@@ -2029,13 +2049,19 @@
dump_cdb(common);
/* Wait for the next buffer to become available for data or status */
+ spin_lock_irq(&common->lock);
bh = common->next_buffhd_to_fill;
common->next_buffhd_to_drain = bh;
while (bh->state != BUF_STATE_EMPTY) {
+ spin_unlock_irq(&common->lock);
rc = sleep_thread(common);
if (rc)
return rc;
+
+ spin_lock_irq(&common->lock);
}
+ spin_unlock_irq(&common->lock);
+
common->phase_error = 0;
common->short_packet_received = 0;
@@ -2376,12 +2402,17 @@
int rc = 0;
/* Wait for the next buffer to become available */
+ spin_lock_irq(&common->lock);
bh = common->next_buffhd_to_fill;
while (bh->state != BUF_STATE_EMPTY) {
+ spin_unlock_irq(&common->lock);
rc = sleep_thread(common);
if (rc)
return rc;
+
+ spin_lock_irq(&common->lock);
}
+ spin_unlock_irq(&common->lock);
/* Queue a request to read a Bulk-only CBW */
set_bulk_out_req_length(common, bh, US_BULK_CB_WRAP_LEN);
@@ -2396,14 +2427,23 @@
*/
/* Wait for the CBW to arrive */
+ spin_lock_irq(&common->lock);
while (bh->state != BUF_STATE_FULL) {
+ spin_unlock_irq(&common->lock);
rc = sleep_thread(common);
if (rc)
return rc;
+
+ spin_lock_irq(&common->lock);
}
+ spin_unlock_irq(&common->lock);
+
smp_rmb();
rc = fsg_is_set(common) ? received_cbw(common->fsg, bh) : -EIO;
+
+ spin_lock_irq(&common->lock);
bh->state = BUF_STATE_EMPTY;
+ spin_unlock_irq(&common->lock);
return rc;
}
@@ -2586,10 +2626,13 @@
/* Wait until everything is idle */
for (;;) {
int num_active = 0;
+ spin_lock_irq(&common->lock);
for (i = 0; i < fsg_num_buffers; ++i) {
bh = &common->buffhds[i];
num_active += bh->inreq_busy + bh->outreq_busy;
}
+ spin_unlock_irq(&common->lock);
+
if (num_active == 0)
break;
if (sleep_thread(common))
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index d1d0f91..0ea9778 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -752,6 +752,19 @@
return -EBUSY;
}
+ if (pdata->consider_ipa_handshake) {
+ dev_dbg(mehci->dev, "%s:Wait for resources release\n",
+ __func__);
+ if (!msm_bam_hsic_lpm_ok()) {
+ dev_dbg(mehci->dev, "%s:Prod+Cons not released\n",
+ __func__);
+ enable_irq(hcd->irq);
+ return -EBUSY;
+ }
+ dev_dbg(mehci->dev, "%s:Prod+Cons resources released\n",
+ __func__);
+ }
+
/*
* PHY may take some time or even fail to enter into low power
* mode (LPM). Hence poll for 500 msec and reset the PHY and link
@@ -829,7 +842,7 @@
wake_unlock(&mehci->wlock);
- dev_dbg(mehci->dev, "HSIC-USB in low power mode\n");
+ dev_info(mehci->dev, "HSIC-USB in low power mode\n");
return 0;
}
@@ -848,6 +861,14 @@
return 0;
}
+ if (pdata->consider_ipa_handshake) {
+ dev_dbg(mehci->dev, "%s:Wait for producer resource\n",
+ __func__);
+ msm_bam_wait_for_hsic_prod_granted();
+ dev_dbg(mehci->dev, "%s:Producer resource obtained\n",
+ __func__);
+ }
+
/* Handles race with Async interrupt */
disable_irq(hcd->irq);
@@ -933,7 +954,13 @@
}
enable_irq(hcd->irq);
- dev_dbg(mehci->dev, "HSIC-USB exited from low power mode\n");
+ dev_info(mehci->dev, "HSIC-USB exited from low power mode\n");
+
+ if (pdata->consider_ipa_handshake) {
+ dev_dbg(mehci->dev, "%s:Notify usb bam on resume complete\n",
+ __func__);
+ msm_bam_hsic_notify_on_resume();
+ }
return 0;
}
@@ -1853,6 +1880,8 @@
"qcom,enable-hbm");
pdata->disable_park_mode = (of_property_read_bool(node,
"qcom,disable-park-mode"));
+ pdata->consider_ipa_handshake = (of_property_read_bool(node,
+ "hsic,consider-ipa-handshake"));
return pdata;
}
@@ -2092,6 +2121,8 @@
if (mehci->enable_hbm)
hbm_init(hcd, pdata->disable_park_mode);
+ msm_bam_set_hsic_host_dev(&pdev->dev);
+
return 0;
destroy_wq:
@@ -2115,6 +2146,8 @@
struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
+ msm_bam_set_hsic_host_dev(NULL);
+
/* If the device was removed no need to call pm_runtime_disable */
if (pdev->dev.power.power_state.event != PM_EVENT_INVALID)
pm_runtime_disable(&pdev->dev);
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index 3d990c2..b5134a7 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -24,6 +24,7 @@
#include "mdp3.h"
#include "mdp3_ppp.h"
+#define MDP_CORE_CLK_RATE 100000000
#define MDP_VSYNC_CLK_RATE 19200000
#define VSYNC_PERIOD 16
@@ -240,17 +241,8 @@
{
int rc = 0;
if (status) {
- struct mdss_panel_info *panel_info = mfd->panel_info;
- unsigned long core_clk;
- int vtotal;
- vtotal = panel_info->lcdc.v_back_porch +
- panel_info->lcdc.v_front_porch +
- panel_info->lcdc.v_pulse_width +
- panel_info->yres;
- core_clk = panel_info->xres * panel_info->yres;
- core_clk *= panel_info->mipi.frame_rate;
- core_clk = (core_clk / panel_info->yres) * vtotal;
- mdp3_clk_set_rate(MDP3_CLK_CORE, core_clk);
+
+ mdp3_clk_set_rate(MDP3_CLK_CORE, MDP_CORE_CLK_RATE);
mdp3_clk_set_rate(MDP3_CLK_VSYNC, MDP_VSYNC_CLK_RATE);
rc = mdp3_clk_enable(true);
diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
index a09f503..fa2e9eb 100644
--- a/drivers/video/msm/mdss/mdp3_dma.c
+++ b/drivers/video/msm/mdss/mdp3_dma.c
@@ -218,7 +218,7 @@
* NOTE: MDP_DMA_P_FETCH_CFG: max_burst_size need to use value 4, not
* the default 16 for MDP hang issue workaround
*/
- MDP3_REG_WRITE(MDP3_REG_DMA_P_FETCH_CFG, 0x10);
+ MDP3_REG_WRITE(MDP3_REG_DMA_P_FETCH_CFG, 0x20);
MDP3_REG_WRITE(MDP3_REG_PRIMARY_RD_PTR_IRQ, 0x10);
dma->source_config = *source_config;
@@ -809,6 +809,7 @@
temp |= BIT(2);
MDP3_REG_WRITE(MDP3_REG_DSI_VIDEO_CTL_POLARITY, temp);
+ MDP3_REG_WRITE(MDP3_REG_DSI_VIDEO_UNDERFLOW_CTL, 0x800000ff);
return 0;
}
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index c663170..db3cecc 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -418,6 +418,9 @@
/* disable DSI phy */
mdss_dsi_phy_enable(ctrl_pdata->ctrl_base, 0);
+
+ mdss_dsi_disable_bus_clocks(ctrl_pdata);
+
ret = mdss_dsi_panel_power_on(pdata, 0);
if (ret) {
pr_err("%s: Panel power off failed\n", __func__);
@@ -502,6 +505,14 @@
pdata->panel_info.panel_power_on = 1;
+ ret = mdss_dsi_enable_bus_clocks(ctrl_pdata);
+ if (ret) {
+ pr_err("%s: failed to enable bus clocks. rc=%d\n", __func__,
+ ret);
+ mdss_dsi_panel_power_on(pdata, 0);
+ return ret;
+ }
+
mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base));
mdss_dsi_phy_init(pdata);
@@ -1094,6 +1105,11 @@
* register in mdp driver
*/
+ ctrl_pdata->pclk_rate = dsi_pclk_rate;
+ ctrl_pdata->byte_clk_rate = panel_data->panel_info.clk_rate / 8;
+ pr_debug("%s: pclk=%d, bclk=%d\n", __func__,
+ ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate);
+
cont_splash_enabled = of_property_read_bool(pdev->dev.of_node,
"qcom,cont-splash-enabled");
if (!cont_splash_enabled) {
@@ -1112,15 +1128,18 @@
pr_err("%s: Panel power on failed\n", __func__);
return rc;
}
- }
- ctrl_pdata->pclk_rate = dsi_pclk_rate;
- ctrl_pdata->byte_clk_rate = panel_data->panel_info.clk_rate / 8;
- pr_debug("%s: pclk=%d, bclk=%d\n", __func__,
- ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate);
+ rc = mdss_dsi_enable_bus_clocks(ctrl_pdata);
+ if (rc) {
+ pr_err("%s: failed to enable bus clocks. rc=%d\n",
+ __func__, rc);
+ rc = mdss_dsi_panel_power_on(
+ &(ctrl_pdata->panel_data), 0);
+ return rc;
+ }
- if (ctrl_pdata->panel_data.panel_info.cont_splash_enabled)
mdss_dsi_clk_ctrl(ctrl_pdata, 1);
+ }
rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data));
if (rc) {
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index 602ed9e..c78c5cf 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -327,6 +327,8 @@
unsigned char *ctrl_base;
int reg_size;
u32 clk_cnt;
+ struct clk *ahb_clk;
+ struct clk *axi_clk;
struct clk *byte_clk;
struct clk *esc_clk;
struct clk *pixel_clk;
@@ -409,6 +411,8 @@
void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mdss_dsi_prepare_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mdss_dsi_unprepare_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+int mdss_dsi_enable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+void mdss_dsi_disable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable);
void mdss_dsi_phy_enable(unsigned char *ctrl_base, int on);
void mdss_dsi_phy_init(struct mdss_panel_data *pdata);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index ab91320..fe10189 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -614,6 +614,37 @@
}
} /* hdmi_tx_set_audio_switch_node */
+static int hdmi_tx_config_avmute(struct hdmi_tx_ctrl *hdmi_ctrl, int set)
+{
+ struct dss_io_data *io;
+
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return -EINVAL;
+ }
+
+ io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ if (!io->base) {
+ DEV_ERR("%s: Core io is not initialized\n", __func__);
+ return -EINVAL;
+ }
+
+ if (set)
+ DSS_REG_W(io, HDMI_GC,
+ DSS_REG_R(io, HDMI_GC) | BIT(0));
+ else
+ DSS_REG_W(io, HDMI_GC,
+ DSS_REG_R(io, HDMI_GC) & ~BIT(0));
+
+ /* Enable AV Mute tranmission here */
+ DSS_REG_W(io, HDMI_VBI_PKT_CTRL,
+ DSS_REG_R(io, HDMI_VBI_PKT_CTRL) | (BIT(4) & BIT(5)));
+
+ DEV_DBG("%s: AVMUTE %s\n", __func__, set ? "set" : "cleared");
+
+ return 0;
+} /* hdmi_tx_config_avmute */
+
void hdmi_tx_hdcp_cb(void *ptr, enum hdmi_hdcp_state status)
{
int rc = 0;
@@ -629,13 +660,25 @@
switch (status) {
case HDCP_STATE_AUTHENTICATED:
- if (hdmi_ctrl->hpd_state)
+ if (hdmi_ctrl->hpd_state) {
+ /* Clear AV Mute */
+ rc = hdmi_tx_config_avmute(hdmi_ctrl, 0);
+ if (rc)
+ DEV_ERR("%s: Failed to clear av mute. rc=%d\n",
+ __func__, rc);
hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1, false);
+ }
break;
case HDCP_STATE_AUTH_FAIL:
hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0, false);
if (hdmi_ctrl->hpd_state) {
+ /* Set AV Mute */
+ rc = hdmi_tx_config_avmute(hdmi_ctrl, 1);
+ if (rc)
+ DEV_ERR("%s: Failed to set av mute. rc=%d\n",
+ __func__, rc);
+
DEV_DBG("%s: Reauthenticating\n", __func__);
rc = hdmi_hdcp_reauthenticate(
hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP]);
@@ -2743,6 +2786,12 @@
case MDSS_EVENT_PANEL_ON:
if (hdmi_ctrl->hdcp_feature_on && hdmi_ctrl->present_hdcp) {
+ /* Set AV Mute before starting authentication */
+ rc = hdmi_tx_config_avmute(hdmi_ctrl, 1);
+ if (rc)
+ DEV_ERR("%s: Failed to set av mute. rc=%d\n",
+ __func__, rc);
+
DEV_DBG("%s: Starting HDCP authentication\n", __func__);
rc = hdmi_hdcp_authenticate(
hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP]);
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index e346082..4b763aa 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1505,7 +1505,6 @@
mdss_mdp_pp_setup_locked(ctl);
mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, ctl->flush_bits);
if (sctl) {
- mdss_mdp_pp_setup_locked(sctl);
mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_FLUSH,
sctl->flush_bits);
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index fcc1c1a..9d28265 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -888,14 +888,19 @@
return ret;
}
-static int pp_mixer_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
+static int pp_mixer_setup(u32 disp_num,
struct mdss_mdp_mixer *mixer)
{
u32 flags, offset, dspp_num, opmode = 0;
struct mdp_pgc_lut_data *pgc_config;
struct pp_sts_type *pp_sts;
+ struct mdss_mdp_ctl *ctl;
dspp_num = mixer->num;
+ if (!mixer || !mixer->ctl)
+ return -EINVAL;
+ ctl = mixer->ctl;
+
/* no corresponding dspp */
if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
(dspp_num >= MDSS_MDP_MAX_DSPP))
@@ -1003,8 +1008,7 @@
return ret;
}
-static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
- struct mdss_mdp_mixer *mixer)
+static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
{
u32 flags, base, offset, dspp_num, opmode = 0;
struct mdp_dither_cfg_data *dither_cfg;
@@ -1014,12 +1018,12 @@
char __iomem *basel;
int i, ret = 0;
struct mdss_data_type *mdata;
+ struct mdss_mdp_ctl *ctl;
- mdata = ctl->mdata;
-
- if (!mixer || !ctl || !mdata)
+ if (!mixer || !mixer->ctl || !mixer->ctl->mdata)
return -EINVAL;
-
+ ctl = mixer->ctl;
+ mdata = ctl->mdata;
dspp_num = mixer->num;
/* no corresponding dspp */
if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
@@ -1174,12 +1178,12 @@
mutex_lock(&mdss_pp_mutex);
if (ctl->mixer_left) {
- pp_mixer_setup(disp_num, ctl, ctl->mixer_left);
- pp_dspp_setup(disp_num, ctl, ctl->mixer_left);
+ pp_mixer_setup(disp_num, ctl->mixer_left);
+ pp_dspp_setup(disp_num, ctl->mixer_left);
}
if (ctl->mixer_right) {
- pp_mixer_setup(disp_num, ctl, ctl->mixer_right);
- pp_dspp_setup(disp_num, ctl, ctl->mixer_right);
+ pp_mixer_setup(disp_num, ctl->mixer_right);
+ pp_dspp_setup(disp_num, ctl->mixer_right);
}
/* clear dirty flag */
if (disp_num < MDSS_BLOCK_DISP_NUM)
diff --git a/drivers/video/msm/mdss/mhl_msc.c b/drivers/video/msm/mdss/mhl_msc.c
index 08d0693..15811bb 100644
--- a/drivers/video/msm/mdss/mhl_msc.c
+++ b/drivers/video/msm/mdss/mhl_msc.c
@@ -201,6 +201,22 @@
return 0;
}
+int mhl_msc_clear(struct mhl_tx_ctrl *mhl_ctrl)
+{
+ if (!mhl_ctrl)
+ return -EFAULT;
+
+ memset(mhl_ctrl->devcap, 0, 16);
+ mhl_ctrl->devcap_state = 0;
+ mhl_ctrl->path_en_state = 0;
+ mhl_ctrl->status[0] = 0;
+ mhl_ctrl->status[1] = 0;
+ mhl_ctrl->scrpd_busy = 0;
+ mhl_ctrl->wr_burst_pending = 0;
+
+ return 0;
+}
+
int mhl_msc_command_done(struct mhl_tx_ctrl *mhl_ctrl,
struct msc_command_struct *req)
{
@@ -541,7 +557,7 @@
* connected device bits
* changed and DEVCAP READY
*/
- if (((value ^ mhl_ctrl->devcap_state) &
+ if (((value ^ mhl_ctrl->status[offset]) &
MHL_STATUS_DCAP_RDY)) {
if (value & MHL_STATUS_DCAP_RDY) {
mhl_ctrl->devcap_state = 0;
@@ -563,7 +579,7 @@
* bit set
*/
tmds_en = mhl_check_tmds_enabled(mhl_ctrl);
- if ((value ^ mhl_ctrl->path_en_state)
+ if ((value ^ mhl_ctrl->status[offset])
& MHL_STATUS_PATH_ENABLED) {
if (value & MHL_STATUS_PATH_ENABLED) {
if (tmds_en &&
@@ -593,7 +609,7 @@
}
break;
}
- mhl_ctrl->path_en_state = value;
+ mhl_ctrl->status[offset] = value;
return 0;
}
diff --git a/drivers/video/msm/mdss/mhl_msc.h b/drivers/video/msm/mdss/mhl_msc.h
index 8a1fd39..3137f17 100644
--- a/drivers/video/msm/mdss/mhl_msc.h
+++ b/drivers/video/msm/mdss/mhl_msc.h
@@ -25,6 +25,8 @@
/******************************************************************/
/* the below APIs are implemented by the MSC functionality */
+int mhl_msc_clear(struct mhl_tx_ctrl *mhl_ctrl);
+
int mhl_msc_command_done(struct mhl_tx_ctrl *mhl_ctrl,
struct msc_command_struct *req);
diff --git a/drivers/video/msm/mdss/mhl_sii8334.c b/drivers/video/msm/mdss/mhl_sii8334.c
index 3c11317..a1053fb 100644
--- a/drivers/video/msm/mdss/mhl_sii8334.c
+++ b/drivers/video/msm/mdss/mhl_sii8334.c
@@ -867,6 +867,7 @@
/* disabling Tx termination */
MHL_SII_REG_NAME_WR(REG_MHLTX_CTL1, 0xD0);
switch_mode(mhl_ctrl, POWER_STATE_D3, true);
+ mhl_msc_clear(mhl_ctrl);
}
static int mhl_msm_read_rgnd_int(struct mhl_tx_ctrl *mhl_ctrl)
diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c
index 12bc5e0..d4eb716 100644
--- a/drivers/video/msm/mdss/msm_mdss_io_8974.c
+++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c
@@ -32,6 +32,7 @@
struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
struct device *dev = NULL;
+ int rc = 0;
if (!pdev) {
pr_err("%s: Invalid pdev\n", __func__);
@@ -39,32 +40,53 @@
}
dev = &pdev->dev;
+ ctrl_pdata->ahb_clk = clk_get(dev, "iface_clk");
+ if (IS_ERR(ctrl_pdata->ahb_clk)) {
+ rc = PTR_ERR(ctrl_pdata->ahb_clk);
+ pr_err("%s: Unable to get mdss ahb clk. rc=%d\n",
+ __func__, rc);
+ goto mdss_dsi_clk_err;
+ }
+
+ ctrl_pdata->axi_clk = clk_get(dev, "bus_clk");
+ if (IS_ERR(ctrl_pdata->axi_clk)) {
+ rc = PTR_ERR(ctrl_pdata->axi_clk);
+ pr_err("%s: Unable to get axi bus clk. rc=%d\n",
+ __func__, rc);
+ goto mdss_dsi_clk_err;
+ }
+
ctrl_pdata->byte_clk = clk_get(dev, "byte_clk");
if (IS_ERR(ctrl_pdata->byte_clk)) {
- pr_err("can't find dsi_byte_clk\n");
+ rc = PTR_ERR(ctrl_pdata->byte_clk);
+ pr_err("%s: can't find dsi_byte_clk. rc=%d\n",
+ __func__, rc);
ctrl_pdata->byte_clk = NULL;
goto mdss_dsi_clk_err;
}
ctrl_pdata->pixel_clk = clk_get(dev, "pixel_clk");
if (IS_ERR(ctrl_pdata->pixel_clk)) {
- pr_err("can't find dsi_pixel_clk\n");
+ rc = PTR_ERR(ctrl_pdata->pixel_clk);
+ pr_err("%s: can't find dsi_pixel_clk. rc=%d\n",
+ __func__, rc);
ctrl_pdata->pixel_clk = NULL;
goto mdss_dsi_clk_err;
}
ctrl_pdata->esc_clk = clk_get(dev, "core_clk");
if (IS_ERR(ctrl_pdata->esc_clk)) {
- pr_err("can't find dsi_esc_clk\n");
+ rc = PTR_ERR(ctrl_pdata->esc_clk);
+ pr_err("%s: can't find dsi_esc_clk. rc=%d\n",
+ __func__, rc);
ctrl_pdata->esc_clk = NULL;
goto mdss_dsi_clk_err;
}
- return 0;
-
mdss_dsi_clk_err:
- mdss_dsi_clk_deinit(ctrl_pdata);
- return -EPERM;
+ if (rc)
+ mdss_dsi_clk_deinit(ctrl_pdata);
+ return rc;
}
void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
@@ -75,6 +97,10 @@
clk_put(ctrl_pdata->esc_clk);
if (ctrl_pdata->pixel_clk)
clk_put(ctrl_pdata->pixel_clk);
+ if (ctrl_pdata->axi_clk)
+ clk_put(ctrl_pdata->axi_clk);
+ if (ctrl_pdata->ahb_clk)
+ clk_put(ctrl_pdata->ahb_clk);
}
#define PREF_DIV_RATIO 27
@@ -156,6 +182,33 @@
return 0;
}
+int mdss_dsi_enable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+{
+ int rc = 0;
+
+ rc = clk_prepare_enable(ctrl_pdata->ahb_clk);
+ if (rc) {
+ pr_err("%s: failed to enable ahb clock. rc=%d\n", __func__, rc);
+ goto error;
+ }
+
+ rc = clk_prepare_enable(ctrl_pdata->axi_clk);
+ if (rc) {
+ pr_err("%s: failed to enable ahb clock. rc=%d\n", __func__, rc);
+ clk_disable_unprepare(ctrl_pdata->ahb_clk);
+ goto error;
+ }
+
+error:
+ return rc;
+}
+
+void mdss_dsi_disable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+{
+ clk_disable_unprepare(ctrl_pdata->axi_clk);
+ clk_disable_unprepare(ctrl_pdata->ahb_clk);
+}
+
void mdss_dsi_prepare_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
clk_prepare(ctrl_pdata->byte_clk);
diff --git a/include/linux/mhl_8334.h b/include/linux/mhl_8334.h
index a66a411..f04bf80 100644
--- a/include/linux/mhl_8334.h
+++ b/include/linux/mhl_8334.h
@@ -146,6 +146,7 @@
struct completion msc_cmd_done;
uint8_t devcap[16];
uint8_t devcap_state;
+ uint8_t status[2];
uint8_t path_en_state;
void *hdmi_mhl_ops;
struct work_struct mhl_msc_send_work;
diff --git a/include/linux/msm_audio_acdb.h b/include/linux/msm_audio_acdb.h
index 3d159c4..a741107 100644
--- a/include/linux/msm_audio_acdb.h
+++ b/include/linux/msm_audio_acdb.h
@@ -72,6 +72,13 @@
uint16_t gain;
};
+enum msm_spkr_prot_states {
+ MSM_SPKR_PROT_CALIBRATED,
+ MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS,
+ MSM_SPKR_PROT_DISABLED,
+ MSM_SPKR_PROT_NOT_CALIBRATED
+};
+
struct msm_spk_prot_cfg {
int r0;
int t0;
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index f14cc52..2c1fa11 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -20,6 +20,7 @@
int32_t limit_temp_degC;
int32_t temp_hysteresis_degC;
uint32_t freq_step;
+ uint32_t freq_control_mask;
int32_t core_limit_temp_degC;
int32_t core_temp_hysteresis_degC;
uint32_t core_control_mask;
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 4ae3b79..209062b 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -424,6 +424,7 @@
bool pool_64_bit_align;
bool enable_hbm;
bool disable_park_mode;
+ bool consider_ipa_handshake;
};
struct msm_usb_host_platform_data {
@@ -465,8 +466,16 @@
};
#ifdef CONFIG_USB_BAM
bool msm_bam_lpm_ok(void);
+void msm_bam_set_hsic_host_dev(struct device *dev);
+void msm_bam_wait_for_hsic_prod_granted(void);
+bool msm_bam_hsic_lpm_ok(void);
+void msm_bam_hsic_notify_on_resume(void);
#else
static inline bool msm_bam_lpm_ok(void) { return true; }
+static inline void msm_bam_set_hsic_host_dev(struct device *dev) {}
+static inline void msm_bam_wait_for_hsic_prod_granted(void) {}
+static inline bool msm_bam_hsic_lpm_ok(void) { return true; }
+static inline void msm_bam_hsic_notify_on_resume(void) {}
#endif
#ifdef CONFIG_USB_CI13XXX_MSM
void msm_hw_bam_disable(bool bam_disable);
diff --git a/include/media/msmb_pproc.h b/include/media/msmb_pproc.h
index aead2d2..6cd4995 100644
--- a/include/media/msmb_pproc.h
+++ b/include/media/msmb_pproc.h
@@ -112,9 +112,10 @@
struct timeval in_time, out_time;
void *cookie;
int32_t *status;
-
+ int32_t duplicate_output;
+ uint32_t duplicate_identity;
struct msm_cpp_buffer_info_t input_buffer_info;
- struct msm_cpp_buffer_info_t output_buffer_info;
+ struct msm_cpp_buffer_info_t output_buffer_info[2];
};
struct cpp_hw_info {
diff --git a/include/sound/Kbuild b/include/sound/Kbuild
index edadaa9..60847b0 100644
--- a/include/sound/Kbuild
+++ b/include/sound/Kbuild
@@ -12,3 +12,4 @@
header-y += compress_params.h
header-y += compress_offload.h
header-y += lsm_params.h
+header-y += voice_params.h
diff --git a/include/sound/voice_params.h b/include/sound/voice_params.h
new file mode 100644
index 0000000..43e3b9d
--- /dev/null
+++ b/include/sound/voice_params.h
@@ -0,0 +1,14 @@
+#ifndef __VOICE_PARAMS_H__
+#define __VOICE_PARAMS_H__
+
+#include <linux/types.h>
+#include <sound/asound.h>
+
+enum voice_lch_mode {
+ VOICE_LCH_START = 1,
+ VOICE_LCH_STOP
+};
+
+#define SNDRV_VOICE_IOCTL_LCH _IOW('U', 0x00, enum voice_lch_mode)
+
+#endif
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 99e5237..8946dce 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -41,6 +41,8 @@
#define TAIKO_MAD_SLIMBUS_TX_PORT 12
#define TAIKO_MAD_AUDIO_FIRMWARE_PATH "wcd9320/wcd9320_mad_audio.bin"
+#define TAIKO_VALIDATE_RX_SBPORT_RANGE(port) ((port >= 16) && (port <= 22))
+#define TAIKO_CONVERT_RX_SBPORT_ID(port) (port - 16) /* RX1 port ID = 0 */
#define TAIKO_HPH_PA_SETTLE_COMP_ON 3000
#define TAIKO_HPH_PA_SETTLE_COMP_OFF 13000
@@ -4275,6 +4277,65 @@
return 0;
}
+static void taiko_set_rxsb_port_format(struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
+ struct wcd9xxx_codec_dai_data *cdc_dai;
+ struct wcd9xxx_ch *ch;
+ int port;
+ u8 bit_sel;
+ u16 sb_ctl_reg, field_shift;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ bit_sel = 0x2;
+ taiko_p->dai[dai->id].bit_width = 16;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ bit_sel = 0x0;
+ taiko_p->dai[dai->id].bit_width = 24;
+ break;
+ default:
+ dev_err(codec->dev, "Invalid format\n");
+ return;
+ }
+
+ cdc_dai = &taiko_p->dai[dai->id];
+
+ list_for_each_entry(ch, &cdc_dai->wcd9xxx_ch_list, list) {
+ port = wcd9xxx_get_slave_port(ch->ch_num);
+
+ if (IS_ERR_VALUE(port) ||
+ !TAIKO_VALIDATE_RX_SBPORT_RANGE(port)) {
+ dev_warn(codec->dev,
+ "%s: invalid port ID %d returned for RX DAI\n",
+ __func__, port);
+ return;
+ }
+
+ port = TAIKO_CONVERT_RX_SBPORT_ID(port);
+
+ if (port <= 3) {
+ sb_ctl_reg = TAIKO_A_CDC_CONN_RX_SB_B1_CTL;
+ field_shift = port << 1;
+ } else if (port <= 6) {
+ sb_ctl_reg = TAIKO_A_CDC_CONN_RX_SB_B2_CTL;
+ field_shift = (port - 4) << 1;
+ } else { /* should not happen */
+ dev_warn(codec->dev,
+ "%s: bad port ID %d\n", __func__, port);
+ return;
+ }
+
+ dev_dbg(codec->dev, "%s: sb_ctl_reg %x field_shift %x\n",
+ __func__, sb_ctl_reg, field_shift);
+ snd_soc_update_bits(codec, sb_ctl_reg, 0x3 << field_shift,
+ bit_sel << field_shift);
+ }
+}
+
static int taiko_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -4389,29 +4450,7 @@
snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_I2S_CTL,
0x03, (rx_fs_rate >> 0x05));
} else {
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- snd_soc_update_bits(codec,
- TAIKO_A_CDC_CONN_RX_SB_B1_CTL,
- 0xFF, 0xAA);
- snd_soc_update_bits(codec,
- TAIKO_A_CDC_CONN_RX_SB_B2_CTL,
- 0xFF, 0x2A);
- taiko->dai[dai->id].bit_width = 16;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- snd_soc_update_bits(codec,
- TAIKO_A_CDC_CONN_RX_SB_B1_CTL,
- 0xFF, 0x00);
- snd_soc_update_bits(codec,
- TAIKO_A_CDC_CONN_RX_SB_B2_CTL,
- 0xFF, 0x00);
- taiko->dai[dai->id].bit_width = 24;
- break;
- default:
- dev_err(codec->dev, "Invalid format\n");
- break;
- }
+ taiko_set_rxsb_port_format(params, dai);
taiko->dai[dai->id].rate = params_rate(params);
}
break;
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 945840d..ae92ca4 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -1949,6 +1949,52 @@
.codec_name = "snd-soc-dummy",
.be_id = MSM_FRONTEND_DAI_LSM1,
},
+ /* Multiple Tunnel instances */
+ {
+ .name = "MSM8974 Compr2",
+ .stream_name = "COMPR2",
+ .cpu_dai_name = "MultiMedia6",
+ .platform_name = "msm-compr-dsp",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6,
+ },
+ {
+ .name = "MSM8974 Compr3",
+ .stream_name = "COMPR3",
+ .cpu_dai_name = "MultiMedia7",
+ .platform_name = "msm-compr-dsp",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7,
+ },
+ {
+ .name = "MSM8974 Compr4",
+ .stream_name = "COMPR4",
+ .cpu_dai_name = "MultiMedia8",
+ .platform_name = "msm-compr-dsp",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
+ },
/* Backend BT/FM DAI Links */
{
.name = LPASS_BE_INT_BT_SCO_RX,
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index bb13695..60f4669 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -1058,7 +1058,9 @@
}
/* Set encoder properties. */
switch (common.mvs_info.media_type) {
- case VSS_MEDIA_ID_EVRC_MODEM: {
+ case VSS_MEDIA_ID_EVRC_MODEM:
+ case VSS_MEDIA_ID_4GV_NB_MODEM:
+ case VSS_MEDIA_ID_4GV_WB_MODEM: {
struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
pr_debug("Setting EVRC min-max rate\n");
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.c b/sound/soc/msm/qdsp6v2/audio_acdb.c
index a2e0b87..3b6a415 100644
--- a/sound/soc/msm/qdsp6v2/audio_acdb.c
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.c
@@ -1010,10 +1010,11 @@
case AUDIO_GET_SPEAKER_PROT:
mutex_lock(&acdb_data.acdb_mutex);
/*Indicates calibration was succesfull*/
- if (!acdb_data.spk_prot_cfg.mode) {
+ if (acdb_data.spk_prot_cfg.mode == MSM_SPKR_PROT_CALIBRATED) {
prot_status.r0 = acdb_data.spk_prot_cfg.r0;
prot_status.status = 0;
- } else if (acdb_data.spk_prot_cfg.mode == 1) {
+ } else if (acdb_data.spk_prot_cfg.mode ==
+ MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) {
/*Call AFE to query the status*/
acdb_spk_status.status = -EINVAL;
acdb_spk_status.r0 = -1;
@@ -1021,7 +1022,8 @@
prot_status.r0 = acdb_spk_status.r0;
prot_status.status = acdb_spk_status.status;
if (!acdb_spk_status.status) {
- acdb_data.spk_prot_cfg.mode = 0;
+ acdb_data.spk_prot_cfg.mode =
+ MSM_SPKR_PROT_CALIBRATED;
acdb_data.spk_prot_cfg.r0 = prot_status.r0;
}
} else {
@@ -1206,7 +1208,7 @@
{
memset(&acdb_data, 0, sizeof(acdb_data));
/*Speaker protection disabled*/
- acdb_data.spk_prot_cfg.mode = -1;
+ acdb_data.spk_prot_cfg.mode = MSM_SPKR_PROT_DISABLED;
mutex_init(&acdb_data.acdb_mutex);
atomic_set(&usage_count, 0);
atomic_set(&acdb_data.valid_adm_custom_top, 1);
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
index ec5359c..620f667 100644
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
@@ -497,6 +497,10 @@
if (!atomic_cmpxchg(&compressed_audio.audio_ocmem_req,
0, 1))
audio_ocmem_process_req(AUDIO, true);
+ else
+ atomic_inc(&compressed_audio.audio_ocmem_req);
+ pr_debug("%s: req: %d\n", __func__,
+ atomic_read(&compressed_audio.audio_ocmem_req));
}
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
@@ -619,7 +623,6 @@
populate_codec_list(compr, runtime);
runtime->private_data = compr;
atomic_set(&prtd->eos, 0);
- atomic_set(&compressed_audio.audio_ocmem_req, 0);
compressed_audio.prtd = &compr->prtd;
return 0;
@@ -653,8 +656,14 @@
dir = IN;
atomic_set(&prtd->pending_buffer, 0);
- if (atomic_cmpxchg(&compressed_audio.audio_ocmem_req, 1, 0))
+
+ if (atomic_read(&compressed_audio.audio_ocmem_req) > 1)
+ atomic_dec(&compressed_audio.audio_ocmem_req);
+ else if (atomic_cmpxchg(&compressed_audio.audio_ocmem_req, 1, 0))
audio_ocmem_process_req(AUDIO, false);
+
+ pr_debug("%s: req: %d\n", __func__,
+ atomic_read(&compressed_audio.audio_ocmem_req));
prtd->pcm_irq_pos = 0;
q6asm_cmd(prtd->audio_client, CMD_CLOSE);
compressed_audio.prtd = NULL;
@@ -1171,6 +1180,8 @@
dev_info(&pdev->dev, "%s: dev name %s\n",
__func__, dev_name(&pdev->dev));
+
+ atomic_set(&compressed_audio.audio_ocmem_req, 0);
return snd_soc_register_platform(&pdev->dev,
&msm_soc_platform);
}
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 643f280..70db200 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -257,6 +257,12 @@
{INVALID_SESSION, INVALID_SESSION},
/* MULTIMEDIA5 */
{INVALID_SESSION, INVALID_SESSION},
+ /* MULTIMEDIA6 */
+ {INVALID_SESSION, INVALID_SESSION},
+ /* MULTIMEDIA7 */
+ {INVALID_SESSION, INVALID_SESSION},
+ /* MULTIMEDIA8 */
+ {INVALID_SESSION, INVALID_SESSION},
};
static uint8_t is_be_dai_extproc(int be_dai)
@@ -379,6 +385,10 @@
else if (msm_bedais[i].format ==
SNDRV_PCM_FORMAT_S24_LE)
bits_per_sample = 24;
+
+ if (msm_bedais[i].port_id == VOICE_RECORD_RX ||
+ msm_bedais[i].port_id == VOICE_RECORD_TX)
+ topology = DEFAULT_COPP_TOPOLOGY;
if ((stream_type == SNDRV_PCM_STREAM_PLAYBACK) &&
(channels > 0))
adm_multi_ch_copp_open(msm_bedais[i].port_id,
@@ -508,6 +518,10 @@
if (msm_bedais[reg].format == SNDRV_PCM_FORMAT_S24_LE)
bits_per_sample = 24;
+ if (msm_bedais[reg].port_id == VOICE_RECORD_RX ||
+ msm_bedais[reg].port_id == VOICE_RECORD_TX)
+ topology = DEFAULT_COPP_TOPOLOGY;
+
if ((session_type == SESSION_TYPE_RX) &&
(channels > 0)) {
perf_mode = test_bit(val,
@@ -1345,6 +1359,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_I2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = {
@@ -1363,6 +1386,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_I2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
@@ -1381,6 +1413,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = {
@@ -1399,6 +1440,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = {
@@ -1417,6 +1467,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = {
@@ -1450,6 +1509,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mi2s_hl_mixer_controls[] = {
@@ -1477,6 +1545,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
@@ -1495,6 +1572,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
/* incall music delivery mixer */
static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = {
@@ -1531,6 +1617,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_BT_SCO_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
@@ -1549,6 +1644,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_FM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT_FM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT_FM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT_FM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
@@ -1567,6 +1671,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AFE_PCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
@@ -1585,6 +1698,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = {
@@ -1603,6 +1725,15 @@
SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
@@ -2555,6 +2686,9 @@
SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
@@ -2855,6 +2989,9 @@
{"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"PRI_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"PRI_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"PRI_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"PRI_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
{"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
{"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -2862,6 +2999,9 @@
{"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"SEC_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SEC_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SEC_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SEC_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
{"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -2869,6 +3009,9 @@
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SLIMBUS_0_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SLIMBUS_0_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SLIMBUS_0_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
{"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
{"HDMI Mixer", "MultiMedia1", "MM_DL1"},
@@ -2876,6 +3019,9 @@
{"HDMI Mixer", "MultiMedia3", "MM_DL3"},
{"HDMI Mixer", "MultiMedia4", "MM_DL4"},
{"HDMI Mixer", "MultiMedia5", "MM_DL5"},
+ {"HDMI Mixer", "MultiMedia6", "MM_DL6"},
+ {"HDMI Mixer", "MultiMedia7", "MM_DL7"},
+ {"HDMI Mixer", "MultiMedia8", "MM_DL8"},
{"HDMI", NULL, "HDMI Mixer"},
/* incall */
@@ -2896,6 +3042,9 @@
{"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
{"MI2S_RX", NULL, "MI2S_RX Audio Mixer"},
{"QUAT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -2948,6 +3097,9 @@
{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
{"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -2955,6 +3107,9 @@
{"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"INTERNAL_FM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"INTERNAL_FM_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"INTERNAL_FM_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"INTERNAL_FM_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
{"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
{"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -2962,6 +3117,9 @@
{"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"AFE_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"AFE_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"AFE_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"AFE_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
{"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
{"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
@@ -2982,6 +3140,9 @@
{"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
{"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
{"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -2989,6 +3150,9 @@
{"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
{"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX Audio Mixer"},
{"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
@@ -3348,6 +3512,10 @@
if (bedai->format == SNDRV_PCM_FORMAT_S24_LE)
bits_per_sample = 24;
+ if (bedai->port_id == VOICE_RECORD_RX ||
+ bedai->port_id == VOICE_RECORD_TX)
+ topology = DEFAULT_COPP_TOPOLOGY;
+
if ((playback) && (channels > 0)) {
perf_mode = test_bit(i, &(bedai->perf_mode));
adm_multi_ch_copp_open(bedai->port_id,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index 4a58369..9750756 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -67,6 +67,9 @@
MSM_FRONTEND_DAI_MULTIMEDIA3,
MSM_FRONTEND_DAI_MULTIMEDIA4,
MSM_FRONTEND_DAI_MULTIMEDIA5,
+ MSM_FRONTEND_DAI_MULTIMEDIA6,
+ MSM_FRONTEND_DAI_MULTIMEDIA7,
+ MSM_FRONTEND_DAI_MULTIMEDIA8,
MSM_FRONTEND_DAI_CS_VOICE,
MSM_FRONTEND_DAI_VOIP,
MSM_FRONTEND_DAI_AFE_RX,
@@ -79,8 +82,8 @@
MSM_FRONTEND_DAI_MAX,
};
-#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA5 + 1)
-#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA5
+#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA8 + 1)
+#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA8
enum {
MSM_BACKEND_DAI_PRI_I2S_RX = 0,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
index 25bb72f..5485440 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
@@ -281,6 +281,58 @@
return ret;
}
+static int msm_pcm_ioctl(struct snd_pcm_substream *substream,
+ unsigned int cmd, void *arg)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct msm_voice *prtd = runtime->private_data;
+ uint16_t session_id = get_session_id(prtd);
+ enum voice_lch_mode lch_mode;
+ int ret = 0;
+
+ switch (cmd) {
+ case SNDRV_VOICE_IOCTL_LCH:
+ if (copy_from_user(&lch_mode, (void *)arg,
+ sizeof(enum voice_lch_mode))) {
+ pr_err("%s: Copy from user failed, size %d\n", __func__,
+ sizeof(enum voice_lch_mode));
+
+ ret = -EFAULT;
+ break;
+ }
+
+ pr_debug("%s: %s lch_mode:%d\n",
+ __func__, substream->pcm->id, lch_mode);
+
+ switch (lch_mode) {
+ case VOICE_LCH_START:
+ case VOICE_LCH_STOP:
+ ret = voc_set_lch(session_id, lch_mode);
+ break;
+
+ default:
+ pr_err("%s: Invalid LCH MODE %d\n", __func__, lch_mode);
+
+ ret = -EFAULT;
+ }
+
+ break;
+ default:
+ pr_debug("%s: Falling into default snd_lib_ioctl cmd 0x%x\n",
+ __func__, cmd);
+
+ ret = snd_pcm_lib_ioctl(substream, cmd, arg);
+ break;
+ }
+
+ if (!ret)
+ pr_debug("%s: ret %d\n", __func__, ret);
+ else
+ pr_err("%s: cmd 0x%x failed %d\n", __func__, cmd, ret);
+
+ return ret;
+}
+
static int msm_voice_volume_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -476,29 +528,6 @@
return 0;
}
-static int msm_voice_widevoice_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int wv_enable = ucontrol->value.integer.value[0];
-
- pr_debug("%s: wv enable=%d\n", __func__, wv_enable);
-
- voc_set_widevoice_enable(voc_get_session_id(VOICE_SESSION_NAME),
- wv_enable);
- voc_set_widevoice_enable(voc_get_session_id(VOICE2_SESSION_NAME),
- wv_enable);
-
- return 0;
-}
-
-static int msm_voice_widevoice_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] =
- voc_get_widevoice_enable(voc_get_session_id(VOICE_SESSION_NAME));
- return 0;
-}
-
static int msm_voice_slowtalk_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -524,30 +553,6 @@
return 0;
}
-static int msm_voice_fens_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int fens_enable = ucontrol->value.integer.value[0];
-
- pr_debug("%s: fens enable=%d\n", __func__, fens_enable);
-
- voc_set_pp_enable(voc_get_session_id(VOICE_SESSION_NAME),
- MODULE_ID_VOICE_MODULE_FENS, fens_enable);
- voc_set_pp_enable(voc_get_session_id(VOICE2_SESSION_NAME),
- MODULE_ID_VOICE_MODULE_FENS, fens_enable);
-
- return 0;
-}
-
-static int msm_voice_fens_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] =
- voc_get_pp_enable(voc_get_session_id(VOICE_SESSION_NAME),
- MODULE_ID_VOICE_MODULE_FENS);
- return 0;
-}
-
static struct snd_kcontrol_new msm_voice_controls[] = {
SOC_SINGLE_EXT("Voice Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
msm_voice_rx_device_mute_get,
@@ -558,12 +563,8 @@
msm_voice_volume_get, msm_voice_volume_put),
SOC_ENUM_EXT("TTY Mode", msm_tty_mode_enum[0], msm_voice_tty_mode_get,
msm_voice_tty_mode_put),
- SOC_SINGLE_EXT("Widevoice Enable", SND_SOC_NOPM, 0, 1, 0,
- msm_voice_widevoice_get, msm_voice_widevoice_put),
SOC_SINGLE_EXT("Slowtalk Enable", SND_SOC_NOPM, 0, 1, 0,
msm_voice_slowtalk_get, msm_voice_slowtalk_put),
- SOC_SINGLE_EXT("FENS Enable", SND_SOC_NOPM, 0, 1, 0,
- msm_voice_fens_get, msm_voice_fens_put),
SOC_SINGLE_EXT("VoLTE Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
msm_volte_rx_device_mute_get,
msm_volte_rx_device_mute_put),
@@ -581,11 +582,12 @@
};
static struct snd_pcm_ops msm_pcm_ops = {
- .open = msm_pcm_open,
- .hw_params = msm_pcm_hw_params,
- .close = msm_pcm_close,
- .prepare = msm_pcm_prepare,
- .trigger = msm_pcm_trigger,
+ .open = msm_pcm_open,
+ .hw_params = msm_pcm_hw_params,
+ .close = msm_pcm_close,
+ .prepare = msm_pcm_prepare,
+ .trigger = msm_pcm_trigger,
+ .ioctl = msm_pcm_ioctl,
};
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
index b5ce28f..9b3cc8d 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
@@ -1145,6 +1145,7 @@
static const struct of_device_id msm_voip_dt_match[] = {
{.compatible = "qcom,msm-voip-dsp"},
+ {}
};
MODULE_DEVICE_TABLE(of, msm_voip_dt_match);
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index ce5e816..f05f772 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -56,6 +56,9 @@
#define TIMEOUT_MS 1000
#define Q6AFE_MAX_VOLUME 0x3FFF
+#define Q6AFE_MSM_SPKR_PROCESSING 0
+#define Q6AFE_MSM_SPKR_CALIBRATION 1
+
static int pcm_afe_instance[2];
static int proxy_afe_instance[2];
bool afe_close_done[2] = {true, true};
@@ -515,25 +518,31 @@
/*Get spkr protection cfg data*/
get_spk_protection_cfg(&prot_cfg);
- if ((!prot_cfg.mode || prot_cfg.mode == 1) &&
+ if ((prot_cfg.mode != MSM_SPKR_PROT_DISABLED) &&
(this_afe.vi_tx_port == port_id)) {
afe_spk_config.mode_rx_cfg.minor_version = 1;
- afe_spk_config.mode_rx_cfg.mode =
- (uint32_t)prot_cfg.mode;
+ if (prot_cfg.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
+ afe_spk_config.mode_rx_cfg.mode =
+ Q6AFE_MSM_SPKR_CALIBRATION;
+ else
+ afe_spk_config.mode_rx_cfg.mode =
+ Q6AFE_MSM_SPKR_PROCESSING;
if (afe_spk_prot_prepare(port_id,
AFE_PARAM_ID_MODE_VI_PROC_CFG,
&afe_spk_config))
pr_err("%s TX VI_PROC_CFG failed\n", __func__);
- afe_spk_config.vi_proc_cfg.minor_version = 1;
- afe_spk_config.vi_proc_cfg.r0_cali_q24 =
- (uint32_t) prot_cfg.r0;
- afe_spk_config.vi_proc_cfg.t0_cali_q6 =
- (uint32_t) prot_cfg.t0;
- if (afe_spk_prot_prepare(port_id,
- AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG,
- &afe_spk_config))
- pr_err("%s SPKR_CALIB_VI_PROC_CFG failed\n",
- __func__);
+ if (prot_cfg.mode != MSM_SPKR_PROT_NOT_CALIBRATED) {
+ afe_spk_config.vi_proc_cfg.minor_version = 1;
+ afe_spk_config.vi_proc_cfg.r0_cali_q24 =
+ (uint32_t) prot_cfg.r0;
+ afe_spk_config.vi_proc_cfg.t0_cali_q6 =
+ (uint32_t) prot_cfg.t0;
+ if (afe_spk_prot_prepare(port_id,
+ AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG,
+ &afe_spk_config))
+ pr_err("%s SPKR_CALIB_VI_PROC_CFG failed\n",
+ __func__);
+ }
}
}
@@ -545,9 +554,13 @@
/*Get spkr protection cfg data*/
get_spk_protection_cfg(&prot_cfg);
- if (!prot_cfg.mode || prot_cfg.mode == 1) {
- afe_spk_config.mode_rx_cfg.mode =
- (uint32_t)prot_cfg.mode;
+ if (prot_cfg.mode != MSM_SPKR_PROT_DISABLED) {
+ if (prot_cfg.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
+ afe_spk_config.mode_rx_cfg.mode =
+ Q6AFE_MSM_SPKR_CALIBRATION;
+ else
+ afe_spk_config.mode_rx_cfg.mode =
+ Q6AFE_MSM_SPKR_PROCESSING;
afe_spk_config.mode_rx_cfg.minor_version = 1;
if (afe_spk_prot_prepare(port_id,
AFE_PARAM_ID_FBSP_MODE_RX_CFG,
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index e9d0a7e..60999fa 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -82,7 +82,6 @@
static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv);
static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv);
-static int voice_send_set_widevoice_enable_cmd(struct voice_data *v);
static int voice_send_set_pp_enable_cmd(struct voice_data *v,
uint32_t module_id, int enable);
@@ -841,56 +840,6 @@
return -EINVAL;
}
-static int voice_send_set_widevoice_enable_cmd(struct voice_data *v)
-{
- struct mvm_set_widevoice_enable_cmd mvm_set_wv_cmd;
- int ret = 0;
- void *apr_mvm;
- u16 mvm_handle;
-
- if (v == NULL) {
- pr_err("%s: v is NULL\n", __func__);
- return -EINVAL;
- }
- apr_mvm = common.apr_q6_mvm;
-
- if (!apr_mvm) {
- pr_err("%s: apr_mvm is NULL.\n", __func__);
- return -EINVAL;
- }
- mvm_handle = voice_get_mvm_handle(v);
-
- mvm_set_wv_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- mvm_set_wv_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
- sizeof(mvm_set_wv_cmd) -
- APR_HDR_SIZE);
- mvm_set_wv_cmd.hdr.src_port = v->session_id;
- mvm_set_wv_cmd.hdr.dest_port = mvm_handle;
- mvm_set_wv_cmd.hdr.token = 0;
- mvm_set_wv_cmd.hdr.opcode = VSS_IWIDEVOICE_CMD_SET_WIDEVOICE;
-
- mvm_set_wv_cmd.vss_set_wv.enable = v->wv_enable;
-
- v->mvm_state = CMD_STATUS_FAIL;
- ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_wv_cmd);
- if (ret < 0) {
- pr_err("Fail: sending mvm set widevoice enable,\n");
- goto fail;
- }
- ret = wait_event_timeout(v->mvm_wait,
- (v->mvm_state == CMD_STATUS_SUCCESS),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- goto fail;
- }
- return 0;
-fail:
- return -EINVAL;
-}
-
static int voice_send_set_pp_enable_cmd(struct voice_data *v,
uint32_t module_id, int enable)
{
@@ -1207,7 +1156,9 @@
}
/* Set encoder properties. */
switch (common.mvs_info.media_type) {
- case VSS_MEDIA_ID_EVRC_MODEM: {
+ case VSS_MEDIA_ID_EVRC_MODEM:
+ case VSS_MEDIA_ID_4GV_NB_MODEM:
+ case VSS_MEDIA_ID_4GV_WB_MODEM: {
struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
pr_debug("Setting EVRC min-max rate\n");
@@ -1442,6 +1393,34 @@
return -EINVAL;
}
+static void voc_get_tx_rx_topology(struct voice_data *v,
+ uint32_t *tx_topology_id,
+ uint32_t *rx_topology_id)
+{
+ uint32_t tx_id = 0;
+ uint32_t rx_id = 0;
+
+ if (v->lch_mode == VOICE_LCH_START) {
+ pr_debug("%s: Setting TX and RX topology to NONE for LCH\n",
+ __func__);
+
+ tx_id = VSS_IVOCPROC_TOPOLOGY_ID_NONE;
+ rx_id = VSS_IVOCPROC_TOPOLOGY_ID_NONE;
+ } else {
+ /* Use default topology if invalid value in ACDB */
+ tx_id = get_voice_tx_topology();
+ if (tx_id == 0)
+ tx_id = VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
+
+ rx_id = get_voice_rx_topology();
+ if (rx_id == 0)
+ rx_id = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
+ }
+
+ *tx_topology_id = tx_id;
+ *rx_topology_id = rx_id;
+}
+
static int voice_send_set_device_cmd(struct voice_data *v)
{
struct cvp_set_device_cmd cvp_setdev_cmd;
@@ -1472,26 +1451,22 @@
cvp_setdev_cmd.hdr.src_port = v->session_id;
cvp_setdev_cmd.hdr.dest_port = cvp_handle;
cvp_setdev_cmd.hdr.token = 0;
- cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
+ cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE_V2;
- /* Use default topology if invalid value in ACDB */
- cvp_setdev_cmd.cvp_set_device.tx_topology_id =
- get_voice_tx_topology();
- if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
- cvp_setdev_cmd.cvp_set_device.tx_topology_id =
- VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
+ voc_get_tx_rx_topology(v,
+ &cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id,
+ &cvp_setdev_cmd.cvp_set_device_v2.rx_topology_id);
- cvp_setdev_cmd.cvp_set_device.rx_topology_id =
- get_voice_rx_topology();
- if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
- cvp_setdev_cmd.cvp_set_device.rx_topology_id =
- VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
- cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
- cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
+ cvp_setdev_cmd.cvp_set_device_v2.tx_port_id = v->dev_tx.port_id;
+ cvp_setdev_cmd.cvp_set_device_v2.rx_port_id = v->dev_rx.port_id;
+ cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
+ VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
+ cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
+ VSS_IVOCPROC_PORT_ID_NONE;
pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
- cvp_setdev_cmd.cvp_set_device.tx_topology_id,
- cvp_setdev_cmd.cvp_set_device.tx_port_id,
- cvp_setdev_cmd.cvp_set_device.rx_port_id);
+ cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id,
+ cvp_setdev_cmd.cvp_set_device_v2.tx_port_id,
+ cvp_setdev_cmd.cvp_set_device_v2.rx_port_id);
v->cvp_state = CMD_STATUS_FAIL;
ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
@@ -2247,18 +2222,9 @@
cvp_session_cmd.hdr.opcode =
VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V2;
- /* Use default topology if invalid value in ACDB */
- cvp_session_cmd.cvp_session.tx_topology_id =
- get_voice_tx_topology();
- if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
- cvp_session_cmd.cvp_session.tx_topology_id =
- VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
-
- cvp_session_cmd.cvp_session.rx_topology_id =
- get_voice_rx_topology();
- if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
- cvp_session_cmd.cvp_session.rx_topology_id =
- VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
+ voc_get_tx_rx_topology(v,
+ &cvp_session_cmd.cvp_session.tx_topology_id,
+ &cvp_session_cmd.cvp_session.rx_topology_id);
cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
@@ -2327,20 +2293,11 @@
voice_send_netid_timing_cmd(v);
}
- /* enable widevoice if wv_enable is set */
- if (v->wv_enable)
- voice_send_set_widevoice_enable_cmd(v);
-
/* enable slowtalk if st_enable is set */
if (v->st_enable)
voice_send_set_pp_enable_cmd(v,
MODULE_ID_VOICE_MODULE_ST,
v->st_enable);
-
- voice_send_set_pp_enable_cmd(v,
- MODULE_ID_VOICE_MODULE_FENS,
- v->fens_enable);
-
/* Start in-call music delivery if this feature is enabled */
if (v->music_info.play_enable)
voice_cvs_start_playback(v);
@@ -2643,6 +2600,9 @@
if (v->dtmf_rx_detect_en)
voice_send_dtmf_rx_detection_cmd(v, 0);
+ /* reset LCH mode */
+ v->lch_mode = 0;
+
/* detach VOCPROC and wait for response from mvm */
mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE),
@@ -2882,7 +2842,7 @@
return -EINVAL;
}
-static int voice_send_mute_cmd(struct voice_data *v)
+static int voice_send_stream_mute_cmd(struct voice_data *v)
{
struct cvs_set_mute_cmd cvs_mute_cmd;
int ret = 0;
@@ -2910,7 +2870,7 @@
cvs_mute_cmd.hdr.token = 0;
cvs_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
cvs_mute_cmd.cvs_set_mute.direction = VSS_IVOLUME_DIRECTION_TX;
- cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
+ cvs_mute_cmd.cvs_set_mute.mute_flag = v->stream_tx.stream_mute;
cvs_mute_cmd.cvs_set_mute.ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
v->cvs_state = CMD_STATUS_FAIL;
@@ -2935,7 +2895,8 @@
return -EINVAL;
}
-static int voice_send_rx_device_mute_cmd(struct voice_data *v)
+static int voice_send_device_mute_cmd(struct voice_data *v, uint16_t direction,
+ uint16_t mute_flag)
{
struct cvp_set_mute_cmd cvp_mute_cmd;
int ret = 0;
@@ -2961,8 +2922,8 @@
cvp_mute_cmd.hdr.dest_port = voice_get_cvp_handle(v);
cvp_mute_cmd.hdr.token = 0;
cvp_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
- cvp_mute_cmd.cvp_set_mute.direction = VSS_IVOLUME_DIRECTION_RX;
- cvp_mute_cmd.cvp_set_mute.mute_flag = v->dev_rx.mute;
+ cvp_mute_cmd.cvp_set_mute.direction = direction;
+ cvp_mute_cmd.cvp_set_mute.mute_flag = mute_flag;
cvp_mute_cmd.cvp_set_mute.ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
v->cvp_state = CMD_STATUS_FAIL;
@@ -3491,7 +3452,7 @@
int ret = 0;
if (v == NULL) {
- pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+ pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);
return -EINVAL;
}
@@ -3501,7 +3462,7 @@
if (v->voc_state == VOC_CHANGE) {
ret = voice_send_set_device_cmd(v);
if (ret < 0) {
- pr_err("%s: set device failed\n", __func__);
+ pr_err("%s: Set device failed\n", __func__);
goto fail;
}
@@ -3509,31 +3470,45 @@
voice_send_cvp_register_cal_cmd(v);
voice_send_cvp_register_vol_cal_cmd(v);
+ if (v->lch_mode == VOICE_LCH_START) {
+ pr_debug("%s: TX and RX mute ON\n", __func__);
+
+ voice_send_device_mute_cmd(v,
+ VSS_IVOLUME_DIRECTION_TX,
+ VSS_IVOLUME_MUTE_ON);
+ voice_send_device_mute_cmd(v,
+ VSS_IVOLUME_DIRECTION_RX,
+ VSS_IVOLUME_MUTE_ON);
+ } else if (v->lch_mode == VOICE_LCH_STOP) {
+ pr_debug("%s: TX and RX mute OFF\n", __func__);
+
+ voice_send_device_mute_cmd(v,
+ VSS_IVOLUME_DIRECTION_TX,
+ VSS_IVOLUME_MUTE_OFF);
+ voice_send_device_mute_cmd(v,
+ VSS_IVOLUME_DIRECTION_RX,
+ VSS_IVOLUME_MUTE_OFF);
+ /* Reset lch mode when VOICE_LCH_STOP is recieved */
+ v->lch_mode = 0;
+ } else {
+ pr_debug("%s: Mute commands not sent for lch_mode=%d\n",
+ __func__, v->lch_mode);
+ }
+
ret = voice_send_enable_vocproc_cmd(v);
if (ret < 0) {
- pr_err("%s: enable vocproc failed %d\n", __func__, ret);
+ pr_err("%s: Enable vocproc failed %d\n", __func__, ret);
+
goto fail;
}
/* Send tty mode if tty device is used */
voice_send_tty_mode_cmd(v);
-
- /* enable widevoice if wv_enable is set */
- if (v->wv_enable)
- voice_send_set_widevoice_enable_cmd(v);
-
/* enable slowtalk */
if (v->st_enable)
voice_send_set_pp_enable_cmd(v,
MODULE_ID_VOICE_MODULE_ST,
v->st_enable);
-
- /* enable FENS */
- if (v->fens_enable)
- voice_send_set_pp_enable_cmd(v,
- MODULE_ID_VOICE_MODULE_FENS,
- v->fens_enable);
-
rtac_add_voice(voice_get_cvs_handle(v),
voice_get_cvp_handle(v),
v->dev_rx.port_id, v->dev_tx.port_id,
@@ -3591,12 +3566,12 @@
mutex_lock(&v->lock);
- v->dev_tx.mute = mute;
+ v->stream_tx.stream_mute = mute;
if ((v->voc_state == VOC_RUN) ||
(v->voc_state == VOC_CHANGE) ||
(v->voc_state == VOC_STANDBY))
- ret = voice_send_mute_cmd(v);
+ ret = voice_send_stream_mute_cmd(v);
mutex_unlock(&v->lock);
@@ -3616,10 +3591,12 @@
mutex_lock(&v->lock);
- v->dev_rx.mute = mute;
+ v->dev_rx.dev_mute = mute;
if (v->voc_state == VOC_RUN)
- ret = voice_send_rx_device_mute_cmd(v);
+ ret = voice_send_device_mute_cmd(v,
+ VSS_IVOLUME_DIRECTION_RX,
+ v->dev_rx.dev_mute);
mutex_unlock(&v->lock);
@@ -3639,7 +3616,7 @@
mutex_lock(&v->lock);
- ret = v->dev_rx.mute;
+ ret = v->dev_rx.dev_mute;
mutex_unlock(&v->lock);
@@ -3686,51 +3663,6 @@
return ret;
}
-int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable)
-{
- struct voice_data *v = voice_get_session(session_id);
- u16 mvm_handle;
- int ret = 0;
-
- if (v == NULL) {
- pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
-
- return -EINVAL;
- }
-
- mutex_lock(&v->lock);
-
- v->wv_enable = wv_enable;
-
- mvm_handle = voice_get_mvm_handle(v);
- if (mvm_handle != 0)
- voice_send_set_widevoice_enable_cmd(v);
-
- mutex_unlock(&v->lock);
-
- return ret;
-}
-
-uint32_t voc_get_widevoice_enable(uint16_t session_id)
-{
- struct voice_data *v = voice_get_session(session_id);
- int ret = 0;
-
- if (v == NULL) {
- pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
-
- return -EINVAL;
- }
-
- mutex_lock(&v->lock);
-
- ret = v->wv_enable;
-
- mutex_unlock(&v->lock);
-
- return ret;
-}
-
int voc_set_pp_enable(uint16_t session_id, uint32_t module_id, uint32_t enable)
{
struct voice_data *v = voice_get_session(session_id);
@@ -3745,18 +3677,12 @@
mutex_lock(&v->lock);
if (module_id == MODULE_ID_VOICE_MODULE_ST)
v->st_enable = enable;
- else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
- v->fens_enable = enable;
if (v->voc_state == VOC_RUN) {
if (module_id == MODULE_ID_VOICE_MODULE_ST)
ret = voice_send_set_pp_enable_cmd(v,
MODULE_ID_VOICE_MODULE_ST,
enable);
- else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
- ret = voice_send_set_pp_enable_cmd(v,
- MODULE_ID_VOICE_MODULE_FENS,
- enable);
}
mutex_unlock(&v->lock);
@@ -3778,9 +3704,6 @@
mutex_lock(&v->lock);
if (module_id == MODULE_ID_VOICE_MODULE_ST)
ret = v->st_enable;
- else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
- ret = v->fens_enable;
-
mutex_unlock(&v->lock);
return ret;
@@ -3958,6 +3881,49 @@
return ret;
}
+int voc_set_lch(uint16_t session_id, enum voice_lch_mode lch_mode)
+{
+ struct voice_data *v = voice_get_session(session_id);
+ int ret = 0;
+
+ if (v == NULL) {
+ pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);
+
+ ret = -EINVAL;
+ goto done;
+ }
+
+ mutex_lock(&v->lock);
+ if (v->lch_mode == lch_mode) {
+ pr_debug("%s: Session %d already in LCH mode %d\n",
+ __func__, session_id, lch_mode);
+
+ mutex_unlock(&v->lock);
+ goto done;
+ }
+
+ v->lch_mode = lch_mode;
+ mutex_unlock(&v->lock);
+
+ ret = voc_disable_cvp(session_id);
+ if (ret < 0) {
+ pr_err("%s: voc_disable_cvp failed ret=%d\n", __func__, ret);
+
+ goto done;
+ }
+
+ /* Mute and topology_none will be set as part of voc_enable_cvp() */
+ ret = voc_enable_cvp(session_id);
+ if (ret < 0) {
+ pr_err("%s: voc_enable_cvp failed ret=%d\n", __func__, ret);
+
+ goto done;
+ }
+
+done:
+ return ret;
+}
+
int voc_resume_voice_call(uint16_t session_id)
{
struct voice_data *v = voice_get_session(session_id);
@@ -4179,7 +4145,6 @@
case VSS_IMVM_CMD_DETACH_STREAM:
case VSS_ICOMMON_CMD_SET_NETWORK:
case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
- case VSS_IWIDEVOICE_CMD_SET_WIDEVOICE:
case VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL:
case VSS_IMVM_CMD_SET_CAL_NETWORK:
case VSS_IMVM_CMD_SET_CAL_MEDIA_TYPE:
@@ -4578,7 +4543,7 @@
v->cvp_state = CMD_STATUS_SUCCESS;
wake_up(&v->cvp_wait);
break;
- case VSS_IVOCPROC_CMD_SET_DEVICE:
+ case VSS_IVOCPROC_CMD_SET_DEVICE_V2:
case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
case VSS_IVOCPROC_CMD_ENABLE:
case VSS_IVOCPROC_CMD_DISABLE:
@@ -4767,13 +4732,16 @@
/* initialize dev_rx and dev_tx */
common.voice[i].dev_rx.volume = common.default_vol_val;
- common.voice[i].dev_rx.mute = 0;
- common.voice[i].dev_tx.mute = common.default_mute_val;
+ common.voice[i].dev_rx.dev_mute = 0;
+ common.voice[i].dev_tx.dev_mute = 0;
+ common.voice[i].stream_rx.stream_mute = common.default_mute_val;
+ common.voice[i].stream_tx.stream_mute = common.default_mute_val;
common.voice[i].dev_tx.port_id = 0x100B;
common.voice[i].dev_rx.port_id = 0x100A;
common.voice[i].sidetone_gain = 0x512;
common.voice[i].dtmf_rx_detect_en = 0;
+ common.voice[i].lch_mode = 0;
common.voice[i].voc_state = VOC_INIT;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index ef5c6e3..386634b 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -14,6 +14,7 @@
#include <mach/qdsp6v2/apr.h>
#include <linux/msm_ion.h>
+#include <sound/voice_params.h>
#define MAX_VOC_PKT_SIZE 642
#define SESSION_NAME_LEN 20
@@ -41,11 +42,15 @@
void *cb_handle;
};
-/* Device information payload structure */
+/* Stream information payload structure */
+struct stream_data {
+ uint32_t stream_mute;
+};
+/* Device information payload structure */
struct device_data {
uint32_t volume; /* in index */
- uint32_t mute;
+ uint32_t dev_mute;
uint32_t sample;
uint32_t enabled;
uint32_t dev_id;
@@ -194,9 +199,6 @@
#define VSS_ICOMMON_CMD_SET_VOICE_TIMING 0x000111E0
/* Set the voice timing parameters. */
-#define VSS_IWIDEVOICE_CMD_SET_WIDEVOICE 0x00011243
-/* Enable/disable WideVoice */
-
#define VSS_IMEMORY_CMD_MAP_PHYSICAL 0x00011334
#define VSS_IMEMORY_RSP_MAP 0x00011336
#define VSS_IMEMORY_CMD_UNMAP 0x00011337
@@ -291,14 +293,6 @@
/* Set to TRUE to enable modem state machine control */
} __packed;
-struct vss_iwidevoice_cmd_set_widevoice_t {
- uint32_t enable;
- /* WideVoice enable/disable; possible values:
- * - 0 -- WideVoice disabled
- * - 1 -- WideVoice enabled
- */
-} __packed;
-
struct mvm_attach_vocproc_cmd {
struct apr_hdr hdr;
struct vss_istream_cmd_attach_vocproc_t mvm_attach_cvp_handle;
@@ -344,11 +338,6 @@
struct vss_icommon_cmd_set_voice_timing_t timing;
} __packed;
-struct mvm_set_widevoice_enable_cmd {
- struct apr_hdr hdr;
- struct vss_iwidevoice_cmd_set_widevoice_t vss_set_wv;
-} __packed;
-
struct vss_imemory_table_descriptor_t {
uint64_t mem_address;
/*
@@ -484,7 +473,6 @@
#define VSS_ISTREAM_CMD_SET_ENC_DTX_MODE 0x0001101D
/* Set encoder DTX mode. */
-#define MODULE_ID_VOICE_MODULE_FENS 0x00010EEB
#define MODULE_ID_VOICE_MODULE_ST 0x00010EE3
#define VOICE_PARAM_MOD_ENABLE 0x00010E00
#define MOD_ENABLE_PARAM_LEN 4
@@ -904,7 +892,7 @@
#define APRV2_IBASIC_CMD_DESTROY_SESSION 0x0001003C
-#define VSS_IVOCPROC_CMD_SET_DEVICE 0x000100C4
+#define VSS_IVOCPROC_CMD_SET_DEVICE_V2 0x000112C6
#define VSS_IVOCPROC_CMD_SET_VP3_DATA 0x000110EB
@@ -1042,8 +1030,8 @@
*/
} __packed;
-struct vss_ivocproc_cmd_set_device_t {
- uint32_t tx_port_id;
+struct vss_ivocproc_cmd_set_device_v2_t {
+ uint16_t tx_port_id;
/*
* TX device port ID which vocproc will connect to.
* VSS_IVOCPROC_PORT_ID_NONE means vocproc will not connect to any port.
@@ -1054,7 +1042,7 @@
* VSS_IVOCPROC_TOPOLOGY_ID_NONE means vocproc does not contain any
* pre/post-processing blocks and is pass-through.
*/
- int32_t rx_port_id;
+ uint16_t rx_port_id;
/*
* RX device port ID which vocproc will connect to.
* VSS_IVOCPROC_PORT_ID_NONE means vocproc will not connect to any port.
@@ -1065,6 +1053,15 @@
* VSS_IVOCPROC_TOPOLOGY_ID_NONE means vocproc does not contain any
* pre/post-processing blocks and is pass-through.
*/
+ uint32_t vocproc_mode;
+ /* Vocproc mode. The supported values:
+ * VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING - 0x00010F7C
+ * VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING - 0x00010F7D
+ */
+ uint16_t ec_ref_port_id;
+ /* Port ID to which the vocproc connects for receiving
+ * echo
+ */
} __packed;
struct vss_ivocproc_cmd_register_device_config_t {
@@ -1128,7 +1125,7 @@
struct cvp_set_device_cmd {
struct apr_hdr hdr;
- struct vss_ivocproc_cmd_set_device_t cvp_set_device;
+ struct vss_ivocproc_cmd_set_device_v2_t cvp_set_device_v2;
} __packed;
struct cvp_set_vp3_data_cmd {
@@ -1230,10 +1227,14 @@
wait_queue_head_t cvs_wait;
wait_queue_head_t cvp_wait;
- /* cache the values related to Rx and Tx */
+ /* Cache the values related to Rx and Tx devices */
struct device_data dev_rx;
struct device_data dev_tx;
+ /* Cache the values related to Rx and Tx streams */
+ struct stream_data stream_rx;
+ struct stream_data stream_tx;
+
u32 mvm_state;
u32 cvs_state;
u32 cvp_state;
@@ -1249,14 +1250,11 @@
uint16_t sidetone_gain;
uint8_t tty_mode;
- /* widevoice enable value */
- uint8_t wv_enable;
/* slowtalk enable value */
uint32_t st_enable;
- /* FENC enable value */
- uint32_t fens_enable;
-
uint32_t dtmf_rx_detect_en;
+ /* Local Call Hold mode */
+ uint8_t lch_mode;
struct voice_dev_route_state voc_route_state;
@@ -1345,14 +1343,13 @@
int voc_set_pp_enable(uint16_t session_id, uint32_t module_id,
uint32_t enable);
int voc_get_pp_enable(uint16_t session_id, uint32_t module_id);
-int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable);
-uint32_t voc_get_widevoice_enable(uint16_t session_id);
uint8_t voc_get_tty_mode(uint16_t session_id);
int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode);
int voc_start_voice_call(uint16_t session_id);
int voc_end_voice_call(uint16_t session_id);
int voc_standby_voice_call(uint16_t session_id);
int voc_resume_voice_call(uint16_t session_id);
+int voc_set_lch(uint16_t session_id, enum voice_lch_mode lch_mode);
int voc_set_rxtx_port(uint16_t session_id,
uint32_t dev_port_id,
uint32_t dev_type);