Merge "mmc: sdhci: Fix issues with power IRQ handling"
diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq
index 40f98a9..0ba6ea2 100644
--- a/Documentation/ABI/testing/sysfs-class-devfreq
+++ b/Documentation/ABI/testing/sysfs-class-devfreq
@@ -11,7 +11,7 @@
Date: September 2011
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
- The /sys/class/devfreq/.../governor shows the name of the
+ The /sys/class/devfreq/.../governor show or set the name of the
governor used by the corresponding devfreq object.
What: /sys/class/devfreq/.../cur_freq
@@ -71,3 +71,10 @@
the available frequencies of the corresponding devfreq object.
This is a snapshot of available frequencies and not limited
by the min/max frequency restrictions.
+
+What: /sys/class/devfreq/.../available_governors
+Date: October 2012
+Contact: Nishanth Menon <nm@ti.com>
+Description:
+ The /sys/class/devfreq/.../available_governors shows
+ currently available governors in the system.
diff --git a/Documentation/devicetree/bindings/arm/msm/smp2p.txt b/Documentation/devicetree/bindings/arm/msm/smp2p.txt
index 7a5f506..a7af9e7 100644
--- a/Documentation/devicetree/bindings/arm/msm/smp2p.txt
+++ b/Documentation/devicetree/bindings/arm/msm/smp2p.txt
@@ -2,9 +2,7 @@
Required properties:
-compatible : should be "qcom,smp2p"
--reg : the location and offset of the irq register base memory
--reg-names : "irq-reg-base", "irq-reg-offset" - string to identify the irq
- register region and offset values
+-reg : the location of the irq register base memory
-qcom,remote-pid : the SMP2P remote processor ID (see smp2p_private_api.h)
-qcom,irq-bitmask : the sending irq bitmask
-interrupts : the receiving interrupt line
@@ -13,8 +11,7 @@
qcom,smp2p-modem {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <1>;
qcom,irq-bitmask = <0x4000>;
interrupts = <0 27 1>;
diff --git a/Documentation/devicetree/bindings/crypto/msm/qcedev.txt b/Documentation/devicetree/bindings/crypto/msm/qcedev.txt
index bf97e80..b9a71f6 100644
--- a/Documentation/devicetree/bindings/crypto/msm/qcedev.txt
+++ b/Documentation/devicetree/bindings/crypto/msm/qcedev.txt
@@ -13,6 +13,11 @@
- qcom,msm_bus,num_paths: The paths for source and destination ports
- qcom,msm_bus,vectors: Vectors for bus topology.
+Optional properties:
+ - qcom,ce-hw-shared : optional, indicates if the hardware is shared between EE.
+
+
+
Example:
qcom,qcedev@fd440000 {
@@ -23,6 +28,7 @@
interrupts = <0 235 0>;
qcom,bam-pipe-pair = <0>;
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>;
diff --git a/Documentation/devicetree/bindings/crypto/msm/qcrypto.txt b/Documentation/devicetree/bindings/crypto/msm/qcrypto.txt
index c99262b..59f9879 100644
--- a/Documentation/devicetree/bindings/crypto/msm/qcrypto.txt
+++ b/Documentation/devicetree/bindings/crypto/msm/qcrypto.txt
@@ -13,6 +13,10 @@
- qcom,msm_bus,num_paths: The paths for source and destination ports
- qcom,msm_bus,vectors: Vectors for bus topology.
+Optional properties:
+ - qcom,ce-hw-shared : optional, indicates if the hardware is shared between EE.
+
+
Example:
qcom,qcrypto@fd444000 {
@@ -23,6 +27,7 @@
interrupts = <0 235 0>;
qcom,bam-pipe-pair = <1>;
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>;
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index 17b878c..6b95625 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -10,6 +10,8 @@
- reg-names : names to refer to register sets related to this device
- interrupts : Interrupt associated with MDSS.
- vdd-supply : Phandle for vdd regulator device node.
+- qcom,max-clk-rate: Specify maximum MDP core clock rate in hz that this
+ device supports.
- qcom,mdss-pipe-vig-off: Array of offset for MDP source surface pipes of
type VIG, the offsets are calculated from
register "mdp_phys" defined in reg property.
@@ -115,7 +117,7 @@
reg-names = "mdp_phys", "vbif_phys";
interrupts = <0 72 0>;
vdd-supply = <&gdsc_mdss>;
-
+ qcom,max-clk-rate = <320000000>;
qcom,vbif-settings = <0x0004 0x00000001>,
<0x00D8 0x00000707>;
qcom,mdp-settings = <0x02E0 0x000000AA>,
diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
index 2764657..70f8b55 100644
--- a/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
+++ b/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
@@ -10,7 +10,7 @@
- reg: Pairs of physical base addresses and region sizes of
memory mapped registers.
- reg-names: Names of the bases for the above registers. "qdsp6_base"
- and "halt_base" are expected.
+ "halt_base", and "restart_reg" are expected.
- interrupts: The lpass watchdog interrupt
- vdd_cx-supply: Reference to the regulator that supplies the vdd_cx domain.
- qcom,firmware-name: Base name of the firmware image. Ex. "lpass"
@@ -23,8 +23,9 @@
qcom,lpass@fe200000 {
compatible = "qcom,pil-q6v5-lpass";
reg = <0xfe200000 0x00100>,
- <0xfd485100 0x00010>;
- reg-names = "qdsp6_base", "halt_base";
+ <0xfd485100 0x00010>,
+ <0xfc4016c0 0x00004>;
+ reg-names = "qdsp6_base", "halt_base", "restart_reg";
interrupts = <0 194 1>;
vdd_cx-supply = <&pm8841_s2>;
qcom,firmware-name = "lpass";
diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
index df3f71c..86b3ccb 100644
--- a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
+++ b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
@@ -17,6 +17,8 @@
- vdd_cx-supply: Reference to the regulator that supplies the vdd_cx domain.
- vdd_mx-supply: Reference to the regulator that supplies the memory rail.
- qcom,firmware-name: Base name of the firmware image. Ex. "mdsp"
+- qcom,gpio-err-fatal: GPIO used by the modem to indicate error fatal to the apps.
+- qcom,gpio-force-stop: GPIO used by the apps to force the modem to shutdown.
Optional properties:
- vdd_pll-supply: Reference to the regulator that supplies the PLL's rail.
@@ -44,4 +46,10 @@
qcom,is-loadable;
qcom,firmware-name = "mba";
qcom,pil-self-auth;
+
+ /* GPIO inputs from mss */
+ gpio_err_fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
+
+ /* GPIO output to mss */
+ gpio_force_stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
};
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
new file mode 100644
index 0000000..9ce5421
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -0,0 +1,20 @@
+synopsys DWC3 CORE
+
+DWC3- USB3 CONTROLLER
+
+Required properties:
+ - compatible: must be "synopsys,dwc3"
+ - reg : Address and length of the register set for the device
+ - interrupts: Interrupts used by the dwc3 controller.
+
+Optional properties:
+ - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
+
+This is usually a subnode to DWC3 glue to which it is connected.
+
+dwc3@4a030000 {
+ compatible = "synopsys,dwc3";
+ reg = <0x4a030000 0xcfff>;
+ interrupts = <0 92 4>
+ tx-fifo-resize;
+};
diff --git a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
index 9f8bbd9..1fb2ba9 100644
--- a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
@@ -10,6 +10,19 @@
Required "supply-name" is "HSIC_VDDCX" and optionally - "HSIC_GDSC".
Optional properties :
+- interrupt-parent - This must provide reference to the current
+ device node.
+- #address-cells - Should provide a value of 0.
+- interrupts - Should be <0 1 2> and it is an index to the
+ interrupt-map.
+- #interrupt-cells - should provide a value of 1.
+- #interrupt-mask - should provide a value of 0xffffffff.
+- interrupt-map - Must create mapping for the number of interrupts
+ that are defined in above interrupts property.
+ For HSIC device node, it should define 3 mappings for
+ core_irq, async_irq and wakeup in the format
+ mentioned in below example node of HSIC.
+
- interrupt-names : Optional interrupt resource entries are:
"async_irq" : Interrupt from HSIC for asynchronous events in HSIC LPM.
"wakeup" : Wakeup interrupt from HSIC during suspend (or XO shutdown).
@@ -25,21 +38,45 @@
STROBE GPIO PAD.
- hsic,data-pad-offset : Offset of TLMM register for configuring HSIC
DATA GPIO PAD.
+- Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for
+ below optional properties:
+ - qcom,msm_bus,name
+ - qcom,msm_bus,num_cases
+ - qcom,msm_bus,active_only
+ - qcom,msm_bus,num_paths
+ - qcom,msm_bus,vectors
+
Example MSM HSIC EHCI controller device node :
- hsic@f9a15000 {
+ hsic_host: hsic@f9a15000 {
compatible = "qcom,hsic-host";
reg = <0xf9a15000 0x400>;
- interrupts = <0 136 0>;
- interrupt-names = "core_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&hsic_host>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 136 0
+ 1 &intc 0 148 0
+ 2 &msmgpio 144 0x8>;
+ interrupt-names = "core_irq", "async_irq", "wakeup";
HSIC_VDDCX-supply = <&pm8019_l12>;
HSIC_GDSC-supply = <&gdsc_usb_hsic>;
hsic,strobe-gpio = <&msmgpio 144 0x00>;
hsic,data-gpio = <&msmgpio 145 0x00>;
+ hsic,resume-gpio = <&msmgpio 80 0x00>;
hsic,ignore-cal-pad-config;
hsic,strobe-pad-offset = <0x2050>;
hsic,data-pad-offset = <0x2054>;
- };
+
+ qcom,msm-bus,name = "hsic";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only = <0>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <85 512 0 0>,
+ <85 512 40000 160000>;
+ };
SMSC HSIC HUB
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9a1c759..a5fac80 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -522,7 +522,7 @@
coherent_pool=nn[KMG] [ARM,KNL]
Sets the size of memory pool for coherent, atomic dma
- allocations if Contiguous Memory Allocator (CMA) is used.
+ allocations, by default set to 256K.
code_bytes [X86] How many bytes of object code to print
in an oops report.
diff --git a/arch/arm/boot/dts/dsi-panel-nt35590-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-nt35590-720p-video.dtsi
index f09a78a..2825288 100644
--- a/arch/arm/boot/dts/dsi-panel-nt35590-720p-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-nt35590-720p-video.dtsi
@@ -136,6 +136,371 @@
29 01 00 00 00 02 5E 03
29 01 00 00 00 02 6C 00
29 01 00 00 00 02 6D 00
+ 29 01 00 00 00 02 FB 01
+ 29 01 00 00 00 02 FF 01
+ 29 01 00 00 00 02 FB 01
+ 29 01 00 00 00 02 75 00
+ 29 01 00 00 00 02 76 7D
+ 29 01 00 00 00 02 77 00
+ 29 01 00 00 00 02 78 8A
+ 29 01 00 00 00 02 79 00
+ 29 01 00 00 00 02 7A 9C
+ 29 01 00 00 00 02 7B 00
+ 29 01 00 00 00 02 7C B1
+ 29 01 00 00 00 02 7D 00
+ 29 01 00 00 00 02 7E BF
+ 29 01 00 00 00 02 7F 00
+ 29 01 00 00 00 02 80 CF
+ 29 01 00 00 00 02 81 00
+ 29 01 00 00 00 02 82 DD
+ 29 01 00 00 00 02 83 00
+ 29 01 00 00 00 02 84 E8
+ 29 01 00 00 00 02 85 00
+ 29 01 00 00 00 02 86 F2
+ 29 01 00 00 00 02 87 01
+ 29 01 00 00 00 02 88 1F
+ 29 01 00 00 00 02 89 01
+ 29 01 00 00 00 02 8A 41
+ 29 01 00 00 00 02 8B 01
+ 29 01 00 00 00 02 8C 78
+ 29 01 00 00 00 02 8D 01
+ 29 01 00 00 00 02 8E A5
+ 29 01 00 00 00 02 8F 01
+ 29 01 00 00 00 02 90 EE
+ 29 01 00 00 00 02 91 02
+ 29 01 00 00 00 02 92 29
+ 29 01 00 00 00 02 93 02
+ 29 01 00 00 00 02 94 2A
+ 29 01 00 00 00 02 95 02
+ 29 01 00 00 00 02 96 5D
+ 29 01 00 00 00 02 97 02
+ 29 01 00 00 00 02 98 93
+ 29 01 00 00 00 02 99 02
+ 29 01 00 00 00 02 9A B8
+ 29 01 00 00 00 02 9B 02
+ 29 01 00 00 00 02 9C E7
+ 29 01 00 00 00 02 9D 03
+ 29 01 00 00 00 02 9E 07
+ 29 01 00 00 00 02 9F 03
+ 29 01 00 00 00 02 A0 37
+ 29 01 00 00 00 02 A2 03
+ 29 01 00 00 00 02 A3 46
+ 29 01 00 00 00 02 A4 03
+ 29 01 00 00 00 02 A5 56
+ 29 01 00 00 00 02 A6 03
+ 29 01 00 00 00 02 A7 66
+ 29 01 00 00 00 02 A9 03
+ 29 01 00 00 00 02 AA 7A
+ 29 01 00 00 00 02 AB 03
+ 29 01 00 00 00 02 AC 93
+ 29 01 00 00 00 02 AD 03
+ 29 01 00 00 00 02 AE A3
+ 29 01 00 00 00 02 AF 03
+ 29 01 00 00 00 02 B0 B4
+ 29 01 00 00 00 02 B1 03
+ 29 01 00 00 00 02 B2 CB
+ 29 01 00 00 00 02 B3 00
+ 29 01 00 00 00 02 B4 7D
+ 29 01 00 00 00 02 B5 00
+ 29 01 00 00 00 02 B6 8A
+ 29 01 00 00 00 02 B7 00
+ 29 01 00 00 00 02 B8 9C
+ 29 01 00 00 00 02 B9 00
+ 29 01 00 00 00 02 BA B1
+ 29 01 00 00 00 02 BB 00
+ 29 01 00 00 00 02 BC BF
+ 29 01 00 00 00 02 BD 00
+ 29 01 00 00 00 02 BE CF
+ 29 01 00 00 00 02 BF 00
+ 29 01 00 00 00 02 C0 DD
+ 29 01 00 00 00 02 C1 00
+ 29 01 00 00 00 02 C2 E8
+ 29 01 00 00 00 02 C3 00
+ 29 01 00 00 00 02 C4 F2
+ 29 01 00 00 00 02 C5 01
+ 29 01 00 00 00 02 C6 1F
+ 29 01 00 00 00 02 C7 01
+ 29 01 00 00 00 02 C8 41
+ 29 01 00 00 00 02 C9 01
+ 29 01 00 00 00 02 CA 78
+ 29 01 00 00 00 02 CB 01
+ 29 01 00 00 00 02 CC A5
+ 29 01 00 00 00 02 CD 01
+ 29 01 00 00 00 02 CE EE
+ 29 01 00 00 00 02 CF 02
+ 29 01 00 00 00 02 D0 29
+ 29 01 00 00 00 02 D1 02
+ 29 01 00 00 00 02 D2 2A
+ 29 01 00 00 00 02 D3 02
+ 29 01 00 00 00 02 D4 5D
+ 29 01 00 00 00 02 D5 02
+ 29 01 00 00 00 02 D6 93
+ 29 01 00 00 00 02 D7 02
+ 29 01 00 00 00 02 D8 B8
+ 29 01 00 00 00 02 D9 02
+ 29 01 00 00 00 02 DA E7
+ 29 01 00 00 00 02 DB 03
+ 29 01 00 00 00 02 DC 07
+ 29 01 00 00 00 02 DD 03
+ 29 01 00 00 00 02 DE 37
+ 29 01 00 00 00 02 DF 03
+ 29 01 00 00 00 02 E0 46
+ 29 01 00 00 00 02 E1 03
+ 29 01 00 00 00 02 E2 56
+ 29 01 00 00 00 02 E3 03
+ 29 01 00 00 00 02 E4 66
+ 29 01 00 00 00 02 E5 03
+ 29 01 00 00 00 02 E6 7A
+ 29 01 00 00 00 02 E7 03
+ 29 01 00 00 00 02 E8 93
+ 29 01 00 00 00 02 E9 03
+ 29 01 00 00 00 02 EA A3
+ 29 01 00 00 00 02 EB 03
+ 29 01 00 00 00 02 EC B4
+ 29 01 00 00 00 02 ED 03
+ 29 01 00 00 00 02 EE CB
+ 29 01 00 00 00 02 EF 00
+ 29 01 00 00 00 02 F0 ED
+ 29 01 00 00 00 02 F1 00
+ 29 01 00 00 00 02 F2 F3
+ 29 01 00 00 00 02 F3 00
+ 29 01 00 00 00 02 F4 FE
+ 29 01 00 00 00 02 F5 01
+ 29 01 00 00 00 02 F6 09
+ 29 01 00 00 00 02 F7 01
+ 29 01 00 00 00 02 F8 13
+ 29 01 00 00 00 02 F9 01
+ 29 01 00 00 00 02 FA 1D
+ 29 01 00 00 00 02 FF 02
+ 29 01 00 00 00 02 FB 01
+ 29 01 00 00 00 02 00 01
+ 29 01 00 00 00 02 01 26
+ 29 01 00 00 00 02 02 01
+ 29 01 00 00 00 02 03 2F
+ 29 01 00 00 00 02 04 01
+ 29 01 00 00 00 02 05 37
+ 29 01 00 00 00 02 06 01
+ 29 01 00 00 00 02 07 56
+ 29 01 00 00 00 02 08 01
+ 29 01 00 00 00 02 09 70
+ 29 01 00 00 00 02 0A 01
+ 29 01 00 00 00 02 0B 9D
+ 29 01 00 00 00 02 0C 01
+ 29 01 00 00 00 02 0D C2
+ 29 01 00 00 00 02 0E 01
+ 29 01 00 00 00 02 0F FF
+ 29 01 00 00 00 02 10 02
+ 29 01 00 00 00 02 11 31
+ 29 01 00 00 00 02 12 02
+ 29 01 00 00 00 02 13 32
+ 29 01 00 00 00 02 14 02
+ 29 01 00 00 00 02 15 60
+ 29 01 00 00 00 02 16 02
+ 29 01 00 00 00 02 17 94
+ 29 01 00 00 00 02 18 02
+ 29 01 00 00 00 02 19 B5
+ 29 01 00 00 00 02 1A 02
+ 29 01 00 00 00 02 1B E3
+ 29 01 00 00 00 02 1C 03
+ 29 01 00 00 00 02 1D 03
+ 29 01 00 00 00 02 1E 03
+ 29 01 00 00 00 02 1F 2D
+ 29 01 00 00 00 02 20 03
+ 29 01 00 00 00 02 21 3A
+ 29 01 00 00 00 02 22 03
+ 29 01 00 00 00 02 23 48
+ 29 01 00 00 00 02 24 03
+ 29 01 00 00 00 02 25 57
+ 29 01 00 00 00 02 26 03
+ 29 01 00 00 00 02 27 68
+ 29 01 00 00 00 02 28 03
+ 29 01 00 00 00 02 29 7B
+ 29 01 00 00 00 02 2A 03
+ 29 01 00 00 00 02 2B 90
+ 29 01 00 00 00 02 2D 03
+ 29 01 00 00 00 02 2F A0
+ 29 01 00 00 00 02 30 03
+ 29 01 00 00 00 02 31 CB
+ 29 01 00 00 00 02 32 00
+ 29 01 00 00 00 02 33 ED
+ 29 01 00 00 00 02 34 00
+ 29 01 00 00 00 02 35 F3
+ 29 01 00 00 00 02 36 00
+ 29 01 00 00 00 02 37 FE
+ 29 01 00 00 00 02 38 01
+ 29 01 00 00 00 02 39 09
+ 29 01 00 00 00 02 3A 01
+ 29 01 00 00 00 02 3B 13
+ 29 01 00 00 00 02 3D 01
+ 29 01 00 00 00 02 3F 1D
+ 29 01 00 00 00 02 40 01
+ 29 01 00 00 00 02 41 26
+ 29 01 00 00 00 02 42 01
+ 29 01 00 00 00 02 43 2F
+ 29 01 00 00 00 02 44 01
+ 29 01 00 00 00 02 45 37
+ 29 01 00 00 00 02 46 01
+ 29 01 00 00 00 02 47 56
+ 29 01 00 00 00 02 48 01
+ 29 01 00 00 00 02 49 70
+ 29 01 00 00 00 02 4A 01
+ 29 01 00 00 00 02 4B 9D
+ 29 01 00 00 00 02 4C 01
+ 29 01 00 00 00 02 4D C2
+ 29 01 00 00 00 02 4E 01
+ 29 01 00 00 00 02 4F FF
+ 29 01 00 00 00 02 50 02
+ 29 01 00 00 00 02 51 31
+ 29 01 00 00 00 02 52 02
+ 29 01 00 00 00 02 53 32
+ 29 01 00 00 00 02 54 02
+ 29 01 00 00 00 02 55 60
+ 29 01 00 00 00 02 56 02
+ 29 01 00 00 00 02 58 94
+ 29 01 00 00 00 02 59 02
+ 29 01 00 00 00 02 5A B5
+ 29 01 00 00 00 02 5B 02
+ 29 01 00 00 00 02 5C E3
+ 29 01 00 00 00 02 5D 03
+ 29 01 00 00 00 02 5E 03
+ 29 01 00 00 00 02 5F 03
+ 29 01 00 00 00 02 60 2D
+ 29 01 00 00 00 02 61 03
+ 29 01 00 00 00 02 62 3A
+ 29 01 00 00 00 02 63 03
+ 29 01 00 00 00 02 64 48
+ 29 01 00 00 00 02 65 03
+ 29 01 00 00 00 02 66 57
+ 29 01 00 00 00 02 67 03
+ 29 01 00 00 00 02 68 68
+ 29 01 00 00 00 02 69 03
+ 29 01 00 00 00 02 6A 7B
+ 29 01 00 00 00 02 6B 03
+ 29 01 00 00 00 02 6C 90
+ 29 01 00 00 00 02 6D 03
+ 29 01 00 00 00 02 6E A0
+ 29 01 00 00 00 02 6F 03
+ 29 01 00 00 00 02 70 CB
+ 29 01 00 00 00 02 71 00
+ 29 01 00 00 00 02 72 19
+ 29 01 00 00 00 02 73 00
+ 29 01 00 00 00 02 74 36
+ 29 01 00 00 00 02 75 00
+ 29 01 00 00 00 02 76 55
+ 29 01 00 00 00 02 77 00
+ 29 01 00 00 00 02 78 70
+ 29 01 00 00 00 02 79 00
+ 29 01 00 00 00 02 7A 83
+ 29 01 00 00 00 02 7B 00
+ 29 01 00 00 00 02 7C 99
+ 29 01 00 00 00 02 7D 00
+ 29 01 00 00 00 02 7E A8
+ 29 01 00 00 00 02 7F 00
+ 29 01 00 00 00 02 80 B7
+ 29 01 00 00 00 02 81 00
+ 29 01 00 00 00 02 82 C5
+ 29 01 00 00 00 02 83 00
+ 29 01 00 00 00 02 84 F7
+ 29 01 00 00 00 02 85 01
+ 29 01 00 00 00 02 86 1E
+ 29 01 00 00 00 02 87 01
+ 29 01 00 00 00 02 88 60
+ 29 01 00 00 00 02 89 01
+ 29 01 00 00 00 02 8A 95
+ 29 01 00 00 00 02 8B 01
+ 29 01 00 00 00 02 8C E1
+ 29 01 00 00 00 02 8D 02
+ 29 01 00 00 00 02 8E 20
+ 29 01 00 00 00 02 8F 02
+ 29 01 00 00 00 02 90 23
+ 29 01 00 00 00 02 91 02
+ 29 01 00 00 00 02 92 59
+ 29 01 00 00 00 02 93 02
+ 29 01 00 00 00 02 94 94
+ 29 01 00 00 00 02 95 02
+ 29 01 00 00 00 02 96 B4
+ 29 01 00 00 00 02 97 02
+ 29 01 00 00 00 02 98 E1
+ 29 01 00 00 00 02 99 03
+ 29 01 00 00 00 02 9A 01
+ 29 01 00 00 00 02 9B 03
+ 29 01 00 00 00 02 9C 28
+ 29 01 00 00 00 02 9D 03
+ 29 01 00 00 00 02 9E 30
+ 29 01 00 00 00 02 9F 03
+ 29 01 00 00 00 02 A0 37
+ 29 01 00 00 00 02 A2 03
+ 29 01 00 00 00 02 A3 3B
+ 29 01 00 00 00 02 A4 03
+ 29 01 00 00 00 02 A5 40
+ 29 01 00 00 00 02 A6 03
+ 29 01 00 00 00 02 A7 50
+ 29 01 00 00 00 02 A9 03
+ 29 01 00 00 00 02 AA 6D
+ 29 01 00 00 00 02 AB 03
+ 29 01 00 00 00 02 AC 80
+ 29 01 00 00 00 02 AD 03
+ 29 01 00 00 00 02 AE CB
+ 29 01 00 00 00 02 AF 00
+ 29 01 00 00 00 02 B0 19
+ 29 01 00 00 00 02 B1 00
+ 29 01 00 00 00 02 B2 36
+ 29 01 00 00 00 02 B3 00
+ 29 01 00 00 00 02 B4 55
+ 29 01 00 00 00 02 B5 00
+ 29 01 00 00 00 02 B6 70
+ 29 01 00 00 00 02 B7 00
+ 29 01 00 00 00 02 B8 83
+ 29 01 00 00 00 02 B9 00
+ 29 01 00 00 00 02 BA 99
+ 29 01 00 00 00 02 BB 00
+ 29 01 00 00 00 02 BC A8
+ 29 01 00 00 00 02 BD 00
+ 29 01 00 00 00 02 BE B7
+ 29 01 00 00 00 02 BF 00
+ 29 01 00 00 00 02 C0 C5
+ 29 01 00 00 00 02 C1 00
+ 29 01 00 00 00 02 C2 F7
+ 29 01 00 00 00 02 C3 01
+ 29 01 00 00 00 02 C4 1E
+ 29 01 00 00 00 02 C5 01
+ 29 01 00 00 00 02 C6 60
+ 29 01 00 00 00 02 C7 01
+ 29 01 00 00 00 02 C8 95
+ 29 01 00 00 00 02 C9 01
+ 29 01 00 00 00 02 CA E1
+ 29 01 00 00 00 02 CB 02
+ 29 01 00 00 00 02 CC 20
+ 29 01 00 00 00 02 CD 02
+ 29 01 00 00 00 02 CE 23
+ 29 01 00 00 00 02 CF 02
+ 29 01 00 00 00 02 D0 59
+ 29 01 00 00 00 02 D1 02
+ 29 01 00 00 00 02 D2 94
+ 29 01 00 00 00 02 D3 02
+ 29 01 00 00 00 02 D4 B4
+ 29 01 00 00 00 02 D5 02
+ 29 01 00 00 00 02 D6 E1
+ 29 01 00 00 00 02 D7 03
+ 29 01 00 00 00 02 D8 01
+ 29 01 00 00 00 02 D9 03
+ 29 01 00 00 00 02 DA 28
+ 29 01 00 00 00 02 DB 03
+ 29 01 00 00 00 02 DC 30
+ 29 01 00 00 00 02 DD 03
+ 29 01 00 00 00 02 DE 37
+ 29 01 00 00 00 02 DF 03
+ 29 01 00 00 00 02 E0 3B
+ 29 01 00 00 00 02 E1 03
+ 29 01 00 00 00 02 E2 40
+ 29 01 00 00 00 02 E3 03
+ 29 01 00 00 00 02 E4 50
+ 29 01 00 00 00 02 E5 03
+ 29 01 00 00 00 02 E6 6D
+ 29 01 00 00 00 02 E7 03
+ 29 01 00 00 00 02 E8 80
+ 29 01 00 00 00 02 E9 03
+ 29 01 00 00 00 02 EA CB
29 01 00 00 00 02 FF 01
29 01 00 00 00 02 FB 01
29 01 00 00 00 02 FF 02
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index b996766..ce6da0f 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -152,6 +152,54 @@
};
};
+ pm8226_bms: qcom,bms {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-bms";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+
+ qcom,r-sense-uohm = <10000>;
+ qcom,v-cutoff-uv = <3400000>;
+ qcom,max-voltage-uv = <4200000>;
+ qcom,r-conn-mohm = <18>;
+ qcom,shutdown-soc-valid-limit = <20>;
+ qcom,adjust-soc-low-threshold = <25>;
+ qcom,adjust-soc-high-threshold = <45>;
+ qcom,ocv-voltage-high-threshold-uv = <3750000>;
+ qcom,ocv-voltage-low-threshold-uv = <3650000>;
+ qcom,low-soc-calculate-soc-threshold = <15>;
+ qcom,low-soc-calculate-soc-ms = <5000>;
+ qcom,calculate-soc-ms = <20000>;
+ qcom,chg-term-ua = <100000>;
+ qcom,batt-type = <0>;
+
+ qcom,bms-iadc@3800 {
+ reg = <0x3800 0x100>;
+ };
+
+ qcom,bms-bms@4000 {
+ reg = <0x4000 0x100>;
+ interrupts = <0x0 0x40 0x0>,
+ <0x0 0x40 0x1>,
+ <0x0 0x40 0x2>,
+ <0x0 0x40 0x3>,
+ <0x0 0x40 0x4>,
+ <0x0 0x40 0x5>,
+ <0x0 0x40 0x6>,
+ <0x0 0x40 0x7>;
+
+ interrupt-names = "vsense_for_r",
+ "vsense_avg",
+ "sw_cc_thr",
+ "ocv_thr",
+ "charge_begin",
+ "good_ocv",
+ "ocv_for_r",
+ "cc_thr";
+ };
+ };
+
pm8226_gpios: gpios {
spmi-dev-container;
compatible = "qcom,qpnp-pin";
diff --git a/arch/arm/boot/dts/msm8226-mdss.dtsi b/arch/arm/boot/dts/msm8226-mdss.dtsi
index 21ed66a..ef8cb700 100644
--- a/arch/arm/boot/dts/msm8226-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8226-mdss.dtsi
@@ -19,6 +19,7 @@
interrupts = <0 72 0>;
vdd-supply = <&gdsc_mdss>;
+ qcom,max-clk-rate = <200000000>;
qcom,mdss-pipe-vig-off = <0x00001200>;
qcom,mdss-pipe-rgb-off = <0x00001E00>;
qcom,mdss-pipe-dma-off = <0x00002A00>;
diff --git a/arch/arm/boot/dts/msm8226-smp2p.dtsi b/arch/arm/boot/dts/msm8226-smp2p.dtsi
index 60f63a8..1b08246 100644
--- a/arch/arm/boot/dts/msm8226-smp2p.dtsi
+++ b/arch/arm/boot/dts/msm8226-smp2p.dtsi
@@ -12,8 +12,7 @@
/ {
qcom,smp2p-modem {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <1>;
qcom,irq-bitmask = <0x4000>;
interrupts = <0 27 1>;
@@ -21,8 +20,7 @@
qcom,smp2p-adsp {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <2>;
qcom,irq-bitmask = <0x400>;
interrupts = <0 158 1>;
@@ -30,8 +28,7 @@
qcom,smp2p-wcnss {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <4>;
qcom,irq-bitmask = <0x40000>;
interrupts = <0 143 1>;
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index c49f9fe..ae2a135 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -608,11 +608,16 @@
qcom,firmware-name = "wcnss";
};
+ qcom,iris-fm {
+ compatible = "qcom,iris_fm";
+ };
+
qcom,lpass@fe200000 {
compatible = "qcom,pil-q6v5-lpass";
reg = <0xfe200000 0x00100>,
- <0xfd485100 0x00010>;
- reg-names = "qdsp6_base", "halt_base";
+ <0xfd485100 0x00010>,
+ <0xfc4016c0 0x00004>;
+ reg-names = "qdsp6_base", "halt_base", "restart_reg";
vdd_cx-supply = <&pm8226_s1_corner>;
interrupts = <0 162 1>;
diff --git a/arch/arm/boot/dts/msm8610-coresight.dtsi b/arch/arm/boot/dts/msm8610-coresight.dtsi
index 298cb68..2515e62 100644
--- a/arch/arm/boot/dts/msm8610-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8610-coresight.dtsi
@@ -128,12 +128,76 @@
coresight-child-ports = <7>;
};
+ etm0: etm@fc34c000 {
+ compatible = "arm,coresight-etm";
+ reg = <0xfc34c000 0x1000>;
+ reg-names = "etm0-base";
+
+ coresight-id = <9>;
+ coresight-name = "coresight-etm0";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_a7ss>;
+ coresight-child-ports = <0>;
+
+ qcom,pc-save;
+ qcom,round-robin;
+ };
+
+ etm1: etm@fc34d000 {
+ compatible = "arm,coresight-etm";
+ reg = <0xfc34d000 0x1000>;
+ reg-names = "etm1-base";
+
+ coresight-id = <10>;
+ coresight-name = "coresight-etm1";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_a7ss>;
+ coresight-child-ports = <1>;
+
+ qcom,pc-save;
+ qcom,round-robin;
+ };
+
+ etm2: etm@fc34e000 {
+ compatible = "arm,coresight-etm";
+ reg = <0xfc34e000 0x1000>;
+ reg-names = "etm2-base";
+
+ coresight-id = <11>;
+ coresight-name = "coresight-etm2";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_a7ss>;
+ coresight-child-ports = <2>;
+
+ qcom,pc-save;
+ qcom,round-robin;
+ };
+
+ etm3: etm@fc34f000 {
+ compatible = "arm,coresight-etm";
+ reg = <0xfc34f000 0x1000>;
+ reg-names = "etm3-base";
+
+ coresight-id = <12>;
+ coresight-name = "coresight-etm3";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_a7ss>;
+ coresight-child-ports = <3>;
+
+ qcom,pc-save;
+ qcom,round-robin;
+ };
+
csr: csr@fc301000 {
compatible = "qcom,coresight-csr";
reg = <0xfc301000 0x1000>;
reg-names = "csr-base";
- coresight-id = <9>;
+ coresight-id = <13>;
coresight-name = "coresight-csr";
coresight-nr-inports = <0>;
diff --git a/arch/arm/boot/dts/msm8610-pm.dtsi b/arch/arm/boot/dts/msm8610-pm.dtsi
index d6e143c..ff16b8d 100644
--- a/arch/arm/boot/dts/msm8610-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-pm.dtsi
@@ -306,10 +306,12 @@
qcom,gic-map = <47 172>, /* usb2_hsic_async_wakeup_irq */
<53 104>, /* mdss_irq */
<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+ <0xff 56>, /* q6_wdog_expired_irq */
<0xff 57>, /* mss_to_apps_irq(0) */
<0xff 58>, /* mss_to_apps_irq(1) */
<0xff 59>, /* mss_to_apps_irq(2) */
<0xff 60>, /* mss_to_apps_irq(3) */
+ <0xff 61>, /* mss_a2_bam_irq */
<0xff 173>, /* o_wcss_apss_smd_hi */
<0xff 174>, /* o_wcss_apss_smd_med */
<0xff 175>, /* o_wcss_apss_smd_low */
@@ -317,17 +319,17 @@
<0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */
<0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */
<0xff 179>, /* o_wcss_apss_asic_intr
-
+ <0xff 181>, /* o_wcss_apss_wdog_bite_and_reset_rdy */
+ <0xff 161>, /* lpass_irq_out_spare[4] /
+ <0xff 162>, /* lpass_irq_out_spare[5]*/
+ <0xff 234>, /* lpass_irq_out_spare[6]*/
+ <0xff 235>, /* lpass_irq_out_spare[7]*/
<0xff 188>, /* lpass_irq_out_apcs(0) */
<0xff 189>, /* lpass_irq_out_apcs(1) */
<0xff 190>, /* lpass_irq_out_apcs(2) */
<0xff 191>, /* lpass_irq_out_apcs(3) */
<0xff 192>, /* lpass_irq_out_apcs(4) */
- <0xff 193>, /* lpass_irq_out_apcs(5) */
<0xff 194>, /* lpass_irq_out_apcs(6) */
- <0xff 195>, /* lpass_irq_out_apcs(7) */
- <0xff 196>, /* lpass_irq_out_apcs(8) */
- <0xff 197>, /* lpass_irq_out_apcs(9) */
<0xff 200>, /* rpm_ipc(4) */
<0xff 201>, /* rpm_ipc(5) */
<0xff 202>, /* rpm_ipc(6) */
@@ -336,47 +338,54 @@
<0xff 205>, /* rpm_ipc(25) */
<0xff 206>, /* rpm_ipc(26) */
<0xff 207>, /* rpm_ipc(27) */
+ <0xff 258>, /* rpm_ipc(28) */
+ <0xff 259>, /* rpm_ipc(29) */
+ <0xff 275>, /* rpm_ipc(30) */
+ <0xff 276>, /* rpm_ipc(31) */
+ <0xff 269>, /* rpm_wdog_expired_irq */
<0xff 240>; /* summary_irq_kpss */
qcom,gpio-parent = <&msmgpio>;
- qcom,gpio-map = <3 102>,
- <4 1 >,
+ qcom,gpio-map = <3 1>,
+ <4 4 >,
<5 5 >,
<6 9 >,
- <7 18>,
- <8 20>,
- <9 24>,
+ <7 13>,
+ <8 17>,
+ <9 21>,
<10 27>,
- <11 28>,
- <12 34>,
- <13 35>,
- <14 37>,
- <15 42>,
- <16 44>,
- <17 46>,
- <18 50>,
- <19 54>,
- <20 59>,
- <21 61>,
- <22 62>,
- <23 64>,
- <24 65>,
- <25 66>,
- <26 67>,
- <27 68>,
- <28 71>,
- <29 72>,
- <30 73>,
- <31 74>,
- <32 75>,
- <33 77>,
- <34 79>,
- <35 80>,
- <36 82>,
- <37 86>,
- <38 92>,
- <39 93>,
- <40 95>;
+ <11 29>,
+ <12 31>,
+ <13 33>,
+ <14 35>,
+ <15 37>,
+ <16 38>,
+ <17 39>,
+ <18 41>,
+ <19 46>,
+ <20 48>,
+ <21 49>,
+ <22 50>,
+ <23 51>,
+ <24 52>,
+ <25 54>,
+ <26 62>,
+ <27 63>,
+ <28 64>,
+ <29 65>,
+ <30 66>,
+ <31 67>,
+ <32 68>,
+ <33 69>,
+ <34 71>,
+ <35 72>,
+ <36 106>,
+ <37 107>,
+ <38 108>,
+ <39 109>,
+ <40 110>,
+ <54 111>,
+ <55 113>;
};
qcom,pm-8x60@fe805664 {
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 6aa87ce..53d0d5d 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -236,6 +236,7 @@
compatible = "qcom,rpm-smd";
rpm-channel-name = "rpm_requests";
rpm-channel-type = <15>; /* SMD_APPS_RPM */
+ rpm-standalone;
};
qcom,msm-mem-hole {
@@ -431,8 +432,9 @@
qcom,lpass@fe200000 {
compatible = "qcom,pil-q6v5-lpass";
reg = <0xfe200000 0x00100>,
- <0xfd485100 0x00010>;
- reg-names = "qdsp6_base", "halt_base";
+ <0xfd485100 0x00010>,
+ <0xfc4016c0 0x00004>;
+ reg-names = "qdsp6_base", "halt_base", "restart_reg";
interrupts = <0 162 1>;
vdd_cx-supply = <&pm8110_s1_corner>;
qcom,firmware-name = "adsp";
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 2c513e8..1a57534 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -194,6 +194,7 @@
sound {
qcom,model = "msm8974-taiko-cdp-snd-card";
qcom,hdmi-audio-rx;
+ qcom,us-euro-gpios = <&pm8941_gpios 20 0>;
};
usb2_otg_sw: regulator-tpd4s214 {
@@ -205,19 +206,34 @@
enable-active-high;
};
- hsic@f9a00000 {
- compatible = "qcom,hsic-host";
- reg = <0xf9a00000 0x400>;
- interrupts = <0 136 0>, <0 148 0>;
- interrupt-names = "core_irq", "async_irq";
- HSIC_VDDCX-supply = <&pm8841_s2>;
- HSIC_GDSC-supply = <&gdsc_usb_hsic>;
- hsic,strobe-gpio = <&msmgpio 144 0x00>;
- hsic,data-gpio = <&msmgpio 145 0x00>;
- hsic,resume-gpio = <&msmgpio 80 0x00>;
- hsic,ignore-cal-pad-config;
- hsic,strobe-pad-offset = <0x2050>;
- hsic,data-pad-offset = <0x2054>;
+ hsic_host: hsic@f9a00000 {
+ compatible = "qcom,hsic-host";
+ reg = <0xf9a00000 0x400>;
+ #address-cells = <0>;
+ interrupt-parent = <&hsic_host>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 136 0
+ 1 &intc 0 148 0
+ 2 &msmgpio 144 0x8>;
+ interrupt-names = "core_irq", "async_irq", "wakeup";
+ HSIC_VDDCX-supply = <&pm8841_s2>;
+ HSIC_GDSC-supply = <&gdsc_usb_hsic>;
+ hsic,strobe-gpio = <&msmgpio 144 0x00>;
+ hsic,data-gpio = <&msmgpio 145 0x00>;
+ hsic,resume-gpio = <&msmgpio 80 0x00>;
+ hsic,ignore-cal-pad-config;
+ hsic,strobe-pad-offset = <0x2050>;
+ hsic,data-pad-offset = <0x2054>;
+
+ qcom,msm-bus,name = "hsic";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only = <0>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <85 512 0 0>,
+ <85 512 40000 160000>;
};
};
@@ -484,6 +500,14 @@
};
gpio@d300 { /* GPIO 20 */
+ qcom,mode = <1>; /* QPNP_PIN_MODE_DIG_OUT */
+ qcom,output-type = <0>; /* QPNP_PIN_OUT_BUF_CMOS */
+ qcom,invert = <0>; /* Output low initially */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+ qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,out-strength = <2>; /* QPNP_PIN_OUT_STRENGTH_MED */
+ qcom,src-sel = <0>; /* QPNP_PIN_SEL_FUNC_CONSTANT */
+ qcom,master-en = <1>;
};
gpio@d400 { /* GPIO 21 */
@@ -541,6 +565,7 @@
&pm8941_mpps {
mpp@a000 { /* MPP 1 */
+ status = "disabled";
};
mpp@a100 { /* MPP 2 */
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index b18bf88..2ddc61d 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -536,6 +536,7 @@
&pm8941_mpps {
mpp@a000 { /* MPP 1 */
+ status = "disabled";
};
mpp@a100 { /* MPP 2 */
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index a35b9d2..0cf78bc 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -606,6 +606,7 @@
&pm8941_mpps {
mpp@a000 { /* MPP 1 */
+ status = "disabled";
};
mpp@a100 { /* MPP 2 */
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index 2f9adbb..0912a33 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -19,6 +19,7 @@
interrupts = <0 72 0>;
vdd-supply = <&gdsc_mdss>;
+ qcom,max-clk-rate = <320000000>;
qcom,mdss-pipe-vig-off = <0x00001200 0x00001600
0x00001A00>;
qcom,mdss-pipe-rgb-off = <0x00001E00 0x00002200
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index 4f0469c..6011d52 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -508,6 +508,7 @@
&pm8941_mpps {
mpp@a000 { /* MPP 1 */
+ status = "disabled";
};
mpp@a100 { /* MPP 2 */
diff --git a/arch/arm/boot/dts/msm8974-smp2p.dtsi b/arch/arm/boot/dts/msm8974-smp2p.dtsi
index 511f91f..1b08246 100644
--- a/arch/arm/boot/dts/msm8974-smp2p.dtsi
+++ b/arch/arm/boot/dts/msm8974-smp2p.dtsi
@@ -12,8 +12,7 @@
/ {
qcom,smp2p-modem {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <1>;
qcom,irq-bitmask = <0x4000>;
interrupts = <0 27 1>;
@@ -21,8 +20,7 @@
qcom,smp2p-adsp {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <2>;
qcom,irq-bitmask = <0x400>;
interrupts = <0 158 1>;
@@ -30,8 +28,7 @@
qcom,smp2p-wcnss {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <4>;
qcom,irq-bitmask = <0x40000>;
interrupts = <0 143 1>;
@@ -103,6 +100,29 @@
gpios = <&smp2pgpio_smp2p_1_out 0 0>;
};
+ /* SMP2P SSR Driver for inbound entry from modem. */
+ smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "slave-kernel";
+ qcom,remote-pid = <1>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* SMP2P SSR Driver for outbound entry to modem */
+ smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "master-kernel";
+ qcom,remote-pid = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
/* SMP2P Test Driver for adsp inbound */
smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in {
compatible = "qcom,smp2pgpio";
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index aa3742f..9b9b1d1 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -741,8 +741,9 @@
qcom,lpass@fe200000 {
compatible = "qcom,pil-q6v5-lpass";
reg = <0xfe200000 0x00100>,
- <0xfd485100 0x00010>;
- reg-names = "qdsp6_base", "halt_base";
+ <0xfd485100 0x00010>,
+ <0xfc4016c0 0x00004>;
+ reg-names = "qdsp6_base", "halt_base", "restart_reg";
vdd_cx-supply = <&pm8841_s2_corner>;
interrupts = <0 162 1>;
@@ -993,6 +994,12 @@
qcom,is-loadable;
qcom,firmware-name = "mba";
qcom,pil-self-auth;
+
+ /* GPIO input from mss */
+ qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
+
+ /* GPIO output to mss */
+ qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
};
qcom,pronto@fb21b000 {
diff --git a/arch/arm/boot/dts/msm9625-smp2p.dtsi b/arch/arm/boot/dts/msm9625-smp2p.dtsi
index 425bf00..02c95e4 100644
--- a/arch/arm/boot/dts/msm9625-smp2p.dtsi
+++ b/arch/arm/boot/dts/msm9625-smp2p.dtsi
@@ -12,8 +12,7 @@
/ {
qcom,smp2p-modem {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <1>;
qcom,irq-bitmask = <0x4000>;
interrupts = <0 27 1>;
@@ -21,8 +20,7 @@
qcom,smp2p-adsp {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <2>;
qcom,irq-bitmask = <0x400>;
interrupts = <0 158 1>;
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index cfdff6f..097e830 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -183,6 +183,17 @@
CONFIG_SYNC=y
CONFIG_SW_SYNC=y
CONFIG_CMA=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCISMD=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_MD=y
@@ -233,6 +244,8 @@
CONFIG_REGULATOR=y
CONFIG_REGULATOR_STUB=y
CONFIG_REGULATOR_QPNP=y
+CONFIG_RADIO_IRIS=y
+CONFIG_RADIO_IRIS_TRANSPORT=m
CONFIG_ION=y
CONFIG_ION_MSM=y
CONFIG_MSM_KGSL=y
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index abb222f..3cc2b52 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -318,7 +318,7 @@
* DMA region above it's default value of 2MB. It must be called before the
* memory allocator is initialised, i.e. before any core_initcall.
*/
-extern void __init init_consistent_dma_size(unsigned long size);
+static inline void init_consistent_dma_size(unsigned long size) { }
/*
* For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic"
diff --git a/arch/arm/mach-msm/acpuclock-8226.c b/arch/arm/mach-msm/acpuclock-8226.c
index 8ba1b39..fcbd74d 100644
--- a/arch/arm/mach-msm/acpuclock-8226.c
+++ b/arch/arm/mach-msm/acpuclock-8226.c
@@ -98,13 +98,13 @@
drv_data.apcs_rcg_config = drv_data.apcs_rcg_cmd + 4;
- drv_data.vdd_cpu = regulator_get(&pdev->dev, "a7_cpu");
+ drv_data.vdd_cpu = devm_regulator_get(&pdev->dev, "a7_cpu");
if (IS_ERR(drv_data.vdd_cpu)) {
dev_err(&pdev->dev, "regulator for %s get failed\n", "a7_cpu");
return PTR_ERR(drv_data.vdd_cpu);
}
- drv_data.vdd_mem = regulator_get(&pdev->dev, "a7_mem");
+ drv_data.vdd_mem = devm_regulator_get(&pdev->dev, "a7_mem");
if (IS_ERR(drv_data.vdd_mem)) {
dev_err(&pdev->dev, "regulator for %s get failed\n", "a7_mem");
return PTR_ERR(drv_data.vdd_mem);
diff --git a/arch/arm/mach-msm/acpuclock-9625.c b/arch/arm/mach-msm/acpuclock-9625.c
index b439088..34952fb 100644
--- a/arch/arm/mach-msm/acpuclock-9625.c
+++ b/arch/arm/mach-msm/acpuclock-9625.c
@@ -105,13 +105,13 @@
if (!drv_data.apcs_cpu_pwr_ctl)
return -ENOMEM;
- drv_data.vdd_cpu = regulator_get(&pdev->dev, "a5_cpu");
+ drv_data.vdd_cpu = devm_regulator_get(&pdev->dev, "a5_cpu");
if (IS_ERR(drv_data.vdd_cpu)) {
dev_err(&pdev->dev, "regulator for %s get failed\n", "a5_cpu");
return PTR_ERR(drv_data.vdd_cpu);
}
- drv_data.vdd_mem = regulator_get(&pdev->dev, "a5_mem");
+ drv_data.vdd_mem = devm_regulator_get(&pdev->dev, "a5_mem");
if (IS_ERR(drv_data.vdd_mem)) {
dev_err(&pdev->dev, "regulator for %s get failed\n", "a5_mem");
return PTR_ERR(drv_data.vdd_mem);
diff --git a/arch/arm/mach-msm/acpuclock-cortex.c b/arch/arm/mach-msm/acpuclock-cortex.c
index ce56b6b..88bf919 100644
--- a/arch/arm/mach-msm/acpuclock-cortex.c
+++ b/arch/arm/mach-msm/acpuclock-cortex.c
@@ -40,7 +40,7 @@
#define POLL_INTERVAL_US 1
#define APCS_RCG_UPDATE_TIMEOUT_US 20
-static struct acpuclk_drv_data *acpuclk_init_data;
+static struct acpuclk_drv_data *priv;
static uint32_t bus_perf_client;
/* Update the bus bandwidth request. */
@@ -48,7 +48,7 @@
{
int ret;
- if (bw >= acpuclk_init_data->bus_scale->num_usecases) {
+ if (bw >= priv->bus_scale->num_usecases) {
pr_err("invalid bandwidth request (%d)\n", bw);
return;
}
@@ -67,15 +67,13 @@
int rc = 0;
/* Increase vdd_mem before vdd_cpu. vdd_mem should be >= vdd_cpu. */
- rc = regulator_set_voltage(acpuclk_init_data->vdd_mem, vdd_mem,
- acpuclk_init_data->vdd_max_mem);
+ rc = regulator_set_voltage(priv->vdd_mem, vdd_mem, priv->vdd_max_mem);
if (rc) {
pr_err("vdd_mem increase failed (%d)\n", rc);
return rc;
}
- rc = regulator_set_voltage(acpuclk_init_data->vdd_cpu, vdd_cpu,
- acpuclk_init_data->vdd_max_cpu);
+ rc = regulator_set_voltage(priv->vdd_cpu, vdd_cpu, priv->vdd_max_cpu);
if (rc)
pr_err("vdd_cpu increase failed (%d)\n", rc);
@@ -88,16 +86,14 @@
int ret;
/* Update CPU voltage. */
- ret = regulator_set_voltage(acpuclk_init_data->vdd_cpu, vdd_cpu,
- acpuclk_init_data->vdd_max_cpu);
+ ret = regulator_set_voltage(priv->vdd_cpu, vdd_cpu, priv->vdd_max_cpu);
if (ret) {
pr_err("vdd_cpu decrease failed (%d)\n", ret);
return;
}
/* Decrease vdd_mem after vdd_cpu. vdd_mem should be >= vdd_cpu. */
- ret = regulator_set_voltage(acpuclk_init_data->vdd_mem, vdd_mem,
- acpuclk_init_data->vdd_max_mem);
+ ret = regulator_set_voltage(priv->vdd_mem, vdd_mem, priv->vdd_max_mem);
if (ret)
pr_err("vdd_mem decrease failed (%d)\n", ret);
}
@@ -142,14 +138,14 @@
{
int rc = 0;
unsigned int tgt_freq_hz = tgt_s->khz * 1000;
- struct clkctl_acpu_speed *strt_s = acpuclk_init_data->current_speed;
- struct clkctl_acpu_speed *cxo_s = &acpuclk_init_data->freq_tbl[0];
- struct clk *strt = acpuclk_init_data->src_clocks[strt_s->src].clk;
- struct clk *tgt = acpuclk_init_data->src_clocks[tgt_s->src].clk;
+ struct clkctl_acpu_speed *strt_s = priv->current_speed;
+ struct clkctl_acpu_speed *cxo_s = &priv->freq_tbl[0];
+ struct clk *strt = priv->src_clocks[strt_s->src].clk;
+ struct clk *tgt = priv->src_clocks[tgt_s->src].clk;
if (strt_s->src == ACPUPLL && tgt_s->src == ACPUPLL) {
/* Switch to another always on src */
- select_clk_source_div(acpuclk_init_data, cxo_s);
+ select_clk_source_div(priv, cxo_s);
/* Re-program acpu pll */
if (atomic)
@@ -167,7 +163,7 @@
BUG_ON(clk_prepare_enable(tgt));
/* Switch back to acpu pll */
- select_clk_source_div(acpuclk_init_data, tgt_s);
+ select_clk_source_div(priv, tgt_s);
} else if (strt_s->src != ACPUPLL && tgt_s->src == ACPUPLL) {
rc = clk_set_rate(tgt, tgt_freq_hz);
@@ -186,7 +182,7 @@
return rc;
}
- select_clk_source_div(acpuclk_init_data, tgt_s);
+ select_clk_source_div(priv, tgt_s);
if (atomic)
clk_disable(strt);
@@ -201,11 +197,11 @@
if (rc) {
pr_err("%s enable failed\n",
- acpuclk_init_data->src_clocks[tgt_s->src].name);
+ priv->src_clocks[tgt_s->src].name);
return rc;
}
- select_clk_source_div(acpuclk_init_data, tgt_s);
+ select_clk_source_div(priv, tgt_s);
if (atomic)
clk_disable(strt);
@@ -224,16 +220,16 @@
int rc = 0;
if (reason == SETRATE_CPUFREQ)
- mutex_lock(&acpuclk_init_data->lock);
+ mutex_lock(&priv->lock);
- strt_s = acpuclk_init_data->current_speed;
+ strt_s = priv->current_speed;
/* Return early if rate didn't change */
if (rate == strt_s->khz)
goto out;
/* Find target frequency */
- for (tgt_s = acpuclk_init_data->freq_tbl; tgt_s->khz != 0; tgt_s++)
+ for (tgt_s = priv->freq_tbl; tgt_s->khz != 0; tgt_s++)
if (tgt_s->khz == rate)
break;
if (tgt_s->khz == 0) {
@@ -261,7 +257,7 @@
if (rc)
goto out;
- acpuclk_init_data->current_speed = tgt_s;
+ priv->current_speed = tgt_s;
pr_debug("CPU speed change complete\n");
/* Nothing else to do for SWFI or power-collapse. */
@@ -277,13 +273,13 @@
out:
if (reason == SETRATE_CPUFREQ)
- mutex_unlock(&acpuclk_init_data->lock);
+ mutex_unlock(&priv->lock);
return rc;
}
static unsigned long acpuclk_cortex_get_rate(int cpu)
{
- return acpuclk_init_data->current_speed->khz;
+ return priv->current_speed->khz;
}
#ifdef CONFIG_CPU_FREQ_MSM
@@ -293,18 +289,17 @@
{
int i, freq_cnt = 0;
- /* Construct the freq_table tables from acpuclk_init_data->freq_tbl. */
- for (i = 0; acpuclk_init_data->freq_tbl[i].khz != 0
+ /* Construct the freq_table tables from priv->freq_tbl. */
+ for (i = 0; priv->freq_tbl[i].khz != 0
&& freq_cnt < ARRAY_SIZE(freq_table); i++) {
- if (!acpuclk_init_data->freq_tbl[i].use_for_scaling)
+ if (!priv->freq_tbl[i].use_for_scaling)
continue;
freq_table[freq_cnt].index = freq_cnt;
- freq_table[freq_cnt].frequency =
- acpuclk_init_data->freq_tbl[i].khz;
+ freq_table[freq_cnt].frequency = priv->freq_tbl[i].khz;
freq_cnt++;
}
/* freq_table not big enough to store all usable freqs. */
- BUG_ON(acpuclk_init_data->freq_tbl[i].khz != 0);
+ BUG_ON(priv->freq_tbl[i].khz != 0);
freq_table[freq_cnt].index = freq_cnt;
freq_table[freq_cnt].frequency = CPUFREQ_TABLE_END;
@@ -332,43 +327,40 @@
unsigned long max_cpu_khz = 0;
int i, rc;
- acpuclk_init_data = data;
- mutex_init(&acpuclk_init_data->lock);
+ priv = data;
+ mutex_init(&priv->lock);
- bus_perf_client = msm_bus_scale_register_client(
- acpuclk_init_data->bus_scale);
+ bus_perf_client = msm_bus_scale_register_client(priv->bus_scale);
if (!bus_perf_client) {
pr_err("Unable to register bus client\n");
BUG();
}
for (i = 0; i < NUM_SRC; i++) {
- if (!acpuclk_init_data->src_clocks[i].name)
+ if (!priv->src_clocks[i].name)
continue;
- acpuclk_init_data->src_clocks[i].clk =
- clk_get(&pdev->dev,
- acpuclk_init_data->src_clocks[i].name);
- BUG_ON(IS_ERR(acpuclk_init_data->src_clocks[i].clk));
+ priv->src_clocks[i].clk =
+ devm_clk_get(&pdev->dev, priv->src_clocks[i].name);
+ BUG_ON(IS_ERR(priv->src_clocks[i].clk));
}
/* Improve boot time by ramping up CPU immediately */
- for (i = 0; acpuclk_init_data->freq_tbl[i].khz != 0; i++)
- if (acpuclk_init_data->freq_tbl[i].use_for_scaling)
- max_cpu_khz = acpuclk_init_data->freq_tbl[i].khz;
+ for (i = 0; priv->freq_tbl[i].khz != 0; i++)
+ if (priv->freq_tbl[i].use_for_scaling)
+ max_cpu_khz = priv->freq_tbl[i].khz;
/* Initialize regulators */
- rc = increase_vdd(acpuclk_init_data->vdd_max_cpu,
- acpuclk_init_data->vdd_max_mem);
+ rc = increase_vdd(priv->vdd_max_cpu, priv->vdd_max_mem);
if (rc)
goto err_vdd;
- rc = regulator_enable(acpuclk_init_data->vdd_mem);
+ rc = regulator_enable(priv->vdd_mem);
if (rc) {
dev_err(&pdev->dev, "regulator_enable for mem failed\n");
goto err_vdd;
}
- rc = regulator_enable(acpuclk_init_data->vdd_cpu);
+ rc = regulator_enable(priv->vdd_cpu);
if (rc) {
dev_err(&pdev->dev, "regulator_enable for cpu failed\n");
goto err_vdd_cpu;
@@ -388,15 +380,7 @@
return 0;
err_vdd_cpu:
- regulator_disable(acpuclk_init_data->vdd_mem);
+ regulator_disable(priv->vdd_mem);
err_vdd:
- regulator_put(acpuclk_init_data->vdd_mem);
- regulator_put(acpuclk_init_data->vdd_cpu);
-
- for (i = 0; i < NUM_SRC; i++) {
- if (!acpuclk_init_data->src_clocks[i].name)
- continue;
- clk_put(acpuclk_init_data->src_clocks[i].clk);
- }
return rc;
}
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index 9566cea..a6f4423 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -44,8 +44,6 @@
#define PRI_SRC_SEL_HFPLL 1
#define PRI_SRC_SEL_HFPLL_DIV2 2
-#define SECCLKAGD BIT(4)
-
static DEFINE_MUTEX(driver_lock);
static DEFINE_SPINLOCK(l2_lock);
@@ -75,20 +73,10 @@
{
u32 regval;
- /* 8064 Errata: disable sec_src clock gating during switch. */
regval = get_l2_indirect_reg(sc->l2cpmr_iaddr);
- regval |= SECCLKAGD;
- set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
-
- /* Program the MUX */
regval &= ~(0x3 << 2);
regval |= ((sec_src_sel & 0x3) << 2);
set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
-
- /* 8064 Errata: re-enabled sec_src clock gating. */
- regval &= ~SECCLKAGD;
- set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
-
/* Wait for switch to complete. */
mb();
udelay(1);
@@ -620,9 +608,8 @@
writel_relaxed(drv.hfpll_data->droop_val,
sc->hfpll_base + drv.hfpll_data->droop_offset);
- /* Set an initial rate and enable the PLL. */
+ /* Set an initial PLL rate. */
hfpll_set_rate(sc, tgt_s);
- hfpll_enable(sc, false);
}
static int __cpuinit rpm_regulator_init(struct scalable *sc, enum vregs vreg,
@@ -793,7 +780,9 @@
regval &= ~(0x3 << 6);
set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
- /* Switch to the target clock source. */
+ /* Enable and switch to the target clock source. */
+ if (tgt_s->src == HFPLL)
+ hfpll_enable(sc, false);
set_pri_clk_src(sc, tgt_s->pri_src_sel);
sc->cur_speed = tgt_s;
@@ -922,11 +911,12 @@
static void __init cpufreq_table_init(void)
{
int cpu;
+ int freq_cnt = 0;
for_each_possible_cpu(cpu) {
- int i, freq_cnt = 0;
+ int i;
/* Construct the freq_table tables from acpu_freq_tbl. */
- for (i = 0; drv.acpu_freq_tbl[i].speed.khz != 0
+ for (i = 0, freq_cnt = 0; drv.acpu_freq_tbl[i].speed.khz != 0
&& freq_cnt < ARRAY_SIZE(*freq_table); i++) {
if (drv.acpu_freq_tbl[i].use_for_scaling) {
freq_table[cpu][freq_cnt].index = freq_cnt;
@@ -941,12 +931,11 @@
freq_table[cpu][freq_cnt].index = freq_cnt;
freq_table[cpu][freq_cnt].frequency = CPUFREQ_TABLE_END;
- dev_info(drv.dev, "CPU%d: %d frequencies supported\n",
- cpu, freq_cnt);
-
/* Register table with CPUFreq. */
cpufreq_frequency_table_get_attr(freq_table[cpu], cpu);
}
+
+ dev_info(drv.dev, "CPU Frequencies Supported: %d\n", freq_cnt);
}
#else
static void __init cpufreq_table_init(void) {}
diff --git a/arch/arm/mach-msm/board-8610.c b/arch/arm/mach-msm/board-8610.c
index 2723e20..5f5366f 100644
--- a/arch/arm/mach-msm/board-8610.c
+++ b/arch/arm/mach-msm/board-8610.c
@@ -49,6 +49,7 @@
#include "platsmp.h"
#include "spm.h"
#include "lpm_resources.h"
+#include "modem_notifier.h"
static struct memtype_reserve msm8610_reserve_table[] __initdata = {
[MEMTYPE_SMI] = {
@@ -94,6 +95,8 @@
void __init msm8610_add_drivers(void)
{
+ msm_init_modem_notifier_list();
+ msm_smd_init();
msm_rpm_driver_init();
msm_lpmrs_module_init();
msm_spm_device_init();
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 0436a82..cc478da 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -1668,7 +1668,7 @@
F_MMSS( 100000000, gpll0, 6, 0, 0),
F_MMSS( 150000000, gpll0, 4, 0, 0),
F_MMSS( 200000000, mmpll0_pll, 4, 0, 0),
- F_MMSS( 266000000, mmpll0_pll, 3, 0, 0),
+ F_MMSS( 266666666, mmpll0_pll, 3, 0, 0),
F_END
};
@@ -1820,14 +1820,17 @@
CLK_INIT(dsipll0_pixel_clk_src),
};
-static struct clk_freq_tbl pixel_freq = {
- .src_clk = &dsipll0_pixel_clk_src,
- .div_src_val = BVAL(10, 8, dsipll0_pixel_mm_source_val),
+static struct clk_freq_tbl pixel_freq_tbl[] = {
+ {
+ .src_clk = &dsipll0_pixel_clk_src,
+ .div_src_val = BVAL(10, 8, dsipll0_pixel_mm_source_val),
+ },
+ F_END
};
static struct rcg_clk pclk0_clk_src = {
.cmd_rcgr_reg = PCLK0_CMD_RCGR,
- .current_freq = &pixel_freq,
+ .current_freq = pixel_freq_tbl,
.base = &virt_bases[MMSS_BASE],
.c = {
.parent = &dsipll0_pixel_clk_src,
@@ -1919,6 +1922,8 @@
};
static struct clk_freq_tbl ftbl_camss_mclk0_1_clk[] = {
+ F_MMSS( 19200000, xo, 1, 0, 0),
+ F_MMSS( 24000000, gpll0, 5, 1, 5),
F_MMSS( 66670000, gpll0, 9, 0, 0),
F_END
};
@@ -2007,14 +2012,17 @@
},
};
-static struct clk_freq_tbl byte_freq = {
- .src_clk = &dsipll0_byte_clk_src,
- .div_src_val = BVAL(10, 8, dsipll0_byte_mm_source_val),
+static struct clk_freq_tbl byte_freq_tbl[] = {
+ {
+ .src_clk = &dsipll0_byte_clk_src,
+ .div_src_val = BVAL(10, 8, dsipll0_byte_mm_source_val),
+ },
+ F_END
};
static struct rcg_clk byte0_clk_src = {
.cmd_rcgr_reg = BYTE0_CMD_RCGR,
- .current_freq = &byte_freq,
+ .current_freq = byte_freq_tbl,
.base = &virt_bases[MMSS_BASE],
.c = {
.parent = &dsipll0_byte_clk_src,
@@ -3062,7 +3070,8 @@
CLK_LOOKUP("a7sspll", a7sspll.c, "f9011050.qcom,acpuclk"),
/* WCNSS CLOCKS */
- CLK_LOOKUP("xo", xo.c, "fb000000.qcom,wcnss-wlan"),
+ CLK_LOOKUP("xo", xo.c, "fb000000.qcom,wcnss-wlan"),
+ CLK_LOOKUP("rf_clk", cxo_a2.c, "fb000000.qcom,wcnss-wlan"),
/* BUS DRIVER */
CLK_LOOKUP("bus_clk", cnoc_msmbus_clk.c, "msm_config_noc"),
@@ -3179,6 +3188,11 @@
CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "qseecom"),
CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "qseecom"),
+ CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "scm"),
+ CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "scm"),
+ CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "scm"),
+ CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "scm"),
+
/* SDCC */
CLK_LOOKUP("iface_clk", gcc_sdcc1_ahb_clk.c, "f9824000.qcom,sdcc"),
CLK_LOOKUP("core_clk", gcc_sdcc1_apps_clk.c, "f9824000.qcom,sdcc"),
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index 0aee878..c517c10 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -3016,7 +3016,12 @@
static struct clk_lookup msm_clocks_8610[] = {
CLK_LOOKUP("xo", gcc_xo_clk_src.c, "msm_otg"),
CLK_LOOKUP("xo", gcc_xo_clk_src.c, "fe200000.qcom,lpass"),
- CLK_LOOKUP("xo", gcc_xo_clk_src.c, "pil-q6v5-mss"),
+
+ CLK_LOOKUP("xo", gcc_xo_clk_src.c, "fc880000.qcom,mss"),
+ CLK_LOOKUP("bus_clk", gcc_mss_q6_bimc_axi_clk.c, "fc880000.qcom,mss"),
+ CLK_LOOKUP("iface_clk", gcc_mss_cfg_ahb_clk.c, "fc880000.qcom,mss"),
+ CLK_LOOKUP("mem_clk", gcc_boot_rom_ahb_clk.c, "fc880000.qcom,mss"),
+
CLK_LOOKUP("xo", gcc_xo_clk_src.c, "pil-mba"),
CLK_LOOKUP("xo", gcc_xo_clk_src.c, "fb000000.qcom,wcnss-wlan"),
CLK_LOOKUP("xo", gcc_xo_clk_src.c, "fb21b000.qcom,pronto"),
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 0657c21..90f11c5 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -3026,14 +3026,17 @@
CLK_INIT(dsipll0_pixel_clk_src),
};
-static struct clk_freq_tbl byte_freq = {
- .src_clk = &dsipll0_byte_clk_src,
- .div_src_val = BVAL(10, 8, dsipll0_byte_mm_source_val),
+static struct clk_freq_tbl byte_freq_tbl[] = {
+ {
+ .src_clk = &dsipll0_byte_clk_src,
+ .div_src_val = BVAL(10, 8, dsipll0_byte_mm_source_val),
+ },
+ F_END
};
static struct rcg_clk byte0_clk_src = {
.cmd_rcgr_reg = BYTE0_CMD_RCGR,
- .current_freq = &byte_freq,
+ .current_freq = byte_freq_tbl,
.base = &virt_bases[MMSS_BASE],
.c = {
.parent = &dsipll0_byte_clk_src,
@@ -3047,7 +3050,7 @@
static struct rcg_clk byte1_clk_src = {
.cmd_rcgr_reg = BYTE1_CMD_RCGR,
- .current_freq = &byte_freq,
+ .current_freq = byte_freq_tbl,
.base = &virt_bases[MMSS_BASE],
.c = {
.parent = &dsipll0_byte_clk_src,
@@ -3228,14 +3231,17 @@
},
};
-static struct clk_freq_tbl pixel_freq = {
- .src_clk = &dsipll0_pixel_clk_src,
- .div_src_val = BVAL(10, 8, dsipll0_pixel_mm_source_val),
+static struct clk_freq_tbl pixel_freq_tbl[] = {
+ {
+ .src_clk = &dsipll0_pixel_clk_src,
+ .div_src_val = BVAL(10, 8, dsipll0_pixel_mm_source_val),
+ },
+ F_END
};
static struct rcg_clk pclk0_clk_src = {
.cmd_rcgr_reg = PCLK0_CMD_RCGR,
- .current_freq = &pixel_freq,
+ .current_freq = pixel_freq_tbl,
.base = &virt_bases[MMSS_BASE],
.c = {
.parent = &dsipll0_pixel_clk_src,
@@ -3248,7 +3254,7 @@
static struct rcg_clk pclk1_clk_src = {
.cmd_rcgr_reg = PCLK1_CMD_RCGR,
- .current_freq = &pixel_freq,
+ .current_freq = pixel_freq_tbl,
.base = &virt_bases[MMSS_BASE],
.c = {
.parent = &dsipll0_pixel_clk_src,
@@ -4739,6 +4745,7 @@
CLK_LOOKUP("xo", cxo_pil_lpass_clk.c, "fe200000.qcom,lpass"),
CLK_LOOKUP("xo", cxo_pil_mss_clk.c, "fc880000.qcom,mss"),
CLK_LOOKUP("xo", cxo_wlan_clk.c, "fb000000.qcom,wcnss-wlan"),
+ CLK_LOOKUP("rf_clk", cxo_a2.c, "fb000000.qcom,wcnss-wlan"),
CLK_LOOKUP("xo", cxo_pil_pronto_clk.c, "fb21b000.qcom,pronto"),
CLK_LOOKUP("xo", cxo_dwc3_clk.c, "msm_dwc3"),
CLK_LOOKUP("xo", cxo_ehci_host_clk.c, "msm_ehci_host"),
@@ -4815,6 +4822,11 @@
CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "qseecom"),
CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "qseecom"),
+ CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "scm"),
+ CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "scm"),
+ CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "scm"),
+ CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "scm"),
+
CLK_LOOKUP("core_clk", gcc_gp1_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_gp2_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_gp3_clk.c, ""),
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index a173ba9..5da1663 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -560,7 +560,11 @@
return to_rcg_clk(c)->enabled;
}
-/* Return a supported rate that's at least the specified rate. */
+/*
+ * Return a supported rate that's at least the specified rate or
+ * the max supported rate if the specified rate is larger than the
+ * max supported rate.
+ */
static long rcg_clk_round_rate(struct clk *c, unsigned long rate)
{
struct rcg_clk *rcg = to_rcg_clk(c);
@@ -570,7 +574,8 @@
if (f->freq_hz >= rate)
return f->freq_hz;
- return -EPERM;
+ f--;
+ return f->freq_hz;
}
/* Return the nth supported frequency for a given clock. */
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index c3b4ca7..2879b49 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -211,7 +211,11 @@
return 0;
}
-/* Return a supported rate that's at least the specified rate. */
+/*
+ * Return a supported rate that's at least the specified rate or
+ * the max supported rate if the specified rate is larger than the
+ * max supported rate.
+ */
static long rcg_clk_round_rate(struct clk *c, unsigned long rate)
{
struct rcg_clk *rcg = to_rcg_clk(c);
@@ -221,7 +225,8 @@
if (f->freq_hz >= rate)
return f->freq_hz;
- return -EPERM;
+ f--;
+ return f->freq_hz;
}
/* Return the nth supported frequency for a given clock. */
diff --git a/arch/arm/mach-msm/pil-q6v5-lpass.c b/arch/arm/mach-msm/pil-q6v5-lpass.c
index dfbda74..ef13c34 100644
--- a/arch/arm/mach-msm/pil-q6v5-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v5-lpass.c
@@ -114,6 +114,8 @@
pil_q6v5_shutdown(pil);
pil_lpass_disable_clks(drv);
+ writel_relaxed(1, drv->restart_reg);
+
drv->is_booted = false;
return 0;
@@ -125,6 +127,11 @@
unsigned long start_addr = pil_get_entry_addr(pil);
int ret;
+ /* Deassert reset to subsystem and wait for propagation */
+ writel_relaxed(0, drv->restart_reg);
+ mb();
+ udelay(2);
+
ret = pil_lpass_enable_clks(drv);
if (ret)
return ret;
@@ -385,6 +392,7 @@
struct lpass_data *drv;
struct q6v5_data *q6;
struct pil_desc *desc;
+ struct resource *res;
int ret;
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
@@ -405,6 +413,11 @@
desc->owner = THIS_MODULE;
desc->proxy_timeout = PROXY_TIMEOUT_MS;
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "restart_reg");
+ q6->restart_reg = devm_request_and_ioremap(&pdev->dev, res);
+ if (!q6->restart_reg)
+ return -ENOMEM;
+
q6->core_clk = devm_clk_get(&pdev->dev, "core_clk");
if (IS_ERR(q6->core_clk))
return PTR_ERR(q6->core_clk);
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index 1954ec3..2ceb06d 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -24,6 +24,7 @@
#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/interrupt.h>
+#include <linux/of_gpio.h>
#include <mach/subsystem_restart.h>
#include <mach/clk.h>
@@ -92,6 +93,8 @@
bool crash_shutdown;
bool ignore_errors;
int is_loadable;
+ int err_fatal_irq;
+ int force_stop_gpio;
};
static int pbl_mba_boot_timeout_ms = 100;
@@ -470,18 +473,17 @@
subsystem_restart_dev(drv->subsys);
}
-static void smsm_state_cb(void *data, uint32_t old_state, uint32_t new_state)
+static irqreturn_t modem_err_fatal_intr_handler(int irq, void *dev_id)
{
- struct mba_data *drv = data;
+ struct mba_data *drv = dev_id;
- /* Ignore if we're the one that set SMSM_RESET */
+ /* Ignore if we're the one that set the force stop GPIO */
if (drv->crash_shutdown)
- return;
+ return IRQ_HANDLED;
- if (new_state & SMSM_RESET) {
- pr_err("Probable fatal error on the modem.\n");
- restart_modem(drv);
- }
+ pr_err("Fatal error on the modem.\n");
+ restart_modem(drv);
+ return IRQ_HANDLED;
}
static int modem_shutdown(const struct subsys_desc *subsys)
@@ -521,7 +523,7 @@
{
struct mba_data *drv = subsys_to_drv(subsys);
drv->crash_shutdown = true;
- smsm_reset_modem(SMSM_RESET);
+ gpio_set_value(drv->force_stop_gpio, 1);
}
static struct ramdump_segment smem_segments[] = {
@@ -658,10 +660,11 @@
goto err_irq;
}
- ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
- smsm_state_cb, drv);
+ ret = devm_request_irq(&pdev->dev, drv->err_fatal_irq,
+ modem_err_fatal_intr_handler,
+ IRQF_TRIGGER_RISING, "pil-mss", drv);
if (ret < 0) {
- dev_err(&pdev->dev, "Unable to register SMSM callback!\n");
+ dev_err(&pdev->dev, "Unable to register SMP2P err fatal handler!\n");
goto err_irq;
}
@@ -671,14 +674,11 @@
ret = PTR_ERR(drv->adsp_state_notifier);
dev_err(&pdev->dev, "%s: Registration with the SSR notification driver failed (%d)",
__func__, ret);
- goto err_smsm;
+ goto err_irq;
}
return 0;
-err_smsm:
- smsm_state_cb_deregister(SMSM_MODEM_STATE, SMSM_RESET, smsm_state_cb,
- drv);
err_irq:
destroy_ramdump_device(drv->smem_ramdump_dev);
err_ramdump_smem:
@@ -794,7 +794,7 @@
static int __devinit pil_mss_driver_probe(struct platform_device *pdev)
{
struct mba_data *drv;
- int ret;
+ int ret, err_fatal_gpio;
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
if (!drv)
@@ -809,6 +809,22 @@
return ret;
}
+ /* Get the IRQ from the GPIO for registering inbound handler */
+ err_fatal_gpio = of_get_named_gpio(pdev->dev.of_node,
+ "qcom,gpio-err-fatal", 0);
+ if (err_fatal_gpio < 0)
+ return err_fatal_gpio;
+
+ drv->err_fatal_irq = gpio_to_irq(err_fatal_gpio);
+ if (drv->err_fatal_irq < 0)
+ return drv->err_fatal_irq;
+
+ /* Get the GPIO pin for writing the outbound bits: add more as needed */
+ drv->force_stop_gpio = of_get_named_gpio(pdev->dev.of_node,
+ "qcom,gpio-force-stop", 0);
+ if (drv->force_stop_gpio < 0)
+ return drv->force_stop_gpio;
+
return pil_subsys_init(drv, pdev);
}
@@ -818,8 +834,6 @@
subsys_notif_unregister_notifier(drv->adsp_state_notifier,
&adsp_state_notifier_block);
- smsm_state_cb_deregister(SMSM_MODEM_STATE, SMSM_RESET,
- smsm_state_cb, drv);
subsys_unregister(drv->subsys);
destroy_ramdump_device(drv->smem_ramdump_dev);
destroy_ramdump_device(drv->ramdump_dev);
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 717c057..3c50bc6 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -974,7 +974,7 @@
if (acc_sts & msm_pm_slp_sts[cpu].mask)
return 0;
- usleep(100);
+ udelay(100);
}
pr_info("%s(): Timed out waiting for CPU %u SPM to enter sleep state",
@@ -1021,6 +1021,9 @@
*/
void msm_pm_enable_retention(bool enable)
{
+ if (enable == msm_pm_ldo_retention_enabled)
+ return;
+
msm_pm_ldo_retention_enabled = enable;
/*
* If retention is being disabled, wakeup all online core to ensure
diff --git a/arch/arm/mach-msm/scm-pas.c b/arch/arm/mach-msm/scm-pas.c
index f73055e..b7271bb 100644
--- a/arch/arm/mach-msm/scm-pas.c
+++ b/arch/arm/mach-msm/scm-pas.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-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
@@ -29,6 +29,23 @@
#define PAS_SHUTDOWN_CMD 6
#define PAS_IS_SUPPORTED_CMD 7
+enum scm_clock_ids {
+ BUS_CLK = 0,
+ CORE_CLK,
+ IFACE_CLK,
+ CORE_CLK_SRC,
+ NUM_CLKS
+};
+
+static const char * const scm_clock_names[NUM_CLKS] = {
+ [BUS_CLK] = "bus_clk",
+ [CORE_CLK] = "core_clk",
+ [IFACE_CLK] = "iface_clk",
+ [CORE_CLK_SRC] = "core_clk_src",
+};
+
+static struct clk *scm_clocks[NUM_CLKS];
+
int pas_init_image(enum pas_id id, const u8 *metadata, size_t size)
{
int ret;
@@ -108,14 +125,13 @@
};
static uint32_t scm_perf_client;
-static struct clk *scm_bus_clk;
static DEFINE_MUTEX(scm_pas_bw_mutex);
static int scm_pas_bw_count;
static int scm_pas_enable_bw(void)
{
- int ret = 0;
+ int ret = 0, i;
if (!scm_perf_client)
return -EINVAL;
@@ -123,30 +139,40 @@
mutex_lock(&scm_pas_bw_mutex);
if (!scm_pas_bw_count) {
ret = msm_bus_scale_client_update_request(scm_perf_client, 1);
- if (ret) {
- pr_err("bandwidth request failed (%d)\n", ret);
- } else if (scm_bus_clk) {
- ret = clk_prepare_enable(scm_bus_clk);
- if (ret)
- pr_err("clock enable failed\n");
- }
- }
- if (ret)
- msm_bus_scale_client_update_request(scm_perf_client, 0);
- else
+ if (ret)
+ goto err_bus;
scm_pas_bw_count++;
+ }
+ for (i = 0; i < NUM_CLKS; i++)
+ if (clk_prepare_enable(scm_clocks[i]))
+ goto err_clk;
+
+ mutex_unlock(&scm_pas_bw_mutex);
+ return ret;
+
+err_clk:
+ pr_err("clk prepare_enable failed (%s)\n", scm_clock_names[i]);
+ for (i--; i >= 0; i--)
+ clk_disable_unprepare(scm_clocks[i]);
+
+err_bus:
+ pr_err("bandwidth request failed (%d)\n", ret);
+ msm_bus_scale_client_update_request(scm_perf_client, 0);
+
mutex_unlock(&scm_pas_bw_mutex);
return ret;
}
static void scm_pas_disable_bw(void)
{
+ int i;
mutex_lock(&scm_pas_bw_mutex);
if (scm_pas_bw_count-- == 1) {
msm_bus_scale_client_update_request(scm_perf_client, 0);
- if (scm_bus_clk)
- clk_disable_unprepare(scm_bus_clk);
}
+ for (i = NUM_CLKS - 1; i >= 0; i--)
+ clk_disable_unprepare(scm_clocks[i]);
+
mutex_unlock(&scm_pas_bw_mutex);
}
@@ -214,17 +240,25 @@
static int __init scm_pas_init(void)
{
- if (cpu_is_msm8974()) {
+ int i, rate;
+ for (i = 0; i < NUM_CLKS; i++) {
+ scm_clocks[i] = clk_get_sys("scm", scm_clock_names[i]);
+ if (IS_ERR(scm_clocks[i]))
+ scm_clocks[i] = NULL;
+ }
+
+ /* Fail silently if this clock is not supported */
+ rate = clk_round_rate(scm_clocks[CORE_CLK_SRC], 1);
+ clk_set_rate(scm_clocks[CORE_CLK_SRC], rate);
+
+ if (cpu_is_msm8974() || cpu_is_msm8226()) {
scm_pas_bw_tbl[0].vectors[0].src = MSM_BUS_MASTER_CRYPTO_CORE0;
scm_pas_bw_tbl[1].vectors[0].src = MSM_BUS_MASTER_CRYPTO_CORE0;
} else {
- scm_bus_clk = clk_get_sys("scm", "bus_clk");
- if (!IS_ERR(scm_bus_clk)) {
- clk_set_rate(scm_bus_clk, 64000000);
- } else {
- scm_bus_clk = NULL;
+ if (!IS_ERR(scm_clocks[BUS_CLK]))
+ clk_set_rate(scm_clocks[BUS_CLK], 64000000);
+ else
pr_warn("unable to get bus clock\n");
- }
}
scm_perf_client = msm_bus_scale_register_client(&scm_pas_bus_pdata);
diff --git a/arch/arm/mach-msm/smp2p.c b/arch/arm/mach-msm/smp2p.c
index 8066005..7bdcce9 100644
--- a/arch/arm/mach-msm/smp2p.c
+++ b/arch/arm/mach-msm/smp2p.c
@@ -1599,8 +1599,8 @@
*/
static int __devinit msm_smp2p_probe(struct platform_device *pdev)
{
- struct resource *irq_out_base;
- struct resource *irq_offset;
+ struct resource *r;
+ void *irq_out_ptr;
char *key;
uint32_t edge;
int ret;
@@ -1617,15 +1617,18 @@
goto fail;
}
- key = "irq-reg-base";
- irq_out_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, key);
- if (!irq_out_base)
- goto missing_key;
-
- key = "irq-reg-offset";
- irq_offset = platform_get_resource_byname(pdev, IORESOURCE_MEM, key);
- if (!irq_offset)
- goto missing_key;
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ SMP2P_ERR("%s: failed gathering irq-reg resource for edge %d\n"
+ , __func__, edge);
+ goto fail;
+ }
+ irq_out_ptr = ioremap_nocache(r->start, resource_size(r));
+ if (!irq_out_ptr) {
+ SMP2P_ERR("%s: failed remap from phys to virt for edge %d\n",
+ __func__, edge);
+ return -ENOMEM;
+ }
key = "qcom,irq-bitmask";
ret = of_property_read_u32(node, key, &irq_bitmask);
@@ -1656,9 +1659,7 @@
*/
smp2p_int_cfgs[edge].in_int_id = irq_line;
smp2p_int_cfgs[edge].out_int_mask = irq_bitmask;
- smp2p_int_cfgs[edge].out_int_ptr =
- (uint32_t *)((uint32_t)irq_out_base->start +
- (uint32_t)irq_offset->start);
+ smp2p_int_cfgs[edge].out_int_ptr = irq_out_ptr;
smp2p_int_cfgs[edge].is_configured = true;
return 0;
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index a8ae50c..57c85e1 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -44,6 +44,7 @@
HW_PLATFORM_LIQUID = 9,
/* Dragonboard platform id is assigned as 10 in CDT */
HW_PLATFORM_DRAGON = 10,
+ HW_PLATFORM_QRD = 11,
HW_PLATFORM_HRD = 13,
HW_PLATFORM_DTV = 14,
HW_PLATFORM_INVALID
@@ -59,6 +60,7 @@
[HW_PLATFORM_MTP] = "MTP",
[HW_PLATFORM_LIQUID] = "Liquid",
[HW_PLATFORM_DRAGON] = "Dragon",
+ [HW_PLATFORM_QRD] = "QRD",
[HW_PLATFORM_HRD] = "HRD",
[HW_PLATFORM_DTV] = "DTV",
};
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 56a9a4a..f385fc4 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -22,6 +22,7 @@
#include <linux/memblock.h>
#include <linux/slab.h>
#include <linux/iommu.h>
+#include <linux/io.h>
#include <linux/vmalloc.h>
#include <asm/memory.h>
@@ -230,116 +231,73 @@
}
#ifdef CONFIG_MMU
-
-#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - consistent_base) >> PAGE_SHIFT)
-#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - consistent_base) >> PMD_SHIFT)
-
-/*
- * These are the page tables (2MB each) covering uncached, DMA consistent allocations
- */
-static pte_t **consistent_pte;
-
-#define DEFAULT_CONSISTENT_DMA_SIZE (7*SZ_2M)
-
-static unsigned long consistent_base = CONSISTENT_END - DEFAULT_CONSISTENT_DMA_SIZE;
-
-void __init init_consistent_dma_size(unsigned long size)
-{
- unsigned long base = CONSISTENT_END - ALIGN(size, SZ_2M);
-
- BUG_ON(consistent_pte); /* Check we're called before DMA region init */
- BUG_ON(base < VMALLOC_END);
-
- /* Grow region to accommodate specified size */
- if (base < consistent_base)
- consistent_base = base;
-}
-
-#include "vmregion.h"
-
-static struct arm_vmregion_head consistent_head = {
- .vm_lock = __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),
- .vm_list = LIST_HEAD_INIT(consistent_head.vm_list),
- .vm_end = CONSISTENT_END,
-};
-
#ifdef CONFIG_HUGETLB_PAGE
#error ARM Coherent DMA allocator does not (yet) support huge TLB
#endif
-/*
- * Initialise the consistent memory allocation.
- */
-static int __init consistent_init(void)
+static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
+ pgprot_t prot, struct page **ret_page,
+ const void *caller);
+
+static void *
+__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
+ const void *caller)
{
- int ret = 0;
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- int i = 0;
- unsigned long base = consistent_base;
- unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT;
+ struct vm_struct *area;
+ unsigned long addr;
- if (IS_ENABLED(CONFIG_CMA) && !IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU))
- return 0;
+ /*
+ * DMA allocation can be mapped to user space, so lets
+ * set VM_USERMAP flags too.
+ */
+ area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP,
+ caller);
+ if (!area)
+ return NULL;
+ addr = (unsigned long)area->addr;
+ area->phys_addr = __pfn_to_phys(page_to_pfn(page));
- consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL);
- if (!consistent_pte) {
- pr_err("%s: no memory\n", __func__);
- return -ENOMEM;
+ if (ioremap_page_range(addr, addr + size, area->phys_addr, prot)) {
+ vunmap((void *)addr);
+ return NULL;
}
-
- pr_debug("DMA memory: 0x%08lx - 0x%08lx:\n", base, CONSISTENT_END);
- consistent_head.vm_start = base;
-
- do {
- pgd = pgd_offset(&init_mm, base);
-
- pud = pud_alloc(&init_mm, pgd, base);
- if (!pud) {
- pr_err("%s: no pud tables\n", __func__);
- ret = -ENOMEM;
- break;
- }
-
- pmd = pmd_alloc(&init_mm, pud, base);
- if (!pmd) {
- pr_err("%s: no pmd tables\n", __func__);
- ret = -ENOMEM;
- break;
- }
- WARN_ON(!pmd_none(*pmd));
-
- pte = pte_alloc_kernel(pmd, base);
- if (!pte) {
- pr_err("%s: no pte tables\n", __func__);
- ret = -ENOMEM;
- break;
- }
-
- consistent_pte[i++] = pte;
- base += PMD_SIZE;
- } while (base < CONSISTENT_END);
-
- return ret;
+ return (void *)addr;
}
-core_initcall(consistent_init);
+
+static void __dma_free_remap(void *cpu_addr, size_t size, bool no_warn)
+{
+ unsigned int flags = VM_ARM_DMA_CONSISTENT | VM_USERMAP;
+ struct vm_struct *area = find_vm_area(cpu_addr);
+ if (!area || (area->flags & flags) != flags) {
+ if (!no_warn)
+ WARN(1, "trying to free invalid coherent area: %p\n",
+ cpu_addr);
+ return;
+ }
+ unmap_kernel_range((unsigned long)cpu_addr, size);
+ vunmap(cpu_addr);
+}
static void *__alloc_from_contiguous(struct device *dev, size_t size,
pgprot_t prot, struct page **ret_page,
bool no_kernel_mapping, const void *caller);
-static struct arm_vmregion_head coherent_head = {
- .vm_lock = __SPIN_LOCK_UNLOCKED(&coherent_head.vm_lock),
- .vm_list = LIST_HEAD_INIT(coherent_head.vm_list),
+struct dma_pool {
+ size_t size;
+ spinlock_t lock;
+ unsigned long *bitmap;
+ unsigned long nr_pages;
+ void *vaddr;
+ struct page *page;
};
-static size_t coherent_pool_size = DEFAULT_CONSISTENT_DMA_SIZE / 8;
+static struct dma_pool atomic_pool = {
+ .size = SZ_256K,
+};
static int __init early_coherent_pool(char *p)
{
- coherent_pool_size = memparse(p, &p);
+ atomic_pool.size = memparse(p, &p);
return 0;
}
early_param("coherent_pool", early_coherent_pool);
@@ -347,33 +305,46 @@
/*
* Initialise the coherent pool for atomic allocations.
*/
-static int __init coherent_init(void)
+static int __init atomic_pool_init(void)
{
+ struct dma_pool *pool = &atomic_pool;
pgprot_t prot = pgprot_dmacoherent(pgprot_kernel);
- size_t size = coherent_pool_size;
+ unsigned long nr_pages = pool->size >> PAGE_SHIFT;
+ unsigned long *bitmap;
struct page *page;
void *ptr;
+ int bitmap_size = BITS_TO_LONGS(nr_pages) * sizeof(long);
- if (!IS_ENABLED(CONFIG_CMA))
- return 0;
+ bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+ if (!bitmap)
+ goto no_bitmap;
- ptr = __alloc_from_contiguous(NULL, size, prot, &page, false,
- coherent_init);
+ if (IS_ENABLED(CONFIG_CMA))
+ ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page,
+ false, atomic_pool_init);
+ else
+ ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot,
+ &page, NULL);
if (ptr) {
- coherent_head.vm_start = (unsigned long) ptr;
- coherent_head.vm_end = (unsigned long) ptr + size;
- printk(KERN_INFO "DMA: preallocated %u KiB pool for atomic coherent allocations\n",
- (unsigned)size / 1024);
+ spin_lock_init(&pool->lock);
+ pool->vaddr = ptr;
+ pool->page = page;
+ pool->bitmap = bitmap;
+ pool->nr_pages = nr_pages;
+ pr_info("DMA: preallocated %u KiB pool for atomic coherent allocations\n",
+ (unsigned)pool->size / 1024);
return 0;
}
- printk(KERN_ERR "DMA: failed to allocate %u KiB pool for atomic coherent allocation\n",
- (unsigned)size / 1024);
+ kfree(bitmap);
+no_bitmap:
+ pr_err("DMA: failed to allocate %u KiB pool for atomic coherent allocation\n",
+ (unsigned)pool->size / 1024);
return -ENOMEM;
}
/*
* CMA is activated by core_initcall, so we must be called after it.
*/
-postcore_initcall(coherent_init);
+postcore_initcall(atomic_pool_init);
struct dma_contig_early_reserve {
phys_addr_t base;
@@ -421,114 +392,6 @@
}
}
-static void *
-__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
- const void *caller)
-{
- struct arm_vmregion *c;
- size_t align;
- int bit;
-
- if (!consistent_pte) {
- pr_err("%s: not initialised\n", __func__);
- dump_stack();
- return NULL;
- }
-
- /*
- * Align the virtual region allocation - maximum alignment is
- * a section size, minimum is a page size. This helps reduce
- * fragmentation of the DMA space, and also prevents allocations
- * smaller than a section from crossing a section boundary.
- */
- bit = fls(size - 1);
- if (bit > SECTION_SHIFT)
- bit = SECTION_SHIFT;
- align = 1 << bit;
-
- /*
- * Allocate a virtual address in the consistent mapping region.
- */
- c = arm_vmregion_alloc(&consistent_head, align, size,
- gfp & ~(__GFP_DMA | __GFP_HIGHMEM), caller);
- if (c) {
- pte_t *pte;
- int idx = CONSISTENT_PTE_INDEX(c->vm_start);
- u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
-
- pte = consistent_pte[idx] + off;
- c->priv = page;
-
- do {
- BUG_ON(!pte_none(*pte));
-
- set_pte_ext(pte, mk_pte(page, prot), 0);
- page++;
- pte++;
- off++;
- if (off >= PTRS_PER_PTE) {
- off = 0;
- pte = consistent_pte[++idx];
- }
- } while (size -= PAGE_SIZE);
-
- dsb();
-
- return (void *)c->vm_start;
- }
- return NULL;
-}
-
-static void __dma_free_remap(void *cpu_addr, size_t size, bool no_warn)
-{
- struct arm_vmregion *c;
- unsigned long addr;
- pte_t *ptep;
- int idx;
- u32 off;
-
- c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
- if (!c) {
- if (!no_warn) {
- pr_err("%s: trying to free invalid coherent area: %p\n",
- __func__, cpu_addr);
- dump_stack();
- }
- return;
- }
-
- if ((c->vm_end - c->vm_start) != size) {
- pr_err("%s: freeing wrong coherent size (%ld != %d)\n",
- __func__, c->vm_end - c->vm_start, size);
- dump_stack();
- size = c->vm_end - c->vm_start;
- }
-
- idx = CONSISTENT_PTE_INDEX(c->vm_start);
- off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
- ptep = consistent_pte[idx] + off;
- addr = c->vm_start;
- do {
- pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
-
- ptep++;
- addr += PAGE_SIZE;
- off++;
- if (off >= PTRS_PER_PTE) {
- off = 0;
- ptep = consistent_pte[++idx];
- }
-
- if (pte_none(pte) || !pte_present(pte))
- pr_crit("%s: bad page in kernel page table\n",
- __func__);
- } while (size -= PAGE_SIZE);
-
- flush_tlb_kernel_range(c->vm_start, c->vm_end);
-
- arm_vmregion_free(&consistent_head, c);
-}
-
static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr,
void *data)
{
@@ -584,16 +447,17 @@
return ptr;
}
-static void *__alloc_from_pool(struct device *dev, size_t size,
- struct page **ret_page, const void *caller)
+static void *__alloc_from_pool(size_t size, struct page **ret_page)
{
- struct arm_vmregion *c;
+ struct dma_pool *pool = &atomic_pool;
+ unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ unsigned int pageno;
+ unsigned long flags;
+ void *ptr = NULL;
size_t align;
- if (!coherent_head.vm_start) {
- printk(KERN_ERR "%s: coherent pool not initialised!\n",
- __func__);
- dump_stack();
+ if (!pool->vaddr) {
+ WARN(1, "coherent pool not initialised!\n");
return NULL;
}
@@ -603,35 +467,41 @@
* size. This helps reduce fragmentation of the DMA space.
*/
align = PAGE_SIZE << get_order(size);
- c = arm_vmregion_alloc(&coherent_head, align, size, 0, caller);
- if (c) {
- void *ptr = (void *)c->vm_start;
- struct page *page = virt_to_page(ptr);
- *ret_page = page;
- return ptr;
+
+ spin_lock_irqsave(&pool->lock, flags);
+ pageno = bitmap_find_next_zero_area(pool->bitmap, pool->nr_pages,
+ 0, count, (1 << align) - 1);
+ if (pageno < pool->nr_pages) {
+ bitmap_set(pool->bitmap, pageno, count);
+ ptr = pool->vaddr + PAGE_SIZE * pageno;
+ *ret_page = pool->page + pageno;
}
- return NULL;
+ spin_unlock_irqrestore(&pool->lock, flags);
+
+ return ptr;
}
-static int __free_from_pool(void *cpu_addr, size_t size)
+static int __free_from_pool(void *start, size_t size)
{
- unsigned long start = (unsigned long)cpu_addr;
- unsigned long end = start + size;
- struct arm_vmregion *c;
+ struct dma_pool *pool = &atomic_pool;
+ unsigned long pageno, count;
+ unsigned long flags;
- if (start < coherent_head.vm_start || end > coherent_head.vm_end)
+ if (start < pool->vaddr || start > pool->vaddr + pool->size)
return 0;
- c = arm_vmregion_find_remove(&coherent_head, (unsigned long)start);
-
- if ((c->vm_end - c->vm_start) != size) {
- printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
- __func__, c->vm_end - c->vm_start, size);
- dump_stack();
- size = c->vm_end - c->vm_start;
+ if (start + size > pool->vaddr + pool->size) {
+ WARN(1, "freeing wrong coherent size from pool\n");
+ return 0;
}
- arm_vmregion_free(&coherent_head, c);
+ pageno = (start - pool->vaddr) >> PAGE_SHIFT;
+ count = size >> PAGE_SHIFT;
+
+ spin_lock_irqsave(&pool->lock, flags);
+ bitmap_clear(pool->bitmap, pageno, count);
+ spin_unlock_irqrestore(&pool->lock, flags);
+
return 1;
}
@@ -766,10 +636,10 @@
if (arch_is_coherent() || nommu())
addr = __alloc_simple_buffer(dev, size, gfp, &page);
+ else if (gfp & GFP_ATOMIC)
+ addr = __alloc_from_pool(size, &page);
else if (!IS_ENABLED(CONFIG_CMA))
addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller);
- else if (gfp & GFP_ATOMIC)
- addr = __alloc_from_pool(dev, size, &page, caller);
else
addr = __alloc_from_contiguous(dev, size, prot, &page,
no_kernel_mapping, caller);
@@ -1067,9 +937,6 @@
static int __init dma_debug_do_init(void)
{
-#ifdef CONFIG_MMU
- arm_vmregion_create_proc("dma-mappings", &consistent_head);
-#endif
dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
return 0;
}
@@ -1186,61 +1053,32 @@
* Create a CPU mapping for a specified pages
*/
static void *
-__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot)
+__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot,
+ const void *caller)
{
- struct arm_vmregion *c;
- size_t align;
- size_t count = size >> PAGE_SHIFT;
- int bit;
+ unsigned int i, nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ struct vm_struct *area;
+ unsigned long p;
- if (!consistent_pte[0]) {
- pr_err("%s: not initialised\n", __func__);
- dump_stack();
+ area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP,
+ caller);
+ if (!area)
return NULL;
+
+ area->pages = pages;
+ area->nr_pages = nr_pages;
+ p = (unsigned long)area->addr;
+
+ for (i = 0; i < nr_pages; i++) {
+ phys_addr_t phys = __pfn_to_phys(page_to_pfn(pages[i]));
+ if (ioremap_page_range(p, p + PAGE_SIZE, phys, prot))
+ goto err;
+ p += PAGE_SIZE;
}
-
- /*
- * Align the virtual region allocation - maximum alignment is
- * a section size, minimum is a page size. This helps reduce
- * fragmentation of the DMA space, and also prevents allocations
- * smaller than a section from crossing a section boundary.
- */
- bit = fls(size - 1);
- if (bit > SECTION_SHIFT)
- bit = SECTION_SHIFT;
- align = 1 << bit;
-
- /*
- * Allocate a virtual address in the consistent mapping region.
- */
- c = arm_vmregion_alloc(&consistent_head, align, size,
- gfp & ~(__GFP_DMA | __GFP_HIGHMEM), NULL);
- if (c) {
- pte_t *pte;
- int idx = CONSISTENT_PTE_INDEX(c->vm_start);
- int i = 0;
- u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
-
- pte = consistent_pte[idx] + off;
- c->priv = pages;
-
- do {
- BUG_ON(!pte_none(*pte));
-
- set_pte_ext(pte, mk_pte(pages[i], prot), 0);
- pte++;
- off++;
- i++;
- if (off >= PTRS_PER_PTE) {
- off = 0;
- pte = consistent_pte[++idx];
- }
- } while (i < count);
-
- dsb();
-
- return (void *)c->vm_start;
- }
+ return area->addr;
+err:
+ unmap_kernel_range((unsigned long)area->addr, size);
+ vunmap(area->addr);
return NULL;
}
@@ -1299,6 +1137,16 @@
return 0;
}
+static struct page **__iommu_get_pages(void *cpu_addr)
+{
+ struct vm_struct *area;
+
+ area = find_vm_area(cpu_addr);
+ if (area && (area->flags & VM_ARM_DMA_CONSISTENT))
+ return area->pages;
+ return NULL;
+}
+
static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
{
@@ -1317,7 +1165,8 @@
if (*handle == DMA_ERROR_CODE)
goto err_buffer;
- addr = __iommu_alloc_remap(pages, size, gfp, prot);
+ addr = __iommu_alloc_remap(pages, size, gfp, prot,
+ __builtin_return_address(0));
if (!addr)
goto err_mapping;
@@ -1334,31 +1183,25 @@
void *cpu_addr, dma_addr_t dma_addr, size_t size,
struct dma_attrs *attrs)
{
- struct arm_vmregion *c;
+ unsigned long uaddr = vma->vm_start;
+ unsigned long usize = vma->vm_end - vma->vm_start;
+ struct page **pages = __iommu_get_pages(cpu_addr);
vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
- c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
- if (c) {
- struct page **pages = c->priv;
+ if (!pages)
+ return -ENXIO;
- unsigned long uaddr = vma->vm_start;
- unsigned long usize = vma->vm_end - vma->vm_start;
- int i = 0;
+ do {
+ int ret = vm_insert_page(vma, uaddr, *pages++);
+ if (ret) {
+ pr_err("Remapping memory failed: %d\n", ret);
+ return ret;
+ }
+ uaddr += PAGE_SIZE;
+ usize -= PAGE_SIZE;
+ } while (usize > 0);
- do {
- int ret;
-
- ret = vm_insert_page(vma, uaddr, pages[i++]);
- if (ret) {
- pr_err("Remapping memory, error: %d\n", ret);
- return ret;
- }
-
- uaddr += PAGE_SIZE;
- usize -= PAGE_SIZE;
- } while (usize > 0);
- }
return 0;
}
@@ -1369,16 +1212,19 @@
void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t handle, struct dma_attrs *attrs)
{
- struct arm_vmregion *c;
+ struct page **pages = __iommu_get_pages(cpu_addr);
size = PAGE_ALIGN(size);
- c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
- if (c) {
- struct page **pages = c->priv;
- __dma_free_remap(cpu_addr, size, false);
- __iommu_remove_mapping(dev, handle, size);
- __iommu_free_buffer(dev, pages, size);
+ if (!pages) {
+ WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
+ return;
}
+
+ unmap_kernel_range((unsigned long)cpu_addr, size);
+ vunmap(cpu_addr);
+
+ __iommu_remove_mapping(dev, handle, size);
+ __iommu_free_buffer(dev, pages, size);
}
/*
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 87fa3f2..a8ee92d 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -62,6 +62,9 @@
#define VM_ARM_MTYPE(mt) ((mt) << 20)
#define VM_ARM_MTYPE_MASK (0x1f << 20)
+/* consistent regions used by dma_alloc_attrs() */
+#define VM_ARM_DMA_CONSISTENT 0x20000000
+
#endif
#ifdef CONFIG_ZONE_DMA
diff --git a/block/blk-core.c b/block/blk-core.c
index 04604cf..bd50c8e 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -29,6 +29,7 @@
#include <linux/fault-inject.h>
#include <linux/list_sort.h>
#include <linux/delay.h>
+#include <linux/ratelimit.h>
#define CREATE_TRACE_POINTS
#include <trace/events/block.h>
@@ -2203,9 +2204,11 @@
error_type = "I/O";
break;
}
- printk(KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
- error_type, req->rq_disk ? req->rq_disk->disk_name : "?",
- (unsigned long long)blk_rq_pos(req));
+ printk_ratelimited(
+ KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
+ error_type,
+ req->rq_disk ? req->rq_disk->disk_name : "?",
+ (unsigned long long)blk_rq_pos(req));
}
blk_account_io_completion(req, nr_bytes);
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 0b3ffef..e2864ec 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -633,7 +633,7 @@
config MSM_ROTATOR
tristate "MSM Offline Image Rotator Driver"
- depends on (ARCH_MSM7X30 || ARCH_MSM8X60 || ARCH_MSM8960) && ANDROID_PMEM
+ depends on (ARCH_MSM7X30 || ARCH_MSM8X60 || ARCH_MSM8960)
default y
help
This driver provides support for the image rotator HW block in the
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 0c93101..071dd69 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-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
@@ -734,8 +734,8 @@
(driver->log_on_demand_support)) {
driver->apps_rsp_buf[0] = 0x78;
/* Copy log code received */
- *(uint16_t *)(driver->apps_rsp_buf+1) =
- *(uint16_t *)buf;
+ *(uint16_t *)(driver->apps_rsp_buf + 1) =
+ *(uint16_t *)(buf + 1);
driver->apps_rsp_buf[3] = 0x1;/* Unknown */
encode_rsp_and_send(3);
}
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index a4eea54..9d9df2a 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -162,6 +162,8 @@
smd_channel_t *ch;
smd_channel_t *ch_save;
+ struct mutex smd_ch_mutex;
+
int in_busy_1;
int in_busy_2;
@@ -249,6 +251,7 @@
unsigned char *buf_event_mask_update;
unsigned char *buf_feature_mask_update;
int read_len_legacy;
+ struct mutex diag_hdlc_mutex;
unsigned char *hdlc_buf;
unsigned hdlc_count;
unsigned hdlc_escape;
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 6a14143..79a73f3 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -611,8 +611,12 @@
diag_check_mode_reset(buf)) {
return;
}
+ mutex_lock(&driver->smd_data[index].
+ smd_ch_mutex);
smd_write(driver->smd_data[index].ch,
buf, len);
+ mutex_unlock(&driver->smd_data[index].
+ smd_ch_mutex);
} else {
pr_err("diag: In %s, smd channel %d not open\n",
__func__, index);
@@ -1003,6 +1007,9 @@
{
struct diag_hdlc_decode_type hdlc;
int ret, type = 0;
+
+ mutex_lock(&driver->diag_hdlc_mutex);
+
pr_debug("diag: HDLC decode fn, len of data %d\n", len);
hdlc.dest_ptr = driver->hdlc_buf;
hdlc.dest_size = USB_MAX_OUT_BUF;
@@ -1023,14 +1030,17 @@
if (hdlc.dest_idx < 4) {
pr_err_ratelimited("diag: In %s, message is too short, len: %d, dest len: %d\n",
__func__, len, hdlc.dest_idx);
+ mutex_unlock(&driver->diag_hdlc_mutex);
return;
}
if (ret) {
type = diag_process_apps_pkt(driver->hdlc_buf,
hdlc.dest_idx - 3);
- if (type < 0)
+ if (type < 0) {
+ mutex_unlock(&driver->diag_hdlc_mutex);
return;
+ }
} else if (driver->debug_flag) {
printk(KERN_ERR "Packet dropped due to bad HDLC coding/CRC"
" errors or partial packet received, packet"
@@ -1049,10 +1059,15 @@
if (chk_apps_only()) {
diag_send_error_rsp(hdlc.dest_idx);
} else { /* APQ 8060, Let Q6 respond */
- if (driver->smd_data[LPASS_DATA].ch)
+ if (driver->smd_data[LPASS_DATA].ch) {
+ mutex_lock(&driver->smd_data[LPASS_DATA].
+ smd_ch_mutex);
smd_write(driver->smd_data[LPASS_DATA].ch,
driver->hdlc_buf,
hdlc.dest_idx - 3);
+ mutex_unlock(&driver->smd_data[LPASS_DATA].
+ smd_ch_mutex);
+ }
}
type = 0;
}
@@ -1067,8 +1082,10 @@
if ((driver->smd_data[MODEM_DATA].ch) && (ret) && (type) &&
(hdlc.dest_idx > 3)) {
APPEND_DEBUG('g');
+ mutex_lock(&driver->smd_data[MODEM_DATA].smd_ch_mutex);
smd_write(driver->smd_data[MODEM_DATA].ch,
driver->hdlc_buf, hdlc.dest_idx - 3);
+ mutex_unlock(&driver->smd_data[MODEM_DATA].smd_ch_mutex);
APPEND_DEBUG('h');
#ifdef DIAG_DEBUG
printk(KERN_INFO "writing data to SMD, pkt length %d\n", len);
@@ -1076,6 +1093,7 @@
1, DUMP_PREFIX_ADDRESS, data, len, 1);
#endif /* DIAG DEBUG */
}
+ mutex_unlock(&driver->diag_hdlc_mutex);
}
#ifdef CONFIG_DIAG_OVER_USB
@@ -1411,6 +1429,7 @@
{
smd_info->peripheral = peripheral;
smd_info->type = type;
+ mutex_init(&smd_info->smd_ch_mutex);
switch (peripheral) {
case MODEM_DATA:
@@ -1525,6 +1544,7 @@
diag_debug_buf_idx = 0;
driver->read_len_legacy = 0;
driver->use_device_tree = has_device_tree();
+ mutex_init(&driver->diag_hdlc_mutex);
mutex_init(&driver->diag_cntl_mutex);
success = diag_smd_constructor(&driver->smd_data[MODEM_DATA],
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index 2f87803..b0fb9d8 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -19,7 +19,6 @@
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
-#include <linux/android_pmem.h>
#include <linux/msm_rotator.h>
#include <linux/io.h>
#include <mach/msm_rotator_imem.h>
@@ -856,10 +855,6 @@
struct file *file = NULL;
int put_needed, fb_num;
#endif
-#ifdef CONFIG_ANDROID_PMEM
- unsigned long vstart;
-#endif
-
*p_need = 0;
#ifdef CONFIG_FB
@@ -890,27 +885,14 @@
}
#endif
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
return msm_rotator_iommu_map_buf(fbd->memory_id, domain, start,
len, p_ihdl, secure);
-#endif
-#ifdef CONFIG_ANDROID_PMEM
- if (!get_pmem_file(fbd->memory_id, start, &vstart, len, p_file))
- return 0;
- else
- return -ENOMEM;
-#endif
}
static void put_img(struct file *p_file, struct ion_handle *p_ihdl,
int domain, unsigned int secure)
{
-#ifdef CONFIG_ANDROID_PMEM
- if (p_file != NULL)
- put_pmem_file(p_file);
-#endif
-
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
if (!IS_ERR_OR_NULL(p_ihdl)) {
pr_debug("%s(): p_ihdl %p\n", __func__, p_ihdl);
diff --git a/drivers/crypto/msm/qce.c b/drivers/crypto/msm/qce.c
index 5c1cc5a..24cf30a 100644
--- a/drivers/crypto/msm/qce.c
+++ b/drivers/crypto/msm/qce.c
@@ -2366,6 +2366,7 @@
ce_support->aes_ccm = false;
ce_support->ota = pce_dev->ota;
ce_support->aligned_only = false;
+ ce_support->is_shared = false;
ce_support->bam = false;
return 0;
}
diff --git a/drivers/crypto/msm/qce.h b/drivers/crypto/msm/qce.h
index 8a31003..3ff84cf 100644
--- a/drivers/crypto/msm/qce.h
+++ b/drivers/crypto/msm/qce.h
@@ -113,6 +113,7 @@
bool ota;
bool aligned_only;
bool bam;
+ bool is_shared;
};
/* Sha operation parameters */
diff --git a/drivers/crypto/msm/qce40.c b/drivers/crypto/msm/qce40.c
index 84d41da..7b0964d 100644
--- a/drivers/crypto/msm/qce40.c
+++ b/drivers/crypto/msm/qce40.c
@@ -2634,6 +2634,7 @@
ce_support->aes_ccm = true;
ce_support->ota = false;
ce_support->aligned_only = false;
+ ce_support->is_shared = false;
ce_support->bam = false;
return 0;
}
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 9d8e825..fe8cf57 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -61,6 +61,7 @@
unsigned char *coh_vmem; /* Allocated coherent virtual memory */
dma_addr_t coh_pmem; /* Allocated coherent physical memory */
int memsize; /* Memory allocated */
+ int is_shared; /* CE HW is shared */
void __iomem *iobase; /* Virtual io base of CE HW */
unsigned int phy_iobase; /* Physical io base of CE HW */
@@ -1047,7 +1048,7 @@
/* Producer pipe will handle this connection */
sps_connect_info->mode = SPS_MODE_SRC;
sps_connect_info->options =
- SPS_O_AUTO_ENABLE | SPS_O_EOT | SPS_O_DESC_DONE;
+ SPS_O_AUTO_ENABLE | SPS_O_DESC_DONE;
} else {
/* For CE consumer transfer, source should be
* system memory where as destination should
@@ -2333,6 +2334,7 @@
/* Register callback event for EOT (End of transfer) event. */
pce_dev->ce_sps.producer.event.callback = _aead_sps_producer_callback;
+ pce_dev->ce_sps.producer.event.options = SPS_O_DESC_DONE;
rc = sps_register_event(pce_dev->ce_sps.producer.pipe,
&pce_dev->ce_sps.producer.event);
if (rc) {
@@ -2341,6 +2343,7 @@
}
/* Register callback event for EOT (End of transfer) event. */
pce_dev->ce_sps.consumer.event.callback = _aead_sps_consumer_callback;
+ pce_dev->ce_sps.consumer.event.options = SPS_O_DESC_DONE;
rc = sps_register_event(pce_dev->ce_sps.consumer.pipe,
&pce_dev->ce_sps.consumer.event);
if (rc) {
@@ -2400,8 +2403,6 @@
if (totallen_in > SPS_MAX_PKT_SIZE) {
_qce_set_flag(&pce_dev->ce_sps.out_transfer,
SPS_IOVEC_FLAG_INT);
- pce_dev->ce_sps.producer.event.options =
- SPS_O_DESC_DONE;
pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_IDLE;
} else {
_qce_sps_add_data(
@@ -2489,6 +2490,7 @@
/* Register callback event for EOT (End of transfer) event. */
pce_dev->ce_sps.producer.event.callback =
_ablk_cipher_sps_producer_callback;
+ pce_dev->ce_sps.producer.event.options = SPS_O_DESC_DONE;
rc = sps_register_event(pce_dev->ce_sps.producer.pipe,
&pce_dev->ce_sps.producer.event);
if (rc) {
@@ -2498,6 +2500,7 @@
/* Register callback event for EOT (End of transfer) event. */
pce_dev->ce_sps.consumer.event.callback =
_ablk_cipher_sps_consumer_callback;
+ pce_dev->ce_sps.consumer.event.options = SPS_O_DESC_DONE;
rc = sps_register_event(pce_dev->ce_sps.consumer.pipe,
&pce_dev->ce_sps.consumer.event);
if (rc) {
@@ -2519,7 +2522,6 @@
if (areq->nbytes > SPS_MAX_PKT_SIZE) {
_qce_set_flag(&pce_dev->ce_sps.out_transfer,
SPS_IOVEC_FLAG_INT);
- pce_dev->ce_sps.producer.event.options = SPS_O_DESC_DONE;
pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_IDLE;
} else {
pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_COMP;
@@ -2571,6 +2573,7 @@
/* Register callback event for EOT (End of transfer) event. */
pce_dev->ce_sps.producer.event.callback = _sha_sps_producer_callback;
+ pce_dev->ce_sps.producer.event.options = SPS_O_DESC_DONE;
rc = sps_register_event(pce_dev->ce_sps.producer.pipe,
&pce_dev->ce_sps.producer.event);
if (rc) {
@@ -2580,6 +2583,7 @@
/* Register callback event for EOT (End of transfer) event. */
pce_dev->ce_sps.consumer.event.callback = _sha_sps_consumer_callback;
+ pce_dev->ce_sps.consumer.event.options = SPS_O_DESC_DONE;
rc = sps_register_event(pce_dev->ce_sps.consumer.pipe,
&pce_dev->ce_sps.consumer.event);
if (rc) {
@@ -2619,6 +2623,9 @@
struct resource *resource;
int rc = 0;
+ pce_dev->is_shared = of_property_read_bool((&pdev->dev)->of_node,
+ "qcom,ce-hw-shared");
+
if (of_property_read_u32((&pdev->dev)->of_node,
"qcom,bam-pipe-pair",
&pce_dev->ce_sps.pipe_pair_index)) {
@@ -2902,6 +2909,7 @@
ce_support->aes_xts = true;
ce_support->ota = false;
ce_support->bam = true;
+ ce_support->is_shared = (pce_dev->is_shared == 1) ? true : false;
ce_support->aes_ccm = true;
if (pce_dev->ce_sps.minor_version)
ce_support->aligned_only = false;
diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 464fa21..1c63b70 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -30,7 +30,7 @@
comment "DEVFREQ Governors"
config DEVFREQ_GOV_SIMPLE_ONDEMAND
- bool "Simple Ondemand"
+ tristate "Simple Ondemand"
help
Chooses frequency based on the recent load on the device. Works
similar as ONDEMAND governor of CPUFREQ does. A device with
@@ -39,7 +39,7 @@
values to the governor with data field at devfreq_add_device().
config DEVFREQ_GOV_PERFORMANCE
- bool "Performance"
+ tristate "Performance"
help
Sets the frequency at the maximum available frequency.
This governor always returns UINT_MAX as frequency so that
@@ -47,7 +47,7 @@
at any time.
config DEVFREQ_GOV_POWERSAVE
- bool "Powersave"
+ tristate "Powersave"
help
Sets the frequency at the minimum available frequency.
This governor always returns 0 as frequency so that
@@ -55,7 +55,7 @@
at any time.
config DEVFREQ_GOV_USERSPACE
- bool "Userspace"
+ tristate "Userspace"
help
Sets the frequency at the user specified one.
This governor returns the user configured frequency if there
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 2ab79d2..89d779c 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -159,6 +159,9 @@
return -EINVAL;
}
+ if (!devfreq->governor)
+ return -EINVAL;
+
/* Reevaluate the proper frequency */
err = devfreq->governor->get_target_freq(devfreq, &freq);
if (err)
@@ -232,6 +235,7 @@
queue_delayed_work(devfreq_wq, &devfreq->work,
msecs_to_jiffies(devfreq->profile->polling_ms));
}
+EXPORT_SYMBOL(devfreq_monitor_start);
/**
* devfreq_monitor_stop() - Stop load monitoring of a devfreq instance
@@ -245,6 +249,7 @@
{
cancel_delayed_work_sync(&devfreq->work);
}
+EXPORT_SYMBOL(devfreq_monitor_stop);
/**
* devfreq_monitor_suspend() - Suspend load monitoring of a devfreq instance
@@ -270,6 +275,7 @@
mutex_unlock(&devfreq->lock);
cancel_delayed_work_sync(&devfreq->work);
}
+EXPORT_SYMBOL(devfreq_monitor_suspend);
/**
* devfreq_monitor_resume() - Resume load monitoring of a devfreq instance
@@ -294,6 +300,7 @@
out:
mutex_unlock(&devfreq->lock);
}
+EXPORT_SYMBOL(devfreq_monitor_resume);
/**
* devfreq_interval_update() - Update device devfreq monitoring interval
@@ -340,6 +347,7 @@
out:
mutex_unlock(&devfreq->lock);
}
+EXPORT_SYMBOL(devfreq_interval_update);
/**
* devfreq_notifier_call() - Notify that the device frequency requirements
@@ -379,7 +387,9 @@
list_del(&devfreq->node);
mutex_unlock(&devfreq_list_lock);
- devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_STOP, NULL);
+ if (devfreq->governor)
+ devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_STOP, NULL);
if (devfreq->profile->exit)
devfreq->profile->exit(devfreq->dev.parent);
@@ -412,19 +422,20 @@
* devfreq_add_device() - Add devfreq feature to the device
* @dev: the device to add devfreq feature.
* @profile: device-specific profile to run devfreq.
- * @governor: the policy to choose frequency.
+ * @governor_name: name of the policy to choose frequency.
* @data: private data for the governor. The devfreq framework does not
* touch this value.
*/
struct devfreq *devfreq_add_device(struct device *dev,
struct devfreq_dev_profile *profile,
- const struct devfreq_governor *governor,
+ const char *governor_name,
void *data)
{
struct devfreq *devfreq;
+ struct devfreq_governor *governor;
int err = 0;
- if (!dev || !profile || !governor) {
+ if (!dev || !profile || !governor_name) {
dev_err(dev, "%s: Invalid parameters.\n", __func__);
return ERR_PTR(-EINVAL);
}
@@ -452,7 +463,7 @@
devfreq->dev.class = devfreq_class;
devfreq->dev.release = devfreq_dev_release;
devfreq->profile = profile;
- devfreq->governor = governor;
+ strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN);
devfreq->previous_freq = profile->initial_freq;
devfreq->data = data;
devfreq->nb.notifier_call = devfreq_notifier_call;
@@ -478,10 +489,14 @@
mutex_lock(&devfreq_list_lock);
list_add(&devfreq->node, &devfreq_list);
- mutex_unlock(&devfreq_list_lock);
- err = devfreq->governor->event_handler(devfreq,
- DEVFREQ_GOV_START, NULL);
+ governor = find_devfreq_governor(devfreq->governor_name);
+ if (!IS_ERR(governor))
+ devfreq->governor = governor;
+ if (devfreq->governor)
+ err = devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_START, NULL);
+ mutex_unlock(&devfreq_list_lock);
if (err) {
dev_err(dev, "%s: Unable to start governor for the device\n",
__func__);
@@ -524,6 +539,9 @@
if (!devfreq)
return -EINVAL;
+ if (!devfreq->governor)
+ return 0;
+
return devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_SUSPEND, NULL);
}
@@ -538,6 +556,9 @@
if (!devfreq)
return -EINVAL;
+ if (!devfreq->governor)
+ return 0;
+
return devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_RESUME, NULL);
}
@@ -550,6 +571,7 @@
int devfreq_add_governor(struct devfreq_governor *governor)
{
struct devfreq_governor *g;
+ struct devfreq *devfreq;
int err = 0;
if (!governor) {
@@ -568,6 +590,38 @@
list_add(&governor->node, &devfreq_governor_list);
+ list_for_each_entry(devfreq, &devfreq_list, node) {
+ int ret = 0;
+ struct device *dev = devfreq->dev.parent;
+
+ if (!strncmp(devfreq->governor_name, governor->name,
+ DEVFREQ_NAME_LEN)) {
+ /* The following should never occur */
+ if (devfreq->governor) {
+ dev_warn(dev,
+ "%s: Governor %s already present\n",
+ __func__, devfreq->governor->name);
+ ret = devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_STOP, NULL);
+ if (ret) {
+ dev_warn(dev,
+ "%s: Governor %s stop = %d\n",
+ __func__,
+ devfreq->governor->name, ret);
+ }
+ /* Fall through */
+ }
+ devfreq->governor = governor;
+ ret = devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_START, NULL);
+ if (ret) {
+ dev_warn(dev, "%s: Governor %s start=%d\n",
+ __func__, devfreq->governor->name,
+ ret);
+ }
+ }
+ }
+
err_out:
mutex_unlock(&devfreq_list_lock);
@@ -582,6 +636,7 @@
int devfreq_remove_governor(struct devfreq_governor *governor)
{
struct devfreq_governor *g;
+ struct devfreq *devfreq;
int err = 0;
if (!governor) {
@@ -593,10 +648,33 @@
g = find_devfreq_governor(governor->name);
if (IS_ERR(g)) {
pr_err("%s: governor %s not registered\n", __func__,
- g->name);
- err = -EINVAL;
+ governor->name);
+ err = PTR_ERR(g);
goto err_out;
}
+ list_for_each_entry(devfreq, &devfreq_list, node) {
+ int ret;
+ struct device *dev = devfreq->dev.parent;
+
+ if (!strncmp(devfreq->governor_name, governor->name,
+ DEVFREQ_NAME_LEN)) {
+ /* we should have a devfreq governor! */
+ if (!devfreq->governor) {
+ dev_warn(dev, "%s: Governor %s NOT present\n",
+ __func__, governor->name);
+ continue;
+ /* Fall through */
+ }
+ ret = devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_STOP, NULL);
+ if (ret) {
+ dev_warn(dev, "%s: Governor %s stop=%d\n",
+ __func__, devfreq->governor->name,
+ ret);
+ }
+ devfreq->governor = NULL;
+ }
+ }
list_del(&governor->node);
err_out:
@@ -609,9 +687,76 @@
static ssize_t show_governor(struct device *dev,
struct device_attribute *attr, char *buf)
{
+ if (!to_devfreq(dev)->governor)
+ return -EINVAL;
+
return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name);
}
+static ssize_t store_governor(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct devfreq *df = to_devfreq(dev);
+ int ret;
+ char str_governor[DEVFREQ_NAME_LEN + 1];
+ struct devfreq_governor *governor;
+
+ ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor);
+ if (ret != 1)
+ return -EINVAL;
+
+ mutex_lock(&devfreq_list_lock);
+ governor = find_devfreq_governor(str_governor);
+ if (IS_ERR(governor)) {
+ ret = PTR_ERR(governor);
+ goto out;
+ }
+ if (df->governor == governor)
+ goto out;
+
+ if (df->governor) {
+ ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL);
+ if (ret) {
+ dev_warn(dev, "%s: Governor %s not stopped(%d)\n",
+ __func__, df->governor->name, ret);
+ goto out;
+ }
+ }
+ df->governor = governor;
+ strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN);
+ ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
+ if (ret)
+ dev_warn(dev, "%s: Governor %s not started(%d)\n",
+ __func__, df->governor->name, ret);
+out:
+ mutex_unlock(&devfreq_list_lock);
+
+ if (!ret)
+ ret = count;
+ return ret;
+}
+static ssize_t show_available_governors(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct devfreq_governor *tmp_governor;
+ ssize_t count = 0;
+
+ mutex_lock(&devfreq_list_lock);
+ list_for_each_entry(tmp_governor, &devfreq_governor_list, node)
+ count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
+ "%s ", tmp_governor->name);
+ mutex_unlock(&devfreq_list_lock);
+
+ /* Truncate the trailing space */
+ if (count)
+ count--;
+
+ count += sprintf(&buf[count], "\n");
+
+ return count;
+}
+
static ssize_t show_freq(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -645,6 +790,9 @@
unsigned int value;
int ret;
+ if (!df->governor)
+ return -EINVAL;
+
ret = sscanf(buf, "%u", &value);
if (ret != 1)
return -EINVAL;
@@ -794,7 +942,8 @@
}
static struct device_attribute devfreq_attrs[] = {
- __ATTR(governor, S_IRUGO, show_governor, NULL),
+ __ATTR(governor, S_IRUGO | S_IWUSR, show_governor, store_governor),
+ __ATTR(available_governors, S_IRUGO, show_available_governors, NULL),
__ATTR(cur_freq, S_IRUGO, show_freq, NULL),
__ATTR(available_frequencies, S_IRUGO, show_available_freqs, NULL),
__ATTR(target_freq, S_IRUGO, show_target_freq, NULL),
@@ -845,6 +994,11 @@
* @freq: The frequency given to target function
* @flags: Flags handed from devfreq framework.
*
+ * Locking: This function must be called under rcu_read_lock(). opp is a rcu
+ * protected pointer. The reason for the same is that the opp pointer which is
+ * returned will remain valid for use with opp_get_{voltage, freq} only while
+ * under the locked area. The pointer returned must be used prior to unlocking
+ * with rcu_read_unlock() to maintain the integrity of the pointer.
*/
struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq,
u32 flags)
@@ -879,11 +1033,18 @@
*/
int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq)
{
- struct srcu_notifier_head *nh = opp_get_notifier(dev);
+ struct srcu_notifier_head *nh;
+ int ret = 0;
+ rcu_read_lock();
+ nh = opp_get_notifier(dev);
if (IS_ERR(nh))
- return PTR_ERR(nh);
- return srcu_notifier_chain_register(nh, &devfreq->nb);
+ ret = PTR_ERR(nh);
+ rcu_read_unlock();
+ if (!ret)
+ ret = srcu_notifier_chain_register(nh, &devfreq->nb);
+
+ return ret;
}
/**
@@ -898,11 +1059,18 @@
*/
int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq)
{
- struct srcu_notifier_head *nh = opp_get_notifier(dev);
+ struct srcu_notifier_head *nh;
+ int ret = 0;
+ rcu_read_lock();
+ nh = opp_get_notifier(dev);
if (IS_ERR(nh))
- return PTR_ERR(nh);
- return srcu_notifier_chain_unregister(nh, &devfreq->nb);
+ ret = PTR_ERR(nh);
+ rcu_read_unlock();
+ if (!ret)
+ ret = srcu_notifier_chain_unregister(nh, &devfreq->nb);
+
+ return ret;
}
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c
index 88ddc77..f6c54bd 100644
--- a/drivers/devfreq/exynos4_bus.c
+++ b/drivers/devfreq/exynos4_bus.c
@@ -73,6 +73,16 @@
#define EX4210_LV_NUM (LV_2 + 1)
#define EX4x12_LV_NUM (LV_4 + 1)
+/**
+ * struct busfreq_opp_info - opp information for bus
+ * @rate: Frequency in hertz
+ * @volt: Voltage in microvolts corresponding to this OPP
+ */
+struct busfreq_opp_info {
+ unsigned long rate;
+ unsigned long volt;
+};
+
struct busfreq_data {
enum exynos4_busf_type type;
struct device *dev;
@@ -80,7 +90,7 @@
bool disabled;
struct regulator *vdd_int;
struct regulator *vdd_mif; /* Exynos4412/4212 only */
- struct opp *curr_opp;
+ struct busfreq_opp_info curr_oppinfo;
struct exynos4_ppmu dmc[2];
struct notifier_block pm_notifier;
@@ -296,13 +306,14 @@
};
-static int exynos4210_set_busclk(struct busfreq_data *data, struct opp *opp)
+static int exynos4210_set_busclk(struct busfreq_data *data,
+ struct busfreq_opp_info *oppi)
{
unsigned int index;
unsigned int tmp;
for (index = LV_0; index < EX4210_LV_NUM; index++)
- if (opp_get_freq(opp) == exynos4210_busclk_table[index].clk)
+ if (oppi->rate == exynos4210_busclk_table[index].clk)
break;
if (index == EX4210_LV_NUM)
@@ -361,13 +372,14 @@
return 0;
}
-static int exynos4x12_set_busclk(struct busfreq_data *data, struct opp *opp)
+static int exynos4x12_set_busclk(struct busfreq_data *data,
+ struct busfreq_opp_info *oppi)
{
unsigned int index;
unsigned int tmp;
for (index = LV_0; index < EX4x12_LV_NUM; index++)
- if (opp_get_freq(opp) == exynos4x12_mifclk_table[index].clk)
+ if (oppi->rate == exynos4x12_mifclk_table[index].clk)
break;
if (index == EX4x12_LV_NUM)
@@ -576,11 +588,12 @@
return -EINVAL;
}
-static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp,
- struct opp *oldopp)
+static int exynos4_bus_setvolt(struct busfreq_data *data,
+ struct busfreq_opp_info *oppi,
+ struct busfreq_opp_info *oldoppi)
{
int err = 0, tmp;
- unsigned long volt = opp_get_voltage(opp);
+ unsigned long volt = oppi->volt;
switch (data->type) {
case TYPE_BUSF_EXYNOS4210:
@@ -595,11 +608,11 @@
if (err)
break;
- tmp = exynos4x12_get_intspec(opp_get_freq(opp));
+ tmp = exynos4x12_get_intspec(oppi->rate);
if (tmp < 0) {
err = tmp;
regulator_set_voltage(data->vdd_mif,
- opp_get_voltage(oldopp),
+ oldoppi->volt,
MAX_SAFEVOLT);
break;
}
@@ -609,7 +622,7 @@
/* Try to recover */
if (err)
regulator_set_voltage(data->vdd_mif,
- opp_get_voltage(oldopp),
+ oldoppi->volt,
MAX_SAFEVOLT);
break;
default:
@@ -626,17 +639,26 @@
struct platform_device *pdev = container_of(dev, struct platform_device,
dev);
struct busfreq_data *data = platform_get_drvdata(pdev);
- struct opp *opp = devfreq_recommended_opp(dev, _freq, flags);
- unsigned long freq = opp_get_freq(opp);
- unsigned long old_freq = opp_get_freq(data->curr_opp);
+ struct opp *opp;
+ unsigned long freq;
+ unsigned long old_freq = data->curr_oppinfo.rate;
+ struct busfreq_opp_info new_oppinfo;
- if (IS_ERR(opp))
+ rcu_read_lock();
+ opp = devfreq_recommended_opp(dev, _freq, flags);
+ if (IS_ERR(opp)) {
+ rcu_read_unlock();
return PTR_ERR(opp);
+ }
+ new_oppinfo.rate = opp_get_freq(opp);
+ new_oppinfo.volt = opp_get_voltage(opp);
+ rcu_read_unlock();
+ freq = new_oppinfo.rate;
if (old_freq == freq)
return 0;
- dev_dbg(dev, "targetting %lukHz %luuV\n", freq, opp_get_voltage(opp));
+ dev_dbg(dev, "targetting %lukHz %luuV\n", freq, new_oppinfo.volt);
mutex_lock(&data->lock);
@@ -644,17 +666,18 @@
goto out;
if (old_freq < freq)
- err = exynos4_bus_setvolt(data, opp, data->curr_opp);
+ err = exynos4_bus_setvolt(data, &new_oppinfo,
+ &data->curr_oppinfo);
if (err)
goto out;
if (old_freq != freq) {
switch (data->type) {
case TYPE_BUSF_EXYNOS4210:
- err = exynos4210_set_busclk(data, opp);
+ err = exynos4210_set_busclk(data, &new_oppinfo);
break;
case TYPE_BUSF_EXYNOS4x12:
- err = exynos4x12_set_busclk(data, opp);
+ err = exynos4x12_set_busclk(data, &new_oppinfo);
break;
default:
err = -EINVAL;
@@ -664,11 +687,12 @@
goto out;
if (old_freq > freq)
- err = exynos4_bus_setvolt(data, opp, data->curr_opp);
+ err = exynos4_bus_setvolt(data, &new_oppinfo,
+ &data->curr_oppinfo);
if (err)
goto out;
- data->curr_opp = opp;
+ data->curr_oppinfo = new_oppinfo;
out:
mutex_unlock(&data->lock);
return err;
@@ -702,7 +726,7 @@
exynos4_read_ppmu(data);
busier_dmc = exynos4_get_busier_dmc(data);
- stat->current_frequency = opp_get_freq(data->curr_opp);
+ stat->current_frequency = data->curr_oppinfo.rate;
if (busier_dmc)
addr = S5P_VA_DMC1;
@@ -933,6 +957,7 @@
struct busfreq_data *data = container_of(this, struct busfreq_data,
pm_notifier);
struct opp *opp;
+ struct busfreq_opp_info new_oppinfo;
unsigned long maxfreq = ULONG_MAX;
int err = 0;
@@ -943,18 +968,29 @@
data->disabled = true;
+ rcu_read_lock();
opp = opp_find_freq_floor(data->dev, &maxfreq);
+ if (IS_ERR(opp)) {
+ rcu_read_unlock();
+ dev_err(data->dev, "%s: unable to find a min freq\n",
+ __func__);
+ return PTR_ERR(opp);
+ }
+ new_oppinfo.rate = opp_get_freq(opp);
+ new_oppinfo.volt = opp_get_voltage(opp);
+ rcu_read_unlock();
- err = exynos4_bus_setvolt(data, opp, data->curr_opp);
+ err = exynos4_bus_setvolt(data, &new_oppinfo,
+ &data->curr_oppinfo);
if (err)
goto unlock;
switch (data->type) {
case TYPE_BUSF_EXYNOS4210:
- err = exynos4210_set_busclk(data, opp);
+ err = exynos4210_set_busclk(data, &new_oppinfo);
break;
case TYPE_BUSF_EXYNOS4x12:
- err = exynos4x12_set_busclk(data, opp);
+ err = exynos4x12_set_busclk(data, &new_oppinfo);
break;
default:
err = -EINVAL;
@@ -962,7 +998,7 @@
if (err)
goto unlock;
- data->curr_opp = opp;
+ data->curr_oppinfo = new_oppinfo;
unlock:
mutex_unlock(&data->lock);
if (err)
@@ -987,7 +1023,7 @@
struct device *dev = &pdev->dev;
int err = 0;
- data = kzalloc(sizeof(struct busfreq_data), GFP_KERNEL);
+ data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data), GFP_KERNEL);
if (data == NULL) {
dev_err(dev, "Cannot allocate memory.\n");
return -ENOMEM;
@@ -1012,63 +1048,52 @@
err = -EINVAL;
}
if (err)
- goto err_regulator;
+ return err;
- data->vdd_int = regulator_get(dev, "vdd_int");
+ data->vdd_int = devm_regulator_get(dev, "vdd_int");
if (IS_ERR(data->vdd_int)) {
dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
- err = PTR_ERR(data->vdd_int);
- goto err_regulator;
+ return PTR_ERR(data->vdd_int);
}
if (data->type == TYPE_BUSF_EXYNOS4x12) {
- data->vdd_mif = regulator_get(dev, "vdd_mif");
+ data->vdd_mif = devm_regulator_get(dev, "vdd_mif");
if (IS_ERR(data->vdd_mif)) {
dev_err(dev, "Cannot get the regulator \"vdd_mif\"\n");
- err = PTR_ERR(data->vdd_mif);
- regulator_put(data->vdd_int);
- goto err_regulator;
-
+ return PTR_ERR(data->vdd_mif);
}
}
+ rcu_read_lock();
opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq);
if (IS_ERR(opp)) {
+ rcu_read_unlock();
dev_err(dev, "Invalid initial frequency %lu kHz.\n",
- exynos4_devfreq_profile.initial_freq);
- err = PTR_ERR(opp);
- goto err_opp_add;
+ exynos4_devfreq_profile.initial_freq);
+ return PTR_ERR(opp);
}
- data->curr_opp = opp;
+ data->curr_oppinfo.rate = opp_get_freq(opp);
+ data->curr_oppinfo.volt = opp_get_voltage(opp);
+ rcu_read_unlock();
platform_set_drvdata(pdev, data);
busfreq_mon_reset(data);
data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile,
- &devfreq_simple_ondemand, NULL);
- if (IS_ERR(data->devfreq)) {
- err = PTR_ERR(data->devfreq);
- goto err_opp_add;
- }
+ "simple_ondemand", NULL);
+ if (IS_ERR(data->devfreq))
+ return PTR_ERR(data->devfreq);
devfreq_register_opp_notifier(dev, data->devfreq);
err = register_pm_notifier(&data->pm_notifier);
if (err) {
dev_err(dev, "Failed to setup pm notifier\n");
- goto err_devfreq_add;
+ devfreq_remove_device(data->devfreq);
+ return err;
}
return 0;
-err_devfreq_add:
- devfreq_remove_device(data->devfreq);
-err_opp_add:
- if (data->vdd_mif)
- regulator_put(data->vdd_mif);
- regulator_put(data->vdd_int);
-err_regulator:
- kfree(data);
- return err;
}
static __devexit int exynos4_busfreq_remove(struct platform_device *pdev)
@@ -1077,10 +1102,6 @@
unregister_pm_notifier(&data->pm_notifier);
devfreq_remove_device(data->devfreq);
- regulator_put(data->vdd_int);
- if (data->vdd_mif)
- regulator_put(data->vdd_mif);
- kfree(data);
return 0;
}
diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c
index db8ff77..c72f942 100644
--- a/drivers/devfreq/governor_performance.c
+++ b/drivers/devfreq/governor_performance.c
@@ -10,6 +10,7 @@
*/
#include <linux/devfreq.h>
+#include <linux/module.h>
#include "governor.h"
static int devfreq_performance_func(struct devfreq *df,
@@ -40,7 +41,7 @@
return ret;
}
-const struct devfreq_governor devfreq_performance = {
+static struct devfreq_governor devfreq_performance = {
.name = "performance",
.get_target_freq = devfreq_performance_func,
.event_handler = devfreq_performance_handler,
@@ -63,3 +64,4 @@
return;
}
module_exit(devfreq_performance_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c
index 30f0fca..0c6bed5 100644
--- a/drivers/devfreq/governor_powersave.c
+++ b/drivers/devfreq/governor_powersave.c
@@ -10,6 +10,7 @@
*/
#include <linux/devfreq.h>
+#include <linux/module.h>
#include "governor.h"
static int devfreq_powersave_func(struct devfreq *df,
@@ -37,7 +38,7 @@
return ret;
}
-const struct devfreq_governor devfreq_powersave = {
+static struct devfreq_governor devfreq_powersave = {
.name = "powersave",
.get_target_freq = devfreq_powersave_func,
.event_handler = devfreq_powersave_handler,
@@ -60,3 +61,4 @@
return;
}
module_exit(devfreq_powersave_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c
index 85f9ed5..0720ba8 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -10,6 +10,7 @@
*/
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/devfreq.h>
#include <linux/math64.h>
#include "governor.h"
@@ -120,7 +121,7 @@
return 0;
}
-const struct devfreq_governor devfreq_simple_ondemand = {
+static struct devfreq_governor devfreq_simple_ondemand = {
.name = "simple_ondemand",
.get_target_freq = devfreq_simple_ondemand_func,
.event_handler = devfreq_simple_ondemand_handler,
@@ -143,3 +144,4 @@
return;
}
module_exit(devfreq_simple_ondemand_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c
index 110f178..35de6e8 100644
--- a/drivers/devfreq/governor_userspace.c
+++ b/drivers/devfreq/governor_userspace.c
@@ -14,6 +14,7 @@
#include <linux/devfreq.h>
#include <linux/pm.h>
#include <linux/mutex.h>
+#include <linux/module.h>
#include "governor.h"
struct userspace_data {
@@ -135,7 +136,7 @@
return ret;
}
-const struct devfreq_governor devfreq_userspace = {
+static struct devfreq_governor devfreq_userspace = {
.name = "userspace",
.get_target_freq = devfreq_userspace_func,
.event_handler = devfreq_userspace_handler,
@@ -158,3 +159,4 @@
return;
}
module_exit(devfreq_userspace_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/qpnp-pin.c b/drivers/gpio/qpnp-pin.c
index f0c12f9..64341e9 100644
--- a/drivers/gpio/qpnp-pin.c
+++ b/drivers/gpio/qpnp-pin.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
@@ -821,7 +821,7 @@
param.invert = q_reg_get(&q_spec->regs[Q_REG_I_MODE_CTL],
Q_REG_OUT_INVERT_SHIFT,
Q_REG_OUT_INVERT_MASK);
- param.pull = q_reg_get(&q_spec->regs[Q_REG_I_MODE_CTL],
+ param.pull = q_reg_get(&q_spec->regs[Q_REG_I_DIG_PULL_CTL],
Q_REG_PULL_SHIFT, Q_REG_PULL_MASK);
param.vin_sel = q_reg_get(&q_spec->regs[Q_REG_I_DIG_VIN_CTL],
Q_REG_VIN_SHIFT, Q_REG_VIN_MASK);
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index b51fa6a..798c027 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -241,25 +241,78 @@
void *vaddr, unsigned int offset, unsigned int length,
unsigned int cmd)
{
- void (*outer_cache_op)(phys_addr_t, phys_addr_t);
+ void (*outer_cache_op)(phys_addr_t, phys_addr_t) = NULL;
struct ion_carveout_heap *carveout_heap =
container_of(heap, struct ion_carveout_heap, heap);
+ unsigned int size_to_vmap, total_size;
+ int i, j;
+ void *ptr = NULL;
+ ion_phys_addr_t buff_phys = buffer->priv_phys;
- switch (cmd) {
- case ION_IOC_CLEAN_CACHES:
- dmac_clean_range(vaddr, vaddr + length);
- outer_cache_op = outer_clean_range;
- break;
- case ION_IOC_INV_CACHES:
- dmac_inv_range(vaddr, vaddr + length);
- outer_cache_op = outer_inv_range;
- break;
- case ION_IOC_CLEAN_INV_CACHES:
- dmac_flush_range(vaddr, vaddr + length);
- outer_cache_op = outer_flush_range;
- break;
- default:
- return -EINVAL;
+ if (!vaddr) {
+ /*
+ * Split the vmalloc space into smaller regions in
+ * order to clean and/or invalidate the cache.
+ */
+ size_to_vmap = ((VMALLOC_END - VMALLOC_START)/8);
+ total_size = buffer->size;
+
+ for (i = 0; i < total_size; i += size_to_vmap) {
+ size_to_vmap = min(size_to_vmap, total_size - i);
+ for (j = 0; j < 10 && size_to_vmap; ++j) {
+ ptr = ioremap(buff_phys, size_to_vmap);
+ if (ptr) {
+ switch (cmd) {
+ case ION_IOC_CLEAN_CACHES:
+ dmac_clean_range(ptr,
+ ptr + size_to_vmap);
+ outer_cache_op =
+ outer_clean_range;
+ break;
+ case ION_IOC_INV_CACHES:
+ dmac_inv_range(ptr,
+ ptr + size_to_vmap);
+ outer_cache_op =
+ outer_inv_range;
+ break;
+ case ION_IOC_CLEAN_INV_CACHES:
+ dmac_flush_range(ptr,
+ ptr + size_to_vmap);
+ outer_cache_op =
+ outer_flush_range;
+ break;
+ default:
+ return -EINVAL;
+ }
+ buff_phys += size_to_vmap;
+ break;
+ } else {
+ size_to_vmap >>= 1;
+ }
+ }
+ if (!ptr) {
+ pr_err("Couldn't io-remap the memory\n");
+ return -EINVAL;
+ }
+ iounmap(ptr);
+ }
+ } else {
+ switch (cmd) {
+ case ION_IOC_CLEAN_CACHES:
+ dmac_clean_range(vaddr, vaddr + length);
+ outer_cache_op = outer_clean_range;
+ break;
+ case ION_IOC_INV_CACHES:
+ dmac_inv_range(vaddr, vaddr + length);
+ outer_cache_op = outer_inv_range;
+ break;
+ case ION_IOC_CLEAN_INV_CACHES:
+ dmac_flush_range(vaddr, vaddr + length);
+ outer_cache_op = outer_flush_range;
+ break;
+ default:
+ return -EINVAL;
+ }
}
if (carveout_heap->has_outer_cache) {
diff --git a/drivers/gpu/ion/ion_cma_heap.c b/drivers/gpu/ion/ion_cma_heap.c
index a01b347..4f12e38 100644
--- a/drivers/gpu/ion/ion_cma_heap.c
+++ b/drivers/gpu/ion/ion_cma_heap.c
@@ -281,15 +281,30 @@
switch (cmd) {
case ION_IOC_CLEAN_CACHES:
- dmac_clean_range(vaddr, vaddr + length);
+ if (!vaddr)
+ dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_TO_DEVICE);
+ else
+ dmac_clean_range(vaddr, vaddr + length);
outer_cache_op = outer_clean_range;
break;
case ION_IOC_INV_CACHES:
- dmac_inv_range(vaddr, vaddr + length);
+ if (!vaddr)
+ dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_FROM_DEVICE);
+ else
+ dmac_inv_range(vaddr, vaddr + length);
outer_cache_op = outer_inv_range;
break;
case ION_IOC_CLEAN_INV_CACHES:
- dmac_flush_range(vaddr, vaddr + length);
+ if (!vaddr) {
+ dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_TO_DEVICE);
+ dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_FROM_DEVICE);
+ } else {
+ dmac_flush_range(vaddr, vaddr + length);
+ }
outer_cache_op = outer_flush_range;
break;
default:
diff --git a/drivers/gpu/ion/ion_cma_secure_heap.c b/drivers/gpu/ion/ion_cma_secure_heap.c
index 3be3a00..d7a5920 100644
--- a/drivers/gpu/ion/ion_cma_secure_heap.c
+++ b/drivers/gpu/ion/ion_cma_secure_heap.c
@@ -73,6 +73,8 @@
{
struct device *dev = heap->priv;
struct ion_secure_cma_buffer_info *info;
+ DEFINE_DMA_ATTRS(attrs);
+ dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
dev_dbg(dev, "Request buffer allocation len %ld\n", len);
@@ -82,12 +84,7 @@
return ION_CMA_ALLOCATE_FAILED;
}
- if (!ION_IS_CACHED(flags))
- info->cpu_addr = dma_alloc_writecombine(dev, len,
- &(info->handle), 0);
- else
- info->cpu_addr = dma_alloc_nonconsistent(dev, len,
- &(info->handle), 0);
+ info->cpu_addr = dma_alloc_attrs(dev, len, &(info->handle), 0, &attrs);
if (!info->cpu_addr) {
dev_err(dev, "Fail to allocate buffer\n");
@@ -100,8 +97,6 @@
goto err;
}
- info->is_cached = ION_IS_CACHED(flags);
-
ion_secure_cma_get_sgtable(dev,
info->table, info->cpu_addr, info->handle, len);
@@ -131,6 +126,13 @@
return -ENOMEM;
}
+ if (ION_IS_CACHED(flags)) {
+ pr_err("%s: cannot allocate cached memory from secure heap %s\n",
+ __func__, heap->name);
+ return -ENOMEM;
+ }
+
+
buf = __ion_secure_cma_allocate(heap, buffer, len, align, flags);
if (buf) {
@@ -191,24 +193,22 @@
struct ion_buffer *buffer,
struct vm_area_struct *vma)
{
+ pr_info("%s: mmaping from secure heap %s disallowed\n",
+ __func__, mapper->name);
return -EINVAL;
}
static void *ion_secure_cma_map_kernel(struct ion_heap *heap,
struct ion_buffer *buffer)
{
- struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
-
- atomic_inc(&info->secure.map_cnt);
- return info->cpu_addr;
+ pr_info("%s: kernel mapping from secure heap %s disallowed\n",
+ __func__, heap->name);
+ return NULL;
}
static void ion_secure_cma_unmap_kernel(struct ion_heap *heap,
struct ion_buffer *buffer)
{
- struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
-
- atomic_dec(&info->secure.map_cnt);
return;
}
@@ -311,32 +311,9 @@
unsigned int offset, unsigned int length,
unsigned int cmd)
{
- void (*outer_cache_op)(phys_addr_t, phys_addr_t);
-
- switch (cmd) {
- case ION_IOC_CLEAN_CACHES:
- dmac_clean_range(vaddr, vaddr + length);
- outer_cache_op = outer_clean_range;
- break;
- case ION_IOC_INV_CACHES:
- dmac_inv_range(vaddr, vaddr + length);
- outer_cache_op = outer_inv_range;
- break;
- case ION_IOC_CLEAN_INV_CACHES:
- dmac_flush_range(vaddr, vaddr + length);
- outer_cache_op = outer_flush_range;
- break;
- default:
- return -EINVAL;
- }
-
- if (cma_heap_has_outer_cache) {
- struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
-
- outer_cache_op(info->handle, info->handle + length);
- }
-
- return 0;
+ pr_info("%s: cache operations disallowed from secure heap %s\n",
+ __func__, heap->name);
+ return -EINVAL;
}
static int ion_secure_cma_print_debug(struct ion_heap *heap, struct seq_file *s,
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index a7473e2..3000252 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -731,26 +731,78 @@
void *vaddr, unsigned int offset, unsigned int length,
unsigned int cmd)
{
- void (*outer_cache_op)(phys_addr_t, phys_addr_t);
+ void (*outer_cache_op)(phys_addr_t, phys_addr_t) = NULL;
struct ion_cp_heap *cp_heap =
- container_of(heap, struct ion_cp_heap, heap);
+ container_of(heap, struct ion_cp_heap, heap);
+ unsigned int size_to_vmap, total_size;
struct ion_cp_buffer *buf = buffer->priv_virt;
+ int i, j;
+ void *ptr = NULL;
+ ion_phys_addr_t buff_phys = buffer->priv_phys;
- switch (cmd) {
- case ION_IOC_CLEAN_CACHES:
- dmac_clean_range(vaddr, vaddr + length);
- outer_cache_op = outer_clean_range;
- break;
- case ION_IOC_INV_CACHES:
- dmac_inv_range(vaddr, vaddr + length);
- outer_cache_op = outer_inv_range;
- break;
- case ION_IOC_CLEAN_INV_CACHES:
- dmac_flush_range(vaddr, vaddr + length);
- outer_cache_op = outer_flush_range;
- break;
- default:
- return -EINVAL;
+ if (!vaddr) {
+ /*
+ * Split the vmalloc space into smaller regions in
+ * order to clean and/or invalidate the cache.
+ */
+ size_to_vmap = (VMALLOC_END - VMALLOC_START)/8;
+ total_size = buffer->size;
+ for (i = 0; i < total_size; i += size_to_vmap) {
+ size_to_vmap = min(size_to_vmap, total_size - i);
+ for (j = 0; j < 10 && size_to_vmap; ++j) {
+ ptr = ioremap(buff_phys, size_to_vmap);
+ if (ptr) {
+ switch (cmd) {
+ case ION_IOC_CLEAN_CACHES:
+ dmac_clean_range(ptr,
+ ptr + size_to_vmap);
+ outer_cache_op =
+ outer_clean_range;
+ break;
+ case ION_IOC_INV_CACHES:
+ dmac_inv_range(ptr,
+ ptr + size_to_vmap);
+ outer_cache_op =
+ outer_inv_range;
+ break;
+ case ION_IOC_CLEAN_INV_CACHES:
+ dmac_flush_range(ptr,
+ ptr + size_to_vmap);
+ outer_cache_op =
+ outer_flush_range;
+ break;
+ default:
+ return -EINVAL;
+ }
+ buff_phys += size_to_vmap;
+ break;
+ } else {
+ size_to_vmap >>= 1;
+ }
+ }
+ if (!ptr) {
+ pr_err("Couldn't io-remap the memory\n");
+ return -EINVAL;
+ }
+ iounmap(ptr);
+ }
+ } else {
+ switch (cmd) {
+ case ION_IOC_CLEAN_CACHES:
+ dmac_clean_range(vaddr, vaddr + length);
+ outer_cache_op = outer_clean_range;
+ break;
+ case ION_IOC_INV_CACHES:
+ dmac_inv_range(vaddr, vaddr + length);
+ outer_cache_op = outer_inv_range;
+ break;
+ case ION_IOC_CLEAN_INV_CACHES:
+ dmac_flush_range(vaddr, vaddr + length);
+ outer_cache_op = outer_flush_range;
+ break;
+ default:
+ return -EINVAL;
+ }
}
if (cp_heap->has_outer_cache) {
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index 761fdde..ba48b50 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -409,15 +409,30 @@
switch (cmd) {
case ION_IOC_CLEAN_CACHES:
- dmac_clean_range(vaddr, vaddr + length);
+ if (!vaddr)
+ dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_TO_DEVICE);
+ else
+ dmac_clean_range(vaddr, vaddr + length);
outer_cache_op = outer_clean_range;
break;
case ION_IOC_INV_CACHES:
- dmac_inv_range(vaddr, vaddr + length);
+ if (!vaddr)
+ dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_FROM_DEVICE);
+ else
+ dmac_inv_range(vaddr, vaddr + length);
outer_cache_op = outer_inv_range;
break;
case ION_IOC_CLEAN_INV_CACHES:
- dmac_flush_range(vaddr, vaddr + length);
+ if (!vaddr) {
+ dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_TO_DEVICE);
+ dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_FROM_DEVICE);
+ } else {
+ dmac_flush_range(vaddr, vaddr + length);
+ }
outer_cache_op = outer_flush_range;
break;
default:
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index f33fc18..7ca2cd2 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -28,6 +28,7 @@
#include <mach/memory.h>
#include <asm/cacheflush.h>
#include <linux/msm_ion.h>
+#include <linux/dma-mapping.h>
static atomic_t system_heap_allocated;
static atomic_t system_contig_heap_allocated;
@@ -184,15 +185,30 @@
switch (cmd) {
case ION_IOC_CLEAN_CACHES:
- dmac_clean_range(vaddr, vaddr + length);
+ if (!vaddr)
+ dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_TO_DEVICE);
+ else
+ dmac_clean_range(vaddr, vaddr + length);
outer_cache_op = outer_clean_range;
break;
case ION_IOC_INV_CACHES:
- dmac_inv_range(vaddr, vaddr + length);
+ if (!vaddr)
+ dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_FROM_DEVICE);
+ else
+ dmac_inv_range(vaddr, vaddr + length);
outer_cache_op = outer_inv_range;
break;
case ION_IOC_CLEAN_INV_CACHES:
- dmac_flush_range(vaddr, vaddr + length);
+ if (!vaddr) {
+ dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_TO_DEVICE);
+ dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+ buffer->sg_table->nents, DMA_FROM_DEVICE);
+ } else {
+ dmac_flush_range(vaddr, vaddr + length);
+ }
outer_cache_op = outer_flush_range;
break;
default:
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index bd27385..1f73d47 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -715,7 +715,7 @@
start = (unsigned long) data.vaddr;
end = (unsigned long) data.vaddr + data.length;
- if (check_vaddr_bounds(start, end)) {
+ if (start && check_vaddr_bounds(start, end)) {
up_read(&mm->mmap_sem);
pr_err("%s: virtual address %p is out of bounds\n",
__func__, data.vaddr);
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index e245cfc..ed351bd 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -232,12 +232,14 @@
#define A3XX_SP_VS_OUT_REG_7 0x22CE
#define A3XX_SP_VS_VPC_DST_REG_0 0x22D0
#define A3XX_SP_VS_OBJ_OFFSET_REG 0x22D4
+#define A3XX_SP_VS_OBJ_START_REG 0x22D5
#define A3XX_SP_VS_PVT_MEM_ADDR_REG 0x22D7
#define A3XX_SP_VS_PVT_MEM_SIZE_REG 0x22D8
#define A3XX_SP_VS_LENGTH_REG 0x22DF
#define A3XX_SP_FS_CTRL_REG0 0x22E0
#define A3XX_SP_FS_CTRL_REG1 0x22E1
#define A3XX_SP_FS_OBJ_OFFSET_REG 0x22E2
+#define A3XX_SP_FS_OBJ_START_REG 0x22E3
#define A3XX_SP_FS_PVT_MEM_ADDR_REG 0x22E5
#define A3XX_SP_FS_PVT_MEM_SIZE_REG 0x22E6
#define A3XX_SP_FS_FLAT_SHAD_MODE_REG_0 0x22E8
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 949ac97..6c57078 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -112,6 +112,7 @@
unsigned int gpulist_index;
struct ocmem_buf *ocmem_hdl;
unsigned int ocmem_base;
+ unsigned int gpu_cycles;
};
struct adreno_gpudev {
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 9adfe69..f1024d6 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2704,26 +2704,22 @@
static unsigned int a3xx_busy_cycles(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = &adreno_dev->dev;
- unsigned int reg, val;
-
- /* Freeze the counter */
- adreno_regread(device, A3XX_RBBM_RBBM_CTL, ®);
- reg &= ~RBBM_RBBM_CTL_ENABLE_PWR_CTR1;
- adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, reg);
+ unsigned int val;
+ unsigned int ret = 0;
/* Read the value */
adreno_regread(device, A3XX_RBBM_PERFCTR_PWR_1_LO, &val);
- /* Reset the counter */
- reg |= RBBM_RBBM_CTL_RESET_PWR_CTR1;
- adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, reg);
+ /* Return 0 for the first read */
+ if (adreno_dev->gpu_cycles != 0) {
+ if (val < adreno_dev->gpu_cycles)
+ ret = (0xFFFFFFFF - adreno_dev->gpu_cycles) + val;
+ else
+ ret = val - adreno_dev->gpu_cycles;
+ }
- /* Re-enable the counter */
- reg &= ~RBBM_RBBM_CTL_RESET_PWR_CTR1;
- reg |= RBBM_RBBM_CTL_ENABLE_PWR_CTR1;
- adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, reg);
-
- return val;
+ adreno_dev->gpu_cycles = val;
+ return ret;
}
struct a3xx_vbif_data {
@@ -2844,6 +2840,7 @@
struct kgsl_device *device = &adreno_dev->dev;
struct a3xx_vbif_data *vbif = NULL;
int i;
+ unsigned int reg;
for (i = 0; i < ARRAY_SIZE(a3xx_vbif_platforms); i++) {
if (a3xx_vbif_platforms[i].devfunc(adreno_dev)) {
@@ -2924,6 +2921,20 @@
adreno_regwrite(device, A3XX_SP_PERFCOUNTER7_SELECT,
SP_FS_CFLOW_INSTRUCTIONS);
}
+
+ adreno_regwrite(device, A3XX_SP_PERFCOUNTER7_SELECT,
+ SP_FS_FULL_ALU_INSTRUCTIONS);
+
+ /* Turn on the GPU busy counter and let it run free */
+
+ adreno_dev->gpu_cycles = 0;
+
+ adreno_regread(device, A3XX_RBBM_RBBM_CTL, ®);
+ reg |= RBBM_RBBM_CTL_RESET_PWR_CTR1;
+ adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, reg);
+ reg &= ~RBBM_RBBM_CTL_RESET_PWR_CTR1;
+ reg |= RBBM_RBBM_CTL_ENABLE_PWR_CTR1;
+ adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, reg);
}
/* Defined in adreno_a3xx_snapshot.c */
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index c8229e7..d7bf36e 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -162,6 +162,12 @@
static unsigned int sp_fs_pvt_mem_addr;
/*
+ * Cached value of SP_VS_OBJ_START_REG and SP_FS_OBJ_START_REG.
+ */
+static unsigned int sp_vs_obj_start_reg;
+static unsigned int sp_fs_obj_start_reg;
+
+/*
* Each load state block has two possible types. Each type has a different
* number of dwords per unit. Use this handy lookup table to make sure
* we dump the right amount of data from the indirect buffer
@@ -373,6 +379,26 @@
sp_fs_pvt_mem_addr = 0;
}
+ if (sp_vs_obj_start_reg) {
+ ret = kgsl_snapshot_get_object(device, ptbase,
+ sp_vs_obj_start_reg & 0xFFFFFFE0, 0,
+ SNAPSHOT_GPU_OBJECT_GENERIC);
+ if (ret < 0)
+ return -EINVAL;
+ snapshot_frozen_objsize += ret;
+ sp_vs_obj_start_reg = 0;
+ }
+
+ if (sp_fs_obj_start_reg) {
+ ret = kgsl_snapshot_get_object(device, ptbase,
+ sp_fs_obj_start_reg & 0xFFFFFFE0, 0,
+ SNAPSHOT_GPU_OBJECT_GENERIC);
+ if (ret < 0)
+ return -EINVAL;
+ snapshot_frozen_objsize += ret;
+ sp_fs_obj_start_reg = 0;
+ }
+
/* Finally: VBOs */
/* The number of active VBOs is stored in VFD_CONTROL_O[31:27] */
@@ -505,6 +531,12 @@
case A3XX_SP_FS_PVT_MEM_ADDR_REG:
sp_fs_pvt_mem_addr = ptr[i + 1];
break;
+ case A3XX_SP_VS_OBJ_START_REG:
+ sp_vs_obj_start_reg = ptr[i + 1];
+ break;
+ case A3XX_SP_FS_OBJ_START_REG:
+ sp_fs_obj_start_reg = ptr[i + 1];
+ break;
}
}
}
@@ -786,6 +818,64 @@
return size + sizeof(*header);
}
+static int snapshot_capture_mem_list(struct kgsl_device *device, void *snapshot,
+ int remain, void *priv)
+{
+ struct kgsl_snapshot_replay_mem_list *header = snapshot;
+ struct kgsl_process_private *private;
+ unsigned int ptbase;
+ struct rb_node *node;
+ struct kgsl_mem_entry *entry = NULL;
+ int num_mem;
+ unsigned int *data = snapshot + sizeof(*header);
+
+ ptbase = kgsl_mmu_get_current_ptbase(&device->mmu);
+ mutex_lock(&kgsl_driver.process_mutex);
+ list_for_each_entry(private, &kgsl_driver.process_list, list) {
+ if (kgsl_mmu_pt_equal(&device->mmu, private->pagetable,
+ ptbase))
+ break;
+ }
+ mutex_unlock(&kgsl_driver.process_mutex);
+ if (!private) {
+ KGSL_DRV_ERR(device,
+ "Failed to get pointer to process private structure\n");
+ return 0;
+ }
+ /* We need to know the number of memory objects that the process has */
+ spin_lock(&private->mem_lock);
+ for (node = rb_first(&private->mem_rb), num_mem = 0; node; ) {
+ entry = rb_entry(node, struct kgsl_mem_entry, node);
+ node = rb_next(&entry->node);
+ num_mem++;
+ }
+
+ if (remain < ((num_mem * 3 * sizeof(unsigned int)) +
+ sizeof(*header))) {
+ KGSL_DRV_ERR(device,
+ "snapshot: Not enough memory for the mem list section");
+ spin_unlock(&private->mem_lock);
+ return 0;
+ }
+ header->num_entries = num_mem;
+ header->ptbase = ptbase;
+ /*
+ * Walk throught the memory list and store the
+ * tuples(gpuaddr, size, memtype) in snapshot
+ */
+ for (node = rb_first(&private->mem_rb); node; ) {
+ entry = rb_entry(node, struct kgsl_mem_entry, node);
+ node = rb_next(&entry->node);
+
+ *data++ = entry->memdesc.gpuaddr;
+ *data++ = entry->memdesc.size;
+ *data++ = (entry->memdesc.priv & KGSL_MEMTYPE_MASK) >>
+ KGSL_MEMTYPE_SHIFT;
+ }
+ spin_unlock(&private->mem_lock);
+ return sizeof(*header) + (num_mem * 3 * sizeof(unsigned int));
+}
+
/* Snapshot the memory for an indirect buffer */
static int snapshot_ib(struct kgsl_device *device, void *snapshot,
int remain, void *priv)
@@ -889,6 +979,13 @@
snapshot, remain, snapshot_rb, NULL);
/*
+ * Add a section that lists (gpuaddr, size, memtype) tuples of the
+ * hanging process
+ */
+ snapshot = kgsl_snapshot_add_section(device,
+ KGSL_SNAPSHOT_SECTION_MEMLIST, snapshot, remain,
+ snapshot_capture_mem_list, NULL);
+ /*
* Make sure that the last IB1 that was being executed is dumped.
* Since this was the last IB1 that was processed, we should have
* already added it to the list during the ringbuffer parse but we
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index 42e79a0..296de11 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -169,8 +169,9 @@
header->grpclk = kgsl_get_clkrate(pwr->grp_clks[0]);
header->busclk = kgsl_get_clkrate(pwr->ebi1_clk);
- /* Future proof for per-context timestamps */
- header->current_context = -1;
+ /* Save the last active context */
+ kgsl_sharedmem_readl(&device->memstore, &header->current_context,
+ KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context));
/* Get the current PT base */
header->ptbase = kgsl_mmu_get_current_ptbase(&device->mmu);
@@ -375,8 +376,8 @@
/* If the buffer is already on the list, skip it */
list_for_each_entry(obj, &device->snapshot_obj_list, node) {
if (obj->gpuaddr == gpuaddr && obj->ptbase == ptbase) {
- /* If the size is different, use the new size */
- if (obj->size != size)
+ /* If the size is different, use the bigger size */
+ if (obj->size < size)
obj->size = size;
return 0;
diff --git a/drivers/gpu/msm/kgsl_snapshot.h b/drivers/gpu/msm/kgsl_snapshot.h
index 327d18a..4db2815 100644
--- a/drivers/gpu/msm/kgsl_snapshot.h
+++ b/drivers/gpu/msm/kgsl_snapshot.h
@@ -52,6 +52,7 @@
#define KGSL_SNAPSHOT_SECTION_DEBUG 0x0901
#define KGSL_SNAPSHOT_SECTION_DEBUGBUS 0x0A01
#define KGSL_SNAPSHOT_SECTION_GPU_OBJECT 0x0B01
+#define KGSL_SNAPSHOT_SECTION_MEMLIST 0x0E01
#define KGSL_SNAPSHOT_SECTION_END 0xFFFF
@@ -103,6 +104,17 @@
int count; /* Number of dwords in the dump */
} __packed;
+/* Replay or Memory list section, both sections have same header */
+struct kgsl_snapshot_replay_mem_list {
+ /*
+ * Number of IBs to replay for replay section or
+ * number of memory list entries for mem list section
+ */
+ int num_entries;
+ /* Pagetable base to which the replay IBs or memory entries belong */
+ __u32 ptbase;
+} __packed;
+
/* Indirect buffer sub-section header */
struct kgsl_snapshot_ib {
__u32 gpuaddr; /* GPU address of the the IB */
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 9ed3d53..41f79be 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -693,8 +693,8 @@
spin_lock_irq(&client->buffer_lock);
client->use_wake_lock = false;
- wake_lock_destroy(&client->wake_lock);
spin_unlock_irq(&client->buffer_lock);
+ wake_lock_destroy(&client->wake_lock);
return 0;
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 3a24428..22e8400 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -169,6 +169,8 @@
struct msm_isp_qbuf_info *info, struct vb2_buffer *vb2_buf)
{
int rc = -1;
+ unsigned long flags;
+ struct msm_isp_bufq *bufq = NULL;
struct msm_isp_buffer *buf_info = NULL;
struct v4l2_buffer *buf = NULL;
struct v4l2_plane *plane = NULL;
@@ -180,14 +182,26 @@
return rc;
}
- if (buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED)
- return buf_info->state;
+ bufq = msm_isp_get_bufq(buf_mgr, buf_info->bufq_handle);
+ if (!bufq) {
+ pr_err("%s: Invalid bufq\n", __func__);
+ return rc;
+ }
+
+ spin_lock_irqsave(&bufq->bufq_lock, flags);
+ if (buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) {
+ rc = buf_info->state;
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
+ return rc;
+ }
if (buf_info->state != MSM_ISP_BUFFER_STATE_INITIALIZED) {
pr_err("%s: Invalid buffer state: %d\n",
__func__, buf_info->state);
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
return rc;
}
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
if (vb2_buf) {
buf = &vb2_buf->v4l2_buf;
@@ -217,7 +231,9 @@
kfree(plane);
return rc;
}
+ spin_lock_irqsave(&bufq->bufq_lock, flags);
buf_info->state = MSM_ISP_BUFFER_STATE_PREPARED;
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
kfree(plane);
return rc;
}
@@ -245,10 +261,11 @@
return 0;
}
-static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr,
+static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
uint32_t bufq_handle, struct msm_isp_buffer **buf_info)
{
int rc = -1;
+ unsigned long flags;
struct msm_isp_buffer *temp_buf_info;
struct msm_isp_bufq *bufq = NULL;
struct vb2_buffer *vb2_buf = NULL;
@@ -259,6 +276,25 @@
}
*buf_info = NULL;
+ spin_lock_irqsave(&bufq->bufq_lock, flags);
+ if (bufq->buf_type == ISP_SHARE_BUF) {
+ list_for_each_entry(temp_buf_info,
+ &bufq->share_head, share_list) {
+ if (!temp_buf_info->buf_used[id]) {
+ *buf_info = temp_buf_info;
+ temp_buf_info->buf_used[id] = 1;
+ temp_buf_info->buf_get_count++;
+ if (temp_buf_info->buf_get_count ==
+ bufq->buf_client_count)
+ list_del_init(
+ &temp_buf_info->share_list);
+ spin_unlock_irqrestore(
+ &bufq->bufq_lock, flags);
+ return 0;
+ }
+ }
+ }
+
if (BUF_SRC(bufq->stream_id)) {
list_for_each_entry(temp_buf_info, &bufq->head, list) {
if (temp_buf_info->state ==
@@ -280,16 +316,26 @@
} else {
pr_err("%s: Incorrect buf index %d\n",
__func__, vb2_buf->v4l2_buf.index);
- return -EINVAL;
+ rc = -EINVAL;
}
}
}
- if (!(*buf_info))
+ if (!(*buf_info)) {
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
return rc;
-
+ }
(*buf_info)->state = MSM_ISP_BUFFER_STATE_DEQUEUED;
+ if (bufq->buf_type == ISP_SHARE_BUF) {
+ memset((*buf_info)->buf_used, 0,
+ sizeof(uint8_t) * bufq->buf_client_count);
+ (*buf_info)->buf_used[id] = 1;
+ (*buf_info)->buf_get_count = 1;
+ (*buf_info)->buf_put_count = 0;
+ list_add_tail(&(*buf_info)->share_list, &bufq->share_head);
+ }
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
return 0;
}
@@ -297,6 +343,7 @@
uint32_t bufq_handle, uint32_t buf_index)
{
int rc = -1;
+ unsigned long flags;
struct msm_isp_bufq *bufq = NULL;
struct msm_isp_buffer *buf_info = NULL;
@@ -312,6 +359,7 @@
return rc;
}
+ spin_lock_irqsave(&bufq->bufq_lock, flags);
switch (buf_info->state) {
case MSM_ISP_BUFFER_STATE_PREPARED:
case MSM_ISP_BUFFER_STATE_DEQUEUED:
@@ -330,6 +378,7 @@
__func__, buf_info->state);
break;
}
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
return rc;
}
@@ -339,8 +388,10 @@
struct timeval *tv, uint32_t frame_id)
{
int rc = -1;
+ unsigned long flags;
struct msm_isp_bufq *bufq = NULL;
struct msm_isp_buffer *buf_info = NULL;
+ enum msm_isp_buffer_state state;
bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
if (!bufq) {
@@ -354,9 +405,23 @@
return rc;
}
- if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED ||
- buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) {
+ spin_lock_irqsave(&bufq->bufq_lock, flags);
+ state = buf_info->state;
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
+
+ if (state == MSM_ISP_BUFFER_STATE_DEQUEUED ||
+ state == MSM_ISP_BUFFER_STATE_DIVERTED) {
+ spin_lock_irqsave(&bufq->bufq_lock, flags);
+ if (bufq->buf_type == ISP_SHARE_BUF) {
+ buf_info->buf_put_count++;
+ if (buf_info->buf_put_count != ISP_SHARE_BUF_CLIENT) {
+ rc = buf_info->buf_put_count;
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
+ return rc;
+ }
+ }
buf_info->state = MSM_ISP_BUFFER_STATE_DISPATCHED;
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
if ((BUF_SRC(bufq->stream_id))) {
rc = msm_isp_put_buf(buf_mgr, buf_info->bufq_handle,
buf_info->buf_idx);
@@ -379,6 +444,7 @@
uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type)
{
int rc = -1, i;
+ unsigned long flags;
struct msm_isp_bufq *bufq = NULL;
struct msm_isp_buffer *buf_info = NULL;
@@ -395,6 +461,7 @@
continue;
}
+ spin_lock_irqsave(&bufq->bufq_lock, flags);
if (flush_type == MSM_ISP_BUFFER_FLUSH_DIVERTED &&
buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) {
buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED;
@@ -404,6 +471,7 @@
buf_info->state == MSM_ISP_BUFFER_STATE_DISPATCHED)) {
buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED;
}
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
}
return 0;
}
@@ -413,6 +481,7 @@
struct timeval *tv, uint32_t frame_id)
{
int rc = -1;
+ unsigned long flags;
struct msm_isp_bufq *bufq = NULL;
struct msm_isp_buffer *buf_info = NULL;
@@ -428,11 +497,22 @@
return rc;
}
+ spin_lock_irqsave(&bufq->bufq_lock, flags);
+ if (bufq->buf_type == ISP_SHARE_BUF) {
+ buf_info->buf_put_count++;
+ if (buf_info->buf_put_count != ISP_SHARE_BUF_CLIENT) {
+ rc = buf_info->buf_put_count;
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
+ return rc;
+ }
+ }
+
if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED) {
buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED;
buf_info->tv = tv;
buf_info->frame_id = frame_id;
}
+ spin_unlock_irqrestore(&bufq->bufq_lock, flags);
return 0;
}
@@ -516,11 +596,16 @@
return rc;
}
+ spin_lock_init(&bufq->bufq_lock);
bufq->bufq_handle = buf_request->handle;
bufq->session_id = buf_request->session_id;
bufq->stream_id = buf_request->stream_id;
bufq->num_bufs = buf_request->num_buf;
+ bufq->buf_type = buf_request->buf_type;
+ if (bufq->buf_type == ISP_SHARE_BUF)
+ bufq->buf_client_count = ISP_SHARE_BUF_CLIENT;
INIT_LIST_HEAD(&bufq->head);
+ INIT_LIST_HEAD(&bufq->share_head);
for (i = 0; i < buf_request->num_buf; i++) {
bufq->bufs[i].state = MSM_ISP_BUFFER_STATE_INITIALIZED;
bufq->bufs[i].bufq_handle = bufq->bufq_handle;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
index c3b97d9..d4e7c88 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
@@ -19,6 +19,7 @@
/*Buffer source can be from userspace / HAL*/
#define BUF_SRC(id) (id & ISP_NATIVE_BUF_BIT)
+#define ISP_SHARE_BUF_CLIENT 2
struct msm_isp_buf_mgr;
@@ -59,6 +60,11 @@
/*Vb2 buffer data*/
struct vb2_buffer *vb2_buf;
+ /*Share buffer cache state*/
+ struct list_head share_list;
+ uint8_t buf_used[ISP_SHARE_BUF_CLIENT];
+ uint8_t buf_get_count;
+ uint8_t buf_put_count;
};
struct msm_isp_bufq {
@@ -66,10 +72,15 @@
uint32_t stream_id;
uint32_t num_bufs;
uint32_t bufq_handle;
+ enum msm_isp_buf_type buf_type;
struct msm_isp_buffer *bufs;
+ spinlock_t bufq_lock;
/*Native buffer queue*/
struct list_head head;
+ /*Share buffer cache queue*/
+ struct list_head share_head;
+ uint8_t buf_client_count;
};
struct msm_isp_buf_ops {
@@ -85,7 +96,7 @@
int (*get_bufq_handle) (struct msm_isp_buf_mgr *buf_mgr,
uint32_t session_id, uint32_t stream_id);
- int (*get_buf) (struct msm_isp_buf_mgr *buf_mgr,
+ int (*get_buf) (struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
uint32_t bufq_handle, struct msm_isp_buffer **buf_info);
int (*put_buf) (struct msm_isp_buf_mgr *buf_mgr,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index 38130db..cfbe29c 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -228,6 +228,7 @@
enum msm_vfe_axi_stream_src stream_src;
uint8_t num_planes;
uint8_t wm[MAX_PLANES_PER_STREAM];
+ uint32_t plane_offset[MAX_PLANES_PER_STREAM];
uint8_t comp_mask_index;
struct msm_isp_buffer *buf[2];
uint32_t session_id;
@@ -312,6 +313,7 @@
uint32_t framedrop_pattern;
uint32_t irq_subsample_pattern;
+ uint32_t buffer_offset;
struct msm_isp_buffer *buf[2];
uint32_t bufq_handle;
};
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index f08644f..a780526 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -64,7 +64,7 @@
int msm_isp_validate_axi_request(struct msm_vfe_axi_shared_data *axi_data,
struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
{
- int rc = -1;
+ int rc = -1, i;
struct msm_vfe_axi_stream *stream_info =
&axi_data->stream_info[
(stream_cfg_cmd->axi_stream_handle & 0xFF)];
@@ -129,6 +129,10 @@
return rc;
}
+ for (i = 0; i < stream_info->num_planes; i++)
+ stream_info->plane_offset[i] =
+ stream_cfg_cmd->plane_cfg[i].plane_addr_offset;
+
stream_info->stream_src = stream_cfg_cmd->stream_src;
stream_info->frame_based = stream_cfg_cmd->frame_base;
return 0;
@@ -596,8 +600,9 @@
struct msm_isp_buffer *buf = stream_info->buf[1];
for (i = 0; i < stream_info->num_planes; i++)
vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
- vfe_dev, stream_info->wm[i],
- VFE_PING_FLAG, buf->mapped_info[i].paddr);
+ vfe_dev, stream_info->wm[i],
+ VFE_PING_FLAG, buf->mapped_info[i].paddr +
+ stream_info->plane_offset[i]);
stream_info->buf[0] = buf;
}
@@ -626,8 +631,8 @@
uint32_t bufq_handle = stream_info->bufq_handle;
uint32_t stream_idx = stream_info->stream_handle & 0xFF;
- rc = vfe_dev->buf_mgr->ops->get_buf(
- vfe_dev->buf_mgr, bufq_handle, &buf);
+ rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr,
+ vfe_dev->pdev->id, bufq_handle, &buf);
if (rc < 0) {
vfe_dev->error_info.
stream_framedrop_count[stream_idx]++;
@@ -642,8 +647,9 @@
for (i = 0; i < stream_info->num_planes; i++)
vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
- vfe_dev, stream_info->wm[i],
- pingpong_status, buf->mapped_info[i].paddr);
+ vfe_dev, stream_info->wm[i],
+ pingpong_status, buf->mapped_info[i].paddr +
+ stream_info->plane_offset[i]);
pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1);
stream_info->buf[pingpong_bit] = buf;
@@ -658,6 +664,7 @@
struct msm_vfe_axi_stream *stream_info, struct msm_isp_buffer *buf,
struct msm_isp_timestamp *ts)
{
+ int rc;
struct msm_isp_event_data buf_event;
uint32_t stream_idx = stream_info->stream_handle & 0xFF;
uint32_t frame_id = vfe_dev->axi_data.
@@ -665,20 +672,27 @@
if (buf && ts) {
if (stream_info->buf_divert) {
- vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr,
+ rc = vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr,
buf->bufq_handle, buf->buf_idx,
&ts->buf_time, frame_id);
- buf_event.frame_id = frame_id;
- buf_event.timestamp = ts->buf_time;
- buf_event.u.buf_done.session_id =
- stream_info->session_id;
- buf_event.u.buf_done.stream_id =
- stream_info->stream_id;
- buf_event.u.buf_done.handle =
- stream_info->bufq_handle;
- buf_event.u.buf_done.buf_idx = buf->buf_idx;
- msm_isp_send_event(vfe_dev, ISP_EVENT_BUF_DIVERT +
- stream_idx, &buf_event);
+ /* Buf divert return value represent whether the buf
+ * can be diverted. A positive return value means
+ * other ISP hardware is still processing the frame.
+ */
+ if (rc == 0) {
+ buf_event.frame_id = frame_id;
+ buf_event.timestamp = ts->buf_time;
+ buf_event.u.buf_done.session_id =
+ stream_info->session_id;
+ buf_event.u.buf_done.stream_id =
+ stream_info->stream_id;
+ buf_event.u.buf_done.handle =
+ stream_info->bufq_handle;
+ buf_event.u.buf_done.buf_idx = buf->buf_idx;
+ msm_isp_send_event(vfe_dev,
+ ISP_EVENT_BUF_DIVERT + stream_idx,
+ &buf_event);
+ }
} else {
vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr,
buf->bufq_handle, buf->buf_idx,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
index a29fe9c..c47209f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
@@ -27,8 +27,8 @@
vfe_dev->hw_info->stats_hw_info->stats_ping_pong_offset;
pingpong_bit = (~(pingpong_status >> stats_pingpong_offset) & 0x1);
- rc = vfe_dev->buf_mgr->ops->get_buf(
- vfe_dev->buf_mgr, bufq_handle, &buf);
+ rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr,
+ vfe_dev->pdev->id, bufq_handle, &buf);
if (rc < 0) {
vfe_dev->error_info.stats_framedrop_count[
STATS_IDX(stream_info->stream_handle)]++;
@@ -43,7 +43,8 @@
vfe_dev->hw_info->vfe_ops.stats_ops.update_ping_pong_addr(
vfe_dev, stream_info,
- pingpong_status, buf->mapped_info[0].paddr);
+ pingpong_status, buf->mapped_info[0].paddr +
+ stream_info->buffer_offset);
if (stream_info->buf[pingpong_bit] && done_buf)
*done_buf = stream_info->buf[pingpong_bit];
@@ -60,7 +61,7 @@
uint32_t irq_status0, uint32_t irq_status1,
struct msm_isp_timestamp *ts)
{
- int i;
+ int i, rc;
struct msm_isp_event_data buf_event;
struct msm_isp_stats_event *stats_event = &buf_event.u.stats;
struct msm_isp_buffer *done_buf;
@@ -93,13 +94,17 @@
msm_isp_stats_cfg_ping_pong_address(vfe_dev,
stream_info, pingpong_status, &done_buf);
if (done_buf) {
- stats_event->stats_mask |= 1 << stream_info->stats_type;
- stats_event->stats_buf_idxs[stream_info->stats_type] =
- done_buf->buf_idx;
- vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr,
+ rc = vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr,
done_buf->bufq_handle, done_buf->buf_idx,
&ts->buf_time, vfe_dev->axi_data.
src_info[VFE_PIX_0].frame_id);
+ if (rc == 0) {
+ stats_event->stats_mask |=
+ 1 << stream_info->stats_type;
+ stats_event->stats_buf_idxs[
+ stream_info->stats_type] =
+ done_buf->buf_idx;
+ }
}
}
@@ -166,6 +171,7 @@
stream_info->session_id = stream_req_cmd->session_id;
stream_info->stream_id = stream_req_cmd->stream_id;
stream_info->stats_type = stream_req_cmd->stats_type;
+ stream_info->buffer_offset = stream_req_cmd->buffer_offset;
stream_info->framedrop_pattern = stream_req_cmd->framedrop_pattern;
stream_info->irq_subsample_pattern =
stream_req_cmd->irq_subsample_pattern;
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 ddf4c67..85788e9 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -19,6 +19,7 @@
#include <linux/videodev2.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <media/msmb_isp.h>
#include "msm_ispif.h"
#include "msm.h"
@@ -205,7 +206,8 @@
spin_lock_irqsave(&ispif->auto_complete_lock, flags);
ispif->wait_timeout[VFE0] = 0;
init_completion(&ispif->reset_complete[VFE0]);
- if (ispif->csid_version >= CSID_VERSION_V3) {
+ if (ispif->csid_version >= CSID_VERSION_V3 &&
+ ispif->vfe_info.num_vfe > 1) {
ispif->wait_timeout[VFE1] = 0;
init_completion(&ispif->reset_complete[VFE1]);
}
@@ -231,7 +233,8 @@
goto end;
}
- if (ispif->csid_version >= CSID_VERSION_V3) {
+ if (ispif->csid_version >= CSID_VERSION_V3 &&
+ ispif->vfe_info.num_vfe > 1) {
msm_camera_io_w_mb(ISPIF_RST_CMD_1_MASK, ispif->base +
ISPIF_RST_CMD_1_ADDR);
@@ -450,7 +453,8 @@
CDBG("%s intftype %x, vfe_intf %d, csid %d\n", __func__,
intftype, vfe_intf, params->entries[i].csid);
- if ((intftype >= INTF_MAX) || (vfe_intf >= VFE_MAX) ||
+ if ((intftype >= INTF_MAX) ||
+ (vfe_intf >= ispif->vfe_info.num_vfe) ||
(ispif->csid_version <= CSID_VERSION_V2 &&
(vfe_intf > VFE0))) {
pr_err("%s: VFEID %d and CSID version %d mismatch\n",
@@ -738,7 +742,8 @@
ispif_process_irq(ispif, out, VFE0);
}
- if (ispif->csid_version >= CSID_VERSION_V3) {
+ if (ispif->csid_version >= CSID_VERSION_V3 &&
+ ispif->vfe_info.num_vfe > 1) {
out[VFE1].ispifIrqStatus0 = msm_camera_io_r(ispif->base +
ISPIF_VFE_m_IRQ_STATUS_0(VFE1));
msm_camera_io_w(out[VFE1].ispifIrqStatus0,
@@ -790,6 +795,14 @@
return IRQ_HANDLED;
}
+static int msm_ispif_set_vfe_info(struct ispif_device *ispif,
+ struct msm_ispif_vfe_info *vfe_info)
+{
+ memcpy(&ispif->vfe_info, vfe_info, sizeof(struct msm_ispif_vfe_info));
+
+ return 0;
+}
+
static int msm_ispif_init(struct ispif_device *ispif,
uint32_t csid_version)
{
@@ -818,7 +831,8 @@
goto error_clk0;
}
- if (ispif->csid_version >= CSID_VERSION_V3) {
+ if (ispif->csid_version >= CSID_VERSION_V3 &&
+ ispif->vfe_info.num_vfe > 1) {
rc = msm_ispif_clk_enable(ispif, VFE1, 1);
if (rc < 0) {
pr_err("%s: unable to enable clocks for VFE1",
@@ -852,7 +866,8 @@
iounmap(ispif->base);
end:
- if (ispif->csid_version >= CSID_VERSION_V3)
+ if (ispif->csid_version >= CSID_VERSION_V3 &&
+ ispif->vfe_info.num_vfe > 1)
msm_ispif_clk_enable(ispif, VFE1, 0);
error_clk1:
@@ -873,7 +888,7 @@
return;
}
- for (i = 0; i < VFE_MAX; i++)
+ for (i = 0; i < ispif->vfe_info.num_vfe; i++)
msm_ispif_clk_enable(ispif, i, 1);
/* make sure no streaming going on */
@@ -883,7 +898,7 @@
iounmap(ispif->base);
- for (i = 0; i < VFE_MAX; i++)
+ for (i = 0; i < ispif->vfe_info.num_vfe; i++)
msm_ispif_clk_enable(ispif, i, 0);
ispif->ispif_state = ISPIF_POWER_DOWN;
@@ -927,6 +942,9 @@
case ISPIF_RELEASE:
msm_ispif_release(ispif);
break;
+ case ISPIF_SET_VFE_INFO:
+ rc = msm_ispif_set_vfe_info(ispif, &pcdata->vfe_info);
+ break;
default:
pr_err("%s: invalid cfg_type\n", __func__);
rc = -EINVAL;
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h
index ef7a1bf..2c77292 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h
@@ -57,5 +57,6 @@
struct ispif_intf_cmd applied_intf_cmd[VFE_MAX];
enum msm_ispif_state_t ispif_state;
struct clk *ispif_clk[VFE_MAX][INTF_MAX];
+ struct msm_ispif_vfe_info vfe_info;
};
#endif
diff --git a/drivers/media/platform/msm/vidc/q6_hfi.c b/drivers/media/platform/msm/vidc/q6_hfi.c
index f0ca050..afe1431 100644
--- a/drivers/media/platform/msm/vidc/q6_hfi.c
+++ b/drivers/media/platform/msm/vidc/q6_hfi.c
@@ -1132,6 +1132,15 @@
if (!device)
return -EINVAL;
+ if (!device->resources.fw.cookie)
+ device->resources.fw.cookie = subsystem_get("adsp");
+
+ if (IS_ERR_OR_NULL(device->resources.fw.cookie)) {
+ dprintk(VIDC_ERR, "Failed to download firmware\n");
+ rc = -ENOMEM;
+ goto fail_subsystem_get;
+ }
+
/*Set Q6 to loaded state*/
apr_set_q6_state(APR_SUBSYS_LOADED);
@@ -1156,9 +1165,11 @@
fail_iommu_attach:
apr_deregister(device->apr);
+ device->apr = NULL;
fail_apr_register:
subsystem_put(device->resources.fw.cookie);
device->resources.fw.cookie = NULL;
+fail_subsystem_get:
return rc;
}
@@ -1168,8 +1179,17 @@
if (!device)
return;
- if (device->apr)
- apr_deregister(device->apr);
+
+ if (device->resources.fw.cookie) {
+ subsystem_put(device->resources.fw.cookie);
+ device->resources.fw.cookie = NULL;
+ }
+
+ if (device->apr) {
+ if (apr_deregister(device->apr))
+ dprintk(VIDC_ERR, "Failed to deregister APR");
+ device->apr = NULL;
+ }
}
static int q6_hfi_get_fw_info(void *dev, enum fw_info info)
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index cfa5487..e8096d1 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -523,7 +523,7 @@
TI wl127x chips.
config TSIF
- depends on ARCH_MSM
+ depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064
tristate "TSIF (Transport Stream InterFace) support"
default n
---help---
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 6b3cc3d..b2a3a38 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -35,6 +35,7 @@
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/mmc/cd-gpio.h>
+#include <linux/dma-mapping.h>
#include <mach/gpio.h>
#include <mach/msm_bus.h>
@@ -1894,7 +1895,33 @@
return;
}
+static int sdhci_msm_set_uhs_signaling(struct sdhci_host *host,
+ unsigned int uhs)
+{
+ u16 ctrl_2;
+
+ ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ /* Select Bus Speed Mode for host */
+ ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
+ if (uhs == MMC_TIMING_MMC_HS200)
+ ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
+ else if (uhs == MMC_TIMING_UHS_SDR12)
+ ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
+ else if (uhs == MMC_TIMING_UHS_SDR25)
+ ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
+ else if (uhs == MMC_TIMING_UHS_SDR50)
+ ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
+ else if (uhs == MMC_TIMING_UHS_SDR104)
+ ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
+ else if (uhs == MMC_TIMING_UHS_DDR50)
+ ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
+ sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
+
+ return 0;
+}
+
static struct sdhci_ops sdhci_msm_ops = {
+ .set_uhs_signaling = sdhci_msm_set_uhs_signaling,
.check_power_status = sdhci_msm_check_power_status,
.execute_tuning = sdhci_msm_execute_tuning,
.toggle_cdr = sdhci_msm_toggle_cdr,
@@ -2108,6 +2135,13 @@
}
}
+ if (dma_supported(mmc_dev(host->mmc), DMA_BIT_MASK(32))) {
+ host->dma_mask = DMA_BIT_MASK(32);
+ mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
+ } else {
+ dev_err(&pdev->dev, "%s: Failed to set dma mask\n", __func__);
+ }
+
ret = sdhci_add_host(host);
if (ret) {
dev_err(&pdev->dev, "Add host failed (%d)\n", ret);
diff --git a/drivers/net/wireless/wcnss/wcnss_vreg.c b/drivers/net/wireless/wcnss/wcnss_vreg.c
index 0aa9677..7e6cd4f 100644
--- a/drivers/net/wireless/wcnss/wcnss_vreg.c
+++ b/drivers/net/wireless/wcnss/wcnss_vreg.c
@@ -28,8 +28,6 @@
static void __iomem *msm_wcnss_base;
-static struct msm_xo_voter *wlan_clock;
-static const char *id = "WLAN";
static LIST_HEAD(power_on_lock_list);
static DEFINE_MUTEX(list_lock);
static DEFINE_SEMAPHORE(wcnss_power_on_lock);
@@ -93,7 +91,7 @@
{"qcom,iris-vddpa", VREG_NULL_CONFIG, 2900000, 0,
3000000, 515000, NULL},
{"qcom,iris-vdddig", VREG_NULL_CONFIG, 1225000, 0,
- 1225000, 10000, NULL},
+ 1300000, 10000, NULL},
};
/* WCNSS regulators for Pronto hardware */
@@ -124,6 +122,7 @@
void __iomem *pmu_conf_reg;
void __iomem *spare_reg;
struct clk *clk;
+ struct clk *clk_rf = NULL;
if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
wcnss_phys_addr = MSM_PRONTO_PHYS;
@@ -136,6 +135,15 @@
pr_err("Couldn't get xo clock\n");
return PTR_ERR(clk);
}
+
+ if (!use_48mhz_xo) {
+ clk_rf = clk_get(dev, "rf_clk");
+ if (IS_ERR(clk_rf)) {
+ pr_err("Couldn't get rf_clk\n");
+ clk_put(clk);
+ return PTR_ERR(clk_rf);
+ }
+ }
} else {
wcnss_phys_addr = MSM_RIVA_PHYS;
pmu_offset = RIVA_PMU_OFFSET;
@@ -162,6 +170,7 @@
pr_err("clk enable failed\n");
goto fail;
}
+
/* NV bit is set to indicate that platform driver is capable
* of doing NV download. SSR should not set NV bit; during
* SSR NV bin is downloaded by WLAN driver.
@@ -205,40 +214,28 @@
clk_disable_unprepare(clk);
if (!use_48mhz_xo) {
- wlan_clock = msm_xo_get(MSM_XO_TCXO_A2, id);
- if (IS_ERR(wlan_clock)) {
- rc = PTR_ERR(wlan_clock);
- pr_err("Failed to get MSM_XO_TCXO_A2 voter (%d)\n",
- rc);
+ rc = clk_prepare_enable(clk_rf);
+ if (rc) {
+ pr_err("clk_rf enable failed\n");
goto fail;
}
-
- rc = msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_ON);
- if (rc < 0) {
- pr_err("Configuring MSM_XO_MODE_ON failed (%d)\n",
- rc);
- goto msm_xo_vote_fail;
- }
}
- } else {
- if (wlan_clock != NULL && !use_48mhz_xo) {
- rc = msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_OFF);
- if (rc < 0)
- pr_err("Configuring MSM_XO_MODE_OFF failed (%d)\n",
- rc);
- }
- }
-
+ } else if (clk_rf != NULL && !use_48mhz_xo)
+ clk_disable_unprepare(clk_rf);
/* Add some delay for XO to settle */
msleep(20);
clk_put(clk);
+
+ if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
+ if (!use_48mhz_xo)
+ clk_put(clk_rf);
+ }
+
return rc;
-
-msm_xo_vote_fail:
- msm_xo_put(wlan_clock);
-
fail:
+ if (clk_rf != NULL)
+ clk_put(clk_rf);
clk_put(clk);
return rc;
}
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index ee76304..0158235 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -48,6 +48,10 @@
module_param(has_48mhz_xo, int, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(has_48mhz_xo, "Is an external 48 MHz XO present");
+static int do_not_cancel_vote = WCNSS_CONFIG_UNSPECIFIED;
+module_param(do_not_cancel_vote, int, S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(do_not_cancel_vote, "Do not cancel votes for wcnss");
+
static DEFINE_SPINLOCK(reg_spinlock);
#define MSM_RIVA_PHYS 0x03204000
@@ -87,6 +91,9 @@
#define CCU_PRONTO_LAST_ADDR1_OFFSET 0x10
#define CCU_PRONTO_LAST_ADDR2_OFFSET 0x14
+#define MSM_PRONTO_CCPU_CTL_BASE 0xfb21d000
+#define BOOT_REMAP_OFFSET 0x04
+
#define WCNSS_CTRL_CHANNEL "WCNSS_CTRL"
#define WCNSS_MAX_FRAME_SIZE 500
#define WCNSS_VERSION_LEN 30
@@ -193,6 +200,7 @@
void __iomem *riva_ccu_base;
void __iomem *pronto_a2xb_base;
void __iomem *pronto_ccpu_base;
+ void __iomem *pronto_ctl_base;
} *penv = NULL;
static ssize_t wcnss_serial_number_show(struct device *dev,
@@ -326,6 +334,10 @@
reg = readl_relaxed(reg_addr);
pr_info_ratelimited("%s: CCU_CCPU_LAST_ADDR2 %08x\n", __func__, reg);
+ reg_addr = penv->pronto_ctl_base + BOOT_REMAP_OFFSET;
+ reg = readl_relaxed(reg_addr);
+ pr_info_ratelimited("%s: BOOT_REMAP_ADDR %08x\n", __func__, reg);
+
tst_addr = penv->pronto_a2xb_base + A2XB_TSTBUS_OFFSET;
tst_ctrl_addr = penv->pronto_a2xb_base + A2XB_TSTBUS_CTRL_OFFSET;
@@ -396,12 +408,13 @@
{
if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
wcnss_pronto_log_debug_regs();
- pr_err("%s: reset interrupt not supported\n", __func__);
- return;
+ wmb();
+ __raw_writel(1 << 16, MSM_APCS_GCC_BASE + 0x8);
+ } else {
+ wcnss_riva_log_debug_regs();
+ wmb();
+ __raw_writel(1 << 24, MSM_APCS_GCC_BASE + 0x8);
}
- wcnss_riva_log_debug_regs();
- wmb();
- __raw_writel(1 << 24, MSM_APCS_GCC_BASE + 0x8);
}
EXPORT_SYMBOL(wcnss_reset_intr);
@@ -477,6 +490,11 @@
static void wcnss_post_bootup(struct work_struct *work)
{
+ if (do_not_cancel_vote == 1) {
+ pr_info("%s: Keeping APPS vote for Iris & WCNSS\n", __func__);
+ return;
+ }
+
pr_info("%s: Cancel APPS vote for Iris & WCNSS\n", __func__);
/* Since WCNSS is up, cancel any APPS vote for Iris & WCNSS VREGs */
@@ -1173,11 +1191,20 @@
pr_err("%s: ioremap wcnss physical failed\n", __func__);
goto fail_ioremap2;
}
+ penv->pronto_ctl_base = ioremap(MSM_PRONTO_CCPU_CTL_BASE,
+ SZ_32);
+ if (!penv->pronto_ctl_base) {
+ ret = -ENOMEM;
+ pr_err("%s: ioremap wcnss physical failed\n", __func__);
+ goto fail_ioremap3;
+ }
}
penv->cold_boot_done = 1;
return 0;
+fail_ioremap3:
+ iounmap(penv->pronto_ccpu_base);
fail_ioremap2:
iounmap(penv->pronto_a2xb_base);
fail_ioremap:
diff --git a/drivers/platform/msm/ipa/ipa.c b/drivers/platform/msm/ipa/ipa.c
index 42a0016..db7f7f0 100644
--- a/drivers/platform/msm/ipa/ipa.c
+++ b/drivers/platform/msm/ipa/ipa.c
@@ -119,7 +119,7 @@
module_param(ip4_rt_tbl_lcl, bool, 0644);
MODULE_PARM_DESC(ip4_rt_tbl_lcl,
"where ip4 rt tables reside 1-local; 0-system");
-static bool ip6_rt_tbl_lcl = 1;
+static bool ip6_rt_tbl_lcl;
module_param(ip6_rt_tbl_lcl, bool, 0644);
MODULE_PARM_DESC(ip6_rt_tbl_lcl,
"where ip6 rt tables reside 1-local; 0-system");
diff --git a/drivers/platform/msm/ipa/ipa_client.c b/drivers/platform/msm/ipa/ipa_client.c
index b57585c..0ee7f27 100644
--- a/drivers/platform/msm/ipa/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_client.c
@@ -310,6 +310,8 @@
IPA_HOLB_TMR_VAL);
}
+ IPADBG("client %d (ep: %d) connected\n", in->client, ipa_ep_idx);
+
return 0;
sps_connect_fail:
@@ -345,6 +347,7 @@
return result;
}
EXPORT_SYMBOL(ipa_connect);
+
/**
* ipa_disconnect() - low-level IPA client disconnect
* @clnt_hdl: [in] opaque client handle assigned by IPA to client
@@ -420,6 +423,8 @@
ipa_disable_clks();
}
+ IPADBG("client (ep: %d) disconnected\n", clnt_hdl);
+
return 0;
}
EXPORT_SYMBOL(ipa_disconnect);
diff --git a/drivers/platform/msm/ipa/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_debugfs.c
index 1605ed2..51a950d 100644
--- a/drivers/platform/msm/ipa/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_debugfs.c
@@ -18,6 +18,8 @@
#define IPA_MAX_MSG_LEN 4096
+#define IPA_DBG_CNTR_ON 127265
+#define IPA_DBG_CNTR_OFF 127264
const char *ipa_client_name[] = {
__stringify(IPA_CLIENT_HSIC1_PROD),
@@ -76,6 +78,19 @@
__stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_IP),
};
+const char *ipa_event_name[] = {
+ __stringify(WLAN_CLIENT_CONNECT),
+ __stringify(WLAN_CLIENT_DISCONNECT),
+ __stringify(WLAN_CLIENT_POWER_SAVE_MODE),
+ __stringify(WLAN_CLIENT_NORMAL_MODE),
+ __stringify(SW_ROUTING_ENABLE),
+ __stringify(SW_ROUTING_DISABLE),
+ __stringify(WLAN_AP_CONNECT),
+ __stringify(WLAN_AP_DISCONNECT),
+ __stringify(WLAN_STA_CONNECT),
+ __stringify(WLAN_STA_DISCONNECT),
+};
+
static struct dentry *dent;
static struct dentry *dfile_gen_reg;
static struct dentry *dfile_ep_reg;
@@ -85,6 +100,8 @@
static struct dentry *dfile_ip4_flt;
static struct dentry *dfile_ip6_flt;
static struct dentry *dfile_stats;
+static struct dentry *dfile_dbg_cnt;
+static struct dentry *dfile_msg;
static char dbg_buff[IPA_MAX_MSG_LEN];
static s8 ep_reg_idx;
@@ -199,7 +216,10 @@
"IPA_ENDP_INIT_HDR_%u=0x%x\n"
"IPA_ENDP_INIT_MODE_%u=0x%x\n"
"IPA_ENDP_INIT_AGGR_%u=0x%x\n"
- "IPA_ENDP_INIT_ROUTE_%u=0x%x\n",
+ "IPA_ENDP_INIT_ROUTE_%u=0x%x\n"
+ "IPA_ENDP_INIT_CTRL_%u=0x%x\n"
+ "IPA_ENDP_INIT_HOL_EN_%u=0x%x\n"
+ "IPA_ENDP_INIT_HOL_TIMER_%u=0x%x\n",
i, ipa_read_reg(ipa_ctx->mmio,
IPA_ENDP_INIT_NAT_n_OFST_v2(i)),
i, ipa_read_reg(ipa_ctx->mmio,
@@ -209,7 +229,14 @@
i, ipa_read_reg(ipa_ctx->mmio,
IPA_ENDP_INIT_AGGR_n_OFST_v2(i)),
i, ipa_read_reg(ipa_ctx->mmio,
- IPA_ENDP_INIT_ROUTE_n_OFST_v2(i)));
+ IPA_ENDP_INIT_ROUTE_n_OFST_v2(i)),
+ i, ipa_read_reg(ipa_ctx->mmio,
+ IPA_ENDP_INIT_CTRL_n_OFST(i)),
+ i, ipa_read_reg(ipa_ctx->mmio,
+ IPA_ENDP_INIT_HOL_BLOCK_EN_n_OFST(i)),
+ i, ipa_read_reg(ipa_ctx->mmio,
+ IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_OFST(i))
+ );
}
*ppos = pos;
@@ -516,6 +543,10 @@
int nbytes;
int i;
int cnt = 0;
+ uint connect = 0;
+
+ for (i = 0; i < IPA_NUM_PIPES; i++)
+ connect |= (ipa_ctx->ep[i].valid << i);
nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
"sw_tx=%u\n"
@@ -523,13 +554,17 @@
"rx=%u\n"
"rx_repl_repost=%u\n"
"x_intr_repost=%u\n"
- "rx_q_len=%u\n",
+ "rx_q_len=%u\n"
+ "act_clnt=%u\n"
+ "con_clnt_bmap=0x%x\n",
ipa_ctx->stats.tx_sw_pkts,
ipa_ctx->stats.tx_hw_pkts,
ipa_ctx->stats.rx_pkts,
ipa_ctx->stats.rx_repl_repost,
ipa_ctx->stats.x_intr_repost,
- ipa_ctx->stats.rx_q_len);
+ ipa_ctx->stats.rx_q_len,
+ atomic_read(&ipa_ctx->ipa_active_clients),
+ connect);
cnt += nbytes;
for (i = 0; i < MAX_NUM_EXCP; i++) {
@@ -560,6 +595,64 @@
return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
}
+static ssize_t ipa_write_dbg_cnt(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long missing;
+ u32 option = 0;
+
+ if (sizeof(dbg_buff) < count + 1)
+ return -EFAULT;
+
+ missing = copy_from_user(dbg_buff, buf, count);
+ if (missing)
+ return -EFAULT;
+
+ dbg_buff[count] = '\0';
+ if (kstrtou32(dbg_buff, 0, &option))
+ return -EFAULT;
+
+ if (option == 1)
+ ipa_write_reg(ipa_ctx->mmio, IPA_DEBUG_CNT_CTRL_n_OFST(0),
+ IPA_DBG_CNTR_ON);
+ else
+ ipa_write_reg(ipa_ctx->mmio, IPA_DEBUG_CNT_CTRL_n_OFST(0),
+ IPA_DBG_CNTR_OFF);
+
+ return count;
+}
+
+static ssize_t ipa_read_dbg_cnt(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ int nbytes;
+
+ nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
+ "IPA_DEBUG_CNT_REG_0=0x%x\n",
+ ipa_read_reg(ipa_ctx->mmio,
+ IPA_DEBUG_CNT_REG_n_OFST(0)));
+
+ return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
+}
+
+static ssize_t ipa_read_msg(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ int nbytes;
+ int cnt = 0;
+ int i;
+
+ for (i = 0; i < IPA_EVENT_MAX; i++) {
+ nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
+ "msg[%u:%27s] W:%u R:%u\n", i,
+ ipa_event_name[i],
+ ipa_ctx->stats.msg_w[i],
+ ipa_ctx->stats.msg_r[i]);
+ cnt += nbytes;
+ }
+
+ return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
+}
const struct file_operations ipa_gen_reg_ops = {
.read = ipa_read_gen_reg,
@@ -588,6 +681,15 @@
.read = ipa_read_stats,
};
+const struct file_operations ipa_msg_ops = {
+ .read = ipa_read_msg,
+};
+
+const struct file_operations ipa_dbg_cnt_ops = {
+ .read = ipa_read_dbg_cnt,
+ .write = ipa_write_dbg_cnt,
+};
+
void ipa_debugfs_init(void)
{
const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH;
@@ -656,6 +758,20 @@
goto fail;
}
+ dfile_dbg_cnt = debugfs_create_file("dbg_cnt", read_write_mode, dent, 0,
+ &ipa_dbg_cnt_ops);
+ if (!dfile_dbg_cnt || IS_ERR(dfile_dbg_cnt)) {
+ IPAERR("fail to create file for debug_fs dbg_cnt\n");
+ goto fail;
+ }
+
+ dfile_msg = debugfs_create_file("msg", read_only_mode, dent, 0,
+ &ipa_msg_ops);
+ if (!dfile_msg || IS_ERR(dfile_msg)) {
+ IPAERR("fail to create file for debug_fs msg\n");
+ goto fail;
+ }
+
return;
fail:
diff --git a/drivers/platform/msm/ipa/ipa_dp.c b/drivers/platform/msm/ipa/ipa_dp.c
index 971cf5e..dabf86f 100644
--- a/drivers/platform/msm/ipa/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_dp.c
@@ -900,6 +900,8 @@
*clnt_hdl = ipa_ep_idx;
+ IPADBG("client %d (ep: %d) connected\n", sys_in->client, ipa_ep_idx);
+
return 0;
fail_register_event:
@@ -936,6 +938,9 @@
ipa_ctx->ep[clnt_hdl].connect.desc.phys_base);
sps_free_endpoint(ipa_ctx->ep[clnt_hdl].ep_hdl);
memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context));
+
+ IPADBG("client (ep: %d) disconnected\n", clnt_hdl);
+
return 0;
}
EXPORT_SYMBOL(ipa_teardown_sys_pipe);
diff --git a/drivers/platform/msm/ipa/ipa_i.h b/drivers/platform/msm/ipa/ipa_i.h
index 45f7b09..d79504e 100644
--- a/drivers/platform/msm/ipa/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_i.h
@@ -529,6 +529,8 @@
u32 rx_repl_repost;
u32 x_intr_repost;
u32 rx_q_len;
+ u32 msg_w[IPA_EVENT_MAX];
+ u32 msg_r[IPA_EVENT_MAX];
};
/**
diff --git a/drivers/platform/msm/ipa/ipa_intf.c b/drivers/platform/msm/ipa/ipa_intf.c
index 9876650..0f41d2c 100644
--- a/drivers/platform/msm/ipa/ipa_intf.c
+++ b/drivers/platform/msm/ipa/ipa_intf.c
@@ -268,6 +268,11 @@
return -EINVAL;
}
+ if (meta->msg_type >= IPA_EVENT_MAX) {
+ IPAERR("unsupported message type %d\n", meta->msg_type);
+ return -EINVAL;
+ }
+
msg = kzalloc(sizeof(struct ipa_push_msg), GFP_KERNEL);
if (msg == NULL) {
IPAERR("fail to alloc ipa_msg container\n");
@@ -281,6 +286,7 @@
mutex_lock(&ipa_ctx->msg_lock);
list_add_tail(&msg->link, &ipa_ctx->msg_list);
mutex_unlock(&ipa_ctx->msg_lock);
+ IPA_STATS_INC_CNT(ipa_ctx->stats.msg_w[meta->msg_type]);
wake_up(&ipa_ctx->msg_waitq);
@@ -424,6 +430,8 @@
msg->callback(msg->buff, msg->meta.msg_len,
msg->meta.msg_type);
}
+ IPA_STATS_INC_CNT(
+ ipa_ctx->stats.msg_r[msg->meta.msg_type]);
}
ret = -EAGAIN;
diff --git a/drivers/platform/msm/ipa/ipa_ram_mmap.h b/drivers/platform/msm/ipa/ipa_ram_mmap.h
index 7e12b6a..d120f37 100644
--- a/drivers/platform/msm/ipa/ipa_ram_mmap.h
+++ b/drivers/platform/msm/ipa/ipa_ram_mmap.h
@@ -19,17 +19,18 @@
*/
#define IPA_RAM_NAT_OFST 0
-#define IPA_RAM_NAT_SIZE 2048
-#define IPA_RAM_HDR_OFST 2048
-#define IPA_RAM_HDR_SIZE 440
+#define IPA_RAM_NAT_SIZE 0
+#define IPA_RAM_HDR_OFST (IPA_RAM_NAT_OFST + IPA_RAM_NAT_SIZE)
+#define IPA_RAM_HDR_SIZE 1288
#define IPA_RAM_V4_FLT_OFST (IPA_RAM_HDR_OFST + IPA_RAM_HDR_SIZE)
-#define IPA_RAM_V4_FLT_SIZE 1024
+#define IPA_RAM_V4_FLT_SIZE 1420
#define IPA_RAM_V4_RT_OFST (IPA_RAM_V4_FLT_OFST + IPA_RAM_V4_FLT_SIZE)
-#define IPA_RAM_V4_RT_SIZE 1024
+#define IPA_RAM_V4_RT_SIZE 2192
#define IPA_RAM_V6_FLT_OFST (IPA_RAM_V4_RT_OFST + IPA_RAM_V4_RT_SIZE)
-#define IPA_RAM_V6_FLT_SIZE 1024
+#define IPA_RAM_V6_FLT_SIZE 1228
#define IPA_RAM_V6_RT_OFST (IPA_RAM_V6_FLT_OFST + IPA_RAM_V6_FLT_SIZE)
-#define IPA_RAM_V6_RT_SIZE 1024
+#define IPA_RAM_V6_RT_SIZE 528
#define IPA_RAM_END_OFST (IPA_RAM_V6_RT_OFST + IPA_RAM_V6_RT_SIZE)
+#define IPA_RAM_V6_RT_SIZE_DDR 15764
#endif /* _IPA_RAM_MMAP_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_reg.h b/drivers/platform/msm/ipa/ipa_reg.h
index 03d1972..ffa81dc 100644
--- a/drivers/platform/msm/ipa/ipa_reg.h
+++ b/drivers/platform/msm/ipa/ipa_reg.h
@@ -183,6 +183,27 @@
#define IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_TIMER_BMSK 0x1ff
#define IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_TIMER_SHFT 0x0
+#define IPA_DEBUG_CNT_REG_n_OFST(n) (0x00000340 + 0x4 * (n))
+#define IPA_DEBUG_CNT_REG_n_RMSK 0xffffffff
+#define IPA_DEBUG_CNT_REG_n_MAXn 15
+#define IPA_DEBUG_CNT_REG_n_DBG_CNT_REG_BMSK 0xffffffff
+#define IPA_DEBUG_CNT_REG_n_DBG_CNT_REG_SHFT 0x0
+
+#define IPA_DEBUG_CNT_CTRL_n_OFST(n) (0x00000380 + 0x4 * (n))
+#define IPA_DEBUG_CNT_CTRL_n_RMSK 0x1ff1f171
+#define IPA_DEBUG_CNT_CTRL_n_MAXn 15
+#define IPA_DEBUG_CNT_CTRL_n_DBG_CNT_RULE_INDEX_BMSK 0x1ff00000
+#define IPA_DEBUG_CNT_CTRL_n_DBG_CNT_RULE_INDEX_SHFT 0x14
+#define IPA_DEBUG_CNT_CTRL_n_DBG_CNT_SOURCE_PIPE_BMSK 0x1f000
+#define IPA_DEBUG_CNT_CTRL_n_DBG_CNT_SOURCE_PIPE_SHFT 0xc
+#define IPA_DEBUG_CNT_CTRL_n_DBG_CNT_PRODUCT_BMSK 0x100
+#define IPA_DEBUG_CNT_CTRL_n_DBG_CNT_PRODUCT_SHFT 0x8
+#define IPA_DEBUG_CNT_CTRL_n_DBG_CNT_TYPE_BMSK 0x70
+#define IPA_DEBUG_CNT_CTRL_n_DBG_CNT_TYPE_SHFT 0x4
+#define IPA_DEBUG_CNT_CTRL_n_DBG_CNT_EN_BMSK 0x1
+#define IPA_DEBUG_CNT_CTRL_n_DBG_CNT_EN_SHFT 0x0
+
+
#endif
diff --git a/drivers/platform/msm/ipa/ipa_rt.c b/drivers/platform/msm/ipa/ipa_rt.c
index 7d509c6..fcc5e58 100644
--- a/drivers/platform/msm/ipa/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_rt.c
@@ -361,7 +361,8 @@
avail = IPA_RAM_V4_RT_SIZE;
size = sizeof(struct ipa_ip_v4_routing_init);
} else {
- avail = IPA_RAM_V6_RT_SIZE;
+ avail = ipa_ctx->ip6_rt_tbl_lcl ? IPA_RAM_V6_RT_SIZE :
+ IPA_RAM_V6_RT_SIZE_DDR;
size = sizeof(struct ipa_ip_v6_routing_init);
}
cmd = kmalloc(size, GFP_KERNEL);
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index 37dfc1b..b34f9dc 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -555,14 +555,14 @@
return;
}
- dfile_info = debugfs_create_file("info", 0666, dent, 0,
+ dfile_info = debugfs_create_file("info", 0664, dent, 0,
&sps_info_ops);
if (!dfile_info || IS_ERR(dfile_info)) {
pr_err("sps:fail to create the file for debug_fs info.\n");
goto info_err;
}
- dfile_logging_option = debugfs_create_file("logging_option", 0666,
+ dfile_logging_option = debugfs_create_file("logging_option", 0664,
dent, 0, &sps_logging_option_ops);
if (!dfile_logging_option || IS_ERR(dfile_logging_option)) {
pr_err("sps:fail to create the file for debug_fs "
@@ -571,7 +571,7 @@
}
dfile_debug_level_option = debugfs_create_u8("debug_level_option",
- 0666, dent, &debug_level_option);
+ 0664, dent, &debug_level_option);
if (!dfile_debug_level_option || IS_ERR(dfile_debug_level_option)) {
pr_err("sps:fail to create the file for debug_fs "
"debug_level_option.\n");
@@ -579,14 +579,14 @@
}
dfile_print_limit_option = debugfs_create_u8("print_limit_option",
- 0666, dent, &print_limit_option);
+ 0664, dent, &print_limit_option);
if (!dfile_print_limit_option || IS_ERR(dfile_print_limit_option)) {
pr_err("sps:fail to create the file for debug_fs "
"print_limit_option.\n");
goto print_limit_option_err;
}
- dfile_reg_dump_option = debugfs_create_u8("reg_dump_option", 0666,
+ dfile_reg_dump_option = debugfs_create_u8("reg_dump_option", 0664,
dent, ®_dump_option);
if (!dfile_reg_dump_option || IS_ERR(dfile_reg_dump_option)) {
pr_err("sps:fail to create the file for debug_fs "
@@ -594,28 +594,28 @@
goto reg_dump_option_err;
}
- dfile_testbus_sel = debugfs_create_u32("testbus_sel", 0666,
+ dfile_testbus_sel = debugfs_create_u32("testbus_sel", 0664,
dent, &testbus_sel);
if (!dfile_testbus_sel || IS_ERR(dfile_testbus_sel)) {
pr_err("sps:fail to create debug_fs file for testbus_sel.\n");
goto testbus_sel_err;
}
- dfile_bam_pipe_sel = debugfs_create_u32("bam_pipe_sel", 0666,
+ dfile_bam_pipe_sel = debugfs_create_u32("bam_pipe_sel", 0664,
dent, &bam_pipe_sel);
if (!dfile_bam_pipe_sel || IS_ERR(dfile_bam_pipe_sel)) {
pr_err("sps:fail to create debug_fs file for bam_pipe_sel.\n");
goto bam_pipe_sel_err;
}
- dfile_desc_option = debugfs_create_u32("desc_option", 0666,
+ dfile_desc_option = debugfs_create_u32("desc_option", 0664,
dent, &desc_option);
if (!dfile_desc_option || IS_ERR(dfile_desc_option)) {
pr_err("sps:fail to create debug_fs file for desc_option.\n");
goto desc_option_err;
}
- dfile_bam_addr = debugfs_create_file("bam_addr", 0666,
+ dfile_bam_addr = debugfs_create_file("bam_addr", 0664,
dent, 0, &sps_bam_addr_ops);
if (!dfile_bam_addr || IS_ERR(dfile_bam_addr)) {
pr_err("sps:fail to create the file for debug_fs "
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 68f4bdd..5136fdf 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -3142,6 +3142,9 @@
static void pm_batt_external_power_changed(struct power_supply *psy)
{
+ if (!the_chip)
+ return;
+
/* Only look for an external supply if it hasn't been registered */
if (!the_chip->ext_psy)
class_for_each_device(power_supply_class, NULL, psy,
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index bc6f289..a194c49 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -116,6 +116,8 @@
u8 revision1;
u8 revision2;
int battery_present;
+ bool new_battery;
+ bool last_soc_invalid;
/* platform data */
int r_sense_uohm;
unsigned int v_cutoff_uv;
@@ -135,6 +137,7 @@
int default_rbatt_mohm;
struct delayed_work calculate_soc_delayed_work;
+ struct work_struct recalc_work;
struct mutex bms_output_lock;
struct mutex last_ocv_uv_mutex;
@@ -144,7 +147,7 @@
bool use_ocv_thresholds;
bool ignore_shutdown_soc;
- int shutdown_soc_invalid;
+ bool shutdown_soc_invalid;
int shutdown_soc;
int shutdown_iavg_ma;
@@ -552,6 +555,100 @@
pr_err("cc reenable failed: %d\n", rc);
}
+static bool is_battery_charging(struct qpnp_bms_chip *chip)
+{
+ union power_supply_propval ret = {0,};
+
+ if (chip->batt_psy == NULL)
+ chip->batt_psy = power_supply_get_by_name("battery");
+ if (chip->batt_psy) {
+ /* if battery has been registered, use the status property */
+ chip->batt_psy->get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_STATUS, &ret);
+ return ret.intval == POWER_SUPPLY_STATUS_CHARGING;
+ }
+
+ /* Default to false if the battery power supply is not registered. */
+ pr_debug("battery power supply is not registered\n");
+ return false;
+}
+
+static bool is_batfet_open(struct qpnp_bms_chip *chip)
+{
+ union power_supply_propval ret = {0,};
+
+ if (chip->batt_psy == NULL)
+ chip->batt_psy = power_supply_get_by_name("battery");
+ if (chip->batt_psy) {
+ /* if battery has been registered, use the status property */
+ chip->batt_psy->get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_STATUS, &ret);
+ return ret.intval == POWER_SUPPLY_STATUS_FULL;
+ }
+
+ /* Default to true if the battery power supply is not registered. */
+ pr_debug("battery power supply is not registered\n");
+ return true;
+}
+
+static int get_simultaneous_batt_v_and_i(struct qpnp_bms_chip *chip,
+ int *ibat_ua, int *vbat_uv)
+{
+ struct qpnp_iadc_result i_result;
+ struct qpnp_vadc_result v_result;
+ enum qpnp_iadc_channels iadc_channel;
+ int rc;
+
+ iadc_channel = chip->use_external_rsense ?
+ EXTERNAL_RSENSE : INTERNAL_RSENSE;
+ rc = qpnp_iadc_vadc_sync_read(iadc_channel, &i_result,
+ VBAT_SNS, &v_result);
+ if (rc) {
+ pr_err("vadc read failed with rc: %d\n", rc);
+ return rc;
+ }
+ /*
+ * reverse the current read by the iadc, since the bms uses
+ * flipped battery current polarity.
+ */
+ *ibat_ua = -1 * (int)i_result.result_ua;
+ *vbat_uv = (int)v_result.physical;
+
+ return 0;
+}
+
+static int estimate_ocv(struct qpnp_bms_chip *chip)
+{
+ int ibat_ua, vbat_uv, ocv_est_uv;
+ int rc;
+ int rbatt_mohm = chip->default_rbatt_mohm + chip->r_conn_mohm;
+
+ rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
+ if (rc) {
+ pr_err("simultaneous failed rc = %d\n", rc);
+ return rc;
+ }
+
+ ocv_est_uv = vbat_uv + (ibat_ua * rbatt_mohm) / 1000;
+ pr_debug("estimated pon ocv = %d\n", ocv_est_uv);
+ return ocv_est_uv;
+}
+
+static void reset_for_new_battery(struct qpnp_bms_chip *chip, int batt_temp)
+{
+ chip->last_ocv_uv = estimate_ocv(chip);
+ chip->last_soc = -EINVAL;
+ chip->soc_at_cv = -EINVAL;
+ chip->shutdown_soc_invalid = true;
+ chip->shutdown_soc = 0;
+ chip->shutdown_iavg_ma = 0;
+ chip->prev_pc_unusable = -EINVAL;
+ reset_cc(chip);
+ chip->last_cc_uah = INT_MIN;
+ chip->last_ocv_temp = batt_temp;
+ chip->last_soc_invalid = true;
+}
+
#define OCV_RAW_UNINITIALIZED 0xFFFF
static int read_soc_params_raw(struct qpnp_bms_chip *chip,
struct raw_soc_params *raw,
@@ -590,6 +687,12 @@
if (chip->prev_last_good_ocv_raw == OCV_RAW_UNINITIALIZED) {
convert_and_store_ocv(chip, raw, batt_temp);
pr_debug("PON_OCV_UV = %d\n", chip->last_ocv_uv);
+ } else if (chip->new_battery) {
+ /* if a new battery was inserted, estimate the ocv */
+ reset_for_new_battery(chip, batt_temp);
+ raw->cc = 0;
+ raw->last_good_ocv_uv = chip->last_ocv_uv;
+ chip->new_battery = false;
} else if (chip->prev_last_good_ocv_raw != raw->last_good_ocv_raw) {
convert_and_store_ocv(chip, raw, batt_temp);
/* forget the old cc value upon ocv */
@@ -1083,75 +1186,13 @@
pr_debug("rejecting shutdown soc = %d, soc = %d limit = %d\n",
chip->shutdown_soc, soc,
chip->shutdown_soc_valid_limit);
- chip->shutdown_soc_invalid = 1;
+ chip->shutdown_soc_invalid = true;
return 0;
}
return 1;
}
-static bool is_battery_charging(struct qpnp_bms_chip *chip)
-{
- union power_supply_propval ret = {0,};
-
- if (chip->batt_psy == NULL)
- chip->batt_psy = power_supply_get_by_name("battery");
- if (chip->batt_psy) {
- /* if battery has been registered, use the status property */
- chip->batt_psy->get_property(chip->batt_psy,
- POWER_SUPPLY_PROP_STATUS, &ret);
- return ret.intval == POWER_SUPPLY_STATUS_CHARGING;
- }
-
- /* Default to false if the battery power supply is not registered. */
- pr_debug("battery power supply is not registered\n");
- return false;
-}
-
-static bool is_batfet_open(struct qpnp_bms_chip *chip)
-{
- union power_supply_propval ret = {0,};
-
- if (chip->batt_psy == NULL)
- chip->batt_psy = power_supply_get_by_name("battery");
- if (chip->batt_psy) {
- /* if battery has been registered, use the status property */
- chip->batt_psy->get_property(chip->batt_psy,
- POWER_SUPPLY_PROP_STATUS, &ret);
- return ret.intval == POWER_SUPPLY_STATUS_FULL;
- }
-
- /* Default to true if the battery power supply is not registered. */
- pr_debug("battery power supply is not registered\n");
- return true;
-}
-
-static int get_simultaneous_batt_v_and_i(struct qpnp_bms_chip *chip,
- int *ibat_ua, int *vbat_uv)
-{
- struct qpnp_iadc_result i_result;
- struct qpnp_vadc_result v_result;
- enum qpnp_iadc_channels iadc_channel;
- int rc;
-
- iadc_channel = chip->use_external_rsense ?
- EXTERNAL_RSENSE : INTERNAL_RSENSE;
- rc = qpnp_iadc_vadc_sync_read(iadc_channel, &i_result,
- VBAT_SNS, &v_result);
- if (rc) {
- pr_err("vadc read failed with rc: %d\n", rc);
- return rc;
- }
- /*
- * reverse the current read by the iadc, since the bms uses
- * flipped battery current polarity.
- */
- *ibat_ua = -1 * (int)i_result.result_ua;
- *vbat_uv = (int)v_result.physical;
-
- return 0;
-}
-
static int bound_soc(int soc)
{
soc = max(0, soc);
@@ -1188,6 +1229,7 @@
pr_debug("forcing ocv to be %d due to bms reset mode\n", ocv_est_uv);
chip->last_ocv_uv = ocv_est_uv;
chip->last_soc = -EINVAL;
+ chip->last_soc_invalid = true;
reset_cc(chip);
chip->last_cc_uah = INT_MIN;
stop_ocv_updates(chip);
@@ -1475,6 +1517,11 @@
int shutdown_soc, new_calculated_soc, remaining_usable_charge_uah;
struct soc_params params;
+ if (!chip->battery_present) {
+ pr_debug("battery gone, reporting 0\n");
+ new_calculated_soc = 0;
+ goto done_calculating;
+ }
calculate_soc_params(chip, raw, ¶ms, batt_temp);
/* calculate remaining usable charge */
remaining_usable_charge_uah = params.ocv_charge_uah
@@ -1574,6 +1621,10 @@
}
chip->calculated_soc = new_calculated_soc;
+ if (chip->last_soc_invalid) {
+ chip->last_soc_invalid = false;
+ chip->last_soc = -EINVAL;
+ }
pr_debug("CC based calculated SOC = %d\n", chip->calculated_soc);
chip->first_time_calc_soc = 0;
get_current_time(&chip->last_recalc_time);
@@ -1639,6 +1690,15 @@
return soc;
}
+static void recalculate_work(struct work_struct *work)
+{
+ struct qpnp_bms_chip *chip = container_of(work,
+ struct qpnp_bms_chip,
+ recalc_work);
+
+ recalculate_soc(chip);
+}
+
static void calculate_soc_work(struct work_struct *work)
{
struct qpnp_bms_chip *chip = container_of(work,
@@ -1820,7 +1880,7 @@
pr_debug("Reported SOC = %d\n", chip->last_soc);
chip->t_soc_queried = now;
- return chip->last_soc;
+ return soc;
}
static int report_state_of_charge(struct qpnp_bms_chip *chip)
@@ -1872,8 +1932,14 @@
static void set_prop_bms_present(struct qpnp_bms_chip *chip, int present)
{
- if (chip->battery_present != present)
+ if (chip->battery_present != present) {
chip->battery_present = present;
+ if (present)
+ chip->new_battery = true;
+ /* a new battery was inserted or removed, so force a soc
+ * recalculation to update the SoC */
+ schedule_work(&chip->recalc_work);
+ }
}
static void qpnp_bms_external_power_changed(struct power_supply *psy)
@@ -1969,7 +2035,7 @@
u8 temp;
if (chip->ignore_shutdown_soc) {
- chip->shutdown_soc_invalid = 1;
+ chip->shutdown_soc_invalid = true;
chip->shutdown_soc = 0;
chip->shutdown_iavg_ma = 0;
} else {
@@ -2003,7 +2069,7 @@
if (chip->shutdown_soc == 0) {
pr_debug("No shutdown soc available\n");
- chip->shutdown_soc_invalid = 1;
+ chip->shutdown_soc_invalid = true;
chip->shutdown_iavg_ma = 0;
} else if (chip->shutdown_soc == SOC_ZERO) {
chip->shutdown_soc = 0;
@@ -2391,6 +2457,7 @@
"qpnp_low_voltage_lock");
INIT_DELAYED_WORK(&chip->calculate_soc_delayed_work,
calculate_soc_work);
+ INIT_WORK(&chip->recalc_work, recalculate_work);
read_shutdown_soc_and_iavg(chip);
@@ -2403,6 +2470,9 @@
chip->batt_psy->get_property(chip->batt_psy,
POWER_SUPPLY_PROP_PRESENT, &retval);
chip->battery_present = retval.intval;
+ pr_debug("present = %d\n", chip->battery_present);
+ } else {
+ chip->battery_present = 1;
}
calculate_soc_work(&(chip->calculate_soc_delayed_work.work));
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 63acde1..8806004 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -200,7 +200,6 @@
struct work_struct clock_off_w; /* work for actual clock off */
struct workqueue_struct *hsuart_wq; /* hsuart workqueue */
struct mutex clk_mutex; /* mutex to guard against clock off/clock on */
- struct work_struct reset_bam_rx; /* work for reset bam rx endpoint */
struct work_struct disconnect_rx_endpoint; /* disconnect rx_endpoint */
bool tty_flush_receive;
enum uart_core_type uart_type;
@@ -219,6 +218,7 @@
/* BLSP UART required BUS Scaling data */
struct msm_bus_scale_pdata *bus_scale_table;
bool rx_discard_flush_issued;
+ int rx_count_callback;
};
#define MSM_UARTDM_BURST_SIZE 16 /* DM burst size (in bytes) */
@@ -231,6 +231,7 @@
#define BUS_SCALING 1
#define BUS_RESET 0
#define RX_FLUSH_COMPLETE_TIMEOUT 300 /* In jiffies */
+#define BLSP_UART_CLK_FMAX 63160000
static struct dentry *debug_base;
static struct msm_hs_port q_uart_port[UARTDM_NR];
@@ -750,6 +751,17 @@
mb();
if (bps > 460800) {
uport->uartclk = bps * 16;
+ if (is_blsp_uart(msm_uport)) {
+ /* BLSP based UART supports maximum clock frequency
+ * of 63.16 Mhz. With this (63.16 Mhz) clock frequency
+ * UART can support baud rate of 3.94 Mbps which is
+ * equivalent to 4 Mbps.
+ * UART hardware is robust enough to handle this
+ * deviation to achieve baud rate ~4 Mbps.
+ */
+ if (bps == 4000000)
+ uport->uartclk = BLSP_UART_CLK_FMAX;
+ }
} else {
uport->uartclk = 7372800;
}
@@ -823,22 +835,6 @@
}
-/* Reset BAM RX Endpoint Pipe Index from workqueue context*/
-
-static void hsuart_reset_bam_rx_work(struct work_struct *w)
-{
- struct msm_hs_port *msm_uport = container_of(w, struct msm_hs_port,
- reset_bam_rx);
- struct uart_port *uport = &msm_uport->uport;
- struct msm_hs_rx *rx = &msm_uport->rx;
- struct sps_pipe *sps_pipe_handle = rx->prod.pipe_handle;
-
- sps_disconnect(sps_pipe_handle);
- msm_hs_spsconnect_rx(uport);
-
- msm_serial_hs_rx_tlet((unsigned long) &rx->tlet);
-}
-
/*
* termios : new ktermios
* oldtermios: old ktermios previous setting
@@ -1073,13 +1069,6 @@
if (!is_blsp_uart(msm_uport) && msm_uport->rx.flush != FLUSH_SHUTDOWN)
msm_uport->rx.flush = FLUSH_STOP;
- /* During uart port close, due to spurious rx stale interrupt,
- * the rx state machine is causing BUG_ON to be hit in
- * msm_hs_shutdown causing kernel panic.
- * Hence fixing the same by handling the rx state machine.
- */
- if (is_blsp_uart(msm_uport) && msm_uport->rx.flush == FLUSH_DATA_READY)
- msm_uport->rx.flush = FLUSH_SHUTDOWN;
}
/* Transmit the next chunk of data */
@@ -1178,10 +1167,6 @@
printk(KERN_ERR "Error: rx started in buffer state = %x",
buffer_pending);
- if (is_blsp_uart(msm_uport)) {
- /* Issue RX BAM Start IFC command */
- msm_hs_write(uport, UARTDM_CR_ADDR, START_RX_BAM_IFC);
- }
msm_hs_write(uport, UARTDM_CR_ADDR, RESET_STALE_INT);
msm_hs_write(uport, UARTDM_DMRX_ADDR, UARTDM_RX_BUF_SIZE);
msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_ENABLE);
@@ -1204,6 +1189,19 @@
/* Calling next DMOV API. Hence mb() here. */
mb();
+ if (is_blsp_uart(msm_uport)) {
+ /*
+ * RX-transfer will be automatically re-activated
+ * after last data of previous transfer was read.
+ */
+ data = (RX_STALE_AUTO_RE_EN | RX_TRANS_AUTO_RE_ACTIVATE |
+ RX_DMRX_CYCLIC_EN);
+ msm_hs_write(uport, UARTDM_RX_TRANS_CTRL_ADDR, data);
+ /* Issue RX BAM Start IFC command */
+ msm_hs_write(uport, UARTDM_CR_ADDR, START_RX_BAM_IFC);
+ mb();
+ }
+
msm_uport->rx.flush = FLUSH_NONE;
if (is_blsp_uart(msm_uport)) {
@@ -1276,7 +1274,6 @@
{
int retval;
int rx_count;
- static int remaining_rx_count, bytes_pending;
unsigned long status;
unsigned long flags;
unsigned int error_f = 0;
@@ -1284,17 +1281,24 @@
struct msm_hs_port *msm_uport;
unsigned int flush;
struct tty_struct *tty;
+ struct sps_event_notify *notify;
+ struct msm_hs_rx *rx;
+ struct sps_pipe *sps_pipe_handle;
+ u32 sps_flags = SPS_IOVEC_FLAG_EOT;
msm_uport = container_of((struct tasklet_struct *)tlet_ptr,
struct msm_hs_port, rx.tlet);
uport = &msm_uport->uport;
tty = uport->state->port.tty;
+ notify = &msm_uport->notify;
+ rx = &msm_uport->rx;
status = msm_hs_read(uport, UARTDM_SR_ADDR);
spin_lock_irqsave(&uport->lock, flags);
- msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE);
+ if (!is_blsp_uart(msm_uport))
+ msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE);
/* overflow is not connect to data in a FIFO */
if (unlikely((status & UARTDM_SR_OVERRUN_BMSK) &&
@@ -1351,24 +1355,13 @@
if (flush >= FLUSH_DATA_INVALID)
goto out;
- rx_count = msm_hs_read(uport, UARTDM_RX_TOTAL_SNAP_ADDR);
-
if (is_blsp_uart(msm_uport)) {
- if (rx_count > UARTDM_RX_BUF_SIZE) {
- if (bytes_pending) {
- rx_count = remaining_rx_count;
- bytes_pending = 0;
- } else {
- remaining_rx_count = rx_count -
- UARTDM_RX_BUF_SIZE;
- if (remaining_rx_count)
- bytes_pending = 1;
- rx_count = UARTDM_RX_BUF_SIZE;
- }
- }
+ rx_count = msm_uport->rx_count_callback;
+ } else {
+ rx_count = msm_hs_read(uport, UARTDM_RX_TOTAL_SNAP_ADDR);
+ /* order the read of rx.buffer */
+ rmb();
}
- /* order the read of rx.buffer */
- rmb();
if (0 != (uport->read_status_mask & CREAD)) {
retval = tty_insert_flip_string(tty, msm_uport->rx.buffer,
@@ -1382,9 +1375,17 @@
/* order the read of rx.buffer and the start of next rx xfer */
wmb();
- if (!msm_uport->rx.buffer_pending)
- msm_hs_start_rx_locked(uport);
-
+ if (!msm_uport->rx.buffer_pending) {
+ if (is_blsp_uart(msm_uport)) {
+ msm_uport->rx.flush = FLUSH_NONE;
+ sps_pipe_handle = rx->prod.pipe_handle;
+ /* Queue transfer request to SPS */
+ sps_transfer_one(sps_pipe_handle, rx->rbuffer,
+ UARTDM_RX_BUF_SIZE, msm_uport, sps_flags);
+ } else {
+ msm_hs_start_rx_locked(uport);
+ }
+ }
out:
if (msm_uport->rx.buffer_pending) {
if (hs_serial_debug_mask)
@@ -1502,7 +1503,10 @@
struct msm_hs_port *msm_uport =
(struct msm_hs_port *)
((struct sps_event_notify *)notify)->user;
+ struct uart_port *uport;
+ unsigned long flags;
+ uport = &(msm_uport->uport);
msm_uport->notify = *notify;
pr_debug("%s: sps ev_id=%d, addr=0x%x, size=0x%x, flags=0x%x\n",
__func__, notify->event_id,
@@ -1510,8 +1514,12 @@
notify->data.transfer.iovec.size,
notify->data.transfer.iovec.flags);
- if (msm_uport->rx.flush == FLUSH_NONE)
+ if (msm_uport->rx.flush == FLUSH_NONE) {
+ spin_lock_irqsave(&uport->lock, flags);
+ msm_uport->rx_count_callback = notify->data.transfer.iovec.size;
+ spin_unlock_irqrestore(&uport->lock, flags);
tasklet_schedule(&msm_uport->rx.tlet);
+ }
}
/*
@@ -1691,6 +1699,8 @@
int ret;
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
struct circ_buf *tx_buf = &uport->state->xmit;
+ struct msm_hs_rx *rx = &msm_uport->rx;
+ struct sps_pipe *sps_pipe_handle = rx->prod.pipe_handle;
mutex_lock(&msm_uport->clk_mutex);
spin_lock_irqsave(&uport->lock, flags);
@@ -1717,26 +1727,26 @@
switch (msm_uport->clk_req_off_state) {
case CLK_REQ_OFF_START:
msm_uport->clk_req_off_state = CLK_REQ_OFF_RXSTALE_ISSUED;
- if (is_blsp_uart(msm_uport)) {
- /* Stale interrupt when RX-FIFO is empty
- * will fire if STALE_IRQ_EMPTY bit is set
- * for UART Core v1.4
- */
- msm_hs_write(uport, UARTDM_BCR_ADDR,
- UARTDM_BCR_STALE_IRQ_EMPTY);
+
+ if (!is_blsp_uart(msm_uport)) {
+ msm_hs_write(uport, UARTDM_CR_ADDR, FORCE_STALE_EVENT);
+ /*
+ * Before returning make sure that device writel
+ * completed. Hence mb() requires here.
+ */
+ mb();
}
- msm_hs_write(uport, UARTDM_CR_ADDR, FORCE_STALE_EVENT);
- /*
- * Before returning make sure that device writel completed.
- * Hence mb() requires here.
- */
- mb();
spin_unlock_irqrestore(&uport->lock, flags);
mutex_unlock(&msm_uport->clk_mutex);
return 0; /* RXSTALE flush not complete - retry */
case CLK_REQ_OFF_RXSTALE_ISSUED:
case CLK_REQ_OFF_FLUSH_ISSUED:
spin_unlock_irqrestore(&uport->lock, flags);
+ if (is_blsp_uart(msm_uport)) {
+ msm_uport->clk_req_off_state =
+ CLK_REQ_OFF_RXSTALE_FLUSHED;
+ sps_disconnect(sps_pipe_handle);
+ }
mutex_unlock(&msm_uport->clk_mutex);
return 0; /* RXSTALE flush not complete - retry */
case CLK_REQ_OFF_RXSTALE_FLUSHED:
@@ -1846,24 +1856,13 @@
mb();
if (msm_uport->clk_req_off_state ==
- CLK_REQ_OFF_RXSTALE_ISSUED) {
+ CLK_REQ_OFF_RXSTALE_ISSUED)
msm_uport->clk_req_off_state =
- CLK_REQ_OFF_FLUSH_ISSUED;
+ CLK_REQ_OFF_FLUSH_ISSUED;
- if (is_blsp_uart(msm_uport)) {
- /* Reset BCR Register for UARTDM Core v14*/
- msm_hs_write(uport, UARTDM_BCR_ADDR, 0x0);
- }
- }
-
- if (rx->flush == FLUSH_NONE) {
+ if (!is_blsp_uart(msm_uport) && (rx->flush == FLUSH_NONE)) {
rx->flush = FLUSH_DATA_READY;
- if (is_blsp_uart(msm_uport)) {
- queue_work(msm_uport->hsuart_wq,
- &msm_uport->reset_bam_rx);
- } else {
- msm_dmov_flush(msm_uport->dma_rx_channel, 1);
- }
+ msm_dmov_flush(msm_uport->dma_rx_channel, 1);
}
}
/* tx ready interrupt */
@@ -1993,8 +1992,14 @@
mb();
}
hrtimer_try_to_cancel(&msm_uport->clk_off_timer);
- if (msm_uport->rx.flush == FLUSH_SHUTDOWN)
+ if (msm_uport->rx.flush == FLUSH_SHUTDOWN) {
+ if (is_blsp_uart(msm_uport)) {
+ spin_unlock_irqrestore(&uport->lock, flags);
+ msm_hs_spsconnect_rx(uport);
+ spin_lock_irqsave(&uport->lock, flags);
+ }
msm_hs_start_rx_locked(uport);
+ }
if (msm_uport->rx.flush == FLUSH_STOP)
msm_uport->rx.flush = FLUSH_IGNORE;
msm_uport->clk_state = MSM_HS_CLK_ON;
@@ -2265,9 +2270,10 @@
tx->command_ptr->dst_row_addr =
msm_uport->uport.mapbase + UARTDM_TF_ADDR;
+
+ msm_uport->imr_reg |= UARTDM_ISR_RXSTALE_BMSK;
}
- msm_uport->imr_reg |= UARTDM_ISR_RXSTALE_BMSK;
/* Enable reading the current CTS, no harm even if CTS is ignored */
msm_uport->imr_reg |= UARTDM_ISR_CURRENT_CTS_BMSK;
@@ -2378,7 +2384,10 @@
}
/* Set up Uart Receive */
- msm_hs_write(uport, UARTDM_RFWR_ADDR, 0);
+ if (is_blsp_uart(msm_uport))
+ msm_hs_write(uport, UARTDM_RFWR_ADDR, 32);
+ else
+ msm_hs_write(uport, UARTDM_RFWR_ADDR, 0);
INIT_DELAYED_WORK(&rx->flip_insert_work, flip_insert_work);
@@ -2975,9 +2984,6 @@
INIT_WORK(&msm_uport->clock_off_w, hsuart_clock_off_work);
- /* Init work for Reset Rx bam endpoints */
- INIT_WORK(&msm_uport->reset_bam_rx, hsuart_reset_bam_rx_work);
-
/* Init work for sps_disconnect in stop_rx_locked */
INIT_WORK(&msm_uport->disconnect_rx_endpoint,
hsuart_disconnect_rx_endpoint_work);
diff --git a/drivers/tty/serial/msm_serial_hs_hwreg.h b/drivers/tty/serial/msm_serial_hs_hwreg.h
index 9fa4f55..cdd0450 100644
--- a/drivers/tty/serial/msm_serial_hs_hwreg.h
+++ b/drivers/tty/serial/msm_serial_hs_hwreg.h
@@ -68,6 +68,14 @@
*/
#define UARTDM_BCR_STALE_IRQ_EMPTY 0x2
+/* TRANSFER_CONTROL Register for UARTDM Core v1.4 */
+#define UARTDM_RX_TRANS_CTRL_ADDR 0xcc
+
+/* TRANSFER_CONTROL Register bits */
+#define RX_STALE_AUTO_RE_EN 0x1
+#define RX_TRANS_AUTO_RE_ACTIVATE 0x2
+#define RX_DMRX_CYCLIC_EN 0x4
+
/* write only register */
#define UARTDM_CSR_115200 0xFF
#define UARTDM_CSR_57600 0xEE
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 265a685..f9a26cf 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -541,8 +541,7 @@
else
dwc->maximum_speed = DWC3_DCFG_SUPERSPEED;
- if (of_get_property(node, "tx-fifo-resize", NULL))
- dwc->needs_fifo_resize = true;
+ dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
pm_runtime_no_callbacks(dev);
pm_runtime_set_active(dev);
@@ -667,11 +666,22 @@
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id of_dwc3_match[] = {
+ {
+ .compatible = "synopsys,dwc3"
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_dwc3_match);
+#endif
+
static struct platform_driver dwc3_driver = {
.probe = dwc3_probe,
.remove = __devexit_p(dwc3_remove),
.driver = {
.name = "dwc3",
+ .of_match_table = of_match_ptr(of_dwc3_match),
},
};
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index 282f49e..daf9a26 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -494,6 +494,9 @@
power_supply_set_supply_type(dotg->psy, power_supply_type);
+ if ((dotg->charger->chg_type == DWC3_CDP_CHARGER) && mA > 2)
+ mA = DWC3_IDEV_CHG_MAX;
+
if (dotg->charger->max_power == mA)
return 0;
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index 88f8be5..590723a 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -132,7 +132,7 @@
default n
config FB_MSM_OVERLAY
- depends on FB_MSM_MDP40 && ANDROID_PMEM
+ depends on FB_MSM_MDP40
bool "MDP4 overlay support"
default n
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index e50055f..4dd4245 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -29,7 +29,6 @@
#include <linux/fb.h>
#include <linux/msm_mdp.h>
#include <linux/file.h>
-#include <linux/android_pmem.h>
#include <linux/major.h>
#include <asm/system.h>
#include <asm/mach-types.h>
@@ -3109,9 +3108,6 @@
{
struct file *file;
int put_needed, ret = 0, fb_num;
-#ifdef CONFIG_ANDROID_PMEM
- unsigned long vstart;
-#endif
*p_need = 0;
if (img->flags & MDP_BLIT_SRC_GEM) {
@@ -3146,13 +3142,6 @@
return mdp4_overlay_iommu_map_buf(img->memory_id, pipe, plane,
start, len, srcp_ihdl);
#endif
-#ifdef CONFIG_ANDROID_PMEM
- if (!get_pmem_file(img->memory_id, start, &vstart,
- len, srcp_file))
- return 0;
- else
- return -EINVAL;
-#endif
}
#ifdef CONFIG_FB_MSM_MIPI_DSI
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
index 415b575..2e795fd 100644
--- a/drivers/video/msm/mdp_ppp.c
+++ b/drivers/video/msm/mdp_ppp.c
@@ -22,7 +22,6 @@
#include <linux/fb.h>
#include <linux/msm_mdp.h>
#include <linux/file.h>
-#include <linux/android_pmem.h>
#include <linux/major.h>
#include "linux/proc_fs.h"
@@ -548,40 +547,8 @@
format == MDP_Y_CRCB_H2V2) ? 2 : (format == MDP_Y_CBCR_H2V1 || \
format == MDP_Y_CRCB_H2V1) ? 1 : 1)
-#ifdef CONFIG_ANDROID_PMEM
-static void get_len(struct mdp_img *img, struct mdp_rect *rect, uint32_t bpp,
- uint32_t *len0, uint32_t *len1)
-{
- *len0 = IMG_LEN(rect->h, img->width, rect->w, bpp);
- if (IS_PSEUDOPLNR(img->format))
- *len1 = *len0/Y_TO_CRCB_RATIO(img->format);
- else
- *len1 = 0;
-}
-
-static void flush_imgs(struct mdp_blit_req *req, int src_bpp, int dst_bpp,
- struct file *p_src_file, struct file *p_dst_file)
-{
- uint32_t src0_len, src1_len;
-
- if (!(req->flags & MDP_BLIT_NON_CACHED)) {
- /* flush src images to memory before dma to mdp */
- get_len(&req->src, &req->src_rect, src_bpp,
- &src0_len, &src1_len);
-
- flush_pmem_file(p_src_file,
- req->src.offset, src0_len);
-
- if (IS_PSEUDOPLNR(req->src.format))
- flush_pmem_file(p_src_file,
- req->src.offset + src0_len, src1_len);
- }
-
-}
-#else
static void flush_imgs(struct mdp_blit_req *req, int src_bpp, int dst_bpp,
struct file *p_src_file, struct file *p_dst_file) { }
-#endif
static void mdp_start_ppp(struct msm_fb_data_type *mfd, MDPIBUF *iBuf,
struct mdp_blit_req *req, struct file *p_src_file, struct file *p_dst_file)
@@ -1286,9 +1253,6 @@
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
#endif
-#ifdef CONFIG_ANDROID_PMEM
- unsigned long vstart;
-#endif
if (req->flags & MDP_MEMORY_ID_TYPE_FB) {
file = fget_light(img->memory_id, &put_needed);
@@ -1321,21 +1285,10 @@
return -EINVAL;
#endif
-#ifdef CONFIG_ANDROID_PMEM
- if (!get_pmem_file(img->memory_id, start, &vstart, len, srcp_file))
- return ret;
- else
- return -EINVAL;
-#endif
}
void put_img(struct file *p_src_file, struct ion_handle *p_ihdl)
{
-#ifdef CONFIG_ANDROID_PMEM
- if (p_src_file)
- put_pmem_file(p_src_file);
-#endif
-
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
if (!IS_ERR_OR_NULL(p_ihdl))
ion_free(ppp_display_iclient, p_ihdl);
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 8ceb62e..207fbf3 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -60,6 +60,7 @@
u32 mdp_rev;
struct clk *mdp_clk[MDSS_MAX_CLK];
struct regulator *fs;
+ u32 max_mdp_clk_rate;
struct workqueue_struct *clk_ctrl_wq;
struct work_struct clk_ctrl_worker;
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index 4a06be5..b365f36 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -252,7 +252,7 @@
struct dsi_panel_cmds_list {
struct dsi_cmd_desc *buf;
- char size;
+ u32 size;
char ctrl_state;
};
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 94261cc..4e74858 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -16,7 +16,6 @@
#define pr_fmt(fmt) "%s: " fmt, __func__
-#include <linux/android_pmem.h>
#include <linux/bootmem.h>
#include <linux/console.h>
#include <linux/debugfs.h>
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index f9b05fc..a8eeec6 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -522,11 +522,15 @@
void mdss_mdp_set_clk_rate(unsigned long min_clk_rate)
{
+ struct mdss_data_type *mdata = mdss_res;
unsigned long clk_rate;
struct clk *clk = mdss_mdp_get_clk(MDSS_CLK_MDP_SRC);
if (clk) {
mutex_lock(&mdp_clk_lock);
- clk_rate = clk_round_rate(clk, min_clk_rate);
+ if (min_clk_rate < mdata->max_mdp_clk_rate)
+ clk_rate = clk_round_rate(clk, min_clk_rate);
+ else
+ clk_rate = mdata->max_mdp_clk_rate;
if (IS_ERR_VALUE(clk_rate)) {
pr_err("unable to round rate err=%ld\n", clk_rate);
} else if (clk_rate != clk_get_rate(clk)) {
@@ -637,6 +641,15 @@
{
int ret;
+ ret = of_property_read_u32(mdata->pdev->dev.of_node,
+ "qcom,max-clk-rate", &mdata->max_mdp_clk_rate);
+ if (ret) {
+ pr_err("failed to get max mdp clock rate\n");
+ return ret;
+ }
+
+ pr_debug("max mdp clk rate=%d\n", mdata->max_mdp_clk_rate);
+
ret = devm_request_irq(&mdata->pdev->dev, mdata->irq, mdss_irq_handler,
IRQF_DISABLED, "MDSS", mdata);
if (ret) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 911e29f..1c0d306 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -12,7 +12,6 @@
*/
#define pr_fmt(fmt) "%s: " fmt, __func__
-#include <linux/android_pmem.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/file.h>
@@ -310,7 +309,6 @@
data->srcp_file = NULL;
} else if (data->srcp_file) {
pr_debug("pmem buf=0x%x\n", data->addr);
- put_pmem_file(data->srcp_file);
data->srcp_file = NULL;
} else if (!IS_ERR_OR_NULL(data->srcp_ihdl)) {
pr_debug("ion hdl=%p buf=0x%x\n", data->srcp_ihdl, data->addr);
@@ -414,10 +412,6 @@
pr_err("failed to map ion handle (%d)\n", ret);
return ret;
}
- } else {
- unsigned long vstart;
- ret = get_pmem_file(img->memory_id, start, &vstart, len,
- &data->srcp_file);
}
if (!ret && (img->offset < data->len)) {
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 258034b..797d4a3 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -38,7 +38,6 @@
#include <linux/vmalloc.h>
#include <linux/debugfs.h>
#include <linux/console.h>
-#include <linux/android_pmem.h>
#include <linux/leds.h>
#include <linux/pm_runtime.h>
#include <linux/sync.h>
@@ -1747,9 +1746,12 @@
mutex_lock(&mfd->sync_mutex);
if (mfd->is_committing) {
mutex_unlock(&mfd->sync_mutex);
- ret = wait_for_completion_timeout(&mfd->commit_comp,
+ ret = wait_for_completion_interruptible_timeout(
+ &mfd->commit_comp,
msecs_to_jiffies(WAIT_FENCE_TIMEOUT));
if (ret <= 0)
+ ret = -ERESTARTSYS;
+ else if (!ret)
pr_err("%s wait for commit_comp timeout %d %d",
__func__, ret, mfd->is_committing);
} else {
diff --git a/drivers/video/msm/msm_fb_def.h b/drivers/video/msm/msm_fb_def.h
index dcd648b..34cf427 100644
--- a/drivers/video/msm/msm_fb_def.h
+++ b/drivers/video/msm/msm_fb_def.h
@@ -34,7 +34,6 @@
#include <linux/vmalloc.h>
#include <linux/debugfs.h>
#include <linux/console.h>
-#include <linux/android_pmem.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 6484a3f..235248c 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -125,6 +125,7 @@
* using devfreq.
* @profile: device-specific devfreq profile
* @governor: method how to choose frequency based on the usage.
+ * @governor_name: devfreq governor name for use with this devfreq
* @nb: notifier block used to notify devfreq object that it should
* reevaluate operable frequencies. Devfreq users may use
* devfreq.nb to the corresponding register notifier call chain.
@@ -155,6 +156,7 @@
struct device dev;
struct devfreq_dev_profile *profile;
const struct devfreq_governor *governor;
+ char governor_name[DEVFREQ_NAME_LEN];
struct notifier_block nb;
struct delayed_work work;
@@ -176,7 +178,7 @@
#if defined(CONFIG_PM_DEVFREQ)
extern struct devfreq *devfreq_add_device(struct device *dev,
struct devfreq_dev_profile *profile,
- const struct devfreq_governor *governor,
+ const char *governor_name,
void *data);
extern int devfreq_remove_device(struct devfreq *devfreq);
extern int devfreq_suspend_device(struct devfreq *devfreq);
@@ -190,17 +192,7 @@
extern int devfreq_unregister_opp_notifier(struct device *dev,
struct devfreq *devfreq);
-#ifdef CONFIG_DEVFREQ_GOV_POWERSAVE
-extern const struct devfreq_governor devfreq_powersave;
-#endif
-#ifdef CONFIG_DEVFREQ_GOV_PERFORMANCE
-extern const struct devfreq_governor devfreq_performance;
-#endif
-#ifdef CONFIG_DEVFREQ_GOV_USERSPACE
-extern const struct devfreq_governor devfreq_userspace;
-#endif
#ifdef CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND
-extern const struct devfreq_governor devfreq_simple_ondemand;
/**
* struct devfreq_simple_ondemand_data - void *data fed to struct devfreq
* and devfreq_add_device
@@ -223,7 +215,7 @@
#else /* !CONFIG_PM_DEVFREQ */
static struct devfreq *devfreq_add_device(struct device *dev,
struct devfreq_dev_profile *profile,
- struct devfreq_governor *governor,
+ const char *governor_name,
void *data)
{
return NULL;
@@ -262,11 +254,6 @@
return -EINVAL;
}
-#define devfreq_powersave NULL
-#define devfreq_performance NULL
-#define devfreq_userspace NULL
-#define devfreq_simple_ondemand NULL
-
#endif /* CONFIG_PM_DEVFREQ */
#endif /* __LINUX_DEVFREQ_H__ */
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index a2b59d7..1ca1b83 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1074,6 +1074,90 @@
#define WLAN_HT_SMPS_CONTROL_STATIC 1
#define WLAN_HT_SMPS_CONTROL_DYNAMIC 3
+/**
+ * struct ieee80211_vht_mcs_info - VHT MCS information
+ * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams
+ * @rx_highest: Indicates highest long GI VHT PPDU data rate
+ * STA can receive. Rate expressed in units of 1 Mbps.
+ * If this field is 0 this value should not be used to
+ * consider the highest RX data rate supported.
+ * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams
+ * @tx_highest: Indicates highest long GI VHT PPDU data rate
+ * STA can transmit. Rate expressed in units of 1 Mbps.
+ * If this field is 0 this value should not be used to
+ * consider the highest TX data rate supported.
+ */
+struct ieee80211_vht_mcs_info {
+ __le16 rx_mcs_map;
+ __le16 rx_highest;
+ __le16 tx_mcs_map;
+ __le16 tx_highest;
+} __packed;
+
+/**
+ * struct ieee80211_vht_cap - VHT capabilities
+ *
+ * This structure is the "VHT capabilities element" as
+ * described in 802.11ac D3.0 8.4.2.160
+ * @vht_cap_info: VHT capability info
+ * @supp_mcs: VHT MCS supported rates
+ */
+struct ieee80211_vht_cap {
+ __le32 vht_cap_info;
+ struct ieee80211_vht_mcs_info supp_mcs;
+} __packed;
+
+/**
+ * struct ieee80211_vht_operation - VHT operation IE
+ *
+ * This structure is the "VHT operation element" as
+ * described in 802.11ac D3.0 8.4.2.161
+ * @chan_width: Operating channel width
+ * @center_freq_seg1_idx: center freq segment 1 index
+ * @center_freq_seg2_idx: center freq segment 2 index
+ * @basic_mcs_set: VHT Basic MCS rate set
+ */
+struct ieee80211_vht_operation {
+ u8 chan_width;
+ u8 center_freq_seg1_idx;
+ u8 center_freq_seg2_idx;
+ __le16 basic_mcs_set;
+} __packed;
+
+
+#define IEEE80211_VHT_MCS_ZERO_TO_SEVEN_SUPPORT 0
+#define IEEE80211_VHT_MCS_ZERO_TO_EIGHT_SUPPORT 1
+#define IEEE80211_VHT_MCS_ZERO_TO_NINE_SUPPORT 2
+#define IEEE80211_VHT_MCS_NOT_SUPPORTED 3
+
+/* 802.11ac VHT Capabilities */
+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x00000000
+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 0x00000001
+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 0x00000002
+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ 0x00000004
+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ 0x00000008
+#define IEEE80211_VHT_CAP_RXLDPC 0x00000010
+#define IEEE80211_VHT_CAP_SHORT_GI_80 0x00000020
+#define IEEE80211_VHT_CAP_SHORT_GI_160 0x00000040
+#define IEEE80211_VHT_CAP_TXSTBC 0x00000080
+#define IEEE80211_VHT_CAP_RXSTBC_1 0x00000100
+#define IEEE80211_VHT_CAP_RXSTBC_2 0x00000200
+#define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300
+#define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400
+#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800
+#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000
+#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000
+#define IEEE80211_VHT_CAP_SOUNDING_DIMENTION_MAX 0x00030000
+#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000
+#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000
+#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000
+#define IEEE80211_VHT_CAP_HTC_VHT 0x00400000
+#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT 0x00800000
+#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB 0x08000000
+#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB 0x0c000000
+#define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN 0x10000000
+#define IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN 0x20000000
+
/* Authentication algorithms */
#define WLAN_AUTH_OPEN 0
#define WLAN_AUTH_SHARED_KEY 1
@@ -1334,6 +1418,9 @@
WLAN_EID_DSE_REGISTERED_LOCATION = 58,
WLAN_EID_SUPPORTED_REGULATORY_CLASSES = 59,
WLAN_EID_EXT_CHANSWITCH_ANN = 60,
+
+ WLAN_EID_VHT_CAPABILITY = 191,
+ WLAN_EID_VHT_OPERATION = 192,
};
/* Action category code */
diff --git a/include/linux/msm_ipa.h b/include/linux/msm_ipa.h
index b377a6c..5151654 100644
--- a/include/linux/msm_ipa.h
+++ b/include/linux/msm_ipa.h
@@ -173,6 +173,7 @@
WLAN_AP_DISCONNECT,
WLAN_STA_CONNECT,
WLAN_STA_DISCONNECT,
+ IPA_EVENT_MAX
};
/**
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index ce5ddf3..bde9078 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1783,6 +1783,9 @@
* @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
* @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
* @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
+ * @NL80211_BAND_ATTR_VHT_MCS_SET: 32-byte attribute containing the MCS set as
+ * defined in 802.11ac
+ * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE
* @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
* @__NL80211_BAND_ATTR_AFTER_LAST: internal use
*/
@@ -1796,6 +1799,9 @@
NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
+ NL80211_BAND_ATTR_VHT_MCS_SET,
+ NL80211_BAND_ATTR_VHT_CAPA,
+
/* keep last */
__NL80211_BAND_ATTR_AFTER_LAST,
NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index dcdfc2b..6071e91 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -32,7 +32,7 @@
struct page **pages;
unsigned int nr_pages;
phys_addr_t phys_addr;
- void *caller;
+ const void *caller;
};
/*
@@ -62,7 +62,7 @@
extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot);
extern void *__vmalloc_node_range(unsigned long size, unsigned long align,
unsigned long start, unsigned long end, gfp_t gfp_mask,
- pgprot_t prot, int node, void *caller);
+ pgprot_t prot, int node, const void *caller);
extern void vfree(const void *addr);
extern void *vmap(struct page **pages, unsigned int count,
@@ -85,14 +85,15 @@
extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags);
extern struct vm_struct *get_vm_area_caller(unsigned long size,
- unsigned long flags, void *caller);
+ unsigned long flags, const void *caller);
extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
unsigned long start, unsigned long end);
extern struct vm_struct *__get_vm_area_caller(unsigned long size,
unsigned long flags,
unsigned long start, unsigned long end,
- void *caller);
+ const void *caller);
extern struct vm_struct *remove_vm_area(const void *addr);
+extern struct vm_struct *find_vm_area(const void *addr);
extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
struct page ***pages);
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index 34b3139..7f70a01 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -9,6 +9,8 @@
#define ISP_VERSION_40 40
#define ISP_VERSION_32 32
#define ISP_NATIVE_BUF_BIT 0x10000
+#define ISP0_BIT 0x20000
+#define ISP1_BIT 0x40000
#define ISP_STATS_STREAM_BIT 0x80000000
enum ISP_START_PIXEL_PATTERN {
@@ -115,7 +117,7 @@
uint32_t output_stride;
uint32_t output_scan_lines;
uint32_t output_plane_format; /*Y/Cb/Cr/CbCr*/
-
+ uint32_t plane_addr_offset;
uint8_t csid_src; /*RDI 0-2*/
uint8_t rdi_cid;/*CID 1-16*/
};
@@ -192,6 +194,7 @@
enum msm_isp_stats_type stats_type;
uint32_t framedrop_pattern;
uint32_t irq_subsample_pattern;
+ uint32_t buffer_offset;
uint32_t stream_handle;
uint8_t comp_flag;
};
@@ -259,11 +262,18 @@
enum msm_vfe_reg_cfg_type cmd_type;
};
+enum msm_isp_buf_type {
+ ISP_PRIVATE_BUF,
+ ISP_SHARE_BUF,
+ MAX_ISP_BUF_TYPE,
+};
+
struct msm_isp_buf_request {
uint32_t session_id;
uint32_t stream_id;
uint8_t num_buf;
uint32_t handle;
+ enum msm_isp_buf_type buf_type;
};
struct msm_isp_qbuf_info {
diff --git a/include/media/msmb_ispif.h b/include/media/msmb_ispif.h
index fc27ef6..3546004 100644
--- a/include/media/msmb_ispif.h
+++ b/include/media/msmb_ispif.h
@@ -76,6 +76,17 @@
struct msm_ispif_params_entry entries[INTF_MAX];
};
+struct msm_isp_info {
+ uint32_t max_resolution;
+ uint32_t id;
+ uint32_t ver;
+};
+
+struct msm_ispif_vfe_info {
+ int num_vfe;
+ struct msm_isp_info info[VFE_MAX];
+};
+
enum ispif_cfg_type_t {
ISPIF_CLK_ENABLE,
ISPIF_CLK_DISABLE,
@@ -86,6 +97,7 @@
ISPIF_STOP_IMMEDIATELY,
ISPIF_RELEASE,
ISPIF_ENABLE_REG_DUMP,
+ ISPIF_SET_VFE_INFO,
};
struct ispif_cfg_data {
@@ -93,6 +105,7 @@
union {
int reg_dump; /* ISPIF_ENABLE_REG_DUMP */
uint32_t csid_version; /* ISPIF_INIT */
+ struct msm_ispif_vfe_info vfe_info; /* ISPIF_SET_VFE_INFO */
struct msm_ispif_param_data params; /* CFG, START, STOP */
};
};
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1645608..275dc10 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -211,6 +211,22 @@
};
/**
+ * struct ieee80211_sta_vht_cap - STA's VHT capabilities
+ *
+ * This structure describes most essential parameters needed
+ * to describe 802.11ac VHT capabilities for an STA.
+ *
+ * @vht_supported: is VHT supported by the STA
+ * @cap: VHT capabilities map as described in 802.11ac spec
+ * @vht_mcs: Supported VHT MCS rates
+ */
+struct ieee80211_sta_vht_cap {
+ bool vht_supported;
+ u32 cap; /* use IEEE80211_VHT_CAP_ */
+ struct ieee80211_vht_mcs_info vht_mcs;
+};
+
+/**
* struct ieee80211_supported_band - frequency band definition
*
* This structure describes a frequency band a wiphy
@@ -233,6 +249,7 @@
int n_channels;
int n_bitrates;
struct ieee80211_sta_ht_cap ht_cap;
+ struct ieee80211_sta_vht_cap vht_cap;
};
/*
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 07a3858..5065adb 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1280,7 +1280,7 @@
struct vm_struct *vmlist;
static void setup_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va,
- unsigned long flags, void *caller)
+ unsigned long flags, const void *caller)
{
vm->flags = flags;
vm->addr = (void *)va->va_start;
@@ -1306,7 +1306,7 @@
}
static void insert_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va,
- unsigned long flags, void *caller)
+ unsigned long flags, const void *caller)
{
setup_vmalloc_vm(vm, va, flags, caller);
insert_vmalloc_vmlist(vm);
@@ -1314,7 +1314,7 @@
static struct vm_struct *__get_vm_area_node(unsigned long size,
unsigned long align, unsigned long flags, unsigned long start,
- unsigned long end, int node, gfp_t gfp_mask, void *caller)
+ unsigned long end, int node, gfp_t gfp_mask, const void *caller)
{
struct vmap_area *va;
struct vm_struct *area;
@@ -1375,7 +1375,7 @@
struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags,
unsigned long start, unsigned long end,
- void *caller)
+ const void *caller)
{
return __get_vm_area_node(size, 1, flags, start, end, -1, GFP_KERNEL,
caller);
@@ -1397,13 +1397,21 @@
}
struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags,
- void *caller)
+ const void *caller)
{
return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
-1, GFP_KERNEL, caller);
}
-static struct vm_struct *find_vm_area(const void *addr)
+/**
+ * find_vm_area - find a continuous kernel virtual area
+ * @addr: base address
+ *
+ * Search for the kernel VM area starting at @addr, and return it.
+ * It is up to the caller to do all required locking to keep the returned
+ * pointer valid.
+ */
+struct vm_struct *find_vm_area(const void *addr)
{
struct vmap_area *va;
@@ -1568,9 +1576,9 @@
static void *__vmalloc_node(unsigned long size, unsigned long align,
gfp_t gfp_mask, pgprot_t prot,
- int node, void *caller);
+ int node, const void *caller);
static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
- pgprot_t prot, int node, void *caller)
+ pgprot_t prot, int node, const void *caller)
{
const int order = 0;
struct page **pages;
@@ -1643,7 +1651,7 @@
*/
void *__vmalloc_node_range(unsigned long size, unsigned long align,
unsigned long start, unsigned long end, gfp_t gfp_mask,
- pgprot_t prot, int node, void *caller)
+ pgprot_t prot, int node, const void *caller)
{
struct vm_struct *area;
void *addr;
@@ -1704,7 +1712,7 @@
*/
static void *__vmalloc_node(unsigned long size, unsigned long align,
gfp_t gfp_mask, pgprot_t prot,
- int node, void *caller)
+ int node, const void *caller)
{
return __vmalloc_node_range(size, align, VMALLOC_START, VMALLOC_END,
gfp_mask, prot, node, caller);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index db8fae5..96d1d5d 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -378,6 +378,7 @@
IEEE80211_STA_UAPSD_ENABLED = BIT(7),
IEEE80211_STA_NULLFUNC_ACKED = BIT(8),
IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9),
+ IEEE80211_STA_DISABLE_VHT = BIT(11),
};
struct ieee80211_mgd_auth_data {
@@ -1474,6 +1475,8 @@
struct ieee80211_sta_ht_cap *ht_cap,
struct ieee80211_channel *channel,
enum nl80211_channel_type channel_type);
+u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
+ u32 cap);
/* internal work items */
void ieee80211_work_init(struct ieee80211_local *local);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 1633648..018e3fb 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -673,7 +673,7 @@
int result, i;
enum ieee80211_band band;
int channels, max_bitrates;
- bool supp_ht;
+ bool supp_ht, supp_vht;
static const u32 cipher_suites[] = {
/* keep WEP first, it may be removed below */
WLAN_CIPHER_SUITE_WEP40,
@@ -706,6 +706,7 @@
channels = 0;
max_bitrates = 0;
supp_ht = false;
+ supp_vht = false;
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
struct ieee80211_supported_band *sband;
@@ -723,6 +724,7 @@
if (max_bitrates < sband->n_bitrates)
max_bitrates = sband->n_bitrates;
supp_ht = supp_ht || sband->ht_cap.ht_supported;
+ supp_vht = supp_vht || sband->vht_cap.vht_supported;
}
local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) +
@@ -798,6 +800,10 @@
if (supp_ht)
local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
+ if (supp_vht)
+ local->scan_ies_len +=
+ 2 + sizeof(struct ieee80211_vht_cap);
+
if (!local->ops->hw_scan) {
/* For hw_scan, driver needs to set these up. */
local->hw.wiphy->max_scan_ssids = 4;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 20c680b..a48a35c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -383,6 +383,26 @@
ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
}
+static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb,
+ struct ieee80211_supported_band *sband)
+{
+ u8 *pos;
+ u32 cap;
+ struct ieee80211_sta_vht_cap vht_cap;
+
+ BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap));
+
+ memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));
+
+ /* determine capability flags */
+ cap = vht_cap.cap;
+
+ /* reserve and fill IE */
+ pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
+ ieee80211_ie_build_vht_cap(pos, &vht_cap, cap);
+}
+
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
@@ -428,6 +448,7 @@
4 + /* power capability */
2 + 2 * sband->n_channels + /* supported channels */
2 + sizeof(struct ieee80211_ht_cap) + /* HT */
+ 2 + sizeof(struct ieee80211_vht_cap) + /* VHT */
assoc_data->ie_len + /* extra IEs */
9, /* WMM */
GFP_KERNEL);
@@ -560,6 +581,9 @@
ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie,
sband, local->oper_channel, ifmgd->ap_smps);
+ if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
+ ieee80211_add_vht_ie(sdata, skb, sband);
+
/* if present, add any custom non-vendor IEs that go after HT */
if (assoc_data->ie_len && assoc_data->ie) {
noffset = ieee80211_ie_split_vendor(assoc_data->ie,
@@ -3289,6 +3313,7 @@
ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
+ ifmgd->flags &= ~IEEE80211_STA_DISABLE_VHT;
ifmgd->beacon_crc_valid = false;
@@ -3299,14 +3324,21 @@
* We can set this to true for non-11n hardware, that'll be checked
* separately along with the peer capabilities.
*/
- for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
+ for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) {
if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
- req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
+ req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) {
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+ ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
+ netdev_info(sdata->dev,
+ "disabling HT/VHT due to WEP/TKIP use\n");
+ }
+ }
- if (req->flags & ASSOC_REQ_DISABLE_HT)
+ if (req->flags & ASSOC_REQ_DISABLE_HT) {
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+ ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
+ }
/* Also disable HT if we don't support it or the AP doesn't use WMM */
sband = local->hw.wiphy->bands[req->bss->channel->band];
@@ -3314,6 +3346,14 @@
local->hw.queues < 4 || !bss->wmm_used)
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+ /* disable VHT if we don't support it or the AP doesn't use WMM */
+ if (!sband->vht_cap.vht_supported ||
+ local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) {
+ ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
+ netdev_info(sdata->dev,
+ "disabling VHT as WMM/QoS is not supported\n");
+ }
+
memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask,
sizeof(ifmgd->ht_capa_mask));
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 32f7a3b..8ee7267 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1031,6 +1031,10 @@
pos += noffset - offset;
}
+ if (sband->vht_cap.vht_supported)
+ pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap,
+ sband->vht_cap.cap);
+
return pos - buffer;
}
@@ -1611,6 +1615,27 @@
return pos;
}
+u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
+ u32 cap)
+{
+ __le32 tmp;
+
+ *pos++ = WLAN_EID_VHT_CAPABILITY;
+ *pos++ = sizeof(struct ieee80211_vht_cap);
+ memset(pos, 0, sizeof(struct ieee80211_vht_cap));
+
+ /* capability flags */
+ tmp = cpu_to_le32(cap);
+ memcpy(pos, &tmp, sizeof(u32));
+ pos += sizeof(u32);
+
+ /* VHT MCS set */
+ memcpy(pos, &vht_cap->vht_mcs, sizeof(vht_cap->vht_mcs));
+ pos += sizeof(vht_cap->vht_mcs);
+
+ return pos;
+}
+
u8 *ieee80211_ie_build_ht_info(u8 *pos,
struct ieee80211_sta_ht_cap *ht_cap,
struct ieee80211_channel *channel,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 68a6b17..d82b7e3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -811,6 +811,15 @@
dev->wiphy.bands[band]->ht_cap.ampdu_density);
}
+ /* add VHT info */
+ if (dev->wiphy.bands[band]->vht_cap.vht_supported &&
+ (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
+ sizeof(dev->wiphy.bands[band]->vht_cap.vht_mcs),
+ &dev->wiphy.bands[band]->vht_cap.vht_mcs) ||
+ nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
+ dev->wiphy.bands[band]->vht_cap.cap)))
+ goto nla_put_failure;
+
/* add frequencies */
nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
if (!nl_freqs)
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index fb77c8d..cafc5c3 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -41,8 +41,9 @@
#define MSM_SLIM_0_RX_MAX_CHANNELS 2
#define MSM_SLIM_0_TX_MAX_CHANNELS 4
-#define BTSCO_RATE_8KHZ 8000
-#define BTSCO_RATE_16KHZ 16000
+#define SAMPLE_RATE_8KHZ 8000
+#define SAMPLE_RATE_16KHZ 16000
+#define SAMPLE_RATE_48KHZ 48000
#define BOTTOM_SPK_AMP_POS 0x1
#define BOTTOM_SPK_AMP_NEG 0x2
@@ -67,6 +68,7 @@
enum {
SLIM_1_RX_1 = 145, /* BT-SCO and USB TX */
SLIM_1_TX_1 = 146, /* BT-SCO and USB RX */
+ SLIM_1_TX_2 = 147, /* USB RX */
SLIM_3_RX_1 = 151, /* External echo-cancellation ref */
SLIM_3_RX_2 = 152, /* External echo-cancellation ref */
SLIM_3_TX_1 = 153, /* HDMI RX */
@@ -90,8 +92,11 @@
static int msm_slim_0_tx_ch = 1;
static int msm_slim_3_rx_ch = 1;
-static int msm_btsco_rate = BTSCO_RATE_8KHZ;
+static int msm_slim_1_rate = SAMPLE_RATE_8KHZ;
static int msm_btsco_ch = 1;
+static int msm_slim_1_rx_ch = 1;
+static int msm_slim_1_tx_ch = 1;
+
static int hdmi_rate_variable;
static int rec_mode = INCALL_REC_MONO;
@@ -651,11 +656,14 @@
SOC_ENUM_SINGLE_EXT(2, hdmi_rate),
};
-static const char *btsco_rate_text[] = {"8000", "16000"};
-static const struct soc_enum msm_btsco_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
+static const char * const slim1_rate_text[] = {"8000", "16000", "48000"};
+static const struct soc_enum msm_slim_1_rate_enum[] = {
+ SOC_ENUM_SINGLE_EXT(3, slim1_rate_text),
};
-
+static const char * const slim1_tx_ch_text[] = {"One", "Two"};
+static const struct soc_enum msm_slim_1_tx_ch_enum[] = {
+ SOC_ENUM_SINGLE_EXT(2, slim1_tx_ch_text),
+};
static int msm_slim_0_rx_ch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -671,7 +679,7 @@
msm_slim_0_rx_ch = ucontrol->value.integer.value[0] + 1;
pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__,
- msm_slim_0_rx_ch);
+ msm_slim_0_rx_ch);
return 1;
}
@@ -694,6 +702,27 @@
return 1;
}
+static int msm_slim_1_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_slim_1_tx_ch = %d\n", __func__,
+ msm_slim_1_tx_ch);
+
+ ucontrol->value.integer.value[0] = msm_slim_1_tx_ch - 1;
+ return 0;
+}
+
+static int msm_slim_1_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_slim_1_tx_ch = ucontrol->value.integer.value[0] + 1;
+
+ pr_debug("%s: msm_slim_1_tx_ch = %d\n", __func__,
+ msm_slim_1_tx_ch);
+
+ return 1;
+}
+
static int msm_slim_3_rx_ch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -713,31 +742,35 @@
return 1;
}
-static int msm_btsco_rate_get(struct snd_kcontrol *kcontrol,
+static int msm_slim_1_rate_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- pr_debug("%s: msm_btsco_rate = %d", __func__,
- msm_btsco_rate);
- ucontrol->value.integer.value[0] = msm_btsco_rate;
+ pr_debug("%s: msm_slim_1_rate = %d", __func__,
+ msm_slim_1_rate);
+
+ ucontrol->value.integer.value[0] = msm_slim_1_rate;
return 0;
}
-static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol,
+static int msm_slim_1_rate_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
switch (ucontrol->value.integer.value[0]) {
case 8000:
- msm_btsco_rate = BTSCO_RATE_8KHZ;
+ msm_slim_1_rate = SAMPLE_RATE_8KHZ;
break;
case 16000:
- msm_btsco_rate = BTSCO_RATE_16KHZ;
+ msm_slim_1_rate = SAMPLE_RATE_16KHZ;
+ break;
+ case 48000:
+ msm_slim_1_rate = SAMPLE_RATE_48KHZ;
break;
default:
- msm_btsco_rate = BTSCO_RATE_8KHZ;
+ msm_slim_1_rate = SAMPLE_RATE_8KHZ;
break;
}
- pr_debug("%s: msm_btsco_rate = %d\n", __func__,
- msm_btsco_rate);
+ pr_debug("%s: msm_slim_1_rate = %d\n", __func__,
+ msm_slim_1_rate);
return 0;
}
@@ -780,8 +813,10 @@
msm_slim_0_rx_ch_get, msm_slim_0_rx_ch_put),
SOC_ENUM_EXT("SLIM_0_TX Channels", msm_enum[2],
msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put),
- SOC_ENUM_EXT("Internal BTSCO SampleRate", msm_btsco_enum[0],
- msm_btsco_rate_get, msm_btsco_rate_put),
+ SOC_ENUM_EXT("SLIM_1_TX Channels", msm_slim_1_tx_ch_enum[0],
+ msm_slim_1_tx_ch_get, msm_slim_1_tx_ch_put),
+ SOC_ENUM_EXT("SLIM_1 SampleRate", msm_slim_1_rate_enum[0],
+ msm_slim_1_rate_get, msm_slim_1_rate_put),
SOC_SINGLE_EXT("Incall Rec Mode", SND_SOC_NOPM, 0, 1, 0,
msm_incall_rec_mode_get, msm_incall_rec_mode_put),
SOC_ENUM_EXT("SLIM_3_RX Channels", msm_enum[1],
@@ -1001,7 +1036,7 @@
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret = 0;
- unsigned int rx_ch = SLIM_1_RX_1, tx_ch = SLIM_1_TX_1;
+ unsigned int rx_ch = SLIM_1_RX_1, tx_ch[2] = {SLIM_1_TX_1, SLIM_1_TX_2};
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
pr_debug("%s: APQ BT/USB TX -> SLIMBUS_1_RX -> MDM TX shared ch %d\n",
@@ -1015,10 +1050,11 @@
goto end;
}
} else {
- pr_debug("%s: MDM RX -> SLIMBUS_1_TX -> APQ BT/USB Rx shared ch %d\n",
- __func__, tx_ch);
+ pr_debug("%s: MDM RX ->SLIMBUS_1_TX ->APQ BT/USB Rx shared ch %d %d\n",
+ __func__, tx_ch[0], tx_ch[1]);
- ret = snd_soc_dai_set_channel_map(cpu_dai, 1, &tx_ch, 0, 0);
+ ret = snd_soc_dai_set_channel_map(cpu_dai, msm_slim_1_tx_ch,
+ tx_ch, 0, 0);
if (ret < 0) {
pr_err("%s: Erorr %d setting SLIM_1 TX channel map\n",
__func__, ret);
@@ -1358,16 +1394,46 @@
struct snd_pcm_hw_params *params)
{
struct snd_interval *rate = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_RATE);
+ SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *channels = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
+ SNDRV_PCM_HW_PARAM_CHANNELS);
- rate->min = rate->max = msm_btsco_rate;
+ rate->min = rate->max = msm_slim_1_rate;
channels->min = channels->max = msm_btsco_ch;
return 0;
}
+static int msm_slim_1_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ rate->min = rate->max = msm_slim_1_rate;
+ channels->min = channels->max = msm_slim_1_rx_ch;
+
+ return 0;
+}
+
+static int msm_slim_1_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ rate->min = rate->max = msm_slim_1_rate;
+ channels->min = channels->max = msm_slim_1_tx_ch;
+
+ return 0;
+}
+
static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -1728,20 +1794,18 @@
.codec_name = "snd-soc-dummy",
},
{
- .name = "VoLTE",
- .stream_name = "VoLTE",
- .cpu_dai_name = "VoLTE",
- .platform_name = "msm-pcm-voice",
+ .name = "VoLTE Stub",
+ .stream_name = "VoLTE Stub",
+ .cpu_dai_name = "VOLTE_STUB",
+ .platform_name = "msm-pcm-hostless",
.dynamic = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
- SND_SOC_DPCM_TRIGGER_POST},
+ SND_SOC_DPCM_TRIGGER_POST},
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
.ignore_suspend = 1,
- /* this dainlink has playback support */
.ignore_pmdown_time = 1,
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
- .be_id = MSM_FRONTEND_DAI_VOLTE,
},
{
.name = "MSM8960 LowLatency",
@@ -1800,6 +1864,21 @@
.ignore_pmdown_time = 1, /* this dailink has playback support */
.be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
},
+ {
+ .name = "Voice2 Stub",
+ .stream_name = "Voice2 Stub",
+ .cpu_dai_name = "VOICE2_STUB",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
/* Backend DAI Links */
{
.name = LPASS_BE_SLIMBUS_0_RX,
@@ -1971,7 +2050,7 @@
.codec_dai_name = "msm-stub-rx",
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX,
- .be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+ .be_hw_params_fixup = msm_slim_1_rx_be_hw_params_fixup,
.ops = &msm_slimbus_1_be_ops,
.ignore_pmdown_time = 1, /* this dainlink has playback support */
@@ -1985,7 +2064,7 @@
.codec_dai_name = "msm-stub-tx",
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
- .be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+ .be_hw_params_fixup = msm_slim_1_tx_be_hw_params_fixup,
.ops = &msm_slimbus_1_be_ops,
},
/* Ultrasound TX Back End DAI Link */
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index e00e409..734bd39 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -550,8 +550,8 @@
},
{
.playback = {
- .stream_name = "SGLTE Playback",
- .aif_name = "SGLTE_DL",
+ .stream_name = "Voice2 Playback",
+ .aif_name = "VOICE2_DL",
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
@@ -560,8 +560,8 @@
.rate_max = 48000,
},
.capture = {
- .stream_name = "SGLTE Capture",
- .aif_name = "SGLTE_UL",
+ .stream_name = "Voice2 Capture",
+ .aif_name = "VOICE2_UL",
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
@@ -570,7 +570,7 @@
.rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
- .name = "SGLTE",
+ .name = "Voice2",
},
{
.playback = {
@@ -626,6 +626,54 @@
.ops = &msm_fe_dai_ops,
.name = "LSM",
},
+ {
+ .playback = {
+ .stream_name = "VoLTE Stub Playback",
+ .aif_name = "VOLTE_STUB_DL",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "VoLTE Stub Capture",
+ .aif_name = "VOLTE_STUB_UL",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "VOLTE_STUB",
+ },
+ {
+ .playback = {
+ .stream_name = "Voice2 Stub Playback",
+ .aif_name = "VOICE2_STUB_DL",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "Voice2 Stub Capture",
+ .aif_name = "VOICE2_STUB_UL",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "VOICE2_STUB",
+ },
};
static __devinit int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 6cf74d5..c5cb560 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -733,8 +733,8 @@
session_id = voc_get_session_id(VOICE_SESSION_NAME);
else if (val == MSM_FRONTEND_DAI_VOLTE)
session_id = voc_get_session_id(VOLTE_SESSION_NAME);
- else if (val == MSM_FRONTEND_DAI_SGLTE)
- session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+ else if (val == MSM_FRONTEND_DAI_VOICE2)
+ session_id = voc_get_session_id(VOICE2_SESSION_NAME);
else
session_id = voc_get_session_id(VOIP_SESSION_NAME);
@@ -1768,12 +1768,18 @@
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_PRI_I2S_RX,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_PRI_I2S_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_PRI_I2S_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_PRI_I2S_RX,
MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
@@ -1789,8 +1795,8 @@
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_I2S_RX,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_SEC_I2S_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SEC_I2S_RX,
MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
@@ -1807,8 +1813,8 @@
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
@@ -1825,11 +1831,17 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
@@ -1846,8 +1858,14 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_MI2S_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_MI2S_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_MI2S_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_MI2S_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_MI2S_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_MI2S_RX,
MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
@@ -1864,11 +1882,17 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AFE_PCM_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AFE_PCM_RX,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_AFE_PCM_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AFE_PCM_RX,
MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
@@ -1885,11 +1909,17 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_AUXPCM_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
@@ -1906,8 +1936,8 @@
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
@@ -1927,8 +1957,14 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_HDMI_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
@@ -1939,18 +1975,36 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_EXTPROC_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_EXTPROC_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_EXTPROC_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
};
static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = {
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
};
static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = {
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
};
static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
@@ -2004,30 +2058,30 @@
msm_routing_put_voice_mixer),
};
-static const struct snd_kcontrol_new tx_sglte_mixer_controls[] = {
- SOC_SINGLE_EXT("PRI_TX_SGLTE", MSM_BACKEND_DAI_PRI_I2S_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+static const struct snd_kcontrol_new tx_voice2_mixer_controls[] = {
+ SOC_SINGLE_EXT("PRI_TX_Voice2", MSM_BACKEND_DAI_PRI_I2S_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SEC_TX_SGLTE", MSM_BACKEND_DAI_SEC_I2S_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("SEC_TX_Voice2", MSM_BACKEND_DAI_SEC_I2S_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("MI2S_TX_SGLTE", MSM_BACKEND_DAI_MI2S_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("MI2S_TX_Voice2", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SLIM_0_TX_SGLTE", MSM_BACKEND_DAI_SLIMBUS_0_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("SLIM_0_TX_Voice2", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_SGLTE",
- MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_SGLTE, 1, 0,
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice2",
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICE2, 1, 0,
msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("AFE_PCM_TX_SGLTE", MSM_BACKEND_DAI_AFE_PCM_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("AFE_PCM_TX_Voice2", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("AUX_PCM_TX_SGLTE", MSM_BACKEND_DAI_AUXPCM_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_AUXPCM_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SEC_AUX_PCM_TX_SGLTE", MSM_BACKEND_DAI_SEC_AUXPCM_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("SEC_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_SEC_AUXPCM_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
@@ -2087,6 +2141,66 @@
msm_routing_put_voice_stub_mixer),
};
+static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = {
+ SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("PRIMARY_I2S_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("SECONDARY_I2S_TX", MSM_BACKEND_DAI_SEC_I2S_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+};
+
+static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = {
+ SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("PRIMARY_I2S_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("SECONDARY_I2S_TX", MSM_BACKEND_DAI_SEC_I2S_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+};
+
static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
@@ -2553,8 +2667,8 @@
SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("VoLTE_DL", "VoLTE Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("VoLTE_UL", "VoLTE Capture", 0, 0, 0, 0),
- SND_SOC_DAPM_AIF_IN("SGLTE_DL", "SGLTE Playback", 0, 0, 0, 0),
- SND_SOC_DAPM_AIF_OUT("SGLTE_UL", "SGLTE Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("VOICE2_DL", "Voice2 Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("VOICE2_UL", "Voice2 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback",
0, 0, 0, 0),
@@ -2622,6 +2736,12 @@
0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("VOLTE_STUB_DL", "VOLTE_STUB Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("VOLTE_STUB_UL", "VOLTE_STUB Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("VOICE2_STUB_DL",
+ "VOICE2_STUB Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("VOICE2_STUB_UL",
+ "VOICE2_STUB Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("STUB_RX", "Stub Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("STUB_TX", "Stub Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0),
@@ -2712,9 +2832,9 @@
SND_SOC_DAPM_MIXER("VoLTE_Tx Mixer",
SND_SOC_NOPM, 0, 0, tx_volte_mixer_controls,
ARRAY_SIZE(tx_volte_mixer_controls)),
- SND_SOC_DAPM_MIXER("SGLTE_Tx Mixer",
- SND_SOC_NOPM, 0, 0, tx_sglte_mixer_controls,
- ARRAY_SIZE(tx_sglte_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Voice2_Tx Mixer",
+ SND_SOC_NOPM, 0, 0, tx_voice2_mixer_controls,
+ ARRAY_SIZE(tx_voice2_mixer_controls)),
SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
@@ -2758,7 +2878,12 @@
ARRAY_SIZE(sbus_3_rx_port_mixer_controls)),
SND_SOC_DAPM_MIXER("MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0,
mi2s_rx_port_mixer_controls, ARRAY_SIZE(mi2s_rx_port_mixer_controls)),
-
+ SND_SOC_DAPM_MIXER("VoLTE Stub Tx Mixer", SND_SOC_NOPM, 0, 0,
+ tx_volte_stub_mixer_controls,
+ ARRAY_SIZE(tx_volte_stub_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Voice2 Stub Tx Mixer", SND_SOC_NOPM, 0, 0,
+ tx_voice2_stub_mixer_controls,
+ ARRAY_SIZE(tx_voice2_stub_mixer_controls)),
/* Virtual Pins to force backends ON atm */
SND_SOC_DAPM_OUTPUT("BE_OUT"),
SND_SOC_DAPM_INPUT("BE_IN"),
@@ -2890,7 +3015,7 @@
{"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"PRI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"PRI_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"PRI_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"PRI_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
{"PRI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
@@ -2898,49 +3023,49 @@
{"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"SEC_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"SEC_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"SEC_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"SEC_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
{"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"},
{"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"SLIM_0_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"SLIM_0_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"SLIM_0_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"SLIM_0_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
{"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"INTERNAL_BT_SCO_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
{"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"AFE_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"AFE_PCM_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"AFE_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"AFE_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
{"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
{"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"AUX_PCM_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
{"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
{"SEC_AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"SEC_AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"SEC_AUX_PCM_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"SEC_AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"SEC_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"SEC_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
{"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX_Voice Mixer"},
{"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"HDMI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"HDMI_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"HDMI_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"HDMI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
{"HDMI", NULL, "HDMI_RX_Voice Mixer"},
@@ -2963,15 +3088,15 @@
{"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"},
{"VoLTE_Tx Mixer", "SEC_AUX_PCM_TX_VoLTE", "SEC_AUX_PCM_TX"},
{"VoLTE_UL", NULL, "VoLTE_Tx Mixer"},
- {"SGLTE_Tx Mixer", "PRI_TX_SGLTE", "PRI_I2S_TX"},
- {"SGLTE_Tx Mixer", "SEC_TX_SGLTE", "SEC_I2S_TX"},
- {"SGLTE_Tx Mixer", "MI2S_TX_SGLTE", "MI2S_TX"},
- {"SGLTE_Tx Mixer", "SLIM_0_TX_SGLTE", "SLIMBUS_0_TX"},
- {"SGLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_SGLTE", "INT_BT_SCO_TX"},
- {"SGLTE_Tx Mixer", "AFE_PCM_TX_SGLTE", "PCM_TX"},
- {"SGLTE_Tx Mixer", "AUX_PCM_TX_SGLTE", "AUX_PCM_TX"},
- {"SGLTE_Tx Mixer", "SEC_AUX_PCM_TX_SGLTE", "SEC_AUX_PCM_TX"},
- {"SGLTE_UL", NULL, "SGLTE_Tx Mixer"},
+ {"Voice2_Tx Mixer", "PRI_TX_Voice2", "PRI_I2S_TX"},
+ {"Voice2_Tx Mixer", "SEC_TX_Voice2", "SEC_I2S_TX"},
+ {"Voice2_Tx Mixer", "MI2S_TX_Voice2", "MI2S_TX"},
+ {"Voice2_Tx Mixer", "SLIM_0_TX_Voice2", "SLIMBUS_0_TX"},
+ {"Voice2_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice2", "INT_BT_SCO_TX"},
+ {"Voice2_Tx Mixer", "AFE_PCM_TX_Voice2", "PCM_TX"},
+ {"Voice2_Tx Mixer", "AUX_PCM_TX_Voice2", "AUX_PCM_TX"},
+ {"Voice2_Tx Mixer", "SEC_AUX_PCM_TX_Voice2", "SEC_AUX_PCM_TX"},
+ {"VOICE2_UL", NULL, "Voice2_Tx Mixer"},
{"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
{"Voip_Tx Mixer", "SEC_TX_Voip", "SEC_I2S_TX"},
{"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"},
@@ -3017,17 +3142,53 @@
{"Voice Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"},
{"VOICE_STUB_UL", NULL, "Voice Stub Tx Mixer"},
+ {"VoLTE Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"},
+ {"VoLTE Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
+ {"VoLTE Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"VoLTE Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"},
+ {"VoLTE Stub Tx Mixer", "MI2S_TX", "MI2S_TX"},
+ {"VoLTE Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"},
+ {"VoLTE Stub Tx Mixer", "PRIMARY_I2S_TX", "PRI_I2S_TX"},
+ {"VoLTE Stub Tx Mixer", "SECONDARY_I2S_TX", "SEC_I2S_TX"},
+ {"VoLTE Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"VOLTE_STUB_UL", NULL, "VoLTE Stub Tx Mixer"},
+
+ {"Voice2 Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"},
+ {"Voice2 Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
+ {"Voice2 Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"Voice2 Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"},
+ {"Voice2 Stub Tx Mixer", "MI2S_TX", "MI2S_TX"},
+ {"Voice2 Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"},
+ {"Voice2 Stub Tx Mixer", "PRIMARY_I2S_TX", "PRI_I2S_TX"},
+ {"Voice2 Stub Tx Mixer", "SECONDARY_I2S_TX", "SEC_I2S_TX"},
+ {"Voice2 Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"VOICE2_STUB_UL", NULL, "Voice2 Stub Tx Mixer"},
+
{"STUB_RX Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"STUB_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"STUB_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"STUB_RX", NULL, "STUB_RX Mixer"},
{"SLIMBUS_1_RX Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"SLIMBUS_1_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"SLIMBUS_1_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
{"HDMI_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"HDMI_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"HDMI_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"AFE_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"AFE_PCM_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"AFE_PCM_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"SLIMBUS_3_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"SLIMBUS_3_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"SLIMBUS_3_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"},
{"SLIMBUS_1_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index b571483..c42e155 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -69,8 +69,10 @@
MSM_FRONTEND_DAI_AFE_TX,
MSM_FRONTEND_DAI_VOICE_STUB,
MSM_FRONTEND_DAI_VOLTE,
- MSM_FRONTEND_DAI_SGLTE,
+ MSM_FRONTEND_DAI_VOICE2,
MSM_FRONTEND_DAI_DTMF_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB,
+ MSM_FRONTEND_DAI_VOICE2_STUB,
MSM_FRONTEND_DAI_MAX,
};
diff --git a/sound/soc/msm/msm-pcm-voice.c b/sound/soc/msm/msm-pcm-voice.c
index ac5bc34..26e6ae6 100644
--- a/sound/soc/msm/msm-pcm-voice.c
+++ b/sound/soc/msm/msm-pcm-voice.c
@@ -59,9 +59,10 @@
return false;
}
-static int is_sglte(struct msm_voice *psglte)
+static int is_voice2(struct msm_voice *pvoice2)
+
{
- if (psglte == &voice_info[SGLTE_SESSION_INDEX])
+ if (pvoice2 == &voice_info[VOICE2_SESSION_INDEX])
return true;
else
return false;
@@ -100,15 +101,15 @@
if (!strncmp("VoLTE", substream->pcm->id, 5)) {
voice = &voice_info[VOLTE_SESSION_INDEX];
pr_debug("%s: Open VoLTE Substream Id=%s\n",
- __func__, substream->pcm->id);
- } else if (!strncmp("SGLTE", substream->pcm->id, 5)) {
- voice = &voice_info[SGLTE_SESSION_INDEX];
- pr_debug("%s: Open SGLTE Substream Id=%s\n",
- __func__, substream->pcm->id);
+ __func__, substream->pcm->id);
+ } else if (!strncmp("Voice2", substream->pcm->id, 6)) {
+ voice = &voice_info[VOICE2_SESSION_INDEX];
+ pr_debug("%s: Open Voice2 Substream Id=%s\n",
+ __func__, substream->pcm->id);
} else {
voice = &voice_info[VOICE_SESSION_INDEX];
pr_debug("%s: Open VOICE Substream Id=%s\n",
- __func__, substream->pcm->id);
+ __func__, substream->pcm->id);
}
mutex_lock(&voice->lock);
@@ -174,8 +175,8 @@
pr_debug("end voice call\n");
if (is_volte(prtd))
session_id = voc_get_session_id(VOLTE_SESSION_NAME);
- else if (is_sglte(prtd))
- session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+ else if (is_voice2(prtd))
+ session_id = voc_get_session_id(VOICE2_SESSION_NAME);
else
session_id = voc_get_session_id(VOICE_SESSION_NAME);
voc_end_voice_call(session_id);
@@ -201,8 +202,8 @@
if (prtd->playback_start && prtd->capture_start) {
if (is_volte(prtd))
session_id = voc_get_session_id(VOLTE_SESSION_NAME);
- else if (is_sglte(prtd))
- session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+ else if (is_voice2(prtd))
+ session_id = voc_get_session_id(VOICE2_SESSION_NAME);
else
session_id = voc_get_session_id(VOICE_SESSION_NAME);
voc_start_voice_call(session_id);
@@ -233,8 +234,8 @@
pr_debug("%s: cmd = %d\n", __func__, cmd);
if (is_volte(prtd))
session_id = voc_get_session_id(VOLTE_SESSION_NAME);
- else if (is_sglte(prtd))
- session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+ else if (is_voice2(prtd))
+ session_id = voc_get_session_id(VOICE2_SESSION_NAME);
else
session_id = voc_get_session_id(VOICE_SESSION_NAME);
@@ -308,19 +309,20 @@
return 0;
}
-static int msm_sglte_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+static int msm_voice2_volume_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = 0;
return 0;
}
-static int msm_sglte_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+static int msm_voice2_volume_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
int volume = ucontrol->value.integer.value[0];
pr_debug("%s: volume: %d\n", __func__, volume);
- voc_set_rx_vol_index(voc_get_session_id(SGLTE_SESSION_NAME),
+
+ voc_set_rx_vol_index(voc_get_session_id(VOICE2_SESSION_NAME),
RX_PATH, volume);
return 0;
}
@@ -401,21 +403,21 @@
return 0;
}
-static int msm_sglte_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+static int msm_voice2_mute_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = 0;
return 0;
}
-static int msm_sglte_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+static int msm_voice2_mute_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
int mute = ucontrol->value.integer.value[0];
pr_debug("%s: mute=%d\n", __func__, mute);
- voc_set_tx_mute(voc_get_session_id(SGLTE_SESSION_NAME), TX_PATH, mute);
+ voc_set_tx_mute(voc_get_session_id(VOICE2_SESSION_NAME), TX_PATH, mute);
return 0;
}
@@ -460,22 +462,22 @@
return 0;
}
-static int msm_sglte_rx_device_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+static int msm_voice2_rx_device_mute_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] =
- voc_get_rx_device_mute(voc_get_session_id(SGLTE_SESSION_NAME));
+ voc_get_rx_device_mute(voc_get_session_id(VOICE2_SESSION_NAME));
return 0;
}
-static int msm_sglte_rx_device_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+static int msm_voice2_rx_device_mute_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
int mute = ucontrol->value.integer.value[0];
pr_debug("%s: mute=%d\n", __func__, mute);
- voc_set_rx_device_mute(voc_get_session_id(SGLTE_SESSION_NAME), mute);
+ voc_set_rx_device_mute(voc_get_session_id(VOICE2_SESSION_NAME), mute);
return 0;
}
@@ -502,7 +504,7 @@
voc_set_tty_mode(voc_get_session_id(VOICE_SESSION_NAME), tty_mode);
- voc_set_tty_mode(voc_get_session_id(SGLTE_SESSION_NAME), tty_mode);
+ voc_set_tty_mode(voc_get_session_id(VOICE2_SESSION_NAME), tty_mode);
return 0;
}
static int msm_voice_widevoice_put(struct snd_kcontrol *kcontrol,
@@ -514,7 +516,7 @@
voc_set_widevoice_enable(voc_get_session_id(VOICE_SESSION_NAME),
wv_enable);
- voc_set_widevoice_enable(voc_get_session_id(SGLTE_SESSION_NAME),
+ voc_set_widevoice_enable(voc_get_session_id(VOICE2_SESSION_NAME),
wv_enable);
return 0;
}
@@ -536,9 +538,9 @@
pr_debug("%s: st enable=%d\n", __func__, st_enable);
voc_set_pp_enable(voc_get_session_id(VOICE_SESSION_NAME),
- MODULE_ID_VOICE_MODULE_ST, st_enable);
- voc_set_pp_enable(voc_get_session_id(SGLTE_SESSION_NAME),
- MODULE_ID_VOICE_MODULE_ST, st_enable);
+ MODULE_ID_VOICE_MODULE_ST, st_enable);
+ voc_set_pp_enable(voc_get_session_id(VOICE2_SESSION_NAME),
+ MODULE_ID_VOICE_MODULE_ST, st_enable);
return 0;
}
@@ -560,9 +562,9 @@
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(SGLTE_SESSION_NAME),
- MODULE_ID_VOICE_MODULE_FENS, fens_enable);
+ 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;
}
@@ -605,13 +607,13 @@
SOC_SINGLE_EXT("VoLTE Topology Disable", SND_SOC_NOPM, 0, 1, 0,
msm_volte_topology_disable_get,
msm_volte_topology_disable_put),
- SOC_SINGLE_EXT("SGLTE Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
- msm_sglte_rx_device_mute_get,
- msm_sglte_rx_device_mute_put),
- SOC_SINGLE_EXT("SGLTE Tx Mute", SND_SOC_NOPM, 0, 1, 0,
- msm_sglte_mute_get, msm_sglte_mute_put),
- SOC_SINGLE_EXT("SGLTE Rx Volume", SND_SOC_NOPM, 0, 5, 0,
- msm_sglte_volume_get, msm_sglte_volume_put),
+ SOC_SINGLE_EXT("Voice2 Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
+ msm_voice2_rx_device_mute_get,
+ msm_voice2_rx_device_mute_put),
+ SOC_SINGLE_EXT("Voice2 Tx Mute", SND_SOC_NOPM, 0, 1, 0,
+ msm_voice2_mute_get, msm_voice2_mute_put),
+ SOC_SINGLE_EXT("Voice2 Rx Volume", SND_SOC_NOPM, 0, 5, 0,
+ msm_voice2_volume_get, msm_voice2_volume_put),
};
static struct snd_pcm_ops msm_pcm_ops = {
@@ -674,7 +676,7 @@
memset(&voice_info, 0, sizeof(voice_info));
mutex_init(&voice_info[VOICE_SESSION_INDEX].lock);
mutex_init(&voice_info[VOLTE_SESSION_INDEX].lock);
- mutex_init(&voice_info[SGLTE_SESSION_INDEX].lock);
+ mutex_init(&voice_info[VOICE2_SESSION_INDEX].lock);
return platform_driver_register(&msm_pcm_driver);
}
diff --git a/sound/soc/msm/msm-pcm-voice.h b/sound/soc/msm/msm-pcm-voice.h
index 6eb2060..207e7a7 100644
--- a/sound/soc/msm/msm-pcm-voice.h
+++ b/sound/soc/msm/msm-pcm-voice.h
@@ -16,7 +16,7 @@
enum {
VOICE_SESSION_INDEX,
VOLTE_SESSION_INDEX,
- SGLTE_SESSION_INDEX,
+ VOICE2_SESSION_INDEX,
VOICE_SESSION_INDEX_MAX,
};
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index ae9468f..2bd5c88 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -1105,9 +1105,9 @@
.be_id = MSM_FRONTEND_DAI_VOLTE,
},
{
- .name = "SGLTE",
- .stream_name = "SGLTE",
- .cpu_dai_name = "SGLTE",
+ .name = "Voice2",
+ .stream_name = "Voice2",
+ .cpu_dai_name = "Voice2",
.platform_name = "msm-pcm-voice",
.dynamic = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
@@ -1118,7 +1118,7 @@
.ignore_pmdown_time = 1,
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
- .be_id = MSM_FRONTEND_DAI_SGLTE,
+ .be_id = MSM_FRONTEND_DAI_VOICE2,
},
{
.name = "MSM8960 LowLatency",
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index f987eb4..8c0d1a9 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -1361,9 +1361,9 @@
.be_id = MSM_FRONTEND_DAI_VOLTE,
},
{
- .name = "SGLTE",
- .stream_name = "SGLTE",
- .cpu_dai_name = "SGLTE",
+ .name = "Voice2",
+ .stream_name = "Voice2",
+ .cpu_dai_name = "Voice2",
.platform_name = "msm-pcm-voice",
.dynamic = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
@@ -1373,7 +1373,7 @@
.ignore_pmdown_time = 1,/* this dainlink has playback support */
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
- .be_id = MSM_FRONTEND_DAI_SGLTE,
+ .be_id = MSM_FRONTEND_DAI_VOICE2,
},
{
.name = "MSM8960 LowLatency",
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 0dbe3f7..50a0113 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -2104,8 +2104,7 @@
sizeof(struct msm8974_asoc_mach_data), GFP_KERNEL);
if (!pdata) {
dev_err(&pdev->dev, "Can't allocate msm8974_asoc_mach_data\n");
- ret = -ENOMEM;
- goto err;
+ return -ENOMEM;
}
ret = msm8974_dtparse_auxpcm(pdev, &pdata);
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index f04947c..17f2d03 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -31,11 +31,6 @@
#define CMD_STATUS_SUCCESS 0
#define CMD_STATUS_FAIL 1
-#define VOC_PATH_PASSIVE 0
-#define VOC_PATH_FULL 1
-#define VOC_PATH_VOLTE_PASSIVE 2
-#define VOC_PATH_SGLTE_PASSIVE 3
-
#define CAL_BUFFER_SIZE 4096
#define NUM_CVP_CAL_BLOCKS 75
#define NUM_CVS_CAL_BLOCKS 15
@@ -173,9 +168,9 @@
else if (!strncmp(name, "VoLTE session", 13))
session_id =
common.voice[VOC_PATH_VOLTE_PASSIVE].session_id;
- else if (!strncmp(name, "SGLTE session", 13))
+ else if (!strncmp(name, "Voice2 session", 14))
session_id =
- common.voice[VOC_PATH_SGLTE_PASSIVE].session_id;
+ common.voice[VOC_PATH_VOICE2_PASSIVE].session_id;
else
session_id = common.voice[VOC_PATH_FULL].session_id;
@@ -216,9 +211,9 @@
return (session_id == common.voice[VOC_PATH_VOLTE_PASSIVE].session_id);
}
-static bool is_sglte_session(u16 session_id)
+static bool is_voice2_session(u16 session_id)
{
- return (session_id == common.voice[VOC_PATH_SGLTE_PASSIVE].session_id);
+ return (session_id == common.voice[VOC_PATH_VOICE2_PASSIVE].session_id);
}
/* Only for memory allocated in the voice driver */
@@ -373,9 +368,9 @@
pr_err("%s: apr_mvm is NULL.\n", __func__);
return -EINVAL;
}
- pr_debug("%s: VoLTE/SGLTE command to MVM\n", __func__);
+ pr_debug("%s: VoLTE/Voice2 command to MVM\n", __func__);
if (is_volte_session(v->session_id) ||
- is_sglte_session(v->session_id)) {
+ is_voice2_session(v->session_id)) {
mvm_handle = voice_get_mvm_handle(v);
mvm_voice_ctl_cmd.hdr.hdr_field = APR_HDR_FIELD(
@@ -451,7 +446,7 @@
if (!mvm_handle) {
if (is_voice_session(v->session_id) ||
is_volte_session(v->session_id) ||
- is_sglte_session(v->session_id)) {
+ is_voice2_session(v->session_id)) {
mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE),
@@ -471,7 +466,7 @@
strlcpy(mvm_session_cmd.mvm_session.name,
"default volte voice",
sizeof(mvm_session_cmd.mvm_session.name) - 1);
- } else if (is_sglte_session(v->session_id)) {
+ } else if (is_voice2_session(v->session_id)) {
strlcpy(mvm_session_cmd.mvm_session.name,
"default modem voice2",
sizeof(mvm_session_cmd.mvm_session.name));
@@ -538,7 +533,7 @@
if (!cvs_handle) {
if (is_voice_session(v->session_id) ||
is_volte_session(v->session_id) ||
- is_sglte_session(v->session_id)) {
+ is_voice2_session(v->session_id)) {
pr_debug("%s: creating CVS passive session\n",
__func__);
@@ -559,7 +554,7 @@
strlcpy(cvs_session_cmd.cvs_session.name,
"default volte voice",
sizeof(cvs_session_cmd.cvs_session.name) - 1);
- } else if (is_sglte_session(v->session_id)) {
+ } else if (is_voice2_session(v->session_id)) {
strlcpy(cvs_session_cmd.cvs_session.name,
"default modem voice2",
sizeof(cvs_session_cmd.cvs_session.name));
diff --git a/sound/soc/msm/qdsp6/q6voice.h b/sound/soc/msm/qdsp6/q6voice.h
index 8df6c38..0bae384 100644
--- a/sound/soc/msm/qdsp6/q6voice.h
+++ b/sound/soc/msm/qdsp6/q6voice.h
@@ -1314,12 +1314,12 @@
#define VOICE_SESSION_NAME "Voice session"
#define VOIP_SESSION_NAME "VoIP session"
#define VOLTE_SESSION_NAME "VoLTE session"
-#define SGLTE_SESSION_NAME "SGLTE session"
+#define VOICE2_SESSION_NAME "Voice2 session"
#define VOC_PATH_PASSIVE 0
#define VOC_PATH_FULL 1
#define VOC_PATH_VOLTE_PASSIVE 2
-#define VOC_PATH_SGLTE_PASSIVE 3
+#define VOC_PATH_VOICE2_PASSIVE 3
uint16_t voc_get_session_id(char *name);
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 5cf1b90..5b18311 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -1351,7 +1351,7 @@
ctrl = &mi2s_config_controls[3];
}
- if (!ctrl) {
+ if (ctrl) {
kcontrol = snd_ctl_new1(ctrl,
&mi2s_dai_data->rx_dai.mi2s_dai_data);
rc = snd_ctl_add(dai->card->snd_card, kcontrol);
@@ -1371,7 +1371,7 @@
ctrl = &mi2s_config_controls[4];
}
- if (!ctrl) {
+ if (ctrl) {
rc = snd_ctl_add(dai->card->snd_card,
snd_ctl_new1(ctrl,
&mi2s_dai_data->tx_dai.mi2s_dai_data));
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index b32daaa..b1db277 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -992,6 +992,8 @@
if (tmp >= 0 && tmp < AFE_MAX_PORTS)
copps_list[i] =
atomic_read(&this_adm.copp_id[tmp]);
+ else
+ continue;
pr_debug("%s: port_id[%#x]: %d, index: %d act coppid[0x%x]\n",
__func__, i, port_id[i], tmp,
atomic_read(&this_adm.copp_id[tmp]));