Merge "msm: vidc: allocate i/p buffers based on h/w capability"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_ion.txt b/Documentation/devicetree/bindings/arm/msm/msm_ion.txt
index 5c6b804..2d83614 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_ion.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_ion.txt
@@ -6,12 +6,19 @@
type of heap ION must reserve memory using the msm specific memory reservation
bindings (see Documentation/devicetree/bindings/arm/msm/memory-reserve.txt).
-Required properties
+Required properties for Ion
- compatible: "qcom,msm-ion"
+
+
+All child nodes of a qcom,msm-ion node are interpreted as Ion heap
+configurations.
+
+Required properties for Ion heaps
+
- reg: The ID of the ION heap.
-Optional properties
+Optional properties for Ion heaps
- compatible: "qcom,msm-ion-reserve" This is required if memory is to be reserved
as specified by qcom,memory-reservation-size below.
diff --git a/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt b/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt
index d930799..3d70a9b 100644
--- a/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt
+++ b/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt
@@ -62,6 +62,28 @@
1. This value shift is necessary to work around
limitations in the regulator framework which
treat 0 uV as an error.
+- qcom,use-voltage-floor-corner: Flag that signifies if regulator_set_voltage
+ calls should modify the floor corner parameter
+ instead of the voltage parameter. When used,
+ voltages specified inside of the regulator
+ framework represent corners that have been
+ incremented by 1. The properties
+ qcom,use-voltage-corner and
+ qcom,use-voltage-floor-corner are mutually
+ exclusive. Only one may be specified for a
+ given regulator.
+- qcom,always-send-voltage: Flag which indicates that updates to the voltage
+ or voltage corner set point should always be
+ sent immediately to the RPM. If this flag is
+ not specified, then voltage set point updates
+ are only sent if the given regulator has also
+ been enabled by a Linux consumer.
+- qcom,always-send-current: Flag which indicates that updates to the load
+ current should always be sent immediately to the
+ RPM. If this flag is not specified, then load
+ current updates are only sent if the given
+ regulator has also been enabled by a Linux
+ consumer.
The following properties specify initial values for parameters to be sent to the
RPM in regulator requests.
- qcom,init-enable: 0 = regulator disabled
@@ -94,25 +116,9 @@
BIT(2) = follow HW2_EN signal
BIT(3) = follow HW3_EN signal
BIT(4) = follow PMIC awake state
-- qcom,init-frequency: Switching frequency in MHz for SMPS regulators.
- Supported values are:
- 0 = Don't care about frequency used
- 1 = 19.20
- 2 = 9.60
- 3 = 6.40
- 4 = 4.80
- 5 = 3.84
- 6 = 3.20
- 7 = 2.74
- 8 = 2.40
- 9 = 2.13
- 10 = 1.92
- 11 = 1.75
- 12 = 1.60
- 13 = 1.48
- 14 = 1.37
- 15 = 1.28
- 16 = 1.20
+- qcom,init-frequency: Switching frequency divisor for SMPS regulators.
+ Supported values are n = 0 to 31 where
+ freq = 19.2 MHz / (n + 1).
- qcom,init-head-room: Voltage head room in mV required for the
regulator. This head room value should be used
in situations where the device connected to the
@@ -165,6 +171,10 @@
0 = Allow RPM to utilize LDO bypass mode
if possible
1 = Disallow LDO bypass mode
+- qcom,init-voltage-floor-corner: Minimum performance corner to use if any
+ processor in the system is awake. This property
+ supports the same values as
+ qcom,init-voltage-corner.
All properties specified within the core regulator framework can also be used in
second level nodes. These bindings can be found in:
diff --git a/Documentation/devicetree/bindings/arm/msm/spm-regulator.txt b/Documentation/devicetree/bindings/arm/msm/spm-regulator.txt
new file mode 100644
index 0000000..c012eec
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/spm-regulator.txt
@@ -0,0 +1,32 @@
+Qualcomm SPM Regulators
+
+spm-regulator is a regulator device which supports PMIC processor supply
+regulators via the SPM module.
+
+Required properties:
+- compatible: Must be "qcom,spm-regulator"
+- reg: Specifies the SPMI address and size for this regulator device
+- regulator-name: A string used as a descriptive name for the regulator
+
+Required structure:
+- A qcom,spm-regulator node must be a child of an SPMI node that has specified
+ the spmi-slave-container property
+
+All properties specified within the core regulator framework can also be used.
+These bindings can be found in regulator.txt.
+
+Example:
+ qcom,spmi@fc4c0000 {
+
+ qcom,pm8226@1 {
+ spmi-slave-container;
+
+ spm-regulator@1700 {
+ compatible = "qcom,spm-regulator";
+ regulator-name = "8226_s2";
+ reg = <0x1700 0x100>;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1275000>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/bluetooth/bluesleep.txt b/Documentation/devicetree/bindings/bluetooth/bluesleep.txt
new file mode 100644
index 0000000..a5c5a16
--- /dev/null
+++ b/Documentation/devicetree/bindings/bluetooth/bluesleep.txt
@@ -0,0 +1,41 @@
+* Bluetooth Sleep Protocol driver
+Bluetooth controller communicates with the Bluetooth Host using HCI Transport layer.
+HCI Transport layer can be based on UART or USB serial communication protocol.
+
+Apart from the transport layer, Bluetooth Controller also supports Low Power Mode
+using various mechanisms. One of such mechanism is Out-of-Band Sleep. Also known
+as 2-wire sleep mechanism.
+
+Out-of-Band Sleep:
+It requires two GPIOs to communicate the sleep protocol between Host and Controller.
+One of them is called as Host Wake GPIO where as other is known as a External wake
+GPIO.
+Host Wake GPIO is used for awake the Host from the Sleep Mode. It is controlled by the
+Controller. It should be wakeup interruptible source on the Host.
+External Wake GPIO is used for awake the Controller from the Sleep Mode. It is controlled
+by the Host.
+
+Required Properties:
+
+ - compatible: Should be "qca,ar3002_bluesleep"
+ - host-wake-gpio: Specify GPIO for Host wake signal (Controller -> Host).
+ - ext-wake-gpio: Specify GPIO for Controller wake signal(Host -> Controller).
+ - interrupt-parent: Should be phandle for the interrupt controller
+ that services interrupts for this device.
+ - interrupts: Should contain host wake interrupt from controller.
+ - interrupt-names: indicates interrupts passed to driver
+ (via interrupts property) by name. "host_wake" is mandatory.
+
+Optional Properties:
+ None
+
+Example:
+
+ bt_sleep {
+ compatible = "qca,ar3002_bluesleep";
+ host-wake-gpio = <&msmgpio 12 0>;
+ ext-wake-gpio = <&msmgpio 13 0>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <12 0>;
+ interrupt-names = "host_wake";
+ };
diff --git a/Documentation/devicetree/bindings/coresight/coresight.txt b/Documentation/devicetree/bindings/coresight/coresight.txt
index c830bc4..25219cd 100644
--- a/Documentation/devicetree/bindings/coresight/coresight.txt
+++ b/Documentation/devicetree/bindings/coresight/coresight.txt
@@ -24,16 +24,12 @@
- reg-names : names corresponding to each reg property value. The reg-names that
need to be used with corresponding compatible string for a coresight device
are:
- - for coresight tmc-etr device:
+ - for coresight tmc-etr or tmc-etf device:
compatible : should be "arm,coresight-tmc"
reg-names : should be:
- "tmc-etr-base" - physical base address of tmc-etr registers
- "tmc-etr-bam-base" - physical base address of tmc-etr bam
- registers
- - for coresight tmc-etf device:
- compatible : should be "arm,coresight-tmc"
- reg-names : should be:
- "tmc-etf-base" - physical base address of tmc-etf registers
+ "tmc-base" - physical base address of tmc configuration
+ registers
+ "bam-base" - physical base address of tmc-etr bam registers
- for coresight tpiu device:
compatible : should be "arm,coresight-tpiu"
reg-names : should be:
@@ -41,24 +37,22 @@
- for coresight replicator device
compatible : should be "qcom,coresight-replicator"
reg-names : should be:
- "replicator-base" - physical base address of replicator registers
+ "replicator-base" - physical base address of replicator
+ registers
- for coresight funnel devices
compatible : should be "arm,coresight-funnel"
reg-names : should be:
- "funnel-<val>-base" - physical base address of funnel registers
- where <val> can be "merg", "in0", "in1", "kpss", "a7ss" or
- "mmss"
+ "funnel-base" - physical base address of funnel registers
- for coresight stm trace device
compatible : should be "arm,coresight-stm"
reg-names : should be:
- "stm-base" - physical base address of stm registers
+ "stm-base" - physical base address of stm configuration
+ registers
"stm-data-base" - physical base address of stm data registers
- for coresight etm trace devices
compatible : should be "arm,coresight-etm"
reg-names : should be:
- "etm<num>-base" - physical base address of etm registers in
- general where <num> is the number of etm components or cores
- present for more than one cpu core
+ "etm-base" - physical base address of etm registers
- for coresight csr device:
compatible : should be "qcom,coresight-csr"
reg-names : should be:
@@ -66,12 +60,7 @@
- for coresight cti devices:
compatible : should be "arm,coresight-cti"
reg-names : should be:
- "cti<num>-base" - physical base address of cti registers in general
- where <num> is the cti component number for more than one
- cti components
- "cti-cpu<num>-base" - physical base address of cti cpu registers
- where <num> is the component number for more than one cpu core
- "cti-l2" - physical base address of L2 cti registers
+ "cti<num>-base" - physical base address of cti registers
- coresight-id : unique integer identifier for the component
- coresight-name : unique descriptive name of the component
- coresight-nr-inports : number of input ports on the component
@@ -99,6 +88,23 @@
- qcom,reset-flush-race : indicates if a race exists between flushing and ddr
being put into self-refresh during watchdog reset
- qcom,write-64bit : only 64bit data writes supported by stm
+- vdd-supply: phandle to the regulator device tree node. Used for tpiu component
+- qcom,vdd-voltage-level : specifies voltage level for vdd supply. Should be
+ specified in pairs (min, max) with units being uV
+- qcom,vdd-current-level : specifies current load levels for vdd supply. Should
+ be specified in paris (lpm, hpm) with units being uA
+- qcom,seta-gpios : specifies gpios included in set A that are routed to the
+ mictor connector. Used for tpiu component
+- qcom,seta-gpios-func : active function select for set A gpios
+- qcom,seta-gpios-drv : active drive strength for set A gpios
+- qcom,seta-gpios-pull : active pull configuration for set A gpios
+- qcom,seta-gpios-dir : active direction for set A gpios
+- qcom,setb-gpios : specifies gpios included in set B that are routed to the
+ mictor connector. Used for tpiu component
+- qcom,setb-gpios-func : active function select for set B gpios
+- qcom,setb-gpios-drv : active drive strength for set B gpios
+- qcom,setb-gpios-pull : active pull configuration for set B gpios
+- qcom,setb-gpios-dir : active direction for set B gpios
Examples:
@@ -107,7 +113,7 @@
compatible = "arm,coresight-tmc";
reg = <0xfc322000 0x1000>,
<0xfc37c000 0x3000>;
- reg-names = "tmc-etr-base", "tmc-etr-bam-base";
+ reg-names = "tmc-base", "bam-base";
coresight-id = <0>;
coresight-name = "coresight-tmc-etr";
@@ -123,13 +129,18 @@
coresight-id = <1>;
coresight-name = "coresight-tpiu";
coresight-nr-inports = <1>;
+
+ vdd-supply = <&pm8941_l21>;
+
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <9000 800000>;
};
2. Links
funnel_merg: funnel@fc31b000 {
compatible = "arm,coresight-funnel";
reg = <0xfc31b000 0x1000>;
- reg-names = "funnel-merg-base";
+ reg-names = "funnel-base";
coresight-id = <4>;
coresight-name = "coresight-funnel-merg";
@@ -142,7 +153,7 @@
funnel_in0: funnel@fc319000 {
compatible = "arm,coresight-funnel";
reg = <0xfc319000 0x1000>;
- reg-names = "funnel-in0-base";
+ reg-names = "funnel-base";
coresight-id = <5>;
coresight-name = "coresight-funnel-in0";
@@ -170,7 +181,7 @@
etm0: etm@fc33c000 {
compatible = "arm,coresight-etm";
reg = <0xfc33c000 0x1000>;
- reg-names = "etm0-base";
+ reg-names = "etm-base";
coresight-id = <10>;
coresight-name = "coresight-etm0";
@@ -186,7 +197,7 @@
cti0: cti@fc308000 {
compatible = "arm,coresight-cti";
reg = <0xfc308000 0x1000>;
- reg-names = "cti0-base";
+ reg-names = "cti-base";
coresight-id = <15>;
coresight-name = "coresight-cti0";
@@ -196,7 +207,7 @@
cti1: cti@fc309000 {
compatible = "arm,coresight-cti";
reg = <0xfc309000 0x1000>;
- reg-names = "cti1-base";
+ reg-names = "cti-base";
coresight-id = <16>;
coresight-name = "coresight-cti1";
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..497471a 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.
@@ -97,6 +99,9 @@
settings used to setup MDSS QoS for best performance.
The key used should be offset from "mdp_phys" register
defined in reg property.
+- qcom,mdss-rot-block-size: The size of a memory block (in pixels) to be used
+ by the rotator. If this property is not specified,
+ then a default value of 128 pixels would be used.
Optional subnodes:
Child nodes representing the frame buffer virtual devices.
@@ -115,7 +120,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>,
@@ -129,6 +134,7 @@
qcom,mdss-pipe-rgb-fetch-id = <16 17 18>;
qcom,mdss-pipe-dma-fetch-id = <10 13>;
qcom,mdss-smp-data = <22 4096>;
+ qcom,mdss-rot-block-size = <64>;
qcom,mdss-ctl-off = <0x00000600 0x00000700 0x00000800
0x00000900 0x0000A00>;
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp.txt b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
index b9bac1d..812a895 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
@@ -51,12 +51,17 @@
Required properties for RGB led:
- qcom,mode: mode the led should operate in, options 0 = PWM, 1 = LPG
- qcom,pwm-channel: pwm channel the led will operate on
+
+Required properties for PWM mode only:
- qcom,pwm-us: time the pwm device will modulate at (us)
Required properties for LPG mode only:
-- qcom,duty-ms: duty cycle time the led will operate at (ms)
- qcom,duty-pcts: array of values for duty cycle to go through
- qcom,start-idx: starting point duty-pcts array
+- qcom,pause-lo: pause at low end of cycle
+- qcom,pause-hi: pause at high end of cycle
+- qcom,ramp-step-ms: step between each cycle (ms)
+- qcom,lut-flags: flags to be used in lut configuration
Optional properties for RGB led:
- linux,default-trigger: trigger the led from external modules such as display
@@ -90,12 +95,14 @@
linux,name = "led:rgb_blue";
qcom,mode = <1>;
qcom,pwm-channel = <4>;
- qcom,pwm-us = <1000>;
- qcom,duty-ms = <20>;
qcom,start-idx = <1>;
qcom,idx-len = <10>;
qcom,duty-pcts = [00 19 32 4B 64
64 4B 32 19 00];
+ qcom,lut-flags = <3>;
+ qcom,pause-lo = <0>;
+ qcom,pause-hi = <0>;
+ qcom,ramp-step-ms = <255>;
qcom,max-current = <12>;
qcom,default-state = "on";
qcom,turn-off-delay-ms = <500>;
diff --git a/Documentation/devicetree/bindings/media/video/msm-csid.txt b/Documentation/devicetree/bindings/media/video/msm-csid.txt
index 76a2825..50b085b 100644
--- a/Documentation/devicetree/bindings/media/video/msm-csid.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-csid.txt
@@ -10,6 +10,10 @@
- interrupts : should contain the csid interrupt.
- interrupt-names : should specify relevant names to each interrupts
property defined.
+- qcom,csi-vdd-voltage : should specify voltage level
+ for mipi csi in uV.
+- qcom,mipi-csi-vdd-supply : should contain regulator to be used for
+ this csid core
Example:
@@ -20,4 +24,6 @@
reg-names = "csid";
interrupts = <0 51 0>;
interrupt-names = "csiphy";
+ qcom,csi-vdd-voltage = <1800000>;
+ qcom,mipi-csi-vdd-supply = <&pm8941_l12>;
};
diff --git a/Documentation/devicetree/bindings/misc/qpnp-misc.txt b/Documentation/devicetree/bindings/misc/qpnp-misc.txt
new file mode 100644
index 0000000..34c344a
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/qpnp-misc.txt
@@ -0,0 +1,27 @@
+QPNP-MISC
+
+QPNP-MISC provides a way to read the PMIC part number and revision.
+
+Required properties:
+- compatible : should be "qcom,qpnp-misc"
+- reg : offset and length of the PMIC peripheral register map.
+
+Example:
+ qcom,spmi@fc4c0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+
+ qcom,pm8941@0 {
+ spmi-slave-container;
+ reg = <0x0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qcom,misc@900 {
+ compatible = "qcom,qpnp-misc";
+ reg = <0x900 0x100>;
+ };
+ }
+ };
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt
index d5937cf..87281f7 100644
--- a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt
+++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt
@@ -12,6 +12,8 @@
Required "interrupt-names" are "hc_irq" and "pwr_irq".
- <supply-name>-supply: phandle to the regulator device tree node
Required "supply-name" are "vdd" and "vdd-io".
+ - qcom,clk-rates: this is an array that specifies supported SDHC clock
+ frequencies for a slot, Units - Hz.
Required alias:
- The slot number is specified via an alias with the following format
@@ -112,6 +114,7 @@
qcom,bus-width = <4>;
qcom,nonremovable;
qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 200000000>;
gpios = <&msmgpio 40 0>, /* CLK */
<&msmgpio 39 0>, /* CMD */
@@ -120,7 +123,6 @@
<&msmgpio 36 0>, /* DATA2 */
<&msmgpio 35 0>; /* DATA3 */
qcom,gpio-names = "CLK", "CMD", "DAT0", "DAT1", "DAT2", "DAT3";
- qcom,cpu-dma-latency-us = <200>;
};
sdhc_2: qcom,sdhc@f98a4900 {
@@ -143,6 +145,7 @@
vdd-io-supply = <&pm8941_l13>;
qcom,bus-width = <4>;
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 200000000>;
qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
diff --git a/Documentation/devicetree/bindings/net/wireless/ath/ath6kl.txt b/Documentation/devicetree/bindings/net/wireless/ath/ath6kl.txt
index 7b9feae..6c3e98e 100644
--- a/Documentation/devicetree/bindings/net/wireless/ath/ath6kl.txt
+++ b/Documentation/devicetree/bindings/net/wireless/ath/ath6kl.txt
@@ -2,15 +2,15 @@
Required properties:
- compatible: Can be "qca,ar6004-sdio" for SDIO device and
- "qca,ar6004-hsic" for HSIC devcie.
+ "qca,ar6004-hsic" for HSIC device. For AR6003, "qca,ar6003-sdio" can be
+ used.
- qca,chip-pwd-l-gpios: specify GPIO for CHIP_PWD_L.
Optional Properties:
- cell-index: WLAN Hardware index.
- qca,pm-enable-gpios: Specify this GPIO if internal PMU needs to be used.
- - qca,ar6004-vbatt-supply: Specify this if VBATT is provided through a
- regulator.
- - qca,ar6004-vdd-io-supply: Specify this if VDD-IO is provided through a
+ - qca,vbatt-supply: Specify this if VBATT is provided through a regulator.
+ - qca,vdd-io-supply: Specify this if VDD-IO is provided through a
regulator.
Example:
@@ -20,5 +20,5 @@
compatible = "qca,ar6004-sdio";
qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+ qca,vdd-io-supply = <&pm8019_l11>;
};
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/thermal/qpnp-adc-tm.txt b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
index f1f4e94..3854598 100644
--- a/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
+++ b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
@@ -20,6 +20,13 @@
- qcom,adc-bit-resolution : Bit resolution of the ADC.
- qcom,adc-vdd-reference : Voltage reference used by the ADC.
+Optional properties:
+- qcom,thermal-node : If present a thermal node is created and the channel is registered as
+ part of the thermal sysfs which allows clients to use the thermal framework
+ to set temperature thresholds and receive notification when the temperature
+ crosses a set threshold, read temperature and enable/set trip types supported
+ by the thermal framework.
+
Channel nodes
NOTE: Atleast one Channel node is required.
@@ -105,7 +112,7 @@
qcom,adc-bit-resolution = <15>;
qcom,adc-vdd-reference = <1800>;
- /* Channel Node */
+ /* Channel Node to be registered as part of thermal sysfs */
chan@b5 {
label = "pa_therm1";
reg = <0xb5>;
@@ -116,5 +123,19 @@
qcom,hw-settle-time = <0>;
qcom,fast-avg-setup = <0>;
qcom,btm-channel-number = <0x70>;
+ qcom,thermal-node;
};
+
+ /* Channel Node */
+ chan@6 {
+ label = "vbat_sns";
+ reg = <6>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <3>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x78>;
+ };
};
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..effc7c5 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";
@@ -630,5 +678,43 @@
compatible = "qcom,qpnp-regulator";
status = "disabled";
};
+
+ qcom,leds@d300 {
+ compatible = "qcom,leds-qpnp";
+ status = "disable";
+ reg = <0xd300 0x100>;
+ label = "flash";
+ pm8226_flash0: qcom,flash_0 {
+ qcom,max-current = <1000>;
+ qcom,default-state = "off";
+ qcom,headroom = <0>;
+ qcom,duration = <1280>;
+ qcom,clamp-curr = <200>;
+ qcom,startup-dly = <1>;
+ qcom,safety-timer;
+ label = "flash";
+ linux,default-trigger =
+ "flash0_trigger";
+ qcom,id = <1>;
+ linux,name = "led:flash_0";
+ qcom,current = <625>;
+ };
+
+ pm8226_flash1: qcom,flash_1 {
+ qcom,max-current = <1000>;
+ qcom,default-state = "off";
+ qcom,headroom = <0>;
+ qcom,duration = <1280>;
+ qcom,clamp-curr = <200>;
+ qcom,startup-dly = <1>;
+ qcom,safety-timer;
+ linux,default-trigger =
+ "flash1_trigger";
+ label = "flash";
+ qcom,id = <2>;
+ linux,name = "led:flash_1";
+ qcom,current = <625>;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 320c3e4a..5ccdbf3 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -22,6 +22,11 @@
#address-cells = <1>;
#size-cells = <1>;
+ pm8941_misc: qcom,misc@900 {
+ compatible = "qcom,qpnp-misc";
+ reg = <0x900 0x100>;
+ };
+
qcom,revid@100 {
compatible = "qcom,qpnp-revid";
reg = <0x100 0x100>;
@@ -825,6 +830,30 @@
qcom,btm-channel-number = <0x68>;
};
+ chan@8 {
+ label = "die_temp";
+ reg = <8>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <1>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x88>;
+ };
+
+ chan@6 {
+ label = "vbat_sns";
+ reg = <6>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <3>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x90>;
+ };
+
chan@b5 {
label = "pa_therm1";
reg = <0xb5>;
@@ -835,6 +864,7 @@
qcom,hw-settle-time = <2>;
qcom,fast-avg-setup = <0>;
qcom,btm-channel-number = <0x70>;
+ qcom,thermal-node;
};
chan@b7 {
@@ -847,6 +877,7 @@
qcom,hw-settle-time = <2>;
qcom,fast-avg-setup = <0>;
qcom,btm-channel-number = <0x78>;
+ qcom,thermal-node;
};
chan@b4 {
@@ -859,6 +890,20 @@
qcom,hw-settle-time = <2>;
qcom,fast-avg-setup = <0>;
qcom,btm-channel-number = <0x80>;
+ qcom,thermal-node;
+ };
+
+ chan@b3 {
+ label = "msm_therm";
+ reg = <0xb3>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x98>;
+ qcom,thermal-node;
};
};
};
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-cdp-mtp-qrd.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-cdp-mtp-qrd.dtsi
new file mode 100644
index 0000000..b7f837f
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-cdp-mtp-qrd.dtsi
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/ {
+
+ led_flash0: qcom,camera-led-flash {
+ cell-index = <0>;
+ compatible = "qcom,camera-led-flash";
+ qcom,flash-type = <1>;
+ qcom,flash-source = <&pm8226_flash0 &pm8226_flash1>;
+ };
+};
+
+&cci {
+
+ actuator0: qcom,actuator@6e {
+ cell-index = <3>;
+ reg = <0x6c 0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ };
+
+ qcom,camera@6f {
+ compatible = "qcom,ov8825";
+ reg = <0x6f>;
+ qcom,slave-id = <0x6c 0x300a 0x8825>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,led-flash-src = <&led_flash0>;
+ qcom,mount-angle = <90>;
+ qcom,sensor-name = "ov8825";
+ cam_vdig-supply = <&pm8226_l5>;
+ cam_vana-supply = <&pm8226_l19>;
+ cam_vio-supply = <&pm8226_lvs1>;
+ cam_vaf-supply = <&pm8226_l15>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 26 0>,
+ <&msmgpio 37 0>,
+ <&msmgpio 36 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x1f>;
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <0>;
+ };
+
+ qcom,camera@6d {
+ compatible = "qcom,ov9724";
+ reg = <0x6d>;
+ qcom,slave-id = <0x20 0x0 0x9724>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,sensor-name = "ov9724";
+ cam_vdig-supply = <&pm8226_l5>;
+ cam_vana-supply = <&pm8226_l19>;
+ cam_vio-supply = <&pm8226_lvs1>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-type = <0 1 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 26 0>,
+ <&msmgpio 28 0>,
+ <&msmgpio 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET",
+ "CAM_STANDBY";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 4000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x3>;
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+};
diff --git a/arch/arm/boot/dts/msm8226-camera.dtsi b/arch/arm/boot/dts/msm8226-camera.dtsi
index 2a9fdf2..e94459e 100644
--- a/arch/arm/boot/dts/msm8226-camera.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera.dtsi
@@ -1,4 +1,5 @@
-/* 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
@@ -11,8 +12,125 @@
*/
/ {
- qcom,cam_server {
- compatible = "qcom,cam_server";
- reg = <0xfd8C0000 0x10000>;
+ qcom,msm-cam@fd8c0000 {
+ compatible = "qcom,msm-cam";
+ reg = <0xfd8c0000 0x10000>;
+ reg-names = "msm-cam";
+ };
+
+ qcom,csiphy@fda0ac00 {
+ cell-index = <0>;
+ compatible = "qcom,csiphy";
+ reg = <0xfda0ac00 0x200>;
+ reg-names = "csiphy";
+ interrupts = <0 78 0>;
+ interrupt-names = "csiphy";
+ };
+
+ qcom,csiphy@fda0b000 {
+ cell-index = <1>;
+ compatible = "qcom,csiphy";
+ reg = <0xfda0b000 0x200>;
+ reg-names = "csiphy";
+ interrupts = <0 79 0>;
+ interrupt-names = "csiphy";
+ };
+
+ qcom,csid@fda08000 {
+ cell-index = <0>;
+ compatible = "qcom,csid";
+ reg = <0xfda08000 0x100>;
+ reg-names = "csid";
+ interrupts = <0 51 0>;
+ interrupt-names = "csid";
+ qcom,csi-vdd-voltage = <1200000>;
+ qcom,mipi-csi-vdd-supply = <&pm8226_l4>;
+ };
+
+ qcom,csid@fda08400 {
+ cell-index = <1>;
+ compatible = "qcom,csid";
+ reg = <0xfda08400 0x100>;
+ reg-names = "csid";
+ interrupts = <0 52 0>;
+ interrupt-names = "csid";
+ qcom,csi-vdd-voltage = <1200000>;
+ qcom,mipi-csi-vdd-supply = <&pm8226_l4>;
+ };
+
+ qcom,ispif@fda0a000 {
+ cell-index = <0>;
+ compatible = "qcom,ispif";
+ reg = <0xfda0a000 0x500>;
+ reg-names = "ispif";
+ interrupts = <0 55 0>;
+ interrupt-names = "ispif";
+ };
+
+ qcom,vfe@fda10000 {
+ cell-index = <0>;
+ compatible = "qcom,vfe40";
+ reg = <0xfda10000 0x1000>,
+ <0xfda40000 0x200>;
+ reg-names = "vfe", "vfe_vbif";
+ interrupts = <0 57 0>;
+ interrupt-names = "vfe";
+ vdd-supply = <&gdsc_vfe>;
+ };
+
+ qcom,jpeg@fda1c000 {
+ cell-index = <0>;
+ compatible = "qcom,jpeg";
+ reg = <0xfda1c000 0x400>;
+ reg-names = "jpeg";
+ interrupts = <0 59 0>;
+ interrupt-names = "jpeg";
+ vdd-supply = <&gdsc_jpeg>;
+ };
+
+ qcom,irqrouter@fda00000 {
+ cell-index = <0>;
+ compatible = "qcom,irqrouter";
+ reg = <0xfda00000 0x100>;
+ reg-names = "irqrouter";
+ };
+
+ qcom,cpp@fda04000 {
+ cell-index = <0>;
+ compatible = "qcom,cpp";
+ reg = <0xfda04000 0x100>,
+ <0xfda40000 0x200>,
+ <0xfda18000 0x008>;
+ reg-names = "cpp", "cpp_vbif", "cpp_hw";
+ interrupts = <0 49 0>;
+ interrupt-names = "cpp";
+ vdd-supply = <&gdsc_vfe>;
+ };
+
+ cci: qcom,cci@fda0c000 {
+ cell-index = <0>;
+ compatible = "qcom,cci";
+ reg = <0xfda0c000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "cci";
+ interrupts = <0 50 0>;
+ interrupt-names = "cci";
+ gpios = <&msmgpio 29 0>,
+ <&msmgpio 30 0>;
+ qcom,gpio-tbl-num = <0 1>;
+ qcom,gpio-tbl-flags = <1 1>;
+ qcom,gpio-tbl-label = "CCI_I2C_DATA0",
+ "CCI_I2C_CLK0";
+ qcom,hw-thigh = <78>;
+ qcom,hw-tlow = <114>;
+ qcom,hw-tsu-sto = <28>;
+ qcom,hw-tsu-sta = <28>;
+ qcom,hw-thd-dat = <10>;
+ qcom,hw-thd-sta = <77>;
+ qcom,hw-tbuf = <118>;
+ qcom,hw-scl-stretch-en = <0>;
+ qcom,hw-trdhld = <6>;
+ qcom,hw-tsp = <1>;
};
};
diff --git a/arch/arm/boot/dts/msm8226-cdp.dts b/arch/arm/boot/dts/msm8226-cdp.dts
index 800cd8f..04b7c7e 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dts
+++ b/arch/arm/boot/dts/msm8226-cdp.dts
@@ -13,6 +13,7 @@
/dts-v1/;
/include/ "msm8226.dtsi"
/include/ "dsi-panel-nt35590-720p-video.dtsi"
+/include/ "msm8226-camera-sensor-cdp-mtp-qrd.dtsi"
/ {
model = "Qualcomm MSM 8226 CDP";
@@ -89,6 +90,28 @@
};
sound {
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "SPK_OUT", "MCLK",
+ "SPK_OUT", "EXT_VDD_SPKR",
+ "AMIC1", "MIC BIAS1 Internal1",
+ "MIC BIAS1 Internal1", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCLeft Headset Mic",
+ "DMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic1",
+ "DMIC2", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic2",
+ "DMIC3", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic3",
+ "DMIC4", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic4";
+
qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
};
diff --git a/arch/arm/boot/dts/msm8226-coresight.dtsi b/arch/arm/boot/dts/msm8226-coresight.dtsi
index b891d3d..35d329c 100644
--- a/arch/arm/boot/dts/msm8226-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8226-coresight.dtsi
@@ -15,7 +15,7 @@
compatible = "arm,coresight-tmc";
reg = <0xfc322000 0x1000>,
<0xfc37c000 0x3000>;
- reg-names = "tmc-etr-base", "tmc-etr-bam-base";
+ reg-names = "tmc-base", "bam-base";
qcom,memory-reservation-type = "EBI1";
qcom,memory-reservation-size = <0x100000>; /* 1M EBI1 buffer */
@@ -52,7 +52,7 @@
tmc_etf: tmc@fc307000 {
compatible = "arm,coresight-tmc";
reg = <0xfc307000 0x1000>;
- reg-names = "tmc-etf-base";
+ reg-names = "tmc-base";
coresight-id = <3>;
coresight-name = "coresight-tmc-etf";
@@ -67,7 +67,7 @@
funnel_merg: funnel@fc31b000 {
compatible = "arm,coresight-funnel";
reg = <0xfc31b000 0x1000>;
- reg-names = "funnel-merg-base";
+ reg-names = "funnel-base";
coresight-id = <4>;
coresight-name = "coresight-funnel-merg";
@@ -80,7 +80,7 @@
funnel_in0: funnel@fc319000 {
compatible = "arm,coresight-funnel";
reg = <0xfc319000 0x1000>;
- reg-names = "funnel-in0-base";
+ reg-names = "funnel-base";
coresight-id = <5>;
coresight-name = "coresight-funnel-in0";
@@ -93,7 +93,7 @@
funnel_in1: funnel@fc31a000 {
compatible = "arm,coresight-funnel";
reg = <0xfc31a000 0x1000>;
- reg-names = "funnel-in1-base";
+ reg-names = "funnel-base";
coresight-id = <6>;
coresight-name = "coresight-funnel-in1";
@@ -106,7 +106,7 @@
funnel_a7ss: funnel@fc345000 {
compatible = "arm,coresight-funnel";
reg = <0xfc345000 0x1000>;
- reg-names = "funnel-a7ss-base";
+ reg-names = "funnel-base";
coresight-id = <7>;
coresight-name = "coresight-funnel-a7ss";
@@ -119,7 +119,7 @@
funnel_mmss: funnel@fc364000 {
compatible = "arm,coresight-funnel";
reg = <0xfc364000 0x1000>;
- reg-names = "funnel-mmss-base";
+ reg-names = "funnel-base";
coresight-id = <8>;
@@ -147,7 +147,7 @@
etm0: etm@fc33c000 {
compatible = "arm,coresight-etm";
reg = <0xfc33c000 0x1000>;
- reg-names = "etm0-base";
+ reg-names = "etm-base";
coresight-id = <10>;
coresight-name = "coresight-etm0";
@@ -162,7 +162,7 @@
etm1: etm@fc33d000 {
compatible = "arm,coresight-etm";
reg = <0xfc33d000 0x1000>;
- reg-names = "etm1-base";
+ reg-names = "etm-base";
coresight-id = <11>;
coresight-name = "coresight-etm1";
@@ -177,7 +177,7 @@
etm2: etm@fc33e000 {
compatible = "arm,coresight-etm";
reg = <0xfc33e000 0x1000>;
- reg-names = "etm2-base";
+ reg-names = "etm-base";
coresight-id = <12>;
coresight-name = "coresight-etm2";
@@ -192,7 +192,7 @@
etm3: etm@fc33f000 {
compatible = "arm,coresight-etm";
reg = <0xfc33f000 0x1000>;
- reg-names = "etm3-base";
+ reg-names = "etm-base";
coresight-id = <13>;
coresight-name = "coresight-etm3";
@@ -219,7 +219,7 @@
cti0: cti@fc308000 {
compatible = "arm,coresight-cti";
reg = <0xfc308000 0x1000>;
- reg-names = "cti0-base";
+ reg-names = "cti-base";
coresight-id = <15>;
coresight-name = "coresight-cti0";
@@ -229,7 +229,7 @@
cti1: cti@fc309000 {
compatible = "arm,coresight-cti";
reg = <0xfc309000 0x1000>;
- reg-names = "cti1-base";
+ reg-names = "cti-base";
coresight-id = <16>;
coresight-name = "coresight-cti1";
@@ -239,7 +239,7 @@
cti2: cti@fc30a000 {
compatible = "arm,coresight-cti";
reg = <0xfc30a000 0x1000>;
- reg-names = "cti2-base";
+ reg-names = "cti-base";
coresight-id = <17>;
coresight-name = "coresight-cti2";
@@ -249,7 +249,7 @@
cti3: cti@fc30b000 {
compatible = "arm,coresight-cti";
reg = <0xfc30b000 0x1000>;
- reg-names = "cti3-base";
+ reg-names = "cti-base";
coresight-id = <18>;
coresight-name = "coresight-cti3";
@@ -259,7 +259,7 @@
cti4: cti@fc30c000 {
compatible = "arm,coresight-cti";
reg = <0xfc30c000 0x1000>;
- reg-names = "cti4-base";
+ reg-names = "cti-base";
coresight-id = <19>;
coresight-name = "coresight-cti4";
@@ -269,7 +269,7 @@
cti5: cti@fc30d000 {
compatible = "arm,coresight-cti";
reg = <0xfc30d000 0x1000>;
- reg-names = "cti5-base";
+ reg-names = "cti-base";
coresight-id = <20>;
coresight-name = "coresight-cti5";
@@ -279,7 +279,7 @@
cti6: cti@fc30e000 {
compatible = "arm,coresight-cti";
reg = <0xfc30e000 0x1000>;
- reg-names = "cti6-base";
+ reg-names = "cti-base";
coresight-id = <21>;
coresight-name = "coresight-cti6";
@@ -289,7 +289,7 @@
cti7: cti@fc30f000 {
compatible = "arm,coresight-cti";
reg = <0xfc30f000 0x1000>;
- reg-names = "cti7-base";
+ reg-names = "cti-base";
coresight-id = <22>;
coresight-name = "coresight-cti7";
@@ -299,7 +299,7 @@
cti8: cti@fc310000 {
compatible = "arm,coresight-cti";
reg = <0xfc310000 0x1000>;
- reg-names = "cti8-base";
+ reg-names = "cti-base";
coresight-id = <23>;
coresight-name = "coresight-cti8";
@@ -309,7 +309,7 @@
cti_l2: cti@fc340000 {
compatible = "arm,coresight-cti";
reg = <0xfc340000 0x1000>;
- reg-names = "cti-l2-base";
+ reg-names = "cti-base";
coresight-id = <24>;
coresight-name = "coresight-cti-l2";
@@ -319,7 +319,7 @@
cti_cpu0: cti@fc341000 {
compatible = "arm,coresight-cti";
reg = <0xfc341000 0x1000>;
- reg-names = "cti-cpu0-base";
+ reg-names = "cti-base";
coresight-id = <25>;
coresight-name = "coresight-cti-cpu0";
@@ -329,7 +329,7 @@
cti_cpu1: cti@fc342000 {
compatible = "arm,coresight-cti";
reg = <0xfc342000 0x1000>;
- reg-names = "cti-cpu1-base";
+ reg-names = "cti-base";
coresight-id = <26>;
coresight-name = "coresight-cti-cpu1";
@@ -339,7 +339,7 @@
cti_cpu2: cti@fc343000 {
compatible = "arm,coresight-cti";
reg = <0xfc343000 0x1000>;
- reg-names = "cti-cpu2-base";
+ reg-names = "cti-base";
coresight-id = <27>;
coresight-name = "coresight-cti-cpu2";
@@ -349,7 +349,7 @@
cti_cpu3: cti@fc344000 {
compatible = "arm,coresight-cti";
reg = <0xfc344000 0x1000>;
- reg-names = "cti-cpu3-base";
+ reg-names = "cti-base";
coresight-id = <28>;
coresight-name = "coresight-cti-cpu3";
diff --git a/arch/arm/boot/dts/msm8226-gpu.dtsi b/arch/arm/boot/dts/msm8226-gpu.dtsi
index 2734726..ebd7749 100644
--- a/arch/arm/boot/dts/msm8226-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8226-gpu.dtsi
@@ -24,9 +24,9 @@
qcom,msm-bus,num-paths = <2>;
qcom,msm-bus,vectors-KBps =
<26 512 0 0>, <89 604 0 0>,
- <26 512 0 1600000>, <89 604 0 6400000>,
- <26 512 0 3200000>, <89 604 0 12800000>,
- <26 512 0 4264000>, <89 604 0 12800000>;
+ <26 512 0 1600000>, <89 604 0 3200000>,
+ <26 512 0 3200000>, <89 604 0 5120000>,
+ <26 512 0 4256000>, <89 604 0 6400000>;
/* GDSC oxili regulators */
vddcx-supply = "\0";
diff --git a/arch/arm/boot/dts/msm8226-mdss.dtsi b/arch/arm/boot/dts/msm8226-mdss.dtsi
index 21ed66a..9c76512 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>;
@@ -33,6 +34,7 @@
qcom,mdss-dspp-off = <0x00004600>;
qcom,mdss-wb-off = <0x00011100 0x00013100>;
qcom,mdss-intf-off = <0x00000000 0x00021300>;
+ qcom,mdss-rot-block-size = <64>;
qcom,vbif-settings = <0x004 0x00000001>,
<0x0D8 0x00000707>,
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/msm8226-mtp.dts
index 3d1fe19..be831b4 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-mtp.dts
@@ -13,6 +13,7 @@
/dts-v1/;
/include/ "msm8226.dtsi"
/include/ "dsi-panel-nt35590-720p-video.dtsi"
+/include/ "msm8226-camera-sensor-cdp-mtp-qrd.dtsi"
/ {
model = "Qualcomm MSM 8226 MTP";
@@ -89,6 +90,20 @@
};
sound {
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "SPK_OUT", "MCLK",
+ "SPK_OUT", "EXT_VDD_SPKR",
+ "AMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS1 External",
+ "MIC BIAS1 External", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCLeft Headset Mic";
+
qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
};
@@ -156,6 +171,10 @@
&spmi_bus {
qcom,pm8226@1 {
+ qcom,leds@d300 {
+ status = "okay";
+ };
+
qcom,leds@d800 {
status = "okay";
qcom,wled_0 {
diff --git a/arch/arm/boot/dts/msm8226-qrd.dts b/arch/arm/boot/dts/msm8226-qrd.dts
index 4fa37d6..6bd5ea9 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dts
+++ b/arch/arm/boot/dts/msm8226-qrd.dts
@@ -13,6 +13,7 @@
/dts-v1/;
/include/ "msm8226.dtsi"
/include/ "dsi-panel-nt35590-720p-video.dtsi"
+/include/ "msm8226-camera-sensor-cdp-mtp-qrd.dtsi"
/ {
model = "Qualcomm MSM 8226 QRD";
@@ -89,6 +90,20 @@
};
sound {
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "SPK_OUT", "MCLK",
+ "SPK_OUT", "EXT_VDD_SPKR",
+ "AMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS1 External",
+ "MIC BIAS1 External", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCLeft Headset Mic";
+
qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
};
@@ -159,6 +174,10 @@
&spmi_bus {
qcom,pm8226@1 {
+ qcom,leds@d300 {
+ status = "okay";
+ };
+
qcom,leds@d800 {
status = "okay";
qcom,wled_0 {
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index c39d987..448a5be 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -10,18 +10,16 @@
* GNU General Public License for more details.
*/
-/* QPNP controlled regulators: */
+/* SPM controlled regulators: */
&spmi_bus {
qcom,pm8226@1 {
- pm8226_s2: regulator@1700 {
- status = "okay";
+ pm8226_s2: spm-regulator@1700 {
+ compatible = "qcom,spm-regulator";
regulator-name = "8226_s2";
- qcom,enable-time = <500>;
- qcom,system-load = <100000>;
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1150000>;
- regulator-always-on;
+ reg = <0x1700 0x100>;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1275000>;
};
};
};
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index f975a08..6322b8f 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -12,6 +12,7 @@
/include/ "skeleton.dtsi"
/include/ "msm8226-ion.dtsi"
+/include/ "msm8226-camera.dtsi"
/include/ "msm-gdsc.dtsi"
/include/ "msm8226-iommu.dtsi"
/include/ "msm8226-pm.dtsi"
@@ -227,29 +228,6 @@
sound {
compatible = "qcom,msm8226-audio-tapan";
qcom,model = "msm8226-tapan-snd-card";
-
- qcom,audio-routing =
- "RX_BIAS", "MCLK",
- "LDO_H", "MCLK",
- "SPK_OUT", "MCLK",
- "SPK_OUT", "EXT_VDD_SPKR",
- "AMIC1", "MIC BIAS1 Internal1",
- "MIC BIAS1 Internal1", "Handset Mic",
- "AMIC2", "MIC BIAS2 External",
- "MIC BIAS2 External", "Headset Mic",
- "AMIC3", "MIC BIAS2 External",
- "MIC BIAS2 External", "ANCRight Headset Mic",
- "AMIC4", "MIC BIAS2 External",
- "MIC BIAS2 External", "ANCLeft Headset Mic",
- "DMIC1", "MIC BIAS1 External",
- "MIC BIAS1 External", "Digital Mic1",
- "DMIC2", "MIC BIAS1 External",
- "MIC BIAS1 External", "Digital Mic2",
- "DMIC3", "MIC BIAS3 External",
- "MIC BIAS3 External", "Digital Mic3",
- "DMIC4", "MIC BIAS3 External",
- "MIC BIAS3 External", "Digital Mic4";
-
qcom,tapan-mclk-clk-freq = <9600000>;
};
@@ -402,6 +380,43 @@
qcom,msm-pcm-hostless {
compatible = "qcom,msm-pcm-hostless";
};
+ qcom,pronto@fb21b000 {
+ compatible = "qcom,pil-pronto";
+ reg = <0xfb21b000 0x3000>,
+ <0xfc401700 0x4>,
+ <0xfd485300 0xc>;
+ reg-names = "pmu_base", "clk_base", "halt_base";
+ interrupts = <0 149 1>;
+ vdd_pronto_pll-supply = <&pm8226_l12>;
+
+ qcom,firmware-name = "wcnss";
+ };
+ qcom,wcnss-wlan@fb000000 {
+ compatible = "qcom,wcnss_wlan";
+ reg = <0xfb000000 0x280000>;
+ reg-names = "wcnss_mmio";
+ interrupts = <0 145 0 0 146 0>;
+ interrupt-names = "wcnss_wlantx_irq", "wcnss_wlanrx_irq";
+
+ qcom,pronto-vddmx-supply = <&pm8226_l3>;
+ qcom,pronto-vddcx-supply = <&pm8226_s1>;
+ qcom,pronto-vddpx-supply = <&pm8226_l6>;
+ qcom,iris-vddxo-supply = <&pm8226_l10>;
+ qcom,iris-vddrfa-supply = <&pm8226_l24>;
+ qcom,iris-vddpa-supply = <&pm8226_l16>;
+ qcom,iris-vdddig-supply = <&pm8226_l24>;
+
+ gpios = <&msmgpio 40 0>, <&msmgpio 41 0>, <&msmgpio 42 0>, <&msmgpio 43 0>, <&msmgpio 44 0>;
+ qcom,has_pronto_hw;
+ };
+
+ qcom,msm-adsp-sensors {
+ compatible = "qcom,msm-adsp-sensors";
+ qcom,src-id = <11>;
+ qcom,dst-id = <604>;
+ qcom,ab = <32505856>;
+ qcom,ib = <32505856>;
+ };
qcom,wdt@f9017000 {
compatible = "qcom,msm-watchdog";
@@ -608,6 +623,10 @@
qcom,firmware-name = "wcnss";
};
+ qcom,iris-fm {
+ compatible = "qcom,iris_fm";
+ };
+
qcom,lpass@fe200000 {
compatible = "qcom,pil-q6v5-lpass";
reg = <0xfe200000 0x00100>,
@@ -641,6 +660,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,msm-mem-hole {
@@ -709,9 +734,9 @@
qcom,msm-rng-iface-clk;
};
- qcom,tz-log@fc5b82c {
+ qcom,tz-log@fe805720 {
compatible = "qcom,tz-log";
- reg = <0x0fc5b82c 0x1000>;
+ reg = <0x0fe805720 0x1000>;
};
jtag_mm0: jtagmm@fc33c000 {
diff --git a/arch/arm/boot/dts/msm8610-cdp.dts b/arch/arm/boot/dts/msm8610-cdp.dts
new file mode 100644
index 0000000..390c02a
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-cdp.dts
@@ -0,0 +1,26 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8610.dtsi"
+
+/ {
+ model = "Qualcomm MSM 8610 CDP";
+ compatible = "qcom,msm8610-cdp", "qcom,msm8610";
+ qcom,msm-id = <147 1 0>;
+
+ serial@f991f000 {
+ status = "ok";
+ };
+};
+
diff --git a/arch/arm/boot/dts/msm8610-coresight.dtsi b/arch/arm/boot/dts/msm8610-coresight.dtsi
index 298cb68..3612078 100644
--- a/arch/arm/boot/dts/msm8610-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8610-coresight.dtsi
@@ -15,7 +15,7 @@
compatible = "arm,coresight-tmc";
reg = <0xfc326000 0x1000>,
<0xfc37c000 0x3000>;
- reg-names = "tmc-etr-base", "tmc-etr-bam-base";
+ reg-names = "tmc-base", "bam-base";
qcom,memory-reservation-type = "EBI1";
qcom,memory-reservation-size = <0x100000>; /* 1M EBI1 buffer */
@@ -23,6 +23,7 @@
coresight-id = <0>;
coresight-name = "coresight-tmc-etr";
coresight-nr-inports = <1>;
+ coresight-ctis = <&cti0 &cti8>;
};
tpiu: tpiu@fc320000 {
@@ -51,7 +52,7 @@
tmc_etf: tmc@fc325000 {
compatible = "arm,coresight-tmc";
reg = <0xfc325000 0x1000>;
- reg-names = "tmc-etf-base";
+ reg-names = "tmc-base";
coresight-id = <3>;
coresight-name = "coresight-tmc-etf";
@@ -60,12 +61,13 @@
coresight-child-list = <&replicator>;
coresight-child-ports = <0>;
coresight-default-sink;
+ coresight-ctis = <&cti0 &cti8>;
};
funnel_merg: funnel@fc323000 {
compatible = "arm,coresight-funnel";
reg = <0xfc323000 0x1000>;
- reg-names = "funnel-merg-base";
+ reg-names = "funnel-base";
coresight-id = <4>;
coresight-name = "coresight-funnel-merg";
@@ -78,7 +80,7 @@
funnel_in0: funnel@fc321000 {
compatible = "arm,coresight-funnel";
reg = <0xfc321000 0x1000>;
- reg-names = "funnel-in0-base";
+ reg-names = "funnel-base";
coresight-id = <5>;
coresight-name = "coresight-funnel-in0";
@@ -91,7 +93,7 @@
funnel_in1: funnel@fc322000 {
compatible = "arm,coresight-funnel";
reg = <0xfc322000 0x1000>;
- reg-names = "funnel-in1-base";
+ reg-names = "funnel-base";
coresight-id = <6>;
coresight-name = "coresight-funnel-in1";
@@ -104,7 +106,7 @@
funnel_a7ss: funnel@fc355000 {
compatible = "arm,coresight-funnel";
reg = <0xfc355000 0x1000>;
- reg-names = "funnel-a7ss-base";
+ reg-names = "funnel-base";
coresight-id = <7>;
coresight-name = "coresight-funnel-a7ss";
@@ -128,15 +130,209 @@
coresight-child-ports = <7>;
};
+ etm0: etm@fc34c000 {
+ compatible = "arm,coresight-etm";
+ reg = <0xfc34c000 0x1000>;
+ reg-names = "etm-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 = "etm-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 = "etm-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 = "etm-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>;
qcom,blk-size = <3>;
};
+
+ cti0: cti@fc310000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc310000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <14>;
+ coresight-name = "coresight-cti0";
+ coresight-nr-inports = <0>;
+ };
+
+ cti1: cti@fc311000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc311000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <15>;
+ coresight-name = "coresight-cti1";
+ coresight-nr-inports = <0>;
+ };
+
+ cti2: cti@fc312000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc312000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <16>;
+ coresight-name = "coresight-cti2";
+ coresight-nr-inports = <0>;
+ };
+
+ cti3: cti@fc313000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc313000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <17>;
+ coresight-name = "coresight-cti3";
+ coresight-nr-inports = <0>;
+ };
+
+ cti4: cti@fc314000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc314000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <18>;
+ coresight-name = "coresight-cti4";
+ coresight-nr-inports = <0>;
+ };
+
+ cti5: cti@fc315000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc315000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <19>;
+ coresight-name = "coresight-cti5";
+ coresight-nr-inports = <0>;
+ };
+
+ cti6: cti@fc316000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc316000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <20>;
+ coresight-name = "coresight-cti6";
+ coresight-nr-inports = <0>;
+ };
+
+ cti7: cti@fc317000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc317000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <21>;
+ coresight-name = "coresight-cti7";
+ coresight-nr-inports = <0>;
+ };
+
+ cti8: cti@fc318000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc318000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <22>;
+ coresight-name = "coresight-cti8";
+ coresight-nr-inports = <0>;
+ };
+
+ cti_cpu0: cti@fc351000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc351000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <23>;
+ coresight-name = "coresight-cti-cpu0";
+ coresight-nr-inports = <0>;
+ };
+
+ cti_cpu1: cti@fc352000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc352000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <24>;
+ coresight-name = "coresight-cti-cpu1";
+ coresight-nr-inports = <0>;
+ };
+
+ cti_cpu2: cti@fc353000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc353000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <25>;
+ coresight-name = "coresight-cti-cpu2";
+ coresight-nr-inports = <0>;
+ };
+
+ cti_cpu3: cti@fc354000 {
+ compatible = "arm,coresight-cti";
+ reg = <0xfc354000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <26>;
+ coresight-name = "coresight-cti-cpu3";
+ coresight-nr-inports = <0>;
+ };
};
diff --git a/arch/arm/boot/dts/msm8610-iommu-domains.dtsi b/arch/arm/boot/dts/msm8610-iommu-domains.dtsi
index 52a8c47..0f48517 100644
--- a/arch/arm/boot/dts/msm8610-iommu-domains.dtsi
+++ b/arch/arm/boot/dts/msm8610-iommu-domains.dtsi
@@ -27,7 +27,7 @@
qcom,virtual-addr-pool = <0x10000000 0x0FFFFFFF>;
};
- qcom,iommu-domain3 {
+ q6_domain_ns:qcom,iommu-domain3 {
label = "lpass_video";
qcom,iommu-contexts = <&lpass_video_shared>;
qcom,virtual-addr-pool = <0x20000000 0x0FFFFFFF>;
diff --git a/arch/arm/boot/dts/msm8610-mtp.dts b/arch/arm/boot/dts/msm8610-mtp.dts
new file mode 100644
index 0000000..70ac0e8
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-mtp.dts
@@ -0,0 +1,26 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8610.dtsi"
+
+/ {
+ model = "Qualcomm MSM 8610 MTP";
+ compatible = "qcom,msm8610-mtp", "qcom,msm8610";
+ qcom,msm-id = <147 8 0>;
+
+ serial@f991f000 {
+ status = "ok";
+ };
+};
+
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 18f3df9..407104f 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -71,7 +71,12 @@
qcom,vidc@fdc00000 {
compatible = "qcom,msm-vidc";
- hfi = "q6";
+ qcom,vidc-ns-map = <0x40000000 0x40000000>;
+ qcom,iommu-groups = <&q6_domain_ns>;
+ qcom,iommu-group-buffer-types = <0xfff>;
+ qcom,buffer-type-tz-usage-map = <0x1 0x1>,
+ <0x1fe 0x2>;
+ qcom,hfi = "q6";
};
usb@f9a55000 {
@@ -236,6 +241,7 @@
compatible = "qcom,rpm-smd";
rpm-channel-name = "rpm_requests";
rpm-channel-type = <15>; /* SMD_APPS_RPM */
+ rpm-standalone;
};
qcom,msm-mem-hole {
@@ -428,6 +434,28 @@
compatible = "qcom,msm-pcm-hostless";
};
+ qcom,mss@fc880000 {
+ compatible = "qcom,pil-q6v5-mss";
+ reg = <0xfc880000 0x100>,
+ <0xfd485000 0x400>,
+ <0xfc820000 0x020>,
+ <0xfc401680 0x004>,
+ <0x0d1fc000 0x4000>,
+ <0xfd485194 0x4>;
+ reg-names = "qdsp6_base", "halt_base", "rmb_base",
+ "restart_reg", "metadata_base", "cxrail_bhs_reg";
+
+ interrupts = <0 24 1>;
+ vdd_mss-supply = <&pm8110_s1>;
+ vdd_cx-supply = <&pm8110_s1_corner>;
+ vdd_mx-supply = <&pm8110_l3>;
+ vdd_pll-supply = <&pm8110_l10>;
+ qcom,vdd_pll = <1800000>;
+ qcom,is-loadable;
+ qcom,firmware-name = "mba";
+ qcom,pil-self-auth;
+ };
+
qcom,lpass@fe200000 {
compatible = "qcom,pil-q6v5-lpass";
reg = <0xfe200000 0x00100>,
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-cdp-mtp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-cdp-mtp.dtsi
index 15a549c..3fb5b20 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-cdp-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-cdp-mtp.dtsi
@@ -15,7 +15,7 @@
actuator0: qcom,actuator@18 {
cell-index = <0>;
- reg = <0x18 0x0>;
+ reg = <0x18>;
compatible = "qcom,actuator";
qcom,cci-master = <0>;
};
@@ -27,6 +27,7 @@
qcom,csiphy-sd-index = <0>;
qcom,csid-sd-index = <0>;
qcom,actuator-src = <&actuator0>;
+ qcom,led-flash-src = <&led_flash0>;
qcom,mount-angle = <90>;
qcom,sensor-name = "s5k3l1yx";
cam_vdig-supply = <&pm8941_l3>;
@@ -136,7 +137,7 @@
qcom,camera@90 {
compatible = "qcom,mt9m114";
- reg = <0x90 0x0>;
+ reg = <0x90>;
qcom,slave-id = <0x90 0x0 0x2481>;
qcom,csiphy-sd-index = <1>;
qcom,csid-sd-index = <0>;
diff --git a/arch/arm/boot/dts/msm8974-camera.dtsi b/arch/arm/boot/dts/msm8974-camera.dtsi
index 95cafdb..0bd303f 100644
--- a/arch/arm/boot/dts/msm8974-camera.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera.dtsi
@@ -54,7 +54,8 @@
reg-names = "csid";
interrupts = <0 51 0>;
interrupt-names = "csid";
- mipi_csi_vdd-supply = <&pm8941_l12>;
+ qcom,csi-vdd-voltage = <1800000>;
+ qcom,mipi-csi-vdd-supply = <&pm8941_l12>;
};
qcom,csid@fda08400 {
@@ -64,7 +65,8 @@
reg-names = "csid";
interrupts = <0 52 0>;
interrupt-names = "csid";
- mipi_csi_vdd-supply = <&pm8941_l12>;
+ qcom,csi-vdd-voltage = <1800000>;
+ qcom,mipi-csi-vdd-supply = <&pm8941_l12>;
};
qcom,csid@fda08800 {
@@ -74,7 +76,8 @@
reg-names = "csid";
interrupts = <0 53 0>;
interrupt-names = "csid";
- mipi_csi_vdd-supply = <&pm8941_l12>;
+ qcom,csi-vdd-voltage = <1800000>;
+ qcom,mipi-csi-vdd-supply = <&pm8941_l12>;
};
qcom,csid@fda08C00 {
@@ -84,7 +87,8 @@
reg-names = "csid";
interrupts = <0 54 0>;
interrupt-names = "csid";
- mipi_csi_vdd-supply = <&pm8941_l12>;
+ qcom,csi-vdd-voltage = <1800000>;
+ qcom,mipi-csi-vdd-supply = <&pm8941_l12>;
};
qcom,ispif@fda0A000 {
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 2c513e8..9d98476 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 */
@@ -592,6 +617,55 @@
};
};
+/* CoreSight */
+&tpiu {
+ qcom,seta-gpios = <&msmgpio 31 0>,
+ <&msmgpio 32 0>,
+ <&msmgpio 33 0>,
+ <&msmgpio 34 0>,
+ <&msmgpio 35 0>,
+ <&msmgpio 36 0>,
+ <&msmgpio 37 0>,
+ <&msmgpio 38 0>,
+ <&msmgpio 39 0>,
+ <&msmgpio 40 0>,
+ <&msmgpio 41 0>,
+ <&msmgpio 42 0>,
+ <&msmgpio 43 0>,
+ <&msmgpio 44 0>,
+ <&msmgpio 45 0>,
+ <&msmgpio 46 0>,
+ <&msmgpio 47 0>,
+ <&msmgpio 48 0>;
+ qcom,seta-gpios-func = <4 4 4 3 4 4 4 3 4 3 5 5 5 5 4 4 5 5>;
+ qcom,seta-gpios-drv = <7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7>;
+ qcom,seta-gpios-pull = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
+ qcom,seta-gpios-dir = <2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2>;
+
+ qcom,setb-gpios = <&msmgpio 15 0>,
+ <&msmgpio 16 0>,
+ <&msmgpio 17 0>,
+ <&msmgpio 18 0>,
+ <&msmgpio 19 0>,
+ <&msmgpio 20 0>,
+ <&msmgpio 21 0>,
+ <&msmgpio 22 0>,
+ <&msmgpio 23 0>,
+ <&msmgpio 24 0>,
+ <&msmgpio 25 0>,
+ <&msmgpio 26 0>,
+ <&msmgpio 27 0>,
+ <&msmgpio 28 0>,
+ <&msmgpio 89 0>,
+ <&msmgpio 90 0>,
+ <&msmgpio 91 0>,
+ <&msmgpio 92 0>;
+ qcom,setb-gpios-func = <2 2 2 2 5 5 5 5 6 6 6 7 7 5 2 3 3 3>;
+ qcom,setb-gpios-drv = <7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7>;
+ qcom,setb-gpios-pull = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
+ qcom,setb-gpios-dir = <2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2>;
+};
+
&slim_msm {
taiko_codec {
qcom,cdc-micbias1-ext-cap;
diff --git a/arch/arm/boot/dts/msm8974-coresight.dtsi b/arch/arm/boot/dts/msm8974-coresight.dtsi
index 5df8f10..c064b59 100644
--- a/arch/arm/boot/dts/msm8974-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8974-coresight.dtsi
@@ -15,7 +15,7 @@
compatible = "arm,coresight-tmc";
reg = <0xfc322000 0x1000>,
<0xfc37c000 0x3000>;
- reg-names = "tmc-etr-base", "tmc-etr-bam-base";
+ reg-names = "tmc-base", "bam-base";
qcom,memory-reservation-type = "EBI1";
qcom,memory-reservation-size = <0x100000>; /* 1M EBI1 buffer */
@@ -34,6 +34,11 @@
coresight-id = <1>;
coresight-name = "coresight-tpiu";
coresight-nr-inports = <1>;
+
+ vdd-supply = <&pm8941_l21>;
+
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <9000 800000>;
};
replicator: replicator@fc31c000 {
@@ -52,7 +57,7 @@
tmc_etf: tmc@fc307000 {
compatible = "arm,coresight-tmc";
reg = <0xfc307000 0x1000>;
- reg-names = "tmc-etf-base";
+ reg-names = "tmc-base";
coresight-id = <3>;
coresight-name = "coresight-tmc-etf";
@@ -67,7 +72,7 @@
funnel_merg: funnel@fc31b000 {
compatible = "arm,coresight-funnel";
reg = <0xfc31b000 0x1000>;
- reg-names = "funnel-merg-base";
+ reg-names = "funnel-base";
coresight-id = <4>;
coresight-name = "coresight-funnel-merg";
@@ -80,7 +85,7 @@
funnel_in0: funnel@fc319000 {
compatible = "arm,coresight-funnel";
reg = <0xfc319000 0x1000>;
- reg-names = "funnel-in0-base";
+ reg-names = "funnel-base";
coresight-id = <5>;
coresight-name = "coresight-funnel-in0";
@@ -93,7 +98,7 @@
funnel_in1: funnel@fc31a000 {
compatible = "arm,coresight-funnel";
reg = <0xfc31a000 0x1000>;
- reg-names = "funnel-in1-base";
+ reg-names = "funnel-base";
coresight-id = <6>;
coresight-name = "coresight-funnel-in1";
@@ -106,7 +111,7 @@
funnel_kpss: funnel@fc345000 {
compatible = "arm,coresight-funnel";
reg = <0xfc345000 0x1000>;
- reg-names = "funnel-kpss-base";
+ reg-names = "funnel-base";
coresight-id = <7>;
coresight-name = "coresight-funnel-kpss";
@@ -119,7 +124,7 @@
funnel_mmss: funnel@fc364000 {
compatible = "arm,coresight-funnel";
reg = <0xfc364000 0x1000>;
- reg-names = "funnel-mmss-base";
+ reg-names = "funnel-base";
coresight-id = <8>;
@@ -147,7 +152,7 @@
etm0: etm@fc33c000 {
compatible = "arm,coresight-etm";
reg = <0xfc33c000 0x1000>;
- reg-names = "etm0-base";
+ reg-names = "etm-base";
coresight-id = <10>;
coresight-name = "coresight-etm0";
@@ -163,7 +168,7 @@
etm1: etm@fc33d000 {
compatible = "arm,coresight-etm";
reg = <0xfc33d000 0x1000>;
- reg-names = "etm1-base";
+ reg-names = "etm-base";
coresight-id = <11>;
coresight-name = "coresight-etm1";
@@ -179,7 +184,7 @@
etm2: etm@fc33e000 {
compatible = "arm,coresight-etm";
reg = <0xfc33e000 0x1000>;
- reg-names = "etm2-base";
+ reg-names = "etm-base";
coresight-id = <12>;
coresight-name = "coresight-etm2";
@@ -195,7 +200,7 @@
etm3: etm@fc33f000 {
compatible = "arm,coresight-etm";
reg = <0xfc33f000 0x1000>;
- reg-names = "etm3-base";
+ reg-names = "etm-base";
coresight-id = <13>;
coresight-name = "coresight-etm3";
@@ -223,7 +228,7 @@
cti0: cti@fc308000 {
compatible = "arm,coresight-cti";
reg = <0xfc308000 0x1000>;
- reg-names = "cti0-base";
+ reg-names = "cti-base";
coresight-id = <15>;
coresight-name = "coresight-cti0";
@@ -233,7 +238,7 @@
cti1: cti@fc309000 {
compatible = "arm,coresight-cti";
reg = <0xfc309000 0x1000>;
- reg-names = "cti1-base";
+ reg-names = "cti-base";
coresight-id = <16>;
coresight-name = "coresight-cti1";
@@ -243,7 +248,7 @@
cti2: cti@fc30a000 {
compatible = "arm,coresight-cti";
reg = <0xfc30a000 0x1000>;
- reg-names = "cti2-base";
+ reg-names = "cti-base";
coresight-id = <17>;
coresight-name = "coresight-cti2";
@@ -253,7 +258,7 @@
cti3: cti@fc30b000 {
compatible = "arm,coresight-cti";
reg = <0xfc30b000 0x1000>;
- reg-names = "cti3-base";
+ reg-names = "cti-base";
coresight-id = <18>;
coresight-name = "coresight-cti3";
@@ -263,7 +268,7 @@
cti4: cti@fc30c000 {
compatible = "arm,coresight-cti";
reg = <0xfc30c000 0x1000>;
- reg-names = "cti4-base";
+ reg-names = "cti-base";
coresight-id = <19>;
coresight-name = "coresight-cti4";
@@ -273,7 +278,7 @@
cti5: cti@fc30d000 {
compatible = "arm,coresight-cti";
reg = <0xfc30d000 0x1000>;
- reg-names = "cti5-base";
+ reg-names = "cti-base";
coresight-id = <20>;
coresight-name = "coresight-cti5";
@@ -283,7 +288,7 @@
cti6: cti@fc30e000 {
compatible = "arm,coresight-cti";
reg = <0xfc30e000 0x1000>;
- reg-names = "cti6-base";
+ reg-names = "cti-base";
coresight-id = <21>;
coresight-name = "coresight-cti6";
@@ -293,7 +298,7 @@
cti7: cti@fc30f000 {
compatible = "arm,coresight-cti";
reg = <0xfc30f000 0x1000>;
- reg-names = "cti7-base";
+ reg-names = "cti-base";
coresight-id = <22>;
coresight-name = "coresight-cti7";
@@ -303,7 +308,7 @@
cti8: cti@fc310000 {
compatible = "arm,coresight-cti";
reg = <0xfc310000 0x1000>;
- reg-names = "cti8-base";
+ reg-names = "cti-base";
coresight-id = <23>;
coresight-name = "coresight-cti8";
@@ -313,7 +318,7 @@
cti_l2: cti@fc340000 {
compatible = "arm,coresight-cti";
reg = <0xfc340000 0x1000>;
- reg-names = "cti-l2-base";
+ reg-names = "cti-base";
coresight-id = <24>;
coresight-name = "coresight-cti-l2";
@@ -323,7 +328,7 @@
cti_cpu0: cti@fc341000 {
compatible = "arm,coresight-cti";
reg = <0xfc341000 0x1000>;
- reg-names = "cti-cpu0-base";
+ reg-names = "cti-base";
coresight-id = <25>;
coresight-name = "coresight-cti-cpu0";
@@ -333,7 +338,7 @@
cti_cpu1: cti@fc342000 {
compatible = "arm,coresight-cti";
reg = <0xfc342000 0x1000>;
- reg-names = "cti-cpu1-base";
+ reg-names = "cti-base";
coresight-id = <26>;
coresight-name = "coresight-cti-cpu1";
@@ -343,7 +348,7 @@
cti_cpu2: cti@fc343000 {
compatible = "arm,coresight-cti";
reg = <0xfc343000 0x1000>;
- reg-names = "cti-cpu2-base";
+ reg-names = "cti-base";
coresight-id = <27>;
coresight-name = "coresight-cti-cpu2";
@@ -353,7 +358,7 @@
cti_cpu3: cti@fc344000 {
compatible = "arm,coresight-cti";
reg = <0xfc344000 0x1000>;
- reg-names = "cti-cpu3-base";
+ reg-names = "cti-base";
coresight-id = <28>;
coresight-name = "coresight-cti-cpu3";
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-ion.dtsi b/arch/arm/boot/dts/msm8974-ion.dtsi
index b1f39d1..31afd9c 100644
--- a/arch/arm/boot/dts/msm8974-ion.dtsi
+++ b/arch/arm/boot/dts/msm8974-ion.dtsi
@@ -20,6 +20,10 @@
reg = <30>;
};
+ qcom,ion-heap@21 { /* SYSTEM CONTIG HEAP */
+ reg = <21>;
+ };
+
qcom,ion-heap@8 { /* CP_MM HEAP */
compatible = "qcom,msm-ion-reserve";
reg = <8>;
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index a35b9d2..a10d1d6 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -299,6 +299,15 @@
qca,bt-reset-gpio = <&pm8941_gpios 34 0>;
};
+ bt_ar3002_sleep {
+ compatible = "qca,ar3002_bluesleep";
+ host-wake-gpio = <&msmgpio 79 0>;
+ ext-wake-gpio = <&msmgpio 51 0>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <79 2>;
+ interrupt-names = "host_wake";
+ };
+
sound {
qcom,model = "msm8974-taiko-liquid-snd-card";
@@ -606,6 +615,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-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 5eff79c..b125138 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -93,6 +93,15 @@
qcom,use-voltage-corner;
compatible = "qcom,rpm-regulator-smd";
};
+ pm8841_s2_floor_corner: regulator-s2-floor-corner {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8841_s2_floor_corner";
+ qcom,set = <3>;
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <7>;
+ qcom,use-voltage-floor-corner;
+ qcom,always-send-voltage;
+ };
};
rpm-regulator-smpb3 {
@@ -121,6 +130,15 @@
regulator-max-microvolt = <7>;
qcom,init-voltage-corner = <3>; /* SVS SOC */
};
+ pm8841_s4_floor_corner: regulator-s4-floor-corner {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8841_s4_floor_corner";
+ qcom,set = <3>;
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <7>;
+ qcom,use-voltage-floor-corner;
+ qcom,always-send-voltage;
+ };
};
rpm-regulator-smpa1 {
diff --git a/arch/arm/boot/dts/msm8974-smp2p.dtsi b/arch/arm/boot/dts/msm8974-smp2p.dtsi
index 964eecb..1b08246 100644
--- a/arch/arm/boot/dts/msm8974-smp2p.dtsi
+++ b/arch/arm/boot/dts/msm8974-smp2p.dtsi
@@ -100,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-v2-cdp.dts b/arch/arm/boot/dts/msm8974-v2-cdp.dts
index 319debe..e591dee 100644
--- a/arch/arm/boot/dts/msm8974-v2-cdp.dts
+++ b/arch/arm/boot/dts/msm8974-v2-cdp.dts
@@ -32,4 +32,6 @@
2 &intc 0 133 0
3 &spmi_bus 0x0 0x0 0x9 0x0>;
interrupt-names = "irq", "otg_irq", "hs_phy_irq", "pmic_id_irq";
+
+ qcom,misc-ref = <&pm8941_misc>;
};
diff --git a/arch/arm/boot/dts/msm8974-v2-fluid.dts b/arch/arm/boot/dts/msm8974-v2-fluid.dts
index 5759b56..4efad9e 100644
--- a/arch/arm/boot/dts/msm8974-v2-fluid.dts
+++ b/arch/arm/boot/dts/msm8974-v2-fluid.dts
@@ -20,3 +20,18 @@
compatible = "qcom,msm8974-fluid", "qcom,msm8974";
qcom,msm-id = <126 3 0x20000>;
};
+
+&usb3 {
+ #address-cells = <0>;
+ interrupt-parent = <&usb3>;
+ interrupts = <0 1 2 3>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 131 0
+ 1 &intc 0 179 0
+ 2 &intc 0 133 0
+ 3 &spmi_bus 0x0 0x0 0x9 0x0>;
+ interrupt-names = "irq", "otg_irq", "hs_phy_irq", "pmic_id_irq";
+
+ qcom,misc-ref = <&pm8941_misc>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v2-liquid.dts b/arch/arm/boot/dts/msm8974-v2-liquid.dts
index 6812f60..86584f8 100644
--- a/arch/arm/boot/dts/msm8974-v2-liquid.dts
+++ b/arch/arm/boot/dts/msm8974-v2-liquid.dts
@@ -20,3 +20,18 @@
compatible = "qcom,msm8974-liquid", "qcom,msm8974";
qcom,msm-id = <126 9 0x20000>;
};
+
+&usb3 {
+ #address-cells = <0>;
+ interrupt-parent = <&usb3>;
+ interrupts = <0 1 2 3>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 131 0
+ 1 &intc 0 179 0
+ 2 &intc 0 133 0
+ 3 &spmi_bus 0x0 0x0 0x9 0x0>;
+ interrupt-names = "irq", "otg_irq", "hs_phy_irq", "pmic_id_irq";
+
+ qcom,misc-ref = <&pm8941_misc>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v2-mtp.dts b/arch/arm/boot/dts/msm8974-v2-mtp.dts
index b29d4ca..a2e2ffa 100644
--- a/arch/arm/boot/dts/msm8974-v2-mtp.dts
+++ b/arch/arm/boot/dts/msm8974-v2-mtp.dts
@@ -20,3 +20,18 @@
compatible = "qcom,msm8974-mtp", "qcom,msm8974";
qcom,msm-id = <126 8 0x20000>;
};
+
+&usb3 {
+ #address-cells = <0>;
+ interrupt-parent = <&usb3>;
+ interrupts = <0 1 2 3>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 131 0
+ 1 &intc 0 179 0
+ 2 &intc 0 133 0
+ 3 &spmi_bus 0x0 0x0 0x9 0x0>;
+ interrupt-names = "irq", "otg_irq", "hs_phy_irq", "pmic_id_irq";
+
+ qcom,misc-ref = <&pm8941_misc>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v2-pm.dtsi b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
index 2cfb192..24b68b5 100644
--- a/arch/arm/boot/dts/msm8974-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
@@ -28,11 +28,12 @@
qcom,saw2-spm-dly= <0x3C102800>;
qcom,saw2-spm-ctl = <0x1>;
qcom,saw2-spm-cmd-wfi = [03 0b 0f];
- qcom,saw2-spm-cmd-ret = [42 1b 00 d0 03 d4 5b 0b 00 42 1b 0f];
- qcom,saw2-spm-cmd-spc = [00 20 80 10 E0 03 3B E4 5B 82 10 0B
- 30 06 26 30 0F];
- qcom,saw2-spm-cmd-pc = [00 20 50 80 60 70 10 E0 07 6E 70 3B
- E4 5B 82 3F 50 10 0B 30 06 26 30 0F];
+ qcom,saw2-spm-cmd-ret = [42 1b 00 d0 c0 a0 90 03 d0 98 a2 c0
+ 0b 00 42 1b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 80 10 90 a0 b0 03 3b 98 a2 b0 82
+ 10 0b 30 06 26 30 0f];
+ qcom,saw2-spm-cmd-pc = [00 20 80 10 90 a0 b0 07 3b 98 a2 b0 82
+ 10 0b 30 06 26 30 0f];
};
qcom,spm@f9099000 {
@@ -50,11 +51,12 @@
qcom,saw2-spm-dly= <0x3C102800>;
qcom,saw2-spm-ctl = <0x1>;
qcom,saw2-spm-cmd-wfi = [03 0b 0f];
- qcom,saw2-spm-cmd-ret = [42 1b 00 d0 03 d4 5b 0b 00 42 1b 0f];
- qcom,saw2-spm-cmd-spc = [00 20 80 10 E0 03 3B E4 5B 82 10 0B
- 30 06 26 30 0F];
- qcom,saw2-spm-cmd-pc = [00 20 50 80 60 70 10 E0 07 6E 70 3B
- E4 5B 82 3F 50 10 0B 30 06 26 30 0F];
+ qcom,saw2-spm-cmd-ret = [42 1b 00 d0 c0 a0 90 03 d0 98 a2 c0
+ 0b 00 42 1b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 80 10 90 a0 b0 03 3b 98 a2 b0 82
+ 10 0b 30 06 26 30 0f];
+ qcom,saw2-spm-cmd-pc = [00 20 80 10 90 a0 b0 07 3b 98 a2 b0 82
+ 10 0b 30 06 26 30 0f];
};
qcom,spm@f90a9000 {
@@ -72,11 +74,12 @@
qcom,saw2-spm-dly= <0x3C102800>;
qcom,saw2-spm-ctl = <0x1>;
qcom,saw2-spm-cmd-wfi = [03 0b 0f];
- qcom,saw2-spm-cmd-ret = [42 1b 00 d0 03 d4 5b 0b 00 42 1b 0f];
- qcom,saw2-spm-cmd-spc = [00 20 80 10 E0 03 3B E4 5B 82 10 0B
- 30 06 26 30 0F];
- qcom,saw2-spm-cmd-pc = [00 20 50 80 60 70 10 E0 07 6E 70 3B
- E4 5B 82 3F 50 10 0B 30 06 26 30 0F];
+ qcom,saw2-spm-cmd-ret = [42 1b 00 d0 c0 a0 90 03 d0 98 a2 c0
+ 0b 00 42 1b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 80 10 90 a0 b0 03 3b 98 a2 b0 82
+ 10 0b 30 06 26 30 0f];
+ qcom,saw2-spm-cmd-pc = [00 20 80 10 90 a0 b0 07 3b 98 a2 b0 82
+ 10 0b 30 06 26 30 0f];
};
qcom,spm@f90b9000 {
@@ -94,11 +97,12 @@
qcom,saw2-spm-dly= <0x3C102800>;
qcom,saw2-spm-ctl = <0x1>;
qcom,saw2-spm-cmd-wfi = [03 0b 0f];
- qcom,saw2-spm-cmd-ret = [42 1b 00 d0 03 d4 5b 0b 00 42 1b 0f];
- qcom,saw2-spm-cmd-spc = [00 20 80 10 E0 03 3B E4 5B 82 10 0B
- 30 06 26 30 0F];
- qcom,saw2-spm-cmd-pc = [00 20 50 80 60 70 10 E0 07 6E 70 3B
- E4 5B 82 3F 50 10 0B 30 06 26 30 0F];
+ qcom,saw2-spm-cmd-ret = [42 1b 00 d0 c0 a0 90 03 d0 98 a2 c0
+ 0b 00 42 1b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 80 10 90 a0 b0 03 3b 98 a2 b0 82
+ 10 0b 30 06 26 30 0f];
+ qcom,saw2-spm-cmd-pc = [00 20 80 10 90 a0 b0 07 3b 98 a2 b0 82
+ 10 0b 30 06 26 30 0f];
};
qcom,spm@f9012000 {
@@ -122,10 +126,9 @@
qcom,phase-port = <0x1>;
qcom,pfm-port = <0x2>;
qcom,saw2-spm-cmd-ret = [1f 00 20 03 22 00 0f];
- qcom,saw2-spm-cmd-gdhs = [00 20 32 60 70 80 42 07 78 80 44 22 50
- 3b 60 02 32 50 0f];
- qcom,saw2-spm-cmd-pc = [00 10 32 60 70 80 b0 11 42 07 01 b0 78
- 80 12 44 50 3b 60 02 32 50 0f];
+ qcom,saw2-spm-cmd-gdhs = [00 20 32 42 07 44 22 50 02 32 50 0f];
+ qcom,saw2-spm-cmd-pc = [00 10 32 b0 11 42 07 01 b0 12 44
+ 50 02 32 50 0f];
};
qcom,lpm-resources {
@@ -423,7 +426,6 @@
reg = <0xfe805664 0x40>;
qcom,pc-mode = "tz_l2_int";
qcom,use-sync-timer;
- qcom,saw-turns-off-pll;
qcom,cpu-sleep-status@f9088008{
compatible = "qcom,cpu-sleep-status";
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 00518a0..9102770 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -98,6 +98,11 @@
qcom,has-ocmem;
};
+ qcom,vidc {
+ compatible = "qcom,msm-vidc";
+ qcom,hfi = "q6";
+ };
+
qcom,wfd {
compatible = "qcom,msm-wfd";
};
@@ -351,6 +356,7 @@
reg-names = "hc_mem", "core_mem";
interrupts = <0 123 0>, <0 138 0>;
interrupt-names = "hc_irq", "pwr_irq";
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 200000000>;
qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
qcom,cpu-dma-latency-us = <200>;
@@ -377,6 +383,7 @@
interrupts = <0 125 0>, <0 221 0>;
interrupt-names = "hc_irq", "pwr_irq";
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 200000000>;
qcom,bus-width = <4>;
qcom,cpu-dma-latency-us = <200>;
@@ -410,6 +417,7 @@
<&msmgpio 35 0>; /* DATA3 */
qcom,gpio-names = "CLK", "CMD", "DAT0", "DAT1", "DAT2", "DAT3";
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000>;
qcom,bus-width = <4>;
qcom,cpu-dma-latency-us = <200>;
@@ -443,6 +451,7 @@
<&msmgpio 92 0>; /* DATA3 */
qcom,gpio-names = "CLK", "CMD", "DAT0", "DAT1", "DAT2", "DAT3";
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000>;
qcom,bus-width = <4>;
qcom,cpu-dma-latency-us = <200>;
@@ -994,6 +1003,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-coresight.dtsi b/arch/arm/boot/dts/msm9625-coresight.dtsi
index 0af8fa5..69a1d7b 100644
--- a/arch/arm/boot/dts/msm9625-coresight.dtsi
+++ b/arch/arm/boot/dts/msm9625-coresight.dtsi
@@ -15,7 +15,7 @@
compatible = "arm,coresight-tmc";
reg = <0xfc322000 0x1000>,
<0xfc37c000 0x3000>;
- reg-names = "tmc-etr-base", "tmc-etr-bam-base";
+ reg-names = "tmc-base", "bam-base";
qcom,memory-reservation-type = "EBI1";
qcom,memory-reservation-size = <0x20000>; /* 128K EBI1 buffer */
@@ -52,7 +52,7 @@
tmc_etf: tmc@fc307000 {
compatible = "arm,coresight-tmc";
reg = <0xfc307000 0x1000>;
- reg-names = "tmc-etf-base";
+ reg-names = "tmc-base";
coresight-id = <3>;
coresight-name = "coresight-tmc-etf";
@@ -67,7 +67,7 @@
funnel_merg: funnel@fc31b000 {
compatible = "arm,coresight-funnel";
reg = <0xfc31b000 0x1000>;
- reg-names = "funnel-merg-base";
+ reg-names = "funnel-base";
coresight-id = <4>;
coresight-name = "coresight-funnel-merg";
@@ -80,7 +80,7 @@
funnel_in0: funnel@fc319000 {
compatible = "arm,coresight-funnel";
reg = <0xfc319000 0x1000>;
- reg-names = "funnel-in0-base";
+ reg-names = "funnel-base";
coresight-id = <5>;
coresight-name = "coresight-funnel-in0";
@@ -93,7 +93,7 @@
funnel_in1: funnel@fc31a000 {
compatible = "arm,coresight-funnel";
reg = <0xfc31a000 0x1000>;
- reg-names = "funnel-in1-base";
+ reg-names = "funnel-base";
coresight-id = <6>;
coresight-name = "coresight-funnel-in1";
@@ -147,7 +147,7 @@
cti0: cti@fc308000 {
compatible = "arm,coresight-cti";
reg = <0xfc308000 0x1000>;
- reg-names = "cti0-base";
+ reg-names = "cti-base";
coresight-id = <10>;
coresight-name = "coresight-cti0";
@@ -157,7 +157,7 @@
cti1: cti@fc309000 {
compatible = "arm,coresight-cti";
reg = <0xfc309000 0x1000>;
- reg-names = "cti1-base";
+ reg-names = "cti-base";
coresight-id = <11>;
coresight-name = "coresight-cti1";
@@ -167,7 +167,7 @@
cti2: cti@fc30a000 {
compatible = "arm,coresight-cti";
reg = <0xfc30a000 0x1000>;
- reg-names = "cti2-base";
+ reg-names = "cti-base";
coresight-id = <12>;
coresight-name = "coresight-cti2";
@@ -177,7 +177,7 @@
cti3: cti@fc30b000 {
compatible = "arm,coresight-cti";
reg = <0xfc30b000 0x1000>;
- reg-names = "cti3-base";
+ reg-names = "cti-base";
coresight-id = <13>;
coresight-name = "coresight-cti3";
@@ -187,7 +187,7 @@
cti4: cti@fc30c000 {
compatible = "arm,coresight-cti";
reg = <0xfc30c000 0x1000>;
- reg-names = "cti4-base";
+ reg-names = "cti-base";
coresight-id = <14>;
coresight-name = "coresight-cti4";
@@ -197,7 +197,7 @@
cti5: cti@fc30d000 {
compatible = "arm,coresight-cti";
reg = <0xfc30d000 0x1000>;
- reg-names = "cti5-base";
+ reg-names = "cti-base";
coresight-id = <15>;
coresight-name = "coresight-cti5";
@@ -207,7 +207,7 @@
cti6: cti@fc30e000 {
compatible = "arm,coresight-cti";
reg = <0xfc30e000 0x1000>;
- reg-names = "cti6-base";
+ reg-names = "cti-base";
coresight-id = <16>;
coresight-name = "coresight-cti6";
@@ -217,7 +217,7 @@
cti7: cti@fc30f000 {
compatible = "arm,coresight-cti";
reg = <0xfc30f000 0x1000>;
- reg-names = "cti7-base";
+ reg-names = "cti-base";
coresight-id = <17>;
coresight-name = "coresight-cti7";
@@ -227,7 +227,7 @@
cti8: cti@fc310000 {
compatible = "arm,coresight-cti";
reg = <0xfc310000 0x1000>;
- reg-names = "cti8-base";
+ reg-names = "cti-base";
coresight-id = <18>;
coresight-name = "coresight-cti8";
@@ -237,7 +237,7 @@
cti_cpu: cti@fc333000 {
compatible = "arm,coresight-cti";
reg = <0xfc333000 0x1000>;
- reg-names = "cti-cpu-base";
+ reg-names = "cti-base";
coresight-id = <19>;
coresight-name = "coresight-cti-cpu";
diff --git a/arch/arm/boot/dts/msm9625-v1-cdp.dts b/arch/arm/boot/dts/msm9625-v1-cdp.dts
index 6221ba1..cc7a758 100644
--- a/arch/arm/boot/dts/msm9625-v1-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-v1-cdp.dts
@@ -45,7 +45,15 @@
compatible = "qca,ar6004-sdio";
qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+ qca,vdd-io-supply = <&pm8019_l11>;
+ };
+
+ qca,wlan_ar6003 {
+ cell-index = <0>;
+ compatible = "qca,ar6003-sdio";
+ qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+ qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+ qca,vdd-io-supply = <&pm8019_l11>;
};
};
diff --git a/arch/arm/boot/dts/msm9625-v1-mtp.dts b/arch/arm/boot/dts/msm9625-v1-mtp.dts
index 5ff9e92..d78bb77 100644
--- a/arch/arm/boot/dts/msm9625-v1-mtp.dts
+++ b/arch/arm/boot/dts/msm9625-v1-mtp.dts
@@ -45,7 +45,15 @@
compatible = "qca,ar6004-sdio";
qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+ qca,vdd-io-supply = <&pm8019_l11>;
+ };
+
+ qca,wlan_ar6003 {
+ cell-index = <0>;
+ compatible = "qca,ar6003-sdio";
+ qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+ qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+ qca,vdd-io-supply = <&pm8019_l11>;
};
};
diff --git a/arch/arm/boot/dts/msm9625-v2-cdp.dts b/arch/arm/boot/dts/msm9625-v2-cdp.dts
index 919c6d5..94fe019 100644
--- a/arch/arm/boot/dts/msm9625-v2-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-v2-cdp.dts
@@ -47,7 +47,15 @@
compatible = "qca,ar6004-hsic";
qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+ qca,vdd-io-supply = <&pm8019_l11>;
+ };
+
+ qca,wlan_ar6003 {
+ cell-index = <0>;
+ compatible = "qca,ar6003-sdio";
+ qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+ qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+ qca,vdd-io-supply = <&pm8019_l11>;
};
};
diff --git a/arch/arm/boot/dts/msm9625-v2-mtp.dts b/arch/arm/boot/dts/msm9625-v2-mtp.dts
index 7949080..2840024 100644
--- a/arch/arm/boot/dts/msm9625-v2-mtp.dts
+++ b/arch/arm/boot/dts/msm9625-v2-mtp.dts
@@ -45,7 +45,15 @@
compatible = "qca,ar6004-hsic";
qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+ qca,vdd-io-supply = <&pm8019_l11>;
+ };
+
+ qca,wlan_ar6003 {
+ cell-index = <0>;
+ compatible = "qca,ar6003-sdio";
+ qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+ qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+ qca,vdd-io-supply = <&pm8019_l11>;
};
};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 9172029..3dbc95d 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -140,31 +140,27 @@
qcom,pipe0 {
label = "hsusb-ipa-out-0";
- qcom,usb-bam-mem-type = <0>;
+ qcom,usb-bam-mem-type = <2>;
qcom,bam-type = <1>;
qcom,dir = <0>;
qcom,pipe-num = <0>;
qcom,peer-bam = <2>;
qcom,src-bam-physical-address = <0xf9a44000>;
qcom,src-bam-pipe-index = <1>;
- qcom,data-fifo-offset = <0x2200>;
- qcom,data-fifo-size = <0x1e00>;
- qcom,descriptor-fifo-offset = <0x2100>;
- qcom,descriptor-fifo-size = <0x100>;
+ qcom,data-fifo-size = <0x8000>;
+ qcom,descriptor-fifo-size = <0x2000>;
};
qcom,pipe1 {
label = "hsusb-ipa-in-0";
- qcom,usb-bam-mem-type = <0>;
+ qcom,usb-bam-mem-type = <2>;
qcom,bam-type = <1>;
qcom,dir = <1>;
qcom,pipe-num = <0>;
qcom,peer-bam = <2>;
qcom,dst-bam-physical-address = <0xf9a44000>;
qcom,dst-bam-pipe-index = <0>;
- qcom,data-fifo-offset = <0x300>;
- qcom,data-fifo-size = <0x1e00>;
- qcom,descriptor-fifo-offset = <0>;
- qcom,descriptor-fifo-size = <0x300>;
+ qcom,data-fifo-size = <0x8000>;
+ qcom,descriptor-fifo-size = <0x2000>;
};
qcom,pipe2 {
label = "hsusb-qdss-in-0";
@@ -193,6 +189,7 @@
qcom,dst-bam-pipe-index = <3>;
qcom,data-fifo-size = <0xD480>;
qcom,descriptor-fifo-size = <0x1A80>;
+ qcom,reset-bam-on-connect;
};
qcom,pipe4 {
label = "hsic-ipa-in-1";
@@ -205,6 +202,7 @@
qcom,dst-bam-pipe-index = <4>;
qcom,data-fifo-size = <0xD480>;
qcom,descriptor-fifo-size = <0x1A80>;
+ qcom,reset-bam-on-connect;
};
qcom,pipe5 {
label = "hsic-ipa-in-2";
@@ -217,6 +215,7 @@
qcom,dst-bam-pipe-index = <5>;
qcom,data-fifo-size = <0xD480>;
qcom,descriptor-fifo-size = <0x1A80>;
+ qcom,reset-bam-on-connect;
};
qcom,pipe6 {
label = "hsic-ipa-in-3";
@@ -229,6 +228,7 @@
qcom,dst-bam-pipe-index = <6>;
qcom,data-fifo-size = <0xD480>;
qcom,descriptor-fifo-size = <0x1A80>;
+ qcom,reset-bam-on-connect;
};
qcom,pipe7 {
label = "hsic-ipa-out-0";
@@ -241,6 +241,7 @@
qcom,src-bam-pipe-index = <7>;
qcom,data-fifo-size = <0xD480>;
qcom,descriptor-fifo-size = <0x1A80>;
+ qcom,reset-bam-on-connect;
};
};
diff --git a/arch/arm/configs/fsm9xxx-perf_defconfig b/arch/arm/configs/fsm9xxx-perf_defconfig
index 8a7928b..10414e1 100644
--- a/arch/arm/configs/fsm9xxx-perf_defconfig
+++ b/arch/arm/configs/fsm9xxx-perf_defconfig
@@ -9,7 +9,6 @@
CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_PANIC_TIMEOUT=5
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_SLAB=y
CONFIG_PROFILING=y
@@ -34,7 +33,6 @@
CONFIG_MSM_IPC_ROUTER=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
# CONFIG_MSM_ONCRPCROUTER_DEBUG is not set
-# CONFIG_MSM_HW3D is not set
# CONFIG_QSD_AUDIO is not set
# CONFIG_SURF_FFA_GPIO_KEYPAD is not set
CONFIG_MSM_SMCMOD=m
@@ -156,6 +154,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_TIMED_GPIO=y
diff --git a/arch/arm/configs/fsm9xxx_defconfig b/arch/arm/configs/fsm9xxx_defconfig
index db2f25d..aa3befa 100644
--- a/arch/arm/configs/fsm9xxx_defconfig
+++ b/arch/arm/configs/fsm9xxx_defconfig
@@ -10,7 +10,6 @@
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_KALLSYMS_ALL=y
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_SLAB=y
CONFIG_PROFILING=y
@@ -33,7 +32,6 @@
CONFIG_MSM_ONCRPCROUTER=y
CONFIG_MSM_IPC_ROUTER=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
-# CONFIG_MSM_HW3D is not set
# CONFIG_QSD_AUDIO is not set
# CONFIG_SURF_FFA_GPIO_KEYPAD is not set
CONFIG_MSM_SMCMOD=m
@@ -155,6 +153,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_TIMED_GPIO=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 8eac20f..aea092e 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -15,7 +15,6 @@
CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
@@ -45,7 +44,6 @@
CONFIG_MSM_IPC_ROUTER=y
# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
CONFIG_MSM_RMT_STORAGE_CLIENT=y
-# CONFIG_MSM_HW3D is not set
CONFIG_MSM7X27A_AUDIO=y
CONFIG_MSM_DMA_TEST=y
CONFIG_MSM_SLEEP_STATS_DEVICE=y
@@ -67,7 +65,6 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0xC800000
CONFIG_COMPACTION=y
CONFIG_CP_ACCESS=y
CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -83,7 +80,6 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -249,7 +245,6 @@
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_MSM_HS=y
-# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
CONFIG_DIAG_CHAR=y
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
@@ -271,9 +266,6 @@
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
# CONFIG_RC_CORE is not set
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_VIDEOBUF2_MSM_MEM=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA_V4L2=y
CONFIG_OV5647=y
CONFIG_AD5046_ACT=y
@@ -286,6 +278,9 @@
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
CONFIG_OV7692=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_RADIO_TAVARUA=y
CONFIG_ION=y
CONFIG_ION_MSM=y
@@ -356,6 +351,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
CONFIG_EXT2_FS=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 27c10d0..b903a0b 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -15,7 +15,6 @@
CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
@@ -45,7 +44,6 @@
CONFIG_MSM_IPC_ROUTER=y
# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
CONFIG_MSM_RMT_STORAGE_CLIENT=y
-# CONFIG_MSM_HW3D is not set
CONFIG_MSM7X27A_AUDIO=y
CONFIG_MSM_DMA_TEST=y
CONFIG_MSM_SLEEP_STATS_DEVICE=y
@@ -69,7 +67,6 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0xC800000
CONFIG_COMPACTION=y
CONFIG_CP_ACCESS=y
CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -85,7 +82,6 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -251,7 +247,6 @@
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_MSM_HS=y
-# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
CONFIG_DIAG_CHAR=y
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
@@ -273,9 +268,6 @@
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
# CONFIG_RC_CORE is not set
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_VIDEOBUF2_MSM_MEM=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA_V4L2=y
CONFIG_OV5647=y
CONFIG_AD5046_ACT=y
@@ -288,6 +280,9 @@
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
CONFIG_OV7692=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_RADIO_TAVARUA=y
CONFIG_ION=y
CONFIG_ION_MSM=y
@@ -357,6 +352,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
CONFIG_EXT2_FS=y
diff --git a/arch/arm/configs/msm7630-perf_defconfig b/arch/arm/configs/msm7630-perf_defconfig
index e46b835..d925ab3 100644
--- a/arch/arm/configs/msm7630-perf_defconfig
+++ b/arch/arm/configs/msm7630-perf_defconfig
@@ -13,7 +13,6 @@
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_SLAB=y
CONFIG_PROFILING=y
@@ -30,13 +29,9 @@
# CONFIG_MSM_STACKED_MEMORY is not set
CONFIG_MSM_SMD=y
CONFIG_MSM_SMD_PKG3=y
-CONFIG_MSM_SDIO_DMUX=y
-CONFIG_MSM_SDIO_CMUX=y
-CONFIG_MSM_SDIO_CTL=y
CONFIG_MSM_ONCRPCROUTER=y
CONFIG_MSM_RPC_WATCHDOG=y
CONFIG_MSM_RMT_STORAGE_CLIENT=y
-# CONFIG_MSM_HW3D is not set
# CONFIG_QSD_AUDIO is not set
CONFIG_MSM_MEMORY_LOW_POWER_MODE=y
CONFIG_MSM_MEMORY_LOW_POWER_MODE_IDLE_RETENTION=y
@@ -52,7 +47,6 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x1A000000
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M ip=dhcp"
@@ -64,7 +58,6 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -212,7 +205,6 @@
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_TUN=y
-CONFIG_MSM_RMNET_SDIO=y
CONFIG_SMC91X=y
CONFIG_SMSC911X=y
CONFIG_SLIP=y
@@ -326,7 +318,6 @@
CONFIG_USB_G_ANDROID=y
CONFIG_RMNET_SMD_CTL_CHANNEL="DATA40_CNTL"
CONFIG_RMNET_SMD_DATA_CHANNEL="DATA40"
-CONFIG_RMNET_SDIO_SMD_DATA_CHANNEL=""
CONFIG_USB_MSM_ACA=y
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
@@ -349,6 +340,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_TIMED_GPIO=y
diff --git a/arch/arm/configs/msm7630_defconfig b/arch/arm/configs/msm7630_defconfig
index 5964afb..9eea95c 100644
--- a/arch/arm/configs/msm7630_defconfig
+++ b/arch/arm/configs/msm7630_defconfig
@@ -13,7 +13,6 @@
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_SLAB=y
CONFIG_PROFILING=y
@@ -30,13 +29,9 @@
# CONFIG_MSM_STACKED_MEMORY is not set
CONFIG_MSM_SMD=y
CONFIG_MSM_SMD_PKG3=y
-CONFIG_MSM_SDIO_DMUX=y
-CONFIG_MSM_SDIO_CMUX=y
-CONFIG_MSM_SDIO_CTL=y
CONFIG_MSM_ONCRPCROUTER=y
CONFIG_MSM_RPC_WATCHDOG=y
CONFIG_MSM_RMT_STORAGE_CLIENT=y
-# CONFIG_MSM_HW3D is not set
# CONFIG_QSD_AUDIO is not set
CONFIG_MSM_MEMORY_LOW_POWER_MODE=y
CONFIG_MSM_MEMORY_LOW_POWER_MODE_IDLE_RETENTION=y
@@ -53,7 +48,6 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x1A000000
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M ip=dhcp"
@@ -65,7 +59,6 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -213,7 +206,6 @@
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_TUN=y
-CONFIG_MSM_RMNET_SDIO=y
CONFIG_SMC91X=y
CONFIG_SMSC911X=y
CONFIG_SLIP=y
@@ -322,7 +314,6 @@
CONFIG_USB_G_ANDROID=y
CONFIG_RMNET_SMD_CTL_CHANNEL="DATA40_CNTL"
CONFIG_RMNET_SMD_DATA_CHANNEL="DATA40"
-CONFIG_RMNET_SDIO_SMD_DATA_CHANNEL=""
CONFIG_USB_MSM_ACA=y
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
@@ -345,6 +336,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_TIMED_GPIO=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index 097e830..2a6ba73 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -23,7 +23,6 @@
CONFIG_RD_LZMA=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_KALLSYMS_ALL=y
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
@@ -36,49 +35,55 @@
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8610=y
CONFIG_ARCH_MSM8226=y
-CONFIG_SND_SOC_MSM8226=y
-CONFIG_SND_SOC_MSM8X10=y
# CONFIG_MSM_STACKED_MEMORY is not set
CONFIG_CPU_HAS_L2_PMU=y
# CONFIG_MSM_FIQ_SUPPORT is not set
# CONFIG_MSM_PROC_COMM is not set
CONFIG_MSM_SMD=y
CONFIG_MSM_SMD_PKG4=y
-CONFIG_MSM_IPC_LOGGING=y
CONFIG_MSM_BAM_DMUX=y
CONFIG_MSM_SMP2P=y
CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_IPC_LOGGING=y
CONFIG_MSM_IPC_ROUTER=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
CONFIG_MSM_QMI_INTERFACE=y
-# CONFIG_MSM_HW3D is not set
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_SYSMON_COMM=y
CONFIG_MSM_PIL_LPASS_QDSP6V5=y
-CONFIG_MSM_PIL_PRONTO=y
CONFIG_MSM_PIL_MSS_QDSP6V5=y
CONFIG_MSM_PIL_VENUS=y
+CONFIG_MSM_PIL_PRONTO=y
+CONFIG_MSM_TZ_LOG=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_WATCHDOG_V2=y
CONFIG_MSM_DLOAD_MODE=y
CONFIG_MSM_ADSP_LOADER=m
+CONFIG_MSM_OCMEM=y
+CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
+CONFIG_MSM_OCMEM_DEBUG=y
+CONFIG_MSM_OCMEM_NONSECURE=y
CONFIG_MSM_OCMEM_POWER_DISABLE=y
+CONFIG_SENSORS_ADSP=y
+CONFIG_MSM_RTB=y
+CONFIG_MSM_RTB_SEPARATE_CPUS=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_SMP=y
CONFIG_SCHED_MC=y
CONFIG_ARM_ARCH_TIMER=y
-CONFIG_HOTPLUG_CPU=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_USE_OF=y
CONFIG_CPU_IDLE=y
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -180,9 +185,6 @@
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_CLS_FW=y
-CONFIG_SYNC=y
-CONFIG_SW_SYNC=y
-CONFIG_CMA=y
CONFIG_BT=y
CONFIG_BT_RFCOMM=y
CONFIG_BT_RFCOMM_TTY=y
@@ -191,9 +193,9 @@
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_CMA=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_MD=y
@@ -201,18 +203,18 @@
CONFIG_DM_CRYPT=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
+CONFIG_KS8851=y
# CONFIG_MSM_RMNET is not set
CONFIG_MSM_RMNET_BAM=y
-CONFIG_KS8851=y
CONFIG_WCNSS_CORE=y
CONFIG_WCNSS_CORE_PRONTO=y
CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=m
+CONFIG_KEYBOARD_GPIO=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
-CONFIG_KEYBOARD_GPIO=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=m
@@ -221,29 +223,49 @@
CONFIG_DIAG_CHAR=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_MSM=y
-CONFIG_SPMI=y
-CONFIG_SPMI_MSM_PMIC_ARB=y
-CONFIG_MSM_QPNP_INT=y
-CONFIG_SLIMBUS=y
-CONFIG_SLIMBUS_MSM_NGD=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_SPI=y
-CONFIG_SPI_QUP=y
-CONFIG_SPI_SPIDEV=m
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_QUP=y
-CONFIG_WCD9306_CODEC=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPI_SPIDEV=m
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB=y
+CONFIG_MSM_QPNP_INT=y
+CONFIG_SLIMBUS_MSM_NGD=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_QPNP_PIN=y
-CONFIG_HWMON=y
CONFIG_POWER_SUPPLY=y
CONFIG_QPNP_CHARGER=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_SENSORS_QPNP_ADC_CURRENT=y
-CONFIG_REGULATOR=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_TSENS8974=y
+CONFIG_THERMAL_MONITOR=y
+CONFIG_THERMAL_QPNP_ADC_TM=y
+CONFIG_WCD9306_CODEC=y
CONFIG_REGULATOR_STUB=y
CONFIG_REGULATOR_QPNP=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_MSM_CAMERA is not set
+CONFIG_OV8825=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_CPP=y
+CONFIG_MSM_CCI=y
+CONFIG_MSM_CSI30_HEADER=y
+CONFIG_MSM_CSIPHY=y
+CONFIG_MSM_CSID=y
+CONFIG_MSM_ISPIF=y
+CONFIG_MSMB_CAMERA=y
+CONFIG_OV9724=y
+CONFIG_MSMB_JPEG=y
+CONFIG_MSM_VIDC_V4L2=y
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_RADIO_IRIS=y
CONFIG_RADIO_IRIS_TRANSPORT=m
CONFIG_ION=y
@@ -261,6 +283,8 @@
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
+CONFIG_SND_SOC_MSM8226=y
+CONFIG_SND_SOC_MSM8X10=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
@@ -275,25 +299,34 @@
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_TEST=m
CONFIG_MMC_MSM=y
+CONFIG_MMC_MSM_SPS_SUPPORT=y
+CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_MSM is not set
+CONFIG_RTC_DRV_QPNP=y
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_TIMED_GPIO=y
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
-CONFIG_QPNP_PWM=y
-CONFIG_MSM_IOMMU=y
-CONFIG_MSM_IOMMU_PMON=y
CONFIG_SPS=y
CONFIG_SPS_SUPPORT_NDP_BAM=y
-CONFIG_MMC_MSM_SPS_SUPPORT=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_QPNP=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_MSM is not set
-CONFIG_RTC_DRV_QPNP=y
+CONFIG_QPNP_PWM=y
+CONFIG_QPNP_POWER_ON=y
+CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_PMON=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_TMC=y
+CONFIG_CORESIGHT_TPIU=y
+CONFIG_CORESIGHT_FUNNEL=y
+CONFIG_CORESIGHT_REPLICATOR=y
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_ETM=y
+CONFIG_CORESIGHT_EVENT=m
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT3_FS=y
@@ -307,51 +340,16 @@
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_KEYS=y
CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_TWOFISH=y
# CONFIG_CRYPTO_HW is not set
CONFIG_CRC_CCITT=y
-CONFIG_QPNP_POWER_ON=y
-CONFIG_LIBCRC32C=y
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_MEDIA_CAMERA_SUPPORT=y
-# CONFIG_MSM_CAMERA is not set
-CONFIG_MSM_VIDC_V4L2=y
-CONFIG_VIDEO_DEV=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
-CONFIG_VIDEOBUF2_MSM_MEM=y
-CONFIG_MSM_OCMEM=y
-CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
-CONFIG_MSM_OCMEM_DEBUG=y
-CONFIG_MSM_OCMEM_NONSECURE=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_TSENS8974=y
-CONFIG_THERMAL_MONITOR=y
-CONFIG_THERMAL_QPNP_ADC_TM=y
-CONFIG_MSM_RTB=y
-CONFIG_MSM_RTB_SEPARATE_CPUS=y
-CONFIG_CORESIGHT=y
-CONFIG_CORESIGHT_TMC=y
-CONFIG_CORESIGHT_TPIU=y
-CONFIG_CORESIGHT_FUNNEL=y
-CONFIG_CORESIGHT_REPLICATOR=y
-CONFIG_CORESIGHT_STM=y
-CONFIG_CORESIGHT_ETM=y
-CONFIG_CORESIGHT_EVENT=m
-CONFIG_ENABLE_DEFAULT_TRACERS=y
-CONFIG_PM_WAKELOCKS=y
-CONFIG_PM_WAKELOCKS_LIMIT=0
-CONFIG_PM_AUTOSLEEP=y
-# CONFIG_PM_WAKELOCKS_GC is not set
-CONFIG_MSM_TZ_LOG=y
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index baefac5..dda9bd3 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -21,7 +21,6 @@
CONFIG_RD_LZMA=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_PANIC_TIMEOUT=5
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
CONFIG_PROFILING=y
@@ -47,21 +46,15 @@
# CONFIG_MSM_FIQ_SUPPORT is not set
# CONFIG_MSM_PROC_COMM is not set
CONFIG_MSM_SMD=y
-CONFIG_MSM_SDIO_DMUX=y
# CONFIG_MSM_RESET_MODEM is not set
# CONFIG_MSM_SMD_NMEA is not set
-CONFIG_MSM_SDIO_TTY=y
# CONFIG_MSM_SMD_QMI is not set
-CONFIG_MSM_SDIO_CMUX=y
CONFIG_MSM_DSPS=y
-CONFIG_MSM_SDIO_CTL=y
CONFIG_MSM_ONCRPCROUTER=y
# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
# CONFIG_MSM_RPCSERVER_WATCHDOG is not set
# CONFIG_MSM_RPCSERVER_HANDSET is not set
CONFIG_MSM_RMT_STORAGE_CLIENT=y
-CONFIG_MSM_SDIO_SMEM=y
-# CONFIG_MSM_HW3D is not set
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_SYSMON_COMM=y
CONFIG_MSM_PIL_MODEM=y
@@ -84,7 +77,6 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_COMPACTION=y
CONFIG_CP_ACCESS=y
CONFIG_CPU_FREQ=y
@@ -96,7 +88,6 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -252,7 +243,6 @@
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_TUN=y
-CONFIG_MSM_RMNET_SDIO=y
CONFIG_SMC91X=y
CONFIG_SMC911X=y
CONFIG_SMSC911X=y
@@ -315,10 +305,6 @@
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_DEV=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_VIDEOBUF2_MSM_MEM=y
-CONFIG_USB_VIDEO_CLASS=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA_V4L2=y
CONFIG_IMX074=y
CONFIG_WEBCAM_OV9726=y
@@ -328,6 +314,10 @@
CONFIG_MSM_ACTUATOR=y
CONFIG_MSM_GEMINI=y
CONFIG_OV7692=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_RADIO_TAVARUA=y
CONFIG_ION=y
CONFIG_ION_MSM=y
@@ -404,7 +394,6 @@
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_SLEEP=y
CONFIG_SWITCH=y
CONFIG_SWITCH_GPIO=y
CONFIG_RTC_CLASS=y
@@ -413,6 +402,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_TIMED_GPIO=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 28d7b12..abc7460 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -21,7 +21,6 @@
CONFIG_RD_LZMA=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_PANIC_TIMEOUT=5
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
@@ -46,21 +45,15 @@
# CONFIG_MSM_FIQ_SUPPORT is not set
# CONFIG_MSM_PROC_COMM is not set
CONFIG_MSM_SMD=y
-CONFIG_MSM_SDIO_DMUX=y
# CONFIG_MSM_RESET_MODEM is not set
# CONFIG_MSM_SMD_NMEA is not set
-CONFIG_MSM_SDIO_TTY=y
# CONFIG_MSM_SMD_QMI is not set
-CONFIG_MSM_SDIO_CMUX=y
CONFIG_MSM_DSPS=y
-CONFIG_MSM_SDIO_CTL=y
CONFIG_MSM_ONCRPCROUTER=y
# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
# CONFIG_MSM_RPCSERVER_WATCHDOG is not set
# CONFIG_MSM_RPCSERVER_HANDSET is not set
CONFIG_MSM_RMT_STORAGE_CLIENT=y
-CONFIG_MSM_SDIO_SMEM=y
-# CONFIG_MSM_HW3D is not set
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_SYSMON_COMM=y
CONFIG_MSM_PIL_MODEM=y
@@ -83,7 +76,6 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_COMPACTION=y
CONFIG_CP_ACCESS=y
CONFIG_CPU_FREQ=y
@@ -95,7 +87,6 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -252,7 +243,6 @@
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_TUN=y
-CONFIG_MSM_RMNET_SDIO=y
CONFIG_SMC91X=y
CONFIG_SMC911X=y
CONFIG_SMSC911X=y
@@ -315,10 +305,6 @@
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_DEV=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_VIDEOBUF2_MSM_MEM=y
-CONFIG_USB_VIDEO_CLASS=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA_V4L2=y
CONFIG_IMX074=y
CONFIG_WEBCAM_OV9726=y
@@ -328,6 +314,10 @@
CONFIG_MSM_ACTUATOR=y
CONFIG_MSM_GEMINI=y
CONFIG_OV7692=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_RADIO_TAVARUA=y
CONFIG_ION=y
CONFIG_ION_MSM=y
@@ -404,7 +394,6 @@
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_SLEEP=y
CONFIG_SWITCH=y
CONFIG_SWITCH_GPIO=y
CONFIG_RTC_CLASS=y
@@ -413,6 +402,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_TIMED_GPIO=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index a8ea31d..4e6cb05 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -24,7 +24,6 @@
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_KALLSYMS_ALL=y
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
@@ -35,6 +34,7 @@
CONFIG_MODVERSIONS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_EFI_PARTITION=y
+CONFIG_IOSCHED_TEST=y
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8960=y
CONFIG_ARCH_MSM8930=y
@@ -69,7 +69,6 @@
CONFIG_MSM_IPC_ROUTER=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
CONFIG_MSM_AVS_HW=y
-# CONFIG_MSM_HW3D is not set
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_SYSMON_COMM=y
CONFIG_MSM_PIL_LPASS_QDSP6V4=y
@@ -107,7 +106,6 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_CC_STACKPROTECTOR=y
CONFIG_CP_ACCESS=y
CONFIG_CPU_FREQ=y
@@ -119,7 +117,10 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -134,8 +135,6 @@
CONFIG_IP_PNP_DHCP=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_LRO is not set
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
@@ -355,11 +354,6 @@
CONFIG_DVB_CORE=m
CONFIG_USER_RC_INPUT=y
CONFIG_IR_GPIO_CIR=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_VIDEOBUF2_MSM_MEM=y
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-CONFIG_USB_VIDEO_CLASS=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA_V4L2=y
CONFIG_IMX074=y
CONFIG_MT9M114=y
@@ -376,17 +370,22 @@
CONFIG_MSM_GEMINI=y
CONFIG_MSM_MERCURY=y
CONFIG_MSM_CSI20_HEADER=y
-CONFIG_S5K3L1YX=y
-CONFIG_IMX091=y
CONFIG_MSM_CSIPHY=y
CONFIG_MSM_CSID=y
+CONFIG_S5K3L1YX=y
+CONFIG_IMX091=y
CONFIG_MSM_WFD=y
-CONFIG_RADIO_IRIS=y
-CONFIG_RADIO_IRIS_TRANSPORT=m
-# CONFIG_DVB_FE_CUSTOMISE is not set
CONFIG_DVB_MPQ=m
CONFIG_DVB_MPQ_DEMUX=m
CONFIG_DVB_MPQ_VIDEO=m
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_RADIO_IRIS=y
+CONFIG_RADIO_IRIS_TRANSPORT=m
+# CONFIG_DVB_FE_CUSTOMISE is not set
CONFIG_ION=y
CONFIG_ION_MSM=y
CONFIG_MSM_KGSL=y
@@ -457,14 +456,13 @@
CONFIG_MMC_BLOCK_MINORS=32
# CONFIG_MMC_BLOCK_BOUNCE is not set
CONFIG_MMC_TEST=m
+CONFIG_MMC_BLOCK_TEST=y
CONFIG_MMC_MSM=y
CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT=y
# CONFIG_MMC_MSM_SDC2_SUPPORT is not set
CONFIG_MMC_MSM_SDC3_SUPPORT=y
CONFIG_MMC_MSM_SDC3_WP_SUPPORT=y
CONFIG_MMC_MSM_SPS_SUPPORT=y
-CONFIG_IOSCHED_TEST=y
-CONFIG_MMC_BLOCK_TEST=y
CONFIG_LEDS_PM8XXX=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
@@ -475,6 +473,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_TIMED_GPIO=y
@@ -529,9 +528,3 @@
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
-CONFIG_SYNC=y
-CONFIG_SW_SYNC=y
-CONFIG_PM_WAKELOCKS=y
-CONFIG_PM_WAKELOCKS_LIMIT=0
-CONFIG_PM_AUTOSLEEP=y
-# CONFIG_PM_WAKELOCKS_GC is not set
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 9f10bc4..c4fffb9 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -23,7 +23,6 @@
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_KALLSYMS_ALL=y
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
@@ -34,6 +33,7 @@
CONFIG_MODVERSIONS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_EFI_PARTITION=y
+CONFIG_IOSCHED_TEST=y
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8960=y
CONFIG_ARCH_MSM8930=y
@@ -68,7 +68,6 @@
CONFIG_MSM_IPC_ROUTER=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
CONFIG_MSM_AVS_HW=y
-# CONFIG_MSM_HW3D is not set
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_SYSMON_COMM=y
CONFIG_MSM_PIL_LPASS_QDSP6V4=y
@@ -112,7 +111,6 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_CC_STACKPROTECTOR=y
CONFIG_CP_ACCESS=y
CONFIG_CPU_FREQ=y
@@ -124,7 +122,10 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -139,8 +140,6 @@
CONFIG_IP_PNP_DHCP=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_LRO is not set
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
@@ -360,11 +359,6 @@
CONFIG_DVB_CORE=m
CONFIG_USER_RC_INPUT=y
CONFIG_IR_GPIO_CIR=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_VIDEOBUF2_MSM_MEM=y
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-CONFIG_USB_VIDEO_CLASS=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA_V4L2=y
CONFIG_IMX074=y
CONFIG_MT9M114=y
@@ -380,17 +374,22 @@
CONFIG_MSM_GEMINI=y
CONFIG_MSM_MERCURY=y
CONFIG_MSM_CSI20_HEADER=y
-CONFIG_S5K3L1YX=y
-CONFIG_IMX091=y
CONFIG_MSM_CSIPHY=y
CONFIG_MSM_CSID=y
+CONFIG_S5K3L1YX=y
+CONFIG_IMX091=y
CONFIG_MSM_WFD=y
-CONFIG_RADIO_IRIS=y
-CONFIG_RADIO_IRIS_TRANSPORT=m
-# CONFIG_DVB_FE_CUSTOMISE is not set
CONFIG_DVB_MPQ=m
CONFIG_DVB_MPQ_DEMUX=m
CONFIG_DVB_MPQ_VIDEO=m
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_RADIO_IRIS=y
+CONFIG_RADIO_IRIS_TRANSPORT=m
+# CONFIG_DVB_FE_CUSTOMISE is not set
CONFIG_ION=y
CONFIG_ION_MSM=y
CONFIG_MSM_KGSL=y
@@ -460,14 +459,13 @@
CONFIG_MMC_BLOCK_MINORS=32
# CONFIG_MMC_BLOCK_BOUNCE is not set
CONFIG_MMC_TEST=m
+CONFIG_MMC_BLOCK_TEST=y
CONFIG_MMC_MSM=y
CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT=y
# CONFIG_MMC_MSM_SDC2_SUPPORT is not set
CONFIG_MMC_MSM_SDC3_SUPPORT=y
CONFIG_MMC_MSM_SDC3_WP_SUPPORT=y
CONFIG_MMC_MSM_SPS_SUPPORT=y
-CONFIG_IOSCHED_TEST=y
-CONFIG_MMC_BLOCK_TEST=y
CONFIG_LEDS_PM8XXX=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
@@ -478,6 +476,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_TIMED_GPIO=y
@@ -547,9 +546,3 @@
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
-CONFIG_SYNC=y
-CONFIG_SW_SYNC=y
-CONFIG_PM_WAKELOCKS=y
-CONFIG_PM_WAKELOCKS_LIMIT=0
-CONFIG_PM_AUTOSLEEP=y
-# CONFIG_PM_WAKELOCKS_GC is not set
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 663e937..c33a236 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -24,7 +24,6 @@
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_KALLSYMS_ALL=y
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
@@ -54,7 +53,6 @@
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
CONFIG_MSM_IPC_ROUTER_SECURITY=y
CONFIG_MSM_QMI_INTERFACE=y
-# CONFIG_MSM_HW3D is not set
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_SYSMON_COMM=y
CONFIG_MSM_PIL_LPASS_QDSP6V5=y
@@ -63,6 +61,7 @@
CONFIG_MSM_PIL_PRONTO=y
CONFIG_MSM_TZ_LOG=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
+CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_BUS_SCALING=y
CONFIG_MSM_WATCHDOG_V2=y
CONFIG_MSM_MEMORY_DUMP=y
@@ -71,6 +70,7 @@
CONFIG_MSM_OCMEM=y
CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
CONFIG_MSM_OCMEM_DEBUG=y
+CONFIG_SENSORS_ADSP=y
CONFIG_MSM_RTB=y
CONFIG_MSM_RTB_SEPARATE_CPUS=y
CONFIG_MSM_CACHE_ERP=y
@@ -80,6 +80,7 @@
CONFIG_MSM_L2_ERP_2BIT_PANIC=y
CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
CONFIG_MSM_UARTDM_Core_v14=y
+CONFIG_MSM_BOOT_STATS=y
CONFIG_STRICT_MEMORY_RWX=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -90,7 +91,6 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_CC_STACKPROTECTOR=y
CONFIG_CP_ACCESS=y
CONFIG_USE_OF=y
@@ -103,7 +103,10 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -117,8 +120,6 @@
CONFIG_IP_PNP_DHCP=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_IPV6=y
@@ -226,19 +227,20 @@
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=y
CONFIG_BT_HCISMD=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_ATH3K=y
CONFIG_MSM_BT_POWER=y
CONFIG_CFG80211=y
CONFIG_NL80211_TESTMODE=y
CONFIG_RFKILL=y
CONFIG_GENLOCK=y
CONFIG_GENLOCK_MISCDEVICE=y
-CONFIG_SYNC=y
-CONFIG_SW_SYNC=y
CONFIG_CMA=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_HAPTIC_ISA1200=y
CONFIG_QSEECOM=y
+CONFIG_QPNP_MISC=y
CONFIG_USB_HSIC_SMSC_HUB=y
CONFIG_TI_DRV2667=y
CONFIG_SCSI=y
@@ -291,7 +293,6 @@
CONFIG_SPMI=y
CONFIG_SPMI_MSM_PMIC_ARB=y
CONFIG_MSM_QPNP_INT=y
-CONFIG_QPNP_REVID=y
CONFIG_SLIMBUS_MSM_NGD=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
@@ -322,14 +323,14 @@
# CONFIG_MSM_CAMERA is not set
CONFIG_MT9M114=y
CONFIG_OV2720=y
+CONFIG_IMX135=y
CONFIG_MSM_CAMERA_SENSOR=y
-CONFIG_MSM_CCI=y
CONFIG_MSM_CPP=y
+CONFIG_MSM_CCI=y
CONFIG_MSM_CSI30_HEADER=y
CONFIG_MSM_CSIPHY=y
CONFIG_MSM_CSID=y
CONFIG_MSM_ISPIF=y
-CONFIG_IMX135=y
CONFIG_S5K3L1YX=y
CONFIG_MSMB_CAMERA=y
CONFIG_MSMB_JPEG=y
@@ -399,8 +400,8 @@
CONFIG_MMC_BLOCK_TEST=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_MSM=y
+CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_MSM_SPS_SUPPORT=y
CONFIG_LEDS_QPNP=y
CONFIG_LEDS_TRIGGERS=y
@@ -413,6 +414,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_TIMED_GPIO=y
@@ -424,6 +426,7 @@
CONFIG_QPNP_PWM=y
CONFIG_QPNP_POWER_ON=y
CONFIG_QPNP_CLKDIV=y
+CONFIG_QPNP_REVID=y
CONFIG_QPNP_COINCELL=y
CONFIG_MSM_IOMMU=y
CONFIG_MOBICORE_SUPPORT=m
@@ -462,17 +465,10 @@
CONFIG_PID_IN_CONTEXTIDR=y
CONFIG_KEYS=y
CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_DEV_QCRYPTO=m
CONFIG_CRYPTO_DEV_QCE=y
CONFIG_CRYPTO_DEV_QCEDEV=y
-CONFIG_CRC_CCITT=y
-CONFIG_MSM_EVENT_TIMER=y
-CONFIG_PM_WAKELOCKS=y
-CONFIG_PM_WAKELOCKS_LIMIT=0
-CONFIG_PM_AUTOSLEEP=y
-# CONFIG_PM_WAKELOCKS_GC is not set
-CONFIG_MSM_BOOT_STATS=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 2de81d4d1..1cda524 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -23,7 +23,6 @@
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_KALLSYMS_ALL=y
-CONFIG_ASHMEM=y
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
@@ -53,7 +52,6 @@
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
CONFIG_MSM_IPC_ROUTER_SECURITY=y
CONFIG_MSM_QMI_INTERFACE=y
-# CONFIG_MSM_HW3D is not set
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_SYSMON_COMM=y
CONFIG_MSM_PIL_LPASS_QDSP6V5=y
@@ -62,6 +60,7 @@
CONFIG_MSM_PIL_PRONTO=y
CONFIG_MSM_TZ_LOG=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
+CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_BUS_SCALING=y
CONFIG_MSM_WATCHDOG_V2=y
CONFIG_MSM_MEMORY_DUMP=y
@@ -70,6 +69,7 @@
CONFIG_MSM_OCMEM=y
CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
CONFIG_MSM_OCMEM_DEBUG=y
+CONFIG_SENSORS_ADSP=y
CONFIG_MSM_RTB=y
CONFIG_MSM_RTB_SEPARATE_CPUS=y
CONFIG_MSM_CACHE_ERP=y
@@ -84,6 +84,7 @@
CONFIG_MSM_CACHE_DUMP_ON_PANIC=y
CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
CONFIG_MSM_UARTDM_Core_v14=y
+CONFIG_MSM_BOOT_STATS=y
CONFIG_STRICT_MEMORY_RWX=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -94,7 +95,6 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_CC_STACKPROTECTOR=y
CONFIG_CP_ACCESS=y
CONFIG_USE_OF=y
@@ -107,7 +107,10 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -121,8 +124,6 @@
CONFIG_IP_PNP_DHCP=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_IPV6=y
@@ -230,20 +231,21 @@
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=y
CONFIG_BT_HCISMD=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_ATH3K=y
CONFIG_MSM_BT_POWER=y
CONFIG_CFG80211=y
CONFIG_NL80211_TESTMODE=y
CONFIG_RFKILL=y
CONFIG_GENLOCK=y
CONFIG_GENLOCK_MISCDEVICE=y
-CONFIG_SYNC=y
-CONFIG_SW_SYNC=y
CONFIG_CMA=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_TSPP=m
CONFIG_HAPTIC_ISA1200=y
CONFIG_QSEECOM=y
+CONFIG_QPNP_MISC=y
CONFIG_USB_HSIC_SMSC_HUB=y
CONFIG_TI_DRV2667=y
CONFIG_SCSI=y
@@ -296,7 +298,6 @@
CONFIG_SPMI=y
CONFIG_SPMI_MSM_PMIC_ARB=y
CONFIG_MSM_QPNP_INT=y
-CONFIG_QPNP_REVID=y
CONFIG_SLIMBUS_MSM_NGD=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
@@ -328,15 +329,15 @@
# CONFIG_MSM_CAMERA is not set
CONFIG_MT9M114=y
CONFIG_OV2720=y
+CONFIG_IMX135=y
CONFIG_MSM_CAMERA_SENSOR=y
-CONFIG_MSM_CCI=y
CONFIG_MSM_CPP=y
+CONFIG_MSM_CCI=y
CONFIG_MSM_CSI30_HEADER=y
CONFIG_MSM_CSIPHY=y
CONFIG_MSM_CSID=y
CONFIG_MSM_ISPIF=y
CONFIG_S5K3L1YX=y
-CONFIG_IMX135=y
CONFIG_MSMB_CAMERA=y
CONFIG_MSMB_JPEG=y
CONFIG_MSM_VIDC_V4L2=y
@@ -407,8 +408,8 @@
CONFIG_MMC_BLOCK_TEST=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_MSM=y
+CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_MSM_SPS_SUPPORT=y
CONFIG_LEDS_QPNP=y
CONFIG_LEDS_TRIGGERS=y
@@ -421,6 +422,7 @@
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_TIMED_GPIO=y
@@ -432,6 +434,7 @@
CONFIG_QPNP_PWM=y
CONFIG_QPNP_POWER_ON=y
CONFIG_QPNP_CLKDIV=y
+CONFIG_QPNP_REVID=y
CONFIG_QPNP_COINCELL=y
CONFIG_MSM_IOMMU=y
CONFIG_MSM_IOMMU_PMON=y
@@ -487,17 +490,10 @@
CONFIG_PID_IN_CONTEXTIDR=y
CONFIG_KEYS=y
CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_DEV_QCRYPTO=m
CONFIG_CRYPTO_DEV_QCE=y
CONFIG_CRYPTO_DEV_QCEDEV=y
-CONFIG_CRC_CCITT=y
-CONFIG_MSM_EVENT_TIMER=y
-CONFIG_PM_WAKELOCKS=y
-CONFIG_PM_WAKELOCKS_LIMIT=0
-CONFIG_PM_AUTOSLEEP=y
-# CONFIG_PM_WAKELOCKS_GC is not set
-CONFIG_MSM_BOOT_STATS=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 9ab1cdd..0fb8538 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -62,7 +62,6 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -185,7 +184,6 @@
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
-# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
CONFIG_SERIAL_MSM_HSL=y
CONFIG_SERIAL_MSM_HSL_CONSOLE=y
CONFIG_DIAG_CHAR=y
diff --git a/arch/arm/configs/msm9625-perf_defconfig b/arch/arm/configs/msm9625-perf_defconfig
index c2fb1487..8d6bc81 100644
--- a/arch/arm/configs/msm9625-perf_defconfig
+++ b/arch/arm/configs/msm9625-perf_defconfig
@@ -34,7 +34,6 @@
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM9625=y
# CONFIG_MSM_STACKED_MEMORY is not set
-CONFIG_CPU_HAS_L2_PMU=y
# CONFIG_MSM_FIQ_SUPPORT is not set
# CONFIG_MSM_PROC_COMM is not set
CONFIG_MSM_SMD=y
@@ -52,15 +51,18 @@
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_BUS_SCALING=y
CONFIG_MSM_WATCHDOG_V2=y
+CONFIG_MSM_MEMORY_DUMP=y
CONFIG_MSM_DLOAD_MODE=y
CONFIG_MSM_ADSP_LOADER=m
+CONFIG_MSM_RTB=y
+CONFIG_MSM_UARTDM_Core_v14=y
+CONFIG_MSM_BOOT_STATS=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_USE_OF=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
@@ -71,6 +73,7 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -161,11 +164,18 @@
CONFIG_MTD_BLOCK=y
# CONFIG_MTD_MSM_NAND is not set
CONFIG_MTD_MSM_QPIC_NAND=y
-CONFIG_SYNC=y
-CONFIG_SW_SYNC=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
# CONFIG_ANDROID_PMEM is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_BROADCOM is not set
# CONFIG_NET_VENDOR_CIRRUS is not set
@@ -174,8 +184,8 @@
CONFIG_KS8851=y
# CONFIG_NET_VENDOR_MICROCHIP is not set
# CONFIG_MSM_RMNET is not set
-# CONFIG_MSM_RMNET_BAM is not set
CONFIG_MSM_RMNET_WWAN=y
+CONFIG_ECM_IPA=y
# CONFIG_NET_VENDOR_NATSEMI is not set
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_SMSC is not set
@@ -190,9 +200,8 @@
CONFIG_INPUT_GPIO=m
CONFIG_SERIO_LIBPS2=y
# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_MSM_HSL=y
CONFIG_SERIAL_MSM_HS=y
-CONFIG_MSM_UARTDM_Core_v14=y
+CONFIG_SERIAL_MSM_HSL=y
CONFIG_DIAG_CHAR=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_MSM=y
@@ -222,18 +231,35 @@
CONFIG_ION_MSM=y
CONFIG_FB=y
CONFIG_FB_MSM=y
-CONFIG_FB_MSM_QPIC=y
CONFIG_FB_MSM_QPIC_PANEL_DETECT=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_MDM9625=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_MSM=y
+CONFIG_USB_EHCI_MSM_HSIC=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_GADGET=y
CONFIG_USB_CI13XXX_MSM=y
CONFIG_USB_G_ANDROID=y
-CONFIG_USB=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_MSM_HSIC=y
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
CONFIG_MMC_UNSAFE_RESUME=y
@@ -253,7 +279,6 @@
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_QPNP_POWER_ON=y
CONFIG_IPA=y
-CONFIG_ECM_IPA=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_TMC=y
CONFIG_CORESIGHT_TPIU=y
@@ -262,10 +287,10 @@
CONFIG_CORESIGHT_STM=y
CONFIG_CORESIGHT_ETM=y
CONFIG_CORESIGHT_EVENT=m
+CONFIG_EXT3_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_YAFFS_FS=y
-CONFIG_EXT3_FS=y
CONFIG_YAFFS_DISABLE_TAGS_ECC=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=y
@@ -298,37 +323,3 @@
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
CONFIG_LIBCRC32C=y
-CONFIG_USB=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_EHSET=y
-CONFIG_USB_EHCI_MSM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DEBUG=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_USBAT=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_STORAGE_ALAUDA=y
-CONFIG_USB_STORAGE_ONETOUCH=y
-CONFIG_USB_STORAGE_KARMA=y
-CONFIG_USB_STORAGE_CYPRESS_ATACB=y
-CONFIG_USB_EHSET_TEST_FIXTURE=y
-CONFIG_SCSI=y
-CONFIG_SCSI_TGT=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SCAN_ASYNC=y
-CONFIG_MSM_RTB=y
-CONFIG_MSM_MEMORY_DUMP=y
-CONFIG_PM_AUTOSLEEP=y
-# CONFIG_PM_WAKELOCKS_GC is not set
-CONFIG_MSM_BOOT_STATS=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 828eaa9..9e9bba9 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -34,7 +34,6 @@
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM9625=y
# CONFIG_MSM_STACKED_MEMORY is not set
-CONFIG_CPU_HAS_L2_PMU=y
# CONFIG_MSM_FIQ_SUPPORT is not set
# CONFIG_MSM_PROC_COMM is not set
CONFIG_MSM_SMD=y
@@ -52,15 +51,18 @@
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_BUS_SCALING=y
CONFIG_MSM_WATCHDOG_V2=y
+CONFIG_MSM_MEMORY_DUMP=y
CONFIG_MSM_DLOAD_MODE=y
CONFIG_MSM_ADSP_LOADER=m
+CONFIG_MSM_RTB=y
+CONFIG_MSM_UARTDM_Core_v14=y
+CONFIG_MSM_BOOT_STATS=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_USE_OF=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
@@ -71,6 +73,7 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
@@ -161,11 +164,18 @@
CONFIG_MTD_BLOCK=y
# CONFIG_MTD_MSM_NAND is not set
CONFIG_MTD_MSM_QPIC_NAND=y
-CONFIG_SYNC=y
-CONFIG_SW_SYNC=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
# CONFIG_ANDROID_PMEM is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_BROADCOM is not set
# CONFIG_NET_VENDOR_CIRRUS is not set
@@ -174,8 +184,8 @@
CONFIG_KS8851=y
# CONFIG_NET_VENDOR_MICROCHIP is not set
# CONFIG_MSM_RMNET is not set
-# CONFIG_MSM_RMNET_BAM is not set
CONFIG_MSM_RMNET_WWAN=y
+CONFIG_ECM_IPA=y
# CONFIG_NET_VENDOR_NATSEMI is not set
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_SMSC is not set
@@ -190,10 +200,9 @@
CONFIG_INPUT_GPIO=m
CONFIG_SERIO_LIBPS2=y
# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_HSL=y
CONFIG_SERIAL_MSM_HSL_CONSOLE=y
-CONFIG_SERIAL_MSM_HS=y
-CONFIG_MSM_UARTDM_Core_v14=y
CONFIG_DIAG_CHAR=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_MSM=y
@@ -223,18 +232,35 @@
CONFIG_ION_MSM=y
CONFIG_FB=y
CONFIG_FB_MSM=y
-CONFIG_FB_MSM_QPIC=y
CONFIG_FB_MSM_QPIC_PANEL_DETECT=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_MDM9625=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_MSM=y
+CONFIG_USB_EHCI_MSM_HSIC=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_GADGET=y
CONFIG_USB_CI13XXX_MSM=y
CONFIG_USB_G_ANDROID=y
-CONFIG_USB=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_MSM_HSIC=y
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
CONFIG_MMC_UNSAFE_RESUME=y
@@ -254,7 +280,6 @@
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_QPNP_POWER_ON=y
CONFIG_IPA=y
-CONFIG_ECM_IPA=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_TMC=y
CONFIG_CORESIGHT_TPIU=y
@@ -263,10 +288,10 @@
CONFIG_CORESIGHT_STM=y
CONFIG_CORESIGHT_ETM=y
CONFIG_CORESIGHT_EVENT=m
+CONFIG_EXT3_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_YAFFS_FS=y
-CONFIG_EXT3_FS=y
CONFIG_YAFFS_DISABLE_TAGS_ECC=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=y
@@ -299,37 +324,3 @@
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
CONFIG_LIBCRC32C=y
-CONFIG_USB=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_EHSET=y
-CONFIG_USB_EHCI_MSM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DEBUG=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_USBAT=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_STORAGE_ALAUDA=y
-CONFIG_USB_STORAGE_ONETOUCH=y
-CONFIG_USB_STORAGE_KARMA=y
-CONFIG_USB_STORAGE_CYPRESS_ATACB=y
-CONFIG_USB_EHSET_TEST_FIXTURE=y
-CONFIG_SCSI=y
-CONFIG_SCSI_TGT=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SCAN_ASYNC=y
-CONFIG_MSM_RTB=y
-CONFIG_MSM_MEMORY_DUMP=y
-CONFIG_PM_AUTOSLEEP=y
-# CONFIG_PM_WAKELOCKS_GC is not set
-CONFIG_MSM_BOOT_STATS=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/Kconfig b/arch/arm/mach-msm/Kconfig
index f7d993f..618668f 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -281,7 +281,6 @@
select MSM_RPM_STATS_LOG
select QMI_ENCDEC
select DONT_MAP_HOLE_AFTER_MEMBANK0
- select SENSORS_ADSP
select MSM_ULTRASOUND_B
select MSM_LPM_TEST
select MSM_RPM_LOG
@@ -428,6 +427,7 @@
select ARM_HAS_SG_CHAIN
select REGULATOR
select MSM_RPM_REGULATOR_SMD
+ select MSM_SPM_REGULATOR
config ARCH_MSM8226
bool "MSM8226"
@@ -463,6 +463,7 @@
select ARM_HAS_SG_CHAIN
select REGULATOR
select MSM_RPM_REGULATOR_SMD
+ select MSM_SPM_REGULATOR
select MSM_JTAG_MM if CORESIGHT_ETM
endmenu
@@ -1823,7 +1824,6 @@
config MSM_HW3D
tristate "MSM Hardware 3D Register Driver"
depends on ANDROID_PMEM
- default y
help
Provides access to registers needed by the userspace OpenGL|ES
library.
@@ -2062,6 +2062,16 @@
be used on systems which contain an RPM which communicates with the
application processor over SMD.
+config MSM_SPM_REGULATOR
+ bool "SPM regulator driver"
+ depends on REGULATOR && SPMI && OF_SPMI
+ help
+ Enable support for the SPM regulator driver which is used for
+ setting voltages of processor supply regulators via the SPM module
+ found inside of the MSM chips. The SPM regulator driver can be used
+ on MSM systems where the APSS processor cores are supplied by their
+ own PMIC regulator.
+
config MSM_SMCMOD
tristate "Secure Monitor Call (SMC) Module"
default n
@@ -2631,6 +2641,8 @@
config SENSORS_ADSP
bool "Enable Sensors Driver Support for ADSP"
+ depends on (ARCH_MSM8226 || ARCH_MSM8974)
+ default y
help
Add support for sensors ADSP driver.
This driver is used for exercising different sensors use cases,
@@ -2895,4 +2907,9 @@
display init, total boot time.
This figures are reported in mpm sleep clock cycles and have a
resolution of 31 bits as 1 bit is used as an overflow check.
+
+config MSM_XPU_ERR_FATAL
+ bool "Configure XPU violations as fatal errors"
+ help
+ Select if XPU violations have to be configured as fatal errors.
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 161ee3d..d3acbc7 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -79,6 +79,7 @@
obj-$(CONFIG_MSM_SMP2P) += smp2p.o smp2p_debug.o smp2p_gpio.o
obj-$(CONFIG_MSM_SMP2P_TEST) += smp2p_loopback.o smp2p_test.o smp2p_gpio_test.o smp2p_spinlock_test.o
obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
+obj-$(CONFIG_MSM_XPU_ERR_FATAL) += scm-xpu.o
obj-$(CONFIG_MSM_SECURE_IO) += scm-io.o
obj-$(CONFIG_MSM_PIL) += peripheral-loader.o
obj-$(CONFIG_MSM_PIL) += scm-pas.o
@@ -209,6 +210,7 @@
endif
obj-$(CONFIG_MSM_RPM_REGULATOR_SMD) += rpm-regulator-smd.o
+obj-$(CONFIG_MSM_SPM_REGULATOR) += spm-regulator.o
ifdef CONFIG_MSM_SUBSYSTEM_RESTART
obj-y += subsystem_notif.o
diff --git a/arch/arm/mach-msm/acpuclock-8226.c b/arch/arm/mach-msm/acpuclock-8226.c
index fcbd74d..73ea435 100644
--- a/arch/arm/mach-msm/acpuclock-8226.c
+++ b/arch/arm/mach-msm/acpuclock-8226.c
@@ -57,7 +57,7 @@
{ 1, 300000, PLL0, 4, 2, 1150000, 1150000, 4 },
{ 1, 384000, ACPUPLL, 5, 0, 1150000, 1150000, 4 },
{ 1, 600000, PLL0, 4, 0, 1150000, 1150000, 6 },
- { 1, 787200, ACPUPLL, 5, 0, 1150000, 1150000, 6 },
+ { 1, 787200, ACPUPLL, 5, 0, 1150000, 1150000, 7 },
{ 0, 998400, ACPUPLL, 5, 0, 1150000, 1150000, 7 },
{ 0, 1190400, ACPUPLL, 5, 0, 1150000, 1150000, 7 },
{ 0 }
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/audio-7627a-devices.c b/arch/arm/mach-msm/audio-7627a-devices.c
index 61d06e7..95727de 100644
--- a/arch/arm/mach-msm/audio-7627a-devices.c
+++ b/arch/arm/mach-msm/audio-7627a-devices.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/android_pmem.h>
#include <mach/board.h>
#include "board-msm7627a.h"
diff --git a/arch/arm/mach-msm/board-8226-gpiomux.c b/arch/arm/mach-msm/board-8226-gpiomux.c
index 2b70e7c..819ca56 100644
--- a/arch/arm/mach-msm/board-8226-gpiomux.c
+++ b/arch/arm/mach-msm/board-8226-gpiomux.c
@@ -288,6 +288,115 @@
},
},
};
+
+static struct gpiomux_setting gpio_suspend_config[] = {
+ {
+ .func = GPIOMUX_FUNC_GPIO, /* IN-NP */
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+ {
+ .func = GPIOMUX_FUNC_GPIO, /* O-LOW */
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ .dir = GPIOMUX_OUT_LOW,
+ },
+};
+
+static struct gpiomux_setting cam_settings[] = {
+ {
+ .func = GPIOMUX_FUNC_1, /*active 1*/ /* 0 */
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+
+ {
+ .func = GPIOMUX_FUNC_1, /*suspend*/ /* 1 */
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+ },
+
+ {
+ .func = GPIOMUX_FUNC_1, /*i2c suspend*/ /* 2 */
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_KEEPER,
+ },
+
+ {
+ .func = GPIOMUX_FUNC_GPIO, /*active 0*/ /* 3 */
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+
+ {
+ .func = GPIOMUX_FUNC_GPIO, /*suspend 0*/ /* 4 */
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+ },
+};
+
+
+static struct msm_gpiomux_config msm_sensor_configs[] __initdata = {
+ {
+ .gpio = 26, /* CAM_MCLK0 */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cam_settings[0],
+ [GPIOMUX_SUSPENDED] = &cam_settings[1],
+ },
+ },
+ {
+ .gpio = 27, /* CAM_MCLK1 */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cam_settings[0],
+ [GPIOMUX_SUSPENDED] = &cam_settings[1],
+ },
+
+ },
+ {
+ .gpio = 29, /* CCI_I2C_SDA0 */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cam_settings[0],
+ [GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
+ },
+ },
+ {
+ .gpio = 30, /* CCI_I2C_SCL0 */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cam_settings[0],
+ [GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
+ },
+ },
+ {
+ .gpio = 36, /* CAM1_STANDBY_N */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cam_settings[3],
+ [GPIOMUX_SUSPENDED] = &cam_settings[4],
+ },
+ },
+ {
+ .gpio = 37, /* CAM1_RST_N */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cam_settings[3],
+ [GPIOMUX_SUSPENDED] = &cam_settings[4],
+ },
+ },
+ {
+ .gpio = 35, /* CAM2_STANDBY_N */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cam_settings[3],
+ [GPIOMUX_SUSPENDED] = &cam_settings[4],
+ },
+ },
+ {
+ .gpio = 28, /* CAM2_RST_N */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cam_settings[3],
+ [GPIOMUX_SUSPENDED] = &cam_settings[4],
+ },
+ },
+
+};
+
void __init msm8226_init_gpiomux(void)
{
int rc;
@@ -313,4 +422,5 @@
ARRAY_SIZE(msm_synaptics_configs));
msm_gpiomux_install_nowrite(msm_lcd_configs,
ARRAY_SIZE(msm_lcd_configs));
+ msm_gpiomux_install(msm_sensor_configs, ARRAY_SIZE(msm_sensor_configs));
}
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index dcab9ca..872fabe 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -24,9 +24,6 @@
#include <linux/of_fdt.h>
#include <linux/of_irq.h>
#include <linux/memory.h>
-#ifdef CONFIG_ANDROID_PMEM
-#include <linux/android_pmem.h>
-#endif
#include <linux/regulator/qpnp-regulator.h>
#include <asm/mach/map.h>
#include <asm/hardware/gic.h>
diff --git a/arch/arm/mach-msm/board-8974.c b/arch/arm/mach-msm/board-8974.c
index f864583..e624e3f 100644
--- a/arch/arm/mach-msm/board-8974.c
+++ b/arch/arm/mach-msm/board-8974.c
@@ -20,9 +20,6 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/memory.h>
-#ifdef CONFIG_ANDROID_PMEM
-#include <linux/android_pmem.h>
-#endif
#include <linux/regulator/machine.h>
#include <linux/regulator/krait-regulator.h>
#include <linux/msm_thermal.h>
@@ -126,6 +123,14 @@
"msm_sdcc.3", NULL),
OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF98E4000, \
"msm_sdcc.4", NULL),
+ OF_DEV_AUXDATA("qcom,sdhci-msm", 0xF9824900, \
+ "msm_sdcc.1", NULL),
+ OF_DEV_AUXDATA("qcom,sdhci-msm", 0xF98A4900, \
+ "msm_sdcc.2", NULL),
+ OF_DEV_AUXDATA("qcom,sdhci-msm", 0xF9864900, \
+ "msm_sdcc.3", NULL),
+ OF_DEV_AUXDATA("qcom,sdhci-msm", 0xF98E4900, \
+ "msm_sdcc.4", NULL),
OF_DEV_AUXDATA("qcom,msm-rng", 0xF9BFF000, \
"msm_rng", NULL),
OF_DEV_AUXDATA("qcom,qseecom", 0xFE806000, \
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index 5f0d75f..cca38b0 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -54,7 +54,6 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/i2c.h>
-#include <linux/android_pmem.h>
#include <mach/camera.h>
#ifdef CONFIG_USB_G_ANDROID
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 0654a0d..be3c1a3 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -39,7 +39,6 @@
#include <linux/msm_adc.h>
#include <linux/dma-mapping.h>
#include <linux/regulator/consumer.h>
-
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/setup.h>
@@ -54,7 +53,6 @@
#include <mach/msm_spi.h>
#include <mach/qdsp5v2/msm_lpa.h>
#include <mach/dma.h>
-#include <linux/android_pmem.h>
#include <linux/input/msm_ts.h>
#include <mach/pmic.h>
#include <mach/rpc_pmapp.h>
@@ -3531,19 +3529,6 @@
}
#endif
-static struct android_pmem_platform_data android_pmem_pdata = {
- .name = "pmem",
- .allocator_type = PMEM_ALLOCATORTYPE_ALLORNOTHING,
- .cached = 1,
- .memory_type = MEMTYPE_EBI0,
-};
-
-static struct platform_device android_pmem_device = {
- .name = "android_pmem",
- .id = 0,
- .dev = { .platform_data = &android_pmem_pdata },
-};
-
#ifndef CONFIG_SPI_QSD
static int lcdc_gpio_array_num[] = {
45, /* spi_clk */
@@ -4021,32 +4006,6 @@
.id = -1,
};
-static struct android_pmem_platform_data android_pmem_adsp_pdata = {
- .name = "pmem_adsp",
- .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
- .cached = 0,
- .memory_type = MEMTYPE_EBI0,
-};
-
-static struct android_pmem_platform_data android_pmem_audio_pdata = {
- .name = "pmem_audio",
- .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
- .cached = 0,
- .memory_type = MEMTYPE_EBI0,
-};
-
-static struct platform_device android_pmem_adsp_device = {
- .name = "android_pmem",
- .id = 2,
- .dev = { .platform_data = &android_pmem_adsp_pdata },
-};
-
-static struct platform_device android_pmem_audio_device = {
- .name = "android_pmem",
- .id = 4,
- .dev = { .platform_data = &android_pmem_audio_pdata },
-};
-
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
@@ -5395,7 +5354,6 @@
#ifdef CONFIG_I2C_SSBI
&msm_device_ssbi7,
#endif
- &android_pmem_device,
&msm_fb_device,
#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
&msm_v4l2_video_overlay_device,
@@ -5407,8 +5365,6 @@
&msm_rotator_device,
#endif
&lcdc_sharp_panel_device,
- &android_pmem_adsp_device,
- &android_pmem_audio_device,
&msm_device_i2c,
&msm_device_i2c_2,
&msm_device_uart_dm1,
@@ -7234,39 +7190,6 @@
#endif
}
-static void __init size_pmem_devices(void)
-{
-#ifdef CONFIG_ANDROID_PMEM
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-
- android_pmem_adsp_pdata.size = size;
- android_pmem_audio_pdata.size = pmem_audio_size;
- android_pmem_pdata.size = pmem_sf_size;
-#endif
-#endif
-}
-
-#ifdef CONFIG_ANDROID_PMEM
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-static void __init reserve_memory_for(struct android_pmem_platform_data *p)
-{
- msm7x30_reserve_table[p->memory_type].size += p->size;
-}
-#endif
-#endif
-
-static void __init reserve_pmem_memory(void)
-{
-#ifdef CONFIG_ANDROID_PMEM
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
- reserve_memory_for(&android_pmem_adsp_pdata);
- reserve_memory_for(&android_pmem_audio_pdata);
- reserve_memory_for(&android_pmem_pdata);
- msm7x30_reserve_table[MEMTYPE_EBI0].size += pmem_kernel_ebi0_size;
-#endif
-#endif
-}
-
static void __init reserve_mdp_memory(void)
{
mdp_pdata.ov0_wb_size = MSM_FB_OVERLAY0_WRITEBACK_SIZE;
@@ -7294,8 +7217,6 @@
static void __init msm7x30_calculate_reserve_sizes(void)
{
fix_sizes();
- size_pmem_devices();
- reserve_pmem_memory();
reserve_mdp_memory();
size_ion_devices();
reserve_ion_memory();
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 02a753a..6b98393 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -41,10 +41,6 @@
#include <linux/dma-mapping.h>
#include <linux/i2c/bq27520.h>
-#ifdef CONFIG_ANDROID_PMEM
-#include <linux/android_pmem.h>
-#endif
-
#if defined(CONFIG_SMB137B_CHARGER) || defined(CONFIG_SMB137B_CHARGER_MODULE)
#include <linux/i2c/smb137b.h>
#endif
@@ -2808,47 +2804,6 @@
.dev.platform_data = &msm_fb_pdata,
};
-#ifdef CONFIG_ANDROID_PMEM
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-static struct android_pmem_platform_data android_pmem_pdata = {
- .name = "pmem",
- .allocator_type = PMEM_ALLOCATORTYPE_ALLORNOTHING,
- .cached = 1,
- .memory_type = MEMTYPE_EBI1,
-};
-
-static struct platform_device android_pmem_device = {
- .name = "android_pmem",
- .id = 0,
- .dev = {.platform_data = &android_pmem_pdata},
-};
-
-static struct android_pmem_platform_data android_pmem_adsp_pdata = {
- .name = "pmem_adsp",
- .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
- .cached = 0,
- .memory_type = MEMTYPE_EBI1,
-};
-
-static struct platform_device android_pmem_adsp_device = {
- .name = "android_pmem",
- .id = 2,
- .dev = { .platform_data = &android_pmem_adsp_pdata },
-};
-
-static struct android_pmem_platform_data android_pmem_audio_pdata = {
- .name = "pmem_audio",
- .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
- .cached = 0,
- .memory_type = MEMTYPE_EBI1,
-};
-
-static struct platform_device android_pmem_audio_device = {
- .name = "android_pmem",
- .id = 4,
- .dev = { .platform_data = &android_pmem_audio_pdata },
-};
-#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
#define PMEM_BUS_WIDTH(_bw) \
{ \
.vectors = &(struct msm_bus_vectors){ \
@@ -2891,6 +2846,49 @@
{
return (void *)msm_bus_scale_register_client(&smi_client_pdata);
}
+
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+static struct android_pmem_platform_data android_pmem_pdata = {
+ .name = "pmem",
+ .allocator_type = PMEM_ALLOCATORTYPE_ALLORNOTHING,
+ .cached = 1,
+ .memory_type = MEMTYPE_EBI1,
+};
+
+static struct platform_device android_pmem_device = {
+ .name = "android_pmem",
+ .id = 0,
+ .dev = {.platform_data = &android_pmem_pdata},
+};
+
+static struct android_pmem_platform_data android_pmem_adsp_pdata = {
+ .name = "pmem_adsp",
+ .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
+ .cached = 0,
+ .memory_type = MEMTYPE_EBI1,
+};
+
+static struct platform_device android_pmem_adsp_device = {
+ .name = "android_pmem",
+ .id = 2,
+ .dev = { .platform_data = &android_pmem_adsp_pdata },
+};
+
+static struct android_pmem_platform_data android_pmem_audio_pdata = {
+ .name = "pmem_audio",
+ .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
+ .cached = 0,
+ .memory_type = MEMTYPE_EBI1,
+};
+
+static struct platform_device android_pmem_audio_device = {
+ .name = "android_pmem",
+ .id = 4,
+ .dev = { .platform_data = &android_pmem_audio_pdata },
+};
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
+
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
static struct android_pmem_platform_data android_pmem_smipool_pdata = {
.name = "pmem_smipool",
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 8e2b7c9..1f522a1 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -169,22 +169,14 @@
VDD_DIG_NUM
};
-static const int vdd_corner[] = {
- [VDD_DIG_NONE] = RPM_REGULATOR_CORNER_NONE,
- [VDD_DIG_LOW] = RPM_REGULATOR_CORNER_SVS_SOC,
- [VDD_DIG_NOMINAL] = RPM_REGULATOR_CORNER_NORMAL,
- [VDD_DIG_HIGH] = RPM_REGULATOR_CORNER_SUPER_TURBO,
+static const int *vdd_corner[] = {
+ [VDD_DIG_NONE] = VDD_UV(RPM_REGULATOR_CORNER_NONE),
+ [VDD_DIG_LOW] = VDD_UV(RPM_REGULATOR_CORNER_SVS_SOC),
+ [VDD_DIG_NOMINAL] = VDD_UV(RPM_REGULATOR_CORNER_NORMAL),
+ [VDD_DIG_HIGH] = VDD_UV(RPM_REGULATOR_CORNER_SUPER_TURBO),
};
-static struct regulator *vdd_dig_reg;
-
-static int set_vdd_dig(struct clk_vdd_class *vdd_class, int level)
-{
- return regulator_set_voltage(vdd_dig_reg, vdd_corner[level],
- RPM_REGULATOR_CORNER_SUPER_TURBO);
-}
-
-static DEFINE_VDD_CLASS(vdd_dig, set_vdd_dig, VDD_DIG_NUM);
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner);
#define RPM_MISC_CLK_TYPE 0x306b6c63
#define RPM_BUS_CLK_TYPE 0x316b6c63
@@ -1668,7 +1660,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 +1812,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,
@@ -2009,14 +2004,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,
@@ -2754,19 +2752,12 @@
VDD_SR2_PLL_NUM
};
-static struct regulator *vdd_sr2_reg;
-static int set_vdd_sr2_pll(struct clk_vdd_class *vdd_class, int level)
-{
- if (level == VDD_SR2_PLL_ON) {
- return regulator_set_voltage(vdd_sr2_reg, 1800000,
- 1800000);
- } else {
- return regulator_set_voltage(vdd_sr2_reg, 0, 1800000);
- }
-}
+static const int *vdd_sr2_levels[] = {
+ [VDD_SR2_PLL_OFF] = VDD_UV(0),
+ [VDD_SR2_PLL_ON] = VDD_UV(1800000),
+};
-static DEFINE_VDD_CLASS(vdd_sr2_pll, set_vdd_sr2_pll,
- VDD_SR2_PLL_NUM);
+static DEFINE_VDD_REGULATORS(vdd_sr2_pll, VDD_SR2_PLL_NUM, 1, vdd_sr2_levels);
static struct pll_freq_tbl apcs_pll_freq[] = {
F_APCS_PLL( 384000000, 20, 0x0, 0x1, 0x0, 0x0, 0x0),
@@ -3270,10 +3261,12 @@
CLK_LOOKUP("core_clk", mdss_axi_clk.c, "fd928000.qcom,iommu"),
/* MM sensor clocks */
- CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6e.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6f.qcom,camera"),
CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "90.qcom,camera"),
- CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6e.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6d.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6f.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "90.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6d.qcom,camera"),
/* CCI clocks */
CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
@@ -3365,6 +3358,19 @@
CLK_LOOKUP("core_clk", camss_jpeg_jpeg_axi_clk.c,
"fda64000.qcom,iommu"),
+ CLK_LOOKUP("micro_iface_clk", camss_micro_ahb_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("cpp_iface_clk", camss_vfe_cpp_ahb_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("cpp_core_clk", camss_vfe_cpp_clk.c, "fda04000.qcom,cpp"),
+ CLK_LOOKUP("cpp_bus_clk", camss_vfe_vfe_axi_clk.c, "fda04000.qcom,cpp"),
+ CLK_LOOKUP("vfe_clk_src", vfe0_clk_src.c, "fda04000.qcom,cpp"),
+ CLK_LOOKUP("camss_vfe_vfe_clk", camss_vfe_vfe0_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("iface_clk", camss_vfe_vfe_ahb_clk.c, "fda04000.qcom,cpp"),
+
/* KGSL Clocks */
CLK_LOOKUP("core_clk", oxili_gfx3d_clk.c, "fdb00000.qcom,kgsl-3d0"),
CLK_LOOKUP("iface_clk", oxilicx_ahb_clk.c, "fdb00000.qcom,kgsl-3d0"),
@@ -3505,23 +3511,23 @@
clk_ops_local_pll.enable = sr_hpm_lp_pll_clk_enable;
- vdd_dig_reg = regulator_get(NULL, "vdd_dig");
- if (IS_ERR(vdd_dig_reg))
+ vdd_dig.regulator[0] = regulator_get(NULL, "vdd_dig");
+ if (IS_ERR(vdd_dig.regulator[0]))
panic("clock-8226: Unable to get the vdd_dig regulator!");
- vdd_sr2_reg = regulator_get(NULL, "vdd_sr2_pll");
- if (IS_ERR(vdd_dig_reg))
+ vdd_sr2_pll.regulator[0] = regulator_get(NULL, "vdd_sr2_pll");
+ if (IS_ERR(vdd_sr2_pll.regulator[0]))
panic("clock-8226: Unable to get the sr2_pll regulator!");
/*
* These regulators are used at boot. Ensure they stay on
* while the clock framework comes online.
*/
- regulator_set_voltage(vdd_sr2_reg, 1800000, 1800000);
- regulator_enable(vdd_sr2_reg);
+ regulator_set_voltage(vdd_sr2_pll.regulator[0], 1800000, 1800000);
+ regulator_enable(vdd_sr2_pll.regulator[0]);
vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
- regulator_enable(vdd_dig_reg);
+ regulator_enable(vdd_dig.regulator[0]);
/*
* Hold an active set vote at a rate of 40MHz for the MMSS NOC AHB
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index c517c10..a645e9c 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -445,22 +445,14 @@
VDD_DIG_NUM
};
-static const int vdd_corner[] = {
- [VDD_DIG_NONE] = RPM_REGULATOR_CORNER_NONE,
- [VDD_DIG_LOW] = RPM_REGULATOR_CORNER_SVS_SOC,
- [VDD_DIG_NOMINAL] = RPM_REGULATOR_CORNER_NORMAL,
- [VDD_DIG_HIGH] = RPM_REGULATOR_CORNER_SUPER_TURBO,
+static const int *vdd_corner[] = {
+ [VDD_DIG_NONE] = VDD_UV(RPM_REGULATOR_CORNER_NONE),
+ [VDD_DIG_LOW] = VDD_UV(RPM_REGULATOR_CORNER_SVS_SOC),
+ [VDD_DIG_NOMINAL] = VDD_UV(RPM_REGULATOR_CORNER_NORMAL),
+ [VDD_DIG_HIGH] = VDD_UV(RPM_REGULATOR_CORNER_SUPER_TURBO),
};
-static struct regulator *vdd_dig_reg;
-
-static int set_vdd_dig(struct clk_vdd_class *vdd_class, int level)
-{
- return regulator_set_voltage(vdd_dig_reg, vdd_corner[level],
- RPM_REGULATOR_CORNER_SUPER_TURBO);
-}
-
-static DEFINE_VDD_CLASS(vdd_dig, set_vdd_dig, VDD_DIG_NUM);
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner);
#define RPM_MISC_CLK_TYPE 0x306b6c63
#define RPM_BUS_CLK_TYPE 0x316b6c63
@@ -550,20 +542,13 @@
VDD_SR2_PLL_NUM
};
-static struct regulator *vdd_sr2_reg;
+static const int *vdd_sr2_pll_levels[] = {
+ [VDD_SR2_PLL_OFF] = VDD_UV(0),
+ [VDD_SR2_PLL_ON] = VDD_UV(1800000),
+};
-static int set_vdd_sr2_pll(struct clk_vdd_class *vdd_class, int level)
-{
- if (level == VDD_SR2_PLL_ON) {
- return regulator_set_voltage(vdd_sr2_reg, 1800000,
- 1800000);
- } else {
- return regulator_set_voltage(vdd_sr2_reg, 0, 1800000);
- }
-}
-
-static DEFINE_VDD_CLASS(vdd_sr2_pll, set_vdd_sr2_pll,
- VDD_SR2_PLL_NUM);
+static DEFINE_VDD_REGULATORS(vdd_sr2_pll, VDD_SR2_PLL_NUM, 1,
+ vdd_sr2_pll_levels);
static struct pll_freq_tbl apcs_pll_freq[] = {
F_APCS_PLL( 384000000, 20, 0x0, 0x1, 0x0, 0x0, 0x0),
@@ -3051,6 +3036,8 @@
CLK_LOOKUP("mem_clk", bimc_msmbus_clk.c, "msm_bimc"),
CLK_LOOKUP("mem_a_clk", bimc_msmbus_a_clk.c, "msm_bimc"),
CLK_LOOKUP("mem_clk", bimc_acpu_a_clk.c, ""),
+ CLK_LOOKUP("bus_clk", mmss_s0_axi_clk.c, "msm_mmss_noc"),
+ CLK_LOOKUP("bus_a_clk", mmss_s0_axi_clk.c, "msm_mmss_noc"),
/* CoreSight clocks */
CLK_LOOKUP("core_clk", qdss_clk.c, "fc326000.tmc"),
@@ -3546,16 +3533,16 @@
clk_ops_local_pll.enable = sr_hpm_lp_pll_clk_enable;
- vdd_dig_reg = regulator_get(NULL, "vdd_dig");
- if (IS_ERR(vdd_dig_reg))
+ vdd_dig.regulator[0] = regulator_get(NULL, "vdd_dig");
+ if (IS_ERR(vdd_dig.regulator[0]))
panic("clock-8610: Unable to get the vdd_dig regulator!");
- vdd_sr2_reg = regulator_get(NULL, "vdd_sr2_pll");
- if (IS_ERR(vdd_sr2_reg))
+ vdd_sr2_pll.regulator[0] = regulator_get(NULL, "vdd_sr2_pll");
+ if (IS_ERR(vdd_sr2_pll.regulator[0]))
panic("clock-8610: Unable to get the vdd_sr2_pll regulator!");
- regulator_set_voltage(vdd_sr2_reg, 1800000, 1800000);
- regulator_enable(vdd_sr2_reg);
+ regulator_set_voltage(vdd_sr2_pll.regulator[0], 1800000, 1800000);
+ regulator_enable(vdd_sr2_pll.regulator[0]);
/*
* TODO: Set a voltage and enable vdd_dig, leaving the voltage high
@@ -3564,7 +3551,7 @@
* its necessity.
*/
vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
- regulator_enable(vdd_dig_reg);
+ regulator_enable(vdd_dig.regulator[0]);
enable_rpm_scaling();
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index c5594e2..e6874b7 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/iopoll.h>
+#include <linux/regulator/consumer.h>
#include <mach/rpm-regulator-smd.h>
#include <mach/socinfo.h>
@@ -637,22 +638,14 @@
VDD_DIG_NUM
};
-static const int vdd_corner[] = {
- [VDD_DIG_NONE] = RPM_REGULATOR_CORNER_NONE,
- [VDD_DIG_LOW] = RPM_REGULATOR_CORNER_SVS_SOC,
- [VDD_DIG_NOMINAL] = RPM_REGULATOR_CORNER_NORMAL,
- [VDD_DIG_HIGH] = RPM_REGULATOR_CORNER_SUPER_TURBO,
+static const int *vdd_corner[] = {
+ [VDD_DIG_NONE] = VDD_UV(RPM_REGULATOR_CORNER_NONE),
+ [VDD_DIG_LOW] = VDD_UV(RPM_REGULATOR_CORNER_SVS_SOC),
+ [VDD_DIG_NOMINAL] = VDD_UV(RPM_REGULATOR_CORNER_NORMAL),
+ [VDD_DIG_HIGH] = VDD_UV(RPM_REGULATOR_CORNER_SUPER_TURBO),
};
-static struct rpm_regulator *vdd_dig_reg;
-
-static int set_vdd_dig(struct clk_vdd_class *vdd_class, int level)
-{
- return rpm_regulator_set_voltage(vdd_dig_reg, vdd_corner[level],
- RPM_REGULATOR_CORNER_SUPER_TURBO);
-}
-
-static DEFINE_VDD_CLASS(vdd_dig, set_vdd_dig, VDD_DIG_NUM);
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner);
#define RPM_MISC_CLK_TYPE 0x306b6c63
#define RPM_BUS_CLK_TYPE 0x316b6c63
@@ -714,6 +707,7 @@
static struct pll_vote_clk gpll0_clk_src = {
.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE_REG,
+ .en_mask = BIT(0),
.status_reg = (void __iomem *)GPLL0_STATUS_REG,
.status_mask = BIT(17),
.base = &virt_bases[GCC_BASE],
@@ -3026,14 +3020,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 +3044,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 +3225,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 +3248,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 +4739,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"),
@@ -5482,8 +5483,8 @@
clk_ops_local_pll.enable = sr_hpm_lp_pll_clk_enable;
- vdd_dig_reg = rpm_regulator_get(NULL, "vdd_dig");
- if (IS_ERR(vdd_dig_reg))
+ vdd_dig.regulator[0] = regulator_get(NULL, "vdd_dig");
+ if (IS_ERR(vdd_dig.regulator[0]))
panic("clock-8974: Unable to get the vdd_dig regulator!");
/*
@@ -5493,7 +5494,7 @@
* its necessity.
*/
vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
- rpm_regulator_enable(vdd_dig_reg);
+ regulator_enable(vdd_dig.regulator[0]);
enable_rpm_scaling();
@@ -5548,8 +5549,8 @@
sdcc3_apps_clk_src.freq_tbl = ftbl_gcc_sdcc_apps_rumi_clk;
sdcc4_apps_clk_src.freq_tbl = ftbl_gcc_sdcc_apps_rumi_clk;
- vdd_dig_reg = rpm_regulator_get(NULL, "vdd_dig");
- if (IS_ERR(vdd_dig_reg))
+ vdd_dig.regulator[0] = regulator_get(NULL, "vdd_dig");
+ if (IS_ERR(vdd_dig.regulator[0]))
panic("clock-8974: Unable to get the vdd_dig regulator!");
/*
@@ -5559,7 +5560,7 @@
* its necessity.
*/
vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
- rpm_regulator_enable(vdd_dig_reg);
+ regulator_enable(vdd_dig.regulator[0]);
}
struct clock_init_data msm8974_clock_init_data __initdata = {
diff --git a/arch/arm/mach-msm/clock-9625.c b/arch/arm/mach-msm/clock-9625.c
index 9648320..d8e4ed5 100644
--- a/arch/arm/mach-msm/clock-9625.c
+++ b/arch/arm/mach-msm/clock-9625.c
@@ -278,22 +278,14 @@
VDD_DIG_NUM
};
-static const int vdd_corner[] = {
- [VDD_DIG_NONE] = RPM_REGULATOR_CORNER_NONE,
- [VDD_DIG_LOW] = RPM_REGULATOR_CORNER_SVS_SOC,
- [VDD_DIG_NOMINAL] = RPM_REGULATOR_CORNER_NORMAL,
- [VDD_DIG_HIGH] = RPM_REGULATOR_CORNER_SUPER_TURBO,
+static const int *vdd_corner[] = {
+ [VDD_DIG_NONE] = VDD_UV(RPM_REGULATOR_CORNER_NONE),
+ [VDD_DIG_LOW] = VDD_UV(RPM_REGULATOR_CORNER_SVS_SOC),
+ [VDD_DIG_NOMINAL] = VDD_UV(RPM_REGULATOR_CORNER_NORMAL),
+ [VDD_DIG_HIGH] = VDD_UV(RPM_REGULATOR_CORNER_SUPER_TURBO),
};
-static struct regulator *vdd_dig_reg;
-
-int set_vdd_dig(struct clk_vdd_class *vdd_class, int level)
-{
- return regulator_set_voltage(vdd_dig_reg, vdd_corner[level],
- RPM_REGULATOR_CORNER_SUPER_TURBO);
-}
-
-static DEFINE_VDD_CLASS(vdd_dig, set_vdd_dig, VDD_DIG_NUM);
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner);
/* TODO: Needs to confirm the below values */
#define RPM_MISC_CLK_TYPE 0x306b6c63
@@ -344,6 +336,7 @@
static struct pll_vote_clk gpll0_clk_src = {
.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE_REG,
+ .en_mask = BIT(0),
.status_reg = (void __iomem *)GPLL0_STATUS_REG,
.status_mask = BIT(17),
.soft_vote = &soft_vote_gpll0,
@@ -360,6 +353,7 @@
static struct pll_vote_clk gpll0_activeonly_clk_src = {
.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE_REG,
+ .en_mask = BIT(0),
.status_reg = (void __iomem *)GPLL0_STATUS_REG,
.status_mask = BIT(17),
.soft_vote = &soft_vote_gpll0,
@@ -2060,12 +2054,12 @@
clk_ops_local_pll.enable = sr_pll_clk_enable_9625;
- vdd_dig_reg = regulator_get(NULL, "vdd_dig");
- if (IS_ERR(vdd_dig_reg))
+ vdd_dig.regulator[0] = regulator_get(NULL, "vdd_dig");
+ if (IS_ERR(vdd_dig.regulator[0]))
panic("clock-9625: Unable to get the vdd_dig regulator!");
vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
- regulator_enable(vdd_dig_reg);
+ regulator_enable(vdd_dig.regulator[0]);
enable_rpm_scaling();
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/clock.c b/arch/arm/mach-msm/clock.c
index e0ee084..ecd25fc 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -22,6 +22,7 @@
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/list.h>
+#include <linux/regulator/consumer.h>
#include <trace/events/power.h>
#include <mach/clk-provider.h>
#include "clock.h"
@@ -53,20 +54,39 @@
/* Update voltage level given the current votes. */
static int update_vdd(struct clk_vdd_class *vdd_class)
{
- int level, rc;
+ int level, rc = 0, i;
+ struct regulator **r = vdd_class->regulator;
+ const int **vdd_uv = vdd_class->vdd_uv;
+ int max_level = vdd_class->num_levels - 1;
- for (level = vdd_class->num_levels-1; level > 0; level--)
+ for (level = max_level; level > 0; level--)
if (vdd_class->level_votes[level])
break;
if (level == vdd_class->cur_level)
return 0;
- rc = vdd_class->set_vdd(vdd_class, level);
+ for (i = 0; i < vdd_class->num_regulators; i++) {
+ rc = regulator_set_voltage(r[i], vdd_uv[level][i],
+ vdd_uv[max_level][i]);
+ if (rc)
+ goto set_voltage_fail;
+ }
+ if (vdd_class->set_vdd && !vdd_class->num_regulators)
+ rc = vdd_class->set_vdd(vdd_class, level);
+
if (!rc)
vdd_class->cur_level = level;
return rc;
+
+set_voltage_fail:
+ level = vdd_class->cur_level;
+ for (i--; i >= 0; i--)
+ regulator_set_voltage(r[i], vdd_uv[level][i],
+ vdd_uv[max_level][i]);
+
+ return rc;
}
/* Vote for a voltage level. */
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index b7707d7..656c3f4 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -3154,6 +3154,7 @@
static struct resource coresight_funnel_resources[] = {
{
+ .name = "funnel-base",
.start = CORESIGHT_FUNNEL_PHYS_BASE,
.end = CORESIGHT_FUNNEL_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
@@ -3186,6 +3187,7 @@
static struct resource coresight_etm2_resources[] = {
{
+ .name = "etm-base",
.start = CORESIGHT_ETM2_PHYS_BASE,
.end = CORESIGHT_ETM2_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
@@ -3218,6 +3220,7 @@
static struct resource coresight_etm3_resources[] = {
{
+ .name = "etm-base",
.start = CORESIGHT_ETM3_PHYS_BASE,
.end = CORESIGHT_ETM3_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 2bd9dfe..d4c33e3 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -21,7 +21,6 @@
#include <asm/clkdev.h>
#include <mach/gpio.h>
#include <mach/kgsl.h>
-#include <linux/android_pmem.h>
#include <mach/irqs-8960.h>
#include <mach/dma.h>
#include <linux/dma-mapping.h>
@@ -4105,6 +4104,7 @@
static struct resource coresight_tpiu_resources[] = {
{
+ .name = "tpiu-base",
.start = CORESIGHT_TPIU_PHYS_BASE,
.end = CORESIGHT_TPIU_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
@@ -4130,6 +4130,7 @@
static struct resource coresight_etb_resources[] = {
{
+ .name = "etb-base",
.start = CORESIGHT_ETB_PHYS_BASE,
.end = CORESIGHT_ETB_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
@@ -4156,6 +4157,7 @@
static struct resource coresight_funnel_resources[] = {
{
+ .name = "funnel-base",
.start = CORESIGHT_FUNNEL_PHYS_BASE,
.end = CORESIGHT_FUNNEL_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
@@ -4188,11 +4190,13 @@
static struct resource coresight_stm_resources[] = {
{
+ .name = "stm-base",
.start = CORESIGHT_STM_PHYS_BASE,
.end = CORESIGHT_STM_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{
+ .name = "stm-data-base",
.start = CORESIGHT_STM_CHANNEL_PHYS_BASE,
.end = CORESIGHT_STM_CHANNEL_PHYS_BASE + SZ_1M + SZ_512K - 1,
.flags = IORESOURCE_MEM,
@@ -4225,6 +4229,7 @@
static struct resource coresight_etm0_resources[] = {
{
+ .name = "etm-base",
.start = CORESIGHT_ETM0_PHYS_BASE,
.end = CORESIGHT_ETM0_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
@@ -4257,6 +4262,7 @@
static struct resource coresight_etm1_resources[] = {
{
+ .name = "etm-base",
.start = CORESIGHT_ETM1_PHYS_BASE,
.end = CORESIGHT_ETM1_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index 5152918..397a9d4 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -18,7 +18,6 @@
#include <linux/msm_rotator.h>
#include <linux/dma-mapping.h>
#include <mach/kgsl.h>
-#include <linux/android_pmem.h>
#include <linux/regulator/machine.h>
#include <linux/init.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index f9e7863..91a7394 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -45,7 +45,6 @@
#ifdef CONFIG_MSM_DSPS
#include <mach/msm_dsps.h>
#endif
-#include <linux/android_pmem.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <mach/mdm.h>
diff --git a/arch/arm/mach-msm/gdsc.c b/arch/arm/mach-msm/gdsc.c
index 53a6616..6240195 100644
--- a/arch/arm/mach-msm/gdsc.c
+++ b/arch/arm/mach-msm/gdsc.c
@@ -33,7 +33,7 @@
/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
#define EN_REST_WAIT_VAL (0x2 << 20)
-#define EN_FEW_WAIT_VAL (0x2 << 16)
+#define EN_FEW_WAIT_VAL (0x8 << 16)
#define CLK_DIS_WAIT_VAL (0x2 << 12)
#define TIMEOUT_US 10
diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
index 4714210..1f7d56a 100644
--- a/arch/arm/mach-msm/gpiomux.c
+++ b/arch/arm/mach-msm/gpiomux.c
@@ -13,7 +13,9 @@
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include <linux/io.h>
#include <mach/gpiomux.h>
+#include <mach/msm_iomap.h>
struct msm_gpiomux_rec {
struct gpiomux_setting *sets[GPIOMUX_NSETTINGS];
@@ -121,6 +123,13 @@
}
EXPORT_SYMBOL(msm_gpiomux_put);
+void msm_tlmm_misc_reg_write(enum msm_tlmm_misc_reg misc_reg, int val)
+{
+ writel_relaxed(val, MSM_TLMM_BASE + misc_reg);
+ /* ensure the write completes before returning */
+ mb();
+}
+
int msm_gpiomux_init(size_t ngpio)
{
if (!ngpio)
diff --git a/arch/arm/mach-msm/include/mach/clk-provider.h b/arch/arm/mach-msm/include/mach/clk-provider.h
index 475b483..528e9d5 100644
--- a/arch/arm/mach-msm/include/mach/clk-provider.h
+++ b/arch/arm/mach-msm/include/mach/clk-provider.h
@@ -21,6 +21,7 @@
#include <linux/clkdev.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
+#include <linux/regulator/consumer.h>
#include <mach/clk.h>
/*
@@ -42,14 +43,23 @@
/**
* struct clk_vdd_class - Voltage scaling class
* @class_name: name of the class
- * @set_vdd: function to call when applying a new voltage setting
- * @level_votes: array of votes for each level
+ * @regulator: array of regulators.
+ * @num_regulators: size of regulator array. Standard regulator APIs will be
+ used if this field > 0.
+ * @set_vdd: function to call when applying a new voltage setting.
+ * @vdd_uv: sorted 2D array of legal voltage settings. Indexed by level, then
+ regulator.
+ * @level_votes: array of votes for each level.
+ * @num_levels: specifies the size of level_votes array.
* @cur_level: the currently set voltage level
* @lock: lock to protect this struct
*/
struct clk_vdd_class {
const char *class_name;
+ struct regulator **regulator;
+ int num_regulators;
int (*set_vdd)(struct clk_vdd_class *v_class, int level);
+ const int **vdd_uv;
int *level_votes;
int num_levels;
unsigned long cur_level;
@@ -66,6 +76,20 @@
.lock = __MUTEX_INITIALIZER(_name.lock) \
}
+#define DEFINE_VDD_REGULATORS(_name, _num_levels, _num_regulators, _vdd_uv) \
+ struct clk_vdd_class _name = { \
+ .class_name = #_name, \
+ .vdd_uv = _vdd_uv, \
+ .regulator = (struct regulator * [_num_regulators]) {}, \
+ .num_regulators = _num_regulators, \
+ .level_votes = (int [_num_levels]) {}, \
+ .num_levels = _num_levels, \
+ .cur_level = _num_levels, \
+ .lock = __MUTEX_INITIALIZER(_name.lock) \
+ }
+
+#define VDD_UV(...) ((int []){__VA_ARGS__})
+
enum handoff {
HANDOFF_ENABLED_CLK,
HANDOFF_DISABLED_CLK,
diff --git a/arch/arm/mach-msm/include/mach/gpiomux.h b/arch/arm/mach-msm/include/mach/gpiomux.h
index 5ffcabb..9aae3fb 100644
--- a/arch/arm/mach-msm/include/mach/gpiomux.h
+++ b/arch/arm/mach-msm/include/mach/gpiomux.h
@@ -109,6 +109,14 @@
size_t ncfg;
};
+/* Provide an enum and an API to write to misc TLMM registers */
+enum msm_tlmm_misc_reg {
+ TLMM_ETM_MODE_REG = 0x2014,
+ TLMM_SDC2_HDRV_PULL_CTL = 0x2048,
+};
+
+void msm_tlmm_misc_reg_write(enum msm_tlmm_misc_reg misc_reg, int val);
+
#ifdef CONFIG_MSM_GPIOMUX
/* Before using gpiomux, initialize the subsystem by telling it how many
diff --git a/arch/arm/mach-msm/include/mach/iommu_domains.h b/arch/arm/mach-msm/include/mach/iommu_domains.h
index d908a65..fec734a 100644
--- a/arch/arm/mach-msm/include/mach/iommu_domains.h
+++ b/arch/arm/mach-msm/include/mach/iommu_domains.h
@@ -76,6 +76,8 @@
#if defined(CONFIG_MSM_IOMMU)
+extern void msm_iommu_set_client_name(struct iommu_domain *domain,
+ char const *name);
extern struct iommu_domain *msm_get_iommu_domain(int domain_num);
extern int msm_find_domain_no(const struct iommu_domain *domain);
@@ -121,6 +123,11 @@
extern int msm_register_domain(struct msm_iova_layout *layout);
#else
+static inline void msm_iommu_set_client_name(struct iommu_domain *domain,
+ char const *name)
+{
+}
+
static inline struct iommu_domain
*msm_get_iommu_domain(int subsys_id) { return NULL; }
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8092.h b/arch/arm/mach-msm/include/mach/msm_iomap-8092.h
index 2fdd99c..f460a4e 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8092.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8092.h
@@ -28,12 +28,6 @@
#define MPQ8092_QGIC_DIST_PHYS 0xF9000000
#define MPQ8092_QGIC_DIST_SIZE SZ_4K
-#define MPQ8092_QGIC_CPU_PHYS 0xF9002000
-#define MPQ8092_QGIC_CPU_SIZE SZ_4K
-
-#define MPQ8092_APCS_GCC_PHYS 0xF9011000
-#define MPQ8092_APCS_GCC_SIZE SZ_4K
-
#define MPQ8092_TLMM_PHYS 0xFD510000
#define MPQ8092_TLMM_SIZE SZ_16K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h b/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
index 81b3c48..ac3e912 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
@@ -28,9 +28,6 @@
#define MSM8226_QGIC_DIST_PHYS 0xF9000000
#define MSM8226_QGIC_DIST_SIZE SZ_4K
-#define MSM8226_QGIC_CPU_PHYS 0xF9002000
-#define MSM8226_QGIC_CPU_SIZE SZ_4K
-
#define MSM8226_APCS_GCC_PHYS 0xF9011000
#define MSM8226_APCS_GCC_SIZE SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8974.h b/arch/arm/mach-msm/include/mach/msm_iomap-8974.h
index 594b1cc..ec3c210 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8974.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8974.h
@@ -28,12 +28,6 @@
#define MSM8974_QGIC_DIST_PHYS 0xF9000000
#define MSM8974_QGIC_DIST_SIZE SZ_4K
-#define MSM8974_QGIC_CPU_PHYS 0xF9002000
-#define MSM8974_QGIC_CPU_SIZE SZ_4K
-
-#define MSM8974_APCS_GCC_PHYS 0xF9011000
-#define MSM8974_APCS_GCC_SIZE SZ_4K
-
#define MSM8974_TLMM_PHYS 0xFD510000
#define MSM8974_TLMM_SIZE SZ_16K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-9625.h b/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
index 341bbe3..9a8bfc1 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
@@ -28,12 +28,6 @@
#define MSM9625_QGIC_DIST_PHYS 0xF9000000
#define MSM9625_QGIC_DIST_SIZE SZ_4K
-#define MSM9625_QGIC_CPU_PHYS 0xF9002000
-#define MSM9625_QGIC_CPU_SIZE SZ_4K
-
-#define MSM9625_APCS_GCC_PHYS 0xF9011000
-#define MSM9625_APCS_GCC_SIZE SZ_4K
-
#define MSM9625_TMR_PHYS 0xF9021000
#define MSM9625_TMR_SIZE SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-zinc.h b/arch/arm/mach-msm/include/mach/msm_iomap-zinc.h
index 8283622..0a33055 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-zinc.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-zinc.h
@@ -28,9 +28,6 @@
#define MSMZINC_QGIC_DIST_PHYS 0xF9000000
#define MSMZINC_QGIC_DIST_SIZE SZ_4K
-#define MSMZINC_QGIC_CPU_PHYS 0xF9002000
-#define MSMZINC_QGIC_CPU_SIZE SZ_4K
-
#define MSMZINC_TLMM_PHYS 0xFD510000
#define MSMZINC_TLMM_SIZE SZ_16K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 9cf9517..d3706cd 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -47,15 +47,14 @@
#define MSM8625_WARM_BOOT_PHYS 0x0FD00000
-
-#if defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064) || \
- defined(CONFIG_ARCH_MSM8930) || defined(CONFIG_ARCH_MSM9615) || \
- defined(CONFIG_ARCH_MSM8974) || defined(CONFIG_ARCH_MSM7X27) || \
- defined(CONFIG_ARCH_MSM7X25) || defined(CONFIG_ARCH_MSM7X01A) || \
- defined(CONFIG_ARCH_MSM8625) || defined(CONFIG_ARCH_MSM7X30) || \
- defined(CONFIG_ARCH_MSM9625) || defined(CONFIG_ARCH_MPQ8092) || \
- defined(CONFIG_ARCH_MSM8226) || defined(CONFIG_ARCH_MSM8610) || \
- defined(CONFIG_ARCH_MSMZINC)
+/* Legacy single-target iomap */
+#if defined(CONFIG_ARCH_QSD8X50)
+#include "msm_iomap-8x50.h"
+#elif defined(CONFIG_ARCH_MSM8X60)
+#include "msm_iomap-8x60.h"
+#elif defined(CONFIG_ARCH_FSM9XXX)
+#include "msm_iomap-fsm9xxx.h"
+#else
/* Unified iomap */
@@ -136,18 +135,6 @@
#include "msm_iomap-8226.h"
#include "msm_iomap-8610.h"
-#else
-/* Legacy single-target iomap */
-#if defined(CONFIG_ARCH_QSD8X50)
-#include "msm_iomap-8x50.h"
-#elif defined(CONFIG_ARCH_MSM8X60)
-#include "msm_iomap-8x60.h"
-#elif defined(CONFIG_ARCH_FSM9XXX)
-#include "msm_iomap-fsm9xxx.h"
-#else
-#error "Target compiled without IO map\n"
-#endif
-
#endif
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iommu_priv.h b/arch/arm/mach-msm/include/mach/msm_iommu_priv.h
new file mode 100644
index 0000000..a2f4836
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iommu_priv.h
@@ -0,0 +1,41 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_IOMMU_PRIV_H
+#define MSM_IOMMU_PRIV_H
+
+/**
+ * struct msm_iommu_pt - Container for first level page table and its
+ * attributes.
+ * fl_table: Pointer to the first level page table.
+ * redirect: Set to 1 if L2 redirect for page tables are enabled, 0 otherwise.
+ */
+struct msm_iommu_pt {
+ unsigned long *fl_table;
+ int redirect;
+};
+
+/**
+ * struct msm_iommu_priv - Container for page table attributes and other
+ * private iommu domain information.
+ * attributes.
+ * pt: Page table attribute structure
+ * list_attached: List of devices (contexts) attached to this domain.
+ * client_name: Name of the domain client.
+ */
+struct msm_iommu_priv {
+ struct msm_iommu_pt pt;
+ struct list_head list_attached;
+ const char *client_name;
+};
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index ff1b3c5..45f2646 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -74,6 +74,10 @@
of_machine_is_compatible("qcom,msm8610-sim")
#define machine_is_msm8610_rumi() \
of_machine_is_compatible("qcom,msm8610-rumi")
+#define machine_is_msm8610_mtp() \
+ of_machine_is_compatible("qcom,msm8610-mtp")
+#define machine_is_msm8610_cdp() \
+ of_machine_is_compatible("qcom,msm8610-cdp")
#define early_machine_is_msmzinc() \
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msmzinc")
#define machine_is_msmzinc_sim() \
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index c71a79a..19c7acd 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -301,8 +301,6 @@
#ifdef CONFIG_ARCH_MSM8974
static struct map_desc msm_8974_io_desc[] __initdata = {
MSM_CHIP_DEVICE(QGIC_DIST, MSM8974),
- MSM_CHIP_DEVICE(QGIC_CPU, MSM8974),
- MSM_CHIP_DEVICE(APCS_GCC, MSM8974),
MSM_CHIP_DEVICE(TLMM, MSM8974),
MSM_CHIP_DEVICE(MPM2_PSHOLD, MSM8974),
{
@@ -326,7 +324,6 @@
#ifdef CONFIG_ARCH_MSMZINC
static struct map_desc msm_zinc_io_desc[] __initdata = {
MSM_CHIP_DEVICE(QGIC_DIST, MSMZINC),
- MSM_CHIP_DEVICE(QGIC_CPU, MSMZINC),
MSM_CHIP_DEVICE(TLMM, MSMZINC),
{
.virtual = (unsigned long) MSM_SHARED_RAM_BASE,
@@ -488,9 +485,7 @@
#ifdef CONFIG_ARCH_MSM9625
static struct map_desc msm9625_io_desc[] __initdata = {
- MSM_CHIP_DEVICE(APCS_GCC, MSM9625),
MSM_CHIP_DEVICE(QGIC_DIST, MSM9625),
- MSM_CHIP_DEVICE(QGIC_CPU, MSM9625),
MSM_CHIP_DEVICE(TLMM, MSM9625),
MSM_CHIP_DEVICE(MPM2_PSHOLD, MSM9625),
MSM_CHIP_DEVICE(TMR, MSM9625),
@@ -515,8 +510,6 @@
#ifdef CONFIG_ARCH_MPQ8092
static struct map_desc mpq8092_io_desc[] __initdata = {
MSM_CHIP_DEVICE(QGIC_DIST, MPQ8092),
- MSM_CHIP_DEVICE(QGIC_CPU, MPQ8092),
- MSM_CHIP_DEVICE(APCS_GCC, MPQ8092),
MSM_CHIP_DEVICE(TLMM, MPQ8092),
{
.virtual = (unsigned long) MSM_SHARED_RAM_BASE,
@@ -538,7 +531,6 @@
#ifdef CONFIG_ARCH_MSM8226
static struct map_desc msm_8226_io_desc[] __initdata = {
MSM_CHIP_DEVICE(QGIC_DIST, MSM8226),
- MSM_CHIP_DEVICE(QGIC_CPU, MSM8226),
MSM_CHIP_DEVICE(APCS_GCC, MSM8226),
MSM_CHIP_DEVICE(TLMM, MSM8226),
MSM_CHIP_DEVICE(MPM2_PSHOLD, MSM8226),
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index 5228abc..a837ca1 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -25,6 +25,7 @@
#include <asm/page.h>
#include <mach/iommu.h>
#include <mach/iommu_domains.h>
+#include <mach/msm_iommu_priv.h>
#include <mach/socinfo.h>
#include <mach/msm_subsystem_map.h>
@@ -40,6 +41,12 @@
DEFINE_MUTEX(domain_mutex);
static atomic_t domain_nums = ATOMIC_INIT(-1);
+void msm_iommu_set_client_name(struct iommu_domain *domain, char const *name)
+{
+ struct msm_iommu_priv *priv = domain->priv;
+ priv->client_name = name;
+}
+
int msm_use_iommu()
{
return iommu_present(&platform_bus_type);
@@ -431,6 +438,10 @@
data->npools = layout->npartitions;
data->domain_num = atomic_inc_return(&domain_nums);
data->domain = iommu_domain_alloc(bus, layout->domain_flags);
+ if (!data->domain)
+ goto out;
+
+ msm_iommu_set_client_name(data->domain, layout->client_name);
add_domain(data);
@@ -479,7 +490,8 @@
}
static int create_and_add_domain(struct iommu_group *group,
- const struct device_node *node)
+ struct device_node const *node,
+ char const *name)
{
unsigned int ret_val = 0;
unsigned int i, j;
@@ -539,6 +551,7 @@
part[0].size = 0xFFFFFFFF;
}
+ l.client_name = name;
l.partitions = part;
secure_domain = of_property_read_bool(node, "qcom,secure-domain");
@@ -594,7 +607,7 @@
ret_val = -EINVAL;
goto free_group;
}
- ret_val = create_and_add_domain(group, node);
+ ret_val = create_and_add_domain(group, node, name);
if (ret_val) {
ret_val = -EINVAL;
goto free_group;
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index ea874bd..d81dbb4 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -34,6 +34,7 @@
#include <mach/smem_log.h>
#include <mach/subsystem_notif.h>
#include <mach/msm_ipc_router.h>
+#include <mach/msm_ipc_logging.h>
#include "ipc_router.h"
#include "modem_notifier.h"
@@ -52,15 +53,21 @@
module_param_named(debug_mask, msm_ipc_router_debug_mask,
int, S_IRUGO | S_IWUSR | S_IWGRP);
+static void *ipc_rtr_log_ctxt;
+#define IPC_RTR_LOG_PAGES 5
#define DIAG(x...) pr_info("[RR] ERROR " x)
#if defined(DEBUG)
#define D(x...) do { \
+if (ipc_rtr_log_ctxt) \
+ ipc_log_string(ipc_rtr_log_ctxt, x); \
if (msm_ipc_router_debug_mask & RTR_DBG) \
pr_info(x); \
} while (0)
#define RR(x...) do { \
+if (ipc_rtr_log_ctxt) \
+ ipc_log_string(ipc_rtr_log_ctxt, x); \
if (msm_ipc_router_debug_mask & R2R_MSG) \
pr_info("[RR] "x); \
} while (0)
@@ -1660,10 +1667,10 @@
}
hdr = (struct rr_header *)(head_skb->data);
- RR("- ver=%d type=%d src=%d:%08x crx=%d siz=%d dst=%d:%08x\n",
- hdr->version, hdr->type, hdr->src_node_id, hdr->src_port_id,
- hdr->confirm_rx, hdr->size, hdr->dst_node_id,
- hdr->dst_port_id);
+ RAW("ver=%d type=%d src=%d:%08x crx=%d siz=%d dst=%d:%08x\n",
+ hdr->version, hdr->type, hdr->src_node_id,
+ hdr->src_port_id, hdr->confirm_rx, hdr->size,
+ hdr->dst_node_id, hdr->dst_port_id);
if (hdr->version != IPC_ROUTER_VERSION) {
pr_err("version %d != %d\n",
@@ -2867,6 +2874,12 @@
struct msm_ipc_routing_table_entry *rt_entry;
msm_ipc_router_debug_mask |= SMEM_LOG;
+ ipc_rtr_log_ctxt = ipc_log_context_create(IPC_RTR_LOG_PAGES,
+ "ipc_router");
+ if (!ipc_rtr_log_ctxt)
+ pr_err("%s: Unable to create IPC logging for IPC RTR",
+ __func__);
+
msm_ipc_router_workqueue =
create_singlethread_workqueue("msm_ipc_router");
if (!msm_ipc_router_workqueue)
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 5f11806..edfb45b 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -34,7 +34,6 @@
#include <linux/completion.h>
#include <linux/err.h>
#endif
-#include <linux/android_pmem.h>
#include <mach/msm_iomap.h>
#include <mach/socinfo.h>
#include <linux/sched.h>
@@ -191,6 +190,10 @@
BUG_ON(mr_candidate == NULL);
/* bump mt up against the top of the region */
mt->start = mr_candidate->base + mr_candidate->size - mt->size;
+ ret = memblock_reserve(mt->start, mt->size);
+ BUG_ON(ret);
+ ret = memblock_free(mt->start, mt->size);
+ BUG_ON(ret);
ret = memblock_remove(mt->start, mt->size);
BUG_ON(ret);
}
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index 1954ec3..599b24c 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>
@@ -57,6 +58,7 @@
#define RMB_PMI_CODE_LENGTH 0x18
#define VDD_MSS_UV 1050000
+#define MAX_VDD_MSS_UV 1150000
#define MAX_VDD_MX_UV 1150000
#define PROXY_TIMEOUT_MS 10000
@@ -92,6 +94,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 +474,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 +524,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 +661,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 +675,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:
@@ -739,7 +740,7 @@
if (IS_ERR(q6->vreg_mx))
return PTR_ERR(q6->vreg_mx);
- ret = regulator_set_voltage(q6->vreg, VDD_MSS_UV, VDD_MSS_UV);
+ ret = regulator_set_voltage(q6->vreg, VDD_MSS_UV, MAX_VDD_MSS_UV);
if (ret)
dev_err(&pdev->dev, "Failed to set regulator's voltage.\n");
@@ -794,7 +795,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 +810,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 +835,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/qdsp5/adsp_driver.c b/arch/arm/mach-msm/qdsp5/adsp_driver.c
index d83a140..eb9c388 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_driver.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_driver.c
@@ -25,7 +25,6 @@
#include <linux/module.h>
#include "adsp.h"
#include <linux/msm_adsp.h>
-#include <linux/android_pmem.h>
#include <mach/debug_mm.h>
struct adsp_ion_info {
diff --git a/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
index 4d03dca..62d6d58 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
@@ -17,7 +17,6 @@
*/
#include <linux/io.h>
-#include <linux/android_pmem.h>
#include <mach/qdsp5/qdsp5vdeccmdi.h>
#include "adsp.h"
diff --git a/arch/arm/mach-msm/qdsp5/audio_acdb.c b/arch/arm/mach-msm/qdsp5/audio_acdb.c
index 7819395..608f544 100644
--- a/arch/arm/mach-msm/qdsp5/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_acdb.c
@@ -16,7 +16,6 @@
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/io.h>
-#include <linux/android_pmem.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/uaccess.h>
@@ -110,7 +109,6 @@
audpp_cmd_cfg_object_params_eqalizer eq;
struct audrec_session_info session_info;
/*pmem info*/
- int pmem_fd;
unsigned long paddr;
unsigned long kvaddr;
unsigned long pmem_len;
@@ -1136,7 +1134,6 @@
{
int rc = 0;
unsigned long flags = 0;
- struct msm_audio_pmem_info info;
MM_DBG("%s\n", __func__);
@@ -1156,23 +1153,6 @@
MM_ERR("AUDPP returned err =%d\n", rc);
spin_unlock_irqrestore(&acdb_data.dsp_lock, flags);
break;
- case AUDIO_REGISTER_PMEM:
- MM_DBG("AUDIO_REGISTER_PMEM\n");
- if (copy_from_user(&info, (void *) arg, sizeof(info))) {
- MM_ERR("Cannot copy from user\n");
- return -EFAULT;
- }
- rc = get_pmem_file(info.fd, &acdb_data.paddr,
- &acdb_data.kvaddr,
- &acdb_data.pmem_len,
- &acdb_data.file);
- if (rc == 0)
- acdb_data.pmem_fd = info.fd;
- break;
- case AUDIO_DEREGISTER_PMEM:
- if (acdb_data.pmem_fd)
- put_pmem_file(acdb_data.file);
- break;
case AUDIO_SET_ACDB_BLK:
MM_DBG("IOCTL AUDIO_SET_ACDB_BLK\n");
rc = acdb_set_calibration_blk(arg);
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp_driver.c b/arch/arm/mach-msm/qdsp5v2/adsp_driver.c
index 7249bb1..ad74ca3 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp_driver.c
+++ b/arch/arm/mach-msm/qdsp5v2/adsp_driver.c
@@ -21,7 +21,6 @@
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/msm_adsp.h>
-#include <linux/android_pmem.h>
#include <linux/export.h>
#include "adsp.h"
#include <mach/debug_mm.h>
@@ -87,71 +86,6 @@
res; \
})
-static int adsp_pmem_check(struct msm_adsp_module *module,
- void *vaddr, unsigned long len)
-{
- struct adsp_pmem_region *region_elt;
- struct hlist_node *node;
- struct adsp_pmem_region t = { .vaddr = vaddr, .len = len };
-
- hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
- if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
- OVERLAPS(region_elt, &t)) {
- MM_ERR("module %s:"
- " region (vaddr %p len %ld)"
- " clashes with registered region"
- " (vaddr %p paddr %p len %ld)\n",
- module->name,
- vaddr, len,
- region_elt->vaddr,
- (void *)region_elt->paddr,
- region_elt->len);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int adsp_pmem_add(struct msm_adsp_module *module,
- struct adsp_pmem_info *info)
-{
- unsigned long paddr, kvaddr, len;
- struct file *file;
- struct adsp_pmem_region *region;
- int rc = -EINVAL;
-
- mutex_lock(&module->pmem_regions_lock);
- region = kmalloc(sizeof(*region), GFP_KERNEL);
- if (!region) {
- rc = -ENOMEM;
- goto end;
- }
- INIT_HLIST_NODE(®ion->list);
- if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
- kfree(region);
- goto end;
- }
-
- rc = adsp_pmem_check(module, info->vaddr, len);
- if (rc < 0) {
- put_pmem_file(file);
- kfree(region);
- goto end;
- }
-
- region->vaddr = info->vaddr;
- region->paddr = paddr;
- region->kvaddr = kvaddr;
- region->len = len;
- region->file = file;
-
- hlist_add_head(®ion->list, &module->pmem_regions);
-end:
- mutex_unlock(&module->pmem_regions_lock);
- return rc;
-}
-
static int adsp_pmem_lookup_vaddr(struct msm_adsp_module *module, void **addr,
unsigned long len, struct adsp_pmem_region **region)
{
@@ -417,24 +351,6 @@
return rc;
}
-static int adsp_pmem_del(struct msm_adsp_module *module)
-{
- struct hlist_node *node, *tmp;
- struct adsp_pmem_region *region;
-
- mutex_lock(&module->pmem_regions_lock);
- hlist_for_each_safe(node, tmp, &module->pmem_regions) {
- region = hlist_entry(node, struct adsp_pmem_region, list);
- hlist_del(node);
- put_pmem_file(region->file);
- kfree(region);
- }
- mutex_unlock(&module->pmem_regions_lock);
- BUG_ON(!hlist_empty(&module->pmem_regions));
-
- return 0;
-}
-
static long adsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct adsp_device *adev = filp->private_data;
@@ -466,21 +382,11 @@
return adsp_set_clkrate(adev->module, clk_rate);
}
- case ADSP_IOCTL_REGISTER_PMEM: {
- struct adsp_pmem_info info;
- if (copy_from_user(&info, (void *) arg, sizeof(info)))
- return -EFAULT;
- return adsp_pmem_add(adev->module, &info);
- }
-
case ADSP_IOCTL_ABORT_EVENT_READ:
adev->abort = 1;
wake_up(&adev->event_wait);
break;
- case ADSP_IOCTL_UNREGISTER_PMEM:
- return adsp_pmem_del(adev->module);
-
default:
break;
}
@@ -498,8 +404,6 @@
/* clear module before putting it to avoid race with open() */
adev->module = NULL;
- rc = adsp_pmem_del(module);
-
msm_adsp_put(module);
return rc;
}
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_aac.c b/arch/arm/mach-msm/qdsp5v2/audio_aac.c
index 883da2b..fbce5d6 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_aac.c
@@ -30,7 +30,6 @@
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/earlysuspend.h>
-#include <linux/android_pmem.h>
#include <linux/slab.h>
#include <linux/msm_audio_aac.h>
#include <linux/memory_alloc.h>
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c b/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
index a878e12..cf1f58d 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
@@ -26,7 +26,6 @@
#include <linux/wait.h>
#include <linux/dma-mapping.h>
#include <linux/msm_audio_aac.h>
-#include <linux/android_pmem.h>
#include <linux/memory_alloc.h>
#include <mach/msm_memtypes.h>
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_acdb.c b/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
index 5d7cfd7..85378be 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
@@ -16,7 +16,6 @@
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/io.h>
-#include <linux/android_pmem.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/uaccess.h>
@@ -1287,7 +1286,6 @@
{
int rc = 0;
unsigned long flags = 0;
- struct msm_audio_pmem_info info;
MM_DBG("%s\n", __func__);
@@ -1308,23 +1306,6 @@
MM_ERR("AUDPP returned err =%d\n", rc);
spin_unlock_irqrestore(&acdb_data.dsp_lock, flags);
break;
- case AUDIO_REGISTER_PMEM:
- MM_DBG("AUDIO_REGISTER_PMEM\n");
- if (copy_from_user(&info, (void *) arg, sizeof(info))) {
- MM_ERR("Cannot copy from user\n");
- return -EFAULT;
- }
- rc = get_pmem_file(info.fd, &acdb_data.paddr,
- &acdb_data.kvaddr,
- &acdb_data.pmem_len,
- &acdb_data.file);
- if (rc == 0)
- acdb_data.pmem_fd = info.fd;
- break;
- case AUDIO_DEREGISTER_PMEM:
- if (acdb_data.pmem_fd)
- put_pmem_file(acdb_data.file);
- break;
case AUDIO_SET_ACDB_BLK:
MM_DBG("IOCTL AUDIO_SET_ACDB_BLK\n");
rc = acdb_set_calibration_blk(arg);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
index 7cc3e29..632aa0d 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
@@ -34,7 +34,6 @@
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/earlysuspend.h>
-#include <linux/android_pmem.h>
#include <linux/slab.h>
#include <linux/msm_audio.h>
#include <linux/memory_alloc.h>
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
index c8b4171..bd4f6e1 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
@@ -37,7 +37,6 @@
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/earlysuspend.h>
-#include <linux/android_pmem.h>
#include <linux/memory_alloc.h>
#include <linux/msm_audio.h>
#include <linux/slab.h>
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
index 66d0a9e..e5706c7 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
@@ -37,7 +37,6 @@
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/earlysuspend.h>
-#include <linux/android_pmem.h>
#include <linux/memory_alloc.h>
#include <linux/msm_audio.h>
#include <linux/slab.h>
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
index 2d9327e..ed946f9 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
@@ -32,7 +32,6 @@
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/earlysuspend.h>
-#include <linux/android_pmem.h>
#include <linux/memory_alloc.h>
#include <linux/msm_audio.h>
#include <linux/slab.h>
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_fm.c b/arch/arm/mach-msm/qdsp5v2/audio_fm.c
index cffa7e7..27548ac 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_fm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_fm.c
@@ -29,7 +29,6 @@
#include <linux/wait.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
-#include <linux/android_pmem.h>
#include <linux/msm_audio.h>
#include <asm/atomic.h>
#include <asm/ioctls.h>
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
index 0390edf..bda2e4d 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
@@ -29,7 +29,6 @@
#include <linux/delay.h>
#include <linux/earlysuspend.h>
#include <linux/list.h>
-#include <linux/android_pmem.h>
#include <linux/slab.h>
#include <linux/memory_alloc.h>
#include <linux/msm_audio.h>
@@ -1095,103 +1094,6 @@
return rc;
}
-static int audmp3_pmem_check(struct audio *audio,
- void *vaddr, unsigned long len)
-{
- struct audmp3_pmem_region *region_elt;
- struct audmp3_pmem_region t = { .vaddr = vaddr, .len = len };
-
- list_for_each_entry(region_elt, &audio->pmem_region_queue, list) {
- if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
- OVERLAPS(region_elt, &t)) {
- MM_ERR("region (vaddr %p len %ld)"
- " clashes with registered region"
- " (vaddr %p paddr %p len %ld)\n",
- vaddr, len,
- region_elt->vaddr,
- (void *)region_elt->paddr,
- region_elt->len);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int audmp3_pmem_add(struct audio *audio,
- struct msm_audio_pmem_info *info)
-{
- unsigned long paddr, kvaddr, len;
- struct file *file;
- struct audmp3_pmem_region *region;
- int rc = -EINVAL;
-
- MM_DBG("\n"); /* Macro prints the file name and function */
- region = kmalloc(sizeof(*region), GFP_KERNEL);
-
- if (!region) {
- rc = -ENOMEM;
- goto end;
- }
-
- if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
- kfree(region);
- goto end;
- }
-
- rc = audmp3_pmem_check(audio, info->vaddr, len);
- if (rc < 0) {
- put_pmem_file(file);
- kfree(region);
- goto end;
- }
-
- region->vaddr = info->vaddr;
- region->fd = info->fd;
- region->paddr = paddr;
- region->kvaddr = kvaddr;
- region->len = len;
- region->file = file;
- region->ref_cnt = 0;
- MM_DBG("add region paddr %lx vaddr %p, len %lu\n", region->paddr,
- region->vaddr, region->len);
- list_add_tail(®ion->list, &audio->pmem_region_queue);
-end:
- return rc;
-}
-
-static int audmp3_pmem_remove(struct audio *audio,
- struct msm_audio_pmem_info *info)
-{
- struct audmp3_pmem_region *region;
- struct list_head *ptr, *next;
- int rc = -EINVAL;
-
- MM_DBG("info fd %d vaddr %p\n", info->fd, info->vaddr);
-
- list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
- region = list_entry(ptr, struct audmp3_pmem_region, list);
-
- if ((region->fd == info->fd) &&
- (region->vaddr == info->vaddr)) {
- if (region->ref_cnt) {
- MM_DBG("region %p in use ref_cnt %d\n",
- region, region->ref_cnt);
- break;
- }
- MM_DBG("remove region fd %d vaddr %p \n",
- info->fd, info->vaddr);
- list_del(®ion->list);
- put_pmem_file(region->file);
- kfree(region);
- rc = 0;
- break;
- }
- }
-
- return rc;
-}
-
static int audmp3_pmem_lookup_vaddr(struct audio *audio, void *addr,
unsigned long len, struct audmp3_pmem_region **region)
{
@@ -1688,25 +1590,6 @@
break;
}
- case AUDIO_REGISTER_PMEM: {
- struct msm_audio_pmem_info info;
- MM_DBG("AUDIO_REGISTER_PMEM\n");
- if (copy_from_user(&info, (void *) arg, sizeof(info)))
- rc = -EFAULT;
- else
- rc = audmp3_pmem_add(audio, &info);
- break;
- }
-
- case AUDIO_DEREGISTER_PMEM: {
- struct msm_audio_pmem_info info;
- MM_DBG("AUDIO_DEREGISTER_PMEM\n");
- if (copy_from_user(&info, (void *) arg, sizeof(info)))
- rc = -EFAULT;
- else
- rc = audmp3_pmem_remove(audio, &info);
- break;
- }
case AUDIO_ASYNC_WRITE:
if (audio->drv_status & ADRV_STATUS_FSYNC)
rc = -EBUSY;
@@ -2105,21 +1988,6 @@
return rc;
}
-static void audmp3_reset_pmem_region(struct audio *audio)
-{
- struct audmp3_pmem_region *region;
- struct list_head *ptr, *next;
-
- list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
- region = list_entry(ptr, struct audmp3_pmem_region, list);
- list_del(®ion->list);
- put_pmem_file(region->file);
- kfree(region);
- }
-
- return;
-}
-
static int audio_release(struct inode *inode, struct file *file)
{
struct audio *audio = file->private_data;
@@ -2130,7 +1998,6 @@
audio_disable(audio);
audio->drv_ops.out_flush(audio);
audio->drv_ops.in_flush(audio);
- audmp3_reset_pmem_region(audio);
msm_adsp_put(audio->audplay);
audpp_adec_free(audio->dec_id);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_out.c b/arch/arm/mach-msm/qdsp5v2/audio_out.c
index e5c59ba..712c9f3 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_out.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_out.c
@@ -30,7 +30,6 @@
#include <linux/wakelock.h>
#include <linux/memory_alloc.h>
#include <linux/msm_audio.h>
-#include <linux/android_pmem.h>
#include <linux/pm_qos.h>
#include <mach/msm_adsp.h>
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
index ea8fc83..cbd2913 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
@@ -30,7 +30,6 @@
#include <linux/delay.h>
#include <linux/earlysuspend.h>
#include <linux/list.h>
-#include <linux/android_pmem.h>
#include <linux/memory_alloc.h>
#include <linux/slab.h>
#include <linux/msm_audio.h>
@@ -743,99 +742,6 @@
return rc;
}
-static int audpcm_pmem_check(struct audio *audio,
- void *vaddr, unsigned long len)
-{
- struct audpcm_pmem_region *region_elt;
- struct audpcm_pmem_region t = { .vaddr = vaddr, .len = len };
-
- list_for_each_entry(region_elt, &audio->pmem_region_queue, list) {
- if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
- OVERLAPS(region_elt, &t)) {
- MM_ERR("region (vaddr %p len %ld)"
- " clashes with registered region"
- " (vaddr %p paddr %p len %ld)\n",
- vaddr, len,
- region_elt->vaddr,
- (void *)region_elt->paddr,
- region_elt->len);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int audpcm_pmem_add(struct audio *audio,
- struct msm_audio_pmem_info *info)
-{
- unsigned long paddr, kvaddr, len;
- struct file *file;
- struct audpcm_pmem_region *region;
- int rc = -EINVAL;
-
- MM_DBG("\n"); /* Macro prints the file name and function */
- region = kmalloc(sizeof(*region), GFP_KERNEL);
- if (!region)
- return -ENOMEM;
-
- if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
- kfree(region);
- return -EINVAL;
- }
-
- rc = audpcm_pmem_check(audio, info->vaddr, len);
- if (rc < 0) {
- put_pmem_file(file);
- kfree(region);
- return rc;
- }
-
- region->vaddr = info->vaddr;
- region->fd = info->fd;
- region->paddr = paddr;
- region->kvaddr = kvaddr;
- region->len = len;
- region->file = file;
- region->ref_cnt = 0;
- MM_DBG("add region paddr %lx vaddr %p, len %lu\n", region->paddr,
- region->vaddr, region->len);
- list_add_tail(®ion->list, &audio->pmem_region_queue);
- return rc;
-}
-
-static int audpcm_pmem_remove(struct audio *audio,
- struct msm_audio_pmem_info *info)
-{
- struct audpcm_pmem_region *region;
- struct list_head *ptr, *next;
- int rc = -EINVAL;
-
- MM_DBG("info fd %d vaddr %p\n", info->fd, info->vaddr);
-
- list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
- region = list_entry(ptr, struct audpcm_pmem_region, list);
-
- if ((region->fd == info->fd) &&
- (region->vaddr == info->vaddr)) {
- if (region->ref_cnt) {
- MM_DBG("region %p in use ref_cnt %d\n", region,
- region->ref_cnt);
- break;
- }
- MM_DBG("remove region fd %d vaddr %p \n", info->fd,
- info->vaddr);
- list_del(®ion->list);
- put_pmem_file(region->file);
- kfree(region);
- rc = 0;
- break;
- }
- }
-
- return rc;
-}
-
static int audpcm_pmem_lookup_vaddr(struct audio *audio, void *addr,
unsigned long len, struct audpcm_pmem_region **region)
{
@@ -1124,26 +1030,6 @@
rc = audpp_pause(audio->dec_id, (int) arg);
break;
- case AUDIO_REGISTER_PMEM: {
- struct msm_audio_pmem_info info;
- MM_DBG("AUDIO_REGISTER_PMEM\n");
- if (copy_from_user(&info, (void *) arg, sizeof(info)))
- rc = -EFAULT;
- else
- rc = audpcm_pmem_add(audio, &info);
- break;
- }
-
- case AUDIO_DEREGISTER_PMEM: {
- struct msm_audio_pmem_info info;
- MM_DBG("AUDIO_DEREGISTER_PMEM\n");
- if (copy_from_user(&info, (void *) arg, sizeof(info)))
- rc = -EFAULT;
- else
- rc = audpcm_pmem_remove(audio, &info);
- break;
- }
-
case AUDIO_ASYNC_WRITE:
if (audio->drv_status & ADRV_STATUS_FSYNC)
rc = -EBUSY;
@@ -1344,21 +1230,6 @@
return rc;
}
-static void audpcm_reset_pmem_region(struct audio *audio)
-{
- struct audpcm_pmem_region *region;
- struct list_head *ptr, *next;
-
- list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
- region = list_entry(ptr, struct audpcm_pmem_region, list);
- list_del(®ion->list);
- put_pmem_file(region->file);
- kfree(region);
- }
-
- return;
-}
-
static int audio_release(struct inode *inode, struct file *file)
{
struct audio *audio = file->private_data;
@@ -1369,7 +1240,6 @@
auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id);
audio_disable(audio);
audio->drv_ops.out_flush(audio);
- audpcm_reset_pmem_region(audio);
msm_adsp_put(audio->audplay);
audpp_adec_free(audio->dec_id);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
index bb360be..33ca7a1 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
@@ -33,7 +33,6 @@
#include <linux/debugfs.h>
#include <linux/earlysuspend.h>
#include <linux/list.h>
-#include <linux/android_pmem.h>
#include <linux/slab.h>
#include <linux/msm_audio.h>
#include <linux/memory_alloc.h>
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
index 84cfed6..44fc10f 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
@@ -35,7 +35,6 @@
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/earlysuspend.h>
-#include <linux/android_pmem.h>
#include <linux/msm_audio.h>
#include <linux/slab.h>
#include <linux/msm_audio_wmapro.h>
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c b/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c
index 5895867..9143b5a 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c
@@ -23,7 +23,6 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/wakelock.h>
-#include <linux/android_pmem.h>
#include <linux/gpio.h>
#include <linux/pm_qos.h>
diff --git a/arch/arm/mach-msm/qdsp6/msm_q6vdec.c b/arch/arm/mach-msm/qdsp6/msm_q6vdec.c
index 24d2117..1cb9775 100644
--- a/arch/arm/mach-msm/qdsp6/msm_q6vdec.c
+++ b/arch/arm/mach-msm/qdsp6/msm_q6vdec.c
@@ -32,7 +32,6 @@
#include <linux/wakelock.h>
#include <linux/pm_qos.h>
-#include <linux/android_pmem.h>
#include <linux/msm_q6vdec.h>
#include <mach/cpuidle.h>
diff --git a/arch/arm/mach-msm/qdsp6/msm_q6venc.c b/arch/arm/mach-msm/qdsp6/msm_q6venc.c
index 4704ae7..a2b4b6e 100644
--- a/arch/arm/mach-msm/qdsp6/msm_q6venc.c
+++ b/arch/arm/mach-msm/qdsp6/msm_q6venc.c
@@ -22,7 +22,6 @@
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <linux/wakelock.h>
-#include <linux/android_pmem.h>
#include <linux/msm_q6venc.h>
#include <linux/pm_qos.h>
diff --git a/arch/arm/mach-msm/qdsp6/q6audio.c b/arch/arm/mach-msm/qdsp6/q6audio.c
index f660bdc..9404c3d 100644
--- a/arch/arm/mach-msm/qdsp6/q6audio.c
+++ b/arch/arm/mach-msm/qdsp6/q6audio.c
@@ -22,7 +22,6 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/wakelock.h>
-#include <linux/android_pmem.h>
#include <linux/firmware.h>
#include <linux/miscdevice.h>
#include <linux/pm_qos.h>
diff --git a/arch/arm/mach-msm/qdsp6v2/Makefile b/arch/arm/mach-msm/qdsp6v2/Makefile
index 34d336e..88de98b 100644
--- a/arch/arm/mach-msm/qdsp6v2/Makefile
+++ b/arch/arm/mach-msm/qdsp6v2/Makefile
@@ -24,7 +24,7 @@
obj-$(CONFIG_MSM_QDSP6V2_CODECS) += aac_in.o qcelp_in.o evrc_in.o amrnb_in.o audio_utils.o
obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_wma.o audio_wmapro.o audio_aac.o audio_multi_aac.o audio_utils_aio.o
obj-$(CONFIG_MSM_QDSP6V2_CODECS) += q6audio_v2.o q6audio_v2_aio.o
-obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_evrc.o audio_qcelp.o amrwb_in.o
+obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_amrwbplus.o audio_evrc.o audio_qcelp.o amrwb_in.o
obj-$(CONFIG_MSM_ADSP_LOADER) += adsp-loader.o
obj-$(CONFIG_MSM_ULTRASOUND_A) += ultrasound/version_a/
obj-$(CONFIG_MSM_ULTRASOUND_B) += ultrasound/version_b/
diff --git a/arch/arm/mach-msm/qdsp6v2/fm.c b/arch/arm/mach-msm/qdsp6v2/fm.c
index 3d72b97..23bb716 100644
--- a/arch/arm/mach-msm/qdsp6v2/fm.c
+++ b/arch/arm/mach-msm/qdsp6v2/fm.c
@@ -30,7 +30,6 @@
#include <linux/wait.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
-#include <linux/android_pmem.h>
#include <linux/msm_audio.h>
#include <asm/atomic.h>
#include <asm/ioctls.h>
diff --git a/arch/arm/mach-msm/rpm-regulator-smd.c b/arch/arm/mach-msm/rpm-regulator-smd.c
index 8c96b1a..55ce4b1 100644
--- a/arch/arm/mach-msm/rpm-regulator-smd.c
+++ b/arch/arm/mach-msm/rpm-regulator-smd.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
@@ -69,6 +69,7 @@
RPM_REGULATOR_PARAM_FREQ_REASON,
RPM_REGULATOR_PARAM_CORNER,
RPM_REGULATOR_PARAM_BYPASS,
+ RPM_REGULATOR_PARAM_FLOOR_CORNER,
RPM_REGULATOR_PARAM_MAX,
};
@@ -108,12 +109,13 @@
PARAM(MODE_SMPS, 0, 1, 0, 0, "ssmd", 0, 2, "qcom,init-smps-mode"),
PARAM(PIN_CTRL_ENABLE, 1, 1, 1, 0, "pcen", 0, 0xF, "qcom,init-pin-ctrl-enable"),
PARAM(PIN_CTRL_MODE, 1, 1, 1, 0, "pcmd", 0, 0x1F, "qcom,init-pin-ctrl-mode"),
- PARAM(FREQUENCY, 0, 1, 0, 1, "freq", 0, 16, "qcom,init-frequency"),
+ PARAM(FREQUENCY, 0, 1, 0, 1, "freq", 0, 31, "qcom,init-frequency"),
PARAM(HEAD_ROOM, 1, 0, 0, 1, "hr", 0, 0x7FFFFFFF, "qcom,init-head-room"),
PARAM(QUIET_MODE, 0, 1, 0, 0, "qm", 0, 2, "qcom,init-quiet-mode"),
PARAM(FREQ_REASON, 0, 1, 0, 1, "resn", 0, 8, "qcom,init-freq-reason"),
PARAM(CORNER, 1, 1, 0, 0, "corn", 0, 6, "qcom,init-voltage-corner"),
PARAM(BYPASS, 1, 0, 0, 0, "bypa", 0, 1, "qcom,init-disallow-bypass"),
+ PARAM(FLOOR_CORNER, 1, 1, 0, 0, "vfc", 0, 6, "qcom,init-voltage-floor-corner"),
};
struct rpm_vreg_request {
@@ -147,6 +149,8 @@
struct list_head list;
bool set_active;
bool set_sleep;
+ bool always_send_voltage;
+ bool always_send_current;
struct rpm_vreg_request req;
int system_load;
int min_uV;
@@ -390,6 +394,13 @@
return rc;
}
+#define RPM_VREG_AGGR_MIN(_idx, _param_aggr, _param_reg) \
+{ \
+ _param_aggr[RPM_REGULATOR_PARAM_##_idx] \
+ = min(_param_aggr[RPM_REGULATOR_PARAM_##_idx], \
+ _param_reg[RPM_REGULATOR_PARAM_##_idx]); \
+}
+
#define RPM_VREG_AGGR_MAX(_idx, _param_aggr, _param_reg) \
{ \
_param_aggr[RPM_REGULATOR_PARAM_##_idx] \
@@ -410,20 +421,6 @@
}
/*
- * The RPM treats freq=0 as a special value meaning that this consumer does not
- * care what the SMPS switching freqency is.
- */
-#define RPM_REGULATOR_FREQ_DONT_CARE 0
-
-static inline void rpm_vreg_freqency_aggr(u32 *freq, u32 consumer_freq)
-{
- if (consumer_freq != RPM_REGULATOR_FREQ_DONT_CARE
- && (consumer_freq < *freq
- || *freq == RPM_REGULATOR_FREQ_DONT_CARE))
- *freq = consumer_freq;
-}
-
-/*
* Aggregation is performed on each parameter based on the way that the RPM
* aggregates that type internally between RPM masters.
*/
@@ -436,13 +433,13 @@
RPM_VREG_AGGR_MAX(MODE_SMPS, param_aggr, param_reg);
RPM_VREG_AGGR_OR(PIN_CTRL_ENABLE, param_aggr, param_reg);
RPM_VREG_AGGR_OR(PIN_CTRL_MODE, param_aggr, param_reg);
- rpm_vreg_freqency_aggr(¶m_aggr[RPM_REGULATOR_PARAM_FREQUENCY],
- param_reg[RPM_REGULATOR_PARAM_FREQUENCY]);
+ RPM_VREG_AGGR_MIN(FREQUENCY, param_aggr, param_reg);
RPM_VREG_AGGR_MAX(HEAD_ROOM, param_aggr, param_reg);
RPM_VREG_AGGR_MAX(QUIET_MODE, param_aggr, param_reg);
RPM_VREG_AGGR_MAX(FREQ_REASON, param_aggr, param_reg);
RPM_VREG_AGGR_MAX(CORNER, param_aggr, param_reg);
RPM_VREG_AGGR_MAX(BYPASS, param_aggr, param_reg);
+ RPM_VREG_AGGR_MAX(FLOOR_CORNER, param_aggr, param_reg);
}
static int rpm_vreg_aggregate_requests(struct rpm_regulator *regulator)
@@ -633,8 +630,12 @@
prev_voltage = reg->req.param[RPM_REGULATOR_PARAM_VOLTAGE];
RPM_VREG_SET_PARAM(reg, VOLTAGE, min_uV);
- /* Only send a new voltage if the regulator is currently enabled. */
- if (rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg))
+ /*
+ * Only send a new voltage if the regulator is currently enabled or
+ * if the regulator has been configured to always send voltage updates.
+ */
+ if (reg->always_send_voltage
+ || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg))
rc = rpm_vreg_aggregate_requests(reg);
if (rc) {
@@ -687,8 +688,13 @@
prev_corner = reg->req.param[RPM_REGULATOR_PARAM_CORNER];
RPM_VREG_SET_PARAM(reg, CORNER, corner);
- /* Only send a new voltage if the regulator is currently enabled. */
- if (rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg))
+ /*
+ * Only send a new voltage corner if the regulator is currently enabled
+ * or if the regulator has been configured to always send voltage
+ * updates.
+ */
+ if (reg->always_send_voltage
+ || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg))
rc = rpm_vreg_aggregate_requests(reg);
if (rc) {
@@ -709,6 +715,61 @@
+ RPM_REGULATOR_CORNER_NONE;
}
+static int rpm_vreg_set_voltage_floor_corner(struct regulator_dev *rdev,
+ int min_uV, int max_uV, unsigned *selector)
+{
+ struct rpm_regulator *reg = rdev_get_drvdata(rdev);
+ int rc = 0;
+ int corner;
+ u32 prev_corner;
+
+ /*
+ * Translate from values which work as inputs in the
+ * regulator_set_voltage function to the actual corner values
+ * sent to the RPM.
+ */
+ corner = min_uV - RPM_REGULATOR_CORNER_NONE;
+
+ if (corner < params[RPM_REGULATOR_PARAM_FLOOR_CORNER].min
+ || corner > params[RPM_REGULATOR_PARAM_FLOOR_CORNER].max) {
+ vreg_err(reg, "corner=%d is not within allowed range: [%u, %u]\n",
+ corner, params[RPM_REGULATOR_PARAM_FLOOR_CORNER].min,
+ params[RPM_REGULATOR_PARAM_FLOOR_CORNER].max);
+ return -EINVAL;
+ }
+
+ rpm_vreg_lock(reg->rpm_vreg);
+
+ prev_corner = reg->req.param[RPM_REGULATOR_PARAM_FLOOR_CORNER];
+ RPM_VREG_SET_PARAM(reg, FLOOR_CORNER, corner);
+
+ /*
+ * Only send a new voltage floor corner if the regulator is currently
+ * enabled or if the regulator has been configured to always send
+ * voltage updates.
+ */
+ if (reg->always_send_voltage
+ || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg))
+ rc = rpm_vreg_aggregate_requests(reg);
+
+ if (rc) {
+ vreg_err(reg, "set voltage corner failed, rc=%d", rc);
+ RPM_VREG_SET_PARAM(reg, FLOOR_CORNER, prev_corner);
+ }
+
+ rpm_vreg_unlock(reg->rpm_vreg);
+
+ return rc;
+}
+
+static int rpm_vreg_get_voltage_floor_corner(struct regulator_dev *rdev)
+{
+ struct rpm_regulator *reg = rdev_get_drvdata(rdev);
+
+ return reg->req.param[RPM_REGULATOR_PARAM_FLOOR_CORNER]
+ + RPM_REGULATOR_CORNER_NONE;
+}
+
static int rpm_vreg_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
struct rpm_regulator *reg = rdev_get_drvdata(rdev);
@@ -737,8 +798,13 @@
return -EINVAL;
}
- /* Only send a new mode value if the regulator is currently enabled. */
- if (rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg))
+ /*
+ * Only send a new load current value if the regulator is currently
+ * enabled or if the regulator has been configured to always send
+ * current updates.
+ */
+ if (reg->always_send_current
+ || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg))
rc = rpm_vreg_aggregate_requests(reg);
if (rc) {
@@ -1035,6 +1101,18 @@
.enable_time = rpm_vreg_enable_time,
};
+static struct regulator_ops ldo_floor_corner_ops = {
+ .enable = rpm_vreg_enable,
+ .disable = rpm_vreg_disable,
+ .is_enabled = rpm_vreg_is_enabled,
+ .set_voltage = rpm_vreg_set_voltage_floor_corner,
+ .get_voltage = rpm_vreg_get_voltage_floor_corner,
+ .set_mode = rpm_vreg_set_mode,
+ .get_mode = rpm_vreg_get_mode,
+ .get_optimum_mode = rpm_vreg_get_optimum_mode,
+ .enable_time = rpm_vreg_enable_time,
+};
+
static struct regulator_ops smps_ops = {
.enable = rpm_vreg_enable,
.disable = rpm_vreg_disable,
@@ -1059,6 +1137,18 @@
.enable_time = rpm_vreg_enable_time,
};
+static struct regulator_ops smps_floor_corner_ops = {
+ .enable = rpm_vreg_enable,
+ .disable = rpm_vreg_disable,
+ .is_enabled = rpm_vreg_is_enabled,
+ .set_voltage = rpm_vreg_set_voltage_floor_corner,
+ .get_voltage = rpm_vreg_get_voltage_floor_corner,
+ .set_mode = rpm_vreg_set_mode,
+ .get_mode = rpm_vreg_get_mode,
+ .get_optimum_mode = rpm_vreg_get_optimum_mode,
+ .enable_time = rpm_vreg_enable_time,
+};
+
static struct regulator_ops switch_ops = {
.enable = rpm_vreg_enable,
.disable = rpm_vreg_disable,
@@ -1192,12 +1282,30 @@
* is specified in the device node (SMPS and LDO only).
*/
if (of_property_read_bool(node, "qcom,use-voltage-corner")) {
+ if (of_property_read_bool(node,
+ "qcom,use-voltage-floor-corner")) {
+ dev_err(dev, "%s: invalid properties: both qcom,use-voltage-corner and qcom,use-voltage-floor-corner specified\n",
+ __func__);
+ goto fail_free_reg;
+ }
+
if (regulator_type == RPM_REGULATOR_SMD_TYPE_SMPS)
reg->rdesc.ops = &smps_corner_ops;
else if (regulator_type == RPM_REGULATOR_SMD_TYPE_LDO)
reg->rdesc.ops = &ldo_corner_ops;
+ } else if (of_property_read_bool(node,
+ "qcom,use-voltage-floor-corner")) {
+ if (regulator_type == RPM_REGULATOR_SMD_TYPE_SMPS)
+ reg->rdesc.ops = &smps_floor_corner_ops;
+ else if (regulator_type == RPM_REGULATOR_SMD_TYPE_LDO)
+ reg->rdesc.ops = &ldo_floor_corner_ops;
}
+ reg->always_send_voltage
+ = of_property_read_bool(node, "qcom,always-send-voltage");
+ reg->always_send_current
+ = of_property_read_bool(node, "qcom,always-send-current");
+
if (regulator_type == RPM_REGULATOR_SMD_TYPE_VS)
reg->rdesc.n_voltages = 0;
else
diff --git a/arch/arm/mach-msm/scm-xpu.c b/arch/arm/mach-msm/scm-xpu.c
new file mode 100644
index 0000000..0c38842
--- /dev/null
+++ b/arch/arm/mach-msm/scm-xpu.c
@@ -0,0 +1,44 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <mach/scm.h>
+
+#define ERR_FATAL_ENABLE 0x0
+#define ERR_FATAL_DISABLE 0x1
+#define ERR_FATAL_READ 0x2
+#define XPU_ERR_FATAL 0xe
+
+static int __init xpu_err_fatal_init(void)
+{
+ int ret, response;
+ struct {
+ unsigned int config;
+ unsigned int spare;
+ } cmd;
+ cmd.config = ERR_FATAL_ENABLE;
+ cmd.spare = 0;
+
+ ret = scm_call(SCM_SVC_MP, XPU_ERR_FATAL, &cmd, sizeof(cmd), &response,
+ sizeof(response));
+
+ if (ret != 0)
+ pr_warn("Failed to set XPU violations as fatal errors: %d\n",
+ ret);
+ else
+ pr_info("Configuring XPU violations to be fatal errors\n");
+
+ return ret;
+}
+early_initcall(xpu_err_fatal_init);
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 57c85e1..1f0fa85 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -278,6 +278,7 @@
/* 8974 IDs */
[126] = MSM_CPU_8974,
+ [184] = MSM_CPU_8974,
/* 8625 IDs */
[127] = MSM_CPU_8625,
diff --git a/arch/arm/mach-msm/spm-regulator.c b/arch/arm/mach-msm/spm-regulator.c
new file mode 100644
index 0000000..00817c0
--- /dev/null
+++ b/arch/arm/mach-msm/spm-regulator.c
@@ -0,0 +1,405 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/spmi.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+
+#include "spm.h"
+#include "spm-regulator.h"
+
+#define SPM_REGULATOR_DRIVER_NAME "qcom,spm-regulator"
+
+struct voltage_range {
+ int min_uV;
+ int set_point_min_uV;
+ int max_uV;
+ int step_uV;
+};
+
+/* Properties for FTS2 type QPNP PMIC regulators. */
+
+static const struct voltage_range fts2_range0 = {0, 350000, 1275000, 5000};
+static const struct voltage_range fts2_range1 = {0, 700000, 2040000, 10000};
+
+/* Specifies the PMIC internal slew rate in uV/us. */
+#define QPNP_FTS2_SLEW_RATE 6000
+
+#define QPNP_FTS2_REG_TYPE 0x04
+#define QPNP_FTS2_REG_SUBTYPE 0x05
+#define QPNP_FTS2_REG_VOLTAGE_RANGE 0x40
+#define QPNP_FTS2_REG_VOLTAGE_SETPOINT 0x41
+
+#define QPNP_FTS2_TYPE 0x1C
+#define QPNP_FTS2_SUBTYPE 0x08
+
+struct spm_vreg {
+ struct regulator_desc rdesc;
+ struct regulator_dev *rdev;
+ struct spmi_device *spmi_dev;
+ const struct voltage_range *range;
+ int uV;
+ int last_set_uV;
+ unsigned vlevel;
+ unsigned last_set_vlevel;
+ bool online;
+ u16 spmi_base_addr;
+};
+
+static int _spm_regulator_set_voltage(struct regulator_dev *rdev)
+{
+ struct spm_vreg *vreg = rdev_get_drvdata(rdev);
+ int rc;
+
+ if (vreg->vlevel == vreg->last_set_vlevel)
+ return 0;
+
+ rc = msm_spm_apcs_set_vdd(vreg->vlevel);
+ if (rc) {
+ pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->rdesc.name, rc);
+ return rc;
+ }
+
+ if (vreg->uV > vreg->last_set_uV) {
+ /* Wait for voltage to stabalize. */
+ udelay(DIV_ROUND_UP(vreg->uV - vreg->last_set_uV,
+ QPNP_FTS2_SLEW_RATE));
+ }
+ vreg->last_set_uV = vreg->uV;
+ vreg->last_set_vlevel = vreg->vlevel;
+
+ return rc;
+}
+
+static int spm_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
+ int max_uV, unsigned *selector)
+{
+ struct spm_vreg *vreg = rdev_get_drvdata(rdev);
+ const struct voltage_range *range = vreg->range;
+ int uV = min_uV;
+ unsigned vlevel;
+
+ if (uV < range->set_point_min_uV && max_uV >= range->set_point_min_uV)
+ uV = range->set_point_min_uV;
+
+ if (uV < range->set_point_min_uV || uV > range->max_uV) {
+ pr_err("%s: request v=[%d, %d] is outside possible v=[%d, %d]\n",
+ vreg->rdesc.name, min_uV, max_uV,
+ range->set_point_min_uV, range->max_uV);
+ return -EINVAL;
+ }
+
+ vlevel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
+ uV = vlevel * range->step_uV + range->min_uV;
+
+ if (uV > max_uV) {
+ pr_err("%s: request v=[%d, %d] cannot be met by any set point\n",
+ vreg->rdesc.name, min_uV, max_uV);
+ return -EINVAL;
+ }
+
+ vreg->vlevel = vlevel;
+ vreg->uV = uV;
+ *selector = vlevel -
+ (vreg->range->set_point_min_uV - vreg->range->min_uV)
+ / vreg->range->step_uV;
+
+ if (!vreg->online)
+ return 0;
+
+ return _spm_regulator_set_voltage(rdev);
+}
+
+static int spm_regulator_get_voltage(struct regulator_dev *rdev)
+{
+ struct spm_vreg *vreg = rdev_get_drvdata(rdev);
+
+ return vreg->uV;
+}
+
+static int spm_regulator_list_voltage(struct regulator_dev *rdev,
+ unsigned selector)
+{
+ struct spm_vreg *vreg = rdev_get_drvdata(rdev);
+
+ if (selector >= vreg->rdesc.n_voltages)
+ return 0;
+
+ return selector * vreg->range->step_uV + vreg->range->set_point_min_uV;
+}
+
+static int spm_regulator_enable(struct regulator_dev *rdev)
+{
+ struct spm_vreg *vreg = rdev_get_drvdata(rdev);
+ int rc;
+
+ rc = _spm_regulator_set_voltage(rdev);
+
+ if (!rc)
+ vreg->online = true;
+
+ return rc;
+}
+
+static int spm_regulator_disable(struct regulator_dev *rdev)
+{
+ struct spm_vreg *vreg = rdev_get_drvdata(rdev);
+
+ vreg->online = false;
+
+ return 0;
+}
+
+static int spm_regulator_is_enabled(struct regulator_dev *rdev)
+{
+ struct spm_vreg *vreg = rdev_get_drvdata(rdev);
+
+ return vreg->online;
+}
+
+static struct regulator_ops spm_regulator_ops = {
+ .get_voltage = spm_regulator_get_voltage,
+ .set_voltage = spm_regulator_set_voltage,
+ .list_voltage = spm_regulator_list_voltage,
+ .enable = spm_regulator_enable,
+ .disable = spm_regulator_disable,
+ .is_enabled = spm_regulator_is_enabled,
+};
+
+static int qpnp_fts2_check_type(struct spm_vreg *vreg)
+{
+ int rc;
+ u8 type[2];
+
+ rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
+ vreg->spmi_base_addr + QPNP_FTS2_REG_TYPE, type, 2);
+ if (rc) {
+ dev_err(&vreg->spmi_dev->dev, "%s: could not read type register, rc=%d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ if (type[0] != QPNP_FTS2_TYPE || type[1] != QPNP_FTS2_SUBTYPE) {
+ dev_err(&vreg->spmi_dev->dev, "%s: invalid type=0x%02X or subtype=0x%02X register value\n",
+ __func__, type[0], type[1]);
+ return -ENODEV;
+ }
+
+ return rc;
+}
+
+static int qpnp_fts2_init_range(struct spm_vreg *vreg)
+{
+ int rc;
+ u8 reg = 0;
+
+ rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
+ vreg->spmi_base_addr + QPNP_FTS2_REG_VOLTAGE_RANGE, ®, 1);
+ if (rc) {
+ dev_err(&vreg->spmi_dev->dev, "%s: could not read voltage range register, rc=%d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ if (reg == 0x00) {
+ vreg->range = &fts2_range0;
+ } else if (reg == 0x01) {
+ vreg->range = &fts2_range1;
+ } else {
+ dev_err(&vreg->spmi_dev->dev, "%s: voltage range=%d is invalid\n",
+ __func__, reg);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+static int qpnp_fts2_init_voltage(struct spm_vreg *vreg)
+{
+ int rc;
+ u8 reg = 0;
+
+ rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
+ vreg->spmi_base_addr + QPNP_FTS2_REG_VOLTAGE_SETPOINT, ®, 1);
+ if (rc) {
+ dev_err(&vreg->spmi_dev->dev, "%s: could not read voltage setpoint register, rc=%d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ vreg->vlevel = reg;
+ vreg->uV = vreg->vlevel * vreg->range->step_uV + vreg->range->min_uV;
+ vreg->last_set_uV = vreg->uV;
+
+ return rc;
+}
+
+static int __devinit spm_regulator_probe(struct spmi_device *spmi)
+{
+ struct device_node *node = spmi->dev.of_node;
+ struct regulator_init_data *init_data;
+ struct spm_vreg *vreg;
+ struct resource *res;
+ int rc;
+
+ if (!node) {
+ dev_err(&spmi->dev, "%s: device node missing\n", __func__);
+ return -ENODEV;
+ }
+
+ vreg = devm_kzalloc(&spmi->dev, sizeof(*vreg), GFP_KERNEL);
+ if (!vreg) {
+ pr_err("allocation failed.\n");
+ return -ENOMEM;
+ }
+ vreg->spmi_dev = spmi;
+
+ res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&spmi->dev, "%s: node is missing base address\n",
+ __func__);
+ return -EINVAL;
+ }
+ vreg->spmi_base_addr = res->start;
+
+ rc = qpnp_fts2_check_type(vreg);
+ if (rc)
+ return rc;
+
+ /*
+ * The FTS2 regulator must be initialized to range 0 or range 1 during
+ * PMIC power on sequence. Once it is set, it cannot be changed
+ * dynamically.
+ */
+ rc = qpnp_fts2_init_range(vreg);
+ if (rc)
+ return rc;
+
+ rc = qpnp_fts2_init_voltage(vreg);
+ if (rc)
+ return rc;
+
+ init_data = of_get_regulator_init_data(&spmi->dev, node);
+ if (!init_data) {
+ dev_err(&spmi->dev, "%s: unable to allocate memory\n",
+ __func__);
+ return -ENOMEM;
+ }
+ init_data->constraints.input_uV = init_data->constraints.max_uV;
+ init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_STATUS
+ | REGULATOR_CHANGE_VOLTAGE;
+
+ if (!init_data->constraints.name) {
+ dev_err(&spmi->dev, "%s: node is missing regulator name\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ vreg->rdesc.name = init_data->constraints.name;
+ vreg->rdesc.type = REGULATOR_VOLTAGE;
+ vreg->rdesc.owner = THIS_MODULE;
+ vreg->rdesc.ops = &spm_regulator_ops;
+ vreg->rdesc.n_voltages
+ = (vreg->range->max_uV - vreg->range->set_point_min_uV)
+ / vreg->range->step_uV + 1;
+
+ vreg->rdev = regulator_register(&vreg->rdesc, &spmi->dev,
+ init_data, vreg, node);
+ if (IS_ERR(vreg->rdev)) {
+ rc = PTR_ERR(vreg->rdev);
+ dev_err(&spmi->dev, "%s: regulator_register failed, rc=%d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ dev_set_drvdata(&spmi->dev, vreg);
+
+ pr_info("name=%s, range=%d\n", vreg->rdesc.name,
+ (vreg->range == &fts2_range0) ? 0 : 1);
+
+ return rc;
+}
+
+static int __devexit spm_regulator_remove(struct spmi_device *spmi)
+{
+ struct spm_vreg *vreg = dev_get_drvdata(&spmi->dev);
+
+ regulator_unregister(vreg->rdev);
+
+ return 0;
+}
+
+static struct of_device_id spm_regulator_match_table[] = {
+ { .compatible = SPM_REGULATOR_DRIVER_NAME, },
+ {}
+};
+
+static const struct spmi_device_id spm_regulator_id[] = {
+ { SPM_REGULATOR_DRIVER_NAME, 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(spmi, spm_regulator_id);
+
+static struct spmi_driver spm_regulator_driver = {
+ .driver = {
+ .name = SPM_REGULATOR_DRIVER_NAME,
+ .of_match_table = spm_regulator_match_table,
+ .owner = THIS_MODULE,
+ },
+ .probe = spm_regulator_probe,
+ .remove = __devexit_p(spm_regulator_remove),
+ .id_table = spm_regulator_id,
+};
+
+/**
+ * spm_regulator_init() - register spmi driver for spm-regulator
+ *
+ * This initialization function should be called in systems in which driver
+ * registration ordering must be controlled precisely.
+ *
+ * Returns 0 on success or errno on failure.
+ */
+int __init spm_regulator_init(void)
+{
+ static bool has_registered;
+
+ if (has_registered)
+ return 0;
+ else
+ has_registered = true;
+
+ return spmi_driver_register(&spm_regulator_driver);
+}
+EXPORT_SYMBOL(spm_regulator_init);
+
+static void __exit spm_regulator_exit(void)
+{
+ spmi_driver_unregister(&spm_regulator_driver);
+}
+
+arch_initcall(spm_regulator_init);
+module_exit(spm_regulator_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("SPM regulator driver");
+MODULE_ALIAS("platform:spm-regulator");
diff --git a/arch/arm/mach-msm/spm-regulator.h b/arch/arm/mach-msm/spm-regulator.h
new file mode 100644
index 0000000..394aecc
--- /dev/null
+++ b/arch/arm/mach-msm/spm-regulator.h
@@ -0,0 +1,25 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ARCH_ARM_MACH_MSM_SPM_REGULATOR_H
+#define _ARCH_ARM_MACH_MSM_SPM_REGULATOR_H
+
+#include <linux/err.h>
+#include <linux/init.h>
+
+#ifdef CONFIG_MSM_SPM_REGULATOR
+int __init spm_regulator_init(void);
+#else
+static inline int __init spm_regulator_init(void) { return -ENODEV; }
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/tz_log.c b/arch/arm/mach-msm/tz_log.c
index 11dc436..84e8df5 100644
--- a/arch/arm/mach-msm/tz_log.c
+++ b/arch/arm/mach-msm/tz_log.c
@@ -708,23 +708,18 @@
*/
tzdiag_phy_iobase = readl_relaxed(virt_iobase);
- if (!pdev->dev.of_node) {
+ /*
+ * Map the 4KB diagnostic information area
+ */
+ tzdbg.virt_iobase = devm_ioremap_nocache(&pdev->dev,
+ tzdiag_phy_iobase, DEBUG_MAX_RW_BUF);
- /*
- * Map the 4KB diagnostic information area
- */
- tzdbg.virt_iobase = devm_ioremap_nocache(&pdev->dev,
- tzdiag_phy_iobase, DEBUG_MAX_RW_BUF);
-
- if (!tzdbg.virt_iobase) {
- dev_err(&pdev->dev,
- "%s: ERROR could not ioremap: start=%p, len=%u\n",
- __func__, (void *) tzdiag_phy_iobase,
- DEBUG_MAX_RW_BUF);
- return -ENXIO;
- }
- } else {
- tzdbg.virt_iobase = virt_iobase;
+ if (!tzdbg.virt_iobase) {
+ dev_err(&pdev->dev,
+ "%s: ERROR could not ioremap: start=%p, len=%u\n",
+ __func__, (void *) tzdiag_phy_iobase,
+ DEBUG_MAX_RW_BUF);
+ return -ENXIO;
}
ptr = kzalloc(DEBUG_MAX_RW_BUF, GFP_KERNEL);
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 56a9a4a..1c8a25d 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);
@@ -838,12 +708,12 @@
if (arch_is_coherent() || nommu()) {
__dma_free_buffer(page, size);
+ } else if (__free_from_pool(cpu_addr, size)) {
+ return;
} else if (!IS_ENABLED(CONFIG_CMA)) {
__dma_free_remap(cpu_addr, size, false);
__dma_free_buffer(page, size);
} else {
- if (__free_from_pool(cpu_addr, size))
- return;
/*
* Non-atomic allocations cannot be freed with IRQs disabled
*/
@@ -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/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index ed91480..45c9023 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -227,7 +227,7 @@
pr_info("Found %s, memory base %lx, size %ld MiB\n", uname,
(unsigned long)base, (unsigned long)size / SZ_1M);
- dma_contiguous_reserve_area(size, &base, 0, name);
+ dma_contiguous_reserve_area(size, &base, MEMBLOCK_ALLOC_ANYWHERE, name);
return 0;
}
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
index b6d90d4..2557983 100644
--- a/drivers/bluetooth/hci_ath.c
+++ b/drivers/bluetooth/hci_ath.c
@@ -5,7 +5,7 @@
* power management protocol extension to H4 to support AR300x Bluetooth Chip.
*
* Copyright (c) 2009-2010 Atheros Communications Inc.
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
*
* Acknowledgements:
* This file is based on hci_h4.c, which was written
@@ -38,7 +38,7 @@
#include <linux/skbuff.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
-
+#include <linux/of_gpio.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -52,6 +52,13 @@
/*
* Global variables
*/
+
+/** Device table */
+static struct of_device_id bluesleep_match_table[] = {
+ { .compatible = "qca,ar3002_bluesleep" },
+ {}
+};
+
/** Global state flags */
static unsigned long flags;
@@ -436,10 +443,59 @@
.flush = ath_flush,
};
-static int __init bluesleep_probe(struct platform_device *pdev)
+
+static int bluesleep_populate_dt_pinfo(struct platform_device *pdev)
+{
+ BT_DBG("");
+
+ if (!bsi)
+ return -ENOMEM;
+
+ bsi->host_wake = of_get_named_gpio(pdev->dev.of_node,
+ "host-wake-gpio", 0);
+ if (bsi->host_wake < 0) {
+ BT_ERR("couldn't find host_wake gpio\n");
+ return -ENODEV;
+ }
+
+ bsi->ext_wake = of_get_named_gpio(pdev->dev.of_node,
+ "ext-wake-gpio", 0);
+ if (bsi->ext_wake < 0) {
+ BT_ERR("couldn't find ext_wake gpio\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int bluesleep_populate_pinfo(struct platform_device *pdev)
+{
+ struct resource *res;
+
+ BT_DBG("");
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IO,
+ "gpio_host_wake");
+ if (!res) {
+ BT_ERR("couldn't find host_wake gpio\n");
+ return -ENODEV;
+ }
+ bsi->host_wake = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IO,
+ "gpio_ext_wake");
+ if (!res) {
+ BT_ERR("couldn't find ext_wake gpio\n");
+ return -ENODEV;
+ }
+ bsi->ext_wake = res->start;
+
+ return 0;
+}
+
+static int __devinit bluesleep_probe(struct platform_device *pdev)
{
int ret;
- struct resource *res;
BT_DBG("");
@@ -449,23 +505,22 @@
goto failed;
}
- res = platform_get_resource_byname(pdev, IORESOURCE_IO,
- "gpio_host_wake");
- if (!res) {
- BT_ERR("couldn't find host_wake gpio\n");
- ret = -ENODEV;
- goto free_bsi;
+ if (pdev->dev.of_node) {
+ ret = bluesleep_populate_dt_pinfo(pdev);
+ if (ret < 0) {
+ BT_ERR("Failed to populate device tree info");
+ goto free_bsi;
+ }
+ } else {
+ ret = bluesleep_populate_pinfo(pdev);
+ if (ret < 0) {
+ BT_ERR("Failed to populate device info");
+ goto free_bsi;
+ }
}
- bsi->host_wake = res->start;
- res = platform_get_resource_byname(pdev, IORESOURCE_IO,
- "gpio_ext_wake");
- if (!res) {
- BT_ERR("couldn't find ext_wake gpio\n");
- ret = -ENODEV;
- goto free_bsi;
- }
- bsi->ext_wake = res->start;
+ BT_DBG("host_wake_gpio: %d ext_wake_gpio: %d",
+ bsi->host_wake, bsi->ext_wake);
bsi->host_wake_irq = platform_get_irq_byname(pdev, "host_wake");
if (bsi->host_wake_irq < 0) {
@@ -492,10 +547,12 @@
}
static struct platform_driver bluesleep_driver = {
+ .probe = bluesleep_probe,
.remove = bluesleep_remove,
.driver = {
.name = "bluesleep",
.owner = THIS_MODULE,
+ .of_match_table = bluesleep_match_table,
},
};
@@ -511,9 +568,13 @@
BT_ERR("HCIATH3K protocol registration failed");
return ret;
}
- ret = platform_driver_probe(&bluesleep_driver, bluesleep_probe);
- if (ret)
+
+ ret = platform_driver_register(&bluesleep_driver);
+ if (ret) {
+ BT_ERR("Failed to register bluesleep driver");
return ret;
+ }
+
return 0;
}
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/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/coresight/coresight-tpiu.c b/drivers/coresight/coresight-tpiu.c
index 3726a0d..73800dd 100644
--- a/drivers/coresight/coresight-tpiu.c
+++ b/drivers/coresight/coresight-tpiu.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
@@ -18,9 +18,15 @@
#include <linux/io.h>
#include <linux/err.h>
#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
#include <linux/clk.h>
#include <linux/of_coresight.h>
#include <linux/coresight.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <mach/gpiomux.h>
#include "coresight-priv.h"
@@ -58,20 +64,194 @@
#define TPIU_ITATBCTR1 (0xEF4)
#define TPIU_ITATBCTR0 (0xEF8)
+enum tpiu_out_mode {
+ TPIU_OUT_MODE_NONE,
+ TPIU_OUT_MODE_MICTOR,
+ TPIU_OUT_MODE_SDC,
+};
+
+enum tpiu_set {
+ TPIU_SET_NONE,
+ TPIU_SET_A,
+ TPIU_SET_B,
+};
+
struct tpiu_drvdata {
void __iomem *base;
struct device *dev;
struct coresight_device *csdev;
struct clk *clk;
+ struct mutex mutex;
+ enum tpiu_out_mode out_mode;
+ struct regulator *reg;
+ unsigned int reg_low;
+ unsigned int reg_high;
+ unsigned int reg_lpm;
+ unsigned int reg_hpm;
+ enum tpiu_set set;
+ unsigned int seta_gpiocnt;
+ unsigned int *seta_gpios;
+ struct gpiomux_setting *seta_cfgs;
+ unsigned int setb_gpiocnt;
+ unsigned int *setb_gpios;
+ struct gpiomux_setting *setb_cfgs;
+ bool enable;
};
-static void __tpiu_enable(struct tpiu_drvdata *drvdata)
+struct gpiomux_setting old_cfg;
+
+static void tpiu_flush_and_stop(struct tpiu_drvdata *drvdata)
{
+ int count;
+ uint32_t ffcr;
+
+ ffcr = tpiu_readl(drvdata, TPIU_FFCR);
+ ffcr |= BIT(12);
+ tpiu_writel(drvdata, ffcr, TPIU_FFCR);
+ ffcr |= BIT(6);
+ tpiu_writel(drvdata, ffcr, TPIU_FFCR);
+ /* Ensure flush completes */
+ for (count = TIMEOUT_US; BVAL(tpiu_readl(drvdata, TPIU_FFCR), 6) != 0
+ && count > 0; count--)
+ udelay(1);
+ WARN(count == 0, "timeout while flushing TPIU, TPIU_FFCR: %#x\n",
+ tpiu_readl(drvdata, TPIU_FFCR));
+}
+
+static int __tpiu_enable_seta(struct tpiu_drvdata *drvdata)
+{
+ int i, ret;
+
+ if (!drvdata->seta_gpiocnt)
+ return -EINVAL;
+
+ for (i = 0; i < drvdata->seta_gpiocnt; i++) {
+ ret = gpio_request(drvdata->seta_gpios[i], NULL);
+ if (ret) {
+ dev_err(drvdata->dev,
+ "gpio_request failed for seta_gpio: %u\n",
+ drvdata->seta_gpios[i]);
+ goto err0;
+ }
+ ret = msm_gpiomux_write(drvdata->seta_gpios[i],
+ GPIOMUX_ACTIVE,
+ &drvdata->seta_cfgs[i],
+ &old_cfg);
+ if (ret < 0) {
+ dev_err(drvdata->dev,
+ "gpio write failed for seta_gpio: %u\n",
+ drvdata->seta_gpios[i]);
+ goto err1;
+ }
+ }
+ return 0;
+err1:
+ gpio_free(drvdata->seta_gpios[i]);
+err0:
+ i--;
+ while (i >= 0) {
+ gpio_free(drvdata->seta_gpios[i]);
+ i--;
+ }
+ return ret;
+}
+
+static int __tpiu_enable_setb(struct tpiu_drvdata *drvdata)
+{
+ int i, ret;
+
+ if (!drvdata->setb_gpiocnt)
+ return -EINVAL;
+
+ for (i = 0; i < drvdata->setb_gpiocnt; i++) {
+ ret = gpio_request(drvdata->setb_gpios[i], NULL);
+ if (ret) {
+ dev_err(drvdata->dev,
+ "gpio_request failed for setb_gpio: %u\n",
+ drvdata->setb_gpios[i]);
+ goto err0;
+ }
+ ret = msm_gpiomux_write(drvdata->setb_gpios[i],
+ GPIOMUX_ACTIVE,
+ &drvdata->setb_cfgs[i],
+ &old_cfg);
+ if (ret < 0) {
+ dev_err(drvdata->dev,
+ "gpio write failed for setb_gpio: %u\n",
+ drvdata->setb_gpios[i]);
+ goto err1;
+ }
+ }
+ return 0;
+err1:
+ gpio_free(drvdata->setb_gpios[i]);
+err0:
+ i--;
+ while (i >= 0) {
+ gpio_free(drvdata->setb_gpios[i]);
+ i--;
+ }
+ return ret;
+}
+
+static int __tpiu_enable_to_mictor(struct tpiu_drvdata *drvdata)
+{
+ int ret;
+
+ if (drvdata->set == TPIU_SET_A) {
+ ret = __tpiu_enable_seta(drvdata);
+ if (ret)
+ return ret;
+ } else if (drvdata->set == TPIU_SET_B) {
+ ret = __tpiu_enable_setb(drvdata);
+ if (ret)
+ return ret;
+ }
+
TPIU_UNLOCK(drvdata);
- /* TODO: fill this up */
+ tpiu_writel(drvdata, 0x8000, TPIU_CURR_PORTSZ);
+ tpiu_writel(drvdata, 0x101, TPIU_FFCR);
TPIU_LOCK(drvdata);
+
+ return 0;
+}
+
+static int __tpiu_enable_to_sdc(struct tpiu_drvdata *drvdata)
+{
+ int ret;
+
+ if (!drvdata->reg)
+ return -EINVAL;
+
+ ret = regulator_set_optimum_mode(drvdata->reg, drvdata->reg_hpm);
+ if (ret < 0)
+ return ret;
+ ret = regulator_set_voltage(drvdata->reg, drvdata->reg_low,
+ drvdata->reg_high);
+ if (ret)
+ goto err0;
+ ret = regulator_enable(drvdata->reg);
+ if (ret)
+ goto err1;
+
+ msm_tlmm_misc_reg_write(TLMM_SDC2_HDRV_PULL_CTL, 0x16D);
+ msm_tlmm_misc_reg_write(TLMM_ETM_MODE_REG, 1);
+
+ TPIU_UNLOCK(drvdata);
+
+ tpiu_writel(drvdata, 0x8, TPIU_CURR_PORTSZ);
+ tpiu_writel(drvdata, 0x103, TPIU_FFCR);
+
+ TPIU_LOCK(drvdata);
+
+ return 0;
+err1:
+ regulator_set_voltage(drvdata->reg, 0, drvdata->reg_high);
+err0:
+ regulator_set_optimum_mode(drvdata->reg, 0);
+ return ret;
}
static int tpiu_enable(struct coresight_device *csdev)
@@ -83,27 +263,85 @@
if (ret)
return ret;
- __tpiu_enable(drvdata);
+ mutex_lock(&drvdata->mutex);
+
+ if (drvdata->out_mode == TPIU_OUT_MODE_MICTOR)
+ ret = __tpiu_enable_to_mictor(drvdata);
+ else
+ ret = __tpiu_enable_to_sdc(drvdata);
+ if (ret)
+ goto err;
+ drvdata->enable = true;
+
+ mutex_unlock(&drvdata->mutex);
dev_info(drvdata->dev, "TPIU enabled\n");
return 0;
+err:
+ mutex_unlock(&drvdata->mutex);
+ clk_disable_unprepare(drvdata->clk);
+ return ret;
}
static void __tpiu_disable(struct tpiu_drvdata *drvdata)
{
TPIU_UNLOCK(drvdata);
- tpiu_writel(drvdata, 0x3000, TPIU_FFCR);
- tpiu_writel(drvdata, 0x3040, TPIU_FFCR);
+ tpiu_flush_and_stop(drvdata);
TPIU_LOCK(drvdata);
}
+static void __tpiu_disable_seta(struct tpiu_drvdata *drvdata)
+{
+ int i;
+
+ for (i = 0; i < drvdata->seta_gpiocnt; i++)
+ gpio_free(drvdata->seta_gpios[i]);
+}
+
+static void __tpiu_disable_setb(struct tpiu_drvdata *drvdata)
+{
+ int i;
+
+ for (i = 0; i < drvdata->setb_gpiocnt; i++)
+ gpio_free(drvdata->setb_gpios[i]);
+}
+
+static void __tpiu_disable_to_mictor(struct tpiu_drvdata *drvdata)
+{
+ __tpiu_disable(drvdata);
+
+ if (drvdata->set == TPIU_SET_A)
+ __tpiu_disable_seta(drvdata);
+ else if (drvdata->set == TPIU_SET_B)
+ __tpiu_disable_setb(drvdata);
+}
+
+static void __tpiu_disable_to_sdc(struct tpiu_drvdata *drvdata)
+{
+ __tpiu_disable(drvdata);
+
+ msm_tlmm_misc_reg_write(TLMM_ETM_MODE_REG, 0);
+
+ regulator_disable(drvdata->reg);
+ regulator_set_optimum_mode(drvdata->reg, 0);
+ regulator_set_voltage(drvdata->reg, 0, drvdata->reg_high);
+}
+
static void tpiu_disable(struct coresight_device *csdev)
{
struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
- __tpiu_disable(drvdata);
+ mutex_lock(&drvdata->mutex);
+
+ if (drvdata->out_mode == TPIU_OUT_MODE_MICTOR)
+ __tpiu_disable_to_mictor(drvdata);
+ else
+ __tpiu_disable_to_sdc(drvdata);
+ drvdata->enable = false;
+
+ mutex_unlock(&drvdata->mutex);
clk_disable_unprepare(drvdata->clk);
@@ -125,10 +363,331 @@
.abort = tpiu_abort,
};
+static ssize_t tpiu_show_out_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct tpiu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ return scnprintf(buf, PAGE_SIZE, "%s\n",
+ drvdata->out_mode == TPIU_OUT_MODE_MICTOR ?
+ "mictor" : "sdc");
+}
+
+static ssize_t tpiu_store_out_mode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct tpiu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ char str[10] = "";
+ int ret;
+
+ if (strlen(buf) >= 10)
+ return -EINVAL;
+ if (sscanf(buf, "%s", str) != 1)
+ return -EINVAL;
+
+ mutex_lock(&drvdata->mutex);
+ if (!strcmp(str, "mictor")) {
+ if (drvdata->out_mode == TPIU_OUT_MODE_MICTOR)
+ goto out;
+
+ if (!drvdata->enable) {
+ drvdata->out_mode = TPIU_OUT_MODE_MICTOR;
+ goto out;
+ }
+ __tpiu_disable_to_sdc(drvdata);
+ ret = __tpiu_enable_to_mictor(drvdata);
+ if (ret) {
+ dev_err(drvdata->dev, "failed to enable mictor\n");
+ goto err;
+ }
+ drvdata->out_mode = TPIU_OUT_MODE_MICTOR;
+ } else if (!strcmp(str, "sdc")) {
+ if (drvdata->out_mode == TPIU_OUT_MODE_SDC)
+ goto out;
+
+ if (!drvdata->enable) {
+ drvdata->out_mode = TPIU_OUT_MODE_SDC;
+ goto out;
+ }
+ __tpiu_disable_to_mictor(drvdata);
+ ret = __tpiu_enable_to_sdc(drvdata);
+ if (ret) {
+ dev_err(drvdata->dev, "failed to enable sdc\n");
+ goto err;
+ }
+ drvdata->out_mode = TPIU_OUT_MODE_SDC;
+ }
+out:
+ mutex_unlock(&drvdata->mutex);
+ return size;
+err:
+ mutex_unlock(&drvdata->mutex);
+ return ret;
+}
+static DEVICE_ATTR(out_mode, S_IRUGO | S_IWUSR, tpiu_show_out_mode,
+ tpiu_store_out_mode);
+
static const struct coresight_ops tpiu_cs_ops = {
.sink_ops = &tpiu_sink_ops,
};
+static ssize_t tpiu_show_set(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct tpiu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ return scnprintf(buf, PAGE_SIZE, "%s\n",
+ drvdata->set == TPIU_SET_A ?
+ "a" : "b");
+}
+
+static ssize_t tpiu_store_set(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct tpiu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ char str[10] = "";
+ int ret;
+
+ if (strlen(buf) >= 10)
+ return -EINVAL;
+ if (sscanf(buf, "%s", str) != 1)
+ return -EINVAL;
+
+ mutex_lock(&drvdata->mutex);
+ if (!strcmp(str, "a")) {
+ if (drvdata->set == TPIU_SET_A)
+ goto out;
+
+ if (!drvdata->enable || drvdata->out_mode !=
+ TPIU_OUT_MODE_MICTOR) {
+ drvdata->set = TPIU_SET_A;
+ goto out;
+ }
+ __tpiu_disable_setb(drvdata);
+ ret = __tpiu_enable_seta(drvdata);
+ if (ret) {
+ dev_err(drvdata->dev, "failed to enable set A\n");
+ goto err;
+ }
+ drvdata->set = TPIU_SET_A;
+ } else if (!strcmp(str, "b")) {
+ if (drvdata->set == TPIU_SET_B)
+ goto out;
+
+ if (!drvdata->enable || drvdata->out_mode !=
+ TPIU_OUT_MODE_MICTOR) {
+ drvdata->set = TPIU_SET_B;
+ goto out;
+ }
+ __tpiu_disable_seta(drvdata);
+ ret = __tpiu_enable_setb(drvdata);
+ if (ret) {
+ dev_err(drvdata->dev, "failed to enable set B\n");
+ goto err;
+ }
+ drvdata->set = TPIU_SET_B;
+ }
+out:
+ mutex_unlock(&drvdata->mutex);
+ return size;
+err:
+ mutex_unlock(&drvdata->mutex);
+ return ret;
+}
+static DEVICE_ATTR(set, S_IRUGO | S_IWUSR, tpiu_show_set, tpiu_store_set);
+
+static struct attribute *tpiu_attrs[] = {
+ &dev_attr_out_mode.attr,
+ &dev_attr_set.attr,
+ NULL,
+};
+
+static struct attribute_group tpiu_attr_grp = {
+ .attrs = tpiu_attrs,
+};
+
+static const struct attribute_group *tpiu_attr_grps[] = {
+ &tpiu_attr_grp,
+ NULL,
+};
+
+static int __devinit tpiu_parse_of_data(struct platform_device *pdev,
+ struct tpiu_drvdata *drvdata)
+{
+ struct device_node *node = pdev->dev.of_node;
+ struct device_node *reg_node = NULL;
+ struct device *dev = &pdev->dev;
+ const __be32 *prop;
+ int i, len, gpio, ret;
+ uint32_t *seta_cfgs, *setb_cfgs;
+
+ reg_node = of_parse_phandle(node, "vdd-supply", 0);
+ if (reg_node) {
+ drvdata->reg = devm_regulator_get(dev, "vdd");
+ if (IS_ERR(drvdata->reg))
+ return PTR_ERR(drvdata->reg);
+
+ prop = of_get_property(node, "qcom,vdd-voltage-level", &len);
+ if (!prop || (len != (2 * sizeof(__be32)))) {
+ of_node_put(reg_node);
+ return -EINVAL;
+ } else {
+ drvdata->reg_low = be32_to_cpup(&prop[0]);
+ drvdata->reg_high = be32_to_cpup(&prop[1]);
+ }
+
+ prop = of_get_property(node, "qcom,vdd-current-level", &len);
+ if (!prop || (len != (2 * sizeof(__be32)))) {
+ of_node_put(reg_node);
+ return -EINVAL;
+ } else {
+ drvdata->reg_lpm = be32_to_cpup(&prop[0]);
+ drvdata->reg_hpm = be32_to_cpup(&prop[1]);
+ }
+ of_node_put(reg_node);
+ } else {
+ dev_err(dev, "sdc voltage supply not specified or available\n");
+ }
+
+ drvdata->out_mode = TPIU_OUT_MODE_MICTOR;
+ drvdata->set = TPIU_SET_B;
+
+ drvdata->seta_gpiocnt = of_gpio_named_count(node, "qcom,seta-gpios");
+ if (drvdata->seta_gpiocnt) {
+ drvdata->seta_gpios = devm_kzalloc(dev,
+ sizeof(*drvdata->seta_gpios) *
+ drvdata->seta_gpiocnt, GFP_KERNEL);
+ if (!drvdata->seta_gpios)
+ return -ENOMEM;
+
+ for (i = 0; i < drvdata->seta_gpiocnt; i++) {
+ gpio = of_get_named_gpio(node, "qcom,seta-gpios", i);
+ if (!gpio_is_valid(gpio))
+ return gpio;
+
+ drvdata->seta_gpios[i] = gpio;
+ }
+
+ drvdata->seta_cfgs = devm_kzalloc(dev,
+ sizeof(*drvdata->seta_cfgs) *
+ drvdata->seta_gpiocnt, GFP_KERNEL);
+ if (!drvdata->seta_cfgs)
+ return -ENOMEM;
+
+ seta_cfgs = devm_kzalloc(dev, sizeof(*seta_cfgs) *
+ drvdata->seta_gpiocnt, GFP_KERNEL);
+ if (!seta_cfgs)
+ return -ENOMEM;
+
+ ret = of_property_read_u32_array(node, "qcom,seta-gpios-func",
+ (u32 *)seta_cfgs,
+ drvdata->seta_gpiocnt);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < drvdata->seta_gpiocnt; i++)
+ drvdata->seta_cfgs[i].func = seta_cfgs[i];
+
+ ret = of_property_read_u32_array(node, "qcom,seta-gpios-drv",
+ (u32 *)seta_cfgs,
+ drvdata->seta_gpiocnt);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < drvdata->seta_gpiocnt; i++)
+ drvdata->seta_cfgs[i].drv = seta_cfgs[i];
+
+ ret = of_property_read_u32_array(node, "qcom,seta-gpios-pull",
+ (u32 *)seta_cfgs,
+ drvdata->seta_gpiocnt);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < drvdata->seta_gpiocnt; i++)
+ drvdata->seta_cfgs[i].pull = seta_cfgs[i];
+
+ ret = of_property_read_u32_array(node, "qcom,seta-gpios-dir",
+ (u32 *)seta_cfgs,
+ drvdata->seta_gpiocnt);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < drvdata->seta_gpiocnt; i++)
+ drvdata->seta_cfgs[i].dir = seta_cfgs[i];
+ } else {
+ dev_err(dev, "seta gpios not specified\n");
+ }
+
+ drvdata->setb_gpiocnt = of_gpio_named_count(node, "qcom,setb-gpios");
+ if (drvdata->setb_gpiocnt) {
+ drvdata->setb_gpios = devm_kzalloc(dev,
+ sizeof(*drvdata->setb_gpios) *
+ drvdata->setb_gpiocnt, GFP_KERNEL);
+ if (!drvdata->setb_gpios)
+ return -ENOMEM;
+
+ for (i = 0; i < drvdata->setb_gpiocnt; i++) {
+ gpio = of_get_named_gpio(node, "qcom,setb-gpios", i);
+ if (!gpio_is_valid(gpio))
+ return gpio;
+
+ drvdata->setb_gpios[i] = gpio;
+ }
+
+ drvdata->setb_cfgs = devm_kzalloc(dev,
+ sizeof(*drvdata->setb_cfgs) *
+ drvdata->setb_gpiocnt, GFP_KERNEL);
+ if (!drvdata->setb_cfgs)
+ return -ENOMEM;
+
+ setb_cfgs = devm_kzalloc(dev, sizeof(*setb_cfgs) *
+ drvdata->setb_gpiocnt, GFP_KERNEL);
+ if (!setb_cfgs)
+ return -ENOMEM;
+
+ ret = of_property_read_u32_array(node, "qcom,setb-gpios-func",
+ (u32 *)setb_cfgs,
+ drvdata->setb_gpiocnt);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < drvdata->setb_gpiocnt; i++)
+ drvdata->setb_cfgs[i].func = setb_cfgs[i];
+
+ ret = of_property_read_u32_array(node, "qcom,setb-gpios-drv",
+ (u32 *)setb_cfgs,
+ drvdata->setb_gpiocnt);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < drvdata->setb_gpiocnt; i++)
+ drvdata->setb_cfgs[i].drv = setb_cfgs[i];
+
+ ret = of_property_read_u32_array(node, "qcom,setb-gpios-pull",
+ (u32 *)setb_cfgs,
+ drvdata->setb_gpiocnt);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < drvdata->setb_gpiocnt; i++)
+ drvdata->setb_cfgs[i].pull = setb_cfgs[i];
+
+ ret = of_property_read_u32_array(node, "qcom,setb-gpios-dir",
+ (u32 *)setb_cfgs,
+ drvdata->setb_gpiocnt);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < drvdata->setb_gpiocnt; i++)
+ drvdata->setb_cfgs[i].dir = setb_cfgs[i];
+ } else {
+ dev_err(dev, "setb gpios not specified\n");
+ }
+
+ return 0;
+}
+
static int __devinit tpiu_probe(struct platform_device *pdev)
{
int ret;
@@ -159,6 +718,8 @@
if (!drvdata->base)
return -ENOMEM;
+ mutex_init(&drvdata->mutex);
+
drvdata->clk = devm_clk_get(dev, "core_clk");
if (IS_ERR(drvdata->clk))
return PTR_ERR(drvdata->clk);
@@ -176,6 +737,12 @@
clk_disable_unprepare(drvdata->clk);
+ if (pdev->dev.of_node) {
+ ret = tpiu_parse_of_data(pdev, drvdata);
+ if (ret)
+ return ret;
+ }
+
desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
if (!desc)
return -ENOMEM;
@@ -184,6 +751,7 @@
desc->ops = &tpiu_cs_ops;
desc->pdata = pdev->dev.platform_data;
desc->dev = &pdev->dev;
+ desc->groups = tpiu_attr_grps;
desc->owner = THIS_MODULE;
drvdata->csdev = coresight_register(desc);
if (IS_ERR(drvdata->csdev))
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index b484c8a..1134f90 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -41,6 +41,7 @@
#define CRYPTO_CONFIG_RESET 0xE001F
#define QCE_MAX_NUM_DSCR 0x400
#define QCE_SIZE_BAM_DSCR 0x08
+#define QCE_SECTOR_SIZE 0x200
static DEFINE_MUTEX(bam_register_cnt);
struct bam_registration_info {
@@ -445,6 +446,7 @@
uint32_t enck_size_in_word = 0;
uint32_t key_size;
bool use_hw_key = false;
+ bool use_pipe_key = false;
uint32_t encr_cfg = 0;
uint32_t ivsize = creq->ivsize;
int i;
@@ -456,6 +458,7 @@
key_size = creq->encklen;
_byte_stream_to_net_words(enckey32, creq->enckey, key_size);
+ pce = cmdlistinfo->go_proc;
/* check for null key. If null, use hw key*/
enck_size_in_word = key_size/sizeof(uint32_t);
@@ -463,15 +466,22 @@
if (enckey32[i] != 0)
break;
}
- pce = cmdlistinfo->go_proc;
if (i == enck_size_in_word) {
use_hw_key = true;
pce->addr = (uint32_t)(CRYPTO_GOPROC_QC_KEY_REG +
pce_dev->phy_iobase);
- } else {
+ }
+ if (use_hw_key == false) {
+ for (i = 0; i < enck_size_in_word; i++) {
+ if (enckey32[i] != 0xFFFFFFFF)
+ break;
+ }
+ if (i == enck_size_in_word)
+ use_pipe_key = true;
+ }
+ if (use_hw_key == false)
pce->addr = (uint32_t)(CRYPTO_GOPROC_REG +
pce_dev->phy_iobase);
- }
if ((creq->op == QCE_REQ_AEAD) && (creq->mode == QCE_MODE_CCM)) {
uint32_t authklen32 = creq->encklen/sizeof(uint32_t);
@@ -600,7 +610,10 @@
/* write xts du size */
pce = cmdlistinfo->encr_xts_du_size;
- pce->data = creq->cryptlen;
+ if (use_pipe_key == true)
+ pce->data = QCE_SECTOR_SIZE;
+ else
+ pce->data = creq->cryptlen;
}
if (creq->mode != QCE_MODE_ECB) {
if (creq->mode == QCE_MODE_XTS)
@@ -653,6 +666,10 @@
break;
} /* end of switch (creq->mode) */
+ if (use_pipe_key)
+ encr_cfg |= (CRYPTO_USE_PIPE_KEY_ENCR_ENABLED
+ << CRYPTO_USE_PIPE_KEY_ENCR);
+
/* write encr seg cfg */
pce = cmdlistinfo->encr_seg_cfg;
if ((creq->alg == CIPHER_ALG_DES) || (creq->alg == CIPHER_ALG_3DES)) {
@@ -1048,7 +1065,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
@@ -2334,6 +2351,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) {
@@ -2342,6 +2360,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) {
@@ -2401,8 +2420,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(
@@ -2490,6 +2507,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) {
@@ -2499,6 +2517,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) {
@@ -2520,7 +2539,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;
@@ -2572,6 +2590,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) {
@@ -2581,6 +2600,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) {
@@ -2715,6 +2735,7 @@
pr_warn("Unable to get CE core src clk, set to NULL\n");
pce_dev->ce_core_src_clk = NULL;
}
+ pce_dev->ce_core_src_clk = ce_core_src_clk;
/* Get CE core clk */
ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
@@ -2752,43 +2773,86 @@
}
pce_dev->ce_bus_clk = ce_bus_clk;
+err_clk:
+ if (rc)
+ pr_err("Unable to init CE clks, rc = %d\n", rc);
+ return rc;
+}
+
+static void __qce_deinit_clk(struct qce_device *pce_dev)
+{
+ if (pce_dev->ce_clk != NULL) {
+ clk_put(pce_dev->ce_clk);
+ pce_dev->ce_clk = NULL;
+ }
+ if (pce_dev->ce_core_clk != NULL) {
+ clk_put(pce_dev->ce_core_clk);
+ pce_dev->ce_core_clk = NULL;
+ }
+ if (pce_dev->ce_bus_clk != NULL) {
+ clk_put(pce_dev->ce_bus_clk);
+ pce_dev->ce_bus_clk = NULL;
+ }
+ if (pce_dev->ce_core_src_clk != NULL) {
+ clk_put(pce_dev->ce_core_src_clk);
+ pce_dev->ce_core_src_clk = NULL;
+ }
+}
+
+static int __qce_enable_clk(void *handle)
+{
+ struct qce_device *pce_dev = (struct qce_device *) handle;
+ int rc = 0;
+
/* Enable CE core clk */
rc = clk_prepare_enable(pce_dev->ce_core_clk);
if (rc) {
pr_err("Unable to enable/prepare CE core clk\n");
- if (pce_dev->ce_core_src_clk != NULL)
- clk_put(pce_dev->ce_core_src_clk);
- clk_put(pce_dev->ce_core_clk);
- clk_put(pce_dev->ce_clk);
- goto err_clk;
- } else {
- /* Enable CE clk */
- rc = clk_prepare_enable(pce_dev->ce_clk);
- if (rc) {
- pr_err("Unable to enable/prepare CE iface clk\n");
- clk_disable_unprepare(pce_dev->ce_core_clk);
- if (pce_dev->ce_core_src_clk != NULL)
- clk_put(pce_dev->ce_core_src_clk);
- clk_put(pce_dev->ce_core_clk);
- clk_put(pce_dev->ce_clk);
- goto err_clk;
- }
- /* Enable AXI clk */
- rc = clk_prepare_enable(pce_dev->ce_bus_clk);
+ return rc;
+ }
+ /* Enable CE clk */
+ rc = clk_prepare_enable(pce_dev->ce_clk);
+ if (rc) {
+ pr_err("Unable to enable/prepare CE iface clk\n");
+ clk_disable_unprepare(pce_dev->ce_core_clk);
+ return rc;
+ }
+ /* Enable AXI clk */
+ rc = clk_prepare_enable(pce_dev->ce_bus_clk);
+ if (rc) {
+ pr_err("Unable to enable/prepare CE BUS clk\n");
+ clk_disable_unprepare(pce_dev->ce_clk);
+ clk_disable_unprepare(pce_dev->ce_core_clk);
+ return rc;
+ }
+ /* Enable CORE SRC (INTERFACE) clk */
+ if (pce_dev->ce_core_src_clk != NULL) {
+ rc = clk_prepare_enable(pce_dev->ce_core_src_clk);
if (rc) {
pr_err("Unable to enable/prepare CE BUS clk\n");
+ clk_disable_unprepare(pce_dev->ce_clk);
clk_disable_unprepare(pce_dev->ce_core_clk);
- if (pce_dev->ce_core_src_clk != NULL)
- clk_put(pce_dev->ce_core_src_clk);
- clk_put(pce_dev->ce_core_clk);
- clk_put(pce_dev->ce_clk);
- clk_put(pce_dev->ce_bus_clk);
- goto err_clk;
+ clk_disable_unprepare(pce_dev->ce_bus_clk);
+ return rc;
}
}
-err_clk:
- if (rc)
- pr_err("Unable to init CE clks, rc = %d\n", rc);
+ return rc;
+}
+
+static int __qce_disable_clk(void *handle)
+{
+ struct qce_device *pce_dev = (struct qce_device *) handle;
+ int rc = 0;
+
+ if (pce_dev->ce_clk != NULL)
+ clk_disable_unprepare(pce_dev->ce_clk);
+ if (pce_dev->ce_core_src_clk != NULL)
+ clk_disable_unprepare(pce_dev->ce_core_src_clk);
+ if (pce_dev->ce_core_clk != NULL)
+ clk_disable_unprepare(pce_dev->ce_core_clk);
+ if (pce_dev->ce_bus_clk != NULL)
+ clk_disable_unprepare(pce_dev->ce_bus_clk);
+
return rc;
}
@@ -2828,8 +2892,13 @@
if (*rc)
goto err_mem;
+ *rc = __qce_enable_clk(pce_dev);
+ if (*rc)
+ goto err;
+
if (_probe_ce_engine(pce_dev)) {
*rc = -ENXIO;
+ __qce_disable_clk(pce_dev);
goto err;
}
*rc = 0;
@@ -2838,13 +2907,8 @@
return pce_dev;
err:
- clk_disable_unprepare(pce_dev->ce_clk);
- clk_disable_unprepare(pce_dev->ce_core_clk);
+ __qce_deinit_clk(pce_dev);
- if (pce_dev->ce_core_src_clk != NULL)
- clk_put(pce_dev->ce_core_src_clk);
- clk_put(pce_dev->ce_clk);
- clk_put(pce_dev->ce_core_clk);
err_mem:
if (pce_dev->coh_vmem)
dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
@@ -2874,14 +2938,8 @@
dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
pce_dev->coh_vmem, pce_dev->coh_pmem);
- clk_disable_unprepare(pce_dev->ce_clk);
- clk_disable_unprepare(pce_dev->ce_core_clk);
- clk_disable_unprepare(pce_dev->ce_bus_clk);
- if (pce_dev->ce_core_src_clk != NULL)
- clk_put(pce_dev->ce_core_src_clk);
- clk_put(pce_dev->ce_clk);
- clk_put(pce_dev->ce_core_clk);
- clk_put(pce_dev->ce_bus_clk);
+ __qce_disable_clk(pce_dev);
+ __qce_deinit_clk(pce_dev);
qce_sps_exit(pce_dev);
kfree(handle);
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.c b/drivers/gpu/ion/ion.c
index 9ab2343..9128177 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -1248,14 +1248,12 @@
mutex_lock(&buffer->lock);
/* now map it to userspace */
ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma);
+ mutex_unlock(&buffer->lock);
if (ret) {
- mutex_unlock(&buffer->lock);
pr_err("%s: failure mapping buffer to userspace\n",
__func__);
} else {
- mutex_unlock(&buffer->lock);
-
vma->vm_ops = &ion_vm_ops;
/*
* move the buffer into the vm_private_data so we can access it
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..8a5e5c9 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -614,6 +614,11 @@
int i;
pgprot_t pgprot;
+ if (!pages) {
+ mutex_unlock(&cp_heap->lock);
+ return ERR_PTR(-ENOMEM);
+ }
+
if (ION_IS_CACHED(buffer->flags))
pgprot = PAGE_KERNEL;
else
@@ -731,26 +736,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..33e6fed 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -54,6 +54,11 @@
.name = ION_VMALLOC_HEAP_NAME,
},
{
+ .id = ION_SYSTEM_CONTIG_HEAP_ID,
+ .type = ION_HEAP_TYPE_SYSTEM_CONTIG,
+ .name = ION_KMALLOC_HEAP_NAME,
+ },
+ {
.id = ION_CP_MM_HEAP_ID,
.type = ION_HEAP_TYPE_SECURE_DMA,
.name = ION_MM_HEAP_NAME,
@@ -715,7 +720,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_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 29d689b..5396196 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -702,7 +702,7 @@
" %08X\n", r1, r2, r3);
KGSL_LOG_DUMP(device, "PAGETABLE SIZE: %08X ",
- kgsl_mmu_get_ptsize());
+ kgsl_mmu_get_ptsize(&device->mmu));
kgsl_regread(device, MH_MMU_TRAN_ERROR, &r1);
KGSL_LOG_DUMP(device, " TRAN_ERROR = %08X\n", r1);
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index c8229e7..a76ed87 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] */
@@ -444,7 +470,7 @@
int offset = type0_pkt_offset(*ptr);
int i;
- for (i = 0; i < size; i++, offset++) {
+ for (i = 0; i < size - 1; i++, offset++) {
/* Visiblity stream buffer */
@@ -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.c b/drivers/gpu/msm/kgsl.c
index 2b0d5d9..e852e29 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -671,9 +671,10 @@
if (kgsl_mmu_enabled())
{
unsigned long pt_name;
+ struct kgsl_mmu *mmu = &cur_dev_priv->device->mmu;
pt_name = task_tgid_nr(current);
- private->pagetable = kgsl_mmu_getpagetable(pt_name);
+ private->pagetable = kgsl_mmu_getpagetable(mmu, pt_name);
if (private->pagetable == NULL) {
kfree(private);
private = NULL;
@@ -872,7 +873,7 @@
{
struct rb_node *node = private->mem_rb.rb_node;
- if (!kgsl_mmu_gpuaddr_in_range(gpuaddr))
+ if (!kgsl_mmu_gpuaddr_in_range(private->pagetable, gpuaddr))
return NULL;
while (node != NULL) {
@@ -925,7 +926,7 @@
struct rb_node *node = private->mem_rb.rb_node;
- if (!kgsl_mmu_gpuaddr_in_range(gpuaddr))
+ if (!kgsl_mmu_gpuaddr_in_range(private->pagetable, gpuaddr))
return 0;
/* don't overflow */
@@ -1193,7 +1194,9 @@
}
for (i = 0; i < param->numibs; i++) {
- if (!kgsl_mmu_gpuaddr_in_range(ibdesc[i].gpuaddr)) {
+ struct kgsl_pagetable *pt = dev_priv->process_priv->pagetable;
+
+ if (!kgsl_mmu_gpuaddr_in_range(pt, ibdesc[i].gpuaddr)) {
result = -ERANGE;
KGSL_DRV_ERR(dev_priv->device,
"invalid ib base GPU virtual addr %x\n",
@@ -1767,13 +1770,6 @@
return -ENOMEM;
}
-static inline int
-can_use_cpu_map(void)
-{
- return (kgsl_mmu_get_mmutype() == KGSL_MMU_TYPE_IOMMU
- && kgsl_mmu_is_perprocess());
-}
-
static long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data)
{
@@ -1805,7 +1801,7 @@
| KGSL_MEMFLAGS_USE_CPU_MAP;
entry->memdesc.flags = param->flags;
- if (!can_use_cpu_map())
+ if (!kgsl_mmu_use_cpu_map(private->pagetable->mmu))
entry->memdesc.flags &= ~KGSL_MEMFLAGS_USE_CPU_MAP;
switch (memtype) {
@@ -2092,7 +2088,7 @@
struct kgsl_mem_entry *entry = NULL;
int result;
- if (!can_use_cpu_map())
+ if (!kgsl_mmu_use_cpu_map(private->pagetable->mmu))
param->flags &= ~KGSL_MEMFLAGS_USE_CPU_MAP;
result = _gpumem_alloc(dev_priv, &entry, param->size, param->flags);
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index cb206ac..5cc0dff 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -19,6 +19,7 @@
#include "kgsl.h"
#include "kgsl_mmu.h"
+#include "kgsl_gpummu.h"
#include "kgsl_device.h"
#include "kgsl_sharedmem.h"
#include "kgsl_trace.h"
@@ -364,10 +365,9 @@
return gpummu_pt && pt_base && (gpummu_pt->base.gpuaddr == pt_base);
}
-void kgsl_gpummu_destroy_pagetable(void *mmu_specific_pt)
+void kgsl_gpummu_destroy_pagetable(struct kgsl_pagetable *pt)
{
- struct kgsl_gpummu_pt *gpummu_pt = (struct kgsl_gpummu_pt *)
- mmu_specific_pt;
+ struct kgsl_gpummu_pt *gpummu_pt = pt->priv;
kgsl_ptpool_free((struct kgsl_ptpool *)kgsl_driver.ptpool,
gpummu_pt->base.hostptr);
@@ -528,6 +528,11 @@
*/
int status = 0;
+ mmu->pt_base = KGSL_PAGETABLE_BASE;
+ mmu->pt_size = CONFIG_MSM_KGSL_PAGE_TABLE_SIZE;
+ mmu->pt_per_process = KGSL_MMU_USE_PER_PROCESS_PT;
+ mmu->use_cpu_map = false;
+
/* sub-client MMU lookups require address translation */
if ((mmu->config & ~0x1) > 0) {
/*make sure virtual address range is a multiple of 64Kb */
@@ -584,7 +589,7 @@
if (mmu->defaultpagetable == NULL)
mmu->defaultpagetable =
- kgsl_mmu_getpagetable(KGSL_MMU_GLOBAL_PT);
+ kgsl_mmu_getpagetable(mmu, KGSL_MMU_GLOBAL_PT);
/* Return error if the default pagetable doesn't exist */
if (mmu->defaultpagetable == NULL)
@@ -604,14 +609,14 @@
}
static int
-kgsl_gpummu_unmap(void *mmu_specific_pt,
+kgsl_gpummu_unmap(struct kgsl_pagetable *pt,
struct kgsl_memdesc *memdesc,
unsigned int *tlb_flags)
{
unsigned int numpages;
unsigned int pte, ptefirst, ptelast, superpte;
unsigned int range = kgsl_sg_size(memdesc->sg, memdesc->sglen);
- struct kgsl_gpummu_pt *gpummu_pt = mmu_specific_pt;
+ struct kgsl_gpummu_pt *gpummu_pt = pt->priv;
/* All GPU addresses as assigned are page aligned, but some
functions purturb the gpuaddr with an offset, so apply the
@@ -653,13 +658,13 @@
GSL_TLBFLUSH_FILTER_ISDIRTY((_p) / GSL_PT_SUPER_PTE))
static int
-kgsl_gpummu_map(void *mmu_specific_pt,
+kgsl_gpummu_map(struct kgsl_pagetable *pt,
struct kgsl_memdesc *memdesc,
unsigned int protflags,
unsigned int *tlb_flags)
{
unsigned int pte;
- struct kgsl_gpummu_pt *gpummu_pt = mmu_specific_pt;
+ struct kgsl_gpummu_pt *gpummu_pt = pt->priv;
struct scatterlist *s;
int flushtlb = 0;
int i;
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index e3cea88..f327c04 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -21,6 +21,7 @@
#include <mach/socinfo.h>
#include <mach/msm_iomap.h>
#include <mach/board.h>
+#include <mach/iommu_domains.h>
#include <stddef.h>
#include "kgsl.h"
@@ -603,9 +604,9 @@
*
* Return - void
*/
-static void kgsl_iommu_destroy_pagetable(void *mmu_specific_pt)
+static void kgsl_iommu_destroy_pagetable(struct kgsl_pagetable *pt)
{
- struct kgsl_iommu_pt *iommu_pt = mmu_specific_pt;
+ struct kgsl_iommu_pt *iommu_pt = pt->priv;
if (iommu_pt->domain)
iommu_domain_free(iommu_pt->domain);
kfree(iommu_pt);
@@ -620,8 +621,20 @@
*/
void *kgsl_iommu_create_pagetable(void)
{
+ int domain_num;
struct kgsl_iommu_pt *iommu_pt;
+ struct msm_iova_partition kgsl_partition = {
+ .start = 0,
+ .size = 0xFFFFFFFF,
+ };
+ struct msm_iova_layout kgsl_layout = {
+ .partitions = &kgsl_partition,
+ .npartitions = 1,
+ .client_name = "kgsl",
+ .domain_flags = 0,
+ };
+
iommu_pt = kzalloc(sizeof(struct kgsl_iommu_pt), GFP_KERNEL);
if (!iommu_pt) {
KGSL_CORE_ERR("kzalloc(%d) failed\n",
@@ -630,18 +643,17 @@
}
/* L2 redirect is not stable on IOMMU v1 */
if (msm_soc_version_supports_iommu_v0())
- iommu_pt->domain = iommu_domain_alloc(&platform_bus_type,
- MSM_IOMMU_DOMAIN_PT_CACHEABLE);
- else
- iommu_pt->domain = iommu_domain_alloc(&platform_bus_type,
- 0);
- if (!iommu_pt->domain) {
+ kgsl_layout.domain_flags = MSM_IOMMU_DOMAIN_PT_CACHEABLE;
+
+ domain_num = msm_register_domain(&kgsl_layout);
+ if (domain_num >= 0) {
+ iommu_pt->domain = msm_get_iommu_domain(domain_num);
+ iommu_set_fault_handler(iommu_pt->domain,
+ kgsl_iommu_fault_handler, NULL);
+ } else {
KGSL_CORE_ERR("Failed to create iommu domain\n");
kfree(iommu_pt);
return NULL;
- } else {
- iommu_set_fault_handler(iommu_pt->domain,
- kgsl_iommu_fault_handler, NULL);
}
return iommu_pt;
@@ -817,7 +829,7 @@
if (KGSL_DEVICE_3D0 != mmu->device->id ||
!msm_soc_version_supports_iommu_v0() ||
- !kgsl_mmu_is_perprocess() ||
+ !kgsl_mmu_is_perprocess(mmu) ||
iommu->sync_lock_vars)
return 0;
@@ -858,7 +870,7 @@
uint32_t page_offset = 0;
if (!msm_soc_version_supports_iommu_v0() ||
- !kgsl_mmu_is_perprocess())
+ !kgsl_mmu_is_perprocess(mmu))
return status;
/*
@@ -1256,6 +1268,32 @@
if (status)
goto done;
+ /* We presently do not support per-process for IOMMU-v1 */
+ mmu->pt_per_process = KGSL_MMU_USE_PER_PROCESS_PT &&
+ msm_soc_version_supports_iommu_v0();
+
+ /*
+ * For IOMMU per-process pagetables, the allocatable range
+ * and the kernel global range must both be outside
+ * the userspace address range. There is a 1Mb gap
+ * between these address ranges to make overrun
+ * detection easier.
+ * For the shared pagetable case use 2GB and because
+ * mirroring the CPU address space is not possible and
+ * we're better off with extra room.
+ */
+ if (mmu->pt_per_process) {
+ mmu->pt_base = PAGE_OFFSET;
+ mmu->pt_size = KGSL_IOMMU_GLOBAL_MEM_BASE
+ - kgsl_mmu_get_base_addr(mmu) - SZ_1M;
+ mmu->use_cpu_map = true;
+ } else {
+ mmu->pt_base = KGSL_PAGETABLE_BASE;
+ mmu->pt_size = SZ_2G;
+ mmu->use_cpu_map = false;
+ }
+
+
iommu->iommu_reg_list = kgsl_iommuv0_reg;
iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V0;
@@ -1309,7 +1347,8 @@
* switching on the 3D side for which a separate table is allocated */
if (!cpu_is_msm8960() && msm_soc_version_supports_iommu_v0()) {
mmu->priv_bank_table =
- kgsl_mmu_getpagetable(KGSL_MMU_PRIV_BANK_TABLE_NAME);
+ kgsl_mmu_getpagetable(mmu,
+ KGSL_MMU_PRIV_BANK_TABLE_NAME);
if (mmu->priv_bank_table == NULL) {
status = -ENOMEM;
goto err;
@@ -1318,7 +1357,7 @@
if (status)
goto err;
}
- mmu->defaultpagetable = kgsl_mmu_getpagetable(KGSL_MMU_GLOBAL_PT);
+ mmu->defaultpagetable = kgsl_mmu_getpagetable(mmu, KGSL_MMU_GLOBAL_PT);
/* Return error if the default pagetable doesn't exist */
if (mmu->defaultpagetable == NULL) {
status = -ENOMEM;
@@ -1522,13 +1561,13 @@
}
static int
-kgsl_iommu_unmap(void *mmu_specific_pt,
+kgsl_iommu_unmap(struct kgsl_pagetable *pt,
struct kgsl_memdesc *memdesc,
unsigned int *tlb_flags)
{
int ret;
unsigned int range = kgsl_sg_size(memdesc->sg, memdesc->sglen);
- struct kgsl_iommu_pt *iommu_pt = mmu_specific_pt;
+ struct kgsl_iommu_pt *iommu_pt = pt->priv;
/* All GPU addresses as assigned are page aligned, but some
functions purturb the gpuaddr with an offset, so apply the
@@ -1549,20 +1588,20 @@
* Flushing only required if per process pagetables are used. With
* global case, flushing will happen inside iommu_map function
*/
- if (!ret && kgsl_mmu_is_perprocess())
+ if (!ret && kgsl_mmu_is_perprocess(pt->mmu))
*tlb_flags = UINT_MAX;
return 0;
}
static int
-kgsl_iommu_map(void *mmu_specific_pt,
+kgsl_iommu_map(struct kgsl_pagetable *pt,
struct kgsl_memdesc *memdesc,
unsigned int protflags,
unsigned int *tlb_flags)
{
int ret;
unsigned int iommu_virt_addr;
- struct kgsl_iommu_pt *iommu_pt = mmu_specific_pt;
+ struct kgsl_iommu_pt *iommu_pt = pt->priv;
int size = kgsl_sg_size(memdesc->sg, memdesc->sglen);
BUG_ON(NULL == iommu_pt);
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index ccaceb3..4e95373 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -23,6 +23,7 @@
#include "kgsl.h"
#include "kgsl_mmu.h"
+#include "kgsl_gpummu.h"
#include "kgsl_device.h"
#include "kgsl_sharedmem.h"
#include "adreno.h"
@@ -103,7 +104,7 @@
if (pagetable->pool)
gen_pool_destroy(pagetable->pool);
- pagetable->pt_ops->mmu_destroy_pagetable(pagetable->priv);
+ pagetable->pt_ops->mmu_destroy_pagetable(pagetable);
kfree(pagetable);
}
@@ -193,7 +194,7 @@
if (pt) {
ret += snprintf(buf, PAGE_SIZE, "0x%x\n",
- kgsl_mmu_get_ptsize());
+ kgsl_mmu_get_ptsize(pt->mmu));
}
kgsl_put_pagetable(pt);
@@ -444,7 +445,8 @@
}
EXPORT_SYMBOL(kgsl_mh_intrcallback);
-static struct kgsl_pagetable *kgsl_mmu_createpagetableobject(
+static struct kgsl_pagetable *
+kgsl_mmu_createpagetableobject(struct kgsl_mmu *mmu,
unsigned int name)
{
int status = 0;
@@ -463,8 +465,8 @@
spin_lock_init(&pagetable->lock);
- ptsize = kgsl_mmu_get_ptsize();
-
+ ptsize = kgsl_mmu_get_ptsize(mmu);
+ pagetable->mmu = mmu;
pagetable->name = name;
pagetable->max_entries = KGSL_PAGETABLE_ENTRIES(ptsize);
pagetable->fault_addr = 0xFFFFFFFF;
@@ -497,7 +499,7 @@
goto err_kgsl_pool;
}
- if (gen_pool_add(pagetable->pool, kgsl_mmu_get_base_addr(),
+ if (gen_pool_add(pagetable->pool, kgsl_mmu_get_base_addr(mmu),
ptsize, -1)) {
KGSL_CORE_ERR("gen_pool_add failed\n");
goto err_pool;
@@ -526,7 +528,7 @@
return pagetable;
err_mmu_create:
- pagetable->pt_ops->mmu_destroy_pagetable(pagetable->priv);
+ pagetable->pt_ops->mmu_destroy_pagetable(pagetable);
err_pool:
gen_pool_destroy(pagetable->pool);
err_kgsl_pool:
@@ -538,20 +540,21 @@
return NULL;
}
-struct kgsl_pagetable *kgsl_mmu_getpagetable(unsigned long name)
+struct kgsl_pagetable *kgsl_mmu_getpagetable(struct kgsl_mmu *mmu,
+ unsigned long name)
{
struct kgsl_pagetable *pt;
if (KGSL_MMU_TYPE_NONE == kgsl_mmu_type)
return (void *)(-1);
- if (!kgsl_mmu_is_perprocess())
+ if (!kgsl_mmu_is_perprocess(mmu))
name = KGSL_MMU_GLOBAL_PT;
pt = kgsl_get_pagetable(name);
if (pt == NULL)
- pt = kgsl_mmu_createpagetableobject(name);
+ pt = kgsl_mmu_createpagetableobject(mmu, name);
return pt;
}
@@ -688,7 +691,7 @@
if (KGSL_MMU_TYPE_IOMMU != kgsl_mmu_get_mmutype())
spin_lock(&pagetable->lock);
- ret = pagetable->pt_ops->mmu_map(pagetable->priv, memdesc, protflags,
+ ret = pagetable->pt_ops->mmu_map(pagetable, memdesc, protflags,
&pagetable->tlb_flags);
if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype())
spin_lock(&pagetable->lock);
@@ -741,7 +744,7 @@
if (KGSL_MMU_TYPE_IOMMU != kgsl_mmu_get_mmutype())
spin_lock(&pagetable->lock);
- pagetable->pt_ops->mmu_unmap(pagetable->priv, memdesc,
+ pagetable->pt_ops->mmu_unmap(pagetable, memdesc,
&pagetable->tlb_flags);
/* If buffer is unmapped 0 fault addr */
@@ -894,15 +897,16 @@
}
EXPORT_SYMBOL(kgsl_mmu_set_mmutype);
-int kgsl_mmu_gpuaddr_in_range(unsigned int gpuaddr)
+int kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pt, unsigned int gpuaddr)
{
if (KGSL_MMU_TYPE_NONE == kgsl_mmu_type)
return 1;
- if (gpuaddr >= kgsl_mmu_get_base_addr() &&
- gpuaddr < kgsl_mmu_get_base_addr() + kgsl_mmu_get_ptsize())
+ if (gpuaddr >= kgsl_mmu_get_base_addr(pt->mmu) &&
+ gpuaddr < kgsl_mmu_get_base_addr(pt->mmu) +
+ kgsl_mmu_get_ptsize(pt->mmu))
return 1;
if (kgsl_mmu_get_mmutype() == KGSL_MMU_TYPE_IOMMU
- && kgsl_mmu_is_perprocess())
+ && kgsl_mmu_is_perprocess(pt->mmu))
return (gpuaddr > 0 && gpuaddr < TASK_SIZE);
return 0;
}
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 2d48e86..d7d9516 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -24,6 +24,13 @@
#define KGSL_MMU_ALIGN_MASK (~((1 << PAGE_SHIFT) - 1))
+/* defconfig option for disabling per process pagetables */
+#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
+#define KGSL_MMU_USE_PER_PROCESS_PT true
+#else
+#define KGSL_MMU_USE_PER_PROCESS_PT false
+#endif
+
/* Identifier for the global page table */
/* Per process page tables will probably pass in the thread group
as an identifier */
@@ -116,6 +123,7 @@
unsigned int tlb_flags;
unsigned int fault_addr;
void *priv;
+ struct kgsl_mmu *mmu;
};
struct kgsl_mmu;
@@ -160,15 +168,15 @@
};
struct kgsl_mmu_pt_ops {
- int (*mmu_map) (void *mmu_pt,
+ int (*mmu_map) (struct kgsl_pagetable *pt,
struct kgsl_memdesc *memdesc,
unsigned int protflags,
unsigned int *tlb_flags);
- int (*mmu_unmap) (void *mmu_pt,
+ int (*mmu_unmap) (struct kgsl_pagetable *pt,
struct kgsl_memdesc *memdesc,
unsigned int *tlb_flags);
void *(*mmu_create_pagetable) (void);
- void (*mmu_destroy_pagetable) (void *pt);
+ void (*mmu_destroy_pagetable) (struct kgsl_pagetable *);
};
#define KGSL_MMU_FLAGS_IOMMU_SYNC BIT(31)
@@ -187,14 +195,19 @@
const struct kgsl_mmu_ops *mmu_ops;
void *priv;
int fault;
+ unsigned long pt_base;
+ unsigned long pt_size;
+ bool pt_per_process;
+ bool use_cpu_map;
};
-#include "kgsl_gpummu.h"
-
extern struct kgsl_mmu_ops iommu_ops;
extern struct kgsl_mmu_pt_ops iommu_pt_ops;
+extern struct kgsl_mmu_ops gpummu_ops;
+extern struct kgsl_mmu_pt_ops gpummu_pt_ops;
-struct kgsl_pagetable *kgsl_mmu_getpagetable(unsigned long name);
+struct kgsl_pagetable *kgsl_mmu_getpagetable(struct kgsl_mmu *,
+ unsigned long name);
void kgsl_mmu_putpagetable(struct kgsl_pagetable *pagetable);
void kgsl_mh_start(struct kgsl_device *device);
void kgsl_mh_intrcallback(struct kgsl_device *device);
@@ -221,7 +234,7 @@
int kgsl_mmu_enabled(void);
void kgsl_mmu_set_mmutype(char *mmutype);
enum kgsl_mmutype kgsl_mmu_get_mmutype(void);
-int kgsl_mmu_gpuaddr_in_range(unsigned int gpuaddr);
+int kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pt, unsigned int gpuaddr);
/*
* Static inline functions of MMU that simply call the SMMU specific
@@ -335,75 +348,51 @@
/*
* kgsl_mmu_is_perprocess() - Runtime check for per-process
* pagetables.
+ * @mmu: the mmu
*
- * Returns non-zero if per-process pagetables are enabled,
- * 0 if not.
+ * Returns true if per-process pagetables are enabled,
+ * false if not.
*/
-#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
-static inline int kgsl_mmu_is_perprocess(void)
+static inline int kgsl_mmu_is_perprocess(struct kgsl_mmu *mmu)
{
+ return mmu->pt_per_process;
+}
- /* We presently do not support per-process for IOMMU-v1 */
- return (kgsl_mmu_get_mmutype() != KGSL_MMU_TYPE_IOMMU)
- || msm_soc_version_supports_iommu_v0();
-}
-#else
-static inline int kgsl_mmu_is_perprocess(void)
+/*
+ * kgsl_mmu_use_cpu_map() - Runtime check for matching the CPU
+ * address space on the GPU.
+ * @mmu: the mmu
+ *
+ * Returns true if supported false if not.
+ */
+static inline int kgsl_mmu_use_cpu_map(struct kgsl_mmu *mmu)
{
- return 0;
+ return mmu->pt_per_process;
}
-#endif
/*
* kgsl_mmu_base_addr() - Get gpu virtual address base.
+ * @mmu: the mmu
*
* Returns the start address of the allocatable gpu
* virtual address space. Other mappings that mirror
* the CPU address space are possible outside this range.
*/
-static inline unsigned int kgsl_mmu_get_base_addr(void)
+static inline unsigned int kgsl_mmu_get_base_addr(struct kgsl_mmu *mmu)
{
- if (KGSL_MMU_TYPE_GPU == kgsl_mmu_get_mmutype()
- || !kgsl_mmu_is_perprocess())
- return KGSL_PAGETABLE_BASE;
- /*
- * This is the start of the kernel address
- * space, so allocations from this range will
- * never conflict with userpace addresses
- */
- return PAGE_OFFSET;
+ return mmu->pt_base;
}
/*
* kgsl_mmu_get_ptsize() - Get gpu pagetable size
+ * @mmu: the mmu
*
* Returns the usable size of the gpu allocatable
* address space.
*/
-static inline unsigned int kgsl_mmu_get_ptsize(void)
+static inline unsigned int kgsl_mmu_get_ptsize(struct kgsl_mmu *mmu)
{
- /*
- * For IOMMU per-process pagetables, the allocatable range
- * and the kernel global range must both be outside
- * the userspace address range. There is a 1Mb gap
- * between these address ranges to make overrun
- * detection easier.
- * For the shared pagetable case use 2GB and because
- * mirroring the CPU address space is not possible and
- * we're better off with extra room.
- */
- enum kgsl_mmutype mmu_type = kgsl_mmu_get_mmutype();
-
- if (KGSL_MMU_TYPE_GPU == mmu_type)
- return CONFIG_MSM_KGSL_PAGE_TABLE_SIZE;
- else if (KGSL_MMU_TYPE_IOMMU == mmu_type) {
- if (kgsl_mmu_is_perprocess())
- return KGSL_IOMMU_GLOBAL_MEM_BASE
- - kgsl_mmu_get_base_addr() - SZ_1M;
- else
- return SZ_2G;
- }
- return 0;
+ return mmu->pt_size;
}
static inline int kgsl_mmu_sync_lock(struct kgsl_mmu *mmu,
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/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
index ecd4bbb..60c2da3 100644
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.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
@@ -212,7 +212,7 @@
bool descending = 1;
uint32_t i = 0;
- if ((pts == NULL) || (output == NULL))
+ if (pts == NULL)
return -EINVAL;
/* Check if table is descending or ascending */
@@ -258,7 +258,7 @@
bool descending = 1;
uint32_t i = 0;
- if ((pts == NULL) || (output == NULL))
+ if (pts == NULL)
return -EINVAL;
/* Check if table is descending or ascending */
@@ -367,7 +367,42 @@
}
EXPORT_SYMBOL_GPL(qpnp_adc_scale_pmic_therm);
-/* Scales the ADC code to 0.001 degrees C using the map
+int32_t qpnp_adc_scale_millidegc_pmic_voltage_thr(
+ struct qpnp_adc_tm_btm_param *param,
+ uint32_t *low_threshold, uint32_t *high_threshold)
+{
+ struct qpnp_vadc_linear_graph btm_param;
+ int64_t low_output = 0, high_output = 0;
+ int rc = 0;
+
+ rc = qpnp_get_vadc_gain_and_offset(&btm_param, CALIB_ABSOLUTE);
+ if (rc < 0) {
+ pr_err("Could not acquire gain and offset\n");
+ return rc;
+ }
+
+ /* Convert to Kelvin and account for voltage to be written as 2mV/K */
+ low_output = (param->low_temp + KELVINMIL_DEGMIL) * 2;
+ /* Convert to voltage threshold */
+ low_output *= btm_param.dy;
+ do_div(low_output, btm_param.adc_vref);
+ low_output += btm_param.adc_gnd;
+
+ /* Convert to Kelvin and account for voltage to be written as 2mV/K */
+ high_output = (param->high_temp + KELVINMIL_DEGMIL) * 2;
+ /* Convert to voltage threshold */
+ high_output *= btm_param.dy;
+ do_div(high_output, btm_param.adc_vref);
+ high_output += btm_param.adc_gnd;
+
+ *low_threshold = low_output;
+ *high_threshold = high_output;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qpnp_adc_scale_millidegc_pmic_voltage_thr);
+
+/* Scales the ADC code to degC using the mapping
* table for the XO thermistor.
*/
int32_t qpnp_adc_tdkntcg_therm(int32_t adc_code,
@@ -577,7 +612,7 @@
}
EXPORT_SYMBOL_GPL(qpnp_adc_scale_default);
-int32_t qpnp_adc_usb_scaler(struct qpnp_adc_tm_usbid_param *param,
+int32_t qpnp_adc_usb_scaler(struct qpnp_adc_tm_btm_param *param,
uint32_t *low_threshold, uint32_t *high_threshold)
{
struct qpnp_vadc_linear_graph usb_param;
@@ -592,46 +627,81 @@
do_div(*high_threshold, usb_param.adc_vref);
*high_threshold += usb_param.adc_gnd;
+ pr_debug("high_volt:%d, low_volt:%d\n", param->high_thr,
+ param->low_thr);
return 0;
}
EXPORT_SYMBOL_GPL(qpnp_adc_usb_scaler);
+int32_t qpnp_adc_vbatt_rscaler(struct qpnp_adc_tm_btm_param *param,
+ uint32_t *low_threshold, uint32_t *high_threshold)
+{
+ struct qpnp_vadc_linear_graph vbatt_param;
+
+ qpnp_get_vadc_gain_and_offset(&vbatt_param, CALIB_ABSOLUTE);
+
+ *low_threshold = param->low_thr * vbatt_param.dy;
+ do_div(*low_threshold, vbatt_param.adc_vref);
+ *low_threshold += vbatt_param.adc_gnd;
+
+ *high_threshold = param->high_thr * vbatt_param.dy;
+ do_div(*high_threshold, vbatt_param.adc_vref);
+ *high_threshold += vbatt_param.adc_gnd;
+
+ pr_debug("high_volt:%d, low_volt:%d\n", param->high_thr,
+ param->low_thr);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qpnp_adc_vbatt_rscaler);
+
int32_t qpnp_adc_btm_scaler(struct qpnp_adc_tm_btm_param *param,
uint32_t *low_threshold, uint32_t *high_threshold)
{
struct qpnp_vadc_linear_graph btm_param;
- int64_t *low_output = 0, *high_output = 0;
+ int64_t low_output = 0, high_output = 0;
int rc = 0;
qpnp_get_vadc_gain_and_offset(&btm_param, CALIB_RATIOMETRIC);
- rc = qpnp_adc_map_temp_voltage(
+ pr_debug("warm_temp:%d and cool_temp:%d\n", param->high_temp,
+ param->low_temp);
+ rc = qpnp_adc_map_voltage_temp(
adcmap_btm_threshold,
ARRAY_SIZE(adcmap_btm_threshold),
(param->low_temp),
- low_output);
- if (rc)
+ &low_output);
+ if (rc) {
+ pr_debug("low_temp mapping failed with %d\n", rc);
return rc;
+ }
- *low_output *= btm_param.dy;
- do_div(*low_output, btm_param.adc_vref);
- *low_output += btm_param.adc_gnd;
+ pr_debug("low_output:%lld\n", low_output);
+ low_output *= btm_param.dy;
+ do_div(low_output, btm_param.adc_vref);
+ low_output += btm_param.adc_gnd;
- rc = qpnp_adc_map_temp_voltage(
+ rc = qpnp_adc_map_voltage_temp(
adcmap_btm_threshold,
ARRAY_SIZE(adcmap_btm_threshold),
(param->high_temp),
- high_output);
- if (rc)
+ &high_output);
+ if (rc) {
+ pr_debug("high temp mapping failed with %d\n", rc);
return rc;
+ }
- *high_output *= btm_param.dy;
- do_div(*high_output, btm_param.adc_vref);
- *high_output += btm_param.adc_gnd;
+ pr_debug("high_output:%lld\n", high_output);
+ high_output *= btm_param.dy;
+ do_div(high_output, btm_param.adc_vref);
+ high_output += btm_param.adc_gnd;
- low_threshold = (uint32_t *) low_output;
- high_threshold = (uint32_t *) high_output;
+ /* btm low temperature correspondes to high voltage threshold */
+ *low_threshold = high_output;
+ /* btm high temperature correspondes to low voltage threshold */
+ *high_threshold = low_output;
+ pr_debug("high_volt:%d, low_volt:%d\n", *high_threshold,
+ *low_threshold);
return 0;
}
EXPORT_SYMBOL_GPL(qpnp_adc_btm_scaler);
diff --git a/drivers/iommu/msm_iommu-v0.c b/drivers/iommu/msm_iommu-v0.c
index 6bf0220..de35f9a 100644
--- a/drivers/iommu/msm_iommu-v0.c
+++ b/drivers/iommu/msm_iommu-v0.c
@@ -29,6 +29,7 @@
#include <mach/iommu_perfmon.h>
#include <mach/iommu_hw-v0.h>
+#include <mach/msm_iommu_priv.h>
#include <mach/iommu.h>
#include <mach/msm_smsm.h>
@@ -131,12 +132,6 @@
return msm_iommu_remote_lock.lock;
}
-struct msm_priv {
- unsigned long *pgtable;
- int redirect;
- struct list_head list_attached;
-};
-
static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
{
int ret;
@@ -198,7 +193,7 @@
static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va)
{
- struct msm_priv *priv = domain->priv;
+ struct msm_iommu_priv *priv = domain->priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
int ret = 0;
@@ -235,7 +230,7 @@
static int __flush_iotlb(struct iommu_domain *domain)
{
- struct msm_priv *priv = domain->priv;
+ struct msm_iommu_priv *priv = domain->priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
int ret = 0;
@@ -396,26 +391,27 @@
static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
{
- struct msm_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ struct msm_iommu_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
goto fail_nomem;
INIT_LIST_HEAD(&priv->list_attached);
- priv->pgtable = (unsigned long *)__get_free_pages(GFP_KERNEL,
+ priv->pt.fl_table = (unsigned long *)__get_free_pages(GFP_KERNEL,
get_order(SZ_16K));
- if (!priv->pgtable)
+ if (!priv->pt.fl_table)
goto fail_nomem;
#ifdef CONFIG_IOMMU_PGTABLES_L2
- priv->redirect = flags & MSM_IOMMU_DOMAIN_PT_CACHEABLE;
+ priv->pt.redirect = flags & MSM_IOMMU_DOMAIN_PT_CACHEABLE;
#endif
- memset(priv->pgtable, 0, SZ_16K);
+ memset(priv->pt.fl_table, 0, SZ_16K);
domain->priv = priv;
- clean_pte(priv->pgtable, priv->pgtable + NUM_FL_PTE, priv->redirect);
+ clean_pte(priv->pt.fl_table, priv->pt.fl_table + NUM_FL_PTE,
+ priv->pt.redirect);
return 0;
@@ -426,7 +422,7 @@
static void msm_iommu_domain_destroy(struct iommu_domain *domain)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
unsigned long *fl_table;
int i;
@@ -435,15 +431,15 @@
domain->priv = NULL;
if (priv) {
- fl_table = priv->pgtable;
+ fl_table = priv->pt.fl_table;
for (i = 0; i < NUM_FL_PTE; i++)
if ((fl_table[i] & 0x03) == FL_TYPE_TABLE)
free_page((unsigned long) __va(((fl_table[i]) &
FL_BASE_MASK)));
- free_pages((unsigned long)priv->pgtable, get_order(SZ_16K));
- priv->pgtable = NULL;
+ free_pages((unsigned long)priv->pt.fl_table, get_order(SZ_16K));
+ priv->pt.fl_table = NULL;
}
kfree(priv);
@@ -452,7 +448,7 @@
static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
struct msm_iommu_ctx_drvdata *tmp_drvdata;
@@ -497,7 +493,7 @@
__program_context(iommu_drvdata->base, iommu_drvdata->glb_base,
ctx_drvdata->num, iommu_drvdata->ncb,
- __pa(priv->pgtable), priv->redirect,
+ __pa(priv->pt.fl_table), priv->pt.redirect,
iommu_drvdata->ttbr_split);
__disable_clocks(iommu_drvdata);
@@ -517,7 +513,7 @@
static void msm_iommu_detach_dev(struct iommu_domain *domain,
struct device *dev)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
int ret;
@@ -605,7 +601,7 @@
return pgprot;
}
-static unsigned long *make_second_level(struct msm_priv *priv,
+static unsigned long *make_second_level(struct msm_iommu_priv *priv,
unsigned long *fl_pte)
{
unsigned long *sl;
@@ -617,12 +613,12 @@
goto fail;
}
memset(sl, 0, SZ_4K);
- clean_pte(sl, sl + NUM_SL_PTE, priv->redirect);
+ clean_pte(sl, sl + NUM_SL_PTE, priv->pt.redirect);
*fl_pte = ((((int)__pa(sl)) & FL_BASE_MASK) | \
FL_TYPE_TABLE);
- clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+ clean_pte(fl_pte, fl_pte + 1, priv->pt.redirect);
fail:
return sl;
}
@@ -694,7 +690,7 @@
static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
phys_addr_t pa, size_t len, int prot)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
unsigned long *fl_table;
unsigned long *fl_pte;
unsigned long fl_offset;
@@ -712,7 +708,7 @@
goto fail;
}
- fl_table = priv->pgtable;
+ fl_table = priv->pt.fl_table;
if (len != SZ_16M && len != SZ_1M &&
len != SZ_64K && len != SZ_4K) {
@@ -741,14 +737,14 @@
ret = fl_16m(fl_pte, pa, pgprot);
if (ret)
goto fail;
- clean_pte(fl_pte, fl_pte + 16, priv->redirect);
+ clean_pte(fl_pte, fl_pte + 16, priv->pt.redirect);
}
if (len == SZ_1M) {
ret = fl_1m(fl_pte, pa, pgprot);
if (ret)
goto fail;
- clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+ clean_pte(fl_pte, fl_pte + 1, priv->pt.redirect);
}
/* Need a 2nd level table */
@@ -776,14 +772,14 @@
if (ret)
goto fail;
- clean_pte(sl_pte, sl_pte + 1, priv->redirect);
+ clean_pte(sl_pte, sl_pte + 1, priv->pt.redirect);
}
if (len == SZ_64K) {
ret = sl_64k(sl_pte, pa, pgprot);
if (ret)
goto fail;
- clean_pte(sl_pte, sl_pte + 16, priv->redirect);
+ clean_pte(sl_pte, sl_pte + 16, priv->pt.redirect);
}
ret = __flush_iotlb_va(domain, va);
@@ -795,7 +791,7 @@
static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
size_t len)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
unsigned long *fl_table;
unsigned long *fl_pte;
unsigned long fl_offset;
@@ -811,7 +807,7 @@
if (!priv)
goto fail;
- fl_table = priv->pgtable;
+ fl_table = priv->pt.fl_table;
if (len != SZ_16M && len != SZ_1M &&
len != SZ_64K && len != SZ_4K) {
@@ -837,13 +833,13 @@
for (i = 0; i < 16; i++)
*(fl_pte+i) = 0;
- clean_pte(fl_pte, fl_pte + 16, priv->redirect);
+ clean_pte(fl_pte, fl_pte + 16, priv->pt.redirect);
}
if (len == SZ_1M) {
*fl_pte = 0;
- clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+ clean_pte(fl_pte, fl_pte + 1, priv->pt.redirect);
}
sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
@@ -854,13 +850,13 @@
for (i = 0; i < 16; i++)
*(sl_pte+i) = 0;
- clean_pte(sl_pte, sl_pte + 16, priv->redirect);
+ clean_pte(sl_pte, sl_pte + 16, priv->pt.redirect);
}
if (len == SZ_4K) {
*sl_pte = 0;
- clean_pte(sl_pte, sl_pte + 1, priv->redirect);
+ clean_pte(sl_pte, sl_pte + 1, priv->pt.redirect);
}
if (len == SZ_4K || len == SZ_64K) {
@@ -873,7 +869,7 @@
free_page((unsigned long)sl_table);
*fl_pte = 0;
- clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+ clean_pte(fl_pte, fl_pte + 1, priv->pt.redirect);
}
}
@@ -969,7 +965,7 @@
unsigned long sl_offset, sl_start;
unsigned int chunk_size, chunk_offset = 0;
int ret = 0;
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
unsigned int pgprot4k, pgprot64k, pgprot1m, pgprot16m;
mutex_lock(&msm_iommu_lock);
@@ -977,7 +973,7 @@
BUG_ON(len & (SZ_4K - 1));
priv = domain->priv;
- fl_table = priv->pgtable;
+ fl_table = priv->pt.fl_table;
pgprot4k = __get_pgprot(prot, SZ_4K);
pgprot64k = __get_pgprot(prot, SZ_64K);
@@ -1013,13 +1009,15 @@
ret = fl_16m(fl_pte, pa, pgprot16m);
if (ret)
goto fail;
- clean_pte(fl_pte, fl_pte + 16, priv->redirect);
+ clean_pte(fl_pte, fl_pte + 16,
+ priv->pt.redirect);
fl_pte += 16;
} else if (chunk_size == SZ_1M) {
ret = fl_1m(fl_pte, pa, pgprot1m);
if (ret)
goto fail;
- clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+ clean_pte(fl_pte, fl_pte + 1,
+ priv->pt.redirect);
fl_pte++;
}
@@ -1101,7 +1099,7 @@
}
clean_pte(sl_table + sl_start, sl_table + sl_offset,
- priv->redirect);
+ priv->pt.redirect);
fl_pte++;
sl_offset = 0;
@@ -1123,14 +1121,14 @@
unsigned long *sl_table;
unsigned long sl_start, sl_end;
int used, i;
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
mutex_lock(&msm_iommu_lock);
BUG_ON(len & (SZ_4K - 1));
priv = domain->priv;
- fl_table = priv->pgtable;
+ fl_table = priv->pt.fl_table;
fl_offset = FL_OFFSET(va); /* Upper 12 bits */
fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */
@@ -1146,7 +1144,7 @@
memset(sl_table + sl_start, 0, (sl_end - sl_start) * 4);
clean_pte(sl_table + sl_start, sl_table + sl_end,
- priv->redirect);
+ priv->pt.redirect);
offset += (sl_end - sl_start) * SZ_4K;
va += (sl_end - sl_start) * SZ_4K;
@@ -1171,13 +1169,14 @@
free_page((unsigned long)sl_table);
*fl_pte = 0;
- clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+ clean_pte(fl_pte, fl_pte + 1,
+ priv->pt.redirect);
}
sl_start = 0;
} else {
*fl_pte = 0;
- clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+ clean_pte(fl_pte, fl_pte + 1, priv->pt.redirect);
va += SZ_1M;
offset += SZ_1M;
sl_start = 0;
@@ -1193,7 +1192,7 @@
static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
unsigned long va)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
unsigned int par;
@@ -1339,8 +1338,8 @@
static phys_addr_t msm_iommu_get_pt_base_addr(struct iommu_domain *domain)
{
- struct msm_priv *priv = domain->priv;
- return __pa(priv->pgtable);
+ struct msm_iommu_priv *priv = domain->priv;
+ return __pa(priv->pt.fl_table);
}
static struct iommu_ops msm_iommu_ops = {
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index 24d2854..f552474 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -30,6 +30,7 @@
#include <mach/iommu_hw-v1.h>
#include <mach/iommu.h>
+#include <mach/msm_iommu_priv.h>
#include <mach/iommu_perfmon.h>
#include "msm_iommu_pagetable.h"
@@ -38,11 +39,6 @@
static DEFINE_MUTEX(msm_iommu_lock);
-struct msm_priv {
- struct iommu_pt pt;
- struct list_head list_attached;
-};
-
static int __enable_regulators(struct msm_iommu_drvdata *drvdata)
{
int ret = regulator_enable(drvdata->gdsc);
@@ -198,7 +194,7 @@
static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va)
{
- struct msm_priv *priv = domain->priv;
+ struct msm_iommu_priv *priv = domain->priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
int ret = 0;
@@ -226,7 +222,7 @@
static int __flush_iotlb(struct iommu_domain *domain)
{
- struct msm_priv *priv = domain->priv;
+ struct msm_iommu_priv *priv = domain->priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
int ret = 0;
@@ -335,7 +331,7 @@
static void msm_iommu_assign_ASID(const struct msm_iommu_drvdata *iommu_drvdata,
struct msm_iommu_ctx_drvdata *curr_ctx,
- struct msm_priv *priv)
+ struct msm_iommu_priv *priv)
{
unsigned int found = 0;
void __iomem *base = iommu_drvdata->base;
@@ -374,7 +370,7 @@
static void __program_context(struct msm_iommu_drvdata *iommu_drvdata,
struct msm_iommu_ctx_drvdata *ctx_drvdata,
- struct msm_priv *priv, bool is_secure)
+ struct msm_iommu_priv *priv, bool is_secure)
{
unsigned int prrr, nmrr;
unsigned int pn;
@@ -469,7 +465,7 @@
static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -493,7 +489,7 @@
static void msm_iommu_domain_destroy(struct iommu_domain *domain)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
mutex_lock(&msm_iommu_lock);
priv = domain->priv;
@@ -508,7 +504,7 @@
static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
struct msm_iommu_ctx_drvdata *tmp_drvdata;
@@ -596,7 +592,7 @@
static void msm_iommu_detach_dev(struct iommu_domain *domain,
struct device *dev)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
int ret;
@@ -649,7 +645,7 @@
static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
phys_addr_t pa, size_t len, int prot)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
int ret = 0;
mutex_lock(&msm_iommu_lock);
@@ -673,7 +669,7 @@
static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
size_t len)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
int ret = -ENODEV;
mutex_lock(&msm_iommu_lock);
@@ -700,7 +696,7 @@
int prot)
{
int ret;
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
mutex_lock(&msm_iommu_lock);
@@ -724,7 +720,7 @@
static int msm_iommu_unmap_range(struct iommu_domain *domain, unsigned int va,
unsigned int len)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
mutex_lock(&msm_iommu_lock);
@@ -739,7 +735,7 @@
static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
unsigned long va)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
unsigned int par;
@@ -876,7 +872,7 @@
static phys_addr_t msm_iommu_get_pt_base_addr(struct iommu_domain *domain)
{
- struct msm_priv *priv = domain->priv;
+ struct msm_iommu_priv *priv = domain->priv;
return __pa(priv->pt.fl_table);
}
diff --git a/drivers/iommu/msm_iommu_pagetable.c b/drivers/iommu/msm_iommu_pagetable.c
index b32bd26..1472293 100644
--- a/drivers/iommu/msm_iommu_pagetable.c
+++ b/drivers/iommu/msm_iommu_pagetable.c
@@ -20,6 +20,7 @@
#include <asm/cacheflush.h>
#include <mach/iommu.h>
+#include <mach/msm_iommu_priv.h>
#include "msm_iommu_pagetable.h"
/* Sharability attributes of MSM IOMMU mappings */
@@ -41,7 +42,7 @@
dmac_flush_range(start, end);
}
-int msm_iommu_pagetable_alloc(struct iommu_pt *pt)
+int msm_iommu_pagetable_alloc(struct msm_iommu_pt *pt)
{
pt->fl_table = (unsigned long *)__get_free_pages(GFP_KERNEL,
get_order(SZ_16K));
@@ -54,7 +55,7 @@
return 0;
}
-void msm_iommu_pagetable_free(struct iommu_pt *pt)
+void msm_iommu_pagetable_free(struct msm_iommu_pt *pt)
{
unsigned long *fl_table;
int i;
@@ -110,7 +111,7 @@
return pgprot;
}
-static unsigned long *make_second_level(struct iommu_pt *pt,
+static unsigned long *make_second_level(struct msm_iommu_pt *pt,
unsigned long *fl_pte)
{
unsigned long *sl;
@@ -194,7 +195,7 @@
return ret;
}
-int msm_iommu_pagetable_map(struct iommu_pt *pt, unsigned long va,
+int msm_iommu_pagetable_map(struct msm_iommu_pt *pt, unsigned long va,
phys_addr_t pa, size_t len, int prot)
{
unsigned long *fl_pte;
@@ -279,7 +280,7 @@
return ret;
}
-size_t msm_iommu_pagetable_unmap(struct iommu_pt *pt, unsigned long va,
+size_t msm_iommu_pagetable_unmap(struct msm_iommu_pt *pt, unsigned long va,
size_t len)
{
unsigned long *fl_pte;
@@ -377,7 +378,7 @@
&& (len >= align);
}
-int msm_iommu_pagetable_map_range(struct iommu_pt *pt, unsigned int va,
+int msm_iommu_pagetable_map_range(struct msm_iommu_pt *pt, unsigned int va,
struct scatterlist *sg, unsigned int len, int prot)
{
phys_addr_t pa;
@@ -518,7 +519,7 @@
return ret;
}
-void msm_iommu_pagetable_unmap_range(struct iommu_pt *pt, unsigned int va,
+void msm_iommu_pagetable_unmap_range(struct msm_iommu_pt *pt, unsigned int va,
unsigned int len)
{
unsigned int offset = 0;
diff --git a/drivers/iommu/msm_iommu_pagetable.h b/drivers/iommu/msm_iommu_pagetable.h
index 3266681..7513aa5 100644
--- a/drivers/iommu/msm_iommu_pagetable.h
+++ b/drivers/iommu/msm_iommu_pagetable.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -71,20 +71,17 @@
#define RCP15_PRRR(reg) MRC(reg, p15, 0, c10, c2, 0)
#define RCP15_NMRR(reg) MRC(reg, p15, 0, c10, c2, 1)
-struct iommu_pt {
- unsigned long *fl_table;
- int redirect;
-};
+struct iommu_pt;
void msm_iommu_pagetable_init(void);
-int msm_iommu_pagetable_alloc(struct iommu_pt *pt);
-void msm_iommu_pagetable_free(struct iommu_pt *pt);
-int msm_iommu_pagetable_map(struct iommu_pt *pt, unsigned long va,
+int msm_iommu_pagetable_alloc(struct msm_iommu_pt *pt);
+void msm_iommu_pagetable_free(struct msm_iommu_pt *pt);
+int msm_iommu_pagetable_map(struct msm_iommu_pt *pt, unsigned long va,
phys_addr_t pa, size_t len, int prot);
-size_t msm_iommu_pagetable_unmap(struct iommu_pt *pt, unsigned long va,
+size_t msm_iommu_pagetable_unmap(struct msm_iommu_pt *pt, unsigned long va,
size_t len);
-int msm_iommu_pagetable_map_range(struct iommu_pt *pt, unsigned int va,
+int msm_iommu_pagetable_map_range(struct msm_iommu_pt *pt, unsigned int va,
struct scatterlist *sg, unsigned int len, int prot);
-void msm_iommu_pagetable_unmap_range(struct iommu_pt *pt, unsigned int va,
+void msm_iommu_pagetable_unmap_range(struct msm_iommu_pt *pt, unsigned int va,
unsigned int len);
#endif
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index 44146a4..5ca6fd9 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -31,6 +31,7 @@
#include <mach/iommu_perfmon.h>
#include <mach/iommu_hw-v1.h>
+#include <mach/msm_iommu_priv.h>
#include <mach/iommu.h>
#include <mach/scm.h>
@@ -45,10 +46,6 @@
static DEFINE_MUTEX(msm_iommu_lock);
-struct msm_priv {
- struct list_head list_attached;
-};
-
struct msm_scm_paddr_list {
unsigned int list;
unsigned int list_size;
@@ -298,7 +295,7 @@
static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -311,7 +308,7 @@
static void msm_iommu_domain_destroy(struct iommu_domain *domain)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
mutex_lock(&msm_iommu_lock);
priv = domain->priv;
@@ -323,7 +320,7 @@
static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
{
- struct msm_priv *priv;
+ struct msm_iommu_priv *priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
struct msm_iommu_ctx_drvdata *tmp_drvdata;
@@ -424,7 +421,7 @@
struct msm_iommu_drvdata **iommu_drvdata,
struct msm_iommu_ctx_drvdata **ctx_drvdata)
{
- struct msm_priv *priv = domain->priv;
+ struct msm_iommu_priv *priv = domain->priv;
struct msm_iommu_ctx_drvdata *ctx;
list_for_each_entry(ctx, &priv->list_attached, attached_elm) {
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index 9e0a147..202edc0 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -142,6 +142,7 @@
#define RGB_LED_ENABLE_MASK 0xE0
#define RGB_LED_SRC_MASK 0x03
#define QPNP_LED_PWM_FLAGS (PM_PWM_LUT_LOOP | PM_PWM_LUT_RAMP_UP)
+#define QPNP_LUT_RAMP_STEP_DEFAULT 255
#define PWM_LUT_MAX_SIZE 63
#define RGB_LED_DISABLE 0x00
@@ -957,7 +958,7 @@
return -EINVAL;
}
rc = pwm_lut_config(led->rgb_cfg->pwm_dev,
- led->rgb_cfg->pwm_period_us,
+ PM_PWM_PERIOD_MIN, /* ignored by hardware */
led->rgb_cfg->duty_cycles->duty_pcts,
led->rgb_cfg->lut_params);
if (rc < 0) {
@@ -1227,11 +1228,13 @@
else
return rc;
- rc = of_property_read_u32(node, "qcom,pwm-us", &val);
- if (!rc)
- led->rgb_cfg->pwm_period_us = val;
- else
- return rc;
+ if (led->rgb_cfg->mode == RGB_MODE_PWM) {
+ rc = of_property_read_u32(node, "qcom,pwm-us", &val);
+ if (!rc)
+ led->rgb_cfg->pwm_period_us = val;
+ else
+ return rc;
+ }
if (led->rgb_cfg->mode == RGB_MODE_LPG) {
led->rgb_cfg->duty_cycles =
@@ -1243,12 +1246,6 @@
return -ENOMEM;
}
- rc = of_property_read_u32(node, "qcom,duty-ms", &val);
- if (!rc)
- led->rgb_cfg->duty_cycles->duty_ms = (u8) val;
- else
- return rc;
-
prop = of_find_property(node, "qcom,duty-pcts",
&led->rgb_cfg->duty_cycles->num_duty_pcts);
if (!prop) {
@@ -1294,12 +1291,37 @@
} else
return rc;
+ led->rgb_cfg->lut_params.lut_pause_hi = 0;
+ rc = of_property_read_u32(node, "qcom,pause-hi", &val);
+ if (!rc)
+ led->rgb_cfg->lut_params.lut_pause_hi = (u8) val;
+ else if (rc != -EINVAL)
+ return rc;
+
+ led->rgb_cfg->lut_params.lut_pause_lo = 0;
+ rc = of_property_read_u32(node, "qcom,pause-lo", &val);
+ if (!rc)
+ led->rgb_cfg->lut_params.lut_pause_lo = (u8) val;
+ else if (rc != -EINVAL)
+ return rc;
+
+ led->rgb_cfg->lut_params.ramp_step_ms =
+ QPNP_LUT_RAMP_STEP_DEFAULT;
+ rc = of_property_read_u32(node, "qcom,ramp-step-ms", &val);
+ if (!rc)
+ led->rgb_cfg->lut_params.ramp_step_ms = (u8) val;
+ else if (rc != -EINVAL)
+ return rc;
+
+ led->rgb_cfg->lut_params.flags = QPNP_LED_PWM_FLAGS;
+ rc = of_property_read_u32(node, "qcom,lut-flags", &val);
+ if (!rc)
+ led->rgb_cfg->lut_params.flags = (u8) val;
+ else if (rc != -EINVAL)
+ return rc;
+
led->rgb_cfg->lut_params.idx_len =
led->rgb_cfg->duty_cycles->num_duty_pcts;
- led->rgb_cfg->lut_params.lut_pause_hi = 0;
- led->rgb_cfg->lut_params.lut_pause_lo = 0;
- led->rgb_cfg->lut_params.ramp_step_ms = 255;
- led->rgb_cfg->lut_params.flags = QPNP_LED_PWM_FLAGS;
}
return 0;
diff --git a/drivers/media/platform/msm/camera_v1/msm_v4l2_video.c b/drivers/media/platform/msm/camera_v1/msm_v4l2_video.c
index 96f968c..1849bf6 100644
--- a/drivers/media/platform/msm/camera_v1/msm_v4l2_video.c
+++ b/drivers/media/platform/msm/camera_v1/msm_v4l2_video.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
@@ -104,13 +104,22 @@
mdp_format = MDP_RGB_888;
break;
case V4L2_PIX_FMT_NV12:
- mdp_format = MDP_Y_CRCB_H2V2;
- break;
- case V4L2_PIX_FMT_NV21:
mdp_format = MDP_Y_CBCR_H2V2;
break;
+ case V4L2_PIX_FMT_NV21:
+ mdp_format = MDP_Y_CRCB_H2V2;
+ break;
case V4L2_PIX_FMT_YUV420:
- mdp_format = MDP_Y_CR_CB_H2V2;
+ mdp_format = MDP_Y_CB_CR_H2V2;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ mdp_format = MDP_CBYCRY_H2V1;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ mdp_format = MDP_YCBYCR_H2V1;
+ break;
+ case V4L2_PIX_FMT_YVU420:
+ mdp_format = MDP_Y_CR_CB_GH2V2;
break;
default:
pr_err("%s:Unrecognized format %u\n", __func__, pixelformat);
diff --git a/drivers/media/platform/msm/camera_v2/Kconfig b/drivers/media/platform/msm/camera_v2/Kconfig
index e4777e6..269e538 100644
--- a/drivers/media/platform/msm/camera_v2/Kconfig
+++ b/drivers/media/platform/msm/camera_v2/Kconfig
@@ -100,6 +100,15 @@
hfr video at 60, 90 and 120 fps. This sensor driver does
not support auto focus.
+config OV9724
+ bool "Sensor OV9724 (BAYER 2M)"
+ depends on MSMB_CAMERA
+ ---help---
+ OmniVision 2 MP Bayer Sensor, supports 2 mipi lanes,
+ preview and snapshot config at 1280*720 at 30 fps,
+ hfr video at 60, 90 and 120 fps. This sensor driver does
+ not support auto focus.
+
config MT9M114
bool "Sensor MT9M114 (YUV 1.26MP)"
depends on MSMB_CAMERA
@@ -109,6 +118,15 @@
1280 * 270. It does not support auto focus. It supports
few special effects like saturation.
+config OV8825
+ bool "OmniVision OV8825 (BAYER 8MP)"
+ depends on MSMB_CAMERA
+ ---help---
+ OmniVision 8 MP Bayer Sensor with auto focus.uses
+ 2 mipi lanes, preview config = 1632*1224 30 fps,
+ snapshot config = 3264 * 2448 at 18 fps.
+ 2 lanes max fps is 18, 4 lanes max fps is 24.
+
config MSM_V4L2_VIDEO_OVERLAY_DEVICE
tristate "Qualcomm MSM V4l2 video overlay device"
---help---
@@ -119,7 +137,7 @@
config MSMB_JPEG
tristate "Qualcomm MSM Jpeg Encoder Engine support"
- depends on MSMB_CAMERA && ARCH_MSM8974
+ depends on MSMB_CAMERA && (ARCH_MSM8974 || ARCH_MSM8226)
---help---
Enable support for Jpeg Encoder/Decoder
Engine for 8974.
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
index 6b27048..32aa4ef 100644
--- a/drivers/media/platform/msm/camera_v2/camera/camera.c
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -42,7 +42,7 @@
};
static void camera_pack_event(struct file *filep, int evt_id,
- int command, struct v4l2_event *event)
+ int command, int value, struct v4l2_event *event)
{
struct msm_v4l2_event_data *event_data =
(struct msm_v4l2_event_data *)&event->u.data[0];
@@ -55,6 +55,7 @@
event_data->command = command;
event_data->session_id = pvdev->vdev->num;
event_data->stream_id = sp->stream_id;
+ event_data->arg_value = value;
}
static int camera_check_event_status(struct v4l2_event *event)
@@ -76,7 +77,7 @@
/* can use cap->driver to make differentiation */
camera_pack_event(filep, MSM_CAMERA_GET_PARM,
- MSM_CAMERA_PRIV_QUERY_CAP, &event);
+ MSM_CAMERA_PRIV_QUERY_CAP, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
@@ -96,7 +97,7 @@
if (crop->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
camera_pack_event(filep, MSM_CAMERA_SET_PARM,
- MSM_CAMERA_PRIV_S_CROP, &event);
+ MSM_CAMERA_PRIV_S_CROP, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
@@ -116,7 +117,7 @@
if (crop->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
camera_pack_event(filep, MSM_CAMERA_GET_PARM,
- MSM_CAMERA_PRIV_G_CROP, &event);
+ MSM_CAMERA_PRIV_G_CROP, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
@@ -137,7 +138,7 @@
if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
camera_pack_event(filep, MSM_CAMERA_GET_PARM,
- ctrl->id, &event);
+ ctrl->id, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
@@ -156,7 +157,8 @@
struct v4l2_event event;
if (ctrl->id >= V4L2_CID_PRIVATE_BASE) {
- camera_pack_event(filep, MSM_CAMERA_GET_PARM, ctrl->id, &event);
+ camera_pack_event(filep, MSM_CAMERA_GET_PARM, ctrl->id, -1,
+ &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
@@ -173,13 +175,16 @@
{
int rc = 0;
struct v4l2_event event;
+ struct msm_v4l2_event_data *event_data;
if (ctrl->id >= V4L2_CID_PRIVATE_BASE) {
- camera_pack_event(filep, MSM_CAMERA_SET_PARM, ctrl->id, &event);
+ camera_pack_event(filep, MSM_CAMERA_SET_PARM, ctrl->id,
+ ctrl->value, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
return rc;
-
+ event_data = (struct msm_v4l2_event_data *)event.u.data;
+ ctrl->value = event_data->ret_value;
rc = camera_check_event_status(&event);
}
@@ -225,7 +230,7 @@
rc = vb2_streamon(&sp->vb2_q, buf_type);
camera_pack_event(filep, MSM_CAMERA_SET_PARM,
- MSM_CAMERA_PRIV_STREAM_ON, &event);
+ MSM_CAMERA_PRIV_STREAM_ON, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
@@ -243,7 +248,7 @@
struct camera_v4l2_private *sp = fh_to_private(fh);
camera_pack_event(filep, MSM_CAMERA_SET_PARM,
- MSM_CAMERA_PRIV_STREAM_OFF, &event);
+ MSM_CAMERA_PRIV_STREAM_OFF, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
@@ -263,7 +268,7 @@
struct v4l2_event event;
camera_pack_event(filep, MSM_CAMERA_GET_PARM,
- MSM_CAMERA_PRIV_G_FMT, &event);
+ MSM_CAMERA_PRIV_G_FMT, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
@@ -300,7 +305,7 @@
user_fmt->plane_sizes[i]);
camera_pack_event(filep, MSM_CAMERA_SET_PARM,
- MSM_CAMERA_PRIV_S_FMT, &event);
+ MSM_CAMERA_PRIV_S_FMT, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
@@ -342,7 +347,7 @@
struct camera_v4l2_private *sp = fh_to_private(fh);
camera_pack_event(filep, MSM_CAMERA_SET_PARM,
- MSM_CAMERA_PRIV_NEW_STREAM, &event);
+ MSM_CAMERA_PRIV_NEW_STREAM, -1, &event);
rc = msm_create_stream(event_data->session_id,
event_data->stream_id, &sp->vb2_q);
@@ -510,7 +515,7 @@
if (rc < 0)
goto command_ack_q_fail;
- camera_pack_event(filep, MSM_CAMERA_NEW_SESSION, 0, &event);
+ camera_pack_event(filep, MSM_CAMERA_NEW_SESSION, 0, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
goto post_fail;
@@ -568,7 +573,7 @@
if (atomic_read(&pvdev->opened) == 0) {
- camera_pack_event(filep, MSM_CAMERA_DEL_SESSION, 0, &event);
+ camera_pack_event(filep, MSM_CAMERA_DEL_SESSION, 0, -1, &event);
/* Donot wait, imaging server may have crashed */
msm_post_event(&event, -1);
@@ -579,7 +584,7 @@
} else {
camera_pack_event(filep, MSM_CAMERA_SET_PARM,
- MSM_CAMERA_PRIV_DEL_STREAM, &event);
+ MSM_CAMERA_PRIV_DEL_STREAM, -1, &event);
/* Donot wait, imaging server may have crashed */
msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
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/camera_v2/jpeg_10/msm_jpeg_platform.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
index b1253fa..59b9746 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
@@ -73,7 +73,6 @@
{"core_clk", 228570000},
{"iface_clk", -1},
{"bus_clk0", -1},
- {"alt_bus_clk", -1},
{"camss_top_ahb_clk", -1},
};
diff --git a/drivers/media/platform/msm/camera_v2/sensor/Makefile b/drivers/media/platform/msm/camera_v2/sensor/Makefile
index 6f941f7..b6708a3 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/Makefile
+++ b/drivers/media/platform/msm/camera_v2/sensor/Makefile
@@ -7,5 +7,7 @@
obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor.o
obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
obj-$(CONFIG_IMX135) += imx135.o
+obj-$(CONFIG_OV8825) += ov8825.o
obj-$(CONFIG_OV2720) += ov2720.o
+obj-$(CONFIG_OV9724) += ov9724.o
obj-$(CONFIG_MT9M114) += mt9m114.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index e939c2b..e1b978f 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -27,7 +27,6 @@
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#endif
-static struct msm_actuator_ctrl_t msm_actuator_t;
static struct msm_actuator msm_vcm_actuator_table;
static struct msm_actuator msm_piezo_actuator_table;
@@ -618,103 +617,21 @@
.close = msm_actuator_close,
};
-static int32_t msm_actuator_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
{
- int rc = 0;
- struct msm_actuator_ctrl_t *act_ctrl_t = NULL;
+ struct msm_actuator_ctrl_t *a_ctrl = v4l2_get_subdevdata(sd);
+ void __user *argp = (void __user *)arg;
CDBG("Enter\n");
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- pr_err("i2c_check_functionality failed\n");
- goto probe_failure;
+ CDBG("%s:%d a_ctrl %p argp %p\n", __func__, __LINE__, a_ctrl, argp);
+ switch (cmd) {
+ case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
+ return msm_actuator_get_subdev_id(a_ctrl, argp);
+ case VIDIOC_MSM_ACTUATOR_CFG:
+ return msm_actuator_config(a_ctrl, argp);
+ default:
+ return -ENOIOCTLCMD;
}
-
- act_ctrl_t = (struct msm_actuator_ctrl_t *)(id->driver_data);
- CDBG("client = %x\n", (unsigned int) client);
- act_ctrl_t->i2c_client.client = client;
- /* Set device type as I2C */
- act_ctrl_t->act_device_type = MSM_CAMERA_I2C_DEVICE;
- act_ctrl_t->i2c_client.i2c_func_tbl = &msm_sensor_qup_func_tbl;
-
- /* Assign name for sub device */
- snprintf(act_ctrl_t->msm_sd.sd.name, sizeof(act_ctrl_t->msm_sd.sd.name),
- "%s", act_ctrl_t->i2c_driver->driver.name);
-
- /* Initialize sub device */
- v4l2_i2c_subdev_init(&act_ctrl_t->msm_sd.sd,
- act_ctrl_t->i2c_client.client,
- act_ctrl_t->act_v4l2_subdev_ops);
- v4l2_set_subdevdata(&act_ctrl_t->msm_sd.sd, act_ctrl_t);
- act_ctrl_t->msm_sd.sd.internal_ops = &msm_actuator_internal_ops;
- act_ctrl_t->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- media_entity_init(&act_ctrl_t->msm_sd.sd.entity, 0, NULL, 0);
- act_ctrl_t->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
- act_ctrl_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
- msm_sd_register(&act_ctrl_t->msm_sd);
- CDBG("succeeded\n");
- CDBG("Exit\n");
-
-probe_failure:
- return rc;
-}
-
-static int32_t msm_actuator_platform_probe(struct platform_device *pdev)
-{
- int32_t rc = 0;
- struct msm_camera_cci_client *cci_client = NULL;
- CDBG("Enter\n");
-
- if (!pdev->dev.of_node) {
- pr_err("of_node NULL\n");
- return -EINVAL;
- }
-
- rc = of_property_read_u32((&pdev->dev)->of_node, "cell-index",
- &pdev->id);
- CDBG("cell-index %d, rc %d\n", pdev->id, rc);
- if (rc < 0) {
- pr_err("failed rc %d\n", rc);
- return rc;
- }
-
- rc = of_property_read_u32((&pdev->dev)->of_node, "qcom,cci-master",
- &msm_actuator_t.cci_master);
- CDBG("qcom,cci-master %d, rc %d\n", msm_actuator_t.cci_master, rc);
- if (rc < 0) {
- pr_err("failed rc %d\n", rc);
- return rc;
- }
-
- msm_actuator_t.cam_name = pdev->id;
-
- /* Set platform device handle */
- msm_actuator_t.pdev = pdev;
- /* Set device type as platform device */
- msm_actuator_t.act_device_type = MSM_CAMERA_PLATFORM_DEVICE;
- msm_actuator_t.i2c_client.i2c_func_tbl = &msm_sensor_cci_func_tbl;
- msm_actuator_t.i2c_client.cci_client = kzalloc(sizeof(
- struct msm_camera_cci_client), GFP_KERNEL);
- if (!msm_actuator_t.i2c_client.cci_client) {
- pr_err("failed no memory\n");
- return -ENOMEM;
- }
-
- cci_client = msm_actuator_t.i2c_client.cci_client;
- cci_client->cci_subdev = msm_cci_get_subdev();
- v4l2_subdev_init(&msm_actuator_t.msm_sd.sd,
- msm_actuator_t.act_v4l2_subdev_ops);
- v4l2_set_subdevdata(&msm_actuator_t.msm_sd.sd, &msm_actuator_t);
- msm_actuator_t.msm_sd.sd.internal_ops = &msm_actuator_internal_ops;
- msm_actuator_t.msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- snprintf(msm_actuator_t.msm_sd.sd.name,
- ARRAY_SIZE(msm_actuator_t.msm_sd.sd.name), "msm_actuator");
- media_entity_init(&msm_actuator_t.msm_sd.sd.entity, 0, NULL, 0);
- msm_actuator_t.msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
- msm_actuator_t.msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
- msm_sd_register(&msm_actuator_t.msm_sd);
- CDBG("Exit\n");
- return rc;
}
static int32_t msm_actuator_power_up(struct msm_actuator_ctrl_t *a_ctrl)
@@ -735,64 +652,6 @@
return rc;
}
-static const struct i2c_device_id msm_actuator_i2c_id[] = {
- {"msm_actuator", (kernel_ulong_t)&msm_actuator_t},
- { }
-};
-
-static struct i2c_driver msm_actuator_i2c_driver = {
- .id_table = msm_actuator_i2c_id,
- .probe = msm_actuator_i2c_probe,
- .remove = __exit_p(msm_actuator_i2c_remove),
- .driver = {
- .name = "msm_actuator",
- },
-};
-
-static const struct of_device_id msm_actuator_dt_match[] = {
- {.compatible = "qcom,actuator", .data = &msm_actuator_t},
- {}
-};
-
-MODULE_DEVICE_TABLE(of, msm_actuator_dt_match);
-
-static struct platform_driver msm_actuator_platform_driver = {
- .driver = {
- .name = "qcom,actuator",
- .owner = THIS_MODULE,
- .of_match_table = msm_actuator_dt_match,
- },
-};
-
-static int __init msm_actuator_init_module(void)
-{
- int32_t rc = 0;
- CDBG("Enter\n");
- rc = platform_driver_probe(msm_actuator_t.pdriver,
- msm_actuator_platform_probe);
- if (!rc)
- return rc;
- CDBG("%s:%d rc %d\n", __func__, __LINE__, rc);
- return i2c_add_driver(msm_actuator_t.i2c_driver);
-}
-
-static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
- unsigned int cmd, void *arg)
-{
- struct msm_actuator_ctrl_t *a_ctrl = v4l2_get_subdevdata(sd);
- void __user *argp = (void __user *)arg;
- CDBG("Enter\n");
- CDBG("%s:%d a_ctrl %p argp %p\n", __func__, __LINE__, a_ctrl, argp);
- switch (cmd) {
- case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
- return msm_actuator_get_subdev_id(a_ctrl, argp);
- case VIDIOC_MSM_ACTUATOR_CFG:
- return msm_actuator_config(a_ctrl, argp);
- default:
- return -ENOIOCTLCMD;
- }
-}
-
static int32_t msm_actuator_power(struct v4l2_subdev *sd, int on)
{
int rc = 0;
@@ -817,17 +676,156 @@
.core = &msm_actuator_subdev_core_ops,
};
-static struct msm_actuator_ctrl_t msm_actuator_t = {
- .i2c_driver = &msm_actuator_i2c_driver,
- .pdriver = &msm_actuator_platform_driver,
- .act_v4l2_subdev_ops = &msm_actuator_subdev_ops,
+static int32_t msm_actuator_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int rc = 0;
+ struct msm_actuator_ctrl_t *act_ctrl_t = NULL;
+ CDBG("Enter\n");
- .curr_step_pos = 0,
- .curr_region_index = 0,
- .actuator_mutex = &msm_actuator_mutex,
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ pr_err("i2c_check_functionality failed\n");
+ goto probe_failure;
+ }
+ act_ctrl_t = (struct msm_actuator_ctrl_t *)(id->driver_data);
+ CDBG("client = %x\n", (unsigned int) client);
+ act_ctrl_t->i2c_client.client = client;
+ /* Set device type as I2C */
+ act_ctrl_t->act_device_type = MSM_CAMERA_I2C_DEVICE;
+ act_ctrl_t->i2c_client.i2c_func_tbl = &msm_sensor_qup_func_tbl;
+ act_ctrl_t->act_v4l2_subdev_ops = &msm_actuator_subdev_ops;
+ act_ctrl_t->actuator_mutex = &msm_actuator_mutex;
+ /* Assign name for sub device */
+ snprintf(act_ctrl_t->msm_sd.sd.name, sizeof(act_ctrl_t->msm_sd.sd.name),
+ "%s", act_ctrl_t->i2c_driver->driver.name);
+
+ /* Initialize sub device */
+ v4l2_i2c_subdev_init(&act_ctrl_t->msm_sd.sd,
+ act_ctrl_t->i2c_client.client,
+ act_ctrl_t->act_v4l2_subdev_ops);
+ v4l2_set_subdevdata(&act_ctrl_t->msm_sd.sd, act_ctrl_t);
+ act_ctrl_t->msm_sd.sd.internal_ops = &msm_actuator_internal_ops;
+ act_ctrl_t->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ media_entity_init(&act_ctrl_t->msm_sd.sd.entity, 0, NULL, 0);
+ act_ctrl_t->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ act_ctrl_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
+ msm_sd_register(&act_ctrl_t->msm_sd);
+ CDBG("succeeded\n");
+ CDBG("Exit\n");
+
+probe_failure:
+ return rc;
+}
+
+static int32_t msm_actuator_platform_probe(struct platform_device *pdev)
+{
+ int32_t rc = 0;
+ struct msm_camera_cci_client *cci_client = NULL;
+ struct msm_actuator_ctrl_t *msm_actuator_t = NULL;
+ CDBG("Enter\n");
+
+ if (!pdev->dev.of_node) {
+ pr_err("of_node NULL\n");
+ return -EINVAL;
+ }
+
+ msm_actuator_t = kzalloc(sizeof(struct msm_actuator_ctrl_t),
+ GFP_KERNEL);
+ if (!msm_actuator_t) {
+ pr_err("%s:%d failed no memory\n", __func__, __LINE__);
+ return -ENOMEM;
+ }
+ rc = of_property_read_u32((&pdev->dev)->of_node, "cell-index",
+ &pdev->id);
+ CDBG("cell-index %d, rc %d\n", pdev->id, rc);
+ if (rc < 0) {
+ pr_err("failed rc %d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32((&pdev->dev)->of_node, "qcom,cci-master",
+ &msm_actuator_t->cci_master);
+ CDBG("qcom,cci-master %d, rc %d\n", msm_actuator_t->cci_master, rc);
+ if (rc < 0) {
+ pr_err("failed rc %d\n", rc);
+ return rc;
+ }
+
+ msm_actuator_t->act_v4l2_subdev_ops = &msm_actuator_subdev_ops;
+ msm_actuator_t->actuator_mutex = &msm_actuator_mutex;
+ msm_actuator_t->cam_name = pdev->id;
+
+ /* Set platform device handle */
+ msm_actuator_t->pdev = pdev;
+ /* Set device type as platform device */
+ msm_actuator_t->act_device_type = MSM_CAMERA_PLATFORM_DEVICE;
+ msm_actuator_t->i2c_client.i2c_func_tbl = &msm_sensor_cci_func_tbl;
+ msm_actuator_t->i2c_client.cci_client = kzalloc(sizeof(
+ struct msm_camera_cci_client), GFP_KERNEL);
+ if (!msm_actuator_t->i2c_client.cci_client) {
+ pr_err("failed no memory\n");
+ return -ENOMEM;
+ }
+
+ cci_client = msm_actuator_t->i2c_client.cci_client;
+ cci_client->cci_subdev = msm_cci_get_subdev();
+ v4l2_subdev_init(&msm_actuator_t->msm_sd.sd,
+ msm_actuator_t->act_v4l2_subdev_ops);
+ v4l2_set_subdevdata(&msm_actuator_t->msm_sd.sd, msm_actuator_t);
+ msm_actuator_t->msm_sd.sd.internal_ops = &msm_actuator_internal_ops;
+ msm_actuator_t->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ snprintf(msm_actuator_t->msm_sd.sd.name,
+ ARRAY_SIZE(msm_actuator_t->msm_sd.sd.name), "msm_actuator");
+ media_entity_init(&msm_actuator_t->msm_sd.sd.entity, 0, NULL, 0);
+ msm_actuator_t->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ msm_actuator_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
+ msm_sd_register(&msm_actuator_t->msm_sd);
+ CDBG("Exit\n");
+ return rc;
+}
+
+static const struct i2c_device_id msm_actuator_i2c_id[] = {
+ {"msm_actuator", (kernel_ulong_t)NULL},
+ { }
};
+static struct i2c_driver msm_actuator_i2c_driver = {
+ .id_table = msm_actuator_i2c_id,
+ .probe = msm_actuator_i2c_probe,
+ .remove = __exit_p(msm_actuator_i2c_remove),
+ .driver = {
+ .name = "msm_actuator",
+ },
+};
+
+static const struct of_device_id msm_actuator_dt_match[] = {
+ {.compatible = "qcom,actuator", .data = NULL},
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, msm_actuator_dt_match);
+
+static struct platform_driver msm_actuator_platform_driver = {
+ .driver = {
+ .name = "qcom,actuator",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_actuator_dt_match,
+ },
+};
+
+static int __init msm_actuator_init_module(void)
+{
+ int32_t rc = 0;
+ CDBG("Enter\n");
+ rc = platform_driver_probe(&msm_actuator_platform_driver,
+ msm_actuator_platform_probe);
+ if (!rc)
+ return rc;
+ CDBG("%s:%d rc %d\n", __func__, __LINE__, rc);
+ return i2c_add_driver(&msm_actuator_i2c_driver);
+}
+
static struct msm_actuator msm_vcm_actuator_table = {
.act_type = ACTUATOR_VCM,
.func_tbl = {
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
index 2c8c8b8..0df0488 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
@@ -244,8 +244,8 @@
{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
};
-static struct camera_vreg_t csid_8974_vreg_info[] = {
- {"mipi_csi_vdd", REG_LDO, 1800000, 1800000, 12000},
+static struct camera_vreg_t csid_vreg_info[] = {
+ {"qcom,mipi-csi-vdd", REG_LDO, 0, 0, 12000},
};
static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
@@ -309,7 +309,7 @@
} else if (CSID_VERSION >= CSID_VERSION_V3) {
CDBG("%s:%d called\n", __func__, __LINE__);
rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
- csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+ csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
NULL, 0, &csid_dev->csi_vdd, 1);
if (rc < 0) {
pr_err("%s: regulator on failed\n", __func__);
@@ -318,7 +318,7 @@
CDBG("%s:%d called\n", __func__, __LINE__);
rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
- csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+ csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
NULL, 0, &csid_dev->csi_vdd, 1);
if (rc < 0) {
pr_err("%s: regulator enable failed\n", __func__);
@@ -382,7 +382,7 @@
NULL, 0, &csid_dev->csi_vdd, 0);
} else if (CSID_VERSION >= CSID_VERSION_V3) {
msm_camera_enable_vreg(&csid_dev->pdev->dev,
- csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+ csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
NULL, 0, &csid_dev->csi_vdd, 0);
}
vreg_enable_failed:
@@ -392,7 +392,7 @@
NULL, 0, &csid_dev->csi_vdd, 0);
} else if (CSID_VERSION >= CSID_VERSION_V3) {
msm_camera_config_vreg(&csid_dev->pdev->dev,
- csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+ csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
NULL, 0, &csid_dev->csi_vdd, 0);
}
vreg_config_failed:
@@ -442,11 +442,11 @@
csid_8974_clk_info[0].num_clk_info, 0);
msm_camera_enable_vreg(&csid_dev->pdev->dev,
- csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+ csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
NULL, 0, &csid_dev->csi_vdd, 0);
msm_camera_config_vreg(&csid_dev->pdev->dev,
- csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+ csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
NULL, 0, &csid_dev->csi_vdd, 0);
}
@@ -576,7 +576,7 @@
static int __devinit csid_probe(struct platform_device *pdev)
{
struct csid_device *new_csid_dev;
-
+ uint32_t csi_vdd_voltage = 0;
int rc = 0;
CDBG("%s:%d called\n", __func__, __LINE__);
new_csid_dev = kzalloc(sizeof(struct csid_device), GFP_KERNEL);
@@ -590,11 +590,30 @@
platform_set_drvdata(pdev, &new_csid_dev->msm_sd.sd);
mutex_init(&new_csid_dev->mutex);
- if (pdev->dev.of_node)
- of_property_read_u32((&pdev->dev)->of_node,
+ if (pdev->dev.of_node) {
+ rc = of_property_read_u32((&pdev->dev)->of_node,
"cell-index", &pdev->id);
+ if (rc < 0) {
+ pr_err("%s:%d failed to read cell-index\n", __func__,
+ __LINE__);
+ goto csid_no_resource;
+ }
+ CDBG("%s device id %d\n", __func__, pdev->id);
- CDBG("%s device id %d\n", __func__, pdev->id);
+ rc = of_property_read_u32((&pdev->dev)->of_node,
+ "qcom,csi-vdd-voltage", &csi_vdd_voltage);
+ if (rc < 0) {
+ pr_err("%s:%d failed to read qcom,csi-vdd-voltage\n",
+ __func__, __LINE__);
+ goto csid_no_resource;
+ }
+ CDBG("%s:%d reading mipi_csi_vdd is %d\n", __func__, __LINE__,
+ csi_vdd_voltage);
+
+ csid_vreg_info[0].min_voltage = csi_vdd_voltage;
+ csid_vreg_info[0].max_voltage = csi_vdd_voltage;
+ }
+
new_csid_dev->mem = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "csid");
if (!new_csid_dev->mem) {
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ov8825.c b/drivers/media/platform/msm/camera_v2/sensor/ov8825.c
new file mode 100644
index 0000000..b56eb10
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/ov8825.c
@@ -0,0 +1,167 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "msm_sensor.h"
+#define OV8825_SENSOR_NAME "ov8825"
+DEFINE_MSM_MUTEX(ov8825_mut);
+
+static struct msm_sensor_ctrl_t ov8825_s_ctrl;
+
+static struct msm_sensor_power_setting ov8825_power_setting[] = {
+ {
+ .seq_type = SENSOR_VREG,
+ .seq_val = CAM_VIO,
+ .config_val = 0,
+ .delay = 5,
+ },
+ {
+ .seq_type = SENSOR_VREG,
+ .seq_val = CAM_VANA,
+ .config_val = 0,
+ .delay = 5,
+ },
+ {
+ .seq_type = SENSOR_VREG,
+ .seq_val = CAM_VDIG,
+ .config_val = 0,
+ .delay = 5,
+ },
+ {
+ .seq_type = SENSOR_VREG,
+ .seq_val = CAM_VAF,
+ .config_val = 0,
+ .delay = 15,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_STANDBY,
+ .config_val = GPIO_OUT_LOW,
+ .delay = 15,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_RESET,
+ .config_val = GPIO_OUT_LOW,
+ .delay = 40,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_STANDBY,
+ .config_val = GPIO_OUT_HIGH,
+ .delay = 40,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_RESET,
+ .config_val = GPIO_OUT_HIGH,
+ .delay = 40,
+ },
+ {
+ .seq_type = SENSOR_CLK,
+ .seq_val = SENSOR_CAM_MCLK,
+ .config_val = 24000000,
+ .delay = 5,
+ },
+ {
+ .seq_type = SENSOR_I2C_MUX,
+ .seq_val = 0,
+ .config_val = 0,
+ .delay = 0,
+ },
+};
+
+static struct v4l2_subdev_info ov8825_subdev_info[] = {
+ {
+ .code = V4L2_MBUS_FMT_SBGGR10_1X10,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .fmt = 1,
+ .order = 0,
+ },
+};
+
+static const struct i2c_device_id ov8825_i2c_id[] = {
+ {OV8825_SENSOR_NAME, (kernel_ulong_t)&ov8825_s_ctrl},
+ { }
+};
+
+static struct i2c_driver ov8825_i2c_driver = {
+ .id_table = ov8825_i2c_id,
+ .probe = msm_sensor_i2c_probe,
+ .driver = {
+ .name = OV8825_SENSOR_NAME,
+ },
+};
+
+static struct msm_camera_i2c_client ov8825_sensor_i2c_client = {
+ .addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static const struct of_device_id ov8825_dt_match[] = {
+ {.compatible = "qcom,ov8825", .data = &ov8825_s_ctrl},
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, ov8825_dt_match);
+
+static struct platform_driver ov8825_platform_driver = {
+ .driver = {
+ .name = "qcom,ov8825",
+ .owner = THIS_MODULE,
+ .of_match_table = ov8825_dt_match,
+ },
+};
+
+static int32_t ov8825_platform_probe(struct platform_device *pdev)
+{
+ int32_t rc = 0;
+ const struct of_device_id *match;
+ match = of_match_device(ov8825_dt_match, &pdev->dev);
+ rc = msm_sensor_platform_probe(pdev, match->data);
+ return rc;
+}
+
+static int __init ov8825_init_module(void)
+{
+ int32_t rc = 0;
+ pr_info("%s:%d\n", __func__, __LINE__);
+ rc = platform_driver_probe(&ov8825_platform_driver,
+ ov8825_platform_probe);
+ if (!rc)
+ return rc;
+ pr_err("%s:%d rc %d\n", __func__, __LINE__, rc);
+ return i2c_add_driver(&ov8825_i2c_driver);
+}
+
+static void __exit ov8825_exit_module(void)
+{
+ pr_info("%s:%d\n", __func__, __LINE__);
+ if (ov8825_s_ctrl.pdev) {
+ msm_sensor_free_sensor_data(&ov8825_s_ctrl);
+ platform_driver_unregister(&ov8825_platform_driver);
+ } else
+ i2c_del_driver(&ov8825_i2c_driver);
+ return;
+}
+
+static struct msm_sensor_ctrl_t ov8825_s_ctrl = {
+ .sensor_i2c_client = &ov8825_sensor_i2c_client,
+ .power_setting_array.power_setting = ov8825_power_setting,
+ .power_setting_array.size = ARRAY_SIZE(ov8825_power_setting),
+ .msm_sensor_mutex = &ov8825_mut,
+ .sensor_v4l2_subdev_info = ov8825_subdev_info,
+ .sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov8825_subdev_info),
+};
+
+module_init(ov8825_init_module);
+module_exit(ov8825_exit_module);
+MODULE_DESCRIPTION("ov8825");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ov9724.c b/drivers/media/platform/msm/camera_v2/sensor/ov9724.c
new file mode 100644
index 0000000..981cc10
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/ov9724.c
@@ -0,0 +1,161 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "msm_sensor.h"
+
+#define OV9724_SENSOR_NAME "ov9724"
+DEFINE_MSM_MUTEX(ov9724_mut);
+
+static struct msm_sensor_ctrl_t ov9724_s_ctrl;
+
+static struct msm_sensor_power_setting ov9724_power_setting[] = {
+ {
+ .seq_type = SENSOR_VREG,
+ .seq_val = CAM_VANA,
+ .config_val = 0,
+ .delay = 0,
+ },
+ {
+ .seq_type = SENSOR_VREG,
+ .seq_val = CAM_VIO,
+ .config_val = 0,
+ .delay = 0,
+ },
+ {
+ .seq_type = SENSOR_VREG,
+ .seq_val = CAM_VDIG,
+ .config_val = 0,
+ .delay = 0,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_RESET,
+ .config_val = GPIO_OUT_LOW,
+ .delay = 5,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_RESET,
+ .config_val = GPIO_OUT_HIGH,
+ .delay = 30,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_STANDBY,
+ .config_val = GPIO_OUT_LOW,
+ .delay = 5,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_STANDBY,
+ .config_val = GPIO_OUT_HIGH,
+ .delay = 30,
+ },
+ {
+ .seq_type = SENSOR_CLK,
+ .seq_val = SENSOR_CAM_MCLK,
+ .config_val = 24000000,
+ .delay = 5,
+ },
+ {
+ .seq_type = SENSOR_I2C_MUX,
+ .seq_val = 0,
+ .config_val = 0,
+ .delay = 0,
+ },
+};
+
+static struct v4l2_subdev_info ov9724_subdev_info[] = {
+ {
+ .code = V4L2_MBUS_FMT_SBGGR10_1X10,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .fmt = 1,
+ .order = 0,
+ },
+};
+
+static const struct i2c_device_id ov9724_i2c_id[] = {
+ {OV9724_SENSOR_NAME, (kernel_ulong_t)&ov9724_s_ctrl},
+ { }
+};
+
+static struct i2c_driver ov9724_i2c_driver = {
+ .id_table = ov9724_i2c_id,
+ .probe = msm_sensor_i2c_probe,
+ .driver = {
+ .name = OV9724_SENSOR_NAME,
+ },
+};
+
+static struct msm_camera_i2c_client ov9724_sensor_i2c_client = {
+ .addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static struct msm_sensor_ctrl_t ov9724_s_ctrl = {
+ .sensor_i2c_client = &ov9724_sensor_i2c_client,
+ .power_setting_array.power_setting = ov9724_power_setting,
+ .power_setting_array.size = ARRAY_SIZE(ov9724_power_setting),
+ .msm_sensor_mutex = &ov9724_mut,
+ .sensor_v4l2_subdev_info = ov9724_subdev_info,
+ .sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov9724_subdev_info),
+};
+
+static const struct of_device_id ov9724_dt_match[] = {
+ {.compatible = "qcom,ov9724", .data = &ov9724_s_ctrl},
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, ov9724_dt_match);
+
+static struct platform_driver ov9724_platform_driver = {
+ .driver = {
+ .name = "qcom,ov9724",
+ .owner = THIS_MODULE,
+ .of_match_table = ov9724_dt_match,
+ },
+};
+
+static int32_t ov9724_platform_probe(struct platform_device *pdev)
+{
+ int32_t rc = 0;
+ const struct of_device_id *match;
+
+ match = of_match_device(ov9724_dt_match, &pdev->dev);
+ rc = msm_sensor_platform_probe(pdev, match->data);
+ return rc;
+}
+
+static int __init ov9724_init_module(void)
+{
+ int32_t rc = 0;
+
+ rc = platform_driver_probe(&ov9724_platform_driver,
+ ov9724_platform_probe);
+ if (!rc)
+ return rc;
+ return i2c_add_driver(&ov9724_i2c_driver);
+}
+
+static void __exit ov9724_exit_module(void)
+{
+ if (ov9724_s_ctrl.pdev) {
+ msm_sensor_free_sensor_data(&ov9724_s_ctrl);
+ platform_driver_unregister(&ov9724_platform_driver);
+ } else
+ i2c_del_driver(&ov9724_i2c_driver);
+ return;
+}
+
+module_init(ov9724_init_module);
+module_exit(ov9724_exit_module);
+MODULE_DESCRIPTION("ov9724");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/dvb/adapter/mpq_stream_buffer.c b/drivers/media/platform/msm/dvb/adapter/mpq_stream_buffer.c
index 6ec1994..76ce0c0 100644
--- a/drivers/media/platform/msm/dvb/adapter/mpq_stream_buffer.c
+++ b/drivers/media/platform/msm/dvb/adapter/mpq_stream_buffer.c
@@ -19,8 +19,6 @@
#include "mpq_stream_buffer.h"
-
-
int mpq_streambuffer_init(
struct mpq_streambuffer *sbuff,
enum mpq_streambuffer_mode mode,
@@ -29,7 +27,8 @@
void *packet_buff,
size_t packet_buff_size)
{
- if ((NULL == sbuff) || (NULL == data_buffers) || (NULL == packet_buff))
+ if ((NULL == sbuff) || (NULL == data_buffers) ||
+ (NULL == packet_buff) || (data_buff_num == 0))
return -EINVAL;
if (data_buff_num > 1) {
@@ -41,7 +40,7 @@
data_buffers,
data_buff_num *
sizeof(struct mpq_streambuffer_buffer_desc));
- } else if (data_buff_num == 1) {
+ } else {
if (mode != MPQ_STREAMBUFFER_BUFFER_MODE_RING)
return -EINVAL;
/* Single ring-buffer */
@@ -58,12 +57,38 @@
}
EXPORT_SYMBOL(mpq_streambuffer_init);
+void mpq_streambuffer_terminate(struct mpq_streambuffer *sbuff)
+{
+ spin_lock(&sbuff->packet_data.lock);
+ spin_lock(&sbuff->raw_data.lock);
+ sbuff->packet_data.error = -ENODEV;
+ sbuff->raw_data.error = -ENODEV;
+ spin_unlock(&sbuff->raw_data.lock);
+ spin_unlock(&sbuff->packet_data.lock);
+
+ wake_up_all(&sbuff->raw_data.queue);
+ wake_up_all(&sbuff->packet_data.queue);
+}
+EXPORT_SYMBOL(mpq_streambuffer_terminate);
ssize_t mpq_streambuffer_pkt_next(
struct mpq_streambuffer *sbuff,
ssize_t idx, size_t *pktlen)
{
- return dvb_ringbuffer_pkt_next(&sbuff->packet_data, idx, pktlen);
+ ssize_t packet_idx;
+
+ spin_lock(&sbuff->packet_data.lock);
+
+ /* buffer was released, return no packet available */
+ if (sbuff->packet_data.error == -ENODEV) {
+ spin_unlock(&sbuff->packet_data.lock);
+ return -ENODEV;
+ }
+
+ packet_idx = dvb_ringbuffer_pkt_next(&sbuff->packet_data, idx, pktlen);
+ spin_unlock(&sbuff->packet_data.lock);
+
+ return packet_idx;
}
EXPORT_SYMBOL(mpq_streambuffer_pkt_next);
@@ -77,6 +102,14 @@
size_t ret;
size_t read_len;
+ spin_lock(&sbuff->packet_data.lock);
+
+ /* buffer was released, return no packet available */
+ if (sbuff->packet_data.error == -ENODEV) {
+ spin_unlock(&sbuff->packet_data.lock);
+ return -ENODEV;
+ }
+
/* read-out the packet header first */
ret = dvb_ringbuffer_pkt_read(
&sbuff->packet_data, idx, 0,
@@ -84,8 +117,10 @@
sizeof(struct mpq_streambuffer_packet_header));
/* verify length, at least packet header should exist */
- if (ret != sizeof(struct mpq_streambuffer_packet_header))
+ if (ret != sizeof(struct mpq_streambuffer_packet_header)) {
+ spin_unlock(&sbuff->packet_data.lock);
return -EINVAL;
+ }
read_len = ret;
@@ -98,12 +133,16 @@
user_data,
packet->user_data_len);
- if (ret < 0)
+ if (ret < 0) {
+ spin_unlock(&sbuff->packet_data.lock);
return ret;
+ }
read_len += ret;
}
+ spin_unlock(&sbuff->packet_data.lock);
+
return read_len;
}
EXPORT_SYMBOL(mpq_streambuffer_pkt_read);
@@ -120,12 +159,22 @@
if (NULL == sbuff)
return -EINVAL;
+ spin_lock(&sbuff->packet_data.lock);
+
+ /* check if buffer was released */
+ if (sbuff->packet_data.error == -ENODEV) {
+ spin_unlock(&sbuff->packet_data.lock);
+ return -ENODEV;
+ }
+
/* read-out the packet header first */
ret = dvb_ringbuffer_pkt_read(&sbuff->packet_data, idx,
0,
(u8 *)&packet,
sizeof(struct mpq_streambuffer_packet_header));
+ spin_unlock(&sbuff->packet_data.lock);
+
if (ret != sizeof(struct mpq_streambuffer_packet_header))
return -EINVAL;
@@ -138,6 +187,17 @@
return ret;
}
+ spin_lock(&sbuff->packet_data.lock);
+ spin_lock(&sbuff->raw_data.lock);
+
+ /* check if buffer was released */
+ if ((sbuff->packet_data.error == -ENODEV) ||
+ (sbuff->raw_data.error == -ENODEV)) {
+ spin_unlock(&sbuff->raw_data.lock);
+ spin_unlock(&sbuff->packet_data.lock);
+ return -ENODEV;
+ }
+
/* Move read pointer to the next linear buffer for subsequent reads */
if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) &&
(packet.raw_data_len > 0)) {
@@ -159,6 +219,9 @@
/* Now clear the packet from the packet header */
dvb_ringbuffer_pkt_dispose(&sbuff->packet_data, idx);
+ spin_unlock(&sbuff->raw_data.lock);
+ spin_unlock(&sbuff->packet_data.lock);
+
if (sbuff->cb)
sbuff->cb(sbuff, sbuff->cb_user_data);
@@ -177,12 +240,22 @@
if ((NULL == sbuff) || (NULL == packet))
return -EINVAL;
+ spin_lock(&sbuff->packet_data.lock);
+
+ /* check if buffer was released */
+ if (sbuff->packet_data.error == -ENODEV) {
+ spin_unlock(&sbuff->packet_data.lock);
+ return -ENODEV;
+ }
+
len = sizeof(struct mpq_streambuffer_packet_header) +
packet->user_data_len;
/* Make sure enough space available for packet header */
- if (dvb_ringbuffer_free(&sbuff->packet_data) < len)
+ if (dvb_ringbuffer_free(&sbuff->packet_data) < len) {
+ spin_unlock(&sbuff->packet_data.lock);
return -ENOSPC;
+ }
/* Starting writing packet header */
idx = dvb_ringbuffer_pkt_start(&sbuff->packet_data, len);
@@ -202,20 +275,22 @@
/* Move write pointer to next linear buffer for subsequent writes */
if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) &&
(packet->raw_data_len > 0)) {
- if (sbuff->pending_buffers_count == sbuff->buffers_num)
+ if (sbuff->pending_buffers_count == sbuff->buffers_num) {
+ spin_unlock(&sbuff->packet_data.lock);
return -ENOSPC;
+ }
DVB_RINGBUFFER_PUSH(&sbuff->raw_data,
sizeof(struct mpq_streambuffer_buffer_desc));
sbuff->pending_buffers_count++;
}
+ spin_unlock(&sbuff->packet_data.lock);
wake_up_all(&sbuff->packet_data.queue);
return 0;
}
EXPORT_SYMBOL(mpq_streambuffer_pkt_write);
-
ssize_t mpq_streambuffer_data_write(
struct mpq_streambuffer *sbuff,
const u8 *buf, size_t len)
@@ -225,15 +300,27 @@
if ((NULL == sbuff) || (NULL == buf))
return -EINVAL;
+ spin_lock(&sbuff->raw_data.lock);
+
+ /* check if buffer was released */
+ if (sbuff->raw_data.error == -ENODEV) {
+ spin_unlock(&sbuff->raw_data.lock);
+ return -ENODEV;
+ }
+
if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
- if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len))
+ if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len)) {
+ spin_unlock(&sbuff->raw_data.lock);
return -ENOSPC;
+ }
/*
* Secure buffers are not permitted to be mapped into kernel
* memory, and so buffer base address may be NULL
*/
- if (NULL == sbuff->raw_data.data)
+ if (NULL == sbuff->raw_data.data) {
+ spin_unlock(&sbuff->raw_data.lock);
return -EPERM;
+ }
res = dvb_ringbuffer_write(&sbuff->raw_data, buf, len);
wake_up_all(&sbuff->raw_data.queue);
} else {
@@ -247,8 +334,10 @@
* Secure buffers are not permitted to be mapped into kernel
* memory, and so buffer base address may be NULL
*/
- if (NULL == desc->base)
+ if (NULL == desc->base) {
+ spin_unlock(&sbuff->raw_data.lock);
return -EPERM;
+ }
if ((sbuff->pending_buffers_count == sbuff->buffers_num) ||
((desc->size - desc->write_ptr) < len)) {
@@ -259,6 +348,7 @@
sbuff->buffers_num,
desc->write_ptr,
desc->size);
+ spin_unlock(&sbuff->raw_data.lock);
return -ENOSPC;
}
memcpy(desc->base + desc->write_ptr, buf, len);
@@ -266,6 +356,7 @@
res = len;
}
+ spin_unlock(&sbuff->raw_data.lock);
return res;
}
EXPORT_SYMBOL(mpq_streambuffer_data_write);
@@ -278,9 +369,19 @@
if (NULL == sbuff)
return -EINVAL;
+ spin_lock(&sbuff->raw_data.lock);
+
+ /* check if buffer was released */
+ if (sbuff->raw_data.error == -ENODEV) {
+ spin_unlock(&sbuff->raw_data.lock);
+ return -ENODEV;
+ }
+
if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
- if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len))
+ if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len)) {
+ spin_unlock(&sbuff->raw_data.lock);
return -ENOSPC;
+ }
DVB_RINGBUFFER_PUSH(&sbuff->raw_data, len);
wake_up_all(&sbuff->raw_data.queue);
@@ -295,11 +396,13 @@
MPQ_DVB_ERR_PRINT(
"%s: No space available!\n",
__func__);
+ spin_unlock(&sbuff->raw_data.lock);
return -ENOSPC;
}
desc->write_ptr += len;
}
+ spin_unlock(&sbuff->raw_data.lock);
return 0;
}
EXPORT_SYMBOL(mpq_streambuffer_data_write_deposit);
@@ -314,13 +417,23 @@
if ((NULL == sbuff) || (NULL == buf))
return -EINVAL;
+ spin_lock(&sbuff->raw_data.lock);
+
+ /* check if buffer was released */
+ if (sbuff->raw_data.error == -ENODEV) {
+ spin_unlock(&sbuff->raw_data.lock);
+ return -ENODEV;
+ }
+
if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
/*
* Secure buffers are not permitted to be mapped into kernel
* memory, and so buffer base address may be NULL
*/
- if (NULL == sbuff->raw_data.data)
+ if (NULL == sbuff->raw_data.data) {
+ spin_unlock(&sbuff->raw_data.lock);
return -EPERM;
+ }
actual_len = dvb_ringbuffer_avail(&sbuff->raw_data);
if (actual_len < len)
@@ -340,8 +453,10 @@
* Secure buffers are not permitted to be mapped into kernel
* memory, and so buffer base address may be NULL
*/
- if (NULL == desc->base)
+ if (NULL == desc->base) {
+ spin_unlock(&sbuff->raw_data.lock);
return -EPERM;
+ }
actual_len = (desc->write_ptr - desc->read_ptr);
if (actual_len < len)
@@ -350,6 +465,7 @@
desc->read_ptr += len;
}
+ spin_unlock(&sbuff->raw_data.lock);
return len;
}
EXPORT_SYMBOL(mpq_streambuffer_data_read);
@@ -364,6 +480,10 @@
if ((NULL == sbuff) || (NULL == buf))
return -EINVAL;
+ /* check if buffer was released */
+ if (sbuff->raw_data.error == -ENODEV)
+ return -ENODEV;
+
if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
/*
* Secure buffers are not permitted to be mapped into kernel
@@ -397,6 +517,7 @@
len = actual_len;
if (copy_to_user(buf, desc->base + desc->read_ptr, len))
return -EFAULT;
+
desc->read_ptr += len;
}
@@ -404,7 +525,6 @@
}
EXPORT_SYMBOL(mpq_streambuffer_data_read_user);
-
int mpq_streambuffer_data_read_dispose(
struct mpq_streambuffer *sbuff,
size_t len)
@@ -412,9 +532,19 @@
if (NULL == sbuff)
return -EINVAL;
+ spin_lock(&sbuff->raw_data.lock);
+
+ /* check if buffer was released */
+ if (sbuff->raw_data.error == -ENODEV) {
+ spin_unlock(&sbuff->raw_data.lock);
+ return -ENODEV;
+ }
+
if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
- if (unlikely(dvb_ringbuffer_avail(&sbuff->raw_data) < len))
+ if (unlikely(dvb_ringbuffer_avail(&sbuff->raw_data) < len)) {
+ spin_unlock(&sbuff->raw_data.lock);
return -EINVAL;
+ }
DVB_RINGBUFFER_SKIP(&sbuff->raw_data, len);
wake_up_all(&sbuff->raw_data.queue);
@@ -429,6 +559,8 @@
desc->read_ptr += len;
}
+ spin_unlock(&sbuff->raw_data.lock);
+
return 0;
}
EXPORT_SYMBOL(mpq_streambuffer_data_read_dispose);
@@ -444,6 +576,14 @@
if ((NULL == sbuff) || (NULL == handle))
return -EINVAL;
+ spin_lock(&sbuff->raw_data.lock);
+
+ /* check if buffer was released */
+ if (sbuff->raw_data.error == -ENODEV) {
+ spin_unlock(&sbuff->raw_data.lock);
+ return -ENODEV;
+ }
+
if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
*handle = sbuff->buffers[0].handle;
} else {
@@ -455,6 +595,9 @@
&sbuff->raw_data.data[sbuff->raw_data.pwrite];
*handle = desc->handle;
}
+
+ spin_unlock(&sbuff->raw_data.lock);
+
return 0;
}
EXPORT_SYMBOL(mpq_streambuffer_get_buffer_handle);
@@ -484,15 +627,29 @@
if (NULL == sbuff)
return -EINVAL;
- if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode)
- return dvb_ringbuffer_free(&sbuff->raw_data);
+ spin_lock(&sbuff->raw_data.lock);
- if (sbuff->pending_buffers_count == sbuff->buffers_num)
+ /* check if buffer was released */
+ if (sbuff->raw_data.error == -ENODEV) {
+ spin_unlock(&sbuff->raw_data.lock);
+ return -ENODEV;
+ }
+
+ if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+ spin_unlock(&sbuff->raw_data.lock);
+ return dvb_ringbuffer_free(&sbuff->raw_data);
+ }
+
+ if (sbuff->pending_buffers_count == sbuff->buffers_num) {
+ spin_unlock(&sbuff->raw_data.lock);
return 0;
+ }
desc = (struct mpq_streambuffer_buffer_desc *)
&sbuff->raw_data.data[sbuff->raw_data.pwrite];
+ spin_unlock(&sbuff->raw_data.lock);
+
return desc->size - desc->write_ptr;
}
EXPORT_SYMBOL(mpq_streambuffer_data_free);
@@ -506,12 +663,25 @@
if (NULL == sbuff)
return -EINVAL;
- if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode)
- return dvb_ringbuffer_avail(&sbuff->raw_data);
+ spin_lock(&sbuff->raw_data.lock);
+
+ /* check if buffer was released */
+ if (sbuff->raw_data.error == -ENODEV) {
+ spin_unlock(&sbuff->raw_data.lock);
+ return -ENODEV;
+ }
+
+ if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+ ssize_t avail = dvb_ringbuffer_avail(&sbuff->raw_data);
+ spin_unlock(&sbuff->raw_data.lock);
+ return avail;
+ }
desc = (struct mpq_streambuffer_buffer_desc *)
&sbuff->raw_data.data[sbuff->raw_data.pread];
+ spin_unlock(&sbuff->raw_data.lock);
+
return desc->write_ptr - desc->read_ptr;
}
EXPORT_SYMBOL(mpq_streambuffer_data_avail);
@@ -524,6 +694,14 @@
if (NULL == sbuff)
return -EINVAL;
+ spin_lock(&sbuff->raw_data.lock);
+
+ /* check if buffer was released */
+ if (sbuff->raw_data.error == -ENODEV) {
+ spin_unlock(&sbuff->raw_data.lock);
+ return -ENODEV;
+ }
+
if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
if (read_offset)
*read_offset = sbuff->raw_data.pread;
@@ -544,6 +722,8 @@
}
}
+ spin_unlock(&sbuff->raw_data.lock);
+
return 0;
}
EXPORT_SYMBOL(mpq_streambuffer_get_data_rw_offset);
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
index 9be4704..83b9bb3 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -1469,7 +1469,6 @@
dec_buffs->buffers_size,
dec_buffs->is_linear);
- feed_data->buffer_desc.decoder_buffers_num = dec_buffs->buffers_num;
if (0 == dec_buffs->buffers_num)
ret = mpq_dmx_init_internal_buffers(
feed_data, dec_buffs, client);
@@ -1515,6 +1514,8 @@
mpq_adapter_unregister_stream_if(feed_data->stream_interface);
+ mpq_streambuffer_terminate(video_buffer);
+
vfree(video_buffer->packet_data.data);
buf_num = feed_data->buffer_desc.decoder_buffers_num;
diff --git a/drivers/media/platform/msm/dvb/include/mpq_stream_buffer.h b/drivers/media/platform/msm/dvb/include/mpq_stream_buffer.h
index 3804fb2..1707c85 100644
--- a/drivers/media/platform/msm/dvb/include/mpq_stream_buffer.h
+++ b/drivers/media/platform/msm/dvb/include/mpq_stream_buffer.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -211,6 +211,18 @@
size_t packet_buff_size);
/**
+ * mpq_streambuffer_terminate - Terminate stream buffer
+ *
+ * @sbuff: The buffer to terminate
+ *
+ * The function sets the the buffers error flags to ENODEV
+ * and wakeup any waiting threads on the buffer queues.
+ * Threads waiting on the buffer queues should check if
+ * error was set.
+ */
+void mpq_streambuffer_terminate(struct mpq_streambuffer *sbuff);
+
+/**
* mpq_streambuffer_packet_next - Returns index of next available packet.
*
* @sbuff: The stream buffer
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 40e09b6..addd235 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -34,6 +34,17 @@
HFI_H264_PROFILE_CONSTRAINED_HIGH,
};
+static int entropy_mode[] = {
+ [ilog2(HAL_H264_ENTROPY_CAVLC)] = HFI_H264_ENTROPY_CAVLC,
+ [ilog2(HAL_H264_ENTROPY_CABAC)] = HFI_H264_ENTROPY_CABAC,
+};
+
+static int cabac_model[] = {
+ [ilog2(HAL_H264_CABAC_MODEL_0)] = HFI_H264_CABAC_MODEL_0,
+ [ilog2(HAL_H264_CABAC_MODEL_1)] = HFI_H264_CABAC_MODEL_1,
+ [ilog2(HAL_H264_CABAC_MODEL_2)] = HFI_H264_CABAC_MODEL_2,
+};
+
static inline int hal_to_hfi_type(int property, int hal_type)
{
if (hal_type && (roundup_pow_of_two(hal_type) != hal_type)) {
@@ -49,6 +60,12 @@
case HAL_PARAM_PROFILE_LEVEL_CURRENT:
return (hal_type >= ARRAY_SIZE(profile_table)) ?
-ENOTSUPP : profile_table[hal_type];
+ case HAL_PARAM_VENC_H264_ENTROPY_CONTROL:
+ return (hal_type >= ARRAY_SIZE(entropy_mode)) ?
+ -ENOTSUPP : entropy_mode[hal_type];
+ case HAL_PARAM_VENC_H264_ENTROPY_CABAC_MODEL:
+ return (hal_type >= ARRAY_SIZE(cabac_model)) ?
+ -ENOTSUPP : cabac_model[hal_type];
default:
return -ENOTSUPP;
}
@@ -918,35 +935,13 @@
HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL;
hfi = (struct hfi_h264_entropy_control *)
&pkt->rg_property_data[1];
- switch (prop->entropy_mode) {
- case HAL_H264_ENTROPY_CAVLC:
- hfi->cabac_model = HFI_H264_ENTROPY_CAVLC;
- break;
- case HAL_H264_ENTROPY_CABAC:
- hfi->cabac_model = HFI_H264_ENTROPY_CABAC;
- switch (prop->cabac_model) {
- case HAL_H264_CABAC_MODEL_0:
- hfi->cabac_model = HFI_H264_CABAC_MODEL_0;
- break;
- case HAL_H264_CABAC_MODEL_1:
- hfi->cabac_model = HFI_H264_CABAC_MODEL_1;
- break;
- case HAL_H264_CABAC_MODEL_2:
- hfi->cabac_model = HFI_H264_CABAC_MODEL_2;
- break;
- default:
- dprintk(VIDC_ERR,
- "Invalid cabac model 0x%x",
- prop->entropy_mode);
- break;
- }
- break;
- default:
- dprintk(VIDC_ERR,
- "Invalid entropy selected: 0x%x",
- prop->cabac_model);
- break;
- }
+ hfi->entropy_mode = hal_to_hfi_type(
+ HAL_PARAM_VENC_H264_ENTROPY_CONTROL,
+ prop->entropy_mode);
+ if (hfi->entropy_mode == HAL_H264_ENTROPY_CABAC)
+ hfi->cabac_model = hal_to_hfi_type(
+ HAL_PARAM_VENC_H264_ENTROPY_CABAC_MODEL,
+ prop->cabac_model);
pkt->size += sizeof(u32) + sizeof(
struct hfi_h264_entropy_control);
break;
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 9aa8175..bf29a95 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -1040,6 +1040,26 @@
default:
goto unknown_value;
}
+ case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
+ switch (value) {
+ case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC:
+ return HAL_H264_ENTROPY_CAVLC;
+ case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC:
+ return HAL_H264_ENTROPY_CABAC;
+ default:
+ goto unknown_value;
+ }
+ case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL:
+ switch (value) {
+ case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0:
+ return HAL_H264_CABAC_MODEL_0;
+ case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1:
+ return HAL_H264_CABAC_MODEL_1;
+ case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2:
+ return HAL_H264_CABAC_MODEL_2;
+ default:
+ goto unknown_value;
+ }
case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
switch (value) {
case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0:
@@ -1241,8 +1261,11 @@
property_id =
HAL_PARAM_VENC_H264_ENTROPY_CONTROL;
- h264_entropy_control.entropy_mode = ctrl->val;
- h264_entropy_control.cabac_model = temp_ctrl->val;
+ h264_entropy_control.entropy_mode = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, ctrl->val);
+ h264_entropy_control.cabac_model = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL,
+ temp_ctrl->val);
pdata = &h264_entropy_control;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL:
@@ -1250,8 +1273,11 @@
property_id =
HAL_PARAM_VENC_H264_ENTROPY_CONTROL;
- h264_entropy_control.cabac_model = ctrl->val;
- h264_entropy_control.entropy_mode = temp_ctrl->val;
+ h264_entropy_control.cabac_model = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, ctrl->val);
+ h264_entropy_control.entropy_mode = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL,
+ temp_ctrl->val);
pdata = &h264_entropy_control;
break;
case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
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/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 5ad0bb5..95e644b 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -165,6 +165,7 @@
HAL_PARAM_VENC_LOW_LATENCY,
HAL_PARAM_VENC_SYNC_FRAME_SEQUENCE_HEADER,
HAL_PARAM_VDEC_SYNC_FRAME_DECODE,
+ HAL_PARAM_VENC_H264_ENTROPY_CABAC_MODEL,
};
enum hal_domain {
@@ -533,15 +534,15 @@
};
*/
enum hal_h264_entropy {
- HAL_H264_ENTROPY_CAVLC,
- HAL_H264_ENTROPY_CABAC,
+ HAL_H264_ENTROPY_CAVLC = 1,
+ HAL_H264_ENTROPY_CABAC = 2,
HAL_UNUSED_ENTROPY = 0x10000000,
};
enum hal_h264_cabac_model {
- HAL_H264_CABAC_MODEL_0,
- HAL_H264_CABAC_MODEL_1,
- HAL_H264_CABAC_MODEL_2,
+ HAL_H264_CABAC_MODEL_0 = 1,
+ HAL_H264_CABAC_MODEL_1 = 2,
+ HAL_H264_CABAC_MODEL_2 = 4,
HAL_UNUSED_CABAC = 0x10000000,
};
diff --git a/drivers/media/platform/msm/wfd/wfd-ioctl.c b/drivers/media/platform/msm/wfd/wfd-ioctl.c
index 3d11400..102b9b9 100644
--- a/drivers/media/platform/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/platform/msm/wfd/wfd-ioctl.c
@@ -18,7 +18,7 @@
#include <linux/init.h>
#include <linux/version.h>
#include <linux/platform_device.h>
-#include <linux/android_pmem.h>
+
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/time.h>
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index e8096d1..2573a16 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -639,6 +639,15 @@
to the fuse block. Currently this is supported only
on FSM targets.
+config QPNP_MISC
+ tristate "QPNP Misc Peripheral"
+ depends on SPMI
+ help
+ Say 'y' here to include support for the Qualcomm QPNP MISC
+ peripheral. The MISC peripheral holds the USB ID interrupt
+ and the driver provides an API to check if this interrupt
+ is available on the current PMIC chip.
+
config USB_HSIC_SMSC_HUB
tristate "Support for HSIC based MSM on-chip SMSC3503 HUB"
depends on USB_EHCI_MSM_HSIC
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index f80f3f2..327d1ec 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -70,3 +70,4 @@
obj-$(CONFIG_QSEECOM) += qseecom.o
obj-$(CONFIG_QFP_FUSE) += qfp_fuse.o
obj-$(CONFIG_TI_DRV2667) += ti_drv2667.o
+obj-$(CONFIG_QPNP_MISC) += qpnp-misc.o
diff --git a/drivers/misc/qpnp-misc.c b/drivers/misc/qpnp-misc.c
new file mode 100644
index 0000000..608be81
--- /dev/null
+++ b/drivers/misc/qpnp-misc.c
@@ -0,0 +1,167 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/spmi.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/qpnp-misc.h>
+
+#define QPNP_MISC_DEV_NAME "qcom,qpnp-misc"
+
+#define REVID_REVISION2 0x1
+
+static DEFINE_MUTEX(qpnp_misc_dev_list_mutex);
+static LIST_HEAD(qpnp_misc_dev_list);
+
+/**
+ * struct qpnp_misc_dev - holds controller device specific information
+ * @list: Doubly-linked list parameter linking to other
+ * qpnp_misc devices.
+ * @mutex: Mutex lock that is used to ensure mutual
+ * exclusion between probing and accessing misc
+ * driver information
+ * @dev: Device pointer to the misc device
+ * @resource: Resource pointer that holds base address
+ * @spmi: Spmi pointer which holds spmi information
+ */
+struct qpnp_misc_dev {
+ struct list_head list;
+ struct mutex mutex;
+ struct device *dev;
+ struct resource *resource;
+ struct spmi_device *spmi;
+};
+
+static struct of_device_id qpnp_misc_match_table[] = {
+ { .compatible = QPNP_MISC_DEV_NAME },
+ {}
+};
+
+static u8 qpnp_read_byte(struct spmi_device *spmi, u16 addr)
+{
+ int rc;
+ u8 val;
+
+ rc = spmi_ext_register_readl(spmi->ctrl, spmi->sid, addr, &val, 1);
+ if (rc) {
+ pr_err("SPMI read failed rc=%d\n", rc);
+ return 0;
+ }
+ return val;
+}
+
+#define REV2_IRQ_AVAILABLE_VERSION 2
+static bool __misc_irqs_available(struct qpnp_misc_dev *dev)
+{
+ u8 rev2;
+
+ rev2 = qpnp_read_byte(dev->spmi,
+ dev->resource->start + REVID_REVISION2);
+ pr_debug("rev2 0x%x\n", rev2);
+
+ if (rev2 >= REV2_IRQ_AVAILABLE_VERSION)
+ return 1;
+
+ return 0;
+}
+
+int qpnp_misc_irqs_available(struct device *consumer_dev)
+{
+ struct device_node *misc_node = NULL;
+ struct qpnp_misc_dev *mdev = NULL;
+ struct qpnp_misc_dev *mdev_found = NULL;
+
+ misc_node = of_parse_phandle(consumer_dev->of_node, "qcom,misc-ref", 0);
+ if (!misc_node) {
+ pr_debug("Could not find qcom,misc-ref property in %s\n",
+ consumer_dev->of_node->full_name);
+ return 0;
+ }
+
+ mutex_lock(&qpnp_misc_dev_list_mutex);
+ list_for_each_entry(mdev, &qpnp_misc_dev_list, list) {
+ if (mdev->dev->of_node == misc_node) {
+ mdev_found = mdev;
+ break;
+ }
+ }
+ mutex_unlock(&qpnp_misc_dev_list_mutex);
+
+ if (!mdev_found) {
+ /* No MISC device was found. This API should only
+ * be called by drivers which have specified the
+ * misc phandle in their device tree node */
+ pr_err("no probed misc device found\n");
+ return -EPROBE_DEFER;
+ }
+
+ return __misc_irqs_available(mdev_found);
+}
+
+static int __devinit qpnp_misc_probe(struct spmi_device *spmi)
+{
+ struct resource *resource;
+ struct qpnp_misc_dev *mdev = ERR_PTR(-EINVAL);
+
+ resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
+ if (!resource) {
+ pr_err("Unable to get spmi resource for MISC\n");
+ return -EINVAL;
+ }
+
+ mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
+ if (!mdev) {
+ pr_err("allocation failed\n");
+ return -ENOMEM;
+ }
+
+ mdev->spmi = spmi;
+ mdev->dev = &(spmi->dev);
+ mdev->resource = resource;
+
+ mutex_lock(&qpnp_misc_dev_list_mutex);
+ list_add_tail(&mdev->list, &qpnp_misc_dev_list);
+ mutex_unlock(&qpnp_misc_dev_list_mutex);
+
+ pr_debug("probed successfully\n");
+ return 0;
+}
+
+static struct spmi_driver qpnp_misc_driver = {
+ .probe = qpnp_misc_probe,
+ .driver = {
+ .name = QPNP_MISC_DEV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = qpnp_misc_match_table,
+ },
+};
+
+static int __init qpnp_misc_init(void)
+{
+ return spmi_driver_register(&qpnp_misc_driver);
+}
+
+static void __exit qpnp_misc_exit(void)
+{
+ return spmi_driver_unregister(&qpnp_misc_driver);
+}
+
+module_init(qpnp_misc_init);
+module_exit(qpnp_misc_exit);
+
+MODULE_DESCRIPTION(QPNP_MISC_DEV_NAME);
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" QPNP_MISC_DEV_NAME);
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 9e22ffb..77a412f 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -57,7 +57,6 @@
#define QSEOS_CHECK_VERSION_CMD 0x00001803
#define QSEE_CE_CLK_100MHZ 100000000
-#define QSEE_CE_CLK_50MHZ 50000000
#define QSEECOM_MAX_SG_ENTRY 512
@@ -1387,6 +1386,14 @@
}
/* Populate the remaining parameters */
load_req.qsee_cmd_id = QSEOS_LOAD_SERV_IMAGE_COMMAND;
+ /* Vote for the SFPB clock */
+ ret = qsee_vote_for_clock(data, CLK_SFPB);
+ if (ret) {
+ pr_err("Unable to vote for SFPB clock: ret = %d", ret);
+ kzfree(img_data);
+ return -EIO;
+ }
+
/* SCM_CALL to load the image */
ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &load_req,
sizeof(struct qseecom_load_lib_image_ireq),
@@ -1417,6 +1424,7 @@
}
}
kzfree(img_data);
+ qsee_disable_clock_vote(data, CLK_SFPB);
return ret;
}
@@ -1746,6 +1754,50 @@
return 0;
}
+static int __qseecom_enable_clk(void)
+{
+ int rc = 0;
+
+ /* Enable CE core clk */
+ rc = clk_prepare_enable(ce_core_clk);
+ if (rc) {
+ pr_err("Unable to enable/prepare CE core clk\n");
+ goto err;
+ } else {
+ /* Enable CE clk */
+ rc = clk_prepare_enable(ce_clk);
+ if (rc) {
+ pr_err("Unable to enable/prepare CE iface clk\n");
+ goto ce_clk_err;
+ } else {
+ /* Enable AXI clk */
+ rc = clk_prepare_enable(ce_bus_clk);
+ if (rc) {
+ pr_err("Unable to enable/prepare CE bus clk\n");
+ goto ce_bus_clk_err;
+ }
+ }
+ }
+ return 0;
+
+ce_bus_clk_err:
+ clk_disable_unprepare(ce_clk);
+ce_clk_err:
+ clk_disable_unprepare(ce_core_clk);
+err:
+ return -EIO;
+}
+
+static void __qseecom_disable_clk(void)
+{
+ if (ce_clk != NULL)
+ clk_disable_unprepare(ce_clk);
+ if (ce_core_clk != NULL)
+ clk_disable_unprepare(ce_core_clk);
+ if (ce_bus_clk != NULL)
+ clk_disable_unprepare(ce_bus_clk);
+}
+
static int qsee_vote_for_clock(struct qseecom_dev_handle *data,
int32_t clk_type)
{
@@ -1763,10 +1815,14 @@
qsee_perf_client, 3);
else {
if (ce_core_src_clk != NULL)
- clk_set_rate(ce_core_src_clk,
- QSEE_CE_CLK_100MHZ);
- ret = msm_bus_scale_client_update_request(
+ ret = __qseecom_enable_clk();
+ if (!ret) {
+ ret =
+ msm_bus_scale_client_update_request(
qsee_perf_client, 1);
+ if ((ret) && (ce_core_src_clk != NULL))
+ __qseecom_disable_clk();
+ }
}
if (ret)
pr_err("DFAB Bandwidth req failed (%d)\n",
@@ -1789,10 +1845,14 @@
qsee_perf_client, 3);
else {
if (ce_core_src_clk != NULL)
- clk_set_rate(ce_core_src_clk,
- QSEE_CE_CLK_100MHZ);
- ret = msm_bus_scale_client_update_request(
+ ret = __qseecom_enable_clk();
+ if (!ret) {
+ ret =
+ msm_bus_scale_client_update_request(
qsee_perf_client, 2);
+ if ((ret) && (ce_core_src_clk != NULL))
+ __qseecom_disable_clk();
+ }
}
if (ret)
@@ -1839,9 +1899,8 @@
else {
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 0);
- if (ce_core_src_clk != NULL)
- clk_set_rate(ce_core_src_clk,
- QSEE_CE_CLK_50MHZ);
+ if ((!ret) && (ce_core_src_clk != NULL))
+ __qseecom_disable_clk();
}
if (ret)
pr_err("SFPB Bandwidth req fail (%d)\n",
@@ -1870,9 +1929,8 @@
else {
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 0);
- if (ce_core_src_clk != NULL)
- clk_set_rate(ce_core_src_clk,
- QSEE_CE_CLK_50MHZ);
+ if ((!ret) && (ce_core_src_clk != NULL))
+ __qseecom_disable_clk();
}
if (ret)
pr_err("SFPB Bandwidth req fail (%d)\n",
@@ -1941,6 +1999,13 @@
ret = -EFAULT;
goto qseecom_load_external_elf_set_cpu_err;
}
+ /* Vote for the SFPB clock */
+ ret = qsee_vote_for_clock(data, CLK_SFPB);
+ if (ret) {
+ pr_err("Unable to vote for SFPB clock: ret = %d", ret);
+ ret = -EIO;
+ goto qseecom_load_external_elf_set_cpu_err;
+ }
/* SCM_CALL to load the external elf */
ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &load_req,
@@ -1980,7 +2045,7 @@
/* Deallocate the handle */
if (!IS_ERR_OR_NULL(ihandle))
ion_free(qseecom.ion_clnt, ihandle);
-
+ qsee_disable_clock_vote(data, CLK_SFPB);
return ret;
}
@@ -2350,46 +2415,6 @@
.release = qseecom_release
};
-static int __qseecom_enable_clk(void)
-{
- int rc = 0;
-
- /* Enable CE core clk */
- rc = clk_prepare_enable(ce_core_clk);
- if (rc) {
- pr_err("Unable to enable/prepare CE core clk\n");
- return -EIO;
- } else {
- /* Enable CE clk */
- rc = clk_prepare_enable(ce_clk);
- if (rc) {
- pr_err("Unable to enable/prepare CE iface clk\n");
- clk_disable_unprepare(ce_core_clk);
- return -EIO;
- } else {
- /* Enable AXI clk */
- rc = clk_prepare_enable(ce_bus_clk);
- if (rc) {
- pr_err("Unable to enable/prepare CE iface clk\n");
- clk_disable_unprepare(ce_core_clk);
- clk_disable_unprepare(ce_clk);
- return -EIO;
- }
- }
- }
- return rc;
-}
-
-static void __qseecom_disable_clk(void)
-{
- if (ce_clk != NULL)
- clk_disable_unprepare(ce_clk);
- if (ce_core_clk != NULL)
- clk_disable_unprepare(ce_core_clk);
- if (ce_bus_clk != NULL)
- clk_disable_unprepare(ce_bus_clk);
-}
-
static int __qseecom_init_clk(void)
{
int rc = 0;
@@ -2399,8 +2424,8 @@
/* Get CE3 src core clk. */
ce_core_src_clk = clk_get(pdev, "core_clk_src");
if (!IS_ERR(ce_core_src_clk)) {
- /* Set the core src clk @50Mhz */
- rc = clk_set_rate(ce_core_src_clk, QSEE_CE_CLK_50MHZ);
+ /* Set the core src clk @100Mhz */
+ rc = clk_set_rate(ce_core_src_clk, QSEE_CE_CLK_100MHZ);
if (rc) {
clk_put(ce_core_src_clk);
pr_err("Unable to set the core src clk @100Mhz.\n");
@@ -2561,11 +2586,7 @@
ret = __qseecom_init_clk();
if (ret)
goto err;
- ret = __qseecom_enable_clk();
- if (ret) {
- __qseecom_deinit_clk();
- goto err;
- }
+
qseecom_platform_support = (struct msm_bus_scale_pdata *)
msm_bus_cl_get_pdata(pdev);
if (qseecom.qsee_version >= (QSEE_VERSION_02)) {
@@ -2675,10 +2696,9 @@
if (qsee_perf_client)
msm_bus_scale_client_update_request(qsee_perf_client, 0);
/* register client for bus scaling */
- if (pdev->dev.of_node) {
- __qseecom_disable_clk();
+ if (pdev->dev.of_node)
__qseecom_deinit_clk();
- }
+
return ret;
};
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 7bae401..2769709 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>
@@ -102,6 +103,10 @@
0xFFFFBBBB, 0xFFFF77FF, 0xFF7777FF, 0xEEDDBB77
};
+static int disable_slots;
+/* root can write, others read */
+module_param(disable_slots, int, S_IRUGO|S_IWUSR);
+
/* This structure keeps information per regulator */
struct sdhci_msm_reg_data {
/* voltage regulator handle */
@@ -198,13 +203,14 @@
u32 caps2;
unsigned long mmc_bus_width;
- u32 max_clk;
struct sdhci_msm_slot_reg_data *vreg_data;
bool nonremovable;
struct sdhci_msm_pin_data *pin_data;
u32 cpu_dma_latency_us;
int status_gpio; /* card detection GPIO that is configured as IRQ */
struct sdhci_msm_bus_voting_data *voting_data;
+ u32 *sup_clk_table;
+ unsigned char sup_clk_cnt;
};
struct sdhci_msm_bus_vote {
@@ -228,8 +234,11 @@
struct sdhci_msm_pltfm_data *pdata;
struct mmc_host *mmc;
struct sdhci_pltfm_data sdhci_msm_pdata;
- wait_queue_head_t pwr_irq_wait;
+ u32 curr_pwr_state;
+ u32 curr_io_level;
+ struct completion pwr_irq_completion;
struct sdhci_msm_bus_vote msm_bus_vote;
+ u32 clk_rate; /* Keeps track of current clock rate that is set */
};
enum vdd_io_level {
@@ -549,9 +558,18 @@
int size = sizeof(tuning_block_64); /* Tuning pattern size in bytes */
int rc;
struct mmc_host *mmc = host->mmc;
+ struct mmc_ios ios = host->mmc->ios;
+
+ /*
+ * Tuning is required for SDR104 and HS200 cards and if clock frequency
+ * is greater than 100MHz in these modes.
+ */
+ if (host->clock <= (100 * 1000 * 1000) ||
+ !(ios.timing == MMC_TIMING_MMC_HS200 ||
+ ios.timing == MMC_TIMING_UHS_SDR104))
+ return 0;
pr_debug("%s: Enter %s\n", mmc_hostname(mmc), __func__);
- /* Tuning is only required for SDR104 modes */
spin_lock_irqsave(&host->lock, flags);
if ((opcode == MMC_SEND_TUNING_BLOCK_HS200) &&
@@ -1073,6 +1091,8 @@
u32 bus_width = 0;
u32 cpu_dma_latency;
int len, i;
+ int clk_table_len;
+ u32 *clk_table = NULL;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
@@ -1096,6 +1116,18 @@
&cpu_dma_latency))
pdata->cpu_dma_latency_us = cpu_dma_latency;
+ if (sdhci_msm_dt_get_array(dev, "qcom,clk-rates",
+ &clk_table, &clk_table_len, 0)) {
+ dev_err(dev, "failed parsing supported clock rates\n");
+ goto out;
+ }
+ if (!clk_table || !clk_table_len) {
+ dev_err(dev, "Invalid clock table\n");
+ goto out;
+ }
+ pdata->sup_clk_table = clk_table;
+ pdata->sup_clk_cnt = clk_table_len;
+
pdata->vreg_data = devm_kzalloc(dev, sizeof(struct
sdhci_msm_slot_reg_data),
GFP_KERNEL);
@@ -1121,8 +1153,6 @@
goto out;
}
- of_property_read_u32(np, "qcom,max-clk-rate", &pdata->max_clk);
-
len = of_property_count_strings(np, "qcom,bus-speed-mode");
for (i = 0; i < len; i++) {
@@ -1637,6 +1667,8 @@
u8 irq_status = 0;
u8 irq_ack = 0;
int ret = 0;
+ int pwr_state = 0, io_level = 0;
+ unsigned long flags;
irq_status = readb_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS);
pr_debug("%s: Received IRQ(%d), status=0x%x\n",
@@ -1655,21 +1687,33 @@
/* Handle BUS ON/OFF*/
if (irq_status & CORE_PWRCTL_BUS_ON) {
ret = sdhci_msm_setup_vreg(msm_host->pdata, true, false);
- if (!ret)
+ if (!ret) {
ret = sdhci_msm_setup_pins(msm_host->pdata, true);
+ ret |= sdhci_msm_set_vdd_io_vol(msm_host->pdata,
+ VDD_IO_HIGH, 0);
+ }
if (ret)
irq_ack |= CORE_PWRCTL_BUS_FAIL;
else
irq_ack |= CORE_PWRCTL_BUS_SUCCESS;
+
+ pwr_state = REQ_BUS_ON;
+ io_level = REQ_IO_HIGH;
}
if (irq_status & CORE_PWRCTL_BUS_OFF) {
ret = sdhci_msm_setup_vreg(msm_host->pdata, false, false);
- if (!ret)
+ if (!ret) {
ret = sdhci_msm_setup_pins(msm_host->pdata, false);
+ ret |= sdhci_msm_set_vdd_io_vol(msm_host->pdata,
+ VDD_IO_LOW, 0);
+ }
if (ret)
irq_ack |= CORE_PWRCTL_BUS_FAIL;
else
irq_ack |= CORE_PWRCTL_BUS_SUCCESS;
+
+ pwr_state = REQ_BUS_OFF;
+ io_level = REQ_IO_LOW;
}
/* Handle IO LOW/HIGH */
if (irq_status & CORE_PWRCTL_IO_LOW) {
@@ -1679,6 +1723,8 @@
irq_ack |= CORE_PWRCTL_IO_FAIL;
else
irq_ack |= CORE_PWRCTL_IO_SUCCESS;
+
+ io_level = REQ_IO_LOW;
}
if (irq_status & CORE_PWRCTL_IO_HIGH) {
/* Switch voltage High */
@@ -1687,6 +1733,8 @@
irq_ack |= CORE_PWRCTL_IO_FAIL;
else
irq_ack |= CORE_PWRCTL_IO_SUCCESS;
+
+ io_level = REQ_IO_HIGH;
}
/* ACK status to the core */
@@ -1699,11 +1747,11 @@
*/
mb();
- if (irq_status & CORE_PWRCTL_IO_HIGH)
+ if (io_level & REQ_IO_HIGH)
writel_relaxed((readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC) &
~CORE_IO_PAD_PWR_SWITCH),
host->ioaddr + CORE_VENDOR_SPEC);
- if (irq_status & CORE_PWRCTL_IO_LOW)
+ else if (io_level & REQ_IO_LOW)
writel_relaxed((readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC) |
CORE_IO_PAD_PWR_SWITCH),
host->ioaddr + CORE_VENDOR_SPEC);
@@ -1711,7 +1759,14 @@
pr_debug("%s: Handled IRQ(%d), ret=%d, ack=0x%x\n",
mmc_hostname(msm_host->mmc), irq, ret, irq_ack);
- wake_up_interruptible(&msm_host->pwr_irq_wait);
+ spin_lock_irqsave(&host->lock, flags);
+ if (pwr_state)
+ msm_host->curr_pwr_state = pwr_state;
+ if (io_level)
+ msm_host->curr_io_level = io_level;
+ complete(&msm_host->pwr_irq_completion);
+ spin_unlock_irqrestore(&host->lock, flags);
+
return IRQ_HANDLED;
}
@@ -1757,25 +1812,36 @@
return count;
}
-static void sdhci_msm_check_power_status(struct sdhci_host *host)
+static void sdhci_msm_check_power_status(struct sdhci_host *host, u32 req_type)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_msm_host *msm_host = pltfm_host->priv;
- int ret = 0;
+ unsigned long flags;
+ bool done = false;
- pr_debug("%s: %s: power status before waiting 0x%x\n",
- mmc_hostname(host->mmc), __func__,
- readb_relaxed(msm_host->core_mem + CORE_PWRCTL_CTL));
+ spin_lock_irqsave(&host->lock, flags);
+ pr_debug("%s: %s: request %d curr_pwr_state %x curr_io_level %x\n",
+ mmc_hostname(host->mmc), __func__, req_type,
+ msm_host->curr_pwr_state, msm_host->curr_io_level);
+ if ((req_type & msm_host->curr_pwr_state) ||
+ (req_type & msm_host->curr_io_level))
+ done = true;
+ spin_unlock_irqrestore(&host->lock, flags);
- ret = wait_event_interruptible(msm_host->pwr_irq_wait,
- (readb_relaxed(msm_host->core_mem +
- CORE_PWRCTL_CTL)) != 0x0);
- if (ret)
- pr_warning("%s: %s: returned due to error %d\n",
- mmc_hostname(host->mmc), __func__, ret);
- pr_debug("%s: %s: ret %d power status after handling power IRQ 0x%x\n",
- mmc_hostname(host->mmc), __func__, ret,
- readb_relaxed(msm_host->core_mem + CORE_PWRCTL_CTL));
+ /*
+ * This is needed here to hanlde a case where IRQ gets
+ * triggered even before this function is called so that
+ * x->done counter of completion gets reset. Otherwise,
+ * next call to wait_for_completion returns immediately
+ * without actually waiting for the IRQ to be handled.
+ */
+ if (done)
+ init_completion(&msm_host->pwr_irq_completion);
+ else
+ wait_for_completion(&msm_host->pwr_irq_completion);
+
+ pr_debug("%s: %s: request %d done\n", mmc_hostname(host->mmc),
+ __func__, req_type);
}
static void sdhci_msm_toggle_cdr(struct sdhci_host *host, bool enable)
@@ -1795,16 +1861,58 @@
return SDHCI_MSM_MAX_SEGMENTS;
}
-void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
+static unsigned int sdhci_msm_get_min_clock(struct sdhci_host *host)
{
- int rc;
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_msm_host *msm_host = pltfm_host->priv;
- unsigned long flags;
- if (clock && !atomic_read(&msm_host->clks_on)) {
- pr_debug("%s: request to enable clock at rate %u\n",
- mmc_hostname(host->mmc), clock);
+ return msm_host->pdata->sup_clk_table[0];
+}
+
+static unsigned int sdhci_msm_get_max_clock(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
+ int max_clk_index = msm_host->pdata->sup_clk_cnt;
+
+ return msm_host->pdata->sup_clk_table[max_clk_index - 1];
+}
+
+static unsigned int sdhci_msm_get_sup_clk_rate(struct sdhci_host *host,
+ u32 req_clk)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
+ unsigned int sel_clk = -1;
+ unsigned char cnt;
+
+ if (req_clk < sdhci_msm_get_min_clock(host)) {
+ sel_clk = sdhci_msm_get_min_clock(host);
+ return sel_clk;
+ }
+
+ for (cnt = 0; cnt < msm_host->pdata->sup_clk_cnt; cnt++) {
+ if (msm_host->pdata->sup_clk_table[cnt] > req_clk) {
+ break;
+ } else if (msm_host->pdata->sup_clk_table[cnt] == req_clk) {
+ sel_clk = msm_host->pdata->sup_clk_table[cnt];
+ break;
+ } else {
+ sel_clk = msm_host->pdata->sup_clk_table[cnt];
+ }
+ }
+ return sel_clk;
+}
+
+static int sdhci_msm_prepare_clocks(struct sdhci_host *host, bool enable)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
+ int rc = 0;
+
+ if (enable && !atomic_read(&msm_host->clks_on)) {
+ pr_debug("%s: request to enable clocks\n",
+ mmc_hostname(host->mmc));
if (!IS_ERR_OR_NULL(msm_host->bus_clk)) {
rc = clk_prepare_enable(msm_host->bus_clk);
if (rc) {
@@ -1828,9 +1936,8 @@
goto disable_pclk;
}
mb();
- atomic_set(&msm_host->clks_on, 1);
- } else if (!clock && atomic_read(&msm_host->clks_on)) {
+ } else if (!enable && atomic_read(&msm_host->clks_on)) {
pr_debug("%s: request to disable clocks\n",
mmc_hostname(host->mmc));
sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
@@ -1840,11 +1947,8 @@
clk_disable_unprepare(msm_host->pclk);
if (!IS_ERR_OR_NULL(msm_host->bus_clk))
clk_disable_unprepare(msm_host->bus_clk);
- atomic_set(&msm_host->clks_on, 0);
}
- spin_lock_irqsave(&host->lock, flags);
- host->clock = clock;
- spin_unlock_irqrestore(&host->lock, flags);
+ atomic_set(&msm_host->clks_on, enable);
goto out;
disable_pclk:
if (!IS_ERR_OR_NULL(msm_host->pclk))
@@ -1853,16 +1957,100 @@
if (!IS_ERR_OR_NULL(msm_host->bus_clk))
clk_disable_unprepare(msm_host->bus_clk);
out:
- return;
+ return rc;
+}
+
+static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+ int rc;
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
+ struct mmc_ios curr_ios = host->mmc->ios;
+ u32 sup_clock, ddr_clock;
+
+ if (!clock) {
+ sdhci_msm_prepare_clocks(host, false);
+ host->clock = clock;
+ return;
+ }
+
+ rc = sdhci_msm_prepare_clocks(host, true);
+ if (rc)
+ return;
+
+ sup_clock = sdhci_msm_get_sup_clk_rate(host, clock);
+ if (curr_ios.timing == MMC_TIMING_UHS_DDR50) {
+ /*
+ * The SDHC requires internal clock frequency to be double the
+ * actual clock that will be set for DDR mode. The controller
+ * uses the faster clock(100MHz) for some of its parts and send
+ * the actual required clock (50MHz) to the card.
+ */
+ ddr_clock = clock * 2;
+ sup_clock = sdhci_msm_get_sup_clk_rate(host,
+ ddr_clock);
+ }
+ if (sup_clock != msm_host->clk_rate) {
+ pr_debug("%s: %s: setting clk rate to %u\n",
+ mmc_hostname(host->mmc), __func__, sup_clock);
+ rc = clk_set_rate(msm_host->clk, sup_clock);
+ if (rc) {
+ pr_err("%s: %s: Failed to set rate %u for host-clk : %d\n",
+ mmc_hostname(host->mmc), __func__,
+ sup_clock, rc);
+ return;
+ }
+ msm_host->clk_rate = sup_clock;
+ host->clock = clock;
+ }
+}
+
+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;
+ /*
+ * When clock frquency is less than 100MHz, the feedback clock must be
+ * provided and DLL must not be used so that tuning can be skipped. To
+ * provide feedback clock, the mode selection can be any value less
+ * than 3'b011 in bits [2:0] of HOST CONTROL2 register.
+ */
+ if (host->clock <= (100 * 1000 * 1000) &&
+ (uhs == MMC_TIMING_MMC_HS200 ||
+ uhs == MMC_TIMING_UHS_SDR104))
+ ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
+
+ 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,
.get_max_segments = sdhci_msm_max_segs,
.set_clock = sdhci_msm_set_clock,
.platform_bus_voting = sdhci_msm_bus_voting,
+ .get_min_clock = sdhci_msm_get_min_clock,
+ .get_max_clock = sdhci_msm_get_max_clock,
};
static int __devinit sdhci_msm_probe(struct platform_device *pdev)
@@ -1882,7 +2070,6 @@
ret = -ENOMEM;
goto out;
}
- init_waitqueue_head(&msm_host->pwr_irq_wait);
msm_host->sdhci_msm_pdata.ops = &sdhci_msm_ops;
host = sdhci_pltfm_init(pdev, &msm_host->sdhci_msm_pdata);
@@ -1898,6 +2085,19 @@
/* Extract platform data */
if (pdev->dev.of_node) {
+ ret = of_alias_get_id(pdev->dev.of_node, "sdhc");
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to get slot index %d\n",
+ ret);
+ goto pltfm_free;
+ }
+ if (disable_slots & (1 << (ret - 1))) {
+ dev_info(&pdev->dev, "%s: Slot %d disabled\n", __func__,
+ ret);
+ ret = -ENODEV;
+ goto pltfm_free;
+ }
+
msm_host->pdata = sdhci_msm_populate_pdata(&pdev->dev);
if (!msm_host->pdata) {
dev_err(&pdev->dev, "DT parsing error\n");
@@ -1941,7 +2141,15 @@
if (ret)
goto pclk_disable;
+ /* Set to the minimum supported clock frequency */
+ ret = clk_set_rate(msm_host->clk, sdhci_msm_get_min_clock(host));
+ if (ret) {
+ dev_err(&pdev->dev, "MClk rate set failed (%d)\n", ret);
+ goto clk_disable;
+ }
+ msm_host->clk_rate = sdhci_msm_get_min_clock(host);
atomic_set(&msm_host->clks_on, 1);
+
/* Setup regulators */
ret = sdhci_msm_vreg_init(&pdev->dev, msm_host->pdata, true);
if (ret) {
@@ -1973,6 +2181,8 @@
*/
host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
host->quirks |= SDHCI_QUIRK_SINGLE_POWER_WRITE;
+ host->quirks |= SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN;
+ host->quirks2 |= SDHCI_QUIRK2_ALWAYS_USE_BASE_CLOCK;
host->quirks2 |= SDHCI_QUIRK2_IGNORE_CMDCRC_FOR_TUNING;
host_version = readl_relaxed((host->ioaddr + SDHCI_HOST_VERSION));
@@ -2045,6 +2255,7 @@
msm_host->mmc->caps2 |= MMC_CAP2_CACHE_CTRL;
msm_host->mmc->caps2 |= MMC_CAP2_INIT_BKOPS;
msm_host->mmc->caps2 |= MMC_CAP2_POWEROFF_NOTIFY;
+ msm_host->mmc->caps2 |= MMC_CAP2_CLK_SCALE;
if (msm_host->pdata->nonremovable)
msm_host->mmc->caps |= MMC_CAP_NONREMOVABLE;
@@ -2059,6 +2270,8 @@
INIT_DELAYED_WORK(&msm_host->msm_bus_vote.vote_work,
sdhci_msm_bus_work);
+ init_completion(&msm_host->pwr_irq_completion);
+
if (gpio_is_valid(msm_host->pdata->status_gpio)) {
ret = mmc_cd_gpio_request(msm_host->mmc,
msm_host->pdata->status_gpio);
@@ -2069,21 +2282,19 @@
}
}
+ 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);
goto free_cd_gpio;
}
- /* Set core clk rate, optionally override from dts */
- if (msm_host->pdata->max_clk)
- host->max_clk = msm_host->pdata->max_clk;
- ret = clk_set_rate(msm_host->clk, host->max_clk);
- if (ret) {
- dev_err(&pdev->dev, "MClk rate set failed (%d)\n", ret);
- goto remove_host;
- }
-
msm_host->msm_bus_vote.max_bus_bw.show = show_sdhci_max_bus_bw;
msm_host->msm_bus_vote.max_bus_bw.store = store_sdhci_max_bus_bw;
sysfs_attr_init(&msm_host->msm_bus_vote.max_bus_bw.attr);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 0a89ea2..c247ae9 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -197,7 +197,7 @@
if (host->ops->check_power_status && host->pwr &&
(mask & SDHCI_RESET_ALL))
- host->ops->check_power_status(host);
+ host->ops->check_power_status(host, REQ_BUS_OFF);
/* hw clears the bit when it's done */
while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
@@ -1209,6 +1209,9 @@
if (real_div)
host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div;
+ if (host->quirks2 & SDHCI_QUIRK2_ALWAYS_USE_BASE_CLOCK)
+ div = 0;
+
clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
<< SDHCI_DIVIDER_HI_SHIFT;
@@ -1268,7 +1271,7 @@
if (pwr == 0) {
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
if (host->ops->check_power_status)
- host->ops->check_power_status(host);
+ host->ops->check_power_status(host, REQ_BUS_OFF);
return 0;
}
@@ -1279,7 +1282,7 @@
if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) {
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
if (host->ops->check_power_status)
- host->ops->check_power_status(host);
+ host->ops->check_power_status(host, REQ_BUS_OFF);
}
/*
@@ -1289,14 +1292,14 @@
if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER) {
sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
if (host->ops->check_power_status)
- host->ops->check_power_status(host);
+ host->ops->check_power_status(host, REQ_BUS_ON);
}
pwr |= SDHCI_POWER_ON;
sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
if (host->ops->check_power_status)
- host->ops->check_power_status(host);
+ host->ops->check_power_status(host, REQ_BUS_ON);
/*
* Some controllers need an extra 10ms delay of 10ms before they
@@ -1741,7 +1744,7 @@
ctrl &= ~SDHCI_CTRL_VDD_180;
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
if (host->ops->check_power_status)
- host->ops->check_power_status(host);
+ host->ops->check_power_status(host, REQ_IO_HIGH);
/* Wait for 5ms */
usleep_range(5000, 5500);
@@ -1773,7 +1776,7 @@
ctrl |= SDHCI_CTRL_VDD_180;
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
if (host->ops->check_power_status)
- host->ops->check_power_status(host);
+ host->ops->check_power_status(host, REQ_IO_LOW);
/* Wait for 5ms */
usleep_range(5000, 5500);
@@ -1807,14 +1810,14 @@
pwr &= ~SDHCI_POWER_ON;
sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
if (host->ops->check_power_status)
- host->ops->check_power_status(host);
+ host->ops->check_power_status(host, REQ_BUS_OFF);
/* Wait for 1ms as per the spec */
usleep_range(1000, 1500);
pwr |= SDHCI_POWER_ON;
sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
if (host->ops->check_power_status)
- host->ops->check_power_status(host);
+ host->ops->check_power_status(host, REQ_BUS_ON);
pr_info(DRIVER_NAME ": Switching to 1.8V signalling "
"voltage failed, retrying with S18R set to 0\n");
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 49d7957..c6bef8a 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -277,7 +277,11 @@
void (*hw_reset)(struct sdhci_host *host);
void (*platform_suspend)(struct sdhci_host *host);
void (*platform_resume)(struct sdhci_host *host);
- void (*check_power_status)(struct sdhci_host *host);
+ void (*check_power_status)(struct sdhci_host *host, u32 req_type);
+#define REQ_BUS_OFF (1 << 0)
+#define REQ_BUS_ON (1 << 1)
+#define REQ_IO_LOW (1 << 2)
+#define REQ_IO_HIGH (1 << 3)
int (*execute_tuning)(struct sdhci_host *host, u32 opcode);
void (*toggle_cdr)(struct sdhci_host *host, bool enable);
unsigned int (*get_max_segments)(void);
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_bridge.c b/drivers/platform/msm/ipa/ipa_bridge.c
index 0227ee4..eeb98e9 100644
--- a/drivers/platform/msm/ipa/ipa_bridge.c
+++ b/drivers/platform/msm/ipa/ipa_bridge.c
@@ -43,6 +43,7 @@
struct sps_mem_buffer desc_mem_buf;
struct sps_register_event register_event;
struct list_head free_desc_list;
+ bool valid;
};
struct ipa_bridge_context {
@@ -465,6 +466,7 @@
}
*clnt_hdl = ipa_ep_idx;
+ sys->valid = true;
return 0;
@@ -620,6 +622,8 @@
}
}
+ sys->valid = true;
+
return 0;
event_reg_failed:
@@ -809,12 +813,15 @@
for (; lo <= hi; lo++) {
sys = &bridge[type].pipe[lo];
- sps_disconnect(sys->pipe);
- dma_free_coherent(NULL, sys->desc_mem_buf.size,
- sys->desc_mem_buf.base,
- sys->desc_mem_buf.phys_base);
- sps_free_endpoint(sys->pipe);
- ipa_bridge_free_resources(sys);
+ if (sys->valid) {
+ sps_disconnect(sys->pipe);
+ dma_free_coherent(NULL, sys->desc_mem_buf.size,
+ sys->desc_mem_buf.base,
+ sys->desc_mem_buf.phys_base);
+ sps_free_endpoint(sys->pipe);
+ ipa_bridge_free_resources(sys);
+ sys->valid = false;
+ }
}
memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context));
diff --git a/drivers/platform/msm/ipa/ipa_client.c b/drivers/platform/msm/ipa/ipa_client.c
index b57585c..a4b7e22 100644
--- a/drivers/platform/msm/ipa/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_client.c
@@ -33,56 +33,17 @@
static int ipa_disable_data_path(u32 clnt_hdl)
{
- DECLARE_COMPLETION_ONSTACK(tag_rsp);
- struct ipa_desc desc = {0};
- struct ipa_ip_packet_tag cmd;
struct ipa_ep_context *ep = &ipa_ctx->ep[clnt_hdl];
- struct ipa_tree_node *node;
- int result = 0;
if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_VIRTUAL) {
/* IPA_HW_MODE_VIRTUAL lacks support for TAG IC & EP suspend */
return 0;
}
- node = kmem_cache_zalloc(ipa_ctx->tree_node_cache, GFP_KERNEL);
- if (!node) {
- IPAERR("failed to alloc tree node object\n");
- result = -ENOMEM;
- goto fail_alloc;
- }
-
if (ipa_ctx->ipa_hw_type == IPA_HW_v1_1 && !ep->suspended) {
ipa_write_reg(ipa_ctx->mmio,
IPA_ENDP_INIT_CTRL_n_OFST(clnt_hdl), 1);
- cmd.tag = (u32) &tag_rsp;
-
- desc.pyld = &cmd;
- desc.len = sizeof(struct ipa_ip_packet_tag);
- desc.type = IPA_IMM_CMD_DESC;
- desc.opcode = IPA_IP_PACKET_TAG;
-
- IPADBG("Wait on TAG %p clnt=%d\n", &tag_rsp, clnt_hdl);
-
- node->hdl = cmd.tag;
- mutex_lock(&ipa_ctx->lock);
- if (ipa_insert(&ipa_ctx->tag_tree, node)) {
- IPAERR("failed to add to tree\n");
- result = -EINVAL;
- mutex_unlock(&ipa_ctx->lock);
- goto fail_insert;
- }
- mutex_unlock(&ipa_ctx->lock);
-
- if (ipa_send_cmd(1, &desc)) {
- ipa_write_reg(ipa_ctx->mmio,
- IPA_ENDP_INIT_CTRL_n_OFST(clnt_hdl), 0);
- IPAERR("fail to send TAG command\n");
- result = -EPERM;
- goto fail_send;
- }
- wait_for_completion(&tag_rsp);
if (IPA_CLIENT_IS_CONS(ep->client) &&
ep->cfg.aggr.aggr_en == IPA_ENABLE_AGGR &&
ep->cfg.aggr.aggr_time_limit)
@@ -91,13 +52,6 @@
}
return 0;
-
-fail_send:
- rb_erase(&node->node, &ipa_ctx->tag_tree);
-fail_insert:
- kmem_cache_free(ipa_ctx->tree_node_cache, node);
-fail_alloc:
- return result;
}
static int ipa_connect_configure_sps(const struct ipa_connect_params *in,
@@ -310,6 +264,8 @@
IPA_HOLB_TMR_VAL);
}
+ IPADBG("client %d (ep: %d) connected\n", in->client, ipa_ep_idx);
+
return 0;
sps_connect_fail:
@@ -345,6 +301,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 +377,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..bd1da2c 100644
--- a/drivers/platform/msm/ipa/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_dp.c
@@ -528,8 +528,6 @@
struct ipa_sys_context *sys = &ipa_ctx->sys[IPA_A5_LAN_WAN_IN];
struct ipa_ep_context *ep;
int cnt = 0;
- struct completion *compl;
- struct ipa_tree_node *node;
unsigned int src_pipe;
while ((in_poll_state ? atomic_read(&ipa_ctx->curr_polling_state) :
@@ -584,35 +582,6 @@
IPA_STATS_INC_CNT(ipa_ctx->stats.rx_pkts);
IPA_STATS_EXCP_CNT(mux_hdr->flags, ipa_ctx->stats.rx_excp_pkts);
- if (unlikely(mux_hdr->flags & IPA_A5_MUX_HDR_EXCP_FLAG_TAG)) {
- if (ipa_ctx->ipa_hw_mode != IPA_HW_MODE_VIRTUAL) {
- /* retrieve the compl object from tag value */
- mux_hdr++;
- compl = (struct completion *)
- ntohl(*((u32 *)mux_hdr));
- IPADBG("%x %x %p\n", *(u32 *)mux_hdr,
- *((u32 *)mux_hdr + 1), compl);
-
- mutex_lock(&ipa_ctx->lock);
- node = ipa_search(&ipa_ctx->tag_tree,
- (u32)compl);
- if (node) {
- complete_all(compl);
- rb_erase(&node->node,
- &ipa_ctx->tag_tree);
- kmem_cache_free(
- ipa_ctx->tree_node_cache, node);
- } else {
- WARN_ON(1);
- }
- mutex_unlock(&ipa_ctx->lock);
- }
- dev_kfree_skb(rx_skb);
- ipa_replenish_rx_cache();
- ++cnt;
- continue;
- }
-
/*
* Any packets arriving over AMPDU_TX should be dispatched
* to the regular WLAN RX data-path.
@@ -900,6 +869,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 +907,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_hdr.c b/drivers/platform/msm/ipa/ipa_hdr.c
index 0439a69..7d0bc24 100644
--- a/drivers/platform/msm/ipa/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_hdr.c
@@ -221,6 +221,8 @@
WARN_ON(1);
}
+ entry->ref_cnt++;
+
return 0;
ofst_alloc_fail:
@@ -246,7 +248,7 @@
return -EINVAL;
}
- if (!entry || (entry->cookie != IPA_COOKIE) || (entry->ref_cnt != 0)) {
+ if (!entry || (entry->cookie != IPA_COOKIE)) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -254,6 +256,11 @@
IPADBG("del hdr of sz=%d hdr_cnt=%d ofst=%d\n", entry->hdr_len,
htbl->hdr_cnt, entry->offset_entry->offset);
+ if (--entry->ref_cnt) {
+ IPADBG("hdr_hdl %x ref_cnt %d\n", hdr_hdl, entry->ref_cnt);
+ return 0;
+ }
+
/* move the offset entry to appropriate free list */
list_move(&entry->offset_entry->link,
&htbl->head_free_offset_list[entry->offset_entry->bin]);
@@ -502,8 +509,7 @@
* ipa_get_hdr() - Lookup the specified header resource
* @lookup: [inout] header to lookup and its handle
*
- * lookup the specified header resource and return handle if it exists, if
- * lookup succeeds the header entry ref cnt is increased
+ * lookup the specified header resource and return handle if it exists
*
* Returns: 0 on success, negative on failure
*
@@ -522,7 +528,6 @@
mutex_lock(&ipa_ctx->lock);
entry = __ipa_find_hdr(lookup->name);
if (entry) {
- entry->ref_cnt++;
lookup->hdl = (uint32_t) entry;
result = 0;
}
@@ -533,6 +538,34 @@
EXPORT_SYMBOL(ipa_get_hdr);
/**
+ * __ipa_release_hdr() - drop reference to header and cause
+ * deletion if reference count permits
+ * @hdr_hdl: [in] handle of header to be released
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int __ipa_release_hdr(u32 hdr_hdl)
+{
+ int result = 0;
+
+ if (__ipa_del_hdr(hdr_hdl)) {
+ IPADBG("fail to del hdr %x\n", hdr_hdl);
+ result = -EFAULT;
+ goto bail;
+ }
+
+ /* commit for put */
+ if (__ipa_commit_hdr()) {
+ IPAERR("fail to commit hdr\n");
+ result = -EFAULT;
+ goto bail;
+ }
+
+bail:
+ return result;
+}
+
+/**
* ipa_put_hdr() - Release the specified header handle
* @hdr_hdl: [in] the header handle to release
*
@@ -554,27 +587,12 @@
goto bail;
}
- if (entry == NULL || entry->cookie != IPA_COOKIE ||
- entry->ref_cnt == 0) {
+ if (entry == NULL || entry->cookie != IPA_COOKIE) {
IPAERR("bad params\n");
result = -EINVAL;
goto bail;
}
- entry->ref_cnt--;
- if (entry->ref_cnt == 0) {
- if (__ipa_del_hdr(hdr_hdl)) {
- IPAERR("fail to del hdr\n");
- result = -EFAULT;
- goto bail;
- }
- /* commit for put */
- if (__ipa_commit_hdr()) {
- IPAERR("fail to commit hdr\n");
- result = -EFAULT;
- goto bail;
- }
- }
result = 0;
bail:
mutex_unlock(&ipa_ctx->lock);
diff --git a/drivers/platform/msm/ipa/ipa_i.h b/drivers/platform/msm/ipa/ipa_i.h
index 45f7b09..ca5740d 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];
};
/**
@@ -795,6 +797,7 @@
void ipa_disable_clks(void);
int __ipa_del_rt_rule(u32 rule_hdl);
int __ipa_del_hdr(u32 hdr_hdl);
+int __ipa_release_hdr(u32 hdr_hdl);
static inline u32 ipa_read_reg(void *base, u32 offset)
{
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..78093b8 100644
--- a/drivers/platform/msm/ipa/ipa_ram_mmap.h
+++ b/drivers/platform/msm/ipa/ipa_ram_mmap.h
@@ -15,21 +15,22 @@
/*
* This header defines the memory map of the IPA RAM (not all 8K is available
- * for SW use) the first 2K are set aside for NAT
+ * for SW use)
*/
#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 1280
#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 1408
#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 2176
#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 1280
#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 512
#define IPA_RAM_END_OFST (IPA_RAM_V6_RT_OFST + IPA_RAM_V6_RT_SIZE)
+#define IPA_RAM_V6_RT_SIZE_DDR 16384
#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..1d88280 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);
@@ -698,7 +699,7 @@
}
if (entry->hdr)
- entry->hdr->ref_cnt--;
+ __ipa_release_hdr((u32)entry->hdr);
list_del(&entry->link);
entry->tbl->rule_cnt--;
IPADBG("del rt rule tbl_idx=%d rule_cnt=%d\n", entry->tbl->idx,
@@ -850,7 +851,7 @@
list_del(&rule->link);
tbl->rule_cnt--;
if (rule->hdr)
- rule->hdr->ref_cnt--;
+ __ipa_release_hdr((u32)rule->hdr);
rule->cookie = 0;
kmem_cache_free(ipa_ctx->rt_rule_cache, rule);
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/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index f9ae3c2..a5fac9e 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -52,6 +52,28 @@
struct sps_connect *sps_connections;
};
+/**
+* struct usb_bam_ctx_type - represents the usb bam driver entity
+* @usb_bam_sps: holds the sps pipes the usb bam driver holds
+* against the sps driver.
+* @usb_bam_pdev: the platfrom device that represents the usb bam.
+* @usb_bam_wq: Worqueue used for managing states of reset against
+* a peer bam.
+* @qscratch_ram1_reg: The memory region mapped to the qscratch
+* registers.
+* @max_connections: The maximum number of pipes that are configured
+* in the platform data.
+* @mem_clk: Clock that controls the usb bam driver memory in
+* case the usb bam uses its private memory for the pipes.
+* @mem_iface_clk: Clock that controls the usb bam private memory in
+* case the usb bam uses its private memory for the pipes.
+* @qdss_core_name: Stores the name of the core ("ssusb", "hsusb" or "hsic")
+* that it used as a peer of the qdss in bam2bam mode.
+* @h_bam: This array stores for each BAM ("ssusb", "hsusb" or "hsic") the
+* handle/device of the sps driver.
+* @pipes_enabled_per_bam: This array stores for each BAM
+* ("ssusb", "hsusb" or "hsic") the number of pipes currently enabled.
+*/
struct usb_bam_ctx_type {
struct usb_bam_sps_type usb_bam_sps;
struct platform_device *usb_bam_pdev;
@@ -61,8 +83,8 @@
struct clk *mem_clk;
struct clk *mem_iface_clk;
char qdss_core_name[USB_BAM_MAX_STR_LEN];
- char bam_enabled_list[USB_BAM_MAX_STR_LEN];
u32 h_bam[MAX_BAMS];
+ u8 pipes_enabled_per_bam[MAX_BAMS];
};
static char *bam_enable_strings[3] = {
@@ -442,7 +464,6 @@
int usb_bam_connect(u8 idx, u32 *bam_pipe_idx)
{
int ret;
- enum usb_bam bam;
struct usb_bam_pipe_connect *pipe_connect = &usb_bam_connections[idx];
struct msm_usb_bam_platform_data *pdata;
@@ -467,13 +488,11 @@
pr_err("idx is wrong %d", idx);
return -EINVAL;
}
- bam = pipe_connect->bam_type;
- if (bam < 0)
- return -EINVAL;
- /* Check if BAM requires RESET before connect */
- if (pdata->reset_on_connect[bam] == true)
- sps_device_reset(ctx.h_bam[bam]);
+ /* Check if BAM requires RESET before connect and reset of first pipe */
+ if ((pdata->reset_on_connect[pipe_connect->bam_type] == true) &&
+ (ctx.pipes_enabled_per_bam[pipe_connect->bam_type] == 0))
+ sps_device_reset(ctx.h_bam[pipe_connect->bam_type]);
ret = connect_pipe(idx, bam_pipe_idx);
if (ret) {
@@ -482,6 +501,7 @@
}
pipe_connect->enabled = 1;
+ ctx.pipes_enabled_per_bam[pipe_connect->bam_type] += 1;
return 0;
}
@@ -548,6 +568,8 @@
u8 idx;
struct usb_bam_pipe_connect *pipe_connect;
int ret;
+ struct msm_usb_bam_platform_data *pdata =
+ ctx.usb_bam_pdev->dev.platform_data;
if (!ipa_params) {
pr_err("%s: Invalid ipa params\n",
@@ -573,8 +595,13 @@
return 0;
}
+ /* Check if BAM requires RESET before connect and reset of first pipe */
+ if ((pdata->reset_on_connect[pipe_connect->bam_type] == true) &&
+ (ctx.pipes_enabled_per_bam[pipe_connect->bam_type] == 0))
+ sps_device_reset(ctx.h_bam[pipe_connect->bam_type]);
+
ret = connect_pipe_ipa(idx, ipa_params);
- ipa_rm_request_resource(IPA_CLIENT_USB_PROD);
+ ipa_rm_request_resource(IPA_RM_RESOURCE_USB_PROD);
if (ret) {
pr_err("%s: dst pipe connection failure\n", __func__);
@@ -582,6 +609,7 @@
}
pipe_connect->enabled = 1;
+ ctx.pipes_enabled_per_bam[pipe_connect->bam_type] += 1;
return 0;
}
@@ -799,6 +827,11 @@
}
pipe_connect->enabled = 0;
+ if (ctx.pipes_enabled_per_bam[pipe_connect->bam_type] == 0)
+ pr_err("%s: wrong pipes enabled counter for bam_type=%d\n",
+ __func__, pipe_connect->bam_type);
+ else
+ ctx.pipes_enabled_per_bam[pipe_connect->bam_type] -= 1;
return 0;
}
@@ -853,7 +886,7 @@
}
}
- ipa_rm_release_resource(IPA_CLIENT_USB_PROD);
+ ipa_rm_release_resource(IPA_RM_RESOURCE_USB_PROD);
return 0;
}
EXPORT_SYMBOL(usb_bam_disconnect_ipa);
@@ -993,6 +1026,7 @@
__func__);
goto err;
}
+ bam = usb_bam_connections[i].bam_type;
rc = of_property_read_u32(node, "qcom,peer-bam",
&usb_bam_connections[i].peer_bam);
@@ -1220,6 +1254,9 @@
usb_bam_work);
}
+ for (i = 0; i < MAX_BAMS; i++)
+ ctx.pipes_enabled_per_bam[i] = 0;
+
spin_lock_init(&usb_bam_lock);
INIT_WORK(&peer_handshake_info.reset_event.event_w, usb_bam_sm_work);
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index becc314..a2701ce 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -59,6 +59,8 @@
#define PON_CNTRL_6 0x018
#define WD_BIT BIT(7)
+#define BATT_ALARM_ACCURACY 50 /* 50mV */
+
enum pmic_bms_interrupts {
PM8921_BMS_SBI_WRITE_OK,
PM8921_BMS_CC_THR,
@@ -159,7 +161,6 @@
int soc_at_cv;
int prev_chg_soc;
struct power_supply *batt_psy;
- bool low_voltage_wake_lock_held;
struct wake_lock low_voltage_wake_lock;
int soc_calc_period;
int normal_voltage_calc_ms;
@@ -170,6 +171,9 @@
int ocv_dis_high_soc;
int ocv_dis_low_soc;
int prev_vbat_batt_terminal_uv;
+ int vbatt_cutoff_count;
+ int low_voltage_detect;
+ int vbatt_cutoff_retries;
};
/*
@@ -391,6 +395,20 @@
return val;
}
+static void pm8921_bms_low_voltage_config(struct pm8921_bms_chip *chip,
+ int time_ms)
+{
+ int ms = 0;
+
+ /* if work was pending and was cancelled, calculate SOC immediately */
+ if (!cancel_delayed_work_sync(&chip->calculate_soc_delayed_work))
+ ms = time_ms;
+
+ chip->soc_calc_period = time_ms;
+ schedule_delayed_work(&chip->calculate_soc_delayed_work,
+ msecs_to_jiffies(ms));
+}
+
static int pm8921_bms_enable_batt_alarm(struct pm8921_bms_chip *chip)
{
int rc = 0;
@@ -479,8 +497,12 @@
* hold the low voltage wakelock until the soc
* work finds it appropriate to release it.
*/
- wake_lock(&the_chip->low_voltage_wake_lock);
- the_chip->low_voltage_wake_lock_held = 1;
+ if (!wake_lock_active(&the_chip->low_voltage_wake_lock)) {
+ pr_debug("Holding low voltage wakelock\n");
+ wake_lock(&the_chip->low_voltage_wake_lock);
+ pm8921_bms_low_voltage_config(the_chip,
+ the_chip->low_voltage_calc_ms);
+ }
rc = pm8xxx_batt_alarm_disable(
PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
@@ -1788,26 +1810,42 @@
* if battery is very low (v_cutoff voltage + 20mv) hold
* a wakelock untill soc = 0%
*/
- if (vbat_uv <= (chip->v_cutoff + 20) * 1000
- && !chip->low_voltage_wake_lock_held) {
+ if (vbat_uv <= (chip->alarm_low_mv + 20) * 1000 &&
+ !wake_lock_active(&the_chip->low_voltage_wake_lock)) {
pr_debug("voltage = %d low holding wakelock\n", vbat_uv);
wake_lock(&chip->low_voltage_wake_lock);
- chip->low_voltage_wake_lock_held = 1;
chip->soc_calc_period = chip->low_voltage_calc_ms;
}
- if (vbat_uv > (chip->v_cutoff + 20) * 1000
- && chip->low_voltage_wake_lock_held) {
+ if (vbat_uv > (chip->alarm_low_mv + 20 + BATT_ALARM_ACCURACY) * 1000
+ && wake_lock_active(&the_chip->low_voltage_wake_lock)) {
pr_debug("voltage = %d releasing wakelock\n", vbat_uv);
- chip->low_voltage_wake_lock_held = 0;
- wake_unlock(&chip->low_voltage_wake_lock);
+ chip->vbatt_cutoff_count = 0;
chip->soc_calc_period = chip->normal_voltage_calc_ms;
rc = pm8921_bms_enable_batt_alarm(chip);
if (rc)
pr_err("Unable to enable batt alarm\n");
+ wake_unlock(&chip->low_voltage_wake_lock);
}
}
+static bool is_voltage_below_cutoff_window(struct pm8921_bms_chip *chip,
+ int ibat_ua, int vbat_uv)
+{
+ if (vbat_uv < (chip->v_cutoff * 1000) && ibat_ua > 0) {
+ chip->vbatt_cutoff_count++;
+ if (chip->vbatt_cutoff_count >= chip->vbatt_cutoff_retries) {
+ pr_debug("cutoff_count >= %d\n",
+ chip->vbatt_cutoff_retries);
+ return true;
+ }
+ } else {
+ chip->vbatt_cutoff_count = 0;
+ }
+
+ return false;
+}
+
static int last_soc_est = -EINVAL;
static int adjust_soc(struct pm8921_bms_chip *chip, int soc,
int batt_temp, int chargecycles,
@@ -1834,6 +1872,15 @@
very_low_voltage_check(chip, ibat_ua, vbat_uv);
+ if (chip->low_voltage_detect &&
+ wake_lock_active(&chip->low_voltage_wake_lock)) {
+ if (is_voltage_below_cutoff_window(chip, ibat_ua, vbat_uv)) {
+ soc = 0;
+ pr_info("Voltage below cutoff, setting soc to 0\n");
+ goto out;
+ }
+ }
+
delta_ocv_uv_limit = DIV_ROUND_CLOSEST(ibat_ua, 1000);
ocv_est_uv = vbat_uv + (ibat_ua * rbatt)/1000;
@@ -3327,6 +3374,8 @@
chip->alarm_low_mv = pdata->alarm_low_mv;
chip->alarm_high_mv = pdata->alarm_high_mv;
+ chip->low_voltage_detect = pdata->low_voltage_detect;
+ chip->vbatt_cutoff_retries = pdata->vbatt_cutoff_retries;
mutex_init(&chip->calib_mutex);
INIT_WORK(&chip->calib_hkadc_work, calibrate_hkadc_work);
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..08cf71e 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 100\n");
+ new_calculated_soc = 100;
+ 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/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 180ca0d..2794fcc 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -190,8 +190,8 @@
* @safe_current: battery safety current setting
* @maxinput_usb_ma: Maximum Input current USB
* @maxinput_dc_ma: Maximum Input current DC
- * @warm_bat_degc Warm battery temperature in degree Celsius
- * @cool_bat_degc Cool battery temperature in degree Celsius
+ * @warm_bat_decidegc Warm battery temperature in degree Celsius
+ * @cool_bat_decidegc Cool battery temperature in degree Celsius
* @revision: PMIC revision
* @thermal_levels amount of thermal mitigation levels
* @thermal_mitigation thermal mitigation level values
@@ -242,8 +242,8 @@
unsigned int term_current;
unsigned int maxinput_usb_ma;
unsigned int maxinput_dc_ma;
- unsigned int warm_bat_degc;
- unsigned int cool_bat_degc;
+ unsigned int warm_bat_decidegc;
+ unsigned int cool_bat_decidegc;
unsigned int safe_current;
unsigned int revision;
unsigned int thermal_levels;
@@ -546,6 +546,12 @@
if (chip->batt_present ^ batt_present) {
chip->batt_present = batt_present;
power_supply_changed(&chip->batt_psy);
+
+ if (chip->cool_bat_decidegc && chip->warm_bat_decidegc
+ && batt_present) {
+ if (qpnp_adc_tm_channel_measure(&chip->adc_param))
+ pr_err("request ADC error\n");
+ }
}
if (chip->bms_psy)
@@ -1019,7 +1025,8 @@
/* Only honour requests while USB is present */
if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
- if (ret.intval <= 2) {
+ if (ret.intval <= 2 && !chip->use_default_batt_values &&
+ get_prop_batt_present(chip)) {
qpnp_chg_usb_suspend_enable(chip, 1);
qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100);
} else {
@@ -1304,7 +1311,7 @@
}
}
-#define TEMP_HYSTERISIS_DEGC 2
+#define HYSTERISIS_DECIDEGC 20
static void
qpnp_chg_adc_notification(enum qpnp_tm_state state, void *ctx)
{
@@ -1323,22 +1330,22 @@
bat_warm = true;
bat_cool = false;
chip->adc_param.low_temp =
- chip->warm_bat_degc - TEMP_HYSTERISIS_DEGC;
+ chip->warm_bat_decidegc - HYSTERISIS_DECIDEGC;
} else if (chip->bat_is_cool) {
bat_warm = false;
bat_cool = false;
- chip->adc_param.high_temp = chip->warm_bat_degc;
+ chip->adc_param.high_temp = chip->warm_bat_decidegc;
}
} else {
if (!chip->bat_is_cool) {
bat_cool = true;
bat_warm = false;
chip->adc_param.high_temp =
- chip->cool_bat_degc + TEMP_HYSTERISIS_DEGC;
+ chip->cool_bat_decidegc + HYSTERISIS_DECIDEGC;
} else if (chip->bat_is_warm) {
bat_cool = false;
bat_warm = false;
- chip->adc_param.low_temp = chip->cool_bat_degc;
+ chip->adc_param.low_temp = chip->cool_bat_decidegc;
}
}
@@ -1353,7 +1360,7 @@
}
/* re-arm ADC interrupt */
- qpnp_adc_tm_btm_configure(&chip->adc_param);
+ qpnp_adc_tm_channel_measure(&chip->adc_param);
}
static int
@@ -1743,8 +1750,8 @@
/* Get the warm-bat-degc property */
rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,chg-warm-bat-degc",
- &chip->warm_bat_degc);
+ "qcom,chg-warm-bat-decidegc",
+ &chip->warm_bat_decidegc);
if (rc && rc != -EINVAL) {
pr_err("Error reading warm-bat-degc property %d\n", rc);
goto fail_chg_enable;
@@ -1752,14 +1759,14 @@
/* Get the cool-bat-degc property */
rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,chg-cool-bat-degc",
- &chip->cool_bat_degc);
+ "qcom,chg-cool-bat-decidegc",
+ &chip->cool_bat_decidegc);
if (rc && rc != -EINVAL) {
pr_err("Error reading cool-bat-degc property %d\n", rc);
goto fail_chg_enable;
}
- if (chip->cool_bat_degc && chip->warm_bat_degc) {
+ if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
rc = qpnp_adc_tm_is_ready();
if (rc) {
pr_err("tm not ready %d\n", rc);
@@ -1997,19 +2004,22 @@
}
}
- if (chip->cool_bat_degc && chip->warm_bat_degc) {
- chip->adc_param.low_temp = chip->cool_bat_degc;
- chip->adc_param.high_temp = chip->warm_bat_degc;
+ if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
+ chip->adc_param.low_temp = chip->cool_bat_decidegc;
+ chip->adc_param.high_temp = chip->warm_bat_decidegc;
chip->adc_param.timer_interval = ADC_MEAS2_INTERVAL_1S;
chip->adc_param.state_request = ADC_TM_HIGH_LOW_THR_ENABLE;
chip->adc_param.btm_ctx = chip;
chip->adc_param.threshold_notification =
qpnp_chg_adc_notification;
+ chip->adc_param.channel = LR_MUX1_BATT_THERM;
- rc = qpnp_adc_tm_btm_configure(&chip->adc_param);
- if (rc) {
- pr_err("request ADC error %d\n", rc);
- goto fail_chg_enable;
+ if (get_prop_batt_present(chip)) {
+ rc = qpnp_adc_tm_channel_measure(&chip->adc_param);
+ if (rc) {
+ pr_err("request ADC error %d\n", rc);
+ goto fail_chg_enable;
+ }
}
}
@@ -2038,6 +2048,10 @@
qpnp_charger_remove(struct spmi_device *spmi)
{
struct qpnp_chg_chip *chip = dev_get_drvdata(&spmi->dev);
+ if (chip->cool_bat_decidegc && chip->warm_bat_decidegc
+ && chip->batt_present) {
+ qpnp_adc_tm_disable_chan_meas(&chip->adc_param);
+ }
dev_set_drvdata(&spmi->dev, NULL);
kfree(chip);
diff --git a/drivers/staging/ste_rmi4/Kconfig b/drivers/staging/ste_rmi4/Kconfig
index e867950..6570368 100644
--- a/drivers/staging/ste_rmi4/Kconfig
+++ b/drivers/staging/ste_rmi4/Kconfig
@@ -1,9 +1,12 @@
-config TOUCHSCREEN_SYNAPTICS_I2C_RMI4
- tristate "Synaptics i2c rmi4 touchscreen"
+config TOUCHSCREEN_SYNAPTICS_I2C_RMI4_STAGING
+ tristate "Synaptics i2c rmi4 touchscreen staging"
depends on I2C && INPUT
help
Say Y here if you have a Synaptics RMI4 and
- want to enable support for the built-in touchscreen.
+ want to enable support for the built-in touchscreen
+ through staging driver. Not to be confused with
+ TOUCHSCREEN_SYNAPTICS_I2C_RMI4 in
+ drivers/input/touchscreen directory.
To compile this driver as a module, choose M here: the
module will be called synaptics_rmi4_ts.
diff --git a/drivers/staging/ste_rmi4/Makefile b/drivers/staging/ste_rmi4/Makefile
index e4c0335..ee9a53e 100644
--- a/drivers/staging/ste_rmi4/Makefile
+++ b/drivers/staging/ste_rmi4/Makefile
@@ -1,5 +1,6 @@
#
# Makefile for the RMI4 touchscreen driver.
#
-obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4_STAGING) \
+ += synaptics_i2c_rmi4_staging.o
obj-$(CONFIG_MACH_MOP500) += board-mop500-u8500uib-rmi4.o
diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4_staging.c
similarity index 99%
rename from drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
rename to drivers/staging/ste_rmi4/synaptics_i2c_rmi4_staging.c
index 11728a0..43115c3 100644
--- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
+++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4_staging.c
@@ -31,7 +31,7 @@
#include <linux/interrupt.h>
#include <linux/regulator/consumer.h>
#include <linux/module.h>
-#include "synaptics_i2c_rmi4.h"
+#include "synaptics_i2c_rmi4_staging.h"
/* TODO: for multiple device support will need a per-device mutex */
#define DRIVER_NAME "synaptics_rmi4_i2c"
diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4_staging.h
similarity index 100%
rename from drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h
rename to drivers/staging/ste_rmi4/synaptics_i2c_rmi4_staging.h
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index 17ae34f..c02db14 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.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
@@ -35,6 +35,8 @@
#include <linux/platform_device.h>
/* QPNP VADC TM register definition */
+#define QPNP_REVISION3 0x3
+#define QPNP_REVISION_EIGHT_CHANNEL_SUPPORT 2
#define QPNP_STATUS1 0x8
#define QPNP_STATUS1_OP_MODE 4
#define QPNP_STATUS1_MEAS_INTERVAL_EN_STS BIT(2)
@@ -79,22 +81,41 @@
#define QPNP_M0_LOW_THR_MSB 0x5d
#define QPNP_M0_HIGH_THR_LSB 0x5e
#define QPNP_M0_HIGH_THR_MSB 0x5f
+#define QPNP_M1_ADC_CH_SEL_CTL 0x68
#define QPNP_M1_LOW_THR_LSB 0x69
#define QPNP_M1_LOW_THR_MSB 0x6a
#define QPNP_M1_HIGH_THR_LSB 0x6b
#define QPNP_M1_HIGH_THR_MSB 0x6c
+#define QPNP_M2_ADC_CH_SEL_CTL 0x70
#define QPNP_M2_LOW_THR_LSB 0x71
#define QPNP_M2_LOW_THR_MSB 0x72
#define QPNP_M2_HIGH_THR_LSB 0x7b
#define QPNP_M2_HIGH_THR_MSB 0x7c
+#define QPNP_M3_ADC_CH_SEL_CTL 0x78
#define QPNP_M3_LOW_THR_LSB 0x79
#define QPNP_M3_LOW_THR_MSB 0x7a
#define QPNP_M3_HIGH_THR_LSB 0x7b
#define QPNP_M3_HIGH_THR_MSB 0x7c
+#define QPNP_M4_ADC_CH_SEL_CTL 0x80
#define QPNP_M4_LOW_THR_LSB 0x81
#define QPNP_M4_LOW_THR_MSB 0x82
#define QPNP_M4_HIGH_THR_LSB 0x83
#define QPNP_M4_HIGH_THR_MSB 0x84
+#define QPNP_M5_ADC_CH_SEL_CTL 0x88
+#define QPNP_M5_LOW_THR_LSB 0x89
+#define QPNP_M5_LOW_THR_MSB 0x8a
+#define QPNP_M5_HIGH_THR_LSB 0x8b
+#define QPNP_M5_HIGH_THR_MSB 0x8c
+#define QPNP_M6_ADC_CH_SEL_CTL 0x90
+#define QPNP_M6_LOW_THR_LSB 0x91
+#define QPNP_M6_LOW_THR_MSB 0x92
+#define QPNP_M6_HIGH_THR_LSB 0x93
+#define QPNP_M6_HIGH_THR_MSB 0x94
+#define QPNP_M7_ADC_CH_SEL_CTL 0x98
+#define QPNP_M7_LOW_THR_LSB 0x99
+#define QPNP_M7_LOW_THR_MSB 0x9a
+#define QPNP_M7_HIGH_THR_LSB 0x9b
+#define QPNP_M7_HIGH_THR_MSB 0x9c
#define QPNP_ADC_TM_MULTI_MEAS_EN 0x41
#define QPNP_ADC_TM_MULTI_MEAS_EN_M0 BIT(0)
@@ -102,24 +123,36 @@
#define QPNP_ADC_TM_MULTI_MEAS_EN_M2 BIT(2)
#define QPNP_ADC_TM_MULTI_MEAS_EN_M3 BIT(3)
#define QPNP_ADC_TM_MULTI_MEAS_EN_M4 BIT(4)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M5 BIT(5)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M6 BIT(6)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M7 BIT(7)
#define QPNP_ADC_TM_LOW_THR_INT_EN 0x42
#define QPNP_ADC_TM_LOW_THR_INT_EN_M0 BIT(0)
#define QPNP_ADC_TM_LOW_THR_INT_EN_M1 BIT(1)
#define QPNP_ADC_TM_LOW_THR_INT_EN_M2 BIT(2)
#define QPNP_ADC_TM_LOW_THR_INT_EN_M3 BIT(3)
#define QPNP_ADC_TM_LOW_THR_INT_EN_M4 BIT(4)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M5 BIT(5)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M6 BIT(6)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M7 BIT(7)
#define QPNP_ADC_TM_HIGH_THR_INT_EN 0x43
#define QPNP_ADC_TM_HIGH_THR_INT_EN_M0 BIT(0)
#define QPNP_ADC_TM_HIGH_THR_INT_EN_M1 BIT(1)
#define QPNP_ADC_TM_HIGH_THR_INT_EN_M2 BIT(2)
#define QPNP_ADC_TM_HIGH_THR_INT_EN_M3 BIT(3)
#define QPNP_ADC_TM_HIGH_THR_INT_EN_M4 BIT(4)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M5 BIT(5)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M6 BIT(6)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M7 BIT(7)
-#define QPNP_ADC_TM_M0_MEAS_INTERVAL_CTL 0x57
+#define QPNP_ADC_TM_M0_MEAS_INTERVAL_CTL 0x59
#define QPNP_ADC_TM_M1_MEAS_INTERVAL_CTL 0x6d
#define QPNP_ADC_TM_M2_MEAS_INTERVAL_CTL 0x75
#define QPNP_ADC_TM_M3_MEAS_INTERVAL_CTL 0x7d
#define QPNP_ADC_TM_M4_MEAS_INTERVAL_CTL 0x85
+#define QPNP_ADC_TM_M5_MEAS_INTERVAL_CTL 0x8d
+#define QPNP_ADC_TM_M6_MEAS_INTERVAL_CTL 0x95
+#define QPNP_ADC_TM_M7_MEAS_INTERVAL_CTL 0x9d
#define QPNP_ADC_TM_STATUS1 0x8
#define QPNP_ADC_TM_STATUS_LOW 0xa
#define QPNP_ADC_TM_STATUS_HIGH 0xb
@@ -131,6 +164,9 @@
#define QPNP_ADC_TM_THR_LSB_MASK(val) (val & 0xff)
#define QPNP_ADC_TM_THR_MSB_MASK(val) ((val & 0xff00) >> 8)
+#define QPNP_MIN_TIME 2000
+#define QPNP_MAX_TIME 2100
+
struct qpnp_adc_tm_sensor {
struct thermal_zone_device *tz_dev;
enum thermal_device_mode mode;
@@ -140,16 +176,19 @@
uint32_t low_thr;
uint32_t high_thr;
uint32_t btm_channel_num;
+ uint32_t vadc_channel_num;
struct work_struct work;
+ struct qpnp_adc_tm_btm_param *btm_param;
+ bool thermal_node;
+ bool low_thr_notify;
+ bool high_thr_notify;
+ uint32_t scale_type;
};
struct qpnp_adc_tm_drv {
struct qpnp_adc_drv *adc;
- struct qpnp_adc_tm_usbid_param *usb_id_param;
- struct work_struct usbid_work;
- struct qpnp_adc_tm_btm_param *battery_param;
- struct work_struct batt_work;
bool adc_tm_initialized;
+ int max_channels_available;
struct qpnp_adc_tm_sensor sensor[0];
};
@@ -163,29 +202,57 @@
u8 multi_meas_en;
u8 low_thr_int_chan_en;
u8 high_thr_int_chan_en;
+ u8 meas_interval_ctl;
};
static struct qpnp_adc_tm_trip_reg_type adc_tm_data[] = {
[QPNP_ADC_TM_M0_ADC_CH_SEL_CTL] = {QPNP_M0_LOW_THR_LSB,
QPNP_M0_LOW_THR_MSB, QPNP_M0_HIGH_THR_LSB,
QPNP_M0_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M0,
- QPNP_ADC_TM_LOW_THR_INT_EN_M0, QPNP_ADC_TM_HIGH_THR_INT_EN_M0},
+ QPNP_ADC_TM_LOW_THR_INT_EN_M0, QPNP_ADC_TM_HIGH_THR_INT_EN_M0,
+ QPNP_ADC_TM_M0_MEAS_INTERVAL_CTL},
[QPNP_ADC_TM_M1_ADC_CH_SEL_CTL] = {QPNP_M1_LOW_THR_LSB,
QPNP_M1_LOW_THR_MSB, QPNP_M1_HIGH_THR_LSB,
QPNP_M1_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M1,
- QPNP_ADC_TM_LOW_THR_INT_EN_M1, QPNP_ADC_TM_HIGH_THR_INT_EN_M1},
+ QPNP_ADC_TM_LOW_THR_INT_EN_M1, QPNP_ADC_TM_HIGH_THR_INT_EN_M1,
+ QPNP_ADC_TM_M1_MEAS_INTERVAL_CTL},
[QPNP_ADC_TM_M2_ADC_CH_SEL_CTL] = {QPNP_M2_LOW_THR_LSB,
QPNP_M2_LOW_THR_MSB, QPNP_M2_HIGH_THR_LSB,
QPNP_M2_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M2,
- QPNP_ADC_TM_LOW_THR_INT_EN_M2, QPNP_ADC_TM_HIGH_THR_INT_EN_M2},
+ QPNP_ADC_TM_LOW_THR_INT_EN_M2, QPNP_ADC_TM_HIGH_THR_INT_EN_M2,
+ QPNP_ADC_TM_M2_MEAS_INTERVAL_CTL},
[QPNP_ADC_TM_M3_ADC_CH_SEL_CTL] = {QPNP_M3_LOW_THR_LSB,
QPNP_M3_LOW_THR_MSB, QPNP_M3_HIGH_THR_LSB,
QPNP_M3_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M3,
- QPNP_ADC_TM_LOW_THR_INT_EN_M3, QPNP_ADC_TM_HIGH_THR_INT_EN_M3},
+ QPNP_ADC_TM_LOW_THR_INT_EN_M3, QPNP_ADC_TM_HIGH_THR_INT_EN_M3,
+ QPNP_ADC_TM_M3_MEAS_INTERVAL_CTL},
[QPNP_ADC_TM_M4_ADC_CH_SEL_CTL] = {QPNP_M4_LOW_THR_LSB,
QPNP_M4_LOW_THR_MSB, QPNP_M4_HIGH_THR_LSB,
QPNP_M4_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M4,
- QPNP_ADC_TM_LOW_THR_INT_EN_M4, QPNP_ADC_TM_HIGH_THR_INT_EN_M4},
+ QPNP_ADC_TM_LOW_THR_INT_EN_M4, QPNP_ADC_TM_HIGH_THR_INT_EN_M4,
+ QPNP_ADC_TM_M4_MEAS_INTERVAL_CTL},
+ [QPNP_ADC_TM_M5_ADC_CH_SEL_CTL] = {QPNP_M5_LOW_THR_LSB,
+ QPNP_M5_LOW_THR_MSB, QPNP_M5_HIGH_THR_LSB,
+ QPNP_M5_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M5,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M5, QPNP_ADC_TM_HIGH_THR_INT_EN_M5,
+ QPNP_ADC_TM_M5_MEAS_INTERVAL_CTL},
+ [QPNP_ADC_TM_M6_ADC_CH_SEL_CTL] = {QPNP_M6_LOW_THR_LSB,
+ QPNP_M6_LOW_THR_MSB, QPNP_M6_HIGH_THR_LSB,
+ QPNP_M6_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M6,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M6, QPNP_ADC_TM_HIGH_THR_INT_EN_M6,
+ QPNP_ADC_TM_M6_MEAS_INTERVAL_CTL},
+ [QPNP_ADC_TM_M7_ADC_CH_SEL_CTL] = {QPNP_M7_LOW_THR_LSB,
+ QPNP_M7_LOW_THR_MSB, QPNP_M7_HIGH_THR_LSB,
+ QPNP_M7_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M7,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M7, QPNP_ADC_TM_HIGH_THR_INT_EN_M7,
+ QPNP_ADC_TM_M7_MEAS_INTERVAL_CTL},
+};
+
+static struct qpnp_adc_tm_reverse_scale_fn adc_tm_rscale_fn[] = {
+ [SCALE_R_VBATT] = {qpnp_adc_vbatt_rscaler},
+ [SCALE_RBATT_THERM] = {qpnp_adc_btm_scaler},
+ [SCALE_R_USB_ID] = {qpnp_adc_usb_scaler},
+ [SCALE_RPMIC_THERM] = {qpnp_adc_scale_millidegc_pmic_voltage_thr},
};
static int32_t qpnp_adc_tm_read_reg(int16_t reg, u8 *data)
@@ -217,40 +284,63 @@
return rc;
}
-static int32_t qpnp_adc_tm_enable(bool state)
+static int32_t qpnp_adc_tm_enable(void)
{
int rc = 0;
- u8 data = 0, enable_check = 0;
+ u8 data = 0;
- if (state) {
- data = QPNP_ADC_TM_EN;
- rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1,
- data);
- if (rc < 0)
- pr_err("adc-tm enable failed\n");
- } else {
- rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MULTI_MEAS_EN,
- &enable_check);
+ data = QPNP_ADC_TM_EN;
+ rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1, data);
+ if (rc < 0)
+ pr_err("adc-tm enable failed\n");
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_disable(void)
+{
+ u8 data = 0;
+ int rc = 0;
+
+ rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1, data);
+ if (rc < 0)
+ pr_err("adc-tm disable failed\n");
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_enable_if_channel_meas(void)
+{
+ u8 adc_tm_meas_en = 0;
+ int rc = 0;
+
+ /* Check if a measurement request is still required */
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MULTI_MEAS_EN,
+ &adc_tm_meas_en);
+ if (rc) {
+ pr_err("adc-tm-tm read status high failed with %d\n", rc);
+ return rc;
+ }
+
+ /* Enable only if there are pending measurement requests */
+ if (adc_tm_meas_en) {
+ qpnp_adc_tm_enable();
+
+ /* Request conversion */
+ rc = qpnp_adc_tm_write_reg(QPNP_CONV_REQ, QPNP_CONV_REQ_SET);
if (rc < 0) {
- pr_err("multi measurement read failed\n");
+ pr_err("adc-tm request conversion failed\n");
return rc;
}
-
- if (!enable_check) {
- data = 0;
- rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1, data);
- if (rc < 0)
- pr_err("adc-tm disable failed\n");
- }
}
return rc;
}
-static int32_t qpnp_adc_tm_enable_req_sts_check(void)
+static int32_t qpnp_adc_tm_req_sts_check(void)
{
u8 status1;
- int rc;
+ int rc, count = 0;
/* The VADC_TM bank needs to be disabled for new conversion request */
rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS1, &status1);
@@ -260,19 +350,45 @@
}
/* Disable the bank if a conversion is occuring */
- if (status1 & QPNP_STATUS1_REQ_STS) {
- rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1, 0);
+ while ((status1 & QPNP_STATUS1_REQ_STS) && (count < 5)) {
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS1, &status1);
if (rc < 0)
pr_err("adc-tm disable failed\n");
+ /* Wait time is based on the optimum sampling rate
+ * and adding enough time buffer to account for ADC conversions
+ * occuring on different peripheral banks */
+ usleep_range(QPNP_MIN_TIME, QPNP_MAX_TIME);
+ count++;
}
return rc;
}
+static int32_t qpnp_adc_tm_check_revision(uint32_t btm_chan_num)
+{
+ u8 rev;
+ int rc = 0;
+
+ rc = qpnp_adc_tm_read_reg(QPNP_REVISION3, &rev);
+ if (rc) {
+ pr_err("adc-tm revision read failed\n");
+ return rc;
+ }
+
+ if ((rev < QPNP_REVISION_EIGHT_CHANNEL_SUPPORT) &&
+ (btm_chan_num > QPNP_ADC_TM_M4_ADC_CH_SEL_CTL)) {
+ pr_debug("Version does not support more than 5 channels\n");
+ return -EINVAL;
+ }
+
+ return rc;
+}
static int32_t qpnp_adc_tm_mode_select(u8 mode_ctl)
{
int rc;
+ mode_ctl |= (QPNP_ADC_TRIM_EN | QPNP_AMUX_TRIM_EN);
+
/* VADC_BTM current sets mode to recurring measurements */
rc = qpnp_adc_tm_write_reg(QPNP_MODE_CTL, mode_ctl);
if (rc < 0)
@@ -281,13 +397,13 @@
return rc;
}
-static int32_t qpnp_adc_tm_timer_interval_select(
+static int32_t qpnp_adc_tm_timer_interval_select(uint32_t btm_chan,
struct qpnp_vadc_chan_properties *chan_prop)
{
int rc;
u8 meas_interval_timer2 = 0;
- /* Configure USB_ID to timer1, batt_therm to timer2 */
+ /* Configure kernel clients to timer1 */
switch (chan_prop->timer_select) {
case ADC_MEAS_TIMER_SELECT1:
rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL,
@@ -298,6 +414,7 @@
}
break;
case ADC_MEAS_TIMER_SELECT2:
+ /* Thermal channels uses timer2, default to 1 second */
rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
&meas_interval_timer2);
if (rc < 0) {
@@ -315,7 +432,6 @@
}
break;
case ADC_MEAS_TIMER_SELECT3:
- /* Thermal channels uses timer3, default to 1 second */
rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
&meas_interval_timer2);
if (rc < 0) {
@@ -336,34 +452,40 @@
return -EINVAL;
}
+ /* Select the timer to use for the corresponding channel */
+ adc_tm_data[btm_chan].meas_interval_ctl = chan_prop->timer_select;
+
return rc;
}
-static int32_t qpnp_adc_tm_meas_int_update(uint16_t reg_addr_src,
- u8 reg_addr_dst, bool state)
+static int32_t qpnp_adc_tm_reg_update(uint16_t addr,
+ u8 mask, bool state)
{
- u8 bit_mask_check = 0;
+ u8 reg_value = 0;
int rc = 0;
- rc = qpnp_adc_tm_read_reg(reg_addr_src, &bit_mask_check);
+ rc = qpnp_adc_tm_read_reg(addr, ®_value);
if (rc < 0) {
- pr_err("read failed for addr:%x\n", reg_addr_src);
+ pr_err("read failed for addr:0x%x\n", addr);
return rc;
}
+ reg_value = reg_value & ~mask;
if (state)
- bit_mask_check |= reg_addr_dst;
- else
- bit_mask_check &= ~reg_addr_dst;
+ reg_value |= mask;
- rc = qpnp_adc_tm_write_reg(reg_addr_src, bit_mask_check);
- if (rc < 0)
- pr_err("write failed for addr:%x\n", reg_addr_src);
+ pr_debug("state:%d, reg:0x%x with bits:0x%x and mask:0x%x\n",
+ state, addr, reg_value, ~mask);
+ rc = qpnp_adc_tm_write_reg(addr, reg_value);
+ if (rc < 0) {
+ pr_err("write failed for addr:%x\n", addr);
+ return rc;
+ }
return rc;
}
-static int32_t qpnp_adc_tm_usbid_btm_thr_en(uint32_t btm_chan,
+static int32_t qpnp_adc_tm_thr_update(uint32_t btm_chan,
struct qpnp_vadc_chan_properties *chan_prop)
{
int rc = 0;
@@ -398,6 +520,9 @@
if (rc < 0)
pr_err("high threshold msb setting failed\n");
+ pr_debug("client requested low:%d and high:%d\n",
+ chan_prop->low_thr, chan_prop->high_thr);
+
return rc;
}
@@ -405,13 +530,29 @@
struct qpnp_vadc_chan_properties *chan_prop,
uint32_t amux_channel)
{
- int rc = 0;
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ int rc = 0, i = 0, chan_idx = 0;
+ bool chan_found = false;
+ u8 sensor_mask = 0;
- switch (btm_chan) {
- case QPNP_ADC_TM_M0_ADC_CH_SEL_CTL:
- case QPNP_ADC_TM_M1_ADC_CH_SEL_CTL:
+ while (i < adc_tm->max_channels_available) {
+ if (adc_tm->sensor[i].btm_channel_num == btm_chan) {
+ chan_idx = i;
+ chan_found = true;
+ i++;
+ } else
+ i++;
+ }
+
+ if ((i == adc_tm->max_channels_available) && (!chan_found)) {
+ pr_err("Channel not found\n");
+ return -EINVAL;
+ }
+
+ sensor_mask = 1 << chan_idx;
+ if (!adc_tm->sensor[chan_idx].thermal_node) {
/* Update low and high notification thresholds */
- rc = qpnp_adc_tm_usbid_btm_thr_en(btm_chan,
+ rc = qpnp_adc_tm_thr_update(btm_chan,
chan_prop);
if (rc < 0) {
pr_err("setting chan:%d threshold failed\n", btm_chan);
@@ -422,11 +563,11 @@
ADC_TM_LOW_THR_ENABLE) ||
(chan_prop->state_request ==
ADC_TM_HIGH_LOW_THR_ENABLE)) {
+ pr_debug("low sensor mask:%x with state:%d\n",
+ sensor_mask, chan_prop->state_request);
/* Enable low threshold's interrupt */
- rc = qpnp_adc_tm_meas_int_update(
- QPNP_ADC_TM_LOW_THR_INT_EN,
- adc_tm_data[btm_chan].low_thr_int_chan_en,
- true);
+ rc = qpnp_adc_tm_reg_update(
+ QPNP_ADC_TM_LOW_THR_INT_EN, sensor_mask, true);
if (rc < 0) {
pr_err("low thr enable err:%d\n", btm_chan);
return rc;
@@ -438,37 +579,22 @@
(chan_prop->state_request ==
ADC_TM_HIGH_LOW_THR_ENABLE)) {
/* Enable high threshold's interrupt */
- rc = qpnp_adc_tm_meas_int_update(
- QPNP_ADC_TM_HIGH_THR_INT_EN,
- adc_tm_data[btm_chan].high_thr_int_chan_en,
- true);
+ pr_debug("high sensor mask:%x\n", sensor_mask);
+ rc = qpnp_adc_tm_reg_update(
+ QPNP_ADC_TM_HIGH_THR_INT_EN, sensor_mask, true);
if (rc < 0) {
pr_err("high thr enable err:%d\n", btm_chan);
return rc;
}
}
- /* intention fall through to configure common chan meas */
- case QPNP_ADC_TM_M2_ADC_CH_SEL_CTL:
- case QPNP_ADC_TM_M3_ADC_CH_SEL_CTL:
- case QPNP_ADC_TM_M4_ADC_CH_SEL_CTL:
- /* Configure AMUX control register for channel selection */
- rc = qpnp_adc_tm_write_reg(btm_chan, amux_channel);
- if (rc < 0) {
- pr_err("btm_chan:%d selection failed\n", btm_chan);
- return rc;
- }
+ }
- /* Enable corresponding BTM channel measurement */
- rc = qpnp_adc_tm_meas_int_update(
- QPNP_ADC_TM_MULTI_MEAS_EN,
- adc_tm_data[btm_chan].multi_meas_en, true);
- if (rc < 0) {
- pr_err("multi measurement en failed\n");
- return rc;
- }
- break;
- default:
- return -EINVAL;
+ /* Enable corresponding BTM channel measurement */
+ rc = qpnp_adc_tm_reg_update(
+ QPNP_ADC_TM_MULTI_MEAS_EN, sensor_mask, true);
+ if (rc < 0) {
+ pr_err("multi measurement en failed\n");
+ return rc;
}
return rc;
@@ -477,12 +603,17 @@
static int32_t qpnp_adc_tm_configure(
struct qpnp_adc_amux_properties *chan_prop)
{
- u8 decimation = 0;
+ u8 decimation = 0, op_cntrl = 0;
int rc = 0;
uint32_t btm_chan = 0;
+ /* Disable bank */
+ rc = qpnp_adc_tm_disable();
+ if (rc)
+ return rc;
+
/* Check if a conversion is in progress */
- rc = qpnp_adc_tm_enable_req_sts_check();
+ rc = qpnp_adc_tm_req_sts_check();
if (rc < 0) {
pr_err("adc-tm req_sts check failed\n");
return rc;
@@ -495,9 +626,9 @@
return rc;
}
- /* Configure AMUX channel */
- rc = qpnp_adc_tm_write_reg(QPNP_ADC_CH_SEL_CTL,
- chan_prop->amux_channel);
+ /* Configure AMUX channel select for the corresponding BTM channel*/
+ btm_chan = chan_prop->chan_prop->tm_channel_select;
+ rc = qpnp_adc_tm_write_reg(btm_chan, chan_prop->amux_channel);
if (rc < 0) {
pr_err("adc-tm channel selection err\n");
return rc;
@@ -529,14 +660,14 @@
}
/* Measurement interval setup */
- rc = qpnp_adc_tm_timer_interval_select(chan_prop->chan_prop);
+ rc = qpnp_adc_tm_timer_interval_select(btm_chan,
+ chan_prop->chan_prop);
if (rc < 0) {
pr_err("adc-tm timer select failed\n");
return rc;
}
/* Channel configuration setup */
- btm_chan = chan_prop->chan_prop->tm_channel_select;
rc = qpnp_adc_tm_channel_configure(btm_chan, chan_prop->chan_prop,
chan_prop->amux_channel);
if (rc < 0) {
@@ -544,19 +675,21 @@
return rc;
}
- /* Enable bank */
- rc = qpnp_adc_tm_enable(true);
- if (rc)
- return rc;
-
/* Recurring interval measurement enable */
- rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_MEAS_INTERVAL_OP_CTL,
- QPNP_ADC_MEAS_INTERVAL_OP, true);
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_MEAS_INTERVAL_OP_CTL, &op_cntrl);
+ op_cntrl |= QPNP_ADC_MEAS_INTERVAL_OP;
+ rc = qpnp_adc_tm_reg_update(QPNP_ADC_MEAS_INTERVAL_OP_CTL,
+ op_cntrl, true);
if (rc < 0) {
pr_err("adc-tm meas interval op configure failed\n");
return rc;
}
+ /* Enable bank */
+ rc = qpnp_adc_tm_enable();
+ if (rc)
+ return rc;
+
/* Request conversion */
rc = qpnp_adc_tm_write_reg(QPNP_CONV_REQ, QPNP_CONV_REQ_SET);
if (rc < 0) {
@@ -570,12 +703,13 @@
static int qpnp_adc_tm_get_mode(struct thermal_zone_device *thermal,
enum thermal_device_mode *mode)
{
- struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
+ struct qpnp_adc_tm_sensor *adc_tm_sensor = thermal->devdata;
- if (!adc_tm || !mode)
+ if (!adc_tm_sensor || qpnp_adc_tm_check_revision(
+ adc_tm_sensor->btm_channel_num) || !mode)
return -EINVAL;
- *mode = adc_tm->mode;
+ *mode = adc_tm_sensor->mode;
return 0;
}
@@ -586,12 +720,14 @@
struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
struct qpnp_adc_tm_drv *adc_drv = qpnp_adc_tm;
int rc = 0, channel;
+ u8 sensor_mask = 0;
- if (!adc_tm)
+ if (!adc_tm || qpnp_adc_tm_check_revision(adc_tm->btm_channel_num))
return -EINVAL;
if (mode == THERMAL_DEVICE_ENABLED) {
- adc_drv->adc->amux_prop->amux_channel = adc_tm->sensor_num;
+ adc_drv->adc->amux_prop->amux_channel =
+ adc_tm->vadc_channel_num;
channel = adc_tm->sensor_num;
adc_drv->adc->amux_prop->decimation =
adc_drv->adc->adc_channels[channel].adc_decimation;
@@ -616,17 +752,31 @@
return -EINVAL;
}
} else if (mode == THERMAL_DEVICE_DISABLED) {
- rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_MULTI_MEAS_EN,
- adc_tm_data[adc_tm->btm_channel_num].multi_meas_en,
- false);
+ sensor_mask = 1 << adc_tm->sensor_num;
+ /* Disable bank */
+ rc = qpnp_adc_tm_disable();
+ if (rc < 0) {
+ pr_err("adc-tm disable failed\n");
+ return rc;
+ }
+
+ /* Check if a conversion is in progress */
+ rc = qpnp_adc_tm_req_sts_check();
+ if (rc < 0) {
+ pr_err("adc-tm req_sts check failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_reg_update(QPNP_ADC_TM_MULTI_MEAS_EN,
+ sensor_mask, false);
if (rc < 0) {
pr_err("multi measurement update failed\n");
return rc;
}
- rc = qpnp_adc_tm_enable(false);
+ rc = qpnp_adc_tm_enable_if_channel_meas();
if (rc < 0) {
- pr_err("adc-tm disable failed\n");
+ pr_err("re-enabling measurement failed\n");
return rc;
}
}
@@ -641,7 +791,8 @@
{
struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
- if (!adc_tm || !type || type < 0)
+ if (!adc_tm || qpnp_adc_tm_check_revision(adc_tm->btm_channel_num)
+ || !type || type < 0)
return -EINVAL;
switch (trip) {
@@ -669,7 +820,8 @@
uint16_t reg_low_thr_lsb, reg_low_thr_msb;
uint16_t reg_high_thr_lsb, reg_high_thr_msb;
- if (!adc_tm)
+ if (!adc_tm || qpnp_adc_tm_check_revision(
+ adc_tm_sensor->btm_channel_num))
return -EINVAL;
btm_channel_num = adc_tm_sensor->btm_channel_num;
@@ -733,10 +885,11 @@
uint16_t reg_high_thr_lsb, reg_high_thr_msb;
int rc = 0, btm_channel_num;
- if (!adc_tm)
+ if (!adc_tm || qpnp_adc_tm_check_revision(
+ adc_tm_sensor->btm_channel_num))
return -EINVAL;
- tm_config.channel = adc_tm_sensor->sensor_num;
+ tm_config.channel = adc_tm_sensor->vadc_channel_num;
switch (trip) {
case ADC_TM_TRIP_HIGH_WARM:
tm_config.high_thr_temp = temp;
@@ -748,6 +901,8 @@
return -EINVAL;
}
+ pr_debug("requested a high - %d and low - %d with trip - %d\n",
+ tm_config.high_thr_temp, tm_config.low_thr_temp, trip);
rc = qpnp_adc_tm_scale_therm_voltage_pu2(&tm_config);
if (rc < 0) {
pr_err("Failed to lookup the adc-tm thresholds\n");
@@ -801,131 +956,102 @@
return 0;
}
-static void notify_uspace_qpnp_adc_tm_fn(struct work_struct *work)
+static void notify_battery_therm(struct qpnp_adc_tm_sensor *adc_tm)
+{
+ /* Battery therm's warm temperature translates to low voltage */
+ if (adc_tm->low_thr_notify) {
+ /* HIGH_STATE = WARM_TEMP for battery client */
+ adc_tm->btm_param->threshold_notification(
+ ADC_TM_WARM_STATE, adc_tm->btm_param->btm_ctx);
+ adc_tm->low_thr_notify = false;
+ }
+
+ /* Battery therm's cool temperature translates to high voltage */
+ if (adc_tm->high_thr_notify) {
+ /* LOW_STATE = COOL_TEMP for battery client */
+ adc_tm->btm_param->threshold_notification(
+ ADC_TM_COOL_STATE, adc_tm->btm_param->btm_ctx);
+ adc_tm->high_thr_notify = false;
+ }
+
+ return;
+}
+
+static void notify_clients(struct qpnp_adc_tm_sensor *adc_tm)
+{
+ /* For non batt therm clients */
+ if (adc_tm->low_thr_notify) {
+ pr_debug("notify kernel with low state\n");
+ adc_tm->btm_param->threshold_notification(
+ ADC_TM_LOW_STATE, adc_tm->btm_param->btm_ctx);
+ adc_tm->low_thr_notify = false;
+ }
+
+ if (adc_tm->high_thr_notify) {
+ pr_debug("notify kernel with high state\n");
+ adc_tm->btm_param->threshold_notification(
+ ADC_TM_HIGH_STATE, adc_tm->btm_param->btm_ctx);
+ adc_tm->high_thr_notify = false;
+ }
+
+ return;
+}
+
+static void notify_adc_tm_fn(struct work_struct *work)
{
struct qpnp_adc_tm_sensor *adc_tm = container_of(work,
struct qpnp_adc_tm_sensor, work);
- sysfs_notify(&adc_tm->tz_dev->device.kobj,
+ if (adc_tm->thermal_node) {
+ sysfs_notify(&adc_tm->tz_dev->device.kobj,
NULL, "btm");
-}
-
-static void notify_usb_fn(struct work_struct *work)
-{
- struct qpnp_adc_tm_drv *adc_tm = container_of(work,
- struct qpnp_adc_tm_drv, usbid_work);
- int rc;
- u8 status_low, status_high;
-
- if (adc_tm->usb_id_param->threshold_notification != NULL) {
- rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_LOW,
- &status_low);
- if (rc) {
- pr_err("adc-tm read low status failed\n");
- return;
+ pr_debug("notifying uspace client\n");
+ } else {
+ if (adc_tm->btm_param->threshold_notification != NULL) {
+ if (adc_tm->scale_type == SCALE_RBATT_THERM)
+ notify_battery_therm(adc_tm);
+ else
+ notify_clients(adc_tm);
}
-
- rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_HIGH,
- &status_high);
- if (rc) {
- pr_err("adc-tm read high status failed\n");
- return;
- }
-
- if (status_low & 1)
- adc_tm->usb_id_param->threshold_notification(
- ADC_TM_LOW_STATE, adc_tm->usb_id_param->usbid_ctx);
- else if (status_high & 1)
- adc_tm->usb_id_param->threshold_notification(
- ADC_TM_HIGH_STATE, adc_tm->usb_id_param->usbid_ctx);
}
return;
}
-static void notify_batt_fn(struct work_struct *work)
-{
- struct qpnp_adc_tm_drv *adc_tm = container_of(work,
- struct qpnp_adc_tm_drv, batt_work);
- int rc;
- u8 status_low, status_high;
-
- if (adc_tm->battery_param->threshold_notification != NULL) {
- rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_LOW,
- &status_low);
- if (rc) {
- pr_err("adc-tm read low status failed\n");
- return;
- }
-
- rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_HIGH,
- &status_high);
- if (rc) {
- pr_err("adc-tm read high status failed\n");
- return;
- }
-
- if (status_low & QPNP_ADC_TM_LOW_THR_INT_EN_M1)
- adc_tm->battery_param->threshold_notification(
- ADC_TM_LOW_STATE, adc_tm->battery_param->btm_ctx);
- else if (status_high & QPNP_ADC_TM_HIGH_THR_INT_EN_M1)
- adc_tm->battery_param->threshold_notification(
- ADC_TM_HIGH_STATE, adc_tm->battery_param->btm_ctx);
- }
-
- return;
-}
-
-static int qpnp_adc_tm_activate_trip_type_fn(uint32_t btm_channel_num,
- enum thermal_trip_activation_mode mode, u8 *data, uint32_t reg)
-{
- u8 thr_int = 0;
- int rc = 0;
-
- rc = qpnp_adc_tm_read_reg(reg, &thr_int);
- if (rc) {
- pr_err("multi meas read failed\n");
- return rc;
- }
-
- thr_int = adc_tm_data[btm_channel_num].low_thr_int_chan_en;
-
- if (mode == THERMAL_TRIP_ACTIVATION_ENABLED)
- thr_int |= *data;
- else
- thr_int &= ~*data;
-
- rc = qpnp_adc_tm_write_reg(reg, thr_int);
- if (rc)
- pr_err("multi meas write failed\n");
-
- return rc;
-}
-
static int qpnp_adc_tm_activate_trip_type(struct thermal_zone_device *thermal,
int trip, enum thermal_trip_activation_mode mode)
{
struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
- int rc = 0;
+ int rc = 0, sensor_mask = 0;
u8 thr_int_en = 0;
+ bool state = false;
- if (!adc_tm)
+ if (!adc_tm || qpnp_adc_tm_check_revision(adc_tm->btm_channel_num))
return -EINVAL;
+ if (mode == THERMAL_TRIP_ACTIVATION_ENABLED)
+ state = true;
+
+ sensor_mask = 1 << adc_tm->sensor_num;
+
+ pr_debug("Sensor number:%x with state:%d\n", adc_tm->sensor_num, state);
+
switch (trip) {
case ADC_TM_TRIP_HIGH_WARM:
+ /* low_thr (lower voltage) for higher temp */
thr_int_en = adc_tm_data[adc_tm->btm_channel_num].
low_thr_int_chan_en;
- rc = qpnp_adc_tm_activate_trip_type_fn(adc_tm->btm_channel_num,
- mode, &thr_int_en, QPNP_ADC_TM_LOW_THR_INT_EN);
+ rc = qpnp_adc_tm_reg_update(QPNP_ADC_TM_LOW_THR_INT_EN,
+ sensor_mask, state);
if (rc)
pr_err("channel:%x failed\n", adc_tm->btm_channel_num);
break;
case ADC_TM_TRIP_LOW_COOL:
+ /* high_thr (higher voltage) for cooler temp */
thr_int_en = adc_tm_data[adc_tm->btm_channel_num].
high_thr_int_chan_en;
- rc = qpnp_adc_tm_activate_trip_type_fn(adc_tm->btm_channel_num,
- mode, &thr_int_en, QPNP_ADC_TM_HIGH_THR_INT_EN);
+ rc = qpnp_adc_tm_reg_update(QPNP_ADC_TM_HIGH_THR_INT_EN,
+ sensor_mask, state);
if (rc)
pr_err("channel:%x failed\n", adc_tm->btm_channel_num);
break;
@@ -941,12 +1067,20 @@
struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
u8 status_low = 0, status_high = 0, qpnp_adc_tm_meas_en = 0;
u8 adc_tm_low_enable = 0, adc_tm_high_enable = 0;
- u8 thr_int_disable = 0;
- int rc = 0, sensor_notify_num = 0;
+ u8 sensor_mask = 0;
+ int rc = 0, sensor_notify_num = 0, i = 0, sensor_num = 0, btm_chan_num;
if (!adc_tm || !adc_tm->adc_tm_initialized)
return -ENODEV;
+ mutex_lock(&adc_tm->adc->adc_lock);
+
+ rc = qpnp_adc_tm_req_sts_check();
+ if (rc) {
+ pr_err("adc-tm-tm req sts check failed with %d\n", rc);
+ goto fail;
+ }
+
rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_LOW, &status_low);
if (rc) {
pr_err("adc-tm-tm read status low failed with %d\n", rc);
@@ -972,100 +1106,107 @@
adc_tm_high_enable = qpnp_adc_tm_meas_en & status_high;
if (adc_tm_high_enable) {
- sensor_notify_num = (adc_tm_high_enable >> 3);
- switch (adc_tm_high_enable) {
- case 1:
- case 2:
- {
- if (adc_tm_high_enable == 1)
- thr_int_disable =
- QPNP_ADC_TM_HIGH_THR_INT_EN_M0;
- else if (adc_tm_high_enable == 2)
- thr_int_disable =
- QPNP_ADC_TM_HIGH_THR_INT_EN_M1;
+ sensor_notify_num = adc_tm_high_enable;
+ while (i < adc_tm->max_channels_available) {
+ if ((sensor_notify_num & 0x1) == 1)
+ sensor_num = i;
+ sensor_notify_num >>= 1;
+ i++;
+ }
- rc = qpnp_adc_tm_meas_int_update(
+ btm_chan_num = adc_tm->sensor[sensor_num].btm_channel_num;
+ pr_debug("high:sen:%d, hs:0x%x, ls:0x%x, meas_en:0x%x\n",
+ sensor_num, adc_tm_high_enable, adc_tm_low_enable,
+ qpnp_adc_tm_meas_en);
+ if (!adc_tm->sensor[sensor_num].thermal_node) {
+ /* For non thermal registered clients
+ such as usb_id, vbatt, pmic_therm */
+ sensor_mask = 1 << sensor_num;
+ pr_debug("non thermal node - mask:%x\n", sensor_mask);
+ rc = qpnp_adc_tm_reg_update(
QPNP_ADC_TM_HIGH_THR_INT_EN,
- thr_int_disable, false);
+ sensor_mask, false);
if (rc < 0) {
pr_err("high threshold int read failed\n");
goto fail;
}
-
- if (adc_tm_high_enable == 1)
- schedule_work(&adc_tm->usbid_work);
- else if (adc_tm_high_enable == 2)
- schedule_work(&adc_tm->batt_work);
- }
- break;
- case 4:
- case 8:
- case 16:
- {
- /* High voltage threshold is triggered by low temp */
+ adc_tm->sensor[sensor_num].high_thr_notify = true;
+ } else {
+ /* Uses the thermal sysfs registered device to disable
+ the corresponding high voltage threshold which
+ is triggered by low temp */
+ pr_debug("thermal node with mask:%x\n", sensor_mask);
rc = qpnp_adc_tm_activate_trip_type(
- adc_tm->sensor[sensor_notify_num].tz_dev,
+ adc_tm->sensor[sensor_num].tz_dev,
ADC_TM_TRIP_LOW_COOL,
THERMAL_TRIP_ACTIVATION_DISABLED);
if (rc < 0) {
- pr_err("notify error:%d\n", sensor_notify_num);
+ pr_err("notify error:%d\n", sensor_num);
goto fail;
}
- schedule_work(&adc_tm->sensor[sensor_notify_num].work);
- }
- break;
- default:
- rc = -EINVAL;
}
}
if (adc_tm_low_enable) {
- sensor_notify_num = (adc_tm_low_enable >> 3);
- switch (adc_tm_low_enable) {
- case 1:
- case 2:
- {
- if (adc_tm_low_enable == 1)
- thr_int_disable = QPNP_ADC_TM_LOW_THR_INT_EN_M0;
- else if (adc_tm_low_enable == 2)
- thr_int_disable = QPNP_ADC_TM_LOW_THR_INT_EN_M1;
+ sensor_notify_num = adc_tm_low_enable;
+ i = 0;
+ while (i < adc_tm->max_channels_available) {
+ if ((sensor_notify_num & 0x1) == 1)
+ sensor_num = i;
+ sensor_notify_num >>= 1;
+ i++;
+ }
- rc = qpnp_adc_tm_meas_int_update(
+ btm_chan_num = adc_tm->sensor[sensor_num].btm_channel_num;
+ pr_debug("low:sen:%d, hs:0x%x, ls:0x%x, meas_en:0x%x\n",
+ sensor_num, adc_tm_high_enable, adc_tm_low_enable,
+ qpnp_adc_tm_meas_en);
+ if (!adc_tm->sensor[sensor_num].thermal_node) {
+ /* For non thermal registered clients
+ such as usb_id, vbatt, pmic_therm */
+ pr_debug("non thermal node - mask:%x\n", sensor_mask);
+ sensor_mask = 1 << sensor_num;
+ rc = qpnp_adc_tm_reg_update(
QPNP_ADC_TM_LOW_THR_INT_EN,
- thr_int_disable, false);
+ sensor_mask, false);
if (rc < 0) {
- pr_err("low threshold int disable failed\n");
+ pr_err("low threshold int read failed\n");
goto fail;
}
-
- if (adc_tm_low_enable == 1)
- schedule_work(&adc_tm->usbid_work);
- else if (adc_tm_low_enable == 2)
- schedule_work(&adc_tm->batt_work);
- }
- break;
- case 4:
- case 8:
- case 16:
- {
- /* Low voltage threshold is triggered by high temp */
+ adc_tm->sensor[sensor_num].low_thr_notify = true;
+ } else {
+ /* Uses the thermal sysfs registered device to disable
+ the corresponding low voltage threshold which
+ is triggered by high temp */
+ pr_debug("thermal node with mask:%x\n", sensor_mask);
rc = qpnp_adc_tm_activate_trip_type(
- adc_tm->sensor[sensor_notify_num].tz_dev,
+ adc_tm->sensor[sensor_num].tz_dev,
ADC_TM_TRIP_HIGH_WARM,
THERMAL_TRIP_ACTIVATION_DISABLED);
if (rc < 0) {
- pr_err("notify error:%d\n", sensor_notify_num);
+ pr_err("notify error:%d\n", sensor_num);
goto fail;
}
- schedule_work(&adc_tm->sensor[sensor_notify_num].work);
- }
- break;
- default:
- rc = -EINVAL;
}
}
+ rc = qpnp_adc_tm_reg_update(QPNP_ADC_TM_MULTI_MEAS_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("multi meas disable for channel failed\n");
+ goto fail;
+ }
+
+ rc = qpnp_adc_tm_enable_if_channel_meas();
+ if (rc < 0) {
+ pr_err("re-enabling measurement failed\n");
+ return rc;
+ }
fail:
+ mutex_unlock(&adc_tm->adc->adc_lock);
+
+ schedule_work(&adc_tm->sensor[sensor_num].work);
+
return rc;
}
@@ -1074,6 +1215,8 @@
int rc;
rc = qpnp_adc_tm_read_status();
+ if (rc < 0)
+ pr_err("adc-tm high thr work failed\n");
return;
}
@@ -1082,6 +1225,8 @@
static irqreturn_t qpnp_adc_tm_high_thr_isr(int irq, void *data)
{
+ qpnp_adc_tm_disable();
+
schedule_work(&trigger_completion_adc_tm_high_thr_work);
return IRQ_HANDLED;
@@ -1092,6 +1237,8 @@
int rc;
rc = qpnp_adc_tm_read_status();
+ if (rc < 0)
+ pr_err("adc-tm low thr work failed\n");
return;
}
@@ -1099,6 +1246,8 @@
static irqreturn_t qpnp_adc_tm_low_thr_isr(int irq, void *data)
{
+ qpnp_adc_tm_disable();
+
schedule_work(&trigger_completion_adc_tm_low_thr_work);
return IRQ_HANDLED;
@@ -1120,7 +1269,7 @@
struct qpnp_vadc_result result;
int rc = 0;
- rc = qpnp_vadc_read(adc_tm_sensor->sensor_num, &result);
+ rc = qpnp_vadc_read(adc_tm_sensor->vadc_channel_num, &result);
if (rc)
return rc;
@@ -1139,24 +1288,47 @@
.set_trip_temp = qpnp_adc_tm_set_trip_temp,
};
-int32_t qpnp_adc_tm_usbid_configure(struct qpnp_adc_tm_usbid_param *param)
+int32_t qpnp_adc_tm_channel_measure(struct qpnp_adc_tm_btm_param *param)
{
struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
- uint32_t channel;
+ uint32_t channel, dt_index = 0, scale_type = 0;
int rc = 0;
if (!adc_tm || !adc_tm->adc_tm_initialized)
return -ENODEV;
if (param->threshold_notification == NULL) {
- pr_err("No USB_ID high/low voltage notificaton??\n");
+ pr_err("No notification for high/low temp??\n");
return -EINVAL;
}
mutex_lock(&adc_tm->adc->adc_lock);
- adc_tm->adc->amux_prop->amux_channel = LR_MUX10_PU2_AMUX_USB_ID_LV;
- channel = LR_MUX10_PU2_AMUX_USB_ID_LV;
+ channel = param->channel;
+ while ((adc_tm->adc->adc_channels[dt_index].channel_num
+ != channel) && (dt_index < adc_tm->max_channels_available))
+ dt_index++;
+
+ if (dt_index >= adc_tm->max_channels_available) {
+ pr_err("not a valid ADC_TM channel\n");
+ rc = -EINVAL;
+ goto fail_unlock;
+ }
+
+ rc = qpnp_adc_tm_check_revision(
+ adc_tm->sensor[dt_index].btm_channel_num);
+ if (rc < 0)
+ goto fail_unlock;
+
+ scale_type = adc_tm->adc->adc_channels[dt_index].adc_scale_fn;
+ if (scale_type >= SCALE_RSCALE_NONE) {
+ rc = -EBADF;
+ goto fail_unlock;
+ }
+
+ pr_debug("channel:%d, scale_type:%d, dt_idx:%d",
+ channel, scale_type, dt_index);
+ adc_tm->adc->amux_prop->amux_channel = channel;
adc_tm->adc->amux_prop->decimation =
adc_tm->adc->adc_channels[channel].adc_decimation;
adc_tm->adc->amux_prop->hw_settle_time =
@@ -1167,10 +1339,11 @@
ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
adc_tm->adc->amux_prop->chan_prop->meas_interval1 =
ADC_MEAS1_INTERVAL_1S;
- qpnp_adc_usb_scaler(param, &adc_tm->adc->amux_prop->chan_prop->low_thr,
+ adc_tm_rscale_fn[scale_type].chan(param,
+ &adc_tm->adc->amux_prop->chan_prop->low_thr,
&adc_tm->adc->amux_prop->chan_prop->high_thr);
adc_tm->adc->amux_prop->chan_prop->tm_channel_select =
- QPNP_ADC_TM_M0_ADC_CH_SEL_CTL;
+ adc_tm->sensor[dt_index].btm_channel_num;
adc_tm->adc->amux_prop->chan_prop->timer_select =
ADC_MEAS_TIMER_SELECT1;
adc_tm->adc->amux_prop->chan_prop->state_request =
@@ -1181,144 +1354,103 @@
goto fail_unlock;
}
- adc_tm->usb_id_param = param;
+ adc_tm->sensor[dt_index].btm_param = param;
+ adc_tm->sensor[dt_index].scale_type = scale_type;
fail_unlock:
mutex_unlock(&adc_tm->adc->adc_lock);
return rc;
}
+EXPORT_SYMBOL(qpnp_adc_tm_channel_measure);
+
+int32_t qpnp_adc_tm_disable_chan_meas(struct qpnp_adc_tm_btm_param *param)
+{
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ uint32_t channel, dt_index = 0, btm_chan_num;
+ u8 sensor_mask = 0;
+ int rc = 0;
+
+ if (!adc_tm || !adc_tm->adc_tm_initialized)
+ return -ENODEV;
+
+ mutex_lock(&adc_tm->adc->adc_lock);
+
+ /* Disable bank */
+ rc = qpnp_adc_tm_disable();
+ if (rc < 0) {
+ pr_err("adc-tm disable failed\n");
+ goto fail;
+ }
+
+ /* Check if a conversion is in progress */
+ rc = qpnp_adc_tm_req_sts_check();
+ if (rc < 0) {
+ pr_err("adc-tm req_sts check failed\n");
+ goto fail;
+ }
+
+ channel = param->channel;
+ while ((adc_tm->adc->adc_channels[dt_index].channel_num
+ != channel) && (dt_index < adc_tm->max_channels_available))
+ dt_index++;
+
+ if (dt_index >= adc_tm->max_channels_available) {
+ pr_err("not a valid ADC_TMN channel\n");
+ rc = -EINVAL;
+ goto fail;
+ }
+
+ btm_chan_num = adc_tm->sensor[dt_index].btm_channel_num;
+ sensor_mask = 1 << adc_tm->sensor[dt_index].sensor_num;
+
+ rc = qpnp_adc_tm_reg_update(QPNP_ADC_TM_LOW_THR_INT_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("low threshold int write failed\n");
+ goto fail;
+ }
+
+ rc = qpnp_adc_tm_reg_update(QPNP_ADC_TM_HIGH_THR_INT_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("high threshold int enable failed\n");
+ goto fail;
+ }
+
+ rc = qpnp_adc_tm_reg_update(QPNP_ADC_TM_MULTI_MEAS_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("multi measurement en failed\n");
+ goto fail;
+ }
+
+ rc = qpnp_adc_tm_enable_if_channel_meas();
+ if (rc < 0)
+ pr_err("re-enabling measurement failed\n");
+
+fail:
+ mutex_unlock(&adc_tm->adc->adc_lock);
+
+ return rc;
+}
+EXPORT_SYMBOL(qpnp_adc_tm_disable_chan_meas);
+
+int32_t qpnp_adc_tm_usbid_configure(struct qpnp_adc_tm_btm_param *param)
+{
+ param->channel = LR_MUX10_PU2_AMUX_USB_ID_LV;
+ return qpnp_adc_tm_channel_measure(param);
+}
EXPORT_SYMBOL(qpnp_adc_tm_usbid_configure);
-static int32_t qpnp_adc_tm_chan_usbid_chan_btm_end(
- uint32_t btm_chan_num)
-{
- int32_t rc = 0;
-
- rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_LOW_THR_INT_EN,
- adc_tm_data[btm_chan_num].low_thr_int_chan_en,
- false);
- if (rc < 0) {
- pr_err("low threshold int write failed\n");
- return rc;
- }
-
- rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_HIGH_THR_INT_EN,
- adc_tm_data[btm_chan_num].high_thr_int_chan_en,
- false);
- if (rc < 0) {
- pr_err("high threshold int enable failed\n");
- return rc;
- }
-
- rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_MULTI_MEAS_EN,
- adc_tm_data[btm_chan_num].multi_meas_en,
- false);
- if (rc < 0) {
- pr_err("multi measurement en failed\n");
- return rc;
- }
-
- rc = qpnp_adc_tm_enable(false);
- if (rc < 0)
- pr_err("TM disable failed\n");
-
- return rc;
-}
-
int32_t qpnp_adc_tm_usbid_end(void)
{
- struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
- int rc = 0;
+ struct qpnp_adc_tm_btm_param param;
- if (!adc_tm || !adc_tm->adc_tm_initialized)
- return -ENODEV;
-
- mutex_lock(&adc_tm->adc->adc_lock);
-
- rc = qpnp_adc_tm_chan_usbid_chan_btm_end(
- QPNP_ADC_TM_M0_ADC_CH_SEL_CTL);
- if (rc < 0)
- pr_err("disabling thresholds for usb channel failed\n");
-
- mutex_unlock(&adc_tm->adc->adc_lock);
-
- return rc;
+ return qpnp_adc_tm_disable_chan_meas(¶m);
}
EXPORT_SYMBOL(qpnp_adc_tm_usbid_end);
-int32_t qpnp_adc_tm_btm_configure(struct qpnp_adc_tm_btm_param *param)
-{
- struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
- uint32_t channel;
- int rc = 0;
-
- if (!adc_tm || !adc_tm->adc_tm_initialized)
- return -ENODEV;
-
- if (param->threshold_notification == NULL) {
- pr_err("No battery high/low temp notificaton??\n");
- return -EINVAL;
- }
-
- mutex_lock(&adc_tm->adc->adc_lock);
-
- adc_tm->adc->amux_prop->amux_channel = LR_MUX1_BATT_THERM;
- channel = LR_MUX1_BATT_THERM;
- adc_tm->adc->amux_prop->decimation =
- adc_tm->adc->adc_channels[channel].adc_decimation;
- adc_tm->adc->amux_prop->hw_settle_time =
- adc_tm->adc->adc_channels[channel].hw_settle_time;
- adc_tm->adc->amux_prop->fast_avg_setup =
- adc_tm->adc->adc_channels[channel].fast_avg_setup;
- adc_tm->adc->amux_prop->mode_sel =
- ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
- adc_tm->adc->amux_prop->chan_prop->meas_interval2 =
- ADC_MEAS2_INTERVAL_1S;
- qpnp_adc_btm_scaler(param, &adc_tm->adc->amux_prop->chan_prop->low_thr,
- &adc_tm->adc->amux_prop->chan_prop->high_thr);
- adc_tm->adc->amux_prop->chan_prop->tm_channel_select =
- QPNP_ADC_TM_M1_ADC_CH_SEL_CTL;
- adc_tm->adc->amux_prop->chan_prop->timer_select =
- ADC_MEAS_TIMER_SELECT2;
- adc_tm->adc->amux_prop->chan_prop->state_request =
- param->state_request;
- rc = qpnp_adc_tm_configure(adc_tm->adc->amux_prop);
- if (rc) {
- pr_err("adc-tm configure failed with %d\n", rc);
- goto fail_unlock;
- }
-
- adc_tm->battery_param = param;
-
-fail_unlock:
- mutex_unlock(&adc_tm->adc->adc_lock);
-
- return rc;
-}
-EXPORT_SYMBOL(qpnp_adc_tm_btm_configure);
-
-int32_t qpnp_adc_tm_btm_end(void)
-{
- struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
- int rc = 0;
-
- if (!adc_tm || !adc_tm->adc_tm_initialized)
- return -ENODEV;
-
- mutex_lock(&adc_tm->adc->adc_lock);
-
- rc = qpnp_adc_tm_chan_usbid_chan_btm_end(
- QPNP_ADC_TM_M1_ADC_CH_SEL_CTL);
- if (rc < 0)
- pr_err("disabling thresholds for batt channel failed\n");
-
- mutex_unlock(&adc_tm->adc->adc_lock);
-
- return rc;
-}
-EXPORT_SYMBOL(qpnp_adc_tm_btm_end);
-
int32_t qpnp_adc_tm_is_ready(void)
{
struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
@@ -1335,7 +1467,7 @@
struct device_node *node = spmi->dev.of_node, *child;
struct qpnp_adc_tm_drv *adc_tm;
struct qpnp_adc_drv *adc_qpnp;
- int32_t count_adc_channel_list = 0, rc, i = 0, j = 0;
+ int32_t count_adc_channel_list = 0, rc, sen_idx = 0;
u8 thr_init = 0;
if (!node)
@@ -1363,6 +1495,7 @@
return -ENOMEM;
}
+ qpnp_adc_tm = adc_tm;
adc_qpnp = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_adc_drv),
GFP_KERNEL);
if (!adc_qpnp) {
@@ -1430,41 +1563,45 @@
for_each_child_of_node(node, child) {
char name[25];
int btm_channel_num;
+ bool thermal_node = false;
+
rc = of_property_read_u32(child,
"qcom,btm-channel-number", &btm_channel_num);
if (rc) {
pr_err("Invalid btm channel number\n");
goto fail;
}
-
- if ((btm_channel_num != QPNP_ADC_TM_M0_ADC_CH_SEL_CTL) &&
- (btm_channel_num != QPNP_ADC_TM_M1_ADC_CH_SEL_CTL)) {
+ adc_tm->sensor[sen_idx].btm_channel_num = btm_channel_num;
+ adc_tm->sensor[sen_idx].vadc_channel_num =
+ adc_tm->adc->adc_channels[sen_idx].channel_num;
+ adc_tm->sensor[sen_idx].sensor_num = sen_idx;
+ pr_debug("btm_chan:%x, vadc_chan:%x\n", btm_channel_num,
+ adc_tm->adc->adc_channels[sen_idx].channel_num);
+ if (thermal_node) {
/* Register with the thermal zone */
- adc_tm->sensor[i].mode = THERMAL_DEVICE_DISABLED;
- snprintf(name, sizeof(name), "qpnp_adc_tm_sensor%d", i);
- adc_tm->sensor[i].sensor_num =
- adc_tm->adc->adc_channels[j].channel_num;
- adc_tm->sensor[i].btm_channel_num = btm_channel_num;
- adc_tm->sensor[i].meas_interval =
+ pr_debug("thermal node%x\n", btm_channel_num);
+ adc_tm->sensor[sen_idx].mode = THERMAL_DEVICE_DISABLED;
+ adc_tm->sensor[sen_idx].thermal_node = true;
+ snprintf(name, sizeof(name),
+ adc_tm->adc->adc_channels[sen_idx].name);
+ adc_tm->sensor[sen_idx].meas_interval =
QPNP_ADC_TM_MEAS_INTERVAL;
- adc_tm->sensor[i].low_thr = QPNP_ADC_TM_M0_LOW_THR;
- adc_tm->sensor[i].high_thr = QPNP_ADC_TM_M0_HIGH_THR;
- adc_tm->sensor[i].tz_dev =
+ adc_tm->sensor[sen_idx].low_thr =
+ QPNP_ADC_TM_M0_LOW_THR;
+ adc_tm->sensor[sen_idx].high_thr =
+ QPNP_ADC_TM_M0_HIGH_THR;
+ adc_tm->sensor[sen_idx].tz_dev =
thermal_zone_device_register(name,
ADC_TM_TRIP_NUM,
- &adc_tm->sensor[i],
+ &adc_tm->sensor[sen_idx],
&qpnp_adc_tm_thermal_ops, 0, 0, 0, 0);
- if (IS_ERR(adc_tm->sensor[i].tz_dev))
+ if (IS_ERR(adc_tm->sensor[sen_idx].tz_dev))
pr_err("thermal device register failed.\n");
- INIT_WORK(&adc_tm->sensor[i].work,
- notify_uspace_qpnp_adc_tm_fn);
- i++;
}
- j++;
+ INIT_WORK(&adc_tm->sensor[sen_idx].work, notify_adc_tm_fn);
+ sen_idx++;
}
- INIT_WORK(&adc_tm->usbid_work, notify_usb_fn);
- INIT_WORK(&adc_tm->batt_work, notify_batt_fn);
- qpnp_adc_tm = adc_tm;
+ adc_tm->max_channels_available = count_adc_channel_list;
dev_set_drvdata(&spmi->dev, adc_tm);
rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_HIGH_THR_INT_EN, thr_init);
if (rc < 0) {
@@ -1486,6 +1623,7 @@
adc_tm->adc_tm_initialized = true;
+ pr_debug("OK\n");
return 0;
fail:
qpnp_adc_tm = NULL;
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 21a936e..8806004 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -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;
}
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-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index b48785c..9fad90c 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -31,6 +31,7 @@
#include <linux/uaccess.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
+#include <linux/qpnp-misc.h>
#include <linux/usb/msm_hsusb.h>
#include <linux/regulator/consumer.h>
#include <linux/power_supply.h>
@@ -187,7 +188,7 @@
enum usb_chg_state chg_state;
int pmic_id_irq;
struct work_struct id_work;
- struct qpnp_adc_tm_usbid_param adc_param;
+ struct qpnp_adc_tm_btm_param adc_param;
struct delayed_work init_adc_work;
bool id_adc_detect;
u8 dcd_retries;
@@ -2085,16 +2086,25 @@
static void dwc3_id_work(struct work_struct *w)
{
struct dwc3_msm *mdwc = container_of(w, struct dwc3_msm, id_work);
+ int ret;
/* Give external client a chance to handle */
- if (!mdwc->ext_inuse) {
- if (usb_ext) {
- int ret = usb_ext->notify(usb_ext->ctxt, mdwc->id_state,
- dwc3_ext_notify_online);
- dev_dbg(mdwc->dev, "%s: external handler returned %d\n",
- __func__, ret);
- mdwc->ext_inuse = (ret == 0);
+ if (!mdwc->ext_inuse && usb_ext) {
+ if (mdwc->pmic_id_irq)
+ disable_irq(mdwc->pmic_id_irq);
+
+ ret = usb_ext->notify(usb_ext->ctxt, mdwc->id_state,
+ dwc3_ext_notify_online);
+ dev_dbg(mdwc->dev, "%s: external handler returned %d\n",
+ __func__, ret);
+
+ if (mdwc->pmic_id_irq) {
+ /* ID may have changed while IRQ disabled; update it */
+ mdwc->id_state = !!irq_read_line(mdwc->pmic_id_irq);
+ enable_irq(mdwc->pmic_id_irq);
}
+
+ mdwc->ext_inuse = (ret == 0);
}
if (!mdwc->ext_inuse) { /* notify OTG */
@@ -2106,10 +2116,14 @@
static irqreturn_t dwc3_pmic_id_irq(int irq, void *data)
{
struct dwc3_msm *mdwc = data;
+ enum dwc3_id_state id;
/* If we can't read ID line state for some reason, treat it as float */
- mdwc->id_state = !!irq_read_line(irq);
- queue_work(system_nrt_wq, &mdwc->id_work);
+ id = !!irq_read_line(irq);
+ if (mdwc->id_state != id) {
+ mdwc->id_state = id;
+ queue_work(system_nrt_wq, &mdwc->id_work);
+ }
return IRQ_HANDLED;
}
@@ -2158,7 +2172,7 @@
mdwc->adc_param.high_thr = adc_high_threshold;
mdwc->adc_param.timer_interval = adc_meas_interval;
mdwc->adc_param.state_request = ADC_TM_HIGH_LOW_THR_ENABLE;
- mdwc->adc_param.usbid_ctx = mdwc;
+ mdwc->adc_param.btm_ctx = mdwc;
mdwc->adc_param.threshold_notification = dwc3_adc_notification;
ret = qpnp_adc_tm_usbid_configure(&mdwc->adc_param);
@@ -2369,7 +2383,7 @@
goto free_hs_ldo_init;
}
- msm->ext_xceiv.id = DWC3_ID_FLOAT;
+ msm->id_state = msm->ext_xceiv.id = DWC3_ID_FLOAT;
msm->ext_xceiv.otg_capability = of_property_read_bool(node,
"qcom,otg-capability");
msm->charger.charging_disabled = of_property_read_bool(node,
@@ -2397,17 +2411,30 @@
if (msm->ext_xceiv.otg_capability) {
msm->pmic_id_irq = platform_get_irq_byname(pdev, "pmic_id_irq");
if (msm->pmic_id_irq > 0) {
- ret = devm_request_irq(&pdev->dev, msm->pmic_id_irq,
- dwc3_pmic_id_irq,
- IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING,
- "dwc3_msm_pmic_id", msm);
- if (ret) {
- dev_err(&pdev->dev, "irqreq IDINT failed\n");
+ /* check if PMIC ID IRQ is supported */
+ ret = qpnp_misc_irqs_available(&pdev->dev);
+
+ if (ret == -EPROBE_DEFER) {
+ /* qpnp hasn't probed yet; defer dwc probe */
goto disable_hs_ldo;
+ } else if (ret == 0) {
+ msm->pmic_id_irq = 0;
+ } else {
+ ret = devm_request_irq(&pdev->dev,
+ msm->pmic_id_irq,
+ dwc3_pmic_id_irq,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
+ "dwc3_msm_pmic_id", msm);
+ if (ret) {
+ dev_err(&pdev->dev, "irqreq IDINT failed\n");
+ goto disable_hs_ldo;
+ }
+ enable_irq_wake(msm->pmic_id_irq);
}
- enable_irq_wake(msm->pmic_id_irq);
- } else {
+ }
+
+ if (msm->pmic_id_irq <= 0) {
/* If no PMIC ID IRQ, use ADC for ID pin detection */
queue_work(system_nrt_wq, &msm->init_adc_work.work);
device_create_file(&pdev->dev, &dev_attr_adc_enable);
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..e415a95 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>
@@ -772,6 +771,7 @@
break;
case MDP_YCRYCB_H2V1:
+ case MDP_CBYCRY_H2V1:
if (pipe->src_x & 0x1)
pipe->src_x += 1;
*luma_off += pipe->src_x * 2 +
@@ -973,6 +973,7 @@
case MDP_RGBX_8888:
return OVERLAY_TYPE_RGB;
case MDP_YCRYCB_H2V1:
+ case MDP_CBYCRY_H2V1:
case MDP_Y_CRCB_H2V1:
case MDP_Y_CBCR_H2V1:
case MDP_Y_CRCB_H1V2:
@@ -1168,6 +1169,24 @@
pipe->unpack_tight = 1;
pipe->unpack_align_msb = 0;
pipe->unpack_count = 3;
+ pipe->element3 = C1_B_Cb; /* B */
+ pipe->element2 = C0_G_Y; /* G */
+ pipe->element1 = C2_R_Cr; /* R */
+ pipe->element0 = C0_G_Y; /* G */
+ pipe->bpp = 2; /* 2 bpp */
+ pipe->chroma_sample = MDP4_CHROMA_H2V1;
+ break;
+ case MDP_CBYCRY_H2V1:
+ pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+ pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
+ pipe->a_bit = 0; /* alpha, 4 bits */
+ pipe->r_bit = 3; /* R, 8 bits */
+ pipe->b_bit = 3; /* B, 8 bits */
+ pipe->g_bit = 3; /* G, 8 bits */
+ pipe->alpha_enable = 0;
+ pipe->unpack_tight = 1;
+ pipe->unpack_align_msb = 0;
+ pipe->unpack_count = 3;
pipe->element3 = C0_G_Y; /* G */
pipe->element2 = C2_R_Cr; /* R */
pipe->element1 = C0_G_Y; /* G */
@@ -3109,9 +3128,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 +3162,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..c847ee6 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;
@@ -81,6 +82,7 @@
u8 clk_ena;
u8 fs_ena;
u8 vsync_ena;
+ unsigned long min_mdp_clk;
u32 res_init;
u32 bus_hdl;
@@ -88,6 +90,8 @@
u32 smp_mb_cnt;
u32 smp_mb_size;
+ u32 rot_block_size;
+
struct mdss_hw_settings *hw_settings;
struct mdss_mdp_pipe *vig_pipes;
diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c
index abef27d..7dc4f49 100644
--- a/drivers/video/msm/mdss/mdss_debug.c
+++ b/drivers/video/msm/mdss/mdss_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2009-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
@@ -333,6 +333,9 @@
return -ENODEV;
}
+ debugfs_create_u32("min_mdp_clk", 0644, mdd->root,
+ (u32 *)&mdata->min_mdp_clk);
+
mdata->debug_data = mdd;
return 0;
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_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index e8a3795..b93efd9 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -2283,15 +2283,14 @@
/* If power down is already underway, wait for it to finish */
flush_work_sync(&hdmi_ctrl->power_off_work);
- if (!hdmi_ctrl->panel_power_on) {
+ if (!hdmi_ctrl->panel_power_on)
hdmi_tx_hpd_off(hdmi_ctrl);
- } else {
+ else
hdmi_ctrl->hpd_off_pending = true;
- hdmi_tx_send_cable_notification(hdmi_ctrl, 0);
- DEV_DBG("%s: Hdmi state switch to %d\n", __func__,
- hdmi_ctrl->sdev.state);
- }
+ hdmi_tx_send_cable_notification(hdmi_ctrl, 0);
+ DEV_DBG("%s: Hdmi state switch to %d\n", __func__,
+ hdmi_ctrl->sdev.state);
}
return rc;
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index f9b05fc..217ac18 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -127,6 +127,7 @@
static int mdss_mdp_parse_dt_prop_len(struct platform_device *pdev,
char *prop_name);
static int mdss_mdp_parse_dt_smp(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_misc(struct platform_device *pdev);
int mdss_mdp_alloc_fb_mem(struct msm_fb_data_type *mfd,
u32 size, u32 *phys, void **virt)
@@ -520,13 +521,21 @@
return ret;
}
-void mdss_mdp_set_clk_rate(unsigned long min_clk_rate)
+void mdss_mdp_set_clk_rate(unsigned long rate)
{
+ struct mdss_data_type *mdata = mdss_res;
unsigned long clk_rate;
struct clk *clk = mdss_mdp_get_clk(MDSS_CLK_MDP_SRC);
+ unsigned long min_clk_rate;
+
+ min_clk_rate = max(rate, mdata->min_mdp_clk);
+
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 +646,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) {
@@ -1012,7 +1030,7 @@
vbif_arr = of_get_property(pdev->dev.of_node, "qcom,vbif-settings",
&vbif_len);
- if (!vbif_arr || (mdp_len & 1)) {
+ if (!vbif_arr || (vbif_len & 1)) {
pr_warn("MDSS VBIF settings not found\n");
vbif_len = 0;
}
@@ -1083,6 +1101,12 @@
return rc;
}
+ rc = mdss_mdp_parse_dt_misc(pdev);
+ if (rc) {
+ pr_err("Error in device tree : misc\n");
+ return rc;
+ }
+
return 0;
}
@@ -1367,6 +1391,19 @@
return rc;
}
+static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
+{
+ struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+ u32 data;
+ int rc;
+
+ rc = of_property_read_u32(pdev->dev.of_node, "qcom,mdss-rot-block-size",
+ &data);
+ mdata->rot_block_size = (!rc ? data : 128);
+
+ return 0;
+}
+
static int mdss_mdp_parse_dt_handler(struct platform_device *pdev,
char *prop_name, u32 *offsets, int len)
{
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 43456ca..14c1e52 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -122,6 +122,7 @@
u32 flush_bits;
u32 play_cnt;
+ u32 underrun_cnt;
u16 width;
u16 height;
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index f8cd0ce..18c38a0 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -164,6 +164,9 @@
#define MDSS_MDP_REG_SSPP_STILE_FRAME_SIZE 0x02C
#define MDSS_MDP_REG_SSPP_SRC_FORMAT 0x030
#define MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN 0x034
+#define MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_0 0x050
+#define MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_1 0x054
+#define MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_2 0x058
#define MDSS_MDP_REG_SSPP_SRC_OP_MODE 0x038
#define MDSS_MDP_OP_DEINTERLACE BIT(22)
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index e2c3b23..dab8674 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -244,12 +244,17 @@
rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_TIMEGEN_OFF, NULL);
WARN(rc, "intf %d timegen off error (%d)\n", ctl->intf_num, rc);
+
+ mdss_mdp_irq_disable(MDSS_MDP_IRQ_INTF_UNDER_RUN,
+ ctl->intf_num);
}
mdss_mdp_video_set_vsync_handler(ctl, NULL);
mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num,
NULL, NULL);
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_UNDER_RUN, ctl->intf_num,
+ NULL, NULL);
ctx->ref_cnt--;
ctl->priv_data = NULL;
@@ -304,6 +309,17 @@
return rc;
}
+static void mdss_mdp_video_underrun_intr_done(void *arg)
+{
+ struct mdss_mdp_ctl *ctl = arg;
+ if (unlikely(!ctl))
+ return;
+
+ ctl->underrun_cnt++;
+ pr_warn("display underrun detected for ctl=%d count=%d\n", ctl->num,
+ ctl->underrun_cnt);
+}
+
static int mdss_mdp_video_display(struct mdss_mdp_ctl *ctl, void *arg)
{
struct mdss_mdp_video_ctx *ctx;
@@ -332,6 +348,8 @@
pr_debug("enabling timing gen for intf=%d\n", ctl->intf_num);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_UNDER_RUN, ctl->intf_num);
mdp_video_write(ctx, MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 1);
wmb();
@@ -390,6 +408,8 @@
mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num,
mdss_mdp_video_vsync_intr_done, ctl);
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_UNDER_RUN, ctl->intf_num,
+ mdss_mdp_video_underrun_intr_done, ctl);
itp.width = pinfo->xres + pinfo->lcdc.xres_pad;
itp.height = pinfo->yres + pinfo->lcdc.yres_pad;
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index c6b6e3f..b7b3c23 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -17,8 +17,6 @@
#include "mdss_mdp.h"
#include "mdss_mdp_rotator.h"
-#define ROT_BLK_SIZE 128
-
enum mdss_mdp_writeback_type {
MDSS_MDP_WRITEBACK_TYPE_ROTATOR,
MDSS_MDP_WRITEBACK_TYPE_LINE,
@@ -251,7 +249,7 @@
pr_debug("rot setup wb_num=%d\n", ctx->wb_num);
ctx->opmode = BIT(6); /* ROT EN */
- if (ROT_BLK_SIZE == 128)
+ if (ctl->mdata->rot_block_size == 128)
ctx->opmode |= BIT(4); /* block size 128 */
ctx->opmode |= rot->bwc_mode;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index c6b3472..0a56ba4 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -1467,7 +1467,7 @@
if (!mfd->panel_info->cont_splash_enabled) {
rc = mdss_mdp_overlay_start(mfd);
- if (!IS_ERR_VALUE(rc))
+ if (!IS_ERR_VALUE(rc) && (mfd->panel_info->type != DTV_PANEL))
rc = mdss_mdp_overlay_kickoff(mfd->ctl);
} else {
rc = mdss_mdp_ctl_setup(mfd->ctl);
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 4699e0d..ca741b1 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -19,7 +19,9 @@
#include "mdss_mdp.h"
-#define SMP_MB_CNT (mdss_res->smp_mb_cnt)
+#define SMP_MB_SIZE (mdss_res->smp_mb_size)
+#define SMP_MB_CNT (mdss_res->smp_mb_cnt)
+#define SMP_ENTRIES_PER_MB (SMP_MB_SIZE / 16)
static DEFINE_MUTEX(mdss_mdp_sspp_lock);
static DEFINE_MUTEX(mdss_mdp_smp_lock);
@@ -29,6 +31,17 @@
u32 ndx);
static int mdss_mdp_pipe_free(struct mdss_mdp_pipe *pipe);
+static inline void mdss_mdp_pipe_write(struct mdss_mdp_pipe *pipe,
+ u32 reg, u32 val)
+{
+ writel_relaxed(val, pipe->base + reg);
+}
+
+static inline u32 mdss_mdp_pipe_read(struct mdss_mdp_pipe *pipe, u32 reg)
+{
+ return readl_relaxed(pipe->base + reg);
+}
+
static u32 mdss_mdp_smp_mmb_reserve(unsigned long *smp, size_t n)
{
u32 i, mmb;
@@ -45,9 +58,10 @@
return i;
}
-static void mdss_mdp_smp_mmb_set(int client_id, unsigned long *smp)
+static int mdss_mdp_smp_mmb_set(int client_id, unsigned long *smp)
{
u32 mmb, off, data, s;
+ int cnt = 0;
for_each_set_bit(mmb, smp, SMP_MB_CNT) {
off = (mmb / 3) * 4;
@@ -57,7 +71,9 @@
data |= client_id << s;
MDSS_MDP_REG_WRITE(MDSS_MDP_REG_SMP_ALLOC_W0 + off, data);
MDSS_MDP_REG_WRITE(MDSS_MDP_REG_SMP_ALLOC_R0 + off, data);
+ cnt++;
}
+ return cnt;
}
static void mdss_mdp_smp_mmb_free(unsigned long *smp)
@@ -70,6 +86,24 @@
}
}
+static void mdss_mdp_smp_set_wm_levels(struct mdss_mdp_pipe *pipe, int mb_cnt)
+{
+ u32 entries, val, wm[3];
+
+ entries = mb_cnt * SMP_ENTRIES_PER_MB;
+ val = entries >> 2;
+
+ wm[0] = val;
+ wm[1] = wm[0] + val;
+ wm[2] = wm[1] + val;
+
+ pr_debug("pnum=%d watermarks %u,%u,%u\n", pipe->num,
+ wm[0], wm[1], wm[2]);
+ mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_0, wm[0]);
+ mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_1, wm[1]);
+ mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_2, wm[2]);
+}
+
static void mdss_mdp_smp_free(struct mdss_mdp_pipe *pipe)
{
mutex_lock(&mdss_mdp_smp_lock);
@@ -81,24 +115,31 @@
static int mdss_mdp_smp_reserve(struct mdss_mdp_pipe *pipe)
{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
u32 num_blks = 0, reserved = 0;
struct mdss_mdp_plane_sizes ps;
int i, rc;
- rc = mdss_mdp_get_plane_sizes(pipe->src_fmt->format, pipe->src.w,
- pipe->src.h, &ps);
- if (rc)
- return rc;
+ if ((mdata->mdp_rev >= MDSS_MDP_HW_REV_102) &&
+ pipe->src_fmt->is_yuv) {
+ ps.num_planes = 2;
+ ps.ystride[0] = pipe->src.w;
+ ps.ystride[1] = pipe->src.w;
+ } else {
+ rc = mdss_mdp_get_plane_sizes(pipe->src_fmt->format,
+ pipe->src.w, pipe->src.h, &ps);
+ if (rc)
+ return rc;
+ }
if ((ps.num_planes > 1) && (pipe->type == MDSS_MDP_PIPE_TYPE_RGB))
return -EINVAL;
mutex_lock(&mdss_mdp_smp_lock);
for (i = 0; i < ps.num_planes; i++) {
- num_blks = DIV_ROUND_UP(2 * ps.ystride[i],
- mdss_res->smp_mb_size);
+ num_blks = DIV_ROUND_UP(2 * ps.ystride[i], SMP_MB_SIZE);
- if (mdss_res->mdp_rev == MDSS_MDP_HW_REV_100)
+ if (mdata->mdp_rev == MDSS_MDP_HW_REV_100)
num_blks = roundup_pow_of_two(num_blks);
pr_debug("reserving %d mmb for pnum=%d plane=%d\n",
@@ -123,9 +164,12 @@
static int mdss_mdp_smp_alloc(struct mdss_mdp_pipe *pipe)
{
int i;
+ int cnt = 0;
+
mutex_lock(&mdss_mdp_smp_lock);
- for (i = 0; i < pipe->src_planes.num_planes; i++)
- mdss_mdp_smp_mmb_set(pipe->ftch_id + i, &pipe->smp[i]);
+ for (i = 0; i < MAX_PLANES; i++)
+ cnt += mdss_mdp_smp_mmb_set(pipe->ftch_id + i, &pipe->smp[i]);
+ mdss_mdp_smp_set_wm_levels(pipe, cnt);
mutex_unlock(&mdss_mdp_smp_lock);
return 0;
}
@@ -319,17 +363,6 @@
}
-static inline void mdss_mdp_pipe_write(struct mdss_mdp_pipe *pipe,
- u32 reg, u32 val)
-{
- writel_relaxed(val, pipe->base + reg);
-}
-
-static inline u32 mdss_mdp_pipe_read(struct mdss_mdp_pipe *pipe, u32 reg)
-{
- return readl_relaxed(pipe->base + reg);
-}
-
static int mdss_mdp_image_setup(struct mdss_mdp_pipe *pipe)
{
u32 img_size, src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 911e29f..b54e0ec 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>
@@ -36,6 +35,10 @@
MDP_INTR_VSYNC_INTF_1,
MDP_INTR_VSYNC_INTF_2,
MDP_INTR_VSYNC_INTF_3,
+ MDP_INTR_UNDERRUN_INTF_0,
+ MDP_INTR_UNDERRUN_INTF_1,
+ MDP_INTR_UNDERRUN_INTF_2,
+ MDP_INTR_UNDERRUN_INTF_3,
MDP_INTR_PING_PONG_0,
MDP_INTR_PING_PONG_1,
MDP_INTR_PING_PONG_2,
@@ -57,6 +60,9 @@
{
int index = -1;
switch (intr_type) {
+ case MDSS_MDP_IRQ_INTF_UNDER_RUN:
+ index = MDP_INTR_UNDERRUN_INTF_0 + (intf_num - MDSS_MDP_INTF0);
+ break;
case MDSS_MDP_IRQ_INTF_VSYNC:
index = MDP_INTR_VSYNC_INTF_0 + (intf_num - MDSS_MDP_INTF0);
break;
@@ -129,6 +135,18 @@
if (isr == 0)
goto mdp_isr_done;
+ if (isr & MDSS_MDP_INTR_INTF_0_UNDERRUN)
+ mdss_mdp_intr_done(MDP_INTR_UNDERRUN_INTF_0);
+
+ if (isr & MDSS_MDP_INTR_INTF_1_UNDERRUN)
+ mdss_mdp_intr_done(MDP_INTR_UNDERRUN_INTF_1);
+
+ if (isr & MDSS_MDP_INTR_INTF_2_UNDERRUN)
+ mdss_mdp_intr_done(MDP_INTR_UNDERRUN_INTF_2);
+
+ if (isr & MDSS_MDP_INTR_INTF_3_UNDERRUN)
+ mdss_mdp_intr_done(MDP_INTR_UNDERRUN_INTF_3);
+
if (isr & MDSS_MDP_INTR_PING_PONG_0_DONE)
mdss_mdp_intr_done(MDP_INTR_PING_PONG_0);
@@ -310,7 +328,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);
@@ -388,8 +405,7 @@
if (data->flags & MDP_SECURE_OVERLAY_SESSION) {
domain = MDSS_IOMMU_DOMAIN_SECURE;
ret = msm_ion_secure_buffer(iclient,
- data->srcp_ihdl, 0x2,
- ION_UNSECURE_DELAYED);
+ data->srcp_ihdl, 0x2, 0);
if (IS_ERR_VALUE(ret)) {
ion_free(iclient, data->srcp_ihdl);
pr_err("failed to secure handle (%d)\n",
@@ -402,8 +418,7 @@
ret = ion_map_iommu(iclient, data->srcp_ihdl,
mdss_get_iommu_domain(domain),
- 0, SZ_4K, 0, start, len, 0,
- ION_IOMMU_UNMAP_DELAYED);
+ 0, SZ_4K, 0, start, len, 0, 0);
} else {
ret = ion_phys(iclient, data->srcp_ihdl, start,
(size_t *) len);
@@ -414,10 +429,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/mdss/mhl_msc.c b/drivers/video/msm/mdss/mhl_msc.c
index add65ac..96e8b67 100644
--- a/drivers/video/msm/mdss/mhl_msc.c
+++ b/drivers/video/msm/mdss/mhl_msc.c
@@ -103,8 +103,6 @@
return postpone_send;
}
-
-
void mhl_msc_send_work(struct work_struct *work)
{
struct mhl_tx_ctrl *mhl_ctrl =
@@ -202,7 +200,6 @@
return 0;
}
-
int mhl_msc_command_done(struct mhl_tx_ctrl *mhl_ctrl,
struct msc_command_struct *req)
{
@@ -286,8 +283,6 @@
return 0;
}
-
-
int mhl_msc_send_msc_msg(struct mhl_tx_ctrl *mhl_ctrl,
u8 sub_cmd, u8 cmd_data)
{
@@ -315,7 +310,6 @@
return mhl_queue_msc_command(mhl_ctrl, &req, MSC_PRIORITY_SEND);
}
-
int mhl_msc_read_devcap(struct mhl_tx_ctrl *mhl_ctrl, u8 offset)
{
struct msc_command_struct req;
@@ -340,20 +334,17 @@
return ret;
}
-
static void mhl_handle_input(struct mhl_tx_ctrl *mhl_ctrl,
u8 key_code, u16 input_key_code)
{
int key_press = (key_code & 0x80) == 0;
- pr_debug("%s: send key events[%x][%d]\n",
- __func__, key_code, key_press);
+ pr_debug("%s: send key events[%x][%x][%d]\n",
+ __func__, key_code, input_key_code, key_press);
input_report_key(mhl_ctrl->input, input_key_code, key_press);
input_sync(mhl_ctrl->input);
}
-
-
int mhl_rcp_recv(struct mhl_tx_ctrl *mhl_ctrl, u8 key_code)
{
u8 index = key_code & 0x7f;
@@ -392,7 +383,6 @@
return 0;
}
-
static int mhl_rap_action(struct mhl_tx_ctrl *mhl_ctrl, u8 action_code)
{
switch (action_code) {
@@ -400,7 +390,14 @@
mhl_tmds_ctrl(mhl_ctrl, TMDS_ENABLE);
break;
case MHL_RAP_CONTENT_OFF:
- mhl_tmds_ctrl(mhl_ctrl, TMDS_DISABLE);
+ /*
+ * instead of only disabling tmds
+ * send power button press - CONTENT_OFF
+ */
+ input_report_key(mhl_ctrl->input, KEY_VENDOR, 1);
+ input_sync(mhl_ctrl->input);
+ input_report_key(mhl_ctrl->input, KEY_VENDOR, 0);
+ input_sync(mhl_ctrl->input);
break;
default:
break;
@@ -413,9 +410,9 @@
u8 error_code;
bool tmds_en;
+ tmds_en = mhl_check_tmds_enabled(mhl_ctrl);
switch (action_code) {
case MHL_RAP_POLL:
- tmds_en = mhl_check_tmds_enabled(mhl_ctrl);
if (tmds_en)
error_code = MHL_RAPK_NO_ERROR;
else
@@ -423,8 +420,12 @@
break;
case MHL_RAP_CONTENT_ON:
case MHL_RAP_CONTENT_OFF:
- mhl_rap_action(mhl_ctrl, action_code);
- error_code = MHL_RAPK_NO_ERROR;
+ if (tmds_en) {
+ mhl_rap_action(mhl_ctrl, action_code);
+ error_code = MHL_RAPK_NO_ERROR;
+ } else {
+ error_code = MHL_RAPK_UNSUPPORTED_ACTION_CODE;
+ }
break;
default:
error_code = MHL_RAPK_UNRECOGNIZED_ACTION_CODE;
@@ -437,7 +438,6 @@
error_code);
}
-
int mhl_msc_recv_msc_msg(struct mhl_tx_ctrl *mhl_ctrl,
u8 sub_cmd, u8 cmd_data)
{
@@ -504,6 +504,7 @@
/* SET_INT: GRT_WRT */
pr_debug("%s: recvd req to permit/grant write",
__func__);
+ complete_all(&mhl_ctrl->req_write_done);
mhl_msc_write_burst(
mhl_ctrl,
MHL_SCRATCHPAD_OFFSET,
@@ -599,31 +600,53 @@
u8 start_reg,
u8 length, u8 *data)
{
- int rc = 0;
+ int i, reg;
+ int timeout, retry = 20;
if (!(mhl_ctrl->devcap[DEVCAP_OFFSET_FEATURE_FLAG] &
MHL_FEATURE_SP_SUPPORT)) {
pr_debug("MHL: SCRATCHPAD_NOT_SUPPORTED\n");
- rc = -EFAULT;
- } else {
- if (mhl_ctrl->scrpd_busy) {
- pr_debug("MHL: scratchpad_busy\n");
- rc = -EBUSY;
- } else {
- int i, reg;
- for (i = 0, reg = start_reg; (i < length) &&
- (reg < MHL_SCRATCHPAD_SIZE); i++, reg++)
- mhl_ctrl->scrpd.data[reg] = data[i];
- mhl_ctrl->scrpd.length = length;
- mhl_ctrl->scrpd.offset = start_reg;
- mhl_msc_send_set_int(
- mhl_ctrl,
- MHL_RCHANGE_INT,
- MHL_INT_REQ_WRT,
- MSC_PRIORITY_SEND);
- }
+ return -EFAULT;
}
- return rc;
+
+ /*
+ * scratchpad remains busy as long as a peer's permission or
+ * write bursts are pending; experimentally it was found that
+ * 50ms is optimal
+ */
+ while (mhl_ctrl->scrpd_busy && retry--)
+ msleep(50);
+ if (!retry) {
+ pr_debug("MHL: scratchpad_busy\n");
+ return -EBUSY;
+ }
+
+ for (i = 0, reg = start_reg; (i < length) &&
+ (reg < MHL_SCRATCHPAD_SIZE); i++, reg++)
+ mhl_ctrl->scrpd.data[reg] = data[i];
+ mhl_ctrl->scrpd.length = length;
+ mhl_ctrl->scrpd.offset = start_reg;
+
+ retry = 5;
+ do {
+ init_completion(&mhl_ctrl->req_write_done);
+ mhl_msc_send_set_int(
+ mhl_ctrl,
+ MHL_RCHANGE_INT,
+ MHL_INT_REQ_WRT,
+ MSC_PRIORITY_SEND);
+ timeout = wait_for_completion_interruptible_timeout(
+ &mhl_ctrl->req_write_done,
+ msecs_to_jiffies(MHL_BURST_WAIT));
+ if (!timeout)
+ mhl_ctrl->scrpd_busy = false;
+ } while (retry-- && timeout == 0);
+ if (!timeout) {
+ pr_err("%s: timed out!\n", __func__);
+ return -EAGAIN;
+ }
+
+ return 0;
}
/* write scratchpad entry */
diff --git a/drivers/video/msm/mdss/mhl_sii8334.c b/drivers/video/msm/mdss/mhl_sii8334.c
index ccddf44..a3a1a4e 100644
--- a/drivers/video/msm/mdss/mhl_sii8334.c
+++ b/drivers/video/msm/mdss/mhl_sii8334.c
@@ -36,7 +36,7 @@
#define COMPATIBLE_NAME "qcom,mhl-sii8334"
#define MAX_CURRENT 700000
-#define pr_debug_intr(...) pr_debug("\n")
+#define pr_debug_intr(...)
#define MSC_START_BIT_MSC_CMD (0x01 << 0)
#define MSC_START_BIT_VS_CMD (0x01 << 1)
@@ -475,9 +475,10 @@
POWER_SUPPLY_PROP_CURRENT_MAX,
};
-static void cbus_reset(struct i2c_client *client)
+static void cbus_reset(struct mhl_tx_ctrl *mhl_ctrl)
{
uint8_t i;
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
/*
* REG_SRST
@@ -492,7 +493,10 @@
MHL_SII_REG_NAME_WR(REG_INTR4_MASK,
BIT0 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6);
- MHL_SII_REG_NAME_WR(REG_INTR5_MASK, 0x00);
+ if (mhl_ctrl->chip_rev_id < 1)
+ MHL_SII_REG_NAME_WR(REG_INTR5_MASK, BIT3 | BIT4);
+ else
+ MHL_SII_REG_NAME_WR(REG_INTR5_MASK, 0x00);
/* Unmask CBUS1 Intrs */
MHL_SII_REG_NAME_WR(REG_CBUS_INTR_ENABLE,
@@ -523,7 +527,7 @@
/* Increase DDC translation layer timer*/
MHL_SII_CBUS_WR(0x0007, 0xF2);
/* Drive High Time */
- MHL_SII_CBUS_WR(0x0036, 0x03);
+ MHL_SII_CBUS_WR(0x0036, 0x0B);
/* Use programmed timing */
MHL_SII_CBUS_WR(0x0039, 0x30);
/* CBUS Drive Strength */
@@ -590,6 +594,8 @@
static void mhl_init_reg_settings(struct mhl_tx_ctrl *mhl_ctrl,
bool mhl_disc_en)
{
+ uint8_t regval;
+
/*
* ============================================
* POWER UP
@@ -599,11 +605,6 @@
/* Power up 1.2V core */
MHL_SII_PAGE1_WR(0x003D, 0x3F);
- /*
- * Wait for the source power to be enabled
- * before enabling pll clocks.
- */
- msleep(50);
/* Enable Tx PLL Clock */
MHL_SII_PAGE2_WR(0x0011, 0x01);
/* Enable Tx Clock Path and Equalizer */
@@ -611,22 +612,26 @@
/* Tx Source Termination ON */
MHL_SII_REG_NAME_WR(REG_MHLTX_CTL1, 0x10);
/* Enable 1X MHL Clock output */
- MHL_SII_REG_NAME_WR(REG_MHLTX_CTL6, 0xAC);
+ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL6, 0xBC);
/* Tx Differential Driver Config */
MHL_SII_REG_NAME_WR(REG_MHLTX_CTL2, 0x3C);
- MHL_SII_REG_NAME_WR(REG_MHLTX_CTL4, 0xD9);
+ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL4, 0xC8);
/* PLL Bandwidth Control */
- MHL_SII_REG_NAME_WR(REG_MHLTX_CTL8, 0x02);
+ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL7, 0x03);
+ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL8, 0x0A);
/*
* ============================================
* Analog PLL Control
* ============================================
*/
/* Enable Rx PLL clock */
- MHL_SII_REG_NAME_WR(REG_TMDS_CCTRL, 0x00);
- MHL_SII_PAGE0_WR(0x00F8, 0x0C);
+ MHL_SII_REG_NAME_WR(REG_TMDS_CCTRL, 0x08);
+ MHL_SII_PAGE0_WR(0x00F8, 0x8C);
MHL_SII_PAGE0_WR(0x0085, 0x02);
MHL_SII_PAGE2_WR(0x0000, 0x00);
+ regval = MHL_SII_PAGE2_RD(0x0005);
+ regval &= ~BIT5;
+ MHL_SII_PAGE2_WR(0x0005, regval);
MHL_SII_PAGE2_WR(0x0013, 0x60);
/* PLL Cal ref sel */
MHL_SII_PAGE2_WR(0x0017, 0x03);
@@ -646,6 +651,7 @@
/* Rx PLL Bandwidth value from I2C */
MHL_SII_PAGE2_WR(0x0045, 0x06);
MHL_SII_PAGE2_WR(0x004B, 0x06);
+ MHL_SII_PAGE2_WR(0x004C, 0x60);
/* Manual zone control */
MHL_SII_PAGE2_WR(0x004C, 0xE0);
/* PLL Mode value */
@@ -658,20 +664,21 @@
*/
MHL_SII_REG_NAME_WR(REG_DISC_CTRL2, 0xAD);
/* 1.8V CBUS VTH */
- MHL_SII_REG_NAME_WR(REG_DISC_CTRL5, 0x55);
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL5, 0x57);
/* RGND and single Discovery attempt */
MHL_SII_REG_NAME_WR(REG_DISC_CTRL6, 0x11);
/* Ignore VBUS */
MHL_SII_REG_NAME_WR(REG_DISC_CTRL8, 0x82);
- MHL_SII_REG_NAME_WR(REG_DISC_CTRL9, 0x24);
/* Enable CBUS Discovery */
if (mhl_disc_en) {
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL9, 0x24);
/* Enable MHL Discovery */
MHL_SII_REG_NAME_WR(REG_DISC_CTRL1, 0x27);
/* Pull-up resistance off for IDLE state */
MHL_SII_REG_NAME_WR(REG_DISC_CTRL4, 0x8C);
} else {
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL9, 0x26);
/* Disable MHL Discovery */
MHL_SII_REG_NAME_WR(REG_DISC_CTRL1, 0x26);
MHL_SII_REG_NAME_WR(REG_DISC_CTRL4, 0x8C);
@@ -684,14 +691,14 @@
MHL_SII_PAGE3_WR(0x3C, 0x80);
if (mhl_ctrl->cur_state != POWER_STATE_D3)
- MHL_SII_REG_NAME_MOD(REG_INT_CTRL, BIT5 | BIT4, BIT4);
+ MHL_SII_REG_NAME_MOD(REG_INT_CTRL, BIT6 | BIT5 | BIT4, BIT4);
/* Enable Auto Soft RESET */
MHL_SII_REG_NAME_WR(REG_SRST, 0x084);
/* HDMI Transcode mode enable */
MHL_SII_PAGE0_WR(0x000D, 0x1C);
- cbus_reset(client);
+ cbus_reset(mhl_ctrl);
init_cbus_regs(client);
}
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 7d0d862..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>
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/drm/kgsl_drm.h b/include/drm/kgsl_drm.h
index 41f7c29..2ad1ab2 100644
--- a/include/drm/kgsl_drm.h
+++ b/include/drm/kgsl_drm.h
@@ -86,7 +86,7 @@
struct drm_kgsl_gem_create_from_ion)
/* Maximum number of sub buffers per GEM object */
-#define DRM_KGSL_GEM_MAX_BUFFERS 2
+#define DRM_KGSL_GEM_MAX_BUFFERS 3
/* Memory types - these define the source and caching policies
of the GEM memory chunk */
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/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 0806d31..9461c76 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -44,6 +44,8 @@
* @disable_flat_portion_ocv: feature to disable ocv updates while in sleep
* @ocv_dis_high_soc: the high soc percent when ocv should be disabled
* @ocv_dis_low_soc: the low soc percent when ocv should be enabled
+ * @low_voltage_detect: feature to enable 0 SOC reporting on low volatge
+ * @vbatt_cutoff_retries: number of tries before we report a 0 SOC
*/
struct pm8921_bms_platform_data {
struct pm8xxx_bms_core_data bms_cdata;
@@ -65,6 +67,8 @@
int disable_flat_portion_ocv;
int ocv_dis_high_soc;
int ocv_dis_low_soc;
+ int low_voltage_detect;
+ int vbatt_cutoff_retries;
};
#if defined(CONFIG_PM8921_BMS) || defined(CONFIG_PM8921_BMS_MODULE)
diff --git a/include/linux/mhl_8334.h b/include/linux/mhl_8334.h
index d6f8356..d8eb494 100644
--- a/include/linux/mhl_8334.h
+++ b/include/linux/mhl_8334.h
@@ -157,6 +157,7 @@
struct scrpd_struct scrpd;
int scrpd_busy;
int wr_burst_pending;
+ struct completion req_write_done;
};
int mhl_i2c_reg_read(struct i2c_client *client,
diff --git a/include/linux/mhl_defs.h b/include/linux/mhl_defs.h
index aa63e03..f5dacfd 100644
--- a/include/linux/mhl_defs.h
+++ b/include/linux/mhl_defs.h
@@ -135,7 +135,7 @@
/* manually define highest number */
#define MHL_MAX_BUFFER_SIZE MHL_SCRATCHPAD_SIZE
-
+#define MHL_BURST_WAIT (1000)
enum {
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index f26b903..a5f36b5 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -110,7 +110,12 @@
#define SDHCI_QUIRK2_SLOW_INT_CLR (1<<2)
/* Ignore CMD CRC errors for tuning commands */
#define SDHCI_QUIRK2_IGNORE_CMDCRC_FOR_TUNING (1<<3)
-
+/*
+ * If the base clock can be scalable, then there should be no further
+ * clock dividing as the input clock itself will be scaled down to
+ * required frequency.
+ */
+#define SDHCI_QUIRK2_ALWAYS_USE_BASE_CLOCK (1<<4)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
diff --git a/include/linux/msm_ion.h b/include/linux/msm_ion.h
index a683ed4..95c4e6a 100644
--- a/include/linux/msm_ion.h
+++ b/include/linux/msm_ion.h
@@ -40,6 +40,7 @@
ION_CP_MFC_HEAP_ID = 12,
ION_CP_WB_HEAP_ID = 16, /* 8660 only */
ION_CAMERA_HEAP_ID = 20, /* 8660 only */
+ ION_SYSTEM_CONTIG_HEAP_ID = 21,
ION_ADSP_HEAP_ID = 22,
ION_PIL1_HEAP_ID = 23, /* Currently used for other PIL images */
ION_SF_HEAP_ID = 24,
@@ -90,6 +91,7 @@
#define ION_ADSP_HEAP_NAME "adsp"
#define ION_VMALLOC_HEAP_NAME "vmalloc"
+#define ION_KMALLOC_HEAP_NAME "kmalloc"
#define ION_AUDIO_HEAP_NAME "audio"
#define ION_SF_HEAP_NAME "sf"
#define ION_MM_HEAP_NAME "mm"
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/msm_mdp.h b/include/linux/msm_mdp.h
index 6a2c95d..5deff7a 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -95,6 +95,7 @@
MDP_RGB_888, /* RGB 888 planer */
MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planer w/ Cr is in MSB */
MDP_YCRYCB_H2V1, /* YCrYCb interleave */
+ MDP_CBYCRY_H2V1, /* CbYCrY interleave */
MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */
MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */
MDP_Y_CRCB_H1V2,
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index ce5ddf3..0ab5143 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1221,6 +1221,60 @@
* @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds
* or 0 to disable background scan.
*
+ * @NL80211_ATTR_USER_REG_HINT_TYPE: type of regulatory hint passed from
+ * userspace. If unset it is assumed the hint comes directly from
+ * a user. If set code could specify exactly what type of source
+ * was used to provide the hint. For the different types of
+ * allowed user regulatory hints see nl80211_user_reg_hint_type.
+ *
+ * @NL80211_ATTR_CONN_FAILED_REASON: The reason for which AP has rejected
+ * the connection request from a station. nl80211_connect_failed_reason
+ * enum has different reasons of connection failure.
+ *
+ * @NL80211_ATTR_SAE_DATA: SAE elements in Authentication frames. This starts
+ * with the Authentication transaction sequence number field.
+ *
+ * @NL80211_ATTR_VHT_CAPABILITY: VHT Capability information element (from
+ * association request when used with NL80211_CMD_NEW_STATION)
+ *
+ * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32)
+ *
+ * @NL80211_ATTR_P2P_CTWINDOW: P2P GO Client Traffic Window (u8), used with
+ * the START_AP and SET_BSS commands
+ * @NL80211_ATTR_P2P_OPPPS: P2P GO opportunistic PS (u8), used with the
+ * START_AP and SET_BSS commands. This can have the values 0 or 1;
+ * if not given in START_AP 0 is assumed, if not given in SET_BSS
+ * no change is made.
+ *
+ * @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode
+ * defined in &enum nl80211_mesh_power_mode.
+ *
+ * @NL80211_ATTR_ACL_POLICY: ACL policy, see &enum nl80211_acl_policy,
+ * carried in a u32 attribute
+ *
+ * @NL80211_ATTR_MAC_ADDRS: Array of nested MAC addresses, used for
+ * MAC ACL.
+ *
+ * @NL80211_ATTR_MAC_ACL_MAX: u32 attribute to advertise the maximum
+ * number of MAC addresses that a device can support for MAC
+ * ACL.
+ *
+ * @NL80211_ATTR_RADAR_EVENT: Type of radar event for notification to userspace,
+ * contains a value of enum nl80211_radar_event (u32).
+ *
+ * @NL80211_ATTR_EXT_CAPA: 802.11 extended capabilities that the kernel driver
+ * has and handles. The format is the same as the IE contents. See
+ * 802.11-2012 8.4.2.29 for more information.
+ * @NL80211_ATTR_EXT_CAPA_MASK: Extended capabilities that the kernel driver
+ * has set in the %NL80211_ATTR_EXT_CAPA value, for multibit fields.
+ *
+ * @NL80211_ATTR_STA_CAPABILITY: Station capabilities (u16) are advertised to
+ * the driver, e.g., to enable TDLS power save (PU-APSD).
+ *
+ * @NL80211_ATTR_STA_EXT_CAPABILITY: Station extended capabilities are
+ * advertised to the driver, e.g., to enable TDLS off channel operations
+ * and PU-APSD.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1472,6 +1526,41 @@
NL80211_ATTR_BG_SCAN_PERIOD,
+ NL80211_ATTR_WDEV,
+
+ NL80211_ATTR_USER_REG_HINT_TYPE,
+
+ NL80211_ATTR_CONN_FAILED_REASON,
+
+ NL80211_ATTR_SAE_DATA,
+
+ NL80211_ATTR_VHT_CAPABILITY,
+
+ NL80211_ATTR_SCAN_FLAGS,
+
+ NL80211_ATTR_CHANNEL_WIDTH,
+ NL80211_ATTR_CENTER_FREQ1,
+ NL80211_ATTR_CENTER_FREQ2,
+
+ NL80211_ATTR_P2P_CTWINDOW,
+ NL80211_ATTR_P2P_OPPPS,
+
+ NL80211_ATTR_LOCAL_MESH_POWER_MODE,
+
+ NL80211_ATTR_ACL_POLICY,
+
+ NL80211_ATTR_MAC_ADDRS,
+
+ NL80211_ATTR_MAC_ACL_MAX,
+
+ NL80211_ATTR_RADAR_EVENT,
+
+ NL80211_ATTR_EXT_CAPA,
+ NL80211_ATTR_EXT_CAPA_MASK,
+
+ NL80211_ATTR_STA_CAPABILITY,
+ NL80211_ATTR_STA_EXT_CAPABILITY,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -1515,6 +1604,7 @@
#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16
#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24
#define NL80211_HT_CAPABILITY_LEN 26
+#define NL80211_VHT_CAPABILITY_LEN 12
#define NL80211_MAX_NR_CIPHER_SUITES 5
#define NL80211_MAX_NR_AKM_SUITES 2
@@ -1783,6 +1873,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 +1889,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/qpnp-misc.h b/include/linux/qpnp-misc.h
new file mode 100644
index 0000000..b241e5d
--- /dev/null
+++ b/include/linux/qpnp-misc.h
@@ -0,0 +1,38 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __QPNP_MISC_H
+#define __QPNP_MISC_H
+
+#include <linux/errno.h>
+
+#ifdef CONFIG_QPNP_MISC
+/**
+ * qpnp_misc_irqs_available - check if IRQs are available
+ *
+ * @consumer_dev: device struct
+ *
+ * This function returns true if the MISC interrupts are available
+ * based on a check in the MISC peripheral revision registers.
+ *
+ * Any consumer of this function needs to reference a MISC device phandle
+ * using the qcom,misc-ref in their device tree node.
+ */
+
+int qpnp_misc_irqs_available(struct device *consumer_dev);
+#else
+static int qpnp_misc_irq_available(struct device *consumer_dev)
+{
+ return 0;
+}
+#endif
+#endif
diff --git a/include/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index 05d75ce..fc6ab91 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -195,7 +195,7 @@
};
/**
- * enum qpnp_adc_scale_fn_type - Scaling function for pm8921 pre calibrated
+ * enum qpnp_adc_scale_fn_type - Scaling function for pm8941 pre calibrated
* digital data relative to ADC reference.
* %ADC_SCALE_DEFAULT: Default scaling to convert raw adc code to voltage.
* %ADC_SCALE_BATT_THERM: Conversion to temperature based on btm parameters.
@@ -217,6 +217,26 @@
SCALE_NONE,
};
+
+/**
+ * enum qpnp_adc_tm_rscale_fn_type - Scaling function used to convert the
+ * channels input voltage/temperature to corresponding ADC code that is
+ * applied for thresholds. Check the corresponding channels scaling to
+ * determine the appropriate temperature/voltage units that are passed
+ * to the scaling function. Example battery follows the power supply
+ * framework that needs its units to be in decidegreesC so it passes
+ * deci-degreesC. PA_THERM clients pass the temperature in degrees.
+ * The order below should match the one in the driver for
+ * adc_tm_rscale_fn[].
+ */
+enum qpnp_adc_tm_rscale_fn_type {
+ SCALE_R_VBATT = 0,
+ SCALE_RBATT_THERM,
+ SCALE_R_USB_ID,
+ SCALE_RPMIC_THERM,
+ SCALE_RSCALE_NONE,
+};
+
/**
* enum qpnp_adc_fast_avg_ctl - Provides ability to obtain single result
* from the ADC that is an average of multiple measurement
@@ -560,16 +580,11 @@
};
/**
- * Channel selection registers for each of the 5 configurable measurements
- * Channels allotment is fixed for the given channels below.
- * The USB_ID and BATT_THERM channels are used only by the kernel space
- * USB and Battery drivers.
+ * Channel selection registers for each of the configurable measurements
+ * Channels allotment is set at device config for a channel.
+ * The USB_ID, BATT_THERM, PMIC_THERM and VBAT channels are used by the
+ * kernel space USB, Battery and IADC drivers.
* The other 3 channels are configurable for use by userspace clients.
- * USB_ID uses QPNP_ADC_TM_M0_ADC_CH_SEL_CTL
- * BATT_TEMP uses QPNP_ADC_TM_M1_ADC_CH_SEL_CTL
- * PA_THERM1 uses QPNP_ADC_TM_M2_ADC_CH_SEL_CTL
- * PA_THERM2 uses QPNP_ADC_TM_M3_ADC_CH_SEL_CTL
- * EMMC_THERM uses QPNP_ADC_TM_M4_ADC_CH_SEL_CTL
*/
enum qpnp_adc_tm_channel_select {
QPNP_ADC_TM_M0_ADC_CH_SEL_CTL = 0x48,
@@ -577,6 +592,9 @@
QPNP_ADC_TM_M2_ADC_CH_SEL_CTL = 0x70,
QPNP_ADC_TM_M3_ADC_CH_SEL_CTL = 0x78,
QPNP_ADC_TM_M4_ADC_CH_SEL_CTL = 0x80,
+ QPNP_ADC_TM_M5_ADC_CH_SEL_CTL = 0x88,
+ QPNP_ADC_TM_M6_ADC_CH_SEL_CTL = 0x90,
+ QPNP_ADC_TM_M7_ADC_CH_SEL_CTL = 0x98,
QPNP_ADC_TM_CH_SELECT_NONE
};
@@ -619,75 +637,84 @@
* enum qpnp_tm_state - This lets the client know whether the threshold
* that was crossed was high/low.
* %ADC_TM_HIGH_STATE: Client is notified of crossing the requested high
- * threshold.
+ * voltage threshold.
+ * %ADC_TM_COOL_STATE: Client is notified of crossing the requested cool
+ * temperature threshold.
* %ADC_TM_LOW_STATE: Client is notified of crossing the requested low
- * threshold.
+ * voltage threshold.
+ * %ADC_TM_WARM_STATE: Client is notified of crossing the requested high
+ * temperature threshold.
*/
enum qpnp_tm_state {
ADC_TM_HIGH_STATE = 0,
+ ADC_TM_COOL_STATE = ADC_TM_HIGH_STATE,
ADC_TM_LOW_STATE,
+ ADC_TM_WARM_STATE = ADC_TM_LOW_STATE,
ADC_TM_STATE_NUM,
};
/**
* enum qpnp_state_request - Request to enable/disable the corresponding
* high/low voltage/temperature thresholds.
- * %ADC_TM_HIGH_THR_ENABLE: Enable high voltage/temperature threshold.
+ * %ADC_TM_HIGH_THR_ENABLE: Enable high voltage threshold.
+ * %ADC_TM_COOL_THR_ENABLE = Enables cool temperature threshold.
* %ADC_TM_LOW_THR_ENABLE: Enable low voltage/temperature threshold.
+ * %ADC_TM_WARM_THR_ENABLE = Enables warm temperature threshold.
* %ADC_TM_HIGH_LOW_THR_ENABLE: Enable high and low voltage/temperature
* threshold.
* %ADC_TM_HIGH_THR_DISABLE: Disable high voltage/temperature threshold.
+ * %ADC_TM_COOL_THR_ENABLE = Disables cool temperature threshold.
* %ADC_TM_LOW_THR_DISABLE: Disable low voltage/temperature threshold.
+ * %ADC_TM_WARM_THR_ENABLE = Disables warm temperature threshold.
* %ADC_TM_HIGH_THR_DISABLE: Disable high and low voltage/temperature
* threshold.
*/
enum qpnp_state_request {
ADC_TM_HIGH_THR_ENABLE = 0,
+ ADC_TM_COOL_THR_ENABLE = ADC_TM_HIGH_THR_ENABLE,
ADC_TM_LOW_THR_ENABLE,
+ ADC_TM_WARM_THR_ENABLE = ADC_TM_LOW_THR_ENABLE,
ADC_TM_HIGH_LOW_THR_ENABLE,
ADC_TM_HIGH_THR_DISABLE,
+ ADC_TM_COOL_THR_DISABLE = ADC_TM_HIGH_THR_DISABLE,
ADC_TM_LOW_THR_DISABLE,
+ ADC_TM_WARM_THR_DISABLE = ADC_TM_LOW_THR_DISABLE,
ADC_TM_HIGH_LOW_THR_DISABLE,
ADC_TM_THR_NUM,
};
/**
- * struct qpnp_adc_tm_usbid_param - Represent USB_ID threshold
- * monitoring configuration.
- * @high_thr: High voltage threshold for which notification is requested.
- * @low_thr: Low voltage threshold for which notification is requested.
- * @state_request: Enable/disable the corresponding high and low voltage
- * thresholds.
- * @timer_interval: Select polling rate from qpnp_adc_meas_timer_1 type.
- * @threshold_notification: Notification callback once threshold are crossed.
- * @usbid_ctx: A context of void type.
- */
-struct qpnp_adc_tm_usbid_param {
- int32_t high_thr;
- int32_t low_thr;
- enum qpnp_state_request state_request;
- enum qpnp_adc_meas_timer_1 timer_interval;
- void *usbid_ctx;
- void (*threshold_notification) (enum qpnp_tm_state state,
- void *ctx);
-};
-
-/**
* struct qpnp_adc_tm_btm_param - Represent Battery temperature threshold
* monitoring configuration.
* @high_temp: High temperature threshold for which notification is requested.
* @low_temp: Low temperature threshold for which notification is requested.
+ * @high_thr_voltage: High voltage for which notification is requested.
+ * @low_thr_voltage: Low voltage for which notification is requested.
* @state_request: Enable/disable the corresponding high and low temperature
* thresholds.
- * @timer_interval: Select polling rate from qpnp_adc_meas_timer_2 type.
+ * @timer_interval1: Select polling rate from qpnp_adc_meas_timer_1 type.
+ * @timer_interval2: Select polling rate from qpnp_adc_meas_timer_2 type.
+ * @timer_interval3: Select polling rate from qpnp_adc_meas_timer_3 type.
* @btmid_ctx: A context of void type.
* @threshold_notification: Notification callback once threshold are crossed.
+ * units to be used for High/Low temperature and voltage notification -
+ * This depends on the clients usage. Check the rscaling function
+ * for the appropriate channel nodes.
+ * @Batt therm clients temperature units is decidegreesCentigrate.
+ * @USB_ID inputs the voltage units in milli-volts.
+ * @PA_THERM inputs the units in degC.
+ * @PMIC_THERM inputs the units in millidegC.
*/
struct qpnp_adc_tm_btm_param {
int32_t high_temp;
int32_t low_temp;
+ int32_t high_thr;
+ int32_t low_thr;
+ enum qpnp_vadc_channels channel;
enum qpnp_state_request state_request;
- enum qpnp_adc_meas_timer_2 timer_interval;
+ enum qpnp_adc_meas_timer_1 timer_interval;
+ enum qpnp_adc_meas_timer_2 timer_interval2;
+ enum qpnp_adc_meas_timer_3 timer_interval3;
void *btm_ctx;
void (*threshold_notification) (enum qpnp_tm_state state,
void *ctx);
@@ -841,6 +868,17 @@
};
/**
+ * struct qpnp_adc_tm_reverse_scale_fn - Reverse scaling prototype
+ * @chan: Function pointer to one of the scaling functions
+ * which takes the adc properties, channel properties,
+ * and returns the physical result
+ */
+struct qpnp_adc_tm_reverse_scale_fn {
+ int32_t (*chan) (struct qpnp_adc_tm_btm_param *,
+ uint32_t *, uint32_t *);
+};
+
+/**
* struct qpnp_iadc_calib - IADC channel calibration structure.
* @channel - Channel for which the historical offset and gain is
* calculated. Available channels are internal rsense,
@@ -1107,6 +1145,21 @@
int32_t qpnp_get_vadc_gain_and_offset(struct qpnp_vadc_linear_graph *param,
enum qpnp_adc_calib_type calib_type);
/**
+ * qpnp_adc_scale_millidegc_pmic_voltage_thr() - Performs reverse calibration
+ * on the low/high temperature threshold values passed by the
+ * client. The function coverts milldegC to voltage threshold
+ * and accounts for the corresponding channels scaling as (2mV/K).
+ * @param: The input parameters that contain the low/high temperature
+ * values.
+ * @low_threshold: The low threshold value that needs to be updated with
+ * the above calibrated voltage value.
+ * @high_threshold: The low threshold value that needs to be updated with
+ * the above calibrated voltage value.
+ */
+int32_t qpnp_adc_scale_millidegc_pmic_voltage_thr(
+ struct qpnp_adc_tm_btm_param *param,
+ uint32_t *low_threshold, uint32_t *high_threshold);
+/**
* qpnp_adc_btm_scaler() - Performs reverse calibration on the low/high
* temperature threshold values passed by the client.
* The function maps the temperature to voltage and applies
@@ -1147,7 +1200,21 @@
* @high_threshold: The low threshold value that needs to be updated with
* the above calibrated voltage value.
*/
-int32_t qpnp_adc_usb_scaler(struct qpnp_adc_tm_usbid_param *param,
+int32_t qpnp_adc_usb_scaler(struct qpnp_adc_tm_btm_param *param,
+ uint32_t *low_threshold, uint32_t *high_threshold);
+/**
+ * qpnp_adc_vbatt_rscaler() - Performs reverse calibration on the low/high
+ * voltage threshold values passed by the client.
+ * The function applies ratiometric calibration on the
+ * voltage values.
+ * @param: The input parameters that contain the low/high voltage
+ * threshold values.
+ * @low_threshold: The low threshold value that needs to be updated with
+ * the above calibrated voltage value.
+ * @high_threshold: The low threshold value that needs to be updated with
+ * the above calibrated voltage value.
+ */
+int32_t qpnp_adc_vbatt_rscaler(struct qpnp_adc_tm_btm_param *param,
uint32_t *low_threshold, uint32_t *high_threshold);
/**
* qpnp_vadc_iadc_sync_request() - Performs Voltage ADC read and
@@ -1217,13 +1284,21 @@
enum qpnp_adc_calib_type calib_type)
{ return -ENXIO; }
static inline int32_t qpnp_adc_usb_scaler(
- struct qpnp_adc_tm_usbid_param *param,
+ struct qpnp_adc_tm_btm_param *param,
+ uint32_t *low_threshold, uint32_t *high_threshold)
+{ return -ENXIO; }
+static inline int32_t qpnp_adc_vbatt_rscaler(
+ struct qpnp_adc_tm_btm_param *param,
uint32_t *low_threshold, uint32_t *high_threshold)
{ return -ENXIO; }
static inline int32_t qpnp_adc_btm_scaler(
struct qpnp_adc_tm_btm_param *param,
uint32_t *low_threshold, uint32_t *high_threshold)
{ return -ENXIO; }
+static inline int32_t qpnp_adc_scale_millidegc_pmic_voltage_thr(
+ struct qpnp_adc_tm_btm_param *param,
+ uint32_t *low_threshold, uint32_t *high_threshold)
+{ return -ENXIO; }
static inline int32_t qpnp_adc_tm_scale_therm_voltage_pu2(
struct qpnp_adc_tm_config *param)
{ return -ENXIO; }
@@ -1314,7 +1389,7 @@
* Clients pass the low/high voltage along with the threshold
* notification callback.
*/
-int32_t qpnp_adc_tm_usbid_configure(struct qpnp_adc_tm_usbid_param *param);
+int32_t qpnp_adc_tm_usbid_configure(struct qpnp_adc_tm_btm_param *param);
/**
* qpnp_adc_tm_usbid_end() - Disables the monitoring of channel 0 thats
* assigned for monitoring USB_ID. Disables the low/high
@@ -1323,23 +1398,25 @@
*/
int32_t qpnp_adc_tm_usbid_end(void);
/**
- * qpnp_adc_tm_usbid_configure() - Configures Channel 1 of VADC_BTM to
- * monitor batt_therm channel using 100k internal pull-up.
- * Battery driver passes the high/low voltage threshold along
+ * qpnp_adc_tm_channel_measure() - Configures kernel clients a channel to
+ * monitor the corresponding ADC channel for threshold detection.
+ * Driver passes the high/low voltage threshold along
* with the notification callback once the set thresholds
* are crossed.
* @param: Structure pointer of qpnp_adc_tm_btm_param type.
* Clients pass the low/high temperature along with the threshold
* notification callback.
*/
-int32_t qpnp_adc_tm_btm_configure(struct qpnp_adc_tm_btm_param *param);
+int32_t qpnp_adc_tm_channel_measure(struct qpnp_adc_tm_btm_param *param);
/**
- * qpnp_adc_tm_btm_end() - Disables the monitoring of channel 1 thats
- * assigned for monitoring batt_therm. Disables the low/high
- * threshold activation for channel 1 as well.
- * @param: none.
+ * qpnp_adc_tm_disable_chan_meas() - Disables the monitoring of channel thats
+ * assigned for monitoring kernel clients. Disables the low/high
+ * threshold activation for the corresponding channel.
+ * @param: Structure pointer of qpnp_adc_tm_btm_param type.
+ * This is used to identify the channel for which the corresponding
+ * channels high/low threshold notification will be disabled.
*/
-int32_t qpnp_adc_tm_btm_end(void);
+int32_t qpnp_adc_tm_disable_chan_meas(struct qpnp_adc_tm_btm_param *param);
/**
* qpnp_adc_tm_is_ready() - Clients can use this API to check if the
* device is ready to use.
@@ -1349,14 +1426,14 @@
int32_t qpnp_adc_tm_is_ready(void);
#else
static inline int32_t qpnp_adc_tm_usbid_configure(
- struct qpnp_adc_tm_usbid_param *param)
+ struct qpnp_adc_tm_btm_param *param)
{ return -ENXIO; }
static inline int32_t qpnp_adc_tm_usbid_end(void)
{ return -ENXIO; }
-static inline int32_t qpnp_adc_tm_btm_configure(
+static inline int32_t qpnp_adc_tm_channel_measure(
struct qpnp_adc_tm_btm_param *param)
{ return -ENXIO; }
-static inline int32_t qpnp_adc_tm_btm_end(void)
+static inline int32_t qpnp_adc_tm_disable_chan_meas(void)
{ return -ENXIO; }
static inline int32_t qpnp_adc_tm_is_ready(void)
{ return -ENXIO; }
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_camera.h b/include/media/msmb_camera.h
index 123c86c..21a1c44 100644
--- a/include/media/msmb_camera.h
+++ b/include/media/msmb_camera.h
@@ -102,9 +102,9 @@
/*word 6*/
unsigned int notify;
/*word 7*/
- unsigned int nop1;
+ unsigned int arg_value;
/*word 8*/
- unsigned int nop2;
+ unsigned int ret_value;
/*word 9*/
unsigned int nop3;
/*word 10*/
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..52811ae 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;
};
/*
@@ -445,12 +462,14 @@
/**
* enum station_parameters_apply_mask - station parameter values to apply
* @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp)
+ * @STATION_PARAM_APPLY_CAPABILITY: apply new capability
*
* Not all station parameters have in-band "no change" signalling,
* for those that don't these flags will are used.
*/
enum station_parameters_apply_mask {
STATION_PARAM_APPLY_UAPSD = BIT(0),
+ STATION_PARAM_APPLY_CAPABILITY = BIT(1),
};
/**
@@ -471,6 +490,7 @@
* @plink_action: plink action to take
* @plink_state: set the peer link state for a station
* @ht_capa: HT capabilities of station
+ * @vht_capa: VHT capabilities of station
* @uapsd_queues: bitmap of queues configured for uapsd. same format
* as the AC bitmap in the QoS info field
* @max_sp: max Service Period. same format as the MAX_SP in the
@@ -478,6 +498,9 @@
* @sta_modify_mask: bitmap indicating which parameters changed
* (for those that don't have a natural "no change" value),
* see &enum station_parameters_apply_mask
+ * @capability: station capability
+ * @ext_capab: extended capabilities of the station
+ * @ext_capab_len: number of extended capabilities
*/
struct station_parameters {
u8 *supported_rates;
@@ -490,8 +513,12 @@
u8 plink_action;
u8 plink_state;
struct ieee80211_ht_cap *ht_capa;
+ struct ieee80211_vht_cap *vht_capa;
u8 uapsd_queues;
u8 max_sp;
+ u16 capability;
+ u8 *ext_capab;
+ u8 ext_capab_len;
};
/**
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index f88c817..1484f16 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -2418,6 +2418,16 @@
u32 sample_rate;
} __packed;
+struct asm_amrwbplus_cfg {
+ u32 size_bytes;
+ u32 version;
+ u32 num_channels;
+ u32 amr_band_mode;
+ u32 amr_dtx_mode;
+ u32 amr_frame_fmt;
+ u32 amr_lsf_idx;
+} __packed;
+
struct asm_softpause_params {
u32 enable;
u32 period;
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 5744a43..f9d2a40 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -294,6 +294,8 @@
int q6asm_media_format_block_wmapro(struct audio_client *ac,
void *cfg);
+int q6asm_media_format_block_amrwbplus(struct audio_client *ac,
+ struct asm_amrwbplus_cfg *cfg);
/* PP specific */
int q6asm_equalizer(struct audio_client *ac, void *eq);
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 7aac5f6..fcde89a 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -511,7 +511,7 @@
int error;
if (state == PM_SUSPEND_ON
- && !(strncmp(buf, "off", 3) && strncmp(buf, "off\n", 4)))
+ && strcmp(buf, "off") && strcmp(buf, "off\n"))
return -EINVAL;
error = pm_autosleep_set_state(state);
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/cfg.c b/net/mac80211/cfg.c
index 677d659..685553b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -984,9 +984,11 @@
return -ENOENT;
}
- /* in station mode, supported rates are only valid with TDLS */
+ /* in station mode, some updates are only valid with TDLS */
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
- params->supported_rates &&
+ (params->supported_rates || params->ht_capa || params->vht_capa ||
+ params->sta_modify_mask ||
+ (params->sta_flags_mask & BIT(NL80211_STA_FLAG_WME))) &&
!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
mutex_unlock(&local->sta_mtx);
return -EINVAL;
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..69318b0 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -206,6 +206,12 @@
[NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
[NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
[NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
+ [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
+ [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
+ [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, },
+ [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
+ [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
+ [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
};
/* policy for the key attributes */
@@ -811,6 +817,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)
@@ -2622,6 +2637,54 @@
return ERR_PTR(ret);
}
+static struct nla_policy
+nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
+ [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
+ [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
+};
+
+static int nl80211_set_station_tdls(struct genl_info *info,
+ struct station_parameters *params)
+{
+ struct nlattr *tb[NL80211_STA_WME_MAX + 1];
+ struct nlattr *nla;
+ int err;
+
+ /* Dummy STA entry gets updated once the peer capabilities are known */
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
+ params->ht_capa =
+ nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
+ if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+ params->vht_capa =
+ nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
+
+ /* parse WME attributes if present */
+ if (!info->attrs[NL80211_ATTR_STA_WME])
+ return 0;
+
+ nla = info->attrs[NL80211_ATTR_STA_WME];
+ err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
+ nl80211_sta_wme_policy);
+ if (err)
+ return err;
+
+ if (tb[NL80211_STA_WME_UAPSD_QUEUES])
+ params->uapsd_queues = nla_get_u8(
+ tb[NL80211_STA_WME_UAPSD_QUEUES]);
+ if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
+ return -EINVAL;
+
+ if (tb[NL80211_STA_WME_MAX_SP])
+ params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
+
+ if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
+ return -EINVAL;
+
+ params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
+
+ return 0;
+}
+
static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2650,6 +2713,19 @@
nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
}
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
+ params.capability =
+ nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
+ params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
+ }
+
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
+ params.ext_capab =
+ nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+ params.ext_capab_len =
+ nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+ }
+
if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
params.listen_interval =
nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
@@ -2698,6 +2774,14 @@
BIT(NL80211_STA_FLAG_MFP)))
return -EINVAL;
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
+ return -EINVAL;
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
+ return -EINVAL;
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
+ info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+ return -EINVAL;
+
/* must be last in here for error handling */
params.vlan = get_vlan(info, rdev);
if (IS_ERR(params.vlan))
@@ -2712,7 +2796,17 @@
* to change the flag.
*/
params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
- /* fall through */
+ /* Include parameters for TDLS peer (driver will check) */
+ err = nl80211_set_station_tdls(info, ¶ms);
+ if (err)
+ return err;
+ /* disallow things sta doesn't support */
+ if (params.plink_action)
+ return -EINVAL;
+ if (params.sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
+ BIT(NL80211_STA_FLAG_WME)))
+ return -EINVAL;
+ break;
case NL80211_IFTYPE_ADHOC:
/* disallow things sta doesn't support */
if (params.plink_action)
@@ -2721,6 +2815,9 @@
return -EINVAL;
if (params.listen_interval >= 0)
return -EINVAL;
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
+ info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+ return -EINVAL;
/* reject any changes other than AUTHORIZED */
if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
return -EINVAL;
@@ -2733,6 +2830,13 @@
return -EINVAL;
if (params.listen_interval >= 0)
return -EINVAL;
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
+ return -EINVAL;
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
+ return -EINVAL;
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
+ info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+ return -EINVAL;
/*
* No special handling for TDLS here -- the userspace
* mesh code doesn't have this bug.
@@ -2757,12 +2861,6 @@
return err;
}
-static struct nla_policy
-nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
- [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
- [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
-};
-
static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2797,10 +2895,27 @@
if (!params.aid || params.aid > IEEE80211_MAX_AID)
return -EINVAL;
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
+ params.capability =
+ nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
+ params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
+ }
+
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
+ params.ext_capab =
+ nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+ params.ext_capab_len =
+ nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+ }
+
if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
params.ht_capa =
nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
+ if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+ params.vht_capa =
+ nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
+
if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
params.plink_action =
nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
@@ -2862,6 +2977,7 @@
return -EINVAL;
break;
case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
/* Only TDLS peers can be added */
if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
return -EINVAL;
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index 634493b..ca8cfaa 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -2135,12 +2135,12 @@
dev_dbg(codec->dev, "%s: %s event = %d\n", __func__, w->name, event);
if (w->shift == 5) {
- e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
- e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
- req_clsh_state = WCD9XXX_CLSH_STATE_HPHL;
- } else if (w->shift == 4) {
e_pre_on = WCD9XXX_EVENT_PRE_HPHL_PA_ON;
e_post_off = WCD9XXX_EVENT_POST_HPHL_PA_OFF;
+ req_clsh_state = WCD9XXX_CLSH_STATE_HPHL;
+ } else if (w->shift == 4) {
+ e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
+ e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
req_clsh_state = WCD9XXX_CLSH_STATE_HPHR;
} else {
pr_err("%s: Invalid w->shift %d\n", __func__, w->shift);
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 78d1749..f44487f 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -338,6 +338,7 @@
s32 dmic_5_6_clk_cnt;
u32 anc_slot;
+ bool anc_func;
/*track taiko interface type*/
u8 intf_type;
@@ -505,6 +506,56 @@
return 0;
}
+static int taiko_get_anc_func(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = (taiko->anc_func == true ? 1 : 0);
+ return 0;
+}
+
+static int taiko_put_anc_func(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ mutex_lock(&dapm->codec->mutex);
+ taiko->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
+
+ dev_dbg(codec->dev, "%s: anc_func %x", __func__, taiko->anc_func);
+
+ if (taiko->anc_func == true) {
+ snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
+ snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
+ snd_soc_dapm_enable_pin(dapm, "ANC HEADPHONE");
+ snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
+ snd_soc_dapm_enable_pin(dapm, "ANC EAR");
+ snd_soc_dapm_disable_pin(dapm, "HPHR");
+ snd_soc_dapm_disable_pin(dapm, "HPHL");
+ snd_soc_dapm_disable_pin(dapm, "HEADPHONE");
+ snd_soc_dapm_disable_pin(dapm, "EAR PA");
+ snd_soc_dapm_disable_pin(dapm, "EAR");
+ } else {
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
+ snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
+ snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC EAR");
+ snd_soc_dapm_enable_pin(dapm, "HPHR");
+ snd_soc_dapm_enable_pin(dapm, "HPHL");
+ snd_soc_dapm_enable_pin(dapm, "HEADPHONE");
+ snd_soc_dapm_enable_pin(dapm, "EAR PA");
+ snd_soc_dapm_enable_pin(dapm, "EAR");
+ }
+ snd_soc_dapm_sync(dapm);
+ mutex_unlock(&dapm->codec->mutex);
+ return 0;
+}
+
static int taiko_pa_gain_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -915,6 +966,15 @@
SOC_ENUM_SINGLE_EXT(2, taiko_ear_pa_gain_text),
};
+static const char *const taiko_anc_func_text[] = {"OFF", "ON"};
+static const struct soc_enum taiko_anc_func_enum =
+ SOC_ENUM_SINGLE_EXT(2, taiko_anc_func_text);
+
+static const char *const tabla_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
+static const struct soc_enum tabla_ear_pa_gain_enum[] = {
+ SOC_ENUM_SINGLE_EXT(2, tabla_ear_pa_gain_text),
+};
+
/*cut of frequency for high pass filter*/
static const char * const cf_text[] = {
"MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz"
@@ -1054,8 +1114,10 @@
SOC_SINGLE_TLV("ADC5 Volume", TAIKO_A_TX_5_6_EN, 5, 3, 0, analog_gain),
SOC_SINGLE_TLV("ADC6 Volume", TAIKO_A_TX_5_6_EN, 1, 3, 0, analog_gain),
- SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 0, 100, taiko_get_anc_slot,
+ SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, taiko_get_anc_slot,
taiko_put_anc_slot),
+ SOC_ENUM_EXT("ANC Function", taiko_anc_func_enum, taiko_get_anc_func,
+ taiko_put_anc_func),
SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
@@ -2184,101 +2246,6 @@
return 0;
}
-static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- const char *filename;
- const struct firmware *fw;
- int i;
- int ret;
- int num_anc_slots;
- struct anc_header *anc_head;
- struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
- u32 anc_writes_size = 0;
- int anc_size_remaining;
- u32 *anc_ptr;
- u16 reg;
- u8 mask, val;
-
- pr_debug("%s %d\n", __func__, event);
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
-
- filename = "wcd9320/wcd9320_anc.bin";
-
- ret = request_firmware(&fw, filename, codec->dev);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
- ret);
- return -ENODEV;
- }
-
- if (fw->size < sizeof(struct anc_header)) {
- dev_err(codec->dev, "Not enough data\n");
- release_firmware(fw);
- return -ENOMEM;
- }
-
- /* First number is the number of register writes */
- anc_head = (struct anc_header *)(fw->data);
- anc_ptr = (u32 *)((u32)fw->data + sizeof(struct anc_header));
- anc_size_remaining = fw->size - sizeof(struct anc_header);
- num_anc_slots = anc_head->num_anc_slots;
-
- if (taiko->anc_slot >= num_anc_slots) {
- dev_err(codec->dev, "Invalid ANC slot selected\n");
- release_firmware(fw);
- return -EINVAL;
- }
-
- for (i = 0; i < num_anc_slots; i++) {
-
- if (anc_size_remaining < TAIKO_PACKED_REG_SIZE) {
- dev_err(codec->dev, "Invalid register format\n");
- release_firmware(fw);
- return -EINVAL;
- }
- anc_writes_size = (u32)(*anc_ptr);
- anc_size_remaining -= sizeof(u32);
- anc_ptr += 1;
-
- if (anc_writes_size * TAIKO_PACKED_REG_SIZE
- > anc_size_remaining) {
- dev_err(codec->dev, "Invalid register format\n");
- release_firmware(fw);
- return -ENOMEM;
- }
-
- if (taiko->anc_slot == i)
- break;
-
- anc_size_remaining -= (anc_writes_size *
- TAIKO_PACKED_REG_SIZE);
- anc_ptr += anc_writes_size;
- }
- if (i == num_anc_slots) {
- dev_err(codec->dev, "Selected ANC slot not present\n");
- release_firmware(fw);
- return -ENOMEM;
- }
-
- for (i = 0; i < anc_writes_size; i++) {
- TAIKO_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
- mask, val);
- snd_soc_write(codec, reg, val);
- }
- release_firmware(fw);
-
- break;
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0xFF);
- snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL, 0);
- break;
- }
- return 0;
-}
-
static int taiko_codec_config_mad(struct snd_soc_codec *codec)
{
int ret;
@@ -2780,6 +2747,106 @@
return 0;
}
+static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ const char *filename;
+ const struct firmware *fw;
+ int i;
+ int ret;
+ int num_anc_slots;
+ struct anc_header *anc_head;
+ struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
+ u32 anc_writes_size = 0;
+ int anc_size_remaining;
+ u32 *anc_ptr;
+ u16 reg;
+ u8 mask, val, old_val;
+
+
+ if (taiko->anc_func == 0)
+ return 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ filename = "wcd9320/wcd9320_anc.bin";
+
+ ret = request_firmware(&fw, filename, codec->dev);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
+ ret);
+ return -ENODEV;
+ }
+
+ if (fw->size < sizeof(struct anc_header)) {
+ dev_err(codec->dev, "Not enough data\n");
+ release_firmware(fw);
+ return -ENOMEM;
+ }
+
+ /* First number is the number of register writes */
+ anc_head = (struct anc_header *)(fw->data);
+ anc_ptr = (u32 *)((u32)fw->data + sizeof(struct anc_header));
+ anc_size_remaining = fw->size - sizeof(struct anc_header);
+ num_anc_slots = anc_head->num_anc_slots;
+
+ if (taiko->anc_slot >= num_anc_slots) {
+ dev_err(codec->dev, "Invalid ANC slot selected\n");
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ for (i = 0; i < num_anc_slots; i++) {
+ if (anc_size_remaining < TAIKO_PACKED_REG_SIZE) {
+ dev_err(codec->dev, "Invalid register format\n");
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ anc_writes_size = (u32)(*anc_ptr);
+ anc_size_remaining -= sizeof(u32);
+ anc_ptr += 1;
+
+ if (anc_writes_size * TAIKO_PACKED_REG_SIZE
+ > anc_size_remaining) {
+ dev_err(codec->dev, "Invalid register format\n");
+ release_firmware(fw);
+ return -ENOMEM;
+ }
+
+ if (taiko->anc_slot == i)
+ break;
+
+ anc_size_remaining -= (anc_writes_size *
+ TAIKO_PACKED_REG_SIZE);
+ anc_ptr += anc_writes_size;
+ }
+ if (i == num_anc_slots) {
+ dev_err(codec->dev, "Selected ANC slot not present\n");
+ release_firmware(fw);
+ return -ENOMEM;
+ }
+ for (i = 0; i < anc_writes_size; i++) {
+ TAIKO_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
+ mask, val);
+ old_val = snd_soc_read(codec, reg);
+ snd_soc_write(codec, reg, (old_val & ~mask) |
+ (val & mask));
+ }
+ release_firmware(fw);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ msleep(40);
+ snd_soc_update_bits(codec, TAIKO_A_CDC_ANC1_B1_CTL, 0x01, 0x00);
+ snd_soc_update_bits(codec, TAIKO_A_CDC_ANC2_B1_CTL, 0x02, 0x00);
+ msleep(20);
+ snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0x0F);
+ snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL, 0);
+ snd_soc_write(codec, TAIKO_A_CDC_CLK_ANC_RESET_CTL, 0xFF);
+ break;
+ }
+ return 0;
+}
+
static int taiko_hph_pa_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -2835,6 +2902,46 @@
return 0;
}
+static int taiko_codec_enable_anc_hph(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ int ret = 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ret = taiko_hph_pa_event(w, kcontrol, event);
+ if (w->shift == 4) {
+ ret |= taiko_codec_enable_anc(w, kcontrol, event);
+ msleep(50);
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ if (w->shift == 4) {
+ snd_soc_update_bits(codec,
+ TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x30);
+ msleep(30);
+ }
+ ret = taiko_hph_pa_event(w, kcontrol, event);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ if (w->shift == 5) {
+ snd_soc_update_bits(codec,
+ TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x00);
+ msleep(40);
+ }
+ if (w->shift == 5) {
+ snd_soc_update_bits(codec,
+ TAIKO_A_TX_7_MBHC_EN, 0x80, 00);
+ ret |= taiko_codec_enable_anc(w, kcontrol, event);
+ }
+ case SND_SOC_DAPM_POST_PMD:
+ ret = taiko_hph_pa_event(w, kcontrol, event);
+ break;
+ }
+ return ret;
+}
+
static const struct snd_soc_dapm_widget taiko_dapm_i2s_widgets[] = {
SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", TAIKO_A_CDC_CLK_RX_I2S_CTL,
4, 0, NULL, 0),
@@ -3022,9 +3129,10 @@
{"EAR_PA_MIXER", NULL, "DAC1"},
{"DAC1", NULL, "RX_BIAS"},
+ {"ANC EAR", NULL, "ANC EAR PA"},
+ {"ANC EAR PA", NULL, "EAR_PA_MIXER"},
{"ANC1 FB MUX", "EAR_HPH_L", "RX1 MIX2"},
{"ANC1 FB MUX", "EAR_LINE_1", "RX2 MIX2"},
- {"ANC", NULL, "ANC1 FB MUX"},
/* Headset (RX MIX1 and RX MIX2) */
{"HEADPHONE", NULL, "HPHL"},
@@ -3038,18 +3146,28 @@
{"HPHR_PA_MIXER", NULL, "HPHR DAC"},
{"HPHR DAC", NULL, "RX_BIAS"},
- {"ANC", NULL, "ANC1 MUX"},
- {"ANC", NULL, "ANC2 MUX"},
+ {"ANC HEADPHONE", NULL, "ANC HPHL"},
+ {"ANC HEADPHONE", NULL, "ANC HPHR"},
+
+ {"ANC HPHL", NULL, "HPHL_PA_MIXER"},
+ {"ANC HPHR", NULL, "HPHR_PA_MIXER"},
+
{"ANC1 MUX", "ADC1", "ADC1"},
{"ANC1 MUX", "ADC2", "ADC2"},
{"ANC1 MUX", "ADC3", "ADC3"},
{"ANC1 MUX", "ADC4", "ADC4"},
+ {"ANC1 MUX", "DMIC1", "DMIC1"},
+ {"ANC1 MUX", "DMIC2", "DMIC2"},
+ {"ANC1 MUX", "DMIC3", "DMIC3"},
+ {"ANC1 MUX", "DMIC4", "DMIC4"},
+ {"ANC1 MUX", "DMIC5", "DMIC5"},
+ {"ANC1 MUX", "DMIC6", "DMIC6"},
{"ANC2 MUX", "ADC1", "ADC1"},
{"ANC2 MUX", "ADC2", "ADC2"},
{"ANC2 MUX", "ADC3", "ADC3"},
{"ANC2 MUX", "ADC4", "ADC4"},
- {"ANC", NULL, "CDC_CONN"},
+ {"ANC HPHR", NULL, "CDC_CONN"},
{"DAC1", "Switch", "CLASS_H_DSM MUX"},
{"HPHL DAC", "Switch", "CLASS_H_DSM MUX"},
@@ -3095,8 +3213,8 @@
{"RX1 CHAIN", NULL, "RX1 MIX2"},
{"RX2 CHAIN", NULL, "RX2 MIX2"},
- {"RX1 CHAIN", NULL, "ANC"},
- {"RX2 CHAIN", NULL, "ANC"},
+ {"RX1 MIX2", NULL, "ANC1 MUX"},
+ {"RX2 MIX2", NULL, "ANC2 MUX"},
{"LINEOUT1 DAC", NULL, "RX_BIAS"},
{"LINEOUT2 DAC", NULL, "RX_BIAS"},
@@ -3429,6 +3547,14 @@
(reg <= TAIKO_A_CDC_IIR2_COEF_B2_CTL))
return 1;
+ /* ANC filter registers are not cacheable */
+ if ((reg >= TAIKO_A_CDC_ANC1_IIR_B1_CTL) &&
+ (reg <= TAIKO_A_CDC_ANC1_LPF_B2_CTL))
+ return 1;
+ if ((reg >= TAIKO_A_CDC_ANC2_IIR_B1_CTL) &&
+ (reg <= TAIKO_A_CDC_ANC2_LPF_B2_CTL))
+ return 1;
+
/* Digital gain register is not cacheable so we have to write
* the setting even it is the same
*/
@@ -4457,6 +4583,32 @@
return 0;
}
+static int taiko_codec_enable_anc_ear(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ int ret = 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ret = taiko_codec_enable_anc(w, kcontrol, event);
+ msleep(50);
+ snd_soc_update_bits(codec, TAIKO_A_RX_EAR_EN, 0x10, 0x10);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ ret = taiko_codec_enable_ear_pa(w, kcontrol, event);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, TAIKO_A_RX_EAR_EN, 0x10, 0x00);
+ msleep(40);
+ ret |= taiko_codec_enable_anc(w, kcontrol, event);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = taiko_codec_enable_ear_pa(w, kcontrol, event);
+ break;
+ }
+ return ret;
+}
/* Todo: Have seperate dapm widgets for I2S and Slimbus.
* Might Need to have callbacks registered only for slimbus
@@ -4754,10 +4906,20 @@
SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
- SND_SOC_DAPM_MIXER_E("ANC", SND_SOC_NOPM, 0, 0, NULL, 0,
- taiko_codec_enable_anc, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-
+ SND_SOC_DAPM_OUTPUT("ANC HEADPHONE"),
+ SND_SOC_DAPM_PGA_E("ANC HPHL", SND_SOC_NOPM, 5, 0, NULL, 0,
+ taiko_codec_enable_anc_hph,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_PGA_E("ANC HPHR", SND_SOC_NOPM, 4, 0, NULL, 0,
+ taiko_codec_enable_anc_hph, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+ SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_OUTPUT("ANC EAR"),
+ SND_SOC_DAPM_PGA_E("ANC EAR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
+ taiko_codec_enable_anc_ear,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
SND_SOC_DAPM_INPUT("AMIC2"),
@@ -5258,6 +5420,12 @@
TAIKO_REG_VAL(TAIKO_A_CDC_TX9_MUX_CTL, 0x48),
TAIKO_REG_VAL(TAIKO_A_CDC_TX10_MUX_CTL, 0x48),
TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B4_CTL, 0x8),
+ TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B4_CTL, 0x8),
+ TAIKO_REG_VAL(TAIKO_A_CDC_RX3_B4_CTL, 0x8),
+ TAIKO_REG_VAL(TAIKO_A_CDC_RX4_B4_CTL, 0x8),
+ TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B4_CTL, 0x8),
+ TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B4_CTL, 0x8),
+ TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B4_CTL, 0x8),
TAIKO_REG_VAL(TAIKO_A_CDC_VBAT_GAIN_UPD_MON, 0x0),
TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B1_CTL, 0x0),
TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B2_CTL, 0x0),
@@ -5700,6 +5868,14 @@
(void) taiko_setup_irqs(taiko);
atomic_set(&kp_taiko_priv, (unsigned long)taiko);
+ mutex_lock(&dapm->codec->mutex);
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
+ snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
+ snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC EAR");
+ snd_soc_dapm_sync(dapm);
+ mutex_unlock(&dapm->codec->mutex);
codec->ignore_pmdown_time = 1;
return ret;
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 5b54e1b..764f4c6 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -3018,14 +3018,19 @@
switch (event) {
case WCD9XXX_EVENT_PRE_MICBIAS_1_ON:
ret = MBHC_MICBIAS1;
+ break;
case WCD9XXX_EVENT_PRE_MICBIAS_2_ON:
ret = MBHC_MICBIAS2;
+ break;
case WCD9XXX_EVENT_PRE_MICBIAS_3_ON:
ret = MBHC_MICBIAS3;
+ break;
case WCD9XXX_EVENT_PRE_MICBIAS_4_ON:
ret = MBHC_MICBIAS4;
+ break;
default:
ret = MBHC_MICBIAS_INVALID;
+ break;
}
return ret;
}
diff --git a/sound/soc/msm/lpass-dma.c b/sound/soc/msm/lpass-dma.c
index 39a7f7f..50938df 100644
--- a/sound/soc/msm/lpass-dma.c
+++ b/sound/soc/msm/lpass-dma.c
@@ -16,7 +16,7 @@
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
-#include <linux/android_pmem.h>
+
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 4e6cbaa..e54f8b7 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -29,7 +29,7 @@
#include <sound/pcm_params.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include <sound/timer.h>
#include <mach/qdsp6v2/q6core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/msm/msm-lowlatency-pcm-q6.c b/sound/soc/msm/msm-lowlatency-pcm-q6.c
index 6ad1410..d5281e4 100644
--- a/sound/soc/msm/msm-lowlatency-pcm-q6.c
+++ b/sound/soc/msm/msm-lowlatency-pcm-q6.c
@@ -20,7 +20,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include <asm/dma.h>
#include <sound/core.h>
#include <sound/soc.h>
diff --git a/sound/soc/msm/msm-multi-ch-pcm-q6.c b/sound/soc/msm/msm-multi-ch-pcm-q6.c
index 10b7e30..26bf3d9 100644
--- a/sound/soc/msm/msm-multi-ch-pcm-q6.c
+++ b/sound/soc/msm/msm-multi-ch-pcm-q6.c
@@ -20,7 +20,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include <asm/dma.h>
#include <sound/core.h>
#include <sound/soc.h>
diff --git a/sound/soc/msm/msm-pcm-afe.c b/sound/soc/msm/msm-pcm-afe.c
index e01c759..a3bcf23 100644
--- a/sound/soc/msm/msm-pcm-afe.c
+++ b/sound/soc/msm/msm-pcm-afe.c
@@ -20,7 +20,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
diff --git a/sound/soc/msm/msm-pcm-lpa.c b/sound/soc/msm/msm-pcm-lpa.c
index 6f1a01d..ba054bd 100644
--- a/sound/soc/msm/msm-pcm-lpa.c
+++ b/sound/soc/msm/msm-pcm-lpa.c
@@ -26,7 +26,7 @@
#include <sound/control.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include <sound/compress_params.h>
#include <sound/compress_offload.h>
#include <sound/compress_driver.h>
diff --git a/sound/soc/msm/msm-pcm-q6.c b/sound/soc/msm/msm-pcm-q6.c
index c326437..1d15c11 100644
--- a/sound/soc/msm/msm-pcm-q6.c
+++ b/sound/soc/msm/msm-pcm-q6.c
@@ -27,7 +27,7 @@
#include <sound/control.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include "msm-pcm-q6.h"
#include "msm-pcm-routing.h"
diff --git a/sound/soc/msm/msm7kv2-pcm.c b/sound/soc/msm/msm7kv2-pcm.c
index 2b7a438..ed23521 100644
--- a/sound/soc/msm/msm7kv2-pcm.c
+++ b/sound/soc/msm/msm7kv2-pcm.c
@@ -32,7 +32,7 @@
#include <sound/control.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include <linux/slab.h>
#include "msm7kv2-pcm.h"
#include <mach/qdsp5v2/audio_dev_ctl.h>
diff --git a/sound/soc/msm/msm8x60-pcm.c b/sound/soc/msm/msm8x60-pcm.c
index 7993435..f8b43cf 100644
--- a/sound/soc/msm/msm8x60-pcm.c
+++ b/sound/soc/msm/msm8x60-pcm.c
@@ -27,7 +27,7 @@
#include <asm/dma.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
-#include <linux/android_pmem.h>
+
#include <mach/qdsp6v2/audio_dev_ctl.h>
#include "msm8x60-pcm.h"
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index a55700c..f15f4d1 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -25,7 +25,7 @@
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/msm_audio.h>
-#include <linux/android_pmem.h>
+
#include <linux/memory_alloc.h>
#include <linux/debugfs.h>
#include <linux/time.h>
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
index f6e571b8..5dc5f96 100644
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
@@ -29,7 +29,7 @@
#include <sound/pcm_params.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include <sound/timer.h>
#include "msm-compr-q6-v2.h"
diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
index ea6f390..363fb15 100644
--- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c
+++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
@@ -18,7 +18,6 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
#include <linux/of.h>
#include <sound/core.h>
#include <sound/soc.h>
diff --git a/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
index d0d573c..a078042 100644
--- a/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
@@ -20,7 +20,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include <asm/dma.h>
#include <sound/core.h>
#include <sound/soc.h>
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index 91bb09b..e4f3f94 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -20,7 +20,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
index 3a4a674..64f19ad 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
@@ -26,7 +26,7 @@
#include <sound/control.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include <linux/of_device.h>
#include <sound/compress_params.h>
#include <sound/compress_offload.h>
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 4ca96d7..ca91fe5 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -27,7 +27,7 @@
#include <sound/control.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
+
#include <linux/of_device.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 0549671..ea2b5c6 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -24,7 +24,7 @@
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/msm_audio.h>
-#include <linux/android_pmem.h>
+
#include <linux/memory_alloc.h>
#include <linux/debugfs.h>
#include <linux/time.h>
@@ -1651,6 +1651,9 @@
case FORMAT_AMRWB:
open.dec_fmt_id = ASM_MEDIA_FMT_AMRWB_FS;
break;
+ case FORMAT_AMR_WB_PLUS:
+ open.dec_fmt_id = ASM_MEDIA_FMT_AMR_WB_PLUS_V2;
+ break;
case FORMAT_V13K:
open.dec_fmt_id = ASM_MEDIA_FMT_V13K_FS;
break;
@@ -2532,6 +2535,42 @@
return -EINVAL;
}
+int q6asm_media_format_block_amrwbplus(struct audio_client *ac,
+ struct asm_amrwbplus_cfg *cfg)
+{
+ struct asm_amrwbplus_fmt_blk_v2 fmt;
+ int rc = 0;
+
+ pr_debug("%s:session[%d]band-mode[%d]frame-fmt[%d]ch[%d]\n",
+ __func__,
+ ac->session,
+ cfg->amr_band_mode,
+ cfg->amr_frame_fmt,
+ cfg->num_channels);
+
+ q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
+
+ fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
+ fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
+ sizeof(fmt.fmtblk);
+ fmt.amr_frame_fmt = cfg->amr_frame_fmt;
+
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
+ if (rc < 0) {
+ pr_err("%s:Comamnd media format update failed..\n", __func__);
+ goto fail_cmd;
+ }
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) == 0), 5*HZ);
+ if (!rc) {
+ pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
+ goto fail_cmd;
+ }
+ return 0;
+fail_cmd:
+ return -EINVAL;
+}
+
int q6asm_memory_map(struct audio_client *ac, uint32_t buf_add, int dir,
uint32_t bufsz, uint32_t bufcnt)
{