Merge "iommu: msm: Fix lockdep warnings by removing virtual iommu device"
diff --git a/Documentation/ABI/testing/sysfs-bus-pil b/Documentation/ABI/testing/sysfs-bus-pil
deleted file mode 100644
index 797b2ea..0000000
--- a/Documentation/ABI/testing/sysfs-bus-pil
+++ /dev/null
@@ -1,18 +0,0 @@
-What: /sys/bus/pil/devices/.../name
-Date: March 2012
-Contact: Stephen Boyd <sboyd@codeaurora.org>
-Description:
- Shows the name of the peripheral used in pil_get().
-
-What: /sys/bus/pil/devices/.../state
-Date: March 2012
-Contact: Stephen Boyd <sboyd@codeaurora.org>
-Description:
- Shows the state state of a peripheral. Current states
- supported are:
-
- OFFLINE - peripheral is offline
- ONLINE - peripheral is online
-
- This file supports poll() to detect when a peripheral changes
- state.
diff --git a/Documentation/devicetree/bindings/arm/msm/pm-8x60.txt b/Documentation/devicetree/bindings/arm/msm/pm-8x60.txt
new file mode 100644
index 0000000..b429072
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/pm-8x60.txt
@@ -0,0 +1,28 @@
+* MSM PM-8x60
+
+PM-8x60 is the low power management device for MSM (Snapdragon class) chipsets.
+This device sets up different components to do low power modes and registers with
+the kernel to be notified of idle and suspend states and when called, follows
+through the set of instructions in putting the application cores to the lowest
+power mode possible.
+
+The required properties for PM-8x60 are:
+
+- compatible: "qcom,pm-8x60"
+
+The optional properties are:
+
+- qcom,use-sync-timer: Indicates whether the target uses the synchronized QTimer.
+- qcom,pc-mode: Indicates the type of power collapse used by the target. The
+ valid values for this are:
+ 0 (Power collapse terminates in TZ; integrated L2 cache controller)
+ 1, (Power collapse doesn't terminate in TZ; external L2 cache controller)
+ 2 (Power collapse terminates in TZ; external L2 cache controller)
+
+Example:
+
+qcom,pm-8x60 {
+ compatible = "qcom,pm-8x60";
+ qcom,pc-mode = <0>;
+ qcom,use-sync-timer;
+ };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt
index 88fca69..bcea355 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt
@@ -29,6 +29,8 @@
needed
- atmel,need-calibration : specify to indicate whether calibration is
needed during wakeup.
+ - atmel,no-force-update : flag that signifies whether force configuration
+ update is applicable or not
Example:
i2c@f9966000 {
@@ -52,7 +54,8 @@
vcc_i2c-supply = <&pm8941_lvs1>;
atmel,panel-coords = <0 0 479 799>;
atmel,display-coords = <0 0 479 799>;
- atmel,i2c-pull-up = <1>;
+ atmel,i2c-pull-up;
+ atmel,no-force-update;
atmel,dig-reg-support;
atmel,key-codes = <
102 139 0 0 0 0 0 0
diff --git a/Documentation/devicetree/bindings/pil/pil-venus.txt b/Documentation/devicetree/bindings/pil/pil-venus.txt
index 4b87f17..232c2cd 100644
--- a/Documentation/devicetree/bindings/pil/pil-venus.txt
+++ b/Documentation/devicetree/bindings/pil/pil-venus.txt
@@ -12,8 +12,6 @@
"vbif_base" are expected.
- vdd-supply: regulator to supply venus.
- qcom,firmware-name: Base name of the firmware image. Ex. "venus"
-- qcom,firmware-min-paddr: The lowest addr boundary for firmware image in DDR
-- qcom,firmware-max-paddr: The highest addr boundary for firmware image in DDR
Example:
qcom,venus@fdce0000 {
@@ -24,7 +22,4 @@
vdd-supply = <&gdsc_venus>;
qcom,firmware-name = "venus";
- qcom,firmware-min-paddr = <0xF500000>;
- qcom,firmware-max-paddr = <0xFA00000>;
-
};
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index ed4a81d..6004d15 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -39,7 +39,8 @@
atmel,irq-gpio = <&msmgpio 61 0x00>;
atmel,panel-coords = <0 0 760 1424>;
atmel,display-coords = <0 0 720 1280>;
- atmel,i2c-pull-up = <1>;
+ atmel,i2c-pull-up;
+ atmel,no-force-update;
atmel,cfg_1 {
atmel,family-id = <0x82>;
atmel,variant-id = <0x19>;
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index 39926e2..93f92c7 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -39,7 +39,8 @@
atmel,irq-gpio = <&msmgpio 61 0x00>;
atmel,panel-coords = <0 0 760 1424>;
atmel,display-coords = <0 0 720 1280>;
- atmel,i2c-pull-up = <1>;
+ atmel,i2c-pull-up;
+ atmel,no-force-update;
atmel,cfg_1 {
atmel,family-id = <0x82>;
atmel,variant-id = <0x19>;
diff --git a/arch/arm/boot/dts/msm8974-ion.dtsi b/arch/arm/boot/dts/msm8974-ion.dtsi
index 634ac43..01e200a 100644
--- a/arch/arm/boot/dts/msm8974-ion.dtsi
+++ b/arch/arm/boot/dts/msm8974-ion.dtsi
@@ -28,23 +28,6 @@
qcom,memory-reservation-size = <0x7800000>;
};
- qcom,ion-heap@29 { /* FIRMWARE HEAP */
- compatible = "qcom,msm-ion-reserve";
- reg = <29>;
- qcom,heap-align = <0x20000>;
- qcom,heap-adjacent = <8>;
- qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
- qcom,memory-reservation-size = <0xA00000>;
- };
-
- qcom,ion-heap@12 { /* MFC HEAP */
- compatible = "qcom,msm-ion-reserve";
- reg = <12>;
- qcom,heap-align = <0x1000>;
- qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
- qcom,memory-reservation-size = <0x2000>;
- };
-
qcom,ion-heap@23 { /* PIL1 HEAP */
compatible = "qcom,msm-ion-reserve";
reg = <23>;
@@ -52,14 +35,6 @@
qcom,memory-fixed = <0xd200000 0x2800000>;
};
- qcom,ion-heap@24 { /* SF HEAP */
- compatible = "qcom,msm-ion-reserve";
- reg = <24>;
- qcom,heap-align = <0x1000>;
- qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
- qcom,memory-reservation-size = <0x2800000>;
- };
-
qcom,ion-heap@25 { /* IOMMU HEAP */
reg = <25>;
};
@@ -76,7 +51,7 @@
reg = <27>;
qcom,heap-align = <0x1000>;
qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
- qcom,memory-reservation-size = <0x600000>;
+ qcom,memory-reservation-size = <0x780000>;
};
qcom,ion-heap@28 { /* AUDIO HEAP */
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index ae28fb3..e882c17 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -78,7 +78,8 @@
atmel,irq-gpio = <&msmgpio 61 0x00>;
atmel,panel-coords = <0 0 1080 1920>;
atmel,display-coords = <0 0 1080 1920>;
- atmel,i2c-pull-up = <1>;
+ atmel,i2c-pull-up;
+ atmel,no-force-update;
atmel,cfg_1 {
atmel,family-id = <0xa2>;
atmel,variant-id = <0x00>;
@@ -393,4 +394,4 @@
qcom,src-sel = <0>; /* CONSTANT */
qcom,master-en = <1>; /* ENABLE MPP */
};
-};
\ No newline at end of file
+};
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index c50f650..f4be0dc 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -39,7 +39,8 @@
atmel,irq-gpio = <&msmgpio 61 0x00>;
atmel,panel-coords = <0 0 760 1424>;
atmel,display-coords = <0 0 720 1280>;
- atmel,i2c-pull-up = <1>;
+ atmel,i2c-pull-up;
+ atmel,no-force-update;
atmel,cfg_1 {
atmel,family-id = <0x82>;
atmel,variant-id = <0x19>;
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 467c7ac..c554a5a 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1016,8 +1016,6 @@
vdd-supply = <&gdsc_venus>;
qcom,firmware-name = "venus";
- qcom,firmware-min-paddr = <0xF500000>;
- qcom,firmware-max-paddr = <0xFA00000>;
};
qcom,cache_erp {
diff --git a/arch/arm/boot/dts/msm9625-pm.dtsi b/arch/arm/boot/dts/msm9625-pm.dtsi
new file mode 100644
index 0000000..86e0cf7
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-pm.dtsi
@@ -0,0 +1,207 @@
+/* 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/ "skeleton.dtsi"
+
+/ {
+ qcom,spm@f9009000 {
+ compatible = "qcom,spm-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf9009000 0x1000>;
+ qcom,core-id = <0>;
+ qcom,saw2-ver-reg = <0xfd0>;
+ qcom,saw2-cfg = <0x101>;
+ qcom,saw2-spm-dly= <0>;
+ qcom,saw2-spm-ctl = <0x1>;
+ qcom,saw2-spm-cmd-wfi = [04 03 04 0f];
+ qcom,saw2-spm-cmd-spc = [34 04 44 14 24 54 03 54 44 14 04 24
+ 3e 0f];
+ qcom,saw2-spm-cmd-pc = [34 04 44 14 24 54 07 54 44 14 04 24
+ 3e 0f];
+ };
+
+ qcom,lpm-resources {
+ compatible = "qcom,lpm-resources";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,lpm-resources@0 {
+ reg = <0x0>;
+ qcom,name = "vdd-dig";
+ qcom,resource-type = <0>;
+ qcom,type = <0x616F646C>; /* "ldoa" */
+ qcom,id = <0x0A>;
+ qcom,key = <0x6e726f63>; /* "corn" */
+ };
+
+ qcom,lpm-resources@1 {
+ reg = <0x1>;
+ qcom,name = "vdd-mem";
+ qcom,resource-type = <0>;
+ qcom,type = <0x616F646C>; /* "ldoa" */
+ qcom,id = <0x0C>;
+ qcom,key = <0x7675>; /* "uv" */
+ };
+
+ qcom,lpm-resources@2 {
+ reg = <0x2>;
+ qcom,name = "pxo";
+ qcom,resource-type = <0>;
+ qcom,type = <0x306b6c63>; /* "clk0" */
+ qcom,id = <0x00>;
+ qcom,key = <0x62616e45>; /* "Enab" */
+ };
+ };
+
+ qcom,lpm-levels {
+ compatible = "qcom,lpm-levels";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,lpm-level@0 {
+ reg = <0x0>;
+ qcom,mode = <0>; /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
+ qcom,xo = <1>; /* ON */
+ qcom,l2 = <3>; /* ACTIVE */
+ qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <4>; /* NORMAL */
+ qcom,latency-us = <100>;
+ qcom,ss-power = <8000>;
+ qcom,energy-overhead = <100000>;
+ qcom,time-overhead = <1>;
+ };
+
+ qcom,lpm-level@1 {
+ reg = <0x1>;
+ qcom,mode = <2>; /* MSM_PM_SLEEP_MODE_STANDALONE_POWER_COLLAPSE */
+ qcom,xo = <1>; /* ON */
+ qcom,l2 = <3>; /* ACTIVE */
+ qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <4>; /* NORMAL */
+ qcom,latency-us = <2000>;
+ qcom,ss-power = <5000>;
+ qcom,energy-overhead = <60100000>;
+ qcom,time-overhead = <3000>;
+ };
+
+ qcom,lpm-level@2 {
+ reg = <0x2>;
+ qcom,mode = <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+ qcom,xo = <1>; /* ON */
+ qcom,l2 = <1>; /* GDHS */
+ qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <4>; /* NORMAL */
+ qcom,latency-us = <3500>;
+ qcom,ss-power = <5000>;
+ qcom,energy-overhead = <60350000>;
+ qcom,time-overhead = <6300>;
+ };
+
+ qcom,lpm-level@3 {
+ reg = <0x3>;
+ qcom,mode= <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+ qcom,xo = <0>; /* OFF */
+ qcom,l2 = <0>; /* OFF */
+ qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <4>; /* NORMAL */
+ qcom,latency-us = <6800>;
+ qcom,ss-power = <2000>;
+ qcom,energy-overhead = <71850000>;
+ qcom,time-overhead = <13300>;
+ };
+
+ qcom,lpm-level@4 {
+ reg = <0x4>;
+ qcom,mode= <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+ qcom,xo = <0>; /* OFF */
+ qcom,l2 = <0>; /* OFF */
+ qcom,vdd-mem-upper-bound = <950000>; /* SVS SOC */
+ qcom,vdd-mem-lower-bound = <675000>; /* RETENTION */
+ qcom,vdd-dig-upper-bound = <3>; /* SVS SOC */
+ qcom,vdd-dig-lower-bound = <1>; /* RETENTION */
+ qcom,latency-us = <9800>;
+ qcom,ss-power = <0>;
+ qcom,energy-overhead = <76350000>;
+ qcom,time-overhead = <28300>;
+ };
+ };
+
+ qcom,pm-boot {
+ compatible = "qcom,pm-boot";
+ qcom,mode = <0>; /* MSM_PM_BOOT_CONFIG_TZ */
+ };
+
+ qcom,mpm@fc4281d0 {
+ compatible = "qcom,mpm-v2";
+ reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */
+ <0xf9011008 0x4>; /* MSM_APCS_GCC_BASE 4K */
+ reg-names = "vmpm", "ipc";
+ interrupts = <0 171 1>;
+
+ qcom,ipc-bit-offset = <1>;
+
+ qcom,gic-parent = <&intc>;
+ qcom,gic-map = <41 172>, /* usb2_hsic_async_wakeup_irq */
+ <0xff 208>; /* summary_irq_kpss */
+
+ qcom,gpio-parent = <&msmgpio>;
+ qcom,gpio-map = <4 1>,
+ <5 5>,
+ <6 9>,
+ <7 18>,
+ <8 20>,
+ <9 24>,
+ <10 27>,
+ <11 28>,
+ <12 34>,
+ <13 35>,
+ <14 37>,
+ <15 42>,
+ <16 44>,
+ <17 46>,
+ <18 50>,
+ <19 54>,
+ <20 59>,
+ <21 61>,
+ <22 62>,
+ <23 64>,
+ <24 65>,
+ <25 66>,
+ <26 67>,
+ <27 68>,
+ <28 71>,
+ <29 72>,
+ <30 73>,
+ <31 74>,
+ <32 75>,
+ <33 77>,
+ <34 79>,
+ <35 80>,
+ <36 82>,
+ <37 86>;
+ };
+
+ qcom,pm-8x60 {
+ compatible = "qcom,pm-8x60";
+ qcom,pc-mode = <2>; /*MSM_PC_TZ_L2_EXT */
+ qcom,use-sync-timer;
+ };
+};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 0ebeb9c..0a349f7 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -12,6 +12,7 @@
/include/ "skeleton.dtsi"
/include/ "msm9625-ion.dtsi"
+/include/ "msm9625-pm.dtsi"
/ {
model = "Qualcomm MSM 9625";
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 98c1ede..23b4527 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -275,6 +275,7 @@
CONFIG_QPNP_BMS=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_SENSORS_QPNP_ADC_CURRENT=y
+CONFIG_SENSORS_EPM_ADC=y
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS8974=y
CONFIG_THERMAL_QPNP=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 328a4dc..1a03b5b 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -276,6 +276,7 @@
CONFIG_QPNP_BMS=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_SENSORS_QPNP_ADC_CURRENT=y
+CONFIG_SENSORS_EPM_ADC=y
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS8974=y
CONFIG_THERMAL_QPNP=y
diff --git a/arch/arm/mach-msm/avs.h b/arch/arm/mach-msm/avs.h
index a549e9d..e87bded 100644
--- a/arch/arm/mach-msm/avs.h
+++ b/arch/arm/mach-msm/avs.h
@@ -37,7 +37,8 @@
u32 avs_get_avsdscr(void);
u32 avs_get_tscsr(void);
void avs_set_tscsr(u32 to_tscsr);
-void avs_disable(void);
+u32 avs_disable(void);
+void avs_enable(u32 avscsr);
#else
static inline u32 avs_reset_delays(u32 avsdscr)
{ return 0; }
@@ -48,7 +49,9 @@
static inline u32 avs_get_tscsr(void)
{ return 0; }
static inline void avs_set_tscsr(u32 to_tscsr) {}
-static inline void avs_disable(void) {}
+static inline u32 avs_disable(void)
+{return 0; }
+static inline void avs_enable(u32 avscsr) {}
#endif
/*#define AVSDEBUG(x...) pr_info("AVS: " x);*/
@@ -60,9 +63,13 @@
put_cpu(); \
} while (0);
+/* AVSCSR(0x61) to enable CPU, V and L2 AVS module */
+
#define AVS_ENABLE(cpu, x) do { \
- if (get_cpu() == (cpu)) \
+ if (get_cpu() == (cpu)) { \
avs_reset_delays((x)); \
+ avs_enable(0x61); \
+ } \
put_cpu(); \
} while (0);
diff --git a/arch/arm/mach-msm/avs_hw.S b/arch/arm/mach-msm/avs_hw.S
index 1cc3ce0..efb9c47 100644
--- a/arch/arm/mach-msm/avs_hw.S
+++ b/arch/arm/mach-msm/avs_hw.S
@@ -102,23 +102,23 @@
/* Read r0=AVSDSCR */
mrc p15, 7, r0, c15, c0, 6
-
-/* AVSCSR(0x61) to enable CPU, V and L2 AVS module */
- mov r3, #0x61
- mcr p15, 7, r3, c15, c1, 7
-
bx lr
-
+ .global avs_enable
+avs_enable:
+/* Restore the avs_scr register */
+ mcr p15, 7, r0, c15, c1, 7
+ bx lr
.global avs_disable
avs_disable:
+/* Get the AVSCSR value */
+ mrc p15, 7, r0, c15, c1, 7
/* Clear AVSCSR */
- mov r0, #0
-
+ mov r1, #0
/* Write AVSCSR */
- mcr p15, 7, r0, c15, c1, 7
+ mcr p15, 7, r1, c15, c1, 7
bx lr
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index b9da615..2f3ab7f 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -939,6 +939,7 @@
&msm9615_rpm_stat_device,
&msm9615_rpm_master_stat_device,
&msm_tsens_device,
+ &msm9615_pm_8x60,
};
static void __init msm9615_i2c_init(void)
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index fbfa036..ee06058 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -1874,7 +1874,7 @@
},
{
.irq_config_id = SMD_Q6,
- .subsys_name = "q6",
+ .subsys_name = "adsp",
.edge = SMD_APPS_QDSP,
.smd_int.irq_name = "adsp_a11",
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index f8132b4..d05be0b 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1412,7 +1412,6 @@
.aclk_reg = MSM_CLK_CTL_BASE + 0x2C6C,
.jtag_clk_reg = MSM_CLK_CTL_BASE + 0x2044,
.name = "modem_fw",
- .depends = "q6",
.pas_id = PAS_MODEM_FW,
.bus_port = MSM_BUS_MASTER_MSS_FW_PROC,
},
@@ -1423,7 +1422,6 @@
.aclk_reg = MSM_CLK_CTL_BASE + 0x2040,
.jtag_clk_reg = MSM_CLK_CTL_BASE + 0x2C68,
.name = "modem",
- .depends = "modem_fw",
.pas_id = PAS_MODEM_SW,
.bus_port = MSM_BUS_MASTER_MSS_SW_PROC,
}
@@ -1557,7 +1555,7 @@
},
{
.irq_config_id = SMD_Q6,
- .subsys_name = "q6",
+ .subsys_name = "adsp",
.edge = SMD_APPS_QDSP,
.smd_int.irq_name = "adsp_a11",
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index fe3a4d5..7307f62 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -1421,6 +1421,19 @@
},
};
+static struct msm_pm_init_data_type msm_pm_data = {
+ .use_sync_timer = false,
+ .pc_mode = MSM_PM_PC_NOTZ_L2_EXT,
+};
+
+struct platform_device msm9615_pm_8x60 = {
+ .name = "pm-8x60",
+ .id = -1,
+ .dev = {
+ .platform_data = &msm_pm_data,
+ },
+};
+
uint32_t __init msm9615_rpm_get_swfi_latency(void)
{
int i;
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 97adb35..16b4eee 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -109,6 +109,8 @@
extern struct platform_device msm_device_sdc3;
extern struct platform_device msm_device_sdc4;
+extern struct platform_device msm9615_pm_8x60;
+
extern struct platform_device msm8960_pc_cntr;
extern struct platform_device msm8064_pc_cntr;
extern struct platform_device msm8930_pc_cntr;
diff --git a/arch/arm/mach-msm/idle-v7.S b/arch/arm/mach-msm/idle-v7.S
index 1d8f313..ccd0bf7 100644
--- a/arch/arm/mach-msm/idle-v7.S
+++ b/arch/arm/mach-msm/idle-v7.S
@@ -22,7 +22,7 @@
#include "idle.h"
#include "idle-macros.S"
-#ifdef CONFIG_ARCH_MSM_KRAIT
+#ifdef CONFIG_MSM_SCM
#define SCM_SVC_BOOT 0x1
#define SCM_CMD_TERMINATE_PC 0x2
#endif
@@ -127,7 +127,18 @@
cmp r1, #1
bne skip
bl v7_flush_dcache_all
+ ldr r1, =msm_pm_flush_l2_fn
+ ldr r1, [r1]
+ cmp r1, #0
+ blxne r1
+
skip:
+ ldr r1, =msm_pm_disable_l2_fn
+ ldr r1, [r1]
+ cmp r1, #0
+ blxne r1
+ dmb
+
mrc p15, 0, r0, c0, c0, 5 /* MPIDR */
and r0, r0, #15 /* what CPU am I */
@@ -141,7 +152,7 @@
str r2, [r1]
skip_pc_debug1:
-#ifdef CONFIG_ARCH_MSM_KRAIT
+#ifdef CONFIG_MSM_SCM
ldr r0, =SCM_SVC_BOOT
ldr r1, =SCM_CMD_TERMINATE_PC
ldr r2, =msm_pm_flush_l2_flag
@@ -182,6 +193,11 @@
str r2, [r1]
skip_pc_debug2:
+ ldr r1, =msm_pm_enable_l2_fn
+ ldr r1, [r1]
+ cmp r1, #0
+ blxne r1
+ dmb
#ifdef CONFIG_MSM_JTAG
bl msm_jtag_restore_state
@@ -286,11 +302,16 @@
SET_SMP_COHERENCY ON
#endif
-#ifdef CONFIG_MSM_JTAG
+ ldr r1, =msm_pm_enable_l2_fn
+ ldr r1, [r1]
+ cmp r1, #0
stmfd sp!, {lr}
+ blxne r1
+ dmb
+#ifdef CONFIG_MSM_JTAG
bl msm_jtag_restore_state
- ldmfd sp!, {lr}
#endif
+ ldmfd sp!, {lr}
mov r0, #1
bx lr
nop
@@ -377,6 +398,18 @@
msm_pc_debug_counters:
.long 0x0
+ .globl msm_pm_enable_l2_fn
+msm_pm_enable_l2_fn:
+ .long 0x0
+
+ .globl msm_pm_disable_l2_fn
+msm_pm_disable_l2_fn:
+ .long 0x0
+
+ .globl msm_pm_flush_l2_fn
+msm_pm_flush_l2_fn:
+ .long 0x0
+
/*
* Default the l2 flush flag to 1 so that caches are flushed during power
* collapse unless the L2 driver decides to flush them only during L2
diff --git a/arch/arm/mach-msm/idle.h b/arch/arm/mach-msm/idle.h
index 7a939ab..ee3209c 100644
--- a/arch/arm/mach-msm/idle.h
+++ b/arch/arm/mach-msm/idle.h
@@ -33,6 +33,9 @@
int msm_pm_collapse(void);
void msm_pm_collapse_exit(void);
extern void *msm_saved_state;
+extern void (*msm_pm_disable_l2_fn)(void);
+extern void (*msm_pm_enable_l2_fn)(void);
+extern void (*msm_pm_flush_l2_fn)(void);
extern unsigned long msm_saved_state_phys;
#ifdef CONFIG_CPU_V7
diff --git a/arch/arm/mach-msm/include/mach/peripheral-loader.h b/arch/arm/mach-msm/include/mach/peripheral-loader.h
deleted file mode 100644
index 327c82f..0000000
--- a/arch/arm/mach-msm/include/mach/peripheral-loader.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. 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 __MACH_PERIPHERAL_LOADER_H
-#define __MACH_PERIPHERAL_LOADER_H
-
-#ifdef CONFIG_MSM_PIL
-extern void *pil_get(const char *name);
-extern void pil_put(void *peripheral_handle);
-extern void pil_force_shutdown(const char *name);
-extern int pil_force_boot(const char *name);
-#else
-static inline void *pil_get(const char *name) { return NULL; }
-static inline void pil_put(void *peripheral_handle) { }
-static inline void pil_force_shutdown(const char *name) { }
-static inline int pil_force_boot(const char *name) { return -ENOSYS; }
-#endif
-
-#endif
diff --git a/arch/arm/mach-msm/ipc_router_smd_xprt.c b/arch/arm/mach-msm/ipc_router_smd_xprt.c
index b2e6490..8c0bf4b 100644
--- a/arch/arm/mach-msm/ipc_router_smd_xprt.c
+++ b/arch/arm/mach-msm/ipc_router_smd_xprt.c
@@ -20,7 +20,7 @@
#include <linux/types.h>
#include <mach/msm_smd.h>
-#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
#include "ipc_router.h"
#include "smd_private.h"
@@ -210,7 +210,7 @@
rc = smd_close(smd_xprtp->channel);
if (smd_xprtp->pil) {
- pil_put(smd_xprtp->pil);
+ subsystem_put(smd_xprtp->pil);
smd_xprtp->pil = NULL;
}
return rc;
@@ -402,7 +402,7 @@
peripheral = smd_edge_to_subsystem(edge);
if (peripheral) {
- pil = pil_get(peripheral);
+ pil = subsystem_get(peripheral);
if (IS_ERR(pil)) {
pr_err("%s: Failed to load %s\n",
__func__, peripheral);
@@ -460,7 +460,7 @@
pr_err("%s: Channel open failed for %s\n",
__func__, smd_xprt_cfg[id].ch_name);
if (smd_remote_xprt[id].pil) {
- pil_put(smd_remote_xprt[id].pil);
+ subsystem_put(smd_remote_xprt[id].pil);
smd_remote_xprt[id].pil = NULL;
}
destroy_workqueue(smd_remote_xprt[id].smd_xprt_wq);
@@ -481,7 +481,7 @@
peripheral = smd_edge_to_subsystem(SMD_APPS_MODEM);
if (peripheral && !strncmp(peripheral, "modem", 6)) {
- pil = pil_get(peripheral);
+ pil = subsystem_get(peripheral);
if (IS_ERR(pil)) {
pr_err("%s: Failed to load %s\n",
__func__, peripheral);
@@ -495,7 +495,7 @@
void msm_ipc_unload_default_node(void *pil)
{
if (pil)
- pil_put(pil);
+ subsystem_put(pil);
}
EXPORT_SYMBOL(msm_ipc_unload_default_node);
diff --git a/arch/arm/mach-msm/msm_dsps.c b/arch/arm/mach-msm/msm_dsps.c
index 859fc15..0551130 100644
--- a/arch/arm/mach-msm/msm_dsps.c
+++ b/arch/arm/mach-msm/msm_dsps.c
@@ -585,7 +585,7 @@
*
* If the DSPS is running, then we must reset DSPS CPU & HW before
* setting the clocks off.
- * The DSPS reset should be done as part of the pil_put().
+ * The DSPS reset should be done as part of the subsystem_put().
* The DSPS reset should be used for error recovery if the DSPS firmware
* has crashed and re-loading the firmware is required.
*/
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index 4ff34bf..3824d0e 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.c
@@ -12,28 +12,32 @@
#include <linux/module.h>
#include <linux/string.h>
-#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/io.h>
-#include <linux/debugfs.h>
#include <linux/elf.h>
#include <linux/mutex.h>
#include <linux/memblock.h>
#include <linux/slab.h>
-#include <linux/atomic.h>
#include <linux/suspend.h>
#include <linux/rwsem.h>
#include <linux/sysfs.h>
#include <linux/workqueue.h>
#include <linux/jiffies.h>
#include <linux/wakelock.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/list_sort.h>
#include <asm/uaccess.h>
#include <asm/setup.h>
-#include <mach/peripheral-loader.h>
#include "peripheral-loader.h"
+#define pil_err(desc, fmt, ...) \
+ dev_err(desc->dev, "%s: " fmt, desc->name, ##__VA_ARGS__)
+#define pil_info(desc, fmt, ...) \
+ dev_info(desc->dev, "%s: " fmt, desc->name, ##__VA_ARGS__)
+
/**
* proxy_timeout - Override for proxy vote timeouts
* -1: Use driver-specified timeout
@@ -43,146 +47,280 @@
static int proxy_timeout_ms = -1;
module_param(proxy_timeout_ms, int, S_IRUGO | S_IWUSR);
-enum pil_state {
- PIL_OFFLINE,
- PIL_ONLINE,
+/**
+ * struct pil_mdt - Representation of <name>.mdt file in memory
+ * @hdr: ELF32 header
+ * @phdr: ELF32 program headers
+ */
+struct pil_mdt {
+ struct elf32_hdr hdr;
+ struct elf32_phdr phdr[];
};
-static const char *pil_states[] = {
- [PIL_OFFLINE] = "OFFLINE",
- [PIL_ONLINE] = "ONLINE",
+/**
+ * struct pil_seg - memory map representing one segment
+ * @next: points to next seg mentor NULL if last segment
+ * @paddr: start address of segment
+ * @sz: size of segment
+ * @filesz: size of segment on disk
+ * @num: segment number
+ *
+ * Loosely based on an elf program header. Contains all necessary information
+ * to load and initialize a segment of the image in memory.
+ */
+struct pil_seg {
+ phys_addr_t paddr;
+ unsigned long sz;
+ unsigned long filesz;
+ int num;
+ struct list_head list;
};
-struct pil_device {
- struct pil_desc *desc;
- int count;
- enum pil_state state;
- struct mutex lock;
- struct device dev;
- struct module *owner;
-#ifdef CONFIG_DEBUG_FS
- struct dentry *dentry;
-#endif
+/**
+ * struct pil_priv - Private state for a pil_desc
+ * @proxy: work item used to run the proxy unvoting routine
+ * @wlock: wakelock to prevent suspend during pil_boot
+ * @wname: name of @wlock
+ * @desc: pointer to pil_desc this is private data for
+ * @seg: list of segments sorted by physical address
+ * @entry_addr: physical address where processor starts booting at
+ * @region_start: address where relocatable region starts or lowest address
+ * for non-relocatable images
+ * @region_end: address where relocatable region ends or highest address for
+ * non-relocatable images
+ *
+ * This struct contains data for a pil_desc that should not be exposed outside
+ * of this file. This structure points to the descriptor and the descriptor
+ * points to this structure so that PIL drivers can't access the private
+ * data of a descriptor but this file can access both.
+ */
+struct pil_priv {
struct delayed_work proxy;
struct wake_lock wlock;
- char wake_name[32];
+ char wname[32];
+ struct pil_desc *desc;
+ struct list_head segs;
+ phys_addr_t entry_addr;
+ phys_addr_t region_start;
+ phys_addr_t region_end;
};
-#define to_pil_device(d) container_of(d, struct pil_device, dev)
-
-static ssize_t name_show(struct device *dev, struct device_attribute *attr,
- char *buf)
+/**
+ * pil_get_entry_addr() - Retrieve the entry address of a peripheral image
+ * @desc: descriptor from pil_desc_init()
+ *
+ * Returns the physical address where the image boots at or 0 if unknown.
+ */
+phys_addr_t pil_get_entry_addr(struct pil_desc *desc)
{
- return snprintf(buf, PAGE_SIZE, "%s\n", to_pil_device(dev)->desc->name);
+ return desc->priv ? desc->priv->entry_addr : 0;
}
-
-static ssize_t state_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- enum pil_state state = to_pil_device(dev)->state;
- return snprintf(buf, PAGE_SIZE, "%s\n", pil_states[state]);
-}
-
-static struct device_attribute pil_attrs[] = {
- __ATTR_RO(name),
- __ATTR_RO(state),
- { },
-};
-
-struct bus_type pil_bus_type = {
- .name = "pil",
- .dev_attrs = pil_attrs,
-};
-
-static int __find_peripheral(struct device *dev, void *data)
-{
- struct pil_device *pdev = to_pil_device(dev);
- return !strncmp(pdev->desc->name, data, INT_MAX);
-}
-
-static struct pil_device *find_peripheral(const char *str)
-{
- struct device *dev;
-
- if (!str)
- return NULL;
-
- dev = bus_find_device(&pil_bus_type, NULL, (void *)str,
- __find_peripheral);
- return dev ? to_pil_device(dev) : NULL;
-}
+EXPORT_SYMBOL(pil_get_entry_addr);
static void pil_proxy_work(struct work_struct *work)
{
- struct pil_device *pil;
+ struct delayed_work *delayed = to_delayed_work(work);
+ struct pil_priv *priv = container_of(delayed, struct pil_priv, proxy);
+ struct pil_desc *desc = priv->desc;
- pil = container_of(work, struct pil_device, proxy.work);
- pil->desc->ops->proxy_unvote(pil->desc);
- wake_unlock(&pil->wlock);
+ desc->ops->proxy_unvote(desc);
+ wake_unlock(&priv->wlock);
+ module_put(desc->owner);
}
-static int pil_proxy_vote(struct pil_device *pil)
+static int pil_proxy_vote(struct pil_desc *desc)
{
int ret = 0;
+ struct pil_priv *priv = desc->priv;
- if (pil->desc->ops->proxy_vote) {
- wake_lock(&pil->wlock);
- ret = pil->desc->ops->proxy_vote(pil->desc);
+ if (desc->ops->proxy_vote) {
+ wake_lock(&priv->wlock);
+ ret = desc->ops->proxy_vote(desc);
if (ret)
- wake_unlock(&pil->wlock);
+ wake_unlock(&priv->wlock);
}
return ret;
}
-static void pil_proxy_unvote(struct pil_device *pil, unsigned long timeout)
+static void pil_proxy_unvote(struct pil_desc *desc, unsigned long timeout)
{
+ struct pil_priv *priv = desc->priv;
+
if (proxy_timeout_ms >= 0)
timeout = proxy_timeout_ms;
- if (timeout && pil->desc->ops->proxy_unvote)
- schedule_delayed_work(&pil->proxy, msecs_to_jiffies(timeout));
+ if (timeout && desc->ops->proxy_unvote) {
+ if (WARN_ON(!try_module_get(desc->owner)))
+ return;
+ schedule_delayed_work(&priv->proxy, msecs_to_jiffies(timeout));
+ }
+}
+
+static struct pil_seg *pil_init_seg(const struct pil_desc *desc,
+ const struct elf32_phdr *phdr, int num)
+{
+ struct pil_seg *seg;
+
+ if (memblock_overlaps_memory(phdr->p_paddr, phdr->p_memsz)) {
+ pil_err(desc, "kernel memory would be overwritten [%#08lx, %#08lx)\n",
+ (unsigned long)phdr->p_paddr,
+ (unsigned long)(phdr->p_paddr + phdr->p_memsz));
+ return ERR_PTR(-EPERM);
+ }
+
+ seg = kmalloc(sizeof(*seg), GFP_KERNEL);
+ if (!seg)
+ return ERR_PTR(-ENOMEM);
+ seg->num = num;
+ seg->paddr = phdr->p_paddr;
+ seg->filesz = phdr->p_filesz;
+ seg->sz = phdr->p_memsz;
+ INIT_LIST_HEAD(&seg->list);
+
+ return seg;
+}
+
+#define segment_is_hash(flag) (((flag) & (0x7 << 24)) == (0x2 << 24))
+
+static int segment_is_loadable(const struct elf32_phdr *p)
+{
+ return (p->p_type == PT_LOAD) && !segment_is_hash(p->p_flags);
+}
+
+static void pil_dump_segs(const struct pil_priv *priv)
+{
+ struct pil_seg *seg;
+
+ list_for_each_entry(seg, &priv->segs, list) {
+ pil_info(priv->desc, "%d: %#08zx %#08lx\n", seg->num,
+ seg->paddr, seg->paddr + seg->sz);
+ }
+}
+
+/*
+ * Ensure the entry address lies within the image limits.
+ */
+static int pil_init_entry_addr(struct pil_priv *priv, const struct pil_mdt *mdt)
+{
+ struct pil_seg *seg;
+
+ priv->entry_addr = mdt->hdr.e_entry;
+
+ if (priv->desc->flags & PIL_SKIP_ENTRY_CHECK)
+ return 0;
+
+ list_for_each_entry(seg, &priv->segs, list) {
+ if (priv->entry_addr >= seg->paddr &&
+ priv->entry_addr < seg->paddr + seg->sz)
+ return 0;
+ }
+ pil_err(priv->desc, "boot address %08zx not within range\n",
+ priv->entry_addr);
+ pil_dump_segs(priv);
+ return -EADDRNOTAVAIL;
+}
+
+static int pil_setup_region(struct pil_priv *priv, const struct pil_mdt *mdt)
+{
+ const struct elf32_phdr *phdr;
+ phys_addr_t min_addr, max_addr;
+ int i;
+
+ min_addr = (phys_addr_t)ULLONG_MAX;
+ max_addr = 0;
+
+ /* Find the image limits */
+ for (i = 0; i < mdt->hdr.e_phnum; i++) {
+ phdr = &mdt->phdr[i];
+ if (!segment_is_loadable(phdr))
+ continue;
+
+ min_addr = min(min_addr, phdr->p_paddr);
+ max_addr = max(max_addr, phdr->p_paddr + phdr->p_memsz);
+ }
+
+ priv->region_start = min_addr;
+ priv->region_end = max_addr;
+
+ return 0;
+}
+
+static int pil_cmp_seg(void *priv, struct list_head *a, struct list_head *b)
+{
+ struct pil_seg *seg_a = list_entry(a, struct pil_seg, list);
+ struct pil_seg *seg_b = list_entry(b, struct pil_seg, list);
+
+ return seg_a->paddr - seg_b->paddr;
+}
+
+static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt)
+{
+ struct pil_priv *priv = desc->priv;
+ const struct elf32_phdr *phdr;
+ struct pil_seg *seg;
+ int i, ret;
+
+ ret = pil_setup_region(priv, mdt);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < mdt->hdr.e_phnum; i++) {
+ phdr = &mdt->phdr[i];
+ if (!segment_is_loadable(phdr))
+ continue;
+
+ seg = pil_init_seg(desc, phdr, i);
+ if (IS_ERR(seg))
+ return PTR_ERR(seg);
+
+ list_add_tail(&seg->list, &priv->segs);
+ }
+ list_sort(NULL, &priv->segs, pil_cmp_seg);
+
+ return pil_init_entry_addr(priv, mdt);
+}
+
+static void pil_release_mmap(struct pil_desc *desc)
+{
+ struct pil_priv *priv = desc->priv;
+ struct pil_seg *p, *tmp;
+
+ list_for_each_entry_safe(p, tmp, &priv->segs, list) {
+ list_del(&p->list);
+ kfree(p);
+ }
}
#define IOMAP_SIZE SZ_4M
-static int load_segment(const struct elf32_phdr *phdr, unsigned num,
- struct pil_device *pil)
+static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)
{
int ret = 0, count, paddr;
char fw_name[30];
const struct firmware *fw = NULL;
const u8 *data;
+ int num = seg->num;
- if (memblock_overlaps_memory(phdr->p_paddr, phdr->p_memsz)) {
- dev_err(&pil->dev, "%s: kernel memory would be overwritten "
- "[%#08lx, %#08lx)\n", pil->desc->name,
- (unsigned long)phdr->p_paddr,
- (unsigned long)(phdr->p_paddr + phdr->p_memsz));
- return -EPERM;
- }
-
- if (phdr->p_filesz) {
+ if (seg->filesz) {
snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d",
- pil->desc->name, num);
- ret = request_firmware(&fw, fw_name, &pil->dev);
+ desc->name, num);
+ ret = request_firmware(&fw, fw_name, desc->dev);
if (ret) {
- dev_err(&pil->dev, "%s: Failed to locate blob %s\n",
- pil->desc->name, fw_name);
+ pil_err(desc, "Failed to locate blob %s\n", fw_name);
return ret;
}
- if (fw->size != phdr->p_filesz) {
- dev_err(&pil->dev, "%s: Blob size %u doesn't match "
- "%u\n", pil->desc->name, fw->size,
- phdr->p_filesz);
+ if (fw->size != seg->filesz) {
+ pil_err(desc, "Blob size %u doesn't match %lu\n",
+ fw->size, seg->filesz);
ret = -EPERM;
goto release_fw;
}
}
/* Load the segment into memory */
- count = phdr->p_filesz;
- paddr = phdr->p_paddr;
+ count = seg->filesz;
+ paddr = seg->paddr;
data = fw ? fw->data : NULL;
while (count > 0) {
int size;
@@ -191,8 +329,7 @@
size = min_t(size_t, IOMAP_SIZE, count);
buf = ioremap(paddr, size);
if (!buf) {
- dev_err(&pil->dev, "%s: Failed to map memory\n",
- pil->desc->name);
+ pil_err(desc, "Failed to map memory\n");
ret = -ENOMEM;
goto release_fw;
}
@@ -205,7 +342,7 @@
}
/* Zero out trailing memory */
- count = phdr->p_memsz - phdr->p_filesz;
+ count = seg->sz - seg->filesz;
while (count > 0) {
int size;
u8 __iomem *buf;
@@ -213,8 +350,7 @@
size = min_t(size_t, IOMAP_SIZE, count);
buf = ioremap(paddr, size);
if (!buf) {
- dev_err(&pil->dev, "%s: Failed to map memory\n",
- pil->desc->name);
+ pil_err(desc, "Failed to map memory\n");
ret = -ENOMEM;
goto release_fw;
}
@@ -225,12 +361,10 @@
paddr += size;
}
- if (pil->desc->ops->verify_blob) {
- ret = pil->desc->ops->verify_blob(pil->desc, phdr->p_paddr,
- phdr->p_memsz);
+ if (desc->ops->verify_blob) {
+ ret = desc->ops->verify_blob(desc, seg->paddr, seg->sz);
if (ret)
- dev_err(&pil->dev, "%s: Blob%u failed verification\n",
- pil->desc->name, num);
+ pil_err(desc, "Blob%u failed verification\n", num);
}
release_fw:
@@ -238,423 +372,180 @@
return ret;
}
-#define segment_is_hash(flag) (((flag) & (0x7 << 24)) == (0x2 << 24))
-
-static int segment_is_loadable(const struct elf32_phdr *p)
-{
- return (p->p_type == PT_LOAD) && !segment_is_hash(p->p_flags);
-}
-
-/* Sychronize request_firmware() with suspend */
+/* Synchronize request_firmware() with suspend */
static DECLARE_RWSEM(pil_pm_rwsem);
-static int load_image(struct pil_device *pil)
+/**
+ * pil_boot() - Load a peripheral image into memory and boot it
+ * @desc: descriptor from pil_desc_init()
+ *
+ * Returns 0 on success or -ERROR on failure.
+ */
+int pil_boot(struct pil_desc *desc)
{
- int i, ret;
+ int ret;
char fw_name[30];
- struct elf32_hdr *ehdr;
- const struct elf32_phdr *phdr;
+ const struct pil_mdt *mdt;
+ const struct elf32_hdr *ehdr;
+ struct pil_seg *seg;
const struct firmware *fw;
- unsigned long proxy_timeout = pil->desc->proxy_timeout;
+ unsigned long proxy_timeout = desc->proxy_timeout;
+ struct pil_priv *priv = desc->priv;
+
+ /* Reinitialize for new image */
+ pil_release_mmap(desc);
down_read(&pil_pm_rwsem);
- snprintf(fw_name, sizeof(fw_name), "%s.mdt", pil->desc->name);
- ret = request_firmware(&fw, fw_name, &pil->dev);
+ snprintf(fw_name, sizeof(fw_name), "%s.mdt", desc->name);
+ ret = request_firmware(&fw, fw_name, desc->dev);
if (ret) {
- dev_err(&pil->dev, "%s: Failed to locate %s\n",
- pil->desc->name, fw_name);
+ pil_err(desc, "Failed to locate %s\n", fw_name);
goto out;
}
if (fw->size < sizeof(*ehdr)) {
- dev_err(&pil->dev, "%s: Not big enough to be an elf header\n",
- pil->desc->name);
+ pil_err(desc, "Not big enough to be an elf header\n");
ret = -EIO;
goto release_fw;
}
- ehdr = (struct elf32_hdr *)fw->data;
+ mdt = (const struct pil_mdt *)fw->data;
+ ehdr = &mdt->hdr;
+
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
- dev_err(&pil->dev, "%s: Not an elf header\n", pil->desc->name);
+ pil_err(desc, "Not an elf header\n");
ret = -EIO;
goto release_fw;
}
if (ehdr->e_phnum == 0) {
- dev_err(&pil->dev, "%s: No loadable segments\n",
- pil->desc->name);
+ pil_err(desc, "No loadable segments\n");
ret = -EIO;
goto release_fw;
}
if (sizeof(struct elf32_phdr) * ehdr->e_phnum +
sizeof(struct elf32_hdr) > fw->size) {
- dev_err(&pil->dev, "%s: Program headers not within mdt\n",
- pil->desc->name);
+ pil_err(desc, "Program headers not within mdt\n");
ret = -EIO;
goto release_fw;
}
- ret = pil->desc->ops->init_image(pil->desc, fw->data, fw->size);
+ ret = pil_init_mmap(desc, mdt);
+ if (ret)
+ goto release_fw;
+
+ if (desc->ops->init_image)
+ ret = desc->ops->init_image(desc, fw->data, fw->size);
if (ret) {
- dev_err(&pil->dev, "%s: Invalid firmware metadata\n",
- pil->desc->name);
+ pil_err(desc, "Invalid firmware metadata\n");
goto release_fw;
}
- phdr = (const struct elf32_phdr *)(fw->data + sizeof(struct elf32_hdr));
- for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
- if (!segment_is_loadable(phdr))
- continue;
+ if (desc->ops->mem_setup)
+ ret = desc->ops->mem_setup(desc, priv->region_start,
+ priv->region_end - priv->region_start);
+ if (ret) {
+ pil_err(desc, "Memory setup error\n");
+ goto release_fw;
+ }
- ret = load_segment(phdr, i, pil);
- if (ret) {
- dev_err(&pil->dev, "%s: Failed to load segment %d\n",
- pil->desc->name, i);
+ list_for_each_entry(seg, &desc->priv->segs, list) {
+ ret = pil_load_seg(desc, seg);
+ if (ret)
goto release_fw;
- }
}
- ret = pil_proxy_vote(pil);
+ ret = pil_proxy_vote(desc);
if (ret) {
- dev_err(&pil->dev, "%s: Failed to proxy vote\n",
- pil->desc->name);
+ pil_err(desc, "Failed to proxy vote\n");
goto release_fw;
}
- ret = pil->desc->ops->auth_and_reset(pil->desc);
+ ret = desc->ops->auth_and_reset(desc);
if (ret) {
- dev_err(&pil->dev, "%s: Failed to bring out of reset\n",
- pil->desc->name);
+ pil_err(desc, "Failed to bring out of reset\n");
proxy_timeout = 0; /* Remove proxy vote immediately on error */
goto err_boot;
}
- dev_info(&pil->dev, "%s: Brought out of reset\n", pil->desc->name);
+ pil_info(desc, "Brought out of reset\n");
err_boot:
- pil_proxy_unvote(pil, proxy_timeout);
+ pil_proxy_unvote(desc, proxy_timeout);
release_fw:
release_firmware(fw);
out:
up_read(&pil_pm_rwsem);
+ if (ret)
+ pil_release_mmap(desc);
return ret;
}
-
-static void pil_set_state(struct pil_device *pil, enum pil_state state)
-{
- if (pil->state != state) {
- pil->state = state;
- sysfs_notify(&pil->dev.kobj, NULL, "state");
- }
-}
+EXPORT_SYMBOL(pil_boot);
/**
- * pil_get() - Load a peripheral into memory and take it out of reset
- * @name: pointer to a string containing the name of the peripheral to load
- *
- * This function returns a pointer if it succeeds. If an error occurs an
- * ERR_PTR is returned.
- *
- * If PIL is not enabled in the kernel, the value %NULL will be returned.
+ * pil_shutdown() - Shutdown a peripheral
+ * @desc: descriptor from pil_desc_init()
*/
-void *pil_get(const char *name)
+void pil_shutdown(struct pil_desc *desc)
{
- int ret;
- struct pil_device *pil;
- struct pil_device *pil_d;
- void *retval;
-
- if (!name)
- return NULL;
-
- pil = retval = find_peripheral(name);
- if (!pil)
- return ERR_PTR(-ENODEV);
- if (!try_module_get(pil->owner)) {
- put_device(&pil->dev);
- return ERR_PTR(-ENODEV);
- }
-
- pil_d = pil_get(pil->desc->depends_on);
- if (IS_ERR(pil_d)) {
- retval = pil_d;
- goto err_depends;
- }
-
- mutex_lock(&pil->lock);
- if (!pil->count) {
- ret = load_image(pil);
- if (ret) {
- retval = ERR_PTR(ret);
- goto err_load;
- }
- }
- pil->count++;
- pil_set_state(pil, PIL_ONLINE);
- mutex_unlock(&pil->lock);
-out:
- return retval;
-err_load:
- mutex_unlock(&pil->lock);
- pil_put(pil_d);
-err_depends:
- put_device(&pil->dev);
- module_put(pil->owner);
- goto out;
-}
-EXPORT_SYMBOL(pil_get);
-
-static void pil_shutdown(struct pil_device *pil)
-{
- pil->desc->ops->shutdown(pil->desc);
- if (proxy_timeout_ms == 0 && pil->desc->ops->proxy_unvote)
- pil->desc->ops->proxy_unvote(pil->desc);
+ struct pil_priv *priv = desc->priv;
+ desc->ops->shutdown(desc);
+ if (proxy_timeout_ms == 0 && desc->ops->proxy_unvote)
+ desc->ops->proxy_unvote(desc);
else
- flush_delayed_work(&pil->proxy);
-
- pil_set_state(pil, PIL_OFFLINE);
+ flush_delayed_work(&priv->proxy);
}
+EXPORT_SYMBOL(pil_shutdown);
/**
- * pil_put() - Inform PIL the peripheral no longer needs to be active
- * @peripheral_handle: pointer from a previous call to pil_get()
+ * pil_desc_init() - Initialize a pil descriptor
+ * @desc: descriptor to intialize
*
- * This doesn't imply that a peripheral is shutdown or in reset since another
- * driver could be using the peripheral.
+ * Initialize a pil descriptor for use by other pil functions. This function
+ * must be called before calling pil_boot() or pil_shutdown().
+ *
+ * Returns 0 for success and -ERROR on failure.
*/
-void pil_put(void *peripheral_handle)
+int pil_desc_init(struct pil_desc *desc)
{
- struct pil_device *pil_d, *pil = peripheral_handle;
-
- if (IS_ERR_OR_NULL(pil))
- return;
-
- mutex_lock(&pil->lock);
- if (WARN(!pil->count, "%s: %s: Reference count mismatch\n",
- pil->desc->name, __func__))
- goto err_out;
- if (!--pil->count)
- pil_shutdown(pil);
- mutex_unlock(&pil->lock);
-
- pil_d = find_peripheral(pil->desc->depends_on);
- module_put(pil->owner);
- if (pil_d) {
- pil_put(pil_d);
- put_device(&pil_d->dev);
- }
- put_device(&pil->dev);
- return;
-err_out:
- mutex_unlock(&pil->lock);
- return;
-}
-EXPORT_SYMBOL(pil_put);
-
-void pil_force_shutdown(const char *name)
-{
- struct pil_device *pil;
-
- pil = find_peripheral(name);
- if (!pil) {
- pr_err("%s: Couldn't find %s\n", __func__, name);
- return;
- }
-
- mutex_lock(&pil->lock);
- if (!WARN(!pil->count, "%s: %s: Reference count mismatch\n",
- pil->desc->name, __func__))
- pil_shutdown(pil);
- mutex_unlock(&pil->lock);
-
- put_device(&pil->dev);
-}
-EXPORT_SYMBOL(pil_force_shutdown);
-
-int pil_force_boot(const char *name)
-{
- int ret = -EINVAL;
- struct pil_device *pil;
-
- pil = find_peripheral(name);
- if (!pil) {
- pr_err("%s: Couldn't find %s\n", __func__, name);
- return -EINVAL;
- }
-
- mutex_lock(&pil->lock);
- if (!WARN(!pil->count, "%s: %s: Reference count mismatch\n",
- pil->desc->name, __func__))
- ret = load_image(pil);
- if (!ret)
- pil_set_state(pil, PIL_ONLINE);
- mutex_unlock(&pil->lock);
- put_device(&pil->dev);
-
- return ret;
-}
-EXPORT_SYMBOL(pil_force_boot);
-
-#ifdef CONFIG_DEBUG_FS
-static int msm_pil_debugfs_open(struct inode *inode, struct file *filp)
-{
- filp->private_data = inode->i_private;
- return 0;
-}
-
-static ssize_t msm_pil_debugfs_read(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- int r;
- char buf[40];
- struct pil_device *pil = filp->private_data;
-
- mutex_lock(&pil->lock);
- r = snprintf(buf, sizeof(buf), "%d\n", pil->count);
- mutex_unlock(&pil->lock);
- return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
-}
-
-static ssize_t msm_pil_debugfs_write(struct file *filp,
- const char __user *ubuf, size_t cnt, loff_t *ppos)
-{
- struct pil_device *pil = filp->private_data;
- char buf[4];
-
- if (cnt > sizeof(buf))
- return -EINVAL;
-
- if (copy_from_user(&buf, ubuf, cnt))
- return -EFAULT;
-
- if (!strncmp(buf, "get", 3)) {
- if (IS_ERR(pil_get(pil->desc->name)))
- return -EIO;
- } else if (!strncmp(buf, "put", 3))
- pil_put(pil);
- else
- return -EINVAL;
-
- return cnt;
-}
-
-static const struct file_operations msm_pil_debugfs_fops = {
- .open = msm_pil_debugfs_open,
- .read = msm_pil_debugfs_read,
- .write = msm_pil_debugfs_write,
-};
-
-static struct dentry *pil_base_dir;
-
-static int __init msm_pil_debugfs_init(void)
-{
- pil_base_dir = debugfs_create_dir("pil", NULL);
- if (!pil_base_dir) {
- pil_base_dir = NULL;
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void __exit msm_pil_debugfs_exit(void)
-{
- debugfs_remove_recursive(pil_base_dir);
-}
-
-static int msm_pil_debugfs_add(struct pil_device *pil)
-{
- if (!pil_base_dir)
- return -ENOMEM;
-
- pil->dentry = debugfs_create_file(pil->desc->name, S_IRUGO | S_IWUSR,
- pil_base_dir, pil, &msm_pil_debugfs_fops);
- return !pil->dentry ? -ENOMEM : 0;
-}
-
-static void msm_pil_debugfs_remove(struct pil_device *pil)
-{
- debugfs_remove(pil->dentry);
-}
-#else
-static int __init msm_pil_debugfs_init(void) { return 0; };
-static void __exit msm_pil_debugfs_exit(void) { return 0; };
-static int msm_pil_debugfs_add(struct pil_device *pil) { return 0; }
-static void msm_pil_debugfs_remove(struct pil_device *pil) { }
-#endif
-
-static void pil_device_release(struct device *dev)
-{
- struct pil_device *pil = to_pil_device(dev);
- wake_lock_destroy(&pil->wlock);
- mutex_destroy(&pil->lock);
- kfree(pil);
-}
-
-struct pil_device *msm_pil_register(struct pil_desc *desc)
-{
- int err;
- static atomic_t pil_count = ATOMIC_INIT(-1);
- struct pil_device *pil;
+ struct pil_priv *priv;
/* Ignore users who don't make any sense */
+ WARN(desc->ops->proxy_unvote && !desc->proxy_timeout,
+ "A proxy timeout of 0 was specified.\n");
if (WARN(desc->ops->proxy_unvote && !desc->ops->proxy_vote,
- "invalid proxy voting. ignoring\n"))
+ "Invalid proxy voting. Ignoring\n"))
((struct pil_reset_ops *)desc->ops)->proxy_unvote = NULL;
- WARN(desc->ops->proxy_unvote && !desc->proxy_timeout,
- "A proxy timeout of 0 ms was specified for %s. Specify one in "
- "desc->proxy_timeout.\n", desc->name);
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ desc->priv = priv;
+ priv->desc = desc;
- pil = kzalloc(sizeof(*pil), GFP_KERNEL);
- if (!pil)
- return ERR_PTR(-ENOMEM);
+ snprintf(priv->wname, sizeof(priv->wname), "pil-%s", desc->name);
+ wake_lock_init(&priv->wlock, WAKE_LOCK_SUSPEND, priv->wname);
+ INIT_DELAYED_WORK(&priv->proxy, pil_proxy_work);
+ INIT_LIST_HEAD(&priv->segs);
- mutex_init(&pil->lock);
- pil->desc = desc;
- pil->owner = desc->owner;
- pil->dev.parent = desc->dev;
- pil->dev.bus = &pil_bus_type;
- pil->dev.release = pil_device_release;
-
- snprintf(pil->wake_name, sizeof(pil->wake_name), "pil-%s", desc->name);
- wake_lock_init(&pil->wlock, WAKE_LOCK_SUSPEND, pil->wake_name);
- INIT_DELAYED_WORK(&pil->proxy, pil_proxy_work);
-
- dev_set_name(&pil->dev, "pil%d", atomic_inc_return(&pil_count));
- err = device_register(&pil->dev);
- if (err) {
- put_device(&pil->dev);
- wake_lock_destroy(&pil->wlock);
- mutex_destroy(&pil->lock);
- kfree(pil);
- return ERR_PTR(err);
- }
-
- err = msm_pil_debugfs_add(pil);
- if (err) {
- device_unregister(&pil->dev);
- return ERR_PTR(err);
- }
-
- return pil;
+ return 0;
}
-EXPORT_SYMBOL(msm_pil_register);
+EXPORT_SYMBOL(pil_desc_init);
-void msm_pil_unregister(struct pil_device *pil)
+/**
+ * pil_desc_release() - Release a pil descriptor
+ * @desc: descriptor to free
+ */
+void pil_desc_release(struct pil_desc *desc)
{
- if (IS_ERR_OR_NULL(pil))
- return;
+ struct pil_priv *priv = desc->priv;
- if (get_device(&pil->dev)) {
- mutex_lock(&pil->lock);
- WARN_ON(pil->count);
- flush_delayed_work_sync(&pil->proxy);
- msm_pil_debugfs_remove(pil);
- device_unregister(&pil->dev);
- mutex_unlock(&pil->lock);
- put_device(&pil->dev);
+ if (priv) {
+ flush_delayed_work(&priv->proxy);
+ wake_lock_destroy(&priv->wlock);
}
+ desc->priv = NULL;
+ kfree(priv);
}
-EXPORT_SYMBOL(msm_pil_unregister);
+EXPORT_SYMBOL(pil_desc_release);
static int pil_pm_notify(struct notifier_block *b, unsigned long event, void *p)
{
@@ -675,19 +566,13 @@
static int __init msm_pil_init(void)
{
- int ret = msm_pil_debugfs_init();
- if (ret)
- return ret;
- register_pm_notifier(&pil_pm_notifier);
- return bus_register(&pil_bus_type);
+ return register_pm_notifier(&pil_pm_notifier);
}
subsys_initcall(msm_pil_init);
static void __exit msm_pil_exit(void)
{
- bus_unregister(&pil_bus_type);
unregister_pm_notifier(&pil_pm_notifier);
- msm_pil_debugfs_exit();
}
module_exit(msm_pil_exit);
diff --git a/arch/arm/mach-msm/peripheral-loader.h b/arch/arm/mach-msm/peripheral-loader.h
index 405b73f..1c2faf7 100644
--- a/arch/arm/mach-msm/peripheral-loader.h
+++ b/arch/arm/mach-msm/peripheral-loader.h
@@ -14,28 +14,33 @@
struct device;
struct module;
+struct pil_priv;
/**
* struct pil_desc - PIL descriptor
* @name: string used for pil_get()
- * @depends_on: booted before this peripheral
* @dev: parent device
* @ops: callback functions
* @owner: module the descriptor belongs to
* @proxy_timeout: delay in ms until proxy vote is removed
+ * @flags: bitfield for image flags
+ * @priv: DON'T USE - internal only
*/
struct pil_desc {
const char *name;
- const char *depends_on;
struct device *dev;
const struct pil_reset_ops *ops;
struct module *owner;
unsigned long proxy_timeout;
+ unsigned long flags;
+#define PIL_SKIP_ENTRY_CHECK BIT(0)
+ struct pil_priv *priv;
};
/**
* struct pil_reset_ops - PIL operations
* @init_image: prepare an image for authentication
+ * @mem_setup: prepare the image memory region
* @verify_blob: authenticate a program segment, called once for each loadable
* program segment (optional)
* @proxy_vote: make proxy votes before auth_and_reset (optional)
@@ -46,6 +51,7 @@
struct pil_reset_ops {
int (*init_image)(struct pil_desc *pil, const u8 *metadata,
size_t size);
+ int (*mem_setup)(struct pil_desc *pil, phys_addr_t addr, size_t size);
int (*verify_blob)(struct pil_desc *pil, u32 phy_addr, size_t size);
int (*proxy_vote)(struct pil_desc *pil);
int (*auth_and_reset)(struct pil_desc *pil);
@@ -53,17 +59,21 @@
int (*shutdown)(struct pil_desc *pil);
};
-struct pil_device;
-
#ifdef CONFIG_MSM_PIL
-extern struct pil_device *msm_pil_register(struct pil_desc *desc);
-extern void msm_pil_unregister(struct pil_device *pil);
+extern int pil_desc_init(struct pil_desc *desc);
+extern int pil_boot(struct pil_desc *desc);
+extern void pil_shutdown(struct pil_desc *desc);
+extern void pil_desc_release(struct pil_desc *desc);
+extern phys_addr_t pil_get_entry_addr(struct pil_desc *desc);
#else
-static inline struct pil_device *msm_pil_register(struct pil_desc *desc)
+static inline int pil_desc_init(struct pil_desc *desc) { return 0; }
+static inline int pil_boot(struct pil_desc *desc) { return 0; }
+static inline void pil_shutdown(struct pil_desc *desc) { }
+static inline void pil_desc_release(struct pil_desc *desc) { }
+static inline phys_addr_t pil_get_entry_addr(struct pil_desc *desc)
{
- return NULL;
+ return 0;
}
-static inline void msm_pil_unregister(struct pil_device *pil) { }
#endif
#endif
diff --git a/arch/arm/mach-msm/pil-dsps.c b/arch/arm/mach-msm/pil-dsps.c
index c074086..e19db58 100644
--- a/arch/arm/mach-msm/pil-dsps.c
+++ b/arch/arm/mach-msm/pil-dsps.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/elf.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/delay.h>
@@ -23,7 +22,6 @@
#include <mach/msm_iomap.h>
#include <mach/subsystem_restart.h>
#include <mach/msm_smsm.h>
-#include <mach/peripheral-loader.h>
#include "peripheral-loader.h"
#include "scm-pas.h"
@@ -40,7 +38,6 @@
#define PPSS_WDOG_UNMASKED_INT_EN 0x1808
struct dsps_data {
- struct pil_device *pil;
struct pil_desc desc;
struct subsys_device *subsys;
struct subsys_desc subsys_desc;
@@ -165,19 +162,15 @@
static int dsps_start(const struct subsys_desc *desc)
{
- void *ret;
struct dsps_data *drv = desc_to_drv(desc);
- ret = pil_get(drv->desc.name);
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- return 0;
+ return pil_boot(&drv->desc);
}
static void dsps_stop(const struct subsys_desc *desc)
{
struct dsps_data *drv = desc_to_drv(desc);
- pil_put(drv->pil);
+ pil_shutdown(&drv->desc);
}
static int dsps_shutdown(const struct subsys_desc *desc)
@@ -188,7 +181,7 @@
writel_relaxed(0, drv->ppss_base + PPSS_WDOG_UNMASKED_INT_EN);
mb(); /* Make sure wdog is disabled before shutting down */
}
- pil_force_shutdown(drv->desc.name);
+ pil_shutdown(&drv->desc);
return 0;
}
@@ -196,7 +189,7 @@
{
struct dsps_data *drv = desc_to_drv(desc);
- pil_force_boot(drv->desc.name);
+ pil_boot(&drv->desc);
atomic_set(&drv->crash_in_progress, 0);
enable_irq(drv->wdog_irq);
@@ -273,6 +266,7 @@
desc->name = pdev->dev.platform_data;
desc->dev = &pdev->dev;
desc->owner = THIS_MODULE;
+ desc->flags = PIL_SKIP_ENTRY_CHECK;
if (pas_supported(PAS_DSPS) > 0) {
desc->ops = &pil_dsps_ops_trusted;
dev_info(&pdev->dev, "using secure boot\n");
@@ -280,9 +274,9 @@
desc->ops = &pil_dsps_ops;
dev_info(&pdev->dev, "using non-secure boot\n");
}
- drv->pil = msm_pil_register(desc);
- if (IS_ERR(drv->pil))
- return PTR_ERR(drv->pil);
+ ret = pil_desc_init(desc);
+ if (ret)
+ return ret;
drv->fw_ramdump_segments[0].address = 0x12000000;
drv->fw_ramdump_segments[0].size = 0x28000;
@@ -292,7 +286,7 @@
drv->fw_ramdump_segments[2].size = 0x4000;
drv->fw_ramdump_segments[3].address = 0x8fe00000;
drv->fw_ramdump_segments[3].size = 0x100000;
- drv->ramdump_dev = create_ramdump_device("dsps");
+ drv->ramdump_dev = create_ramdump_device("dsps", &pdev->dev);
if (!drv->ramdump_dev) {
ret = -ENOMEM;
goto err_ramdump;
@@ -300,7 +294,7 @@
drv->smem_ramdump_segments[0].address = PHYS_OFFSET - SZ_2M;
drv->smem_ramdump_segments[0].size = SZ_2M;
- drv->smem_ramdump_dev = create_ramdump_device("smem-dsps");
+ drv->smem_ramdump_dev = create_ramdump_device("smem-dsps", &pdev->dev);
if (!drv->smem_ramdump_dev) {
ret = -ENOMEM;
goto err_smem_ramdump;
@@ -350,7 +344,7 @@
err_smem_ramdump:
destroy_ramdump_device(drv->ramdump_dev);
err_ramdump:
- msm_pil_unregister(drv->pil);
+ pil_desc_release(desc);
return ret;
}
@@ -362,7 +356,7 @@
subsys_unregister(drv->subsys);
destroy_ramdump_device(drv->smem_ramdump_dev);
destroy_ramdump_device(drv->ramdump_dev);
- msm_pil_unregister(drv->pil);
+ pil_desc_release(&drv->desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c
index 0c8f4e3..338253c 100644
--- a/arch/arm/mach-msm/pil-gss.c
+++ b/arch/arm/mach-msm/pil-gss.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/elf.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -31,7 +30,6 @@
#include <mach/msm_bus_board.h>
#include <mach/msm_bus.h>
#include <mach/subsystem_restart.h>
-#include <mach/peripheral-loader.h>
#include "peripheral-loader.h"
#include "scm-pas.h"
@@ -67,9 +65,8 @@
struct gss_data {
void __iomem *base;
void __iomem *qgic2_base;
- unsigned long start_addr;
struct clk *xo;
- struct pil_device *pil;
+ struct pil_desc pil_desc;
struct miscdevice misc_dev;
struct subsys_device *subsys;
struct subsys_desc subsys_desc;
@@ -80,15 +77,6 @@
struct ramdump_device *smem_ramdump_dev;
};
-static int pil_gss_init_image(struct pil_desc *pil, const u8 *metadata,
- size_t size)
-{
- const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
- struct gss_data *drv = dev_get_drvdata(pil->dev);
- drv->start_addr = ehdr->e_entry;
- return 0;
-}
-
static int make_gss_proxy_votes(struct pil_desc *pil)
{
int ret;
@@ -213,7 +201,7 @@
{
struct gss_data *drv = dev_get_drvdata(pil->dev);
void __iomem *base = drv->base;
- unsigned long start_addr = drv->start_addr;
+ unsigned long start_addr = pil_get_entry_addr(pil);
int ret;
/* Unhalt bus port. */
@@ -258,7 +246,6 @@
}
static struct pil_reset_ops pil_gss_ops = {
- .init_image = pil_gss_init_image,
.auth_and_reset = pil_gss_reset,
.shutdown = pil_gss_shutdown,
.proxy_vote = make_gss_proxy_votes,
@@ -373,14 +360,10 @@
static int gss_start(const struct subsys_desc *desc)
{
- void *ret;
struct gss_data *drv;
drv = container_of(desc, struct gss_data, subsys_desc);
- ret = pil_get("gss");
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- return 0;
+ return pil_boot(&drv->pil_desc);
}
static void gss_stop(const struct subsys_desc *desc)
@@ -388,14 +371,14 @@
struct gss_data *drv;
drv = container_of(desc, struct gss_data, subsys_desc);
- pil_put(drv->pil);
+ pil_shutdown(&drv->pil_desc);
}
static int gss_shutdown(const struct subsys_desc *desc)
{
struct gss_data *drv = container_of(desc, struct gss_data, subsys_desc);
- pil_force_shutdown("gss");
+ pil_shutdown(&drv->pil_desc);
disable_irq_nosync(drv->irq);
return 0;
@@ -405,7 +388,7 @@
{
struct gss_data *drv = container_of(desc, struct gss_data, subsys_desc);
- pil_force_boot("gss");
+ pil_boot(&drv->pil_desc);
enable_irq(drv->irq);
return 0;
}
@@ -467,8 +450,10 @@
struct gss_data *drv = container_of(c, struct gss_data, misc_dev);
drv->subsys_handle = subsystem_get("gss");
- if (!drv->subsys_handle)
- pr_debug("%s - subsystem_get returned NULL\n", __func__);
+ if (IS_ERR(drv->subsys_handle)) {
+ pr_debug("%s - subsystem_get returned error\n", __func__);
+ return PTR_ERR(drv->subsys_handle);
+ }
return 0;
}
@@ -510,9 +495,7 @@
if (!drv->base)
return -ENOMEM;
- desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
- if (!desc)
- return -ENOMEM;
+ desc = &drv->pil_desc;
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!res)
@@ -543,14 +526,13 @@
desc->ops = &pil_gss_ops;
dev_info(&pdev->dev, "using non-secure boot\n");
}
+ ret = pil_desc_init(desc);
+ if (ret)
+ return ret;
+
/* Force into low power mode because hardware doesn't do this */
desc->ops->shutdown(desc);
- drv->pil = msm_pil_register(desc);
- if (IS_ERR(drv->pil)) {
- return PTR_ERR(drv->pil);
- }
-
ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
smsm_state_cb, drv);
if (ret < 0)
@@ -579,13 +561,13 @@
if (ret)
goto err_misc;
- drv->ramdump_dev = create_ramdump_device("gss");
+ drv->ramdump_dev = create_ramdump_device("gss", &pdev->dev);
if (!drv->ramdump_dev) {
ret = -ENOMEM;
goto err_ramdump;
}
- drv->smem_ramdump_dev = create_ramdump_device("smem-gss");
+ drv->smem_ramdump_dev = create_ramdump_device("smem-gss", &pdev->dev);
if (!drv->smem_ramdump_dev) {
ret = -ENOMEM;
goto err_smem;
@@ -605,7 +587,7 @@
err_misc:
subsys_unregister(drv->subsys);
err_subsys:
- msm_pil_unregister(drv->pil);
+ pil_desc_release(desc);
return ret;
}
@@ -617,7 +599,7 @@
destroy_ramdump_device(drv->ramdump_dev);
misc_deregister(&drv->misc_dev);
subsys_unregister(drv->subsys);
- msm_pil_unregister(drv->pil);
+ pil_desc_release(&drv->pil_desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index ad27cd1..00b5024 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.c
@@ -15,7 +15,6 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/ioport.h>
-#include <linux/elf.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk.h>
@@ -26,7 +25,6 @@
#include <mach/msm_iomap.h>
#include <mach/subsystem_restart.h>
#include <mach/msm_smsm.h>
-#include <mach/peripheral-loader.h>
#include "modem_notifier.h"
#include "peripheral-loader.h"
@@ -59,12 +57,12 @@
struct modem_data {
void __iomem *base;
void __iomem *wdog;
- unsigned long start_addr;
struct pil_device *pil;
struct clk *xo;
struct notifier_block notifier;
int ignore_smsm_ack;
int irq;
+ struct pil_desc pil_desc;
struct subsys_device *subsys;
struct subsys_desc subsys_desc;
struct delayed_work unlock_work;
@@ -91,19 +89,11 @@
clk_disable_unprepare(drv->xo);
}
-static int modem_init_image(struct pil_desc *pil, const u8 *metadata,
- size_t size)
-{
- const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
- struct modem_data *drv = dev_get_drvdata(pil->dev);
- drv->start_addr = ehdr->e_entry;
- return 0;
-}
-
static int modem_reset(struct pil_desc *pil)
{
u32 reg;
const struct modem_data *drv = dev_get_drvdata(pil->dev);
+ unsigned long start_addr = pil_get_entry_addr(pil);
/* Put modem AHB0,1,2 clocks into reset */
writel_relaxed(BIT(0) | BIT(1), MAHB0_SFAB_PORT_RESET);
@@ -168,7 +158,7 @@
mb();
/* Setup exception vector table base address */
- writel_relaxed(drv->start_addr | 0x1, drv->base + MARM_BOOT_CONTROL);
+ writel_relaxed(start_addr | 0x1, drv->base + MARM_BOOT_CONTROL);
/* Wait for vector table to be setup */
mb();
@@ -219,7 +209,6 @@
}
static struct pil_reset_ops pil_modem_ops = {
- .init_image = modem_init_image,
.auth_and_reset = modem_reset,
.shutdown = modem_pil_shutdown,
.proxy_vote = make_modem_proxy_votes,
@@ -344,14 +333,10 @@
static int modem_start(const struct subsys_desc *subsys)
{
- void *ret;
struct modem_data *drv;
drv = container_of(subsys, struct modem_data, subsys_desc);
- ret = pil_get("modem");
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- return 0;
+ return pil_boot(&drv->pil_desc);
}
static void modem_stop(const struct subsys_desc *subsys)
@@ -359,7 +344,7 @@
struct modem_data *drv;
drv = container_of(subsys, struct modem_data, subsys_desc);
- pil_put(drv->pil);
+ pil_shutdown(&drv->pil_desc);
}
static int modem_shutdown(const struct subsys_desc *subsys)
@@ -389,7 +374,7 @@
/* Wait here to allow the modem to clean up caches, etc. */
msleep(20);
- pil_force_shutdown("modem");
+ pil_shutdown(&drv->pil_desc);
disable_irq_nosync(drv->irq);
return 0;
@@ -401,7 +386,7 @@
int ret;
drv = container_of(subsys, struct modem_data, subsys_desc);
- ret = pil_force_boot("modem");
+ ret = pil_boot(&drv->pil_desc);
enable_irq(drv->irq);
return ret;
@@ -452,10 +437,6 @@
if (IS_ERR(drv->xo))
return PTR_ERR(drv->xo);
- desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
- if (!desc)
- return -ENOMEM;
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!res)
return -EINVAL;
@@ -464,8 +445,8 @@
if (!drv->wdog)
return -ENOMEM;
+ desc = &drv->pil_desc;
desc->name = "modem";
- desc->depends_on = "q6";
desc->dev = &pdev->dev;
desc->owner = THIS_MODULE;
desc->proxy_timeout = 10000;
@@ -477,9 +458,9 @@
desc->ops = &pil_modem_ops;
dev_info(&pdev->dev, "using non-secure boot\n");
}
- drv->pil = msm_pil_register(desc);
- if (IS_ERR(drv->pil))
- return PTR_ERR(drv->pil);
+ ret = pil_desc_init(desc);
+ if (ret)
+ return ret;
drv->notifier.notifier_call = modem_notif_handler,
ret = modem_register_notifier(&drv->notifier);
@@ -487,7 +468,7 @@
goto err_notify;
drv->subsys_desc.name = "modem";
- drv->subsys_desc.depends_on = "q6";
+ drv->subsys_desc.depends_on = "adsp";
drv->subsys_desc.dev = &pdev->dev;
drv->subsys_desc.owner = THIS_MODULE;
drv->subsys_desc.start = modem_start;
@@ -506,7 +487,7 @@
goto err_subsys;
}
- drv->ramdump_dev = create_ramdump_device("modem");
+ drv->ramdump_dev = create_ramdump_device("modem", &pdev->dev);
if (!drv->ramdump_dev) {
ret = -ENOMEM;
goto err_ramdump;
@@ -525,7 +506,7 @@
err_subsys:
modem_unregister_notifier(&drv->notifier);
err_notify:
- msm_pil_unregister(drv->pil);
+ pil_desc_release(desc);
return ret;
}
@@ -536,7 +517,7 @@
destroy_ramdump_device(drv->ramdump_dev);
subsys_unregister(drv->subsys);
modem_unregister_notifier(&drv->notifier);
- msm_pil_unregister(drv->pil);
+ pil_desc_release(&drv->pil_desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-pronto.c b/arch/arm/mach-msm/pil-pronto.c
index 04b3a21..752c829 100644
--- a/arch/arm/mach-msm/pil-pronto.c
+++ b/arch/arm/mach-msm/pil-pronto.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/elf.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -27,9 +26,7 @@
#include <linux/workqueue.h>
#include <linux/wcnss_wlan.h>
-#include <mach/peripheral-loader.h>
#include <mach/subsystem_restart.h>
-#include <mach/peripheral-loader.h>
#include <mach/msm_smsm.h>
#include "peripheral-loader.h"
@@ -74,7 +71,6 @@
void __iomem *base;
void __iomem *reset_base;
void __iomem *axi_halt_base;
- unsigned long start_addr;
struct pil_device *pil;
struct pil_desc desc;
struct subsys_device *subsys;
@@ -116,22 +112,13 @@
clk_disable_unprepare(drv->cxo);
}
-static int pil_pronto_init_image(struct pil_desc *pil, const u8 *metadata,
- size_t size)
-{
- const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
- struct pronto_data *drv = dev_get_drvdata(pil->dev);
- drv->start_addr = ehdr->e_entry;
- return 0;
-}
-
static int pil_pronto_reset(struct pil_desc *pil)
{
u32 reg;
int rc;
struct pronto_data *drv = dev_get_drvdata(pil->dev);
void __iomem *base = drv->base;
- unsigned long start_addr = drv->start_addr;
+ unsigned long start_addr = pil_get_entry_addr(pil);
/* Deassert reset to subsystem and wait for propagation */
reg = readl_relaxed(drv->reset_base);
@@ -234,7 +221,6 @@
}
static struct pil_reset_ops pil_pronto_ops = {
- .init_image = pil_pronto_init_image,
.auth_and_reset = pil_pronto_reset,
.shutdown = pil_pronto_shutdown,
.proxy_vote = pil_pronto_make_proxy_vote,
@@ -245,19 +231,14 @@
static int pronto_start(const struct subsys_desc *desc)
{
- void *ret;
struct pronto_data *drv = subsys_to_drv(desc);
-
- ret = pil_get(drv->desc.name);
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- return 0;
+ return pil_boot(&drv->desc);
}
static void pronto_stop(const struct subsys_desc *desc)
{
struct pronto_data *drv = subsys_to_drv(desc);
- pil_put(drv->pil);
+ pil_shutdown(&drv->desc);
}
static void log_wcnss_sfr(void)
@@ -338,7 +319,7 @@
{
struct pronto_data *drv = subsys_to_drv(subsys);
- pil_force_shutdown("wcnss");
+ pil_shutdown(&drv->desc);
flush_delayed_work(&drv->cancel_vote_work);
wcnss_flush_delayed_boot_votes();
disable_irq_nosync(drv->irq);
@@ -358,7 +339,9 @@
WCNSS_WLAN_SWITCH_ON);
if (!ret) {
msleep(1000);
- pil_force_boot("wcnss");
+ ret = pil_boot(&drv->desc);
+ if (ret)
+ return ret;
}
drv->restart_inprogress = false;
enable_irq(drv->irq);
@@ -456,9 +439,9 @@
if (IS_ERR(drv->cxo))
return PTR_ERR(drv->cxo);
- drv->pil = msm_pil_register(desc);
- if (IS_ERR(drv->pil))
- return PTR_ERR(drv->pil);
+ ret = pil_desc_init(desc);
+ if (ret)
+ return ret;
ret = smsm_state_cb_register(SMSM_WCNSS_STATE, SMSM_RESET,
smsm_state_cb_hdlr, drv);
@@ -502,7 +485,7 @@
smsm_state_cb_deregister(SMSM_WCNSS_STATE, SMSM_RESET,
smsm_state_cb_hdlr, drv);
err_smsm:
- msm_pil_unregister(drv->pil);
+ pil_desc_release(desc);
return ret;
}
@@ -512,7 +495,7 @@
subsys_unregister(drv->subsys);
smsm_state_cb_deregister(SMSM_WCNSS_STATE, SMSM_RESET,
smsm_state_cb_hdlr, drv);
- msm_pil_unregister(drv->pil);
+ pil_desc_release(&drv->desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-q6v3.c b/arch/arm/mach-msm/pil-q6v3.c
index 9de9c60..49b6390 100644
--- a/arch/arm/mach-msm/pil-q6v3.c
+++ b/arch/arm/mach-msm/pil-q6v3.c
@@ -16,7 +16,6 @@
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <linux/elf.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/workqueue.h>
@@ -25,7 +24,6 @@
#include <mach/msm_iomap.h>
#include <mach/subsystem_restart.h>
#include <mach/scm.h>
-#include <mach/peripheral-loader.h>
#include "ramdump.h"
#include "peripheral-loader.h"
@@ -73,7 +71,6 @@
* @base: register base
* @wk_base: wakeup register base
* @wd_base: watchdog register base
- * @start_addr: address that processor starts running at
* @irq: watchdog irq
* @pil: peripheral handle
* @subsys: subsystem restart handle
@@ -86,9 +83,8 @@
void __iomem *base;
void __iomem *wk_base;
void __iomem *wd_base;
- unsigned long start_addr;
int irq;
- struct pil_device *pil;
+ struct pil_desc pil_desc;
struct subsys_device *subsys;
struct subsys_desc subsys_desc;
struct work_struct fatal_wrk;
@@ -96,15 +92,6 @@
struct ramdump_device *ramdump_dev;
};
-static int pil_q6v3_init_image(struct pil_desc *pil, const u8 *metadata,
- size_t size)
-{
- const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
- struct q6v3_data *drv = dev_get_drvdata(pil->dev);
- drv->start_addr = ehdr->e_entry;
- return 0;
-}
-
static void pil_q6v3_remove_proxy_votes(struct pil_desc *pil)
{
struct q6v3_data *drv = dev_get_drvdata(pil->dev);
@@ -128,6 +115,7 @@
{
u32 reg;
struct q6v3_data *drv = dev_get_drvdata(pil->dev);
+ unsigned long start_addr = pil_get_entry_addr(pil);
/* Put Q6 into reset */
reg = readl_relaxed(LCC_Q6_FUNC);
@@ -152,7 +140,7 @@
/* Wait for clocks to be enabled */
mb();
/* Program boot address */
- writel_relaxed((drv->start_addr >> 12) & 0xFFFFF,
+ writel_relaxed((start_addr >> 12) & 0xFFFFF,
drv->base + QDSP6SS_RST_EVB);
writel_relaxed(Q6_STRAP_TCM_CONFIG | Q6_STRAP_TCM_BASE,
@@ -196,7 +184,6 @@
}
static struct pil_reset_ops pil_q6v3_ops = {
- .init_image = pil_q6v3_init_image,
.auth_and_reset = pil_q6v3_reset,
.shutdown = pil_q6v3_shutdown,
.proxy_vote = pil_q6v3_make_proxy_votes,
@@ -250,14 +237,10 @@
static int lpass_q6_start(const struct subsys_desc *subsys)
{
- void *ret;
struct q6v3_data *drv;
drv = container_of(subsys, struct q6v3_data, subsys_desc);
- ret = pil_get("q6");
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- return 0;
+ return pil_boot(&drv->pil_desc);
}
static void lpass_q6_stop(const struct subsys_desc *subsys)
@@ -265,7 +248,7 @@
struct q6v3_data *drv;
drv = container_of(subsys, struct q6v3_data, subsys_desc);
- pil_put(drv->pil);
+ pil_shutdown(&drv->pil_desc);
}
static int lpass_q6_shutdown(const struct subsys_desc *subsys)
@@ -277,7 +260,7 @@
writel_relaxed(0x0, drv->wd_base + 0x24);
mb();
- pil_force_shutdown("q6");
+ pil_shutdown(&drv->pil_desc);
disable_irq_nosync(drv->irq);
return 0;
@@ -289,7 +272,7 @@
int ret;
drv = container_of(subsys, struct q6v3_data, subsys_desc);
- ret = pil_force_boot("q6");
+ ret = pil_boot(&drv->pil_desc);
enable_irq(drv->irq);
return ret;
}
@@ -375,10 +358,7 @@
if (IS_ERR(drv->pll))
return PTR_ERR(drv->pll);
- desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
- if (!drv)
- return -ENOMEM;
-
+ desc = &drv->pil_desc;
desc->name = "q6";
desc->dev = &pdev->dev;
desc->owner = THIS_MODULE;
@@ -392,11 +372,11 @@
dev_info(&pdev->dev, "using non-secure boot\n");
}
- drv->pil = msm_pil_register(desc);
- if (IS_ERR(drv->pil))
- return PTR_ERR(drv->pil);
+ ret = pil_desc_init(desc);
+ if (ret)
+ return ret;
- drv->subsys_desc.name = "lpass";
+ drv->subsys_desc.name = "adsp";
drv->subsys_desc.dev = &pdev->dev;
drv->subsys_desc.owner = THIS_MODULE;
drv->subsys_desc.start = lpass_q6_start;
@@ -408,7 +388,7 @@
INIT_WORK(&drv->fatal_wrk, q6_fatal_fn);
- drv->ramdump_dev = create_ramdump_device("lpass");
+ drv->ramdump_dev = create_ramdump_device("lpass", &pdev->dev);
if (!drv->ramdump_dev) {
ret = -ENOMEM;
goto err_ramdump;
@@ -433,7 +413,7 @@
err_subsys:
destroy_ramdump_device(drv->ramdump_dev);
err_ramdump:
- msm_pil_unregister(drv->pil);
+ pil_desc_release(desc);
return ret;
}
@@ -442,7 +422,7 @@
struct q6v3_data *drv = platform_get_drvdata(pdev);
subsys_unregister(drv->subsys);
destroy_ramdump_device(drv->ramdump_dev);
- msm_pil_unregister(drv->pil);
+ pil_desc_release(&drv->pil_desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-q6v4-lpass.c b/arch/arm/mach-msm/pil-q6v4-lpass.c
index c32cf5c..076caa16 100644
--- a/arch/arm/mach-msm/pil-q6v4-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v4-lpass.c
@@ -22,7 +22,6 @@
#include <linux/delay.h>
#include <mach/scm.h>
-#include <mach/peripheral-loader.h>
#include <mach/subsystem_restart.h>
#include <mach/subsystem_notif.h>
@@ -43,7 +42,6 @@
void *ramdump_dev;
struct work_struct work;
int loadable;
- void *pil;
};
static int pil_q6v4_lpass_boot(struct pil_desc *pil)
@@ -71,7 +69,6 @@
}
static struct pil_reset_ops pil_q6v4_lpass_ops = {
- .init_image = pil_q6v4_init_image,
.auth_and_reset = pil_q6v4_lpass_boot,
.shutdown = pil_q6v4_lpass_shutdown,
.proxy_vote = pil_q6v4_make_proxy_votes,
@@ -197,19 +194,17 @@
{
struct lpass_q6v4 *drv = subsys_to_lpass(desc);
- if (drv->loadable) {
- drv->pil = pil_get("q6");
- if (IS_ERR(drv->pil))
- return PTR_ERR(drv->pil);
- }
+ if (drv->loadable)
+ return pil_boot(&drv->q6.desc);
return 0;
}
static void lpass_stop(const struct subsys_desc *desc)
{
struct lpass_q6v4 *drv = subsys_to_lpass(desc);
+
if (drv->loadable)
- pil_put(drv->pil);
+ pil_shutdown(&drv->q6.desc);
}
static int lpass_shutdown(const struct subsys_desc *subsys)
@@ -218,7 +213,7 @@
send_q6_nmi();
if (drv->loadable)
- pil_force_shutdown("q6");
+ pil_shutdown(&drv->q6.desc);
disable_irq_nosync(drv->q6.wdog_irq);
return 0;
@@ -230,7 +225,7 @@
int ret = 0;
if (drv->loadable)
- ret = pil_force_boot("q6");
+ ret = pil_boot(&drv->q6.desc);
enable_irq(drv->q6.wdog_irq);
return ret;
@@ -320,12 +315,12 @@
dev_info(&pdev->dev, "using non-secure boot\n");
}
- q6->pil = msm_pil_register(desc);
- if (IS_ERR(q6->pil))
- return PTR_ERR(q6->pil);
+ ret = pil_desc_init(desc);
+ if (ret)
+ return ret;
}
- drv->subsys_desc.name = "lpass";
+ drv->subsys_desc.name = "adsp";
drv->subsys_desc.dev = &pdev->dev;
drv->subsys_desc.owner = THIS_MODULE;
drv->subsys_desc.start = lpass_start;
@@ -337,7 +332,7 @@
INIT_WORK(&drv->work, lpass_fatal_fn);
- drv->ramdump_dev = create_ramdump_device("lpass");
+ drv->ramdump_dev = create_ramdump_device("lpass", &pdev->dev);
if (!drv->ramdump_dev) {
ret = -ENOMEM;
goto err_ramdump;
@@ -385,7 +380,7 @@
destroy_ramdump_device(drv->ramdump_dev);
err_ramdump:
if (drv->loadable)
- msm_pil_unregister(q6->pil);
+ pil_desc_release(desc);
return ret;
}
@@ -399,7 +394,7 @@
subsys_unregister(drv->subsys);
destroy_ramdump_device(drv->ramdump_dev);
if (drv->loadable)
- msm_pil_unregister(drv->q6.pil);
+ pil_desc_release(&drv->q6.desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-q6v4-mss.c b/arch/arm/mach-msm/pil-q6v4-mss.c
index aa59bbd..e42bcdb 100644
--- a/arch/arm/mach-msm/pil-q6v4-mss.c
+++ b/arch/arm/mach-msm/pil-q6v4-mss.c
@@ -23,7 +23,6 @@
#include <mach/msm_iomap.h>
#include <mach/subsystem_restart.h>
#include <mach/msm_smsm.h>
-#include <mach/peripheral-loader.h>
#include "smd_private.h"
#include "ramdump.h"
@@ -123,7 +122,6 @@
}
static struct pil_reset_ops pil_q6v4_modem_ops = {
- .init_image = pil_q6v4_init_image,
.auth_and_reset = pil_q6v4_modem_boot,
.shutdown = pil_q6v4_modem_shutdown,
.proxy_vote = pil_q6v4_make_proxy_votes,
@@ -173,20 +171,26 @@
static int modem_start(const struct subsys_desc *desc)
{
struct q6v4_modem *drv = desc_to_modem(desc);
+ int ret = 0;
if (drv->loadable) {
- drv->pil = pil_get("modem");
- if (IS_ERR(drv->pil))
- return PTR_ERR(drv->pil);
+ ret = pil_boot(&drv->q6_fw.desc);
+ if (ret)
+ return ret;
+ ret = pil_boot(&drv->q6_sw.desc);
+ if (ret)
+ pil_shutdown(&drv->q6_fw.desc);
}
- return 0;
+ return ret;
}
static void modem_stop(const struct subsys_desc *desc)
{
struct q6v4_modem *drv = desc_to_modem(desc);
- if (drv->loadable)
- pil_put(drv->pil);
+ if (drv->loadable) {
+ pil_shutdown(&drv->q6_sw.desc);
+ pil_shutdown(&drv->q6_fw.desc);
+ }
}
static int modem_shutdown(const struct subsys_desc *subsys)
@@ -199,8 +203,8 @@
mb();
if (drv->loadable) {
- pil_force_shutdown("modem");
- pil_force_shutdown("modem_fw");
+ pil_shutdown(&drv->q6_sw.desc);
+ pil_shutdown(&drv->q6_fw.desc);
}
disable_irq_nosync(drv->q6_fw.wdog_irq);
@@ -212,10 +216,17 @@
static int modem_powerup(const struct subsys_desc *subsys)
{
struct q6v4_modem *drv = desc_to_modem(subsys);
+ int ret;
if (drv->loadable) {
- pil_force_boot("modem_fw");
- pil_force_boot("modem");
+ ret = pil_boot(&drv->q6_fw.desc);
+ if (ret)
+ return ret;
+ ret = pil_boot(&drv->q6_sw.desc);
+ if (ret) {
+ pil_shutdown(&drv->q6_fw.desc);
+ return ret;
+ }
}
enable_irq(drv->q6_fw.wdog_irq);
enable_irq(drv->q6_sw.wdog_irq);
@@ -327,7 +338,6 @@
desc = &drv->desc;
desc->name = pdata->name;
- desc->depends_on = pdata->depends;
desc->dev = &pdev->dev;
desc->owner = THIS_MODULE;
desc->proxy_timeout = 10000;
@@ -404,19 +414,17 @@
if (!drv->modem_base)
return -ENOMEM;
- drv_fw->pil = msm_pil_register(&drv_fw->desc);
- if (IS_ERR(drv_fw->pil))
- return PTR_ERR(drv_fw->pil);
+ ret = pil_desc_init(&drv_fw->desc);
+ if (ret)
+ return ret;
- drv_sw->pil = msm_pil_register(&drv_sw->desc);
- if (IS_ERR(drv_sw->pil)) {
- ret = PTR_ERR(drv_sw->pil);
+ ret = pil_desc_init(&drv_sw->desc);
+ if (ret)
goto err_pil_sw;
- }
}
drv->subsys_desc.name = "modem";
- drv->subsys_desc.depends_on = "lpass";
+ drv->subsys_desc.depends_on = "adsp";
drv->subsys_desc.dev = &pdev->dev;
drv->subsys_desc.owner = THIS_MODULE;
drv->subsys_desc.start = modem_start;
@@ -426,19 +434,19 @@
drv->subsys_desc.ramdump = modem_ramdump;
drv->subsys_desc.crash_shutdown = modem_crash_shutdown;
- drv->fw_ramdump_dev = create_ramdump_device("modem_fw");
+ drv->fw_ramdump_dev = create_ramdump_device("modem_fw", &pdev->dev);
if (!drv->fw_ramdump_dev) {
ret = -ENOMEM;
goto err_fw_ramdump;
}
- drv->sw_ramdump_dev = create_ramdump_device("modem_sw");
+ drv->sw_ramdump_dev = create_ramdump_device("modem_sw", &pdev->dev);
if (!drv->sw_ramdump_dev) {
ret = -ENOMEM;
goto err_sw_ramdump;
}
- drv->smem_ramdump_dev = create_ramdump_device("smem-modem");
+ drv->smem_ramdump_dev = create_ramdump_device("smem-modem", &pdev->dev);
if (!drv->smem_ramdump_dev) {
ret = -ENOMEM;
goto err_smem_ramdump;
@@ -480,9 +488,9 @@
destroy_ramdump_device(drv->fw_ramdump_dev);
err_fw_ramdump:
if (drv->loadable)
- msm_pil_unregister(drv_sw->pil);
+ pil_desc_release(&drv_sw->desc);
err_pil_sw:
- msm_pil_unregister(drv_fw->pil);
+ pil_desc_release(&drv_fw->desc);
return ret;
}
@@ -497,8 +505,8 @@
destroy_ramdump_device(drv->sw_ramdump_dev);
destroy_ramdump_device(drv->fw_ramdump_dev);
if (drv->loadable) {
- msm_pil_unregister(drv->q6_sw.pil);
- msm_pil_unregister(drv->q6_fw.pil);
+ pil_desc_release(&drv->q6_sw.desc);
+ pil_desc_release(&drv->q6_fw.desc);
}
return 0;
}
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
index 47033fc..7f04c64 100644
--- a/arch/arm/mach-msm/pil-q6v4.c
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -16,7 +16,6 @@
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/regulator/consumer.h>
-#include <linux/elf.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk.h>
@@ -52,16 +51,6 @@
#define Q6SS_CLK_ENA BIT(1)
#define Q6SS_SRC_SWITCH_CLK_OVR BIT(8)
-int pil_q6v4_init_image(struct pil_desc *pil, const u8 *metadata,
- size_t size)
-{
- const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
- struct q6v4_data *drv = pil_to_q6v4_data(pil);
- drv->start_addr = ehdr->e_entry;
- return 0;
-}
-EXPORT_SYMBOL(pil_q6v4_init_image);
-
int pil_q6v4_make_proxy_votes(struct pil_desc *pil)
{
const struct q6v4_data *drv = pil_to_q6v4_data(pil);
@@ -141,6 +130,7 @@
{
u32 reg, err;
const struct q6v4_data *drv = pil_to_q6v4_data(pil);
+ unsigned long start_addr = pil_get_entry_addr(pil);
/* Enable Q6 ACLK */
writel_relaxed(0x10, drv->aclk_reg);
@@ -156,7 +146,7 @@
writel_relaxed(reg, drv->base + QDSP6SS_RESET);
/* Program boot address */
- writel_relaxed((drv->start_addr >> 8) & 0xFFFFFF,
+ writel_relaxed((start_addr >> 8) & 0xFFFFFF,
drv->base + QDSP6SS_RST_EVB);
/* Program TCM and AHB address ranges */
diff --git a/arch/arm/mach-msm/pil-q6v4.h b/arch/arm/mach-msm/pil-q6v4.h
index 0395bed..86e55ea 100644
--- a/arch/arm/mach-msm/pil-q6v4.h
+++ b/arch/arm/mach-msm/pil-q6v4.h
@@ -21,7 +21,6 @@
void __iomem *aclk_reg;
void __iomem *jtag_clk_reg;
const char *name;
- const char *depends;
const unsigned pas_id;
int bus_port;
};
@@ -36,7 +35,6 @@
struct q6v4_data {
void __iomem *base;
void __iomem *wdog_base;
- unsigned long start_addr;
unsigned long strap_tcm_base;
unsigned long strap_ahb_upper;
unsigned long strap_ahb_lower;
@@ -51,14 +49,11 @@
bool vreg_enabled;
struct clk *xo;
- struct pil_device *pil;
struct pil_desc desc;
};
#define pil_to_q6v4_data(p) container_of(p, struct q6v4_data, desc)
-extern int pil_q6v4_init_image(struct pil_desc *pil, const u8 *metadata,
- size_t size);
extern int pil_q6v4_make_proxy_votes(struct pil_desc *pil);
extern void pil_q6v4_remove_proxy_votes(struct pil_desc *pil);
extern int pil_q6v4_power_up(struct q6v4_data *drv);
diff --git a/arch/arm/mach-msm/pil-q6v5-lpass.c b/arch/arm/mach-msm/pil-q6v5-lpass.c
index 3c68da0..662377d 100644
--- a/arch/arm/mach-msm/pil-q6v5-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v5-lpass.c
@@ -26,7 +26,6 @@
#include <mach/subsystem_restart.h>
#include <mach/subsystem_notif.h>
#include <mach/scm.h>
-#include <mach/peripheral-loader.h>
#include "peripheral-loader.h"
#include "pil-q6v5.h"
@@ -119,6 +118,7 @@
static int pil_lpass_reset(struct pil_desc *pil)
{
struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc);
+ unsigned long start_addr = pil_get_entry_addr(pil);
int ret;
ret = pil_lpass_enable_clks(drv);
@@ -126,7 +126,7 @@
return ret;
/* Program Image Address */
- writel_relaxed(((drv->start_addr >> 4) & 0x0FFFFFF0),
+ writel_relaxed((start_addr >> 4) & 0x0FFFFFF0,
drv->reg_base + QDSP6SS_RST_EVB);
ret = pil_q6v5_reset(pil);
@@ -141,7 +141,6 @@
}
static struct pil_reset_ops pil_lpass_ops = {
- .init_image = pil_q6v5_init_image,
.proxy_vote = pil_q6v5_make_proxy_votes,
.proxy_unvote = pil_q6v5_remove_proxy_votes,
.auth_and_reset = pil_lpass_reset,
@@ -286,7 +285,7 @@
send_q6_nmi();
/* The write needs to go through before the q6 is shutdown. */
mb();
- pil_force_shutdown("adsp");
+ pil_shutdown(&drv->q6->desc);
disable_irq_nosync(drv->wdog_irq);
return 0;
@@ -302,7 +301,7 @@
msleep(10000);
}
- ret = pil_force_boot("adsp");
+ ret = pil_boot(&drv->q6->desc);
enable_irq(drv->wdog_irq);
return ret;
@@ -339,19 +338,15 @@
static int lpass_start(const struct subsys_desc *desc)
{
- void *ret;
struct lpass_data *drv = subsys_to_drv(desc);
- ret = pil_get(drv->q6->desc.name);
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- return 0;
+ return pil_boot(&drv->q6->desc);
}
static void lpass_stop(const struct subsys_desc *desc)
{
struct lpass_data *drv = subsys_to_drv(desc);
- pil_put(drv->q6->pil);
+ pil_shutdown(&drv->q6->desc);
}
static int __devinit pil_lpass_driver_probe(struct platform_device *pdev)
@@ -403,9 +398,9 @@
dev_info(&pdev->dev, "using non-secure boot\n");
}
- drv->q6->pil = msm_pil_register(desc);
- if (IS_ERR(drv->q6->pil))
- return PTR_ERR(drv->q6->pil);
+ ret = pil_desc_init(desc);
+ if (ret)
+ return ret;
drv->subsys_desc.name = desc->name;
drv->subsys_desc.owner = THIS_MODULE;
@@ -419,7 +414,7 @@
INIT_WORK(&drv->work, adsp_fatal_fn);
- drv->ramdump_dev = create_ramdump_device("adsp");
+ drv->ramdump_dev = create_ramdump_device("adsp", &pdev->dev);
if (!drv->ramdump_dev) {
ret = -ENOMEM;
goto err_ramdump;
@@ -464,7 +459,7 @@
err_subsys:
destroy_ramdump_device(drv->ramdump_dev);
err_ramdump:
- msm_pil_unregister(drv->q6->pil);
+ pil_desc_release(desc);
return 0;
}
@@ -477,7 +472,7 @@
adsp_smsm_state_cb, drv);
subsys_unregister(drv->subsys);
destroy_ramdump_device(drv->ramdump_dev);
- msm_pil_unregister(drv->q6->pil);
+ pil_desc_release(&drv->q6->desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index 8a02251..b033bf4 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -17,7 +17,6 @@
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/ioport.h>
-#include <linux/elf.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/clk.h>
@@ -26,7 +25,6 @@
#include <linux/regulator/consumer.h>
#include <linux/interrupt.h>
-#include <mach/peripheral-loader.h>
#include <mach/subsystem_restart.h>
#include <mach/clk.h>
#include <mach/msm_smsm.h>
@@ -73,7 +71,6 @@
void __iomem *rmb_base;
void __iomem *io_clamp_reg;
unsigned long metadata_phys;
- struct pil_device *pil;
struct pil_desc desc;
struct subsys_device *subsys;
struct subsys_desc subsys_desc;
@@ -209,6 +206,7 @@
struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc);
struct platform_device *pdev = to_platform_device(pil->dev);
struct mba_data *mba = platform_get_drvdata(pdev);
+ unsigned long start_addr = pil_get_entry_addr(pil);
int ret;
/* Deassert reset to subsystem and wait for propagation */
@@ -230,11 +228,11 @@
/* Program Image Address */
if (mba->self_auth) {
- writel_relaxed(drv->start_addr, mba->rmb_base + RMB_MBA_IMAGE);
+ writel_relaxed(start_addr, mba->rmb_base + RMB_MBA_IMAGE);
/* Ensure write to RMB base occurs before reset is released. */
mb();
} else {
- writel_relaxed((drv->start_addr >> 4) & 0x0FFFFFF0,
+ writel_relaxed((start_addr >> 4) & 0x0FFFFFF0,
drv->reg_base + QDSP6SS_RST_EVB);
}
@@ -264,7 +262,6 @@
}
static struct pil_reset_ops pil_mss_ops = {
- .init_image = pil_q6v5_init_image,
.proxy_vote = pil_q6v5_make_proxy_votes,
.proxy_unvote = pil_q6v5_remove_proxy_votes,
.auth_and_reset = pil_mss_reset,
@@ -365,18 +362,12 @@
return ret;
}
-static int pil_mba_shutdown(struct pil_desc *pil)
-{
- return 0;
-}
-
static struct pil_reset_ops pil_mba_ops = {
.init_image = pil_mba_init_image,
.proxy_vote = pil_mba_make_proxy_votes,
.proxy_unvote = pil_mba_remove_proxy_votes,
.verify_blob = pil_mba_verify_blob,
.auth_and_reset = pil_mba_auth,
- .shutdown = pil_mba_shutdown,
};
#define subsys_to_drv(d) container_of(d, struct mba_data, subsys_desc)
@@ -426,23 +417,30 @@
static int modem_shutdown(const struct subsys_desc *subsys)
{
- pil_force_shutdown("modem");
- pil_force_shutdown("mba");
+ struct mba_data *drv = subsys_to_drv(subsys);
+
+ /* MBA doesn't support shutdown */
+ pil_shutdown(&drv->q6->desc);
return 0;
}
static int modem_powerup(const struct subsys_desc *subsys)
{
struct mba_data *drv = subsys_to_drv(subsys);
+ int ret;
/*
* At this time, the modem is shutdown. Therefore this function cannot
* run concurrently with either the watchdog bite error handler or the
* SMSM callback, making it safe to unset the flag below.
*/
drv->ignore_errors = false;
- pil_force_boot("mba");
- pil_force_boot("modem");
- return 0;
+ ret = pil_boot(&drv->q6->desc);
+ if (ret)
+ return ret;
+ ret = pil_boot(&drv->desc);
+ if (ret)
+ pil_shutdown(&drv->q6->desc);
+ return ret;
}
static void modem_crash_shutdown(const struct subsys_desc *subsys)
@@ -468,7 +466,9 @@
if (!enable)
return 0;
- pil_force_boot("mba");
+ ret = pil_boot(&drv->q6->desc);
+ if (ret)
+ return ret;
ret = do_ramdump(drv->ramdump_dev, modem_segments,
ARRAY_SIZE(modem_segments));
@@ -485,7 +485,7 @@
}
out:
- pil_force_shutdown("mba");
+ pil_shutdown(&drv->q6->desc);
return ret;
}
@@ -501,19 +501,23 @@
static int mss_start(const struct subsys_desc *desc)
{
- void *ret;
+ int ret;
struct mba_data *drv = subsys_to_drv(desc);
- ret = pil_get(drv->desc.name);
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- return 0;
+ ret = pil_boot(&drv->q6->desc);
+ if (ret)
+ return ret;
+ ret = pil_boot(&drv->desc);
+ if (ret)
+ pil_shutdown(&drv->q6->desc);
+ return ret;
}
static void mss_stop(const struct subsys_desc *desc)
{
struct mba_data *drv = subsys_to_drv(desc);
- pil_put(drv->pil);
+ /* MBA doesn't support shutdown */
+ pil_shutdown(&drv->q6->desc);
}
static int __devinit pil_mss_driver_probe(struct platform_device *pdev)
@@ -595,23 +599,20 @@
if (IS_ERR(q6->rom_clk))
return PTR_ERR(q6->rom_clk);
- q6->pil = msm_pil_register(q6_desc);
- if (IS_ERR(q6->pil))
- return PTR_ERR(q6->pil);
+ ret = pil_desc_init(q6_desc);
+ if (ret)
+ return ret;
mba_desc = &drv->desc;
mba_desc->name = "modem";
- mba_desc->depends_on = "mba";
mba_desc->dev = &pdev->dev;
mba_desc->ops = &pil_mba_ops;
mba_desc->owner = THIS_MODULE;
mba_desc->proxy_timeout = PROXY_TIMEOUT_MS;
- drv->pil = msm_pil_register(mba_desc);
- if (IS_ERR(drv->pil)) {
- ret = PTR_ERR(drv->pil);
+ ret = pil_desc_init(mba_desc);
+ if (ret)
goto err_mba_desc;
- }
drv->subsys_desc.name = "modem";
drv->subsys_desc.dev = &pdev->dev;
@@ -623,7 +624,7 @@
drv->subsys_desc.start = mss_start;
drv->subsys_desc.stop = mss_stop;
- drv->ramdump_dev = create_ramdump_device("modem");
+ drv->ramdump_dev = create_ramdump_device("modem", &pdev->dev);
if (!drv->ramdump_dev) {
pr_err("%s: Unable to create a modem ramdump device.\n",
__func__);
@@ -631,7 +632,7 @@
goto err_ramdump;
}
- drv->smem_ramdump_dev = create_ramdump_device("smem-modem");
+ drv->smem_ramdump_dev = create_ramdump_device("smem-modem", &pdev->dev);
if (!drv->smem_ramdump_dev) {
pr_err("%s: Unable to create an smem ramdump device.\n",
__func__);
@@ -668,9 +669,9 @@
err_ramdump_smem:
destroy_ramdump_device(drv->ramdump_dev);
err_ramdump:
- msm_pil_unregister(drv->pil);
+ pil_desc_release(mba_desc);
err_mba_desc:
- msm_pil_unregister(q6->pil);
+ pil_desc_release(q6_desc);
return ret;
}
@@ -682,8 +683,8 @@
subsys_unregister(drv->subsys);
destroy_ramdump_device(drv->smem_ramdump_dev);
destroy_ramdump_device(drv->ramdump_dev);
- msm_pil_unregister(drv->pil);
- msm_pil_unregister(drv->q6->pil);
+ pil_desc_release(&drv->desc);
+ pil_desc_release(&drv->q6->desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-q6v5.c b/arch/arm/mach-msm/pil-q6v5.c
index 70a12de..b7e9560 100644
--- a/arch/arm/mach-msm/pil-q6v5.c
+++ b/arch/arm/mach-msm/pil-q6v5.c
@@ -16,7 +16,6 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/iopoll.h>
-#include <linux/elf.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/clk.h>
@@ -100,16 +99,6 @@
}
EXPORT_SYMBOL(pil_q6v5_halt_axi_port);
-int pil_q6v5_init_image(struct pil_desc *pil, const u8 *metadata,
- size_t size)
-{
- const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
- struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc);
- drv->start_addr = ehdr->e_entry;
- return 0;
-}
-EXPORT_SYMBOL(pil_q6v5_init_image);
-
void pil_q6v5_shutdown(struct pil_desc *pil)
{
u32 val;
diff --git a/arch/arm/mach-msm/pil-q6v5.h b/arch/arm/mach-msm/pil-q6v5.h
index 340b5e3..ecdaf9b 100644
--- a/arch/arm/mach-msm/pil-q6v5.h
+++ b/arch/arm/mach-msm/pil-q6v5.h
@@ -30,18 +30,14 @@
struct clk *rom_clk; /* Boot ROM */
void __iomem *axi_halt_base;
void __iomem *restart_reg;
- unsigned long start_addr;
struct regulator *vreg;
bool is_booted;
- struct pil_device *pil;
struct pil_desc desc;
};
int pil_q6v5_make_proxy_votes(struct pil_desc *pil);
void pil_q6v5_remove_proxy_votes(struct pil_desc *pil);
void pil_q6v5_halt_axi_port(struct pil_desc *pil, void __iomem *halt_base);
-int pil_q6v5_init_image(struct pil_desc *pil, const u8 *metadata,
- size_t size);
void pil_q6v5_shutdown(struct pil_desc *pil);
int pil_q6v5_reset(struct pil_desc *pil);
struct q6v5_data *pil_q6v5_init(struct platform_device *pdev);
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index a0e39ea..89cc4f8 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/elf.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -25,7 +24,6 @@
#include <mach/msm_iomap.h>
#include <mach/subsystem_restart.h>
-#include <mach/peripheral-loader.h>
#include "peripheral-loader.h"
#include "scm-pas.h"
@@ -84,10 +82,9 @@
struct riva_data {
void __iomem *base;
- unsigned long start_addr;
struct clk *xo;
struct regulator *pll_supply;
- struct pil_device *pil;
+ struct pil_desc pil_desc;
int irq;
int crash;
int rst_in_progress;
@@ -133,21 +130,12 @@
clk_disable_unprepare(drv->xo);
}
-static int pil_riva_init_image(struct pil_desc *pil, const u8 *metadata,
- size_t size)
-{
- const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
- struct riva_data *drv = dev_get_drvdata(pil->dev);
- drv->start_addr = ehdr->e_entry;
- return 0;
-}
-
static int pil_riva_reset(struct pil_desc *pil)
{
u32 reg, sel;
struct riva_data *drv = dev_get_drvdata(pil->dev);
void __iomem *base = drv->base;
- unsigned long start_addr = drv->start_addr;
+ unsigned long start_addr = pil_get_entry_addr(pil);
bool use_cxo = cxo_is_needed(drv);
/* Enable A2XB bridge */
@@ -254,7 +242,6 @@
}
static struct pil_reset_ops pil_riva_ops = {
- .init_image = pil_riva_init_image,
.auth_and_reset = pil_riva_reset,
.shutdown = pil_riva_shutdown,
.proxy_vote = pil_riva_make_proxy_vote,
@@ -374,15 +361,10 @@
static int riva_start(const struct subsys_desc *desc)
{
- void *ret;
struct riva_data *drv;
drv = container_of(desc, struct riva_data, subsys_desc);
-
- ret = pil_get("wcnss");
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- return 0;
+ return pil_boot(&drv->pil_desc);
}
static void riva_stop(const struct subsys_desc *desc)
@@ -390,7 +372,7 @@
struct riva_data *drv;
drv = container_of(desc, struct riva_data, subsys_desc);
- pil_put(drv->pil);
+ pil_shutdown(&drv->pil_desc);
}
static int riva_shutdown(const struct subsys_desc *desc)
@@ -398,7 +380,7 @@
struct riva_data *drv;
drv = container_of(desc, struct riva_data, subsys_desc);
- pil_force_shutdown("wcnss");
+ pil_shutdown(&drv->pil_desc);
flush_delayed_work(&drv->cancel_work);
wcnss_flush_delayed_boot_votes();
disable_irq_nosync(drv->irq);
@@ -418,7 +400,7 @@
ret = wcnss_wlan_power(&pdev->dev, pwlanconfig,
WCNSS_WLAN_SWITCH_ON);
if (!ret)
- pil_force_boot("wcnss");
+ pil_boot(&drv->pil_desc);
}
drv->rst_in_progress = 0;
enable_irq(drv->irq);
@@ -480,10 +462,6 @@
if (!drv->base)
return -ENOMEM;
- desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
- if (!desc)
- return -ENOMEM;
-
drv->pll_supply = devm_regulator_get(&pdev->dev, "pll_vdd");
if (IS_ERR(drv->pll_supply)) {
dev_err(&pdev->dev, "failed to get pll supply\n");
@@ -509,6 +487,11 @@
if (drv->irq < 0)
return drv->irq;
+ drv->xo = devm_clk_get(&pdev->dev, "cxo");
+ if (IS_ERR(drv->xo))
+ return PTR_ERR(drv->xo);
+
+ desc = &drv->pil_desc;
desc->name = "wcnss";
desc->dev = &pdev->dev;
desc->owner = THIS_MODULE;
@@ -521,14 +504,7 @@
desc->ops = &pil_riva_ops;
dev_info(&pdev->dev, "using non-secure boot\n");
}
-
- drv->xo = devm_clk_get(&pdev->dev, "cxo");
- if (IS_ERR(drv->xo))
- return PTR_ERR(drv->xo);
-
- drv->pil = msm_pil_register(desc);
- if (IS_ERR(drv->pil))
- return PTR_ERR(drv->pil);
+ ret = pil_desc_init(desc);
ret = smsm_state_cb_register(SMSM_WCNSS_STATE, SMSM_RESET,
smsm_state_cb_hdlr, drv);
@@ -547,7 +523,7 @@
INIT_DELAYED_WORK(&drv->cancel_work, riva_post_bootup);
- drv->ramdump_dev = create_ramdump_device("riva");
+ drv->ramdump_dev = create_ramdump_device("riva", &pdev->dev);
if (!drv->ramdump_dev) {
ret = -ENOMEM;
goto err_ramdump;
@@ -573,7 +549,7 @@
smsm_state_cb_deregister(SMSM_WCNSS_STATE, SMSM_RESET,
smsm_state_cb_hdlr, drv);
err_smsm:
- msm_pil_unregister(drv->pil);
+ pil_desc_release(desc);
return ret;
}
@@ -585,7 +561,7 @@
destroy_ramdump_device(drv->ramdump_dev);
smsm_state_cb_deregister(SMSM_WCNSS_STATE, SMSM_RESET,
smsm_state_cb_hdlr, drv);
- msm_pil_unregister(drv->pil);
+ pil_desc_release(&drv->pil_desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-tzapps.c b/arch/arm/mach-msm/pil-tzapps.c
index be78fab..8658e6e 100644
--- a/arch/arm/mach-msm/pil-tzapps.c
+++ b/arch/arm/mach-msm/pil-tzapps.c
@@ -13,17 +13,15 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/elf.h>
#include <linux/err.h>
-#include <mach/peripheral-loader.h>
#include <mach/subsystem_restart.h>
#include "peripheral-loader.h"
#include "scm-pas.h"
struct tzapps_data {
- struct pil_device *pil;
+ struct pil_desc pil_desc;
struct subsys_device *subsys;
struct subsys_desc subsys_desc;
};
@@ -54,44 +52,39 @@
static int tzapps_start(const struct subsys_desc *desc)
{
- void *ret;
+ struct tzapps_data *drv = subsys_to_drv(desc);
- ret = pil_get("tzapps");
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- return 0;
+ return pil_boot(&drv->pil_desc);
}
static void tzapps_stop(const struct subsys_desc *desc)
{
struct tzapps_data *drv = subsys_to_drv(desc);
- pil_put(drv->pil);
+ pil_shutdown(&drv->pil_desc);
}
static int __devinit pil_tzapps_driver_probe(struct platform_device *pdev)
{
struct pil_desc *desc;
struct tzapps_data *drv;
+ int ret;
if (pas_supported(PAS_TZAPPS) < 0)
return -ENOSYS;
- desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
- if (!desc)
- return -ENOMEM;
-
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
if (!drv)
return -ENOMEM;
platform_set_drvdata(pdev, drv);
+ desc = &drv->pil_desc;
desc->name = "tzapps";
desc->dev = &pdev->dev;
desc->ops = &pil_tzapps_ops;
desc->owner = THIS_MODULE;
- drv->pil = msm_pil_register(desc);
- if (IS_ERR(drv->pil))
- return PTR_ERR(drv->pil);
+ ret = pil_desc_init(desc);
+ if (ret)
+ return ret;
drv->subsys_desc.name = "tzapps";
drv->subsys_desc.dev = &pdev->dev;
@@ -101,7 +94,7 @@
drv->subsys = subsys_register(&drv->subsys_desc);
if (IS_ERR(drv->subsys)) {
- msm_pil_unregister(drv->pil);
+ pil_desc_release(desc);
return PTR_ERR(drv->subsys);
}
return 0;
@@ -111,7 +104,7 @@
{
struct tzapps_data *drv = platform_get_drvdata(pdev);
subsys_unregister(drv->subsys);
- msm_pil_unregister(drv->pil);
+ pil_desc_release(&drv->pil_desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-venus.c b/arch/arm/mach-msm/pil-venus.c
index e3125cf..31ac4ef 100644
--- a/arch/arm/mach-msm/pil-venus.c
+++ b/arch/arm/mach-msm/pil-venus.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/elf.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -29,7 +28,6 @@
#include <mach/iommu.h>
#include <mach/iommu_domains.h>
#include <mach/subsystem_restart.h>
-#include <mach/peripheral-loader.h>
#include "peripheral-loader.h"
#include "scm-pas.h"
@@ -67,11 +65,10 @@
struct venus_data {
void __iomem *venus_wrapper_base;
void __iomem *venus_vbif_base;
- struct pil_device *pil;
+ struct pil_desc desc;
struct subsys_device *subsys;
struct subsys_desc subsys_desc;
struct regulator *gdsc;
- phys_addr_t start_addr;
struct clk *clks[ARRAY_SIZE(clk_names)];
struct device *iommu_fw_ctx;
struct iommu_domain *iommu_fw_domain;
@@ -184,22 +181,29 @@
regulator_disable(drv->gdsc);
}
-static int pil_venus_init_image(struct pil_desc *pil, const u8 *metadata,
- size_t size)
+static int pil_venus_mem_setup(struct pil_desc *pil, phys_addr_t addr,
+ size_t size)
{
- const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
+ int domain;
struct venus_data *drv = dev_get_drvdata(pil->dev);
- drv->start_addr = ehdr->e_entry;
-
- if (drv->start_addr < drv->fw_min_paddr ||
- drv->start_addr >= drv->fw_max_paddr) {
- dev_err(pil->dev, "fw start addr is not within valid range\n");
- return -EINVAL;
+ /* TODO: unregister? */
+ if (!drv->venus_domain_num) {
+ size = round_up(size, SZ_4K);
+ domain = venus_register_domain(size);
+ if (domain < 0) {
+ dev_err(pil->dev, "Venus fw iommu domain register failed\n");
+ return -ENODEV;
+ }
+ drv->iommu_fw_domain = msm_get_iommu_domain(domain);
+ if (!drv->iommu_fw_domain) {
+ dev_err(pil->dev, "No iommu fw domain found\n");
+ return -ENODEV;
+ }
+ drv->venus_domain_num = domain;
+ drv->fw_sz = size;
}
- drv->fw_sz = drv->fw_max_paddr - drv->start_addr;
-
return 0;
}
@@ -208,7 +212,7 @@
int rc;
struct venus_data *drv = dev_get_drvdata(pil->dev);
void __iomem *wrapper_base = drv->venus_wrapper_base;
- phys_addr_t pa = drv->start_addr;
+ phys_addr_t pa = pil_get_entry_addr(pil);
unsigned long iova;
/*
@@ -327,7 +331,7 @@
}
static struct pil_reset_ops pil_venus_ops = {
- .init_image = pil_venus_init_image,
+ .mem_setup = pil_venus_mem_setup,
.auth_and_reset = pil_venus_reset,
.shutdown = pil_venus_shutdown,
.proxy_vote = pil_venus_make_proxy_vote,
@@ -389,19 +393,15 @@
static int venus_start(const struct subsys_desc *desc)
{
- void *ret;
struct venus_data *drv = subsys_to_drv(desc);
- ret = pil_get(drv->subsys_desc.name);
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- return 0;
+ return pil_boot(&drv->desc);
}
static void venus_stop(const struct subsys_desc *desc)
{
struct venus_data *drv = subsys_to_drv(desc);
- pil_put(drv->pil);
+ pil_shutdown(&drv->desc);
}
static int __devinit pil_venus_probe(struct platform_device *pdev)
@@ -451,45 +451,7 @@
return -ENODEV;
}
- /* Get fw address boundaries */
- rc = of_property_read_u32(pdev->dev.of_node,
- "qcom,firmware-max-paddr",
- &drv->fw_max_paddr);
- if (rc) {
- dev_err(&pdev->dev, "Failed to get fw max paddr\n");
- return rc;
- }
-
- rc = of_property_read_u32(pdev->dev.of_node,
- "qcom,firmware-min-paddr",
- &drv->fw_min_paddr);
- if (rc) {
- dev_err(&pdev->dev, "Failed to get fw min paddr\n");
- return rc;
- }
-
- if (drv->fw_max_paddr <= drv->fw_min_paddr) {
- dev_err(&pdev->dev, "Invalid fw max paddr or min paddr\n");
- return -EINVAL;
- }
-
- drv->venus_domain_num =
- venus_register_domain(drv->fw_max_paddr - drv->fw_min_paddr);
- if (drv->venus_domain_num < 0) {
- dev_err(&pdev->dev, "Venus fw iommu domain register failed\n");
- return -ENODEV;
- }
-
- drv->iommu_fw_domain = msm_get_iommu_domain(drv->venus_domain_num);
- if (!drv->iommu_fw_domain) {
- dev_err(&pdev->dev, "No iommu fw domain found\n");
- return -ENODEV;
- }
-
- desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
- if (!desc)
- return -ENOMEM;
-
+ desc = &drv->desc;
rc = of_property_read_string(pdev->dev.of_node, "qcom,firmware-name",
&desc->name);
if (rc)
@@ -507,9 +469,9 @@
dev_info(&pdev->dev, "using non-secure boot\n");
}
- drv->pil = msm_pil_register(desc);
- if (IS_ERR(drv->pil))
- return PTR_ERR(drv->pil);
+ rc = pil_desc_init(desc);
+ if (rc)
+ return rc;
drv->subsys_desc.name = desc->name;
drv->subsys_desc.owner = THIS_MODULE;
@@ -519,7 +481,7 @@
drv->subsys = subsys_register(&drv->subsys_desc);
if (IS_ERR(drv->subsys)) {
- msm_pil_unregister(drv->pil);
+ pil_desc_release(desc);
return PTR_ERR(drv->subsys);
}
@@ -530,7 +492,7 @@
{
struct venus_data *drv = platform_get_drvdata(pdev);
subsys_unregister(drv->subsys);
- msm_pil_unregister(drv->pil);
+ pil_desc_release(&drv->desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-vidc.c b/arch/arm/mach-msm/pil-vidc.c
index b2609b1..42bb51c 100644
--- a/arch/arm/mach-msm/pil-vidc.c
+++ b/arch/arm/mach-msm/pil-vidc.c
@@ -13,11 +13,9 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/elf.h>
#include <linux/err.h>
#include <linux/clk.h>
-#include <mach/peripheral-loader.h>
#include <mach/subsystem_restart.h>
#include "peripheral-loader.h"
@@ -26,7 +24,7 @@
struct vidc_data {
struct clk *smmu_iface;
struct clk *core;
- struct pil_device *pil;
+ struct pil_desc pil_desc;
struct subsys_device *subsys;
struct subsys_desc subsys_desc;
};
@@ -72,32 +70,25 @@
static int vidc_start(const struct subsys_desc *desc)
{
- void *ret;
-
- ret = pil_get("vidc");
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- return 0;
+ struct vidc_data *drv = subsys_to_drv(desc);
+ return pil_boot(&drv->pil_desc);
}
static void vidc_stop(const struct subsys_desc *desc)
{
struct vidc_data *drv = subsys_to_drv(desc);
- pil_put(drv->pil);
+ pil_shutdown(&drv->pil_desc);
}
static int __devinit pil_vidc_driver_probe(struct platform_device *pdev)
{
struct pil_desc *desc;
struct vidc_data *drv;
+ int ret;
if (pas_supported(PAS_VIDC) < 0)
return -ENOSYS;
- desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
- if (!desc)
- return -ENOMEM;
-
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
if (!drv)
return -ENOMEM;
@@ -111,13 +102,14 @@
if (IS_ERR(drv->core))
return PTR_ERR(drv->core);
+ desc = &drv->pil_desc;
desc->name = "vidc";
desc->dev = &pdev->dev;
desc->ops = &pil_vidc_ops;
desc->owner = THIS_MODULE;
- drv->pil = msm_pil_register(desc);
- if (IS_ERR(drv->pil))
- return PTR_ERR(drv->pil);
+ ret = pil_desc_init(desc);
+ if (ret)
+ return ret;
drv->subsys_desc.name = "vidc";
drv->subsys_desc.dev = &pdev->dev;
@@ -127,7 +119,7 @@
drv->subsys = subsys_register(&drv->subsys_desc);
if (IS_ERR(drv->subsys)) {
- msm_pil_unregister(drv->pil);
+ pil_desc_release(desc);
return PTR_ERR(drv->subsys);
}
return 0;
@@ -137,7 +129,7 @@
{
struct vidc_data *drv = platform_get_drvdata(pdev);
subsys_unregister(drv->subsys);
- msm_pil_unregister(drv->pil);
+ pil_desc_release(&drv->pil_desc);
return 0;
}
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index f55d509..2eac6b7 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -35,7 +35,7 @@
#include <asm/hardware/gic.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
-#include <asm/hardware/cache-l2x0.h>
+#include <asm/outercache.h>
#ifdef CONFIG_VFP
#include <asm/vfp.h>
#endif
@@ -114,6 +114,7 @@
"standalone_power_collapse",
};
+static struct msm_pm_init_data_type msm_pm_init_data;
static struct hrtimer pm_hrtimer;
static struct msm_pm_sleep_ops pm_sleep_ops;
/*
@@ -473,7 +474,6 @@
}
static void *msm_pm_idle_rs_limits;
-static bool msm_pm_use_qtimer;
static void msm_pm_swfi(void)
{
@@ -499,24 +499,6 @@
msm_pm_config_hw_after_retention();
}
-#ifdef CONFIG_CACHE_L2X0
-static inline bool msm_pm_l2x0_power_collapse(void)
-{
- bool collapsed = 0;
-
- l2cc_suspend();
- collapsed = msm_pm_collapse();
- l2cc_resume();
-
- return collapsed;
-}
-#else
-static inline bool msm_pm_l2x0_power_collapse(void)
-{
- return msm_pm_collapse();
-}
-#endif
-
static bool __ref msm_pm_spm_power_collapse(
unsigned int cpu, bool from_idle, bool notify_rpm)
{
@@ -547,7 +529,7 @@
#ifdef CONFIG_VFP
vfp_pm_suspend();
#endif
- collapsed = msm_pm_l2x0_power_collapse();
+ collapsed = msm_pm_collapse();
msm_pm_boot_config_after_pc(cpu);
@@ -576,11 +558,13 @@
{
unsigned int cpu = smp_processor_id();
unsigned int avsdscr_setting;
+ unsigned int avscsr_enable;
bool collapsed;
avsdscr_setting = avs_get_avsdscr();
- avs_disable();
+ avscsr_enable = avs_disable();
collapsed = msm_pm_spm_power_collapse(cpu, from_idle, false);
+ avs_enable(avscsr_enable);
avs_reset_delays(avsdscr_setting);
return collapsed;
}
@@ -590,6 +574,7 @@
unsigned int cpu = smp_processor_id();
unsigned long saved_acpuclk_rate;
unsigned int avsdscr_setting;
+ unsigned int avscsr_enable;
bool collapsed;
if (MSM_PM_DEBUG_POWER_COLLAPSE & msm_pm_debug_mask)
@@ -601,7 +586,7 @@
pr_info("CPU%u: %s: pre power down\n", cpu, __func__);
avsdscr_setting = avs_get_avsdscr();
- avs_disable();
+ avscsr_enable = avs_disable();
if (cpu_online(cpu))
saved_acpuclk_rate = acpuclk_power_collapse();
@@ -643,6 +628,7 @@
}
+ avs_enable(avscsr_enable);
avs_reset_delays(avsdscr_setting);
msm_pm_config_hw_after_power_up();
if (MSM_PM_DEBUG_POWER_COLLAPSE & msm_pm_debug_mask)
@@ -657,14 +643,11 @@
{
if (cpu_is_apq8064())
msm_pm_save_cp15 = true;
-
- if (cpu_is_msm8974())
- msm_pm_use_qtimer = true;
}
static int64_t msm_pm_timer_enter_idle(void)
{
- if (msm_pm_use_qtimer)
+ if (msm_pm_init_data.use_sync_timer)
return ktime_to_ns(tick_nohz_get_sleep_length());
return msm_timer_enter_idle();
@@ -672,7 +655,7 @@
static void msm_pm_timer_exit_idle(bool timer_halted)
{
- if (msm_pm_use_qtimer)
+ if (msm_pm_init_data.use_sync_timer)
return;
msm_timer_exit_idle((int) timer_halted);
@@ -682,7 +665,7 @@
{
int64_t time = 0;
- if (msm_pm_use_qtimer)
+ if (msm_pm_init_data.use_sync_timer)
return sched_clock();
time = msm_timer_get_sclk_time(period);
@@ -694,7 +677,7 @@
static int64_t msm_pm_timer_exit_suspend(int64_t time, int64_t period)
{
- if (msm_pm_use_qtimer)
+ if (msm_pm_init_data.use_sync_timer)
return sched_clock() - time;
if (time != 0) {
@@ -1165,3 +1148,73 @@
}
late_initcall(msm_pm_init);
+
+static void __devinit msm_pm_set_flush_fn(uint32_t pc_mode)
+{
+ msm_pm_disable_l2_fn = NULL;
+ msm_pm_enable_l2_fn = NULL;
+ msm_pm_flush_l2_fn = outer_flush_all;
+
+ if (pc_mode == MSM_PM_PC_NOTZ_L2_EXT) {
+ msm_pm_disable_l2_fn = outer_disable;
+ msm_pm_enable_l2_fn = outer_resume;
+ }
+}
+
+static int __devinit msm_pm_8x60_probe(struct platform_device *pdev)
+{
+ char *key = NULL;
+ uint32_t val = 0;
+ int ret = 0;
+
+ if (!pdev->dev.of_node) {
+ struct msm_pm_init_data_type *d = pdev->dev.platform_data;
+
+ if (!d)
+ goto pm_8x60_probe_done;
+
+ msm_pm_init_data.pc_mode = d->pc_mode;
+ msm_pm_set_flush_fn(msm_pm_init_data.pc_mode);
+ msm_pm_init_data.use_sync_timer = d->use_sync_timer;
+ } else {
+ key = "qcom,pc-mode";
+ ret = of_property_read_u32(pdev->dev.of_node, key, &val);
+
+ if (ret) {
+ pr_debug("%s: Cannot read %s,defaulting to 0",
+ __func__, key);
+ val = MSM_PM_PC_TZ_L2_INT;
+ ret = 0;
+ }
+
+ msm_pm_init_data.pc_mode = val;
+ msm_pm_set_flush_fn(msm_pm_init_data.pc_mode);
+
+ key = "qcom,use-sync-timer";
+ msm_pm_init_data.use_sync_timer =
+ of_property_read_bool(pdev->dev.of_node, key);
+ }
+
+pm_8x60_probe_done:
+ return ret;
+}
+
+static struct of_device_id msm_pm_8x60_table[] = {
+ {.compatible = "qcom,pm-8x60"},
+ {},
+};
+
+static struct platform_driver msm_pm_8x60_driver = {
+ .probe = msm_pm_8x60_probe,
+ .driver = {
+ .name = "pm-8x60",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_pm_8x60_table,
+ },
+};
+
+static int __init msm_pm_8x60_init(void)
+{
+ return platform_driver_register(&msm_pm_8x60_driver);
+}
+module_init(msm_pm_8x60_init);
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index 51256ca..faefe34 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -87,6 +87,20 @@
bool notify_rpm, bool collapsed);
};
+enum msm_pm_pc_mode_type {
+ MSM_PM_PC_TZ_L2_INT = 0, /*Power collapse terminates in TZ;
+ integrated L2 cache controller */
+ MSM_PM_PC_NOTZ_L2_EXT = 1, /* Power collapse doesn't terminate in
+ TZ; external L2 cache controller */
+ MSM_PM_PC_TZ_L2_EXT = 2, /* Power collapse terminates in TZ;
+ external L2 cache controller */
+};
+
+struct msm_pm_init_data_type {
+ enum msm_pm_pc_mode_type pc_mode;
+ bool use_sync_timer;
+};
+
struct msm_pm_cpr_ops {
void (*cpr_suspend)(void);
void (*cpr_resume)(void);
diff --git a/arch/arm/mach-msm/qdsp6v2/adsp-loader.c b/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
index 9924b52..c28e403 100644
--- a/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
+++ b/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
@@ -17,7 +17,7 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
-#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
#include <mach/qdsp6v2/apr.h>
#define Q6_PIL_GET_DELAY_MS 100
@@ -37,7 +37,7 @@
platform_set_drvdata(pdev, priv);
- priv->pil_h = pil_get("adsp");
+ priv->pil_h = subsystem_get("adsp");
if (IS_ERR(priv->pil_h)) {
pr_err("%s: pil get adsp failed, error:%d\n", __func__, rc);
devm_kfree(&pdev->dev, priv);
@@ -62,7 +62,7 @@
struct adsp_loader_private *priv;
priv = platform_get_drvdata(pdev);
- pil_put(priv->pil_h);
+ subsystem_put(priv->pil_h);
pr_info("%s: Q6/ADSP image is unloaded\n", __func__);
return 0;
diff --git a/arch/arm/mach-msm/qdsp6v2/apr.c b/arch/arm/mach-msm/qdsp6v2/apr.c
index d494069..39bec8e 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr.c
@@ -27,7 +27,7 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <asm/mach-types.h>
-#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
#include <mach/msm_smd.h>
#include <mach/qdsp6v2/apr.h>
#include <mach/qdsp6v2/apr_tal.h>
@@ -223,7 +223,7 @@
int rc = 0;
mutex_lock(&q6.lock);
if (apr_get_q6_state() == APR_SUBSYS_UP) {
- q6.pil = pil_get("q6");
+ q6.pil = subsystem_get("adsp");
if (IS_ERR(q6.pil)) {
rc = PTR_ERR(q6.pil);
pr_err("APR: Unable to load q6 image, error:%d\n", rc);
diff --git a/arch/arm/mach-msm/qdsp6v2/apr_v1.c b/arch/arm/mach-msm/qdsp6v2/apr_v1.c
index 011a73b..870bbb4 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr_v1.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr_v1.c
@@ -19,7 +19,6 @@
#include <mach/qdsp6v2/apr.h>
#include <mach/qdsp6v2/apr_tal.h>
#include <mach/qdsp6v2/dsp_debug.h>
-#include <mach/peripheral-loader.h>
static const char *lpass_subsys_name = "lpass";
diff --git a/arch/arm/mach-msm/ramdump.c b/arch/arm/mach-msm/ramdump.c
index 21e81dd..e33ec48 100644
--- a/arch/arm/mach-msm/ramdump.c
+++ b/arch/arm/mach-msm/ramdump.c
@@ -181,7 +181,7 @@
.poll = ramdump_poll
};
-void *create_ramdump_device(const char *dev_name)
+void *create_ramdump_device(const char *dev_name, struct device *parent)
{
int ret;
struct ramdump_device *rd_dev;
@@ -207,6 +207,7 @@
rd_dev->device.minor = MISC_DYNAMIC_MINOR;
rd_dev->device.name = rd_dev->name;
rd_dev->device.fops = &ramdump_file_ops;
+ rd_dev->device.parent = parent;
init_waitqueue_head(&rd_dev->dump_wait_q);
diff --git a/arch/arm/mach-msm/ramdump.h b/arch/arm/mach-msm/ramdump.h
index 9006010..3e5bfaf 100644
--- a/arch/arm/mach-msm/ramdump.h
+++ b/arch/arm/mach-msm/ramdump.h
@@ -13,12 +13,14 @@
#ifndef _RAMDUMP_HEADER
#define _RAMDUMP_HEADER
+struct device;
+
struct ramdump_segment {
unsigned long address;
unsigned long size;
};
-void *create_ramdump_device(const char *dev_name);
+void *create_ramdump_device(const char *dev_name, struct device *parent);
void destroy_ramdump_device(void *dev);
int do_ramdump(void *handle, struct ramdump_segment *segments,
int nsegments);
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index c6da910..3c0cbf7 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -706,7 +706,7 @@
*/
static struct edge_to_pid edge_to_pids[] = {
[SMD_APPS_MODEM] = {SMD_APPS, SMD_MODEM, "modem"},
- [SMD_APPS_QDSP] = {SMD_APPS, SMD_Q6, "q6"},
+ [SMD_APPS_QDSP] = {SMD_APPS, SMD_Q6, "adsp"},
[SMD_MODEM_QDSP] = {SMD_MODEM, SMD_Q6},
[SMD_APPS_DSPS] = {SMD_APPS, SMD_DSPS, "dsps"},
[SMD_MODEM_DSPS] = {SMD_MODEM, SMD_DSPS},
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 928e59b..ecdc951 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -34,7 +34,7 @@
#include <linux/wakelock.h>
#include <mach/msm_smd.h>
-#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
#include <mach/msm_ipc_logging.h>
#include "smd_private.h"
@@ -823,12 +823,11 @@
peripheral = smd_edge_to_subsystem(
smd_ch_edge[smd_pkt_devp->i]);
if (peripheral) {
- smd_pkt_devp->pil = pil_get(peripheral);
+ smd_pkt_devp->pil = subsystem_get(peripheral);
if (IS_ERR(smd_pkt_devp->pil)) {
r = PTR_ERR(smd_pkt_devp->pil);
- pr_err("%s failed on smd_pkt_dev id:%d -"
- " pil_get failed for %s\n", __func__,
- smd_pkt_devp->i, peripheral);
+ pr_err("%s failed on smd_pkt_dev id:%d - subsystem_get failed for %s\n",
+ __func__, smd_pkt_devp->i, peripheral);
goto release_pd;
}
@@ -908,7 +907,7 @@
}
release_pil:
if (peripheral && (r < 0))
- pil_put(smd_pkt_devp->pil);
+ subsystem_put(smd_pkt_devp->pil);
release_pd:
if (r < 0) {
@@ -952,7 +951,7 @@
platform_driver_unregister(&smd_pkt_devp->driver);
smd_pkt_devp->driver.probe = NULL;
if (smd_pkt_devp->pil)
- pil_put(smd_pkt_devp->pil);
+ subsystem_put(smd_pkt_devp->pil);
smd_pkt_devp->has_reset = 0;
smd_pkt_devp->do_reset_notification = 0;
smd_pkt_devp->wakelock_locked = 0;
diff --git a/arch/arm/mach-msm/smd_rpcrouter_device.c b/arch/arm/mach-msm/smd_rpcrouter_device.c
index e84d213..7b51beb 100644
--- a/arch/arm/mach-msm/smd_rpcrouter_device.c
+++ b/arch/arm/mach-msm/smd_rpcrouter_device.c
@@ -1,7 +1,7 @@
/* arch/arm/mach-msm/smd_rpcrouter_device.c
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
* Author: San Mehat <san@android.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -34,7 +34,7 @@
#include <asm/uaccess.h>
#include <asm/byteorder.h>
-#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
#include "smd_rpcrouter.h"
/* Support 64KB of data plus some space for headers */
@@ -61,7 +61,7 @@
static void msm_rpcrouter_unload_modem(void *pil)
{
if (pil)
- pil_put(pil);
+ subsystem_put(pil);
}
static void *msm_rpcrouter_load_modem(void)
@@ -69,7 +69,7 @@
void *pil;
int rc;
- pil = pil_get("modem");
+ pil = subsystem_get("modem");
if (IS_ERR(pil))
pr_err("%s: modem load failed\n", __func__);
else {
diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
index 44ef822..881da18 100644
--- a/arch/arm/mach-msm/smd_tty.c
+++ b/arch/arm/mach-msm/smd_tty.c
@@ -30,7 +30,7 @@
#include <linux/tty_flip.h>
#include <mach/msm_smd.h>
-#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
#include <mach/socinfo.h>
#include "smd_private.h"
@@ -245,7 +245,7 @@
if (info->open_count++ == 0) {
peripheral = smd_edge_to_subsystem(smd_tty[n].smd->edge);
if (peripheral) {
- info->pil = pil_get(peripheral);
+ info->pil = subsystem_get(peripheral);
if (IS_ERR(info->pil)) {
res = PTR_ERR(info->pil);
goto out;
@@ -325,7 +325,7 @@
release_pil:
if (res < 0)
- pil_put(info->pil);
+ subsystem_put(info->pil);
else
smd_disable_read_intr(info->ch);
out:
@@ -357,7 +357,7 @@
if (info->ch) {
smd_close(info->ch);
info->ch = 0;
- pil_put(info->pil);
+ subsystem_put(info->pil);
}
}
mutex_unlock(&smd_tty_lock);
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index 8951cfe..ea9337d 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -33,7 +33,6 @@
#include <asm/current.h>
-#include <mach/peripheral-loader.h>
#include <mach/socinfo.h>
#include <mach/subsystem_notif.h>
#include <mach/subsystem_restart.h>
@@ -228,7 +227,7 @@
/* MSM 8x60 restart ordering info */
static const char * const _order_8x60_all[] = {
- "external_modem", "modem", "lpass"
+ "external_modem", "modem", "adsp"
};
DEFINE_SINGLE_RESTART_ORDER(orders_8x60_all, _order_8x60_all);
@@ -839,7 +838,6 @@
subsys->dev.parent = desc->dev;
subsys->dev.bus = &subsys_bus_type;
subsys->dev.release = subsys_device_release;
- subsys->track.state = SUBSYS_ONLINE; /* Until proper refcounting */
subsys->notify = subsys_notif_add_subsys(desc->name);
subsys->restart_order = update_restart_order(subsys);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index f671806..b3bd8a0 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -363,6 +363,7 @@
int t38_start_addr;
bool update_cfg;
const char *fw_name;
+ bool no_force_update;
};
static struct dentry *debug_base;
@@ -984,9 +985,9 @@
continue;
}
- /* check whether report id is part of T9 or T15 */
id = reportid - data->t9_min_reportid;
+ /* check whether report id is part of T9,T15 or T42*/
if (reportid >= data->t9_min_reportid &&
reportid <= data->t9_max_reportid)
mxt_input_touchevent(data, &message, id);
@@ -1273,25 +1274,18 @@
data->cfg_version[0], data->cfg_version[1],
data->cfg_version[2]);
- /* It is possible that the config data on the controller is not
- * versioned and the version number returns 0. In this case,
- * find a match without the config version checking.
- */
- error = mxt_search_config_array(data,
- data->cfg_version[0] != 0 ? true : false);
+ /* configuration update requires major match */
+ error = mxt_search_config_array(data, true);
+
+ /* if no_force_update is false , try again with false
+ as the second parameter to mxt_search_config_array */
+ if (error && (data->no_force_update == false))
+ error = mxt_search_config_array(data, false);
+
if (error) {
- /* If a match wasn't found for a non-zero config version,
- * it means the controller has the wrong config data. Search
- * for a best match based on controller and firmware version,
- * but not config version.
- */
- if (data->cfg_version[0])
- error = mxt_search_config_array(data, false);
- if (error) {
- dev_err(dev,
- "Unable to find matching config in pdata\n");
- return error;
- }
+ dev_err(dev,
+ "Unable to find matching config in pdata\n");
+ return error;
}
return 0;
@@ -1418,13 +1412,62 @@
return 0;
}
+static int mxt_update_cfg(struct mxt_data *data)
+{
+ int error;
+ const u8 *cfg_ver;
+
+ /* Get config data from platform data */
+ error = mxt_get_config(data);
+ if (error)
+ dev_dbg(&data->client->dev, "Config info not found.\n");
+
+ /* Check register init values */
+ if (data->config_info && data->config_info->config) {
+ if (data->update_cfg) {
+ error = mxt_check_reg_init(data);
+ if (error) {
+ dev_err(&data->client->dev,
+ "Failed to check reg init value\n");
+ return error;
+ }
+
+ error = mxt_backup_nv(data);
+ if (error) {
+ dev_err(&data->client->dev, "Failed to back up NV\n");
+ return error;
+ }
+
+ cfg_ver = data->config_info->config +
+ data->cfg_version_idx;
+ dev_info(&data->client->dev,
+ "Config updated from %d.%d.%d to %d.%d.%d\n",
+ data->cfg_version[0], data->cfg_version[1],
+ data->cfg_version[2],
+ cfg_ver[0], cfg_ver[1], cfg_ver[2]);
+
+ memcpy(data->cfg_version, cfg_ver, MXT_CFG_VERSION_LEN);
+ }
+ } else {
+ dev_info(&data->client->dev,
+ "No cfg data defined, skipping check reg init\n");
+ }
+
+ error = mxt_save_objects(data);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+
+
static int mxt_initialize(struct mxt_data *data)
{
struct i2c_client *client = data->client;
struct mxt_info *info = &data->info;
int error;
u8 val;
- const u8 *cfg_ver;
error = mxt_get_info(data);
if (error) {
@@ -1465,46 +1508,9 @@
if (error)
goto free_object_table;
- /* Get config data from platform data */
- error = mxt_get_config(data);
- if (error)
- dev_dbg(&client->dev, "Config info not found.\n");
-
- /* Check register init values */
- if (data->config_info && data->config_info->config) {
- if (data->update_cfg) {
- error = mxt_check_reg_init(data);
- if (error) {
- dev_err(&client->dev,
- "Failed to check reg init value\n");
- goto free_object_table;
- }
-
- error = mxt_backup_nv(data);
- if (error) {
- dev_err(&client->dev, "Failed to back up NV\n");
- goto free_object_table;
- }
-
- cfg_ver = data->config_info->config +
- data->cfg_version_idx;
- dev_info(&client->dev,
- "Config updated from %d.%d.%d to %d.%d.%d\n",
- data->cfg_version[0], data->cfg_version[1],
- data->cfg_version[2],
- cfg_ver[0], cfg_ver[1], cfg_ver[2]);
-
- memcpy(data->cfg_version, cfg_ver, MXT_CFG_VERSION_LEN);
- }
- } else {
- dev_info(&client->dev,
- "No cfg data defined, skipping check reg init\n");
- }
-
- error = mxt_save_objects(data);
+ error = mxt_update_cfg(data);
if (error)
goto free_object_table;
-
/* Update matrix size at info struct */
error = mxt_read_reg(client, MXT_MATRIX_X_SIZE, &val);
if (error)
@@ -1732,6 +1738,30 @@
return fw_name;
}
+static ssize_t mxt_force_cfg_update_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct mxt_data *data = dev_get_drvdata(dev);
+ int flag = buf[0]-'0';
+ int error;
+ data->no_force_update = !flag;
+
+ if (data->state == APPMODE) {
+ disable_irq(data->irq);
+ error = mxt_update_cfg(data);
+ enable_irq(data->irq);
+ if (error)
+ return error;
+ } else {
+ dev_err(dev,
+ "Not in APPMODE, Unable to force cfg update\n");
+ return -EINVAL;
+ }
+
+ return count;
+}
+
static ssize_t mxt_update_fw_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -1742,7 +1772,7 @@
u8 bootldr_id;
u8 cfg_version[MXT_CFG_VERSION_LEN] = {0};
-
+ data->no_force_update = false;
/* If fw_name is set, then the existing firmware has an upgrade */
if (!data->fw_name) {
/*
@@ -1824,10 +1854,12 @@
static DEVICE_ATTR(object, 0444, mxt_object_show, NULL);
static DEVICE_ATTR(update_fw, 0664, NULL, mxt_update_fw_store);
+static DEVICE_ATTR(force_cfg_update, 0664, NULL, mxt_force_cfg_update_store);
static struct attribute *mxt_attrs[] = {
&dev_attr_object.attr,
&dev_attr_update_fw.attr,
+ &dev_attr_force_cfg_update.attr,
NULL
};
@@ -2433,6 +2465,10 @@
pdata->i2c_pull_up = of_property_read_bool(np, "atmel,i2c-pull-up");
pdata->digital_pwr_regulator = of_property_read_bool(np,
"atmel,dig-reg-support");
+
+ pdata->no_force_update = of_property_read_bool(np,
+ "atmel,no-force-update");
+
/* reset, irq gpio info */
pdata->reset_gpio = of_get_named_gpio_flags(np, "atmel,reset-gpio",
0, &pdata->reset_gpio_flags);
@@ -2583,6 +2619,7 @@
data->client = client;
data->input_dev = input_dev;
data->pdata = pdata;
+ data->no_force_update = pdata->no_force_update;
__set_bit(EV_ABS, input_dev->evbit);
__set_bit(EV_KEY, input_dev->evbit);
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 56bcf65..46dab5c 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -17,7 +17,7 @@
#include <asm/div64.h>
#include <mach/iommu.h>
#include <mach/iommu_domains.h>
-#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
#include "msm_vidc_common.h"
#include "vidc_hal_api.h"
@@ -837,12 +837,12 @@
}
if (!core->resources.fw.cookie)
- core->resources.fw.cookie = pil_get("venus");
+ core->resources.fw.cookie = subsystem_get("venus");
if (IS_ERR_OR_NULL(core->resources.fw.cookie)) {
dprintk(VIDC_ERR, "Failed to download firmware\n");
rc = -ENOMEM;
- goto fail_pil_get;
+ goto fail_subsystem_get;
}
rc = msm_comm_enable_clks(core);
@@ -860,9 +860,9 @@
fail_iommu_attach:
msm_comm_disable_clks(core);
fail_enable_clks:
- pil_put(core->resources.fw.cookie);
+ subsystem_put(core->resources.fw.cookie);
core->resources.fw.cookie = NULL;
-fail_pil_get:
+fail_subsystem_get:
return rc;
}
@@ -873,7 +873,7 @@
return;
}
if (core->resources.fw.cookie) {
- pil_put(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);
diff --git a/drivers/media/video/msm_vidc/msm_vidc_ssr.c b/drivers/media/video/msm_vidc/msm_vidc_ssr.c
index e8a6745..33464c6f 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_ssr.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_ssr.c
@@ -157,7 +157,8 @@
dprintk(VIDC_ERR, "msm_vidc Sub System registration failed\n");
rc = -ENODEV;
}
- core->ssr_info.msm_vidc_ramdump_dev = create_ramdump_device("msm_vidc");
+ core->ssr_info.msm_vidc_ramdump_dev = create_ramdump_device("msm_vidc",
+ msm_vidc_subsystem.dev);
if (!core->ssr_info.msm_vidc_ramdump_dev) {
dprintk(VIDC_ERR, "Unable to create msm_vidc ramdump device\n");
rc = -ENODEV;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 8cb903a..26ba379 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -39,7 +39,7 @@
#include <mach/msm_bus.h>
#include <mach/msm_bus_board.h>
#include <mach/scm.h>
-#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
#include <mach/socinfo.h>
#include "qseecom_legacy.h"
#include "qseecom_kernel.h"
@@ -2089,7 +2089,7 @@
int pil_error;
mutex_lock(&pil_access_lock);
if (pil_ref_cnt == 0) {
- pil = pil_get("tzapps");
+ pil = subsystem_get("tzapps");
if (IS_ERR(pil)) {
pr_err("Playready PIL image load failed\n");
pil_error = PTR_ERR(pil);
@@ -2124,7 +2124,7 @@
if (qseecom.qseos_version == QSEOS_VERSION_13) {
mutex_lock(&pil_access_lock);
if (pil_ref_cnt == 1)
- pil_put(pil);
+ subsystem_put(pil);
pil_ref_cnt--;
mutex_unlock(&pil_access_lock);
}
diff --git a/drivers/net/ethernet/msm/msm_rmnet.c b/drivers/net/ethernet/msm/msm_rmnet.c
index 41ad8af..4af2d8c 100644
--- a/drivers/net/ethernet/msm/msm_rmnet.c
+++ b/drivers/net/ethernet/msm/msm_rmnet.c
@@ -3,7 +3,7 @@
* Virtual Ethernet Interface for MSM7K Networking
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -37,7 +37,7 @@
#endif
#include <mach/msm_smd.h>
-#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
/* Debug message support */
static int msm_rmnet_debug_mask;
@@ -403,7 +403,7 @@
static void msm_rmnet_unload_modem(void *pil)
{
if (pil)
- pil_put(pil);
+ subsystem_put(pil);
}
static void *msm_rmnet_load_modem(struct net_device *dev)
@@ -412,7 +412,7 @@
int rc;
struct rmnet_private *p = netdev_priv(dev);
- pil = pil_get("modem");
+ pil = subsystem_get("modem");
if (IS_ERR(pil))
pr_err("[%s] %s: modem load failed\n",
dev->name, __func__);
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 2bf857c..b9459dd 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -25,9 +25,11 @@
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
-#include <mach/peripheral-loader.h>
+
#include <mach/msm_smd.h>
#include <mach/msm_iomap.h>
+#include <mach/subsystem_restart.h>
+
#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
#include "wcnss_prealloc.h"
#endif
@@ -664,7 +666,7 @@
}
/* trigger initialization of the WCNSS */
- penv->pil = pil_get(WCNSS_PIL_DEVICE);
+ penv->pil = subsystem_get(WCNSS_PIL_DEVICE);
if (IS_ERR(penv->pil)) {
dev_err(&pdev->dev, "Peripheral Loader failed on WCNSS.\n");
ret = PTR_ERR(penv->pil);
@@ -694,7 +696,7 @@
fail_res:
if (penv->pil)
- pil_put(penv->pil);
+ subsystem_put(penv->pil);
fail_pil:
wcnss_wlan_power(&pdev->dev, &penv->wlan_config,
WCNSS_WLAN_SWITCH_OFF);
@@ -840,7 +842,7 @@
{
if (penv) {
if (penv->pil)
- pil_put(penv->pil);
+ subsystem_put(penv->pil);
kfree(penv);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index 31f60e5..9d5368b 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -13,7 +13,7 @@
#include <linux/memory_alloc.h>
#include <linux/delay.h>
#include <mach/msm_subsystem_map.h>
-#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
#include "vcd_ddl_utils.h"
#include "vcd_ddl.h"
#include "vcd_res_tracker_api.h"
@@ -361,12 +361,12 @@
pr_err("Failed to enable iommu clocks\n");
return false;
}
- dram_base->pil_cookie = pil_get("vidc");
+ dram_base->pil_cookie = subsystem_get("vidc");
if (res_trk_disable_iommu_clocks())
pr_err("Failed to disable iommu clocks\n");
if (IS_ERR_OR_NULL(dram_base->pil_cookie)) {
res_trk_disable_footswitch();
- pr_err("pil_get failed\n");
+ pr_err("subsystem_get failed\n");
return false;
}
} else {
@@ -398,7 +398,7 @@
pr_err("Failed to enable iommu clocks\n");
return;
}
- pil_put(cookie);
+ subsystem_put(cookie);
if (res_trk_disable_iommu_clocks())
pr_err("Failed to disable iommu clocks\n");
if (res_trk_disable_footswitch())
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index 348a231..fe23993 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -74,6 +74,7 @@
u32 irq_gpio_flags;
int *key_codes;
bool need_calibration;
+ bool no_force_update;
u8(*read_chg) (void);
int (*init_hw) (bool);
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 26957b6..7b52956 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -35,7 +35,6 @@
#include <mach/memory.h>
#include <mach/debug_mm.h>
-#include <mach/peripheral-loader.h>
#include <mach/qdsp6v2/audio_acdb.h>
#include <mach/qdsp6v2/rtac.h>
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 875bf47..2d52c43 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -34,7 +34,6 @@
#include <mach/memory.h>
#include <mach/debug_mm.h>
-#include <mach/peripheral-loader.h>
#include <mach/qdsp6v2/audio_acdb.h>
#include <mach/qdsp6v2/rtac.h>
#include <mach/msm_subsystem_map.h>