Merge "ASoC: msm: Add MDM9625 machine driver"
diff --git a/Documentation/devicetree/bindings/arm/msm/smem.txt b/Documentation/devicetree/bindings/arm/msm/smem.txt
new file mode 100644
index 0000000..a38984c
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/smem.txt
@@ -0,0 +1,107 @@
+Qualcomm Shared Memory
+
+[Root level node]
+Required properties:
+-compatible : should be "qcom,smem"
+-reg : the location and size of smem, the irq register base memory, and
+ optionally any auxiliary smem areas
+-reg-names : "smem" - string to identify the shared memory region
+ "irq-reg-base" - string to identify the irq register region
+ "aux-mem1", "aux-mem2", "aux-mem3", ... - optional strings to
+ identify any auxiliary shared memory regions
+
+[Second level nodes]
+
+qcom,smd
+Required properties:
+-compatible : should be "qcom,smd"
+-qcom,smd-edge : the smd edge
+-qcom,smd-irq-offset : the offset into the irq register base memory for sending
+ interrupts
+-qcom,smd-irq-bitmask : the sending irq bitmask
+-interrupts : the receiving interrupt line
+
+Optional properties:
+-qcom,pil-string : the name to use when loading this edge
+-qcom,irq-no-suspend: configure the incoming irq line as active during suspend
+
+qcom,smsm
+Required properties:
+-compatible : should be "qcom,smsm"
+-qcom,smsm-edge : the smsm edge
+-qcom,smsm-irq-offset : the offset into the irq register base memory for sending
+ interrupts
+-qcom,smsm-irq-bitmask : the sending irq bitmask
+-interrupts : the receiving interrupt line
+
+
+Example:
+
+ qcom,smem@fa00000 {
+ compatible = "qcom,smem";
+ reg = <0xfa00000 0x200000>,
+ <0xfa006000 0x1000>,
+ <0xfc428000 0x4000>;
+ reg-names = "smem", "irq-reg-base", "aux-mem1";
+
+ qcom,smd-modem {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <0>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x1000>;
+ qcom,pil-string = "modem";
+ interrupts = <0 25 1>;
+ };
+
+ qcom,smsm-modem {
+ compatible = "qcom,smsm";
+ qcom,smsm-edge = <0>;
+ qcom,smsm-irq-offset = <0x8>;
+ qcom,smsm-irq-bitmask = <0x2000>;
+ interrupts = <0 26 1>;
+ };
+
+ qcom,smd-adsp {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <1>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x100>;
+ qcom,pil-string = "adsp";
+ interrupts = <0 156 1>;
+ };
+
+ qcom,smsm-adsp {
+ compatible = "qcom,smsm";
+ qcom,smsm-edge = <1>;
+ qcom,smsm-irq-offset = <0x8>;
+ qcom,smsm-irq-bitmask = <0x200>;
+ interrupts = <0 157 1>;
+ };
+
+ qcom,smd-wcnss {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <6>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x20000>;
+ qcom,pil-string = "wcnss";
+ interrupts = <0 142 1>;
+ };
+
+ qcom,smsm-wcnss {
+ compatible = "qcom,smsm";
+ qcom,smsm-edge = <6>;
+ qcom,smsm-irq-offset = <0x8>;
+ qcom,smsm-irq-bitmask = <0x80000>;
+ interrupts = <0 144 1>;
+ };
+
+ qcom,smd-rpm {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <15>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x1>;
+ interrupts = <0 168 1>;
+ qcom,irq-no-syspend;
+ };
+ };
+
diff --git a/Documentation/devicetree/bindings/slimbus/slim-msm-ctrl.txt b/Documentation/devicetree/bindings/slimbus/slim-msm-ctrl.txt
index ecac09d..6b090fa 100644
--- a/Documentation/devicetree/bindings/slimbus/slim-msm-ctrl.txt
+++ b/Documentation/devicetree/bindings/slimbus/slim-msm-ctrl.txt
@@ -1,4 +1,19 @@
Qualcomm SLIMBUS controller
+Qualcomm implements 2 type of slimbus controllers:
+1. "qcom,slim-msm": This controller is used if applications processor
+ driver is controlling slimbus master component. This driver is
+ responsible for communicating with slave HW directly using
+ messaging interface, and doing data channel management. Driver
+ also communicates with satellite component (driver implemented
+ by other execution environment, such as ADSP) to get its
+ requirements for data channel and bandwidth requirements.
+2. "qcom,slim-ngd": This controller is used if applications processor
+ driver is controlling slimbus satellite component (also known as
+ Non-ported Generic Device, or NGD). This is light-weight slimbus
+ controller responsible for communicating with slave HW directly
+ over bus messaging interface, and communicating with master component
+ (driver residing on other execution environment, such as ADSP)
+ for bandwidth and data channel management.
Required properties:
@@ -8,7 +23,8 @@
"slimbus_physical": Physical adderss of controller register blocks
"slimbus_bam_physical": Physical address of Bus Access Module (BAM)
for this controller
- - compatible : should be "qcom,slim-msm"
+ - compatible : should be "qcom,slim-msm" if this is master component driver
+ - compatible : should be "qcom,slim-ngd" if this is satellite component driver
- cell-index : SLIMBUS number used for this controller
- interrupts : Interrupt numbers used by this controller
- interrupt-names : Required interrupt resource entries are:
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5d5f9de..89c7417 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -264,6 +264,29 @@
def_bool y
depends on BUG
+config GENERIC_TIME_VSYSCALL
+ bool "Enable gettimeofday updates"
+ depends on CPU_V7
+ help
+ Enables updating the kernel user helper area with the xtime struct
+ data for gettimeofday via kernel user helpers.
+
+config ARM_USE_USER_ACCESSIBLE_TIMERS
+ bool "Enables mapping a timer counter page to user space"
+ depends on USE_USER_ACCESSIBLE_TIMERS && GENERIC_TIME_VSYSCALL
+ help
+ Enables ARM-specific user-accessible timers via a shared
+ memory page containing the cycle counter.
+
+config ARM_USER_ACCESSIBLE_TIMER_BASE
+ hex "Base address of user-accessible timer counter page"
+ default 0xfffef000
+ depends on ARM_USE_USER_ACCESSIBLE_TIMERS
+ help
+ Specify the base user-space virtual address where the user-accessible
+ timer counter page should be mapped by the kernel. User-space apps
+ will read directly from the page at this address.
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 8018e6a..89d4df8 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -58,10 +58,10 @@
};
};
- bms@4000 {
+ pm8941_bms: bms@4000 {
#address-cells = <1>;
#size-cells = <1>;
-
+ status = "disabled";
compatible = "qcom,qpnp-bms";
reg = <0x4000 0x100>;
@@ -95,6 +95,7 @@
qcom,bms-calculate-soc-ms = <20000>;
qcom,bms-chg-term-ua = <100000>;
qcom,bms-batt-type = <0>;
+ qcom,bms-use-voltage-soc;
};
clkdiv@5b00 {
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index f0e950a..09b57a4 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -73,6 +73,15 @@
compatible = "qcom,android-usb";
};
+ qcom,wdt@f9017000 {
+ compatible = "qcom,msm-watchdog";
+ reg = <0xf9017000 0x1000>;
+ interrupts = <0 3 0>, <0 4 0>;
+ qcom,bark-time = <11000>;
+ qcom,pet-time = <10000>;
+ qcom,ipi-ping = <1>;
+ };
+
};
/include/ "msm8226-regulator.dtsi"
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index b2c73e1..e1b2863 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -153,6 +153,43 @@
vdd-phy-supply = <&spi_eth_vreg>;
};
};
+
+ sound {
+ compatible = "qcom,msm8974-audio-taiko";
+ qcom,model = "msm8974-taiko-cdp-snd-card";
+
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "Ext Spk Bottom Pos", "LINEOUT1",
+ "Ext Spk Bottom Neg", "LINEOUT3",
+ "Ext Spk Top Pos", "LINEOUT2",
+ "Ext Spk Top Neg", "LINEOUT4",
+ "AMIC1", "MIC BIAS1 Internal1",
+ "MIC BIAS1 Internal1", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCLeft Headset Mic",
+ "DMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic1",
+ "DMIC2", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic2",
+ "DMIC3", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic3",
+ "DMIC4", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic4",
+ "DMIC5", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic5",
+ "DMIC6", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic6";
+
+ qcom,cdc-mclk-gpios = <&pm8941_gpios 15 0>;
+ taiko-mclk-clk = <&pm8941_clkdiv1>;
+ qcom,taiko-mclk-clk-freq = <9600000>;
+ };
};
&sdcc2 {
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index 9092dd0..15fb799 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -153,6 +153,43 @@
vdd-phy-supply = <&spi_eth_vreg>;
};
};
+
+ sound {
+ compatible = "qcom,msm8974-audio-taiko";
+ qcom,model = "msm8974-taiko-fluid-snd-card";
+
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "Ext Spk Bottom Pos", "LINEOUT1",
+ "Ext Spk Bottom Neg", "LINEOUT3",
+ "Ext Spk Top Pos", "LINEOUT2",
+ "Ext Spk Top Neg", "LINEOUT4",
+ "AMIC1", "MIC BIAS1 Internal1",
+ "MIC BIAS1 Internal1", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCLeft Headset Mic",
+ "DMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic1",
+ "DMIC2", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic2",
+ "DMIC3", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic3",
+ "DMIC4", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic4",
+ "DMIC5", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic5",
+ "DMIC6", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic6";
+
+ qcom,cdc-mclk-gpios = <&pm8941_gpios 15 0>;
+ taiko-mclk-clk = <&pm8941_clkdiv1>;
+ qcom,taiko-mclk-clk-freq = <9600000>;
+ };
};
&sdcc1 {
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index a34694e..f391621 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -78,6 +78,32 @@
status = "ok";
};
+ drv2667_vreg: drv2667_vdd_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_drv2667";
+ };
+
+ i2c@f9967000 {
+ ti-drv2667@59 {
+ compatible = "ti,drv2667";
+ reg = <0x59>;
+ vdd-supply = <&drv2667_vreg>;
+ vdd-i2c-supply = <&pm8941_s3>;
+ ti,label = "vibrator";
+ ti,gain = <2>;
+ ti,idle-timeout-ms = <20>;
+ ti,max-runtime-ms = <15000>;
+ ti,mode = <2>;
+ ti,wav-seq = [
+ /* wave form id */
+ 01
+ /* header size, start and stop bytes */
+ 05 80 06 00 09
+ /* repeat, amp, freq, duration, envelope */
+ 01 ff 19 02 00];
+ };
+ };
+
i2c@f9924000 {
atmel_mxt_ts@4a {
compatible = "atmel,mxt-ts";
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index 1c6302c..80d2440 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -153,6 +153,43 @@
vdd-phy-supply = <&spi_eth_vreg>;
};
};
+
+ sound {
+ compatible = "qcom,msm8974-audio-taiko";
+ qcom,model = "msm8974-taiko-mtp-snd-card";
+
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "Ext Spk Bottom Pos", "LINEOUT1",
+ "Ext Spk Bottom Neg", "LINEOUT3",
+ "Ext Spk Top Pos", "LINEOUT2",
+ "Ext Spk Top Neg", "LINEOUT4",
+ "AMIC1", "MIC BIAS1 Internal1",
+ "MIC BIAS1 Internal1", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCLeft Headset Mic",
+ "DMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic1",
+ "DMIC2", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic2",
+ "DMIC3", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic3",
+ "DMIC4", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic4",
+ "DMIC5", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic5",
+ "DMIC6", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic6";
+
+ qcom,cdc-mclk-gpios = <&pm8941_gpios 15 0>;
+ taiko-mclk-clk = <&pm8941_clkdiv1>;
+ qcom,taiko-mclk-clk-freq = <9600000>;
+ };
};
&sdcc2 {
@@ -176,6 +213,10 @@
qcom,otg-capability;
};
+&pm8941_bms {
+ status = "ok";
+};
+
&pm8941_chg {
status = "ok";
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 0e30129..93ba2bf 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -299,14 +299,12 @@
slim_msm: slim@fe12f000 {
cell-index = <1>;
- compatible = "qcom,slim-msm";
+ compatible = "qcom,slim-ngd";
reg = <0xfe12f000 0x35000>,
<0xfe104000 0x20000>;
reg-names = "slimbus_physical", "slimbus_bam_physical";
interrupts = <0 163 0 0 164 0>;
interrupt-names = "slimbus_irq", "slimbus_bam_irq";
- qcom,min-clk-gear = <10>;
- qcom,rxreg-access;
taiko_codec {
compatible = "qcom,taiko-slim-pgd";
@@ -1216,6 +1214,74 @@
compatible = "qcom,msm-mem-hole";
qcom,memblock-remove = <0x8400000 0x7b00000>; /* Address and Size of Hole */
};
+
+ qcom,smem@fa00000 {
+ compatible = "qcom,smem";
+ reg = <0xfa00000 0x200000>,
+ <0xfa006000 0x1000>,
+ <0xfc428000 0x4000>;
+ reg-names = "smem", "irq-reg-base", "aux-mem1";
+
+ qcom,smd-modem {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <0>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x1000>;
+ qcom,pil-string = "modem";
+ interrupts = <0 25 1>;
+ };
+
+ qcom,smsm-modem {
+ compatible = "qcom,smsm";
+ qcom,smsm-edge = <0>;
+ qcom,smsm-irq-offset = <0x8>;
+ qcom,smsm-irq-bitmask = <0x2000>;
+ interrupts = <0 26 1>;
+ };
+
+ qcom,smd-adsp {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <1>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x100>;
+ qcom,pil-string = "adsp";
+ interrupts = <0 156 1>;
+ };
+
+ qcom,smsm-adsp {
+ compatible = "qcom,smsm";
+ qcom,smsm-edge = <1>;
+ qcom,smsm-irq-offset = <0x8>;
+ qcom,smsm-irq-bitmask = <0x200>;
+ interrupts = <0 157 1>;
+ };
+
+ qcom,smd-wcnss {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <6>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x20000>;
+ qcom,pil-string = "wcnss";
+ interrupts = <0 142 1>;
+ };
+
+ qcom,smsm-wcnss {
+ compatible = "qcom,smsm";
+ qcom,smsm-edge = <6>;
+ qcom,smsm-irq-offset = <0x8>;
+ qcom,smsm-irq-bitmask = <0x80000>;
+ interrupts = <0 144 1>;
+ };
+
+ qcom,smd-rpm {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <15>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x1>;
+ interrupts = <0 168 1>;
+ qcom,irq-no-suspend;
+ };
+ };
};
/include/ "msm-pm8x41-rpm-regulator.dtsi"
diff --git a/arch/arm/boot/dts/msm9625-cdp.dts b/arch/arm/boot/dts/msm9625-cdp.dts
index ba5bbcf..232fba7 100644
--- a/arch/arm/boot/dts/msm9625-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-cdp.dts
@@ -37,6 +37,14 @@
summit,temperature-max = <3>; /* 45 C */
};
};
+
+ wlan0: qca,wlan {
+ cell-index = <0>;
+ compatible = "qca,ar6004-sdio";
+ qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+ qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+ qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+ };
};
/* PM8019 GPIO and MPP configuration */
diff --git a/arch/arm/boot/dts/msm9625-mtp.dts b/arch/arm/boot/dts/msm9625-mtp.dts
index 7780686..faf86d4 100644
--- a/arch/arm/boot/dts/msm9625-mtp.dts
+++ b/arch/arm/boot/dts/msm9625-mtp.dts
@@ -37,6 +37,14 @@
summit,temperature-max = <3>; /* 45 C */
};
};
+
+ wlan0: qca,wlan {
+ cell-index = <0>;
+ compatible = "qca,ar6004-sdio";
+ qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+ qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+ qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+ };
};
/* PM8019 GPIO and MPP configuration */
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index a4bec1b..b79f370 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -274,7 +274,172 @@
compatible = "qcom,msm-rng";
reg = <0xf9bff000 0x200>;
qcom,msm-rng-iface-clk;
- };
+ };
+
+ wcd9xxx_intc: wcd9xxx-irq {
+ compatible = "qcom,wcd9xxx-irq";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <20 0>;
+ interrupt-names = "cdc-int";
+ };
+
+ i2c@f9925000 {
+ cell-index = <3>;
+ compatible = "qcom,i2c-qup";
+ reg = <0xf9925000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ interrupts = <0 97 0>;
+ interrupt-names = "qup_err_intr";
+ qcom,i2c-bus-freq = <100000>;
+ qcom,i2c-src-freq = <24000000>;
+
+ wcd9xxx_codec@0d{
+ compatible = "qcom,wcd9xxx-i2c";
+ reg = <0x0d>;
+ qcom,cdc-reset-gpio = <&msmgpio 22 0>;
+ interrupt-parent = <&wcd9xxx_intc>;
+ interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28>;
+ cdc-vdd-buck-supply = <&pm8019_l11>;
+ qcom,cdc-vdd-buck-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-buck-current = <25000>;
+
+ cdc-vdd-tx-h-supply = <&pm8019_l11>;
+ qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-tx-h-current = <25000>;
+
+ cdc-vdd-rx-h-supply = <&pm8019_l11>;
+ qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-rx-h-current = <25000>;
+
+ cdc-vddpx-1-supply = <&pm8019_l11>;
+ qcom,cdc-vddpx-1-voltage = <1800000 1800000>;
+ qcom,cdc-vddpx-1-current = <10000>;
+
+ cdc-vdd-a-1p2v-supply = <&pm8019_l9>;
+ qcom,cdc-vdd-a-1p2v-voltage = <1200000 1200000>;
+ qcom,cdc-vdd-a-1p2v-current = <10000>;
+
+ cdc-vddcx-1-supply = <&pm8019_l9>;
+ qcom,cdc-vddcx-1-voltage = <1200000 1200000>;
+ qcom,cdc-vddcx-1-current = <10000>;
+
+ cdc-vddcx-2-supply = <&pm8019_l9>;
+ qcom,cdc-vddcx-2-voltage = <1200000 1200000>;
+ qcom,cdc-vddcx-2-current = <10000>;
+
+ qcom,cdc-micbias-ldoh-v = <0x3>;
+ qcom,cdc-micbias-cfilt1-mv = <1800>;
+ qcom,cdc-micbias-cfilt2-mv = <2700>;
+ qcom,cdc-micbias-cfilt3-mv = <1800>;
+ qcom,cdc-micbias1-cfilt-sel = <0x0>;
+ qcom,cdc-micbias2-cfilt-sel = <0x1>;
+ qcom,cdc-micbias3-cfilt-sel = <0x2>;
+ qcom,cdc-micbias4-cfilt-sel = <0x2>;
+ };
+
+ wcd9xxx_codec@77{
+ compatible = "qcom,wcd9xxx-i2c";
+ reg = <0x77>;
+ };
+
+ wcd9xxx_codec@66{
+ compatible = "qcom,wcd9xxx-i2c";
+ reg = <0x66>;
+ };
+
+ wcd9xxx_codec@55{
+ compatible = "qcom,wcd9xxx-i2c";
+ reg = <0x55>;
+ };
+ };
+
+ sound {
+ compatible = "qcom,mdm9625-audio-taiko";
+ qcom,model = "mdm9625-taiko-i2s-snd-card";
+
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "Ext Spk Bottom Pos", "LINEOUT1",
+ "Ext Spk Bottom Neg", "LINEOUT3",
+ "Ext Spk Top Pos", "LINEOUT2",
+ "Ext Spk Top Neg", "LINEOUT4",
+ "AMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS3 Internal1",
+ "MIC BIAS3 Internal1", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS1 Internal2",
+ "MIC BIAS1 Internal2", "ANCLeft Headset Mic",
+ "DMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic1",
+ "DMIC2", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic2",
+ "DMIC3", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic3",
+ "DMIC4", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic4",
+ "DMIC5", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic5",
+ "DMIC6", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic6";
+ qcom,taiko-mclk-clk-freq = <12288000>;
+ };
+
+ qcom,msm-adsp-loader {
+ compatible = "qcom,adsp-loader";
+ };
+
+ qcom,msm-pcm {
+ compatible = "qcom,msm-pcm-dsp";
+ };
+
+ qcom,msm-pcm-routing {
+ compatible = "qcom,msm-pcm-routing";
+ };
+
+ qcom,msm-compr-dsp {
+ compatible = "qcom,msm-compr-dsp";
+ };
+
+ qcom,msm-voip-dsp {
+ compatible = "qcom,msm-voip-dsp";
+ };
+
+ qcom,msm-pcm-voice {
+ compatible = "qcom,msm-pcm-voice";
+ };
+
+ qcom,msm-dai-fe {
+ compatible = "qcom,msm-dai-fe";
+ };
+
+ qcom,msm-pcm-afe {
+ compatible = "qcom,msm-pcm-afe";
+ };
+
+ qcom,msm-pcm-hostless {
+ compatible = "qcom,msm-pcm-hostless";
+ };
+
+ qcom,msm-dai-mi2s {
+ compatible = "qcom,msm-dai-mi2s";
+ qcom,msm-dai-q6-mi2s-prim {
+ compatible = "qcom,msm-dai-q6-mi2s";
+ qcom,msm-dai-q6-mi2s-dev-id = <0>;
+ qcom,msm-mi2s-rx-lines = <2>;
+ qcom,msm-mi2s-tx-lines = <1>;
+ };
+ };
+
+ qcom,msm-dai-q6 {
+ compatible = "qcom,msm-dai-q6";
+ };
};
/include/ "msm-pm8019-rpm-regulator.dtsi"
diff --git a/arch/arm/configs/msm8910_defconfig b/arch/arm/configs/msm8910_defconfig
index 5876a0f..e2e05b2 100644
--- a/arch/arm/configs/msm8910_defconfig
+++ b/arch/arm/configs/msm8910_defconfig
@@ -40,8 +40,10 @@
# CONFIG_MSM_FIQ_SUPPORT is not set
# CONFIG_MSM_PROC_COMM is not set
CONFIG_MSM_SMD=y
+CONFIG_MSM_SMD_PKG4=y
# CONFIG_MSM_HW3D is not set
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
+CONFIG_MSM_WATCHDOG_V2=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
# CONFIG_SMP_ON_UP is not set
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 5e1fa4a..0070e22 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -264,7 +264,7 @@
CONFIG_SPMI=y
CONFIG_SPMI_MSM_PMIC_ARB=y
CONFIG_MSM_QPNP_INT=y
-CONFIG_SLIMBUS_MSM_CTRL=y
+CONFIG_SLIMBUS_MSM_NGD=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_QPNP_PIN=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 4d68a72..33400ea 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -266,7 +266,7 @@
CONFIG_SPMI=y
CONFIG_SPMI_MSM_PMIC_ARB=y
CONFIG_MSM_QPNP_INT=y
-CONFIG_SLIMBUS_MSM_CTRL=y
+CONFIG_SLIMBUS_MSM_NGD=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_QPNP_PIN=y
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
index cd5be28..f705388 100644
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -37,6 +37,7 @@
#define MT_MEMORY_RW 16
#define MT_MEMORY_RX 17
#define MT_MEMORY_DMA_READY 18
+#define MT_DEVICE_USER_ACCESSIBLE 19
#ifdef CONFIG_MMU
extern void iotable_init(struct map_desc *, int);
diff --git a/arch/arm/include/asm/user_accessible_timer.h b/arch/arm/include/asm/user_accessible_timer.h
new file mode 100644
index 0000000..c6d7bd4
--- /dev/null
+++ b/arch/arm/include/asm/user_accessible_timer.h
@@ -0,0 +1,49 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ARM_KERNEL_USER_ACCESSIBLE_TIMER_H_
+#define _ARM_KERNEL_USER_ACCESSIBLE_TIMER_H_
+
+#define ARM_USER_ACCESSIBLE_TIMERS_INVALID_PAGE -1
+
+extern unsigned long zero_pfn;
+
+#ifdef CONFIG_ARM_USE_USER_ACCESSIBLE_TIMERS
+#ifndef CONFIG_ARM_USER_ACCESSIBLE_TIMER_BASE
+#define CONFIG_ARM_USER_ACCESSIBLE_TIMER_BASE 0xfffef000
+#endif
+extern void setup_user_timer_offset(unsigned long addr);
+extern int get_timer_page_address(void);
+static inline int get_user_accessible_timers_base(void)
+{
+ return CONFIG_ARM_USER_ACCESSIBLE_TIMER_BASE;
+}
+extern void set_user_accessible_timer_flag(bool flag);
+#else
+#define CONFIG_ARM_USER_ACCESSIBLE_TIMER_BASE 0
+static inline void setup_user_timer_offset(unsigned long addr)
+{
+}
+static inline int get_timer_page_address(void)
+{
+ return ARM_USER_ACCESSIBLE_TIMERS_INVALID_PAGE;
+}
+static inline int get_user_accessible_timers_base(void)
+{
+ return 0;
+}
+static inline void set_user_accessible_timer_flag(bool flag)
+{
+}
+#endif
+
+#endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 22b0f1e..fc00a23 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -63,6 +63,7 @@
obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o
CFLAGS_swp_emulate.o := -Wa,-march=armv7-a
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
+obj-$(CONFIG_GENERIC_TIME_VSYSCALL) += update_vsyscall_arm.o
obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o
obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
@@ -73,6 +74,7 @@
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
+obj-$(CONFIG_ARM_USE_USER_ACCESSIBLE_TIMERS) += user_accessible_timer.o
ifneq ($(CONFIG_ARCH_EBSA110),y)
obj-y += io.o
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 7a8c2d6..ddd421c 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -764,6 +764,97 @@
.align 5
.globl __kuser_helper_start
__kuser_helper_start:
+#ifdef GENERIC_TIME_VSYSCALL
+/*
+ * Reference declaration:
+ *
+ * extern struct timezone __kernel_helper_gtod_timezone
+ * extern unsigned int __kernel_helper_gtod_seqnum
+ *
+ * Definition and user space usage example:
+ *
+ * #define __kernel_helper_gtod_timezone (*(unsigned int*)0xffff0f20)
+ * #define __kernel_helper_gtod_seqnum (*(unsigned int*)0xffff0f28)
+ *
+ * unsigned int prelock, postlock ;
+ * do {
+ * prelock = __kernel_helper_gtod_seqnum;
+ * memcpy(&tz, (void*)&(__kernel_helper_gtod_timezone),
+ * sizeof(struct timezone)) ;
+ * postlock = __kernel_helper_gtod_seqnum;
+ * } while (prelock != postlock);
+ *
+ * 0xffff0f20-3: tz_minuteswest
+ * 0xffff0f24-7: tz_dsttime
+ * 0xffff0f28-b: sequence #.
+ * 0xffff0f30-3: offset into CONFIG_USER_ACCESSIBLE_TIMER_BASE to get the timer.
+ * 0xffff0f34-7: Feature flag
+ * 0xffff0f38-b: wall-to-mononic: tv_sec
+ * 0xffff0f3c-f: wall-to-mononic: tv_nsec
+ */
+ .globl __kuser_gtod_timezone
+__kuser_gtod_timezone: @0xffff0f20
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ /* This offset is where the flag to enable the
+ * user accessible timers is located.
+ */
+ .word 0
+ .word 0
+ .word 0
+ .align 5
+
+/*
+ * Reference declaration:
+ *
+ * extern struct timeval __kernel_helper_gtod_timeval
+ * extern unsigned int __kernel_helper_gtod_seqnum
+ *
+ * Definition and user space usage example:
+ *
+ * #define __kernel_helper_gtod_timeval (*(unsigned int*)0xffff0f40)
+ * #define __kernel_helper_gtod_seqnum (*(unsigned int*)0xffff0f48)
+ *
+ * unsigned int prelock, postlock ;
+ * struct gtod {
+ * uint64_t cycle_last;
+ * uint64_t mask;
+ * uint32_t mult;
+ * uint32_t shift;
+ * uint32_t tv_sec;
+ * uint32_t tv_nsec;
+ * };
+ * struct gtod gdtod;
+ *
+ * do {
+ * prelock = __kernel_helper_gtod_seqnum;
+ * memcpy(&gdtod, (void*)&(__kernel_helper_gtod_timeval),
+ * sizeof(struct gtod)) ;
+ * postlock = __kernel_helper_gtod_seqnum;
+ * } while (prelock != postlock);
+ *
+ * 0xffff0f40-7: cycle_last
+ * 0xffff0f48-f: mask
+ * 0xffff0f50-3: mult
+ * 0xffff0f54-7: shift
+ * 0xffff0f58-b: tv_sec
+ * 0xffff0f5c-f: tv_nsec
+ */
+ .globl __kuser_gtod_timeval
+__kuser_gtod_timeval: @0xffff0f40
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .align 5
+#endif
/*
* Due to the length of some sequences, __kuser_cmpxchg64 spans 2 regular
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index af21496..ac17480 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -680,6 +680,11 @@
const char *arch_vma_name(struct vm_area_struct *vma)
{
- return (vma == &gate_vma) ? "[vectors]" : NULL;
+ if (vma == &gate_vma)
+ return "[vectors]";
+ else if (vma == get_user_timers_vma(NULL))
+ return "[timers]";
+ else
+ return NULL;
}
#endif
diff --git a/arch/arm/kernel/update_vsyscall_arm.c b/arch/arm/kernel/update_vsyscall_arm.c
new file mode 100644
index 0000000..51f47ae
--- /dev/null
+++ b/arch/arm/kernel/update_vsyscall_arm.c
@@ -0,0 +1,100 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/export.h>
+#include <linux/clocksource.h>
+#include <linux/time.h>
+#include "update_vsyscall_arm.h"
+/*
+ * See entry-armv.S for the offsets into the kernel user helper for
+ * these fields.
+ */
+#define ARM_VSYSCALL_TIMER_TZ 0xf20
+#define ARM_VSYSCALL_TIMER_SEQ 0xf28
+#define ARM_VSYSCALL_TIMER_OFFSET 0xf30
+#define ARM_VSYSCALL_TIMER_WTM_TV_SEC 0xf38
+#define ARM_VSYSCALL_TIMER_WTM_TV_NSEC 0xf3c
+#define ARM_VSYSCALL_TIMER_CYCLE_LAST 0xf40
+#define ARM_VSYSCALL_TIMER_MASK 0xf48
+#define ARM_VSYSCALL_TIMER_MULT 0xf50
+#define ARM_VSYSCALL_TIMER_SHIFT 0xf54
+#define ARM_VSYSCALL_TIMER_TV_SEC 0xf58
+#define ARM_VSYSCALL_TIMER_TV_NSEC 0xf5c
+
+struct kernel_gtod_t {
+ u64 cycle_last;
+ u64 mask;
+ u32 mult;
+ u32 shift;
+ u32 tv_sec;
+ u32 tv_nsec;
+};
+
+struct kernel_tz_t {
+ u32 tz_minuteswest;
+ u32 tz_dsttime;
+};
+
+struct kernel_wtm_t {
+ u32 tv_sec;
+ u32 tv_nsec;
+};
+
+/*
+ * Updates the kernel user helper area with the current timespec
+ * data, as well as additional fields needed to calculate
+ * gettimeofday, clock_gettime, etc.
+ */
+void
+update_vsyscall(struct timespec *ts, struct timespec *wtm,
+ struct clocksource *c, u32 mult)
+{
+ unsigned long vectors = (unsigned long)vectors_page;
+ unsigned long flags;
+ unsigned *seqnum = (unsigned *)(vectors + ARM_VSYSCALL_TIMER_SEQ);
+ struct kernel_gtod_t *dgtod = (struct kernel_gtod_t *)(vectors +
+ ARM_VSYSCALL_TIMER_CYCLE_LAST);
+ struct kernel_wtm_t *dgwtm = (struct kernel_wtm_t *)(vectors +
+ ARM_VSYSCALL_TIMER_WTM_TV_SEC);
+
+ write_seqlock_irqsave(&kuh_time_lock, flags);
+ *seqnum = kuh_time_lock.sequence;
+ dgtod->cycle_last = c->cycle_last;
+ dgtod->mask = c->mask;
+ dgtod->mult = c->mult;
+ dgtod->shift = c->shift;
+ dgtod->tv_sec = ts->tv_sec;
+ dgtod->tv_nsec = ts->tv_nsec;
+ dgwtm->tv_sec = wtm->tv_sec;
+ dgwtm->tv_nsec = wtm->tv_nsec;
+ *seqnum = kuh_time_lock.sequence + 1;
+ write_sequnlock_irqrestore(&kuh_time_lock, flags);
+}
+EXPORT_SYMBOL(update_vsyscall);
+
+void
+update_vsyscall_tz(void)
+{
+ unsigned long vectors = (unsigned long)vectors_page;
+ unsigned long flags;
+ unsigned *seqnum = (unsigned *)(vectors + ARM_VSYSCALL_TIMER_SEQ);
+ struct kernel_tz_t *dgtod = (struct kernel_tz_t *)(vectors +
+ ARM_VSYSCALL_TIMER_TZ);
+
+ write_seqlock_irqsave(&kuh_time_lock, flags);
+ *seqnum = kuh_time_lock.sequence;
+ dgtod->tz_minuteswest = sys_tz.tz_minuteswest;
+ dgtod->tz_dsttime = sys_tz.tz_dsttime;
+ *seqnum = kuh_time_lock.sequence + 1;
+ write_sequnlock_irqrestore(&kuh_time_lock, flags);
+}
+EXPORT_SYMBOL(update_vsyscall_tz);
diff --git a/arch/arm/kernel/update_vsyscall_arm.h b/arch/arm/kernel/update_vsyscall_arm.h
new file mode 100644
index 0000000..d06ca56
--- /dev/null
+++ b/arch/arm/kernel/update_vsyscall_arm.h
@@ -0,0 +1,23 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/export.h>
+#include <linux/clocksource.h>
+#include <linux/time.h>
+
+extern void *vectors_page;
+extern struct timezone sys_tz;
+
+/*
+ * This read-write spinlock protects us from races in SMP while
+ * updating the kernel user helper-embedded time.
+ */
+__cacheline_aligned_in_smp DEFINE_SEQLOCK(kuh_time_lock);
diff --git a/arch/arm/kernel/user_accessible_timer.c b/arch/arm/kernel/user_accessible_timer.c
new file mode 100644
index 0000000..c550c03
--- /dev/null
+++ b/arch/arm/kernel/user_accessible_timer.c
@@ -0,0 +1,132 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <asm/user_accessible_timer.h>
+#include <asm/traps.h>
+
+#define USER_ACCESS_TIMER_OFFSET 0xf30
+#define USER_ACCESS_FEATURE_OFFSET 0xf34
+#define USER_ACCESS_FEATURE_FLAG 0xffff0f20
+
+static struct vm_area_struct user_timers_vma;
+static int __init user_timers_vma_init(void)
+{
+ user_timers_vma.vm_start = CONFIG_ARM_USER_ACCESSIBLE_TIMER_BASE;
+ user_timers_vma.vm_end = CONFIG_ARM_USER_ACCESSIBLE_TIMER_BASE
+ + PAGE_SIZE;
+ user_timers_vma.vm_page_prot = PAGE_READONLY;
+ user_timers_vma.vm_flags = VM_READ | VM_MAYREAD;
+ return 0;
+}
+arch_initcall(user_timers_vma_init);
+
+int in_user_timers_area(struct mm_struct *mm, unsigned long addr)
+{
+ return (addr >= user_timers_vma.vm_start) &&
+ (addr < user_timers_vma.vm_end);
+}
+EXPORT_SYMBOL(in_user_timers_area);
+
+struct vm_area_struct *get_user_timers_vma(struct mm_struct *mm)
+{
+ return &user_timers_vma;
+}
+EXPORT_SYMBOL(get_user_timers_vma);
+
+int get_user_timer_page(struct vm_area_struct *vma,
+ struct mm_struct *mm, unsigned long start, unsigned int gup_flags,
+ struct page **pages, int idx, int *goto_next_page)
+{
+ /* Replicates the earlier work done in mm/memory.c */
+ unsigned long pg = start & PAGE_MASK;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ /* Unset this flag -- this only gets activated if the
+ * caller should go straight to the next_page label on
+ * return.
+ */
+ *goto_next_page = 0;
+
+ /* user gate pages are read-only */
+ if (gup_flags & FOLL_WRITE)
+ return idx ? : -EFAULT;
+ if (pg > TASK_SIZE)
+ pgd = pgd_offset_k(pg);
+ else
+ pgd = pgd_offset_gate(mm, pg);
+ BUG_ON(pgd_none(*pgd));
+ pud = pud_offset(pgd, pg);
+ BUG_ON(pud_none(*pud));
+ pmd = pmd_offset(pud, pg);
+ if (pmd_none(*pmd))
+ return idx ? : -EFAULT;
+ VM_BUG_ON(pmd_trans_huge(*pmd));
+ pte = pte_offset_map(pmd, pg);
+ if (pte_none(*pte)) {
+ pte_unmap(pte);
+ return idx ? : -EFAULT;
+ }
+ vma = get_user_timers_vma(mm);
+ if (pages) {
+ struct page *page;
+
+ page = vm_normal_page(vma, start, *pte);
+ if (!page) {
+ if (!(gup_flags & FOLL_DUMP) &&
+ zero_pfn == pte_pfn(*pte))
+ page = pte_page(*pte);
+ else {
+ pte_unmap(pte);
+ return idx ? : -EFAULT;
+ }
+ }
+ pages[idx] = page;
+ get_page(page);
+ }
+ pte_unmap(pte);
+ /* In this case, set the next page */
+ *goto_next_page = 1;
+ return 0;
+}
+EXPORT_SYMBOL(get_user_timer_page);
+
+void setup_user_timer_offset(unsigned long addr)
+{
+#if defined(CONFIG_CPU_USE_DOMAINS)
+ unsigned long vectors = CONFIG_VECTORS_BASE;
+#else
+ unsigned long vectors = (unsigned long)vectors_page;
+#endif
+ unsigned long *timer_offset = (unsigned long *)(vectors +
+ USER_ACCESS_TIMER_OFFSET);
+ *timer_offset = addr;
+}
+EXPORT_SYMBOL(setup_user_timer_offset);
+
+void set_user_accessible_timer_flag(bool flag)
+{
+#if defined(CONFIG_CPU_USE_DOMAINS)
+ unsigned long vectors = CONFIG_VECTORS_BASE;
+#else
+ unsigned long vectors = (unsigned long)vectors_page;
+#endif
+ unsigned long *timer_offset = (unsigned long *)(vectors +
+ USER_ACCESS_FEATURE_OFFSET);
+ *timer_offset = (flag ? USER_ACCESS_FEATURE_FLAG : 0);
+}
+EXPORT_SYMBOL(set_user_accessible_timer_flag);
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index dbb4328..a0868c7 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -177,6 +177,10 @@
select ARM_HAS_SG_CHAIN
select MSM_KRAIT_WFE_FIXUP
select MSM_ULTRASOUND_A
+ select GENERIC_TIME_VSYSCALL
+ select USE_USER_ACCESSIBLE_TIMERS
+ select ARM_USE_USER_ACCESSIBLE_TIMERS
+ select MSM_USE_USER_ACCESSIBLE_TIMERS
config ARCH_MSM8930
bool "MSM8930"
@@ -209,6 +213,10 @@
select HOLES_IN_ZONE if SPARSEMEM
select ARM_HAS_SG_CHAIN
select MSM_KRAIT_WFE_FIXUP
+ select GENERIC_TIME_VSYSCALL
+ select USE_USER_ACCESSIBLE_TIMERS
+ select ARM_USE_USER_ACCESSIBLE_TIMERS
+ select MSM_USE_USER_ACCESSIBLE_TIMERS
config ARCH_APQ8064
bool "APQ8064"
@@ -237,6 +245,10 @@
select ARM_HAS_SG_CHAIN
select MSM_KRAIT_WFE_FIXUP
select MSM_ULTRASOUND_A
+ select GENERIC_TIME_VSYSCALL
+ select USE_USER_ACCESSIBLE_TIMERS
+ select ARM_USE_USER_ACCESSIBLE_TIMERS
+ select MSM_USE_USER_ACCESSIBLE_TIMERS
config ARCH_MSM8974
bool "MSM8974"
@@ -349,6 +361,9 @@
select SPARSE_IRQ
select MSM_MULTIMEDIA_USE_ION
select MSM_RPM_STATS_LOG
+ select MSM_QDSP6_APRV2
+ select MSM_QDSP6V2_CODECS
+ select MSM_AUDIO_QDSP6V2 if SND_SOC
config ARCH_MSM8910
bool "MSM8910"
@@ -2661,4 +2676,12 @@
if apps is not responding and holding lock with irqs disabled.
Modem will then generate an raise a FIQ on this line before sending
SMSM reset.
+
+config MSM_USE_USER_ACCESSIBLE_TIMERS
+ bool "Enables mapping an MSM timer counter page to user space."
+ depends on ARM_USE_USER_ACCESSIBLE_TIMERS
+ help
+ Enables MSM-specific user accessible timers via a shared
+ memory page containing the cycle counter.
+
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 0c2f8ae..88e5ce2 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -298,7 +298,7 @@
obj-$(CONFIG_ARCH_MSM8974) += krait-regulator.o
obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
obj-$(CONFIG_ARCH_MSM9625) += clock-local2.o clock-pll.o clock-9625.o clock-rpm.o clock-voter.o acpuclock-9625.o
-obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o
+obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o acpuclock-8930ab.o
obj-$(CONFIG_ARCH_MPQ8092) += board-8092.o board-8092-gpiomux.o
obj-$(CONFIG_ARCH_MSM8226) += board-8226.o board-8226-gpiomux.o
obj-$(CONFIG_ARCH_MSM8910) += board-8910.o board-8910-gpiomux.o
@@ -398,6 +398,8 @@
obj-$(CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL) += wdog_debug.o
+obj-$(CONFIG_MSM_USE_USER_ACCESSIBLE_TIMERS) += timer_page.o
+
ifdef CONFIG_MSM_CPR
obj-$(CONFIG_DEBUG_FS) += msm_cpr-debug.o
endif
diff --git a/arch/arm/mach-msm/acpuclock-8930ab.c b/arch/arm/mach-msm/acpuclock-8930ab.c
new file mode 100644
index 0000000..764ae41
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-8930ab.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <mach/rpm-regulator.h>
+#include <mach/msm_bus_board.h>
+#include <mach/msm_bus.h>
+
+#include "acpuclock.h"
+#include "acpuclock-krait.h"
+
+/* Corner type vreg VDD values */
+#define LVL_NONE RPM_VREG_CORNER_NONE
+#define LVL_LOW RPM_VREG_CORNER_LOW
+#define LVL_NOM RPM_VREG_CORNER_NOMINAL
+#define LVL_HIGH RPM_VREG_CORNER_HIGH
+
+static struct hfpll_data hfpll_data __initdata = {
+ .mode_offset = 0x00,
+ .l_offset = 0x08,
+ .m_offset = 0x0C,
+ .n_offset = 0x10,
+ .config_offset = 0x04,
+ .config_val = 0x7845C665,
+ .has_droop_ctl = true,
+ .droop_offset = 0x14,
+ .droop_val = 0x0108C000,
+ .low_vdd_l_max = 37,
+ .nom_vdd_l_max = 74,
+ .vdd[HFPLL_VDD_NONE] = LVL_NONE,
+ .vdd[HFPLL_VDD_LOW] = LVL_LOW,
+ .vdd[HFPLL_VDD_NOM] = LVL_NOM,
+ .vdd[HFPLL_VDD_HIGH] = LVL_HIGH,
+};
+
+static struct scalable scalable_pm8917[] __initdata = {
+ [CPU0] = {
+ .hfpll_phys_base = 0x00903200,
+ .aux_clk_sel_phys = 0x02088014,
+ .aux_clk_sel = 3,
+ .sec_clk_sel = 2,
+ .l2cpmr_iaddr = 0x4501,
+ .vreg[VREG_CORE] = { "krait0", 1300000 },
+ .vreg[VREG_MEM] = { "krait0_mem", 1150000 },
+ .vreg[VREG_DIG] = { "krait0_dig", 1150000 },
+ .vreg[VREG_HFPLL_A] = { "krait0_s8", 2050000 },
+ .vreg[VREG_HFPLL_B] = { "krait0_l23", 1800000 },
+ },
+ [CPU1] = {
+ .hfpll_phys_base = 0x00903300,
+ .aux_clk_sel_phys = 0x02098014,
+ .aux_clk_sel = 3,
+ .sec_clk_sel = 2,
+ .l2cpmr_iaddr = 0x5501,
+ .vreg[VREG_CORE] = { "krait1", 1300000 },
+ .vreg[VREG_MEM] = { "krait1_mem", 1150000 },
+ .vreg[VREG_DIG] = { "krait1_dig", 1150000 },
+ .vreg[VREG_HFPLL_A] = { "krait1_s8", 2050000 },
+ .vreg[VREG_HFPLL_B] = { "krait1_l23", 1800000 },
+ },
+ [L2] = {
+ .hfpll_phys_base = 0x00903400,
+ .aux_clk_sel_phys = 0x02011028,
+ .aux_clk_sel = 3,
+ .sec_clk_sel = 2,
+ .l2cpmr_iaddr = 0x0500,
+ .vreg[VREG_HFPLL_A] = { "l2_s8", 2050000 },
+ .vreg[VREG_HFPLL_B] = { "l2_l23", 1800000 },
+ },
+};
+
+static struct scalable scalable[] __initdata = {
+ [CPU0] = {
+ .hfpll_phys_base = 0x00903200,
+ .aux_clk_sel_phys = 0x02088014,
+ .aux_clk_sel = 3,
+ .sec_clk_sel = 2,
+ .l2cpmr_iaddr = 0x4501,
+ .vreg[VREG_CORE] = { "krait0", 1300000 },
+ .vreg[VREG_MEM] = { "krait0_mem", 1150000 },
+ .vreg[VREG_DIG] = { "krait0_dig", 1150000 },
+ .vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
+ },
+ [CPU1] = {
+ .hfpll_phys_base = 0x00903300,
+ .aux_clk_sel_phys = 0x02098014,
+ .aux_clk_sel = 3,
+ .sec_clk_sel = 2,
+ .l2cpmr_iaddr = 0x5501,
+ .vreg[VREG_CORE] = { "krait1", 1300000 },
+ .vreg[VREG_MEM] = { "krait1_mem", 1150000 },
+ .vreg[VREG_DIG] = { "krait1_dig", 1150000 },
+ .vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
+ },
+ [L2] = {
+ .hfpll_phys_base = 0x00903400,
+ .aux_clk_sel_phys = 0x02011028,
+ .aux_clk_sel = 3,
+ .sec_clk_sel = 2,
+ .l2cpmr_iaddr = 0x0500,
+ .vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
+ },
+};
+
+static struct msm_bus_paths bw_level_tbl[] __initdata = {
+ [0] = BW_MBPS(640), /* At least 80 MHz on bus. */
+ [1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
+ [2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
+ [3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
+ [4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
+ [5] = BW_MBPS(4800), /* At least 600 MHz on bus. */
+};
+
+static struct msm_bus_scale_pdata bus_scale_data __initdata = {
+ .usecase = bw_level_tbl,
+ .num_usecases = ARRAY_SIZE(bw_level_tbl),
+ .active_only = 1,
+ .name = "acpuclk-8930ab",
+};
+
+/* TODO: Update new L2 freqs once they are available */
+static struct l2_level l2_freq_tbl[] __initdata = {
+ [0] = { { 384000, PLL_8, 0, 0x00 }, LVL_NOM, 1050000, 1 },
+ [1] = { { 432000, HFPLL, 2, 0x20 }, LVL_NOM, 1050000, 2 },
+ [2] = { { 486000, HFPLL, 2, 0x24 }, LVL_NOM, 1050000, 2 },
+ [3] = { { 540000, HFPLL, 2, 0x28 }, LVL_NOM, 1050000, 2 },
+ [4] = { { 594000, HFPLL, 1, 0x16 }, LVL_NOM, 1050000, 2 },
+ [5] = { { 648000, HFPLL, 1, 0x18 }, LVL_NOM, 1050000, 4 },
+ [6] = { { 702000, HFPLL, 1, 0x1A }, LVL_NOM, 1050000, 4 },
+ [7] = { { 756000, HFPLL, 1, 0x1C }, LVL_HIGH, 1150000, 4 },
+ [8] = { { 810000, HFPLL, 1, 0x1E }, LVL_HIGH, 1150000, 4 },
+ [9] = { { 864000, HFPLL, 1, 0x20 }, LVL_HIGH, 1150000, 4 },
+ [10] = { { 918000, HFPLL, 1, 0x22 }, LVL_HIGH, 1150000, 5 },
+ [11] = { { 972000, HFPLL, 1, 0x24 }, LVL_HIGH, 1150000, 5 },
+ [12] = { { 1026000, HFPLL, 1, 0x26 }, LVL_HIGH, 1150000, 5 },
+ [13] = { { 1080000, HFPLL, 1, 0x28 }, LVL_HIGH, 1150000, 5 },
+ [14] = { { 1134000, HFPLL, 1, 0x2A }, LVL_HIGH, 1150000, 5 },
+ [15] = { { 1188000, HFPLL, 1, 0x2C }, LVL_HIGH, 1150000, 5 },
+ { }
+};
+
+static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
+ { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 975000 },
+ { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 1000000 },
+ { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1025000 },
+ { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
+ { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
+ { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
+ { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
+ { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
+ { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
+ { 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
+ { 1, { 1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
+ { 1, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
+ { 1, { 1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
+ { 1, { 1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
+ { 1, { 1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
+ { 1, { 1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
+ { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 975000 },
+ { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 1000000 },
+ { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1025000 },
+ { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
+ { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
+ { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
+ { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
+ { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
+ { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
+ { 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
+ { 1, { 1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
+ { 1, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
+ { 1, { 1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
+ { 1, { 1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
+ { 1, { 1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
+ { 1, { 1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
+ { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 975000 },
+ { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 1000000 },
+ { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1025000 },
+ { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
+ { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
+ { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
+ { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
+ { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
+ { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
+ { 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
+ { 1, { 1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
+ { 1, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
+ { 1, { 1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
+ { 1, { 1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
+ { 1, { 1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
+ { 1, { 1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
+ { 0, { 0 } }
+};
+
+/* TODO: Update boost voltage once the pvs data is available */
+static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+[0][PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
+[0][PVS_NOMINAL] = { acpu_freq_tbl_nom, sizeof(acpu_freq_tbl_nom), 0 },
+[0][PVS_FAST] = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 0 },
+};
+
+static struct acpuclk_krait_params acpuclk_8930ab_params __initdata = {
+ .scalable = scalable,
+ .scalable_size = sizeof(scalable),
+ .hfpll_data = &hfpll_data,
+ .pvs_tables = pvs_tables,
+ .l2_freq_tbl = l2_freq_tbl,
+ .l2_freq_tbl_size = sizeof(l2_freq_tbl),
+ .bus_scale = &bus_scale_data,
+ .pte_efuse_phys = 0x007000C0,
+ .stby_khz = 384000,
+};
+
+static int __init acpuclk_8930ab_probe(struct platform_device *pdev)
+{
+ struct acpuclk_platform_data *pdata = pdev->dev.platform_data;
+ if (pdata && pdata->uses_pm8917)
+ acpuclk_8930ab_params.scalable = scalable_pm8917;
+
+ return acpuclk_krait_init(&pdev->dev, &acpuclk_8930ab_params);
+}
+
+static struct platform_driver acpuclk_8930ab_driver = {
+ .driver = {
+ .name = "acpuclk-8930ab",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init acpuclk_8930ab_init(void)
+{
+ return platform_driver_probe(&acpuclk_8930ab_driver,
+ acpuclk_8930ab_probe);
+}
+device_initcall(acpuclk_8930ab_init);
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index 61213cf..0fbd6dc 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -113,14 +113,14 @@
};
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { { 300000, PLL_0, 0, 0 }, LVL_LOW, 950000, 0 },
- [1] = { { 384000, HFPLL, 2, 40 }, LVL_NOM, 950000, 1 },
- [2] = { { 460800, HFPLL, 2, 48 }, LVL_NOM, 950000, 1 },
- [3] = { { 537600, HFPLL, 1, 28 }, LVL_NOM, 950000, 2 },
- [4] = { { 576000, HFPLL, 1, 30 }, LVL_NOM, 950000, 2 },
- [5] = { { 652800, HFPLL, 1, 34 }, LVL_NOM, 950000, 2 },
- [6] = { { 729600, HFPLL, 1, 38 }, LVL_NOM, 950000, 2 },
- [7] = { { 806400, HFPLL, 1, 42 }, LVL_NOM, 950000, 2 },
+ [0] = { { 300000, PLL_0, 0, 0 }, LVL_LOW, 1050000, 0 },
+ [1] = { { 345600, HFPLL, 2, 36 }, LVL_NOM, 1050000, 1 },
+ [2] = { { 422400, HFPLL, 2, 44 }, LVL_NOM, 1050000, 1 },
+ [3] = { { 499200, HFPLL, 2, 52 }, LVL_NOM, 1050000, 2 },
+ [4] = { { 576000, HFPLL, 1, 30 }, LVL_NOM, 1050000, 2 },
+ [5] = { { 652800, HFPLL, 1, 34 }, LVL_NOM, 1050000, 2 },
+ [6] = { { 729600, HFPLL, 1, 38 }, LVL_NOM, 1050000, 2 },
+ [7] = { { 806400, HFPLL, 1, 42 }, LVL_NOM, 1050000, 2 },
[8] = { { 883200, HFPLL, 1, 46 }, LVL_HIGH, 1050000, 2 },
[9] = { { 960000, HFPLL, 1, 50 }, LVL_HIGH, 1050000, 2 },
[10] = { { 1036800, HFPLL, 1, 54 }, LVL_HIGH, 1050000, 3 },
@@ -143,30 +143,30 @@
};
static struct acpu_level acpu_freq_tbl[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 950000, 100000 },
- { 1, { 384000, HFPLL, 2, 40 }, L2(3), 950000, 3200000 },
- { 1, { 460800, HFPLL, 2, 48 }, L2(3), 950000, 3200000 },
- { 1, { 537600, HFPLL, 1, 28 }, L2(5), 950000, 3200000 },
- { 1, { 576000, HFPLL, 1, 30 }, L2(5), 950000, 3200000 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(5), 950000, 3200000 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(5), 950000, 3200000 },
- { 1, { 806400, HFPLL, 1, 42 }, L2(7), 950000, 3200000 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(7), 950000, 3200000 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(7), 950000, 3200000 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(7), 950000, 3200000 },
- { 1, { 1113600, HFPLL, 1, 58 }, L2(12), 1050000, 3200000 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(12), 1050000, 3200000 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(12), 1050000, 3200000 },
- { 1, { 1344000, HFPLL, 1, 70 }, L2(15), 1050000, 3200000 },
- { 1, { 1420800, HFPLL, 1, 74 }, L2(15), 1050000, 3200000 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 1050000, 3200000 },
- { 0, { 1574400, HFPLL, 1, 82 }, L2(20), 1050000, 3200000 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(20), 1050000, 3200000 },
- { 0, { 1728000, HFPLL, 1, 90 }, L2(20), 1050000, 3200000 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(25), 1050000, 3200000 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(25), 1050000, 3200000 },
- { 0, { 1958400, HFPLL, 1, 102 }, L2(25), 1050000, 3200000 },
- { 0, { 1996800, HFPLL, 1, 104 }, L2(25), 1050000, 3200000 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 850000, 100000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(0), 850000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(0), 850000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(0), 850000, 3200000 },
+ { 1, { 576000, HFPLL, 1, 30 }, L2(0), 850000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(16), 850000, 3200000 },
+ { 0, { 729600, HFPLL, 1, 38 }, L2(16), 850000, 3200000 },
+ { 1, { 806400, HFPLL, 1, 42 }, L2(16), 850000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(16), 870000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(16), 880000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(16), 900000, 3200000 },
+ { 1, { 1113600, HFPLL, 1, 58 }, L2(16), 915000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(16), 935000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(16), 950000, 3200000 },
+ { 1, { 1344000, HFPLL, 1, 70 }, L2(16), 970000, 3200000 },
+ { 1, { 1420800, HFPLL, 1, 74 }, L2(16), 985000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 1000000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(16), 1015000, 3200000 },
+ { 1, { 1651200, HFPLL, 1, 86 }, L2(16), 1030000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1050000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(16), 1050000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(16), 1050000, 3200000 },
+ { 0, { 1958400, HFPLL, 1, 102 }, L2(16), 1050000, 3200000 },
+ { 0, { 1996800, HFPLL, 1, 104 }, L2(16), 1050000, 3200000 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index a0bfabf..7e477b1 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -740,11 +740,29 @@
return 0;
if (on) {
+ if (!(hdmi_msm_data.is_mhl_enabled)) {
+ rc = gpio_request(HDMI_MHL_MUX_GPIO, "MHL_HDMI_MUX");
+ if (rc < 0) {
+ pr_err("gpio hdmi_mhl mux req failed:%d\n",
+ rc);
+ return rc;
+ }
+ rc = gpio_direction_output(HDMI_MHL_MUX_GPIO, 1);
+ if (rc < 0) {
+ pr_err("set gpio hdmi_mhl dir failed:%d\n",
+ rc);
+ goto error0;
+ }
+ gpio_set_value(HDMI_MHL_MUX_GPIO, 1);
+ pr_debug("set gpio hdmi mhl mux %d to 1\n",
+ HDMI_MHL_MUX_GPIO);
+ }
+
rc = gpio_request(100, "HDMI_DDC_CLK");
if (rc) {
pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
"HDMI_DDC_CLK", 100, rc);
- return rc;
+ goto error0;
}
rc = gpio_request(101, "HDMI_DDC_DATA");
if (rc) {
@@ -760,6 +778,8 @@
}
pr_debug("%s(on): success\n", __func__);
} else {
+ if (!(hdmi_msm_data.is_mhl_enabled))
+ gpio_free(HDMI_MHL_MUX_GPIO);
gpio_free(100);
gpio_free(101);
gpio_free(102);
@@ -773,6 +793,9 @@
gpio_free(101);
error1:
gpio_free(100);
+error0:
+ if (!(hdmi_msm_data.is_mhl_enabled))
+ gpio_free(HDMI_MHL_MUX_GPIO);
return rc;
}
diff --git a/arch/arm/mach-msm/board-8930-regulator-pm8038.c b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
index 727c4c6..947697a 100644
--- a/arch/arm/mach-msm/board-8930-regulator-pm8038.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
@@ -189,12 +189,14 @@
REGULATOR_SUPPLY("krait0", "acpuclk-8627"),
REGULATOR_SUPPLY("krait0", "acpuclk-8930"),
REGULATOR_SUPPLY("krait0", "acpuclk-8930aa"),
+ REGULATOR_SUPPLY("krait0", "acpuclk-8930ab"),
};
VREG_CONSUMERS(S6) = {
REGULATOR_SUPPLY("8038_s6", NULL),
REGULATOR_SUPPLY("krait1", "acpuclk-8627"),
REGULATOR_SUPPLY("krait1", "acpuclk-8930"),
REGULATOR_SUPPLY("krait1", "acpuclk-8930aa"),
+ REGULATOR_SUPPLY("krait1", "acpuclk-8930ab"),
};
VREG_CONSUMERS(LVS1) = {
REGULATOR_SUPPLY("8038_lvs1", NULL),
@@ -490,7 +492,7 @@
/* ID a_on pd ss min_uV max_uV supply sys_uA freq fm ss_fm */
RPM_SMPS(S1, 0, 1, 1, 500000, 1150000, NULL, 100000, 4p80, AUTO, LPM),
RPM_SMPS(S2, 1, 1, 1, 1400000, 1400000, NULL, 100000, 1p60, AUTO, LPM),
- RPM_SMPS(S3, 0, 1, 1, 1150000, 1150000, NULL, 100000, 3p20, AUTO, LPM),
+ RPM_SMPS(S3, 0, 1, 1, 1150000, 1150000, NULL, 100000, 3p20, AUTO, AUTO),
RPM_SMPS(S4, 1, 1, 1, 1950000, 2200000, NULL, 100000, 1p60, AUTO, LPM),
/* ID a_on pd ss min_uV max_uV supply sys_uA init_ip */
@@ -564,6 +566,14 @@
RPM_REG_MAP(L24, 0, 2, "krait1_mem", "acpuclk-8930aa"),
RPM_REG_MAP(VDD_DIG_CORNER, 0, 1, "krait0_dig", "acpuclk-8930aa"),
RPM_REG_MAP(VDD_DIG_CORNER, 0, 2, "krait1_dig", "acpuclk-8930aa"),
+
+ RPM_REG_MAP(L23, 0, 1, "krait0_hfpll", "acpuclk-8930ab"),
+ RPM_REG_MAP(L23, 0, 2, "krait1_hfpll", "acpuclk-8930ab"),
+ RPM_REG_MAP(L23, 0, 6, "l2_hfpll", "acpuclk-8930ab"),
+ RPM_REG_MAP(L24, 0, 1, "krait0_mem", "acpuclk-8930ab"),
+ RPM_REG_MAP(L24, 0, 2, "krait1_mem", "acpuclk-8930ab"),
+ RPM_REG_MAP(VDD_DIG_CORNER, 0, 1, "krait0_dig", "acpuclk-8930ab"),
+ RPM_REG_MAP(VDD_DIG_CORNER, 0, 2, "krait1_dig", "acpuclk-8930ab"),
};
struct rpm_regulator_platform_data
diff --git a/arch/arm/mach-msm/board-8930-regulator-pm8917.c b/arch/arm/mach-msm/board-8930-regulator-pm8917.c
index 6f58771..3ee052b 100644
--- a/arch/arm/mach-msm/board-8930-regulator-pm8917.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8917.c
@@ -206,12 +206,14 @@
REGULATOR_SUPPLY("krait0", "acpuclk-8627"),
REGULATOR_SUPPLY("krait0", "acpuclk-8930"),
REGULATOR_SUPPLY("krait0", "acpuclk-8930aa"),
+ REGULATOR_SUPPLY("krait0", "acpuclk-8930ab"),
};
VREG_CONSUMERS(S6) = {
REGULATOR_SUPPLY("8917_s6", NULL),
REGULATOR_SUPPLY("krait1", "acpuclk-8627"),
REGULATOR_SUPPLY("krait1", "acpuclk-8930"),
REGULATOR_SUPPLY("krait1", "acpuclk-8930aa"),
+ REGULATOR_SUPPLY("krait1", "acpuclk-8930ab"),
};
VREG_CONSUMERS(S7) = {
REGULATOR_SUPPLY("8917_s7", NULL),
@@ -631,6 +633,18 @@
RPM_REG_MAP(L24, 0, 2, "krait1_mem", "acpuclk-8930aa"),
RPM_REG_MAP(VDD_DIG_CORNER, 0, 1, "krait0_dig", "acpuclk-8930aa"),
RPM_REG_MAP(VDD_DIG_CORNER, 0, 2, "krait1_dig", "acpuclk-8930aa"),
+
+ RPM_REG_MAP(L23, 0, 1, "krait0_l23", "acpuclk-8930ab"),
+ RPM_REG_MAP(S8, 0, 1, "krait0_s8", "acpuclk-8930ab"),
+ RPM_REG_MAP(L23, 0, 2, "krait1_l23", "acpuclk-8930ab"),
+ RPM_REG_MAP(S8, 0, 2, "krait1_s8", "acpuclk-8930ab"),
+ RPM_REG_MAP(L23, 0, 6, "l2_l23", "acpuclk-8930ab"),
+ RPM_REG_MAP(S8, 0, 6, "l2_s8", "acpuclk-8930ab"),
+ RPM_REG_MAP(L24, 0, 1, "krait0_mem", "acpuclk-8930ab"),
+ RPM_REG_MAP(L24, 0, 2, "krait1_mem", "acpuclk-8930ab"),
+ RPM_REG_MAP(VDD_DIG_CORNER, 0, 1, "krait0_dig", "acpuclk-8930ab"),
+ RPM_REG_MAP(VDD_DIG_CORNER, 0, 2, "krait1_dig", "acpuclk-8930ab"),
+
};
struct rpm_regulator_platform_data
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 1b487fa..512ae72 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -112,7 +112,6 @@
#define KS8851_IRQ_GPIO 90
#define HAP_SHIFT_LVL_OE_GPIO 47
-#define HDMI_MHL_MUX_GPIO 73
#define MHL_GPIO_INT 72
#define MHL_GPIO_RESET 71
#define MHL_GPIO_PWR_EN 5
@@ -2756,6 +2755,9 @@
pdata = msm8930_device_acpuclk.dev.platform_data;
pdata->uses_pm8917 = true;
+
+ pdata = msm8930ab_device_acpuclk.dev.platform_data;
+ pdata->uses_pm8917 = true;
}
static void __init msm8930_cdp_init(void)
@@ -2829,6 +2831,8 @@
platform_device_register(&msm8930_device_acpuclk);
else if (cpu_is_msm8930aa())
platform_device_register(&msm8930aa_device_acpuclk);
+ else if (cpu_is_msm8930ab())
+ platform_device_register(&msm8930ab_device_acpuclk);
platform_add_devices(early_common_devices,
ARRAY_SIZE(early_common_devices));
if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917)
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index 055576f..dbcfa9d 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -164,5 +164,7 @@
#define MSM_8930_GSBI10_QUP_I2C_BUS_ID 10
#define MSM_8930_GSBI12_QUP_I2C_BUS_ID 12
+#define HDMI_MHL_MUX_GPIO 73
+
extern struct msm_rtb_platform_data msm8930_rtb_pdata;
extern struct msm_cache_dump_platform_data msm8930_cache_dump_pdata;
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index 50b59e1..89ad4ef 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -152,6 +152,26 @@
};
+static struct gpiomux_setting mhl_suspend_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting mhl_active_1_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+ .dir = GPIOMUX_OUT_HIGH,
+};
+
+static struct gpiomux_setting mhl_active_2_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+
static struct gpiomux_setting hdmi_suspend_cfg = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_2MA,
@@ -170,6 +190,34 @@
.pull = GPIOMUX_PULL_DOWN,
};
+static struct msm_gpiomux_config msm_mhl_configs[] __initdata = {
+ {
+ /* mhl-sii8334 pwr */
+ .gpio = 12,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mhl_suspend_config,
+ [GPIOMUX_ACTIVE] = &mhl_active_1_cfg,
+ },
+ },
+ {
+ /* mhl-sii8334 intr */
+ .gpio = 82,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mhl_suspend_config,
+ [GPIOMUX_ACTIVE] = &mhl_active_1_cfg,
+ },
+ },
+ {
+ /* mhl-sii8334 reset */
+ .gpio = 8,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mhl_suspend_config,
+ [GPIOMUX_ACTIVE] = &mhl_active_2_cfg,
+ },
+ },
+};
+
+
static struct msm_gpiomux_config msm_hdmi_configs[] __initdata = {
{
.gpio = 31,
@@ -575,4 +623,5 @@
msm_gpiomux_install(msm_taiko_config, ARRAY_SIZE(msm_taiko_config));
msm_gpiomux_install(msm_hdmi_configs, ARRAY_SIZE(msm_hdmi_configs));
+ msm_gpiomux_install(msm_mhl_configs, ARRAY_SIZE(msm_mhl_configs));
}
diff --git a/arch/arm/mach-msm/board-8974.c b/arch/arm/mach-msm/board-8974.c
index 98a82b1..b092a53 100644
--- a/arch/arm/mach-msm/board-8974.c
+++ b/arch/arm/mach-msm/board-8974.c
@@ -66,168 +66,6 @@
return MEMTYPE_EBI1;
}
-static struct resource smd_resource[] = {
- {
- .name = "modem_smd_in",
- .start = 32 + 25, /* mss_sw_to_kpss_ipc_irq0 */
- .flags = IORESOURCE_IRQ,
- },
- {
- .name = "modem_smsm_in",
- .start = 32 + 26, /* mss_sw_to_kpss_ipc_irq1 */
- .flags = IORESOURCE_IRQ,
- },
- {
- .name = "adsp_smd_in",
- .start = 32 + 156, /* lpass_to_kpss_ipc_irq0 */
- .flags = IORESOURCE_IRQ,
- },
- {
- .name = "adsp_smsm_in",
- .start = 32 + 157, /* lpass_to_kpss_ipc_irq1 */
- .flags = IORESOURCE_IRQ,
- },
- {
- .name = "wcnss_smd_in",
- .start = 32 + 142, /* WcnssAppsSmdMedIrq */
- .flags = IORESOURCE_IRQ,
- },
- {
- .name = "wcnss_smsm_in",
- .start = 32 + 144, /* RivaAppsWlanSmsmIrq */
- .flags = IORESOURCE_IRQ,
- },
- {
- .name = "rpm_smd_in",
- .start = 32 + 168, /* rpm_to_kpss_ipc_irq4 */
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct smd_subsystem_config smd_config_list[] = {
- {
- .irq_config_id = SMD_MODEM,
- .subsys_name = "modem",
- .edge = SMD_APPS_MODEM,
-
- .smd_int.irq_name = "modem_smd_in",
- .smd_int.flags = IRQF_TRIGGER_RISING,
- .smd_int.irq_id = -1,
- .smd_int.device_name = "smd_dev",
- .smd_int.dev_id = 0,
- .smd_int.out_bit_pos = 1 << 12,
- .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
- .smd_int.out_offset = 0x8,
-
- .smsm_int.irq_name = "modem_smsm_in",
- .smsm_int.flags = IRQF_TRIGGER_RISING,
- .smsm_int.irq_id = -1,
- .smsm_int.device_name = "smsm_dev",
- .smsm_int.dev_id = 0,
- .smsm_int.out_bit_pos = 1 << 13,
- .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
- .smsm_int.out_offset = 0x8,
- },
- {
- .irq_config_id = SMD_Q6,
- .subsys_name = "adsp",
- .edge = SMD_APPS_QDSP,
-
- .smd_int.irq_name = "adsp_smd_in",
- .smd_int.flags = IRQF_TRIGGER_RISING,
- .smd_int.irq_id = -1,
- .smd_int.device_name = "smd_dev",
- .smd_int.dev_id = 0,
- .smd_int.out_bit_pos = 1 << 8,
- .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
- .smd_int.out_offset = 0x8,
-
- .smsm_int.irq_name = "adsp_smsm_in",
- .smsm_int.flags = IRQF_TRIGGER_RISING,
- .smsm_int.irq_id = -1,
- .smsm_int.device_name = "smsm_dev",
- .smsm_int.dev_id = 0,
- .smsm_int.out_bit_pos = 1 << 9,
- .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
- .smsm_int.out_offset = 0x8,
- },
- {
- .irq_config_id = SMD_WCNSS,
- .subsys_name = "wcnss",
- .edge = SMD_APPS_WCNSS,
-
- .smd_int.irq_name = "wcnss_smd_in",
- .smd_int.flags = IRQF_TRIGGER_RISING,
- .smd_int.irq_id = -1,
- .smd_int.device_name = "smd_dev",
- .smd_int.dev_id = 0,
- .smd_int.out_bit_pos = 1 << 17,
- .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
- .smd_int.out_offset = 0x8,
-
- .smsm_int.irq_name = "wcnss_smsm_in",
- .smsm_int.flags = IRQF_TRIGGER_RISING,
- .smsm_int.irq_id = -1,
- .smsm_int.device_name = "smsm_dev",
- .smsm_int.dev_id = 0,
- .smsm_int.out_bit_pos = 1 << 19,
- .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
- .smsm_int.out_offset = 0x8,
- },
- {
- .irq_config_id = SMD_RPM,
- .subsys_name = NULL, /* do not use PIL to load RPM */
- .edge = SMD_APPS_RPM,
-
- .smd_int.irq_name = "rpm_smd_in",
- .smd_int.flags = IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
- .smd_int.irq_id = -1,
- .smd_int.device_name = "smd_dev",
- .smd_int.dev_id = 0,
- .smd_int.out_bit_pos = 1 << 0,
- .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
- .smd_int.out_offset = 0x8,
-
- .smsm_int.irq_name = NULL, /* RPM does not support SMSM */
- .smsm_int.flags = 0,
- .smsm_int.irq_id = 0,
- .smsm_int.device_name = NULL,
- .smsm_int.dev_id = 0,
- .smsm_int.out_bit_pos = 0,
- .smsm_int.out_base = NULL,
- .smsm_int.out_offset = 0,
- },
-};
-
-static struct smd_smem_regions aux_smem_areas[] = {
- {
- .phys_addr = (void *)(0xfc428000),
- .size = 0x4000,
- },
-};
-
-static struct smd_subsystem_restart_config smd_ssr_cfg = {
- .disable_smsm_reset_handshake = 1,
-};
-
-static struct smd_platform smd_platform_data = {
- .num_ss_configs = ARRAY_SIZE(smd_config_list),
- .smd_ss_configs = smd_config_list,
- .smd_ssr_config = &smd_ssr_cfg,
- .num_smem_areas = ARRAY_SIZE(aux_smem_areas),
- .smd_smem_areas = aux_smem_areas,
-};
-
-struct platform_device msm_device_smd_8974 = {
- .name = "msm_smd",
- .id = -1,
- .resource = smd_resource,
- .num_resources = ARRAY_SIZE(smd_resource),
- .dev = {
- .platform_data = &smd_platform_data,
- }
-};
-
static struct reserve_info msm8974_reserve_info __initdata = {
.memtype_reserve_table = msm8974_reserve_table,
.paddr_to_memtype = msm8974_paddr_to_memtype,
@@ -426,11 +264,6 @@
ARRAY_SIZE(msm_bus_8974_devices));
};
-void __init msm8974_add_devices(void)
-{
- platform_device_register(&msm_device_smd_8974);
-}
-
/*
* Used to satisfy dependencies for devices that need to be
* run early or in a particular order. Most likely your device doesn't fall
@@ -536,7 +369,6 @@
regulator_has_full_constraints();
of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
- msm8974_add_devices();
msm8974_add_drivers();
}
diff --git a/arch/arm/mach-msm/board-9625-gpiomux.c b/arch/arm/mach-msm/board-9625-gpiomux.c
index 8f07ff0..9102875 100644
--- a/arch/arm/mach-msm/board-9625-gpiomux.c
+++ b/arch/arm/mach-msm/board-9625-gpiomux.c
@@ -93,6 +93,72 @@
},
};
+static struct gpiomux_setting mi2s_active_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting mi2s_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting codec_reset = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_NONE,
+ .dir = GPIOMUX_OUT_LOW,
+};
+
+static struct msm_gpiomux_config mdm9625_mi2s_configs[] __initdata = {
+ {
+ .gpio = 12, /* mi2s ws */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mi2s_suspend_cfg,
+ [GPIOMUX_ACTIVE] = &mi2s_active_cfg,
+ },
+ },
+ {
+ .gpio = 15, /* mi2s sclk */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mi2s_suspend_cfg,
+ [GPIOMUX_ACTIVE] = &mi2s_active_cfg,
+ },
+ },
+ {
+ .gpio = 14, /* mi2s dout */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mi2s_suspend_cfg,
+ [GPIOMUX_ACTIVE] = &mi2s_active_cfg,
+ },
+ },
+ {
+ .gpio = 13, /* mi2s din */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mi2s_suspend_cfg,
+ [GPIOMUX_ACTIVE] = &mi2s_active_cfg,
+ },
+ },
+ {
+ .gpio = 71, /* mi2s mclk */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mi2s_suspend_cfg,
+ [GPIOMUX_ACTIVE] = &mi2s_active_cfg,
+ },
+ },
+};
+
+static struct msm_gpiomux_config mdm9625_cdc_reset_config[] __initdata = {
+ {
+ .gpio = 22, /* SYS_RST_N */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &codec_reset,
+ },
+ }
+};
+
static struct gpiomux_setting sdc3_clk_active_cfg = {
.func = GPIOMUX_FUNC_1,
.drv = GPIOMUX_DRV_8MA,
@@ -207,4 +273,8 @@
msm_gpiomux_install(sdc3_configs, ARRAY_SIZE(sdc3_configs));
msm_gpiomux_install(wlan_ath6kl_configs,
ARRAY_SIZE(wlan_ath6kl_configs));
+ msm_gpiomux_install(mdm9625_mi2s_configs,
+ ARRAY_SIZE(mdm9625_mi2s_configs));
+ msm_gpiomux_install(mdm9625_cdc_reset_config,
+ ARRAY_SIZE(mdm9625_cdc_reset_config));
}
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index e1390db..3f59035 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -279,8 +279,8 @@
.en_mask = BIT(1),
.status_reg = PLL1_STATUS_BASE_REG,
.status_mask = BIT(16),
- .parent = &tcxo_clk.c,
.c = {
+ .parent = &tcxo_clk.c,
.dbg_name = "pll1_clk",
.rate = 768000000,
.ops = &clk_ops_pll_vote,
@@ -293,8 +293,8 @@
.en_mask = BIT(2),
.status_reg = PLL2_STATUS_BASE_REG,
.status_mask = BIT(16),
- .parent = &tcxo_clk.c,
.c = {
+ .parent = &tcxo_clk.c,
.dbg_name = "pll2_clk",
.rate = 806400000, /* TODO: Support scaling */
.ops = &clk_ops_pll_vote,
@@ -307,8 +307,8 @@
.en_mask = BIT(3),
.status_reg = PLL3_STATUS_BASE_REG,
.status_mask = BIT(16),
- .parent = &lpxo_clk.c,
.c = {
+ .parent = &lpxo_clk.c,
.dbg_name = "pll3_clk",
.rate = 737280000,
.ops = &clk_ops_pll_vote,
@@ -321,8 +321,8 @@
.en_mask = BIT(4),
.status_reg = PLL4_STATUS_BASE_REG,
.status_mask = BIT(16),
- .parent = &lpxo_clk.c,
.c = {
+ .parent = &lpxo_clk.c,
.dbg_name = "pll4_clk",
.rate = 891000000,
.ops = &clk_ops_pll_vote,
@@ -363,8 +363,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 2,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "axi_li_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(axi_li_apps_clk.c),
@@ -379,8 +379,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 14,
},
- .parent = &axi_li_apps_clk.c,
.c = {
+ .parent = &axi_li_apps_clk.c,
.dbg_name = "axi_li_adsp_a_clk",
.ops = &clk_ops_branch,
CLK_INIT(axi_li_adsp_a_clk.c),
@@ -395,8 +395,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 19,
},
- .parent = &axi_li_apps_clk.c,
.c = {
+ .parent = &axi_li_apps_clk.c,
.dbg_name = "axi_li_jpeg_clk",
.ops = &clk_ops_branch,
CLK_INIT(axi_li_jpeg_clk.c),
@@ -411,8 +411,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 23,
},
- .parent = &axi_li_apps_clk.c,
.c = {
+ .parent = &axi_li_apps_clk.c,
.dbg_name = "axi_li_vfe_clk",
.ops = &clk_ops_branch,
CLK_INIT(axi_li_vfe_clk.c),
@@ -427,8 +427,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 29,
},
- .parent = &axi_li_apps_clk.c,
.c = {
+ .parent = &axi_li_apps_clk.c,
.dbg_name = "axi_mdp_clk",
.ops = &clk_ops_branch,
CLK_INIT(axi_mdp_clk.c),
@@ -443,8 +443,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 3,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "axi_li_vg_clk",
.ops = &clk_ops_branch,
CLK_INIT(axi_li_vg_clk.c),
@@ -459,8 +459,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 21,
},
- .parent = &axi_li_vg_clk.c,
.c = {
+ .parent = &axi_li_vg_clk.c,
.dbg_name = "axi_grp_2d_clk",
.ops = &clk_ops_branch,
CLK_INIT(axi_grp_2d_clk.c),
@@ -475,8 +475,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 22,
},
- .parent = &axi_li_vg_clk.c,
.c = {
+ .parent = &axi_li_vg_clk.c,
.dbg_name = "axi_li_grp_clk",
.ops = &clk_ops_branch,
CLK_INIT(axi_li_grp_clk.c),
@@ -491,8 +491,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 20,
},
- .parent = &axi_li_vg_clk.c,
.c = {
+ .parent = &axi_li_vg_clk.c,
.dbg_name = "axi_mfc_clk",
.ops = &clk_ops_branch,
CLK_INIT(axi_mfc_clk.c),
@@ -508,8 +508,8 @@
.halt_bit = 22,
.reset_mask = P_AXI_ROTATOR_CLK,
},
- .parent = &axi_li_vg_clk.c,
.c = {
+ .parent = &axi_li_vg_clk.c,
.dbg_name = "axi_rotator_clk",
.ops = &clk_ops_branch,
CLK_INIT(axi_rotator_clk.c),
@@ -524,8 +524,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 21,
},
- .parent = &axi_li_vg_clk.c,
.c = {
+ .parent = &axi_li_vg_clk.c,
.dbg_name = "axi_vpe_clk",
.ops = &clk_ops_branch,
CLK_INIT(axi_vpe_clk.c),
@@ -542,8 +542,8 @@
.halt_bit = 5,
.reset_mask = P_ADM_CLK,
},
- .parent = &axi_li_apps_clk.c,
.c = {
+ .parent = &axi_li_apps_clk.c,
.dbg_name = "adm_clk",
.ops = &clk_ops_branch,
CLK_INIT(adm_clk.c),
@@ -558,8 +558,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 15,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "adm_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(adm_p_clk.c),
@@ -575,8 +575,8 @@
.halt_bit = 6,
.reset_mask = P_CE_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "ce_clk",
.ops = &clk_ops_branch,
CLK_INIT(ce_clk.c),
@@ -592,8 +592,8 @@
.halt_bit = 9,
.reset_mask = P_CAMIF_PAD_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "camif_pad_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(camif_pad_p_clk.c),
@@ -609,8 +609,8 @@
.halt_bit = 30,
.reset_mask = P_CSI0_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "csi0_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi0_p_clk.c),
@@ -626,8 +626,8 @@
.halt_bit = 3,
.reset_mask = P_EMDH_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "emdh_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(emdh_p_clk.c),
@@ -643,8 +643,8 @@
.halt_bit = 24,
.reset_mask = P_GRP_2D_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "grp_2d_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(grp_2d_p_clk.c),
@@ -660,8 +660,8 @@
.halt_bit = 17,
.reset_mask = P_GRP_3D_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "grp_3d_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(grp_3d_p_clk.c),
@@ -677,8 +677,8 @@
.halt_bit = 24,
.reset_mask = P_JPEG_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "jpeg_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(jpeg_p_clk.c),
@@ -694,8 +694,8 @@
.halt_bit = 7,
.reset_mask = P_LPA_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "lpa_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(lpa_p_clk.c),
@@ -711,8 +711,8 @@
.halt_bit = 6,
.reset_mask = P_MDP_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "mdp_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdp_p_clk.c),
@@ -728,8 +728,8 @@
.halt_bit = 26,
.reset_mask = P_MFC_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "mfc_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(mfc_p_clk.c),
@@ -745,8 +745,8 @@
.halt_bit = 4,
.reset_mask = P_PMDH_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "pmdh_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(pmdh_p_clk.c),
@@ -762,8 +762,8 @@
.halt_bit = 23,
.reset_mask = P_ROTATOR_IMEM_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "rotator_imem_clk",
.ops = &clk_ops_branch,
CLK_INIT(rotator_imem_clk.c),
@@ -779,8 +779,8 @@
.halt_bit = 25,
.reset_mask = P_ROTATOR_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "rotator_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(rotator_p_clk.c),
@@ -796,8 +796,8 @@
.halt_bit = 7,
.reset_mask = P_SDC1_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "sdc1_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(sdc1_p_clk.c),
@@ -813,8 +813,8 @@
.halt_bit = 8,
.reset_mask = P_SDC2_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "sdc2_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(sdc2_p_clk.c),
@@ -830,8 +830,8 @@
.halt_bit = 27,
.reset_mask = P_SDC3_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "sdc3_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(sdc3_p_clk.c),
@@ -847,8 +847,8 @@
.halt_bit = 28,
.reset_mask = P_SDC4_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "sdc4_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(sdc4_p_clk.c),
@@ -864,8 +864,8 @@
.halt_bit = 10,
.reset_mask = P_SPI_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "spi_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(spi_p_clk.c),
@@ -881,8 +881,8 @@
.halt_bit = 18,
.reset_mask = P_TSIF_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "tsif_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(tsif_p_clk.c),
@@ -897,8 +897,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 17,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "uart1dm_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(uart1dm_p_clk.c),
@@ -913,8 +913,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 26,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "uart2dm_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(uart2dm_p_clk.c),
@@ -930,8 +930,8 @@
.halt_bit = 8,
.reset_mask = P_USB_HS2_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "usb_hs2_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_hs2_p_clk.c),
@@ -947,8 +947,8 @@
.halt_bit = 9,
.reset_mask = P_USB_HS3_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "usb_hs3_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_hs3_p_clk.c),
@@ -964,8 +964,8 @@
.halt_bit = 25,
.reset_mask = P_USB_HS_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "usb_hs_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_hs_p_clk.c),
@@ -981,8 +981,8 @@
.halt_bit = 27,
.reset_mask = P_VFE_P_CLK,
},
- .parent = &glbl_root_clk.c,
.c = {
+ .parent = &glbl_root_clk.c,
.dbg_name = "vfe_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(vfe_p_clk.c),
@@ -1320,8 +1320,8 @@
.halt_bit = 18,
.reset_mask = P_GRP_3D_CLK,
},
- .parent = &grp_3d_src_clk.c,
.c = {
+ .parent = &grp_3d_src_clk.c,
.dbg_name = "grp_3d_clk",
.ops = &clk_ops_branch,
CLK_INIT(grp_3d_clk.c),
@@ -1336,8 +1336,8 @@
.halt_bit = 19,
.reset_mask = P_IMEM_CLK,
},
- .parent = &grp_3d_src_clk.c,
.c = {
+ .parent = &grp_3d_src_clk.c,
.dbg_name = "imem_clk",
.ops = &clk_ops_branch,
CLK_INIT(imem_clk.c),
@@ -1542,8 +1542,8 @@
.halt_bit = 29,
.reset_mask = P_MDP_LCDC_PAD_PCLK_CLK,
},
- .parent = &mdp_lcdc_pclk_clk.c,
.c = {
+ .parent = &mdp_lcdc_pclk_clk.c,
.dbg_name = "mdp_lcdc_pad_pclk_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdp_lcdc_pad_pclk_clk.c),
@@ -1616,8 +1616,8 @@
.halt_bit = 13,
.reset_mask = P_MI2S_CODEC_RX_S_CLK,
},
- .parent = &mi2s_codec_rx_m_clk.c,
.c = {
+ .parent = &mi2s_codec_rx_m_clk.c,
.dbg_name = "mi2s_codec_rx_s_clk",
.ops = &clk_ops_branch,
CLK_INIT(mi2s_codec_rx_s_clk.c),
@@ -1656,8 +1656,8 @@
.halt_bit = 11,
.reset_mask = P_MI2S_CODEC_TX_S_CLK,
},
- .parent = &mi2s_codec_tx_m_clk.c,
.c = {
+ .parent = &mi2s_codec_tx_m_clk.c,
.dbg_name = "mi2s_codec_tx_s_clk",
.ops = &clk_ops_branch,
CLK_INIT(mi2s_codec_tx_s_clk.c),
@@ -1702,8 +1702,8 @@
.halt_bit = 3,
.reset_mask = P_MI2S_S_CLK,
},
- .parent = &mi2s_m_clk.c,
.c = {
+ .parent = &mi2s_m_clk.c,
.dbg_name = "mi2s_s_clk",
.ops = &clk_ops_branch,
CLK_INIT(mi2s_s_clk.c),
@@ -1763,8 +1763,8 @@
.halt_bit = 17,
.reset_mask = P_SDAC_M_CLK,
},
- .parent = &sdac_clk.c,
.c = {
+ .parent = &sdac_clk.c,
.dbg_name = "sdac_m_clk",
.ops = &clk_ops_branch,
CLK_INIT(sdac_m_clk.c),
@@ -1807,8 +1807,8 @@
.halt_bit = 7,
.reset_mask = P_HDMI_CLK,
},
- .parent = &tv_clk.c,
.c = {
+ .parent = &tv_clk.c,
.dbg_name = "hdmi_clk",
.ops = &clk_ops_branch,
CLK_INIT(hdmi_clk.c),
@@ -1823,8 +1823,8 @@
.halt_bit = 27,
.reset_mask = P_TV_DAC_CLK,
},
- .parent = &tv_clk.c,
.c = {
+ .parent = &tv_clk.c,
.dbg_name = "tv_dac_clk",
.ops = &clk_ops_branch,
CLK_INIT(tv_dac_clk.c),
@@ -1839,8 +1839,8 @@
.halt_bit = 10,
.reset_mask = P_TV_ENC_CLK,
},
- .parent = &tv_clk.c,
.c = {
+ .parent = &tv_clk.c,
.dbg_name = "tv_enc_clk",
.ops = &clk_ops_branch,
CLK_INIT(tv_enc_clk.c),
@@ -1856,8 +1856,8 @@
.halt_bit = 11,
.reset_mask = P_TSIF_REF_CLK,
},
- .parent = &tv_clk.c,
.c = {
+ .parent = &tv_clk.c,
.dbg_name = "tsif_ref_clk",
.ops = &clk_ops_branch,
CLK_INIT(tsif_ref_clk.c),
@@ -1915,8 +1915,8 @@
.halt_bit = 27,
.reset_mask = P_USB_HS_CORE_CLK,
},
- .parent = &usb_hs_src_clk.c,
.c = {
+ .parent = &usb_hs_src_clk.c,
.dbg_name = "usb_hs_core_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_hs_core_clk.c),
@@ -1931,8 +1931,8 @@
.halt_bit = 3,
.reset_mask = P_USB_HS2_CLK,
},
- .parent = &usb_hs_src_clk.c,
.c = {
+ .parent = &usb_hs_src_clk.c,
.dbg_name = "usb_hs2_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_hs2_clk.c),
@@ -1947,8 +1947,8 @@
.halt_bit = 28,
.reset_mask = P_USB_HS2_CORE_CLK,
},
- .parent = &usb_hs_src_clk.c,
.c = {
+ .parent = &usb_hs_src_clk.c,
.dbg_name = "usb_hs2_core_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_hs2_core_clk.c),
@@ -1963,8 +1963,8 @@
.halt_bit = 2,
.reset_mask = P_USB_HS3_CLK,
},
- .parent = &usb_hs_src_clk.c,
.c = {
+ .parent = &usb_hs_src_clk.c,
.dbg_name = "usb_hs3_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_hs3_clk.c),
@@ -1979,8 +1979,8 @@
.halt_bit = 29,
.reset_mask = P_USB_HS3_CORE_CLK,
},
- .parent = &usb_hs_src_clk.c,
.c = {
+ .parent = &usb_hs_src_clk.c,
.dbg_name = "usb_hs3_core_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_hs3_core_clk.c),
@@ -2062,8 +2062,8 @@
.halt_bit = 9,
.reset_mask = P_VFE_MDC_CLK,
},
- .parent = &vfe_clk.c,
.c = {
+ .parent = &vfe_clk.c,
.dbg_name = "vfe_mdc_clk",
.ops = &clk_ops_branch,
CLK_INIT(vfe_mdc_clk.c),
@@ -2078,8 +2078,8 @@
.halt_bit = 13,
.reset_mask = P_VFE_CAMIF_CLK,
},
- .parent = &vfe_clk.c,
.c = {
+ .parent = &vfe_clk.c,
.dbg_name = "vfe_camif_clk",
.ops = &clk_ops_branch,
CLK_INIT(vfe_camif_clk.c),
@@ -2094,8 +2094,8 @@
.halt_bit = 16,
.reset_mask = P_CSI0_VFE_CLK,
},
- .parent = &vfe_clk.c,
.c = {
+ .parent = &vfe_clk.c,
.dbg_name = "csi0_vfe_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi0_vfe_clk.c),
@@ -2219,8 +2219,8 @@
.halt_bit = 11,
.reset_mask = P_MFC_DIV2_CLK,
},
- .parent = &mfc_clk.c,
.c = {
+ .parent = &mfc_clk.c,
.dbg_name = "mfc_div2_clk",
.ops = &clk_ops_branch,
CLK_INIT(mfc_div2_clk.c),
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index ca47ea1..a4d7e61 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -525,8 +525,8 @@
static struct pll_clk pll2_clk = {
.mode_reg = MM_PLL1_MODE_REG,
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "pll2_clk",
.rate = 800000000,
.ops = &clk_ops_local_pll,
@@ -536,8 +536,8 @@
static struct pll_clk pll3_clk = {
.mode_reg = BB_MMCC_PLL2_MODE_REG,
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "pll3_clk",
.rate = 1200000000,
.ops = &clk_ops_local_pll,
@@ -555,8 +555,8 @@
.en_mask = BIT(4),
.status_reg = LCC_PLL0_STATUS_REG,
.status_mask = BIT(16),
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "pll4_clk",
.rate = 393216000,
.ops = &clk_ops_pll_vote,
@@ -569,8 +569,8 @@
.en_mask = BIT(8),
.status_reg = BB_PLL8_STATUS_REG,
.status_mask = BIT(16),
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "pll8_clk",
.rate = 384000000,
.ops = &clk_ops_pll_vote,
@@ -583,8 +583,8 @@
.en_mask = BIT(14),
.status_reg = BB_PLL14_STATUS_REG,
.status_mask = BIT(16),
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "pll14_clk",
.rate = 480000000,
.ops = &clk_ops_pll_vote,
@@ -594,8 +594,8 @@
static struct pll_clk pll15_clk = {
.mode_reg = MM_PLL3_MODE_REG,
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "pll15_clk",
.rate = 975000000,
.ops = &clk_ops_local_pll,
@@ -1701,8 +1701,8 @@
.halt_reg = CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 24,
},
- .parent = &usb_hsic_xcvr_fs_clk.c,
.c = {
+ .parent = &usb_hsic_xcvr_fs_clk.c,
.dbg_name = "usb_hsic_system_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_hsic_system_clk.c),
@@ -1743,8 +1743,8 @@
.halt_reg = CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 19,
},
- .parent = &usb_hsic_hsic_src_clk.c,
.c = {
+ .parent = &usb_hsic_hsic_src_clk.c,
.dbg_name = "usb_hsic_hsic_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_hsic_hsic_clk.c),
@@ -1823,8 +1823,8 @@
.halt_reg = CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 15,
},
- .parent = &usb_fs1_src_clk.c,
.c = {
+ .parent = &usb_fs1_src_clk.c,
.dbg_name = "usb_fs1_xcvr_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_fs1_xcvr_clk.c),
@@ -1840,8 +1840,8 @@
.halt_reg = CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 16,
},
- .parent = &usb_fs1_src_clk.c,
.c = {
+ .parent = &usb_fs1_src_clk.c,
.dbg_name = "usb_fs1_sys_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_fs1_sys_clk.c),
@@ -1858,8 +1858,8 @@
.halt_reg = CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 12,
},
- .parent = &usb_fs2_src_clk.c,
.c = {
+ .parent = &usb_fs2_src_clk.c,
.dbg_name = "usb_fs2_xcvr_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_fs2_xcvr_clk.c),
@@ -1875,8 +1875,8 @@
.halt_reg = CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 13,
},
- .parent = &usb_fs2_src_clk.c,
.c = {
+ .parent = &usb_fs2_src_clk.c,
.dbg_name = "usb_fs2_sys_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_fs2_sys_clk.c),
@@ -1962,8 +1962,8 @@
.halt_reg = CLK_HALT_MSS_SMPSS_MISC_STATE_REG,
.halt_bit = 5,
},
- .parent = &ce3_src_clk.c,
.c = {
+ .parent = &ce3_src_clk.c,
.dbg_name = "ce3_core_clk",
.ops = &clk_ops_branch,
CLK_INIT(ce3_core_clk.c),
@@ -1979,8 +1979,8 @@
.halt_reg = CLK_HALT_AFAB_SFAB_STATEB_REG,
.halt_bit = 16,
},
- .parent = &ce3_src_clk.c,
.c = {
+ .parent = &ce3_src_clk.c,
.dbg_name = "ce3_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(ce3_p_clk.c),
@@ -2027,8 +2027,8 @@
.halt_reg = CLK_HALT_MSS_SMPSS_MISC_STATE_REG,
.halt_bit = 26,
},
- .parent = &sata_src_clk.c,
.c = {
+ .parent = &sata_src_clk.c,
.dbg_name = "sata_rxoob_clk",
.ops = &clk_ops_branch,
CLK_INIT(sata_rxoob_clk.c),
@@ -2042,8 +2042,8 @@
.halt_reg = CLK_HALT_MSS_SMPSS_MISC_STATE_REG,
.halt_bit = 25,
},
- .parent = &sata_src_clk.c,
.c = {
+ .parent = &sata_src_clk.c,
.dbg_name = "sata_pmalive_clk",
.ops = &clk_ops_branch,
CLK_INIT(sata_pmalive_clk.c),
@@ -2057,8 +2057,8 @@
.halt_reg = CLK_HALT_MSS_SMPSS_MISC_STATE_REG,
.halt_bit = 24,
},
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "sata_phy_ref_clk",
.ops = &clk_ops_branch,
CLK_INIT(sata_phy_ref_clk.c),
@@ -2750,8 +2750,8 @@
.halt_reg = DBG_BUS_VEC_B_REG,
.halt_bit = 13,
},
- .parent = &csi0_src_clk.c,
.c = {
+ .parent = &csi0_src_clk.c,
.dbg_name = "csi0_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi0_clk.c),
@@ -2767,8 +2767,8 @@
.halt_reg = DBG_BUS_VEC_I_REG,
.halt_bit = 9,
},
- .parent = &csi0_src_clk.c,
.c = {
+ .parent = &csi0_src_clk.c,
.dbg_name = "csi0_phy_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi0_phy_clk.c),
@@ -2806,8 +2806,8 @@
.halt_reg = DBG_BUS_VEC_B_REG,
.halt_bit = 14,
},
- .parent = &csi1_src_clk.c,
.c = {
+ .parent = &csi1_src_clk.c,
.dbg_name = "csi1_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi1_clk.c),
@@ -2823,8 +2823,8 @@
.halt_reg = DBG_BUS_VEC_I_REG,
.halt_bit = 10,
},
- .parent = &csi1_src_clk.c,
.c = {
+ .parent = &csi1_src_clk.c,
.dbg_name = "csi1_phy_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi1_phy_clk.c),
@@ -2862,8 +2862,8 @@
.halt_reg = DBG_BUS_VEC_B_REG,
.halt_bit = 29,
},
- .parent = &csi2_src_clk.c,
.c = {
+ .parent = &csi2_src_clk.c,
.dbg_name = "csi2_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi2_clk.c),
@@ -2879,8 +2879,8 @@
.halt_reg = DBG_BUS_VEC_I_REG,
.halt_bit = 29,
},
- .parent = &csi2_src_clk.c,
.c = {
+ .parent = &csi2_src_clk.c,
.dbg_name = "csi2_phy_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi2_phy_clk.c),
@@ -2977,6 +2977,7 @@
mb();
udelay(1);
rdi->cur_rate = rate;
+ c->parent = mux_map[rate];
spin_unlock(&local_clock_reg_lock);
if (rdi->enabled)
@@ -3038,11 +3039,6 @@
return branch_reset(&to_pix_rdi_clk(c)->b, action);
}
-static struct clk *pix_rdi_clk_get_parent(struct clk *c)
-{
- return pix_rdi_mux_map[to_pix_rdi_clk(c)->cur_rate];
-}
-
static int pix_rdi_clk_list_rate(struct clk *c, unsigned n)
{
if (pix_rdi_mux_map[n])
@@ -3064,6 +3060,7 @@
rdi->cur_rate = reg & rdi->s_mask ? 1 : 0;
reg = readl_relaxed(rdi->s2_reg);
rdi->cur_rate = reg & rdi->s2_mask ? 2 : rdi->cur_rate;
+ c->parent = pix_rdi_mux_map[rdi->cur_rate];
return HANDOFF_ENABLED_CLK;
}
@@ -3078,7 +3075,6 @@
.get_rate = pix_rdi_clk_get_rate,
.list_rate = pix_rdi_clk_list_rate,
.reset = pix_rdi_clk_reset,
- .get_parent = pix_rdi_clk_get_parent,
};
static struct pix_rdi_clk csi_pix_clk = {
@@ -3220,8 +3216,8 @@
.halt_reg = DBG_BUS_VEC_I_REG,
.halt_bit = 17,
},
- .parent = &csiphy_timer_src_clk.c,
.c = {
+ .parent = &csiphy_timer_src_clk.c,
.dbg_name = "csi0phy_timer_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi0phy_timer_clk.c),
@@ -3235,8 +3231,8 @@
.halt_reg = DBG_BUS_VEC_I_REG,
.halt_bit = 18,
},
- .parent = &csiphy_timer_src_clk.c,
.c = {
+ .parent = &csiphy_timer_src_clk.c,
.dbg_name = "csi1phy_timer_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi1phy_timer_clk.c),
@@ -3250,8 +3246,8 @@
.halt_reg = DBG_BUS_VEC_I_REG,
.halt_bit = 30,
},
- .parent = &csiphy_timer_src_clk.c,
.c = {
+ .parent = &csiphy_timer_src_clk.c,
.dbg_name = "csi2phy_timer_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi2phy_timer_clk.c),
@@ -3719,8 +3715,8 @@
.halt_reg = DBG_BUS_VEC_J_REG,
.halt_bit = 25,
},
- .parent = &vcap_clk.c,
.c = {
+ .parent = &vcap_clk.c,
.dbg_name = "vcap_npl_clk",
.ops = &clk_ops_branch,
CLK_INIT(vcap_npl_clk.c),
@@ -3937,8 +3933,8 @@
.retain_reg = MDP_LUT_CC_REG,
.retain_mask = BIT(31),
},
- .parent = &mdp_clk.c,
.c = {
+ .parent = &mdp_clk.c,
.dbg_name = "lut_mdp_clk",
.ops = &clk_ops_branch,
CLK_INIT(lut_mdp_clk.c),
@@ -4058,18 +4054,13 @@
spin_unlock_irqrestore(&local_clock_reg_lock, flags);
}
-static struct clk *hdmi_pll_clk_get_parent(struct clk *c)
-{
- return &pxo_clk.c;
-}
-
static struct clk_ops clk_ops_hdmi_pll = {
.enable = hdmi_pll_clk_enable,
.disable = hdmi_pll_clk_disable,
- .get_parent = hdmi_pll_clk_get_parent,
};
static struct clk hdmi_pll_clk = {
+ .parent = &pxo_clk.c,
.dbg_name = "hdmi_pll_clk",
.ops = &clk_ops_hdmi_pll,
.vdd_class = &vdd_sr2_hdmi_pll,
@@ -4176,8 +4167,8 @@
.halt_reg = DBG_BUS_VEC_D_REG,
.halt_bit = 9,
},
- .parent = &tv_src_clk.c,
.c = {
+ .parent = &tv_src_clk.c,
.dbg_name = "tv_enc_clk",
.ops = &clk_ops_branch,
CLK_INIT(tv_enc_clk.c),
@@ -4191,8 +4182,8 @@
.halt_reg = DBG_BUS_VEC_D_REG,
.halt_bit = 10,
},
- .parent = &tv_src_clk.c,
.c = {
+ .parent = &tv_src_clk.c,
.dbg_name = "tv_dac_clk",
.ops = &clk_ops_branch,
CLK_INIT(tv_dac_clk.c),
@@ -4210,8 +4201,8 @@
.retain_reg = TV_CC2_REG,
.retain_mask = BIT(10),
},
- .parent = &tv_src_clk.c,
.c = {
+ .parent = &tv_src_clk.c,
.dbg_name = "mdp_tv_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdp_tv_clk.c),
@@ -4227,8 +4218,8 @@
.halt_reg = DBG_BUS_VEC_D_REG,
.halt_bit = 11,
},
- .parent = &tv_src_clk.c,
.c = {
+ .parent = &tv_src_clk.c,
.dbg_name = "hdmi_tv_clk",
.ops = &clk_ops_branch,
CLK_INIT(hdmi_tv_clk.c),
@@ -4242,8 +4233,8 @@
.halt_reg = DBG_BUS_VEC_J_REG,
.halt_bit = 27,
},
- .parent = &tv_src_clk.c,
.c = {
+ .parent = &tv_src_clk.c,
.dbg_name = "rgb_tv_clk",
.ops = &clk_ops_branch,
CLK_INIT(rgb_tv_clk.c),
@@ -4257,8 +4248,8 @@
.halt_reg = DBG_BUS_VEC_J_REG,
.halt_bit = 26,
},
- .parent = &tv_src_clk.c,
.c = {
+ .parent = &tv_src_clk.c,
.dbg_name = "npl_tv_clk",
.ops = &clk_ops_branch,
CLK_INIT(npl_tv_clk.c),
@@ -4480,8 +4471,8 @@
.halt_reg = DBG_BUS_VEC_B_REG,
.halt_bit = 8,
},
- .parent = &vfe_clk.c,
.c = {
+ .parent = &vfe_clk.c,
.dbg_name = "csi_vfe_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi_vfe_clk.c),
@@ -4753,8 +4744,8 @@
.halt_check = ENABLE,
.halt_bit = 1,
},
- .parent = &audio_slimbus_clk.c,
.c = {
+ .parent = &audio_slimbus_clk.c,
.dbg_name = "sps_slimbus_clk",
.ops = &clk_ops_branch,
CLK_INIT(sps_slimbus_clk.c),
@@ -4768,8 +4759,8 @@
.halt_reg = CLK_HALT_DFAB_STATE_REG,
.halt_bit = 28,
},
- .parent = &sps_slimbus_clk.c,
.c = {
+ .parent = &sps_slimbus_clk.c,
.dbg_name = "slimbus_xo_src_clk",
.ops = &clk_ops_branch,
CLK_INIT(slimbus_xo_src_clk.c),
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 1395f05..c0a553f 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -694,9 +694,9 @@
.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE_REG,
.status_reg = (void __iomem *)GPLL0_STATUS_REG,
.status_mask = BIT(17),
- .parent = &cxo_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.rate = 600000000,
.dbg_name = "gpll0_clk_src",
.ops = &clk_ops_pll_vote,
@@ -709,9 +709,9 @@
.en_mask = BIT(1),
.status_reg = (void __iomem *)GPLL1_STATUS_REG,
.status_mask = BIT(17),
- .parent = &cxo_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.rate = 480000000,
.dbg_name = "gpll1_clk_src",
.ops = &clk_ops_pll_vote,
@@ -724,9 +724,9 @@
.en_mask = BIT(0),
.status_reg = (void __iomem *)LPAPLL_STATUS_REG,
.status_mask = BIT(17),
- .parent = &cxo_clk_src.c,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.rate = 491520000,
.dbg_name = "lpapll0_clk_src",
.ops = &clk_ops_pll_vote,
@@ -739,9 +739,9 @@
.en_mask = BIT(0),
.status_reg = (void __iomem *)MMPLL0_STATUS_REG,
.status_mask = BIT(17),
- .parent = &cxo_clk_src.c,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "mmpll0_clk_src",
.rate = 800000000,
.ops = &clk_ops_pll_vote,
@@ -754,9 +754,9 @@
.en_mask = BIT(1),
.status_reg = (void __iomem *)MMPLL1_STATUS_REG,
.status_mask = BIT(17),
- .parent = &cxo_clk_src.c,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "mmpll1_clk_src",
.rate = 846000000,
.ops = &clk_ops_pll_vote,
@@ -767,9 +767,9 @@
static struct pll_clk mmpll3_clk_src = {
.mode_reg = (void __iomem *)MMPLL3_MODE_REG,
.status_reg = (void __iomem *)MMPLL3_STATUS_REG,
- .parent = &cxo_clk_src.c,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "mmpll3_clk_src",
.rate = 1000000000,
.ops = &clk_ops_local_pll,
@@ -1512,10 +1512,10 @@
static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup1_i2c_apps_clk.c),
@@ -1524,9 +1524,9 @@
static struct branch_clk gcc_blsp1_qup1_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP1_SPI_APPS_CBCR,
- .parent = &blsp1_qup1_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup1_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup1_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup1_spi_apps_clk.c),
@@ -1535,10 +1535,10 @@
static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup2_i2c_apps_clk.c),
@@ -1547,9 +1547,9 @@
static struct branch_clk gcc_blsp1_qup2_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP2_SPI_APPS_CBCR,
- .parent = &blsp1_qup2_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup2_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup2_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup2_spi_apps_clk.c),
@@ -1558,10 +1558,10 @@
static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup3_i2c_apps_clk.c),
@@ -1570,9 +1570,9 @@
static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP3_SPI_APPS_CBCR,
- .parent = &blsp1_qup3_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup3_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup3_spi_apps_clk.c),
@@ -1581,10 +1581,10 @@
static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup4_i2c_apps_clk.c),
@@ -1593,9 +1593,9 @@
static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP4_SPI_APPS_CBCR,
- .parent = &blsp1_qup4_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup4_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup4_spi_apps_clk.c),
@@ -1604,10 +1604,10 @@
static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup5_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup5_i2c_apps_clk.c),
@@ -1616,9 +1616,9 @@
static struct branch_clk gcc_blsp1_qup5_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP5_SPI_APPS_CBCR,
- .parent = &blsp1_qup5_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup5_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup5_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup5_spi_apps_clk.c),
@@ -1627,10 +1627,10 @@
static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup6_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup6_i2c_apps_clk.c),
@@ -1639,9 +1639,9 @@
static struct branch_clk gcc_blsp1_qup6_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP6_SPI_APPS_CBCR,
- .parent = &blsp1_qup6_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup6_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup6_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup6_spi_apps_clk.c),
@@ -1650,9 +1650,9 @@
static struct branch_clk gcc_blsp1_uart1_apps_clk = {
.cbcr_reg = BLSP1_UART1_APPS_CBCR,
- .parent = &blsp1_uart1_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart1_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart1_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart1_apps_clk.c),
@@ -1661,9 +1661,9 @@
static struct branch_clk gcc_blsp1_uart2_apps_clk = {
.cbcr_reg = BLSP1_UART2_APPS_CBCR,
- .parent = &blsp1_uart2_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart2_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart2_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart2_apps_clk.c),
@@ -1672,9 +1672,9 @@
static struct branch_clk gcc_blsp1_uart3_apps_clk = {
.cbcr_reg = BLSP1_UART3_APPS_CBCR,
- .parent = &blsp1_uart3_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart3_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart3_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart3_apps_clk.c),
@@ -1683,9 +1683,9 @@
static struct branch_clk gcc_blsp1_uart4_apps_clk = {
.cbcr_reg = BLSP1_UART4_APPS_CBCR,
- .parent = &blsp1_uart4_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart4_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart4_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart4_apps_clk.c),
@@ -1694,9 +1694,9 @@
static struct branch_clk gcc_blsp1_uart5_apps_clk = {
.cbcr_reg = BLSP1_UART5_APPS_CBCR,
- .parent = &blsp1_uart5_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart5_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart5_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart5_apps_clk.c),
@@ -1705,9 +1705,9 @@
static struct branch_clk gcc_blsp1_uart6_apps_clk = {
.cbcr_reg = BLSP1_UART6_APPS_CBCR,
- .parent = &blsp1_uart6_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart6_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart6_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart6_apps_clk.c),
@@ -1740,10 +1740,10 @@
static struct branch_clk gcc_blsp2_qup1_i2c_apps_clk = {
.cbcr_reg = BLSP2_QUP1_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp2_qup1_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup1_i2c_apps_clk.c),
@@ -1752,9 +1752,9 @@
static struct branch_clk gcc_blsp2_qup1_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP1_SPI_APPS_CBCR,
- .parent = &blsp2_qup1_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_qup1_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp2_qup1_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup1_spi_apps_clk.c),
@@ -1763,10 +1763,10 @@
static struct branch_clk gcc_blsp2_qup2_i2c_apps_clk = {
.cbcr_reg = BLSP2_QUP2_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp2_qup2_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup2_i2c_apps_clk.c),
@@ -1775,9 +1775,9 @@
static struct branch_clk gcc_blsp2_qup2_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP2_SPI_APPS_CBCR,
- .parent = &blsp2_qup2_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_qup2_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp2_qup2_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup2_spi_apps_clk.c),
@@ -1786,10 +1786,10 @@
static struct branch_clk gcc_blsp2_qup3_i2c_apps_clk = {
.cbcr_reg = BLSP2_QUP3_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp2_qup3_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup3_i2c_apps_clk.c),
@@ -1798,9 +1798,9 @@
static struct branch_clk gcc_blsp2_qup3_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP3_SPI_APPS_CBCR,
- .parent = &blsp2_qup3_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_qup3_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp2_qup3_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup3_spi_apps_clk.c),
@@ -1809,10 +1809,10 @@
static struct branch_clk gcc_blsp2_qup4_i2c_apps_clk = {
.cbcr_reg = BLSP2_QUP4_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp2_qup4_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup4_i2c_apps_clk.c),
@@ -1821,9 +1821,9 @@
static struct branch_clk gcc_blsp2_qup4_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP4_SPI_APPS_CBCR,
- .parent = &blsp2_qup4_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_qup4_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp2_qup4_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup4_spi_apps_clk.c),
@@ -1832,10 +1832,10 @@
static struct branch_clk gcc_blsp2_qup5_i2c_apps_clk = {
.cbcr_reg = BLSP2_QUP5_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp2_qup5_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup5_i2c_apps_clk.c),
@@ -1844,9 +1844,9 @@
static struct branch_clk gcc_blsp2_qup5_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP5_SPI_APPS_CBCR,
- .parent = &blsp2_qup5_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_qup5_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp2_qup5_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup5_spi_apps_clk.c),
@@ -1855,10 +1855,10 @@
static struct branch_clk gcc_blsp2_qup6_i2c_apps_clk = {
.cbcr_reg = BLSP2_QUP6_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp2_qup6_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup6_i2c_apps_clk.c),
@@ -1867,9 +1867,9 @@
static struct branch_clk gcc_blsp2_qup6_spi_apps_clk = {
.cbcr_reg = BLSP2_QUP6_SPI_APPS_CBCR,
- .parent = &blsp2_qup6_spi_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_qup6_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp2_qup6_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_qup6_spi_apps_clk.c),
@@ -1878,9 +1878,9 @@
static struct branch_clk gcc_blsp2_uart1_apps_clk = {
.cbcr_reg = BLSP2_UART1_APPS_CBCR,
- .parent = &blsp2_uart1_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_uart1_apps_clk_src.c,
.dbg_name = "gcc_blsp2_uart1_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_uart1_apps_clk.c),
@@ -1889,9 +1889,9 @@
static struct branch_clk gcc_blsp2_uart2_apps_clk = {
.cbcr_reg = BLSP2_UART2_APPS_CBCR,
- .parent = &blsp2_uart2_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_uart2_apps_clk_src.c,
.dbg_name = "gcc_blsp2_uart2_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_uart2_apps_clk.c),
@@ -1900,9 +1900,9 @@
static struct branch_clk gcc_blsp2_uart3_apps_clk = {
.cbcr_reg = BLSP2_UART3_APPS_CBCR,
- .parent = &blsp2_uart3_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_uart3_apps_clk_src.c,
.dbg_name = "gcc_blsp2_uart3_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_uart3_apps_clk.c),
@@ -1911,9 +1911,9 @@
static struct branch_clk gcc_blsp2_uart4_apps_clk = {
.cbcr_reg = BLSP2_UART4_APPS_CBCR,
- .parent = &blsp2_uart4_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_uart4_apps_clk_src.c,
.dbg_name = "gcc_blsp2_uart4_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_uart4_apps_clk.c),
@@ -1922,9 +1922,9 @@
static struct branch_clk gcc_blsp2_uart5_apps_clk = {
.cbcr_reg = BLSP2_UART5_APPS_CBCR,
- .parent = &blsp2_uart5_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_uart5_apps_clk_src.c,
.dbg_name = "gcc_blsp2_uart5_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_uart5_apps_clk.c),
@@ -1933,9 +1933,9 @@
static struct branch_clk gcc_blsp2_uart6_apps_clk = {
.cbcr_reg = BLSP2_UART6_APPS_CBCR,
- .parent = &blsp2_uart6_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp2_uart6_apps_clk_src.c,
.dbg_name = "gcc_blsp2_uart6_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp2_uart6_apps_clk.c),
@@ -2016,9 +2016,9 @@
static struct branch_clk gcc_gp1_clk = {
.cbcr_reg = GP1_CBCR,
- .parent = &gp1_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &gp1_clk_src.c,
.dbg_name = "gcc_gp1_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_gp1_clk.c),
@@ -2027,9 +2027,9 @@
static struct branch_clk gcc_gp2_clk = {
.cbcr_reg = GP2_CBCR,
- .parent = &gp2_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &gp2_clk_src.c,
.dbg_name = "gcc_gp2_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_gp2_clk.c),
@@ -2038,9 +2038,9 @@
static struct branch_clk gcc_gp3_clk = {
.cbcr_reg = GP3_CBCR,
- .parent = &gp3_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &gp3_clk_src.c,
.dbg_name = "gcc_gp3_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_gp3_clk.c),
@@ -2049,9 +2049,9 @@
static struct branch_clk gcc_pdm2_clk = {
.cbcr_reg = PDM2_CBCR,
- .parent = &pdm2_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &pdm2_clk_src.c,
.dbg_name = "gcc_pdm2_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_pdm2_clk.c),
@@ -2094,9 +2094,9 @@
static struct branch_clk gcc_sdcc1_apps_clk = {
.cbcr_reg = SDCC1_APPS_CBCR,
- .parent = &sdcc1_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &sdcc1_apps_clk_src.c,
.dbg_name = "gcc_sdcc1_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_sdcc1_apps_clk.c),
@@ -2116,9 +2116,9 @@
static struct branch_clk gcc_sdcc2_apps_clk = {
.cbcr_reg = SDCC2_APPS_CBCR,
- .parent = &sdcc2_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &sdcc2_apps_clk_src.c,
.dbg_name = "gcc_sdcc2_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_sdcc2_apps_clk.c),
@@ -2138,9 +2138,9 @@
static struct branch_clk gcc_sdcc3_apps_clk = {
.cbcr_reg = SDCC3_APPS_CBCR,
- .parent = &sdcc3_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &sdcc3_apps_clk_src.c,
.dbg_name = "gcc_sdcc3_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_sdcc3_apps_clk.c),
@@ -2160,9 +2160,9 @@
static struct branch_clk gcc_sdcc4_apps_clk = {
.cbcr_reg = SDCC4_APPS_CBCR,
- .parent = &sdcc4_apps_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &sdcc4_apps_clk_src.c,
.dbg_name = "gcc_sdcc4_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_sdcc4_apps_clk.c),
@@ -2182,9 +2182,9 @@
static struct branch_clk gcc_tsif_ref_clk = {
.cbcr_reg = TSIF_REF_CBCR,
- .parent = &tsif_ref_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &tsif_ref_clk_src.c,
.dbg_name = "gcc_tsif_ref_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_tsif_ref_clk.c),
@@ -2193,10 +2193,10 @@
struct branch_clk gcc_sys_noc_usb3_axi_clk = {
.cbcr_reg = SYS_NOC_USB3_AXI_CBCR,
- .parent = &usb30_master_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb30_master_clk_src.c,
.dbg_name = "gcc_sys_noc_usb3_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_sys_noc_usb3_axi_clk.c),
@@ -2206,10 +2206,10 @@
static struct branch_clk gcc_usb30_master_clk = {
.cbcr_reg = USB30_MASTER_CBCR,
.bcr_reg = USB_30_BCR,
- .parent = &usb30_master_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb30_master_clk_src.c,
.dbg_name = "gcc_usb30_master_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb30_master_clk.c),
@@ -2219,9 +2219,9 @@
static struct branch_clk gcc_usb30_mock_utmi_clk = {
.cbcr_reg = USB30_MOCK_UTMI_CBCR,
- .parent = &usb30_mock_utmi_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb30_mock_utmi_clk_src.c,
.dbg_name = "gcc_usb30_mock_utmi_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb30_mock_utmi_clk.c),
@@ -2275,9 +2275,9 @@
static struct branch_clk gcc_usb_hs_system_clk = {
.cbcr_reg = USB_HS_SYSTEM_CBCR,
.bcr_reg = USB_HS_BCR,
- .parent = &usb_hs_system_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb_hs_system_clk_src.c,
.dbg_name = "gcc_usb_hs_system_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb_hs_system_clk.c),
@@ -2298,9 +2298,9 @@
static struct branch_clk gcc_usb_hsic_clk = {
.cbcr_reg = USB_HSIC_CBCR,
.bcr_reg = USB_HS_HSIC_BCR,
- .parent = &usb_hsic_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb_hsic_clk_src.c,
.dbg_name = "gcc_usb_hsic_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb_hsic_clk.c),
@@ -2309,9 +2309,9 @@
static struct branch_clk gcc_usb_hsic_io_cal_clk = {
.cbcr_reg = USB_HSIC_IO_CAL_CBCR,
- .parent = &usb_hsic_io_cal_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb_hsic_io_cal_clk_src.c,
.dbg_name = "gcc_usb_hsic_io_cal_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb_hsic_io_cal_clk.c),
@@ -2320,9 +2320,9 @@
static struct branch_clk gcc_usb_hsic_system_clk = {
.cbcr_reg = USB_HSIC_SYSTEM_CBCR,
- .parent = &usb_hsic_system_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb_hsic_system_clk_src.c,
.dbg_name = "gcc_usb_hsic_system_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb_hsic_system_clk.c),
@@ -2807,18 +2807,15 @@
},
};
-static struct clk *dsi_pll_clk_get_parent(struct clk *c)
-{
- return &cxo_clk_src.c;
-}
-
static struct clk dsipll0_byte_clk_src = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "dsipll0_byte_clk_src",
.ops = &clk_ops_dsi_byte_pll,
CLK_INIT(dsipll0_byte_clk_src),
};
static struct clk dsipll0_pixel_clk_src = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "dsipll0_pixel_clk_src",
.ops = &clk_ops_dsi_pixel_pll,
CLK_INIT(dsipll0_pixel_clk_src),
@@ -2900,6 +2897,7 @@
.current_freq = &byte_freq,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &dsipll0_byte_clk_src,
.dbg_name = "byte0_clk_src",
.ops = &clk_ops_byte,
VDD_DIG_FMAX_MAP3(LOW, 93800000, NOMINAL, 187500000,
@@ -2913,6 +2911,7 @@
.current_freq = &byte_freq,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &dsipll0_byte_clk_src,
.dbg_name = "byte1_clk_src",
.ops = &clk_ops_byte,
VDD_DIG_FMAX_MAP3(LOW, 93800000, NOMINAL, 187500000,
@@ -3045,19 +3044,14 @@
return rc;
}
-static struct clk *hdmi_pll_clk_get_parent(struct clk *c)
-{
- return &cxo_clk_src.c;
-}
-
static struct clk_ops clk_ops_hdmi_pll = {
.enable = hdmi_pll_clk_enable,
.disable = hdmi_pll_clk_disable,
.set_rate = hdmi_pll_clk_set_rate,
- .get_parent = hdmi_pll_clk_get_parent,
};
static struct clk hdmipll_clk_src = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "hdmipll_clk_src",
.ops = &clk_ops_hdmi_pll,
CLK_INIT(hdmipll_clk_src),
@@ -3127,6 +3121,7 @@
.current_freq = &pixel_freq,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &dsipll0_pixel_clk_src,
.dbg_name = "pclk0_clk_src",
.ops = &clk_ops_pixel,
VDD_DIG_FMAX_MAP2(LOW, 125000000, NOMINAL, 250000000),
@@ -3139,6 +3134,7 @@
.current_freq = &pixel_freq,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &dsipll0_pixel_clk_src,
.dbg_name = "pclk1_clk_src",
.ops = &clk_ops_pixel,
VDD_DIG_FMAX_MAP2(LOW, 125000000, NOMINAL, 250000000),
@@ -3203,10 +3199,10 @@
static struct branch_clk camss_cci_cci_clk = {
.cbcr_reg = CAMSS_CCI_CCI_CBCR,
- .parent = &cci_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &cci_clk_src.c,
.dbg_name = "camss_cci_cci_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_cci_cci_clk.c),
@@ -3226,10 +3222,10 @@
static struct branch_clk camss_csi0_clk = {
.cbcr_reg = CAMSS_CSI0_CBCR,
- .parent = &csi0_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi0_clk_src.c,
.dbg_name = "camss_csi0_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi0_clk.c),
@@ -3238,10 +3234,10 @@
static struct branch_clk camss_csi0phy_clk = {
.cbcr_reg = CAMSS_CSI0PHY_CBCR,
- .parent = &csi0_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi0_clk_src.c,
.dbg_name = "camss_csi0phy_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi0phy_clk.c),
@@ -3250,10 +3246,10 @@
static struct branch_clk camss_csi0pix_clk = {
.cbcr_reg = CAMSS_CSI0PIX_CBCR,
- .parent = &csi0_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi0_clk_src.c,
.dbg_name = "camss_csi0pix_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi0pix_clk.c),
@@ -3262,10 +3258,10 @@
static struct branch_clk camss_csi0rdi_clk = {
.cbcr_reg = CAMSS_CSI0RDI_CBCR,
- .parent = &csi0_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi0_clk_src.c,
.dbg_name = "camss_csi0rdi_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi0rdi_clk.c),
@@ -3285,10 +3281,10 @@
static struct branch_clk camss_csi1_clk = {
.cbcr_reg = CAMSS_CSI1_CBCR,
- .parent = &csi1_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi1_clk_src.c,
.dbg_name = "camss_csi1_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi1_clk.c),
@@ -3297,10 +3293,10 @@
static struct branch_clk camss_csi1phy_clk = {
.cbcr_reg = CAMSS_CSI1PHY_CBCR,
- .parent = &csi1_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi1_clk_src.c,
.dbg_name = "camss_csi1phy_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi1phy_clk.c),
@@ -3309,10 +3305,10 @@
static struct branch_clk camss_csi1pix_clk = {
.cbcr_reg = CAMSS_CSI1PIX_CBCR,
- .parent = &csi1_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi1_clk_src.c,
.dbg_name = "camss_csi1pix_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi1pix_clk.c),
@@ -3321,10 +3317,10 @@
static struct branch_clk camss_csi1rdi_clk = {
.cbcr_reg = CAMSS_CSI1RDI_CBCR,
- .parent = &csi1_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi1_clk_src.c,
.dbg_name = "camss_csi1rdi_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi1rdi_clk.c),
@@ -3344,10 +3340,10 @@
static struct branch_clk camss_csi2_clk = {
.cbcr_reg = CAMSS_CSI2_CBCR,
- .parent = &csi2_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi2_clk_src.c,
.dbg_name = "camss_csi2_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi2_clk.c),
@@ -3356,10 +3352,10 @@
static struct branch_clk camss_csi2phy_clk = {
.cbcr_reg = CAMSS_CSI2PHY_CBCR,
- .parent = &csi2_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi2_clk_src.c,
.dbg_name = "camss_csi2phy_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi2phy_clk.c),
@@ -3368,10 +3364,10 @@
static struct branch_clk camss_csi2pix_clk = {
.cbcr_reg = CAMSS_CSI2PIX_CBCR,
- .parent = &csi2_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi2_clk_src.c,
.dbg_name = "camss_csi2pix_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi2pix_clk.c),
@@ -3380,10 +3376,10 @@
static struct branch_clk camss_csi2rdi_clk = {
.cbcr_reg = CAMSS_CSI2RDI_CBCR,
- .parent = &csi2_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi2_clk_src.c,
.dbg_name = "camss_csi2rdi_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi2rdi_clk.c),
@@ -3403,10 +3399,10 @@
static struct branch_clk camss_csi3_clk = {
.cbcr_reg = CAMSS_CSI3_CBCR,
- .parent = &csi3_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi3_clk_src.c,
.dbg_name = "camss_csi3_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi3_clk.c),
@@ -3415,10 +3411,10 @@
static struct branch_clk camss_csi3phy_clk = {
.cbcr_reg = CAMSS_CSI3PHY_CBCR,
- .parent = &csi3_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi3_clk_src.c,
.dbg_name = "camss_csi3phy_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi3phy_clk.c),
@@ -3427,10 +3423,10 @@
static struct branch_clk camss_csi3pix_clk = {
.cbcr_reg = CAMSS_CSI3PIX_CBCR,
- .parent = &csi3_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi3_clk_src.c,
.dbg_name = "camss_csi3pix_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi3pix_clk.c),
@@ -3439,10 +3435,10 @@
static struct branch_clk camss_csi3rdi_clk = {
.cbcr_reg = CAMSS_CSI3RDI_CBCR,
- .parent = &csi3_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi3_clk_src.c,
.dbg_name = "camss_csi3rdi_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi3rdi_clk.c),
@@ -3451,10 +3447,10 @@
static struct branch_clk camss_csi_vfe0_clk = {
.cbcr_reg = CAMSS_CSI_VFE0_CBCR,
- .parent = &vfe0_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &vfe0_clk_src.c,
.dbg_name = "camss_csi_vfe0_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi_vfe0_clk.c),
@@ -3463,10 +3459,10 @@
static struct branch_clk camss_csi_vfe1_clk = {
.cbcr_reg = CAMSS_CSI_VFE1_CBCR,
- .parent = &vfe1_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &vfe1_clk_src.c,
.dbg_name = "camss_csi_vfe1_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_csi_vfe1_clk.c),
@@ -3475,10 +3471,10 @@
static struct branch_clk camss_gp0_clk = {
.cbcr_reg = CAMSS_GP0_CBCR,
- .parent = &mmss_gp0_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &mmss_gp0_clk_src.c,
.dbg_name = "camss_gp0_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_gp0_clk.c),
@@ -3487,10 +3483,10 @@
static struct branch_clk camss_gp1_clk = {
.cbcr_reg = CAMSS_GP1_CBCR,
- .parent = &mmss_gp1_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &mmss_gp1_clk_src.c,
.dbg_name = "camss_gp1_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_gp1_clk.c),
@@ -3510,10 +3506,10 @@
static struct branch_clk camss_jpeg_jpeg0_clk = {
.cbcr_reg = CAMSS_JPEG_JPEG0_CBCR,
- .parent = &jpeg0_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &jpeg0_clk_src.c,
.dbg_name = "camss_jpeg_jpeg0_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_jpeg_jpeg0_clk.c),
@@ -3522,10 +3518,10 @@
static struct branch_clk camss_jpeg_jpeg1_clk = {
.cbcr_reg = CAMSS_JPEG_JPEG1_CBCR,
- .parent = &jpeg1_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &jpeg1_clk_src.c,
.dbg_name = "camss_jpeg_jpeg1_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_jpeg_jpeg1_clk.c),
@@ -3534,10 +3530,10 @@
static struct branch_clk camss_jpeg_jpeg2_clk = {
.cbcr_reg = CAMSS_JPEG_JPEG2_CBCR,
- .parent = &jpeg2_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &jpeg2_clk_src.c,
.dbg_name = "camss_jpeg_jpeg2_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_jpeg_jpeg2_clk.c),
@@ -3557,10 +3553,10 @@
static struct branch_clk camss_jpeg_jpeg_axi_clk = {
.cbcr_reg = CAMSS_JPEG_JPEG_AXI_CBCR,
- .parent = &axi_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &axi_clk_src.c,
.dbg_name = "camss_jpeg_jpeg_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_jpeg_jpeg_axi_clk.c),
@@ -3569,10 +3565,10 @@
static struct branch_clk camss_jpeg_jpeg_ocmemnoc_clk = {
.cbcr_reg = CAMSS_JPEG_JPEG_OCMEMNOC_CBCR,
- .parent = &ocmemnoc_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &ocmemnoc_clk_src.c,
.dbg_name = "camss_jpeg_jpeg_ocmemnoc_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_jpeg_jpeg_ocmemnoc_clk.c),
@@ -3581,10 +3577,10 @@
static struct branch_clk camss_mclk0_clk = {
.cbcr_reg = CAMSS_MCLK0_CBCR,
- .parent = &mclk0_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &mclk0_clk_src.c,
.dbg_name = "camss_mclk0_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_mclk0_clk.c),
@@ -3593,10 +3589,10 @@
static struct branch_clk camss_mclk1_clk = {
.cbcr_reg = CAMSS_MCLK1_CBCR,
- .parent = &mclk1_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &mclk1_clk_src.c,
.dbg_name = "camss_mclk1_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_mclk1_clk.c),
@@ -3605,10 +3601,10 @@
static struct branch_clk camss_mclk2_clk = {
.cbcr_reg = CAMSS_MCLK2_CBCR,
- .parent = &mclk2_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &mclk2_clk_src.c,
.dbg_name = "camss_mclk2_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_mclk2_clk.c),
@@ -3617,10 +3613,10 @@
static struct branch_clk camss_mclk3_clk = {
.cbcr_reg = CAMSS_MCLK3_CBCR,
- .parent = &mclk3_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &mclk3_clk_src.c,
.dbg_name = "camss_mclk3_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_mclk3_clk.c),
@@ -3640,10 +3636,10 @@
static struct branch_clk camss_phy0_csi0phytimer_clk = {
.cbcr_reg = CAMSS_PHY0_CSI0PHYTIMER_CBCR,
- .parent = &csi0phytimer_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi0phytimer_clk_src.c,
.dbg_name = "camss_phy0_csi0phytimer_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_phy0_csi0phytimer_clk.c),
@@ -3652,10 +3648,10 @@
static struct branch_clk camss_phy1_csi1phytimer_clk = {
.cbcr_reg = CAMSS_PHY1_CSI1PHYTIMER_CBCR,
- .parent = &csi1phytimer_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi1phytimer_clk_src.c,
.dbg_name = "camss_phy1_csi1phytimer_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_phy1_csi1phytimer_clk.c),
@@ -3664,10 +3660,10 @@
static struct branch_clk camss_phy2_csi2phytimer_clk = {
.cbcr_reg = CAMSS_PHY2_CSI2PHYTIMER_CBCR,
- .parent = &csi2phytimer_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &csi2phytimer_clk_src.c,
.dbg_name = "camss_phy2_csi2phytimer_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_phy2_csi2phytimer_clk.c),
@@ -3698,10 +3694,10 @@
static struct branch_clk camss_vfe_cpp_clk = {
.cbcr_reg = CAMSS_VFE_CPP_CBCR,
- .parent = &cpp_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &cpp_clk_src.c,
.dbg_name = "camss_vfe_cpp_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_vfe_cpp_clk.c),
@@ -3710,10 +3706,10 @@
static struct branch_clk camss_vfe_vfe0_clk = {
.cbcr_reg = CAMSS_VFE_VFE0_CBCR,
- .parent = &vfe0_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &vfe0_clk_src.c,
.dbg_name = "camss_vfe_vfe0_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_vfe_vfe0_clk.c),
@@ -3722,10 +3718,10 @@
static struct branch_clk camss_vfe_vfe1_clk = {
.cbcr_reg = CAMSS_VFE_VFE1_CBCR,
- .parent = &vfe1_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &vfe1_clk_src.c,
.dbg_name = "camss_vfe_vfe1_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_vfe_vfe1_clk.c),
@@ -3745,10 +3741,10 @@
static struct branch_clk camss_vfe_vfe_axi_clk = {
.cbcr_reg = CAMSS_VFE_VFE_AXI_CBCR,
- .parent = &axi_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &axi_clk_src.c,
.dbg_name = "camss_vfe_vfe_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_vfe_vfe_axi_clk.c),
@@ -3757,10 +3753,10 @@
static struct branch_clk camss_vfe_vfe_ocmemnoc_clk = {
.cbcr_reg = CAMSS_VFE_VFE_OCMEMNOC_CBCR,
- .parent = &ocmemnoc_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &ocmemnoc_clk_src.c,
.dbg_name = "camss_vfe_vfe_ocmemnoc_clk",
.ops = &clk_ops_branch,
CLK_INIT(camss_vfe_vfe_ocmemnoc_clk.c),
@@ -3780,10 +3776,10 @@
static struct branch_clk mdss_axi_clk = {
.cbcr_reg = MDSS_AXI_CBCR,
- .parent = &axi_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &axi_clk_src.c,
.dbg_name = "mdss_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_axi_clk.c),
@@ -3792,10 +3788,10 @@
static struct branch_clk mdss_byte0_clk = {
.cbcr_reg = MDSS_BYTE0_CBCR,
- .parent = &byte0_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &byte0_clk_src.c,
.dbg_name = "mdss_byte0_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_byte0_clk.c),
@@ -3804,10 +3800,10 @@
static struct branch_clk mdss_byte1_clk = {
.cbcr_reg = MDSS_BYTE1_CBCR,
- .parent = &byte1_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &byte1_clk_src.c,
.dbg_name = "mdss_byte1_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_byte1_clk.c),
@@ -3816,10 +3812,10 @@
static struct branch_clk mdss_edpaux_clk = {
.cbcr_reg = MDSS_EDPAUX_CBCR,
- .parent = &edpaux_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &edpaux_clk_src.c,
.dbg_name = "mdss_edpaux_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_edpaux_clk.c),
@@ -3828,10 +3824,10 @@
static struct branch_clk mdss_edplink_clk = {
.cbcr_reg = MDSS_EDPLINK_CBCR,
- .parent = &edplink_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &edplink_clk_src.c,
.dbg_name = "mdss_edplink_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_edplink_clk.c),
@@ -3840,10 +3836,10 @@
static struct branch_clk mdss_edppixel_clk = {
.cbcr_reg = MDSS_EDPPIXEL_CBCR,
- .parent = &edppixel_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &edppixel_clk_src.c,
.dbg_name = "mdss_edppixel_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_edppixel_clk.c),
@@ -3852,10 +3848,10 @@
static struct branch_clk mdss_esc0_clk = {
.cbcr_reg = MDSS_ESC0_CBCR,
- .parent = &esc0_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &esc0_clk_src.c,
.dbg_name = "mdss_esc0_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_esc0_clk.c),
@@ -3864,10 +3860,10 @@
static struct branch_clk mdss_esc1_clk = {
.cbcr_reg = MDSS_ESC1_CBCR,
- .parent = &esc1_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &esc1_clk_src.c,
.dbg_name = "mdss_esc1_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_esc1_clk.c),
@@ -3876,10 +3872,10 @@
static struct branch_clk mdss_extpclk_clk = {
.cbcr_reg = MDSS_EXTPCLK_CBCR,
- .parent = &extpclk_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &extpclk_clk_src.c,
.dbg_name = "mdss_extpclk_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_extpclk_clk.c),
@@ -3899,10 +3895,10 @@
static struct branch_clk mdss_hdmi_clk = {
.cbcr_reg = MDSS_HDMI_CBCR,
- .parent = &hdmi_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &hdmi_clk_src.c,
.dbg_name = "mdss_hdmi_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_hdmi_clk.c),
@@ -3911,10 +3907,10 @@
static struct branch_clk mdss_mdp_clk = {
.cbcr_reg = MDSS_MDP_CBCR,
- .parent = &mdp_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &mdp_clk_src.c,
.dbg_name = "mdss_mdp_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_mdp_clk.c),
@@ -3923,10 +3919,10 @@
static struct branch_clk mdss_mdp_lut_clk = {
.cbcr_reg = MDSS_MDP_LUT_CBCR,
- .parent = &mdp_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &mdp_clk_src.c,
.dbg_name = "mdss_mdp_lut_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_mdp_lut_clk.c),
@@ -3935,10 +3931,10 @@
static struct branch_clk mdss_pclk0_clk = {
.cbcr_reg = MDSS_PCLK0_CBCR,
- .parent = &pclk0_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &pclk0_clk_src.c,
.dbg_name = "mdss_pclk0_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_pclk0_clk.c),
@@ -3947,10 +3943,10 @@
static struct branch_clk mdss_pclk1_clk = {
.cbcr_reg = MDSS_PCLK1_CBCR,
- .parent = &pclk1_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &pclk1_clk_src.c,
.dbg_name = "mdss_pclk1_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_pclk1_clk.c),
@@ -3959,10 +3955,10 @@
static struct branch_clk mdss_vsync_clk = {
.cbcr_reg = MDSS_VSYNC_CBCR,
- .parent = &vsync_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &vsync_clk_src.c,
.dbg_name = "mdss_vsync_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdss_vsync_clk.c),
@@ -3993,10 +3989,10 @@
static struct branch_clk mmss_mmssnoc_axi_clk = {
.cbcr_reg = MMSS_MMSSNOC_AXI_CBCR,
- .parent = &axi_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &axi_clk_src.c,
.dbg_name = "mmss_mmssnoc_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(mmss_mmssnoc_axi_clk.c),
@@ -4005,11 +4001,11 @@
static struct branch_clk mmss_s0_axi_clk = {
.cbcr_reg = MMSS_S0_AXI_CBCR,
- .parent = &axi_clk_src.c,
/* The bus driver needs set_rate to go through to the parent */
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &axi_clk_src.c,
.dbg_name = "mmss_s0_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(mmss_s0_axi_clk.c),
@@ -4019,11 +4015,11 @@
struct branch_clk ocmemnoc_clk = {
.cbcr_reg = OCMEMNOC_CBCR,
- .parent = &ocmemnoc_clk_src.c,
.has_sibling = 0,
.bcr_reg = 0x50b0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &ocmemnoc_clk_src.c,
.dbg_name = "ocmemnoc_clk",
.ops = &clk_ops_branch,
CLK_INIT(ocmemnoc_clk.c),
@@ -4032,10 +4028,10 @@
struct branch_clk ocmemcx_ocmemnoc_clk = {
.cbcr_reg = OCMEMCX_OCMEMNOC_CBCR,
- .parent = &ocmemnoc_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &ocmemnoc_clk_src.c,
.dbg_name = "ocmemcx_ocmemnoc_clk",
.ops = &clk_ops_branch,
CLK_INIT(ocmemcx_ocmemnoc_clk.c),
@@ -4055,10 +4051,10 @@
static struct branch_clk venus0_axi_clk = {
.cbcr_reg = VENUS0_AXI_CBCR,
- .parent = &axi_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &axi_clk_src.c,
.dbg_name = "venus0_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(venus0_axi_clk.c),
@@ -4067,10 +4063,10 @@
static struct branch_clk venus0_ocmemnoc_clk = {
.cbcr_reg = VENUS0_OCMEMNOC_CBCR,
- .parent = &ocmemnoc_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &ocmemnoc_clk_src.c,
.dbg_name = "venus0_ocmemnoc_clk",
.ops = &clk_ops_branch,
CLK_INIT(venus0_ocmemnoc_clk.c),
@@ -4079,10 +4075,10 @@
static struct branch_clk venus0_vcodec0_clk = {
.cbcr_reg = VENUS0_VCODEC0_CBCR,
- .parent = &vcodec0_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &vcodec0_clk_src.c,
.dbg_name = "venus0_vcodec0_clk",
.ops = &clk_ops_branch,
CLK_INIT(venus0_vcodec0_clk.c),
@@ -4091,10 +4087,10 @@
static struct branch_clk oxilicx_axi_clk = {
.cbcr_reg = OXILICX_AXI_CBCR,
- .parent = &axi_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &axi_clk_src.c,
.dbg_name = "oxilicx_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(oxilicx_axi_clk.c),
@@ -4103,9 +4099,9 @@
static struct branch_clk oxili_gfx3d_clk = {
.cbcr_reg = OXILI_GFX3D_CBCR,
- .parent = &oxili_gfx3d_clk_src.c,
.base = &virt_bases[MMSS_BASE],
.c = {
+ .parent = &oxili_gfx3d_clk_src.c,
.dbg_name = "oxili_gfx3d_clk",
.ops = &clk_ops_branch,
CLK_INIT(oxili_gfx3d_clk.c),
@@ -4145,9 +4141,9 @@
static struct branch_clk audio_core_slimbus_core_clk = {
.cbcr_reg = AUDIO_CORE_SLIMBUS_CORE_CBCR,
- .parent = &audio_core_slimbus_core_clk_src.c,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_slimbus_core_clk_src.c,
.dbg_name = "audio_core_slimbus_core_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_slimbus_core_clk.c),
@@ -4293,10 +4289,10 @@
static struct branch_clk audio_core_lpaif_codec_spkr_osr_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_OSR_CBCR,
- .parent = &audio_core_lpaif_codec_spkr_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_codec_spkr_clk_src.c,
.dbg_name = "audio_core_lpaif_codec_spkr_osr_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_codec_spkr_osr_clk.c),
@@ -4316,11 +4312,11 @@
static struct branch_clk audio_core_lpaif_codec_spkr_ibit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_IBIT_CBCR,
- .parent = &audio_core_lpaif_codec_spkr_clk_src.c,
.has_sibling = 1,
.max_div = 15,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_codec_spkr_clk_src.c,
.dbg_name = "audio_core_lpaif_codec_spkr_ibit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_codec_spkr_ibit_clk.c),
@@ -4329,10 +4325,10 @@
static struct branch_clk audio_core_lpaif_pri_osr_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_PRI_OSR_CBCR,
- .parent = &audio_core_lpaif_pri_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_pri_clk_src.c,
.dbg_name = "audio_core_lpaif_pri_osr_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_pri_osr_clk.c),
@@ -4352,11 +4348,11 @@
static struct branch_clk audio_core_lpaif_pri_ibit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_PRI_IBIT_CBCR,
- .parent = &audio_core_lpaif_pri_clk_src.c,
.has_sibling = 1,
.max_div = 15,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_pri_clk_src.c,
.dbg_name = "audio_core_lpaif_pri_ibit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_pri_ibit_clk.c),
@@ -4365,10 +4361,10 @@
static struct branch_clk audio_core_lpaif_sec_osr_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_SEC_OSR_CBCR,
- .parent = &audio_core_lpaif_sec_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_sec_clk_src.c,
.dbg_name = "audio_core_lpaif_sec_osr_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_sec_osr_clk.c),
@@ -4388,11 +4384,11 @@
static struct branch_clk audio_core_lpaif_sec_ibit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_SEC_IBIT_CBCR,
- .parent = &audio_core_lpaif_sec_clk_src.c,
.has_sibling = 1,
.max_div = 15,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_sec_clk_src.c,
.dbg_name = "audio_core_lpaif_sec_ibit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_sec_ibit_clk.c),
@@ -4401,10 +4397,10 @@
static struct branch_clk audio_core_lpaif_ter_osr_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_TER_OSR_CBCR,
- .parent = &audio_core_lpaif_ter_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_ter_clk_src.c,
.dbg_name = "audio_core_lpaif_ter_osr_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_ter_osr_clk.c),
@@ -4424,11 +4420,11 @@
static struct branch_clk audio_core_lpaif_ter_ibit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_TER_IBIT_CBCR,
- .parent = &audio_core_lpaif_ter_clk_src.c,
.has_sibling = 1,
.max_div = 15,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_ter_clk_src.c,
.dbg_name = "audio_core_lpaif_ter_ibit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_ter_ibit_clk.c),
@@ -4437,10 +4433,10 @@
static struct branch_clk audio_core_lpaif_quad_osr_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_QUAD_OSR_CBCR,
- .parent = &audio_core_lpaif_quad_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_quad_clk_src.c,
.dbg_name = "audio_core_lpaif_quad_osr_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_quad_osr_clk.c),
@@ -4460,11 +4456,11 @@
static struct branch_clk audio_core_lpaif_quad_ibit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_QUAD_IBIT_CBCR,
- .parent = &audio_core_lpaif_quad_clk_src.c,
.has_sibling = 1,
.max_div = 15,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_quad_clk_src.c,
.dbg_name = "audio_core_lpaif_quad_ibit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_quad_ibit_clk.c),
@@ -4484,10 +4480,10 @@
static struct branch_clk audio_core_lpaif_pcm0_ibit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR,
- .parent = &audio_core_lpaif_pcm0_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_pcm0_clk_src.c,
.dbg_name = "audio_core_lpaif_pcm0_ibit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_pcm0_ibit_clk.c),
@@ -4496,10 +4492,10 @@
static struct branch_clk audio_core_lpaif_pcm1_ebit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR,
- .parent = &audio_core_lpaif_pcm1_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_pcm1_clk_src.c,
.dbg_name = "audio_core_lpaif_pcm1_ebit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_pcm1_ebit_clk.c),
@@ -4508,10 +4504,10 @@
static struct branch_clk audio_core_lpaif_pcm1_ibit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR,
- .parent = &audio_core_lpaif_pcm1_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_pcm1_clk_src.c,
.dbg_name = "audio_core_lpaif_pcm1_ibit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_pcm1_ibit_clk.c),
@@ -4520,9 +4516,9 @@
struct branch_clk audio_core_lpaif_pcmoe_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR,
- .parent = &audio_core_lpaif_pcmoe_clk_src.c,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_pcmoe_clk_src.c,
.dbg_name = "audio_core_lpaif_pcmoe_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_pcmoe_clk.c),
@@ -5681,11 +5677,9 @@
{
clk_ops_byte = clk_ops_rcg_mnd;
clk_ops_byte.set_rate = set_rate_byte;
- clk_ops_dsi_byte_pll.get_parent = dsi_pll_clk_get_parent;
clk_ops_pixel = clk_ops_rcg;
clk_ops_pixel.set_rate = set_rate_pixel;
- clk_ops_dsi_pixel_pll.get_parent = dsi_pll_clk_get_parent;
mdss_clk_ctrl_init();
}
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 5a9799a..2ad425d 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -317,8 +317,8 @@
.en_mask = BIT(8),
.status_reg = BB_PLL8_STATUS_REG,
.status_mask = BIT(16),
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "pll8_clk",
.rate = 384000000,
.ops = &clk_ops_pll_vote,
@@ -328,8 +328,8 @@
static struct pll_clk pll2_clk = {
.mode_reg = MM_PLL1_MODE_REG,
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "pll2_clk",
.rate = 800000000,
.ops = &clk_ops_local_pll,
@@ -339,8 +339,8 @@
static struct pll_clk pll3_clk = {
.mode_reg = MM_PLL2_MODE_REG,
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "pll3_clk",
.rate = 0, /* TODO: Detect rate dynamically */
.ops = &clk_ops_local_pll,
@@ -360,11 +360,6 @@
msm_rpm_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
}
-static struct clk *pll4_clk_get_parent(struct clk *c)
-{
- return &pxo_clk.c;
-}
-
static bool pll4_clk_is_local(struct clk *c)
{
return false;
@@ -383,13 +378,13 @@
static struct clk_ops clk_ops_pll4 = {
.enable = pll4_clk_enable,
.disable = pll4_clk_disable,
- .get_parent = pll4_clk_get_parent,
.is_local = pll4_clk_is_local,
.handoff = pll4_clk_handoff,
};
static struct fixed_clk pll4_clk = {
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "pll4_clk",
.rate = 540672000,
.ops = &clk_ops_pll4,
@@ -1386,8 +1381,8 @@
.halt_reg = CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 15,
},
- .parent = &usb_fs1_src_clk.c,
.c = {
+ .parent = &usb_fs1_src_clk.c,
.dbg_name = "usb_fs1_xcvr_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_fs1_xcvr_clk.c),
@@ -1403,8 +1398,8 @@
.halt_reg = CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 16,
},
- .parent = &usb_fs1_src_clk.c,
.c = {
+ .parent = &usb_fs1_src_clk.c,
.dbg_name = "usb_fs1_sys_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_fs1_sys_clk.c),
@@ -1421,8 +1416,8 @@
.halt_reg = CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 12,
},
- .parent = &usb_fs2_src_clk.c,
.c = {
+ .parent = &usb_fs2_src_clk.c,
.dbg_name = "usb_fs2_xcvr_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_fs2_xcvr_clk.c),
@@ -1438,8 +1433,8 @@
.halt_reg = CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 13,
},
- .parent = &usb_fs2_src_clk.c,
.c = {
+ .parent = &usb_fs2_src_clk.c,
.dbg_name = "usb_fs2_sys_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_fs2_sys_clk.c),
@@ -1454,8 +1449,8 @@
.halt_reg = CLK_HALT_CFPB_STATEC_REG,
.halt_bit = 0,
},
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "ce2_p_clk",
.ops = &clk_ops_branch,
CLK_INIT(ce2_p_clk.c),
@@ -1808,8 +1803,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 14,
},
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "adm0_clk",
.ops = &clk_ops_branch,
CLK_INIT(adm0_clk.c),
@@ -1839,8 +1834,8 @@
.halt_check = HALT_VOTED,
.halt_bit = 12,
},
- .parent = &pxo_clk.c,
.c = {
+ .parent = &pxo_clk.c,
.dbg_name = "adm1_clk",
.ops = &clk_ops_branch,
CLK_INIT(adm1_clk.c),
@@ -2044,8 +2039,8 @@
.halt_reg = DBG_BUS_VEC_B_REG,
.halt_bit = 13,
},
- .parent = &csi_src_clk.c,
.c = {
+ .parent = &csi_src_clk.c,
.dbg_name = "csi0_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi0_clk.c),
@@ -2061,8 +2056,8 @@
.halt_reg = DBG_BUS_VEC_B_REG,
.halt_bit = 14,
},
- .parent = &csi_src_clk.c,
.c = {
+ .parent = &csi_src_clk.c,
.dbg_name = "csi1_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi1_clk.c),
@@ -2566,8 +2561,8 @@
.halt_reg = DBG_BUS_VEC_C_REG,
.halt_bit = 21,
},
- .parent = &pixel_mdp_clk.c,
.c = {
+ .parent = &pixel_mdp_clk.c,
.dbg_name = "pixel_lcdc_clk",
.ops = &clk_ops_branch,
CLK_INIT(pixel_lcdc_clk.c),
@@ -2695,8 +2690,8 @@
.halt_reg = DBG_BUS_VEC_D_REG,
.halt_bit = 8,
},
- .parent = &tv_src_clk.c,
.c = {
+ .parent = &tv_src_clk.c,
.dbg_name = "tv_enc_clk",
.ops = &clk_ops_branch,
CLK_INIT(tv_enc_clk.c),
@@ -2710,8 +2705,8 @@
.halt_reg = DBG_BUS_VEC_D_REG,
.halt_bit = 9,
},
- .parent = &tv_src_clk.c,
.c = {
+ .parent = &tv_src_clk.c,
.dbg_name = "tv_dac_clk",
.ops = &clk_ops_branch,
CLK_INIT(tv_dac_clk.c),
@@ -2727,8 +2722,8 @@
.halt_reg = DBG_BUS_VEC_D_REG,
.halt_bit = 11,
},
- .parent = &tv_src_clk.c,
.c = {
+ .parent = &tv_src_clk.c,
.dbg_name = "mdp_tv_clk",
.ops = &clk_ops_branch,
CLK_INIT(mdp_tv_clk.c),
@@ -2744,8 +2739,8 @@
.halt_reg = DBG_BUS_VEC_D_REG,
.halt_bit = 10,
},
- .parent = &tv_src_clk.c,
.c = {
+ .parent = &tv_src_clk.c,
.dbg_name = "hdmi_tv_clk",
.ops = &clk_ops_branch,
CLK_INIT(hdmi_tv_clk.c),
@@ -2934,8 +2929,8 @@
.halt_reg = DBG_BUS_VEC_B_REG,
.halt_bit = 7,
},
- .parent = &vfe_clk.c,
.c = {
+ .parent = &vfe_clk.c,
.dbg_name = "csi0_vfe_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi0_vfe_clk.c),
@@ -2951,8 +2946,8 @@
.halt_reg = DBG_BUS_VEC_B_REG,
.halt_bit = 8,
},
- .parent = &vfe_clk.c,
.c = {
+ .parent = &vfe_clk.c,
.dbg_name = "csi1_vfe_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi1_vfe_clk.c),
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 338361b..fffbcea 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -228,10 +228,10 @@
.en_mask = BIT(0),
.status_reg = BB_PLL0_STATUS_REG,
.status_mask = BIT(16),
- .parent = &cxo_clk.c,
.soft_vote = &soft_vote_pll0,
.soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
.c = {
+ .parent = &cxo_clk.c,
.dbg_name = "pll0_clk",
.rate = 276000000,
.ops = &clk_ops_pll_acpu_vote,
@@ -259,8 +259,8 @@
.en_mask = BIT(4),
.status_reg = LCC_PLL0_STATUS_REG,
.status_mask = BIT(16),
- .parent = &cxo_clk.c,
.c = {
+ .parent = &cxo_clk.c,
.dbg_name = "pll4_clk",
.rate = 393216000,
.ops = &clk_ops_pll_vote,
@@ -275,10 +275,10 @@
.en_mask = BIT(8),
.status_reg = BB_PLL8_STATUS_REG,
.status_mask = BIT(16),
- .parent = &cxo_clk.c,
.soft_vote = &soft_vote_pll8,
.soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
.c = {
+ .parent = &cxo_clk.c,
.dbg_name = "pll8_clk",
.rate = 384000000,
.ops = &clk_ops_pll_acpu_vote,
@@ -316,8 +316,8 @@
.en_mask = BIT(11),
.status_reg = BB_PLL14_STATUS_REG,
.status_mask = BIT(16),
- .parent = &cxo_clk.c,
.c = {
+ .parent = &cxo_clk.c,
.dbg_name = "pll14_clk",
.rate = 480000000,
.ops = &clk_ops_pll_vote,
@@ -767,8 +767,8 @@
.halt_reg = CLK_HALT_DFAB_STATE_REG,
.halt_bit = 8,
},
- .parent = &cxo_clk.c,
.c = {
+ .parent = &cxo_clk.c,
.dbg_name = "usb_hsic_hsio_cal_clk",
.ops = &clk_ops_branch,
CLK_INIT(usb_hsic_hsio_cal_clk.c),
@@ -1295,8 +1295,8 @@
.halt_check = ENABLE,
.halt_bit = 1,
},
- .parent = &audio_slimbus_clk.c,
.c = {
+ .parent = &audio_slimbus_clk.c,
.dbg_name = "sps_slimbus_clk",
.ops = &clk_ops_branch,
CLK_INIT(sps_slimbus_clk.c),
@@ -1310,8 +1310,8 @@
.halt_reg = CLK_HALT_DFAB_STATE_REG,
.halt_bit = 28,
},
- .parent = &sps_slimbus_clk.c,
.c = {
+ .parent = &sps_slimbus_clk.c,
.dbg_name = "slimbus_xo_src_clk",
.ops = &clk_ops_branch,
CLK_INIT(slimbus_xo_src_clk.c),
diff --git a/arch/arm/mach-msm/clock-9625.c b/arch/arm/mach-msm/clock-9625.c
index 9f6a00c..33ec10a 100644
--- a/arch/arm/mach-msm/clock-9625.c
+++ b/arch/arm/mach-msm/clock-9625.c
@@ -388,11 +388,11 @@
.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE_REG,
.status_reg = (void __iomem *)GPLL0_STATUS_REG,
.status_mask = BIT(17),
- .parent = &cxo_clk_src.c,
.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_acpu_vote,
@@ -420,9 +420,9 @@
.en_mask = BIT(0),
.status_reg = (void __iomem *)LPAPLL_STATUS_REG,
.status_mask = BIT(17),
- .parent = &cxo_clk_src.c,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.rate = 393216000,
.dbg_name = "lpapll0_clk_src",
.ops = &clk_ops_pll_vote,
@@ -435,9 +435,9 @@
.en_mask = BIT(1),
.status_reg = (void __iomem *)GPLL1_STATUS_REG,
.status_mask = BIT(17),
- .parent = &cxo_clk_src.c,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.rate = 480000000,
.dbg_name = "gpll1_clk_src",
.ops = &clk_ops_pll_vote,
@@ -472,6 +472,7 @@
},
.base = &virt_bases[APCS_PLL_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "apcspll_clk_src",
.ops = &clk_ops_local_pll,
CLK_INIT(apcspll_clk_src.c),
@@ -988,10 +989,10 @@
static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup1_i2c_apps_clk.c),
@@ -1000,10 +1001,10 @@
static struct branch_clk gcc_blsp1_qup1_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP1_SPI_APPS_CBCR,
- .parent = &blsp1_qup1_spi_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup1_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup1_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup1_spi_apps_clk.c),
@@ -1012,10 +1013,10 @@
static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup2_i2c_apps_clk.c),
@@ -1024,10 +1025,10 @@
static struct branch_clk gcc_blsp1_qup2_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP2_SPI_APPS_CBCR,
- .parent = &blsp1_qup2_spi_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup2_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup2_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup2_spi_apps_clk.c),
@@ -1036,10 +1037,10 @@
static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup3_i2c_apps_clk.c),
@@ -1048,10 +1049,10 @@
static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP3_SPI_APPS_CBCR,
- .parent = &blsp1_qup3_spi_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup3_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup3_spi_apps_clk.c),
@@ -1060,10 +1061,10 @@
static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup4_i2c_apps_clk.c),
@@ -1072,10 +1073,10 @@
static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP4_SPI_APPS_CBCR,
- .parent = &blsp1_qup4_spi_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup4_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup4_spi_apps_clk.c),
@@ -1084,10 +1085,10 @@
static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup5_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup5_i2c_apps_clk.c),
@@ -1096,10 +1097,10 @@
static struct branch_clk gcc_blsp1_qup5_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP5_SPI_APPS_CBCR,
- .parent = &blsp1_qup5_spi_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup5_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup5_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup5_spi_apps_clk.c),
@@ -1108,10 +1109,10 @@
static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = {
.cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &cxo_clk_src.c,
.dbg_name = "gcc_blsp1_qup6_i2c_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup6_i2c_apps_clk.c),
@@ -1120,10 +1121,10 @@
static struct branch_clk gcc_blsp1_qup6_spi_apps_clk = {
.cbcr_reg = BLSP1_QUP6_SPI_APPS_CBCR,
- .parent = &blsp1_qup6_spi_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_qup6_spi_apps_clk_src.c,
.dbg_name = "gcc_blsp1_qup6_spi_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_qup6_spi_apps_clk.c),
@@ -1132,10 +1133,10 @@
static struct branch_clk gcc_blsp1_uart1_apps_clk = {
.cbcr_reg = BLSP1_UART1_APPS_CBCR,
- .parent = &blsp1_uart1_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart1_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart1_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart1_apps_clk.c),
@@ -1144,10 +1145,10 @@
static struct branch_clk gcc_blsp1_uart2_apps_clk = {
.cbcr_reg = BLSP1_UART2_APPS_CBCR,
- .parent = &blsp1_uart2_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart2_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart2_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart2_apps_clk.c),
@@ -1156,10 +1157,10 @@
static struct branch_clk gcc_blsp1_uart3_apps_clk = {
.cbcr_reg = BLSP1_UART3_APPS_CBCR,
- .parent = &blsp1_uart3_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart3_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart3_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart3_apps_clk.c),
@@ -1168,10 +1169,10 @@
static struct branch_clk gcc_blsp1_uart4_apps_clk = {
.cbcr_reg = BLSP1_UART4_APPS_CBCR,
- .parent = &blsp1_uart4_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart4_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart4_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart4_apps_clk.c),
@@ -1180,10 +1181,10 @@
static struct branch_clk gcc_blsp1_uart5_apps_clk = {
.cbcr_reg = BLSP1_UART5_APPS_CBCR,
- .parent = &blsp1_uart5_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart5_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart5_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart5_apps_clk.c),
@@ -1192,10 +1193,10 @@
static struct branch_clk gcc_blsp1_uart6_apps_clk = {
.cbcr_reg = BLSP1_UART6_APPS_CBCR,
- .parent = &blsp1_uart6_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &blsp1_uart6_apps_clk_src.c,
.dbg_name = "gcc_blsp1_uart6_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_blsp1_uart6_apps_clk.c),
@@ -1252,10 +1253,10 @@
static struct branch_clk gcc_gp1_clk = {
.cbcr_reg = GP1_CBCR,
- .parent = &gp1_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &gp1_clk_src.c,
.dbg_name = "gcc_gp1_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_gp1_clk.c),
@@ -1264,10 +1265,10 @@
static struct branch_clk gcc_gp2_clk = {
.cbcr_reg = GP2_CBCR,
- .parent = &gp2_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &gp2_clk_src.c,
.dbg_name = "gcc_gp2_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_gp2_clk.c),
@@ -1276,10 +1277,10 @@
static struct branch_clk gcc_gp3_clk = {
.cbcr_reg = GP3_CBCR,
- .parent = &gp3_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &gp3_clk_src.c,
.dbg_name = "gcc_gp3_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_gp3_clk.c),
@@ -1288,10 +1289,10 @@
static struct branch_clk gcc_ipa_clk = {
.cbcr_reg = IPA_CBCR,
- .parent = &ipa_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &ipa_clk_src.c,
.dbg_name = "gcc_ipa_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_ipa_clk.c),
@@ -1311,10 +1312,10 @@
static struct branch_clk gcc_pdm2_clk = {
.cbcr_reg = PDM2_CBCR,
- .parent = &pdm2_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &pdm2_clk_src.c,
.dbg_name = "gcc_pdm2_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_pdm2_clk.c),
@@ -1357,10 +1358,10 @@
static struct branch_clk gcc_qpic_clk = {
.cbcr_reg = QPIC_CBCR,
- .parent = &qpic_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &qpic_clk_src.c,
.dbg_name = "gcc_qpic_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_qpic_clk.c),
@@ -1380,10 +1381,10 @@
static struct branch_clk gcc_sdcc2_apps_clk = {
.cbcr_reg = SDCC2_APPS_CBCR,
- .parent = &sdcc2_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &sdcc2_apps_clk_src.c,
.dbg_name = "gcc_sdcc2_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_sdcc2_apps_clk.c),
@@ -1403,10 +1404,10 @@
static struct branch_clk gcc_sdcc3_apps_clk = {
.cbcr_reg = SDCC3_APPS_CBCR,
- .parent = &sdcc3_apps_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &sdcc3_apps_clk_src.c,
.dbg_name = "gcc_sdcc3_apps_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_sdcc3_apps_clk.c),
@@ -1415,10 +1416,10 @@
static struct branch_clk gcc_sys_noc_ipa_axi_clk = {
.cbcr_reg = SYS_NOC_IPA_AXI_CBCR,
- .parent = &ipa_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &ipa_clk_src.c,
.dbg_name = "gcc_sys_noc_ipa_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_sys_noc_ipa_axi_clk.c),
@@ -1439,10 +1440,10 @@
static struct branch_clk gcc_usb_hs_system_clk = {
.cbcr_reg = USB_HS_SYSTEM_CBCR,
.bcr_reg = USB_HS_BCR,
- .parent = &usb_hs_system_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb_hs_system_clk_src.c,
.dbg_name = "gcc_usb_hs_system_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb_hs_system_clk.c),
@@ -1462,10 +1463,10 @@
static struct branch_clk gcc_usb_hsic_clk = {
.cbcr_reg = USB_HSIC_CBCR,
- .parent = &usb_hsic_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb_hsic_clk_src.c,
.dbg_name = "gcc_usb_hsic_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb_hsic_clk.c),
@@ -1474,10 +1475,10 @@
static struct branch_clk gcc_usb_hsic_io_cal_clk = {
.cbcr_reg = USB_HSIC_IO_CAL_CBCR,
- .parent = &usb_hsic_io_cal_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb_hsic_io_cal_clk_src.c,
.dbg_name = "gcc_usb_hsic_io_cal_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb_hsic_io_cal_clk.c),
@@ -1487,10 +1488,10 @@
static struct branch_clk gcc_usb_hsic_system_clk = {
.cbcr_reg = USB_HSIC_SYSTEM_CBCR,
.bcr_reg = USB_HS_HSIC_BCR,
- .parent = &usb_hsic_system_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb_hsic_system_clk_src.c,
.dbg_name = "gcc_usb_hsic_system_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb_hsic_system_clk.c),
@@ -1499,10 +1500,10 @@
static struct branch_clk gcc_usb_hsic_xcvr_fs_clk = {
.cbcr_reg = USB_HSIC_XCVR_FS_CBCR,
- .parent = &usb_hsic_xcvr_fs_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &usb_hsic_xcvr_fs_clk_src.c,
.dbg_name = "gcc_usb_hsic_xcvr_fs_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb_hsic_xcvr_fs_clk.c),
@@ -1639,9 +1640,9 @@
static struct branch_clk audio_core_lpaif_pcm_data_oe_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR,
- .parent = &audio_core_lpaif_pcmoe_clk_src.c,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_pcmoe_clk_src.c,
.dbg_name = "audio_core_lpaif_pcm_data_oe_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_pcm_data_oe_clk.c),
@@ -1650,9 +1651,9 @@
static struct branch_clk audio_core_slimbus_core_clk = {
.cbcr_reg = AUDIO_CORE_SLIMBUS_CORE_CBCR,
- .parent = &audio_core_slimbus_core_clk_src.c,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_slimbus_core_clk_src.c,
.dbg_name = "audio_core_slimbus_core_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_slimbus_core_clk.c),
@@ -1672,11 +1673,11 @@
static struct branch_clk audio_core_lpaif_pri_ibit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_PRI_IBIT_CBCR,
- .parent = &audio_core_lpaif_pri_clk_src.c,
.has_sibling = 1,
.max_div = 15,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_pri_clk_src.c,
.dbg_name = "audio_core_lpaif_pri_ibit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_pri_ibit_clk.c),
@@ -1685,10 +1686,10 @@
static struct branch_clk audio_core_lpaif_pri_osr_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_PRI_OSR_CBCR,
- .parent = &audio_core_lpaif_pri_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_pri_clk_src.c,
.dbg_name = "audio_core_lpaif_pri_osr_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_pri_osr_clk.c),
@@ -1708,10 +1709,10 @@
static struct branch_clk audio_core_lpaif_pcm0_ibit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR,
- .parent = &audio_core_lpaif_pcm0_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_pcm0_clk_src.c,
.dbg_name = "audio_core_lpaif_pcm0_ibit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_pcm0_ibit_clk.c),
@@ -1731,11 +1732,11 @@
static struct branch_clk audio_core_lpaif_sec_ibit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_SEC_IBIT_CBCR,
- .parent = &audio_core_lpaif_sec_clk_src.c,
.has_sibling = 1,
.max_div = 15,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_sec_clk_src.c,
.dbg_name = "audio_core_lpaif_sec_ibit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_sec_ibit_clk.c),
@@ -1744,10 +1745,10 @@
static struct branch_clk audio_core_lpaif_sec_osr_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_SEC_OSR_CBCR,
- .parent = &audio_core_lpaif_sec_clk_src.c,
.has_sibling = 1,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_sec_clk_src.c,
.dbg_name = "audio_core_lpaif_sec_osr_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_sec_osr_clk.c),
@@ -1767,10 +1768,10 @@
static struct branch_clk audio_core_lpaif_pcm1_ibit_clk = {
.cbcr_reg = AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR,
- .parent = &audio_core_lpaif_pcm1_clk_src.c,
.has_sibling = 0,
.base = &virt_bases[LPASS_BASE],
.c = {
+ .parent = &audio_core_lpaif_pcm1_clk_src.c,
.dbg_name = "audio_core_lpaif_pcm1_ibit_clk",
.ops = &clk_ops_branch,
CLK_INIT(audio_core_lpaif_pcm1_ibit_clk.c),
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index c43ca46..4432795 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -527,6 +527,7 @@
* is called to make sure the MNCNTR_EN bit is set correctly.
*/
rcg->current_freq = nf;
+ c->parent = nf->src_clk;
/* Enable any clocks that were disabled. */
if (!rcg->bank_info) {
@@ -583,11 +584,6 @@
return (rcg->freq_tbl + n)->freq_hz;
}
-static struct clk *rcg_clk_get_parent(struct clk *c)
-{
- return to_rcg_clk(c)->current_freq->src_clk;
-}
-
/* Disable hw clock gating if not set at boot */
enum handoff branch_handoff(struct branch *b, struct clk *c)
{
@@ -644,6 +640,7 @@
return HANDOFF_UNKNOWN_RATE;
rcg->current_freq = freq;
+ c->parent = freq->src_clk;
c->rate = freq->freq_hz;
return HANDOFF_ENABLED_CLK;
@@ -683,11 +680,6 @@
spin_unlock_irqrestore(&local_clock_reg_lock, flags);
}
-static struct clk *branch_clk_get_parent(struct clk *c)
-{
- return to_branch_clk(c)->parent;
-}
-
static int branch_clk_is_enabled(struct clk *c)
{
return to_branch_clk(c)->enabled;
@@ -834,7 +826,6 @@
.in_hwcg_mode = branch_clk_in_hwcg_mode,
.is_enabled = branch_clk_is_enabled,
.reset = branch_clk_reset,
- .get_parent = branch_clk_get_parent,
.handoff = branch_clk_handoff,
.set_flags = branch_clk_set_flags,
};
@@ -843,7 +834,6 @@
.prepare = branch_clk_enable,
.unprepare = branch_clk_disable,
.is_enabled = branch_clk_is_enabled,
- .get_parent = branch_clk_get_parent,
.handoff = branch_clk_handoff,
};
@@ -870,7 +860,6 @@
.is_enabled = rcg_clk_is_enabled,
.round_rate = rcg_clk_round_rate,
.reset = rcg_clk_reset,
- .get_parent = rcg_clk_get_parent,
.set_flags = rcg_clk_set_flags,
};
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index fca6486..ff6dc69 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -235,7 +235,6 @@
* struct branch_clk - branch
* @enabled: true if clock is on, false otherwise
* @b: branch
- * @parent: clock source
* @c: clock
*
* An on/off switch with a rate derived from the parent.
@@ -243,7 +242,6 @@
struct branch_clk {
bool enabled;
struct branch b;
- struct clk *parent;
struct clk c;
};
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index b9c3036..5923951 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -206,6 +206,7 @@
clk_unprepare(cf->src_clk);
rcg->current_freq = nf;
+ c->parent = nf->src_clk;
return 0;
}
@@ -234,11 +235,6 @@
return (rcg->freq_tbl + n)->freq_hz;
}
-static struct clk *rcg_clk_get_parent(struct clk *c)
-{
- return to_rcg_clk(c)->current_freq->src_clk;
-}
-
static enum handoff _rcg_clk_handoff(struct rcg_clk *rcg, int has_mnd)
{
u32 n_regval = 0, m_regval = 0, d_regval = 0;
@@ -306,6 +302,7 @@
return HANDOFF_UNKNOWN_RATE;
rcg->current_freq = freq;
+ rcg->c.parent = freq->src_clk;
rcg->c.rate = freq->freq_hz;
return HANDOFF_ENABLED_CLK;
@@ -431,7 +428,7 @@
return branch_cdiv_set_rate(branch, rate);
if (!branch->has_sibling)
- return clk_set_rate(branch->parent, rate);
+ return clk_set_rate(c->parent, rate);
return -EPERM;
}
@@ -444,7 +441,7 @@
return rate <= (branch->max_div) ? rate : -EPERM;
if (!branch->has_sibling)
- return clk_round_rate(branch->parent, rate);
+ return clk_round_rate(c->parent, rate);
return -EPERM;
}
@@ -457,16 +454,11 @@
return branch->c.rate;
if (!branch->has_sibling)
- return clk_get_rate(branch->parent);
+ return clk_get_rate(c->parent);
return 0;
}
-static struct clk *branch_clk_get_parent(struct clk *c)
-{
- return to_branch_clk(c)->parent;
-}
-
static int branch_clk_list_rate(struct clk *c, unsigned n)
{
struct branch_clk *branch = to_branch_clk(c);
@@ -474,8 +466,8 @@
if (branch->has_sibling == 1)
return -ENXIO;
- if (branch->parent && branch->parent->ops->list_rate)
- return branch->parent->ops->list_rate(branch->parent, n);
+ if (c->parent && c->parent->ops->list_rate)
+ return c->parent->ops->list_rate(c->parent, n);
else
return -ENXIO;
}
@@ -489,9 +481,9 @@
if ((cbcr_regval & CBCR_BRANCH_OFF_BIT))
return HANDOFF_DISABLED_CLK;
- if (branch->parent) {
- if (branch->parent->ops->handoff)
- return branch->parent->ops->handoff(branch->parent);
+ if (c->parent) {
+ if (c->parent->ops->handoff)
+ return c->parent->ops->handoff(c->parent);
}
return HANDOFF_ENABLED_CLK;
@@ -603,7 +595,6 @@
.set_rate = rcg_clk_set_rate,
.list_rate = rcg_clk_list_rate,
.round_rate = rcg_clk_round_rate,
- .get_parent = rcg_clk_get_parent,
.handoff = rcg_clk_handoff,
};
@@ -612,7 +603,6 @@
.set_rate = rcg_clk_set_rate,
.list_rate = rcg_clk_list_rate,
.round_rate = rcg_clk_round_rate,
- .get_parent = rcg_clk_get_parent,
.handoff = rcg_mnd_clk_handoff,
};
@@ -624,7 +614,6 @@
.list_rate = branch_clk_list_rate,
.round_rate = branch_clk_round_rate,
.reset = branch_clk_reset,
- .get_parent = branch_clk_get_parent,
.handoff = branch_clk_handoff,
};
diff --git a/arch/arm/mach-msm/clock-local2.h b/arch/arm/mach-msm/clock-local2.h
index 101dc2d..a6d2ed6 100644
--- a/arch/arm/mach-msm/clock-local2.h
+++ b/arch/arm/mach-msm/clock-local2.h
@@ -87,7 +87,6 @@
/**
* struct branch_clk - branch clock
* @set_rate: Set the frequency of this branch clock.
- * @parent: clock source
* @c: clk
* @cbcr_reg: branch control register
* @bcr_reg: block reset register
@@ -99,7 +98,6 @@
*/
struct branch_clk {
void (*set_rate)(struct branch_clk *, struct clk_freq_tbl *);
- struct clk *parent;
struct clk c;
const u32 cbcr_reg;
const u32 bcr_reg;
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index 240f4e4..8e11d37 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -98,11 +98,6 @@
spin_unlock_irqrestore(&pll_reg_lock, flags);
}
-static struct clk *pll_vote_clk_get_parent(struct clk *c)
-{
- return to_pll_vote_clk(c)->parent;
-}
-
static int pll_vote_clk_is_enabled(struct clk *c)
{
struct pll_vote_clk *pllv = to_pll_vote_clk(c);
@@ -122,7 +117,6 @@
.enable = pll_vote_clk_enable,
.disable = pll_vote_clk_disable,
.is_enabled = pll_vote_clk_is_enabled,
- .get_parent = pll_vote_clk_get_parent,
.handoff = pll_vote_clk_handoff,
};
@@ -229,11 +223,6 @@
return HANDOFF_DISABLED_CLK;
}
-static struct clk *local_pll_clk_get_parent(struct clk *c)
-{
- return to_pll_clk(c)->parent;
-}
-
static int local_pll_clk_set_rate(struct clk *c, unsigned long rate)
{
struct pll_freq_tbl *nf;
@@ -346,7 +335,6 @@
.disable = local_pll_clk_disable,
.set_rate = local_pll_clk_set_rate,
.handoff = local_pll_clk_handoff,
- .get_parent = local_pll_clk_get_parent,
};
struct pll_rate {
@@ -537,7 +525,6 @@
.enable = pll_acpu_vote_clk_enable,
.disable = pll_acpu_vote_clk_disable,
.is_enabled = pll_vote_clk_is_enabled,
- .get_parent = pll_vote_clk_get_parent,
};
static void __init __set_fsm_mode(void __iomem *mode_reg,
diff --git a/arch/arm/mach-msm/clock-pll.h b/arch/arm/mach-msm/clock-pll.h
index 33b35a8..cb334d7 100644
--- a/arch/arm/mach-msm/clock-pll.h
+++ b/arch/arm/mach-msm/clock-pll.h
@@ -35,7 +35,6 @@
* any HW voting
* @id: PLL ID
* @mode_reg: enable register
- * @parent: clock source
* @c: clock
*/
struct pll_shared_clk {
@@ -104,7 +103,6 @@
* @en_mask: ORed with @en_reg to enable the clock
* @status_mask: ANDed with @status_reg to determine if PLL is active.
* @status_reg: status register
- * @parent: clock source
* @c: clock
*/
struct pll_vote_clk {
@@ -115,7 +113,6 @@
void __iomem *const status_reg;
const u32 status_mask;
- struct clk *parent;
struct clk c;
void *const __iomem *base;
};
@@ -144,7 +141,6 @@
* @status_reg: status register, contains the lock detection bit
* @masks: masks used for settings in config_reg
* @freq_tbl: pll freq table
- * @parent: clock source
* @c: clk
* @base: pointer to base address of ioremapped registers.
*/
@@ -159,7 +155,6 @@
struct pll_config_masks masks;
struct pll_freq_tbl *freq_tbl;
- struct clk *parent;
struct clk c;
void *const __iomem *base;
};
diff --git a/arch/arm/mach-msm/clock-voter.c b/arch/arm/mach-msm/clock-voter.c
index fa170bf4..7421ba6 100644
--- a/arch/arm/mach-msm/clock-voter.c
+++ b/arch/arm/mach-msm/clock-voter.c
@@ -43,7 +43,7 @@
mutex_lock(&voter_clk_lock);
if (v->enabled) {
- struct clk *parent = v->parent;
+ struct clk *parent = clk->parent;
/*
* Get the aggregate rate without this clock's vote and update
@@ -79,7 +79,7 @@
struct clk_voter *v = to_clk_voter(clk);
mutex_lock(&voter_clk_lock);
- parent = v->parent;
+ parent = clk->parent;
/*
* Increase the rate if this clock is voting for a higher rate
@@ -105,7 +105,7 @@
struct clk_voter *v = to_clk_voter(clk);
mutex_lock(&voter_clk_lock);
- parent = v->parent;
+ parent = clk->parent;
/*
* Decrease the rate if this clock was the only one voting for
@@ -129,14 +129,7 @@
static long voter_clk_round_rate(struct clk *clk, unsigned long rate)
{
- struct clk_voter *v = to_clk_voter(clk);
- return clk_round_rate(v->parent, rate);
-}
-
-static struct clk *voter_clk_get_parent(struct clk *clk)
-{
- struct clk_voter *v = to_clk_voter(clk);
- return v->parent;
+ return clk_round_rate(clk->parent, rate);
}
static bool voter_clk_is_local(struct clk *clk)
@@ -159,7 +152,6 @@
.set_rate = voter_clk_set_rate,
.is_enabled = voter_clk_is_enabled,
.round_rate = voter_clk_round_rate,
- .get_parent = voter_clk_get_parent,
.is_local = voter_clk_is_local,
.handoff = voter_clk_handoff,
};
diff --git a/arch/arm/mach-msm/clock-voter.h b/arch/arm/mach-msm/clock-voter.h
index 82c071b..eb55a12 100644
--- a/arch/arm/mach-msm/clock-voter.h
+++ b/arch/arm/mach-msm/clock-voter.h
@@ -21,7 +21,6 @@
struct clk_voter {
bool enabled;
- struct clk *parent;
struct clk c;
};
@@ -32,8 +31,8 @@
#define DEFINE_CLK_VOTER(clk_name, _parent, _default_rate) \
struct clk_voter clk_name = { \
- .parent = _parent, \
.c = { \
+ .parent = _parent, \
.dbg_name = #clk_name, \
.ops = &clk_ops_voter, \
.rate = _default_rate, \
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index e9dd974..c2bf5ba 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -163,7 +163,7 @@
mutex_lock(&clk->prepare_lock);
if (clk->prepare_count == 0) {
- parent = clk_get_parent(clk);
+ parent = clk->parent;
ret = clk_prepare(parent);
if (ret)
@@ -213,7 +213,7 @@
WARN(!clk->prepare_count,
"%s: Don't call enable on unprepared clocks\n", name);
if (clk->count == 0) {
- parent = clk_get_parent(clk);
+ parent = clk->parent;
ret = clk_enable(parent);
if (ret)
@@ -258,7 +258,7 @@
if (WARN(clk->count == 0, "%s is unbalanced", name))
goto out;
if (clk->count == 1) {
- struct clk *parent = clk_get_parent(clk);
+ struct clk *parent = clk->parent;
trace_clock_disable(name, 0, smp_processor_id());
if (clk->ops->disable)
@@ -283,7 +283,7 @@
if (WARN(!clk->prepare_count, "%s is unbalanced (prepare)", name))
goto out;
if (clk->prepare_count == 1) {
- struct clk *parent = clk_get_parent(clk);
+ struct clk *parent = clk->parent;
WARN(clk->count,
"%s: Don't call unprepare when the clock is enabled\n",
@@ -411,10 +411,7 @@
if (IS_ERR_OR_NULL(clk))
return NULL;
- if (!clk->ops->get_parent)
- return NULL;
-
- return clk->ops->get_parent(clk);
+ return clk->parent;
}
EXPORT_SYMBOL(clk_get_parent);
@@ -438,7 +435,7 @@
for (n = 0; n < num_clocks; n++) {
clk = clock_tbl[n].clk;
- parent = clk_get_parent(clk);
+ parent = clk->parent;
if (parent && list_empty(&clk->siblings))
list_add(&clk->siblings, &parent->children);
}
@@ -492,11 +489,11 @@
/*
* Handoff functions for children must be called before their parents'
- * so that the correct parent is returned by the clk_get_parent() below.
+ * so that the correct parent is available below.
*/
ret = clk->ops->handoff(clk);
if (ret == HANDOFF_ENABLED_CLK) {
- ret = __handoff_clk(clk_get_parent(clk));
+ ret = __handoff_clk(clk->parent);
if (ret == HANDOFF_ENABLED_CLK) {
h = kmalloc(sizeof(*h), GFP_KERNEL);
if (!h) {
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index c3be6ce..0faf500 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -669,6 +669,18 @@
.id = -1,
};
+static struct acpuclk_platform_data acpuclk_8930ab_pdata = {
+ .uses_pm8917 = false,
+};
+
+struct platform_device msm8930ab_device_acpuclk = {
+ .name = "acpuclk-8930ab",
+ .id = -1,
+ .dev = {
+ .platform_data = &acpuclk_8930ab_pdata,
+ },
+};
+
static struct fs_driver_data gfx3d_fs_data = {
.clks = (struct fs_clk_data[]){
{ .name = "core_clk", .reset_rate = 27000000 },
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index eae01aa..bd5a20f 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -455,6 +455,7 @@
extern struct platform_device msm8x60_device_acpuclk;
extern struct platform_device msm8930_device_acpuclk;
extern struct platform_device msm8930aa_device_acpuclk;
+extern struct platform_device msm8930ab_device_acpuclk;
extern struct platform_device msm8960_device_acpuclk;
extern struct platform_device msm8960ab_device_acpuclk;
extern struct platform_device msm9615_device_acpuclk;
diff --git a/arch/arm/mach-msm/include/mach/clk-provider.h b/arch/arm/mach-msm/include/mach/clk-provider.h
index d47e88e..0f2feaa 100644
--- a/arch/arm/mach-msm/include/mach/clk-provider.h
+++ b/arch/arm/mach-msm/include/mach/clk-provider.h
@@ -103,6 +103,7 @@
* @depends: non-direct parent of clock to enable when this clock is enabled
* @vdd_class: voltage scaling requirement class
* @fmax: maximum frequency in Hz supported at each voltage level
+ * @parent: the current source of this clock
*/
struct clk {
uint32_t flags;
@@ -113,6 +114,7 @@
unsigned long *fmax;
int num_fmax;
unsigned long rate;
+ struct clk *parent;
struct list_head children;
struct list_head siblings;
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 054e70c..57b4bd3 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -161,6 +161,12 @@
}
#endif
+/*
+ * Function to program the global registers of an IOMMU securely.
+ * This should only be called on IOMMUs for which kernel programming
+ * of global registers is not possible
+ */
+int msm_iommu_sec_program_iommu(int sec_id);
static inline int msm_soc_version_supports_iommu_v1(void)
{
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
index d34536d..88cb94a 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
@@ -14,7 +14,7 @@
#define _AUDIO_ACDB_H
#include <linux/msm_audio_acdb.h>
-#ifdef CONFIG_ARCH_MSM8974
+#if defined CONFIG_ARCH_MSM8974 || defined CONFIG_ARCH_MSM9625
#include <sound/q6adm-v2.h>
#else
#include <sound/q6adm.h>
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index 63ae4e6..f7b2b1e 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -159,6 +159,7 @@
int retention_uV;
int headroom_uV;
int ldo_threshold_uV;
+ bool online;
};
static u32 version;
@@ -309,6 +310,7 @@
}
setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
+
return msm_spm_apcs_set_vdd(setpoint);
}
@@ -319,6 +321,8 @@
int rc = 0;
list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
+ if (!kvreg->online)
+ continue;
if (kvreg->uV > kvreg->ldo_threshold_uV
|| kvreg->uV > vmax - kvreg->headroom_uV) {
rc = switch_to_using_hs(kvreg);
@@ -482,6 +486,9 @@
struct pmic_gang_vreg *pvreg = from->pvreg;
list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
+ if (!kvreg->online)
+ continue;
+
v = kvreg->uV;
if (kvreg == from)
@@ -490,6 +497,7 @@
if (vmax < v)
vmax = v;
}
+
return vmax;
}
@@ -499,14 +507,17 @@
struct krait_power_vreg *kvreg;
struct pmic_gang_vreg *pvreg = from->pvreg;
- list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link)
+ list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
+ if (!kvreg->online)
+ continue;
load_total += kvreg->load_uA;
+ }
return load_total;
}
#define ROUND_UP_VOLTAGE(v, res) (DIV_ROUND_UP(v, res) * res)
-static int krait_power_set_voltage(struct regulator_dev *rdev,
+static int _set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
{
struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
@@ -514,6 +525,31 @@
int rc;
int vmax;
+ vmax = get_vmax(kvreg, min_uV);
+
+ /* round up the pmic voltage as per its resolution */
+ vmax = ROUND_UP_VOLTAGE(vmax, LV_RANGE_STEP);
+
+ rc = pmic_gang_set_voltage(kvreg, vmax);
+ if (rc < 0) {
+ dev_err(&rdev->dev, "%s failed set voltage (%d, %d) rc = %d\n",
+ kvreg->name, min_uV, max_uV, rc);
+ goto out;
+ }
+
+ pvreg->pmic_vmax_uV = vmax;
+
+out:
+ return rc;
+}
+
+static int krait_power_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV, unsigned *selector)
+{
+ struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
+ struct pmic_gang_vreg *pvreg = kvreg->pvreg;
+ int rc;
+
/*
* if the voltage requested is below LDO_THRESHOLD this cpu could
* switch to LDO mode. Hence round the voltage as per the LDO
@@ -526,49 +562,29 @@
}
mutex_lock(&pvreg->krait_power_vregs_lock);
-
- vmax = get_vmax(kvreg, min_uV);
-
- /* round up the pmic voltage as per its resolution */
- vmax = ROUND_UP_VOLTAGE(vmax, LV_RANGE_STEP);
-
- /*
- * Assign the voltage before updating the gang voltage as we iterate
- * over all the core voltages and choose HS or LDO for each of them
- */
kvreg->uV = min_uV;
- rc = pmic_gang_set_voltage(kvreg, vmax);
- if (rc < 0) {
- dev_err(&rdev->dev, "%s failed set voltage (%d, %d) rc = %d\n",
- kvreg->name, min_uV, max_uV, rc);
- goto out;
+ if (!kvreg->online) {
+ mutex_unlock(&pvreg->krait_power_vregs_lock);
+ return 0;
}
- pvreg->pmic_vmax_uV = vmax;
-
-out:
+ rc = _set_voltage(rdev, min_uV, max_uV, selector);
mutex_unlock(&pvreg->krait_power_vregs_lock);
+
return rc;
}
#define PMIC_FTS_MODE_PFM 0x00
#define PMIC_FTS_MODE_PWM 0x80
#define PFM_LOAD_UA 500000
-static unsigned int krait_power_get_optimum_mode(struct regulator_dev *rdev,
+static unsigned int _get_optimum_mode(struct regulator_dev *rdev,
int input_uV, int output_uV, int load_uA)
{
struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
struct pmic_gang_vreg *pvreg = kvreg->pvreg;
int rc;
int load_total_uA;
- int reg_mode = -EINVAL;
-
- mutex_lock(&pvreg->krait_power_vregs_lock);
-
- reg_mode = kvreg->mode;
-
- kvreg->load_uA = load_uA;
load_total_uA = get_total_load(kvreg);
@@ -584,8 +600,7 @@
pvreg->pfm_mode = true;
}
}
- mutex_unlock(&pvreg->krait_power_vregs_lock);
- return reg_mode;
+ return kvreg->mode;
}
if (pvreg->pfm_mode) {
@@ -608,8 +623,27 @@
}
out:
+ return kvreg->mode;
+}
+
+static unsigned int krait_power_get_optimum_mode(struct regulator_dev *rdev,
+ int input_uV, int output_uV, int load_uA)
+{
+ struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
+ struct pmic_gang_vreg *pvreg = kvreg->pvreg;
+ int rc;
+
+ mutex_lock(&pvreg->krait_power_vregs_lock);
+ kvreg->load_uA = load_uA;
+ if (!kvreg->online) {
+ mutex_unlock(&pvreg->krait_power_vregs_lock);
+ return kvreg->mode;
+ }
+
+ rc = _get_optimum_mode(rdev, input_uV, output_uV, load_uA);
mutex_unlock(&pvreg->krait_power_vregs_lock);
- return reg_mode;
+
+ return rc;
}
static int krait_power_set_mode(struct regulator_dev *rdev, unsigned int mode)
@@ -624,12 +658,62 @@
return kvreg->mode;
}
+static int krait_power_is_enabled(struct regulator_dev *rdev)
+{
+ struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
+
+ return kvreg->online;
+}
+
+static int krait_power_enable(struct regulator_dev *rdev)
+{
+ struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
+ struct pmic_gang_vreg *pvreg = kvreg->pvreg;
+ int rc;
+
+ mutex_lock(&pvreg->krait_power_vregs_lock);
+ kvreg->online = true;
+ rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
+ kvreg->load_uA);
+ if (rc < 0)
+ goto en_err;
+ rc = _set_voltage(rdev, kvreg->uV,
+ rdev->constraints->max_uV, NULL);
+en_err:
+ mutex_unlock(&pvreg->krait_power_vregs_lock);
+ return rc;
+}
+
+static int krait_power_disable(struct regulator_dev *rdev)
+{
+ struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
+ struct pmic_gang_vreg *pvreg = kvreg->pvreg;
+ int rc;
+
+ mutex_lock(&pvreg->krait_power_vregs_lock);
+ kvreg->online = false;
+
+ rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
+ kvreg->load_uA);
+ if (rc < 0)
+ goto dis_err;
+
+ rc = _set_voltage(rdev, kvreg->uV,
+ rdev->constraints->max_uV, NULL);
+dis_err:
+ mutex_unlock(&pvreg->krait_power_vregs_lock);
+ return rc;
+}
+
static struct regulator_ops krait_power_ops = {
.get_voltage = krait_power_get_voltage,
.set_voltage = krait_power_set_voltage,
.get_optimum_mode = krait_power_get_optimum_mode,
.set_mode = krait_power_set_mode,
.get_mode = krait_power_get_mode,
+ .enable = krait_power_enable,
+ .disable = krait_power_disable,
+ .is_enabled = krait_power_is_enabled,
};
static void kvreg_hw_init(struct krait_power_vreg *kvreg)
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_common.h b/arch/arm/mach-msm/qdsp6v2/q6audio_common.h
index e4291e7..3bc8454 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_common.h
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_common.h
@@ -15,7 +15,7 @@
#ifndef __Q6_AUDIO_COMMON_H__
#define __Q6_AUDIO_COMMON_H__
-#ifdef CONFIG_ARCH_MSM8974
+#if defined(CONFIG_ARCH_MSM8974) || defined(CONFIG_ARCH_MSM9625)
#include <sound/apr_audio-v2.h>
#include <sound/q6asm-v2.h>
#else
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index b1dd1db..7427899 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -36,6 +36,8 @@
#include <linux/notifier.h>
#include <linux/sort.h>
#include <linux/suspend.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
#include <mach/msm_smd.h>
#include <mach/msm_iomap.h>
#include <mach/system.h>
@@ -3502,6 +3504,295 @@
return err_ret;
}
+static int __devinit parse_smd_devicetree(struct device_node *node,
+ void *irq_out_base)
+{
+ uint32_t edge;
+ char *key;
+ int ret;
+ uint32_t irq_offset;
+ uint32_t irq_bitmask;
+ uint32_t irq_line;
+ unsigned long irq_flags = IRQF_TRIGGER_RISING;
+ const char *pilstr;
+ struct interrupt_config_item *private_irq;
+
+ key = "qcom,smd-edge";
+ ret = of_property_read_u32(node, key, &edge);
+ if (ret)
+ goto missing_key;
+ SMD_DBG("%s: %s = %d", __func__, key, edge);
+
+ key = "qcom,smd-irq-offset";
+ ret = of_property_read_u32(node, key, &irq_offset);
+ if (ret)
+ goto missing_key;
+ SMD_DBG("%s: %s = %x", __func__, key, irq_offset);
+
+ key = "qcom,smd-irq-bitmask";
+ ret = of_property_read_u32(node, key, &irq_bitmask);
+ if (ret)
+ goto missing_key;
+ SMD_DBG("%s: %s = %x", __func__, key, irq_bitmask);
+
+ key = "interrupts";
+ irq_line = irq_of_parse_and_map(node, 0);
+ if (!irq_line)
+ goto missing_key;
+ SMD_DBG("%s: %s = %d", __func__, key, irq_line);
+
+ key = "qcom,pil-string";
+ pilstr = of_get_property(node, key, NULL);
+ if (pilstr)
+ SMD_DBG("%s: %s = %s", __func__, key, pilstr);
+
+ key = "qcom,irq-no-suspend";
+ ret = of_property_read_bool(node, key);
+ if (ret)
+ irq_flags |= IRQF_NO_SUSPEND;
+
+ private_irq = &private_intr_config[edge_to_pids[edge].remote_pid].smd;
+ private_irq->out_bit_pos = irq_bitmask;
+ private_irq->out_offset = irq_offset;
+ private_irq->out_base = irq_out_base;
+ private_irq->irq_id = irq_line;
+
+ ret = request_irq(irq_line,
+ private_irq->irq_handler,
+ irq_flags,
+ "smd_dev",
+ NULL);
+ if (ret < 0) {
+ pr_err("%s: request_irq() failed on %d\n", __func__, irq_line);
+ return ret;
+ } else {
+ ret = enable_irq_wake(irq_line);
+ if (ret < 0)
+ pr_err("%s: enable_irq_wake() failed on %d\n", __func__,
+ irq_line);
+ }
+
+ if (pilstr)
+ strlcpy(edge_to_pids[edge].subsys_name, pilstr,
+ SMD_MAX_CH_NAME_LEN);
+
+ return 0;
+
+missing_key:
+ pr_err("%s: missing key: %s", __func__, key);
+ return -ENODEV;
+}
+
+static int __devinit parse_smsm_devicetree(struct device_node *node,
+ void *irq_out_base)
+{
+ uint32_t edge;
+ char *key;
+ int ret;
+ uint32_t irq_offset;
+ uint32_t irq_bitmask;
+ uint32_t irq_line;
+ struct interrupt_config_item *private_irq;
+
+ key = "qcom,smsm-edge";
+ ret = of_property_read_u32(node, key, &edge);
+ if (ret)
+ goto missing_key;
+ SMD_DBG("%s: %s = %d", __func__, key, edge);
+
+ key = "qcom,smsm-irq-offset";
+ ret = of_property_read_u32(node, key, &irq_offset);
+ if (ret)
+ goto missing_key;
+ SMD_DBG("%s: %s = %x", __func__, key, irq_offset);
+
+ key = "qcom,smsm-irq-bitmask";
+ ret = of_property_read_u32(node, key, &irq_bitmask);
+ if (ret)
+ goto missing_key;
+ SMD_DBG("%s: %s = %x", __func__, key, irq_bitmask);
+
+ key = "interrupts";
+ irq_line = irq_of_parse_and_map(node, 0);
+ if (!irq_line)
+ goto missing_key;
+ SMD_DBG("%s: %s = %d", __func__, key, irq_line);
+
+ private_irq = &private_intr_config[edge_to_pids[edge].remote_pid].smsm;
+ private_irq->out_bit_pos = irq_bitmask;
+ private_irq->out_offset = irq_offset;
+ private_irq->out_base = irq_out_base;
+ private_irq->irq_id = irq_line;
+
+ ret = request_irq(irq_line,
+ private_irq->irq_handler,
+ IRQF_TRIGGER_RISING,
+ "smsm_dev",
+ NULL);
+ if (ret < 0) {
+ pr_err("%s: request_irq() failed on %d\n", __func__, irq_line);
+ return ret;
+ } else {
+ ret = enable_irq_wake(irq_line);
+ if (ret < 0)
+ pr_err("%s: enable_irq_wake() failed on %d\n", __func__,
+ irq_line);
+ }
+
+ return 0;
+
+missing_key:
+ pr_err("%s: missing key: %s", __func__, key);
+ return -ENODEV;
+}
+
+static void __devinit unparse_smd_devicetree(struct device_node *node)
+{
+ uint32_t irq_line;
+
+ irq_line = irq_of_parse_and_map(node, 0);
+
+ free_irq(irq_line, NULL);
+}
+
+static void __devinit unparse_smsm_devicetree(struct device_node *node)
+{
+ uint32_t irq_line;
+
+ irq_line = irq_of_parse_and_map(node, 0);
+
+ free_irq(irq_line, NULL);
+}
+
+static int __devinit smd_core_devicetree_init(struct platform_device *pdev)
+{
+ char *key;
+ struct resource *r;
+ void *irq_out_base;
+ void *aux_mem_base;
+ uint32_t aux_mem_size;
+ int temp_string_size = 11; /* max 3 digit count */
+ char temp_string[temp_string_size];
+ int count;
+ struct device_node *node;
+ int ret;
+ const char *compatible;
+ int subnode_num = 0;
+
+ disable_smsm_reset_handshake = 1;
+
+ key = "irq-reg-base";
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, key);
+ if (!r) {
+ pr_err("%s: missing '%s'\n", __func__, key);
+ return -ENODEV;
+ }
+ irq_out_base = (void *)(r->start);
+ SMD_DBG("%s: %s = %p", __func__, key, irq_out_base);
+
+ count = 1;
+ while (1) {
+ scnprintf(temp_string, temp_string_size, "aux-mem%d", count);
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ temp_string);
+ if (!r)
+ break;
+
+ ++num_smem_areas;
+ ++count;
+ if (count > 999) {
+ pr_err("%s: max num aux mem regions reached\n",
+ __func__);
+ break;
+ }
+ }
+
+ if (num_smem_areas) {
+ smem_areas = kmalloc(sizeof(struct smem_area) * num_smem_areas,
+ GFP_KERNEL);
+ if (!smem_areas) {
+ pr_err("%s: smem areas kmalloc failed\n", __func__);
+ num_smem_areas = 0;
+ return -ENOMEM;
+ }
+ count = 1;
+ while (1) {
+ scnprintf(temp_string, temp_string_size, "aux-mem%d",
+ count);
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ temp_string);
+ if (!r)
+ break;
+ aux_mem_base = (void *)(r->start);
+ aux_mem_size = (uint32_t)(resource_size(r));
+ SMD_DBG("%s: %s = %p %x", __func__, temp_string,
+ aux_mem_base, aux_mem_size);
+ smem_areas[count - 1].phys_addr = aux_mem_base;
+ smem_areas[count - 1].size = aux_mem_size;
+ smem_areas[count - 1].virt_addr = ioremap_nocache(
+ (unsigned long)(smem_areas[count-1].phys_addr),
+ smem_areas[count - 1].size);
+ if (!smem_areas[count - 1].virt_addr) {
+ pr_err("%s: ioremap_nocache() of addr:%p size: %x\n",
+ __func__,
+ smem_areas[count - 1].phys_addr,
+ smem_areas[count - 1].size);
+ ret = -ENOMEM;
+ goto free_smem_areas;
+ }
+
+ ++count;
+ if (count > 999) {
+ pr_err("%s: max num aux mem regions reached\n",
+ __func__);
+ break;
+ }
+ }
+ sort(smem_areas, num_smem_areas,
+ sizeof(struct smem_area),
+ sort_cmp_func, NULL);
+ }
+
+ for_each_child_of_node(pdev->dev.of_node, node) {
+ compatible = of_get_property(node, "compatible", NULL);
+ if (!strcmp(compatible, "qcom,smd")) {
+ ret = parse_smd_devicetree(node, irq_out_base);
+ if (ret)
+ goto rollback_subnodes;
+ } else if (!strcmp(compatible, "qcom,smsm")) {
+ ret = parse_smsm_devicetree(node, irq_out_base);
+ if (ret)
+ goto rollback_subnodes;
+ } else {
+ pr_err("%s: invalid child node named: %s\n", __func__,
+ compatible);
+ ret = -ENODEV;
+ goto rollback_subnodes;
+ }
+ ++subnode_num;
+ }
+
+ return 0;
+
+rollback_subnodes:
+ count = 0;
+ for_each_child_of_node(pdev->dev.of_node, node) {
+ if (count >= subnode_num)
+ break;
+ ++count;
+ compatible = of_get_property(node, "compatible", NULL);
+ if (!strcmp(compatible, "qcom,smd"))
+ unparse_smd_devicetree(node);
+ else
+ unparse_smsm_devicetree(node);
+ }
+free_smem_areas:
+ num_smem_areas = 0;
+ kfree(smem_areas);
+ smem_areas = NULL;
+ return ret;
+}
+
static int __devinit msm_smd_probe(struct platform_device *pdev)
{
int ret;
@@ -3522,8 +3813,12 @@
if (pdev) {
if (pdev->dev.of_node) {
- pr_err("SMD: Device tree not currently supported\n");
- return -ENODEV;
+ ret = smd_core_devicetree_init(pdev);
+ if (ret) {
+ pr_err("%s: device tree init failed\n",
+ __func__);
+ return ret;
+ }
} else if (pdev->dev.platform_data) {
ret = smd_core_platform_init(pdev);
if (ret) {
@@ -3600,11 +3895,17 @@
}
late_initcall(modem_restart_late_init);
+static struct of_device_id msm_smem_match_table[] = {
+ { .compatible = "qcom,smem" },
+ {},
+};
+
static struct platform_driver msm_smd_driver = {
.probe = msm_smd_probe,
.driver = {
.name = MODULE_NAME,
.owner = THIS_MODULE,
+ .of_match_table = msm_smem_match_table,
},
};
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index b61604a..3af066d 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -23,12 +23,14 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/percpu.h>
+#include <linux/mm.h>
#include <asm/localtimer.h>
#include <asm/mach/time.h>
#include <asm/hardware/gic.h>
#include <asm/sched_clock.h>
#include <asm/smp_plat.h>
+#include <asm/user_accessible_timer.h>
#include <mach/msm_iomap.h>
#include <mach/irqs.h>
#include <mach/socinfo.h>
@@ -1161,6 +1163,16 @@
}
msm_sched_clock_init();
+ if (use_user_accessible_timers()) {
+ if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_apq8064()) {
+ struct msm_clock *gtclock = &msm_clocks[MSM_CLOCK_GPT];
+ void __iomem *addr = gtclock->regbase +
+ TIMER_COUNT_VAL + global_timer_offset;
+ setup_user_timer_offset(virt_to_phys(addr)&0xfff);
+ set_user_accessible_timer_flag(true);
+ }
+ }
+
#ifdef ARCH_HAS_READ_CURRENT_TIMER
if (is_smp()) {
__raw_writel(1,
diff --git a/arch/arm/mach-msm/timer_page.c b/arch/arm/mach-msm/timer_page.c
new file mode 100644
index 0000000..24d2a35
--- /dev/null
+++ b/arch/arm/mach-msm/timer_page.c
@@ -0,0 +1,36 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/export.h>
+#include <asm/user_accessible_timer.h>
+#include "mach/socinfo.h"
+#include "mach/msm_iomap.h"
+
+#include "timer.h"
+
+inline int get_timer_page_address(void)
+{
+ if (!use_user_accessible_timers())
+ return ARM_USER_ACCESSIBLE_TIMERS_INVALID_PAGE;
+
+ if (cpu_is_msm8960())
+ return MSM8960_TMR0_PHYS;
+ else if (cpu_is_msm8930())
+ return MSM8930_TMR0_PHYS;
+ else if (cpu_is_apq8064())
+ return APQ8064_TMR0_PHYS;
+ else
+ return ARM_USER_ACCESSIBLE_TIMERS_INVALID_PAGE;
+}
+EXPORT_SYMBOL(get_timer_page_address);
+
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 57f41ca..e2cd0120 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -771,6 +771,9 @@
printk(KERN_NOTICE "Virtual kernel memory layout:\n"
" vector : 0x%08lx - 0x%08lx (%4ld kB)\n"
+#ifdef CONFIG_ARM_USE_USER_ACCESSIBLE_TIMERS
+ " timers : 0x%08lx - 0x%08lx (%4ld kB)\n"
+#endif
#ifdef CONFIG_HAVE_TCM
" DTCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
" ITCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
@@ -791,6 +794,11 @@
MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
(PAGE_SIZE)),
+#ifdef CONFIG_ARM_USE_USER_ACCESSIBLE_TIMERS
+ MLK(UL(CONFIG_ARM_USER_ACCESSIBLE_TIMER_BASE),
+ UL(CONFIG_ARM_USER_ACCESSIBLE_TIMER_BASE)
+ + (PAGE_SIZE)),
+#endif
#ifdef CONFIG_HAVE_TCM
MLK(DTCM_OFFSET, (unsigned long) dtcm_end),
MLK(ITCM_OFFSET, (unsigned long) itcm_end),
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index bae23b0..1cb6cba 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -33,6 +33,8 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/user_accessible_timer.h>
+
#include "mm.h"
/*
@@ -309,6 +311,13 @@
.prot_l1 = PMD_TYPE_TABLE,
.domain = DOMAIN_KERNEL,
},
+ [MT_DEVICE_USER_ACCESSIBLE] = {
+ .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED |
+ L_PTE_SHARED | L_PTE_USER | L_PTE_RDONLY,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PROT_SECT_DEVICE | PMD_SECT_S,
+ .domain = DOMAIN_IO,
+ },
};
const struct mem_type *get_mem_type(unsigned int type)
@@ -764,7 +773,9 @@
const struct mem_type *type;
pgd_t *pgd;
- if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
+ if ((md->virtual != vectors_base() &&
+ md->virtual != get_user_accessible_timers_base()) &&
+ md->virtual < TASK_SIZE) {
printk(KERN_WARNING "BUG: not creating mapping for 0x%08llx"
" at 0x%08lx in user region\n",
(long long)__pfn_to_phys((u64)md->pfn), md->virtual);
@@ -1203,6 +1214,20 @@
mdesc->map_io();
fill_pmd_gaps();
+ if (use_user_accessible_timers()) {
+ /*
+ * Generate a mapping for the timer page.
+ */
+ int page_addr = get_timer_page_address();
+ if (page_addr != ARM_USER_ACCESSIBLE_TIMERS_INVALID_PAGE) {
+ map.pfn = __phys_to_pfn(page_addr);
+ map.virtual = CONFIG_ARM_USER_ACCESSIBLE_TIMER_BASE;
+ map.length = PAGE_SIZE;
+ map.type = MT_DEVICE_USER_ACCESSIBLE;
+ create_mapping(&map, false);
+ }
+ }
+
/*
* Finally flush the caches and tlb to ensure that we're in a
* consistent state wrt the writebuffer. This also ensures that
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 28d0565..de3cf52 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -29,6 +29,7 @@
#define IN_BUF_SIZE 16384
#define MAX_IN_BUF_SIZE 32768
#define MAX_SYNC_OBJ_NAME_SIZE 32
+#define UINT32_MAX UINT_MAX
/* Size of the buffer used for deframing a packet
reveived from the PC tool*/
#define HDLC_MAX 4096
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 19c6ed2..7b17ce4 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -358,7 +358,7 @@
}
void diag_add_reg(int j, struct bindpkt_params *params,
- int *success, int *count_entries)
+ int *success, unsigned int *count_entries)
{
*success = 1;
driver->table[j].cmd_code = params->cmd_code;
@@ -399,79 +399,153 @@
long diagchar_ioctl(struct file *filp,
unsigned int iocmd, unsigned long ioarg)
{
- int i, j, count_entries = 0, temp;
- int success = -1;
+ int i, j, temp, success = -1, status;
+ unsigned int count_entries = 0, interim_count = 0;
void *temp_buf;
uint16_t support_list = 0;
- struct diag_dci_client_tbl *params =
- kzalloc(sizeof(struct diag_dci_client_tbl), GFP_KERNEL);
+ struct diag_dci_client_tbl *dci_params;
struct diag_dci_health_stats stats;
- int status;
if (iocmd == DIAG_IOCTL_COMMAND_REG) {
- struct bindpkt_params_per_process *pkt_params =
- (struct bindpkt_params_per_process *) ioarg;
+ struct bindpkt_params_per_process pkt_params;
+ struct bindpkt_params *params;
+ struct bindpkt_params *head_params;
+ if (copy_from_user(&pkt_params, (void *)ioarg,
+ sizeof(struct bindpkt_params_per_process))) {
+ return -EFAULT;
+ }
+ if ((UINT32_MAX/sizeof(struct bindpkt_params)) <
+ pkt_params.count) {
+ pr_warning("diag: integer overflow while multiply\n");
+ return -EFAULT;
+ }
+ params = kzalloc(pkt_params.count*sizeof(
+ struct bindpkt_params), GFP_KERNEL);
+ if (!params) {
+ pr_err("diag: unable to alloc memory\n");
+ return -ENOMEM;
+ } else
+ head_params = params;
+
+ if (copy_from_user(params, pkt_params.params,
+ pkt_params.count*sizeof(struct bindpkt_params))) {
+ kfree(head_params);
+ return -EFAULT;
+ }
mutex_lock(&driver->diagchar_mutex);
for (i = 0; i < diag_max_reg; i++) {
if (driver->table[i].process_id == 0) {
- diag_add_reg(i, pkt_params->params,
- &success, &count_entries);
- if (pkt_params->count > count_entries) {
- pkt_params->params++;
+ diag_add_reg(i, params, &success,
+ &count_entries);
+ if (pkt_params.count > count_entries) {
+ params++;
} else {
mutex_unlock(&driver->diagchar_mutex);
+ kfree(head_params);
return success;
}
}
}
if (i < diag_threshold_reg) {
/* Increase table size by amount required */
- diag_max_reg += pkt_params->count -
+ if (pkt_params.count >= count_entries) {
+ interim_count = pkt_params.count -
count_entries;
+ } else {
+ pr_warning("diag: error in params count\n");
+ kfree(head_params);
+ mutex_unlock(&driver->diagchar_mutex);
+ return -EFAULT;
+ }
+ if (UINT32_MAX - diag_max_reg >=
+ interim_count) {
+ diag_max_reg += interim_count;
+ } else {
+ pr_warning("diag: Integer overflow\n");
+ kfree(head_params);
+ mutex_unlock(&driver->diagchar_mutex);
+ return -EFAULT;
+ }
/* Make sure size doesnt go beyond threshold */
if (diag_max_reg > diag_threshold_reg) {
diag_max_reg = diag_threshold_reg;
pr_info("diag: best case memory allocation\n");
}
+ if (UINT32_MAX/sizeof(struct diag_master_table) <
+ diag_max_reg) {
+ pr_warning("diag: integer overflow\n");
+ kfree(head_params);
+ mutex_unlock(&driver->diagchar_mutex);
+ return -EFAULT;
+ }
temp_buf = krealloc(driver->table,
diag_max_reg*sizeof(struct
diag_master_table), GFP_KERNEL);
if (!temp_buf) {
- diag_max_reg -= pkt_params->count -
- count_entries;
- pr_alert("diag: Insufficient memory for reg.");
+ pr_alert("diag: Insufficient memory for reg.\n");
mutex_unlock(&driver->diagchar_mutex);
+
+ if (pkt_params.count >= count_entries) {
+ interim_count = pkt_params.count -
+ count_entries;
+ } else {
+ pr_warning("diag: params count error\n");
+ mutex_unlock(&driver->diagchar_mutex);
+ kfree(head_params);
+ return -EFAULT;
+ }
+ if (diag_max_reg >= interim_count) {
+ diag_max_reg -= interim_count;
+ } else {
+ pr_warning("diag: Integer underflow\n");
+ mutex_unlock(&driver->diagchar_mutex);
+ kfree(head_params);
+ return -EFAULT;
+ }
+ kfree(head_params);
return 0;
} else {
driver->table = temp_buf;
}
for (j = i; j < diag_max_reg; j++) {
- diag_add_reg(j, pkt_params->params,
- &success, &count_entries);
- if (pkt_params->count > count_entries) {
- pkt_params->params++;
+ diag_add_reg(j, params, &success,
+ &count_entries);
+ if (pkt_params.count > count_entries) {
+ params++;
} else {
mutex_unlock(&driver->diagchar_mutex);
+ kfree(head_params);
return success;
}
}
+ kfree(head_params);
mutex_unlock(&driver->diagchar_mutex);
} else {
mutex_unlock(&driver->diagchar_mutex);
+ kfree(head_params);
pr_err("Max size reached, Pkt Registration failed for"
" Process %d", current->tgid);
}
success = 0;
} else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) {
- struct diagpkt_delay_params *delay_params =
- (struct diagpkt_delay_params *) ioarg;
-
- if ((delay_params->rsp_ptr) &&
- (delay_params->size == sizeof(delayed_rsp_id)) &&
- (delay_params->num_bytes_ptr)) {
- *((uint16_t *)delay_params->rsp_ptr) =
- DIAGPKT_NEXT_DELAYED_RSP_ID(delayed_rsp_id);
- *(delay_params->num_bytes_ptr) = sizeof(delayed_rsp_id);
+ struct diagpkt_delay_params delay_params;
+ uint16_t interim_rsp_id;
+ int interim_size;
+ if (copy_from_user(&delay_params, (void *)ioarg,
+ sizeof(struct diagpkt_delay_params)))
+ return -EFAULT;
+ if ((delay_params.rsp_ptr) &&
+ (delay_params.size == sizeof(delayed_rsp_id)) &&
+ (delay_params.num_bytes_ptr)) {
+ interim_rsp_id = DIAGPKT_NEXT_DELAYED_RSP_ID(
+ delayed_rsp_id);
+ if (copy_to_user((void *)delay_params.rsp_ptr,
+ &interim_rsp_id, sizeof(uint16_t)))
+ return -EFAULT;
+ interim_size = sizeof(delayed_rsp_id);
+ if (copy_to_user((void *)delay_params.num_bytes_ptr,
+ &interim_size, sizeof(int)))
+ return -EFAULT;
success = 0;
}
} else if (iocmd == DIAG_IOCTL_DCI_REG) {
@@ -479,7 +553,13 @@
return DIAG_DCI_NO_REG;
if (driver->num_dci_client >= MAX_DCI_CLIENTS)
return DIAG_DCI_NO_REG;
- if (copy_from_user(params, (void *)ioarg,
+ dci_params = kzalloc(sizeof(struct diag_dci_client_tbl),
+ GFP_KERNEL);
+ if (dci_params == NULL) {
+ pr_err("diag: unable to alloc memory\n");
+ return -ENOMEM;
+ }
+ if (copy_from_user(dci_params, (void *)ioarg,
sizeof(struct diag_dci_client_tbl)))
return -EFAULT;
mutex_lock(&driver->dci_mutex);
@@ -492,9 +572,9 @@
if (driver->dci_client_tbl[i].client == NULL) {
driver->dci_client_tbl[i].client = current;
driver->dci_client_tbl[i].list =
- params->list;
+ dci_params->list;
driver->dci_client_tbl[i].signal_type =
- params->signal_type;
+ dci_params->signal_type;
create_dci_log_mask_tbl(driver->
dci_client_tbl[i].dci_log_mask);
create_dci_event_mask_tbl(driver->
@@ -512,6 +592,7 @@
}
}
mutex_unlock(&driver->dci_mutex);
+ kfree(dci_params);
return driver->dci_client_id;
} else if (iocmd == DIAG_IOCTL_DCI_DEINIT) {
success = -1;
@@ -536,25 +617,29 @@
} else if (iocmd == DIAG_IOCTL_DCI_SUPPORT) {
if (driver->ch_dci)
support_list = support_list | DIAG_CON_MPSS;
- *(uint16_t *)ioarg = support_list;
+ if (copy_to_user((void *)ioarg, &support_list,
+ sizeof(uint16_t)))
+ return -EFAULT;
return DIAG_DCI_NO_ERROR;
} else if (iocmd == DIAG_IOCTL_DCI_HEALTH_STATS) {
if (copy_from_user(&stats, (void *)ioarg,
sizeof(struct diag_dci_health_stats)))
return -EFAULT;
for (i = 0; i < MAX_DCI_CLIENTS; i++) {
- params = &(driver->dci_client_tbl[i]);
- if (params->client &&
- params->client->tgid == current->tgid) {
- stats.dropped_logs = params->dropped_logs;
- stats.dropped_events = params->dropped_events;
- stats.received_logs = params->received_logs;
- stats.received_events = params->received_events;
+ dci_params = &(driver->dci_client_tbl[i]);
+ if (dci_params->client &&
+ dci_params->client->tgid == current->tgid) {
+ stats.dropped_logs = dci_params->dropped_logs;
+ stats.dropped_events =
+ dci_params->dropped_events;
+ stats.received_logs = dci_params->received_logs;
+ stats.received_events =
+ dci_params->received_events;
if (stats.reset_status) {
- params->dropped_logs = 0;
- params->dropped_events = 0;
- params->received_logs = 0;
- params->received_events = 0;
+ dci_params->dropped_logs = 0;
+ dci_params->dropped_events = 0;
+ dci_params->received_logs = 0;
+ dci_params->received_events = 0;
}
break;
}
@@ -567,7 +652,7 @@
for (i = 0; i < driver->num_clients; i++)
if (driver->client_map[i].pid == current->tgid)
break;
- if (i == -1)
+ if (i == driver->num_clients)
return -EINVAL;
driver->data_ready[i] |= DEINIT_TYPE;
wake_up_interruptible(&driver->wait_q);
@@ -1068,7 +1153,7 @@
struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
void *buf_copy = NULL;
- int payload_size;
+ unsigned int payload_size;
#ifdef CONFIG_DIAG_OVER_USB
if (((driver->logging_mode == USB_MODE) && (!driver->usb_connected)) ||
(driver->logging_mode == NO_LOGGING_MODE)) {
@@ -1079,8 +1164,17 @@
/* Get the packet type F3/log/event/Pkt response */
err = copy_from_user((&pkt_type), buf, 4);
/* First 4 bytes indicate the type of payload - ignore these */
+ if (count < 4) {
+ pr_err("diag: Client sending short data\n");
+ return -EBADMSG;
+ }
payload_size = count - 4;
-
+ if (payload_size > USER_SPACE_DATA) {
+ pr_err("diag: Dropping packet, packet payload size crosses 8KB limit. Current payload size %d\n",
+ payload_size);
+ driver->dropped_count++;
+ return -EBADMSG;
+ }
if (pkt_type == DCI_DATA_TYPE) {
err = copy_from_user(driver->user_space_data, buf + 4,
payload_size);
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index 20f84d6..8699178 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -616,18 +616,15 @@
if (end < start)
goto out;
- down_read(&mm->mmap_sem);
vma = find_vma(mm, start);
if (vma && vma->vm_start < end) {
if (start < vma->vm_start)
- goto out_up;
+ goto out;
if (end > vma->vm_end)
- goto out_up;
+ goto out;
ret = 0;
}
-out_up:
- up_read(&mm->mmap_sem);
out:
return ret;
}
@@ -645,20 +642,12 @@
unsigned long start, end;
struct ion_handle *handle = NULL;
int ret;
+ struct mm_struct *mm = current->active_mm;
if (copy_from_user(&data, (void __user *)arg,
sizeof(struct ion_flush_data)))
return -EFAULT;
- start = (unsigned long) data.vaddr;
- end = (unsigned long) data.vaddr + data.length;
-
- if (check_vaddr_bounds(start, end)) {
- pr_err("%s: virtual address %p is out of bounds\n",
- __func__, data.vaddr);
- return -EINVAL;
- }
-
if (!data.handle) {
handle = ion_import_dma_buf(client, data.fd);
if (IS_ERR(handle)) {
@@ -668,11 +657,27 @@
}
}
+ down_read(&mm->mmap_sem);
+
+ start = (unsigned long) data.vaddr;
+ end = (unsigned long) data.vaddr + data.length;
+
+ if (check_vaddr_bounds(start, end)) {
+ up_read(&mm->mmap_sem);
+ pr_err("%s: virtual address %p is out of bounds\n",
+ __func__, data.vaddr);
+ if (!data.handle)
+ ion_free(client, handle);
+ return -EINVAL;
+ }
+
ret = ion_do_cache_op(client,
data.handle ? data.handle : handle,
data.vaddr, data.offset, data.length,
cmd);
+ up_read(&mm->mmap_sem);
+
if (!data.handle)
ion_free(client, handle);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index ca2ad19..c040bf3 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -193,6 +193,52 @@
}
EXPORT_SYMBOL(kgsl_cancel_events);
+int kgsl_memfree_hist_init(void)
+{
+ void *base;
+
+ base = kzalloc(KGSL_MEMFREE_HIST_SIZE, GFP_KERNEL);
+ kgsl_driver.memfree_hist.base_hist_rb = base;
+ if (base == NULL)
+ return -ENOMEM;
+ kgsl_driver.memfree_hist.size = KGSL_MEMFREE_HIST_SIZE;
+ kgsl_driver.memfree_hist.wptr = base;
+ return 0;
+}
+
+void kgsl_memfree_hist_exit(void)
+{
+ kfree(kgsl_driver.memfree_hist.base_hist_rb);
+ kgsl_driver.memfree_hist.base_hist_rb = NULL;
+}
+
+void kgsl_memfree_hist_set_event(unsigned int pid, unsigned int gpuaddr,
+ unsigned int size, int flags)
+{
+ struct kgsl_memfree_hist_elem *p;
+
+ void *base = kgsl_driver.memfree_hist.base_hist_rb;
+ int rbsize = kgsl_driver.memfree_hist.size;
+
+ if (base == NULL)
+ return;
+
+ mutex_lock(&kgsl_driver.memfree_hist_mutex);
+ p = kgsl_driver.memfree_hist.wptr;
+ p->pid = pid;
+ p->gpuaddr = gpuaddr;
+ p->size = size;
+ p->flags = flags;
+
+ kgsl_driver.memfree_hist.wptr++;
+ if ((void *)kgsl_driver.memfree_hist.wptr >= base+rbsize) {
+ kgsl_driver.memfree_hist.wptr =
+ (struct kgsl_memfree_hist_elem *)base;
+ }
+ mutex_unlock(&kgsl_driver.memfree_hist_mutex);
+}
+
+
/* kgsl_get_mem_entry - get the mem_entry structure for the specified object
* @device - Pointer to the device structure
* @ptbase - the pagetable base of the object
@@ -1359,6 +1405,13 @@
if (entry) {
trace_kgsl_mem_free(entry);
+
+ kgsl_memfree_hist_set_event(
+ entry->priv->pid,
+ entry->memdesc.gpuaddr,
+ entry->memdesc.size,
+ entry->memdesc.flags);
+
kgsl_mem_entry_detach_process(entry);
} else {
KGSL_CORE_ERR("invalid gpuaddr %08x\n", param->gpuaddr);
@@ -2338,6 +2391,8 @@
.process_mutex = __MUTEX_INITIALIZER(kgsl_driver.process_mutex),
.ptlock = __SPIN_LOCK_UNLOCKED(kgsl_driver.ptlock),
.devlock = __MUTEX_INITIALIZER(kgsl_driver.devlock),
+ .memfree_hist_mutex =
+ __MUTEX_INITIALIZER(kgsl_driver.memfree_hist_mutex),
};
EXPORT_SYMBOL(kgsl_driver);
@@ -2668,6 +2723,7 @@
kgsl_driver.class = NULL;
}
+ kgsl_memfree_hist_exit();
unregister_chrdev_region(kgsl_driver.major, KGSL_DEVICE_MAX);
}
@@ -2739,6 +2795,9 @@
goto err;
}
+ if (kgsl_memfree_hist_init())
+ KGSL_CORE_ERR("failed to init memfree_hist");
+
return 0;
err:
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 17a5b67..d22cb6d 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -71,6 +71,23 @@
#define KGSL_STATS_ADD(_size, _stat, _max) \
do { _stat += (_size); if (_stat > _max) _max = _stat; } while (0)
+
+#define KGSL_MEMFREE_HIST_SIZE ((int)(PAGE_SIZE * 2))
+
+struct kgsl_memfree_hist_elem {
+ unsigned int pid;
+ unsigned int gpuaddr;
+ unsigned int size;
+ unsigned int flags;
+};
+
+struct kgsl_memfree_hist {
+ void *base_hist_rb;
+ unsigned int size;
+ struct kgsl_memfree_hist_elem *wptr;
+};
+
+
struct kgsl_device;
struct kgsl_driver {
@@ -98,6 +115,9 @@
void *ptpool;
+ struct mutex memfree_hist_mutex;
+ struct kgsl_memfree_hist memfree_hist;
+
struct {
unsigned int vmalloc;
unsigned int vmalloc_max;
diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c
index f731cfc..07a5ff4 100644
--- a/drivers/gpu/msm/kgsl_debugfs.c
+++ b/drivers/gpu/msm/kgsl_debugfs.c
@@ -106,6 +106,52 @@
KGSL_DEBUGFS_LOG(mem_log);
KGSL_DEBUGFS_LOG(pwr_log);
+static int memfree_hist_print(struct seq_file *s, void *unused)
+{
+ void *base = kgsl_driver.memfree_hist.base_hist_rb;
+
+ struct kgsl_memfree_hist_elem *wptr = kgsl_driver.memfree_hist.wptr;
+ struct kgsl_memfree_hist_elem *p;
+ char str[16];
+
+ seq_printf(s, "%8s %8s %8s %11s\n",
+ "pid", "gpuaddr", "size", "flags");
+
+ mutex_lock(&kgsl_driver.memfree_hist_mutex);
+ p = wptr;
+ for (;;) {
+ kgsl_get_memory_usage(str, sizeof(str), p->flags);
+ /*
+ * if the ring buffer is not filled up yet
+ * all its empty elems have size==0
+ * just skip them ...
+ */
+ if (p->size)
+ seq_printf(s, "%8d %08x %8d %11s\n",
+ p->pid, p->gpuaddr, p->size, str);
+ p++;
+ if ((void *)p >= base + kgsl_driver.memfree_hist.size)
+ p = (struct kgsl_memfree_hist_elem *) base;
+
+ if (p == kgsl_driver.memfree_hist.wptr)
+ break;
+ }
+ mutex_unlock(&kgsl_driver.memfree_hist_mutex);
+ return 0;
+}
+
+static int memfree_hist_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, memfree_hist_print, inode->i_private);
+}
+
+static const struct file_operations memfree_hist_fops = {
+ .open = memfree_hist_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
void kgsl_device_debugfs_init(struct kgsl_device *device)
{
if (kgsl_debugfs_dir && !IS_ERR(kgsl_debugfs_dir))
@@ -131,6 +177,8 @@
&mem_log_fops);
debugfs_create_file("log_level_pwr", 0644, device->d_debugfs, device,
&pwr_log_fops);
+ debugfs_create_file("memfree_history", 0444, device->d_debugfs, device,
+ &memfree_hist_fops);
/* Create postmortem dump control files */
diff --git a/drivers/input/misc/lis3dh_acc.c b/drivers/input/misc/lis3dh_acc.c
index af96d3f..cc4ee9f 100644
--- a/drivers/input/misc/lis3dh_acc.c
+++ b/drivers/input/misc/lis3dh_acc.c
@@ -1086,26 +1086,26 @@
static struct device_attribute attributes[] = {
- __ATTR(pollrate_ms, 0666, attr_get_polling_rate,
+ __ATTR(pollrate_ms, 0664, attr_get_polling_rate,
attr_set_polling_rate),
- __ATTR(range, 0666, attr_get_range, attr_set_range),
- __ATTR(enable, 0666, attr_get_enable, attr_set_enable),
- __ATTR(int1_config, 0666, attr_get_intconfig1, attr_set_intconfig1),
- __ATTR(int1_duration, 0666, attr_get_duration1, attr_set_duration1),
- __ATTR(int1_threshold, 0666, attr_get_thresh1, attr_set_thresh1),
+ __ATTR(range, 0664, attr_get_range, attr_set_range),
+ __ATTR(enable, 0664, attr_get_enable, attr_set_enable),
+ __ATTR(int1_config, 0664, attr_get_intconfig1, attr_set_intconfig1),
+ __ATTR(int1_duration, 0664, attr_get_duration1, attr_set_duration1),
+ __ATTR(int1_threshold, 0664, attr_get_thresh1, attr_set_thresh1),
__ATTR(int1_source, 0444, attr_get_source1, NULL),
- __ATTR(click_config, 0666, attr_get_click_cfg, attr_set_click_cfg),
+ __ATTR(click_config, 0664, attr_get_click_cfg, attr_set_click_cfg),
__ATTR(click_source, 0444, attr_get_click_source, NULL),
- __ATTR(click_threshold, 0666, attr_get_click_ths, attr_set_click_ths),
- __ATTR(click_timelimit, 0666, attr_get_click_tlim,
+ __ATTR(click_threshold, 0664, attr_get_click_ths, attr_set_click_ths),
+ __ATTR(click_timelimit, 0664, attr_get_click_tlim,
attr_set_click_tlim),
- __ATTR(click_timelatency, 0666, attr_get_click_tlat,
+ __ATTR(click_timelatency, 0664, attr_get_click_tlat,
attr_set_click_tlat),
- __ATTR(click_timewindow, 0666, attr_get_click_tw, attr_set_click_tw),
+ __ATTR(click_timewindow, 0664, attr_get_click_tw, attr_set_click_tw),
#ifdef DEBUG
- __ATTR(reg_value, 0666, attr_reg_get, attr_reg_set),
- __ATTR(reg_addr, 0222, NULL, attr_addr_set),
+ __ATTR(reg_value, 0664, attr_reg_get, attr_reg_set),
+ __ATTR(reg_addr, 0220, NULL, attr_addr_set),
#endif
};
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c
index 04a7598..db6f93c 100644
--- a/drivers/input/misc/mpu3050.c
+++ b/drivers/input/misc/mpu3050.c
@@ -288,7 +288,7 @@
static struct device_attribute attributes[] = {
- __ATTR(pollrate_ms, 0666,
+ __ATTR(pollrate_ms, 0664,
mpu3050_attr_get_polling_rate,
mpu3050_attr_set_polling_rate),
};
diff --git a/drivers/iommu/msm_iommu-v2.c b/drivers/iommu/msm_iommu-v2.c
index 9d88fdd..425eb8a 100644
--- a/drivers/iommu/msm_iommu-v2.c
+++ b/drivers/iommu/msm_iommu-v2.c
@@ -148,6 +148,9 @@
return ret;
}
+/*
+ * May only be called for non-secure iommus
+ */
static void __reset_iommu(void __iomem *base)
{
int i, smt_size;
@@ -170,6 +173,9 @@
mb();
}
+/*
+ * May only be called for non-secure iommus
+ */
static void __program_iommu(void __iomem *base,
struct msm_iommu_bfb_settings *bfb_settings)
{
@@ -223,14 +229,14 @@
static void __program_context(void __iomem *base, int ctx, int ncb,
phys_addr_t pgtable, int redirect,
- u32 *sids, int len)
+ u32 *sids, int len, bool is_secure)
{
unsigned int prrr, nmrr;
unsigned int pn;
int i, j, found, num = 0, smt_size;
__reset_context(base, ctx);
- smt_size = GET_IDR0_NUMSMRG(base);
+
pn = pgtable >> CB_TTBR0_ADDR_SHIFT;
SET_TTBCR(base, ctx, 0);
SET_CB_TTBR0_ADDR(base, ctx, pn);
@@ -266,41 +272,44 @@
SET_CB_TTBR0_RGN(base, ctx, 1); /* WB, WA */
}
- /* Program the M2V tables for this context */
- for (i = 0; i < len / sizeof(*sids); i++) {
- for (; num < smt_size; num++)
- if (GET_SMR_VALID(base, num) == 0)
- break;
- BUG_ON(num >= smt_size);
+ if (!is_secure) {
+ smt_size = GET_IDR0_NUMSMRG(base);
+ /* Program the M2V tables for this context */
+ for (i = 0; i < len / sizeof(*sids); i++) {
+ for (; num < smt_size; num++)
+ if (GET_SMR_VALID(base, num) == 0)
+ break;
+ BUG_ON(num >= smt_size);
- SET_SMR_VALID(base, num, 1);
- SET_SMR_MASK(base, num, 0);
- SET_SMR_ID(base, num, sids[i]);
+ SET_SMR_VALID(base, num, 1);
+ SET_SMR_MASK(base, num, 0);
+ SET_SMR_ID(base, num, sids[i]);
- SET_S2CR_N(base, num, 0);
- SET_S2CR_CBNDX(base, num, ctx);
- SET_S2CR_MEMATTR(base, num, 0x0A);
- /* Set security bit override to be Non-secure */
- SET_S2CR_NSCFG(base, num, 3);
+ SET_S2CR_N(base, num, 0);
+ SET_S2CR_CBNDX(base, num, ctx);
+ SET_S2CR_MEMATTR(base, num, 0x0A);
+ /* Set security bit override to be Non-secure */
+ SET_S2CR_NSCFG(base, num, 3);
+ }
+ SET_CBAR_N(base, ctx, 0);
+
+ /* Stage 1 Context with Stage 2 bypass */
+ SET_CBAR_TYPE(base, ctx, 1);
+
+ /* Route page faults to the non-secure interrupt */
+ SET_CBAR_IRPTNDX(base, ctx, 1);
+
+ /* Set VMID to non-secure HLOS */
+ SET_CBAR_VMID(base, ctx, 3);
+
+ /* Bypass is treated as inner-shareable */
+ SET_CBAR_BPSHCFG(base, ctx, 2);
+
+ /* Do not downgrade memory attributes */
+ SET_CBAR_MEMATTR(base, ctx, 0x0A);
+
}
- SET_CBAR_N(base, ctx, 0);
-
- /* Stage 1 Context with Stage 2 bypass */
- SET_CBAR_TYPE(base, ctx, 1);
-
- /* Route page faults to the non-secure interrupt */
- SET_CBAR_IRPTNDX(base, ctx, 1);
-
- /* Set VMID to non-secure HLOS */
- SET_CBAR_VMID(base, ctx, 3);
-
- /* Bypass is treated as inner-shareable */
- SET_CBAR_BPSHCFG(base, ctx, 2);
-
- /* Do not downgrade memory attributes */
- SET_CBAR_MEMATTR(base, ctx, 0x0A);
-
/* Find if this page table is used elsewhere, and re-use ASID */
found = 0;
for (i = 0; i < ncb; i++)
@@ -399,6 +408,7 @@
struct msm_iommu_ctx_drvdata *ctx_drvdata;
struct msm_iommu_ctx_drvdata *tmp_drvdata;
int ret;
+ int is_secure;
mutex_lock(&msm_iommu_lock);
@@ -426,6 +436,8 @@
goto fail;
}
+ is_secure = iommu_drvdata->sec_id != -1;
+
ret = regulator_enable(iommu_drvdata->gdsc);
if (ret)
goto fail;
@@ -436,13 +448,25 @@
goto fail;
}
- if (!msm_iommu_ctx_attached(dev->parent))
- __program_iommu(iommu_drvdata->base,
+ if (!msm_iommu_ctx_attached(dev->parent)) {
+ if (!is_secure) {
+ __program_iommu(iommu_drvdata->base,
iommu_drvdata->bfb_settings);
+ } else {
+ ret = msm_iommu_sec_program_iommu(
+ iommu_drvdata->sec_id);
+ if (ret) {
+ regulator_disable(iommu_drvdata->gdsc);
+ __disable_clocks(iommu_drvdata);
+ goto fail;
+ }
+ }
+ }
__program_context(iommu_drvdata->base, ctx_drvdata->num,
iommu_drvdata->ncb, __pa(priv->pt.fl_table),
- priv->pt.redirect, ctx_drvdata->sids, ctx_drvdata->nsid);
+ priv->pt.redirect, ctx_drvdata->sids, ctx_drvdata->nsid,
+ is_secure);
__disable_clocks(iommu_drvdata);
list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
@@ -460,6 +484,7 @@
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
int ret;
+ int is_secure;
mutex_lock(&msm_iommu_lock);
priv = domain->priv;
@@ -475,11 +500,14 @@
if (ret)
goto fail;
+ is_secure = iommu_drvdata->sec_id != -1;
+
SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num,
GET_CB_CONTEXTIDR_ASID(iommu_drvdata->base, ctx_drvdata->num));
__reset_context(iommu_drvdata->base, ctx_drvdata->num);
- __release_smg(iommu_drvdata->base, ctx_drvdata->num);
+ if (!is_secure)
+ __release_smg(iommu_drvdata->base, ctx_drvdata->num);
__disable_clocks(iommu_drvdata);
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index a89c4a8..72ec4a6 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -128,7 +128,7 @@
return ret;
}
-static int msm_iommu_sec_program_iommu(int sec_id)
+int msm_iommu_sec_program_iommu(int sec_id)
{
struct msm_scm_sec_cfg {
unsigned int id;
diff --git a/drivers/media/video/msm_vidc/msm_smem.c b/drivers/media/video/msm_vidc/msm_smem.c
index 3dd2193..83f33a1 100644
--- a/drivers/media/video/msm_vidc/msm_smem.c
+++ b/drivers/media/video/msm_vidc/msm_smem.c
@@ -24,7 +24,7 @@
static int get_device_address(struct ion_client *clnt,
struct ion_handle *hndl, int domain_num, int partition_num,
unsigned long align, unsigned long *iova,
- unsigned long *buffer_size)
+ unsigned long *buffer_size, int flags)
{
int rc;
if (!iova || !buffer_size || !hndl || !clnt) {
@@ -36,25 +36,39 @@
align = 4096;
dprintk(VIDC_DBG, "domain: %d, partition: %d\n",
domain_num, partition_num);
+ if (flags & SMEM_SECURE) {
+ if (flags & SMEM_INPUT)
+ rc = msm_ion_secure_buffer(clnt, hndl, 0x1, 0);
+ else
+ rc = msm_ion_secure_buffer(clnt, hndl, 0x2, 0);
+ if (rc) {
+ dprintk(VIDC_ERR, "Failed to secure memory\n");
+ goto mem_secure_failed;
+ }
+ }
rc = ion_map_iommu(clnt, hndl, domain_num, partition_num, align,
0, iova, buffer_size, 0, 0);
if (rc)
dprintk(VIDC_ERR,
"ion_map_iommu failed(%d).domain: %d,partition: %d\n",
rc, domain_num, partition_num);
-
+mem_secure_failed:
return rc;
}
static void put_device_address(struct ion_client *clnt,
- struct ion_handle *hndl, int domain_num, int partition_num)
+ struct ion_handle *hndl, int domain_num, int partition_num, int flags)
{
ion_unmap_iommu(clnt, hndl, domain_num, partition_num);
+ if (flags & SMEM_SECURE) {
+ if (msm_ion_unsecure_buffer(clnt, hndl))
+ dprintk(VIDC_ERR, "Failed to unsecure memory\n");
+ }
}
static int ion_user_to_kernel(struct smem_client *client,
int fd, u32 offset, int domain, int partition,
- struct msm_smem *mem)
+ struct msm_smem *mem, int flags)
{
struct ion_handle *hndl;
unsigned long iova = 0;
@@ -70,8 +84,9 @@
mem->kvaddr = NULL;
mem->domain = domain;
mem->partition_num = partition;
+ mem->flags = flags;
rc = get_device_address(client->clnt, hndl, mem->domain,
- mem->partition_num, 4096, &iova, &buffer_size);
+ mem->partition_num, 4096, &iova, &buffer_size, flags);
if (rc) {
dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc);
goto fail_device_address;
@@ -101,11 +116,16 @@
unsigned long ionflags = 0;
unsigned long heap_mask = 0;
int rc = 0;
- if (flags == SMEM_CACHED)
+ if (flags & SMEM_CACHED)
ionflags = ION_SET_CACHED(ionflags);
else
ionflags = ION_SET_UNCACHED(ionflags);
+ if (flags & SMEM_SECURE) {
+ ionflags |= ION_SECURE;
+ size = (size + 0xfffff) & (~0xfffff);
+ }
+
heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
if (align < 4096)
align = 4096;
@@ -124,6 +144,7 @@
mem->smem_priv = hndl;
mem->domain = domain;
mem->partition_num = partition;
+ mem->flags = flags;
if (map_kernel) {
mem->kvaddr = ion_map_kernel(client->clnt, hndl);
if (!mem->kvaddr) {
@@ -136,7 +157,7 @@
mem->kvaddr = NULL;
rc = get_device_address(client->clnt, hndl, mem->domain,
- mem->partition_num, align, &iova, &buffer_size);
+ mem->partition_num, align, &iova, &buffer_size, flags);
if (rc) {
dprintk(VIDC_ERR, "Failed to get device address: %d\n",
rc);
@@ -160,7 +181,8 @@
{
if (mem->device_addr)
put_device_address(client->clnt,
- mem->smem_priv, mem->domain, mem->partition_num);
+ mem->smem_priv, mem->domain,
+ mem->partition_num, mem->flags);
if (mem->kvaddr)
ion_unmap_kernel(client->clnt, mem->smem_priv);
if (mem->smem_priv)
@@ -182,7 +204,7 @@
}
struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset,
- int domain, int partition)
+ int domain, int partition, int flags)
{
struct smem_client *client = clt;
int rc = 0;
@@ -199,7 +221,7 @@
switch (client->mem_type) {
case SMEM_ION:
rc = ion_user_to_kernel(clt, fd, offset,
- domain, partition, mem);
+ domain, partition, mem, flags);
break;
default:
dprintk(VIDC_ERR, "Mem type not supported\n");
diff --git a/drivers/media/video/msm_vidc/msm_smem.h b/drivers/media/video/msm_vidc/msm_smem.h
index c109abd..8241fdd 100644
--- a/drivers/media/video/msm_vidc/msm_smem.h
+++ b/drivers/media/video/msm_vidc/msm_smem.h
@@ -20,9 +20,10 @@
SMEM_ION,
};
-enum smem_cache_prop {
- SMEM_CACHED,
- SMEM_UNCACHED,
+enum smem_prop {
+ SMEM_CACHED = 0x1,
+ SMEM_SECURE = 0x2,
+ SMEM_INPUT = 0x4,
};
struct msm_smem {
@@ -32,6 +33,7 @@
unsigned long device_addr;
int domain;
int partition_num;
+ int flags;
void *smem_priv;
};
@@ -41,6 +43,6 @@
void msm_smem_free(void *clt, struct msm_smem *mem);
void msm_smem_delete_client(void *clt);
struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, int
- domain, int partition);
+ domain, int partition, int flags);
int msm_smem_clean_invalidate(void *clt, struct msm_smem *mem);
#endif
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
index 912fad4..4f2373e 100644
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -756,6 +756,8 @@
struct msm_v4l2_vid_inst *v4l2_inst;
int plane = 0;
int i, rc = 0;
+ int smem_flags = 0;
+ int domain;
vidc_inst = get_vidc_inst(file, fh);
v4l2_inst = get_v4l2_inst(file, fh);
if (!v4l2_inst->mem_client) {
@@ -776,6 +778,7 @@
goto exit;
}
for (i = 0; i < b->length; ++i) {
+ smem_flags = 0;
if (EXTRADATA_IDX(b->length) &&
(i == EXTRADATA_IDX(b->length)) &&
!b->m.planes[i].length) {
@@ -792,8 +795,22 @@
kfree(binfo);
goto exit;
}
+ if ((vidc_inst->mode == VIDC_SECURE)
+ && (!EXTRADATA_IDX(b->length)
+ || (i != EXTRADATA_IDX(b->length)))) {
+ smem_flags |= SMEM_SECURE;
+ domain =
+ vidc_inst->core->resources.io_map[CP_MAP].domain;
+ } else
+ domain =
+ vidc_inst->core->resources.io_map[NS_MAP].domain;
+
+ if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ smem_flags |= SMEM_INPUT;
+
temp = get_same_fd_buffer(&v4l2_inst->registered_bufs,
b->m.planes[i].reserved[0], &plane);
+
if (temp) {
binfo->type = b->type;
binfo->fd[i] = b->m.planes[i].reserved[0];
@@ -807,8 +824,7 @@
handle = msm_smem_user_to_kernel(v4l2_inst->mem_client,
b->m.planes[i].reserved[0],
b->m.planes[i].reserved[1],
- vidc_inst->core->resources.io_map[NS_MAP].domain,
- 0);
+ domain, 0, smem_flags);
if (!handle) {
dprintk(VIDC_ERR,
"Failed to get device buffer address\n");
@@ -1119,9 +1135,11 @@
- SHARED_QSIZE;
partition[1].size = SHARED_QSIZE;
layout.npartitions = 2;
+ layout.is_secure = 0;
} else {
partition[0].size = io_map[i].addr_range[1];
layout.npartitions = 1;
+ layout.is_secure = 1;
}
layout.partitions = &partition[0];
layout.client_name = io_map[i].name;
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index 22063d4..c4bfaf4 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -156,7 +156,15 @@
.minimum = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_DISABLE,
.maximum = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE,
.default_value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_DISABLE,
- .step = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE,
+ .name = "Secure mode",
+ .type = V4L2_CTRL_TYPE_BUTTON,
+ .minimum = 0,
+ .maximum = 0,
+ .default_value = 0,
+ .step = 0,
.menu_skip_mask = 0,
.qmenu = NULL,
},
@@ -518,6 +526,9 @@
fmt->get_frame_size(i,
f->fmt.pix_mp.height,
f->fmt.pix_mp.width);
+ inst->bufq[OUTPUT_PORT].
+ vb2_bufq.plane_sizes[i] =
+ f->fmt.pix_mp.plane_fmt[i].sizeimage;
}
} else {
f->fmt.pix_mp.plane_fmt[0].sizeimage =
@@ -527,6 +538,11 @@
f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
inst->buff_req.buffer[HAL_BUFFER_EXTRADATA_OUTPUT].buffer_size;
}
+ for (i = 0; i < fmt->num_planes; ++i)
+ inst->bufq[CAPTURE_PORT].
+ vb2_bufq.plane_sizes[i] =
+ f->fmt.pix_mp.plane_fmt[i].sizeimage;
+
}
} else {
dprintk(VIDC_ERR,
@@ -624,6 +640,10 @@
}
}
f->fmt.pix_mp.num_planes = fmt->num_planes;
+ for (i = 0; i < fmt->num_planes; ++i) {
+ inst->bufq[CAPTURE_PORT].vb2_bufq.plane_sizes[i] =
+ f->fmt.pix_mp.plane_fmt[i].sizeimage;
+ }
} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
inst->prop.width = f->fmt.pix_mp.width;
inst->prop.height = f->fmt.pix_mp.height;
@@ -652,6 +672,10 @@
fmt->get_frame_size(0, f->fmt.pix_mp.height,
f->fmt.pix_mp.width);
f->fmt.pix_mp.num_planes = fmt->num_planes;
+ for (i = 0; i < fmt->num_planes; ++i) {
+ inst->bufq[OUTPUT_PORT].vb2_bufq.plane_sizes[i] =
+ f->fmt.pix_mp.plane_fmt[i].sizeimage;
+ }
}
err_invalid_fmt:
return rc;
@@ -933,7 +957,8 @@
case V4L2_DEC_CMD_STOP:
rc = msm_comm_release_scratch_buffers(inst);
if (rc)
- pr_err("Failed to release scratch buffers: %d\n", rc);
+ dprintk(VIDC_ERR,
+ "Failed to release scratch buffers: %d\n", rc);
rc = msm_comm_release_persist_buffers(inst);
if (rc)
pr_err("Failed to release persist buffers: %d\n", rc);
@@ -1002,17 +1027,8 @@
void *pdata;
struct msm_vidc_inst *inst = container_of(ctrl->handler,
struct msm_vidc_inst, ctrl_handler);
- rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
-
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to move inst: %p to start done state\n", inst);
- goto failed_open_done;
- }
-
control.id = ctrl->id;
control.value = ctrl->val;
-
switch (control.id) {
case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT:
property_id =
@@ -1067,10 +1083,20 @@
hal_property.enable = control.value;
pdata = &hal_property;
break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_SECURE:
+ inst->mode = VIDC_SECURE;
+ dprintk(VIDC_DBG, "Setting secure mode to :%d\n", inst->mode);
+ break;
default:
break;
- }
+ }
if (property_id) {
+ rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to move inst: %p to start done state\n", inst);
+ goto failed_open_done;
+ }
dprintk(VIDC_DBG,
"Control: HAL property=%d,ctrl_id=%d,ctrl_value=%d\n",
property_id,
@@ -1082,9 +1108,7 @@
}
if (rc)
dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
-
failed_open_done:
-
return rc;
}
static int msm_vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index d53da9e..d01841d 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -23,7 +23,6 @@
#define DEFAULT_WIDTH 1280
#define MIN_NUM_OUTPUT_BUFFERS 4
#define MAX_NUM_OUTPUT_BUFFERS 8
-#define MAX_INPUT_BUFFERS 32
#define MIN_BIT_RATE 64000
#define MAX_BIT_RATE 160000000
#define DEFAULT_BIT_RATE 64000
@@ -594,11 +593,11 @@
spin_lock_irqsave(&inst->lock, flags);
*num_buffers = inst->buff_req.buffer[0].buffer_count_actual =
max(*num_buffers, inst->buff_req.buffer[0].
- buffer_count_actual);
+ buffer_count_actual);
spin_unlock_irqrestore(&inst->lock, flags);
property_id = HAL_PARAM_BUFFER_COUNT_ACTUAL;
new_buf_count.buffer_type = HAL_BUFFER_INPUT;
- new_buf_count.buffer_count_actual = MAX_INPUT_BUFFERS;
+ new_buf_count.buffer_count_actual = *num_buffers;
rc = vidc_hal_session_set_property(inst->session,
property_id, &new_buf_count);
dprintk(VIDC_DBG, "size = %d, alignment = %d, count = %d\n",
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
index 1d0124f..64897c7 100644
--- a/drivers/media/video/msm_vidc/msm_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_vidc.c
@@ -413,7 +413,7 @@
inst = kzalloc(sizeof(*inst), GFP_KERNEL);
if (!inst) {
- pr_err("Failed to allocate memory\n") ;
+ dprintk(VIDC_ERR, "Failed to allocate memory\n");
rc = -ENOMEM;
goto err_invalid_core;
}
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 9c81d40..9c7472a 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -18,6 +18,7 @@
#include <mach/iommu.h>
#include <mach/iommu_domains.h>
#include <mach/subsystem_restart.h>
+#include <mach/scm.h>
#include "msm_vidc_common.h"
#include "vidc_hal_api.h"
@@ -50,6 +51,18 @@
__mbs;\
})
+#define TZBSP_MEM_PROTECT_VIDEO_VAR 0x8
+struct tzbsp_memprot {
+ u32 cp_start;
+ u32 cp_size;
+ u32 cp_nonpixel_start;
+ u32 cp_nonpixel_size;
+};
+
+struct tzbsp_resp {
+ int ret;
+};
+
static const u32 bus_table[] = {
0,
36000,
@@ -140,6 +153,31 @@
return rc;
}
+static int protect_cp_mem(struct msm_vidc_core *core)
+{
+ struct tzbsp_memprot memprot;
+ unsigned int resp = 0;
+ int rc = 0;
+ struct msm_vidc_iommu_info *io_map = core->resources.io_map;
+ if (!io_map) {
+ dprintk(VIDC_ERR, "invalid params: %p\n", io_map);
+ return -EINVAL;
+ }
+ memprot.cp_start = 0x0;
+ memprot.cp_size = io_map[CP_MAP].addr_range[0] +
+ io_map[CP_MAP].addr_range[1];
+ memprot.cp_nonpixel_start = 0;
+ memprot.cp_nonpixel_size = 0;
+
+ rc = scm_call(SCM_SVC_CP, TZBSP_MEM_PROTECT_VIDEO_VAR, &memprot,
+ sizeof(memprot), &resp, sizeof(resp));
+ if (rc)
+ dprintk(VIDC_ERR,
+ "Failed to protect memory , rc is :%d, response : %d\n",
+ rc, resp);
+ return rc;
+}
+
struct msm_vidc_core *get_vidc_core(int core_id)
{
struct msm_vidc_core *core;
@@ -924,13 +962,16 @@
rc = -ENOMEM;
goto fail_subsystem_get;
}
-
rc = msm_comm_enable_clks(core);
if (rc) {
dprintk(VIDC_ERR, "Failed to enable clocks: %d\n", rc);
goto fail_enable_clks;
}
-
+ rc = protect_cp_mem(core);
+ if (rc) {
+ dprintk(VIDC_ERR, "Failed to protect memory\n");
+ goto fail_iommu_attach;
+ }
rc = msm_comm_iommu_attach(core);
if (rc) {
dprintk(VIDC_ERR, "Failed to attach iommu");
@@ -953,10 +994,10 @@
return;
}
if (core->resources.fw.cookie) {
- subsystem_put(core->resources.fw.cookie);
- core->resources.fw.cookie = NULL;
msm_comm_iommu_detach(core);
msm_comm_disable_clks(core);
+ subsystem_put(core->resources.fw.cookie);
+ core->resources.fw.cookie = NULL;
}
}
@@ -1431,6 +1472,25 @@
return rc;
}
+static int get_flipped_state(int present_state,
+ int desired_state)
+{
+ int flipped_state = present_state;
+ if (flipped_state < MSM_VIDC_STOP
+ && desired_state > MSM_VIDC_STOP) {
+ flipped_state = MSM_VIDC_STOP + (MSM_VIDC_STOP - flipped_state);
+ flipped_state &= 0xFFFE;
+ flipped_state = flipped_state - 1;
+ } else if (flipped_state > MSM_VIDC_STOP
+ && desired_state < MSM_VIDC_STOP) {
+ flipped_state = MSM_VIDC_STOP -
+ (flipped_state - MSM_VIDC_STOP + 1);
+ flipped_state &= 0xFFFE;
+ flipped_state = flipped_state - 1;
+ }
+ return flipped_state;
+}
+
int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
{
int rc = 0;
@@ -1457,89 +1517,77 @@
"Core is in bad state can't change the state");
goto exit;
}
- flipped_state = inst->state;
- if (flipped_state < MSM_VIDC_STOP
- && state > MSM_VIDC_STOP) {
- flipped_state = MSM_VIDC_STOP + (MSM_VIDC_STOP - flipped_state);
- flipped_state &= 0xFFFE;
- flipped_state = flipped_state - 1;
- } else if (flipped_state > MSM_VIDC_STOP
- && state < MSM_VIDC_STOP) {
- flipped_state = MSM_VIDC_STOP -
- (flipped_state - MSM_VIDC_STOP + 1);
- flipped_state &= 0xFFFE;
- flipped_state = flipped_state - 1;
- }
+ flipped_state = get_flipped_state(inst->state, state);
dprintk(VIDC_DBG,
"flipped_state = 0x%x\n", flipped_state);
switch (flipped_state) {
case MSM_VIDC_CORE_UNINIT_DONE:
case MSM_VIDC_CORE_INIT:
rc = msm_comm_init_core(inst);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_CORE_INIT_DONE:
rc = msm_comm_init_core_done(inst);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_OPEN:
rc = msm_comm_session_init(flipped_state, inst);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_OPEN_DONE:
rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
SESSION_INIT_DONE);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_LOAD_RESOURCES:
rc = msm_vidc_load_resources(flipped_state, inst);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_LOAD_RESOURCES_DONE:
case MSM_VIDC_START:
rc = msm_vidc_start(flipped_state, inst);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_START_DONE:
rc = wait_for_state(inst, flipped_state, MSM_VIDC_START_DONE,
SESSION_START_DONE);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_STOP:
rc = msm_vidc_stop(flipped_state, inst);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_STOP_DONE:
rc = wait_for_state(inst, flipped_state, MSM_VIDC_STOP_DONE,
SESSION_STOP_DONE);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
dprintk(VIDC_DBG, "Moving to Stop Done state\n");
case MSM_VIDC_RELEASE_RESOURCES:
rc = msm_vidc_release_res(flipped_state, inst);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_RELEASE_RESOURCES_DONE:
rc = wait_for_state(inst, flipped_state,
MSM_VIDC_RELEASE_RESOURCES_DONE,
SESSION_RELEASE_RESOURCE_DONE);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
dprintk(VIDC_DBG,
"Moving to release resources done state\n");
case MSM_VIDC_CLOSE:
rc = msm_comm_session_close(flipped_state, inst);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_CLOSE_DONE:
rc = wait_for_state(inst, flipped_state, MSM_VIDC_CLOSE_DONE,
SESSION_END_DONE);
- if (rc || state <= inst->state)
+ if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_CORE_UNINIT:
dprintk(VIDC_DBG, "Sending core uninit\n");
rc = msm_vidc_deinit_core(inst);
- if (rc || state == inst->state)
+ if (rc || state == get_flipped_state(inst->state, state))
break;
default:
dprintk(VIDC_ERR, "State not recognized\n");
@@ -1841,6 +1889,8 @@
struct internal_buf *binfo;
struct vidc_buffer_addr_info buffer_info;
unsigned long flags;
+ int domain;
+ unsigned long smem_flags = 0;
struct hal_buffer_requirements *scratch_buf =
&inst->buff_req.buffer[HAL_BUFFER_INTERNAL_SCRATCH];
int i;
@@ -1850,14 +1900,18 @@
scratch_buf->buffer_size);
if (msm_comm_release_scratch_buffers(inst))
dprintk(VIDC_WARN, "Failed to release scratch buffers\n");
+ if (inst->mode == VIDC_SECURE) {
+ domain = inst->core->resources.io_map[CP_MAP].domain;
+ smem_flags |= SMEM_SECURE;
+ } else
+ domain = inst->core->resources.io_map[NS_MAP].domain;
if (scratch_buf->buffer_size) {
for (i = 0; i < scratch_buf->buffer_count_actual;
i++) {
handle = msm_smem_alloc(inst->mem_client,
- scratch_buf->buffer_size, 1, SMEM_UNCACHED,
- inst->core->resources.io_map[NS_MAP].domain,
- 0, 0);
+ scratch_buf->buffer_size, 1, smem_flags,
+ domain, 0, 0);
if (!handle) {
dprintk(VIDC_ERR,
"Failed to allocate scratch memory\n");
@@ -1903,6 +1957,8 @@
struct internal_buf *binfo;
struct vidc_buffer_addr_info buffer_info;
unsigned long flags;
+ unsigned long smem_flags = 0;
+ int domain;
struct hal_buffer_requirements *persist_buf =
&inst->buff_req.buffer[HAL_BUFFER_INTERNAL_PERSIST];
int i;
@@ -1916,12 +1972,17 @@
return rc;
}
+ if (inst->mode == VIDC_SECURE) {
+ domain = inst->core->resources.io_map[CP_MAP].domain;
+ flags |= SMEM_SECURE;
+ } else
+ domain = inst->core->resources.io_map[NS_MAP].domain;
+
if (persist_buf->buffer_size) {
for (i = 0; i < persist_buf->buffer_count_actual; i++) {
handle = msm_smem_alloc(inst->mem_client,
- persist_buf->buffer_size, 1, SMEM_UNCACHED,
- inst->core->resources.io_map[NS_MAP].domain,
- 0, 0);
+ persist_buf->buffer_size, 1, smem_flags,
+ domain, 0, 0);
if (!handle) {
dprintk(VIDC_ERR,
"Failed to allocate persist memory\n");
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index 8e1a99e..5b2cced 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -210,6 +210,11 @@
bool ssr_in_progress;
};
+enum msm_vidc_mode {
+ VIDC_NON_SECURE,
+ VIDC_SECURE,
+};
+
struct msm_vidc_core {
struct list_head list;
struct mutex sync_lock;
@@ -260,6 +265,7 @@
void *priv;
struct msm_vidc_debug debug;
struct buf_count count;
+ enum msm_vidc_mode mode;
};
extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
index 2a3752f..f44be4d 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ b/drivers/media/video/msm_vidc/vidc_hal.c
@@ -541,7 +541,7 @@
mem_addr = &dev->mem_addr;
rc = vidc_hal_alloc((void *) mem_addr,
dev->hal_client, uc_size, 1,
- SMEM_UNCACHED, domain);
+ 0, domain);
if (rc) {
dprintk(VIDC_ERR, "iface_q_table_alloc_fail");
return -ENOMEM;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index c9c4e70..46015b0 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -35,6 +35,7 @@
#include <linux/elf.h>
#include <linux/firmware.h>
#include <linux/freezer.h>
+#include <linux/scatterlist.h>
#include <mach/board.h>
#include <mach/msm_bus.h>
#include <mach/msm_bus_board.h>
@@ -54,6 +55,8 @@
#define QSEE_CE_CLK_100MHZ 100000000
#define QSEE_CE_CLK_50MHZ 50000000
+#define QSEECOM_MAX_SG_ENTRY 10
+
enum qseecom_command_scm_resp_type {
QSEOS_APP_ID = 0xEE01,
QSEOS_LISTENER_ID
@@ -247,6 +250,11 @@
struct clk *ce_core_src_clk;
struct clk *ce_bus_clk;
+struct qseecom_sg_entry {
+ uint32_t phys_addr;
+ uint32_t len;
+};
+
/* Function proto types */
static int qsee_vote_for_clock(int32_t);
static void qsee_disable_clock_vote(int32_t);
@@ -1093,13 +1101,11 @@
{
struct ion_handle *ihandle;
char *field;
- uint32_t *update;
- ion_phys_addr_t pa;
int ret = 0;
int i = 0;
- uint32_t length;
for (i = 0; i < MAX_ION_FD; i++) {
+ struct sg_table *sg_ptr = NULL;
if (req->ifd_data[i].fd > 0) {
/* Get the handle of the shared fd */
ihandle = ion_import_dma_buf(qseecom.ion_clnt,
@@ -1110,20 +1116,51 @@
}
field = (char *) req->cmd_req_buf +
req->ifd_data[i].cmd_buf_offset;
- update = (uint32_t *) field;
/* Populate the cmd data structure with the phys_addr */
- ret = ion_phys(qseecom.ion_clnt, ihandle, &pa, &length);
- if (ret)
- return -ENOMEM;
-
- *update = (uint32_t)pa;
+ sg_ptr = ion_sg_table(qseecom.ion_clnt, ihandle);
+ if (sg_ptr == NULL) {
+ pr_err("IOn client could not retrieve sg table\n");
+ goto err;
+ }
+ if (sg_ptr->nents == 0) {
+ pr_err("Num of scattered entries is 0\n");
+ goto err;
+ }
+ if (sg_ptr->nents > QSEECOM_MAX_SG_ENTRY) {
+ pr_err("Num of scattered entries");
+ pr_err(" (%d) is greater than max supported %d\n",
+ sg_ptr->nents, QSEECOM_MAX_SG_ENTRY);
+ goto err;
+ }
+ if (sg_ptr->nents == 1) {
+ uint32_t *update;
+ update = (uint32_t *) field;
+ *update = (uint32_t)sg_dma_address(sg_ptr->sgl);
+ } else {
+ struct qseecom_sg_entry *update;
+ struct scatterlist *sg;
+ int j = 0;
+ update = (struct qseecom_sg_entry *) field;
+ sg = sg_ptr->sgl;
+ for (j = 0; j < sg_ptr->nents; j++) {
+ update->phys_addr = (uint32_t)
+ sg_dma_address(sg);
+ update->len = (uint32_t)sg->length;
+ update++;
+ sg = sg_next(sg);
+ }
+ }
/* Deallocate the handle */
if (!IS_ERR_OR_NULL(ihandle))
ion_free(qseecom.ion_clnt, ihandle);
}
}
return ret;
+err:
+ if (!IS_ERR_OR_NULL(ihandle))
+ ion_free(qseecom.ion_clnt, ihandle);
+ return -ENOMEM;
}
static int qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index b34b069..e7a3741 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -23,8 +23,9 @@
#include <linux/scatterlist.h>
#include <linux/io.h>
#include <linux/gpio.h>
-#include <linux/pm_runtime.h>
#include <linux/mmc/sdhci-pci-data.h>
+#include <linux/sfi.h>
+#include <linux/pm_runtime.h>
#include "sdhci.h"
@@ -1451,6 +1452,8 @@
int i;
struct sdhci_pci_chip *chip;
+ sdhci_pci_runtime_pm_forbid(&pdev->dev);
+
chip = pci_get_drvdata(pdev);
if (chip) {
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 55a164f..425d092 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -672,6 +672,7 @@
}
#ifdef CONFIG_PM_SLEEP
+
static int sdhci_s3c_suspend(struct device *dev)
{
struct sdhci_host *host = dev_get_drvdata(dev);
@@ -712,6 +713,13 @@
#define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops)
+static const struct dev_pm_ops sdhci_s3c_pmops = {
+ .suspend = sdhci_s3c_suspend,
+ .resume = sdhci_s3c_resume,
+};
+
+#define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops)
+
#else
#define SDHCI_S3C_PMOPS NULL
#endif
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6df3410..6451d62 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
#include <linux/leds.h>
@@ -42,14 +43,29 @@
#define MAX_TUNING_LOOP 40
static unsigned int debug_quirks = 0;
+static unsigned int debug_quirks2;
static void sdhci_finish_data(struct sdhci_host *);
static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
static void sdhci_finish_command(struct sdhci_host *);
-static int sdhci_execute_tuning(struct mmc_host *mmc);
+static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
static void sdhci_tuning_timer(unsigned long data);
+#ifdef CONFIG_PM_RUNTIME
+static int sdhci_runtime_pm_get(struct sdhci_host *host);
+static int sdhci_runtime_pm_put(struct sdhci_host *host);
+#else
+static inline int sdhci_runtime_pm_get(struct sdhci_host *host)
+{
+ return 0;
+}
+static inline int sdhci_runtime_pm_put(struct sdhci_host *host)
+{
+ return 0;
+}
+#endif
+
static void sdhci_dumpregs(struct sdhci_host *host)
{
printk(KERN_DEBUG DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
@@ -134,6 +150,9 @@
(host->mmc->caps & MMC_CAP_NONREMOVABLE))
return;
+ if (host->quirks2 & SDHCI_QUIRK2_OWN_CARD_DETECTION)
+ return;
+
if (enable)
sdhci_unmask_irqs(host, irqs);
else
@@ -249,11 +268,14 @@
spin_lock_irqsave(&host->lock, flags);
+ if (host->runtime_suspended)
+ goto out;
+
if (brightness == LED_OFF)
sdhci_deactivate_led(host);
else
sdhci_activate_led(host);
-
+out:
spin_unlock_irqrestore(&host->lock, flags);
}
#endif
@@ -653,9 +675,7 @@
break;
}
- if (count >= 0xF) {
- printk(KERN_WARNING "%s: Too large timeout requested for CMD%d!\n",
- mmc_hostname(host->mmc), cmd->opcode);
+ if (count >= 0xF)
count = 0xE;
return count;
@@ -992,7 +1012,8 @@
flags |= SDHCI_CMD_INDEX;
/* CMD19 is special in that the Data Present Select should be set */
- if (cmd->data || (cmd->opcode == MMC_SEND_TUNING_BLOCK))
+ if (cmd->data || cmd->opcode == MMC_SEND_TUNING_BLOCK ||
+ cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200)
flags |= SDHCI_CMD_DATA;
sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
@@ -1208,6 +1229,8 @@
host = mmc_priv(mmc);
+ sdhci_runtime_pm_get(host);
+
spin_lock_irqsave(&host->lock, flags);
WARN_ON(host->mrq != NULL);
@@ -1251,7 +1274,7 @@
if ((host->flags & SDHCI_NEEDS_RETUNING) &&
!(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
spin_unlock_irqrestore(&host->lock, flags);
- sdhci_execute_tuning(mmc);
+ sdhci_execute_tuning(mmc, mrq->cmd->opcode);
spin_lock_irqsave(&host->lock, flags);
/* Restore original mmc_request structure */
@@ -1268,14 +1291,11 @@
spin_unlock_irqrestore(&host->lock, flags);
}
-static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
{
- struct sdhci_host *host;
unsigned long flags;
u8 ctrl;
- host = mmc_priv(mmc);
-
spin_lock_irqsave(&host->lock, flags);
if (host->flags & SDHCI_DEVICE_DEAD)
@@ -1338,7 +1358,8 @@
unsigned int clock;
/* In case of UHS-I modes, set High Speed Enable */
- if ((ios->timing == MMC_TIMING_UHS_SDR50) ||
+ if ((ios->timing == MMC_TIMING_MMC_HS200) ||
+ (ios->timing == MMC_TIMING_UHS_SDR50) ||
(ios->timing == MMC_TIMING_UHS_SDR104) ||
(ios->timing == MMC_TIMING_UHS_DDR50) ||
(ios->timing == MMC_TIMING_UHS_SDR25))
@@ -1391,7 +1412,9 @@
ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
/* Select Bus Speed Mode for host */
ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
- if (ios->timing == MMC_TIMING_UHS_SDR12)
+ if (ios->timing == MMC_TIMING_MMC_HS200)
+ ctrl_2 |= SDHCI_CTRL_HS_SDR200;
+ else if (ios->timing == MMC_TIMING_UHS_SDR12)
ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
else if (ios->timing == MMC_TIMING_UHS_SDR25)
ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
@@ -1424,7 +1447,16 @@
spin_unlock_irqrestore(&host->lock, flags);
}
-static int check_ro(struct sdhci_host *host)
+static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+
+ sdhci_runtime_pm_get(host);
+ sdhci_do_set_ios(host, ios);
+ sdhci_runtime_pm_put(host);
+}
+
+static int sdhci_check_ro(struct sdhci_host *host)
{
unsigned long flags;
int is_readonly;
@@ -1448,19 +1480,16 @@
#define SAMPLE_COUNT 5
-static int sdhci_get_ro(struct mmc_host *mmc)
+static int sdhci_do_get_ro(struct sdhci_host *host)
{
- struct sdhci_host *host;
int i, ro_count;
- host = mmc_priv(mmc);
-
if (!(host->quirks & SDHCI_QUIRK_UNSTABLE_RO_DETECT))
- return check_ro(host);
+ return sdhci_check_ro(host);
ro_count = 0;
for (i = 0; i < SAMPLE_COUNT; i++) {
- if (check_ro(host)) {
+ if (sdhci_check_ro(host)) {
if (++ro_count > SAMPLE_COUNT / 2)
return 1;
}
@@ -1469,38 +1498,64 @@
return 0;
}
-static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
+static void sdhci_hw_reset(struct mmc_host *mmc)
{
- struct sdhci_host *host;
- unsigned long flags;
+ struct sdhci_host *host = mmc_priv(mmc);
- host = mmc_priv(mmc);
+ if (host->ops && host->ops->hw_reset)
+ host->ops->hw_reset(host);
+}
- spin_lock_irqsave(&host->lock, flags);
+static int sdhci_get_ro(struct mmc_host *mmc)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ int ret;
+ sdhci_runtime_pm_get(host);
+ ret = sdhci_do_get_ro(host);
+ sdhci_runtime_pm_put(host);
+ return ret;
+}
+
+static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
+{
if (host->flags & SDHCI_DEVICE_DEAD)
goto out;
if (enable)
+ host->flags |= SDHCI_SDIO_IRQ_ENABLED;
+ else
+ host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
+
+ /* SDIO IRQ will be enabled as appropriate in runtime resume */
+ if (host->runtime_suspended)
+ goto out;
+
+ if (enable)
sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
else
sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
out:
mmiowb();
+}
+static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ sdhci_enable_sdio_irq_nolock(host, enable);
spin_unlock_irqrestore(&host->lock, flags);
}
-static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
- struct mmc_ios *ios)
+static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
+ struct mmc_ios *ios)
{
- struct sdhci_host *host;
u8 pwr;
u16 clk, ctrl;
u32 present_state;
- host = mmc_priv(mmc);
-
/*
* Signal Voltage Switching is only applicable for Host Controllers
* v3.00 and above.
@@ -1593,7 +1648,21 @@
return 0;
}
-static int sdhci_execute_tuning(struct mmc_host *mmc)
+static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
+ struct mmc_ios *ios)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ int err;
+
+ if (host->version < SDHCI_SPEC_300)
+ return 0;
+ sdhci_runtime_pm_get(host);
+ err = sdhci_do_start_signal_voltage_switch(host, ios);
+ sdhci_runtime_pm_put(host);
+ return err;
+}
+
+static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
struct sdhci_host *host;
u16 ctrl;
@@ -1601,26 +1670,35 @@
int tuning_loop_counter = MAX_TUNING_LOOP;
unsigned long timeout;
int err = 0;
+ bool requires_tuning_nonuhs = false;
host = mmc_priv(mmc);
+ sdhci_runtime_pm_get(host);
disable_irq(host->irq);
spin_lock(&host->lock);
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
/*
- * Host Controller needs tuning only in case of SDR104 mode
- * and for SDR50 mode when Use Tuning for SDR50 is set in
+ * The Host Controller needs tuning only in case of SDR104 mode
+ * and for SDR50 mode when Use Tuning for SDR50 is set in the
* Capabilities register.
+ * If the Host Controller supports the HS200 mode then the
+ * tuning function has to be executed.
*/
+ if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
+ (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
+ host->flags & SDHCI_HS200_NEEDS_TUNING))
+ requires_tuning_nonuhs = true;
+
if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
- (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
- (host->flags & SDHCI_SDR50_NEEDS_TUNING)))
+ requires_tuning_nonuhs)
ctrl |= SDHCI_CTRL_EXEC_TUNING;
else {
spin_unlock(&host->lock);
enable_irq(host->irq);
+ sdhci_runtime_pm_put(host);
return 0;
}
@@ -1646,12 +1724,12 @@
timeout = 150;
do {
struct mmc_command cmd = {0};
- struct mmc_request mrq = {0};
+ struct mmc_request mrq = {NULL};
if (!tuning_loop_counter && !timeout)
break;
- cmd.opcode = MMC_SEND_TUNING_BLOCK;
+ cmd.opcode = opcode;
cmd.arg = 0;
cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
cmd.retries = 0;
@@ -1666,7 +1744,17 @@
* block to the Host Controller. So we set the block size
* to 64 here.
*/
- sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE);
+ if (cmd.opcode == MMC_SEND_TUNING_BLOCK_HS200) {
+ if (mmc->ios.bus_width == MMC_BUS_WIDTH_8)
+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 128),
+ SDHCI_BLOCK_SIZE);
+ else if (mmc->ios.bus_width == MMC_BUS_WIDTH_4)
+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64),
+ SDHCI_BLOCK_SIZE);
+ } else {
+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64),
+ SDHCI_BLOCK_SIZE);
+ }
/*
* The tuning block is sent by the card to the host controller.
@@ -1764,18 +1852,16 @@
sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
spin_unlock(&host->lock);
enable_irq(host->irq);
+ sdhci_runtime_pm_put(host);
return err;
}
-static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable)
+static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable)
{
- struct sdhci_host *host;
u16 ctrl;
unsigned long flags;
- host = mmc_priv(mmc);
-
/* Host Controller v3.00 defines preset value registers */
if (host->version < SDHCI_SPEC_300)
return;
@@ -1791,18 +1877,30 @@
if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+ host->flags |= SDHCI_PV_ENABLED;
} else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+ host->flags &= ~SDHCI_PV_ENABLED;
}
spin_unlock_irqrestore(&host->lock, flags);
}
+static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+
+ sdhci_runtime_pm_get(host);
+ sdhci_do_enable_preset_value(host, enable);
+ sdhci_runtime_pm_put(host);
+}
+
static const struct mmc_host_ops sdhci_ops = {
.request = sdhci_request,
.set_ios = sdhci_set_ios,
.get_ro = sdhci_get_ro,
+ .hw_reset = sdhci_hw_reset,
.enable_sdio_irq = sdhci_enable_sdio_irq,
.start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
.execute_tuning = sdhci_execute_tuning,
@@ -1824,19 +1922,19 @@
spin_lock_irqsave(&host->lock, flags);
- if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
- if (host->mrq) {
- printk(KERN_ERR "%s: Card removed during transfer!\n",
- mmc_hostname(host->mmc));
- printk(KERN_ERR "%s: Resetting controller.\n",
- mmc_hostname(host->mmc));
+ /* Check host->mrq first in case we are runtime suspended */
+ if (host->mrq &&
+ !(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
+ printk(KERN_ERR "%s: Card removed during transfer!\n",
+ mmc_hostname(host->mmc));
+ printk(KERN_ERR "%s: Resetting controller.\n",
+ mmc_hostname(host->mmc));
- sdhci_reset(host, SDHCI_RESET_CMD);
- sdhci_reset(host, SDHCI_RESET_DATA);
+ sdhci_reset(host, SDHCI_RESET_CMD);
+ sdhci_reset(host, SDHCI_RESET_DATA);
- host->mrq->cmd->error = -ENOMEDIUM;
- tasklet_schedule(&host->finish_tasklet);
- }
+ host->mrq->cmd->error = -ENOMEDIUM;
+ tasklet_schedule(&host->finish_tasklet);
}
spin_unlock_irqrestore(&host->lock, flags);
@@ -1852,14 +1950,16 @@
host = (struct sdhci_host*)param;
+ spin_lock_irqsave(&host->lock, flags);
+
/*
* If this tasklet gets rescheduled while running, it will
* be run again afterwards but without any active request.
*/
- if (!host->mrq)
+ if (!host->mrq) {
+ spin_unlock_irqrestore(&host->lock, flags);
return;
-
- spin_lock_irqsave(&host->lock, flags);
+ }
del_timer(&host->timer);
@@ -1903,6 +2003,7 @@
spin_unlock_irqrestore(&host->lock, flags);
mmc_request_done(host->mmc, mrq);
+ sdhci_runtime_pm_put(host);
}
static void sdhci_timeout_timer(unsigned long data)
@@ -2036,12 +2137,14 @@
static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
{
+ u32 command;
BUG_ON(intmask == 0);
/* CMD19 generates _only_ Buffer Read Ready interrupt */
if (intmask & SDHCI_INT_DATA_AVAIL) {
- if (SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) ==
- MMC_SEND_TUNING_BLOCK) {
+ command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND));
+ if (command == MMC_SEND_TUNING_BLOCK ||
+ command == MMC_SEND_TUNING_BLOCK_HS200) {
host->tuning_done = 1;
wake_up(&host->buf_ready_int);
return;
@@ -2140,6 +2243,13 @@
spin_lock(&host->lock);
+ if (host->runtime_suspended) {
+ spin_unlock(&host->lock);
+ printk(KERN_WARNING "%s: got irq while runtime suspended\n",
+ mmc_hostname(host->mmc));
+ return IRQ_HANDLED;
+ }
+
intmask = sdhci_readl(host, SDHCI_INT_STATUS);
if (!intmask || intmask == 0xffffffff) {
@@ -2226,7 +2336,7 @@
#ifdef CONFIG_PM
-int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
+int sdhci_suspend_host(struct sdhci_host *host)
{
int ret;
@@ -2266,7 +2376,6 @@
return ret;
}
-
if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
if (host->ops->enable_dma)
host->ops->enable_dma(host);
@@ -2317,6 +2426,90 @@
#endif /* CONFIG_PM */
+#ifdef CONFIG_PM_RUNTIME
+
+static int sdhci_runtime_pm_get(struct sdhci_host *host)
+{
+ return pm_runtime_get_sync(host->mmc->parent);
+}
+
+static int sdhci_runtime_pm_put(struct sdhci_host *host)
+{
+ pm_runtime_mark_last_busy(host->mmc->parent);
+ return pm_runtime_put_autosuspend(host->mmc->parent);
+}
+
+int sdhci_runtime_suspend_host(struct sdhci_host *host)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable tuning since we are suspending */
+ if (host->version >= SDHCI_SPEC_300 &&
+ host->tuning_mode == SDHCI_TUNING_MODE_1) {
+ del_timer_sync(&host->tuning_timer);
+ host->flags &= ~SDHCI_NEEDS_RETUNING;
+ }
+
+ spin_lock_irqsave(&host->lock, flags);
+ sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ synchronize_irq(host->irq);
+
+ spin_lock_irqsave(&host->lock, flags);
+ host->runtime_suspended = true;
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(sdhci_runtime_suspend_host);
+
+int sdhci_runtime_resume_host(struct sdhci_host *host)
+{
+ unsigned long flags;
+ int ret = 0, host_flags = host->flags;
+
+ if (host_flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
+ if (host->ops->enable_dma)
+ host->ops->enable_dma(host);
+ }
+
+ sdhci_init(host, 0);
+
+ /* Force clock and power re-program */
+ host->pwr = 0;
+ host->clock = 0;
+ sdhci_do_set_ios(host, &host->mmc->ios);
+
+ sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios);
+ if (host_flags & SDHCI_PV_ENABLED)
+ sdhci_do_enable_preset_value(host, true);
+
+ /* Set the re-tuning expiration flag */
+ if ((host->version >= SDHCI_SPEC_300) && host->tuning_count &&
+ (host->tuning_mode == SDHCI_TUNING_MODE_1))
+ host->flags |= SDHCI_NEEDS_RETUNING;
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ host->runtime_suspended = false;
+
+ /* Enable SDIO IRQ */
+ if ((host->flags & SDHCI_SDIO_IRQ_ENABLED))
+ sdhci_enable_sdio_irq_nolock(host, true);
+
+ /* Enable Card Detection */
+ sdhci_enable_card_detection(host);
+
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(sdhci_runtime_resume_host);
+
+#endif
+
/*****************************************************************************\
* *
* Device allocation/registration *
@@ -2359,6 +2552,8 @@
if (debug_quirks)
host->quirks = debug_quirks;
+ if (debug_quirks2)
+ host->quirks2 = debug_quirks2;
sdhci_reset(host, SDHCI_RESET_ALL);
@@ -2569,10 +2764,14 @@
if (caps[1] & SDHCI_SUPPORT_DDR50)
mmc->caps |= MMC_CAP_UHS_DDR50;
- /* Does the host needs tuning for SDR50? */
+ /* Does the host need tuning for SDR50? */
if (caps[1] & SDHCI_USE_SDR50_TUNING)
host->flags |= SDHCI_SDR50_NEEDS_TUNING;
+ /* Does the host need tuning for HS200? */
+ if (mmc->caps2 & MMC_CAP2_HS200)
+ host->flags |= SDHCI_HS200_NEEDS_TUNING;
+
/* Driver Type(s) (A, C, D) supported by the host */
if (caps[1] & SDHCI_DRIVER_TYPE_A)
mmc->caps |= MMC_CAP_DRIVER_TYPE_A;
@@ -2893,9 +3092,11 @@
module_exit(sdhci_drv_exit);
module_param(debug_quirks, uint, 0444);
+module_param(debug_quirks2, uint, 0444);
MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
MODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver");
MODULE_LICENSE("GPL");
MODULE_PARM_DESC(debug_quirks, "Force certain quirks.");
+MODULE_PARM_DESC(debug_quirks2, "Force certain other quirks.");
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 0c070d6..1955ff4 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -21,6 +21,8 @@
#include <linux/of_device.h>
#include <linux/power_supply.h>
#include <linux/spmi.h>
+#include <linux/rtc.h>
+#include <linux/delay.h>
#include <linux/qpnp/qpnp-adc.h>
#include <linux/mfd/pm8xxx/batterydata-lib.h>
@@ -38,6 +40,8 @@
#define BMS1_OCV_USE_HIGH_LIMIT_THR0 0x4A
#define BMS1_OCV_USE_HIGH_LIMIT_THR1 0x4B
#define BMS1_OCV_USE_LIMIT_CTL 0x4C
+/* Delay control */
+#define BMS1_S1_DELAY_CTL 0x5A
/* CC interrupt threshold */
#define BMS1_CC_THR0 0x7A
#define BMS1_CC_THR1 0x7B
@@ -76,6 +80,8 @@
#define IAVG_START 600
#define SOC_ZERO 0xFF
+#define IAVG_SAMPLES 16
+
#define QPNP_BMS_DEV_NAME "qcom,qpnp-bms"
struct soc_params {
@@ -96,6 +102,7 @@
struct qpnp_bms_chip {
struct device *dev;
struct power_supply bms_psy;
+ struct power_supply *batt_psy;
struct spmi_device *spmi;
u16 base;
@@ -125,6 +132,7 @@
struct mutex bms_output_lock;
struct mutex last_ocv_uv_mutex;
+ struct mutex soc_invalidation_mutex;
unsigned int start_percent;
unsigned int end_percent;
@@ -137,6 +145,27 @@
int low_soc_calculate_soc_ms;
int calculate_soc_ms;
+ uint16_t ocv_reading_at_100;
+ int64_t cc_reading_at_100;
+ uint16_t prev_last_good_ocv_raw;
+ int last_ocv_uv;
+ int last_cc_uah;
+ unsigned long tm_sec;
+ bool first_time_calc_soc;
+ bool first_time_calc_uuc;
+ int pon_ocv_uv;
+
+ int iavg_samples_ma[IAVG_SAMPLES];
+ int iavg_index;
+ int iavg_num_samples;
+ struct timespec t_soc_queried;
+ int last_soc;
+ int last_soc_est;
+
+ int charge_time_us;
+ int catch_up_time_us;
+ struct single_row_lut *adjusted_fcc_temp_lut;
+
unsigned int vadc_v0625;
unsigned int vadc_v1250;
@@ -307,8 +336,7 @@
return VBATT_MUL_FACTOR * reading_uv;
}
- numerator = ((s64)reading_uv - chip->vadc_v0625)
- * VADC_CALIB_UV;
+ numerator = ((s64)reading_uv - chip->vadc_v0625) * VADC_CALIB_UV;
denominator = (s64)chip->vadc_v1250 - chip->vadc_v0625;
if (denominator == 0)
return reading_uv * VBATT_MUL_FACTOR;
@@ -319,7 +347,13 @@
static inline int convert_vbatt_raw_to_uv(struct qpnp_bms_chip *chip,
uint16_t reading)
{
- return adjust_vbatt_reading(chip, vadc_reading_to_uv(reading));
+ int uv;
+
+ uv = vadc_reading_to_uv(reading);
+ pr_debug("%u raw converted into %d uv\n", reading, uv);
+ uv = adjust_vbatt_reading(chip, uv);
+ pr_debug("adjusted into %d uv\n", uv);
+ return uv;
}
#define CC_READING_RESOLUTION_N 542535
@@ -331,16 +365,16 @@
}
#define QPNP_ADC_GAIN_NV 17857LL
-static s64 cc_adjust_for_gain(s64 uv, s64 gain)
+static s64 cc_adjust_for_gain(s64 uv, uint16_t gain)
{
s64 result_uv;
pr_debug("adjusting_uv = %lld\n", uv);
- pr_debug("adjusting by factor: %lld/%lld = %lld%%\n",
+ pr_debug("adjusting by factor: %lld/%hu = %lld%%\n",
QPNP_ADC_GAIN_NV, gain,
- div_s64(QPNP_ADC_GAIN_NV * 100LL, gain));
+ div_s64(QPNP_ADC_GAIN_NV * 100LL, (s64)gain));
- result_uv = div_s64(uv * QPNP_ADC_GAIN_NV, gain);
+ result_uv = div_s64(uv * QPNP_ADC_GAIN_NV, (s64)gain);
pr_debug("result_uv = %lld\n", result_uv);
return result_uv;
}
@@ -348,7 +382,11 @@
static int convert_vsense_to_uv(struct qpnp_bms_chip *chip,
int16_t reading)
{
- return cc_adjust_for_gain(cc_reading_to_uv(reading), QPNP_ADC_GAIN_NV);
+ struct qpnp_iadc_calib calibration;
+
+ qpnp_iadc_get_gain_and_offset(&calibration);
+ return cc_adjust_for_gain(cc_reading_to_uv(reading),
+ calibration.gain_raw);
}
static int read_vsense_avg(struct qpnp_bms_chip *chip, int *result_uv)
@@ -407,18 +445,944 @@
return 0;
}
+#define CC_36_BIT_MASK 0xFFFFFFFFFLL
+
+static int read_cc_raw(struct qpnp_bms_chip *chip, int64_t *reading)
+{
+ int64_t raw_reading;
+ int rc;
+
+ rc = qpnp_read_wrapper(chip, (u8 *)&raw_reading,
+ chip->base + BMS1_CC_DATA0, 5);
+ if (rc) {
+ pr_err("Error reading cc: rc = %d\n", rc);
+ return -ENXIO;
+ }
+
+ raw_reading = raw_reading & CC_36_BIT_MASK;
+ /* convert 36 bit signed value into 64 signed value */
+ *reading = (raw_reading >> 35) == 0LL ?
+ raw_reading : ((-1LL ^ CC_36_BIT_MASK) | raw_reading);
+ pr_debug("before conversion: %llx, after conversion: %llx\n",
+ raw_reading, *reading);
+
+ return 0;
+}
+
+static int calib_vadc(struct qpnp_bms_chip *chip)
+{
+ int rc;
+ struct qpnp_vadc_result result;
+
+ rc = qpnp_vadc_read(REF_625MV, &result);
+ if (rc) {
+ pr_debug("vadc read failed with rc = %d\n", rc);
+ return rc;
+ }
+ chip->vadc_v0625 = result.physical;
+
+ rc = qpnp_vadc_read(REF_125V, &result);
+ if (rc) {
+ pr_debug("vadc read failed with rc = %d\n", rc);
+ return rc;
+ }
+ chip->vadc_v1250 = result.physical;
+ pr_debug("vadc calib: 0625 = %d, 1250 = %d\n",
+ chip->vadc_v0625, chip->vadc_v1250);
+ return 0;
+}
+
+static void convert_and_store_ocv(struct qpnp_bms_chip *chip,
+ struct raw_soc_params *raw)
+{
+ int rc;
+
+ pr_debug("prev_last_good_ocv_raw = %d, last_good_ocv_raw = %d\n",
+ chip->prev_last_good_ocv_raw,
+ raw->last_good_ocv_raw);
+ rc = calib_vadc(chip);
+ if (rc)
+ pr_err("Vadc reference voltage read failed, rc = %d\n", rc);
+ chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
+ raw->last_good_ocv_uv = convert_vbatt_raw_to_uv(chip,
+ raw->last_good_ocv_raw);
+ chip->last_ocv_uv = raw->last_good_ocv_uv;
+ pr_debug("last_good_ocv_uv = %d\n", raw->last_good_ocv_uv);
+}
+
static int read_soc_params_raw(struct qpnp_bms_chip *chip,
struct raw_soc_params *raw)
{
- /* TODO add real reads */
+ int rc;
+
+ mutex_lock(&chip->bms_output_lock);
+ lock_output_data(chip);
+
+ rc = qpnp_read_wrapper(chip, (u8 *)&raw->last_good_ocv_raw,
+ chip->base + BMS1_OCV_FOR_SOC_DATA0, 2);
+ if (rc) {
+ pr_err("Error reading ocv: rc = %d\n", rc);
+ return -ENXIO;
+ }
+
+ rc = read_cc_raw(chip, &raw->cc);
+ if (rc) {
+ pr_err("Failed to read raw cc data, rc = %d\n", rc);
+ return rc;
+ }
+
+ unlock_output_data(chip);
+ mutex_unlock(&chip->bms_output_lock);
+
+ if (chip->prev_last_good_ocv_raw == 0) {
+ convert_and_store_ocv(chip, raw);
+ pr_debug("PON_OCV_UV = %d\n", chip->last_ocv_uv);
+ } else if (chip->prev_last_good_ocv_raw != raw->last_good_ocv_raw) {
+ convert_and_store_ocv(chip, raw);
+ /* forget the old cc value upon ocv */
+ chip->last_cc_uah = 0;
+ } else {
+ raw->last_good_ocv_uv = chip->last_ocv_uv;
+ }
+
+ /* fake a high OCV if done charging */
+ if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw) {
+ chip->ocv_reading_at_100 = 0;
+ chip->cc_reading_at_100 = 0;
+ } else {
+ /*
+ * force 100% ocv by selecting the highest voltage the
+ * battery could ever reach
+ */
+ raw->last_good_ocv_uv = chip->max_voltage_uv;
+ chip->last_ocv_uv = chip->max_voltage_uv;
+ }
+ pr_debug("last_good_ocv_raw= 0x%x, last_good_ocv_uv= %duV\n",
+ raw->last_good_ocv_raw, raw->last_good_ocv_uv);
+ pr_debug("cc_raw= 0x%llx\n", raw->cc);
return 0;
}
+static int calculate_pc(struct qpnp_bms_chip *chip, int ocv_uv,
+ int batt_temp)
+{
+ int pc;
+
+ pc = interpolate_pc(chip->pc_temp_ocv_lut,
+ batt_temp / 10, ocv_uv / 1000);
+ pr_debug("pc = %u %% for ocv = %d uv batt_temp = %d\n",
+ pc, ocv_uv, batt_temp);
+ /* Multiply the initial FCC value by the scale factor. */
+ return pc;
+}
+
+static int calculate_fcc(struct qpnp_bms_chip *chip, int batt_temp)
+{
+ int fcc_uah;
+
+ if (chip->adjusted_fcc_temp_lut == NULL) {
+ /* interpolate_fcc returns a mv value. */
+ fcc_uah = interpolate_fcc(chip->fcc_temp_lut,
+ batt_temp) * 1000;
+ pr_debug("fcc = %d uAh\n", fcc_uah);
+ return fcc_uah;
+ } else {
+ return 1000 * interpolate_fcc(chip->adjusted_fcc_temp_lut,
+ batt_temp);
+ }
+}
+
+/* calculate remaining charge at the time of ocv */
+static int calculate_ocv_charge(struct qpnp_bms_chip *chip,
+ struct raw_soc_params *raw,
+ int fcc_uah,
+ int batt_temp)
+{
+ int ocv_uv, pc;
+
+ ocv_uv = raw->last_good_ocv_uv;
+ pc = calculate_pc(chip, ocv_uv, batt_temp);
+ pr_debug("ocv_uv = %d pc = %d\n", ocv_uv, pc);
+ return (fcc_uah * pc) / 100;
+}
+
+#define CC_RESOLUTION_N 542535
+#define CC_RESOLUTION_D 100000
+
+static s64 cc_to_uv(s64 cc)
+{
+ return div_s64(cc * CC_RESOLUTION_N, CC_RESOLUTION_D);
+}
+
+#define CC_READING_TICKS 56
+#define SLEEP_CLK_HZ 32764
+#define SECONDS_PER_HOUR 3600
+
+static s64 cc_uv_to_nvh(s64 cc_uv)
+{
+ return div_s64(cc_uv * CC_READING_TICKS * 1000,
+ SLEEP_CLK_HZ * SECONDS_PER_HOUR);
+}
+
+/**
+ * calculate_cc-
+ * @chip: the bms chip pointer
+ * @cc: the cc reading from bms h/w
+ * @val: return value
+ * @coulomb_counter: adjusted coulomb counter for 100%
+ *
+ * RETURNS: in val pointer coulomb counter based charger in uAh
+ * (micro Amp hour)
+ */
+static int calculate_cc(struct qpnp_bms_chip *chip, int64_t cc)
+{
+ int64_t cc_voltage_uv, cc_nvh, cc_uah;
+ struct qpnp_iadc_calib calibration;
+
+ qpnp_iadc_get_gain_and_offset(&calibration);
+ cc_voltage_uv = cc;
+ cc_voltage_uv -= chip->cc_reading_at_100;
+ pr_debug("cc = %lld. after subtracting 0x%llx cc = %lld\n",
+ cc, chip->cc_reading_at_100,
+ cc_voltage_uv);
+ cc_voltage_uv = cc_to_uv(cc_voltage_uv);
+ cc_voltage_uv = cc_adjust_for_gain(cc_voltage_uv, calibration.gain_raw);
+ pr_debug("cc_voltage_uv = %lld uv\n", cc_voltage_uv);
+ cc_nvh = cc_uv_to_nvh(cc_voltage_uv);
+ pr_debug("cc_nvh = %lld nano_volt_hour\n", cc_nvh);
+ cc_uah = div_s64(cc_nvh, chip->r_sense_mohm);
+ /* cc_raw had 4 bits of extra precision.
+ By now it should be within 32 bit range */
+ return (int)cc_uah;
+}
+
+static int get_rbatt(struct qpnp_bms_chip *chip,
+ int soc_rbatt_mohm, int batt_temp)
+{
+ int rbatt_mohm, scalefactor;
+
+ rbatt_mohm = chip->default_rbatt_mohm;
+ pr_debug("rbatt before scaling = %d\n", rbatt_mohm);
+ if (chip->rbatt_sf_lut == NULL) {
+ pr_debug("RBATT = %d\n", rbatt_mohm);
+ return rbatt_mohm;
+ }
+ /* Convert the batt_temp to DegC from deciDegC */
+ batt_temp = batt_temp / 10;
+ scalefactor = interpolate_scalingfactor(chip->rbatt_sf_lut,
+ batt_temp, soc_rbatt_mohm);
+ pr_debug("rbatt sf = %d for batt_temp = %d, soc_rbatt = %d\n",
+ scalefactor, batt_temp, soc_rbatt_mohm);
+ rbatt_mohm = (rbatt_mohm * scalefactor) / 100;
+
+ rbatt_mohm += chip->r_conn_mohm;
+ pr_debug("adding r_conn_mohm = %d rbatt = %d\n",
+ chip->r_conn_mohm, rbatt_mohm);
+
+ pr_debug("RBATT = %d\n", rbatt_mohm);
+ return rbatt_mohm;
+}
+
+static void calculate_iavg(struct qpnp_bms_chip *chip, int cc_uah,
+ int *iavg_ua)
+{
+ int delta_cc_uah, delta_time_s, rc;
+ struct rtc_time tm;
+ struct rtc_device *rtc;
+ unsigned long now_tm_sec = 0;
+
+ rc = 0;
+ /* if anything fails report the previous iavg_ua */
+ *iavg_ua = chip->prev_iavg_ua;
+
+ rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+ if (rtc == NULL) {
+ pr_err("%s: unable to open rtc device (%s)\n",
+ __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
+ goto out;
+ }
+
+ rc = rtc_read_time(rtc, &tm);
+ if (rc) {
+ pr_err("Error reading rtc device (%s) : %d\n",
+ CONFIG_RTC_HCTOSYS_DEVICE, rc);
+ goto out;
+ }
+
+ rc = rtc_valid_tm(&tm);
+ if (rc) {
+ pr_err("Invalid RTC time (%s): %d\n",
+ CONFIG_RTC_HCTOSYS_DEVICE, rc);
+ goto out;
+ }
+ rtc_tm_to_time(&tm, &now_tm_sec);
+
+ if (chip->tm_sec == 0) {
+ get_battery_current(chip, iavg_ua);
+ goto out;
+ }
+
+ delta_time_s = (now_tm_sec - chip->tm_sec);
+
+ /* use the previous iavg if called within 15 seconds */
+ if (delta_time_s < 15) {
+ *iavg_ua = chip->prev_iavg_ua;
+ goto out;
+ }
+
+ delta_cc_uah = cc_uah - chip->last_cc_uah;
+
+ *iavg_ua = div_s64((s64)delta_cc_uah * 3600, delta_time_s);
+
+ pr_debug("tm_sec = %ld, now_tm_sec = %ld delta_s = %d delta_cc = %d iavg_ua = %d\n",
+ chip->tm_sec, now_tm_sec,
+ delta_time_s, delta_cc_uah, (int)*iavg_ua);
+
+out:
+ /* remember the iavg */
+ chip->prev_iavg_ua = *iavg_ua;
+
+ /* remember cc_uah */
+ chip->last_cc_uah = cc_uah;
+
+ /* remember this time */
+ chip->tm_sec = now_tm_sec;
+}
+
+static int calculate_termination_uuc(struct qpnp_bms_chip *chip,
+ struct soc_params *params,
+ int batt_temp, int uuc_iavg_ma,
+ int *ret_pc_unusable)
+{
+ int unusable_uv, pc_unusable, uuc_uah;
+ int i = 0;
+ int ocv_mv;
+ int batt_temp_degc = batt_temp / 10;
+ int rbatt_mohm;
+ int delta_uv;
+ int prev_delta_uv = 0;
+ int prev_rbatt_mohm = 0;
+ int uuc_rbatt_mohm;
+
+ for (i = 0; i <= 100; i++) {
+ ocv_mv = interpolate_ocv(chip->pc_temp_ocv_lut,
+ batt_temp_degc, i);
+ rbatt_mohm = get_rbatt(chip, i, batt_temp);
+ unusable_uv = (rbatt_mohm * uuc_iavg_ma)
+ + (chip->v_cutoff_uv);
+ delta_uv = ocv_mv * 1000 - unusable_uv;
+
+ pr_debug("soc = %d ocv = %d rbat = %d u_uv = %d delta_v = %d\n",
+ i, ocv_mv, rbatt_mohm, unusable_uv, delta_uv);
+
+ if (delta_uv > 0)
+ break;
+
+ prev_delta_uv = delta_uv;
+ prev_rbatt_mohm = rbatt_mohm;
+ }
+
+ uuc_rbatt_mohm = linear_interpolate(rbatt_mohm, delta_uv,
+ prev_rbatt_mohm, prev_delta_uv,
+ 0);
+
+ unusable_uv = (uuc_rbatt_mohm * uuc_iavg_ma) + (chip->v_cutoff_uv);
+
+ pc_unusable = calculate_pc(chip, unusable_uv, batt_temp);
+ uuc_uah = (params->fcc_uah * pc_unusable) / 100;
+ pr_debug("For uuc_iavg_ma = %d, unusable_rbatt = %d unusable_uv = %d unusable_pc = %d uuc = %d\n",
+ uuc_iavg_ma,
+ uuc_rbatt_mohm, unusable_uv,
+ pc_unusable, uuc_uah);
+ *ret_pc_unusable = pc_unusable;
+ return uuc_uah;
+}
+
+static int adjust_uuc(struct qpnp_bms_chip *chip,
+ struct soc_params *params,
+ int new_pc_unusable,
+ int new_uuc_uah,
+ int batt_temp)
+{
+ int new_unusable_mv, new_iavg_ma;
+ int batt_temp_degc = batt_temp / 10;
+
+ if (chip->prev_pc_unusable == -EINVAL
+ || abs(chip->prev_pc_unusable - new_pc_unusable) <= 1) {
+ chip->prev_pc_unusable = new_pc_unusable;
+ return new_uuc_uah;
+ }
+
+ /* the uuc is trying to change more than 1% restrict it */
+ if (new_pc_unusable > chip->prev_pc_unusable)
+ chip->prev_pc_unusable++;
+ else
+ chip->prev_pc_unusable--;
+
+ new_uuc_uah = (params->fcc_uah * chip->prev_pc_unusable) / 100;
+
+ /* also find update the iavg_ma accordingly */
+ new_unusable_mv = interpolate_ocv(chip->pc_temp_ocv_lut,
+ batt_temp_degc, chip->prev_pc_unusable);
+ if (new_unusable_mv < chip->v_cutoff_uv/1000)
+ new_unusable_mv = chip->v_cutoff_uv/1000;
+
+ new_iavg_ma = (new_unusable_mv * 1000 - chip->v_cutoff_uv)
+ / params->rbatt;
+ if (new_iavg_ma == 0)
+ new_iavg_ma = 1;
+ chip->prev_uuc_iavg_ma = new_iavg_ma;
+ pr_debug("Restricting UUC to %d (%d%%) unusable_mv = %d iavg_ma = %d\n",
+ new_uuc_uah, chip->prev_pc_unusable,
+ new_unusable_mv, new_iavg_ma);
+
+ return new_uuc_uah;
+}
+
+#define CHARGING_IAVG_MA 250
+#define MIN_SECONDS_FOR_VALID_SAMPLE 20
+static int calculate_unusable_charge_uah(struct qpnp_bms_chip *chip,
+ struct soc_params *params,
+ int batt_temp)
+{
+ int uuc_uah_iavg;
+ int i;
+ int uuc_iavg_ma = params->iavg_ua / 1000;
+ int pc_unusable;
+
+ /*
+ * if called first time, fill all the samples with
+ * the shutdown_iavg_ma
+ */
+ if (chip->first_time_calc_uuc && chip->shutdown_iavg_ma != 0) {
+ pr_debug("Using shutdown_iavg_ma = %d in all samples\n",
+ chip->shutdown_iavg_ma);
+ for (i = 0; i < IAVG_SAMPLES; i++)
+ chip->iavg_samples_ma[i] = chip->shutdown_iavg_ma;
+
+ chip->iavg_index = 0;
+ chip->iavg_num_samples = IAVG_SAMPLES;
+ }
+
+ /*
+ * if charging use a nominal avg current to keep
+ * a reasonable UUC while charging
+ */
+ if (uuc_iavg_ma < 0)
+ uuc_iavg_ma = CHARGING_IAVG_MA;
+ chip->iavg_samples_ma[chip->iavg_index] = uuc_iavg_ma;
+ chip->iavg_index = (chip->iavg_index + 1) % IAVG_SAMPLES;
+ chip->iavg_num_samples++;
+ if (chip->iavg_num_samples >= IAVG_SAMPLES)
+ chip->iavg_num_samples = IAVG_SAMPLES;
+
+ /* now that this sample is added calcualte the average */
+ uuc_iavg_ma = 0;
+ if (chip->iavg_num_samples != 0) {
+ for (i = 0; i < chip->iavg_num_samples; i++) {
+ pr_debug("iavg_samples_ma[%d] = %d\n", i,
+ chip->iavg_samples_ma[i]);
+ uuc_iavg_ma += chip->iavg_samples_ma[i];
+ }
+
+ uuc_iavg_ma = DIV_ROUND_CLOSEST(uuc_iavg_ma,
+ chip->iavg_num_samples);
+ }
+
+ uuc_uah_iavg = calculate_termination_uuc(chip, params, uuc_iavg_ma,
+ batt_temp, &pc_unusable);
+ pr_debug("uuc_iavg_ma = %d uuc with iavg = %d\n",
+ uuc_iavg_ma, uuc_uah_iavg);
+
+ chip->prev_uuc_iavg_ma = uuc_iavg_ma;
+ /* restrict the uuc such that it can increase only by one percent */
+ uuc_uah_iavg = adjust_uuc(chip, params, pc_unusable,
+ uuc_uah_iavg, batt_temp);
+
+ chip->first_time_calc_uuc = 0;
+ return uuc_uah_iavg;
+}
+
+static void find_ocv_for_soc(struct qpnp_bms_chip *chip,
+ struct soc_params *params,
+ int batt_temp,
+ int shutdown_soc,
+ int *ret_ocv_uv)
+{
+ s64 ocv_charge_uah;
+ int pc, new_pc;
+ int batt_temp_degc = batt_temp / 10;
+ int ocv_uv;
+
+ ocv_charge_uah = (s64)shutdown_soc
+ * (params->fcc_uah - params->uuc_uah);
+ ocv_charge_uah = div_s64(ocv_charge_uah, 100)
+ + params->cc_uah + params->uuc_uah;
+ pc = DIV_ROUND_CLOSEST((int)ocv_charge_uah * 100, params->fcc_uah);
+ pc = clamp(pc, 0, 100);
+
+ ocv_uv = interpolate_ocv(chip->pc_temp_ocv_lut, batt_temp_degc, pc);
+
+ pr_debug("s_soc = %d, fcc = %d uuc = %d rc = %d, pc = %d, ocv mv = %d\n",
+ shutdown_soc, params->fcc_uah,
+ params->uuc_uah, (int)ocv_charge_uah,
+ pc, ocv_uv);
+ new_pc = interpolate_pc(chip->pc_temp_ocv_lut, batt_temp_degc, ocv_uv);
+ pr_debug("test revlookup pc = %d for ocv = %d\n", new_pc, ocv_uv);
+
+ while (abs(new_pc - pc) > 1) {
+ int delta_mv = 5;
+
+ if (new_pc > pc)
+ delta_mv = -1 * delta_mv;
+
+ ocv_uv = ocv_uv + delta_mv;
+ new_pc = interpolate_pc(chip->pc_temp_ocv_lut,
+ batt_temp_degc, ocv_uv);
+ pr_debug("test revlookup pc = %d for ocv = %d\n",
+ new_pc, ocv_uv);
+ }
+
+ *ret_ocv_uv = ocv_uv * 1000;
+ params->ocv_charge_uah = (int)ocv_charge_uah;
+}
+
+static void calculate_soc_params(struct qpnp_bms_chip *chip,
+ struct raw_soc_params *raw,
+ struct soc_params *params,
+ int batt_temp)
+{
+ int soc_rbatt;
+
+ params->fcc_uah = calculate_fcc(chip, batt_temp);
+ pr_debug("FCC = %uuAh batt_temp = %d\n", params->fcc_uah, batt_temp);
+
+ /* calculate remainging charge */
+ params->ocv_charge_uah = calculate_ocv_charge(
+ chip, raw,
+ params->fcc_uah,
+ batt_temp);
+ pr_debug("ocv_charge_uah = %uuAh\n", params->ocv_charge_uah);
+
+ /* calculate cc micro_volt_hour */
+ params->cc_uah = calculate_cc(chip, raw->cc);
+ pr_debug("cc_uah = %duAh raw->cc = %llx cc = %lld after subtracting %llx\n",
+ params->cc_uah, raw->cc,
+ (int64_t)raw->cc - chip->cc_reading_at_100,
+ chip->cc_reading_at_100);
+
+ soc_rbatt = ((params->ocv_charge_uah - params->cc_uah) * 100)
+ / params->fcc_uah;
+ if (soc_rbatt < 0)
+ soc_rbatt = 0;
+ params->rbatt = get_rbatt(chip, soc_rbatt, batt_temp);
+
+ calculate_iavg(chip, params->cc_uah, ¶ms->iavg_ua);
+
+ params->uuc_uah = calculate_unusable_charge_uah(chip, params,
+ batt_temp);
+ pr_debug("UUC = %uuAh\n", params->uuc_uah);
+}
+
+static bool is_shutdown_soc_within_limits(struct qpnp_bms_chip *chip, int soc)
+{
+ if (chip->shutdown_soc_invalid) {
+ pr_debug("NOT forcing shutdown soc = %d\n", chip->shutdown_soc);
+ return 0;
+ }
+
+ if (abs(chip->shutdown_soc - soc) > chip->shutdown_soc_valid_limit) {
+ pr_debug("rejecting shutdown soc = %d, soc = %d limit = %d\n",
+ chip->shutdown_soc, soc,
+ chip->shutdown_soc_valid_limit);
+ chip->shutdown_soc_invalid = 1;
+ return 0;
+ }
+
+ return 1;
+}
+
+#define BMS_OVERRIDE_MODE_EN_BIT BIT(7)
+#define EN_VBAT_BIT BIT(0)
+#define OVERRIDE_MODE_DELAY_MS 20
+static int override_mode_batt_v_and_i(
+ struct qpnp_bms_chip *chip, int *ibat_ua, int *vbat_uv)
+{
+ int16_t vsense_raw, vbat_raw;
+ int vsense_uv, rc;
+ u8 delay;
+
+ mutex_lock(&chip->bms_output_lock);
+
+ delay = 0x00;
+ rc = qpnp_write_wrapper(chip, &delay,
+ chip->base + BMS1_S1_DELAY_CTL, 1);
+ if (rc)
+ pr_err("unable to write into BMS1_S1_DELAY, rc: %d\n", rc);
+
+ rc = qpnp_masked_write(chip, BMS1_MODE_CTL,
+ BMS_OVERRIDE_MODE_EN_BIT | EN_VBAT_BIT,
+ BMS_OVERRIDE_MODE_EN_BIT | EN_VBAT_BIT);
+ if (rc)
+ pr_err("unable to write into BMS1_MODE_CTL, rc: %d\n", rc);
+
+ msleep(OVERRIDE_MODE_DELAY_MS);
+
+ lock_output_data(chip);
+ qpnp_read_wrapper(chip, (u8 *)&vsense_raw,
+ chip->base + BMS1_VSENSE_AVG_DATA0, 2);
+ qpnp_read_wrapper(chip, (u8 *)&vbat_raw,
+ chip->base + BMS1_VBAT_AVG_DATA0, 2);
+ unlock_output_data(chip);
+
+ rc = qpnp_masked_write(chip, BMS1_MODE_CTL,
+ BMS_OVERRIDE_MODE_EN_BIT | EN_VBAT_BIT, 0);
+
+ delay = 0x0B;
+ rc = qpnp_write_wrapper(chip, &delay,
+ chip->base + BMS1_S1_DELAY_CTL, 1);
+ if (rc)
+ pr_err("unable to write into BMS1_S1_DELAY, rc: %d\n", rc);
+
+ mutex_unlock(&chip->bms_output_lock);
+
+ *vbat_uv = convert_vbatt_raw_to_uv(chip, vbat_raw);
+ vsense_uv = convert_vsense_to_uv(chip, vsense_raw);
+ *ibat_ua = vsense_uv * 1000 / (int)chip->r_sense_mohm;
+
+ pr_debug("vsense_raw = 0x%x vbat_raw = 0x%x ibat_ua = %d vbat_uv = %d\n",
+ (uint16_t)vsense_raw, (uint16_t)vbat_raw,
+ *ibat_ua, *vbat_uv);
+ return 0;
+}
+
+static int get_simultaneous_batt_v_and_i(
+ struct qpnp_bms_chip *chip,
+ int *ibat_ua, int *vbat_uv)
+{
+ int rc;
+ union power_supply_propval ret = {0,};
+
+ if (chip->batt_psy == NULL)
+ chip->batt_psy = power_supply_get_by_name("battery");
+ if (chip->batt_psy) {
+ /* if battery has been registered, use the status property */
+ chip->batt_psy->get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_STATUS, &ret);
+ } else {
+ /* default to using separate vbat/ibat if unregistered */
+ ret.intval = POWER_SUPPLY_STATUS_FULL;
+ }
+
+ if (ret.intval == POWER_SUPPLY_STATUS_FULL) {
+ pr_debug("batfet is open using separate vbat and ibat meas\n");
+ rc = get_battery_voltage(vbat_uv);
+ if (rc < 0) {
+ pr_err("adc vbat failed err = %d\n", rc);
+ return rc;
+ }
+ rc = get_battery_current(chip, ibat_ua);
+ if (rc < 0) {
+ pr_err("bms ibat failed err = %d\n", rc);
+ return rc;
+ }
+ } else {
+ return override_mode_batt_v_and_i(chip, ibat_ua, vbat_uv);
+ }
+
+ return 0;
+}
+
+static int bound_soc(int soc)
+{
+ soc = max(0, soc);
+ soc = min(100, soc);
+ return soc;
+}
+
+static int charging_adjustments(struct qpnp_bms_chip *chip,
+ struct soc_params *params, int soc,
+ int vbat_uv, int ibat_ua, int batt_temp)
+{
+ int chg_soc;
+
+ if (chip->soc_at_cv == -EINVAL) {
+ /* In constant current charging return the calc soc */
+ if (vbat_uv <= chip->max_voltage_uv)
+ pr_debug("CC CHG SOC %d\n", soc);
+
+ /* Note the CC to CV point */
+ if (vbat_uv >= chip->max_voltage_uv) {
+ chip->soc_at_cv = soc;
+ chip->prev_chg_soc = soc;
+ chip->ibat_at_cv_ua = ibat_ua;
+ pr_debug("CC_TO_CV ibat_ua = %d CHG SOC %d\n",
+ ibat_ua, soc);
+ }
+ return soc;
+ }
+
+ /*
+ * battery is in CV phase - begin liner inerpolation of soc based on
+ * battery charge current
+ */
+
+ /*
+ * if voltage lessened (possibly because of a system load)
+ * keep reporting the prev chg soc
+ */
+ if (vbat_uv <= chip->max_voltage_uv) {
+ pr_debug("vbat %d < max = %d CC CHG SOC %d\n",
+ vbat_uv, chip->max_voltage_uv, chip->prev_chg_soc);
+ return chip->prev_chg_soc;
+ }
+
+ chg_soc = linear_interpolate(chip->soc_at_cv, chip->ibat_at_cv_ua,
+ 100, -100000,
+ ibat_ua);
+
+ /* always report a higher soc */
+ if (chg_soc > chip->prev_chg_soc) {
+ int new_ocv_uv;
+
+ chip->prev_chg_soc = chg_soc;
+
+ find_ocv_for_soc(chip, params, batt_temp, chg_soc, &new_ocv_uv);
+ chip->last_ocv_uv = new_ocv_uv;
+ pr_debug("CC CHG ADJ OCV = %d CHG SOC %d\n",
+ new_ocv_uv,
+ chip->prev_chg_soc);
+ }
+
+ pr_debug("Reporting CHG SOC %d\n", chip->prev_chg_soc);
+ return chip->prev_chg_soc;
+}
+
+static int adjust_soc(struct qpnp_bms_chip *chip, struct soc_params *params,
+ int soc, int batt_temp)
+{
+ int ibat_ua = 0, vbat_uv = 0;
+ int ocv_est_uv = 0, soc_est = 0, pc_est = 0, pc = 0;
+ int delta_ocv_uv = 0;
+ int n = 0;
+ int rc_new_uah = 0;
+ int pc_new = 0;
+ int soc_new = 0;
+ int slope = 0;
+ int rc = 0;
+ int delta_ocv_uv_limit = 0;
+
+ rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
+ if (rc < 0) {
+ pr_err("simultaneous vbat ibat failed err = %d\n", rc);
+ goto out;
+ }
+
+ delta_ocv_uv_limit = DIV_ROUND_CLOSEST(ibat_ua, 1000);
+
+ ocv_est_uv = vbat_uv + (ibat_ua * params->rbatt)/1000;
+ pc_est = calculate_pc(chip, ocv_est_uv, batt_temp);
+ soc_est = div_s64((s64)params->fcc_uah * pc_est - params->uuc_uah*100,
+ (s64)params->fcc_uah - params->uuc_uah);
+ soc_est = bound_soc(soc_est);
+
+ if (ibat_ua < 0) {
+ soc = charging_adjustments(chip, params, soc, vbat_uv, ibat_ua,
+ batt_temp);
+ goto out;
+ }
+
+ /*
+ * do not adjust
+ * if soc is same as what bms calculated
+ * if soc_est is between 45 and 25, this is the flat portion of the
+ * curve where soc_est is not so accurate. We generally don't want to
+ * adjust when soc_est is inaccurate except for the cases when soc is
+ * way far off (higher than 50 or lesser than 20).
+ * Also don't adjust soc if it is above 90 becuase it might be pulled
+ * low and cause a bad user experience
+ */
+ if (soc_est == soc
+ || (is_between(45, chip->adjust_soc_low_threshold, soc_est)
+ && is_between(50, chip->adjust_soc_low_threshold - 5, soc))
+ || soc >= 90)
+ goto out;
+
+ if (chip->last_soc_est == -EINVAL)
+ chip->last_soc_est = soc;
+
+ n = min(200, max(1 , soc + soc_est + chip->last_soc_est));
+ chip->last_soc_est = soc_est;
+
+ pc = calculate_pc(chip, chip->last_ocv_uv, batt_temp);
+ if (pc > 0) {
+ pc_new = calculate_pc(chip,
+ chip->last_ocv_uv - (++slope * 1000),
+ batt_temp);
+ while (pc_new == pc) {
+ /* start taking 10mV steps */
+ slope = slope + 10;
+ pc_new = calculate_pc(chip,
+ chip->last_ocv_uv - (slope * 1000),
+ batt_temp);
+ }
+ } else {
+ /*
+ * pc is already at the lowest point,
+ * assume 1 millivolt translates to 1% pc
+ */
+ pc = 1;
+ pc_new = 0;
+ slope = 1;
+ }
+
+ delta_ocv_uv = div_s64((soc - soc_est) * (s64)slope * 1000,
+ n * (pc - pc_new));
+
+ if (abs(delta_ocv_uv) > delta_ocv_uv_limit) {
+ pr_debug("limiting delta ocv %d limit = %d\n", delta_ocv_uv,
+ delta_ocv_uv_limit);
+
+ if (delta_ocv_uv > 0)
+ delta_ocv_uv = delta_ocv_uv_limit;
+ else
+ delta_ocv_uv = -1 * delta_ocv_uv_limit;
+ pr_debug("new delta ocv = %d\n", delta_ocv_uv);
+ }
+
+ chip->last_ocv_uv -= delta_ocv_uv;
+
+ if (chip->last_ocv_uv >= chip->max_voltage_uv)
+ chip->last_ocv_uv = chip->max_voltage_uv;
+
+ /* calculate the soc based on this new ocv */
+ pc_new = calculate_pc(chip, chip->last_ocv_uv, batt_temp);
+ rc_new_uah = (params->fcc_uah * pc_new) / 100;
+ soc_new = (rc_new_uah - params->cc_uah - params->uuc_uah)*100
+ / (params->fcc_uah - params->uuc_uah);
+ soc_new = bound_soc(soc_new);
+
+ /*
+ * if soc_new is ZERO force it higher so that phone doesnt report soc=0
+ * soc = 0 should happen only when soc_est == 0
+ */
+ if (soc_new == 0 && soc_est != 0)
+ soc_new = 1;
+
+ soc = soc_new;
+
+out:
+ pr_debug("ibat_ua = %d, vbat_uv = %d, ocv_est_uv = %d, pc_est = %d, soc_est = %d, n = %d, delta_ocv_uv = %d, last_ocv_uv = %d, pc_new = %d, soc_new = %d, rbatt = %d, slope = %d\n",
+ ibat_ua, vbat_uv, ocv_est_uv, pc_est,
+ soc_est, n, delta_ocv_uv, chip->last_ocv_uv,
+ pc_new, soc_new, params->rbatt, slope);
+
+ return soc;
+}
+
static int calculate_state_of_charge(struct qpnp_bms_chip *chip,
struct raw_soc_params *raw,
int batt_temp)
{
- chip->calculated_soc = 50;
+ int soc, new_ocv_uv;
+ int shutdown_soc, new_calculated_soc, remaining_usable_charge_uah;
+ struct soc_params params;
+
+ calculate_soc_params(chip, raw, ¶ms, batt_temp);
+ /* calculate remaining usable charge */
+ remaining_usable_charge_uah = params.ocv_charge_uah
+ - params.cc_uah
+ - params.uuc_uah;
+
+ pr_debug("RUC = %duAh\n", remaining_usable_charge_uah);
+ if (params.fcc_uah - params.uuc_uah <= 0) {
+ pr_warn("FCC = %duAh, UUC = %duAh forcing soc = 0\n",
+ params.fcc_uah,
+ params.uuc_uah);
+ soc = 0;
+ } else {
+ soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
+ (params.fcc_uah
+ - params.uuc_uah));
+ }
+
+ if (chip->first_time_calc_soc && soc < 0) {
+ /*
+ * first time calcualtion and the pon ocv is too low resulting
+ * in a bad soc. Adjust ocv to get 0 soc
+ */
+ pr_debug("soc is %d, adjusting pon ocv to make it 0\n", soc);
+ find_ocv_for_soc(chip, ¶ms, batt_temp, 0, &new_ocv_uv);
+ chip->last_ocv_uv = new_ocv_uv;
+
+ remaining_usable_charge_uah = params.ocv_charge_uah
+ - params.cc_uah
+ - params.uuc_uah;
+
+ soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
+ (params.fcc_uah
+ - params.uuc_uah));
+ pr_debug("DONE for O soc is %d, pon ocv adjusted to %duV\n",
+ soc, chip->last_ocv_uv);
+ }
+
+ if (soc > 100)
+ soc = 100;
+
+ if (soc < 0) {
+ pr_err("bad rem_usb_chg = %d rem_chg %d, cc_uah %d, unusb_chg %d\n",
+ remaining_usable_charge_uah,
+ params.ocv_charge_uah,
+ params.cc_uah, params.uuc_uah);
+
+ pr_err("for bad rem_usb_chg last_ocv_uv = %d batt_temp = %d fcc = %d soc =%d\n",
+ chip->last_ocv_uv, batt_temp,
+ params.fcc_uah, soc);
+ soc = 0;
+ }
+
+ mutex_lock(&chip->soc_invalidation_mutex);
+ shutdown_soc = chip->shutdown_soc;
+
+ if (chip->first_time_calc_soc && soc != shutdown_soc
+ && is_shutdown_soc_within_limits(chip, soc)) {
+ /*
+ * soc for the first time - use shutdown soc
+ * to adjust pon ocv since it is a small percent away from
+ * the real soc
+ */
+ pr_debug("soc = %d before forcing shutdown_soc = %d\n",
+ soc, shutdown_soc);
+ find_ocv_for_soc(chip, ¶ms, batt_temp,
+ shutdown_soc, &new_ocv_uv);
+ chip->pon_ocv_uv = chip->last_ocv_uv;
+ chip->last_ocv_uv = new_ocv_uv;
+
+ remaining_usable_charge_uah = params.ocv_charge_uah
+ - params.cc_uah
+ - params.uuc_uah;
+
+ soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
+ (params.fcc_uah
+ - params.uuc_uah));
+
+ pr_debug("DONE for shutdown_soc = %d soc is %d, adjusted ocv to %duV\n",
+ shutdown_soc, soc, chip->last_ocv_uv);
+ }
+ mutex_unlock(&chip->soc_invalidation_mutex);
+
+ pr_debug("SOC before adjustment = %d\n", soc);
+ new_calculated_soc = adjust_soc(chip, ¶ms, soc, batt_temp);
+
+ if (new_calculated_soc != chip->calculated_soc
+ && chip->bms_psy.name != NULL) {
+ power_supply_changed(&chip->bms_psy);
+ pr_debug("power supply changed\n");
+ }
+
+ chip->calculated_soc = new_calculated_soc;
+ pr_debug("Set calculated SOC = %d\n", chip->calculated_soc);
+ chip->first_time_calc_soc = 0;
return chip->calculated_soc;
}
@@ -472,6 +1436,168 @@
(chip->calculate_soc_ms)));
}
+static void backup_soc_and_iavg(struct qpnp_bms_chip *chip, int batt_temp,
+ int soc)
+{
+ u8 temp;
+ int rc;
+ int iavg_ma = chip->prev_uuc_iavg_ma;
+
+ if (iavg_ma > IAVG_START)
+ temp = (iavg_ma - IAVG_START) / IAVG_STEP_SIZE_MA;
+ else
+ temp = 0;
+
+ rc = qpnp_write_wrapper(chip, &temp,
+ chip->base + IAVG_STORAGE_REG, 1);
+
+ if (soc == 0)
+ temp = SOC_ZERO;
+ else
+ temp = soc;
+
+ /* don't store soc if temperature is below 5degC */
+ if (batt_temp > IGNORE_SOC_TEMP_DECIDEG)
+ rc = qpnp_write_wrapper(chip, &temp,
+ chip->base + SOC_STORAGE_REG, 1);
+}
+
+#define SOC_CATCHUP_SEC_MAX 600
+#define SOC_CATCHUP_SEC_PER_PERCENT 60
+#define MAX_CATCHUP_SOC (SOC_CATCHUP_SEC_MAX/SOC_CATCHUP_SEC_PER_PERCENT)
+static int scale_soc_while_chg(struct qpnp_bms_chip *chip,
+ int delta_time_us, int new_soc, int prev_soc)
+{
+ int chg_time_sec;
+ int catch_up_sec;
+ int scaled_soc;
+ int numerator;
+
+ /*
+ * The device must be charging for reporting a higher soc, if
+ * not ignore this soc and continue reporting the prev_soc.
+ * Also don't report a high value immediately slowly scale the
+ * value from prev_soc to the new soc based on a charge time
+ * weighted average
+ */
+
+ /* if not charging, return last soc */
+ if (chip->start_percent == -EINVAL)
+ return prev_soc;
+
+ chg_time_sec = DIV_ROUND_UP(chip->charge_time_us, USEC_PER_SEC);
+ catch_up_sec = DIV_ROUND_UP(chip->catch_up_time_us, USEC_PER_SEC);
+ pr_debug("cts= %d catch_up_sec = %d\n", chg_time_sec, catch_up_sec);
+
+ /*
+ * if charging for more than catch_up time, simply return
+ * new soc
+ */
+ if (chg_time_sec > catch_up_sec)
+ return new_soc;
+
+ numerator = (catch_up_sec - chg_time_sec) * prev_soc
+ + chg_time_sec * new_soc;
+ scaled_soc = numerator / catch_up_sec;
+
+ pr_debug("cts = %d new_soc = %d prev_soc = %d scaled_soc = %d\n",
+ chg_time_sec, new_soc, prev_soc, scaled_soc);
+
+ return scaled_soc;
+}
+
+/*
+ * bms_fake_battery is set in setups where a battery emulator is used instead
+ * of a real battery. This makes the bms driver report a different/fake value
+ * regardless of the calculated state of charge.
+ */
+static int bms_fake_battery = -EINVAL;
+module_param(bms_fake_battery, int, 0644);
+
+static int report_state_of_charge(struct qpnp_bms_chip *chip)
+{
+ int soc;
+ int delta_time_us;
+ struct timespec now;
+ struct qpnp_vadc_result result;
+ int batt_temp;
+ int rc;
+
+ if (bms_fake_battery != -EINVAL) {
+ pr_debug("Returning Fake SOC = %d%%\n", bms_fake_battery);
+ return bms_fake_battery;
+ }
+
+ soc = chip->calculated_soc;
+
+ rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &result);
+
+ if (rc) {
+ pr_err("error reading adc channel = %d, rc = %d\n",
+ LR_MUX1_BATT_THERM, rc);
+ return rc;
+ }
+ pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
+ result.measurement);
+ batt_temp = (int)result.physical;
+
+ do_posix_clock_monotonic_gettime(&now);
+ if (chip->t_soc_queried.tv_sec != 0) {
+ delta_time_us
+ = (now.tv_sec - chip->t_soc_queried.tv_sec) * USEC_PER_SEC
+ + (now.tv_nsec - chip->t_soc_queried.tv_nsec) / 1000;
+ } else {
+ /* calculation for the first time */
+ delta_time_us = 0;
+ }
+
+ /*
+ * account for charge time - limit it to SOC_CATCHUP_SEC to
+ * avoid overflows when charging continues for extended periods
+ */
+ if (chip->start_percent != -EINVAL) {
+ if (chip->charge_time_us == 0) {
+ /*
+ * calculating soc for the first time
+ * after start of chg. Initialize catchup time
+ */
+ if (abs(soc - chip->last_soc) < MAX_CATCHUP_SOC)
+ chip->catch_up_time_us =
+ (soc - chip->last_soc)
+ * SOC_CATCHUP_SEC_PER_PERCENT
+ * USEC_PER_SEC;
+ else
+ chip->catch_up_time_us =
+ SOC_CATCHUP_SEC_MAX * USEC_PER_SEC;
+
+ if (chip->catch_up_time_us < 0)
+ chip->catch_up_time_us = 0;
+ }
+
+ /* add charge time */
+ if (chip->charge_time_us < SOC_CATCHUP_SEC_MAX * USEC_PER_SEC)
+ chip->charge_time_us += delta_time_us;
+
+ /* end catchup if calculated soc and last soc are same */
+ if (chip->last_soc == soc)
+ chip->catch_up_time_us = 0;
+ }
+
+ /* last_soc < soc ... scale and catch up */
+ if (chip->last_soc != -EINVAL && chip->last_soc < soc && soc != 100)
+ soc = scale_soc_while_chg(chip, delta_time_us,
+ soc, chip->last_soc);
+
+ pr_debug("last_soc = %d, calculated_soc = %d, soc = %d\n",
+ chip->last_soc, chip->calculated_soc, soc);
+ chip->last_soc = soc;
+ backup_soc_and_iavg(chip, batt_temp, chip->last_soc);
+ pr_debug("Reported SOC = %d\n", chip->last_soc);
+ chip->t_soc_queried = now;
+
+ return chip->last_soc;
+}
+
static int calculate_soc_from_voltage(struct qpnp_bms_chip *chip)
{
int voltage_range_uv, voltage_remaining_uv, voltage_based_soc;
@@ -491,8 +1617,8 @@
{
if (use_voltage_soc)
return calculate_soc_from_voltage(chip);
-
- return chip->calculated_soc;
+ else
+ return report_state_of_charge(chip);
}
/* Returns instantaneous current in uA */
@@ -775,7 +1901,11 @@
chip->prev_pc_unusable = -EINVAL;
chip->soc_at_cv = -EINVAL;
chip->calculated_soc = -EINVAL;
+ chip->last_soc = -EINVAL;
chip->last_vbat_read_uv = -EINVAL;
+ chip->last_soc_est = -EINVAL;
+ chip->first_time_calc_soc = 1;
+ chip->first_time_calc_uuc = 1;
}
static int __devinit
@@ -797,6 +1927,7 @@
mutex_init(&chip->bms_output_lock);
mutex_init(&chip->last_ocv_uv_mutex);
+ mutex_init(&chip->soc_invalidation_mutex);
bms_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
if (!bms_resource) {
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index f5df938..239d9f5 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -168,6 +168,8 @@
pipe = vctrl->base_pipe;
mixer = pipe->mixer_num;
+ mdp_update_pm(vctrl->mfd, vctrl->vsync_time);
+
if (vp->update_cnt == 0) {
mutex_unlock(&vctrl->update_lock);
return cnt;
@@ -1110,7 +1112,6 @@
mdp4_dsi_video_pipe_queue(0, pipe);
}
- mdp_update_pm(mfd, vsync_ctrl_db[0].vsync_time);
mdp4_overlay_mdp_perf_upd(mfd, 1);
cnt = mdp4_dsi_video_pipe_commit(cndx, 0);
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 4db684b..398fafa 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -72,6 +72,7 @@
struct completion dmae_comp;
struct completion vsync_comp;
spinlock_t spin_lock;
+ struct msm_fb_data_type *mfd;
struct mdp4_overlay_pipe *base_pipe;
struct vsync_update vlist[2];
int vsync_irq_enabled;
@@ -180,6 +181,8 @@
mixer = pipe->mixer_num;
mdp4_overlay_iommu_unmap_freelist(mixer);
+ mdp_update_pm(vctrl->mfd, vctrl->vsync_time);
+
if (vp->update_cnt == 0) {
mutex_unlock(&vctrl->update_lock);
return 0;
@@ -442,6 +445,9 @@
int hsync_end_x;
struct fb_info *fbi;
struct fb_var_screeninfo *var;
+ struct vsycn_ctrl *vctrl;
+
+ vctrl = &vsync_ctrl_db[0];
if (!mfd)
return -ENODEV;
@@ -452,6 +458,8 @@
fbi = mfd->fbi;
var = &fbi->var;
+ vctrl->mfd = mfd;
+
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
if (hdmi_prim_display) {
if (is_mdp4_hw_reset()) {
@@ -1132,7 +1140,6 @@
pipe->srcp0_addr = (uint32)mfd->ibuf.buf;
mdp4_dtv_pipe_queue(0, pipe);
}
- mdp_update_pm(mfd, vsync_ctrl_db[0].vsync_time);
if (hdmi_prim_display)
wait = 1;
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 172687a..a7058ce 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -172,6 +172,8 @@
pipe = vctrl->base_pipe;
mixer = pipe->mixer_num;
+ mdp_update_pm(vctrl->mfd, vctrl->vsync_time);
+
if (vp->update_cnt == 0) {
mutex_unlock(&vctrl->update_lock);
return 0;
@@ -969,7 +971,6 @@
mdp4_lcdc_pipe_queue(0, pipe);
}
- mdp_update_pm(mfd, vsync_ctrl_db[0].vsync_time);
mdp4_overlay_mdp_perf_upd(mfd, 1);
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index 18c6635..6c2b1f6 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -171,6 +171,8 @@
struct vsycn_ctrl *vctrl;
struct mdp4_overlay_pipe *pipe;
int ret = 0;
+ int undx;
+ struct vsync_update *vp;
pr_debug("%s+:\n", __func__);
@@ -189,6 +191,16 @@
mdp4_overlay_pipe_free(pipe);
vctrl->base_pipe = NULL;
+ undx = vctrl->update_ndx;
+ vp = &vctrl->vlist[undx];
+ if (vp->update_cnt) {
+ /*
+ * pipe's iommu will be freed at next overlay play
+ * and iommu_drop statistic will be increased by one
+ */
+ vp->update_cnt = 0; /* empty queue */
+ }
+
ret = panel_next_off(pdev);
mdp_clk_ctrl(1);
@@ -253,6 +265,12 @@
mdp4_mixer_stage_up(pipe, 0);
mdp4_overlayproc_cfg(pipe);
+
+ if (hdmi_prim_display)
+ outpdw(MDP_BASE + 0x100F4, 0x01);
+ else
+ outpdw(MDP_BASE + 0x100F4, 0x02);
+
/* MDP cmd block disable */
mdp_clk_ctrl(0);
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 45d7a3e..43daaf2 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -675,18 +675,18 @@
};
static const uint32_t msg_bld_masks_22[] = {
- MSG_LVL_HIGH,
- MSG_LVL_HIGH,
- MSG_LVL_HIGH,
- MSG_LVL_HIGH,
- MSG_LVL_HIGH,
- MSG_LVL_HIGH,
- MSG_LVL_HIGH,
- MSG_LVL_HIGH,
- MSG_LVL_HIGH,
- MSG_LVL_HIGH,
- MSG_LVL_HIGH,
- MSG_LVL_HIGH
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW
};
/* LOG CODES */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index ddfb7c5..48268f0 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1561,6 +1561,32 @@
#define in_gate_area(mm, addr) ({(void)mm; in_gate_area_no_mm(addr);})
#endif /* __HAVE_ARCH_GATE_AREA */
+#ifdef CONFIG_USE_USER_ACCESSIBLE_TIMERS
+static inline int use_user_accessible_timers(void) { return 1; }
+extern int in_user_timers_area(struct mm_struct *mm, unsigned long addr);
+extern struct vm_area_struct *get_user_timers_vma(struct mm_struct *mm);
+extern int get_user_timer_page(struct vm_area_struct *vma,
+ struct mm_struct *mm, unsigned long start, unsigned int gup_flags,
+ struct page **pages, int idx, int *goto_next_page);
+#else
+static inline int use_user_accessible_timers(void) { return 0; }
+static inline int in_user_timers_area(struct mm_struct *mm, unsigned long addr)
+{
+ return 0;
+}
+static inline struct vm_area_struct *get_user_timers_vma(struct mm_struct *mm)
+{
+ return NULL;
+}
+static inline int get_user_timer_page(struct vm_area_struct *vma,
+ struct mm_struct *mm, unsigned long start, unsigned int gup_flags,
+ struct page **pages, int idx, int *goto_next_page)
+{
+ *goto_next_page = 0;
+ return 0;
+}
+#endif
+
int drop_caches_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
unsigned long shrink_slab(struct shrink_control *shrink,
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index e9051e1..c5b492b 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -91,6 +91,7 @@
unsigned int quirks2; /* More deviations from spec. */
#define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0)
+#define SDHCI_QUIRK2_OWN_CARD_DETECTION (1<<1)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 41ff312..8f86fce 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1810,6 +1810,8 @@
V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_DISABLE = 0,
V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE = 1
};
+#define V4L2_CID_MPEG_VIDC_VIDEO_SECURE (V4L2_CID_MPEG_MSM_VIDC_BASE+24)
+
/* Camera class control IDs */
#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1)
diff --git a/mm/Kconfig b/mm/Kconfig
index 4cde97f..bbab5a6 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -390,3 +390,14 @@
the memory corresponding to the hole to be removed using memblock-
remove.
+config USE_USER_ACCESSIBLE_TIMERS
+ bool "Enables timers accessible from userspace"
+ depends on MMU
+ help
+ User-accessible timers allow the kernel to map kernel timer
+ registers to a userspace accessible page, to allow faster
+ access to time information. This flag will enable the
+ interface code in the main kernel. However, there are
+ architecture-specific code that will need to be enabled
+ separately.
+
diff --git a/mm/memory.c b/mm/memory.c
index 6105f47..174fcaa 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1726,6 +1726,19 @@
goto next_page;
}
+ if (use_user_accessible_timers()) {
+ if (!vma && in_user_timers_area(mm, start)) {
+ int goto_next_page = 0;
+ int user_timer_ret = get_user_timer_page(vma,
+ mm, start, gup_flags, pages, i,
+ &goto_next_page);
+ if (goto_next_page)
+ goto next_page;
+ else
+ return user_timer_ret;
+ }
+ }
+
if (!vma ||
(vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
!(vm_flags & vma->vm_flags))
diff --git a/mm/mlock.c b/mm/mlock.c
index ef726e8..38c77ab 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -229,7 +229,9 @@
if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) ||
is_vm_hugetlb_page(vma) ||
- vma == get_gate_vma(current->mm))) {
+ vma == get_gate_vma(current->mm) ||
+ ((use_user_accessible_timers() &&
+ (vma == get_user_timers_vma(current->mm)))))) {
__mlock_vma_pages_range(vma, start, end, NULL);
@@ -324,7 +326,9 @@
int lock = !!(newflags & VM_LOCKED);
if (newflags == vma->vm_flags || (vma->vm_flags & VM_SPECIAL) ||
- is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm))
+ is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm) ||
+ ((use_user_accessible_timers()) &&
+ (vma == get_user_timers_vma(current->mm))))
goto out; /* don't set VM_LOCKED, don't count */
pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);