Merge "arm/dt: 8092: Update BFB register settings in device tree."
diff --git a/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt b/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
index e336429..39be71e 100644
--- a/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
+++ b/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
@@ -24,6 +24,12 @@
Channel node
NOTE: Atleast one Channel node is required.
+Client required property:
+- qcom,<consumer name>-iadc : The phandle to the corresponding iadc device.
+ The consumer name passed to the driver when calling
+ qpnp_get_iadc() is used to associate the client
+ with the corresponding device.
+
Required properties:
- label : Channel name used for sysfs entry.
- reg : AMUX channel number.
@@ -113,3 +119,9 @@
qcom,fast-avg-setup = <0>;
};
};
+
+Client device example:
+/* Add to the clients node that needs the IADC */
+client_node {
+ qcom,client-iadc = <&pm8941_iadc>;
+};
diff --git a/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt b/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
index 3720172..0f35e73 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
@@ -20,7 +20,6 @@
- synaptics,panel-x : panel x dimension
- synaptics,panel-y : panel y dimension
- synaptics,fw-image-name : name of firmware .img file in /etc/firmware
- - synaptics,power-down : fully power down regulators in suspend
Example:
i2c@f9927000 { /* BLSP1 QUP5 */
diff --git a/Documentation/devicetree/bindings/media/video/msm-ispif.txt b/Documentation/devicetree/bindings/media/video/msm-ispif.txt
index ff33b17..dc1187a 100644
--- a/Documentation/devicetree/bindings/media/video/msm-ispif.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-ispif.txt
@@ -4,6 +4,7 @@
- cell-index: ispif hardware core index
- compatible :
- "qcom,ispif"
+ - "qcom,ispif-v3.0"
- reg : offset and length of the register set for the device
for the ispif operating in compatible mode.
- reg-names : should specify relevant names to each reg property defined.
@@ -11,9 +12,13 @@
- interrupt-names : should specify relevant names to each interrupts
property defined.
+Optional properties:
+- qcom,num-isps: The number of ISPs the ISPIF module is connected to. If not set
+ the default value used is 1
+
Example:
- qcom,ispif@0xfda0a000 {
+ qcom,ispif@fda0a000 {
cell-index = <0>;
compatible = "qcom,ispif";
reg = <0xfda0a000 0x300>;
@@ -21,3 +26,16 @@
interrupts = <0 55 0>;
interrupt-names = "ispif";
};
+
+or
+
+ qcom,ispif@fda0a000 {
+ cell-index = <0>;
+ compatible = "qcom,ispif-v3.0", "qcom,ispif";
+ reg = <0xfda0a000 0x300>;
+ reg-names = "ispif";
+ interrupts = <0 55 0>;
+ interrupt-names = "ispif";
+ qcom,num-isps = <2>
+ };
+
diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
index ac60e38..cc2506d 100644
--- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
@@ -33,15 +33,31 @@
request by different video encoder usecases.
- qcom,dec-ddr-ab-ib : list of bus vectors(ab, ib pair) for ddr bandwidth
request by different video decoder usecases.
-- qcom,iommu-groups : list of IOMMU groups to be used. Groups are defined as
- phandles in <target>-iommu-domains.dtsi (e.g msm8974-v1-iommu-domains.dtsi)
-- qcom,iommu-group-buffer-types : bitmap of buffer types that can be mapped into
- the corresponding IOMMU group. Buffer types are defined within the vidc driver
- by "enum hal_buffer" in msm_smem.h
- qcom,buffer-type-tz-usage-table : a key-value pair, mapping a buffer type
(enum hal_buffer) to its corresponding TZ usage. The TZ usages are defined
as "enum cp_mem_usage" in include/linux/msm_ion.h
- qcom,has-ocmem: indicate the target has ocmem if this property exists
+- qcom,vidc-iommu-domains: node containing individual domain nodes, each with:
+ - a unique domain name for the domain node (e.g vidc,domain-ns)
+ - qcom,vidc-domain-phandle: phandle for the domain as defined in
+ <target>-iommu-domains.dtsi (e.g msm8974-v1-iommu-domains.dtsi)
+ - qcom,vidc-partition-buffer-types: bitmap of buffer types that can
+ be mapped into each IOMMU domain partition. There must be exactly
+ one buffer bitmap per partition in the domain, with order of the
+ bitmaps to be the same as the order of the respective partitions.
+ - Buffer types are defined as the following:
+ input = 0x1
+ output = 0x2
+ output2 = 0x2
+ extradata input = 0x4
+ extradata output = 0x8
+ extradata output2 = 0x8
+ internal scratch = 0x10
+ internal scratch1 = 0x20
+ internal scratch2 = 0x40
+ internal persist = 0x80
+ internal persist1 = 0x100
+ internal cmd queue = 0x200
Example:
@@ -71,9 +87,20 @@
<60000 664950>;
qcom,dec-ddr-ab-ib = <0 0>,
<110000 909000>;
- qcom,iommu-groups = <&venus_domain_ns &venus_domain_cp>;
- qcom,iommu-group-buffer-types = <0xfff 0x1ff>;
qcom,buffer-type-tz-usage-table = <0x1 0x1>,
<0x1fe 0x2>;
qcom,max-hw-load = <1224450>; /* 4k @ 30 + 1080p @ 30*/
+ qcom,vidc-iommu-domains {
+ qcom,domain-ns {
+ qcom,vidc-domain-phandle = <&venus_domain_ns>;
+ qcom,vidc-partition-buffer-types = <0x1ff>,
+ <0x200>;
+ };
+
+ qcom,domain-cp {
+ qcom,vidc-domain-phandle = <&venus_domain_cp>;
+ qcom,vidc-partition-buffer-types = <0x2>,
+ <0x1f1>;
+ };
+ };
};
diff --git a/Documentation/devicetree/bindings/power/qpnp-bms.txt b/Documentation/devicetree/bindings/power/qpnp-bms.txt
index 2da5c72..1162298 100644
--- a/Documentation/devicetree/bindings/power/qpnp-bms.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-bms.txt
@@ -87,6 +87,7 @@
For example - A value of 10 indicates:
FCC value (in mAh) = (8-bit register value) * 10.
- qcom,bms-vadc: Corresponding VADC device's phandle.
+- qcom,bms-iadc: Corresponding IADC device's phandle.
Parent node optional properties:
- qcom,ignore-shutdown-soc: A boolean that controls whether BMS will
@@ -102,6 +103,8 @@
- qcom,use-ocv-thresholds : A boolean that controls whether BMS will take
new OCVs only between the defined thresholds.
- qcom,enable-fcc-learning: A boolean that defines if FCC learning is enabled.
+- qcom,bms-adc_tm: Corresponding ADC_TM device's phandle to set recurring measurements
+ and receive notifications for die_temperature, vbatt.
All sub node required properties:
@@ -150,6 +153,8 @@
qcom,tm-temp-margin = <5000>;
qcom,battery-data = <&mtp_batterydata>;
qcom,bms-vadc = <&pm8941_vadc>;
+ qcom,bms-iadc = <&pm8941_iadc>;
+ qcom,bms-adc_tm = <&pm8941_adc_tm>;
qcom,bms-iadc@3800 {
reg = <0x3800 0x100>;
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index 3150bbf..4a5e58c 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -89,6 +89,8 @@
to the collective charging device. For example USB detection
and the battery interface are each seperate peripherals and
each should be their own subnode.
+- qcom,chg-adc_tm Corresponding ADC TM device's phandle to set recurring
+ measurements and receive notification for batt_therm.
Sub node required properties:
- compatible: Must be "qcom,qpnp-charger".
@@ -103,6 +105,7 @@
qcom,usb-chgpth:
- usbin-valid
+ - usb-ocp (only for SMBBP and SMBCL)
qcom,chgr:
- chg-done
@@ -149,6 +152,9 @@
- coarse-det-usb: Coarse detect interrupt triggers
at low voltage on USB_IN.
- chg-gone: Triggers on VCHG line.
+ - usb-ocp Triggers on over current conditions when
+ reverse boosting. (Only available on
+ SMBCL and SMBBP devices).
qcom,dc-chgpth:
- dcin-valid: Indicates a valid DC charger
@@ -198,6 +204,7 @@
qcom,batt-cold-percent = <85>;
qcom,btc-disabled = <0>;
qcom,chg-vadc = <&pm8941_vadc>;
+ qcom,chg-adc_tm = <&pm8941_adc_tm>;
qcom,chgr@1000 {
reg = <0x1000 0x100>;
diff --git a/Documentation/devicetree/bindings/regulator/krait-regulator-pmic.txt b/Documentation/devicetree/bindings/regulator/krait-regulator-pmic.txt
new file mode 100644
index 0000000..a0730f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/krait-regulator-pmic.txt
@@ -0,0 +1,47 @@
+Krait Voltage regulators in the PMIC
+
+In certain MSMs the CPUs are powered using a single supply powered by PMIC ganged regulators
+operating in different phases. The krait-regulator-pmic node represents the gang leader and its
+associated control, power stage and frequency peripherals.
+
+[First Level Nodes]
+Required properties:
+- compatible: Must be "qcom,krait-regulator-pmic".
+- spmi-dev-container: Specifies that all the device nodes specified
+ within this node should have their resources coalesced into a
+ single spmi_device. This is used to specify all SPMI peripherals
+ that logically make up the gang leader.
+ - #address-cells: The number of cells dedicated to represent an address
+ This must be set to '1'.
+ - #size-cells: The number of cells dedicated to represent address
+ space range of a peripheral. This must be set to '1'.
+
+[Second Level Nodes]
+Required properties:
+- reg: Specifies the SPMI address and size for this peripheral.
+There must be exactly three subnodes qcom,ctl qcom,ps and qcom,freq representing control,
+power stage and frequency SPMI peripherals respectively of the gang leader.
+
+Example:
+ krait_regulator_pmic: qcom,krait-regulator-pmic {
+ spmi-dev-container;
+ compatible = "qcom,krait-regulator-pmic";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+
+ qcom,ctl@2000 {
+ status = "disabled";
+ reg = <0x2000 0x100>;
+ };
+
+ qcom,ps@2100 {
+ status = "disabled";
+ reg = <0x2100 0x100>;
+ };
+
+ qcom,freq@2200 {
+ status = "disabled";
+ reg = <0x2200 0x100>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
index 64c44b5..e1681ca 100644
--- a/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
+++ b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
@@ -27,6 +27,12 @@
crosses a set threshold, read temperature and enable/set trip types supported
by the thermal framework.
+Client required property:
+- qcom,<consumer name>-adc_tm : The phandle to the corresponding adc_tm device.
+ The consumer name passed to the driver when calling
+ qpnp_get_adc_tm() is used to associate the client
+ with the corresponding device.
+
Channel nodes
NOTE: Atleast one Channel node is required.
@@ -97,6 +103,12 @@
allocated to the corresponding channel node.
- qcom,adc_tm-vadc : phandle to the corresponding VADC device to read the ADC channels.
+Client device example:
+/* Add to the clients node that needs the ADC_TM channel A/D */
+client_node {
+ qcom,client-adc_tm = <&pm8941_adc_tm>;
+};
+
Example:
/* Main Node */
qcom,vadc@3400 {
diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
index ff7b03d..f2a9940 100644
--- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
@@ -49,6 +49,9 @@
is not supported and attached host should always be assumed as SDP.
- USB3_GDSC-supply : phandle to the globally distributed switch controller
regulator node to the USB controller.
+- qcom,dwc_usb3-adc_tm: Corresponding ADC_TM device's phandle to set recurring
+ measurements on USB_ID channel when using ADC and receive
+ notifications for set thresholds.
Sub nodes:
- Sub node for "DWC3- USB3 controller".
@@ -72,6 +75,7 @@
qcom,dwc-usb3-msm-dbm-eps = <4>
qcom,vdd-voltage-level = <1 5 7>;
qcom,dwc-hsphy-init = <0x00D195A4>;
+ qcom,dwc_usb3-adc_tm = <&pm8941_adc_tm>;
qcom,msm_bus,name = "usb3";
qcom,msm_bus,num_cases = <2>;
diff --git a/arch/arm/boot/dts/apq8074-v2.2-cdp.dts b/arch/arm/boot/dts/apq8074-v2.2-cdp.dts
new file mode 100644
index 0000000..a3dc490
--- /dev/null
+++ b/arch/arm/boot/dts/apq8074-v2.2-cdp.dts
@@ -0,0 +1,34 @@
+/* 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/ "apq8074-v2.2.dtsi"
+/include/ "msm8974-cdp.dtsi"
+
+/ {
+ model = "Qualcomm APQ 8074v2.2 CDP";
+ compatible = "qcom,apq8074-cdp", "qcom,apq8074", "qcom,cdp";
+ qcom,msm-id = <184 1 0x20002>;
+};
+
+&usb3 {
+ interrupt-parent = <&usb3>;
+ interrupts = <0 1>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0x0 0xffffffff>;
+ interrupt-map = <0x0 0 &intc 0 133 0
+ 0x0 1 &spmi_bus 0x0 0x0 0x9 0x0>;
+ interrupt-names = "hs_phy_irq", "pmic_id_irq";
+
+ qcom,misc-ref = <&pm8941_misc>;
+};
diff --git a/arch/arm/boot/dts/apq8074-v2.2-dragonboard.dts b/arch/arm/boot/dts/apq8074-v2.2-dragonboard.dts
new file mode 100644
index 0000000..6989088
--- /dev/null
+++ b/arch/arm/boot/dts/apq8074-v2.2-dragonboard.dts
@@ -0,0 +1,22 @@
+/* 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/ "apq8074-v2.2.dtsi"
+/include/ "apq8074-dragonboard.dtsi"
+
+/ {
+ model = "Qualcomm APQ 8074v2.2 DRAGONBOARD";
+ compatible = "qcom,apq8074-dragonboard", "qcom,apq8074", "qcom,dragonboard";
+ qcom,msm-id = <184 10 0x20002>;
+};
diff --git a/arch/arm/boot/dts/apq8074-v2.2-liquid.dts b/arch/arm/boot/dts/apq8074-v2.2-liquid.dts
new file mode 100644
index 0000000..09d6e66
--- /dev/null
+++ b/arch/arm/boot/dts/apq8074-v2.2-liquid.dts
@@ -0,0 +1,22 @@
+/* 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/ "apq8074-v2.2.dtsi"
+/include/ "msm8974-liquid.dtsi"
+
+/ {
+ model = "Qualcomm APQ 8074v2.2 LIQUID";
+ compatible = "qcom,apq8074-liquid", "qcom,apq8074", "qcom,liquid";
+ qcom,msm-id = <184 9 0x20002>;
+};
diff --git a/arch/arm/boot/dts/apq8074-v2.2.dtsi b/arch/arm/boot/dts/apq8074-v2.2.dtsi
new file mode 100644
index 0000000..ddf7ec8
--- /dev/null
+++ b/arch/arm/boot/dts/apq8074-v2.2.dtsi
@@ -0,0 +1,57 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm8974.dtsi file.
+ */
+
+/include/ "msm8974-v2.2.dtsi"
+
+&soc {
+ qcom,qseecom@a700000 {
+ compatible = "qcom,qseecom";
+ reg = <0x0a700000 0x500000>;
+ reg-names = "secapp-region";
+ qcom,disk-encrypt-pipe-pair = <2>;
+ qcom,hlos-ce-hw-instance = <1>;
+ qcom,qsee-ce-hw-instance = <0>;
+ qcom,msm-bus,name = "qseecom-noc";
+ qcom,msm-bus,num-cases = <4>;
+ qcom,msm-bus,active-only = <0>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <55 512 0 0>,
+ <55 512 3936000 393600>,
+ <55 512 3936000 393600>,
+ <55 512 3936000 393600>;
+ };
+
+ sound {
+ compatible = "qcom,apq8074-audio-taiko";
+ };
+};
+
+&memory_hole {
+ qcom,memblock-remove = <0x0a700000 0x5800000>; /* Address and size of the hole */
+};
+
+&qseecom {
+ status = "disabled";
+};
+
+&sdcc3 {
+ qcom,sup-voltages = <2000 2000>;
+ status = "ok";
+};
+
diff --git a/arch/arm/boot/dts/apq8084-regulator.dtsi b/arch/arm/boot/dts/apq8084-regulator.dtsi
index 0c9ca7d..3d5fc7c 100644
--- a/arch/arm/boot/dts/apq8084-regulator.dtsi
+++ b/arch/arm/boot/dts/apq8084-regulator.dtsi
@@ -326,9 +326,9 @@
};
&rpm_bus {
- rpm-regulator-smpb1 {
+ rpm-regulator-smpa1 {
compatible = "qcom,rpm-regulator-smd-resource";
- qcom,resource-name = "smpb";
+ qcom,resource-name = "smpa";
qcom,resource-id = <1>;
qcom,regulator-type = <1>;
qcom,hpm-min-load = <100000>;
@@ -342,9 +342,9 @@
};
};
- rpm-regulator-smpb2 {
+ rpm-regulator-smpa2 {
compatible = "qcom,rpm-regulator-smd-resource";
- qcom,resource-name = "smpb";
+ qcom,resource-name = "smpa";
qcom,resource-id = <2>;
qcom,regulator-type = <1>;
qcom,hpm-min-load = <100000>;
diff --git a/arch/arm/boot/dts/mpq8092-iommu.dtsi b/arch/arm/boot/dts/mpq8092-iommu.dtsi
index 8b3320f..320440c 100644
--- a/arch/arm/boot/dts/mpq8092-iommu.dtsi
+++ b/arch/arm/boot/dts/mpq8092-iommu.dtsi
@@ -279,3 +279,7 @@
interrupts = <0 302 0>;
};
};
+
+&vcap_iommu {
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/msm-iommu-v1.dtsi b/arch/arm/boot/dts/msm-iommu-v1.dtsi
index ef8677d..cd5adaa 100644
--- a/arch/arm/boot/dts/msm-iommu-v1.dtsi
+++ b/arch/arm/boot/dts/msm-iommu-v1.dtsi
@@ -1056,4 +1056,98 @@
label = "lpass_core_cb_2";
};
};
+
+ vcap_iommu: qcom,iommu@fdfb6000 {
+ compatible = "qcom,msm-smmu-v1";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ reg = <0xfdfb6000 0x10000>;
+ reg-names = "iommu_base";
+ interrupts = <0 315 0>;
+ qcom,needs-alt-core-clk;
+ label = "vcap_iommu";
+ status = "disabled";
+ qcom,msm-bus,name = "vcap_ebi";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <48 512 0 0>,
+ <48 512 0 1000>;
+
+ qcom,iommu-pmu-ngroups = <1>;
+ qcom,iommu-pmu-ncounters = <8>;
+ qcom,iommu-pmu-event-classes = <0x00
+ 0x01
+ 0x08
+ 0x09
+ 0x0A
+ 0x10
+ 0x11
+ 0x12
+ 0x80
+ 0x81
+ 0x82
+ 0x83
+ 0x90
+ 0x91
+ 0x92
+ 0xb0
+ 0xb1>;
+
+ qcom,iommu-bfb-regs = <0x204c
+ 0x2514
+ 0x2540
+ 0x256c
+ 0x2314
+ 0x2394
+ 0x2414
+ 0x2494
+ 0x20ac
+ 0x215c
+ 0x220c
+ 0x22bc
+ 0x2008
+ 0x200c>;
+
+ qcom,iommu-bfb-data = <0x0ff
+ 0x00000004
+ 0x00000008
+ 0x0
+ 0x0
+ 0x00000008
+ 0x00000028
+ 0x0
+ 0x001000
+ 0x001000
+ 0x003008
+ 0x0
+ 0x0
+ 0x0>;
+
+ qcom,iommu-ctx@fdfbe000 {
+ compatible = "qcom,msm-smmu-v1-ctx";
+ reg = <0xfdfbe000 0x1000>;
+ interrupts = <0 313 0>;
+ qcom,iommu-ctx-sids = <0>;
+ label = "vcap_cb0";
+ };
+
+ qcom,iommu-ctx@fdfbf000 {
+ compatible = "qcom,msm-smmu-v1-ctx";
+ reg = <0xfdfbf000 0x1000>;
+ interrupts = <0 313 0>;
+ qcom,iommu-ctx-sids = <1>;
+ label = "vcap_cb1";
+ };
+
+ qcom,iommu-ctx@fdfc0000 {
+ compatible = "qcom,msm-smmu-v1-ctx";
+ reg = <0xfdfc0000 0x1000>;
+ interrupts = <0 313 0>;
+ qcom,iommu-ctx-sids = <>;
+ label = "vcap_cb2";
+ };
+ };
};
diff --git a/arch/arm/boot/dts/msm-pm8110.dtsi b/arch/arm/boot/dts/msm-pm8110.dtsi
index 3c17655..1d7eaa5 100644
--- a/arch/arm/boot/dts/msm-pm8110.dtsi
+++ b/arch/arm/boot/dts/msm-pm8110.dtsi
@@ -59,16 +59,17 @@
qcom,vddmax-mv = <4200>;
qcom,vddsafe-mv = <4230>;
- qcom,vinmin-mv = <4200>;
+ qcom,vinmin-mv = <4300>;
qcom,vbatdet-mv = <4100>;
qcom,ibatmax-ma = <1500>;
qcom,ibatterm-ma = <100>;
qcom,ibatsafe-ma = <1500>;
qcom,thermal-mitigation = <1500 700 600 325>;
- qcom,vbatdet-delta-mv = <350>;
+ qcom,vbatdet-delta-mv = <100>;
qcom,resume-soc = <99>;
qcom,tchg-mins = <150>;
qcom,chg-vadc = <&pm8110_vadc>;
+ qcom,chg-adc_tm = <&pm8110_adc_tm>;
qcom,chgr@1000 {
status = "disabled";
@@ -133,11 +134,13 @@
reg = <0x1300 0x100>;
interrupts = <0 0x13 0x0>,
<0 0x13 0x1>,
- <0x0 0x13 0x2>;
+ <0x0 0x13 0x2>,
+ <0x0 0x13 0x3>;
interrupt-names = "coarse-det-usb",
"usbin-valid",
- "chg-gone";
+ "chg-gone",
+ "usb-ocp";
};
qcom,chg-misc@1600 {
@@ -250,7 +253,7 @@
};
};
- iadc@3600 {
+ pm8110_iadc: iadc@3600 {
compatible = "qcom,qpnp-iadc";
reg = <0x3600 0x100>;
#address-cells = <1>;
@@ -325,6 +328,8 @@
qcom,high-ocv-correction-limit-uv = <50>;
qcom,hold-soc-est = <3>;
qcom,bms-vadc = <&pm8110_vadc>;
+ qcom,bms-iadc = <&pm8110_iadc>;
+ qcom,bms-adc_tm = <&pm8110_adc_tm>;
qcom,bms-iadc@3800 {
reg = <0x3800 0x100>;
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index e3daf6c..307e4c7 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -75,8 +75,8 @@
qcom,vddmax-mv = <4200>;
qcom,vddsafe-mv = <4230>;
- qcom,vinmin-mv = <4200>;
- qcom,vbatdet-delta-mv = <150>;
+ qcom,vinmin-mv = <4300>;
+ qcom,vbatdet-delta-mv = <100>;
qcom,ibatmax-ma = <1500>;
qcom,ibatterm-ma = <100>;
qcom,ibatsafe-ma = <1500>;
@@ -84,6 +84,7 @@
qcom,resume-soc = <99>;
qcom,tchg-mins = <150>;
qcom,chg-vadc = <&pm8226_vadc>;
+ qcom,chg-adc_tm = <&pm8226_adc_tm>;
qcom,chgr@1000 {
status = "disabled";
@@ -141,19 +142,6 @@
"bat-fet-on",
"vcp-on",
"psi";
-
- };
-
- pm8226_chg_otg: qcom,usb-chgpth@1300 {
- status = "disabled";
- reg = <0x1300 0x100>;
- interrupts = <0 0x13 0x0>,
- <0 0x13 0x1>,
- <0x0 0x13 0x2>;
-
- interrupt-names = "coarse-det-usb",
- "usbin-valid",
- "chg-gone";
};
pm8226_chg_boost: qcom,boost@1500 {
@@ -166,6 +154,21 @@
"limit-error";
};
+
+ pm8226_chg_otg: qcom,usb-chgpth@1300 {
+ status = "disabled";
+ reg = <0x1300 0x100>;
+ interrupts = <0 0x13 0x0>,
+ <0 0x13 0x1>,
+ <0x0 0x13 0x2>,
+ <0x0 0x13 0x3>;
+
+ interrupt-names = "coarse-det-usb",
+ "usbin-valid",
+ "chg-gone",
+ "usb-ocp";
+ };
+
qcom,chg-misc@1600 {
status = "disabled";
reg = <0x1600 0x100>;
@@ -198,6 +201,8 @@
qcom,hold-soc-est = <3>;
qcom,low-voltage-threshold = <3420000>;
qcom,bms-vadc = <&pm8226_vadc>;
+ qcom,bms-iadc = <&pm8226_iadc>;
+ qcom,bms-adc_tm = <&pm8226_adc_tm>;
qcom,bms-iadc@3800 {
reg = <0x3800 0x100>;
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index fad57a6..12af463 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -135,6 +135,8 @@
qcom,high-ocv-correction-limit-uv = <50>;
qcom,hold-soc-est = <3>;
qcom,bms-vadc = <&pm8941_vadc>;
+ qcom,bms-iadc = <&pm8941_iadc>;
+ qcom,bms-adc_tm = <&pm8941_adc_tm>;
qcom,bms-iadc@3800 {
reg = <0x3800 0x100>;
@@ -204,6 +206,7 @@
qcom,resume-soc = <99>;
qcom,tchg-mins = <150>;
qcom,chg-vadc = <&pm8941_vadc>;
+ qcom,chg-adc_tm = <&pm8941_adc_tm>;
qcom,chgr@1000 {
status = "disabled";
diff --git a/arch/arm/boot/dts/msm-pma8084.dtsi b/arch/arm/boot/dts/msm-pma8084.dtsi
index 3368b36..808f0f6 100644
--- a/arch/arm/boot/dts/msm-pma8084.dtsi
+++ b/arch/arm/boot/dts/msm-pma8084.dtsi
@@ -323,6 +323,7 @@
"low-thr-en-set";
qcom,adc-bit-resolution = <15>;
qcom,adc-vdd-reference = <1800>;
+ qcom,adc_tm-vadc = <&pma8084_vadc>;
};
qcom,rtc {
diff --git a/arch/arm/boot/dts/msm8226-cdp.dtsi b/arch/arm/boot/dts/msm8226-cdp.dtsi
index ef4b236..104cb4c 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-cdp.dtsi
@@ -416,10 +416,6 @@
};
};
-&usb_otg_sw {
- status = "okay";
-};
-
&pm8226_vadc {
chan@14 {
label = "pa_therm0";
diff --git a/arch/arm/boot/dts/msm8226-iommu-domains.dtsi b/arch/arm/boot/dts/msm8226-iommu-domains.dtsi
index 25fca2a..769e4df 100644
--- a/arch/arm/boot/dts/msm8226-iommu-domains.dtsi
+++ b/arch/arm/boot/dts/msm8226-iommu-domains.dtsi
@@ -24,7 +24,8 @@
venus_domain_cp: qcom,iommu-domain2 {
label = "venus_cp";
qcom,iommu-contexts = <&venus_cp>;
- qcom,virtual-addr-pool = <0x1000000 0x3f000000>;
+ qcom,virtual-addr-pool = <0x1000000 0x1f800000
+ 0x20800000 0x1f800000>;
qcom,secure-domain;
};
};
diff --git a/arch/arm/boot/dts/msm8226-mtp.dtsi b/arch/arm/boot/dts/msm8226-mtp.dtsi
index ce7f9e9..977c772 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-mtp.dtsi
@@ -127,7 +127,7 @@
interrupt-names = "core_irq", "async_irq", "pmic_id_irq";
qcom,hsusb-otg-mode = <3>;
- vbus_otg-supply = <&usb_otg_sw>;
+ vbus_otg-supply = <&pm8226_chg_otg>;
};
&sdcc1 {
@@ -452,10 +452,6 @@
qcom,charging-disabled;
};
-&usb_otg_sw {
- status = "okay";
-};
-
&slim_msm {
tapan_codec {
qcom,cdc-micbias1-ext-cap;
diff --git a/arch/arm/boot/dts/msm8226-qrd.dtsi b/arch/arm/boot/dts/msm8226-qrd.dtsi
index 10a2dce..a10b499 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-qrd.dtsi
@@ -442,3 +442,7 @@
qcom,fast-avg-setup = <0>;
};
};
+
+&android_usb {
+ qcom,android-usb-cdrom;
+};
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index d587b77..5b3da9b 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -482,14 +482,10 @@
regulator-name = "8226_smbbp_boost";
};
-&soc {
- usb_otg_sw: regulator-ncp380 {
- compatible = "regulator-fixed";
- regulator-name = "usb_otg_sw";
- gpio = <&msmgpio 67 0>;
- parent-supply = <&pm8226_chg_boost>;
- startup-delay-us = <4000>;
- enable-active-high;
- status = "disabled";
- };
+&pm8226_chg {
+ otg-parent-supply = <&pm8226_chg_boost>;
+};
+
+&pm8226_chg_otg {
+ regulator-name = "8226_smbbp_otg";
};
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index a5d511b..4b78238 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -182,11 +182,23 @@
<103000 134000>,
<268000 348000>,
<505000 657000>;
- qcom,iommu-groups = <&venus_domain_ns &venus_domain_cp>;
- qcom,iommu-group-buffer-types = <0xfff 0x1ff>;
qcom,buffer-type-tz-usage-table = <0x1 0x1>,
- <0x1fe 0x2>;
+ <0x2 0x2>,
+ <0x1f0 0x3>;
qcom,max-hw-load = <352800>; /* 720p @ 30 + 1080p @ 30 */
+ qcom,vidc-iommu-domains {
+ qcom,domain-ns {
+ qcom,vidc-domain-phandle = <&venus_domain_ns>;
+ qcom,vidc-partition-buffer-types = <0x1ff>,
+ <0x200>;
+ };
+
+ qcom,domain-cp {
+ qcom,vidc-domain-phandle = <&venus_domain_cp>;
+ qcom,vidc-partition-buffer-types = <0x2>,
+ <0x1f1>;
+ };
+ };
};
qcom,wfd {
@@ -275,10 +287,9 @@
<87 512 6000 6000>;
};
- android_usb@fe8050c8 {
+ android_usb: android_usb@fe8050c8 {
compatible = "qcom,android-usb";
reg = <0xfe8050c8 0xc8>;
- qcom,android-usb-cdrom;
qcom,android-usb-swfi-latency = <1>;
};
diff --git a/arch/arm/boot/dts/msm8610-cdp.dts b/arch/arm/boot/dts/msm8610-cdp.dts
index b0c0191..f3470c2 100644
--- a/arch/arm/boot/dts/msm8610-cdp.dts
+++ b/arch/arm/boot/dts/msm8610-cdp.dts
@@ -247,6 +247,8 @@
&sdhc_1 {
vdd-supply = <&pm8110_l17>;
+ qcom,vdd-always-on;
+ qcom,vdd-lpm-sup;
qcom,vdd-voltage-level = <2900000 2900000>;
qcom,vdd-current-level = <200 400000>;
diff --git a/arch/arm/boot/dts/msm8610-mtp.dts b/arch/arm/boot/dts/msm8610-mtp.dts
index 221ace4..0d4c174 100644
--- a/arch/arm/boot/dts/msm8610-mtp.dts
+++ b/arch/arm/boot/dts/msm8610-mtp.dts
@@ -285,6 +285,8 @@
&sdhc_1 {
vdd-supply = <&pm8110_l17>;
+ qcom,vdd-always-on;
+ qcom,vdd-lpm-sup;
qcom,vdd-voltage-level = <2900000 2900000>;
qcom,vdd-current-level = <200 400000>;
diff --git a/arch/arm/boot/dts/msm8610-qrd.dtsi b/arch/arm/boot/dts/msm8610-qrd.dtsi
index ea47d45..bd1705f 100644
--- a/arch/arm/boot/dts/msm8610-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8610-qrd.dtsi
@@ -237,6 +237,8 @@
&sdhc_1 {
vdd-supply = <&pm8110_l17>;
+ qcom,vdd-always-on;
+ qcom,vdd-lpm-sup;
qcom,vdd-voltage-level = <2900000 2900000>;
qcom,vdd-current-level = <200 400000>;
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index e6aa347..00d0d15 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -173,13 +173,17 @@
qcom,vidc@fdc00000 {
compatible = "qcom,msm-vidc";
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";
qcom,max-hw-load = <108000>; /* 720p @ 30 * 1 */
- };
+ qcom,vidc-iommu-domains {
+ qcom,domain-ns {
+ qcom,vidc-domain-phandle = <&q6_domain_ns>;
+ qcom,vidc-partition-buffer-types = <0xfff>;
+ };
+ };
+};
qcom,usbbam@f9a44000 {
compatible = "qcom,usb-bam-msm";
@@ -254,6 +258,8 @@
interrupt-names = "core_irq", "bam_irq";
vdd-supply = <&pm8110_l17>;
+ qcom,vdd-always-on;
+ qcom,vdd-lpm-sup;
qcom,vdd-voltage-level = <2900000 2900000>;
qcom,vdd-current-level = <9000 400000>;
diff --git a/arch/arm/boot/dts/msm8974-camera.dtsi b/arch/arm/boot/dts/msm8974-camera.dtsi
index 4be2b38..1413e0c 100644
--- a/arch/arm/boot/dts/msm8974-camera.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera.dtsi
@@ -94,12 +94,13 @@
qcom,ispif@fda0A000 {
cell-index = <0>;
- compatible = "qcom,ispif";
+ compatible = "qcom,ispif-v3.0", "qcom,ispif";
reg = <0xfda0A000 0x500>,
<0xfda00020 0x10>;
reg-names = "ispif", "csi_clk_mux";
interrupts = <0 55 0>;
interrupt-names = "ispif";
+ qcom,num-isps = <0x2>;
};
qcom,vfe@fda10000 {
diff --git a/arch/arm/boot/dts/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974-v2.dtsi
index 0b3b60f..9d5e50b 100644
--- a/arch/arm/boot/dts/msm8974-v2.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -136,12 +136,29 @@
<3240000 1600000>,
<4048000 1600000>,
<4264000 1600000>;
- qcom,iommu-groups = <&venus_domain_ns &venus_domain_sec_bitstream
- &venus_domain_sec_pixel &venus_domain_sec_non_pixel>;
- qcom,iommu-group-buffer-types = <0xfff 0x91 0x42 0x120>;
qcom,buffer-type-tz-usage-table = <0x91 0x1>,
<0x42 0x2>,
<0x120 0x3>;
+ qcom,vidc-iommu-domains {
+ qcom,domain-ns {
+ qcom,vidc-domain-phandle = <&venus_domain_ns>;
+ qcom,vidc-partition-buffer-types = <0x1ff>,
+ <0x200>;
+ };
+ qcom,domain-sec-bs {
+ qcom,vidc-domain-phandle = <&venus_domain_sec_bitstream>;
+ qcom,vidc-partition-buffer-types = <0x91>;
+ };
+ qcom,domain-sec-px {
+ qcom,vidc-domain-phandle = <&venus_domain_sec_pixel>;
+ qcom,vidc-partition-buffer-types = <0x42>;
+ };
+ qcom,domain-sec-np {
+ qcom,vidc-domain-phandle = <&venus_domain_sec_non_pixel>;
+ qcom,vidc-partition-buffer-types = <0x120>;
+ };
+ };
+
};
&krait_pdn {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 725cfaf..c8e3d96 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -897,6 +897,7 @@
qcom,vdd-voltage-level = <1 5 7>;
qcom,dwc-hsphy-init = <0x00D191A4>;
qcom,misc-ref = <&pm8941_misc>;
+ dwc_usb3-adc_tm = <&pm8941_adc_tm>;
qcom,msm-bus,name = "usb3";
qcom,msm-bus,num-cases = <2>;
diff --git a/arch/arm/boot/dts/msm8974pro-ac-mtp.dts b/arch/arm/boot/dts/msm8974pro-ac-mtp.dts
index b8df576..9ac9aaf 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-mtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ac-mtp.dts
@@ -27,3 +27,103 @@
&sdhc_1 {
qcom,clk-rates = <400000 20000000 25000000 50000000 100000000>;
};
+
+&pma8084_vadc {
+ chan@73 {
+ label = "msm_therm";
+ reg = <0x73>;
+ 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>;
+ };
+
+ chan@75 {
+ label = "pa_therm0";
+ reg = <0x75>;
+ 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>;
+ };
+
+ chan@77 {
+ label = "pa_therm1";
+ reg = <0x77>;
+ 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>;
+ };
+
+ chan@78 {
+ label = "quiet_therm";
+ reg = <0x78>;
+ 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>;
+ };
+};
+
+&pma8084_adc_tm {
+ chan@73 {
+ label = "msm_therm";
+ reg = <0x73>;
+ 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 = <0x48>;
+ qcom,thermal-node;
+ };
+
+ chan@75 {
+ label = "pa_therm0";
+ reg = <0x75>;
+ 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 = <0x68>;
+ qcom,thermal-node;
+ };
+
+ chan@77 {
+ label = "pa_therm1";
+ reg = <0x77>;
+ 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 = <0x70>;
+ qcom,thermal-node;
+ };
+
+ chan@78 {
+ label = "quiet_therm";
+ reg = <0x78>;
+ 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 = <0x78>;
+ qcom,thermal-node;
+ };
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
index 4d10ded..0989c34 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
@@ -21,14 +21,6 @@
};
/include/ "msm-pm8941.dtsi"
-&pma8084_vadc {
- status = "disabled";
-};
-
-&pma8084_adc_tm {
- status = "disabled";
-};
-
&pm8941_lsid0 {
qcom,power-on@800 {
status = "disabled";
diff --git a/arch/arm/boot/dts/msmsamarium.dtsi b/arch/arm/boot/dts/msmsamarium.dtsi
index 31ab623..20954f9 100644
--- a/arch/arm/boot/dts/msmsamarium.dtsi
+++ b/arch/arm/boot/dts/msmsamarium.dtsi
@@ -42,7 +42,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0xfd510000 0x4000>;
- ngpio = <145>;
+ ngpio = <146>;
interrupts = <0 208 0>;
qcom,direct-connect-irqs = <8>;
};
@@ -243,3 +243,5 @@
qcom,not-wakeup; /* Needed until MPM is fully configured. */
};
};
+
+/include/ "msm-pma8084.dtsi"
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index 72472f9..9296515 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -60,6 +60,18 @@
dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2.0-1-cdp.dtb
dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2.0-1-liquid.dtb
dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2.0-1-dragonboard.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2.2-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2.2-liquid.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2.2-dragonboard.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2.2-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2.2-fluid.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2.2-liquid.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2.2-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974pro-ab-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974pro-ab-fluid.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974pro-ab-liquid.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974pro-ab-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974pro-ac-mtp.dtb
# APQ8084
zreladdr-$(CONFIG_ARCH_APQ8084) := 0x00008000
@@ -85,6 +97,7 @@
# MSM8226
zreladdr-$(CONFIG_ARCH_MSM8226) := 0x00008000
dtb-$(CONFIG_ARCH_MSM8226) += msm8226-sim.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-fluid.dtb
dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-cdp.dtb
dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-mtp.dtb
dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-qrd-evt.dtb
@@ -120,6 +133,8 @@
# MSM8610
zreladdr-$(CONFIG_ARCH_MSM8610) := 0x00008000
+ dtb-$(CONFIG_ARCH_MSM8610) += msm8610-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8610) += msm8610-mtp.dtb
dtb-$(CONFIG_ARCH_MSM8610) += msm8610-rumi.dtb
dtb-$(CONFIG_ARCH_MSM8610) += msm8610-sim.dtb
dtb-$(CONFIG_ARCH_MSM8610) += msm8610-qrd-skuaa.dtb
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 21a940d..1460f94 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -233,6 +233,7 @@
#define UL_TIMEOUT_DELAY 1000 /* in ms */
#define ENABLE_DISCONNECT_ACK 0x1
#define SHUTDOWN_TIMEOUT_MS 500
+#define UL_WAKEUP_TIMEOUT_MS 2000
static void toggle_apps_ack(void);
static void reconnect_to_bam(void);
static void disconnect_to_bam(void);
@@ -1663,7 +1664,8 @@
if (wait_for_ack) {
BAM_DMUX_LOG("%s waiting for previous ack\n", __func__);
ret = wait_for_completion_timeout(
- &ul_wakeup_ack_completion, HZ);
+ &ul_wakeup_ack_completion,
+ msecs_to_jiffies(UL_WAKEUP_TIMEOUT_MS));
wait_for_ack = 0;
if (unlikely(ret == 0) && ssrestart_check()) {
mutex_unlock(&wakeup_lock);
@@ -1674,14 +1676,16 @@
INIT_COMPLETION(ul_wakeup_ack_completion);
power_vote(1);
BAM_DMUX_LOG("%s waiting for wakeup ack\n", __func__);
- ret = wait_for_completion_timeout(&ul_wakeup_ack_completion, HZ);
+ ret = wait_for_completion_timeout(&ul_wakeup_ack_completion,
+ msecs_to_jiffies(UL_WAKEUP_TIMEOUT_MS));
if (unlikely(ret == 0) && ssrestart_check()) {
mutex_unlock(&wakeup_lock);
BAM_DMUX_LOG("%s timeout wakeup ack\n", __func__);
return;
}
BAM_DMUX_LOG("%s waiting completion\n", __func__);
- ret = wait_for_completion_timeout(&bam_connection_completion, HZ);
+ ret = wait_for_completion_timeout(&bam_connection_completion,
+ msecs_to_jiffies(UL_WAKEUP_TIMEOUT_MS));
if (unlikely(ret == 0) && ssrestart_check()) {
mutex_unlock(&wakeup_lock);
BAM_DMUX_LOG("%s timeout power on\n", __func__);
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index a93cfe5..a29bb88 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -630,16 +630,27 @@
static struct rpm_regulator_init_data *rpm_data;
int i;
- if (machine_is_msm8960_cdp()) {
+ if (machine_is_msm8960_cdp() || cpu_is_msm8960ab()) {
/* Only modify LVS6 consumers for CDP targets. */
for (i = 0; i < ARRAY_SIZE(msm_rpm_regulator_init_data); i++) {
rpm_data = &msm_rpm_regulator_init_data[i];
- if (rpm_data->id == RPM_VREG_ID_PM8921_LVS6) {
+ if (machine_is_msm8960_cdp() &&
+ rpm_data->id == RPM_VREG_ID_PM8921_LVS6) {
rpm_data->init_data.consumer_supplies
= vreg_consumers_CDP_LVS6;
rpm_data->init_data.num_consumer_supplies
= ARRAY_SIZE(vreg_consumers_CDP_LVS6);
}
+ if (cpu_is_msm8960ab() &&
+ rpm_data->id == RPM_VREG_ID_PM8921_S7) {
+ rpm_data->init_data.constraints.min_uV =
+ 1275000;
+ rpm_data->init_data.constraints.max_uV =
+ 1275000;
+ rpm_data->init_data.constraints.input_uV =
+ 1275000;
+ rpm_data->default_uV = 1275000;
+ }
}
}
}
diff --git a/arch/arm/mach-msm/clock-8092.c b/arch/arm/mach-msm/clock-8092.c
index ec7a4b0..802cd1b 100644
--- a/arch/arm/mach-msm/clock-8092.c
+++ b/arch/arm/mach-msm/clock-8092.c
@@ -304,6 +304,9 @@
CLK_DUMMY("core_clk", NULL, "fdc84000.qcom,iommu", OFF),
CLK_DUMMY("iface_clk", NULL, "fdee4000.qcom,iommu", OFF),
CLK_DUMMY("core_clk", NULL, "fdee4000.qcom,iommu", OFF),
+ CLK_DUMMY("iface_clk", NULL, "fdfb6000.qcom,iommu", OFF),
+ CLK_DUMMY("core_clk", NULL, "fdfb6000.qcom,iommu", OFF),
+ CLK_DUMMY("alt_core_clk", NULL, "fdfb6000.qcom,iommu", OFF),
/* BCSS broadcast */
CLK_DUMMY("", bcc_dem_core_b_clk_src.c, "", OFF),
CLK_DUMMY("", adc_01_clk_src.c, "", OFF),
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index cf6c23f..383af54 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -3251,6 +3251,7 @@
CLK_LOOKUP("xo", cxo_otg_clk.c, "f9a55000.usb"),
CLK_LOOKUP("iface_clk", gcc_usb_hs_ahb_clk.c, "f9a55000.usb"),
CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c, "f9a55000.usb"),
+ CLK_LOOKUP("sleep_clk", gcc_usb2a_phy_sleep_clk.c, "f9a55000.usb"),
/* SPS CLOCKS */
CLK_LOOKUP("dfab_clk", pnoc_sps_clk.c, "f9984000.qcom,sps"),
@@ -3309,10 +3310,6 @@
CLK_LOOKUP("iface_clk", gcc_sdcc3_ahb_clk.c, "msm_sdcc.3"),
CLK_LOOKUP("core_clk", gcc_sdcc3_apps_clk.c, "msm_sdcc.3"),
- CLK_LOOKUP("sleep_a_clk", gcc_usb2a_phy_sleep_clk.c, "msm_dwc3"),
- CLK_LOOKUP("ref_clk", diff_clk.c, "msm_dwc3"),
-
-
CLK_LOOKUP("bus_clk", pnoc_clk.c, ""),
CLK_LOOKUP("bus_clk", pnoc_a_clk.c, ""),
CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index b1b9397..4fb3f43 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -2749,7 +2749,7 @@
};
static struct clk_lookup msm_clocks_8610[] = {
- CLK_LOOKUP("xo", cxo_otg_clk.c, "msm_otg"),
+ CLK_LOOKUP("xo", cxo_otg_clk.c, "f9a55000.usb"),
CLK_LOOKUP("xo", cxo_lpass_pil_clk.c, "fe200000.qcom,lpass"),
CLK_LOOKUP("xo", cxo_lpm_clk.c, "fc4281d0.qcom,mpm"),
@@ -2924,7 +2924,7 @@
CLK_LOOKUP("core_clk", gcc_sdcc1_apps_clk.c, "msm_sdcc.1"),
CLK_LOOKUP("iface_clk", gcc_sdcc2_ahb_clk.c, "msm_sdcc.2"),
CLK_LOOKUP("core_clk", gcc_sdcc2_apps_clk.c, "msm_sdcc.2"),
- CLK_LOOKUP("core_clk", gcc_usb2a_phy_sleep_clk.c, ""),
+ CLK_LOOKUP("sleep_clk", gcc_usb2a_phy_sleep_clk.c, "f9a55000.usb"),
CLK_LOOKUP("iface_clk", gcc_usb_hs_ahb_clk.c, "f9a55000.usb"),
CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c, "f9a55000.usb"),
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index a8cb46e..cd6d582 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -718,17 +718,38 @@
DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a1_pin, cxo_a1_a_pin, A1_ID);
DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a2_pin, cxo_a2_a_pin, A2_ID);
+static unsigned int soft_vote_gpll0;
+
+static struct pll_vote_clk gpll0_ao_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,
+ .soft_vote_mask = PLL_SOFT_VOTE_ACPU,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &cxo_a_clk_src.c,
+ .rate = 600000000,
+ .dbg_name = "gpll0_ao_clk_src",
+ .ops = &clk_ops_pll_acpu_vote,
+ CLK_INIT(gpll0_ao_clk_src.c),
+ },
+};
+
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,
+ .soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
.base = &virt_bases[GCC_BASE],
.c = {
.parent = &cxo_clk_src.c,
.rate = 600000000,
.dbg_name = "gpll0_clk_src",
- .ops = &clk_ops_pll_vote,
+ .ops = &clk_ops_pll_acpu_vote,
CLK_INIT(gpll0_clk_src.c),
},
};
@@ -4895,6 +4916,9 @@
CLK_LOOKUP("measure", measure_clk.c, "debug"),
+ CLK_LOOKUP("gpll0", gpll0_clk_src.c, ""),
+ CLK_LOOKUP("gpll0_ao", gpll0_ao_clk_src.c, ""),
+
CLK_LOOKUP("dma_bam_pclk", gcc_bam_dma_ahb_clk.c, "msm_sps"),
CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f991f000.serial"),
CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9924000.i2c"),
@@ -5173,6 +5197,25 @@
CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
"fda0a000.qcom,ispif"),
+ CLK_LOOKUP("vfe0_clk_src", vfe0_clk_src.c, "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("camss_vfe_vfe0_clk", camss_vfe_vfe0_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("camss_csi_vfe0_clk", camss_csi_vfe0_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("vfe1_clk_src", vfe1_clk_src.c, "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("camss_vfe_vfe1_clk", camss_vfe_vfe1_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("camss_csi_vfe1_clk", camss_csi_vfe1_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("csi0_src_clk", csi0_clk_src.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("csi0_clk", camss_csi0_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("csi0_pix_clk", camss_csi0pix_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("csi0_rdi_clk", camss_csi0rdi_clk.c,
+ "fda0a000.qcom,ispif"),
+
/*VFE clocks*/
CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
"fda10000.qcom,vfe"),
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index c0cca1d..64986d0 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -1013,6 +1013,7 @@
return -EINVAL;
}
+ memset(&ctl, 0, sizeof(ctl));
ctl.cmd = IPC_ROUTER_CTRL_CMD_NEW_SERVER;
for (i = 0; i < SRV_HASH_SIZE; i++) {
@@ -1241,6 +1242,7 @@
mode = mode_info->mode;
xprt_info = mode_info->xprt_info;
+ memset(&msg, 0, sizeof(msg));
msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT;
msg.cli.node_id = node_id;
msg.cli.port_id = port_id;
@@ -1295,6 +1297,7 @@
D("Remove server %08x:%08x - %08x:%08x",
server->name.service, server->name.instance,
rport_ptr->node_id, rport_ptr->port_id);
+ memset(&ctl, 0, sizeof(ctl));
ctl.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_SERVER;
ctl.srv.service = server->name.service;
ctl.srv.instance = server->name.instance;
@@ -1313,6 +1316,7 @@
union rr_control_msg ctl;
int j;
+ memset(&ctl, 0, sizeof(ctl));
for (j = 0; j < RP_HASH_SIZE; j++) {
list_for_each_entry_safe(rport_ptr, tmp_rport_ptr,
&rt_entry->remote_port_list[j], list) {
@@ -1847,7 +1851,7 @@
process_done:
if (resume_tx) {
union rr_control_msg msg;
-
+ memset(&msg, 0, sizeof(msg));
msg.cmd = IPC_ROUTER_CTRL_CMD_RESUME_TX;
msg.cli.node_id = resume_tx_node_id;
msg.cli.port_id = resume_tx_port_id;
@@ -1900,6 +1904,7 @@
return -EINVAL;
}
+ memset(&ctl, 0, sizeof(ctl));
ctl.cmd = IPC_ROUTER_CTRL_CMD_NEW_SERVER;
ctl.srv.service = server->name.service;
ctl.srv.instance = server->name.instance;
@@ -1948,6 +1953,7 @@
return -ENODEV;
}
+ memset(&ctl, 0, sizeof(ctl));
ctl.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_SERVER;
ctl.srv.service = server->name.service;
ctl.srv.instance = server->name.instance;
@@ -2433,6 +2439,7 @@
up_write(&local_ports_lock_lha2);
if (port_ptr->type == SERVER_PORT) {
+ memset(&msg, 0, sizeof(msg));
msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_SERVER;
msg.srv.service = port_ptr->port_name.service;
msg.srv.instance = port_ptr->port_name.instance;
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index 8a3ecb1..94281b1 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.c
@@ -573,7 +573,8 @@
{
int clk_ready = 0;
- if (of_find_property(desc->dev->of_node,
+ if (desc->ops->proxy_unvote &&
+ of_find_property(desc->dev->of_node,
"qcom,gpio-proxy-unvote",
NULL)) {
clk_ready = of_get_named_gpio(desc->dev->of_node,
@@ -780,7 +781,7 @@
"Invalid proxy unvote callback or a proxy timeout of 0"
" was specified or no proxy unvote IRQ was specified.\n");
- if (desc->proxy_unvote_irq > 0 && desc->ops->proxy_unvote) {
+ if (desc->proxy_unvote_irq) {
ret = request_threaded_irq(desc->proxy_unvote_irq,
NULL,
proxy_unvote_intr_handler,
diff --git a/block/row-iosched.c b/block/row-iosched.c
index 8e19c94..dfb46b4 100644
--- a/block/row-iosched.c
+++ b/block/row-iosched.c
@@ -396,7 +396,6 @@
"added urgent request (total on queue=%d)",
rqueue->nr_req);
rq->cmd_flags |= REQ_URGENT;
- WARN_ON(rqueue->nr_req > 1);
rd->pending_urgent_rq = rq;
}
} else
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index 606d8dd..8e6afc1 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -134,27 +134,28 @@
u8 revision;
};
-struct qpnp_iadc_drv {
+struct qpnp_iadc_chip {
struct qpnp_adc_drv *adc;
int32_t rsense;
bool external_rsense;
struct device *iadc_hwmon;
- bool iadc_initialized;
+ struct list_head list;
int64_t die_temp;
struct delayed_work iadc_work;
struct mutex iadc_vadc_lock;
bool iadc_mode_sel;
struct qpnp_iadc_comp iadc_comp;
struct qpnp_vadc_chip *vadc_dev;
+ struct work_struct trigger_completion_work;
struct sensor_device_attribute sens_attr[0];
bool skip_auto_calibrations;
};
-static struct qpnp_iadc_drv *qpnp_iadc;
+LIST_HEAD(qpnp_iadc_device_list);
-static int32_t qpnp_iadc_read_reg(uint32_t reg, u8 *data)
+static int32_t qpnp_iadc_read_reg(struct qpnp_iadc_chip *iadc,
+ uint32_t reg, u8 *data)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
int rc;
rc = spmi_ext_register_readl(iadc->adc->spmi->ctrl, iadc->adc->slave,
@@ -167,9 +168,9 @@
return 0;
}
-static int32_t qpnp_iadc_write_reg(uint32_t reg, u8 data)
+static int32_t qpnp_iadc_write_reg(struct qpnp_iadc_chip *iadc,
+ uint32_t reg, u8 data)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
int rc;
u8 *buf;
@@ -184,41 +185,54 @@
return 0;
}
-static void trigger_iadc_completion(struct work_struct *work)
+static int qpnp_iadc_is_valid(struct qpnp_iadc_chip *iadc)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
+ struct qpnp_iadc_chip *iadc_chip = NULL;
- if (!iadc || !iadc->iadc_initialized)
+ list_for_each_entry(iadc_chip, &qpnp_iadc_device_list, list)
+ if (iadc == iadc_chip)
+ return 0;
+
+ return -EINVAL;
+}
+
+static void qpnp_iadc_trigger_completion(struct work_struct *work)
+{
+ struct qpnp_iadc_chip *iadc = container_of(work,
+ struct qpnp_iadc_chip, trigger_completion_work);
+
+ if (qpnp_iadc_is_valid(iadc) < 0)
return;
complete(&iadc->adc->adc_rslt_completion);
return;
}
-DECLARE_WORK(trigger_iadc_completion_work, trigger_iadc_completion);
static irqreturn_t qpnp_iadc_isr(int irq, void *dev_id)
{
- schedule_work(&trigger_iadc_completion_work);
+ struct qpnp_iadc_chip *iadc = dev_id;
+
+ schedule_work(&iadc->trigger_completion_work);
return IRQ_HANDLED;
}
-static int32_t qpnp_iadc_enable(bool state)
+static int32_t qpnp_iadc_enable(struct qpnp_iadc_chip *dev, bool state)
{
int rc = 0;
u8 data = 0;
data = QPNP_IADC_ADC_EN;
if (state) {
- rc = qpnp_iadc_write_reg(QPNP_IADC_EN_CTL1,
+ rc = qpnp_iadc_write_reg(dev, QPNP_IADC_EN_CTL1,
data);
if (rc < 0) {
pr_err("IADC enable failed\n");
return rc;
}
} else {
- rc = qpnp_iadc_write_reg(QPNP_IADC_EN_CTL1,
+ rc = qpnp_iadc_write_reg(dev, QPNP_IADC_EN_CTL1,
(~data & QPNP_IADC_ADC_EN));
if (rc < 0) {
pr_err("IADC disable failed\n");
@@ -229,36 +243,36 @@
return 0;
}
-static int32_t qpnp_iadc_status_debug(void)
+static int32_t qpnp_iadc_status_debug(struct qpnp_iadc_chip *dev)
{
int rc = 0;
u8 mode = 0, status1 = 0, chan = 0, dig = 0, en = 0;
- rc = qpnp_iadc_read_reg(QPNP_IADC_MODE_CTL, &mode);
+ rc = qpnp_iadc_read_reg(dev, QPNP_IADC_MODE_CTL, &mode);
if (rc < 0) {
pr_err("mode ctl register read failed with %d\n", rc);
return rc;
}
- rc = qpnp_iadc_read_reg(QPNP_ADC_DIG_PARAM, &dig);
+ rc = qpnp_iadc_read_reg(dev, QPNP_ADC_DIG_PARAM, &dig);
if (rc < 0) {
pr_err("digital param read failed with %d\n", rc);
return rc;
}
- rc = qpnp_iadc_read_reg(QPNP_IADC_ADC_CH_SEL_CTL, &chan);
+ rc = qpnp_iadc_read_reg(dev, QPNP_IADC_ADC_CH_SEL_CTL, &chan);
if (rc < 0) {
pr_err("channel read failed with %d\n", rc);
return rc;
}
- rc = qpnp_iadc_read_reg(QPNP_STATUS1, &status1);
+ rc = qpnp_iadc_read_reg(dev, QPNP_STATUS1, &status1);
if (rc < 0) {
pr_err("status1 read failed with %d\n", rc);
return rc;
}
- rc = qpnp_iadc_read_reg(QPNP_IADC_EN_CTL1, &en);
+ rc = qpnp_iadc_read_reg(dev, QPNP_IADC_EN_CTL1, &en);
if (rc < 0) {
pr_err("en read failed with %d\n", rc);
return rc;
@@ -267,7 +281,7 @@
pr_debug("EOC not set with status:%x, dig:%x, ch:%x, mode:%x, en:%x\n",
status1, dig, chan, mode, en);
- rc = qpnp_iadc_enable(false);
+ rc = qpnp_iadc_enable(dev, false);
if (rc < 0) {
pr_err("IADC disable failed with %d\n", rc);
return rc;
@@ -276,19 +290,20 @@
return 0;
}
-static int32_t qpnp_iadc_read_conversion_result(uint16_t *data)
+static int32_t qpnp_iadc_read_conversion_result(struct qpnp_iadc_chip *iadc,
+ int16_t *data)
{
uint8_t rslt_lsb, rslt_msb;
uint16_t rslt;
int32_t rc;
- rc = qpnp_iadc_read_reg(QPNP_IADC_DATA0, &rslt_lsb);
+ rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_DATA0, &rslt_lsb);
if (rc < 0) {
pr_err("qpnp adc result read failed with %d\n", rc);
return rc;
}
- rc = qpnp_iadc_read_reg(QPNP_IADC_DATA1, &rslt_msb);
+ rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_DATA1, &rslt_msb);
if (rc < 0) {
pr_err("qpnp adc result read failed with %d\n", rc);
return rc;
@@ -297,7 +312,7 @@
rslt = (rslt_msb << 8) | rslt_lsb;
*data = rslt;
- rc = qpnp_iadc_enable(false);
+ rc = qpnp_iadc_enable(iadc, false);
if (rc)
return rc;
@@ -364,32 +379,30 @@
return 0;
}
-int32_t qpnp_iadc_comp_result(int64_t *result)
+int32_t qpnp_iadc_comp_result(struct qpnp_iadc_chip *iadc, int64_t *result)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
-
return qpnp_iadc_comp(result, iadc->iadc_comp, iadc->die_temp);
}
EXPORT_SYMBOL(qpnp_iadc_comp_result);
-static int32_t qpnp_iadc_comp_info(void)
+static int32_t qpnp_iadc_comp_info(struct qpnp_iadc_chip *iadc)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
int rc = 0;
- rc = qpnp_iadc_read_reg(QPNP_INT_TEST_VAL, &iadc->iadc_comp.id);
+ rc = qpnp_iadc_read_reg(iadc, QPNP_INT_TEST_VAL, &iadc->iadc_comp.id);
if (rc < 0) {
pr_err("qpnp adc comp id failed with %d\n", rc);
return rc;
}
- rc = qpnp_iadc_read_reg(QPNP_IADC_REVISION2, &iadc->iadc_comp.revision);
+ rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_REVISION2,
+ &iadc->iadc_comp.revision);
if (rc < 0) {
pr_err("qpnp adc revision read failed with %d\n", rc);
return rc;
}
- rc = qpnp_iadc_read_reg(QPNP_IADC_ATE_GAIN_CALIB_OFFSET,
+ rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_ATE_GAIN_CALIB_OFFSET,
&iadc->iadc_comp.sys_gain);
if (rc < 0) {
pr_err("full scale read failed with %d\n", rc);
@@ -407,10 +420,10 @@
return rc;
}
-static int32_t qpnp_iadc_configure(enum qpnp_iadc_channels channel,
+static int32_t qpnp_iadc_configure(struct qpnp_iadc_chip *iadc,
+ enum qpnp_iadc_channels channel,
uint16_t *raw_code, uint32_t mode_sel)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
u8 qpnp_iadc_mode_reg = 0, qpnp_iadc_ch_sel_reg = 0;
u8 qpnp_iadc_conv_req = 0, qpnp_iadc_dig_param_reg = 0;
int32_t rc = 0;
@@ -426,34 +439,34 @@
qpnp_iadc_conv_req = QPNP_IADC_CONV_REQ;
- rc = qpnp_iadc_write_reg(QPNP_IADC_MODE_CTL, qpnp_iadc_mode_reg);
+ rc = qpnp_iadc_write_reg(iadc, QPNP_IADC_MODE_CTL, qpnp_iadc_mode_reg);
if (rc) {
pr_err("qpnp adc read adc failed with %d\n", rc);
return rc;
}
- rc = qpnp_iadc_write_reg(QPNP_IADC_ADC_CH_SEL_CTL,
+ rc = qpnp_iadc_write_reg(iadc, QPNP_IADC_ADC_CH_SEL_CTL,
qpnp_iadc_ch_sel_reg);
if (rc) {
pr_err("qpnp adc read adc failed with %d\n", rc);
return rc;
}
- rc = qpnp_iadc_write_reg(QPNP_ADC_DIG_PARAM,
+ rc = qpnp_iadc_write_reg(iadc, QPNP_ADC_DIG_PARAM,
qpnp_iadc_dig_param_reg);
if (rc) {
pr_err("qpnp adc read adc failed with %d\n", rc);
return rc;
}
- rc = qpnp_iadc_write_reg(QPNP_HW_SETTLE_DELAY,
+ rc = qpnp_iadc_write_reg(iadc, QPNP_HW_SETTLE_DELAY,
iadc->adc->amux_prop->hw_settle_time);
if (rc < 0) {
pr_err("qpnp adc configure error for hw settling time setup\n");
return rc;
}
- rc = qpnp_iadc_write_reg(QPNP_FAST_AVG_CTL,
+ rc = qpnp_iadc_write_reg(iadc, QPNP_FAST_AVG_CTL,
iadc->adc->amux_prop->fast_avg_setup);
if (rc < 0) {
pr_err("qpnp adc fast averaging configure error\n");
@@ -462,11 +475,11 @@
INIT_COMPLETION(iadc->adc->adc_rslt_completion);
- rc = qpnp_iadc_enable(true);
+ rc = qpnp_iadc_enable(iadc, true);
if (rc)
return rc;
- rc = qpnp_iadc_write_reg(QPNP_CONV_REQ, qpnp_iadc_conv_req);
+ rc = qpnp_iadc_write_reg(iadc, QPNP_CONV_REQ, qpnp_iadc_conv_req);
if (rc) {
pr_err("qpnp adc read adc failed with %d\n", rc);
return rc;
@@ -476,14 +489,14 @@
QPNP_ADC_COMPLETION_TIMEOUT);
if (!rc) {
u8 status1 = 0;
- rc = qpnp_iadc_read_reg(QPNP_STATUS1, &status1);
+ rc = qpnp_iadc_read_reg(iadc, QPNP_STATUS1, &status1);
if (rc < 0)
return rc;
status1 &= (QPNP_STATUS1_REQ_STS | QPNP_STATUS1_EOC);
if (status1 == QPNP_STATUS1_EOC)
pr_debug("End of conversion status set\n");
else {
- rc = qpnp_iadc_status_debug();
+ rc = qpnp_iadc_status_debug(iadc);
if (rc < 0) {
pr_err("status1 read failed with %d\n", rc);
return rc;
@@ -492,7 +505,7 @@
}
}
- rc = qpnp_iadc_read_conversion_result(raw_code);
+ rc = qpnp_iadc_read_conversion_result(iadc, raw_code);
if (rc) {
pr_err("qpnp adc read adc failed with %d\n", rc);
return rc;
@@ -504,9 +517,8 @@
#define IADC_CENTER 0xC000
#define IADC_READING_RESOLUTION_N 542535
#define IADC_READING_RESOLUTION_D 100000
-static int32_t qpnp_convert_raw_offset_voltage(void)
+static int32_t qpnp_convert_raw_offset_voltage(struct qpnp_iadc_chip *iadc)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
s64 numerator;
if ((iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw) == 0) {
@@ -531,20 +543,20 @@
return 0;
}
-int32_t qpnp_iadc_calibrate_for_trim(bool batfet_closed)
+int32_t qpnp_iadc_calibrate_for_trim(struct qpnp_iadc_chip *iadc,
+ bool batfet_closed)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
uint8_t rslt_lsb, rslt_msb;
int32_t rc = 0;
uint16_t raw_data;
uint32_t mode_sel = 0;
- if (!iadc || !iadc->iadc_initialized)
+ if (qpnp_iadc_is_valid(iadc) < 0)
return -EPROBE_DEFER;
mutex_lock(&iadc->adc->adc_lock);
- rc = qpnp_iadc_configure(GAIN_CALIBRATION_17P857MV,
+ rc = qpnp_iadc_configure(iadc, GAIN_CALIBRATION_17P857MV,
&raw_data, mode_sel);
if (rc < 0) {
pr_err("qpnp adc result read failed with %d\n", rc);
@@ -562,7 +574,7 @@
*/
if (!batfet_closed || iadc->external_rsense) {
/* external offset calculation */
- rc = qpnp_iadc_configure(OFFSET_CALIBRATION_CSP_CSN,
+ rc = qpnp_iadc_configure(iadc, OFFSET_CALIBRATION_CSP_CSN,
&raw_data, mode_sel);
if (rc < 0) {
pr_err("qpnp adc result read failed with %d\n", rc);
@@ -570,7 +582,7 @@
}
} else {
/* internal offset calculation */
- rc = qpnp_iadc_configure(OFFSET_CALIBRATION_CSP2_CSN2,
+ rc = qpnp_iadc_configure(iadc, OFFSET_CALIBRATION_CSP2_CSN2,
&raw_data, mode_sel);
if (rc < 0) {
pr_err("qpnp adc result read failed with %d\n", rc);
@@ -587,7 +599,7 @@
pr_debug("raw gain:0x%x, raw offset:0x%x\n",
iadc->adc->calib.gain_raw, iadc->adc->calib.offset_raw);
- rc = qpnp_convert_raw_offset_voltage();
+ rc = qpnp_convert_raw_offset_voltage(iadc);
if (rc < 0) {
pr_err("qpnp raw_voltage conversion failed\n");
goto fail;
@@ -599,28 +611,28 @@
pr_debug("trim values:lsb:0x%x and msb:0x%x\n", rslt_lsb, rslt_msb);
- rc = qpnp_iadc_write_reg(QPNP_IADC_SEC_ACCESS,
+ rc = qpnp_iadc_write_reg(iadc, QPNP_IADC_SEC_ACCESS,
QPNP_IADC_SEC_ACCESS_DATA);
if (rc < 0) {
pr_err("qpnp iadc configure error for sec access\n");
goto fail;
}
- rc = qpnp_iadc_write_reg(QPNP_IADC_MSB_OFFSET,
+ rc = qpnp_iadc_write_reg(iadc, QPNP_IADC_MSB_OFFSET,
rslt_msb);
if (rc < 0) {
pr_err("qpnp iadc configure error for MSB write\n");
goto fail;
}
- rc = qpnp_iadc_write_reg(QPNP_IADC_SEC_ACCESS,
+ rc = qpnp_iadc_write_reg(iadc, QPNP_IADC_SEC_ACCESS,
QPNP_IADC_SEC_ACCESS_DATA);
if (rc < 0) {
pr_err("qpnp iadc configure error for sec access\n");
goto fail;
}
- rc = qpnp_iadc_write_reg(QPNP_IADC_LSB_OFFSET,
+ rc = qpnp_iadc_write_reg(iadc, QPNP_IADC_LSB_OFFSET,
rslt_lsb);
if (rc < 0) {
pr_err("qpnp iadc configure error for LSB write\n");
@@ -634,11 +646,12 @@
static void qpnp_iadc_work(struct work_struct *work)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
+ struct qpnp_iadc_chip *iadc = container_of(work,
+ struct qpnp_iadc_chip, iadc_work.work);
int rc = 0;
if (!iadc->skip_auto_calibrations) {
- rc = qpnp_iadc_calibrate_for_trim(true);
+ rc = qpnp_iadc_calibrate_for_trim(iadc, true);
if (rc)
pr_debug("periodic IADC calibration failed\n");
}
@@ -649,12 +662,12 @@
return;
}
-static int32_t qpnp_iadc_version_check(void)
+static int32_t qpnp_iadc_version_check(struct qpnp_iadc_chip *iadc)
{
uint8_t revision;
int rc;
- rc = qpnp_iadc_read_reg(QPNP_IADC_REVISION2, &revision);
+ rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_REVISION2, &revision);
if (rc < 0) {
pr_err("qpnp adc result read failed with %d\n", rc);
return rc;
@@ -668,24 +681,31 @@
return 0;
}
-int32_t qpnp_iadc_is_ready(void)
+struct qpnp_iadc_chip *qpnp_get_iadc(struct device *dev, const char *name)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
+ struct qpnp_iadc_chip *iadc;
+ struct device_node *node = NULL;
+ char prop_name[QPNP_MAX_PROP_NAME_LEN];
- if (!iadc || !iadc->iadc_initialized)
- return -EPROBE_DEFER;
- else
- return 0;
+ snprintf(prop_name, QPNP_MAX_PROP_NAME_LEN, "qcom,%s-iadc", name);
+
+ node = of_parse_phandle(dev->of_node, prop_name, 0);
+ if (node == NULL)
+ return ERR_PTR(-ENODEV);
+
+ list_for_each_entry(iadc, &qpnp_iadc_device_list, list)
+ if (iadc->adc->spmi->dev.of_node == node)
+ return iadc;
+ return ERR_PTR(-EPROBE_DEFER);
}
-EXPORT_SYMBOL(qpnp_iadc_is_ready);
+EXPORT_SYMBOL(qpnp_get_iadc);
-int32_t qpnp_iadc_get_rsense(int32_t *rsense)
+int32_t qpnp_iadc_get_rsense(struct qpnp_iadc_chip *iadc, int32_t *rsense)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
uint8_t rslt_rsense;
int32_t rc = 0, sign_bit = 0;
- if (!iadc || !iadc->iadc_initialized)
+ if (qpnp_iadc_is_valid(iadc) < 0)
return -EPROBE_DEFER;
if (iadc->external_rsense) {
@@ -693,7 +713,7 @@
return rc;
}
- rc = qpnp_iadc_read_reg(QPNP_IADC_NOMINAL_RSENSE, &rslt_rsense);
+ rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_NOMINAL_RSENSE, &rslt_rsense);
if (rc < 0) {
pr_err("qpnp adc rsense read failed with %d\n", rc);
return rc;
@@ -717,9 +737,8 @@
}
EXPORT_SYMBOL(qpnp_iadc_get_rsense);
-static int32_t qpnp_check_pmic_temp(void)
+static int32_t qpnp_check_pmic_temp(struct qpnp_iadc_chip *iadc)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
struct qpnp_vadc_result result_pmic_therm;
int64_t die_temp_offset;
int rc = 0;
@@ -736,7 +755,7 @@
if (die_temp_offset > QPNP_IADC_DIE_TEMP_CALIB_OFFSET) {
iadc->die_temp = result_pmic_therm.physical;
if (!iadc->skip_auto_calibrations) {
- rc = qpnp_iadc_calibrate_for_trim(true);
+ rc = qpnp_iadc_calibrate_for_trim(iadc, true);
if (rc)
pr_err("IADC calibration failed rc = %d\n", rc);
}
@@ -745,20 +764,20 @@
return rc;
}
-int32_t qpnp_iadc_read(enum qpnp_iadc_channels channel,
+int32_t qpnp_iadc_read(struct qpnp_iadc_chip *iadc,
+ enum qpnp_iadc_channels channel,
struct qpnp_iadc_result *result)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
int32_t rc, rsense_n_ohms, sign = 0, num, mode_sel = 0;
int32_t rsense_u_ohms = 0;
int64_t result_current;
uint16_t raw_data;
- if (!iadc || !iadc->iadc_initialized)
+ if (qpnp_iadc_is_valid(iadc) < 0)
return -EPROBE_DEFER;
if (!iadc->iadc_mode_sel) {
- rc = qpnp_check_pmic_temp();
+ rc = qpnp_check_pmic_temp(iadc);
if (rc) {
pr_err("Error checking pmic therm temp\n");
return rc;
@@ -767,13 +786,13 @@
mutex_lock(&iadc->adc->adc_lock);
- rc = qpnp_iadc_configure(channel, &raw_data, mode_sel);
+ rc = qpnp_iadc_configure(iadc, channel, &raw_data, mode_sel);
if (rc < 0) {
pr_err("qpnp adc result read failed with %d\n", rc);
goto fail;
}
- rc = qpnp_iadc_get_rsense(&rsense_n_ohms);
+ rc = qpnp_iadc_get_rsense(iadc, &rsense_n_ohms);
pr_debug("current raw:0%x and rsense:%d\n",
raw_data, rsense_n_ohms);
rsense_u_ohms = rsense_n_ohms/1000;
@@ -794,7 +813,7 @@
result->result_uv = -result->result_uv;
result_current = -result_current;
}
- rc = qpnp_iadc_comp_result(&result_current);
+ rc = qpnp_iadc_comp_result(iadc, &result_current);
if (rc < 0)
pr_err("Error during compensating the IADC\n");
rc = 0;
@@ -807,15 +826,15 @@
}
EXPORT_SYMBOL(qpnp_iadc_read);
-int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_calib *result)
+int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_chip *iadc,
+ struct qpnp_iadc_calib *result)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
int rc;
- if (!iadc || !iadc->iadc_initialized)
+ if (qpnp_iadc_is_valid(iadc) < 0)
return -EPROBE_DEFER;
- rc = qpnp_check_pmic_temp();
+ rc = qpnp_check_pmic_temp(iadc);
if (rc) {
pr_err("Error checking pmic therm temp\n");
return rc;
@@ -839,43 +858,32 @@
}
EXPORT_SYMBOL(qpnp_iadc_get_gain_and_offset);
-int qpnp_iadc_skip_calibration(void)
+int qpnp_iadc_skip_calibration(struct qpnp_iadc_chip *iadc)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
-
- if (!iadc || !iadc->iadc_initialized)
- return -EPROBE_DEFER;
-
iadc->skip_auto_calibrations = true;
return 0;
}
EXPORT_SYMBOL(qpnp_iadc_skip_calibration);
-int qpnp_iadc_resume_calibration(void)
+int qpnp_iadc_resume_calibration(struct qpnp_iadc_chip *iadc)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
-
- if (!iadc || !iadc->iadc_initialized)
- return -EPROBE_DEFER;
-
iadc->skip_auto_calibrations = false;
return 0;
}
EXPORT_SYMBOL(qpnp_iadc_resume_calibration);
-int32_t qpnp_iadc_vadc_sync_read(
+int32_t qpnp_iadc_vadc_sync_read(struct qpnp_iadc_chip *iadc,
enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
int rc = 0;
- if (!iadc || !iadc->iadc_initialized)
+ if (qpnp_iadc_is_valid(iadc) < 0)
return -EPROBE_DEFER;
mutex_lock(&iadc->iadc_vadc_lock);
- rc = qpnp_check_pmic_temp();
+ rc = qpnp_check_pmic_temp(iadc);
if (rc) {
pr_err("PMIC die temp check failed\n");
goto fail;
@@ -889,7 +897,7 @@
goto fail;
}
- rc = qpnp_iadc_read(i_channel, i_result);
+ rc = qpnp_iadc_read(iadc, i_channel, i_result);
if (rc)
pr_err("Configuring IADC failed\n");
/* Intentional fall through to release VADC */
@@ -911,10 +919,11 @@
struct device_attribute *devattr, char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct qpnp_iadc_chip *iadc = dev_get_drvdata(dev);
struct qpnp_iadc_result result;
int rc = -1;
- rc = qpnp_iadc_read(attr->index, &result);
+ rc = qpnp_iadc_read(iadc, attr->index, &result);
if (rc)
return 0;
@@ -926,9 +935,9 @@
static struct sensor_device_attribute qpnp_adc_attr =
SENSOR_ATTR(NULL, S_IRUGO, qpnp_iadc_show, NULL, 0);
-static int32_t qpnp_iadc_init_hwmon(struct spmi_device *spmi)
+static int32_t qpnp_iadc_init_hwmon(struct qpnp_iadc_chip *iadc,
+ struct spmi_device *spmi)
{
- struct qpnp_iadc_drv *iadc = qpnp_iadc;
struct device_node *child;
struct device_node *node = spmi->dev.of_node;
int rc = 0, i = 0, channel;
@@ -960,19 +969,11 @@
static int __devinit qpnp_iadc_probe(struct spmi_device *spmi)
{
- struct qpnp_iadc_drv *iadc;
+ struct qpnp_iadc_chip *iadc;
struct qpnp_adc_drv *adc_qpnp;
struct device_node *node = spmi->dev.of_node;
struct device_node *child;
- int rc, count_adc_channel_list = 0;
-
- if (!node)
- return -EINVAL;
-
- if (qpnp_iadc) {
- pr_err("IADC already in use\n");
- return -EBUSY;
- }
+ int rc, count_adc_channel_list = 0, i = 0;
for_each_child_of_node(node, child)
count_adc_channel_list++;
@@ -982,7 +983,7 @@
return -EINVAL;
}
- iadc = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_iadc_drv) +
+ iadc = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_iadc_chip) +
(sizeof(struct sensor_device_attribute) *
count_adc_channel_list), GFP_KERNEL);
if (!iadc) {
@@ -1030,50 +1031,56 @@
IRQF_TRIGGER_RISING, "qpnp_iadc_interrupt", iadc);
if (rc) {
dev_err(&spmi->dev, "failed to request adc irq\n");
- goto fail;
+ return rc;
} else
enable_irq_wake(iadc->adc->adc_irq_eoc);
- dev_set_drvdata(&spmi->dev, iadc);
- qpnp_iadc = iadc;
-
- rc = qpnp_iadc_init_hwmon(spmi);
+ rc = qpnp_iadc_init_hwmon(iadc, spmi);
if (rc) {
dev_err(&spmi->dev, "failed to initialize qpnp hwmon adc\n");
- goto fail;
+ return rc;
}
iadc->iadc_hwmon = hwmon_device_register(&iadc->adc->spmi->dev);
- rc = qpnp_iadc_version_check();
+ rc = qpnp_iadc_version_check(iadc);
if (rc) {
dev_err(&spmi->dev, "IADC version not supported\n");
goto fail;
}
mutex_init(&iadc->iadc_vadc_lock);
+ INIT_WORK(&iadc->trigger_completion_work, qpnp_iadc_trigger_completion);
INIT_DELAYED_WORK(&iadc->iadc_work, qpnp_iadc_work);
- rc = qpnp_iadc_comp_info();
+ rc = qpnp_iadc_comp_info(iadc);
if (rc) {
dev_err(&spmi->dev, "abstracting IADC comp info failed!\n");
goto fail;
}
- iadc->iadc_initialized = true;
- rc = qpnp_iadc_calibrate_for_trim(true);
+ dev_set_drvdata(&spmi->dev, iadc);
+ list_add(&iadc->list, &qpnp_iadc_device_list);
+ rc = qpnp_iadc_calibrate_for_trim(iadc, true);
if (rc)
dev_err(&spmi->dev, "failed to calibrate for USR trim\n");
+
schedule_delayed_work(&iadc->iadc_work,
round_jiffies_relative(msecs_to_jiffies
(QPNP_IADC_CALIB_SECONDS)));
return 0;
fail:
- qpnp_iadc = NULL;
+ for_each_child_of_node(node, child) {
+ device_remove_file(&spmi->dev,
+ &iadc->sens_attr[i].dev_attr);
+ i++;
+ }
+ hwmon_device_unregister(iadc->iadc_hwmon);
+
return rc;
}
static int __devexit qpnp_iadc_remove(struct spmi_device *spmi)
{
- struct qpnp_iadc_drv *iadc = dev_get_drvdata(&spmi->dev);
+ struct qpnp_iadc_chip *iadc = dev_get_drvdata(&spmi->dev);
struct device_node *node = spmi->dev.of_node;
struct device_node *child;
int i = 0;
@@ -1085,6 +1092,7 @@
&iadc->sens_attr[i].dev_attr);
i++;
}
+ hwmon_device_unregister(iadc->iadc_hwmon);
dev_set_drvdata(&spmi->dev, NULL);
return 0;
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c
index 519b7e4..ded2b6e 100644
--- a/drivers/input/misc/mpu3050.c
+++ b/drivers/input/misc/mpu3050.c
@@ -302,9 +302,6 @@
/**
* Set/get enable function is just needed by sensor HAL.
- * Normally, the open function does all the initialization
- * and power work. And close undo that open does.
- * Just keeping the function simple.
*/
static ssize_t mpu3050_attr_set_enable(struct device *dev,
@@ -316,8 +313,25 @@
if (kstrtoul(buf, 10, &val))
return -EINVAL;
- sensor->enable = (u32)val;
-
+ sensor->enable = (u32)val == 0 ? 0 : 1;
+ if (sensor->enable) {
+ pm_runtime_get_sync(sensor->dev);
+ gpio_set_value(sensor->enable_gpio, 1);
+ if (sensor->use_poll)
+ schedule_delayed_work(&sensor->input_work,
+ msecs_to_jiffies(sensor->poll_interval));
+ else
+ i2c_smbus_write_byte_data(sensor->client,
+ MPU3050_INT_CFG,
+ MPU3050_ACTIVE_LOW |
+ MPU3050_OPEN_DRAIN |
+ MPU3050_RAW_RDY_EN);
+ } else {
+ if (sensor->use_poll)
+ cancel_delayed_work_sync(&sensor->input_work);
+ gpio_set_value(sensor->enable_gpio, 0);
+ pm_runtime_put(sensor->dev);
+ }
return count;
}
@@ -792,14 +806,8 @@
goto err_input_cleanup;
}
- if (sensor->use_poll)
- schedule_delayed_work(&sensor->input_work,
- msecs_to_jiffies(sensor->poll_interval));
- else
- i2c_smbus_write_byte_data(sensor->client, MPU3050_INT_CFG,
- MPU3050_ACTIVE_LOW |
- MPU3050_OPEN_DRAIN |
- MPU3050_RAW_RDY_EN);
+ pm_runtime_enable(&client->dev);
+ pm_runtime_set_autosuspend_delay(&client->dev, MPU3050_AUTO_DELAY);
return 0;
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
index 25228a6..7fac726 100644
--- a/drivers/input/touchscreen/ft5x06_ts.c
+++ b/drivers/input/touchscreen/ft5x06_ts.c
@@ -82,6 +82,7 @@
#define FT_ERASE_PANEL_REG 0x63
#define FT_FW_START_REG 0xBF
+#define FT_STATUS_NUM_TP_MASK 0x0F
#define FT_VTG_MIN_UV 2600000
#define FT_VTG_MAX_UV 3300000
@@ -329,6 +330,7 @@
static int ft5x06_handle_touchdata(struct ft5x06_ts_data *data)
{
struct ts_event *event = &data->event;
+ int num_points;
int ret, i;
u8 buf[POINT_READ_BUF] = { 0 };
u8 pointid = FT_MAX_ID;
@@ -342,7 +344,9 @@
memset(event, 0, sizeof(struct ts_event));
event->touch_point = 0;
- for (i = 0; i < CFG_MAX_TOUCH_POINTS; i++) {
+ num_points = buf[2] & FT_STATUS_NUM_TP_MASK;
+
+ for (i = 0; i < num_points; i++) {
pointid = (buf[FT_TOUCH_ID_POS + FT_TOUCH_STEP * i]) >> 4;
if (pointid >= FT_MAX_ID)
break;
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
index 908d0d7..ba0be2b 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -1056,8 +1056,6 @@
rmi4_pdata->i2c_pull_up = of_property_read_bool(np,
"synaptics,i2c-pull-up");
- rmi4_pdata->power_down_enable = of_property_read_bool(np,
- "synaptics,power-down");
rmi4_pdata->x_flip = of_property_read_bool(np, "synaptics,x-flip");
rmi4_pdata->y_flip = of_property_read_bool(np, "synaptics,y-flip");
@@ -2005,7 +2003,7 @@
error_reg_en_vcc_i2c:
if (rmi4_data->board->i2c_pull_up)
- reg_set_optimum_mode_check(rmi4_data->vcc_i2c, 0);
+ reg_set_optimum_mode_check(rmi4_data->vdd, 0);
error_reg_opt_i2c:
regulator_disable(rmi4_data->vdd);
error_reg_en_vdd:
@@ -2594,51 +2592,27 @@
bool on)
{
int retval;
- int load_ua;
if (on == false)
goto regulator_hpm;
- load_ua = rmi4_data->board->power_down_enable ? 0 : RMI4_LPM_LOAD_UA;
- retval = reg_set_optimum_mode_check(rmi4_data->vdd, load_ua);
+ retval = reg_set_optimum_mode_check(rmi4_data->vdd, RMI4_LPM_LOAD_UA);
if (retval < 0) {
dev_err(&rmi4_data->i2c_client->dev,
- "Regulator vdd_ana set_opt failed rc=%d\n",
+ "Regulator vcc_ana set_opt failed rc=%d\n",
retval);
goto fail_regulator_lpm;
}
- if (rmi4_data->board->power_down_enable) {
- retval = regulator_disable(rmi4_data->vdd);
- if (retval) {
- dev_err(&rmi4_data->i2c_client->dev,
- "Regulator vdd disable failed rc=%d\n",
- retval);
- goto fail_regulator_lpm;
- }
- }
-
if (rmi4_data->board->i2c_pull_up) {
- load_ua = rmi4_data->board->power_down_enable ?
- 0 : RMI4_I2C_LPM_LOAD_UA;
retval = reg_set_optimum_mode_check(rmi4_data->vcc_i2c,
- load_ua);
+ RMI4_I2C_LPM_LOAD_UA);
if (retval < 0) {
dev_err(&rmi4_data->i2c_client->dev,
- "Regulator vcc_i2c set_opt failed " \
- "rc=%d\n", retval);
+ "Regulator vcc_i2c set_opt failed rc=%d\n",
+ retval);
goto fail_regulator_lpm;
}
-
- if (rmi4_data->board->power_down_enable) {
- retval = regulator_disable(rmi4_data->vcc_i2c);
- if (retval) {
- dev_err(&rmi4_data->i2c_client->dev,
- "Regulator vcc_i2c disable failed " \
- "rc=%d\n", retval);
- goto fail_regulator_lpm;
- }
- }
}
return 0;
@@ -2654,16 +2628,6 @@
goto fail_regulator_hpm;
}
- if (rmi4_data->board->power_down_enable) {
- retval = regulator_enable(rmi4_data->vdd);
- if (retval) {
- dev_err(&rmi4_data->i2c_client->dev,
- "Regulator vdd enable failed rc=%d\n",
- retval);
- goto fail_regulator_hpm;
- }
- }
-
if (rmi4_data->board->i2c_pull_up) {
retval = reg_set_optimum_mode_check(rmi4_data->vcc_i2c,
RMI4_I2C_LOAD_UA);
@@ -2673,26 +2637,6 @@
retval);
goto fail_regulator_hpm;
}
-
- if (rmi4_data->board->power_down_enable) {
- retval = regulator_enable(rmi4_data->vcc_i2c);
- if (retval) {
- dev_err(&rmi4_data->i2c_client->dev,
- "Regulator vcc_i2c enable failed " \
- "rc=%d\n", retval);
- goto fail_regulator_hpm;
- }
- }
- }
-
- if (rmi4_data->board->power_down_enable) {
- retval = synaptics_rmi4_reset_device(rmi4_data);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to issue reset command, rc = %d\n",
- __func__, retval);
- return retval;
- }
}
return 0;
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 3082e99..2f6e6a7 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -18,6 +18,7 @@
#include <linux/videodev2.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <linux/iopoll.h>
#include <media/msmb_isp.h>
#include "msm_ispif.h"
@@ -38,6 +39,9 @@
#define ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY 0x01
#define ISPIF_INTF_CMD_DISABLE_IMMEDIATELY 0x02
+#define ISPIF_TIMEOUT_SLEEP_US 1000
+#define ISPIF_TIMEOUT_ALL_US 500000
+
#undef CDBG
#ifdef CONFIG_MSMB_CAMERA_DEBUG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
@@ -63,6 +67,78 @@
{"ispif_ahb_clk", -1},
};
+static struct msm_cam_clk_info ispif_8974_reset_clk_info[] = {
+ {"csi0_src_clk", INIT_RATE},
+ {"csi0_clk", NO_SET_RATE},
+ {"csi0_pix_clk", NO_SET_RATE},
+ {"csi0_rdi_clk", NO_SET_RATE},
+ {"vfe0_clk_src", INIT_RATE},
+ {"camss_vfe_vfe0_clk", NO_SET_RATE},
+ {"camss_csi_vfe0_clk", NO_SET_RATE},
+ {"vfe1_clk_src", INIT_RATE},
+ {"camss_vfe_vfe1_clk", NO_SET_RATE},
+ {"camss_csi_vfe1_clk", NO_SET_RATE},
+};
+
+static int msm_ispif_reset_hw(struct ispif_device *ispif)
+{
+ int rc = 0;
+ long timeout = 0;
+ struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)];
+
+ if (ispif->csid_version < CSID_VERSION_V30) {
+ /* currently reset is done only for 8974 */
+ return 0;
+ }
+
+ rc = msm_cam_clk_enable(&ispif->pdev->dev,
+ ispif_8974_reset_clk_info, reset_clk,
+ ARRAY_SIZE(ispif_8974_reset_clk_info), 1);
+ if (rc < 0) {
+ pr_err("%s: cannot enable clock, error = %d",
+ __func__, rc);
+ }
+
+ init_completion(&ispif->reset_complete[VFE0]);
+ if (ispif->hw_num_isps > 1)
+ init_completion(&ispif->reset_complete[VFE1]);
+
+ /* initiate reset of ISPIF */
+ msm_camera_io_w(ISPIF_RST_CMD_MASK,
+ ispif->base + ISPIF_RST_CMD_ADDR);
+ if (ispif->hw_num_isps > 1)
+ msm_camera_io_w(ISPIF_RST_CMD_1_MASK,
+ ispif->base + ISPIF_RST_CMD_1_ADDR);
+
+ timeout = wait_for_completion_interruptible_timeout(
+ &ispif->reset_complete[VFE0], msecs_to_jiffies(500));
+ CDBG("%s: VFE0 done\n", __func__);
+ if (timeout <= 0) {
+ pr_err("%s: VFE0 reset wait timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ if (ispif->hw_num_isps > 1) {
+ timeout = wait_for_completion_interruptible_timeout(
+ &ispif->reset_complete[VFE1],
+ msecs_to_jiffies(500));
+ CDBG("%s: VFE1 done\n", __func__);
+ if (timeout <= 0) {
+ pr_err("%s: VFE1 reset wait timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+ }
+
+ rc = msm_cam_clk_enable(&ispif->pdev->dev,
+ ispif_8974_reset_clk_info, reset_clk,
+ ARRAY_SIZE(ispif_8974_reset_clk_info), 0);
+ if (rc < 0) {
+ pr_err("%s: cannot disable clock, error = %d",
+ __func__, rc);
+ }
+ return rc;
+}
+
static int msm_ispif_clk_ahb_enable(struct ispif_device *ispif, int enable)
{
int rc = 0;
@@ -573,6 +649,7 @@
uint16_t cid_mask = 0;
uint32_t intf_addr;
enum msm_ispif_vfe_intf vfe_intf;
+ uint32_t stop_flag = 0;
BUG_ON(!ispif);
BUG_ON(!params);
@@ -625,10 +702,12 @@
goto end;
}
- /* todo_bug_fix? very bad. use readl_poll_timeout */
- while ((msm_camera_io_r(ispif->base + intf_addr) & 0xF) != 0xF)
- CDBG("%s: Wait for %d Idle\n", __func__,
- params->entries[i].intftype);
+ rc = readl_poll_timeout(ispif->base + intf_addr, stop_flag,
+ (stop_flag & 0xF) == 0xF,
+ ISPIF_TIMEOUT_SLEEP_US,
+ ISPIF_TIMEOUT_ALL_US);
+ if (rc < 0)
+ goto end;
/* disable CIDs in CID_MASK register */
msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype,
@@ -706,6 +785,9 @@
ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
if (out[VFE0].ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) {
+ if (out[VFE0].ispifIrqStatus0 & RESET_DONE_IRQ)
+ complete(&ispif->reset_complete[VFE0]);
+
if (out[VFE0].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ)
pr_err("%s: VFE0 pix0 overflow.\n", __func__);
@@ -721,6 +803,9 @@
ispif_process_irq(ispif, out, VFE0);
}
if (ispif->vfe_info.num_vfe > 1) {
+ if (out[VFE1].ispifIrqStatus0 & RESET_DONE_IRQ)
+ complete(&ispif->reset_complete[VFE1]);
+
if (out[VFE1].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ)
pr_err("%s: VFE1 pix0 overflow.\n", __func__);
@@ -811,7 +896,7 @@
pr_err("%s: ahb_clk enable failed", __func__);
goto error_ahb;
}
-
+ msm_ispif_reset_hw(ispif);
rc = msm_ispif_reset(ispif);
if (rc == 0) {
ispif->ispif_state = ISPIF_POWER_UP;
@@ -1002,9 +1087,18 @@
goto error_sd_register;
}
- if (pdev->dev.of_node)
+
+ if (pdev->dev.of_node) {
of_property_read_u32((&pdev->dev)->of_node,
"cell-index", &pdev->id);
+ rc = of_property_read_u32((&pdev->dev)->of_node,
+ "qcom,num-isps", &ispif->hw_num_isps);
+ if (rc)
+ /* backward compatibility */
+ ispif->hw_num_isps = 1;
+ /* not an error condition */
+ rc = 0;
+ }
ispif->mem = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "ispif");
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 faa32aa..45e7354 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h
@@ -58,5 +58,7 @@
enum msm_ispif_state_t ispif_state;
struct msm_ispif_vfe_info vfe_info;
struct clk *ahb_clk;
+ struct completion reset_complete[VFE_MAX];
+ uint32_t hw_num_isps;
};
#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
index c2a5cad..6bd7feb 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
@@ -140,6 +140,7 @@
{
int i;
int rc = 0;
+ long clk_rate;
if (enable) {
for (i = 0; i < num_clk; i++) {
CDBG("%s enable %s\n", __func__,
@@ -158,6 +159,24 @@
clk_info[i].clk_name);
goto cam_clk_set_err;
}
+ } else if (clk_info[i].clk_rate == INIT_RATE) {
+ clk_rate = clk_get_rate(clk_ptr[i]);
+ if (clk_rate == 0) {
+ clk_rate =
+ clk_round_rate(clk_ptr[i], 0);
+ if (clk_rate < 0) {
+ pr_err("%s round rate failed\n",
+ clk_info[i].clk_name);
+ goto cam_clk_set_err;
+ }
+ rc = clk_set_rate(clk_ptr[i],
+ clk_rate);
+ if (rc < 0) {
+ pr_err("%s set rate failed\n",
+ clk_info[i].clk_name);
+ goto cam_clk_set_err;
+ }
+ }
}
rc = clk_prepare(clk_ptr[i]);
if (rc < 0) {
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
index 73376e2..2e6f809 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
@@ -18,6 +18,9 @@
#include <mach/camera2.h>
#include <media/msm_cam_sensor.h>
+#define NO_SET_RATE -1
+#define INIT_RATE -2
+
void msm_camera_io_w(u32 data, void __iomem *addr);
void msm_camera_io_w_mb(u32 data, void __iomem *addr);
u32 msm_camera_io_r(void __iomem *addr);
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c
index 79a492e..5140a03 100644
--- a/drivers/media/platform/msm/vidc/msm_smem.c
+++ b/drivers/media/platform/msm/vidc/msm_smem.c
@@ -500,8 +500,13 @@
struct smem_client *client = clt;
struct iommu_set *iommu_group_set = &client->res->iommu_group_set;
int i;
+ int j;
bool is_secure = (flags & SMEM_SECURE);
struct iommu_info *iommu_map;
+ if (!domain_num || !partition_num) {
+ dprintk(VIDC_DBG, "passed null to get domain partition!");
+ return -EINVAL;
+ }
*domain_num = -1;
*partition_num = -1;
@@ -512,14 +517,14 @@
for (i = 0; i < iommu_group_set->count; i++) {
iommu_map = &iommu_group_set->iommu_maps[i];
- if ((iommu_map->is_secure == is_secure) &&
- (iommu_map->buffer_type & buffer_type)) {
- *domain_num = iommu_map->domain;
- *partition_num = 0;
- if ((buffer_type & HAL_BUFFER_INTERNAL_CMD_QUEUE) &&
- (iommu_map->npartitions == 2))
- *partition_num = 1;
- break;
+ if (iommu_map->is_secure == is_secure) {
+ for (j = 0; j < iommu_map->npartitions; j++) {
+ if (iommu_map->buffer_type[j] & buffer_type) {
+ *domain_num = iommu_map->domain;
+ *partition_num = j;
+ break;
+ }
+ }
}
}
dprintk(VIDC_DBG, "domain: %d, partition: %d found!\n",
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
index cb08da7..394ecdc5 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
@@ -386,65 +386,56 @@
{
int rc = 0;
struct platform_device *pdev = res->pdev;
- struct device_node *ctx_node;
+ struct device_node *domains_parent_node = NULL;
+ struct device_node *domains_child_node = NULL;
struct iommu_set *iommu_group_set = &res->iommu_group_set;
- int array_size;
- int i;
+ int domain_idx = 0;
struct iommu_info *iommu_map;
- u32 *buffer_types = NULL;
+ int array_size = 0;
- if (!of_get_property(pdev->dev.of_node, "qcom,iommu-groups",
- &array_size)) {
- dprintk(VIDC_DBG, "iommu_groups property not present\n");
- iommu_group_set->count = 0;
+ domains_parent_node = of_find_node_by_name(pdev->dev.of_node,
+ "qcom,vidc-iommu-domains");
+ if (!domains_parent_node) {
+ dprintk(VIDC_DBG, "Node qcom,vidc-iommu-domains not found.\n");
return 0;
}
- iommu_group_set->count = array_size / sizeof(u32);
+ iommu_group_set->count = 0;
+ for_each_child_of_node(domains_parent_node, domains_child_node) {
+ iommu_group_set->count++;
+ }
+
if (iommu_group_set->count == 0) {
- dprintk(VIDC_ERR, "No group present in iommu_groups\n");
+ dprintk(VIDC_ERR, "No group present in iommu_domains\n");
rc = -ENOENT;
goto err_no_of_node;
}
-
iommu_group_set->iommu_maps = kzalloc(iommu_group_set->count *
sizeof(*(iommu_group_set->iommu_maps)), GFP_KERNEL);
+
if (!iommu_group_set->iommu_maps) {
- dprintk(VIDC_ERR, "%s Failed to alloc iommu_maps\n",
- __func__);
+ dprintk(VIDC_ERR, "Cannot allocate iommu_maps\n");
rc = -ENOMEM;
goto err_no_of_node;
}
- buffer_types = kzalloc(iommu_group_set->count * sizeof(*buffer_types),
- GFP_KERNEL);
- if (!buffer_types) {
- dprintk(VIDC_ERR,
- "%s Failed to alloc iommu group buffer types\n",
- __func__);
- rc = -ENOMEM;
- goto err_load_groups;
- }
+ /* set up each context bank */
+ for_each_child_of_node(domains_parent_node, domains_child_node) {
+ struct device_node *ctx_node = of_parse_phandle(
+ domains_child_node,
+ "qcom,vidc-domain-phandle",
+ 0);
+ if (domain_idx >= iommu_group_set->count)
+ break;
- rc = of_property_read_u32_array(pdev->dev.of_node,
- "qcom,iommu-group-buffer-types", buffer_types,
- iommu_group_set->count);
- if (rc) {
- dprintk(VIDC_ERR,
- "%s Failed to read iommu group buffer types\n", __func__);
- goto err_load_groups;
- }
-
- for (i = 0; i < iommu_group_set->count; i++) {
- iommu_map = &iommu_group_set->iommu_maps[i];
- ctx_node = of_parse_phandle(pdev->dev.of_node,
- "qcom,iommu-groups", i);
+ iommu_map = &iommu_group_set->iommu_maps[domain_idx];
if (!ctx_node) {
- dprintk(VIDC_ERR, "Unable to parse phandle : %u\n", i);
+ dprintk(VIDC_ERR, "Unable to parse pHandle\n");
rc = -EBADHANDLE;
goto err_load_groups;
}
+ /* domain info from domains.dtsi */
rc = of_property_read_string(ctx_node, "label",
&(iommu_map->name));
if (rc) {
@@ -452,6 +443,11 @@
goto err_load_groups;
}
+ dprintk(VIDC_DBG,
+ "domain %d has name %s\n",
+ domain_idx,
+ iommu_map->name);
+
if (!of_get_property(ctx_node, "qcom,virtual-addr-pool",
&array_size)) {
dprintk(VIDC_ERR,
@@ -463,25 +459,48 @@
iommu_map->npartitions = array_size / sizeof(u32) / 2;
+ dprintk(VIDC_DBG,
+ "%d partitions in domain %d",
+ iommu_map->npartitions,
+ domain_idx);
+
rc = of_property_read_u32_array(ctx_node,
"qcom,virtual-addr-pool",
(u32 *)iommu_map->addr_range,
iommu_map->npartitions * 2);
if (rc) {
dprintk(VIDC_ERR,
- "Could not read addr pool for group : %s\n",
- iommu_map->name);
+ "Could not read addr pool for group : %s (%d)\n",
+ iommu_map->name,
+ rc);
goto err_load_groups;
}
- iommu_map->buffer_type = buffer_types[i];
iommu_map->is_secure =
of_property_read_bool(ctx_node, "qcom,secure-domain");
+
+ dprintk(VIDC_DBG,
+ "domain %s : secure = %d",
+ iommu_map->name,
+ iommu_map->is_secure);
+
+ /* setup partitions and buffer type per partition */
+ rc = of_property_read_u32_array(domains_child_node,
+ "qcom,vidc-partition-buffer-types",
+ iommu_map->buffer_type,
+ iommu_map->npartitions);
+
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "cannot load partition buffertype information (%d)",
+ rc);
+ rc = -ENOENT;
+ goto err_load_groups;
+ }
+ domain_idx++;
}
- kfree(buffer_types);
- return 0;
+ return rc;
err_load_groups:
- kfree(buffer_types);
msm_vidc_free_iommu_groups(res);
err_no_of_node:
return rc;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_resources.h b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
index 43af909..8176ea5 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_resources.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <media/msm_vidc.h>
+#define MAX_BUFFER_TYPES 32
struct load_freq_table {
u32 load;
@@ -39,11 +40,11 @@
struct iommu_info {
const char *name;
- u32 buffer_type;
+ u32 buffer_type[MAX_BUFFER_TYPES];
struct iommu_group *group;
int domain;
bool is_secure;
- struct addr_range addr_range[2];
+ struct addr_range addr_range[MAX_BUFFER_TYPES];
int npartitions;
};
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 47b88db..5416210 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -2804,6 +2804,9 @@
iommu_map->addr_range[0].start;
memprot.cp_nonpixel_size =
iommu_map->addr_range[0].size;
+ } else if (strcmp(iommu_map->name, "venus_cp") == 0) {
+ memprot.cp_nonpixel_start =
+ iommu_map->addr_range[1].start;
}
}
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index a990f43..b140510 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -416,7 +416,7 @@
if (ret)
pr_err("%s: %s: failed setting runtime active: ret: %d\n",
mmc_hostname(card->host), __func__, ret);
- else
+ else if (!mmc_card_sdio(card))
pm_runtime_enable(&card->dev);
}
@@ -424,7 +424,7 @@
if (ret)
return ret;
- if (mmc_use_core_runtime_pm(card->host)) {
+ if (mmc_use_core_runtime_pm(card->host) && !mmc_card_sdio(card)) {
card->rpm_attrib.show = show_rpm_delay;
card->rpm_attrib.store = store_rpm_delay;
sysfs_attr_init(&card->rpm_attrib.attr);
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 3495f4d..96f8f2e 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -2472,6 +2472,7 @@
msm_host->mmc->caps2 |= MMC_CAP2_CLK_SCALE;
msm_host->mmc->caps2 |= MMC_CAP2_STOP_REQUEST;
msm_host->mmc->caps2 |= MMC_CAP2_ASYNC_SDIO_IRQ_4BIT_MODE;
+ msm_host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
if (msm_host->pdata->nonremovable)
msm_host->mmc->caps |= MMC_CAP_NONREMOVABLE;
diff --git a/drivers/platform/msm/qpnp-revid.c b/drivers/platform/msm/qpnp-revid.c
index 897dc2a..9471188 100644
--- a/drivers/platform/msm/qpnp-revid.c
+++ b/drivers/platform/msm/qpnp-revid.c
@@ -30,7 +30,10 @@
"PM8841",
"PM8019",
"PM8226",
- "PM8110"
+ "PM8110",
+ "PMA8084",
+ "PMI8962",
+ "PMD9635",
};
static struct of_device_id qpnp_revid_match_table[] = {
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index c43a777..73c7e62 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -276,6 +276,8 @@
struct bms_irq sw_cc_thr_irq;
struct bms_irq ocv_thr_irq;
struct qpnp_vadc_chip *vadc_dev;
+ struct qpnp_iadc_chip *iadc_dev;
+ struct qpnp_adc_tm_chip *adc_tm_dev;
};
static struct of_device_id qpnp_bms_match_table[] = {
@@ -515,13 +517,13 @@
return result_uv;
}
-static s64 cc_reverse_adjust_for_gain(s64 uv)
+static s64 cc_reverse_adjust_for_gain(struct qpnp_bms_chip *chip, s64 uv)
{
struct qpnp_iadc_calib calibration;
int gain;
s64 result_uv;
- qpnp_iadc_get_gain_and_offset(&calibration);
+ qpnp_iadc_get_gain_and_offset(chip->iadc_dev, &calibration);
gain = (int)calibration.gain_raw - (int)calibration.offset_raw;
pr_debug("reverse adjusting_uv = %lld\n", uv);
@@ -544,7 +546,7 @@
{
struct qpnp_iadc_calib calibration;
- qpnp_iadc_get_gain_and_offset(&calibration);
+ qpnp_iadc_get_gain_and_offset(chip->iadc_dev, &calibration);
return cc_adjust_for_gain(cc_reading_to_uv(reading),
calibration.gain_raw - calibration.offset_raw);
}
@@ -587,7 +589,7 @@
temp_current = div_s64((vsense_uv * 1000000LL),
(int)chip->r_sense_uohm);
- rc = qpnp_iadc_comp_result(&temp_current);
+ rc = qpnp_iadc_comp_result(chip->iadc_dev, &temp_current);
if (rc)
pr_debug("error compensation failed: %d\n", rc);
@@ -814,7 +816,8 @@
}
*vbat_uv = (int)v_result.physical;
} else {
- rc = qpnp_iadc_vadc_sync_read(iadc_channel, &i_result,
+ rc = qpnp_iadc_vadc_sync_read(chip->iadc_dev,
+ iadc_channel, &i_result,
VBAT_SNS, &v_result);
if (rc) {
pr_err("adc sync read failed with rc: %d\n", rc);
@@ -1055,7 +1058,7 @@
return *software_counter;
}
- qpnp_iadc_get_gain_and_offset(&calibration);
+ qpnp_iadc_get_gain_and_offset(chip->iadc_dev, &calibration);
pr_debug("%scc = %lld, die_temp = %lld\n",
cc_type == SHDW_CC ? "shdw_" : "",
cc, result.physical);
@@ -1065,7 +1068,7 @@
- calibration.offset_raw);
cc_pvh = cc_uv_to_pvh(cc_voltage_uv);
cc_uah = div_s64(cc_pvh, chip->r_sense_uohm);
- rc = qpnp_iadc_comp_result(&cc_uah);
+ rc = qpnp_iadc_comp_result(chip->iadc_dev, &cc_uah);
if (rc)
pr_debug("error compensation failed: %d\n", rc);
if (clear_cc == RESET) {
@@ -2132,9 +2135,9 @@
target_cc_uah = CC_STEP_INCREMENT_UAH;
}
iadc_comp_factor = 100000;
- qpnp_iadc_comp_result(&iadc_comp_factor);
+ qpnp_iadc_comp_result(chip->iadc_dev, &iadc_comp_factor);
target_cc_uah = div64_s64(target_cc_uah * 100000, iadc_comp_factor);
- target_cc_uah = cc_reverse_adjust_for_gain(target_cc_uah);
+ target_cc_uah = cc_reverse_adjust_for_gain(chip, target_cc_uah);
cc_raw_64 = convert_cc_uah_to_raw(chip, target_cc_uah);
cc_raw = convert_s64_to_s36(cc_raw_64);
@@ -2353,13 +2356,14 @@
mutex_lock(&chip->vbat_monitor_mutex);
if (chip->vbat_monitor_params.state_request !=
ADC_TM_HIGH_LOW_THR_DISABLE)
- qpnp_adc_tm_channel_measure(&chip->vbat_monitor_params);
+ qpnp_adc_tm_channel_measure(chip->adc_tm_dev,
+ &chip->vbat_monitor_params);
mutex_unlock(&chip->vbat_monitor_mutex);
if (chip->use_voltage_soc) {
soc = calculate_soc_from_voltage(chip);
} else {
if (!chip->batfet_closed)
- qpnp_iadc_calibrate_for_trim(true);
+ qpnp_iadc_calibrate_for_trim(chip->iadc_dev, true);
rc = qpnp_vadc_read(chip->vadc_dev, LR_MUX1_BATT_THERM,
&result);
if (rc) {
@@ -2455,7 +2459,8 @@
chip->vbat_monitor_params.low_thr,
chip->vbat_monitor_params.high_thr);
}
- qpnp_adc_tm_channel_measure(&chip->vbat_monitor_params);
+ qpnp_adc_tm_channel_measure(chip->adc_tm_dev,
+ &chip->vbat_monitor_params);
mutex_unlock(&chip->vbat_monitor_mutex);
}
@@ -2503,7 +2508,8 @@
chip->vbat_monitor_params.low_thr,
chip->vbat_monitor_params.high_thr);
}
- qpnp_adc_tm_channel_measure(&chip->vbat_monitor_params);
+ qpnp_adc_tm_channel_measure(chip->adc_tm_dev,
+ &chip->vbat_monitor_params);
mutex_unlock(&chip->vbat_monitor_mutex);
}
@@ -2527,7 +2533,7 @@
configure_vbat_monitor_low(chip);
} else {
pr_debug("faulty btm trigger, discarding\n");
- qpnp_adc_tm_channel_measure(
+ qpnp_adc_tm_channel_measure(chip->adc_tm_dev,
&chip->vbat_monitor_params);
}
} else if (state == ADC_TM_HIGH_STATE) {
@@ -2537,7 +2543,7 @@
configure_vbat_monitor_high(chip);
} else {
pr_debug("faulty btm trigger, discarding\n");
- qpnp_adc_tm_channel_measure(
+ qpnp_adc_tm_channel_measure(chip->adc_tm_dev,
&chip->vbat_monitor_params);
}
} else {
@@ -2553,7 +2559,8 @@
chip->vbat_monitor_params.state_request = ADC_TM_HIGH_LOW_THR_DISABLE;
- rc = qpnp_adc_tm_disable_chan_meas(&chip->vbat_monitor_params);
+ rc = qpnp_adc_tm_channel_measure(chip->adc_tm_dev,
+ &chip->vbat_monitor_params);
if (rc) {
pr_err("tm disable failed: %d\n", rc);
return rc;
@@ -2573,12 +2580,6 @@
{
int rc;
- rc = qpnp_adc_tm_is_ready();
- if (rc) {
- pr_info("adc tm is not ready yet: %d, defer probe\n", rc);
- return -EPROBE_DEFER;
- }
-
chip->vbat_monitor_params.low_thr = chip->low_voltage_threshold;
chip->vbat_monitor_params.high_thr = chip->max_voltage_uv
- VBATT_ERROR_MARGIN;
@@ -2596,12 +2597,14 @@
chip->vbat_monitor_params.state_request =
ADC_TM_HIGH_LOW_THR_DISABLE;
} else {
- rc = qpnp_adc_tm_channel_measure(&chip->vbat_monitor_params);
+ rc = qpnp_adc_tm_channel_measure(chip->adc_tm_dev,
+ &chip->vbat_monitor_params);
if (rc) {
pr_err("tm setup failed: %d\n", rc);
- return rc;
+ return rc;
}
}
+
pr_debug("setup complete\n");
return 0;
}
@@ -2961,7 +2964,7 @@
*/
for (i = 0; (!chip->batfet_closed) && i < MAX_CAL_TRIES; i++) {
- rc = qpnp_iadc_calibrate_for_trim(false);
+ rc = qpnp_iadc_calibrate_for_trim(chip->iadc_dev, false);
/*
* Wait 20mS after calibration and before reading battery
* current. The BMS h/w uses calibration values in the
@@ -3086,11 +3089,11 @@
if (batfet_closed == false) {
/* batfet opened */
schedule_work(&chip->batfet_open_work);
- qpnp_iadc_skip_calibration();
+ qpnp_iadc_skip_calibration(chip->iadc_dev);
} else {
/* batfet closed */
- qpnp_iadc_calibrate_for_trim(true);
- qpnp_iadc_resume_calibration();
+ qpnp_iadc_calibrate_for_trim(chip->iadc_dev, true);
+ qpnp_iadc_resume_calibration(chip->iadc_dev);
}
}
}
@@ -3385,6 +3388,38 @@
return 0;
}
+static int bms_get_adc(struct qpnp_bms_chip *chip,
+ struct spmi_device *spmi)
+{
+ int rc = 0;
+
+ chip->vadc_dev = qpnp_get_vadc(&spmi->dev, "bms");
+ if (IS_ERR(chip->vadc_dev)) {
+ rc = PTR_ERR(chip->vadc_dev);
+ if (rc != -EPROBE_DEFER)
+ pr_err("vadc property missing, rc=%d\n", rc);
+ return rc;
+ }
+
+ chip->iadc_dev = qpnp_get_iadc(&spmi->dev, "bms");
+ if (IS_ERR(chip->iadc_dev)) {
+ rc = PTR_ERR(chip->iadc_dev);
+ if (rc != -EPROBE_DEFER)
+ pr_err("iadc property missing, rc=%d\n", rc);
+ return rc;
+ }
+
+ chip->adc_tm_dev = qpnp_get_adc_tm(&spmi->dev, "bms");
+ if (IS_ERR(chip->adc_tm_dev)) {
+ rc = PTR_ERR(chip->adc_tm_dev);
+ if (rc != -EPROBE_DEFER)
+ pr_err("adc-tm not ready, defer probe\n");
+ return rc;
+ }
+
+ return 0;
+}
+
#define SPMI_PROP_READ(chip_prop, qpnp_spmi_property, retval) \
do { \
if (retval) \
@@ -3683,7 +3718,7 @@
chip->software_shdw_cc_uah = 0;
}
- rc = qpnp_iadc_get_rsense(&rds_rsense_nohm);
+ rc = qpnp_iadc_get_rsense(chip->iadc_dev, &rds_rsense_nohm);
if (rc) {
pr_err("Unable to read RDS resistance value from IADC; rc = %d\n",
rc);
@@ -3740,7 +3775,8 @@
- chip->temperature_margin;
chip->die_temp_monitor_params.state_request =
ADC_TM_HIGH_LOW_THR_ENABLE;
- return qpnp_adc_tm_channel_measure(&chip->die_temp_monitor_params);
+ return qpnp_adc_tm_channel_measure(chip->adc_tm_dev,
+ &chip->die_temp_monitor_params);
}
static void btm_notify_die_temp(enum qpnp_tm_state state, void *ctx)
@@ -3763,17 +3799,14 @@
static int setup_die_temp_monitoring(struct qpnp_bms_chip *chip)
{
- int rc = qpnp_adc_tm_is_ready();
- if (rc) {
- pr_info("adc tm is not ready yet: %d, defer probe\n", rc);
- return -EPROBE_DEFER;
- }
+ int rc;
+
chip->die_temp_monitor_params.channel = DIE_TEMP;
chip->die_temp_monitor_params.btm_ctx = (void *)chip;
chip->die_temp_monitor_params.timer_interval = ADC_MEAS1_INTERVAL_1S;
chip->die_temp_monitor_params.threshold_notification =
&btm_notify_die_temp;
- refresh_die_temp_monitor(chip);
+ rc = refresh_die_temp_monitor(chip);
if (rc) {
pr_err("tm setup failed: %d\n", rc);
return rc;
@@ -3795,20 +3828,9 @@
return -ENOMEM;
}
- chip->vadc_dev = qpnp_get_vadc(&(spmi->dev), "bms");
- if (IS_ERR(chip->vadc_dev)) {
- rc = PTR_ERR(chip->vadc_dev);
- if (rc != -EPROBE_DEFER)
- pr_err("vadc property missing, rc=%d\n", rc);
+ rc = bms_get_adc(chip, spmi);
+ if (rc < 0)
goto error_read;
- }
-
- rc = qpnp_iadc_is_ready();
- if (rc) {
- pr_info("iadc not ready: %d, deferring probe\n", rc);
- rc = -EPROBE_DEFER;
- goto error_read;
- }
mutex_init(&chip->bms_output_lock);
mutex_init(&chip->last_ocv_uv_mutex);
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index c023a6d..0883312 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -100,6 +100,8 @@
#define BOOST_ENABLE_CONTROL 0x46
#define COMP_OVR1 0xEA
#define BAT_IF_BTC_CTRL 0x49
+#define USB_OCP_THR 0x52
+#define USB_OCP_CLR 0x53
#define REG_OFFSET_PERP_SUBTYPE 0x05
@@ -142,6 +144,11 @@
#define BAT_THM_EN BIT(1)
#define BAT_ID_EN BIT(0)
#define BOOST_PWR_EN BIT(7)
+#define OCP_CLR_BIT BIT(7)
+#define OCP_THR_MASK 0x03
+#define OCP_THR_900_MA 0x02
+#define OCP_THR_500_MA 0x01
+#define OCP_THR_200_MA 0x00
/* Interrupt definitions */
/* smbb_chg_interrupts */
@@ -267,6 +274,7 @@
u16 misc_base;
u16 freq_base;
struct qpnp_chg_irq usbin_valid;
+ struct qpnp_chg_irq usb_ocp;
struct qpnp_chg_irq dcin_valid;
struct qpnp_chg_irq chg_gone;
struct qpnp_chg_irq chg_fastchg;
@@ -328,6 +336,7 @@
struct qpnp_chg_regulator otg_vreg;
struct qpnp_chg_regulator boost_vreg;
struct qpnp_vadc_chip *vadc_dev;
+ struct qpnp_adc_tm_chip *adc_tm_dev;
};
@@ -918,7 +927,7 @@
struct qpnp_chg_chip *chip = container_of(work,
struct qpnp_chg_chip, adc_measure_work);
- if (qpnp_adc_tm_channel_measure(&chip->adc_param))
+ if (qpnp_adc_tm_channel_measure(chip->adc_tm_dev, &chip->adc_param))
pr_err("request ADC error\n");
}
@@ -982,6 +991,32 @@
return IRQ_HANDLED;
}
+static irqreturn_t
+qpnp_chg_usb_usb_ocp_irq_handler(int irq, void *_chip)
+{
+ struct qpnp_chg_chip *chip = _chip;
+ int rc;
+
+ pr_debug("usb-ocp triggered\n");
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->usb_chgpth_base + USB_OCP_CLR,
+ OCP_CLR_BIT,
+ OCP_CLR_BIT, 1);
+ if (rc)
+ pr_err("Failed to clear OCP bit rc = %d\n", rc);
+
+ /* force usb ovp fet off */
+ rc = qpnp_chg_masked_write(chip,
+ chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
+ USB_OTG_EN_BIT,
+ USB_OTG_EN_BIT, 1);
+ if (rc)
+ pr_err("Failed to turn off usb ovp rc = %d\n", rc);
+
+ return IRQ_HANDLED;
+}
+
#define ENUM_T_STOP_BIT BIT(0)
static irqreturn_t
qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
@@ -2346,7 +2381,7 @@
qpnp_chg_set_appropriate_vbatdet(chip);
}
- if (qpnp_adc_tm_channel_measure(&chip->adc_param))
+ if (qpnp_adc_tm_channel_measure(chip->adc_tm_dev, &chip->adc_param))
pr_err("request ADC error\n");
power_supply_changed(&chip->batt_psy);
@@ -2631,6 +2666,27 @@
return rc;
}
+ if ((subtype == SMBBP_USB_CHGPTH_SUBTYPE) ||
+ (subtype == SMBCL_USB_CHGPTH_SUBTYPE)) {
+ chip->usb_ocp.irq = spmi_get_irq_byname(spmi,
+ spmi_resource, "usb-ocp");
+ if (chip->usb_ocp.irq < 0) {
+ pr_err("Unable to get usbin irq\n");
+ return rc;
+ }
+ rc = devm_request_irq(chip->dev,
+ chip->usb_ocp.irq,
+ qpnp_chg_usb_usb_ocp_irq_handler,
+ IRQF_TRIGGER_RISING, "usb-ocp", chip);
+ if (rc < 0) {
+ pr_err("Can't request %d usb-ocp: %d\n",
+ chip->usb_ocp.irq, rc);
+ return rc;
+ }
+
+ enable_irq_wake(chip->usb_ocp.irq);
+ }
+
enable_irq_wake(chip->usbin_valid.irq);
enable_irq_wake(chip->chg_gone.irq);
break;
@@ -2685,8 +2741,11 @@
return rc;
}
- if (batt_data.max_voltage_uv >= 0)
+ if (batt_data.max_voltage_uv >= 0) {
chip->max_voltage_mv = batt_data.max_voltage_uv / 1000;
+ chip->safe_voltage_mv = chip->max_voltage_mv
+ + MAX_DELTA_VDD_MAX_MV;
+ }
if (batt_data.iterm_ua >= 0)
chip->term_current = batt_data.iterm_ua / 1000;
}
@@ -2882,6 +2941,16 @@
0xFF,
0x80, 1);
+ if ((subtype == SMBBP_USB_CHGPTH_SUBTYPE) ||
+ (subtype == SMBCL_USB_CHGPTH_SUBTYPE)) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->usb_chgpth_base + USB_OCP_THR,
+ OCP_THR_MASK,
+ OCP_THR_900_MA, 1);
+ if (rc)
+ pr_err("Failed to configure OCP rc = %d\n", rc);
+ }
+
break;
case SMBB_DC_CHGPTH_SUBTYPE:
break;
@@ -2999,6 +3068,7 @@
if (rc) {
/* Select BAT_THM as default BPD scheme */
chip->bpd_detection = BPD_TYPE_BAT_THM;
+ rc = 0;
} else {
chip->bpd_detection = get_bpd(bpd);
if (chip->bpd_detection < 0) {
@@ -3009,9 +3079,11 @@
/* Look up JEITA compliance parameters if cool and warm temp provided */
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);
+ chip->adc_tm_dev = qpnp_get_adc_tm(chip->dev, "chg");
+ if (IS_ERR(chip->adc_tm_dev)) {
+ rc = PTR_ERR(chip->adc_tm_dev);
+ if (rc != -EPROBE_DEFER)
+ pr_err("adc-tm not ready, defer probe\n");
return rc;
}
@@ -3358,7 +3430,8 @@
chip->adc_param.channel = LR_MUX1_BATT_THERM;
if (get_prop_batt_present(chip)) {
- rc = qpnp_adc_tm_channel_measure(&chip->adc_param);
+ rc = qpnp_adc_tm_channel_measure(chip->adc_tm_dev,
+ &chip->adc_param);
if (rc) {
pr_err("request ADC error %d\n", rc);
goto fail_chg_enable;
@@ -3418,7 +3491,8 @@
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);
+ qpnp_adc_tm_disable_chan_meas(chip->adc_tm_dev,
+ &chip->adc_param);
}
cancel_work_sync(&chip->adc_measure_work);
cancel_delayed_work_sync(&chip->eoc_work);
diff --git a/drivers/spmi/qpnp-int.c b/drivers/spmi/qpnp-int.c
index eedb1e5..03e9021 100644
--- a/drivers/spmi/qpnp-int.c
+++ b/drivers/spmi/qpnp-int.c
@@ -167,21 +167,20 @@
pr_err_ratelimited("%s: decode failed on hwirq %lu\n",
__func__, d->hwirq);
return rc;
- } else {
- if (irq_d->priv_d == QPNPINT_INVALID_DATA) {
- rc = chip_d->cb->register_priv_data(chip_d->spmi_ctrl,
- &q_spec, &irq_d->priv_d);
- if (rc) {
- pr_err_ratelimited(
- "%s: decode failed on hwirq %lu\n",
- __func__, d->hwirq);
- return rc;
- }
-
- }
- arb_op(chip_d->spmi_ctrl, &q_spec, irq_d->priv_d);
}
+ if (irq_d->priv_d == QPNPINT_INVALID_DATA) {
+ rc = chip_d->cb->register_priv_data(chip_d->spmi_ctrl,
+ &q_spec, &irq_d->priv_d);
+ if (rc) {
+ pr_err_ratelimited(
+ "%s: decode failed on hwirq %lu rc = %d\n",
+ __func__, d->hwirq, rc);
+ return rc;
+ }
+ }
+ arb_op(chip_d->spmi_ctrl, &q_spec, irq_d->priv_d);
+
return 0;
}
@@ -191,6 +190,7 @@
struct q_chip_data *chip_d = irq_d->chip_d;
struct q_perip_data *per_d = irq_d->per_d;
int rc;
+ uint8_t prev_int_en = per_d->int_en;
pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);
@@ -201,10 +201,16 @@
return;
}
- qpnpint_arbiter_op(d, irq_d, chip_d->cb->mask);
-
per_d->int_en &= ~irq_d->mask_shift;
+ if (prev_int_en && !(per_d->int_en)) {
+ /*
+ * no interrupt on this peripheral is enabled
+ * ask the arbiter to ignore this peripheral
+ */
+ qpnpint_arbiter_op(d, irq_d, chip_d->cb->mask);
+ }
+
rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_EN_CLR,
(u8 *)&irq_d->mask_shift, 1);
if (rc) {
@@ -221,6 +227,7 @@
struct q_chip_data *chip_d = irq_d->chip_d;
struct q_perip_data *per_d = irq_d->per_d;
int rc;
+ uint8_t prev_int_en = per_d->int_en;
pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);
@@ -231,10 +238,16 @@
return;
}
- qpnpint_arbiter_op(d, irq_d, chip_d->cb->mask);
-
per_d->int_en &= ~irq_d->mask_shift;
+ if (prev_int_en && !(per_d->int_en)) {
+ /*
+ * no interrupt on this peripheral is enabled
+ * ask the arbiter to ignore this peripheral
+ */
+ qpnpint_arbiter_op(d, irq_d, chip_d->cb->mask);
+ }
+
rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_EN_CLR,
&irq_d->mask_shift, 1);
if (rc) {
@@ -256,6 +269,7 @@
struct q_chip_data *chip_d = irq_d->chip_d;
struct q_perip_data *per_d = irq_d->per_d;
int rc;
+ uint8_t prev_int_en = per_d->int_en;
pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);
@@ -266,9 +280,15 @@
return;
}
- qpnpint_arbiter_op(d, irq_d, chip_d->cb->unmask);
-
per_d->int_en |= irq_d->mask_shift;
+ if (!prev_int_en && per_d->int_en) {
+ /*
+ * no interrupt prior to this call was enabled for the
+ * peripheral. Ask the arbiter to enable interrupts for
+ * this peripheral
+ */
+ qpnpint_arbiter_op(d, irq_d, chip_d->cb->unmask);
+ }
rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_EN_SET,
&irq_d->mask_shift, 1);
if (rc) {
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 05a4806..f85a576 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -101,6 +101,9 @@
#define PMIC_ARB_APID_MASK 0xFF
#define PMIC_ARB_PPID_MASK 0xFFF
+/* interrupt enable bit */
+#define SPMI_PIC_ACC_ENABLE_BIT BIT(0)
+
/**
* base - base address of the PMIC Arbiter core registers.
* intr - base address of the SPMI interrupt control registers
@@ -434,8 +437,10 @@
spin_lock_irqsave(&pmic_arb->lock, flags);
status = readl_relaxed(pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
- if (!status) {
- writel_relaxed(0x1, pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
+ if (!(status & SPMI_PIC_ACC_ENABLE_BIT)) {
+ status = status | SPMI_PIC_ACC_ENABLE_BIT;
+ writel_relaxed(status,
+ pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
/* Interrupt needs to be enabled before returning to caller */
wmb();
}
@@ -467,8 +472,11 @@
spin_lock_irqsave(&pmic_arb->lock, flags);
status = readl_relaxed(pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
- if (status) {
- writel_relaxed(0x0, pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
+ if (status & SPMI_PIC_ACC_ENABLE_BIT) {
+ /* clear the enable bit and write */
+ status = status & ~SPMI_PIC_ACC_ENABLE_BIT;
+ writel_relaxed(status,
+ pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
/* Interrupt needs to be disabled before returning to caller */
wmb();
}
@@ -480,7 +488,7 @@
periph_interrupt(struct spmi_pmic_arb_dev *pmic_arb, u8 apid)
{
u16 ppid = get_peripheral_id(pmic_arb, apid);
- void __iomem *base = pmic_arb->intr;
+ void __iomem *intr = pmic_arb->intr;
u8 sid = (ppid >> 8) & 0x0F;
u8 pid = ppid & 0xFF;
u32 status;
@@ -491,11 +499,20 @@
/* return IRQ_NONE; */
}
+ status = readl_relaxed(intr + SPMI_PIC_ACC_ENABLE(apid));
+ if (!(status & SPMI_PIC_ACC_ENABLE_BIT)) {
+ /*
+ * All interrupts from this peripheral are disabled
+ * don't bother calling the qpnpint handler
+ */
+ return IRQ_HANDLED;
+ }
+
/* Read the peripheral specific interrupt bits */
- status = readl_relaxed(base + SPMI_PIC_IRQ_STATUS(apid));
+ status = readl_relaxed(intr + SPMI_PIC_IRQ_STATUS(apid));
/* Clear the peripheral interrupts */
- writel_relaxed(status, base + SPMI_PIC_IRQ_CLEAR(apid));
+ writel_relaxed(status, intr + SPMI_PIC_IRQ_CLEAR(apid));
/* Interrupt needs to be cleared/acknowledged before exiting ISR */
mb();
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index fc21fbb..348ed3e 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -363,21 +363,27 @@
static inline int
spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid)
{
- BUG_ON(!ctrl || !ctrl->cmd);
+ if (!ctrl || !ctrl->cmd || ctrl->dev.type != &spmi_ctrl_type)
+ return -EINVAL;
+
return ctrl->cmd(ctrl, opcode, sid);
}
static inline int spmi_read_cmd(struct spmi_controller *ctrl,
u8 opcode, u8 sid, u16 addr, u8 bc, u8 *buf)
{
- BUG_ON(!ctrl || !ctrl->read_cmd);
+ if (!ctrl || !ctrl->read_cmd || ctrl->dev.type != &spmi_ctrl_type)
+ return -EINVAL;
+
return ctrl->read_cmd(ctrl, opcode, sid, addr, bc, buf);
}
static inline int spmi_write_cmd(struct spmi_controller *ctrl,
u8 opcode, u8 sid, u16 addr, u8 bc, u8 *buf)
{
- BUG_ON(!ctrl || !ctrl->write_cmd);
+ if (!ctrl || !ctrl->write_cmd || ctrl->dev.type != &spmi_ctrl_type)
+ return -EINVAL;
+
return ctrl->write_cmd(ctrl, opcode, sid, addr, bc, buf);
}
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index eae5cc8..5b78cdd 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -171,6 +171,7 @@
struct qpnp_adc_tm_sensor {
struct thermal_zone_device *tz_dev;
+ struct qpnp_adc_tm_chip *chip;
enum thermal_device_mode mode;
uint32_t sensor_num;
enum qpnp_adc_meas_timer_select timer_select;
@@ -187,15 +188,18 @@
uint32_t scale_type;
};
-struct qpnp_adc_tm_drv {
+struct qpnp_adc_tm_chip {
struct qpnp_adc_drv *adc;
+ struct list_head list;
bool adc_tm_initialized;
int max_channels_available;
struct qpnp_vadc_chip *vadc_dev;
+ struct work_struct trigger_high_thr_work;
+ struct work_struct trigger_low_thr_work;
struct qpnp_adc_tm_sensor sensor[0];
};
-struct qpnp_adc_tm_drv *qpnp_adc_tm;
+LIST_HEAD(qpnp_adc_tm_device_list);
struct qpnp_adc_tm_trip_reg_type {
uint16_t low_thr_lsb_addr;
@@ -258,67 +262,79 @@
[SCALE_RPMIC_THERM] = {qpnp_adc_scale_millidegc_pmic_voltage_thr},
};
-static int32_t qpnp_adc_tm_read_reg(int16_t reg, u8 *data)
+static int32_t qpnp_adc_tm_read_reg(struct qpnp_adc_tm_chip *chip,
+ int16_t reg, u8 *data)
{
- struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
int rc = 0;
- rc = spmi_ext_register_readl(adc_tm->adc->spmi->ctrl,
- adc_tm->adc->slave, (adc_tm->adc->offset + reg), data, 1);
+ rc = spmi_ext_register_readl(chip->adc->spmi->ctrl,
+ chip->adc->slave, (chip->adc->offset + reg), data, 1);
if (rc < 0)
pr_err("adc-tm read reg %d failed with %d\n", reg, rc);
return rc;
}
-static int32_t qpnp_adc_tm_write_reg(int16_t reg, u8 data)
+static int32_t qpnp_adc_tm_write_reg(struct qpnp_adc_tm_chip *chip,
+ int16_t reg, u8 data)
{
- struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
int rc = 0;
u8 *buf;
buf = &data;
- rc = spmi_ext_register_writel(adc_tm->adc->spmi->ctrl,
- adc_tm->adc->slave, (adc_tm->adc->offset + reg), buf, 1);
+ rc = spmi_ext_register_writel(chip->adc->spmi->ctrl,
+ chip->adc->slave, (chip->adc->offset + reg), buf, 1);
if (rc < 0)
pr_err("adc-tm write reg %d failed with %d\n", reg, rc);
return rc;
}
-static int32_t qpnp_adc_tm_enable(void)
+static int32_t qpnp_adc_tm_enable(struct qpnp_adc_tm_chip *chip)
{
int rc = 0;
u8 data = 0;
data = QPNP_ADC_TM_EN;
- rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1, data);
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_EN_CTL1, data);
if (rc < 0)
pr_err("adc-tm enable failed\n");
return rc;
}
-static int32_t qpnp_adc_tm_disable(void)
+static int32_t qpnp_adc_tm_disable(struct qpnp_adc_tm_chip *chip)
{
u8 data = 0;
int rc = 0;
- rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1, data);
+ rc = qpnp_adc_tm_write_reg(chip, 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)
+static int qpnp_adc_tm_is_valid(struct qpnp_adc_tm_chip *chip)
+{
+ struct qpnp_adc_tm_chip *adc_tm_chip = NULL;
+
+ list_for_each_entry(adc_tm_chip, &qpnp_adc_tm_device_list, list)
+ if (chip == adc_tm_chip)
+ return 0;
+
+ return -EINVAL;
+}
+
+static int32_t qpnp_adc_tm_enable_if_channel_meas(
+ struct qpnp_adc_tm_chip *chip)
{
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,
+ rc = qpnp_adc_tm_read_reg(chip, 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);
@@ -327,10 +343,11 @@
/* Enable only if there are pending measurement requests */
if (adc_tm_meas_en) {
- qpnp_adc_tm_enable();
+ qpnp_adc_tm_enable(chip);
/* Request conversion */
- rc = qpnp_adc_tm_write_reg(QPNP_CONV_REQ, QPNP_CONV_REQ_SET);
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_CONV_REQ,
+ QPNP_CONV_REQ_SET);
if (rc < 0) {
pr_err("adc-tm request conversion failed\n");
return rc;
@@ -340,13 +357,13 @@
return rc;
}
-static int32_t qpnp_adc_tm_req_sts_check(void)
+static int32_t qpnp_adc_tm_req_sts_check(struct qpnp_adc_tm_chip *chip)
{
u8 status1;
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);
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_STATUS1, &status1);
if (rc) {
pr_err("adc-tm read status1 failed\n");
return rc;
@@ -354,7 +371,7 @@
/* Disable the bank if a conversion is occuring */
while ((status1 & QPNP_STATUS1_REQ_STS) && (count < 5)) {
- rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS1, &status1);
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_STATUS1, &status1);
if (rc < 0)
pr_err("adc-tm disable failed\n");
/* Wait time is based on the optimum sampling rate
@@ -367,18 +384,19 @@
return rc;
}
-static int32_t qpnp_adc_tm_check_revision(uint32_t btm_chan_num)
+static int32_t qpnp_adc_tm_check_revision(struct qpnp_adc_tm_chip *chip,
+ uint32_t btm_chan_num)
{
u8 rev, perph_subtype;
int rc = 0;
- rc = qpnp_adc_tm_read_reg(QPNP_REVISION3, &rev);
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_REVISION3, &rev);
if (rc) {
pr_err("adc-tm revision read failed\n");
return rc;
}
- rc = qpnp_adc_tm_read_reg(QPNP_PERPH_SUBTYPE, &perph_subtype);
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_PERPH_SUBTYPE, &perph_subtype);
if (rc) {
pr_err("adc-tm perph_subtype read failed\n");
return rc;
@@ -394,21 +412,23 @@
return rc;
}
-static int32_t qpnp_adc_tm_mode_select(u8 mode_ctl)
+static int32_t qpnp_adc_tm_mode_select(struct qpnp_adc_tm_chip *chip,
+ 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);
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_MODE_CTL, mode_ctl);
if (rc < 0)
pr_err("adc-tm write mode selection err\n");
return rc;
}
-static int32_t qpnp_adc_tm_timer_interval_select(uint32_t btm_chan,
+static int32_t qpnp_adc_tm_timer_interval_select(
+ struct qpnp_adc_tm_chip *chip, uint32_t btm_chan,
struct qpnp_vadc_chan_properties *chan_prop)
{
int rc;
@@ -417,7 +437,8 @@
/* 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,
+ rc = qpnp_adc_tm_write_reg(chip,
+ QPNP_ADC_TM_MEAS_INTERVAL_CTL,
chan_prop->meas_interval1);
if (rc < 0) {
pr_err("timer1 configure failed\n");
@@ -426,7 +447,8 @@
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,
+ rc = qpnp_adc_tm_read_reg(chip,
+ QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
&meas_interval_timer2);
if (rc < 0) {
pr_err("timer2 configure read failed\n");
@@ -435,7 +457,8 @@
meas_interval_timer2 |=
(chan_prop->meas_interval2 <<
QPNP_ADC_TM_MEAS_INTERVAL_CTL2_SHIFT);
- rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
+ rc = qpnp_adc_tm_write_reg(chip,
+ QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
meas_interval_timer2);
if (rc < 0) {
pr_err("timer2 configure failed\n");
@@ -443,7 +466,8 @@
}
break;
case ADC_MEAS_TIMER_SELECT3:
- rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
+ rc = qpnp_adc_tm_read_reg(chip,
+ QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
&meas_interval_timer2);
if (rc < 0) {
pr_err("timer3 read failed\n");
@@ -451,7 +475,8 @@
}
chan_prop->meas_interval2 = ADC_MEAS3_INTERVAL_1S;
meas_interval_timer2 |= chan_prop->meas_interval2;
- rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
+ rc = qpnp_adc_tm_write_reg(chip,
+ QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
meas_interval_timer2);
if (rc < 0) {
pr_err("timer3 configure failed\n");
@@ -469,13 +494,13 @@
return rc;
}
-static int32_t qpnp_adc_tm_reg_update(uint16_t addr,
- u8 mask, bool state)
+static int32_t qpnp_adc_tm_reg_update(struct qpnp_adc_tm_chip *chip,
+ uint16_t addr, u8 mask, bool state)
{
u8 reg_value = 0;
int rc = 0;
- rc = qpnp_adc_tm_read_reg(addr, ®_value);
+ rc = qpnp_adc_tm_read_reg(chip, addr, ®_value);
if (rc < 0) {
pr_err("read failed for addr:0x%x\n", addr);
return rc;
@@ -487,7 +512,7 @@
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);
+ rc = qpnp_adc_tm_write_reg(chip, addr, reg_value);
if (rc < 0) {
pr_err("write failed for addr:%x\n", addr);
return rc;
@@ -496,12 +521,13 @@
return rc;
}
-static int32_t qpnp_adc_tm_thr_update(uint32_t btm_chan,
+static int32_t qpnp_adc_tm_thr_update(struct qpnp_adc_tm_chip *chip,
+ uint32_t btm_chan,
struct qpnp_vadc_chan_properties *chan_prop)
{
int rc = 0;
- rc = qpnp_adc_tm_write_reg(
+ rc = qpnp_adc_tm_write_reg(chip,
adc_tm_data[btm_chan].low_thr_lsb_addr,
QPNP_ADC_TM_THR_LSB_MASK(chan_prop->low_thr));
if (rc < 0) {
@@ -509,7 +535,7 @@
return rc;
}
- rc = qpnp_adc_tm_write_reg(
+ rc = qpnp_adc_tm_write_reg(chip,
adc_tm_data[btm_chan].low_thr_msb_addr,
QPNP_ADC_TM_THR_MSB_MASK(chan_prop->low_thr));
if (rc < 0) {
@@ -517,7 +543,7 @@
return rc;
}
- rc = qpnp_adc_tm_write_reg(
+ rc = qpnp_adc_tm_write_reg(chip,
adc_tm_data[btm_chan].high_thr_lsb_addr,
QPNP_ADC_TM_THR_LSB_MASK(chan_prop->high_thr));
if (rc < 0) {
@@ -525,7 +551,7 @@
return rc;
}
- rc = qpnp_adc_tm_write_reg(
+ rc = qpnp_adc_tm_write_reg(chip,
adc_tm_data[btm_chan].high_thr_msb_addr,
QPNP_ADC_TM_THR_MSB_MASK(chan_prop->high_thr));
if (rc < 0)
@@ -537,17 +563,17 @@
return rc;
}
-static int32_t qpnp_adc_tm_channel_configure(uint32_t btm_chan,
+static int32_t qpnp_adc_tm_channel_configure(struct qpnp_adc_tm_chip *chip,
+ uint32_t btm_chan,
struct qpnp_vadc_chan_properties *chan_prop,
uint32_t amux_channel)
{
- 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;
- while (i < adc_tm->max_channels_available) {
- if (adc_tm->sensor[i].btm_channel_num == btm_chan) {
+ while (i < chip->max_channels_available) {
+ if (chip->sensor[i].btm_channel_num == btm_chan) {
chan_idx = i;
chan_found = true;
i++;
@@ -561,9 +587,9 @@
}
sensor_mask = 1 << chan_idx;
- if (!adc_tm->sensor[chan_idx].thermal_node) {
+ if (!chip->sensor[chan_idx].thermal_node) {
/* Update low and high notification thresholds */
- rc = qpnp_adc_tm_thr_update(btm_chan,
+ rc = qpnp_adc_tm_thr_update(chip, btm_chan,
chan_prop);
if (rc < 0) {
pr_err("setting chan:%d threshold failed\n", btm_chan);
@@ -577,7 +603,7 @@
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_reg_update(
+ rc = qpnp_adc_tm_reg_update(chip,
QPNP_ADC_TM_LOW_THR_INT_EN, sensor_mask, true);
if (rc < 0) {
pr_err("low thr enable err:%d\n", btm_chan);
@@ -591,7 +617,7 @@
ADC_TM_HIGH_LOW_THR_ENABLE)) {
/* Enable high threshold's interrupt */
pr_debug("high sensor mask:%x\n", sensor_mask);
- rc = qpnp_adc_tm_reg_update(
+ rc = qpnp_adc_tm_reg_update(chip,
QPNP_ADC_TM_HIGH_THR_INT_EN, sensor_mask, true);
if (rc < 0) {
pr_err("high thr enable err:%d\n", btm_chan);
@@ -601,7 +627,7 @@
}
/* Enable corresponding BTM channel measurement */
- rc = qpnp_adc_tm_reg_update(
+ rc = qpnp_adc_tm_reg_update(chip,
QPNP_ADC_TM_MULTI_MEAS_EN, sensor_mask, true);
if (rc < 0) {
pr_err("multi measurement en failed\n");
@@ -611,7 +637,7 @@
return rc;
}
-static int32_t qpnp_adc_tm_configure(
+static int32_t qpnp_adc_tm_configure(struct qpnp_adc_tm_chip *chip,
struct qpnp_adc_amux_properties *chan_prop)
{
u8 decimation = 0, op_cntrl = 0;
@@ -619,19 +645,19 @@
uint32_t btm_chan = 0;
/* Disable bank */
- rc = qpnp_adc_tm_disable();
+ rc = qpnp_adc_tm_disable(chip);
if (rc)
return rc;
/* Check if a conversion is in progress */
- rc = qpnp_adc_tm_req_sts_check();
+ rc = qpnp_adc_tm_req_sts_check(chip);
if (rc < 0) {
pr_err("adc-tm req_sts check failed\n");
return rc;
}
/* Set measurement in recurring mode */
- rc = qpnp_adc_tm_mode_select(chan_prop->mode_sel);
+ rc = qpnp_adc_tm_mode_select(chip, chan_prop->mode_sel);
if (rc < 0) {
pr_err("adc-tm mode select failed\n");
return rc;
@@ -639,7 +665,7 @@
/* 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);
+ rc = qpnp_adc_tm_write_reg(chip, btm_chan, chan_prop->amux_channel);
if (rc < 0) {
pr_err("adc-tm channel selection err\n");
return rc;
@@ -648,14 +674,14 @@
/* Digital paramater setup */
decimation |= chan_prop->decimation <<
QPNP_ADC_DIG_DEC_RATIO_SEL_SHIFT;
- rc = qpnp_adc_tm_write_reg(QPNP_ADC_DIG_PARAM, decimation);
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_ADC_DIG_PARAM, decimation);
if (rc < 0) {
pr_err("adc-tm digital parameter setup err\n");
return rc;
}
/* Hardware setting time */
- rc = qpnp_adc_tm_write_reg(QPNP_HW_SETTLE_DELAY,
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_HW_SETTLE_DELAY,
chan_prop->hw_settle_time);
if (rc < 0) {
pr_err("adc-tm hw settling time setup err\n");
@@ -663,7 +689,7 @@
}
/* Fast averaging setup */
- rc = qpnp_adc_tm_write_reg(QPNP_FAST_AVG_CTL,
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_FAST_AVG_CTL,
chan_prop->fast_avg_setup);
if (rc < 0) {
pr_err("adc-tm fast-avg setup err\n");
@@ -671,7 +697,7 @@
}
/* Measurement interval setup */
- rc = qpnp_adc_tm_timer_interval_select(btm_chan,
+ rc = qpnp_adc_tm_timer_interval_select(chip, btm_chan,
chan_prop->chan_prop);
if (rc < 0) {
pr_err("adc-tm timer select failed\n");
@@ -679,17 +705,18 @@
}
/* Channel configuration setup */
- rc = qpnp_adc_tm_channel_configure(btm_chan, chan_prop->chan_prop,
- chan_prop->amux_channel);
+ rc = qpnp_adc_tm_channel_configure(chip, btm_chan,
+ chan_prop->chan_prop, chan_prop->amux_channel);
if (rc < 0) {
pr_err("adc-tm channel configure failed\n");
return rc;
}
/* Recurring interval measurement enable */
- rc = qpnp_adc_tm_read_reg(QPNP_ADC_MEAS_INTERVAL_OP_CTL, &op_cntrl);
+ rc = qpnp_adc_tm_read_reg(chip, 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,
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_ADC_MEAS_INTERVAL_OP_CTL,
op_cntrl, true);
if (rc < 0) {
pr_err("adc-tm meas interval op configure failed\n");
@@ -697,12 +724,12 @@
}
/* Enable bank */
- rc = qpnp_adc_tm_enable();
+ rc = qpnp_adc_tm_enable(chip);
if (rc)
return rc;
/* Request conversion */
- rc = qpnp_adc_tm_write_reg(QPNP_CONV_REQ, QPNP_CONV_REQ_SET);
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_CONV_REQ, QPNP_CONV_REQ_SET);
if (rc < 0) {
pr_err("adc-tm request conversion failed\n");
return rc;
@@ -714,13 +741,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_sensor = thermal->devdata;
+ struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
- if (!adc_tm_sensor || qpnp_adc_tm_check_revision(
- adc_tm_sensor->btm_channel_num) || !mode)
+ if ((IS_ERR(adc_tm)) || qpnp_adc_tm_check_revision(
+ adc_tm->chip, adc_tm->btm_channel_num))
return -EINVAL;
- *mode = adc_tm_sensor->mode;
+ *mode = adc_tm->mode;
return 0;
}
@@ -729,35 +756,38 @@
enum thermal_device_mode mode)
{
struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
- struct qpnp_adc_tm_drv *adc_drv = qpnp_adc_tm;
+ struct qpnp_adc_tm_chip *chip = adc_tm->chip;
int rc = 0, channel;
u8 sensor_mask = 0;
- if (!adc_tm || qpnp_adc_tm_check_revision(adc_tm->btm_channel_num))
+ if (qpnp_adc_tm_is_valid(chip))
+ return -ENODEV;
+
+ if (qpnp_adc_tm_check_revision(chip, adc_tm->btm_channel_num))
return -EINVAL;
if (mode == THERMAL_DEVICE_ENABLED) {
- adc_drv->adc->amux_prop->amux_channel =
+ chip->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;
- adc_drv->adc->amux_prop->hw_settle_time =
- adc_drv->adc->adc_channels[channel].hw_settle_time;
- adc_drv->adc->amux_prop->fast_avg_setup =
- adc_drv->adc->adc_channels[channel].fast_avg_setup;
- adc_drv->adc->amux_prop->mode_sel =
+ chip->adc->amux_prop->decimation =
+ chip->adc->adc_channels[channel].adc_decimation;
+ chip->adc->amux_prop->hw_settle_time =
+ chip->adc->adc_channels[channel].hw_settle_time;
+ chip->adc->amux_prop->fast_avg_setup =
+ chip->adc->adc_channels[channel].fast_avg_setup;
+ chip->adc->amux_prop->mode_sel =
ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
- adc_drv->adc->amux_prop->chan_prop->timer_select =
+ chip->adc->amux_prop->chan_prop->timer_select =
ADC_MEAS_TIMER_SELECT1;
- adc_drv->adc->amux_prop->chan_prop->meas_interval1 =
+ chip->adc->amux_prop->chan_prop->meas_interval1 =
ADC_MEAS1_INTERVAL_1S;
- adc_drv->adc->amux_prop->chan_prop->low_thr = adc_tm->low_thr;
- adc_drv->adc->amux_prop->chan_prop->high_thr = adc_tm->high_thr;
- adc_drv->adc->amux_prop->chan_prop->tm_channel_select =
+ chip->adc->amux_prop->chan_prop->low_thr = adc_tm->low_thr;
+ chip->adc->amux_prop->chan_prop->high_thr = adc_tm->high_thr;
+ chip->adc->amux_prop->chan_prop->tm_channel_select =
adc_tm->btm_channel_num;
- rc = qpnp_adc_tm_configure(adc_drv->adc->amux_prop);
+ rc = qpnp_adc_tm_configure(chip, chip->adc->amux_prop);
if (rc) {
pr_err("adc-tm tm configure failed with %d\n", rc);
return -EINVAL;
@@ -765,27 +795,27 @@
} else if (mode == THERMAL_DEVICE_DISABLED) {
sensor_mask = 1 << adc_tm->sensor_num;
/* Disable bank */
- rc = qpnp_adc_tm_disable();
+ rc = qpnp_adc_tm_disable(chip);
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();
+ rc = qpnp_adc_tm_req_sts_check(chip);
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);
+ rc = qpnp_adc_tm_reg_update(chip,
+ 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_if_channel_meas();
+ rc = qpnp_adc_tm_enable_if_channel_meas(chip);
if (rc < 0) {
pr_err("re-enabling measurement failed\n");
return rc;
@@ -801,9 +831,12 @@
int trip, enum thermal_trip_type *type)
{
struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
+ struct qpnp_adc_tm_chip *chip = adc_tm->chip;
- if (!adc_tm || qpnp_adc_tm_check_revision(adc_tm->btm_channel_num)
- || !type || type < 0)
+ if (qpnp_adc_tm_is_valid(chip))
+ return -ENODEV;
+
+ if (qpnp_adc_tm_check_revision(chip, adc_tm->btm_channel_num))
return -EINVAL;
switch (trip) {
@@ -824,15 +857,17 @@
int trip, unsigned long *temp)
{
struct qpnp_adc_tm_sensor *adc_tm_sensor = thermal->devdata;
- struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ struct qpnp_adc_tm_chip *chip = adc_tm_sensor->chip;
int64_t result = 0;
u8 trip_cool_thr0, trip_cool_thr1, trip_warm_thr0, trip_warm_thr1;
unsigned int reg, rc = 0, btm_channel_num;
uint16_t reg_low_thr_lsb, reg_low_thr_msb;
uint16_t reg_high_thr_lsb, reg_high_thr_msb;
- if (!adc_tm || qpnp_adc_tm_check_revision(
- adc_tm_sensor->btm_channel_num))
+ if (qpnp_adc_tm_is_valid(chip))
+ return -ENODEV;
+
+ if (qpnp_adc_tm_check_revision(chip, adc_tm_sensor->btm_channel_num))
return -EINVAL;
btm_channel_num = adc_tm_sensor->btm_channel_num;
@@ -843,13 +878,15 @@
switch (trip) {
case ADC_TM_TRIP_HIGH_WARM:
- rc = qpnp_adc_tm_read_reg(reg_low_thr_lsb, &trip_warm_thr0);
+ rc = qpnp_adc_tm_read_reg(chip, reg_low_thr_lsb,
+ &trip_warm_thr0);
if (rc) {
pr_err("adc-tm low_thr_lsb err\n");
return rc;
}
- rc = qpnp_adc_tm_read_reg(reg_low_thr_msb, &trip_warm_thr1);
+ rc = qpnp_adc_tm_read_reg(chip, reg_low_thr_msb,
+ &trip_warm_thr1);
if (rc) {
pr_err("adc-tm low_thr_msb err\n");
return rc;
@@ -857,13 +894,15 @@
reg = (trip_warm_thr1 << 8) | trip_warm_thr0;
break;
case ADC_TM_TRIP_LOW_COOL:
- rc = qpnp_adc_tm_read_reg(reg_high_thr_lsb, &trip_cool_thr0);
+ rc = qpnp_adc_tm_read_reg(chip, reg_high_thr_lsb,
+ &trip_cool_thr0);
if (rc) {
pr_err("adc-tm_tm high_thr_lsb err\n");
return rc;
}
- rc = qpnp_adc_tm_read_reg(reg_high_thr_msb, &trip_cool_thr1);
+ rc = qpnp_adc_tm_read_reg(chip, reg_high_thr_msb,
+ &trip_cool_thr1);
if (rc) {
pr_err("adc-tm_tm high_thr_lsb err\n");
return rc;
@@ -874,7 +913,7 @@
return -EINVAL;
}
- rc = qpnp_adc_tm_scale_voltage_therm_pu2(adc_tm->vadc_dev, reg,
+ rc = qpnp_adc_tm_scale_voltage_therm_pu2(chip->vadc_dev, reg,
&result);
if (rc < 0) {
pr_err("Failed to lookup the therm thresholds\n");
@@ -889,19 +928,21 @@
static int qpnp_adc_tm_set_trip_temp(struct thermal_zone_device *thermal,
int trip, long temp)
{
- struct qpnp_adc_tm_sensor *adc_tm_sensor = thermal->devdata;
- struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
+ struct qpnp_adc_tm_chip *chip = adc_tm->chip;
struct qpnp_adc_tm_config tm_config;
u8 trip_cool_thr0, trip_cool_thr1, trip_warm_thr0, trip_warm_thr1;
uint16_t reg_low_thr_lsb, reg_low_thr_msb;
uint16_t reg_high_thr_lsb, reg_high_thr_msb;
int rc = 0, btm_channel_num;
- if (!adc_tm || qpnp_adc_tm_check_revision(
- adc_tm_sensor->btm_channel_num))
+ if (qpnp_adc_tm_is_valid(chip))
+ return -ENODEV;
+
+ if (qpnp_adc_tm_check_revision(chip, adc_tm->btm_channel_num))
return -EINVAL;
- tm_config.channel = adc_tm_sensor->vadc_channel_num;
+ tm_config.channel = adc_tm->vadc_channel_num;
switch (trip) {
case ADC_TM_TRIP_HIGH_WARM:
tm_config.high_thr_temp = temp;
@@ -915,7 +956,7 @@
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(adc_tm->vadc_dev, &tm_config);
+ rc = qpnp_adc_tm_scale_therm_voltage_pu2(chip->vadc_dev, &tm_config);
if (rc < 0) {
pr_err("Failed to lookup the adc-tm thresholds\n");
return rc;
@@ -926,7 +967,7 @@
trip_cool_thr0 = ((tm_config.high_thr_voltage << 24) >> 24);
trip_cool_thr1 = ((tm_config.high_thr_voltage << 16) >> 24);
- btm_channel_num = adc_tm_sensor->btm_channel_num;
+ btm_channel_num = adc_tm->btm_channel_num;
reg_low_thr_lsb = adc_tm_data[btm_channel_num].low_thr_lsb_addr;
reg_low_thr_msb = adc_tm_data[btm_channel_num].low_thr_msb_addr;
reg_high_thr_lsb = adc_tm_data[btm_channel_num].high_thr_lsb_addr;
@@ -934,32 +975,36 @@
switch (trip) {
case ADC_TM_TRIP_HIGH_WARM:
- rc = qpnp_adc_tm_write_reg(reg_low_thr_lsb, trip_cool_thr0);
+ rc = qpnp_adc_tm_write_reg(chip, reg_low_thr_lsb,
+ trip_cool_thr0);
if (rc) {
pr_err("adc-tm_tm read threshold err\n");
return rc;
}
- rc = qpnp_adc_tm_write_reg(reg_low_thr_msb, trip_cool_thr1);
+ rc = qpnp_adc_tm_write_reg(chip, reg_low_thr_msb,
+ trip_cool_thr1);
if (rc) {
pr_err("adc-tm_tm read threshold err\n");
return rc;
}
- adc_tm_sensor->low_thr = tm_config.high_thr_voltage;
+ adc_tm->low_thr = tm_config.high_thr_voltage;
break;
case ADC_TM_TRIP_LOW_COOL:
- rc = qpnp_adc_tm_write_reg(reg_high_thr_lsb, trip_warm_thr0);
+ rc = qpnp_adc_tm_write_reg(chip, reg_high_thr_lsb,
+ trip_warm_thr0);
if (rc) {
pr_err("adc-tm_tm read threshold err\n");
return rc;
}
- rc = qpnp_adc_tm_write_reg(reg_high_thr_msb, trip_warm_thr1);
+ rc = qpnp_adc_tm_write_reg(chip, reg_high_thr_msb,
+ trip_warm_thr1);
if (rc) {
pr_err("adc-tm_tm read threshold err\n");
return rc;
}
- adc_tm_sensor->high_thr = tm_config.low_thr_voltage;
+ adc_tm->high_thr = tm_config.low_thr_voltage;
break;
default:
return -EINVAL;
@@ -1034,11 +1079,15 @@
int trip, enum thermal_trip_activation_mode mode)
{
struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
+ struct qpnp_adc_tm_chip *chip = adc_tm->chip;
int rc = 0, sensor_mask = 0;
u8 thr_int_en = 0;
bool state = false;
- if (!adc_tm || qpnp_adc_tm_check_revision(adc_tm->btm_channel_num))
+ if (qpnp_adc_tm_is_valid(chip))
+ return -ENODEV;
+
+ if (qpnp_adc_tm_check_revision(chip, adc_tm->btm_channel_num))
return -EINVAL;
if (mode == THERMAL_TRIP_ACTIVATION_ENABLED)
@@ -1053,7 +1102,7 @@
/* 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_reg_update(QPNP_ADC_TM_LOW_THR_INT_EN,
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_ADC_TM_LOW_THR_INT_EN,
sensor_mask, state);
if (rc)
pr_err("channel:%x failed\n", adc_tm->btm_channel_num);
@@ -1062,7 +1111,7 @@
/* 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_reg_update(QPNP_ADC_TM_HIGH_THR_INT_EN,
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_ADC_TM_HIGH_THR_INT_EN,
sensor_mask, state);
if (rc)
pr_err("channel:%x failed\n", adc_tm->btm_channel_num);
@@ -1074,32 +1123,31 @@
return rc;
}
-static int qpnp_adc_tm_read_status(void)
+static int qpnp_adc_tm_read_status(struct qpnp_adc_tm_chip *chip)
{
- 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 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)
+ if (qpnp_adc_tm_is_valid(chip))
return -ENODEV;
- mutex_lock(&adc_tm->adc->adc_lock);
+ mutex_lock(&chip->adc->adc_lock);
- rc = qpnp_adc_tm_req_sts_check();
+ rc = qpnp_adc_tm_req_sts_check(chip);
if (rc) {
pr_err("adc-tm-tm req sts check failed with %d\n", rc);
goto fail;
}
- rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_LOW, &status_low);
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_STATUS_LOW, &status_low);
if (rc) {
pr_err("adc-tm-tm read status low failed with %d\n", rc);
goto fail;
}
- rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_HIGH, &status_high);
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_STATUS_HIGH, &status_high);
if (rc) {
pr_err("adc-tm-tm read status high failed with %d\n", rc);
goto fail;
@@ -1107,7 +1155,7 @@
/* Check which interrupt threshold is lower and measure against the
* enabled channel */
- rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MULTI_MEAS_EN,
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_MULTI_MEAS_EN,
&qpnp_adc_tm_meas_en);
if (rc) {
pr_err("adc-tm-tm read status high failed with %d\n", rc);
@@ -1119,37 +1167,37 @@
if (adc_tm_high_enable) {
sensor_notify_num = adc_tm_high_enable;
- while (i < adc_tm->max_channels_available) {
+ while (i < chip->max_channels_available) {
if ((sensor_notify_num & 0x1) == 1)
sensor_num = i;
sensor_notify_num >>= 1;
i++;
}
- btm_chan_num = adc_tm->sensor[sensor_num].btm_channel_num;
+ btm_chan_num = chip->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) {
+ if (!chip->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(
+ rc = qpnp_adc_tm_reg_update(chip,
QPNP_ADC_TM_HIGH_THR_INT_EN,
sensor_mask, false);
if (rc < 0) {
pr_err("high threshold int read failed\n");
goto fail;
}
- adc_tm->sensor[sensor_num].high_thr_notify = true;
+ chip->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_num].tz_dev,
+ chip->sensor[sensor_num].tz_dev,
ADC_TM_TRIP_LOW_COOL,
THERMAL_TRIP_ACTIVATION_DISABLED);
if (rc < 0) {
@@ -1162,37 +1210,37 @@
if (adc_tm_low_enable) {
sensor_notify_num = adc_tm_low_enable;
i = 0;
- while (i < adc_tm->max_channels_available) {
+ while (i < chip->max_channels_available) {
if ((sensor_notify_num & 0x1) == 1)
sensor_num = i;
sensor_notify_num >>= 1;
i++;
}
- btm_chan_num = adc_tm->sensor[sensor_num].btm_channel_num;
+ btm_chan_num = chip->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) {
+ if (!chip->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(
+ rc = qpnp_adc_tm_reg_update(chip,
QPNP_ADC_TM_LOW_THR_INT_EN,
sensor_mask, false);
if (rc < 0) {
pr_err("low threshold int read failed\n");
goto fail;
}
- adc_tm->sensor[sensor_num].low_thr_notify = true;
+ chip->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_num].tz_dev,
+ chip->sensor[sensor_num].tz_dev,
ADC_TM_TRIP_HIGH_WARM,
THERMAL_TRIP_ACTIVATION_DISABLED);
if (rc < 0) {
@@ -1203,14 +1251,14 @@
}
if (adc_tm_high_enable || adc_tm_low_enable) {
- rc = qpnp_adc_tm_reg_update(QPNP_ADC_TM_MULTI_MEAS_EN,
+ rc = qpnp_adc_tm_reg_update(chip, 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();
+ rc = qpnp_adc_tm_enable_if_channel_meas(chip);
if (rc < 0) {
pr_err("re-enabling measurement failed\n");
return rc;
@@ -1220,62 +1268,67 @@
sensor_mask);
fail:
- mutex_unlock(&adc_tm->adc->adc_lock);
+ mutex_unlock(&chip->adc->adc_lock);
if (adc_tm_high_enable || adc_tm_low_enable)
- schedule_work(&adc_tm->sensor[sensor_num].work);
+ schedule_work(&chip->sensor[sensor_num].work);
return rc;
}
static void qpnp_adc_tm_high_thr_work(struct work_struct *work)
{
+ struct qpnp_adc_tm_chip *chip = container_of(work,
+ struct qpnp_adc_tm_chip, trigger_high_thr_work);
int rc;
- rc = qpnp_adc_tm_read_status();
+ rc = qpnp_adc_tm_read_status(chip);
if (rc < 0)
pr_err("adc-tm high thr work failed\n");
return;
}
-DECLARE_WORK(trigger_completion_adc_tm_high_thr_work,
- qpnp_adc_tm_high_thr_work);
static irqreturn_t qpnp_adc_tm_high_thr_isr(int irq, void *data)
{
- qpnp_adc_tm_disable();
+ struct qpnp_adc_tm_chip *chip = data;
- schedule_work(&trigger_completion_adc_tm_high_thr_work);
+ qpnp_adc_tm_disable(chip);
+
+ schedule_work(&chip->trigger_high_thr_work);
return IRQ_HANDLED;
}
static void qpnp_adc_tm_low_thr_work(struct work_struct *work)
{
+ struct qpnp_adc_tm_chip *chip = container_of(work,
+ struct qpnp_adc_tm_chip, trigger_low_thr_work);
int rc;
- rc = qpnp_adc_tm_read_status();
+ rc = qpnp_adc_tm_read_status(chip);
if (rc < 0)
pr_err("adc-tm low thr work failed\n");
return;
}
-DECLARE_WORK(trigger_completion_adc_tm_low_thr_work, qpnp_adc_tm_low_thr_work);
static irqreturn_t qpnp_adc_tm_low_thr_isr(int irq, void *data)
{
- qpnp_adc_tm_disable();
+ struct qpnp_adc_tm_chip *chip = data;
- schedule_work(&trigger_completion_adc_tm_low_thr_work);
+ qpnp_adc_tm_disable(chip);
+
+ schedule_work(&chip->trigger_low_thr_work);
return IRQ_HANDLED;
}
-static irqreturn_t qpnp_adc_tm_isr(int irq, void *dev_id)
+static irqreturn_t qpnp_adc_tm_isr(int irq, void *data)
{
- struct qpnp_adc_tm_drv *adc_tm = dev_id;
+ struct qpnp_adc_tm_chip *chip = data;
- complete(&adc_tm->adc->adc_rslt_completion);
+ complete(&chip->adc->adc_rslt_completion);
return IRQ_HANDLED;
}
@@ -1284,11 +1337,11 @@
unsigned long *temp)
{
struct qpnp_adc_tm_sensor *adc_tm_sensor = thermal->devdata;
- struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ struct qpnp_adc_tm_chip *chip = adc_tm_sensor->chip;
struct qpnp_vadc_result result;
int rc = 0;
- rc = qpnp_vadc_read(adc_tm->vadc_dev,
+ rc = qpnp_vadc_read(chip->vadc_dev,
adc_tm_sensor->vadc_channel_num, &result);
if (rc)
return rc;
@@ -1308,14 +1361,14 @@
.set_trip_temp = qpnp_adc_tm_set_trip_temp,
};
-int32_t qpnp_adc_tm_channel_measure(struct qpnp_adc_tm_btm_param *param)
+int32_t qpnp_adc_tm_channel_measure(struct qpnp_adc_tm_chip *chip,
+ struct qpnp_adc_tm_btm_param *param)
{
- struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
uint32_t channel, dt_index = 0, scale_type = 0;
int rc = 0, i = 0;
bool chan_found = false;
- if (!adc_tm || !adc_tm->adc_tm_initialized)
+ if (qpnp_adc_tm_is_valid(chip))
return -ENODEV;
if (param->threshold_notification == NULL) {
@@ -1323,11 +1376,11 @@
return -EINVAL;
}
- mutex_lock(&adc_tm->adc->adc_lock);
+ mutex_lock(&chip->adc->adc_lock);
channel = param->channel;
- while (i < adc_tm->max_channels_available) {
- if (adc_tm->adc->adc_channels[i].channel_num ==
+ while (i < chip->max_channels_available) {
+ if (chip->adc->adc_channels[i].channel_num ==
channel) {
dt_index = i;
chan_found = true;
@@ -1342,12 +1395,12 @@
goto fail_unlock;
}
- rc = qpnp_adc_tm_check_revision(
- adc_tm->sensor[dt_index].btm_channel_num);
+ rc = qpnp_adc_tm_check_revision(chip,
+ chip->sensor[dt_index].btm_channel_num);
if (rc < 0)
goto fail_unlock;
- scale_type = adc_tm->adc->adc_channels[dt_index].adc_scale_fn;
+ scale_type = chip->adc->adc_channels[dt_index].adc_scale_fn;
if (scale_type >= SCALE_RSCALE_NONE) {
rc = -EBADF;
goto fail_unlock;
@@ -1355,155 +1408,158 @@
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[dt_index].adc_decimation;
- adc_tm->adc->amux_prop->hw_settle_time =
- adc_tm->adc->adc_channels[dt_index].hw_settle_time;
- adc_tm->adc->amux_prop->fast_avg_setup =
- adc_tm->adc->adc_channels[dt_index].fast_avg_setup;
- adc_tm->adc->amux_prop->mode_sel =
+ chip->adc->amux_prop->amux_channel = channel;
+ chip->adc->amux_prop->decimation =
+ chip->adc->adc_channels[dt_index].adc_decimation;
+ chip->adc->amux_prop->hw_settle_time =
+ chip->adc->adc_channels[dt_index].hw_settle_time;
+ chip->adc->amux_prop->fast_avg_setup =
+ chip->adc->adc_channels[dt_index].fast_avg_setup;
+ chip->adc->amux_prop->mode_sel =
ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
- adc_tm->adc->amux_prop->chan_prop->meas_interval1 =
+ chip->adc->amux_prop->chan_prop->meas_interval1 =
ADC_MEAS1_INTERVAL_1S;
- adc_tm_rscale_fn[scale_type].chan(adc_tm->vadc_dev, 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 =
- adc_tm->sensor[dt_index].btm_channel_num;
- adc_tm->adc->amux_prop->chan_prop->timer_select =
+ adc_tm_rscale_fn[scale_type].chan(chip->vadc_dev, param,
+ &chip->adc->amux_prop->chan_prop->low_thr,
+ &chip->adc->amux_prop->chan_prop->high_thr);
+ chip->adc->amux_prop->chan_prop->tm_channel_select =
+ chip->sensor[dt_index].btm_channel_num;
+ chip->adc->amux_prop->chan_prop->timer_select =
ADC_MEAS_TIMER_SELECT1;
- adc_tm->adc->amux_prop->chan_prop->state_request =
+ chip->adc->amux_prop->chan_prop->state_request =
param->state_request;
- rc = qpnp_adc_tm_configure(adc_tm->adc->amux_prop);
+ rc = qpnp_adc_tm_configure(chip, chip->adc->amux_prop);
if (rc) {
pr_err("adc-tm configure failed with %d\n", rc);
goto fail_unlock;
}
- adc_tm->sensor[dt_index].btm_param = param;
- adc_tm->sensor[dt_index].scale_type = scale_type;
+ chip->sensor[dt_index].btm_param = param;
+ chip->sensor[dt_index].scale_type = scale_type;
fail_unlock:
- mutex_unlock(&adc_tm->adc->adc_lock);
+ mutex_unlock(&chip->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)
+int32_t qpnp_adc_tm_disable_chan_meas(struct qpnp_adc_tm_chip *chip,
+ 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)
+ if (qpnp_adc_tm_is_valid(chip))
return -ENODEV;
- mutex_lock(&adc_tm->adc->adc_lock);
+ mutex_lock(&chip->adc->adc_lock);
/* Disable bank */
- rc = qpnp_adc_tm_disable();
+ rc = qpnp_adc_tm_disable(chip);
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();
+ rc = qpnp_adc_tm_req_sts_check(chip);
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))
+ while ((chip->adc->adc_channels[dt_index].channel_num
+ != channel) && (dt_index < chip->max_channels_available))
dt_index++;
- if (dt_index >= adc_tm->max_channels_available) {
+ if (dt_index >= chip->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;
+ btm_chan_num = chip->sensor[dt_index].btm_channel_num;
+ sensor_mask = 1 << chip->sensor[dt_index].sensor_num;
- rc = qpnp_adc_tm_reg_update(QPNP_ADC_TM_LOW_THR_INT_EN,
+ rc = qpnp_adc_tm_reg_update(chip, 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,
+ rc = qpnp_adc_tm_reg_update(chip, 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,
+ rc = qpnp_adc_tm_reg_update(chip, 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();
+ rc = qpnp_adc_tm_enable_if_channel_meas(chip);
if (rc < 0)
pr_err("re-enabling measurement failed\n");
fail:
- mutex_unlock(&adc_tm->adc->adc_lock);
+ mutex_unlock(&chip->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)
+int32_t qpnp_adc_tm_usbid_configure(struct qpnp_adc_tm_chip *chip,
+ struct qpnp_adc_tm_btm_param *param)
{
param->channel = LR_MUX10_PU2_AMUX_USB_ID_LV;
- return qpnp_adc_tm_channel_measure(param);
+ return qpnp_adc_tm_channel_measure(chip, param);
}
EXPORT_SYMBOL(qpnp_adc_tm_usbid_configure);
-int32_t qpnp_adc_tm_usbid_end(void)
+int32_t qpnp_adc_tm_usbid_end(struct qpnp_adc_tm_chip *chip)
{
struct qpnp_adc_tm_btm_param param;
- return qpnp_adc_tm_disable_chan_meas(¶m);
+ return qpnp_adc_tm_disable_chan_meas(chip, ¶m);
}
EXPORT_SYMBOL(qpnp_adc_tm_usbid_end);
-int32_t qpnp_adc_tm_is_ready(void)
+struct qpnp_adc_tm_chip *qpnp_get_adc_tm(struct device *dev, const char *name)
{
- struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ struct qpnp_adc_tm_chip *chip;
+ struct device_node *node = NULL;
+ char prop_name[QPNP_MAX_PROP_NAME_LEN];
- if (!adc_tm || !adc_tm->adc_tm_initialized)
- return -EPROBE_DEFER;
- else
- return 0;
+ snprintf(prop_name, QPNP_MAX_PROP_NAME_LEN, "qcom,%s-adc_tm", name);
+
+ node = of_parse_phandle(dev->of_node, prop_name, 0);
+ if (node == NULL)
+ return ERR_PTR(-ENODEV);
+
+ list_for_each_entry(chip, &qpnp_adc_tm_device_list, list)
+ if (chip->adc->spmi->dev.of_node == node)
+ return chip;
+
+ return ERR_PTR(-EPROBE_DEFER);
}
-EXPORT_SYMBOL(qpnp_adc_tm_is_ready);
+EXPORT_SYMBOL(qpnp_get_adc_tm);
static int __devinit qpnp_adc_tm_probe(struct spmi_device *spmi)
{
struct device_node *node = spmi->dev.of_node, *child;
- struct qpnp_adc_tm_drv *adc_tm;
+ struct qpnp_adc_tm_chip *chip;
struct qpnp_adc_drv *adc_qpnp;
- int32_t count_adc_channel_list = 0, rc, sen_idx = 0;
+ int32_t count_adc_channel_list = 0, rc, sen_idx = 0, i = 0;
u8 thr_init = 0;
-
- if (!node)
- return -EINVAL;
-
- if (qpnp_adc_tm) {
- pr_err("adc-tm already in use\n");
- return -EBUSY;
- }
+ bool thermal_node = false;
for_each_child_of_node(node, child)
count_adc_channel_list++;
@@ -1513,16 +1569,15 @@
return -EINVAL;
}
- adc_tm = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_adc_tm_drv) +
+ chip = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_adc_tm_chip) +
(count_adc_channel_list *
sizeof(struct qpnp_adc_tm_sensor)),
GFP_KERNEL);
- if (!adc_tm) {
+ if (!chip) {
dev_err(&spmi->dev, "Unable to allocate memory\n");
return -ENOMEM;
}
- qpnp_adc_tm = adc_tm;
adc_qpnp = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_adc_drv),
GFP_KERNEL);
if (!adc_qpnp) {
@@ -1531,75 +1586,74 @@
goto fail;
}
- adc_tm->adc = adc_qpnp;
+ chip->adc = adc_qpnp;
- rc = qpnp_adc_get_devicetree_data(spmi, adc_tm->adc);
+ rc = qpnp_adc_get_devicetree_data(spmi, chip->adc);
if (rc) {
dev_err(&spmi->dev, "failed to read device tree\n");
goto fail;
}
- mutex_init(&adc_tm->adc->adc_lock);
+ mutex_init(&chip->adc->adc_lock);
/* Register the ADC peripheral interrupt */
- adc_tm->adc->adc_high_thr_irq = spmi_get_irq_byname(spmi,
+ chip->adc->adc_high_thr_irq = spmi_get_irq_byname(spmi,
NULL, "high-thr-en-set");
- if (adc_tm->adc->adc_high_thr_irq < 0) {
+ if (chip->adc->adc_high_thr_irq < 0) {
pr_err("Invalid irq\n");
rc = -ENXIO;
goto fail;
}
- adc_tm->adc->adc_low_thr_irq = spmi_get_irq_byname(spmi,
+ chip->adc->adc_low_thr_irq = spmi_get_irq_byname(spmi,
NULL, "low-thr-en-set");
- if (adc_tm->adc->adc_low_thr_irq < 0) {
+ if (chip->adc->adc_low_thr_irq < 0) {
pr_err("Invalid irq\n");
rc = -ENXIO;
goto fail;
}
- adc_tm->vadc_dev = qpnp_get_vadc(&spmi->dev, "adc_tm");
- if (IS_ERR(adc_tm->vadc_dev)) {
- rc = PTR_ERR(adc_tm->vadc_dev);
+ chip->vadc_dev = qpnp_get_vadc(&spmi->dev, "adc_tm");
+ if (IS_ERR(chip->vadc_dev)) {
+ rc = PTR_ERR(chip->vadc_dev);
if (rc != -EPROBE_DEFER)
pr_err("vadc property missing, rc=%d\n", rc);
goto fail;
}
- rc = devm_request_irq(&spmi->dev, adc_tm->adc->adc_irq_eoc,
+ rc = devm_request_irq(&spmi->dev, chip->adc->adc_irq_eoc,
qpnp_adc_tm_isr, IRQF_TRIGGER_RISING,
- "qpnp_adc_tm_interrupt", adc_tm);
+ "qpnp_adc_tm_interrupt", chip);
if (rc) {
dev_err(&spmi->dev,
"failed to request adc irq with error %d\n", rc);
goto fail;
} else {
- enable_irq_wake(adc_tm->adc->adc_irq_eoc);
+ enable_irq_wake(chip->adc->adc_irq_eoc);
}
- rc = devm_request_irq(&spmi->dev, adc_tm->adc->adc_high_thr_irq,
+ rc = devm_request_irq(&spmi->dev, chip->adc->adc_high_thr_irq,
qpnp_adc_tm_high_thr_isr,
- IRQF_TRIGGER_RISING, "qpnp_adc_tm_high_interrupt", adc_tm);
+ IRQF_TRIGGER_RISING, "qpnp_adc_tm_high_interrupt", chip);
if (rc) {
dev_err(&spmi->dev, "failed to request adc irq\n");
goto fail;
} else {
- enable_irq_wake(adc_tm->adc->adc_high_thr_irq);
+ enable_irq_wake(chip->adc->adc_high_thr_irq);
}
- rc = devm_request_irq(&spmi->dev, adc_tm->adc->adc_low_thr_irq,
+ rc = devm_request_irq(&spmi->dev, chip->adc->adc_low_thr_irq,
qpnp_adc_tm_low_thr_isr,
- IRQF_TRIGGER_RISING, "qpnp_adc_tm_low_interrupt", adc_tm);
+ IRQF_TRIGGER_RISING, "qpnp_adc_tm_low_interrupt", chip);
if (rc) {
dev_err(&spmi->dev, "failed to request adc irq\n");
goto fail;
} else {
- enable_irq_wake(adc_tm->adc->adc_low_thr_irq);
+ enable_irq_wake(chip->adc->adc_low_thr_irq);
}
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);
@@ -1607,80 +1661,95 @@
pr_err("Invalid btm channel number\n");
goto fail;
}
- 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;
+ chip->sensor[sen_idx].btm_channel_num = btm_channel_num;
+ chip->sensor[sen_idx].vadc_channel_num =
+ chip->adc->adc_channels[sen_idx].channel_num;
+ chip->sensor[sen_idx].sensor_num = sen_idx;
+ chip->sensor[sen_idx].chip = chip;
pr_debug("btm_chan:%x, vadc_chan:%x\n", btm_channel_num,
- adc_tm->adc->adc_channels[sen_idx].channel_num);
+ chip->adc->adc_channels[sen_idx].channel_num);
thermal_node = of_property_read_bool(child,
"qcom,thermal-node");
if (thermal_node) {
/* Register with the thermal zone */
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;
+ chip->sensor[sen_idx].mode = THERMAL_DEVICE_DISABLED;
+ chip->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 =
+ chip->adc->adc_channels[sen_idx].name);
+ chip->sensor[sen_idx].meas_interval =
QPNP_ADC_TM_MEAS_INTERVAL;
- adc_tm->sensor[sen_idx].low_thr =
+ chip->sensor[sen_idx].low_thr =
QPNP_ADC_TM_M0_LOW_THR;
- adc_tm->sensor[sen_idx].high_thr =
+ chip->sensor[sen_idx].high_thr =
QPNP_ADC_TM_M0_HIGH_THR;
- adc_tm->sensor[sen_idx].tz_dev =
+ chip->sensor[sen_idx].tz_dev =
thermal_zone_device_register(name,
ADC_TM_TRIP_NUM,
- &adc_tm->sensor[sen_idx],
+ &chip->sensor[sen_idx],
&qpnp_adc_tm_thermal_ops, 0, 0, 0, 0);
- if (IS_ERR(adc_tm->sensor[sen_idx].tz_dev))
+ if (IS_ERR(chip->sensor[sen_idx].tz_dev))
pr_err("thermal device register failed.\n");
}
- INIT_WORK(&adc_tm->sensor[sen_idx].work, notify_adc_tm_fn);
+ INIT_WORK(&chip->sensor[sen_idx].work, notify_adc_tm_fn);
sen_idx++;
}
- 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);
+ chip->max_channels_available = count_adc_channel_list;
+ INIT_WORK(&chip->trigger_high_thr_work, qpnp_adc_tm_high_thr_work);
+ INIT_WORK(&chip->trigger_low_thr_work, qpnp_adc_tm_low_thr_work);
+ dev_set_drvdata(&spmi->dev, chip);
+ list_add(&chip->list, &qpnp_adc_tm_device_list);
+
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_ADC_TM_HIGH_THR_INT_EN,
+ thr_init);
if (rc < 0) {
pr_err("high thr init failed\n");
goto fail;
}
- rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_LOW_THR_INT_EN, thr_init);
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_ADC_TM_LOW_THR_INT_EN,
+ thr_init);
if (rc < 0) {
pr_err("low thr init failed\n");
goto fail;
}
- rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MULTI_MEAS_EN, thr_init);
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_ADC_TM_MULTI_MEAS_EN,
+ thr_init);
if (rc < 0) {
pr_err("multi meas en failed\n");
goto fail;
}
- adc_tm->adc_tm_initialized = true;
-
pr_debug("OK\n");
return 0;
fail:
- qpnp_adc_tm = NULL;
+ for_each_child_of_node(node, child) {
+ thermal_node = of_property_read_bool(child,
+ "qcom,thermal-node");
+ if (thermal_node)
+ thermal_zone_device_unregister(chip->sensor[i].tz_dev);
+ i++;
+ }
+ dev_set_drvdata(&spmi->dev, NULL);
return rc;
}
static int __devexit qpnp_adc_tm_remove(struct spmi_device *spmi)
{
- struct qpnp_adc_tm_drv *adc_tm = dev_get_drvdata(&spmi->dev);
- struct device_node *node = spmi->dev.of_node;
- struct device_node *child;
+ struct qpnp_adc_tm_chip *chip = dev_get_drvdata(&spmi->dev);
+ struct device_node *node = spmi->dev.of_node, *child;
+ bool thermal_node = false;
int i = 0;
for_each_child_of_node(node, child) {
- thermal_zone_device_unregister(adc_tm->sensor[i].tz_dev);
+ thermal_node = of_property_read_bool(child,
+ "qcom,thermal-node");
+ if (thermal_node)
+ thermal_zone_device_unregister(chip->sensor[i].tz_dev);
i++;
}
- adc_tm->adc_tm_initialized = false;
dev_set_drvdata(&spmi->dev, NULL);
return 0;
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index e1a7d58..d3ea3be 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -204,6 +204,7 @@
int pmic_id_irq;
struct work_struct id_work;
struct qpnp_adc_tm_btm_param adc_param;
+ struct qpnp_adc_tm_chip *adc_tm_dev;
struct delayed_work init_adc_work;
bool id_adc_detect;
u8 dcd_retries;
@@ -2356,7 +2357,7 @@
dwc3_id_work(&mdwc->id_work);
/* re-arm ADC interrupt */
- qpnp_adc_tm_usbid_configure(&mdwc->adc_param);
+ qpnp_adc_tm_usbid_configure(mdwc->adc_tm_dev, &mdwc->adc_param);
}
static void dwc3_init_adc_work(struct work_struct *w)
@@ -2365,10 +2366,14 @@
init_adc_work.work);
int ret;
- ret = qpnp_adc_tm_is_ready();
- if (ret == -EPROBE_DEFER) {
- queue_delayed_work(system_nrt_wq, to_delayed_work(w),
+ mdwc->adc_tm_dev = qpnp_get_adc_tm(mdwc->dev, "dwc_usb3-adc_tm");
+ if (IS_ERR(mdwc->adc_tm_dev)) {
+ if (PTR_ERR(mdwc->adc_tm_dev) == -EPROBE_DEFER)
+ queue_delayed_work(system_nrt_wq, to_delayed_work(w),
msecs_to_jiffies(100));
+ else
+ mdwc->adc_tm_dev = NULL;
+
return;
}
@@ -2379,7 +2384,7 @@
mdwc->adc_param.btm_ctx = mdwc;
mdwc->adc_param.threshold_notification = dwc3_adc_notification;
- ret = qpnp_adc_tm_usbid_configure(&mdwc->adc_param);
+ ret = qpnp_adc_tm_usbid_configure(mdwc->adc_tm_dev, &mdwc->adc_param);
if (ret) {
dev_err(mdwc->dev, "%s: request ADC error %d\n", __func__, ret);
return;
@@ -2414,7 +2419,7 @@
dwc3_init_adc_work(&mdwc->init_adc_work.work);
return size;
} else if (!strnicmp(buf, "disable", 7)) {
- qpnp_adc_tm_usbid_end();
+ qpnp_adc_tm_usbid_end(mdwc->adc_tm_dev);
mdwc->id_adc_detect = false;
return size;
}
@@ -3044,7 +3049,7 @@
}
if (mdwc->id_adc_detect)
- qpnp_adc_tm_usbid_end();
+ qpnp_adc_tm_usbid_end(mdwc->adc_tm_dev);
if (dwc3_debugfs_root)
debugfs_remove_recursive(dwc3_debugfs_root);
if (mdwc->otg_xceiv) {
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 06e3a1b..9139447 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -4292,11 +4292,27 @@
goto put_core_clk;
}
+ /*
+ * On few platforms USB PHY is fed with sleep clk.
+ * Hence don't fail probe.
+ */
+ motg->sleep_clk = devm_clk_get(&pdev->dev, "sleep_clk");
+ if (IS_ERR(motg->sleep_clk)) {
+ dev_dbg(&pdev->dev, "failed to get sleep_clk\n");
+ } else {
+ ret = clk_prepare_enable(motg->sleep_clk);
+ if (ret) {
+ dev_err(&pdev->dev, "%s failed to vote sleep_clk%d\n",
+ __func__, ret);
+ goto put_pclk;
+ }
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "failed to get platform resource mem\n");
ret = -ENODEV;
- goto put_pclk;
+ goto disable_sleep_clk;
}
motg->io_res = res;
@@ -4304,7 +4320,7 @@
if (!motg->regs) {
dev_err(&pdev->dev, "ioremap failed\n");
ret = -ENOMEM;
- goto put_pclk;
+ goto disable_sleep_clk;
}
dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs);
@@ -4603,6 +4619,9 @@
msm_xo_put(motg->xo_handle);
free_regs:
iounmap(motg->regs);
+disable_sleep_clk:
+ if (!IS_ERR(motg->sleep_clk))
+ clk_disable_unprepare(motg->sleep_clk);
put_pclk:
clk_put(motg->pclk);
put_core_clk:
@@ -4697,6 +4716,10 @@
} else {
msm_xo_put(motg->xo_handle);
}
+
+ if (!IS_ERR(motg->sleep_clk))
+ clk_disable_unprepare(motg->sleep_clk);
+
msm_hsusb_ldo_enable(motg, USB_PHY_REG_OFF);
msm_hsusb_ldo_init(motg, 0);
regulator_disable(hsusb_vdd);
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index ac87cbd..94fced0 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -274,8 +274,8 @@
{
struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
- if (mfd->ref_cnt > 1)
- mfd->ref_cnt = 1;
+ for (; mfd->ref_cnt > 1; mfd->ref_cnt--)
+ pm_runtime_put(mfd->fbi->dev);
mdss_fb_release(mfd->fbi, 0);
}
@@ -1096,7 +1096,8 @@
mfd->op_enable);
if (result) {
pm_runtime_put(info->dev);
- pr_err("mdss_fb_open: can't turn on display!\n");
+ pr_err("can't turn on fb%d! rc=%d\n", mfd->index,
+ result);
return result;
}
}
@@ -1122,8 +1123,7 @@
ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info,
mfd->op_enable);
if (ret) {
- pr_err("can't turn off display attached to fb%d!\n",
- mfd->index);
+ pr_err("can't turn off fb%d! rc=%d\n", mfd->index, ret);
return ret;
}
}
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index 7609cdc..ad134a0 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -193,12 +193,18 @@
{20480, 247500} } },
};
-static bool is_cea_format(int mode)
+static bool hdmi_tx_is_cea_format(int mode)
{
- if ((mode > 0) && (mode < HDMI_EVFRMT_END))
- return true;
+ bool cea_fmt;
+
+ if ((mode > 0) && (mode <= HDMI_EVFRMT_END))
+ cea_fmt = true;
else
- return false;
+ cea_fmt = false;
+
+ DEV_DBG("%s: %s\n", __func__, cea_fmt ? "Yes" : "No");
+
+ return cea_fmt;
}
const char *hdmi_tx_pm_name(enum hdmi_tx_power_module_type module)
@@ -2211,7 +2217,7 @@
}
if (!hdmi_tx_is_dvi_mode(hdmi_ctrl) &&
- is_cea_format(hdmi_ctrl->video_resolution)) {
+ hdmi_tx_is_cea_format(hdmi_ctrl->video_resolution)) {
rc = hdmi_tx_audio_setup(hdmi_ctrl);
if (rc) {
DEV_ERR("%s: hdmi_msm_audio_setup failed. rc=%d\n",
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 6f9c98e..0a41ef8 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -133,7 +133,6 @@
struct mdss_hw *mdss_irq_handlers[MDSS_MAX_HW_BLK];
static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on);
-static inline int mdss_mdp_suspend_sub(struct mdss_data_type *mdata);
static int mdss_mdp_parse_dt(struct platform_device *pdev);
static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev);
static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev);
@@ -911,18 +910,6 @@
}
}
-static void mdss_mdp_shutdown(struct platform_device *pdev)
-{
- struct mdss_data_type *mdata = platform_get_drvdata(pdev);
-
- if (!mdata)
- return;
-
- pr_debug("display shutdown\n");
-
- mdss_mdp_suspend_sub(mdata);
-}
-
static int mdss_mdp_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -1795,7 +1782,7 @@
.remove = mdss_mdp_remove,
.suspend = mdss_mdp_suspend,
.resume = mdss_mdp_resume,
- .shutdown = mdss_mdp_shutdown,
+ .shutdown = NULL,
.driver = {
/*
* Driver name must match the device name added in
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index 9b81633..6fb8883 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -409,11 +409,9 @@
if (ctx->polling_en) {
rc = mdss_mdp_video_pollwait(ctl);
} else {
- rc = wait_for_completion_interruptible_timeout(&ctx->vsync_comp,
+ rc = wait_for_completion_timeout(&ctx->vsync_comp,
usecs_to_jiffies(VSYNC_TIMEOUT_US));
- if (rc < 0) {
- pr_warn("vsync wait interrupted ctl=%d\n", ctl->num);
- } else if (rc == 0) {
+ if (rc == 0) {
pr_warn("vsync wait timeout %d, fallback to poll mode\n",
ctl->num);
ctx->polling_en++;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 4032b91..c4dee86 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -595,7 +595,8 @@
mutex_lock(&mfd->lock);
if (pipe->play_cnt == 0) {
pr_debug("failed for pipe %d\n", pipe->num);
- list_del(&pipe->used_list);
+ if (!list_empty(&pipe->used_list))
+ list_del_init(&pipe->used_list);
mdss_mdp_pipe_destroy(pipe);
}
@@ -827,20 +828,17 @@
pipe->params_changed++;
buf = &pipe->front_buf;
} else if (!pipe->params_changed) {
- if (pipe->mixer) {
- if (!mdss_mdp_pipe_is_staged(pipe)) {
- list_del(&pipe->used_list);
- list_add(&pipe->cleanup_list,
- &mdp5_data->pipes_cleanup);
- }
+ if (pipe->mixer && !mdss_mdp_pipe_is_staged(pipe) &&
+ !list_empty(&pipe->used_list)) {
+ list_del_init(&pipe->used_list);
+ list_add(&pipe->cleanup_list,
+ &mdp5_data->pipes_cleanup);
}
continue;
} else if (pipe->front_buf.num_planes) {
buf = &pipe->front_buf;
} else {
- pr_warn("pipe queue w/o buffer. unstaging layer\n");
- pipe->params_changed = 0;
- mdss_mdp_mixer_pipe_unstage(pipe);
+ pr_warn("pipe queue w/o buffer\n");
continue;
}
@@ -894,9 +892,11 @@
continue;
}
mutex_lock(&mfd->lock);
- list_del(&pipe->used_list);
- list_add(&pipe->cleanup_list,
- &mdp5_data->pipes_cleanup);
+ if (!list_empty(&pipe->used_list)) {
+ list_del_init(&pipe->used_list);
+ list_add(&pipe->cleanup_list,
+ &mdp5_data->pipes_cleanup);
+ }
mutex_unlock(&mfd->lock);
mdss_mdp_mixer_pipe_unstage(pipe);
mdss_mdp_pipe_unmap(pipe);
diff --git a/include/linux/input/synaptics_dsx.h b/include/linux/input/synaptics_dsx.h
index d121695..73016d6 100644
--- a/include/linux/input/synaptics_dsx.h
+++ b/include/linux/input/synaptics_dsx.h
@@ -35,11 +35,8 @@
* struct synaptics_rmi4_platform_data - rmi4 platform data
* @x_flip: x flip flag
* @y_flip: y flip flag
- * @i2c_pull_up: pull up i2c bus with regulator
- * @power_down_enable: enable complete regulator shutdown in suspend
* @irq_gpio: attention interrupt gpio
* @irq_flags: flags used by the irq
- * @reset_flags: flags used by reset line
* @reset_gpio: reset gpio
* @panel_x: panel maximum values on the x
* @panel_y: panel maximum values on the y
@@ -50,7 +47,6 @@
bool x_flip;
bool y_flip;
bool i2c_pull_up;
- bool power_down_enable;
unsigned irq_gpio;
u32 irq_flags;
u32 reset_flags;
diff --git a/include/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index a9e13d5..4f39eaa 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -143,6 +143,12 @@
/* Structure device for qpnp vadc */
struct qpnp_vadc_chip;
+/* Structure device for qpnp iadc */
+struct qpnp_iadc_chip;
+
+/* Structure device for qpnp adc tm */
+struct qpnp_adc_tm_chip;
+
/**
* enum qpnp_adc_decimation_type - Sampling rate supported.
* %DECIMATION_TYPE1: 512
@@ -1436,44 +1442,59 @@
|| defined(CONFIG_SENSORS_QPNP_ADC_CURRENT_MODULE)
/**
* qpnp_iadc_read() - Performs ADC read on the current channel.
+ * @dev: Structure device for qpnp iadc
* @channel: Input channel to perform the ADC read.
* @result: Current across rsense in mA.
+ * @return: 0 on success.
*/
-int32_t qpnp_iadc_read(enum qpnp_iadc_channels channel,
+int32_t qpnp_iadc_read(struct qpnp_iadc_chip *dev,
+ enum qpnp_iadc_channels channel,
struct qpnp_iadc_result *result);
/**
* qpnp_iadc_get_rsense() - Reads the RDS resistance value from the
trim registers.
+ * @dev: Structure device for qpnp iadc
* @rsense: RDS resistance in nOhms.
+ * @return: 0 on success.
*/
-int32_t qpnp_iadc_get_rsense(int32_t *rsense);
+int32_t qpnp_iadc_get_rsense(struct qpnp_iadc_chip *dev, int32_t *rsense);
/**
* qpnp_iadc_get_gain_and_offset() - Performs gain calibration
* over 17.8571mV and offset over selected
* channel. Channel can be internal rsense,
* external rsense and alternate lead pair.
+ * @dev: Structure device for qpnp iadc
* @result: result structure where the gain and offset is stored of
* type qpnp_iadc_calib.
+ * @return: 0 on success.
*/
-int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_calib *result);
+int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_chip *dev,
+ struct qpnp_iadc_calib *result);
/**
- * qpnp_iadc_is_ready() - Clients can use this API to check if the
- * device is ready to use.
- * @result: 0 on success and -EPROBE_DEFER when probe for the device
- * has not occured.
+ * qpnp_get_iadc() - Clients need to register with the iadc with the
+ * corresponding device instance it wants to read the channels.
+ * Read the bindings document on how to pass the phandle for
+ * the corresponding vadc driver to register with.
+ * @dev: Clients device structure
+ * @name: Corresponding client's DT parser name. Read the DT bindings
+ * document on how to register with the iadc
+ * @struct qpnp_iadc_chip * - On success returns the iadc device structure
+ * pointer used everytime client makes an ADC request.
*/
-int32_t qpnp_iadc_is_ready(void);
+struct qpnp_iadc_chip *qpnp_get_iadc(struct device *dev, const char *name);
/**
* qpnp_iadc_vadc_sync_read() - Performs synchronous VADC and IADC read.
* The api is to be used only by the BMS to perform
* simultaneous VADC and IADC measurement for battery voltage
* and current.
+ * @dev: Structure device for qpnp iadc
* @i_channel: Input battery current channel to perform the IADC read.
* @i_result: Current across the rsense in mA.
* @v_channel: Input battery voltage channel to perform VADC read.
* @v_result: Voltage on the vbatt channel with units in mV.
+ * @return: 0 on success.
*/
-int32_t qpnp_iadc_vadc_sync_read(
+int32_t qpnp_iadc_vadc_sync_read(struct qpnp_iadc_chip *dev,
enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result);
/**
@@ -1481,31 +1502,60 @@
* IADC. The offset and gain values are programmed in the trim
* registers. The offset and the gain can be retrieved using
* qpnp_iadc_get_gain_and_offset
+ * @dev: Structure device for qpnp iadc
* @batfet_closed: batfet is opened or closed. The IADC chooses proper
* channel (internal/external) based on batfet status
* for calibration.
* RETURNS: 0 on success.
*/
-int32_t qpnp_iadc_calibrate_for_trim(bool batfet_closed);
-int32_t qpnp_iadc_comp_result(int64_t *result);
+int32_t qpnp_iadc_calibrate_for_trim(struct qpnp_iadc_chip *dev,
+ bool batfet_closed);
+/**
+ * qpnp_iadc_comp_result() - Compensates the result of the current based on
+ * the gain and offset co-effients and rsense parameters.
+ * @dev: Structure device for qpnp iadc
+ * @result: Current value to perform the compensation.
+ * @return: 0 on success.
+ */
+int32_t qpnp_iadc_comp_result(struct qpnp_iadc_chip *dev, int64_t *result);
+/**
+ * qpnp_iadc_skip_calibration() - Clients can use this API to ask the driver
+ * to skip iadc calibrations
+ * @dev: Structure device for qpnp iadc
+ * @result: 0 on success and -EPROBE_DEFER when probe for the device
+ * has not occured.
+ */
+int qpnp_iadc_skip_calibration(struct qpnp_iadc_chip *dev);
+/**
+ * qpnp_iadc_resume_calibration() - Clients can use this API to ask the driver
+ * to resume iadc calibrations
+ * @dev: Structure device for qpnp iadc
+ * @result: 0 on success and -EPROBE_DEFER when probe for the device
+ * has not occured.
+ */
+int qpnp_iadc_resume_calibration(struct qpnp_iadc_chip *dev);
#else
-static inline int32_t qpnp_iadc_read(enum qpnp_iadc_channels channel,
- struct qpnp_iadc_result *result)
+static inline int32_t qpnp_iadc_read(struct qpnp_iadc_chip *iadc,
+ enum qpnp_iadc_channels channel, struct qpnp_iadc_result *result)
{ return -ENXIO; }
-static inline int32_t qpnp_iadc_get_rsense(int32_t *rsense)
+static inline int32_t qpnp_iadc_get_rsense(struct qpnp_iadc_chip *iadc,
+ int32_t *rsense)
{ return -ENXIO; }
-static inline int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_calib
- *result)
+static inline int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_chip *iadc,
+ struct qpnp_iadc_calib *result)
{ return -ENXIO; }
-static inline int32_t qpnp_iadc_is_ready(void)
-{ return -ENXIO; }
-static inline int32_t qpnp_iadc_vadc_sync_read(
+static inline struct qpnp_iadc_chip *qpnp_get_iadc(struct device *dev,
+ const char *name)
+{ return ERR_PTR(-ENXIO); }
+static inline int32_t qpnp_iadc_vadc_sync_read(struct qpnp_iadc_chip *iadc,
enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result)
{ return -ENXIO; }
-static inline int32_t qpnp_iadc_calibrate_for_trim(bool batfet_closed)
+static inline int32_t qpnp_iadc_calibrate_for_trim(struct qpnp_iadc_chip *iadc,
+ bool batfet_closed)
{ return -ENXIO; }
-static inline int32_t qpnp_iadc_comp_result(int64_t *result, int32_t sign)
+static inline int32_t qpnp_iadc_comp_result(struct qpnp_iadc_chip *iadc,
+ int64_t *result, int32_t sign)
{ return -ENXIO; }
#endif
@@ -1522,14 +1572,15 @@
* Clients pass the low/high voltage along with the threshold
* notification callback.
*/
-int32_t qpnp_adc_tm_usbid_configure(struct qpnp_adc_tm_btm_param *param);
+int32_t qpnp_adc_tm_usbid_configure(struct qpnp_adc_tm_chip *chip,
+ 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
* threshold activation for channel 0 as well.
* @param: none.
*/
-int32_t qpnp_adc_tm_usbid_end(void);
+int32_t qpnp_adc_tm_usbid_end(struct qpnp_adc_tm_chip *chip);
/**
* qpnp_adc_tm_channel_measure() - Configures kernel clients a channel to
* monitor the corresponding ADC channel for threshold detection.
@@ -1540,7 +1591,8 @@
* Clients pass the low/high temperature along with the threshold
* notification callback.
*/
-int32_t qpnp_adc_tm_channel_measure(struct qpnp_adc_tm_btm_param *param);
+int32_t qpnp_adc_tm_channel_measure(struct qpnp_adc_tm_chip *chip,
+ struct qpnp_adc_tm_btm_param *param);
/**
* qpnp_adc_tm_disable_chan_meas() - Disables the monitoring of channel thats
* assigned for monitoring kernel clients. Disables the low/high
@@ -1549,45 +1601,36 @@
* This is used to identify the channel for which the corresponding
* channels high/low threshold notification will be disabled.
*/
-int32_t qpnp_adc_tm_disable_chan_meas(struct qpnp_adc_tm_btm_param *param);
+int32_t qpnp_adc_tm_disable_chan_meas(struct qpnp_adc_tm_chip *chip,
+ 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.
- * @result: 0 on success and -EPROBE_DEFER when probe for the device
- * has not occured.
+ * qpnp_get_adc_tm() - Clients need to register with the adc_tm using the
+ * corresponding device instance it wants to read the channels
+ * from. Read the bindings document on how to pass the phandle
+ * for the corresponding adc_tm driver to register with.
+ * @name: Corresponding client's DT parser name. Read the DT bindings
+ * document on how to register with the vadc
+ * @struct qpnp_adc_tm_chip * - On success returns the vadc device structure
+ * pointer that needs to be used during an ADC TM request.
*/
-int32_t qpnp_adc_tm_is_ready(void);
-/**
- * qpnp_iadc_skip_calibration() - Clients can use this API to ask the driver
- * to skip iadc calibrations
- * @result: 0 on success and -EPROBE_DEFER when probe for the device
- * has not occured.
- */
-int qpnp_iadc_skip_calibration(void);
-/**
- * qpnp_iadc_resume_calibration() - Clients can use this API to ask the driver
- * to resume iadc calibrations
- * @result: 0 on success and -EPROBE_DEFER when probe for the device
- * has not occured.
- */
-int qpnp_iadc_resume_calibration(void);
+struct qpnp_adc_tm_chip *qpnp_get_adc_tm(struct device *dev, const char *name);
#else
static inline int32_t qpnp_adc_tm_usbid_configure(
+ struct qpnp_adc_tm_chip *chip,
struct qpnp_adc_tm_btm_param *param)
{ return -ENXIO; }
-static inline int32_t qpnp_adc_tm_usbid_end(void)
+static inline int32_t qpnp_adc_tm_usbid_end(struct qpnp_adc_tm_chip *chip)
{ return -ENXIO; }
static inline int32_t qpnp_adc_tm_channel_measure(
- struct qpnp_adc_tm_btm_param *param)
+ struct qpnp_adc_tm_chip *chip,
+ struct qpnp_adc_tm_btm_param *param)
{ return -ENXIO; }
-static inline int32_t qpnp_adc_tm_disable_chan_meas(void)
+static inline int32_t qpnp_adc_tm_disable_chan_meas(
+ struct qpnp_adc_tm_chip *chip)
{ return -ENXIO; }
-static inline int32_t qpnp_adc_tm_is_ready(void)
-{ return -ENXIO; }
-static inline int qpnp_iadc_skip_calibration(void)
-{ return -ENXIO; }
-static inline int qpnp_iadc_resume_calibration(void);
-{ return -ENXIO; }
+static inline struct qpnp_adc_tm_chip *qpnp_get_adc_tm(struct device *dev,
+ const char *name)
+{ return ERR_PTR(-ENXIO); }
#endif
#endif
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 8d104c6..77a1c20 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -314,6 +314,7 @@
* @pclk: clock struct of iface_clk.
* @phy_reset_clk: clock struct of phy_clk.
* @core_clk: clock struct of core_bus_clk.
+ * @sleep_clk: clock struct of sleep_clk for USB PHY.
* @core_clk_rate: core clk max frequency
* @regs: ioremapped register base address.
* @inputs: OTG state machine inputs(Id, SessValid etc).
@@ -350,6 +351,7 @@
struct clk *pclk;
struct clk *phy_reset_clk;
struct clk *core_clk;
+ struct clk *sleep_clk;
long core_clk_rate;
struct resource *io_res;
void __iomem *regs;
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 4ad1ca9..bd4cddf 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -92,7 +92,7 @@
#define READDONE_IDX_SEQ_ID 10
#define SOFT_PAUSE_PERIOD 30 /* ramp up/down for 30ms */
-#define SOFT_PAUSE_STEP 2000 /* Step value 2ms or 2000us */
+#define SOFT_PAUSE_STEP 0 /* Step value 0ms or 0us */
enum {
SOFT_PAUSE_CURVE_LINEAR = 0,
SOFT_PAUSE_CURVE_EXP,
@@ -100,7 +100,7 @@
};
#define SOFT_VOLUME_PERIOD 30 /* ramp up/down for 30ms */
-#define SOFT_VOLUME_STEP 2000 /* Step value 2ms or 2000us */
+#define SOFT_VOLUME_STEP 0 /* Step value 0ms or 0us */
enum {
SOFT_VOLUME_CURVE_LINEAR = 0,
SOFT_VOLUME_CURVE_EXP,
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 056e2dc..60dd522 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -379,6 +379,21 @@
return false;
}
+static void voc_set_error_state(uint16_t reset_proc)
+{
+ struct voice_data *v = NULL;
+ int i;
+
+ for (i = 0; i < MAX_VOC_SESSIONS; i++) {
+ if (reset_proc == APR_DEST_MODEM && i == VOC_PATH_FULL)
+ continue;
+
+ v = &common.voice[i];
+ if (v != NULL)
+ v->voc_state = VOC_ERROR;
+ }
+}
+
static bool is_other_session_active(u32 session_id)
{
int i;
@@ -4347,7 +4362,7 @@
mutex_lock(&v->lock);
if (v->voc_state == VOC_RUN || v->voc_state == VOC_ERROR ||
- v->voc_state == VOC_STANDBY) {
+ v->voc_state == VOC_CHANGE || v->voc_state == VOC_STANDBY) {
pr_debug("%s: VOC_STATE: %d\n", __func__, v->voc_state);
@@ -4357,7 +4372,13 @@
voice_destroy_mvm_cvs_session(v);
v->voc_state = VOC_RELEASE;
+ } else {
+ pr_err("%s: Error: End voice called in state %d\n",
+ __func__, v->voc_state);
+
+ ret = -EINVAL;
}
+
mutex_unlock(&v->lock);
return ret;
}
@@ -4559,8 +4580,10 @@
}
v->voc_state = VOC_RUN;
- } else if (v->voc_state == VOC_STANDBY) {
- pr_err("Error: start voice in Standby\n");
+ } else {
+ pr_err("%s: Error: Start voice called in state %d\n",
+ __func__, v->voc_state);
+
ret = -EINVAL;
goto fail;
}
@@ -4602,7 +4625,6 @@
struct common_data *c = NULL;
struct voice_data *v = NULL;
int i = 0;
- uint32_t session_id = 0;
if ((data == NULL) || (priv == NULL)) {
pr_err("%s: data or priv is NULL\n", __func__);
@@ -4619,25 +4641,6 @@
if (data->reset_proc == APR_DEST_MODEM) {
pr_debug("%s: Received MODEM reset event\n", __func__);
- session_id = voc_get_session_id(VOICE_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
-
- session_id = voc_get_session_id(VOICE2_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
-
- session_id = voc_get_session_id(VOLTE_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
-
- session_id = voc_get_session_id(QCHAT_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
} else {
pr_debug("%s: Reset event received in Voice service\n",
__func__);
@@ -4655,7 +4658,7 @@
}
/* clean up srvcc rec flag */
c->srvcc_rec_flag = false;
-
+ voc_set_error_state(data->reset_proc);
return 0;
}
@@ -4753,7 +4756,6 @@
struct common_data *c = NULL;
struct voice_data *v = NULL;
int i = 0;
- uint32_t session_id = 0;
if ((data == NULL) || (priv == NULL)) {
pr_err("%s: data or priv is NULL\n", __func__);
@@ -4770,25 +4772,6 @@
if (data->reset_proc == APR_DEST_MODEM) {
pr_debug("%s: Received Modem reset event\n", __func__);
- session_id = voc_get_session_id(VOICE_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
-
- session_id = voc_get_session_id(VOICE2_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
-
- session_id = voc_get_session_id(VOLTE_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
-
- session_id = voc_get_session_id(QCHAT_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
} else {
pr_debug("%s: Reset event received in Voice service\n",
__func__);
@@ -4800,6 +4783,8 @@
for (i = 0; i < MAX_VOC_SESSIONS; i++)
c->voice[i].cvs_handle = 0;
}
+
+ voc_set_error_state(data->reset_proc);
return 0;
}
@@ -5034,7 +5019,6 @@
struct common_data *c = NULL;
struct voice_data *v = NULL;
int i = 0;
- uint32_t session_id = 0;
if ((data == NULL) || (priv == NULL)) {
pr_err("%s: data or priv is NULL\n", __func__);
@@ -5047,25 +5031,6 @@
if (data->reset_proc == APR_DEST_MODEM) {
pr_debug("%s: Received Modem reset event\n", __func__);
- session_id = voc_get_session_id(VOICE_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
-
- session_id = voc_get_session_id(VOICE2_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
-
- session_id = voc_get_session_id(VOLTE_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
-
- session_id = voc_get_session_id(QCHAT_SESSION_NAME);
- v = voice_get_session(session_id);
- if (v != NULL)
- v->voc_state = VOC_ERROR;
} else {
pr_debug("%s: Reset event received in Voice service\n",
__func__);
@@ -5077,6 +5042,8 @@
for (i = 0; i < MAX_VOC_SESSIONS; i++)
c->voice[i].cvp_handle = 0;
}
+
+ voc_set_error_state(data->reset_proc);
return 0;
}