Merge "msm: pil-riva: Partially revert 6fe41b0"
diff --git a/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt b/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt
index 46b39ec..21d376a 100644
--- a/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt
+++ b/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt
@@ -13,7 +13,7 @@
- interrupts: Specifies the interrupt associated with PON.
Optional properties:
-- qcom,pon-dbc-delay: The debouce delay for the power-key interrupt
+- qcom,pon-dbc-delay The debouce delay for the power-key interrupt
specifed in us. The value ranges from 2 seconds
to 1/64 of a second. Possible values are -
- 2, 1, 1/2, 1/4, 1/8, 1/16, 1/32, 1/64
@@ -24,11 +24,15 @@
reset source. All the child nodes are optional,
if none of them are specified the driver fails
to register.
+- qcom,system-reset Specifies that this PON peripheral can be used
+ to reset the system. This property can only be
+ used by one device on the system. It is an error
+ to include it more than once.
All the below properties are in the sub-node section (properties of the child
node).
-- qcom,pull-up: The initial state of the reset pin under
+- qcom,pull-up The initial state of the reset pin under
consideration.
0 = No pull-up
1 = pull-up enabled
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 0f5fd1c..facb1a8 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -30,6 +30,7 @@
<0x0 0x8 0x4>;
interrupt-names = "kpdpwr", "resin", "resin-bark";
qcom,pon-dbc-delay = <15625>;
+ qcom,system-reset;
qcom,pon_1 {
qcom,pon-type = <0>;
diff --git a/arch/arm/boot/dts/msm8974_pm.dtsi b/arch/arm/boot/dts/msm8974_pm.dtsi
index f3efbb8..8e3f4b8 100644
--- a/arch/arm/boot/dts/msm8974_pm.dtsi
+++ b/arch/arm/boot/dts/msm8974_pm.dtsi
@@ -309,8 +309,9 @@
qcom,ipc-bit-offset = <1>;
qcom,gic-parent = <&intc>;
- qcom,gic-map = <47 180>, /* usb2_hsic_async_wakeup_irq */
+ qcom,gic-map = <47 172>, /* usb2_hsic_async_wakeup_irq */
<53 104>, /* mdss_irq */
+ <62 222>, /* ee0_krait_hlos_spmi_periph_irq */
<0xff 57>, /* mss_to_apps_irq(0) */
<0xff 58>, /* mss_to_apps_irq(1) */
<0xff 59>, /* mss_to_apps_irq(2) */
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 1b792d9..7f10641 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -283,6 +283,7 @@
CONFIG_ION=y
CONFIG_ION_MSM=y
CONFIG_MSM_KGSL=y
+CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES=y
CONFIG_FB=y
CONFIG_FB_MSM=y
# CONFIG_FB_MSM_BACKLIGHT is not set
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index aeb59af..0e0653f 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -285,6 +285,7 @@
CONFIG_ION=y
CONFIG_ION_MSM=y
CONFIG_MSM_KGSL=y
+CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES=y
CONFIG_FB=y
CONFIG_FB_MSM=y
# CONFIG_FB_MSM_BACKLIGHT is not set
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 2c8f71e..db184cd 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -69,6 +69,7 @@
CONFIG_MSM_DSPS=y
CONFIG_MSM_IPC_ROUTER=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_AVS_HW=y
# CONFIG_MSM_HW3D is not set
CONFIG_MSM_PIL_QDSP6V4=y
CONFIG_MSM_PIL_RIVA=y
@@ -96,6 +97,7 @@
CONFIG_MSM_L1_ERR_PANIC=y
CONFIG_MSM_L1_ERR_LOG=y
CONFIG_MSM_L2_ERP_2BIT_PANIC=y
+CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_DCVS=y
CONFIG_MSM_HSIC_SYSMON=y
CONFIG_STRICT_MEMORY_RWX=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index a2deab2..5415425 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -68,6 +68,7 @@
CONFIG_MSM_DSPS=y
CONFIG_MSM_IPC_ROUTER=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_AVS_HW=y
# CONFIG_MSM_HW3D is not set
CONFIG_MSM_PIL_QDSP6V4=y
CONFIG_MSM_PIL_RIVA=y
@@ -87,6 +88,7 @@
CONFIG_MSM_RPM_RBCPR_STATS_LOG=y
CONFIG_MSM_BUS_SCALING=y
CONFIG_MSM_BUS_RPM_MULTI_TIER_ENABLED=y
+CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_WATCHDOG=y
CONFIG_MSM_DLOAD_MODE=y
CONFIG_MSM_RTB=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index badee85..c9b786c 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -2142,6 +2142,14 @@
depends on PM
bool
+config MSM_EVENT_TIMER
+ bool "Event timer"
+ help
+ This option enables a modules that manages a list of event timers that
+ need to be monitored by the PM. The enables the PM code to monitor
+ events that require the core to be awake and ready to handle the
+ event.
+
config MSM_NOPM
default y if !PM
bool
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 70234bf..d8e625a 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -343,6 +343,7 @@
obj-$(CONFIG_MSM_BUSPM_DEV) += msm-buspm-dev.o
obj-$(CONFIG_MSM_IOMMU) += devices-iommu.o iommu_domains.o
+obj-$(CONFIG_MSM_EVENT_TIMER) += event_timer.o
ifdef CONFIG_VCM
obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60-vcm.o
diff --git a/arch/arm/mach-msm/acpuclock-7627.c b/arch/arm/mach-msm/acpuclock-7627.c
index 7be3667..1a2ae48 100644
--- a/arch/arm/mach-msm/acpuclock-7627.c
+++ b/arch/arm/mach-msm/acpuclock-7627.c
@@ -739,7 +739,8 @@
}
}
- if (!(plls_enabled & (1 << tgt_s->pll))) {
+ if ((tgt_s->pll != ACPU_PLL_TCXO) &&
+ !(plls_enabled & (1 << tgt_s->pll))) {
rc = clk_enable(pll_clk[tgt_s->pll].clk);
if (rc < 0) {
pr_err("PLL%d enable failed (%d)\n",
@@ -827,7 +828,8 @@
goto out;
/* Change the AXI bus frequency if we can. */
- if (strt_s->axiclk_khz != tgt_s->axiclk_khz) {
+ if (reason != SETRATE_PC &&
+ strt_s->axiclk_khz != tgt_s->axiclk_khz) {
res = clk_set_rate(drv_state.ebi1_clk,
tgt_s->axiclk_khz * 1000);
if (res < 0)
diff --git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c
index 3c80875..06c2579 100644
--- a/arch/arm/mach-msm/acpuclock-8064.c
+++ b/arch/arm/mach-msm/acpuclock-8064.c
@@ -219,7 +219,7 @@
.l2_freq_tbl = l2_freq_tbl,
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
- .qfprom_phys_base = 0x00700000,
+ .pte_efuse_phys = 0x007000C0,
.stby_khz = 384000,
};
diff --git a/arch/arm/mach-msm/acpuclock-8627.c b/arch/arm/mach-msm/acpuclock-8627.c
index 07a7f8f..9e6662d 100644
--- a/arch/arm/mach-msm/acpuclock-8627.c
+++ b/arch/arm/mach-msm/acpuclock-8627.c
@@ -138,7 +138,7 @@
.l2_freq_tbl = l2_freq_tbl,
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
- .qfprom_phys_base = 0x00700000,
+ .pte_efuse_phys = 0x007000C0,
.stby_khz = 384000,
};
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
index 77876ee..b8ca865 100644
--- a/arch/arm/mach-msm/acpuclock-8930.c
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -221,7 +221,7 @@
.l2_freq_tbl = l2_freq_tbl,
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
- .qfprom_phys_base = 0x00700000,
+ .pte_efuse_phys = 0x007000C0,
.stby_khz = 384000,
};
diff --git a/arch/arm/mach-msm/acpuclock-8930aa.c b/arch/arm/mach-msm/acpuclock-8930aa.c
index dbc3e32..d589f1a 100644
--- a/arch/arm/mach-msm/acpuclock-8930aa.c
+++ b/arch/arm/mach-msm/acpuclock-8930aa.c
@@ -200,7 +200,7 @@
.l2_freq_tbl = l2_freq_tbl,
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
- .qfprom_phys_base = 0x00700000,
+ .pte_efuse_phys = 0x007000C0,
.stby_khz = 384000,
};
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 631bd7e..e16c6b6 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -112,8 +112,10 @@
{ }
};
+#define AVS(x) .avsdscr_setting = (x)
+
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 950000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 950000, AVS(0x40001F) },
{ 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 975000 },
{ 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 975000 },
{ 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 1000000 },
@@ -126,20 +128,20 @@
{ 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1100000 },
{ 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1125000 },
{ 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1125000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1175000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1175000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1200000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1200000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1225000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1225000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1237500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1237500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1250000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1175000, AVS(0x400015) },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1175000, AVS(0x400015) },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1200000, AVS(0x400015) },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1200000, AVS(0x400015) },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1225000, AVS(0x400015) },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1225000, AVS(0x400015) },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1237500, AVS(0x400015) },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1237500, AVS(0x100018) },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1250000, AVS(0x400012) },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000, AVS(0x40007F) },
{ 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 925000 },
{ 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 925000 },
{ 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 950000 },
@@ -152,20 +154,20 @@
{ 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1050000 },
{ 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1075000 },
{ 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1075000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1125000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1125000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1150000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1150000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1175000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1175000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1187500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1187500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1200000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1125000, AVS(0x400015) },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1125000, AVS(0x400015) },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1150000, AVS(0x400015) },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1150000, AVS(0x400015) },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1175000, AVS(0x400015) },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1175000, AVS(0x400015) },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1187500, AVS(0x400015) },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1187500, AVS(0x100018) },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1200000, AVS(0x400012) },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 850000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 850000, AVS(0x4000FF) },
{ 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 875000 },
{ 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 875000 },
{ 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 900000 },
@@ -178,15 +180,15 @@
{ 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1000000 },
{ 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1025000 },
{ 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1025000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1075000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1075000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1100000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1100000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1125000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1125000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1137500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1137500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1150000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1075000, AVS(0x10001B) },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1075000, AVS(0x10001B) },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1100000, AVS(0x10001B) },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1100000, AVS(0x10001B) },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1125000, AVS(0x10001B) },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1125000, AVS(0x400012) },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1137500, AVS(0x400012) },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1137500, AVS(0x400012) },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1150000, AVS(0x400012) },
{ 0, { 0 } }
};
@@ -204,7 +206,7 @@
.l2_freq_tbl = l2_freq_tbl,
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
- .qfprom_phys_base = 0x00700000,
+ .pte_efuse_phys = 0x007000C0,
.stby_khz = 384000,
};
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index 63bff55..628e1ba 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -146,7 +146,7 @@
.l2_freq_tbl = l2_freq_tbl,
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
- .qfprom_phys_base = 0x00700000,
+ .pte_efuse_phys = 0x007000C0,
.stby_khz = 384000,
};
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index 16f77ba..ee2ca45 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -179,7 +179,7 @@
.l2_freq_tbl = l2_freq_tbl,
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
- .qfprom_phys_base = 0xFC4A8000,
+ .pte_efuse_phys = 0xFC4B80B0,
.stby_khz = 300000,
};
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index 9afa7c0..2951c1a 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -36,6 +36,7 @@
#include "acpuclock.h"
#include "acpuclock-krait.h"
+#include "avs.h"
/* MUX source selects. */
#define PRI_SRC_SEL_SEC_SRC 0
@@ -44,9 +45,6 @@
#define SEC_SRC_SEL_L2PLL 1
#define SEC_SRC_SEL_AUX 2
-/* PTE EFUSE register offset. */
-#define PTE_EFUSE 0xC0
-
static DEFINE_MUTEX(driver_lock);
static DEFINE_SPINLOCK(l2_lock);
@@ -472,6 +470,12 @@
vdd_data.vdd_core = calculate_vdd_core(tgt);
vdd_data.ua_core = tgt->ua_core;
+ /* Disable AVS before voltage switch */
+ if (reason == SETRATE_CPUFREQ && drv.scalable[cpu].avs_enabled) {
+ AVS_DISABLE(cpu);
+ drv.scalable[cpu].avs_enabled = false;
+ }
+
/* Increase VDD levels if needed. */
if (reason == SETRATE_CPUFREQ || reason == SETRATE_HOTPLUG) {
rc = increase_vdd(cpu, &vdd_data, reason);
@@ -507,6 +511,12 @@
/* Drop VDD levels if we can. */
decrease_vdd(cpu, &vdd_data, reason);
+ /* Re-enable AVS */
+ if (reason == SETRATE_CPUFREQ && tgt->avsdscr_setting) {
+ AVS_ENABLE(cpu, tgt->avsdscr_setting);
+ drv.scalable[cpu].avs_enabled = true;
+ }
+
dev_dbg(drv.dev, "ACPU%d speed change complete\n", cpu);
out:
@@ -926,25 +936,27 @@
static void krait_apply_vmin(struct acpu_level *tbl)
{
- for (; tbl->speed.khz != 0; tbl++)
+ for (; tbl->speed.khz != 0; tbl++) {
if (tbl->vdd_core < 1150000)
tbl->vdd_core = 1150000;
+ tbl->avsdscr_setting = 0;
+ }
}
-static int __init select_freq_plan(u32 qfprom_phys)
+static int __init select_freq_plan(u32 pte_efuse_phys)
{
- void __iomem *qfprom_base;
- u32 pte_efuse, pvs, tbl_idx;
+ void __iomem *pte_efuse;
+ u32 pte_efuse_val, pvs, tbl_idx;
char *pvs_names[] = { "Slow", "Nominal", "Fast", "Faster", "Unknown" };
- qfprom_base = ioremap(qfprom_phys, SZ_256);
+ pte_efuse = ioremap(pte_efuse_phys, 4);
/* Select frequency tables. */
- if (qfprom_base) {
- pte_efuse = readl_relaxed(qfprom_base + PTE_EFUSE);
- pvs = (pte_efuse >> 10) & 0x7;
- iounmap(qfprom_base);
+ if (pte_efuse) {
+ pte_efuse_val = readl_relaxed(pte_efuse);
+ pvs = (pte_efuse_val >> 10) & 0x7;
+ iounmap(pte_efuse);
if (pvs == 0x7)
- pvs = (pte_efuse >> 13) & 0x7;
+ pvs = (pte_efuse_val >> 13) & 0x7;
switch (pvs) {
case 0x0:
@@ -1005,7 +1017,7 @@
GFP_KERNEL);
BUG_ON(!drv.bus_scale->usecase);
- tbl_idx = select_freq_plan(params->qfprom_phys_base);
+ tbl_idx = select_freq_plan(params->pte_efuse_phys);
drv.acpu_freq_tbl = kmemdup(params->pvs_tables[tbl_idx].table,
params->pvs_tables[tbl_idx].size,
GFP_KERNEL);
diff --git a/arch/arm/mach-msm/acpuclock-krait.h b/arch/arm/mach-msm/acpuclock-krait.h
index 1b891b1..d615b85 100644
--- a/arch/arm/mach-msm/acpuclock-krait.h
+++ b/arch/arm/mach-msm/acpuclock-krait.h
@@ -143,6 +143,7 @@
* @l2_level: L2 configuration to use.
* @vdd_core: CPU core voltage in uV.
* @ua_core: CPU core current consumption in uA.
+ * @avsdscr_setting: AVS DSCR configuration.
*/
struct acpu_level {
const int use_for_scaling;
@@ -150,6 +151,7 @@
const unsigned int l2_level;
int vdd_core;
int ua_core;
+ unsigned int avsdscr_setting;
};
/**
@@ -203,6 +205,7 @@
* @l2_vote: L2 performance level vote associate with the current CPU speed.
* @vreg: Array of voltage regulators needed by the scalable.
* @initialized: Flag set to true when per_cpu_init() has been called.
+ * @avs_enabled: True if avs is enabled for the scalabale. False otherwise.
*/
struct scalable {
const phys_addr_t hfpll_phys_base;
@@ -214,6 +217,7 @@
unsigned int l2_vote;
struct vreg vreg[NUM_VREG];
bool initialized;
+ bool avs_enabled;
};
/**
@@ -236,7 +240,7 @@
* @pvs_tables: CPU frequency tables.
* @l2_freq_tbl: L2 frequency table.
* @l2_freq_tbl_size: Size of @l2_freq_tbl.
- * @qfprom_phys_base: Physical base address of QFPROM.
+ * @pte_efuse_phys: Physical address of PTE EFUSE.
* @bus_scale: MSM bus driver parameters.
* @stby_khz: KHz value corresponding to an always-on clock source.
*/
@@ -247,7 +251,7 @@
struct pvs_table *pvs_tables;
struct l2_level *l2_freq_tbl;
size_t l2_freq_tbl_size;
- phys_addr_t qfprom_phys_base;
+ phys_addr_t pte_efuse_phys;
struct msm_bus_scale_pdata *bus_scale;
unsigned long stby_khz;
};
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index bbb9a81..6cdafbc 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -189,6 +189,7 @@
REGULATOR_SUPPLY("vcc_i2c", "3-0024"),
REGULATOR_SUPPLY("vddp", "0-0048"),
REGULATOR_SUPPLY("hdmi_lvl_tsl", "hdmi_msm.0"),
+ REGULATOR_SUPPLY("vdd-io", "spi0.2"),
};
VREG_CONSUMERS(S5) = {
REGULATOR_SUPPLY("8921_s5", NULL),
@@ -252,7 +253,7 @@
};
VREG_CONSUMERS(EXT_3P3V) = {
REGULATOR_SUPPLY("ext_3p3v", NULL),
- REGULATOR_SUPPLY("vdd_io", "spi0.2"),
+ REGULATOR_SUPPLY("vdd-phy", "spi0.2"),
REGULATOR_SUPPLY("mhl_usb_hs_switch", "msm_otg"),
REGULATOR_SUPPLY("lvds_vccs_3p3v", "lvds.0"),
REGULATOR_SUPPLY("dsi1_vccs_3p3v", "mipi_dsi.1"),
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 3a82b07..06efc03 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1688,8 +1688,8 @@
.reg_base_addr = MSM_SAW0_BASE,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
#if defined(CONFIG_MSM_AVS_HW)
- .reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
- .reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
+ .reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x50589464,
+ .reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00020000,
#endif
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x03020004,
@@ -1703,8 +1703,8 @@
.reg_base_addr = MSM_SAW1_BASE,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
#if defined(CONFIG_MSM_AVS_HW)
- .reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
- .reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
+ .reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x50589464,
+ .reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00020000,
#endif
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020204,
@@ -2822,19 +2822,24 @@
msm_kgsl_3d0.dev.platform_data;
uint32_t soc_platform_version = socinfo_get_version();
+ /* Fixup data that needs to change based on GPU ID */
if (cpu_is_msm8960ab()) {
kgsl_3d0_pdata->chipid = ADRENO_CHIPID(3, 2, 1, 0);
/* 8960PRO nominal clock rate is 325Mhz instead of 320Mhz */
kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 325000000;
- } else if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
- kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
- kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
- } else if (SOCINFO_VERSION_MAJOR(soc_platform_version) >= 3) {
- /* 8960v3 GPU registers returns 5 for patch release
- * but it should be 6, so dummy up the chipid here
- * based the platform type
- */
- kgsl_3d0_pdata->chipid = ADRENO_CHIPID(2, 2, 0, 6);
+ } else {
+ kgsl_3d0_pdata->iommu_count = 1;
+ if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
+ kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
+ kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
+ }
+ if (SOCINFO_VERSION_MAJOR(soc_platform_version) >= 3) {
+ /* 8960v3 GPU registers returns 5 for patch release
+ * but it should be 6, so dummy up the chipid here
+ * based the platform type
+ */
+ kgsl_3d0_pdata->chipid = ADRENO_CHIPID(2, 2, 0, 6);
+ }
}
/* Register the 3D core */
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 01bc9dd..6ddb462 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -6430,16 +6430,16 @@
is_pll_enabled = readl_relaxed(BB_PLL14_STATUS_REG) & BIT(16);
if (!is_pll_enabled)
/* Ref clk = 27MHz and program pll14 to 480MHz */
- configure_pll(&pll14_config, &pll14_regs, 1);
+ configure_sr_pll(&pll14_config, &pll14_regs, 1);
/* Program PLL15 to 975MHz with ref clk = 27MHz */
- configure_pll(&pll15_config, &pll15_regs, 0);
+ configure_sr_pll(&pll15_config, &pll15_regs, 0);
/* Check if PLL4 is active */
is_pll_enabled = readl_relaxed(LCC_PLL0_STATUS_REG) & BIT(16);
if (!is_pll_enabled)
/* Ref clk = 27MHz and program pll4 to 393.2160MHz */
- configure_pll(&pll4_config_393, &pll4_regs, 1);
+ configure_sr_pll(&pll4_config_393, &pll4_regs, 1);
/* Enable PLL4 source on the LPASS Primary PLL Mux */
writel_relaxed(0x1, LCC_PRI_PLL_CLK_CTL_REG);
@@ -6457,7 +6457,7 @@
pll15_config.l = 0x21 | BVAL(31, 7, 0x600);
pll15_config.m = 0x1;
pll15_config.n = 0x3;
- configure_pll(&pll15_config, &pll15_regs, 0);
+ configure_sr_pll(&pll15_config, &pll15_regs, 0);
/* Disable AUX and BIST outputs */
writel_relaxed(0, MM_PLL3_TEST_CTL_REG);
}
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index b054e08..62e8f0f 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -5594,16 +5594,16 @@
if (!(readl_relaxed(GCC_REG_BASE(GPLL0_STATUS_REG))
& gpll0_clk_src.status_mask))
- configure_pll(&gpll0_config, &gpll0_regs, 1);
+ configure_sr_hpm_lp_pll(&gpll0_config, &gpll0_regs, 1);
if (!(readl_relaxed(GCC_REG_BASE(GPLL1_STATUS_REG))
& gpll1_clk_src.status_mask))
- configure_pll(&gpll1_config, &gpll1_regs, 1);
+ configure_sr_hpm_lp_pll(&gpll1_config, &gpll1_regs, 1);
- configure_pll(&mmpll0_config, &mmpll0_regs, 1);
- configure_pll(&mmpll1_config, &mmpll1_regs, 1);
- configure_pll(&mmpll3_config, &mmpll3_regs, 0);
- configure_pll(&lpapll0_config, &lpapll0_regs, 1);
+ configure_sr_hpm_lp_pll(&mmpll0_config, &mmpll0_regs, 1);
+ configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
+ configure_sr_hpm_lp_pll(&mmpll3_config, &mmpll3_regs, 0);
+ configure_sr_hpm_lp_pll(&lpapll0_config, &lpapll0_regs, 1);
/* Enable GPLL0's aux outputs. */
regval = readl_relaxed(GCC_REG_BASE(GPLL0_USER_CTL_REG));
@@ -5769,7 +5769,7 @@
if (!virt_bases[APCS_BASE])
panic("clock-8974: Unable to ioremap APCS_GCC_CC memory!");
- clk_ops_local_pll.enable = msm8974_pll_clk_enable;
+ clk_ops_local_pll.enable = sr_hpm_lp_pll_clk_enable;
vdd_dig_reg = rpm_regulator_get(NULL, "vdd_dig");
if (IS_ERR(vdd_dig_reg))
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 648a8d4..15eaa4b 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1807,14 +1807,14 @@
regval |= BIT(12);
writel_relaxed(regval, BB_PLL0_TEST_CTL_REG);
- configure_pll(&pll0_config, &pll0_regs, 1);
+ configure_sr_pll(&pll0_config, &pll0_regs, 1);
}
/* Check if PLL14 is enabled in FSM mode */
is_pll_enabled = readl_relaxed(BB_PLL14_STATUS_REG) & BIT(16);
if (!is_pll_enabled)
- configure_pll(&pll14_config, &pll14_regs, 1);
+ configure_sr_pll(&pll14_config, &pll14_regs, 1);
else if (!(readl_relaxed(BB_PLL14_MODE_REG) & BIT(20)))
WARN(1, "PLL14 enabled in non-FSM mode!\n");
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index d5831e2..23941d7 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -247,7 +247,7 @@
#define PLL_LOCKED_BIT BIT(16)
-int msm8974_pll_clk_enable(struct clk *c)
+int sr_hpm_lp_pll_clk_enable(struct clk *c)
{
unsigned long flags;
struct pll_clk *pll = to_pll_clk(c);
@@ -255,23 +255,12 @@
int ret = 0;
spin_lock_irqsave(&pll_reg_lock, flags);
- mode = readl_relaxed(PLL_MODE_REG(pll));
- /* Disable PLL bypass mode. */
- mode |= PLL_BYPASSNL;
+
+ /* Disable PLL bypass mode and de-assert reset. */
+ mode = PLL_BYPASSNL | PLL_RESET_N;
writel_relaxed(mode, PLL_MODE_REG(pll));
- /*
- * H/W requires a 5us delay between disabling the bypass and
- * de-asserting the reset. Delay 10us just to be safe.
- */
- mb();
- udelay(10);
-
- /* De-assert active-low PLL reset. */
- mode |= PLL_RESET_N;
- writel_relaxed(mode, PLL_MODE_REG(pll));
-
- /* Wait for pll to enable. */
+ /* Wait for pll to lock. */
for (count = ENABLE_WAIT_MAX_LOOPS; count > 0; count--) {
if (readl_relaxed(PLL_STATUS_REG(pll)) & PLL_LOCKED_BIT)
break;
@@ -453,7 +442,8 @@
.is_enabled = pll_clk_is_enabled,
};
-static void __init __set_fsm_mode(void __iomem *mode_reg)
+static void __init __set_fsm_mode(void __iomem *mode_reg,
+ u32 bias_count, u32 lock_count)
{
u32 regval = readl_relaxed(mode_reg);
@@ -463,12 +453,12 @@
/* Program bias count */
regval &= ~BM(19, 14);
- regval |= BVAL(19, 14, 0x1);
+ regval |= BVAL(19, 14, bias_count);
writel_relaxed(regval, mode_reg);
/* Program lock count */
regval &= ~BM(13, 8);
- regval |= BVAL(13, 8, 0x8);
+ regval |= BVAL(13, 8, lock_count);
writel_relaxed(regval, mode_reg);
/* Enable PLL FSM voting */
@@ -476,7 +466,7 @@
writel_relaxed(regval, mode_reg);
}
-void __init configure_pll(struct pll_config *config,
+void __init __configure_pll(struct pll_config *config,
struct pll_config_regs *regs, u32 ena_fsm_mode)
{
u32 regval;
@@ -509,8 +499,21 @@
regval &= ~config->vco_mask;
regval |= config->vco_val;
writel_relaxed(regval, PLL_CONFIG_REG(regs));
-
- /* Configure in FSM mode if necessary */
- if (ena_fsm_mode)
- __set_fsm_mode(PLL_MODE_REG(regs));
}
+
+void __init configure_sr_pll(struct pll_config *config,
+ struct pll_config_regs *regs, u32 ena_fsm_mode)
+{
+ __configure_pll(config, regs, ena_fsm_mode);
+ if (ena_fsm_mode)
+ __set_fsm_mode(PLL_MODE_REG(regs), 0x1, 0x8);
+}
+
+void __init configure_sr_hpm_lp_pll(struct pll_config *config,
+ struct pll_config_regs *regs, u32 ena_fsm_mode)
+{
+ __configure_pll(config, regs, ena_fsm_mode);
+ if (ena_fsm_mode)
+ __set_fsm_mode(PLL_MODE_REG(regs), 0x1, 0x0);
+}
+
diff --git a/arch/arm/mach-msm/clock-pll.h b/arch/arm/mach-msm/clock-pll.h
index 90f8a95..30f595b 100644
--- a/arch/arm/mach-msm/clock-pll.h
+++ b/arch/arm/mach-msm/clock-pll.h
@@ -111,7 +111,7 @@
}
int sr_pll_clk_enable(struct clk *c);
-int msm8974_pll_clk_enable(struct clk *c);
+int sr_hpm_lp_pll_clk_enable(struct clk *c);
/*
* PLL vote clock APIs
@@ -146,6 +146,8 @@
void *const __iomem *base;
};
-void __init configure_pll(struct pll_config *, struct pll_config_regs *, u32);
-
+void configure_sr_pll(struct pll_config *config, struct pll_config_regs *regs,
+ u32 ena_fsm_mode);
+void configure_sr_hpm_lp_pll(struct pll_config *config,
+ struct pll_config_regs *, u32 ena_fsm_mode);
#endif
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index 05bd56ef..6c9b413 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -32,19 +32,6 @@
#include "acpuclock.h"
-#ifdef CONFIG_SMP
-struct cpufreq_work_struct {
- struct work_struct work;
- struct cpufreq_policy *policy;
- struct completion complete;
- int frequency;
- int status;
-};
-
-static DEFINE_PER_CPU(struct cpufreq_work_struct, cpufreq_work);
-static struct workqueue_struct *msm_cpufreq_wq;
-#endif
-
struct cpufreq_suspend_t {
struct mutex suspend_mutex;
int device_suspended;
@@ -91,45 +78,6 @@
return ret;
}
-#ifdef CONFIG_SMP
-static int __cpuinit msm_cpufreq_cpu_callback(struct notifier_block *nfb,
- unsigned long action, void *hcpu)
-{
- unsigned int cpu = (unsigned long)hcpu;
-
- switch (action) {
- case CPU_ONLINE:
- case CPU_ONLINE_FROZEN:
- per_cpu(cpufreq_suspend, cpu).device_suspended = 0;
- break;
- case CPU_DOWN_PREPARE:
- case CPU_DOWN_PREPARE_FROZEN:
- mutex_lock(&per_cpu(cpufreq_suspend, cpu).suspend_mutex);
- per_cpu(cpufreq_suspend, cpu).device_suspended = 1;
- mutex_unlock(&per_cpu(cpufreq_suspend, cpu).suspend_mutex);
- break;
- case CPU_DOWN_FAILED:
- case CPU_DOWN_FAILED_FROZEN:
- per_cpu(cpufreq_suspend, cpu).device_suspended = 0;
- break;
- }
- return NOTIFY_OK;
-}
-
-static struct notifier_block __refdata msm_cpufreq_cpu_notifier = {
- .notifier_call = msm_cpufreq_cpu_callback,
-};
-
-static void set_cpu_work(struct work_struct *work)
-{
- struct cpufreq_work_struct *cpu_work =
- container_of(work, struct cpufreq_work_struct, work);
-
- cpu_work->status = set_cpu_freq(cpu_work->policy, cpu_work->frequency);
- complete(&cpu_work->complete);
-}
-#endif
-
static int msm_cpufreq_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
@@ -137,19 +85,12 @@
int ret = -EFAULT;
int index;
struct cpufreq_frequency_table *table;
-#ifdef CONFIG_SMP
- struct cpufreq_work_struct *cpu_work = NULL;
- cpumask_var_t mask;
if (!cpu_active(policy->cpu)) {
pr_info("cpufreq: cpu %d is not active.\n", policy->cpu);
return -ENODEV;
}
- if (!alloc_cpumask_var(&mask, GFP_KERNEL))
- return -ENOMEM;
-#endif
-
mutex_lock(&per_cpu(cpufreq_suspend, policy->cpu).suspend_mutex);
if (per_cpu(cpufreq_suspend, policy->cpu).device_suspended) {
@@ -167,39 +108,13 @@
goto done;
}
-#ifdef CONFIG_CPU_FREQ_DEBUG
pr_debug("CPU[%d] target %d relation %d (%d-%d) selected %d\n",
policy->cpu, target_freq, relation,
policy->min, policy->max, table[index].frequency);
-#endif
-#ifdef CONFIG_SMP
- cpu_work = &per_cpu(cpufreq_work, policy->cpu);
- cpu_work->policy = policy;
- cpu_work->frequency = table[index].frequency;
- cpu_work->status = -ENODEV;
-
- cpumask_clear(mask);
- cpumask_set_cpu(policy->cpu, mask);
- if (cpumask_equal(mask, ¤t->cpus_allowed)) {
- ret = set_cpu_freq(cpu_work->policy, cpu_work->frequency);
- goto done;
- } else {
- cancel_work_sync(&cpu_work->work);
- INIT_COMPLETION(cpu_work->complete);
- queue_work_on(policy->cpu, msm_cpufreq_wq, &cpu_work->work);
- wait_for_completion(&cpu_work->complete);
- }
-
- ret = cpu_work->status;
-#else
ret = set_cpu_freq(policy, table[index].frequency);
-#endif
done:
-#ifdef CONFIG_SMP
- free_cpumask_var(mask);
-#endif
mutex_unlock(&per_cpu(cpufreq_suspend, policy->cpu).suspend_mutex);
return ret;
}
@@ -282,10 +197,6 @@
int cur_freq;
int index;
struct cpufreq_frequency_table *table;
-#ifdef CONFIG_SMP
- struct cpufreq_work_struct *cpu_work = NULL;
-#endif
-
table = cpufreq_frequency_get_table(policy->cpu);
if (table == NULL)
@@ -314,7 +225,7 @@
CPUFREQ_RELATION_H, &index) &&
cpufreq_frequency_table_target(policy, table, cur_freq,
CPUFREQ_RELATION_L, &index)) {
- pr_info("cpufreq: cpu%d at invalid freq: %d\n",
+ pr_info("%s: cpu%d at invalid freq: %d\n", __func__,
policy->cpu, cur_freq);
return -EINVAL;
}
@@ -334,15 +245,39 @@
policy->cpuinfo.transition_latency =
acpuclk_get_switch_time() * NSEC_PER_USEC;
-#ifdef CONFIG_SMP
- cpu_work = &per_cpu(cpufreq_work, policy->cpu);
- INIT_WORK(&cpu_work->work, set_cpu_work);
- init_completion(&cpu_work->complete);
-#endif
return 0;
}
+static int __cpuinit msm_cpufreq_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ per_cpu(cpufreq_suspend, cpu).device_suspended = 0;
+ break;
+ case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
+ mutex_lock(&per_cpu(cpufreq_suspend, cpu).suspend_mutex);
+ per_cpu(cpufreq_suspend, cpu).device_suspended = 1;
+ mutex_unlock(&per_cpu(cpufreq_suspend, cpu).suspend_mutex);
+ break;
+ case CPU_DOWN_FAILED:
+ case CPU_DOWN_FAILED_FROZEN:
+ per_cpu(cpufreq_suspend, cpu).device_suspended = 0;
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __refdata msm_cpufreq_cpu_notifier = {
+ .notifier_call = msm_cpufreq_cpu_callback,
+};
+
static int msm_cpufreq_suspend(void)
{
int cpu;
@@ -382,6 +317,10 @@
}
}
+static struct notifier_block msm_cpufreq_pm_notifier = {
+ .notifier_call = msm_cpufreq_pm_event,
+};
+
static struct freq_attr *msm_freq_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
@@ -398,10 +337,6 @@
.attr = msm_freq_attr,
};
-static struct notifier_block msm_cpufreq_pm_notifier = {
- .notifier_call = msm_cpufreq_pm_event,
-};
-
static int __init msm_cpufreq_register(void)
{
int cpu;
@@ -411,10 +346,7 @@
per_cpu(cpufreq_suspend, cpu).device_suspended = 0;
}
-#ifdef CONFIG_SMP
- msm_cpufreq_wq = create_workqueue("msm-cpufreq");
register_hotcpu_notifier(&msm_cpufreq_cpu_notifier);
-#endif
register_pm_notifier(&msm_cpufreq_pm_notifier);
return cpufreq_register_driver(&msm_cpufreq_driver);
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index d22690c..33782ab 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -3145,18 +3145,29 @@
},
};
-static const struct kgsl_iommu_ctx kgsl_3d0_iommu_ctxs[] = {
+static const struct kgsl_iommu_ctx kgsl_3d0_iommu0_ctxs[] = {
{ "gfx3d_user", 0 },
{ "gfx3d_priv", 1 },
};
+static const struct kgsl_iommu_ctx kgsl_3d0_iommu1_ctxs[] = {
+ { "gfx3d1_user", 0 },
+ { "gfx3d1_priv", 1 },
+};
+
static struct kgsl_device_iommu_data kgsl_3d0_iommu_data[] = {
{
- .iommu_ctxs = kgsl_3d0_iommu_ctxs,
- .iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu_ctxs),
+ .iommu_ctxs = kgsl_3d0_iommu0_ctxs,
+ .iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu0_ctxs),
.physstart = 0x07C00000,
.physend = 0x07C00000 + SZ_1M - 1,
},
+ {
+ .iommu_ctxs = kgsl_3d0_iommu1_ctxs,
+ .iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu1_ctxs),
+ .physstart = 0x07D00000,
+ .physend = 0x07D00000 + SZ_1M - 1,
+ },
};
static struct kgsl_device_platform_data kgsl_3d0_pdata = {
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index cd5b2e5..c877ba9 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1728,7 +1728,7 @@
uint32_t quot;
/* This formula is as per chip characterization data */
- quot = max_quot - ((max_freq / 10 - new_freq / 10) * 5);
+ quot = max_quot - (((max_freq - new_freq) * 5) / 10);
return quot;
}
diff --git a/arch/arm/mach-msm/event_timer.c b/arch/arm/mach-msm/event_timer.c
new file mode 100644
index 0000000..e06dad4
--- /dev/null
+++ b/arch/arm/mach-msm/event_timer.c
@@ -0,0 +1,318 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <mach/event_timer.h>
+
+#define __INIT_HEAD(x) { .head = RB_ROOT,\
+ .next = NULL, }
+
+#define DEFINE_TIME_HEAD(x) struct timerqueue_head x = __INIT_HEAD(x)
+
+/**
+ * struct event_timer_info - basic event timer structure
+ * @node: timerqueue node to track time ordered data structure
+ * of event timers
+ * @timer: hrtimer created for this event.
+ * @function : callback function for event timer.
+ * @data : callback data for event timer.
+ */
+struct event_timer_info {
+ struct timerqueue_node node;
+ void (*function)(void *);
+ void *data;
+};
+
+
+static DEFINE_TIME_HEAD(timer_head);
+static DEFINE_SPINLOCK(event_timer_lock);
+static struct hrtimer event_hrtimer;
+static enum hrtimer_restart event_hrtimer_cb(struct hrtimer *hrtimer);
+
+static int msm_event_debug_mask;
+module_param_named(
+ debug_mask, msm_event_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
+);
+
+enum {
+ MSM_EVENT_TIMER_DEBUG = 1U << 0,
+};
+
+
+/**
+ * add_event_timer() : Add a wakeup event. Intended to be called
+ * by clients once. Returns a handle to be used
+ * for future transactions.
+ * @function : The callback function will be called when event
+ * timer expires.
+ * @data: callback data provided by client.
+ */
+struct event_timer_info *add_event_timer(void (*function)(void *), void *data)
+{
+ struct event_timer_info *event_info =
+ kzalloc(sizeof(struct event_timer_info), GFP_KERNEL);
+
+ if (!event_info)
+ return NULL;
+
+ event_info->function = function;
+ event_info->data = data;
+ /* Init rb node and hr timer */
+ timerqueue_init(&event_info->node);
+
+ return event_info;
+}
+
+/**
+ * is_event_next(): Helper function to check if the event is the next
+ * next expiring event
+ * @event : handle to the event to be checked.
+ */
+static bool is_event_next(struct event_timer_info *event)
+{
+ struct event_timer_info *next_event;
+ struct timerqueue_node *next;
+ bool ret = false;
+
+ next = timerqueue_getnext(&timer_head);
+ if (!next)
+ goto exit_is_next_event;
+
+ next_event = container_of(next, struct event_timer_info, node);
+ if (!next_event)
+ goto exit_is_next_event;
+
+ if (next_event == event)
+ ret = true;
+
+exit_is_next_event:
+ return ret;
+}
+
+/**
+ * is_event_active(): Helper function to check if the timer for a given event
+ * has been started.
+ * @event : handle to the event to be checked.
+ */
+static bool is_event_active(struct event_timer_info *event)
+{
+ struct timerqueue_node *next;
+ struct event_timer_info *next_event;
+ bool ret = false;
+
+ for (next = timerqueue_getnext(&timer_head); next;
+ next = timerqueue_iterate_next(next)) {
+ next_event = container_of(next, struct event_timer_info, node);
+
+ if (event == next_event) {
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+}
+
+/**
+ * create_httimer(): Helper function to setup hrtimer.
+ */
+static void create_hrtimer(ktime_t expires)
+{
+ static bool timer_initialized;
+
+ if (!timer_initialized) {
+ hrtimer_init(&event_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ timer_initialized = true;
+ }
+
+ event_hrtimer.function = event_hrtimer_cb;
+ hrtimer_start(&event_hrtimer, expires, HRTIMER_MODE_ABS);
+
+ if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+ pr_info("%s: Setting timer for %lu", __func__,
+ (unsigned long)ktime_to_ns(expires));
+}
+
+/**
+ * event_hrtimer_cb() : Callback function for hr timer.
+ * Make the client CB from here and remove the event
+ * from the time ordered queue.
+ */
+static enum hrtimer_restart event_hrtimer_cb(struct hrtimer *hrtimer)
+{
+ struct event_timer_info *event;
+ struct timerqueue_node *next;
+
+ next = timerqueue_getnext(&timer_head);
+
+ while (next && (ktime_to_ns(next->expires)
+ <= ktime_to_ns(hrtimer->node.expires))) {
+ if (!next)
+ goto hrtimer_cb_exit;
+
+ event = container_of(next, struct event_timer_info, node);
+ if (!event)
+ goto hrtimer_cb_exit;
+
+ if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+ pr_info("%s: Deleting event @ %lu", __func__,
+ (unsigned long)ktime_to_ns(next->expires));
+
+ timerqueue_del(&timer_head, &event->node);
+
+ if (event->function)
+ event->function(event->data);
+ next = timerqueue_getnext(&timer_head);
+ }
+
+ if (next)
+ create_hrtimer(next->expires);
+
+hrtimer_cb_exit:
+ return HRTIMER_NORESTART;
+}
+
+/**
+ * create_timer_smp(): Helper function used setting up timer on core 0.
+ */
+static void create_timer_smp(void *data)
+{
+ unsigned long flags;
+ struct event_timer_info *event =
+ (struct event_timer_info *)data;
+
+ local_irq_save(flags);
+ create_hrtimer(event->node.expires);
+ local_irq_restore(flags);
+}
+
+/**
+ * setup_timer() : Helper function to setup timer on primary
+ * core during hrtimer callback.
+ * @event: event handle causing the wakeup.
+ */
+static void setup_event_hrtimer(struct event_timer_info *event)
+{
+ struct timerqueue_node *next;
+ unsigned long flags;
+
+ spin_lock_irqsave(&event_timer_lock, flags);
+ if (is_event_active(event))
+ timerqueue_del(&timer_head, &event->node);
+
+ next = timerqueue_getnext(&timer_head);
+ timerqueue_add(&timer_head, &event->node);
+ spin_unlock_irqrestore(&event_timer_lock, flags);
+
+ if (!next ||
+ (next && (ktime_to_ns(event->node.expires) <
+ ktime_to_ns(next->expires)))) {
+ if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+ pr_info("%s: Setting timer for %lu", __func__,
+ (unsigned long)ktime_to_ns(event->node.expires));
+
+ smp_call_function_single(0, create_timer_smp, event, 1);
+ }
+}
+
+/**
+ * activate_event_timer() : Set the expiration time for an event in absolute
+ * ktime. This is a oneshot event timer, clients
+ * should call this again to set another expiration.
+ * @event : event handle.
+ * @event_time : event time in absolute ktime.
+ */
+void activate_event_timer(struct event_timer_info *event, ktime_t event_time)
+{
+ if (!event)
+ return;
+
+ if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+ pr_info("%s: Adding event timer @ %lu", __func__,
+ (unsigned long)ktime_to_us(event_time));
+
+ event->node.expires = event_time;
+ /* Start hr timer and add event to rb tree */
+ setup_event_hrtimer(event);
+}
+
+
+/**
+ * deactivate_event_timer() : Deactivate an event timer, this removes the event from
+ * the time ordered queue of event timers.
+ * @event: event handle.
+ */
+void deactivate_event_timer(struct event_timer_info *event)
+{
+ unsigned long flags;
+
+ if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+ pr_info("%s: Deactivate timer", __func__);
+
+ spin_lock_irqsave(&event_timer_lock, flags);
+ if (is_event_active(event)) {
+ if (is_event_next(event))
+ hrtimer_try_to_cancel(&event_hrtimer);
+
+ timerqueue_del(&timer_head, &event->node);
+ }
+ spin_unlock_irqrestore(&event_timer_lock, flags);
+}
+
+/**
+ * destroy_event_timer() : Free the event info data structure allocated during
+ * add_event_timer().
+ * @event: event handle.
+ */
+void destroy_event_timer(struct event_timer_info *event)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&event_timer_lock, flags);
+ if (is_event_active(event)) {
+ if (is_event_next(event))
+ hrtimer_try_to_cancel(&event_hrtimer);
+
+ timerqueue_del(&timer_head, &event->node);
+ }
+ spin_unlock_irqrestore(&event_timer_lock, flags);
+ kfree(event);
+}
+
+/**
+ * get_next_event_timer() - Get the next wakeup event. Returns
+ * a ktime value of the next expiring event.
+ */
+ktime_t get_next_event_time(void)
+{
+ unsigned long flags;
+ struct timerqueue_node *next;
+ ktime_t next_event = ns_to_ktime(0);
+
+ spin_lock_irqsave(&event_timer_lock, flags);
+ next = timerqueue_getnext(&timer_head);
+ spin_unlock_irqrestore(&event_timer_lock, flags);
+
+ if (!next)
+ return next_event;
+
+ next_event = hrtimer_get_remaining(&event_hrtimer);
+ if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+ pr_info("%s: Next Event %lu", __func__,
+ (unsigned long)ktime_to_us(next_event));
+
+ return next_event;
+}
diff --git a/arch/arm/mach-msm/include/mach/event_timer.h b/arch/arm/mach-msm/include/mach/event_timer.h
new file mode 100644
index 0000000..7a00b23
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/event_timer.h
@@ -0,0 +1,77 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_EVENT_TIMER_H
+#define __ARCH_ARM_MACH_MSM_EVENT_TIMER_H
+
+#include <linux/hrtimer.h>
+
+struct event_timer_info;
+
+#ifdef CONFIG_MSM_EVENT_TIMER
+/**
+ * add_event_timer() : Add a wakeup event. Intended to be called
+ * by clients once. Returns a handle to be used
+ * for future transactions.
+ * @function : The callback function will be called when event
+ * timer expires.
+ * @data : Callback data provided by client.
+ */
+struct event_timer_info *add_event_timer(void (*function)(void *), void *data);
+
+/** activate_event_timer() : Set the expiration time for an event in absolute
+ * ktime. This is a oneshot event timer, clients
+ * should call this again to set another expiration.
+ * @event : Event handle.
+ * @event_time : Event time in absolute ktime.
+ */
+void activate_event_timer(struct event_timer_info *event, ktime_t event_time);
+
+/**
+ * deactivate_event_timer() : Deactivate an event timer.
+ * @event: event handle.
+ */
+void deactivate_event_timer(struct event_timer_info *event);
+
+/**
+ * destroy_event_timer() : Free the event info data structure allocated during
+ * add_event_timer().
+ * @event: event handle.
+ */
+void destroy_event_timer(struct event_timer_info *event);
+
+/**
+ * get_next_event_timer() : Get the next wakeup event.
+ * returns a ktime value of the next
+ * expiring event.
+ */
+ktime_t get_next_event_time(void);
+#else
+static inline void *add_event_timer(void (*function)(void *), void *data)
+{
+ return NULL;
+}
+
+static inline void activate_event_timer(void *event, ktime_t event_time) {}
+
+static inline void deactivate_event_timer(void *event) {}
+
+static inline void destroy_event_timer(void *event) {}
+
+static inline ktime_t get_next_event_time(void)
+{
+ return ns_to_ktime(0);
+}
+
+#endif /* CONFIG_MSM_EVENT_TIMER_MANAGER */
+#endif /* __ARCH_ARM_MACH_MSM_EVENT_TIMER_H */
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-9625.h b/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
index 493cf36..eecdd67 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
@@ -23,7 +23,7 @@
*
*/
-#define MSM9625_SHARED_RAM_PHYS 0x18D00000
+#define MSM9625_SHARED_RAM_PHYS 0x00000000
#define MSM9625_APCS_GCC_PHYS 0xF9011000
#define MSM9625_APCS_GCC_SIZE SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 21bea4f..6f925d4 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -105,7 +105,7 @@
#if defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_MSM7X27) \
- || defined(CONFIG_ARCH_MSM7X30)
+ || defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM9625)
#define MSM_SHARED_RAM_SIZE SZ_1M
#else
#define MSM_SHARED_RAM_SIZE SZ_2M
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 5430f99..e0fec65 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -497,7 +497,7 @@
void __init msm_map_mpq8092_io(void)
{
- msm_shared_ram_phys = MSM8974_MSM_SHARED_RAM_PHYS;
+ msm_shared_ram_phys = MSM8092_MSM_SHARED_RAM_PHYS;
msm_map_io(mpq8092_io_desc, ARRAY_SIZE(mpq8092_io_desc));
}
#endif /* CONFIG_ARCH_MPQ8092 */
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index 7dc8d0f..c82eac1 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -2096,7 +2096,7 @@
mutex_lock(&rt_entry->lock);
i += scnprintf(buf + i, max - i,
"Node Id: 0x%08x\n", rt_entry->node_id);
- if (j == IPC_ROUTER_NID_LOCAL) {
+ if (rt_entry->node_id == IPC_ROUTER_NID_LOCAL) {
i += scnprintf(buf + i, max - i,
"XPRT Name: Loopback\n");
i += scnprintf(buf + i, max - i,
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index f7456ef..8218a42 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -92,8 +92,8 @@
}
static void *msm_lpm_lowest_limits(bool from_idle,
- enum msm_pm_sleep_mode sleep_mode, uint32_t latency_us,
- uint32_t sleep_us, uint32_t *power)
+ enum msm_pm_sleep_mode sleep_mode,
+ struct msm_pm_time_params *time_param, uint32_t *power)
{
unsigned int cpu = smp_processor_id();
struct msm_rpmrs_level *best_level = NULL;
@@ -114,20 +114,22 @@
if (sleep_mode != level->sleep_mode)
continue;
- if (latency_us < level->latency_us)
+ if (time_param->latency_us < level->latency_us)
continue;
- if (sleep_us <= 1) {
+ if (time_param->sleep_us <= 1) {
pwr = level->energy_overhead;
- } else if (sleep_us <= level->time_overhead_us) {
- pwr = level->energy_overhead / sleep_us;
- } else if ((sleep_us >> 10) > level->time_overhead_us) {
+ } else if (time_param->sleep_us <= level->time_overhead_us) {
+ pwr = level->energy_overhead / time_param->sleep_us;
+ } else if ((time_param->sleep_us >> 10)
+ > level->time_overhead_us) {
pwr = level->steady_state_power;
} else {
pwr = level->steady_state_power;
pwr -= (level->time_overhead_us *
- level->steady_state_power)/sleep_us;
- pwr += level->energy_overhead / sleep_us;
+ level->steady_state_power) /
+ time_param->sleep_us;
+ pwr += level->energy_overhead / time_param->sleep_us;
}
if (!best_level || best_level->rs_limits.power[cpu] >= pwr) {
diff --git a/arch/arm/mach-msm/msm_cpr.c b/arch/arm/mach-msm/msm_cpr.c
index e2640a2..12f7d96 100644
--- a/arch/arm/mach-msm/msm_cpr.c
+++ b/arch/arm/mach-msm/msm_cpr.c
@@ -44,6 +44,8 @@
*/
#define TIMER_COUNT(freq, delay) ((freq * delay) / 1000)
#define ALL_CPR_IRQ 0x3F
+#define STEP_QUOT_MAX 25
+#define STEP_QUOT_MIN 12
/* Need platform device handle for suspend and resume APIs */
static struct platform_device *cpr_pdev;
@@ -269,8 +271,19 @@
goto err_poll_result;
}
quot2 = (cpr_read_reg(cpr, RBCPR_DEBUG1) & QUOT_SLOW_M) >> 12;
- chip_data->step_quot = (quot1 - quot2) / 4;
- pr_info("%s: Calculated Step Quot is %d\n",
+ /*
+ * Based on chip characterization data, it is good to add some
+ * margin on top of calculated step quot to help reduce the
+ * number of CPR interrupts. The present value suggested is 3.
+ * Further, if the step quot is outside range, clamp it to the
+ * maximum permitted value.
+ */
+ chip_data->step_quot = ((quot1 - quot2) / 4) + 3;
+ if (chip_data->step_quot < STEP_QUOT_MIN ||
+ chip_data->step_quot > STEP_QUOT_MAX)
+ chip_data->step_quot = STEP_QUOT_MAX;
+
+ pr_info("%s: Step Quot is %d\n",
__func__, chip_data->step_quot);
/* Disable the cpr */
cpr_modify_reg(cpr, RBCPR_CTL, LOOP_EN_M, DISABLE_CPR);
@@ -626,6 +639,8 @@
RBCPR_GCNT_TARGET(cpr->curr_osc)));
pr_debug("%s: new_freq: %d, set_freq: %d, quot: %d\n", __func__,
freqs->new, new_freq, quot);
+ pr_info("%s: PVS Voltage setting is: %d\n", __func__,
+ regulator_get_voltage(cpr->vreg_cx));
enable_irq(cpr->irq);
/**
diff --git a/arch/arm/mach-msm/ocmem_rdm.c b/arch/arm/mach-msm/ocmem_rdm.c
index 85dc85d..4aba69c 100644
--- a/arch/arm/mach-msm/ocmem_rdm.c
+++ b/arch/arm/mach-msm/ocmem_rdm.c
@@ -93,8 +93,8 @@
static void *br_base;
static void *dm_base;
-static atomic_t dm_pending;
-static wait_queue_head_t dm_wq;
+struct completion dm_clear_event;
+struct completion dm_transfer_event;
/* Shadow tables for debug purposes */
struct ocmem_br_table {
unsigned int offset;
@@ -136,22 +136,22 @@
pr_debug("Data mover completed\n");
irq_status &= ~BIT(0);
ocmem_write(irq_status, dm_base + DM_INTR_CLR);
+ complete(&dm_transfer_event);
} else if (irq_status & BIT(1)) {
pr_debug("Data clear engine completed\n");
irq_status &= ~BIT(1);
ocmem_write(irq_status, dm_base + DM_INTR_CLR);
+ complete(&dm_clear_event);
} else {
BUG_ON(1);
}
- atomic_set(&dm_pending, 0);
- wake_up_interruptible(&dm_wq);
return IRQ_HANDLED;
}
#ifdef CONFIG_MSM_OCMEM_NONSECURE
int ocmem_clear(unsigned long start, unsigned long size)
{
- atomic_set(&dm_pending, 1);
+ INIT_COMPLETION(dm_clear_event);
/* Clear DM Mask */
ocmem_write(DM_MASK_RESET, dm_base + DM_INTR_MASK);
/* Clear DM Interrupts */
@@ -169,8 +169,8 @@
/* Trigger Data Clear */
ocmem_write(DM_CLR_ENABLE, dm_base + DM_CLR_TRIGGER);
- wait_event_interruptible(dm_wq,
- atomic_read(&dm_pending) == 0);
+ wait_for_completion(&dm_clear_event);
+
return 0;
}
#else
@@ -249,7 +249,7 @@
status = ocmem_read(dm_base + DM_GEN_STATUS);
pr_debug("Transfer status before %x\n", status);
- atomic_set(&dm_pending, 1);
+ INIT_COMPLETION(dm_transfer_event);
/* The DM and BR tables must be programmed before triggering the
* Data Mover else the coherent transfer would be corrupted
*/
@@ -258,9 +258,7 @@
ocmem_write(dm_ctrl, dm_base + DM_CTRL);
pr_debug("ocmem: rdm: dm_ctrl %x br_ctrl %x\n", dm_ctrl, br_ctrl);
- wait_event_interruptible(dm_wq,
- atomic_read(&dm_pending) == 0);
-
+ wait_for_completion(&dm_transfer_event);
ocmem_disable_core_clock();
return 0;
}
@@ -291,7 +289,8 @@
return rc;
}
- init_waitqueue_head(&dm_wq);
+ init_completion(&dm_clear_event);
+ init_completion(&dm_transfer_event);
/* Clear DM Mask */
ocmem_write(DM_MASK_RESET, dm_base + DM_INTR_MASK);
/* enable dm interrupts */
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index dbb23d5..60ee8f0 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -49,6 +49,7 @@
#include "spm.h"
#include "timer.h"
#include "pm-boot.h"
+#include <mach/event_timer.h>
/******************************************************************************
* Debug Definitions
@@ -112,6 +113,7 @@
"standalone_power_collapse",
};
+static struct hrtimer pm_hrtimer;
static struct msm_pm_sleep_ops pm_sleep_ops;
/*
* Write out the attribute.
@@ -645,6 +647,28 @@
return time;
}
+/**
+ * pm_hrtimer_cb() : Callback function for hrtimer created if the
+ * core needs to be awake to handle an event.
+ * @hrtimer : Pointer to hrtimer
+ */
+static enum hrtimer_restart pm_hrtimer_cb(struct hrtimer *hrtimer)
+{
+ return HRTIMER_NORESTART;
+}
+
+/**
+ * msm_pm_set_timer() : Set an hrtimer to wakeup the core in time
+ * to handle an event.
+ */
+static void msm_pm_set_timer(uint32_t modified_time_us)
+{
+ u64 modified_time_ns = modified_time_us * NSEC_PER_USEC;
+ ktime_t modified_ktime = ns_to_ktime(modified_time_ns);
+ pm_hrtimer.function = pm_hrtimer_cb;
+ hrtimer_start(&pm_hrtimer, modified_ktime, HRTIMER_MODE_ABS);
+}
+
/******************************************************************************
* External Idle/Suspend Functions
*****************************************************************************/
@@ -657,15 +681,25 @@
int msm_pm_idle_prepare(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index)
{
- uint32_t latency_us;
- uint32_t sleep_us;
int i;
unsigned int power_usage = -1;
int ret = 0;
+ uint32_t modified_time_us = 0;
+ struct msm_pm_time_params time_param;
- latency_us = (uint32_t) pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
- sleep_us = (uint32_t) ktime_to_ns(tick_nohz_get_sleep_length());
- sleep_us = DIV_ROUND_UP(sleep_us, 1000);
+ time_param.latency_us =
+ (uint32_t) pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
+ time_param.sleep_us =
+ (uint32_t) (ktime_to_us(tick_nohz_get_sleep_length())
+ & UINT_MAX);
+ time_param.modified_time_us = 0;
+
+ if (!dev->cpu)
+ time_param.next_event_us =
+ (uint32_t) (ktime_to_us(get_next_event_time())
+ & UINT_MAX);
+ else
+ time_param.next_event_us = 0;
for (i = 0; i < dev->state_count; i++) {
struct cpuidle_state *state = &drv->states[i];
@@ -702,17 +736,18 @@
case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
if (!allow)
break;
+ /* fall through */
if (pm_sleep_ops.lowest_limits)
rs_limits = pm_sleep_ops.lowest_limits(true,
- mode, latency_us, sleep_us,
- &power);
+ mode, &time_param, &power);
if (MSM_PM_DEBUG_IDLE & msm_pm_debug_mask)
pr_info("CPU%u: %s: %s, latency %uus, "
"sleep %uus, limit %p\n",
dev->cpu, __func__, state->desc,
- latency_us, sleep_us, rs_limits);
+ time_param.latency_us,
+ time_param.sleep_us, rs_limits);
if (!rs_limits)
allow = false;
@@ -730,6 +765,7 @@
if (allow) {
if (power < power_usage) {
power_usage = power;
+ modified_time_us = time_param.modified_time_us;
ret = mode;
}
@@ -738,6 +774,8 @@
}
}
+ if (modified_time_us && !dev->cpu)
+ msm_pm_set_timer(modified_time_us);
return ret;
}
@@ -850,6 +888,11 @@
int i;
int64_t period = 0;
int64_t time = msm_pm_timer_enter_suspend(&period);
+ struct msm_pm_time_params time_param;
+
+ time_param.latency_us = -1;
+ time_param.sleep_us = -1;
+ time_param.next_event_us = 0;
if (MSM_PM_DEBUG_SUSPEND & msm_pm_debug_mask)
pr_info("%s\n", __func__);
@@ -887,8 +930,7 @@
#endif /* CONFIG_MSM_SLEEP_TIME_OVERRIDE */
if (pm_sleep_ops.lowest_limits)
rs_limits = pm_sleep_ops.lowest_limits(false,
- MSM_PM_SLEEP_MODE_POWER_COLLAPSE, -1,
- -1, &power);
+ MSM_PM_SLEEP_MODE_POWER_COLLAPSE, &time_param, &power);
if (rs_limits) {
if (pm_sleep_ops.enter_sleep)
@@ -1046,6 +1088,7 @@
suspend_set_ops(&msm_pm_ops);
msm_pm_qtimer_available();
+ hrtimer_init(&pm_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
msm_cpuidle_init();
platform_driver_register(&msm_pc_counter_driver);
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index e2553e2..51256ca 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -57,6 +57,13 @@
#define MSM_PM_MODE(cpu, mode_nr) ((cpu) * MSM_PM_SLEEP_MODE_NR + (mode_nr))
+struct msm_pm_time_params {
+ uint32_t latency_us;
+ uint32_t sleep_us;
+ uint32_t next_event_us;
+ uint32_t modified_time_us;
+};
+
struct msm_pm_platform_data {
u8 idle_supported; /* Allow device to enter mode during idle */
u8 suspend_supported; /* Allow device to enter mode during suspend */
@@ -72,8 +79,8 @@
struct msm_pm_sleep_ops {
void *(*lowest_limits)(bool from_idle,
- enum msm_pm_sleep_mode sleep_mode, uint32_t latency_us,
- uint32_t sleep_us, uint32_t *power);
+ enum msm_pm_sleep_mode sleep_mode,
+ struct msm_pm_time_params *time_param, uint32_t *power);
int (*enter_sleep)(uint32_t sclk_count, void *limits,
bool from_idle, bool notify_rpm);
void (*exit_sleep)(void *limits, bool from_idle,
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 53736ac..5883b0c 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -24,6 +24,7 @@
#include <linux/mfd/pmic8058.h>
#include <linux/mfd/pmic8901.h>
#include <linux/mfd/pm8xxx/misc.h>
+#include <linux/qpnp/power-on.h>
#include <asm/mach-types.h>
#include <asm/cacheflush.h>
@@ -128,6 +129,7 @@
set_dload_mode(0);
#endif
pm8xxx_reset_pwr_off(0);
+ qpnp_pon_system_pwr_off(0);
if (lower_pshold) {
if (!use_restart_v2())
@@ -208,6 +210,7 @@
#endif
pm8xxx_reset_pwr_off(1);
+ qpnp_pon_system_pwr_off(1);
if (cmd != NULL) {
if (!strncmp(cmd, "bootloader", 10)) {
diff --git a/arch/arm/mach-msm/rpm_resources.c b/arch/arm/mach-msm/rpm_resources.c
index 9d794e7..2a835f7 100644
--- a/arch/arm/mach-msm/rpm_resources.c
+++ b/arch/arm/mach-msm/rpm_resources.c
@@ -20,6 +20,7 @@
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <linux/cpu.h>
+#include <linux/hrtimer.h>
#include <mach/rpm.h>
#include <mach/msm_iomap.h>
#include <asm/mach-types.h>
@@ -37,6 +38,7 @@
enum {
MSM_RPMRS_DEBUG_OUTPUT = BIT(0),
MSM_RPMRS_DEBUG_BUFFER = BIT(1),
+ MSM_RPMRS_DEBUG_EVENT_TIMER = BIT(2),
};
static int msm_rpmrs_debug_mask;
@@ -891,8 +893,8 @@
}
static void *msm_rpmrs_lowest_limits(bool from_idle,
- enum msm_pm_sleep_mode sleep_mode, uint32_t latency_us,
- uint32_t sleep_us, uint32_t *power)
+ enum msm_pm_sleep_mode sleep_mode,
+ struct msm_pm_time_params *time_param, uint32_t *power)
{
unsigned int cpu = smp_processor_id();
struct msm_rpmrs_level *best_level = NULL;
@@ -900,6 +902,8 @@
bool gpio_detectable = false;
int i;
uint32_t pwr;
+ uint32_t next_wakeup_us = time_param->sleep_us;
+ bool modify_event_timer;
if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
irqs_detectable = msm_mpm_irqs_detectable(from_idle);
@@ -909,16 +913,32 @@
for (i = 0; i < msm_rpmrs_level_count; i++) {
struct msm_rpmrs_level *level = &msm_rpmrs_levels[i];
+ modify_event_timer = false;
+
if (!level->available)
continue;
if (sleep_mode != level->sleep_mode)
continue;
- if (latency_us < level->latency_us)
+ if (time_param->latency_us < level->latency_us)
continue;
- if (sleep_us <= level->time_overhead_us)
+ if (time_param->next_event_us &&
+ time_param->next_event_us < level->latency_us)
+ continue;
+
+ if (time_param->next_event_us) {
+ if ((time_param->next_event_us < time_param->sleep_us)
+ || ((time_param->next_event_us - level->latency_us) <
+ time_param->sleep_us)) {
+ modify_event_timer = true;
+ next_wakeup_us = time_param->next_event_us -
+ level->latency_us;
+ }
+ }
+
+ if (next_wakeup_us <= level->time_overhead_us)
continue;
if (!msm_rpmrs_irqs_detectable(&level->rs_limits,
@@ -929,18 +949,17 @@
if (!cpu && msm_rpm_local_request_is_outstanding())
break;
-
- if (sleep_us <= 1) {
+ if (next_wakeup_us <= 1) {
pwr = level->energy_overhead;
- } else if (sleep_us <= level->time_overhead_us) {
- pwr = level->energy_overhead / sleep_us;
- } else if ((sleep_us >> 10) > level->time_overhead_us) {
+ } else if (next_wakeup_us <= level->time_overhead_us) {
+ pwr = level->energy_overhead / next_wakeup_us;
+ } else if ((next_wakeup_us >> 10) > level->time_overhead_us) {
pwr = level->steady_state_power;
} else {
pwr = level->steady_state_power;
pwr -= (level->time_overhead_us *
- level->steady_state_power)/sleep_us;
- pwr += level->energy_overhead / sleep_us;
+ level->steady_state_power)/next_wakeup_us;
+ pwr += level->energy_overhead / next_wakeup_us;
}
if (!best_level ||
@@ -950,6 +969,12 @@
best_level = level;
if (power)
*power = pwr;
+ if (modify_event_timer && best_level->latency_us > 1)
+ time_param->modified_time_us =
+ time_param->next_event_us -
+ best_level->latency_us;
+ else
+ time_param->modified_time_us = 0;
}
}
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 5962d71..30acebf 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -65,6 +65,7 @@
wait_queue_head_t ch_opened_wait_queue;
int i;
+ int ref_cnt;
int blocking_write;
int is_open;
@@ -270,6 +271,7 @@
if (!smd_pkt_devp)
return -EINVAL;
+ mutex_lock(&smd_pkt_devp->ch_lock);
switch (cmd) {
case TIOCMGET:
D_STATUS("%s TIOCMGET command on smd_pkt_dev id:%d\n",
@@ -288,6 +290,7 @@
pr_err("%s: Unrecognized ioctl command %d\n", __func__, cmd);
ret = -1;
}
+ mutex_unlock(&smd_pkt_devp->ch_lock);
return ret;
}
@@ -867,9 +870,12 @@
smd_pkt_devp->ch_size =
smd_write_avail(smd_pkt_devp->ch);
r = 0;
+ smd_pkt_devp->ref_cnt++;
D_STATUS("Finished %s on smd_pkt_dev id:%d\n",
__func__, smd_pkt_devp->i);
}
+ } else {
+ smd_pkt_devp->ref_cnt++;
}
release_pil:
if (peripheral && (r < 0))
@@ -902,12 +908,14 @@
D_STATUS("Begin %s on smd_pkt_dev id:%d\n",
__func__, smd_pkt_devp->i);
- clean_and_signal(smd_pkt_devp);
-
mutex_lock(&smd_pkt_devp->ch_lock);
mutex_lock(&smd_pkt_devp->rx_lock);
mutex_lock(&smd_pkt_devp->tx_lock);
- if (smd_pkt_devp->ch != 0) {
+ if (smd_pkt_devp->ref_cnt > 0)
+ smd_pkt_devp->ref_cnt--;
+
+ if (smd_pkt_devp->ch != 0 && smd_pkt_devp->ref_cnt == 0) {
+ clean_and_signal(smd_pkt_devp);
r = smd_close(smd_pkt_devp->ch);
smd_pkt_devp->ch = 0;
smd_pkt_devp->blocking_write = 0;
@@ -916,15 +924,15 @@
smd_pkt_devp->driver.probe = NULL;
if (smd_pkt_devp->pil)
pil_put(smd_pkt_devp->pil);
+ smd_pkt_devp->has_reset = 0;
+ smd_pkt_devp->do_reset_notification = 0;
+ smd_pkt_devp->wakelock_locked = 0;
+ wake_lock_destroy(&smd_pkt_devp->pa_wake_lock);
}
mutex_unlock(&smd_pkt_devp->tx_lock);
mutex_unlock(&smd_pkt_devp->rx_lock);
mutex_unlock(&smd_pkt_devp->ch_lock);
- smd_pkt_devp->has_reset = 0;
- smd_pkt_devp->do_reset_notification = 0;
- smd_pkt_devp->wakelock_locked = 0;
- wake_lock_destroy(&smd_pkt_devp->pa_wake_lock);
D_STATUS("Finished %s on smd_pkt_dev id:%d\n",
__func__, smd_pkt_devp->i);
diff --git a/arch/arm/mach-msm/spm-v2.c b/arch/arm/mach-msm/spm-v2.c
index 26dfdff..1eab9bf 100644
--- a/arch/arm/mach-msm/spm-v2.c
+++ b/arch/arm/mach-msm/spm-v2.c
@@ -310,9 +310,43 @@
return 0;
}
+#ifdef CONFIG_MSM_AVS_HW
+static void msm_spm_drv_disable_avs(struct msm_spm_driver_data *dev)
+{
+ msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_AVS_CTL);
+ dev->reg_shadow[MSM_SPM_REG_SAW2_AVS_CTL] &= ~BIT(27);
+ msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_AVS_CTL);
+}
+
+static void msm_spm_drv_enable_avs(struct msm_spm_driver_data *dev)
+{
+ dev->reg_shadow[MSM_SPM_REG_SAW2_AVS_CTL] |= BIT(27);
+ msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_AVS_CTL);
+}
+
+static void msm_spm_drv_set_avs_vlevel(struct msm_spm_driver_data *dev,
+ unsigned int vlevel)
+{
+ vlevel &= 0x3f;
+ dev->reg_shadow[MSM_SPM_REG_SAW2_AVS_CTL] &= ~0x7efc00;
+ dev->reg_shadow[MSM_SPM_REG_SAW2_AVS_CTL] |= ((vlevel - 4) << 10);
+ dev->reg_shadow[MSM_SPM_REG_SAW2_AVS_CTL] |= (vlevel << 17);
+ msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_AVS_CTL);
+}
+
+#else
+
+static void msm_spm_drv_disable_avs(struct msm_spm_driver_data *dev) { }
+
+static void msm_spm_drv_enable_avs(struct msm_spm_driver_data *dev) { }
+
+static void msm_spm_drv_set_avs_vlevel(struct msm_spm_driver_data *dev,
+ unsigned int vlevel) { }
+#endif
+
int msm_spm_drv_set_vdd(struct msm_spm_driver_data *dev, unsigned int vlevel)
{
- uint32_t timeout_us;
+ uint32_t timeout_us, new_level;
if (!dev)
return -EINVAL;
@@ -321,42 +355,46 @@
return -ENOSYS;
if (msm_spm_debug_mask & MSM_SPM_DEBUG_VCTL)
- pr_info("%s: requesting vlevel 0x%x\n",
- __func__, vlevel);
+ pr_info("%s: requesting vlevel %#x\n", __func__, vlevel);
+
+ msm_spm_drv_disable_avs(dev);
+
+ /* Kick the state machine back to idle */
+ dev->reg_shadow[MSM_SPM_REG_SAW2_RST] = 1;
+ msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_RST);
msm_spm_drv_apcs_set_vctl(dev, vlevel);
msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_VCTL);
msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_PMIC_DATA_0);
msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_PMIC_DATA_1);
- mb();
- /* Wait for PMIC state to return to idle or until timeout */
timeout_us = dev->vctl_timeout_us;
- while (msm_spm_drv_get_sts_pmic_state(dev) != MSM_SPM_PMIC_STATE_IDLE) {
- if (!timeout_us)
- goto set_vdd_bail;
-
- if (timeout_us > 10) {
- udelay(10);
- timeout_us -= 10;
- } else {
- udelay(timeout_us);
- timeout_us = 0;
- }
+ /* Confirm the voltage we set was what hardware sent */
+ do {
+ new_level = msm_spm_drv_get_sts_curr_pmic_data(dev);
+ if (new_level == vlevel)
+ break;
+ udelay(1);
+ } while (--timeout_us);
+ if (!timeout_us) {
+ pr_info("Wrong level %#x\n", new_level);
+ goto set_vdd_bail;
}
- if (msm_spm_drv_get_sts_curr_pmic_data(dev) != vlevel)
- goto set_vdd_bail;
+ /* Set AVS min/max */
+ msm_spm_drv_set_avs_vlevel(dev, vlevel);
if (msm_spm_debug_mask & MSM_SPM_DEBUG_VCTL)
pr_info("%s: done, remaining timeout %uus\n",
__func__, timeout_us);
+ msm_spm_drv_enable_avs(dev);
return 0;
set_vdd_bail:
- pr_err("%s: failed, remaining timeout %uus, vlevel 0x%x\n",
- __func__, timeout_us, msm_spm_drv_get_sts_curr_pmic_data(dev));
+ msm_spm_drv_enable_avs(dev);
+ pr_err("%s: failed %#x, remaining timeout %uus, vlevel %#x\n",
+ __func__, vlevel, timeout_us, new_level);
return -EIO;
}
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 05d11d2..b87b0f1 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -38,16 +38,38 @@
uint32_t num_modes;
};
+struct msm_spm_vdd_info {
+ uint32_t cpu;
+ uint32_t vlevel;
+ int err;
+};
+
static struct msm_spm_device msm_spm_l2_device;
static DEFINE_PER_CPU_SHARED_ALIGNED(struct msm_spm_device, msm_cpu_spm_device);
-int msm_spm_set_vdd(unsigned int cpu, unsigned int vlevel)
+
+/* Must be called on the same cpu as the one being set to */
+static void msm_spm_smp_set_vdd(void *data)
{
struct msm_spm_device *dev;
- int ret = -EIO;
+ struct msm_spm_vdd_info *info = (struct msm_spm_vdd_info *)data;
- dev = &per_cpu(msm_cpu_spm_device, cpu);
- ret = msm_spm_drv_set_vdd(&dev->reg_data, vlevel);
+ dev = &per_cpu(msm_cpu_spm_device, info->cpu);
+ info->err = msm_spm_drv_set_vdd(&dev->reg_data, info->vlevel);
+}
+
+int msm_spm_set_vdd(unsigned int cpu, unsigned int vlevel)
+{
+ struct msm_spm_vdd_info info;
+ int ret;
+
+ info.cpu = cpu;
+ info.vlevel = vlevel;
+
+ /* Set to true to block on vdd change */
+ ret = smp_call_function_single(cpu, msm_spm_smp_set_vdd, &info, true);
+ if (!ret)
+ ret = info.err;
return ret;
}
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 1c14859..b18d709 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -279,12 +279,14 @@
struct diag_request *write_ptr_mdm;
/* HSIC variables */
int hsic_ch;
+ int hsic_inited;
int hsic_device_enabled;
int hsic_device_opened;
int hsic_suspend;
int in_busy_hsic_read_on_device;
int in_busy_hsic_write;
struct work_struct diag_read_hsic_work;
+ struct mutex bridge_mutex;
/* USB MDM channel variables */
int usb_mdm_connected;
int read_len_mdm;
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 52fd673..e417d5a 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -558,6 +558,7 @@
ret = scnprintf(buf, DEBUG_BUF_SIZE,
"hsic ch: %d\n"
+ "hsic_inited: %d\n"
"hsic enabled: %d\n"
"hsic_opened: %d\n"
"hsic_suspend: %d\n"
@@ -575,6 +576,7 @@
"diag_disconnect_work: %d\n"
"diag_usb_read_complete_work: %d\n",
driver->hsic_ch,
+ driver->hsic_inited,
driver->hsic_device_enabled,
driver->hsic_device_opened,
driver->hsic_suspend,
diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c
index 3878a82..56f2fae 100644
--- a/drivers/char/diag/diagfwd_hsic.c
+++ b/drivers/char/diag/diagfwd_hsic.c
@@ -236,20 +236,20 @@
.resume = diag_hsic_resume,
};
-static int diag_hsic_close(void)
+static void diag_hsic_close(void)
{
if (driver->hsic_device_enabled) {
driver->hsic_ch = 0;
if (driver->hsic_device_opened) {
driver->hsic_device_opened = 0;
diag_bridge_close();
+ pr_debug("diag: %s: closed successfully\n", __func__);
+ } else {
+ pr_debug("diag: %s: already closed\n", __func__);
}
- pr_debug("diag: in %s: closed successfully\n", __func__);
} else {
- pr_debug("diag: in %s: already closed\n", __func__);
+ pr_debug("diag: %s: HSIC device already removed\n", __func__);
}
-
- return 0;
}
/* diagfwd_cancel_hsic is called to cancel outstanding read/writes */
@@ -257,6 +257,7 @@
{
int err;
+ mutex_lock(&driver->bridge_mutex);
if (driver->hsic_device_enabled) {
if (driver->hsic_device_opened) {
driver->hsic_ch = 0;
@@ -274,6 +275,7 @@
}
}
+ mutex_unlock(&driver->bridge_mutex);
return 0;
}
@@ -284,6 +286,7 @@
pr_debug("diag: in %s\n", __func__);
+ mutex_lock(&driver->bridge_mutex);
/* If the usb cable is being connected */
if (process_cable) {
err = usb_diag_alloc_req(driver->mdm_ch, N_MDM_WRITE,
@@ -301,6 +304,7 @@
} else if (driver->diag_smux_enabled) {
driver->in_busy_smux = 0;
diagfwd_connect_smux();
+ mutex_unlock(&driver->bridge_mutex);
return 0;
}
@@ -323,22 +327,24 @@
* Turn on communication over usb mdm and hsic, if the hsic
* device driver is enabled and opened
*/
- if (driver->hsic_device_opened)
+ if (driver->hsic_device_opened) {
driver->hsic_ch = 1;
- /* Poll USB mdm channel to check for data */
- if (driver->logging_mode == USB_MODE)
- queue_work(driver->diag_bridge_wq,
- &driver->diag_read_mdm_work);
+ /* Poll USB mdm channel to check for data */
+ if (driver->logging_mode == USB_MODE)
+ queue_work(driver->diag_bridge_wq,
+ &driver->diag_read_mdm_work);
- /* Poll HSIC channel to check for data */
- queue_work(driver->diag_bridge_wq,
- &driver->diag_read_hsic_work);
+ /* Poll HSIC channel to check for data */
+ queue_work(driver->diag_bridge_wq,
+ &driver->diag_read_hsic_work);
+ }
} else {
/* The hsic device driver has not yet been enabled */
pr_info("diag: HSIC channel not yet enabled\n");
}
+ mutex_unlock(&driver->bridge_mutex);
return 0;
}
@@ -350,6 +356,8 @@
{
pr_debug("diag: In %s, process_cable: %d\n", __func__, process_cable);
+ mutex_lock(&driver->bridge_mutex);
+
/* If the usb cable is being disconnected */
if (process_cable) {
driver->usb_mdm_connected = 0;
@@ -361,7 +369,7 @@
driver->in_busy_hsic_read_on_device = 1;
driver->in_busy_hsic_write = 1;
/* Turn off communication over usb mdm and hsic */
- return diag_hsic_close();
+ diag_hsic_close();
} else if (driver->diag_smux_enabled &&
driver->logging_mode == USB_MODE) {
driver->in_busy_smux = 1;
@@ -370,6 +378,8 @@
/* Turn off communication over usb mdm and smux */
msm_smux_close(LCID_VALID);
}
+
+ mutex_unlock(&driver->bridge_mutex);
return 0;
}
@@ -551,13 +561,15 @@
{
int err = 0;
pr_debug("diag: in %s\n", __func__);
- if (!driver->hsic_device_enabled) {
+ if (!driver->hsic_inited) {
diagmem_hsic_init(driver);
INIT_WORK(&(driver->diag_read_hsic_work),
diag_read_hsic_work_fn);
- driver->hsic_device_enabled = 1;
+ driver->hsic_inited = 1;
}
+ mutex_lock(&driver->bridge_mutex);
+
/*
* The probe function was called after the usb was connected
* on the legacy channel OR ODL is turned on. Communication over usb
@@ -565,11 +577,17 @@
*/
if (driver->usb_mdm_connected || (driver->logging_mode ==
MEMORY_DEVICE_MODE)) {
- /* The hsic (diag_bridge) platform device driver is enabled */
+ if (driver->hsic_device_opened) {
+ /* should not happen. close it before re-opening */
+ pr_warn("diag: HSIC channel already opened in probe\n");
+ diag_bridge_close();
+ }
+
err = diag_bridge_open(&hsic_diag_bridge_ops);
if (err) {
pr_err("diag: could not open HSIC, err: %d\n", err);
driver->hsic_device_opened = 0;
+ mutex_unlock(&driver->bridge_mutex);
return err;
}
@@ -591,13 +609,19 @@
&driver->diag_read_hsic_work);
}
+ /* The hsic (diag_bridge) platform device driver is enabled */
+ driver->hsic_device_enabled = 1;
+ mutex_unlock(&driver->bridge_mutex);
return err;
}
static int diag_hsic_remove(struct platform_device *pdev)
{
pr_debug("diag: %s called\n", __func__);
+ mutex_lock(&driver->bridge_mutex);
diag_hsic_close();
+ driver->hsic_device_enabled = 0;
+ mutex_unlock(&driver->bridge_mutex);
return 0;
}
@@ -670,6 +694,7 @@
driver->itemsize_hsic_write = sizeof(struct diag_request);
driver->poolsize_hsic_write = N_MDM_WRITE;
+ mutex_init(&driver->bridge_mutex);
#ifdef CONFIG_DIAG_OVER_USB
INIT_WORK(&(driver->diag_read_mdm_work), diag_read_mdm_work_fn);
#endif
@@ -713,8 +738,9 @@
if (driver->hsic_device_enabled) {
diag_hsic_close();
driver->hsic_device_enabled = 0;
- diagmem_exit(driver, POOL_TYPE_ALL);
}
+ driver->hsic_inited = 0;
+ diagmem_exit(driver, POOL_TYPE_ALL);
if (driver->diag_smux_enabled) {
driver->lcid = LCID_INVALID;
kfree(driver->buf_in_smux);
diff --git a/drivers/char/diag/diagmem.c b/drivers/char/diag/diagmem.c
index 82c47af..1a522d5 100644
--- a/drivers/char/diag/diagmem.c
+++ b/drivers/char/diag/diagmem.c
@@ -106,7 +106,7 @@
printk(KERN_ALERT "Unable to destroy STRUCT mempool");
}
#ifdef CONFIG_DIAG_BRIDGE_CODE
- if (driver->diag_hsic_pool && (driver->hsic_device_enabled == 0)) {
+ if (driver->diag_hsic_pool && (driver->hsic_inited == 0)) {
if (driver->count_hsic_pool == 0) {
mempool_destroy(driver->diag_hdlc_pool);
driver->diag_hdlc_pool = NULL;
@@ -114,8 +114,7 @@
pr_err("Unable to destroy HDLC mempool");
}
- if (driver->diag_hsic_write_pool &&
- (driver->hsic_device_enabled == 0)) {
+ if (driver->diag_hsic_write_pool && (driver->hsic_inited == 0)) {
/*
* Free up struct pool ONLY if there are no outstanding
* transactions(aggregation buffer) with USB
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 03fdc5a..c799c1f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -556,7 +556,6 @@
PMICs through RPC.
config GPIO_QPNP_PIN
- depends on ARCH_MSM8974
depends on SPMI
depends on OF_SPMI
depends on MSM_QPNP_INT
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 98254b5..7f760ed 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -1391,8 +1391,10 @@
sizeof(struct ion_fd_data)))
return -EFAULT;
data.handle = ion_import_dma_buf(client, data.fd);
- if (IS_ERR(data.handle))
+ if (IS_ERR(data.handle)) {
+ ret = PTR_ERR(data.handle);
data.handle = NULL;
+ }
if (copy_to_user((void __user *)arg, &data,
sizeof(struct ion_fd_data)))
return -EFAULT;
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 1f32e54..2388fff 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1574,8 +1574,6 @@
return;
}
- KGSL_CTXT_INFO(device, "context flags %08x\n", context->flags);
-
cmds[0] = cp_nop_packet(1);
cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER;
cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2);
@@ -1710,18 +1708,24 @@
if (status & CP_INT_CNTL__RB_INT_MASK) {
/* signal intr completion event */
- unsigned int context_id;
- kgsl_sharedmem_readl(&device->memstore,
- &context_id,
+ unsigned int context_id, timestamp;
+ kgsl_sharedmem_readl(&device->memstore, &context_id,
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
current_context));
+
+ kgsl_sharedmem_readl(&device->memstore, ×tamp,
+ KGSL_MEMSTORE_OFFSET(context_id,
+ eoptimestamp));
+
if (context_id < KGSL_MEMSTORE_MAX) {
kgsl_sharedmem_writel(&rb->device->memstore,
KGSL_MEMSTORE_OFFSET(context_id,
ts_cmp_enable), 0);
wmb();
}
- KGSL_CMD_WARN(rb->device, "ringbuffer rb interrupt\n");
+
+ KGSL_CMD_WARN(device, "<%d:0x%x> ringbuffer interrupt\n",
+ context_id, timestamp);
}
for (i = 0; i < ARRAY_SIZE(kgsl_cp_error_irqs); i++) {
@@ -1743,7 +1747,6 @@
adreno_regwrite(device, REG_CP_INT_ACK, status);
if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) {
- KGSL_CMD_WARN(rb->device, "ringbuffer ib1/rb interrupt\n");
queue_work(device->work_queue, &device->ts_expired_ws);
wake_up_interruptible_all(&device->wait_queue);
atomic_notifier_call_chain(&(device->ts_notifier_list),
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index d89e882..b8fca38 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2409,8 +2409,6 @@
return;
}
- KGSL_CTXT_INFO(device, "context flags %08x\n", context->flags);
-
cmds[0] = cp_nop_packet(1);
cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER;
cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2);
@@ -2565,17 +2563,24 @@
struct kgsl_device *device = &adreno_dev->dev;
if (irq == A3XX_INT_CP_RB_INT) {
- unsigned int context_id;
+ unsigned int context_id, timestamp;
kgsl_sharedmem_readl(&device->memstore, &context_id,
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
current_context));
+
+ kgsl_sharedmem_readl(&device->memstore, ×tamp,
+ KGSL_MEMSTORE_OFFSET(context_id,
+ eoptimestamp));
+
if (context_id < KGSL_MEMSTORE_MAX) {
kgsl_sharedmem_writel(&device->memstore,
KGSL_MEMSTORE_OFFSET(context_id,
ts_cmp_enable), 0);
wmb();
}
- KGSL_CMD_WARN(device, "ringbuffer rb interrupt\n");
+
+ KGSL_CMD_WARN(device, "<%d:0x%x> ringbuffer interrupt\n",
+ context_id, timestamp);
}
wake_up_interruptible_all(&device->wait_queue);
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index b51342f..70ad81c 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -288,8 +288,10 @@
return;
}
- KGSL_CTXT_INFO(device, "from %p to %p flags %d\n",
- adreno_dev->drawctxt_active, drawctxt, flags);
+ KGSL_CTXT_INFO(device, "from %d to %d flags %d\n",
+ adreno_dev->drawctxt_active ?
+ adreno_dev->drawctxt_active->id : 0,
+ drawctxt ? drawctxt->id : 0, flags);
/* Save the old context */
adreno_dev->gpudev->ctxt_save(adreno_dev, adreno_dev->drawctxt_active);
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 620b82c..daa78ed 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -50,6 +50,7 @@
{CP_DRAW_INDX, "DRW_NDX_"},
{CP_DRAW_INDX_BIN, "DRW_NDXB"},
{CP_EVENT_WRITE, "EVENT_WT"},
+ {CP_MEM_WRITE, "MEM_WRIT"},
{CP_IM_LOAD, "IN__LOAD"},
{CP_IM_LOAD_IMMEDIATE, "IM_LOADI"},
{CP_IM_STORE, "IM_STORE"},
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index db913a5..1ff219b 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -969,8 +969,8 @@
drawctxt, 0,
&link[0], (cmds - link));
- KGSL_CMD_INFO(device, "ctxt %d g %08x numibs %d ts %d\n",
- context->id, (unsigned int)ibdesc, numibs, *timestamp);
+ KGSL_CMD_INFO(device, "<%d:0x%x> g %08x numibs %d\n",
+ context->id, *timestamp, (unsigned int)ibdesc, numibs);
kfree(link);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index f630f2a..21227a0 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1107,9 +1107,6 @@
}
if (param->flags & KGSL_CONTEXT_SUBMIT_IB_LIST) {
- KGSL_DRV_INFO(dev_priv->device,
- "Using IB list mode for ib submission, numibs: %d\n",
- param->numibs);
if (!param->numibs) {
KGSL_DRV_ERR(dev_priv->device,
"Invalid numibs as parameter: %d\n",
diff --git a/drivers/hwmon/epm_adc.c b/drivers/hwmon/epm_adc.c
index 3969319..56b8841 100644
--- a/drivers/hwmon/epm_adc.c
+++ b/drivers/hwmon/epm_adc.c
@@ -102,8 +102,6 @@
#define EPM_PSOC_BUFFERED_DATA_LENGTH 48
#define EPM_PSOC_BUFFERED_DATA_LENGTH2 54
-#define EPM_SPI_NOR_CS_N_GPIO 53
-
struct epm_adc_drv {
struct platform_device *pdev;
struct device *hwmon;
@@ -172,14 +170,6 @@
{
int rc = 0;
- rc = gpio_request(EPM_SPI_NOR_CS_N_GPIO, "SPI_NOR_CS_N");
- if (!rc)
- gpio_direction_output(EPM_SPI_NOR_CS_N_GPIO, 1);
- else {
- pr_err("Configure spi nor Failed\n");
- return -EINVAL;
- }
-
if (epm_adc_first_request) {
rc = gpio_request(GPIO_EPM_GLOBAL_ENABLE, "EPM_GLOBAL_EN");
if (!rc) {
@@ -521,27 +511,27 @@
struct epm_adc_platform_data *pdata = epm_adc->pdev->dev.platform_data;
uint32_t chan_idx = (conv->device_idx * pdata->chan_per_adc) +
conv->channel_idx;
- int64_t *adc_scaled_data = 0;
+ int64_t adc_scaled_data = 0;
/* Get the channel number */
channel_num = (adc_raw_data[0] & EPM_ADC_ADS_CHANNEL_DATA_CHID);
sign_bit = 1;
/* This is the 16-bit raw data */
- *adc_scaled_data = ((adc_raw_data[1] << 8) | adc_raw_data[2]);
+ adc_scaled_data = ((adc_raw_data[1] << 8) | adc_raw_data[2]);
/* Obtain the internal system reading */
if (channel_num == EPM_ADC_ADS_CHANNEL_VCC) {
- *adc_scaled_data *= EPM_ADC_SCALE_MILLI;
- do_div(*adc_scaled_data, EPM_ADC_SCALE_CODE_VOLTS);
+ adc_scaled_data *= EPM_ADC_SCALE_MILLI;
+ do_div(adc_scaled_data, EPM_ADC_SCALE_CODE_VOLTS);
} else if (channel_num == EPM_ADC_ADS_CHANNEL_GAIN) {
- do_div(*adc_scaled_data, EPM_ADC_SCALE_CODE_GAIN);
+ do_div(adc_scaled_data, EPM_ADC_SCALE_CODE_GAIN);
} else if (channel_num == EPM_ADC_ADS_CHANNEL_REF) {
- *adc_scaled_data *= EPM_ADC_SCALE_MILLI;
- do_div(*adc_scaled_data, EPM_ADC_SCALE_CODE_VOLTS);
+ adc_scaled_data *= EPM_ADC_SCALE_MILLI;
+ do_div(adc_scaled_data, EPM_ADC_SCALE_CODE_VOLTS);
} else if (channel_num == EPM_ADC_ADS_CHANNEL_TEMP) {
/* Convert Code to micro-volts */
/* Use this formula to get the temperature reading */
- *adc_scaled_data -= EPM_ADC_TEMP_TO_DEGC_COEFF;
- do_div(*adc_scaled_data, EPM_ADC_TEMP_SENSOR_COEFF);
+ adc_scaled_data -= EPM_ADC_TEMP_TO_DEGC_COEFF;
+ do_div(adc_scaled_data, EPM_ADC_TEMP_SENSOR_COEFF);
} else if (channel_num == EPM_ADC_ADS_CHANNEL_OFFSET) {
/* The offset should be zero */
pr_debug("%s: ADC Channel Offset\n", __func__);
@@ -553,31 +543,31 @@
* mvVRef is in milli-volts and resistorvalue is in micro-ohms.
* Hence, I = V/R gives us current in kilo-amps.
*/
- if (*adc_scaled_data & EPM_ADC_MAX_NEGATIVE_SCALE_CODE) {
+ if (adc_scaled_data & EPM_ADC_MAX_NEGATIVE_SCALE_CODE) {
sign_bit = -1;
- *adc_scaled_data = (~*adc_scaled_data
+ adc_scaled_data = (~adc_scaled_data
& EPM_ADC_NEG_LSB_CODE);
}
- if (*adc_scaled_data != 0) {
- *adc_scaled_data *= EPM_ADC_SCALE_FACTOR;
+ if (adc_scaled_data != 0) {
+ adc_scaled_data *= EPM_ADC_SCALE_FACTOR;
/* Device is calibrated for 1LSB = VREF/7800h.*/
- *adc_scaled_data *= EPM_ADC_MILLI_VOLTS_SOURCE;
- do_div(*adc_scaled_data, EPM_ADC_VREF_CODE);
+ adc_scaled_data *= EPM_ADC_MILLI_VOLTS_SOURCE;
+ do_div(adc_scaled_data, EPM_ADC_VREF_CODE);
/* Data will now be in micro-volts.*/
- *adc_scaled_data *= EPM_ADC_SCALE_MILLI;
+ adc_scaled_data *= EPM_ADC_SCALE_MILLI;
/* Divide by amplifier gain value.*/
- do_div(*adc_scaled_data, pdata->channel[chan_idx].gain);
+ do_div(adc_scaled_data, pdata->channel[chan_idx].gain);
/* Data will now be in nano-volts.*/
- do_div(*adc_scaled_data, EPM_ADC_SCALE_FACTOR);
- *adc_scaled_data *= EPM_ADC_SCALE_MILLI;
+ do_div(adc_scaled_data, EPM_ADC_SCALE_FACTOR);
+ adc_scaled_data *= EPM_ADC_SCALE_MILLI;
/* Data is now in micro-amps.*/
- do_div(*adc_scaled_data,
+ do_div(adc_scaled_data,
pdata->channel[chan_idx].resistorvalue);
/* Set the sign bit for lekage current. */
- *adc_scaled_data *= sign_bit;
+ adc_scaled_data *= sign_bit;
}
}
- conv->physical = (int32_t) *adc_scaled_data;
+ conv->physical = (int32_t) adc_scaled_data;
return 0;
}
@@ -1600,16 +1590,15 @@
struct device_node *node = spi->dev.of_node;
int rc = 0;
- if (!node) {
- dev_err(&spi->dev, "no platform data?\n");
- pr_info("Error in the probe\n");
- return -EINVAL;
- }
-
if (node)
rc = get_device_tree_data(spi);
- else
- return -ENODEV;
+ else {
+ epm_adc = epm_adc_drv;
+ epm_adc_drv->epm_spi_client = spi;
+ epm_adc_drv->epm_spi_client->bits_per_word =
+ EPM_ADC_ADS_SPI_BITS_PER_WORD;
+ return rc;
+ }
epm_adc = epm_adc_drv;
epm_adc->misc.name = EPM_ADC_DRIVER_NAME;
diff --git a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c b/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
index 9549dcc..d508c1d 100644
--- a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
+++ b/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
@@ -139,11 +139,11 @@
switch (perf_setting) {
case S_INIT:
add_axi_qos();
- break;
- case S_PREVIEW:
update_axi_qos(MSM_AXI_QOS_PREVIEW);
axi_allocate(AXI_FLOW_VIEWFINDER_HI);
break;
+ case S_PREVIEW:
+ break;
case S_VIDEO:
update_axi_qos(MSM_AXI_QOS_RECORDING);
break;
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 2613986..1e17c5c 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -555,6 +555,7 @@
case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC:
case CMD_AXI_START:
case CMD_AXI_STOP:
+ case CMD_AXI_RESET:
case CMD_AXI_CFG_TERT1:
case CMD_AXI_CFG_TERT2:
/* Dont need to pass buffer information.
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index eb6a8b0..f6cf427 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -23,6 +23,8 @@
static struct msm_camera_i2c_reg_conf ov5647_start_settings[] = {
{0x4202, 0x00}, /* streaming on */
+ {0x0100, 0x01},
+ {0x4800, 0x04},
};
static struct msm_camera_i2c_reg_conf ov5647_stop_settings[] = {
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index bb9a9b7..b78e20d 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -1643,6 +1643,10 @@
rp = (struct msm_vfe_resp *)arg;
frame_info = rp->evt_msg.data;
+ if (!frame_info) {
+ interface = PIX_0;
+ break;
+ }
if (frame_info->inst_handle) {
vnode_id = GET_DEVID_MODE(frame_info->inst_handle);
if (vnode_id < MAX_NUM_ACTIVE_CAMERA &&
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
index 15c38af..9deae65 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
@@ -1561,6 +1561,11 @@
}
return 0;
+ case CMD_AXI_START:
+ case CMD_AXI_STOP:
+ case CMD_AXI_RESET:
+ return 0;
+
case CMD_CONFIG_FREE_BUF_ADDR: {
int path = *((int *)cmd->value);
struct buf_info *outch = vfe2x_get_ch(path);
@@ -1853,9 +1858,6 @@
flags);
if (op_mode & SNAPSHOT_MASK_MODE) {
vfe2x_ctrl->stop_pending = 0;
- vfe2x_send_isp_msg(vfe2x_ctrl,
- msgs_map[MSG_STOP_ACK].
- isp_id);
spin_unlock_irqrestore(
&vfe2x_ctrl->table_lock,
flags);
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
index 170322c..a4c4b83 100644
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -31,7 +31,6 @@
#include "msm_smem.h"
#define BASE_DEVICE_NUMBER 32
-#define MAX_EVENTS 30
#define SHARED_QSIZE 0x1000000
static struct msm_bus_vectors enc_ocmem_init_vectors[] = {
@@ -451,7 +450,7 @@
};
struct msm_v4l2_vid_inst {
- struct msm_vidc_inst vidc_inst;
+ struct msm_vidc_inst *vidc_inst;
void *mem_client;
struct list_head registered_bufs;
};
@@ -468,22 +467,7 @@
struct msm_vidc_inst *vidc_inst;
vidc_inst = container_of(filp->private_data,
struct msm_vidc_inst, event_handler);
- return container_of((void *)vidc_inst,
- struct msm_v4l2_vid_inst, vidc_inst);
-}
-
-static int msm_vidc_v4l2_setup_event_queue(void *inst,
- struct video_device *pvdev)
-{
- int rc = 0;
- struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
- spin_lock_init(&pvdev->fh_lock);
- INIT_LIST_HEAD(&pvdev->fh_list);
-
- v4l2_fh_init(&vidc_inst->event_handler, pvdev);
- v4l2_fh_add(&vidc_inst->event_handler);
-
- return rc;
+ return (struct msm_v4l2_vid_inst *)vidc_inst->priv;
}
struct buffer_info *get_registered_buf(struct list_head *list,
@@ -556,7 +540,8 @@
rc = -ENOMEM;
goto fail_mem_client;
}
- rc = msm_vidc_open(&v4l2_inst->vidc_inst, core->id, vid_dev->type);
+
+ v4l2_inst->vidc_inst = msm_vidc_open(core->id, vid_dev->type);
if (rc) {
dprintk(VIDC_ERR,
"Failed to create video instance, core: %d, type = %d\n",
@@ -565,9 +550,9 @@
goto fail_open;
}
INIT_LIST_HEAD(&v4l2_inst->registered_bufs);
- rc = msm_vidc_v4l2_setup_event_queue(&v4l2_inst->vidc_inst, vdev);
+ v4l2_inst->vidc_inst->priv = v4l2_inst;
clear_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags);
- filp->private_data = &(v4l2_inst->vidc_inst.event_handler);
+ filp->private_data = &(v4l2_inst->vidc_inst->event_handler);
return rc;
fail_open:
msm_smem_delete_client(v4l2_inst->mem_client);
@@ -667,7 +652,7 @@
buffer_info.m.planes[0].reserved[0],
buffer_info.m.planes[0].reserved[1],
buffer_info.m.planes[0].length);
- rc = msm_vidc_release_buf(&v4l2_inst->vidc_inst,
+ rc = msm_vidc_release_buf(v4l2_inst->vidc_inst,
&buffer_info);
list_del(&bi->list);
if (bi->handle)
@@ -752,7 +737,7 @@
list_add_tail(&binfo->list, &v4l2_inst->registered_bufs);
b->m.planes[i].m.userptr = binfo->device_addr;
}
- rc = msm_vidc_prepare_buf(&v4l2_inst->vidc_inst, b);
+ rc = msm_vidc_prepare_buf(v4l2_inst->vidc_inst, b);
exit:
return rc;
}
@@ -794,7 +779,7 @@
}
}
}
- rc = msm_vidc_qbuf(&v4l2_inst->vidc_inst, b);
+ rc = msm_vidc_qbuf(v4l2_inst->vidc_inst, b);
err_invalid_buff:
return rc;
}
@@ -823,17 +808,17 @@
static int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
- int rc = 0;
- rc = v4l2_event_subscribe(fh, sub, MAX_EVENTS);
- return rc;
+ struct msm_vidc_inst *vidc_inst = container_of(fh,
+ struct msm_vidc_inst, event_handler);
+ return msm_vidc_subscribe_event((void *)vidc_inst, sub);
}
static int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
- int rc = 0;
- rc = v4l2_event_unsubscribe(fh, sub);
- return rc;
+ struct msm_vidc_inst *vidc_inst = container_of(fh,
+ struct msm_vidc_inst, event_handler);
+ return msm_vidc_unsubscribe_event((void *)vidc_inst, sub);
}
static int msm_v4l2_decoder_cmd(struct file *file, void *fh,
@@ -936,7 +921,7 @@
struct msm_iova_layout layout;
int rc = 0;
int i;
- struct iommu_info *io_map = core->resources.io_map;
+ struct msm_vidc_iommu_info *io_map = core->resources.io_map;
strlcpy(io_map[CP_MAP].name, "vidc-cp-map",
sizeof(io_map[CP_MAP].name));
strlcpy(io_map[CP_MAP].ctx, "venus_cp",
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index 8240890..be2e848 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -229,6 +229,14 @@
.type = OUTPUT_PORT,
},
{
+ .name = "VC1 SP",
+ .description = "VC-1 compressed format G",
+ .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
+ .num_planes = 1,
+ .get_frame_size = get_frame_size_compressed,
+ .type = OUTPUT_PORT,
+ },
+ {
.name = "H264",
.description = "H264 compressed format",
.fourcc = V4L2_PIX_FMT_H264,
@@ -524,6 +532,8 @@
goto err_invalid_fmt;
}
} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ inst->prop.width = f->fmt.pix_mp.width;
+ inst->prop.height = f->fmt.pix_mp.height;
fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
ARRAY_SIZE(vdec_formats), f->fmt.pix_mp.pixelformat,
OUTPUT_PORT);
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
index 449dab2..ec9dac8 100644
--- a/drivers/media/video/msm_vidc/msm_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_vidc.c
@@ -11,6 +11,7 @@
*
*/
+#include <linux/sched.h>
#include <linux/slab.h>
#include <media/msm_vidc.h>
#include "msm_vidc_internal.h"
@@ -21,21 +22,21 @@
#include "msm_smem.h"
#include <linux/delay.h>
-int msm_vidc_poll(void *instance, struct file *filp,
- struct poll_table_struct *wait)
+#define MAX_EVENTS 30
+
+static int get_poll_flags(void *instance)
{
- int rc = 0;
struct msm_vidc_inst *inst = instance;
struct vb2_queue *outq = &inst->vb2_bufq[OUTPUT_PORT];
struct vb2_queue *capq = &inst->vb2_bufq[CAPTURE_PORT];
struct vb2_buffer *out_vb = NULL;
struct vb2_buffer *cap_vb = NULL;
unsigned long flags;
- poll_wait(filp, &inst->event_handler.wait, wait);
- poll_wait(filp, &capq->done_wq, wait);
- poll_wait(filp, &outq->done_wq, wait);
+ int rc = 0;
+
if (v4l2_event_pending(&inst->event_handler))
rc |= POLLPRI;
+
spin_lock_irqsave(&capq->done_lock, flags);
if (!list_empty(&capq->done_list))
cap_vb = list_first_entry(&capq->done_list, struct vb2_buffer,
@@ -44,6 +45,7 @@
|| cap_vb->state == VB2_BUF_STATE_ERROR))
rc |= POLLIN | POLLRDNORM;
spin_unlock_irqrestore(&capq->done_lock, flags);
+
spin_lock_irqsave(&outq->done_lock, flags);
if (!list_empty(&outq->done_list))
out_vb = list_first_entry(&outq->done_list, struct vb2_buffer,
@@ -52,12 +54,55 @@
|| out_vb->state == VB2_BUF_STATE_ERROR))
rc |= POLLOUT | POLLWRNORM;
spin_unlock_irqrestore(&outq->done_lock, flags);
+
return rc;
}
+int msm_vidc_poll(void *instance, struct file *filp,
+ struct poll_table_struct *wait)
+{
+ struct msm_vidc_inst *inst = instance;
+ struct vb2_queue *outq = &inst->vb2_bufq[OUTPUT_PORT];
+ struct vb2_queue *capq = &inst->vb2_bufq[CAPTURE_PORT];
+
+ poll_wait(filp, &inst->event_handler.wait, wait);
+ poll_wait(filp, &capq->done_wq, wait);
+ poll_wait(filp, &outq->done_wq, wait);
+ return get_poll_flags(inst);
+}
+
+/* Kernel client alternative for msm_vidc_poll */
+int msm_vidc_wait(void *instance)
+{
+ struct msm_vidc_inst *inst = instance;
+ int rc = 0;
+
+ wait_event(inst->kernel_event_queue, (rc = get_poll_flags(inst)));
+ return rc;
+}
+
+int msm_vidc_get_iommu_maps(void *instance,
+ struct msm_vidc_iommu_info maps[MAX_MAP])
+{
+ struct msm_vidc_inst *inst = instance;
+ int c = 0;
+
+ if (!inst || !maps)
+ return -EINVAL;
+
+ for (c = 0; c < MAX_MAP; ++c)
+ maps[c] = inst->core->resources.io_map[c];
+
+ return 0;
+}
+
int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !cap)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_querycap(instance, cap);
else if (inst->session_type == MSM_VIDC_ENCODER)
@@ -67,6 +112,10 @@
int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !f)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_enum_fmt(instance, f);
else if (inst->session_type == MSM_VIDC_ENCODER)
@@ -76,6 +125,10 @@
int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !f)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_s_fmt(instance, f);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -85,6 +138,10 @@
int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !f)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_g_fmt(instance, f);
else if (inst->session_type == MSM_VIDC_ENCODER)
@@ -94,6 +151,10 @@
int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !control)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_s_ctrl(instance, control);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -103,6 +164,10 @@
int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !control)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_g_ctrl(instance, control);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -112,6 +177,10 @@
int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !b)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_reqbufs(instance, b);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -122,6 +191,10 @@
int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !b)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_prepare_buf(instance, b);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -132,6 +205,10 @@
int msm_vidc_release_buf(void *instance, struct v4l2_buffer *b)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !b)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_release_buf(instance, b);
return -EINVAL;
@@ -156,6 +233,10 @@
int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !b)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_qbuf(instance, b);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -166,6 +247,10 @@
int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst || !b)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_dqbuf(instance, b);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -176,6 +261,10 @@
int msm_vidc_streamon(void *instance, enum v4l2_buf_type i)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_streamon(instance, i);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -186,6 +275,10 @@
int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i)
{
struct msm_vidc_inst *inst = instance;
+
+ if (!inst)
+ return -EINVAL;
+
if (inst->session_type == MSM_VIDC_DECODER)
return msm_vdec_streamoff(instance, i);
if (inst->session_type == MSM_VIDC_ENCODER)
@@ -193,13 +286,13 @@
return -EINVAL;
}
-void *vidc_get_userptr(void *alloc_ctx, unsigned long vaddr,
+static void *vidc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
{
return (void *)0xdeadbeef;
}
-void vidc_put_userptr(void *buf_priv)
+static void vidc_put_userptr(void *buf_priv)
{
}
@@ -232,9 +325,60 @@
return vb2_queue_init(q);
}
-int msm_vidc_open(void *vidc_inst, int core_id, int session_type)
+static int setup_event_queue(void *inst,
+ struct video_device *pvdev)
{
- struct msm_vidc_inst *inst = (struct msm_vidc_inst *)vidc_inst;
+ int rc = 0;
+ struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+ spin_lock_init(&pvdev->fh_lock);
+ INIT_LIST_HEAD(&pvdev->fh_list);
+
+ v4l2_fh_init(&vidc_inst->event_handler, pvdev);
+ v4l2_fh_add(&vidc_inst->event_handler);
+
+ return rc;
+}
+
+int msm_vidc_subscribe_event(void *inst, struct v4l2_event_subscription *sub)
+{
+ int rc = 0;
+ struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+ if (!inst || !sub)
+ return -EINVAL;
+
+ rc = v4l2_event_subscribe(&vidc_inst->event_handler, sub, MAX_EVENTS);
+ return rc;
+}
+
+
+int msm_vidc_unsubscribe_event(void *inst, struct v4l2_event_subscription *sub)
+{
+ int rc = 0;
+ struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+ if (!inst || !sub)
+ return -EINVAL;
+
+ rc = v4l2_event_unsubscribe(&vidc_inst->event_handler, sub);
+ return rc;
+}
+
+int msm_vidc_dqevent(void *inst, struct v4l2_event *event)
+{
+ int rc = 0;
+ struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+ if (!inst || !event)
+ return -EINVAL;
+
+ rc = v4l2_event_dequeue(&vidc_inst->event_handler, event, false);
+ return rc;
+}
+
+void *msm_vidc_open(int core_id, int session_type)
+{
+ struct msm_vidc_inst *inst = NULL;
struct msm_vidc_core *core = NULL;
unsigned long flags;
int rc = 0;
@@ -252,14 +396,23 @@
goto err_invalid_core;
}
+ inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+ if (!inst) {
+ pr_err("Failed to allocate memory\n") ;
+ rc = -ENOMEM;
+ goto err_invalid_core;
+ }
+
mutex_init(&inst->sync_lock);
spin_lock_init(&inst->lock);
inst->session_type = session_type;
INIT_LIST_HEAD(&inst->pendingq);
INIT_LIST_HEAD(&inst->internalbufs);
INIT_LIST_HEAD(&inst->persistbufs);
+ init_waitqueue_head(&inst->kernel_event_queue);
inst->state = MSM_VIDC_CORE_UNINIT_DONE;
inst->core = core;
+
for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
init_completion(&inst->completions[i]);
@@ -276,6 +429,7 @@
msm_venc_inst_init(inst);
msm_venc_ctrl_init(inst);
}
+
rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
session_type);
if (rc) {
@@ -298,17 +452,20 @@
}
inst->debugfs_root =
msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
+
+ setup_event_queue(inst, &core->vdev[core_id].vdev);
+
spin_lock_irqsave(&core->lock, flags);
list_add_tail(&inst->list, &core->instances);
spin_unlock_irqrestore(&core->lock, flags);
- return rc;
+ return inst;
fail_init:
msm_smem_delete_client(inst->mem_client);
fail_mem_client:
kfree(inst);
inst = NULL;
err_invalid_core:
- return rc;
+ return inst;
}
static void cleanup_instance(struct msm_vidc_inst *inst)
@@ -360,6 +517,10 @@
struct msm_vidc_core *core;
struct list_head *ptr, *next;
int rc = 0;
+
+ if (!inst)
+ return -EINVAL;
+
core = inst->core;
mutex_lock(&core->sync_lock);
list_for_each_safe(ptr, next, &core->instances) {
@@ -373,6 +534,7 @@
dprintk(VIDC_ERR,
"Failed to move video instance to uninit state\n");
cleanup_instance(inst);
+ kfree(inst);
dprintk(VIDC_DBG, "Closed the instance\n");
return 0;
}
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 5b83cfb..7f3096a 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -166,7 +166,7 @@
int rc;
struct iommu_domain *domain;
int i;
- struct iommu_info *io_map;
+ struct msm_vidc_iommu_info *io_map;
struct device *dev;
for (i = 0; i < MAX_MAP; i++) {
io_map = &core->resources.io_map[i];
@@ -202,7 +202,7 @@
{
struct device *dev;
struct iommu_domain *domain;
- struct iommu_info *io_map;
+ struct msm_vidc_iommu_info *io_map;
int i;
if (!core) {
dprintk(VIDC_ERR, "Invalid paramter: %p\n", core);
@@ -408,6 +408,7 @@
inst->reconfig_width = event_notify->width;
inst->in_reconfig = true;
v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+ wake_up(&inst->kernel_event_queue);
return;
} else {
dprintk(VIDC_ERR,
@@ -501,6 +502,7 @@
dqevent.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
dqevent.id = 0;
v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+ wake_up(&inst->kernel_event_queue);
} else {
dprintk(VIDC_ERR, "Failed to get valid response for flush\n");
}
@@ -518,6 +520,7 @@
dqevent.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
dqevent.id = 0;
v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+ wake_up(&inst->kernel_event_queue);
} else {
dprintk(VIDC_ERR,
"Failed to get valid response for session close\n");
@@ -552,13 +555,17 @@
{
struct msm_vidc_cb_data_done *response = data;
struct vb2_buffer *vb;
+ struct msm_vidc_inst *inst;
if (!response) {
dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
return;
}
vb = response->clnt_data;
- if (vb)
+ inst = (struct msm_vidc_inst *)response->session_id;
+ if (vb) {
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ wake_up(&inst->kernel_event_queue);
+ }
}
static void handle_fbd(enum command_response cmd, void *data)
@@ -622,6 +629,7 @@
vb->v4l2_planes[0].bytesused,
vb->v4l2_buf.flags);
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ wake_up(&inst->kernel_event_queue);
} else {
/*
* FIXME:
@@ -737,7 +745,7 @@
dprintk(VIDC_ERR, "Invalid args: %p\n", core);
return -EINVAL;
}
- num_mbs_per_sec = 2 * msm_comm_get_load(core, MSM_VIDC_ENCODER);
+ num_mbs_per_sec = msm_comm_get_load(core, MSM_VIDC_ENCODER);
num_mbs_per_sec += msm_comm_get_load(core, MSM_VIDC_DECODER);
dprintk(VIDC_INFO, "num_mbs_per_sec = %d\n", num_mbs_per_sec);
rc = clk_set_rate(core->resources.clock[VCODEC_CLK].clk,
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index 55aec74..1f2eff8 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -19,6 +19,7 @@
#include <linux/types.h>
#include <linux/completion.h>
#include <linux/clk.h>
+#include <linux/wait.h>
#include <mach/msm_bus.h>
#include <mach/msm_bus_board.h>
#include <mach/ocmem.h>
@@ -141,20 +142,6 @@
void *cookie;
};
-struct iommu_info {
- u32 addr_range[2];
- char name[MAX_NAME_LENGTH];
- char ctx[MAX_NAME_LENGTH];
- int domain;
- int partition;
-};
-
-enum io_maps {
- CP_MAP,
- NS_MAP,
- MAX_MAP
-};
-
enum vidc_clocks {
VCODEC_CLK,
VCODEC_AHB_CLK,
@@ -188,7 +175,7 @@
struct msm_vidc_resources {
struct msm_vidc_fw fw;
- struct iommu_info io_map[MAX_MAP];
+ struct msm_vidc_iommu_info io_map[MAX_MAP];
struct core_clock clock[VCODEC_MAX_CLKS];
struct vidc_bus_info bus_info;
struct on_chip_mem ocmem;
@@ -240,6 +227,7 @@
struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1];
struct v4l2_fh event_handler;
struct msm_smem *extradata_handle;
+ wait_queue_head_t kernel_event_queue;
bool in_reconfig;
u32 reconfig_width;
u32 reconfig_height;
@@ -247,6 +235,7 @@
u32 ftb_count;
u32 fbd_count;
struct vb2_buffer *vb2_seq_hdr;
+ void *priv;
};
extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
index 12ba874..0639dea 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ b/drivers/media/video/msm_vidc/vidc_hal.c
@@ -608,6 +608,9 @@
static void set_vbif_registers(struct hal_device *device)
{
+ /*Disable Dynamic clock gating for Venus VBIF*/
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VENUS_VBIF_CLK_ON, 1, 0);
write_register(device->hal_data->register_base_addr,
VIDC_VBIF_OUT_AXI_AOOO_EN, 0x00000FFF, 0);
write_register(device->hal_data->register_base_addr,
@@ -636,6 +639,8 @@
VIDC_VBIF_OUT_WR_LIM_CONF0, 0x00001010, 0);
write_register(device->hal_data->register_base_addr,
VIDC_VBIF_ARB_CTL, 0x00000030, 0);
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY, 0x5555556, 0);
}
int vidc_hal_core_init(void *device, int domain)
@@ -654,10 +659,6 @@
INIT_LIST_HEAD(&dev->sess_head);
spin_lock_init(&dev->read_lock);
spin_lock_init(&dev->write_lock);
-
- /*Disable Dynamic clock gating for Venus VBIF*/
- write_register(dev->hal_data->register_base_addr,
- VIDC_VENUS_VBIF_CLK_ON, 1, 0);
set_vbif_registers(dev);
if (!dev->hal_client) {
dev->hal_client = msm_smem_new_client(SMEM_ION);
diff --git a/drivers/media/video/msm_vidc/vidc_hal_io.h b/drivers/media/video/msm_vidc/vidc_hal_io.h
index c4b1e0c..b85e015 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_io.h
+++ b/drivers/media/video/msm_vidc/vidc_hal_io.h
@@ -124,9 +124,9 @@
#define VIDC_VBIF_AT_NEW_BASE (VIDC_VBIF_BASE_OFFS + 0xC10)
#define VIDC_VBIF_AT_NEW_HIGH (VIDC_VBIF_BASE_OFFS + 0xC18)
-#define VIDC_VENUS0_VENUS_WRAPPER_VBIF_REQ_PRIORITY \
+#define VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY \
(VIDC_WRAPPER_BASE_OFFS + 0x20)
-#define VIDC_VENUS0_VENUS_WRAPPER_VBIF_PRIORITY_LEVEL \
+#define VIDC_VENUS0_WRAPPER_VBIF_PRIORITY_LEVEL \
(VIDC_WRAPPER_BASE_OFFS + 0x24)
#define VIDC_VENUS_VBIF_REQ_PRIORITY (VIDC_WRAPPER_BASE_OFFS + 0x20)
#define VIDC_VENUS_VBIF_PRIORITY_LEVEL (VIDC_WRAPPER_BASE_OFFS + 0x24)
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
index 28abb36..48532e5 100644
--- a/drivers/media/video/vcap_v4l2.c
+++ b/drivers/media/video/vcap_v4l2.c
@@ -340,6 +340,7 @@
return -EINVAL;
}
+ vb->v4l2_buf.timestamp = b->timestamp;
list_add_tail(&vb->queued_entry, &q->queued_list);
vb->state = VB2_BUF_STATE_QUEUED;
diff --git a/drivers/media/video/vcap_vc.c b/drivers/media/video/vcap_vc.c
index 78e108f..5ae362f 100644
--- a/drivers/media/video/vcap_vc.c
+++ b/drivers/media/video/vcap_vc.c
@@ -122,6 +122,17 @@
return 0;
}
+static struct timeval interpolate_ts(struct timeval tv, uint32_t delta)
+{
+ if (tv.tv_usec < delta) {
+ tv.tv_sec--;
+ tv.tv_usec += VCAP_USEC - delta;
+ } else {
+ tv.tv_usec -= delta;
+ }
+ return tv;
+}
+
irqreturn_t vc_handler(struct vcap_dev *dev)
{
uint32_t irq, timestamp;
@@ -212,6 +223,20 @@
/* If here we know which buffers are done */
timestamp = readl_relaxed(VCAP_VC_TIMESTAMP);
+ if (timestamp < c_data->vc_action.last_ts) {
+ c_data->vc_action.vc_ts.tv_usec +=
+ (0xFFFFFFFF - c_data->vc_action.last_ts) +
+ timestamp + 1;
+ } else {
+ c_data->vc_action.vc_ts.tv_usec +=
+ timestamp - c_data->vc_action.last_ts;
+ }
+
+ c_data->vc_action.vc_ts.tv_sec +=
+ c_data->vc_action.vc_ts.tv_usec / VCAP_USEC;
+ c_data->vc_action.vc_ts.tv_usec =
+ c_data->vc_action.vc_ts.tv_usec % VCAP_USEC;
+ c_data->vc_action.last_ts = timestamp;
c_data->vc_action.buf_num = (buf_num + done_count) % tot;
for (i = 0; i < done_count; i++) {
@@ -232,9 +257,10 @@
/* Config vc with this new buffer */
config_buffer(c_data, buf, VCAP_VC_Y_ADDR_1 + 0x8 * idx,
VCAP_VC_C_ADDR_1 + 0x8 * idx);
- vb->v4l2_buf.timestamp.tv_usec = timestamp -
+ vb->v4l2_buf.timestamp = interpolate_ts(
+ c_data->vc_action.vc_ts,
1000000 / c_data->vc_format.frame_rate *
- (done_count - 1 - i);
+ (done_count - 1 - i));
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
work_todo = true;
c_data->vc_action.buf[idx] = buf;
@@ -298,6 +324,12 @@
VCAP_VC_C_ADDR_1 + i * 8);
}
+ c_data->vc_action.last_ts = readl_relaxed(VCAP_VC_TIMESTAMP);
+ c_data->vc_action.vc_ts.tv_sec =
+ c_data->vc_action.last_ts / VCAP_USEC;
+ c_data->vc_action.vc_ts.tv_usec =
+ c_data->vc_action.last_ts % VCAP_USEC;
+
rc = 0;
for (i = 0; i < c_data->vc_action.tot_buf; i++)
rc = rc << 1 | 0x2;
diff --git a/drivers/media/video/vcap_vp.c b/drivers/media/video/vcap_vp.c
index 139de28..c81206f 100644
--- a/drivers/media/video/vcap_vp.c
+++ b/drivers/media/video/vcap_vp.c
@@ -233,6 +233,10 @@
queue_work(dev->vcap_wq, &dev->vp_to_vc_work.work);
}
+ if (vp_act->bufT0 != NULL && vp_act->vp_state == VP_NORMAL) {
+ vp_act->bufOut->vb.v4l2_buf.timestamp =
+ vp_act->bufT0->vb.v4l2_buf.timestamp;
+ }
vb2_buffer_done(&vp_act->bufOut->vb, VB2_BUF_STATE_DONE);
/* Cycle to next state */
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 52fd5e8..b153b27 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -5798,6 +5798,7 @@
mmc->caps2 |= MMC_CAP2_PACKED_WR_CONTROL;
mmc->caps2 |= (MMC_CAP2_BOOTPART_NOACC | MMC_CAP2_DETECT_ON_ERR);
mmc->caps2 |= MMC_CAP2_SANITIZE;
+ mmc->caps2 |= MMC_CAP2_CACHE_CTRL;
if (plat->nonremovable)
mmc->caps |= MMC_CAP_NONREMOVABLE;
diff --git a/drivers/platform/msm/qpnp-power-on.c b/drivers/platform/msm/qpnp-power-on.c
index 996456f..33b12ae 100644
--- a/drivers/platform/msm/qpnp-power-on.c
+++ b/drivers/platform/msm/qpnp-power-on.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -35,6 +35,7 @@
#define QPNP_PON_RESIN_S1_TIMER(base) (base + 0x44)
#define QPNP_PON_RESIN_S2_TIMER(base) (base + 0x45)
#define QPNP_PON_RESIN_S2_CNTL(base) (base + 0x46)
+#define QPNP_PON_PS_HOLD_RST_CTL(base) (base + 0x5A)
#define QPNP_PON_RESIN_PULL_UP BIT(0)
#define QPNP_PON_KPDPWR_PULL_UP BIT(1)
@@ -50,6 +51,10 @@
#define QPNP_PON_RESIN_N_SET BIT(1)
#define QPNP_PON_RESIN_BARK_N_SET BIT(4)
+#define QPNP_PON_RESET_EN BIT(7)
+#define QPNP_PON_WARM_RESET BIT(0)
+#define QPNP_PON_SHUTDOWN BIT(2)
+
/* Ranges */
#define QPNP_PON_S1_TIMER_MAX 10256
#define QPNP_PON_S2_TIMER_MAX 2000
@@ -84,6 +89,8 @@
struct delayed_work bark_work;
};
+static struct qpnp_pon *sys_reset_dev;
+
static u32 s1_delay[PON_S1_COUNT_MAX + 1] = {
0 , 32, 56, 80, 138, 184, 272, 408, 608, 904, 1352, 2048,
3072, 4480, 6720, 10256
@@ -113,6 +120,57 @@
return rc;
}
+/**
+ * qpnp_pon_system_pwr_off - Configure system-reset PMIC for shutdown or reset
+ * @reset: Configures for shutdown if 0, or reset if 1.
+ *
+ * This function will only configure a single PMIC. The other PMICs in the
+ * system are slaved off of it and require no explicit configuration. Once
+ * the system-reset PMIC is configured properly, the MSM can drop PS_HOLD to
+ * activate the specified configuration.
+ */
+int qpnp_pon_system_pwr_off(bool reset)
+{
+ int rc;
+ struct qpnp_pon *pon = sys_reset_dev;
+
+ if (!pon)
+ return -ENODEV;
+
+ rc = qpnp_pon_masked_write(pon, QPNP_PON_PS_HOLD_RST_CTL(pon->base),
+ QPNP_PON_RESET_EN, 0);
+ if (rc)
+ dev_err(&pon->spmi->dev,
+ "Unable to write to addr=%x, rc(%d)\n",
+ QPNP_PON_PS_HOLD_RST_CTL(pon->base), rc);
+
+ /*
+ * We need 10 sleep clock cycles here. But since the clock is
+ * internally generated, we need to add 50% tolerance to be
+ * conservative.
+ */
+ udelay(500);
+
+ rc = qpnp_pon_masked_write(pon, QPNP_PON_PS_HOLD_RST_CTL(pon->base),
+ QPNP_PON_WARM_RESET | QPNP_PON_SHUTDOWN,
+ reset ? QPNP_PON_WARM_RESET : QPNP_PON_SHUTDOWN);
+ if (rc)
+ dev_err(&pon->spmi->dev,
+ "Unable to write to addr=%x, rc(%d)\n",
+ QPNP_PON_PS_HOLD_RST_CTL(pon->base), rc);
+
+ rc = qpnp_pon_masked_write(pon, QPNP_PON_PS_HOLD_RST_CTL(pon->base),
+ QPNP_PON_RESET_EN,
+ QPNP_PON_RESET_EN);
+ if (rc)
+ dev_err(&pon->spmi->dev,
+ "Unable to write to addr=%x, rc(%d)\n",
+ QPNP_PON_PS_HOLD_RST_CTL(pon->base), rc);
+
+ return rc;
+}
+EXPORT_SYMBOL(qpnp_pon_system_pwr_off);
+
static struct qpnp_pon_config *
qpnp_get_cfg(struct qpnp_pon *pon, u32 pon_type)
{
@@ -662,7 +720,7 @@
struct resource *pon_resource;
struct device_node *itr = NULL;
u32 delay = 0;
- int rc = 0;
+ int rc, sys_reset;
pon = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_pon),
GFP_KERNEL);
@@ -671,6 +729,15 @@
return -ENOMEM;
}
+ sys_reset = of_property_read_bool(spmi->dev.of_node,
+ "qcom,system-reset");
+ if (sys_reset && sys_reset_dev) {
+ dev_err(&spmi->dev, "qcom,system-reset property can only be specified for one device on the system\n");
+ return -EINVAL;
+ } else if (sys_reset) {
+ sys_reset_dev = pon;
+ }
+
pon->spmi = spmi;
/* get the total number of pon configurations */
diff --git a/drivers/platform/msm/sps/bam.c b/drivers/platform/msm/sps/bam.c
index eb9e8ee..bcb4cdb 100644
--- a/drivers/platform/msm/sps/bam.c
+++ b/drivers/platform/msm/sps/bam.c
@@ -679,7 +679,7 @@
bam_write_reg_field(base, CTRL, BAM_EN, 1);
#ifdef CONFIG_SPS_SUPPORT_NDP_BAM
- bam_write_reg_field(base, CTRL, CACHE_MISS_ERR_RESP_EN, 1);
+ bam_write_reg_field(base, CTRL, CACHE_MISS_ERR_RESP_EN, 0);
bam_write_reg_field(base, CTRL, LOCAL_CLK_GATING, 1);
#endif
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index da2a30d..6d96d3b 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -2641,7 +2641,15 @@
slc->state = SLIM_CH_SUSPENDED;
}
- ret = slim_allocbw(sb, &subframe, &clkgear);
+ /*
+ * Controller can override default channel scheduling algorithm.
+ * (e.g. if controller needs to use fixed channel scheduling based
+ * on number of channels)
+ */
+ if (ctrl->allocbw)
+ ret = ctrl->allocbw(sb, &subframe, &clkgear);
+ else
+ ret = slim_allocbw(sb, &subframe, &clkgear);
if (!ret) {
ret = slim_processtxn(ctrl, SLIM_MSG_DEST_BROADCAST,
diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
index 8724138..c32978e 100644
--- a/drivers/spmi/Kconfig
+++ b/drivers/spmi/Kconfig
@@ -21,7 +21,6 @@
config MSM_QPNP_INT
depends on SPARSE_IRQ
- depends on ARCH_MSM8974
depends on SPMI
depends on OF_SPMI
bool "MSM QPNP INT"
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index cad411d..b1b7763 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -60,6 +60,11 @@
return -ENODEV;
}
+ if (dev->ops) {
+ pr_err("bridge already opened");
+ return -EALREADY;
+ }
+
dev->ops = ops;
dev->err = 0;
@@ -82,6 +87,16 @@
{
struct diag_bridge *dev = __dev;
+ if (!dev) {
+ pr_err("dev is null");
+ return;
+ }
+
+ if (!dev->ops) {
+ pr_err("can't close bridge that was not open");
+ return;
+ }
+
dev_dbg(&dev->ifc->dev, "%s:\n", __func__);
usb_kill_anchored_urbs(&dev->submitted);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 5637f19..998978c 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -69,6 +69,13 @@
#define USB_SUSPEND_DELAY_TIME (500 * HZ/1000) /* 500 msec */
+enum msm_otg_phy_reg_mode {
+ USB_PHY_REG_OFF,
+ USB_PHY_REG_ON,
+ USB_PHY_REG_LPM_ON,
+ USB_PHY_REG_LPM_OFF,
+};
+
static DECLARE_COMPLETION(pmic_vbus_init);
static struct msm_otg *the_msm_otg;
static bool debug_aca_enabled;
@@ -168,7 +175,8 @@
return ret;
}
-static int msm_hsusb_ldo_enable(struct msm_otg *motg, int on)
+static int msm_hsusb_ldo_enable(struct msm_otg *motg,
+ enum msm_otg_phy_reg_mode mode)
{
int ret = 0;
@@ -182,7 +190,8 @@
return -ENODEV;
}
- if (on) {
+ switch (mode) {
+ case USB_PHY_REG_ON:
ret = regulator_set_optimum_mode(hsusb_1p8,
USB_PHY_1P8_HPM_LOAD);
if (ret < 0) {
@@ -219,7 +228,9 @@
return ret;
}
- } else {
+ break;
+
+ case USB_PHY_REG_OFF:
ret = regulator_disable(hsusb_1p8);
if (ret) {
dev_err(motg->phy.dev, "%s: unable to disable the hsusb 1p8\n",
@@ -242,9 +253,55 @@
if (ret < 0)
pr_err("%s: Unable to set LPM of the regulator:"
"HSUSB_3p3\n", __func__);
+
+ break;
+
+ case USB_PHY_REG_LPM_ON:
+ ret = regulator_set_optimum_mode(hsusb_1p8,
+ USB_PHY_1P8_LPM_LOAD);
+ if (ret < 0) {
+ pr_err("%s: Unable to set LPM of the regulator: HSUSB_1p8\n",
+ __func__);
+ return ret;
+ }
+
+ ret = regulator_set_optimum_mode(hsusb_3p3,
+ USB_PHY_3P3_LPM_LOAD);
+ if (ret < 0) {
+ pr_err("%s: Unable to set LPM of the regulator: HSUSB_3p3\n",
+ __func__);
+ regulator_set_optimum_mode(hsusb_1p8, USB_PHY_REG_ON);
+ return ret;
+ }
+
+ break;
+
+ case USB_PHY_REG_LPM_OFF:
+ ret = regulator_set_optimum_mode(hsusb_1p8,
+ USB_PHY_1P8_HPM_LOAD);
+ if (ret < 0) {
+ pr_err("%s: Unable to set HPM of the regulator: HSUSB_1p8\n",
+ __func__);
+ return ret;
+ }
+
+ ret = regulator_set_optimum_mode(hsusb_3p3,
+ USB_PHY_3P3_HPM_LOAD);
+ if (ret < 0) {
+ pr_err("%s: Unable to set HPM of the regulator: HSUSB_3p3\n",
+ __func__);
+ regulator_set_optimum_mode(hsusb_1p8, USB_PHY_REG_ON);
+ return ret;
+ }
+
+ break;
+
+ default:
+ pr_err("%s: Unsupported mode (%d).", __func__, mode);
+ return -ENOTSUPP;
}
- pr_debug("reg (%s)\n", on ? "HPM" : "LPM");
+ pr_debug("%s: USB reg mode (%d) (OFF/HPM/LPM)\n", __func__, mode);
return ret < 0 ? ret : 0;
}
@@ -881,8 +938,12 @@
if (motg->caps & ALLOW_PHY_POWER_COLLAPSE &&
!host_bus_suspend && !dcp) {
- msm_hsusb_ldo_enable(motg, 0);
+ msm_hsusb_ldo_enable(motg, USB_PHY_REG_OFF);
motg->lpm_flags |= PHY_PWR_COLLAPSED;
+ } else if (motg->caps & ALLOW_PHY_REGULATORS_LPM &&
+ !host_bus_suspend && !device_bus_suspend && !dcp) {
+ msm_hsusb_ldo_enable(motg, USB_PHY_REG_LPM_ON);
+ motg->lpm_flags |= PHY_REGULATORS_LPM;
}
if (motg->lpm_flags & PHY_RETENTIONED) {
@@ -946,8 +1007,11 @@
}
if (motg->lpm_flags & PHY_PWR_COLLAPSED) {
- msm_hsusb_ldo_enable(motg, 1);
+ msm_hsusb_ldo_enable(motg, USB_PHY_REG_ON);
motg->lpm_flags &= ~PHY_PWR_COLLAPSED;
+ } else if (motg->lpm_flags & PHY_REGULATORS_LPM) {
+ msm_hsusb_ldo_enable(motg, USB_PHY_REG_LPM_OFF);
+ motg->lpm_flags &= ~PHY_REGULATORS_LPM;
}
if (motg->lpm_flags & PHY_RETENTIONED) {
@@ -3622,7 +3686,7 @@
}
}
- ret = msm_hsusb_ldo_enable(motg, 1);
+ ret = msm_hsusb_ldo_enable(motg, USB_PHY_REG_ON);
if (ret) {
dev_err(&pdev->dev, "hsusb vreg enable failed\n");
goto free_ldo_init;
@@ -3724,7 +3788,8 @@
ALLOW_PHY_RETENTION;
if (motg->pdata->otg_control == OTG_PHY_CONTROL)
- motg->caps = ALLOW_PHY_RETENTION;
+ motg->caps = ALLOW_PHY_RETENTION |
+ ALLOW_PHY_REGULATORS_LPM;
}
if (motg->pdata->enable_lpm_on_dev_suspend)
@@ -3756,7 +3821,7 @@
destroy_wlock:
wake_lock_destroy(&motg->wlock);
clk_disable_unprepare(motg->core_clk);
- msm_hsusb_ldo_enable(motg, 0);
+ msm_hsusb_ldo_enable(motg, USB_PHY_REG_OFF);
free_ldo_init:
msm_hsusb_ldo_init(motg, 0);
free_hsusb_vddcx:
@@ -3843,7 +3908,7 @@
clk_disable_unprepare(motg->pclk);
clk_disable_unprepare(motg->core_clk);
msm_xo_put(motg->xo_handle);
- msm_hsusb_ldo_enable(motg, 0);
+ msm_hsusb_ldo_enable(motg, USB_PHY_REG_OFF);
msm_hsusb_ldo_init(motg, 0);
regulator_disable(hsusb_vddcx);
regulator_set_voltage(hsusb_vddcx,
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 6e3567f..f6d9eb7 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -606,7 +606,7 @@
static int mdp_hist_init_mgmt(struct mdp_hist_mgmt *mgmt, uint32_t block)
{
- uint32_t bins, extra, index, term = 0;
+ uint32_t bins, extra, index, intr = 0, term = 0;
init_completion(&mgmt->mdp_hist_comp);
mutex_init(&mgmt->mdp_hist_mutex);
mutex_init(&mgmt->mdp_do_hist_mutex);
@@ -622,6 +622,8 @@
switch (block) {
case MDP_BLOCK_DMA_P:
term = MDP_HISTOGRAM_TERM_DMA_P;
+ intr = (mdp_rev >= MDP_REV_40) ? INTR_DMA_P_HISTOGRAM :
+ MDP_HIST_DONE;
bins = (mdp_rev >= MDP_REV_42) ? MDP_REV42_HIST_MAX_BIN :
MDP_REV41_HIST_MAX_BIN;
extra = 2;
@@ -630,6 +632,7 @@
break;
case MDP_BLOCK_DMA_S:
term = MDP_HISTOGRAM_TERM_DMA_S;
+ intr = INTR_DMA_S_HISTOGRAM;
bins = MDP_REV42_HIST_MAX_BIN;
extra = 2;
mgmt->base += 0x5000;
@@ -637,6 +640,7 @@
break;
case MDP_BLOCK_VG_1:
term = MDP_HISTOGRAM_TERM_VG_1;
+ intr = INTR_VG1_HISTOGRAM;
bins = MDP_REV42_HIST_MAX_BIN;
extra = 1;
mgmt->base += 0x6000;
@@ -644,6 +648,7 @@
break;
case MDP_BLOCK_VG_2:
term = MDP_HISTOGRAM_TERM_VG_2;
+ intr = INTR_VG2_HISTOGRAM;
bins = MDP_REV42_HIST_MAX_BIN;
extra = 1;
mgmt->base += 0x6000;
@@ -651,6 +656,8 @@
break;
default:
term = MDP_HISTOGRAM_TERM_DMA_P;
+ intr = (mdp_rev >= MDP_REV_40) ? INTR_DMA_P_HISTOGRAM :
+ MDP_HIST_DONE;
bins = (mdp_rev >= MDP_REV_42) ? MDP_REV42_HIST_MAX_BIN :
MDP_REV41_HIST_MAX_BIN;
extra = 2;
@@ -658,6 +665,7 @@
index = MDP_HIST_MGMT_DMA_P;
}
mgmt->irq_term = term;
+ mgmt->intr = intr;
mgmt->c0 = kmalloc(bins * sizeof(uint32_t), GFP_KERNEL);
if (mgmt->c0 == NULL)
@@ -802,20 +810,45 @@
static int mdp_histogram_enable(struct mdp_hist_mgmt *mgmt)
{
uint32_t base;
+ unsigned long flag;
if (mgmt->mdp_is_hist_data == TRUE) {
pr_err("%s histogram already started\n", __func__);
return -EINVAL;
}
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
- mdp_enable_irq(mgmt->irq_term);
+ base = (uint32_t) (MDP_BASE + mgmt->base);
+ /*First make sure that device is not collecting histogram*/
+ mgmt->mdp_is_hist_data = FALSE;
+ mgmt->mdp_is_hist_valid = FALSE;
+ mgmt->mdp_is_hist_init = FALSE;
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ outp32(MDP_INTR_CLEAR, mgmt->intr);
+ mdp_intr_mask &= ~mgmt->intr;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ MDP_OUTP(base + 0x001C, 0);
+ MDP_OUTP(base + 0x0018, INTR_HIST_DONE | INTR_HIST_RESET_SEQ_DONE);
+ MDP_OUTP(base + 0x0024, 0);
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+ mutex_unlock(&mgmt->mdp_hist_mutex);
+ cancel_work_sync(&mgmt->mdp_histogram_worker);
+ mutex_lock(&mgmt->mdp_hist_mutex);
+
+ /*Then initialize histogram*/
INIT_COMPLETION(mgmt->mdp_hist_comp);
- base = (uint32_t) (MDP_BASE + mgmt->base);
+ spin_lock_irqsave(&mdp_spin_lock, flag);
MDP_OUTP(base + 0x0018, INTR_HIST_DONE | INTR_HIST_RESET_SEQ_DONE);
MDP_OUTP(base + 0x0010, 1);
MDP_OUTP(base + 0x001C, INTR_HIST_DONE | INTR_HIST_RESET_SEQ_DONE);
+ outp32(MDP_INTR_CLEAR, mgmt->intr);
+ mdp_intr_mask |= mgmt->intr;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ mdp_enable_irq(mgmt->irq_term);
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
MDP_OUTP(base + 0x0004, mgmt->frame_cnt);
if (mgmt->block != MDP_BLOCK_VG_1 && mgmt->block != MDP_BLOCK_VG_2)
MDP_OUTP(base + 0x0008, mgmt->bit_mask);
@@ -830,6 +863,7 @@
static int mdp_histogram_disable(struct mdp_hist_mgmt *mgmt)
{
uint32_t base, status;
+ unsigned long flag;
if (mgmt->mdp_is_hist_data == FALSE) {
pr_err("%s histogram already stopped\n", __func__);
return -EINVAL;
@@ -842,6 +876,13 @@
base = (uint32_t) (MDP_BASE + mgmt->base);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ outp32(MDP_INTR_CLEAR, mgmt->intr);
+ mdp_intr_mask &= ~mgmt->intr;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ mdp_disable_irq(mgmt->irq_term);
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
if (mdp_rev >= MDP_REV_42)
MDP_OUTP(base + 0x0020, 1);
status = inpdw(base + 0x001C);
@@ -856,7 +897,6 @@
complete(&mgmt->mdp_hist_comp);
}
- mdp_disable_irq(mgmt->irq_term);
return 0;
}
@@ -1102,6 +1142,7 @@
struct mdp_hist_mgmt *mgmt = container_of(data, struct mdp_hist_mgmt,
mdp_histogram_worker);
int ret = 0;
+ bool hist_ready;
mutex_lock(&mgmt->mdp_hist_mutex);
if (mgmt->mdp_is_hist_data == FALSE) {
pr_debug("%s, Histogram disabled before read.\n", __func__);
@@ -1116,8 +1157,9 @@
pr_err("mgmt->hist invalid NULL\n");
ret = -EINVAL;
}
+ hist_ready = (mgmt->mdp_is_hist_init && mgmt->mdp_is_hist_valid);
- if (!ret) {
+ if (!ret && hist_ready) {
switch (mgmt->block) {
case MDP_BLOCK_DMA_P:
case MDP_BLOCK_DMA_S:
@@ -1138,7 +1180,7 @@
* if read was triggered by an underrun or failed copying,
* don't wake up readers
*/
- if (!ret && mgmt->mdp_is_hist_valid && mgmt->mdp_is_hist_init) {
+ if (!ret && hist_ready) {
mgmt->hist = NULL;
if (waitqueue_active(&mgmt->mdp_hist_comp.wait))
complete(&mgmt->mdp_hist_comp);
@@ -1150,7 +1192,7 @@
mgmt->mdp_is_hist_init = TRUE;
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
- if (!ret)
+ if (!ret && hist_ready)
__mdp_histogram_kickoff(mgmt);
else
__mdp_histogram_reset(mgmt);
@@ -1728,10 +1770,8 @@
isr &= mask;
if (isr & INTR_HIST_RESET_SEQ_DONE)
__mdp_histogram_kickoff(mgmt);
-
- if (isr & INTR_HIST_DONE) {
+ else if (isr & INTR_HIST_DONE)
queue_work(mdp_hist_wq, &mgmt->mdp_histogram_worker);
- }
}
#ifndef CONFIG_FB_MSM_MDP40
@@ -1741,7 +1781,6 @@
struct mdp_dma_data *dma;
unsigned long flag;
struct mdp_hist_mgmt *mgmt = NULL;
- char *base_addr;
int i, ret;
int vsync_isr;
/* Ensure all the register write are complete */
@@ -1813,13 +1852,7 @@
mgmt = mdp_hist_mgmt_array[i];
if (!mgmt)
continue;
-
- base_addr = MDP_BASE + mgmt->base;
- outpdw(base_addr + 0x010, 1);
- outpdw(base_addr + 0x01C, INTR_HIST_DONE |
- INTR_HIST_RESET_SEQ_DONE);
mgmt->mdp_is_hist_valid = FALSE;
- __mdp_histogram_reset(mgmt);
}
}
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index 1397507..371174c 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -256,6 +256,7 @@
struct mdp_hist_mgmt {
uint32_t block;
uint32_t irq_term;
+ uint32_t intr;
uint32_t base;
struct completion mdp_hist_comp;
struct mutex mdp_hist_mutex;
@@ -323,6 +324,14 @@
#define TV_OUT_DMA3_START BIT(13)
#define MDP_HIST_DONE BIT(20)
+/*MDP4 MDP histogram interrupts*/
+/*note: these are only applicable on MDP4+ targets*/
+#define INTR_VG1_HISTOGRAM BIT(5)
+#define INTR_VG2_HISTOGRAM BIT(6)
+#define INTR_DMA_P_HISTOGRAM BIT(17)
+#define INTR_DMA_S_HISTOGRAM BIT(26)
+/*end MDP4 MDP histogram interrupts*/
+
/* histogram interrupts */
#define INTR_HIST_DONE BIT(1)
#define INTR_HIST_RESET_SEQ_DONE BIT(0)
@@ -337,7 +346,6 @@
MDP_DMA_S_DONE| \
MDP_DMA_E_DONE| \
LCDC_UNDERFLOW| \
- MDP_HIST_DONE| \
TV_ENC_UNDERRUN)
#endif
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 6fc83df..005e87c 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -111,33 +111,23 @@
};
/* system interrupts */
+/*note histogram interrupts defined in mdp.h*/
#define INTR_OVERLAY0_DONE BIT(0)
#define INTR_OVERLAY1_DONE BIT(1)
#define INTR_DMA_S_DONE BIT(2)
#define INTR_DMA_E_DONE BIT(3)
#define INTR_DMA_P_DONE BIT(4)
-#define INTR_VG1_HISTOGRAM BIT(5)
-#define INTR_VG2_HISTOGRAM BIT(6)
#define INTR_PRIMARY_VSYNC BIT(7)
#define INTR_PRIMARY_INTF_UDERRUN BIT(8)
#define INTR_EXTERNAL_VSYNC BIT(9)
#define INTR_EXTERNAL_INTF_UDERRUN BIT(10)
#define INTR_PRIMARY_RDPTR BIT(11) /* read pointer */
-#define INTR_DMA_P_HISTOGRAM BIT(17)
-#define INTR_DMA_S_HISTOGRAM BIT(26)
#define INTR_OVERLAY2_DONE BIT(30)
#ifdef CONFIG_FB_MSM_OVERLAY
-#define MDP4_ANY_INTR_MASK (INTR_DMA_P_HISTOGRAM | \
- INTR_DMA_S_HISTOGRAM | \
- INTR_VG1_HISTOGRAM | \
- INTR_VG2_HISTOGRAM)
+#define MDP4_ANY_INTR_MASK (0)
#else
-#define MDP4_ANY_INTR_MASK (INTR_DMA_P_DONE| \
- INTR_DMA_P_HISTOGRAM | \
- INTR_DMA_S_HISTOGRAM | \
- INTR_VG1_HISTOGRAM | \
- INTR_VG2_HISTOGRAM)
+#define MDP4_ANY_INTR_MASK (INTR_DMA_P_DONE)
#endif
enum {
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index 487e5d5..ee7e9ce 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -294,6 +294,7 @@
mdp4_mixer_stage_commit(pipe->mixer_num);
mdp4_writeback_overlay_kickoff(mfd, pipe);
+ mdp4_writeback_dma_busy_wait(mfd);
/* move current committed iommu to freelist */
mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index 359f37e..b35acfb 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -500,7 +500,6 @@
uint32 isr, mask, panel;
struct mdp_dma_data *dma;
struct mdp_hist_mgmt *mgmt = NULL;
- char *base_addr;
int i, ret;
mdp_is_in_isr = TRUE;
@@ -528,12 +527,7 @@
mgmt = mdp_hist_mgmt_array[i];
if (!mgmt)
continue;
- base_addr = MDP_BASE + mgmt->base;
- MDP_OUTP(base_addr + 0x010, 1);
- outpdw(base_addr + 0x01c, INTR_HIST_DONE |
- INTR_HIST_RESET_SEQ_DONE);
mgmt->mdp_is_hist_valid = FALSE;
- __mdp_histogram_reset(mgmt);
}
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index bd5f464..b0a67938 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -388,7 +388,7 @@
ret = -ENOBUFS;
}
mutex_unlock(&wb->lock);
- return 0;
+ return ret;
}
static void mdss_mdp_wb_callback(void *arg)
diff --git a/drivers/video/msm/mhl/mhl_8334.c b/drivers/video/msm/mhl/mhl_8334.c
index f3b8cd1..6c0778f 100644
--- a/drivers/video/msm/mhl/mhl_8334.c
+++ b/drivers/video/msm/mhl/mhl_8334.c
@@ -62,6 +62,9 @@
void (*notify_usb_online)(int online);
static void mhl_drive_hpd(uint8_t to_state);
static int mhl_send_msc_command(struct msc_command_struct *req);
+static void list_cmd_put(struct msc_command_struct *cmd);
+static struct msc_command_struct *list_cmd_get(void);
+static void mhl_msc_send_work(struct work_struct *work);
static struct i2c_driver mhl_sii_i2c_driver = {
.driver = {
@@ -618,7 +621,7 @@
list_add_tail(&new_cmd->msc_queue_envelope, &mhl_msm_state->list_cmd);
}
-struct msc_command_struct *list_cmd_get(void)
+static struct msc_command_struct *list_cmd_get(void)
{
struct msc_cmd_envelope *cmd_env =
list_first_entry(&mhl_msm_state->list_cmd,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
index 3620f1a..2af76f3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
@@ -70,7 +70,6 @@
case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED:
case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE:
case VIDC_1080P_ERROR_DIVIDE_BY_ZERO:
- case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE:
case VIDC_1080P_ERROR_VSP_NOT_READY:
case VIDC_1080P_ERROR_BUFFER_FULL_STATE:
@@ -242,6 +241,7 @@
case VIDC_1080P_ERROR_HEADER_NOT_FOUND:
case VIDC_1080P_ERROR_SLICE_PARSE_ERROR:
case VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED:
+ case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
vcd_status = VCD_ERR_BITSTREAM_ERR;
DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR");
break;
diff --git a/include/linux/qpnp/power-on.h b/include/linux/qpnp/power-on.h
new file mode 100644
index 0000000..85dbce9
--- /dev/null
+++ b/include/linux/qpnp/power-on.h
@@ -0,0 +1,24 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef QPNP_PON_H
+#define QPNP_PON_H
+
+#include <linux/errno.h>
+
+#ifdef CONFIG_QPNP_POWER_ON
+int qpnp_pon_system_pwr_off(bool reset);
+#else
+static int qpnp_pon_system_pwr_off(bool reset) { return -ENODEV; }
+#endif
+
+#endif
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index d365b15..e92201f 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -498,6 +498,8 @@
* @set_laddr: Setup logical address at laddr for the slave with elemental
* address e_addr. Drivers implementing controller will be expected to
* send unicast message to this device with its logical address.
+ * @allocbw: Controller can override default reconfiguration and channel
+ * scheduling algorithm.
* @wakeup: This function pointer implements controller-specific procedure
* to wake it up from clock-pause. Framework will call this to bring
* the controller out of clock pause.
@@ -542,6 +544,8 @@
struct slim_msg_txn *txn);
int (*set_laddr)(struct slim_controller *ctrl,
const u8 *ea, u8 elen, u8 laddr);
+ int (*allocbw)(struct slim_device *sb,
+ int *subfrmc, int *clkgear);
int (*wakeup)(struct slim_controller *ctrl);
int (*config_port)(struct slim_controller *ctrl,
u8 port);
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index adcc450..8e6550f 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -348,7 +348,7 @@
/*
* Allowing PHY power collpase turns off the HSUSB 3.3v and 1.8v
* analog regulators while going to low power mode.
- * Currently only 8960(28nm PHY) has the support to allowing PHY
+ * Currently only 28nm PHY has the support to allowing PHY
* power collapse since it doesn't have leakage currents while
* turning off the power rails.
*/
@@ -362,12 +362,18 @@
* Allow putting the core in Low Power mode, when
* USB bus is suspended but cable is connected.
*/
-#define ALLOW_LPM_ON_DEV_SUSPEND BIT(2)
+#define ALLOW_LPM_ON_DEV_SUSPEND BIT(2)
+ /*
+ * Allowing PHY regulators LPM puts the HSUSB 3.3v and 1.8v
+ * analog regulators into LPM while going to USB low power mode.
+ */
+#define ALLOW_PHY_REGULATORS_LPM BIT(3)
unsigned long lpm_flags;
#define PHY_PWR_COLLAPSED BIT(0)
#define PHY_RETENTIONED BIT(1)
#define XO_SHUTDOWN BIT(2)
#define CLOCKS_DOWN BIT(3)
+#define PHY_REGULATORS_LPM BIT(4)
int reset_counter;
unsigned long b_last_se0_sess;
unsigned long tmouts;
diff --git a/include/media/msm_vidc.h b/include/media/msm_vidc.h
index 2efe31c..34464c6 100644
--- a/include/media/msm_vidc.h
+++ b/include/media/msm_vidc.h
@@ -14,8 +14,8 @@
#ifndef _MSM_VIDC_H_
#define _MSM_VIDC_H_
-#include <linux/videodev2.h>
#include <linux/poll.h>
+#include <linux/videodev2.h>
enum core_id {
MSM_VIDC_CORE_0 = 0,
@@ -28,7 +28,21 @@
MSM_VIDC_MAX_DEVICES,
};
-int msm_vidc_open(void *vidc_inst, int core_id, int session_type);
+struct msm_vidc_iommu_info {
+ u32 addr_range[2];
+ char name[64];
+ char ctx[64];
+ int domain;
+ int partition;
+};
+
+enum msm_vidc_io_maps {
+ CP_MAP,
+ NS_MAP,
+ MAX_MAP
+};
+
+void *msm_vidc_open(int core_id, int session_type);
int msm_vidc_close(void *instance);
int msm_vidc_querycap(void *instance, struct v4l2_capability *cap);
int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
@@ -47,4 +61,12 @@
int msm_vidc_encoder_cmd(void *instance, struct v4l2_encoder_cmd *enc);
int msm_vidc_poll(void *instance, struct file *filp,
struct poll_table_struct *pt);
+int msm_vidc_get_iommu_maps(void *instance,
+ struct msm_vidc_iommu_info maps[MAX_MAP]);
+int msm_vidc_subscribe_event(void *instance,
+ struct v4l2_event_subscription *sub);
+int msm_vidc_unsubscribe_event(void *instance,
+ struct v4l2_event_subscription *sub);
+int msm_vidc_dqevent(void *instance, struct v4l2_event *event);
+int msm_vidc_wait(void *instance);
#endif
diff --git a/include/media/vcap_v4l2.h b/include/media/vcap_v4l2.h
index 1e18c9e..7b6d817 100644
--- a/include/media/vcap_v4l2.h
+++ b/include/media/vcap_v4l2.h
@@ -38,6 +38,7 @@
writel_relaxed(val, addr); \
} while (0)
+#define VCAP_USEC (1000000)
#define VCAP_BASE (dev->vcapbase)
#define VCAP_OFFSET(off) (VCAP_BASE + off)
@@ -87,6 +88,9 @@
uint8_t tot_buf;
uint8_t buf_num;
+ struct timeval vc_ts;
+ uint32_t last_ts;
+
/* Buffers inside vc */
struct vcap_buffer *buf[6];
};
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index 1041818..9bc565e 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -1739,6 +1739,48 @@
.ignore_pmdown_time = 1,
.be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
},
+ {
+ .name = "MSM8960 Media6",
+ .stream_name = "MultiMedia6",
+ .cpu_dai_name = "MultiMedia6",
+ .platform_name = "msm-multi-ch-pcm-dsp",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* this dailink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6
+ },
+ {
+ .name = "MSM8960 Compr2",
+ .stream_name = "COMPR2",
+ .cpu_dai_name = "MultiMedia7",
+ .platform_name = "msm-compr-dsp",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* this dailink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7,
+ },
+ {
+ .name = "MSM8960 Compr3",
+ .stream_name = "COMPR3",
+ .cpu_dai_name = "MultiMedia8",
+ .platform_name = "msm-compr-dsp",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* this dailink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
+ },
/* Backend DAI Links */
{
.name = LPASS_BE_SLIMBUS_0_RX,
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index a911d9d..78b3abc 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -354,13 +354,14 @@
switch (compr->info.codec_param.codec.id) {
case SND_AUDIOCODEC_MP3:
+ pr_debug("%s: SND_AUDIOCODEC_MP3\n", __func__);
ret = q6asm_media_format_block(prtd->audio_client,
compr->codec);
if (ret < 0)
pr_info("%s: CMD Format block failed\n", __func__);
break;
case SND_AUDIOCODEC_AAC:
- pr_debug("SND_AUDIOCODEC_AAC\n");
+ pr_debug("%s: SND_AUDIOCODEC_AAC\n", __func__);
memset(&aac_cfg, 0x0, sizeof(struct asm_aac_cfg));
aac_cfg.aot = AAC_ENC_MODE_EAAC_P;
aac_cfg.format = 0x03;
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 5b69da4..41f259d 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -74,6 +74,9 @@
static const DECLARE_TLV_DB_LINEAR(compressed_rx_vol_gain, 0,
INT_RX_VOL_MAX_STEPS);
+static int msm_route_compressed2_vol_control;
+static const DECLARE_TLV_DB_LINEAR(compressed2_rx_vol_gain, 0,
+ INT_RX_VOL_MAX_STEPS);
static int msm_route_ec_ref_rx;
/* Equal to Frontend after last of the MULTIMEDIA SESSIONS */
@@ -869,6 +872,22 @@
return 0;
}
+static int msm_routing_get_compressed2_vol_mixer(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = msm_route_compressed2_vol_control;
+ return 0;
+}
+
+static int msm_routing_set_compressed2_vol_mixer(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ if (!compressed_set_volume(ucontrol->value.integer.value[0]))
+ msm_route_compressed2_vol_control =
+ ucontrol->value.integer.value[0];
+ return 0;
+}
+
static int msm_routing_get_srs_trumedia_control(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -1838,6 +1857,12 @@
msm_routing_set_compressed_vol_mixer, compressed_rx_vol_gain),
};
+static const struct snd_kcontrol_new compressed2_vol_mixer_controls[] = {
+ SOC_SINGLE_EXT_TLV("COMPRESSED2 RX Volume", SND_SOC_NOPM, 0,
+ INT_RX_VOL_GAIN, 0, msm_routing_get_compressed2_vol_mixer,
+ msm_routing_set_compressed2_vol_mixer, compressed2_rx_vol_gain),
+};
+
static const struct snd_kcontrol_new lpa_SRS_trumedia_controls[] = {
{.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "SRS TruMedia",
@@ -2780,6 +2805,9 @@
snd_soc_add_platform_controls(platform,
compressed_vol_mixer_controls,
ARRAY_SIZE(compressed_vol_mixer_controls));
+ snd_soc_add_platform_controls(platform,
+ compressed2_vol_mixer_controls,
+ ARRAY_SIZE(compressed2_vol_mixer_controls));
snd_soc_add_platform_controls(platform,
lpa_SRS_trumedia_controls,
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 6bd6adc..1338e2f 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -1372,6 +1372,48 @@
.ignore_pmdown_time = 1,
.be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
},
+ {
+ .name = "MSM8960 Media6",
+ .stream_name = "MultiMedia6",
+ .cpu_dai_name = "MultiMedia6",
+ .platform_name = "msm-multi-ch-pcm-dsp",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* this dailink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6
+ },
+ {
+ .name = "MSM8960 Compr2",
+ .stream_name = "COMPR2",
+ .cpu_dai_name = "MultiMedia7",
+ .platform_name = "msm-compr-dsp",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* this dailink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7,
+ },
+ {
+ .name = "MSM8960 Compr3",
+ .stream_name = "COMPR3",
+ .cpu_dai_name = "MultiMedia8",
+ .platform_name = "msm-compr-dsp",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* this dailink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
+ },
/* Backend BT/FM DAI Links */
{
.name = LPASS_BE_INT_BT_SCO_RX,