Merge "usb: serial: csvt: Modify interface sub class value for PID 0x904c" into msm-3.0
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0a7fe5f..b46d7f1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -140,7 +140,7 @@
Enable ticket locks, which help preserve fairness among
contended locks and prevent livelock in multicore systems.
Say 'y' if system stability is important.
- default y if ARCH_MSM_SCORPIONMP
+ default y if ARCH_MSM_SCORPIONMP || ARCH_MSM_KRAITMP
depends on SMP
config RWSEM_GENERIC_SPINLOCK
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 613ad72..0b89d45 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -106,6 +106,8 @@
# CONFIG_MFD_SUPPORT is not set
CONFIG_ION=y
CONFIG_ION_MSM=y
+CONFIG_FB=y
+CONFIG_FB_VIRTUAL=y
# CONFIG_HID_SUPPORT is not set
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_CI13XXX_MSM=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 043b823..e4456dc 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -227,7 +227,7 @@
CONFIG_BLK_DEV_RAM=y
CONFIG_HAPTIC_ISA1200=y
CONFIG_PMIC8XXX_VIBRATOR=y
-CONFIG_TZCOM=y
+CONFIG_QSEECOM=y
CONFIG_SCSI=y
CONFIG_SCSI_TGT=y
CONFIG_BLK_DEV_SD=y
@@ -337,7 +337,7 @@
CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
CONFIG_FB_MSM_OVERLAY1_WRITEBACK=y
CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
-CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index f41b396..406992a 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -229,7 +229,7 @@
CONFIG_BLK_DEV_RAM=y
CONFIG_HAPTIC_ISA1200=y
CONFIG_PMIC8XXX_VIBRATOR=y
-CONFIG_TZCOM=y
+CONFIG_QSEECOM=y
CONFIG_SCSI=y
CONFIG_SCSI_TGT=y
CONFIG_BLK_DEV_SD=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index c325217..a2c8827 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -485,6 +485,14 @@
help
Support for the Qualcomm MSM8625 SURF.
+config MACH_MSM8625_EVB
+ depends on ARCH_MSM8625
+ depends on !MSM_STACKED_MEMORY
+ default y
+ bool "MSM8625 EVB"
+ help
+ Support for the Qualcomm MSM8625 Reference Design.
+
config MACH_MSM7X30_SURF
depends on ARCH_MSM7X30
depends on !MSM_STACKED_MEMORY
@@ -2090,6 +2098,7 @@
config MSM_RTB_SEPARATE_CPUS
bool "Separate entries for each cpu"
depends on MSM_RTB
+ depends on SMP
help
Under some circumstances, it may be beneficial to give dedicated space
for each cpu to log accesses. Selecting this option will log each cpu
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 2f55215..1f3945e 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -232,6 +232,7 @@
obj-$(CONFIG_ARCH_MSM8625) += devices-msm7x27a.o clock-pcom-lookup.o
obj-$(CONFIG_MACH_MSM8625_RUMI3) += board-msm7x27a.o
obj-$(CONFIG_MACH_MSM8625_SURF) += board-msm7x27a.o board-7627a-all.o
+obj-$(CONFIG_MACH_MSM8625_EVB) += board-qrd7627a.o board-7627a-all.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o memory_topology.o
obj-$(CONFIG_ARCH_MSM7X30) += clock-local.o clock-7x30.o acpuclock-7x30.o
obj-$(CONFIG_MACH_MSM7X25_SURF) += board-msm7x27.o devices-msm7x25.o
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index c4409ff..781d896 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -87,7 +87,6 @@
unsigned int ahbclk_div;
int vdd;
unsigned int axiclk_khz;
- unsigned long lpj; /* loops_per_jiffy */
/* Pointers in acpu_freq_tbl[] for max up/down steppings. */
struct clkctl_acpu_speed *down[ACPU_PLL_END];
struct clkctl_acpu_speed *up[ACPU_PLL_END];
@@ -115,7 +114,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 160000 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627 with CDMA capable modem */
@@ -129,7 +128,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 160000 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627 with GSM capable modem - PLL2 @ 800 */
@@ -143,7 +142,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 1, 133333, 2, 5, 160000 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
{ 1, 800000, ACPU_PLL_2, 2, 0, 200000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627 with CDMA capable modem - PLL2 @ 800 */
@@ -157,7 +156,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 1, 133333, 2, 5, 160000 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
{ 1, 800000, ACPU_PLL_2, 2, 0, 200000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627a PLL2 @ 1200MHz with GSM capable modem */
@@ -172,7 +171,7 @@
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627a PLL2 @ 1200MHz with CDMA capable modem */
@@ -187,7 +186,7 @@
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627aa PLL4 @ 1008MHz with GSM capable modem */
@@ -202,7 +201,7 @@
{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627aa PLL4 @ 1008MHz with CDMA capable modem */
@@ -217,7 +216,7 @@
{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7625a PLL2 @ 1200MHz with GSM capable modem */
@@ -231,7 +230,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 2, 50000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627a PLL2 @ 1200MHz with GSM capable modem */
@@ -246,7 +245,7 @@
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627a PLL2 @ 1200MHz with CDMA capable modem */
@@ -261,7 +260,7 @@
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627aa PLL4 @ 1008MHz with GSM capable modem */
@@ -276,7 +275,7 @@
{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7627aa PLL4 @ 1008MHz with CDMA capable modem */
@@ -291,7 +290,7 @@
{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
/* 7625a PLL2 @ 1200MHz with GSM capable modem */
@@ -305,7 +304,7 @@
{ 0, 400000, ACPU_PLL_2, 2, 2, 50000, 3, 4, 122880 },
{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
};
#define PLL_CONFIG(m0, m1, m2, m4) { \
@@ -578,8 +577,6 @@
acpuclk_set_div(cur_s);
drv_state.current_speed = cur_s;
- /* Re-adjust lpj for the new clock speed. */
- loops_per_jiffy = cur_s->lpj;
mb();
udelay(50);
}
@@ -763,18 +760,6 @@
return found_khz;
}
-/* Initalize the lpj field in the acpu_freq_tbl. */
-static void __init lpj_init(void)
-{
- int i;
- const struct clkctl_acpu_speed *base_clk = drv_state.current_speed;
- for (i = 0; acpu_freq_tbl[i].a11clk_khz; i++) {
- acpu_freq_tbl[i].lpj = cpufreq_scale(loops_per_jiffy,
- base_clk->a11clk_khz,
- acpu_freq_tbl[i].a11clk_khz);
- }
-}
-
static void __init precompute_stepping(void)
{
int i, step_idx;
@@ -867,7 +852,6 @@
acpuclk_7627_data.wait_for_irq_khz = find_wait_for_irq_khz();
precompute_stepping();
acpuclk_hw_init();
- lpj_init();
print_acpu_freq_tbl();
acpuclk_register(&acpuclk_7627_data);
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 99c3d78..8d35148 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -194,7 +194,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x200,
.aux_clk_sel = MSM_ACC0_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait0", 1150000 },
+ .vreg[VREG_CORE] = { "krait0", 1300000 },
.vreg[VREG_MEM] = { "krait0_mem", 1150000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8921_L24 },
@@ -209,7 +209,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x240,
.aux_clk_sel = MSM_ACC1_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait1", 1150000 },
+ .vreg[VREG_CORE] = { "krait1", 1300000 },
.vreg[VREG_MEM] = { "krait1_mem", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_L24 },
@@ -224,7 +224,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x280,
.aux_clk_sel = MSM_ACC2_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait2", 1150000 },
+ .vreg[VREG_CORE] = { "krait2", 1300000 },
.vreg[VREG_MEM] = { "krait2_mem", 1150000,
RPM_VREG_VOTER4,
RPM_VREG_ID_PM8921_L24 },
@@ -239,7 +239,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x2C0,
.aux_clk_sel = MSM_ACC3_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait3", 1150000 },
+ .vreg[VREG_CORE] = { "krait3", 1300000 },
.vreg[VREG_MEM] = { "krait3_mem", 1150000,
RPM_VREG_VOTER5,
RPM_VREG_ID_PM8921_L24 },
@@ -375,6 +375,7 @@
[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
[5] = BW_MBPS(3600), /* At least 450 MHz on bus. */
[6] = BW_MBPS(3936), /* At least 492 MHz on bus. */
+ [7] = BW_MBPS(4264), /* At least 533 MHz on bus. */
};
static struct msm_bus_scale_pdata bus_client_pdata = {
@@ -546,47 +547,48 @@
#define L2(x) (&l2_freq_tbl_8064[(x)])
static struct l2_level l2_freq_tbl_8064[] = {
[0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, 1050000, 1050000, 0 },
- [1] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 0 },
- [2] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 1 },
- [3] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 1 },
- [4] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 1 },
+ [1] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
+ [2] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 2 },
+ [3] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 2 },
+ [4] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 2 },
[5] = { { 594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
- [6] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 2 },
- [7] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 2 },
- [8] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 3 },
- [9] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 3 },
- [10] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 3 },
- [11] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 3 },
- [12] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 3 },
- [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 3 },
- [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 4 },
- [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 4 },
- [16] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 4 },
- [17] = { { 1242000, HFPLL, 1, 0, 0x2E }, 1150000, 1150000, 4 },
- [18] = { { 1296000, HFPLL, 1, 0, 0x30 }, 1150000, 1150000, 4 },
- [19] = { { 1350000, HFPLL, 1, 0, 0x32 }, 1150000, 1150000, 4 },
- [20] = { { 1404000, HFPLL, 1, 0, 0x34 }, 1150000, 1150000, 4 },
- [21] = { { 1458000, HFPLL, 1, 0, 0x36 }, 1150000, 1150000, 5 },
- [22] = { { 1512000, HFPLL, 1, 0, 0x38 }, 1150000, 1150000, 5 },
- [23] = { { 1566000, HFPLL, 1, 0, 0x3A }, 1150000, 1150000, 5 },
- [24] = { { 1620000, HFPLL, 1, 0, 0x3C }, 1150000, 1150000, 5 },
- [25] = { { 1674000, HFPLL, 1, 0, 0x3E }, 1150000, 1150000, 5 },
+ [6] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 4 },
+ [7] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 4 },
+ [8] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 4 },
+ [9] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 4 },
+ [10] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 4 },
+ [11] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 7 },
+ [12] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 7 },
+ [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 7 },
+ [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 7 },
+ [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 7 },
};
/* TODO: Update core voltages when data is available. */
static struct acpu_level acpu_freq_tbl_8064[] = {
- { 0, {STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 1050000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 1050000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(2), 1050000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(3), 1050000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(4), 1050000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 1050000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1050000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 1050000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(8), 1150000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(9), 1150000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1150000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1150000 },
+ { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 975000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 975000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 1000000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 1025000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 1075000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1100000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1125000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1175000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1200000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1225000 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1237500 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(15), 1237500 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(15), 1250000 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 5bef079..97f8722 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -556,8 +556,7 @@
if (!a2_pc_disabled) {
a2_pc_disabled = 1;
- schedule_delayed_work(&ul_timeout_work,
- msecs_to_jiffies(UL_TIMEOUT_DELAY));
+ ul_wakeup();
}
handle_bam_mux_cmd_open(rx_hdr);
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 486ebd3..f23bf2a 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -102,6 +102,13 @@
static struct msm_gpiomux_config apq8064_cam_common_configs[] = {
{
+ .gpio = 1,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cam_settings[2],
+ [GPIOMUX_SUSPENDED] = &cam_settings[0],
+ },
+ },
+ {
.gpio = 2,
.settings = {
[GPIOMUX_ACTIVE] = &cam_settings[12],
@@ -111,7 +118,7 @@
{
.gpio = 3,
.settings = {
- [GPIOMUX_ACTIVE] = &cam_settings[1],
+ [GPIOMUX_ACTIVE] = &cam_settings[2],
[GPIOMUX_SUSPENDED] = &cam_settings[0],
},
},
@@ -173,6 +180,16 @@
},
};
+
+#define VFE_CAMIF_TIMER1_GPIO 3
+#define VFE_CAMIF_TIMER2_GPIO 1
+
+static struct msm_camera_sensor_flash_src msm_flash_src = {
+ .flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
+ ._fsrc.ext_driver_src.led_en = VFE_CAMIF_TIMER1_GPIO,
+ ._fsrc.ext_driver_src.led_flash_en = VFE_CAMIF_TIMER2_GPIO,
+};
+
static struct msm_gpiomux_config apq8064_cam_2d_configs[] = {
};
@@ -419,7 +436,8 @@
};
static struct msm_camera_sensor_flash_data flash_imx074 = {
- .flash_type = MSM_CAMERA_FLASH_NONE,
+ .flash_type = MSM_CAMERA_FLASH_LED,
+ .flash_src = &msm_flash_src
};
static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
@@ -518,6 +536,9 @@
I2C_BOARD_INFO("ov2720", 0x6C),
.platform_data = &msm_camera_sensor_ov2720_data,
},
+ {
+ I2C_BOARD_INFO("sc628a", 0x6E),
+ },
};
struct msm_camera_board_info apq8064_camera_board_info = {
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index e9b497b..9fbb1c7 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -151,17 +151,17 @@
.pwrlevel = {
{
.gpu_freq = 400000000,
- .bus_freq = 4,
+ .bus_freq = 3,
.io_fraction = 0,
},
{
.gpu_freq = 320000000,
- .bus_freq = 3,
+ .bus_freq = 2,
.io_fraction = 33,
},
{
.gpu_freq = 1920000000,
- .bus_freq = 2,
+ .bus_freq = 1,
.io_fraction = 100,
},
{
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index bd5f703..05002a2 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -310,8 +310,8 @@
static struct pm8xxx_irq_platform_data
apq8064_pm8921_irq_pdata __devinitdata = {
.irq_base = PM8921_IRQ_BASE,
- .devirq = PM8921_USR_IRQ_N,
- .irq_trigger_flag = IRQF_TRIGGER_HIGH,
+ .devirq = MSM_GPIO_TO_INT(74),
+ .irq_trigger_flag = IRQF_TRIGGER_LOW,
.dev_id = 0,
};
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 247b230..5a1957b 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -469,15 +469,15 @@
/* SAW regulator constraints */
struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5 =
/* ID vreg_name min_uV max_uV */
- SAW_VREG_INIT(S5, "8921_s5", 950000, 1150000);
+ SAW_VREG_INIT(S5, "8921_s5", 950000, 1300000);
struct regulator_init_data msm8064_saw_regulator_pdata_8921_s6 =
- SAW_VREG_INIT(S6, "8921_s6", 950000, 1150000);
+ SAW_VREG_INIT(S6, "8921_s6", 950000, 1300000);
struct regulator_init_data msm8064_saw_regulator_pdata_8821_s0 =
/* ID vreg_name min_uV max_uV */
- SAW_VREG_INIT(8821_S0, "8821_s0", 950000, 1150000);
+ SAW_VREG_INIT(8821_S0, "8821_s0", 950000, 1300000);
struct regulator_init_data msm8064_saw_regulator_pdata_8821_s1 =
- SAW_VREG_INIT(8821_S1, "8821_s1", 950000, 1150000);
+ SAW_VREG_INIT(8821_S1, "8821_s1", 950000, 1300000);
/* PM8921 regulator constraints */
struct pm8xxx_regulator_platform_data
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 3848262..9d4f0aa 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -54,10 +54,12 @@
#include <linux/bootmem.h>
#include <asm/setup.h>
#include <mach/dma.h>
+#include <mach/msm_dsps.h>
#include <mach/msm_bus_board.h>
#include <mach/cpuidle.h>
#include <mach/mdm2.h>
#include <linux/msm_tsens.h>
+#include <mach/msm_xo.h>
#include "msm_watchdog.h"
#include "board-8064.h"
@@ -1846,6 +1848,18 @@
},
};
+/* Sensors DSPS platform data */
+#define DSPS_PIL_GENERIC_NAME "dsps"
+static void __init apq8064_init_dsps(void)
+{
+ struct msm_dsps_platform_data *pdata =
+ msm_dsps_device_8064.dev.platform_data;
+ pdata->pil_name = DSPS_PIL_GENERIC_NAME;
+ pdata->gpios = NULL;
+ pdata->gpios_num = 0;
+
+ platform_device_register(&msm_dsps_device_8064);
+}
static void __init apq8064_clock_init(void)
{
@@ -1939,6 +1953,8 @@
BUG_ON(msm_rpmrs_levels_init(&msm_rpmrs_data));
regulator_suppress_info_printing();
platform_device_register(&apq8064_device_rpm_regulator);
+ if (msm_xo_init())
+ pr_err("Failed to initialize XO votes\n");
apq8064_clock_init();
apq8064_init_gpiomux();
apq8064_i2c_init();
@@ -1967,6 +1983,7 @@
platform_device_register(&apq8064_slim_ctrl);
slim_register_board_info(apq8064_slim_devices,
ARRAY_SIZE(apq8064_slim_devices));
+ apq8064_init_dsps();
msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
acpuclk_init(&acpuclk_8064_soc_data);
msm_spm_l2_init(msm_spm_l2_data);
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index e89bed4..26211bf 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -52,7 +52,7 @@
.name = "sdc_vdd",
.high_vol_level = 2950000,
.low_vol_level = 2950000,
- .hpm_uA = 600000, /* 600mA */
+ .hpm_uA = 800000, /* 800mA */
}
};
@@ -208,11 +208,11 @@
};
static unsigned int sdc1_sup_clk_rates[] = {
- 400000, 24000000, 48000000
+ 400000, 24000000, 48000000,
};
static unsigned int sdc3_sup_clk_rates[] = {
- 400000, 24000000, 48000000, 96000000
+ 400000, 24000000, 48000000, 96000000, 192000000,
};
#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
@@ -264,7 +264,7 @@
.xpc_cap = 1,
.uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
- MMC_CAP_MAX_CURRENT_600),
+ MMC_CAP_UHS_SDR104 | MMC_CAP_MAX_CURRENT_800),
};
#endif
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index d98ae56..9c1a439 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -221,7 +221,6 @@
};
VREG_CONSUMERS(USB_OTG) = {
REGULATOR_SUPPLY("8921_usb_otg", NULL),
- REGULATOR_SUPPLY("vbus_otg", "msm_otg"),
};
VREG_CONSUMERS(HDMI_MVS) = {
REGULATOR_SUPPLY("8921_hdmi_mvs", NULL),
@@ -245,12 +244,12 @@
};
VREG_CONSUMERS(EXT_OTG_SW) = {
REGULATOR_SUPPLY("ext_otg_sw", NULL),
+ REGULATOR_SUPPLY("vbus_otg", "msm_otg"),
};
#define PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, _modes, _ops, \
_apply_uV, _pull_down, _always_on, _supply_regulator, \
- _system_uA, _enable_time, _reg_id, _ocp_enable, \
- _ocp_enable_time) \
+ _system_uA, _enable_time, _reg_id) \
{ \
.init_data = { \
.constraints = { \
@@ -272,8 +271,6 @@
.pull_down_enable = _pull_down, \
.system_uA = _system_uA, \
.enable_time = _enable_time, \
- .ocp_enable = _ocp_enable, \
- .ocp_enable_time = _ocp_enable_time, \
}
#define PM8XXX_LDO(_id, _name, _always_on, _pull_down, _min_uV, _max_uV, \
@@ -282,7 +279,7 @@
| REGULATOR_MODE_IDLE, REGULATOR_CHANGE_VOLTAGE | \
REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
REGULATOR_CHANGE_DRMS, 0, _pull_down, _always_on, \
- _supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
+ _supply_regulator, _system_uA, _enable_time, _reg_id)
#define PM8XXX_NLDO1200(_id, _name, _always_on, _pull_down, _min_uV, \
_max_uV, _enable_time, _supply_regulator, _system_uA, _reg_id) \
@@ -290,7 +287,7 @@
| REGULATOR_MODE_IDLE, REGULATOR_CHANGE_VOLTAGE | \
REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
REGULATOR_CHANGE_DRMS, 0, _pull_down, _always_on, \
- _supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
+ _supply_regulator, _system_uA, _enable_time, _reg_id)
#define PM8XXX_SMPS(_id, _name, _always_on, _pull_down, _min_uV, _max_uV, \
_enable_time, _supply_regulator, _system_uA, _reg_id) \
@@ -298,32 +295,32 @@
| REGULATOR_MODE_IDLE, REGULATOR_CHANGE_VOLTAGE | \
REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
REGULATOR_CHANGE_DRMS, 0, _pull_down, _always_on, \
- _supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
+ _supply_regulator, _system_uA, _enable_time, _reg_id)
#define PM8XXX_FTSMPS(_id, _name, _always_on, _pull_down, _min_uV, _max_uV, \
_enable_time, _supply_regulator, _system_uA, _reg_id) \
PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, REGULATOR_MODE_NORMAL, \
REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS \
| REGULATOR_CHANGE_MODE, 0, _pull_down, _always_on, \
- _supply_regulator, _system_uA, _enable_time, _reg_id, 0, 0)
+ _supply_regulator, _system_uA, _enable_time, _reg_id)
#define PM8XXX_VS(_id, _name, _always_on, _pull_down, _enable_time, \
- _ocp_enable, _ocp_enable_time, _supply_regulator, _reg_id) \
+ _supply_regulator, _reg_id) \
PM8XXX_VREG_INIT(_id, _name, 0, 0, 0, REGULATOR_CHANGE_STATUS, 0, \
_pull_down, _always_on, _supply_regulator, 0, _enable_time, \
- _reg_id, _ocp_enable, _ocp_enable_time)
+ _reg_id)
#define PM8XXX_VS300(_id, _name, _always_on, _pull_down, _enable_time, \
- _ocp_enable, _ocp_enable_time, _supply_regulator, _reg_id) \
+ _supply_regulator, _reg_id) \
PM8XXX_VREG_INIT(_id, _name, 0, 0, 0, REGULATOR_CHANGE_STATUS, 0, \
_pull_down, _always_on, _supply_regulator, 0, _enable_time, \
- _reg_id, _ocp_enable, _ocp_enable_time)
+ _reg_id)
#define PM8XXX_NCP(_id, _name, _always_on, _min_uV, _max_uV, _enable_time, \
_supply_regulator, _reg_id) \
PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, 0, \
REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, 0, 0, \
- _always_on, _supply_regulator, 0, _enable_time, _reg_id, 0, 0)
+ _always_on, _supply_regulator, 0, _enable_time, _reg_id)
/* Pin control initialization */
#define PM8XXX_PC(_id, _name, _always_on, _pin_fn, _pin_ctrl, \
@@ -472,7 +469,7 @@
GPIO_VREG(EXT_3P3V, "ext_3p3v", "ext_3p3v_en",
PM8921_GPIO_PM_TO_SYS(17), NULL),
GPIO_VREG(EXT_OTG_SW, "ext_otg_sw", "ext_otg_sw_en",
- PM8921_GPIO_PM_TO_SYS(42), "ext_5v"),
+ PM8921_GPIO_PM_TO_SYS(42), "8921_usb_otg"),
};
/* SAW regulator constraints */
@@ -498,13 +495,9 @@
PM8XXX_LDO(L29, "8921_l29", 0, 1, 2050000, 2100000, 200, "8921_s8",
0, 4),
- /*
- * ID name always_on pd en_t ocp ocp_t supply
- * reg_ID
- */
- PM8XXX_VS300(USB_OTG, "8921_usb_otg", 0, 0, 0, 1, 500, "ext_otg_sw",
- 5),
- PM8XXX_VS300(HDMI_MVS, "8921_hdmi_mvs", 0, 1, 0, 0, 0, "ext_5v", 6),
+ /* ID name always_on pd en_t supply reg_ID */
+ PM8XXX_VS300(USB_OTG, "8921_usb_otg", 0, 1, 0, "ext_5v", 5),
+ PM8XXX_VS300(HDMI_MVS, "8921_hdmi_mvs", 0, 1, 0, "ext_5v", 6),
};
static struct rpm_regulator_init_data
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 3a48b25..9a8b843 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2081,8 +2081,8 @@
&msm_device_saw_core0,
&msm_device_saw_core1,
&msm8960_device_ext_5v_vreg,
- &msm8960_device_ext_otg_sw_vreg,
&msm8960_device_ssbi_pmic,
+ &msm8960_device_ext_otg_sw_vreg,
&msm8960_device_qup_spi_gsbi1,
&msm8960_device_qup_i2c_gsbi3,
&msm8960_device_qup_i2c_gsbi4,
@@ -2120,6 +2120,14 @@
&msm_device_bam_dmux,
&msm_fm_platform_init,
+#if defined(CONFIG_TSIF) || defined(CONFIG_TSIF_MODULE)
+#ifdef CONFIG_MSM_USE_TSIF1
+ &msm_device_tsif[1],
+#else
+ &msm_device_tsif[0],
+#endif
+#endif
+
#ifdef CONFIG_HW_RANDOM_MSM
&msm_device_rng,
#endif
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index 9f79abb..a8ab81a 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -100,7 +100,7 @@
{
if (machine_is_msm7627a_qrd1())
gpio_bt_sys_rest_en = 114;
- if (machine_is_msm7627a_evb())
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
gpio_bt_sys_rest_en = 16;
}
@@ -109,14 +109,36 @@
int rc = 0;
struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
+ pr_debug("%s: Setting SYS_RST_PIN(%d) to %d\n",
+ __func__, gpio_bt_sys_rest_en, on);
if (on) {
- rc = gpio_direction_output(gpio_bt_sys_rest_en, 1);
+
+ if (machine_is_msm7627a_evb()) {
+ rc = gpio_tlmm_config(GPIO_CFG(gpio_bt_sys_rest_en, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA),
+ GPIO_CFG_ENABLE);
+
+ gpio_set_value(gpio_bt_sys_rest_en, 1);
+ } else {
+ rc = gpio_direction_output(gpio_bt_sys_rest_en, 1);
+ }
msleep(100);
} else {
+
if (!marimba_get_fm_status(&config) &&
!marimba_get_bt_status(&config)) {
- gpio_set_value_cansleep(gpio_bt_sys_rest_en, 0);
- rc = gpio_direction_input(gpio_bt_sys_rest_en);
+ if (machine_is_msm7627a_evb()) {
+ gpio_set_value(gpio_bt_sys_rest_en, 0);
+ rc = gpio_tlmm_config(GPIO_CFG(
+ gpio_bt_sys_rest_en, 0,
+ GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA),
+ GPIO_CFG_ENABLE);
+ } else {
+ gpio_set_value_cansleep(gpio_bt_sys_rest_en, 0);
+ rc = gpio_direction_input(gpio_bt_sys_rest_en);
+ }
msleep(100);
}
}
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 06fbb7b..7b075cd 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -1041,7 +1041,7 @@
pr_debug("msm7627a_camera_init Entered\n");
/* LCD and camera power (VREG & LDO) init */
- if (machine_is_msm7627a_evb())
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
lcd_camera_power_init();
#ifndef CONFIG_MSM_CAMERA_V4L2
@@ -1049,7 +1049,7 @@
qrd1_camera_gpio_cfg();
platform_add_devices(camera_devices_qrd,
ARRAY_SIZE(camera_devices_qrd));
- } else if (machine_is_msm7627a_evb()) {
+ } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
evb_camera_gpio_cfg();
platform_add_devices(camera_devices_evb,
ARRAY_SIZE(camera_devices_evb));
@@ -1059,7 +1059,8 @@
platform_add_devices(camera_devices_msm,
ARRAY_SIZE(camera_devices_msm));
#endif
- if (!machine_is_msm7627a_qrd1() || !machine_is_msm7627a_evb())
+ if (!machine_is_msm7627a_qrd1() || !machine_is_msm7627a_evb()
+ || !machine_is_msm8625_evb())
register_i2c_devices();
rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_camera), regs_camera);
@@ -1083,7 +1084,7 @@
i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
i2c_camera_devices_qrd,
ARRAY_SIZE(i2c_camera_devices_qrd));
- } else if (machine_is_msm7627a_evb()) {
+ } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
pr_debug("machine_is_msm7627a_evb i2c_register_board_info\n");
i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
i2c_camera_devices_evb,
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 8093295..45bfaed 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -227,7 +227,7 @@
} else if (machine_is_msm7627a_qrd1()) {
if (!strncmp(name, "mipi_video_truly_wvga", 21))
ret = 0;
- } else if (machine_is_msm7627a_evb()) {
+ } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
ret = 0;
}
@@ -558,7 +558,7 @@
if (machine_is_msm7627a_qrd1())
rc = msm_fb_dsi_client_qrd1_reset();
- else if (machine_is_msm7627a_evb())
+ else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
rc = msm_fb_dsi_client_qrd3_reset();
else
rc = msm_fb_dsi_client_msm_reset();
@@ -823,7 +823,7 @@
if (machine_is_msm7627a_qrd1())
rc = mipi_dsi_panel_qrd1_power(on);
- else if (machine_is_msm7627a_evb())
+ else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
rc = mipi_dsi_panel_qrd3_power(on);
else
rc = mipi_dsi_panel_msm_power(on);
@@ -846,7 +846,7 @@
if (machine_is_msm7627a_qrd1())
platform_add_devices(qrd_fb_devices,
ARRAY_SIZE(qrd_fb_devices));
- else if (machine_is_msm7627a_evb())
+ else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
platform_add_devices(evb_fb_devices,
ARRAY_SIZE(evb_fb_devices));
else if (machine_is_msm7627a_qrd3())
diff --git a/arch/arm/mach-msm/board-msm7627a-storage.c b/arch/arm/mach-msm/board-msm7627a-storage.c
index 3bb9c8b..e4ee52e 100644
--- a/arch/arm/mach-msm/board-msm7627a-storage.c
+++ b/arch/arm/mach-msm/board-msm7627a-storage.c
@@ -150,7 +150,8 @@
static int gpio_sdc1_hw_det = 85;
static void gpio_sdc1_config(void)
{
- if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb())
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+ || machine_is_msm8625_evb())
gpio_sdc1_hw_det = 42;
}
@@ -251,7 +252,8 @@
status = gpio_direction_input(gpio_sdc1_hw_det);
if (!status) {
if (machine_is_msm7627a_qrd1() ||
- machine_is_msm7627a_evb())
+ machine_is_msm7627a_evb() ||
+ machine_is_msm8625_evb())
status = !gpio_get_value(gpio_sdc1_hw_det);
else
status = gpio_get_value(gpio_sdc1_hw_det);
diff --git a/arch/arm/mach-msm/board-msm7627a-wlan.c b/arch/arm/mach-msm/board-msm7627a-wlan.c
index 6df7626..53d3c56 100644
--- a/arch/arm/mach-msm/board-msm7627a-wlan.c
+++ b/arch/arm/mach-msm/board-msm7627a-wlan.c
@@ -48,7 +48,8 @@
int gpio_wlan_sys_rest_en = 134;
static void gpio_wlan_config(void)
{
- if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb())
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+ || machine_is_msm8625_evb())
gpio_wlan_sys_rest_en = 124;
}
@@ -229,7 +230,8 @@
* gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
* EVB1.0 and QRD8625,so the below step is required for those devices.
*/
- if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+ || machine_is_msm8625_evb()) {
rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
@@ -302,7 +304,8 @@
* gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
* EVB1.0 and QRD8625,so the below step is required for those devices.
*/
- if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+ || machine_is_msm8625_evb()) {
rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
diff --git a/arch/arm/mach-msm/board-msm7627a.h b/arch/arm/mach-msm/board-msm7627a.h
index 8737de8..bde9b61 100644
--- a/arch/arm/mach-msm/board-msm7627a.h
+++ b/arch/arm/mach-msm/board-msm7627a.h
@@ -66,6 +66,7 @@
QRD_GPIO_CAM_GP_CAMIF_RESET,
};
+#define ADSP_RPC_PROG 0x3000000a
#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
#define FPGA_MSM_CNTRL_REG2 0x90008010
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 628f281..3ad4773 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -14,6 +14,7 @@
#include <linux/gpio_event.h>
#include <linux/memblock.h>
#include <asm/mach-types.h>
+#include <linux/memblock.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
#include <mach/board.h>
@@ -60,7 +61,6 @@
#define PMEM_KERNEL_EBI1_SIZE 0x3A000
#define MSM_PMEM_AUDIO_SIZE 0x5B000
-#define ADSP_RPC_PROG 0x3000000a
#if defined(CONFIG_GPIO_SX150X)
enum {
@@ -384,6 +384,72 @@
.p_addr = 0,
};
+/* 8625 PM platform data */
+static struct msm_pm_platform_data msm8625_pm_data[MSM_PM_SLEEP_MODE_NR * 2] = {
+ /* CORE0 entries */
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
+ .idle_supported = 1,
+ .suspend_supported = 1,
+ .idle_enabled = 0,
+ .suspend_enabled = 0,
+ .latency = 16000,
+ .residency = 20000,
+ },
+
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)] = {
+ .idle_supported = 1,
+ .suspend_supported = 1,
+ .idle_enabled = 0,
+ .suspend_enabled = 0,
+ .latency = 12000,
+ .residency = 20000,
+ },
+
+ /* picked latency & redisdency values from 7x30 */
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
+ .idle_supported = 1,
+ .suspend_supported = 1,
+ .idle_enabled = 0,
+ .suspend_enabled = 0,
+ .latency = 500,
+ .residency = 6000,
+ },
+
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
+ .idle_supported = 1,
+ .suspend_supported = 1,
+ .idle_enabled = 1,
+ .suspend_enabled = 1,
+ .latency = 2,
+ .residency = 10,
+ },
+
+ /* picked latency & redisdency values from 7x30 */
+ [MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
+ .idle_supported = 1,
+ .suspend_supported = 1,
+ .idle_enabled = 0,
+ .suspend_enabled = 0,
+ .latency = 500,
+ .residency = 6000,
+ },
+
+ [MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
+ .idle_supported = 1,
+ .suspend_supported = 1,
+ .idle_enabled = 1,
+ .suspend_enabled = 1,
+ .latency = 2,
+ .residency = 10,
+ },
+
+};
+
+static struct msm_pm_boot_platform_data msm_pm_8625_boot_pdata __initdata = {
+ .mode = MSM_PM_BOOT_CONFIG_REMAP_BOOT_ADDR,
+ .v_addr = MSM_CFG_CTL_BASE,
+};
+
static struct android_pmem_platform_data android_pmem_adsp_pdata = {
.name = "pmem_adsp",
.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
@@ -880,8 +946,9 @@
static void __init msm8625_reserve(void)
{
- memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
msm7x27a_reserve();
+ memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
+ msm_pm_8625_boot_pdata.p_addr = memblock_alloc(SZ_8, SZ_64K);
}
static void __init msm7x27a_device_i2c_init(void)
@@ -1186,6 +1253,11 @@
msm8625_device_i2c_init();
platform_add_devices(msm8625_rumi3_devices,
ARRAY_SIZE(msm8625_rumi3_devices));
+
+ msm_pm_set_platform_data(msm8625_pm_data,
+ ARRAY_SIZE(msm8625_pm_data));
+ BUG_ON(msm_pm_boot_init(&msm_pm_8625_boot_pdata));
+ msm8x25_spm_device_init();
}
#define LED_GPIO_PDM 96
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 260c880..9f7104f 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -5236,7 +5236,8 @@
&msm_batt_device,
&msm_adc_device,
&msm_ebi0_thermal,
- &msm_ebi1_thermal
+ &msm_ebi1_thermal,
+ &msm_adsp_device
};
static struct msm_gpio msm_i2c_gpios_hw[] = {
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index aef9275..61443c3 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -28,9 +28,11 @@
#include <linux/input/rmi_i2c.h>
#include <linux/i2c/atmel_mxt_ts.h>
#include <linux/regulator/consumer.h>
+#include <linux/memblock.h>
#include <asm/mach/mmc.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/hardware/gic.h>
#include <mach/board.h>
#include <mach/msm_iomap.h>
#include <mach/msm_hsusb.h>
@@ -659,7 +661,20 @@
.dev.platform_data = &msm_psy_batt_data,
};
-static struct platform_device *qrd_common_devices[] __initdata = {
+static struct platform_device *common_devices[] __initdata = {
+ &android_usb_device,
+ &android_pmem_device,
+ &android_pmem_adsp_device,
+ &android_pmem_audio_device,
+ &msm_batt_device,
+ &msm_device_adspdec,
+ &msm_device_snd,
+ &asoc_msm_pcm,
+ &asoc_msm_dai0,
+ &asoc_msm_dai1,
+};
+
+static struct platform_device *qrd7627a_devices[] __initdata = {
&msm_device_dmov,
&msm_device_smd,
&msm_device_uart1,
@@ -668,23 +683,23 @@
&msm_gsbi1_qup_i2c_device,
&msm_device_otg,
&msm_device_gadget_peripheral,
- &android_usb_device,
- &android_pmem_device,
- &android_pmem_adsp_device,
- &android_pmem_audio_device,
- &msm_device_snd,
- &msm_device_adspdec,
- &msm_batt_device,
&msm_kgsl_3d0,
- &asoc_msm_pcm,
- &asoc_msm_dai0,
- &asoc_msm_dai1,
};
static struct platform_device *qrd3_devices[] __initdata = {
&msm_device_nand,
};
+static struct platform_device *msm8625_evb_devices[] __initdata = {
+ &msm8625_device_dmov,
+ &msm8625_device_smd,
+ &msm8625_gsbi0_qup_i2c_device,
+ &msm8625_gsbi1_qup_i2c_device,
+ &msm8625_device_uart1,
+ &msm8625_device_otg,
+ &msm8625_device_gadget_peripheral,
+};
+
static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE;
static int __init pmem_kernel_ebi1_size_setup(char *p)
{
@@ -759,12 +774,49 @@
msm_reserve();
}
-static void __init msm_device_i2c_init(void)
+static void __init msm8625_reserve(void)
+{
+ memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
+ msm7627a_reserve();
+}
+
+static void msmqrd_adsp_add_pdev(void)
+{
+ int rc = 0;
+ struct rpc_board_dev *rpc_adsp_pdev;
+
+ rpc_adsp_pdev = kzalloc(sizeof(struct rpc_board_dev), GFP_KERNEL);
+ if (rpc_adsp_pdev == NULL) {
+ pr_err("%s: Memory Allocation failure\n", __func__);
+ return;
+ }
+ rpc_adsp_pdev->prog = ADSP_RPC_PROG;
+
+ if (cpu_is_msm8625())
+ rpc_adsp_pdev->pdev = msm8625_device_adsp;
+ else
+ rpc_adsp_pdev->pdev = msm_adsp_device;
+ rc = msm_rpc_add_board_dev(rpc_adsp_pdev, 1);
+ if (rc < 0) {
+ pr_err("%s: return val: %d\n", __func__, rc);
+ kfree(rpc_adsp_pdev);
+ }
+}
+
+static void __init msm7627a_device_i2c_init(void)
{
msm_gsbi0_qup_i2c_device.dev.platform_data = &msm_gsbi0_qup_i2c_pdata;
msm_gsbi1_qup_i2c_device.dev.platform_data = &msm_gsbi1_qup_i2c_pdata;
}
+static void __init msm8625_device_i2c_init(void)
+{
+ msm8625_gsbi0_qup_i2c_device.dev.platform_data
+ = &msm_gsbi0_qup_i2c_pdata;
+ msm8625_gsbi1_qup_i2c_device.dev.platform_data
+ = &msm_gsbi1_qup_i2c_pdata;
+}
+
static struct msm_handset_platform_data hs_platform_data = {
.hs_name = "7k_handset",
.pwr_key_delay_ms = 500, /* 0 will disable end key */
@@ -955,7 +1007,7 @@
i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
synaptic_i2c_clearpad3k,
ARRAY_SIZE(synaptic_i2c_clearpad3k));
- } else if (machine_is_msm7627a_evb()) {
+ } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
rc = gpio_tlmm_config(GPIO_CFG(MXT_TS_IRQ_GPIO, 0,
GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
GPIO_CFG_8MA), GPIO_CFG_ENABLE);
@@ -986,11 +1038,11 @@
#endif
/* keypad */
- if (machine_is_msm7627a_evb())
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
platform_device_register(&kp_pdev_8625);
/* leds */
- if (machine_is_msm7627a_evb()) {
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
rc = gpio_tlmm_config(GPIO_CFG(LED_RED_GPIO_8625, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
GPIO_CFG_16MA), GPIO_CFG_ENABLE);
@@ -1019,32 +1071,63 @@
static void add_platform_devices(void)
{
- platform_add_devices(qrd_common_devices,
- ARRAY_SIZE(qrd_common_devices));
-
- if (machine_is_msm7627a_qrd3())
- platform_add_devices(qrd3_devices,
- ARRAY_SIZE(qrd3_devices));
+ if (machine_is_msm8625_evb())
+ platform_add_devices(msm8625_evb_devices,
+ ARRAY_SIZE(msm8625_evb_devices));
+ else {
+ platform_add_devices(qrd7627a_devices,
+ ARRAY_SIZE(qrd7627a_devices));
+ if (machine_is_msm7627a_qrd3())
+ platform_add_devices(qrd3_devices,
+ ARRAY_SIZE(qrd3_devices));
+ }
+ platform_add_devices(common_devices,
+ ARRAY_SIZE(common_devices));
}
#define UART1DM_RX_GPIO 45
+static void __init qrd7627a_uart1dm_config(void)
+{
+ msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(UART1DM_RX_GPIO);
+ if (cpu_is_msm8625())
+ msm8625_device_uart_dm1.dev.platform_data =
+ &msm_uart_dm1_pdata;
+ else
+ msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata;
+}
+
+static void __init qrd7627a_otg_gadget(void)
+{
+ msm_otg_pdata.swfi_latency = msm7627a_pm_data
+ [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
+
+ if (cpu_is_msm8625()) {
+ msm8625_device_otg.dev.platform_data = &msm_otg_pdata;
+ msm8625_device_gadget_peripheral.dev.platform_data =
+ &msm_gadget_pdata;
+
+ } else {
+ msm_device_otg.dev.platform_data = &msm_otg_pdata;
+ msm_device_gadget_peripheral.dev.platform_data =
+ &msm_gadget_pdata;
+ }
+}
+
static void __init msm_qrd_init(void)
{
msm7x2x_misc_init();
msm7627a_init_regulators();
- msm_device_i2c_init();
-#ifdef CONFIG_SERIAL_MSM_HS
- msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(UART1DM_RX_GPIO);
- msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata;
-#endif
+ msmqrd_adsp_add_pdev();
-#ifdef CONFIG_USB_MSM_OTG_72K
- msm_otg_pdata.swfi_latency = msm7627a_pm_data
- [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
- msm_device_otg.dev.platform_data = &msm_otg_pdata;
-#endif
- msm_device_gadget_peripheral.dev.platform_data =
- &msm_gadget_pdata;
+ if (cpu_is_msm8625())
+ msm8625_device_i2c_init();
+ else
+ msm7627a_device_i2c_init();
+
+ /* uart1dm*/
+ qrd7627a_uart1dm_config();
+ /*OTG gadget*/
+ qrd7627a_otg_gadget();
add_platform_devices();
@@ -1055,9 +1138,11 @@
#ifdef CONFIG_USB_EHCI_MSM_72K
msm7627a_init_host();
#endif
- msm_pm_set_platform_data(msm7627a_pm_data,
+ if (!machine_is_msm8625_evb()) {
+ msm_pm_set_platform_data(msm7627a_pm_data,
ARRAY_SIZE(msm7627a_pm_data));
- BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+ BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+ }
msm_fb_add_devices();
@@ -1066,7 +1151,6 @@
#endif
msm7627a_camera_init();
-
msm7627a_add_io_devices();
}
@@ -1105,3 +1189,13 @@
.init_early = qrd7627a_init_early,
.handle_irq = vic_handle_irq,
MACHINE_END
+MACHINE_START(MSM8625_EVB, "QRD MSM8625 EVB")
+ .boot_params = PHYS_OFFSET + 0x100,
+ .map_io = msm8625_map_io,
+ .reserve = msm8625_reserve,
+ .init_irq = msm8625_init_irq,
+ .init_machine = msm_qrd_init,
+ .timer = &msm_timer,
+ .init_early = qrd7627a_init_early,
+ .handle_irq = gic_handle_irq,
+MACHINE_END
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 5996388..0a3632e 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5045,7 +5045,7 @@
CLK_LOOKUP("tv_clk", mdp_tv_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("hdmi_clk", hdmi_tv_clk.c, ""),
CLK_LOOKUP("core_clk", hdmi_app_clk.c, ""),
- CLK_LOOKUP("vpe_clk", vpe_clk.c, ""),
+ CLK_LOOKUP("vpe_clk", vpe_clk.c, "msm_vpe.0"),
CLK_LOOKUP("core_clk", vpe_clk.c, "footswitch-8x60.9"),
CLK_LOOKUP("vfe_clk", vfe_clk.c, "msm_vfe.0"),
CLK_LOOKUP("core_clk", vfe_clk.c, "footswitch-8x60.8"),
@@ -5082,7 +5082,7 @@
CLK_LOOKUP("iface_clk", vcodec_p_clk.c, "footswitch-8x60.7"),
CLK_LOOKUP("vfe_pclk", vfe_p_clk.c, "msm_vfe.0"),
CLK_LOOKUP("iface_clk", vfe_p_clk.c, "footswitch-8x60.8"),
- CLK_LOOKUP("vpe_pclk", vpe_p_clk.c, ""),
+ CLK_LOOKUP("vpe_pclk", vpe_p_clk.c, "msm_vpe.0"),
CLK_LOOKUP("iface_clk", vpe_p_clk.c, "footswitch-8x60.9"),
CLK_LOOKUP("bit_clk", mi2s_bit_clk.c, "msm-dai-q6.6"),
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index ca85a0a..630c128 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -23,11 +23,13 @@
#include <mach/usbdiag.h>
#include <mach/msm_sps.h>
#include <mach/dma.h>
+#include <mach/msm_dsps.h>
#include <sound/msm-dai-q6.h>
#include <sound/apr_audio.h>
#include <mach/msm_bus_board.h>
#include <mach/rpm.h>
#include <mach/mdm2.h>
+#include <mach/msm_smd.h>
#include <linux/ion.h>
#include "clock.h"
#include "devices.h"
@@ -1217,9 +1219,157 @@
.dev.platform_data = &msm_sps_pdata,
};
+static struct resource smd_resource[] = {
+ {
+ .name = "a9_m2a_0",
+ .start = INT_A9_M2A_0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "a9_m2a_5",
+ .start = INT_A9_M2A_5,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "adsp_a11",
+ .start = INT_ADSP_A11,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "adsp_a11_smsm",
+ .start = INT_ADSP_A11_SMSM,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "dsps_a11",
+ .start = INT_DSPS_A11,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "dsps_a11_smsm",
+ .start = INT_DSPS_A11_SMSM,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "wcnss_a11",
+ .start = INT_WCNSS_A11,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "wcnss_a11_smsm",
+ .start = INT_WCNSS_A11_SMSM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smd_subsystem_config smd_config_list[] = {
+ {
+ .irq_config_id = SMD_MODEM,
+ .subsys_name = "gss",
+ .edge = SMD_APPS_MODEM,
+
+ .smd_int.irq_name = "a9_m2a_0",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+ .smd_int.out_bit_pos = 1 << 3,
+ .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smd_int.out_offset = 0x8,
+
+ .smsm_int.irq_name = "a9_m2a_5",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smd_smsm",
+ .smsm_int.dev_id = 0,
+ .smsm_int.out_bit_pos = 1 << 4,
+ .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smsm_int.out_offset = 0x8,
+ },
+ {
+ .irq_config_id = SMD_Q6,
+ .subsys_name = "q6",
+ .edge = SMD_APPS_QDSP,
+
+ .smd_int.irq_name = "adsp_a11",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+ .smd_int.out_bit_pos = 1 << 15,
+ .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smd_int.out_offset = 0x8,
+
+ .smsm_int.irq_name = "adsp_a11_smsm",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smd_smsm",
+ .smsm_int.dev_id = 0,
+ .smsm_int.out_bit_pos = 1 << 14,
+ .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smsm_int.out_offset = 0x8,
+ },
+ {
+ .irq_config_id = SMD_DSPS,
+ .subsys_name = "dsps",
+ .edge = SMD_APPS_DSPS,
+
+ .smd_int.irq_name = "dsps_a11",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+ .smd_int.out_bit_pos = 1,
+ .smd_int.out_base = (void __iomem *)MSM_SIC_NON_SECURE_BASE,
+ .smd_int.out_offset = 0x4080,
+
+ .smsm_int.irq_name = "dsps_a11_smsm",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smd_smsm",
+ .smsm_int.dev_id = 0,
+ .smsm_int.out_bit_pos = 1,
+ .smsm_int.out_base = (void __iomem *)MSM_SIC_NON_SECURE_BASE,
+ .smsm_int.out_offset = 0x4094,
+ },
+ {
+ .irq_config_id = SMD_WCNSS,
+ .subsys_name = "wcnss",
+ .edge = SMD_APPS_WCNSS,
+
+ .smd_int.irq_name = "wcnss_a11",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+ .smd_int.out_bit_pos = 1 << 25,
+ .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smd_int.out_offset = 0x8,
+
+ .smsm_int.irq_name = "wcnss_a11_smsm",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smd_smsm",
+ .smsm_int.dev_id = 0,
+ .smsm_int.out_bit_pos = 1 << 23,
+ .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smsm_int.out_offset = 0x8,
+ },
+};
+
+static struct smd_platform smd_platform_data = {
+ .num_ss_configs = ARRAY_SIZE(smd_config_list),
+ .smd_ss_configs = smd_config_list,
+};
+
struct platform_device msm_device_smd_apq8064 = {
.name = "msm_smd",
.id = -1,
+ .resource = smd_resource,
+ .num_resources = ARRAY_SIZE(smd_resource),
+ .dev = {
+ .platform_data = &smd_platform_data,
+ },
};
#ifdef CONFIG_HW_RANDOM_MSM
@@ -1752,6 +1902,53 @@
},
};
+/* Sensors DSPS platform data */
+
+#define PPSS_REG_PHYS_BASE 0x12080000
+
+static struct dsps_clk_info dsps_clks[] = {};
+static struct dsps_regulator_info dsps_regs[] = {};
+
+/*
+ * Note: GPIOs field is intialized in run-time at the function
+ * apq8064_init_dsps().
+ */
+
+struct msm_dsps_platform_data msm_dsps_pdata_8064 = {
+ .clks = dsps_clks,
+ .clks_num = ARRAY_SIZE(dsps_clks),
+ .gpios = NULL,
+ .gpios_num = 0,
+ .regs = dsps_regs,
+ .regs_num = ARRAY_SIZE(dsps_regs),
+ .dsps_pwr_ctl_en = 1,
+ .signature = DSPS_SIGNATURE,
+};
+
+static struct resource msm_dsps_resources[] = {
+ {
+ .start = PPSS_REG_PHYS_BASE,
+ .end = PPSS_REG_PHYS_BASE + SZ_8K - 1,
+ .name = "ppss_reg",
+ .flags = IORESOURCE_MEM,
+ },
+
+ {
+ .start = PPSS_WDOG_TIMER_IRQ,
+ .end = PPSS_WDOG_TIMER_IRQ,
+ .name = "ppss_wdog",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_dsps_device_8064 = {
+ .name = "msm_dsps",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(msm_dsps_resources),
+ .resource = msm_dsps_resources,
+ .dev.platform_data = &msm_dsps_pdata_8064,
+};
+
#ifdef CONFIG_MSM_MPM
static uint16_t msm_mpm_irqs_m2a[MSM_MPM_NR_MPM_IRQS] __initdata = {
[1] = MSM_GPIO_TO_INT(26),
@@ -1891,4 +2088,3 @@
.num_resources = ARRAY_SIZE(mdm_resources),
.resource = mdm_resources,
};
-
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 19a8db7..718cfb1 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -30,8 +30,10 @@
#include <mach/rpm.h>
#include <mach/msm_bus_board.h>
#include <mach/msm_memtypes.h>
+#include <mach/msm_smd.h>
#include <sound/msm-dai-q6.h>
#include <sound/apr_audio.h>
+#include <mach/msm_tsif.h>
#include "clock.h"
#include "devices.h"
#include "devices-msm8x60.h"
@@ -950,9 +952,158 @@
.id = -1,
};
+static struct resource smd_resource[] = {
+ {
+ .name = "a9_m2a_0",
+ .start = INT_A9_M2A_0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "a9_m2a_5",
+ .start = INT_A9_M2A_5,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "adsp_a11",
+ .start = INT_ADSP_A11,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "adsp_a11_smsm",
+ .start = INT_ADSP_A11_SMSM,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "dsps_a11",
+ .start = INT_DSPS_A11,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "dsps_a11_smsm",
+ .start = INT_DSPS_A11_SMSM,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "wcnss_a11",
+ .start = INT_WCNSS_A11,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "wcnss_a11_smsm",
+ .start = INT_WCNSS_A11_SMSM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smd_subsystem_config smd_config_list[] = {
+ {
+ .irq_config_id = SMD_MODEM,
+ .subsys_name = "modem",
+ .edge = SMD_APPS_MODEM,
+
+ .smd_int.irq_name = "a9_m2a_0",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+ .smd_int.out_bit_pos = 1 << 3,
+ .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smd_int.out_offset = 0x8,
+
+ .smsm_int.irq_name = "a9_m2a_5",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smd_smsm",
+ .smsm_int.dev_id = 0,
+ .smsm_int.out_bit_pos = 1 << 4,
+ .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smsm_int.out_offset = 0x8,
+ },
+ {
+ .irq_config_id = SMD_Q6,
+ .subsys_name = "q6",
+ .edge = SMD_APPS_QDSP,
+
+ .smd_int.irq_name = "adsp_a11",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+ .smd_int.out_bit_pos = 1 << 15,
+ .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smd_int.out_offset = 0x8,
+
+ .smsm_int.irq_name = "adsp_a11_smsm",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smd_smsm",
+ .smsm_int.dev_id = 0,
+ .smsm_int.out_bit_pos = 1 << 14,
+ .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smsm_int.out_offset = 0x8,
+ },
+ {
+ .irq_config_id = SMD_DSPS,
+ .subsys_name = "dsps",
+ .edge = SMD_APPS_DSPS,
+
+ .smd_int.irq_name = "dsps_a11",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+ .smd_int.out_bit_pos = 1,
+ .smd_int.out_base = (void __iomem *)MSM_SIC_NON_SECURE_BASE,
+ .smd_int.out_offset = 0x4080,
+
+ .smsm_int.irq_name = "dsps_a11_smsm",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smd_smsm",
+ .smsm_int.dev_id = 0,
+ .smsm_int.out_bit_pos = 1,
+ .smsm_int.out_base = (void __iomem *)MSM_SIC_NON_SECURE_BASE,
+ .smsm_int.out_offset = 0x4094,
+ },
+ {
+ .irq_config_id = SMD_WCNSS,
+ .subsys_name = "wcnss",
+ .edge = SMD_APPS_WCNSS,
+
+ .smd_int.irq_name = "wcnss_a11",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+ .smd_int.out_bit_pos = 1 << 25,
+ .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smd_int.out_offset = 0x8,
+
+ .smsm_int.irq_name = "wcnss_a11_smsm",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smd_smsm",
+ .smsm_int.dev_id = 0,
+ .smsm_int.out_bit_pos = 1 << 23,
+ .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smsm_int.out_offset = 0x8,
+ },
+};
+
+static struct smd_platform smd_platform_data = {
+ .num_ss_configs = ARRAY_SIZE(smd_config_list),
+ .smd_ss_configs = smd_config_list,
+};
+
+
struct platform_device msm_device_smd = {
.name = "msm_smd",
.id = -1,
+ .resource = smd_resource,
+ .num_resources = ARRAY_SIZE(smd_resource),
+ .dev = {
+ .platform_data = &smd_platform_data,
+ },
};
struct platform_device msm_device_bam_dmux = {
@@ -1355,6 +1506,111 @@
};
#endif
+#define MSM_TSIF0_PHYS (0x18200000)
+#define MSM_TSIF1_PHYS (0x18201000)
+#define MSM_TSIF_SIZE (0x200)
+
+#define TSIF_0_CLK GPIO_CFG(75, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_0_EN GPIO_CFG(76, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_0_DATA GPIO_CFG(77, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_0_SYNC GPIO_CFG(82, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_CLK GPIO_CFG(79, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_EN GPIO_CFG(80, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_DATA GPIO_CFG(81, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+#define TSIF_1_SYNC GPIO_CFG(78, 1, GPIO_CFG_INPUT, \
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA)
+
+static const struct msm_gpio tsif0_gpios[] = {
+ { .gpio_cfg = TSIF_0_CLK, .label = "tsif_clk", },
+ { .gpio_cfg = TSIF_0_EN, .label = "tsif_en", },
+ { .gpio_cfg = TSIF_0_DATA, .label = "tsif_data", },
+ { .gpio_cfg = TSIF_0_SYNC, .label = "tsif_sync", },
+};
+
+static const struct msm_gpio tsif1_gpios[] = {
+ { .gpio_cfg = TSIF_1_CLK, .label = "tsif_clk", },
+ { .gpio_cfg = TSIF_1_EN, .label = "tsif_en", },
+ { .gpio_cfg = TSIF_1_DATA, .label = "tsif_data", },
+ { .gpio_cfg = TSIF_1_SYNC, .label = "tsif_sync", },
+};
+
+struct msm_tsif_platform_data tsif1_platform_data = {
+ .num_gpios = ARRAY_SIZE(tsif1_gpios),
+ .gpios = tsif1_gpios,
+ .tsif_pclk = "tsif_pclk",
+ .tsif_ref_clk = "tsif_ref_clk",
+};
+
+struct resource tsif1_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_IRQ,
+ .start = TSIF2_IRQ,
+ .end = TSIF2_IRQ,
+ },
+ [1] = {
+ .flags = IORESOURCE_MEM,
+ .start = MSM_TSIF1_PHYS,
+ .end = MSM_TSIF1_PHYS + MSM_TSIF_SIZE - 1,
+ },
+ [2] = {
+ .flags = IORESOURCE_DMA,
+ .start = DMOV_TSIF_CHAN,
+ .end = DMOV_TSIF_CRCI,
+ },
+};
+
+struct msm_tsif_platform_data tsif0_platform_data = {
+ .num_gpios = ARRAY_SIZE(tsif0_gpios),
+ .gpios = tsif0_gpios,
+ .tsif_pclk = "tsif_pclk",
+ .tsif_ref_clk = "tsif_ref_clk",
+};
+struct resource tsif0_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_IRQ,
+ .start = TSIF1_IRQ,
+ .end = TSIF1_IRQ,
+ },
+ [1] = {
+ .flags = IORESOURCE_MEM,
+ .start = MSM_TSIF0_PHYS,
+ .end = MSM_TSIF0_PHYS + MSM_TSIF_SIZE - 1,
+ },
+ [2] = {
+ .flags = IORESOURCE_DMA,
+ .start = DMOV_TSIF_CHAN,
+ .end = DMOV_TSIF_CRCI,
+ },
+};
+
+struct platform_device msm_device_tsif[2] = {
+ {
+ .name = "msm_tsif",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(tsif0_resources),
+ .resource = tsif0_resources,
+ .dev = {
+ .platform_data = &tsif0_platform_data
+ },
+ },
+ {
+ .name = "msm_tsif",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(tsif1_resources),
+ .resource = tsif1_resources,
+ .dev = {
+ .platform_data = &tsif1_platform_data
+ },
+ }
+};
+
static struct resource resources_ssbi_pmic[] = {
{
.start = MSM_PMIC1_SSBI_CMD_PHYS,
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 334abc0..9a4696f 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -33,6 +33,7 @@
#include "devices-msm7x2xa.h"
#include "footswitch.h"
#include "acpuclock.h"
+#include "spm.h"
/* Address of GSBI blocks */
#define MSM_GSBI0_PHYS 0xA1200000
@@ -641,6 +642,55 @@
#endif
+/* Command sequence for simple WFI */
+static uint8_t spm_wfi_cmd_sequence[] __initdata = {
+ 0x00, 0x40, 0x40, 0x03,
+ 0x00, 0x40, 0x40, 0x0f,
+};
+
+/* Command sequence for GDFS, this won't send any interrupt to the modem */
+static uint8_t spm_pc_without_modem[] __initdata = {
+ 0x20, 0x00, 0x30, 0x10,
+ 0x40, 0x40, 0x03, 0x10,
+ 0x00, 0x30, 0x2E, 0x40,
+ 0x40, 0x0f,
+};
+
+static struct msm_spm_seq_entry msm_spm_seq_list[] __initdata = {
+ [0] = {
+ .mode = MSM_SPM_MODE_CLOCK_GATING,
+ .notify_rpm = false,
+ .cmd = spm_wfi_cmd_sequence,
+ },
+ [1] = {
+ .mode = MSM_SPM_MODE_POWER_COLLAPSE,
+ .notify_rpm = false,
+ .cmd = spm_pc_without_modem,
+ },
+};
+
+static struct msm_spm_platform_data msm_spm_data[] __initdata = {
+ [0] = {
+ .reg_base_addr = MSM_SAW0_BASE,
+ .reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x0,
+ .reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
+ .num_modes = ARRAY_SIZE(msm_spm_seq_list),
+ .modes = msm_spm_seq_list,
+ },
+ [1] = {
+ .reg_base_addr = MSM_SAW1_BASE,
+ .reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x0,
+ .reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
+ .num_modes = ARRAY_SIZE(msm_spm_seq_list),
+ .modes = msm_spm_seq_list,
+ },
+};
+
+void __init msm8x25_spm_device_init(void)
+{
+ msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
+}
+
#define MDP_BASE 0xAA200000
#define MIPI_DSI_HW_BASE 0xA1100000
diff --git a/arch/arm/mach-msm/devices-msm7x2xa.h b/arch/arm/mach-msm/devices-msm7x2xa.h
index c2383c6..3c81ccf 100644
--- a/arch/arm/mach-msm/devices-msm7x2xa.h
+++ b/arch/arm/mach-msm/devices-msm7x2xa.h
@@ -30,4 +30,5 @@
void __init msm8625_init_irq(void);
void __init msm8625_map_io(void);
int ar600x_wlan_power(bool on);
+void __init msm8x25_spm_device_init(void);
#endif
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index e9b94f6..89c8aaf 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -74,6 +74,20 @@
.resource = msm_ebi1_thermal_resources
};
+static struct resource resources_adsp[] = {
+{
+ .start = INT_ADSP_A9_A11,
+ .end = INT_ADSP_A9_A11,
+ .flags = IORESOURCE_IRQ,
+},
+};
+
+struct platform_device msm_adsp_device = {
+ .name = "msm_adsp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_adsp),
+ .resource = resources_adsp,
+};
static struct resource resources_uart1[] = {
{
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 82a3fa1..7f2855d 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -323,3 +323,5 @@
extern struct platform_device msm_bus_8064_cpss_fpb;
extern struct platform_device mdm_8064_device;
+
+extern struct platform_device msm_dsps_device_8064;
diff --git a/arch/arm/mach-msm/idle.h b/arch/arm/mach-msm/idle.h
index 830e36b..6311b3c 100644
--- a/arch/arm/mach-msm/idle.h
+++ b/arch/arm/mach-msm/idle.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2009,2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2007-2009,2012 Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -28,6 +28,15 @@
{
/* empty */
}
+static inline void msm_pm_boot_entry(void)
+{
+ /* empty */
+}
+static inline void msm_pm_write_boot_vector(unsigned int cpu,
+ unsigned long address)
+{
+ /* empty */
+}
#endif
#endif
diff --git a/arch/arm/mach-msm/include/mach/diag_bridge.h b/arch/arm/mach-msm/include/mach/diag_bridge.h
index a39ed25..b06f020 100644
--- a/arch/arm/mach-msm/include/mach/diag_bridge.h
+++ b/arch/arm/mach-msm/include/mach/diag_bridge.h
@@ -19,6 +19,8 @@
int buf_size, int actual);
void (*write_complete_cb)(void *ctxt, char *buf,
int buf_size, int actual);
+ int (*suspend)(void *ctxt);
+ void (*resume)(void *ctxt);
};
#if defined(CONFIG_USB_QCOM_DIAG_BRIDGE) \
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 3cb79b7..d170f5f 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -177,6 +177,9 @@
#define DMOV_CE_OUT_CHAN 1
#define DMOV_CE_OUT_CRCI 3
+#define DMOV_TSIF_CHAN 2
+#define DMOV_TSIF_CRCI 11
+
#define DMOV_HSUART_GSBI6_TX_CHAN 7
#define DMOV_HSUART_GSBI6_TX_CRCI 6
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-copper.h b/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
index 6311dbe..b560276 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
@@ -34,7 +34,7 @@
#define COPPER_APCS_GCC_PHYS 0xF9011000
#define COPPER_APCS_GCC_SIZE SZ_4K
-#define COPPER_TLMM_PHYS 0xFD400000
+#define COPPER_TLMM_PHYS 0xFD510000
#define COPPER_TLMM_SIZE SZ_16K
#ifdef CONFIG_DEBUG_MSMCOPPER_UART
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
index 4be6d9ea..8d3e640 100644
--- a/arch/arm/mach-msm/include/mach/msm_smd.h
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -236,6 +236,22 @@
*/
int smd_write_end(smd_channel_t *ch);
+/*
+ * Returns a pointer to the subsystem name or NULL if no
+ * subsystem name is available.
+ *
+ * @type - Edge definition
+ */
+const char *smd_edge_to_subsystem(uint32_t type);
+
+/*
+ * Returns a pointer to the subsystem name given the
+ * remote processor ID.
+ *
+ * @pid Remote processor ID
+ * @returns Pointer to subsystem name or NULL if not found
+ */
+const char *smd_pid_to_subsystem(uint32_t pid);
#else
static inline int smd_open(const char *name, smd_channel_t **ch, void *priv,
@@ -337,6 +353,16 @@
{
return -ENODEV;
}
+
+static inline const char *smd_edge_to_subsystem(uint32_t type)
+{
+ return NULL;
+}
+
+static inline const char *smd_pid_to_subsystem(uint32_t pid)
+{
+ return NULL;
+}
#endif
#endif
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
index 71f2bd9..20c6fc4 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -96,6 +96,8 @@
int msm_reset_all_device(void);
+int reset_device(void);
+
int msm_clear_all_session(void);
struct msm_snddev_info *audio_dev_ctrl_find_dev(u32 dev_id);
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 7445a61..04c29cc 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -242,6 +242,8 @@
static int mdm_subsys_powerup(const struct subsys_data *crashed_subsys)
{
+ gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 0);
+ gpio_direction_output(mdm_drv->ap2mdm_status_gpio, 1);
mdm_drv->ops->power_on_mdm_cb(mdm_drv);
mdm_drv->boot_type = CHARM_NORMAL_BOOT;
complete(&mdm_needs_reload);
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index 5bff832..28b5995 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -304,6 +304,9 @@
static void init_watchdog_work(struct work_struct *work)
{
u64 timeout = (bark_time * WDT_HZ)/1000;
+
+ configure_bark_dump();
+
__raw_writel(timeout, msm_tmr0_base + WDT0_BARK_TIME);
__raw_writel(timeout + 3*WDT_HZ, msm_tmr0_base + WDT0_BITE_TIME);
@@ -366,8 +369,6 @@
if (pdata->needs_expired_enable)
__raw_writel(0x1, MSM_CLK_CTL_BASE + 0x3820);
- configure_bark_dump();
-
delay_time = msecs_to_jiffies(pdata->pet_time);
schedule_work_on(0, &init_dogwork_struct);
return 0;
diff --git a/arch/arm/mach-msm/msm_xo.c b/arch/arm/mach-msm/msm_xo.c
index 74c64c1..f7d2bcb 100644
--- a/arch/arm/mach-msm/msm_xo.c
+++ b/arch/arm/mach-msm/msm_xo.c
@@ -237,13 +237,6 @@
unsigned long flags;
struct msm_xo_voter *xo_voter;
- /*
- * TODO: Remove early return for 8064 once RPM XO voting support
- * is available.
- */
- if (cpu_is_apq8064())
- return NULL;
-
if (xo_id >= NUM_MSM_XO_IDS) {
ret = -EINVAL;
goto err;
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
index 8081b45..3c46d0f 100644
--- a/arch/arm/mach-msm/platsmp-8625.c
+++ b/arch/arm/mach-msm/platsmp-8625.c
@@ -62,6 +62,10 @@
void __cpuinit platform_secondary_init(unsigned int cpu)
{
+ pr_debug("CPU%u: Booted secondary processor\n", cpu);
+
+ WARN_ON(msm_platform_secondary_init(cpu));
+
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
diff --git a/arch/arm/mach-msm/pm-boot.c b/arch/arm/mach-msm/pm-boot.c
index ce09f9f..f4536f7 100644
--- a/arch/arm/mach-msm/pm-boot.c
+++ b/arch/arm/mach-msm/pm-boot.c
@@ -101,6 +101,7 @@
int __init msm_pm_boot_init(struct msm_pm_boot_platform_data *pdata)
{
int ret = 0;
+ unsigned long entry;
switch (pdata->mode) {
case MSM_PM_BOOT_CONFIG_TZ:
@@ -130,15 +131,44 @@
if (!pdata->p_addr || !pdata->v_addr)
return -ENODEV;
- __raw_writel((pdata->p_addr | BOOT_REMAP_ENABLE),
- pdata->v_addr);
-
ret = msm_pm_boot_reset_vector_init(__va(pdata->p_addr));
- msm_pm_boot_before_pc
- = msm_pm_config_rst_vector_before_pc;
- msm_pm_boot_after_pc
- = msm_pm_config_rst_vector_after_pc;
+ if (!cpu_is_msm8625()) {
+ __raw_writel((pdata->p_addr | BOOT_REMAP_ENABLE),
+ pdata->v_addr);
+
+ msm_pm_boot_before_pc
+ = msm_pm_config_rst_vector_before_pc;
+ msm_pm_boot_after_pc
+ = msm_pm_config_rst_vector_after_pc;
+ } else {
+ entry = virt_to_phys(msm_pm_boot_entry);
+
+ msm_pm_reset_vector[0] = 0xE51FF004; /* ldr pc, 4 */
+ msm_pm_reset_vector[1] = entry;
+
+ /* Here upper 16bits[16:31] used by CORE1
+ * lower 16bits[0:15] used by CORE0
+ */
+ entry = (pdata->p_addr) |
+ ((pdata->p_addr & 0xFFFF0000) >> 16);
+
+ /* write 'entry' to boot remapper register */
+ __raw_writel(entry, (pdata->v_addr +
+ MPA5_BOOT_REMAP_ADDR));
+
+ /* Enable boot remapper for C0 [bit:25th] */
+ __raw_writel(readl_relaxed(pdata->v_addr +
+ MPA5_CFG_CTL_REG) | BIT(25),
+ pdata->v_addr + MPA5_CFG_CTL_REG);
+
+ /* Enable boot remapper for C1 [bit:26th] */
+ __raw_writel(readl_relaxed(pdata->v_addr +
+ MPA5_CFG_CTL_REG) | BIT(26),
+ pdata->v_addr + MPA5_CFG_CTL_REG);
+
+ msm_pm_boot_before_pc = msm_pm_write_boot_vector;
+ }
break;
default:
__WARN();
diff --git a/arch/arm/mach-msm/pm-boot.h b/arch/arm/mach-msm/pm-boot.h
index 185d542..30b67c21 100644
--- a/arch/arm/mach-msm/pm-boot.h
+++ b/arch/arm/mach-msm/pm-boot.h
@@ -13,6 +13,11 @@
#ifndef _ARCH_ARM_MACH_MSM_PM_BOOT_H
#define _ARCH_ARM_MACH_MSM_PM_BOOT_H
+/* 8x25 specific macros */
+#define MPA5_CFG_CTL_REG 0x30
+#define MPA5_BOOT_REMAP_ADDR 0x34
+/* end */
+
enum {
MSM_PM_BOOT_CONFIG_TZ = 0,
MSM_PM_BOOT_CONFIG_RESET_VECTOR_PHYS = 1,
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 7977d22..1396463 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -48,6 +48,7 @@
#ifdef CONFIG_MSM_MEMORY_LOW_POWER_MODE_SUSPEND_DEEP_POWER_DOWN
#include <mach/msm_migrate_pages.h>
#endif
+#include <mach/socinfo.h>
#include "smd_private.h"
#include "smd_rpcrouter.h"
@@ -68,13 +69,14 @@
*****************************************************************************/
enum {
- MSM_PM_DEBUG_SUSPEND = 1U << 0,
- MSM_PM_DEBUG_POWER_COLLAPSE = 1U << 1,
- MSM_PM_DEBUG_STATE = 1U << 2,
- MSM_PM_DEBUG_CLOCK = 1U << 3,
- MSM_PM_DEBUG_RESET_VECTOR = 1U << 4,
- MSM_PM_DEBUG_SMSM_STATE = 1U << 5,
- MSM_PM_DEBUG_IDLE = 1U << 6,
+ MSM_PM_DEBUG_SUSPEND = BIT(0),
+ MSM_PM_DEBUG_POWER_COLLAPSE = BIT(1),
+ MSM_PM_DEBUG_STATE = BIT(2),
+ MSM_PM_DEBUG_CLOCK = BIT(3),
+ MSM_PM_DEBUG_RESET_VECTOR = BIT(4),
+ MSM_PM_DEBUG_SMSM_STATE = BIT(5),
+ MSM_PM_DEBUG_IDLE = BIT(6),
+ MSM_PM_DEBUG_HOTPLUG = BIT(7),
};
static int msm_pm_debug_mask;
@@ -142,7 +144,6 @@
static char *msm_pm_sleep_mode_labels[MSM_PM_SLEEP_MODE_NR] = {
[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND] = " ",
[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = "power_collapse",
- [MSM_PM_SLEEP_MODE_APPS_SLEEP] = "apps_sleep",
[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] =
"ramp_down_and_wfi",
[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT] = "wfi",
@@ -682,8 +683,6 @@
MSM_PM_STAT_IDLE_WFI,
MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE,
MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE,
- MSM_PM_STAT_IDLE_SLEEP,
- MSM_PM_STAT_IDLE_FAILED_SLEEP,
MSM_PM_STAT_IDLE_POWER_COLLAPSE,
MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE,
MSM_PM_STAT_SUSPEND,
@@ -1008,6 +1007,13 @@
memset(msm_pm_smem_data, 0, sizeof(*msm_pm_smem_data));
+ if (cpu_is_msm8625()) {
+ /* Program the SPM */
+ ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_POWER_COLLAPSE,
+ false);
+ WARN_ON(ret);
+ }
+
msm_irq_enter_sleep1(true, from_idle, &msm_pm_smem_data->irq_mask);
msm_sirc_enter_sleep();
msm_gpio_enter_sleep(from_idle);
@@ -1210,6 +1216,13 @@
MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): RUN");
smd_sleep_exit();
+
+ if (cpu_is_msm8625()) {
+ ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING,
+ false);
+ WARN_ON(ret);
+ }
+
return 0;
power_collapse_early_exit:
@@ -1263,6 +1276,12 @@
smd_sleep_exit();
power_collapse_bail:
+ if (cpu_is_msm8625()) {
+ ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING,
+ false);
+ WARN_ON(ret);
+ }
+
return ret;
}
@@ -1272,10 +1291,11 @@
* Return value:
* 0: success
*/
-static int msm_pm_power_collapse_standalone(void)
+static int msm_pm_power_collapse_standalone(bool from_idle)
{
int collapsed = 0;
int ret;
+ void *entry;
MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
KERN_INFO, "%s()\n", __func__);
@@ -1283,21 +1303,26 @@
ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_POWER_COLLAPSE, false);
WARN_ON(ret);
+ entry = (!smp_processor_id() || from_idle) ?
+ msm_pm_collapse_exit : msm_secondary_startup;
+
msm_pm_boot_config_before_pc(smp_processor_id(),
- virt_to_phys(msm_pm_collapse_exit));
+ virt_to_phys(entry));
#ifdef CONFIG_VFP
vfp_flush_context();
#endif
#ifdef CONFIG_CACHE_L2X0
- l2x0_suspend();
+ if (!cpu_is_msm8625())
+ l2x0_suspend();
#endif
collapsed = msm_pm_collapse();
#ifdef CONFIG_CACHE_L2X0
- l2x0_resume(collapsed);
+ if (!cpu_is_msm8625())
+ l2x0_resume(collapsed);
#endif
msm_pm_boot_config_after_pc(smp_processor_id());
@@ -1321,18 +1346,6 @@
}
/*
- * Apps-sleep the Apps processor. This function execute the handshake
- * protocol with Modem.
- *
- * Return value:
- * -ENOSYS: function not implemented yet
- */
-static int msm_pm_apps_sleep(uint32_t sleep_delay, uint32_t sleep_limit)
-{
- return -ENOSYS;
-}
-
-/*
* Bring the Apps processor to SWFI.
*
* Return value:
@@ -1353,7 +1366,9 @@
return -EIO;
}
- msm_pm_config_hw_before_swfi();
+ if (!cpu_is_msm8625())
+ msm_pm_config_hw_before_swfi();
+
msm_arch_idle();
if (ramp_acpu) {
@@ -1395,7 +1410,7 @@
int64_t t1;
static int64_t t2;
int exit_stat;
- #endif /* CONFIG_MSM_IDLE_STATS */
+ #endif
if (!atomic_read(&msm_pm_init_done))
return;
@@ -1412,19 +1427,19 @@
exit_stat = MSM_PM_STAT_IDLE_SPIN;
low_power = 0;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
for (i = 0; i < ARRAY_SIZE(allow); i++)
allow[i] = true;
- if ((timer_expiration < msm_pm_idle_sleep_min_time) ||
+ if (num_online_cpus() > 1 ||
+ (timer_expiration < msm_pm_idle_sleep_min_time) ||
#ifdef CONFIG_HAS_WAKELOCK
has_wake_lock(WAKE_LOCK_IDLE) ||
#endif
!msm_irq_idle_sleep_allowed()) {
allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = false;
allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = false;
- allow[MSM_PM_SLEEP_MODE_APPS_SLEEP] = false;
}
for (i = 0; i < ARRAY_SIZE(allow); i++) {
@@ -1493,32 +1508,15 @@
exit_stat = MSM_PM_STAT_IDLE_POWER_COLLAPSE;
msm_pm_sleep_limit = sleep_limit;
}
-#endif /* CONFIG_MSM_IDLE_STATS */
- } else if (allow[MSM_PM_SLEEP_MODE_APPS_SLEEP]) {
- uint32_t sleep_delay;
-
- sleep_delay = (uint32_t) msm_pm_convert_and_cap_time(
- timer_expiration, MSM_PM_SLEEP_TICK_LIMIT);
- if (sleep_delay == 0) /* 0 would mean infinite time */
- sleep_delay = 1;
-
- ret = msm_pm_apps_sleep(sleep_delay, sleep_limit);
- low_power = 0;
-
-#ifdef CONFIG_MSM_IDLE_STATS
- if (ret)
- exit_stat = MSM_PM_STAT_IDLE_FAILED_SLEEP;
- else
- exit_stat = MSM_PM_STAT_IDLE_SLEEP;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
} else if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE]) {
- ret = msm_pm_power_collapse_standalone();
+ ret = msm_pm_power_collapse_standalone(true);
low_power = 0;
#ifdef CONFIG_MSM_IDLE_STATS
exit_stat = ret ?
MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE :
MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
} else if (allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT]) {
ret = msm_pm_swfi(true);
if (ret)
@@ -1527,20 +1525,20 @@
low_power = 0;
#ifdef CONFIG_MSM_IDLE_STATS
exit_stat = ret ? MSM_PM_STAT_IDLE_SPIN : MSM_PM_STAT_IDLE_WFI;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
} else if (allow[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT]) {
msm_pm_swfi(false);
low_power = 0;
#ifdef CONFIG_MSM_IDLE_STATS
exit_stat = MSM_PM_STAT_IDLE_WFI;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
} else {
while (!msm_irq_pending())
udelay(1);
low_power = 0;
#ifdef CONFIG_MSM_IDLE_STATS
exit_stat = MSM_PM_STAT_IDLE_SPIN;
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
}
msm_timer_exit_idle(low_power);
@@ -1548,13 +1546,14 @@
#ifdef CONFIG_MSM_IDLE_STATS
t2 = ktime_to_ns(ktime_get());
msm_pm_add_stat(exit_stat, t2 - t1);
-#endif /* CONFIG_MSM_IDLE_STATS */
+#endif
}
/*
* Suspend the Apps processor.
*
* Return value:
+ * -EPERM: Suspend happened by a not permitted core
* -EAGAIN: modem reset occurred or early exit from suspend
* -EBUSY: modem not ready for our suspend
* -EINVAL: invalid sleep mode
@@ -1566,13 +1565,20 @@
{
bool allow[MSM_PM_SLEEP_MODE_NR];
uint32_t sleep_limit = SLEEP_LIMIT_NONE;
- int ret;
+ int ret = -EPERM;
int i;
-
#ifdef CONFIG_MSM_IDLE_STATS
int64_t period = 0;
int64_t time = 0;
+#endif
+ /* Must executed by CORE0 */
+ if (smp_processor_id()) {
+ __WARN();
+ goto suspend_exit;
+ }
+
+#ifdef CONFIG_MSM_IDLE_STATS
time = msm_timer_get_sclk_time(&period);
#endif
@@ -1589,8 +1595,6 @@
allow[i] = false;
}
- ret = 0;
-
if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] ||
allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN]) {
#ifdef CONFIG_MSM_IDLE_STATS
@@ -1647,7 +1651,7 @@
msm_pm_add_stat(id, time);
#endif
} else if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE]) {
- ret = msm_pm_power_collapse_standalone();
+ ret = msm_pm_power_collapse_standalone(false);
} else if (allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT]) {
ret = msm_pm_swfi(true);
if (ret)
@@ -1657,6 +1661,7 @@
msm_pm_swfi(false);
}
+suspend_exit:
MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND, KERN_INFO,
"%s(): return %d\n", __func__, ret);
@@ -1673,7 +1678,27 @@
*/
void msm_pm_cpu_enter_lowpower(unsigned int cpu)
{
- return;
+ bool allow[MSM_PM_SLEEP_MODE_NR];
+ int i;
+
+ for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) {
+ struct msm_pm_platform_data *mode;
+
+ mode = &msm_pm_modes[MSM_PM_MODE(cpu, i)];
+ allow[i] = mode->suspend_supported && mode->suspend_enabled;
+ }
+
+ MSM_PM_DPRINTK(MSM_PM_DEBUG_HOTPLUG, KERN_INFO,
+ "CPU%u: %s: shutting down cpu\n", cpu, __func__);
+
+ if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE]) {
+ msm_pm_power_collapse_standalone(false);
+ } else if (allow[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT]) {
+ msm_pm_swfi(false);
+ } else {
+ MSM_PM_DPRINTK(MSM_PM_DEBUG_HOTPLUG, KERN_INFO,
+ "CPU%u: %s: shutting down failed!!!\n", cpu, __func__);
+ }
}
/******************************************************************************
@@ -1725,10 +1750,6 @@
};
-/******************************************************************************
- *
- *****************************************************************************/
-
/*
* Initialize the power management subsystem.
*
@@ -1837,15 +1858,6 @@
first_bucket_time =
CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
- stats[MSM_PM_STAT_IDLE_SLEEP].name = "idle-sleep";
- stats[MSM_PM_STAT_IDLE_SLEEP].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
-
- stats[MSM_PM_STAT_IDLE_FAILED_SLEEP].name =
- "idle-failed-sleep";
- stats[MSM_PM_STAT_IDLE_FAILED_SLEEP].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
-
stats[MSM_PM_STAT_IDLE_POWER_COLLAPSE].name =
"idle-power-collapse";
stats[MSM_PM_STAT_IDLE_POWER_COLLAPSE].first_bucket_time =
diff --git a/arch/arm/mach-msm/qdsp5/audio_voicememo.c b/arch/arm/mach-msm/qdsp5/audio_voicememo.c
index 7a962b2..2011c42 100644
--- a/arch/arm/mach-msm/qdsp5/audio_voicememo.c
+++ b/arch/arm/mach-msm/qdsp5/audio_voicememo.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
*
* This code is based in part on arch/arm/mach-msm/qdsp5/audio_mp3.c
*
@@ -836,6 +836,7 @@
file->private_data = audio;
audio->opened = 1;
+ audio->stopped = 0;
rc = 0;
done:
mutex_unlock(&audio->lock);
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp.c b/arch/arm/mach-msm/qdsp5v2/adsp.c
index b7b56c8..acd9c4c 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp.c
+++ b/arch/arm/mach-msm/qdsp5v2/adsp.c
@@ -2,7 +2,7 @@
* Register/Interrupt access for userspace aDSP library.
*
* Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009,2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009,2011-2012 Code Aurora Forum. All rights reserved.
* Author: Iliyan Malchev <ibm@android.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -46,8 +46,6 @@
static int wdump, rdump;
#endif /* CONFIG_DEBUG_FS */
-#define INT_ADSP INT_ADSP_A9_A11
-
static struct adsp_info adsp_info;
static struct msm_adsp_module *adsp_modules;
static int adsp_open_count;
@@ -889,7 +887,7 @@
mutex_lock(&adsp_open_lock);
if (adsp_open_count++ == 0)
- enable_irq(INT_ADSP);
+ enable_irq(adsp_info.int_adsp);
mutex_unlock(&adsp_open_lock);
break;
case ADSP_STATE_ENABLING:
@@ -944,7 +942,7 @@
mutex_unlock(&module->lock);
mutex_lock(&adsp_open_lock);
if (--adsp_open_count == 0) {
- disable_irq(INT_ADSP);
+ disable_irq(adsp_info.int_adsp);
MM_INFO("disable interrupt\n");
}
mutex_unlock(&adsp_open_lock);
@@ -959,6 +957,12 @@
unsigned count;
int rc, i;
+ adsp_info.int_adsp = platform_get_irq(pdev, 0);
+ if (adsp_info.int_adsp < 0) {
+ MM_ERR("no irq resource?\n");
+ return -ENODEV;
+ }
+
adsp_info.init_info_ptr = kzalloc(
(sizeof(struct adsp_rtos_mp_mtoa_init_info_type)), GFP_KERNEL);
if (!adsp_info.init_info_ptr)
@@ -996,11 +1000,11 @@
spin_lock_init(&adsp_cmd_lock);
spin_lock_init(&adsp_write_lock);
- rc = request_irq(INT_ADSP, adsp_irq_handler,
+ rc = request_irq(adsp_info.int_adsp, adsp_irq_handler,
IRQF_TRIGGER_RISING, "adsp", 0);
if (rc < 0)
goto fail_request_irq;
- disable_irq(INT_ADSP);
+ disable_irq(adsp_info.int_adsp);
for (i = 0; i < count; i++) {
struct msm_adsp_module *mod = adsp_modules + i;
@@ -1056,8 +1060,8 @@
daldevice_detach(adsp_info.handle);
adsp_info.handle = NULL;
fail_dal_attach:
- enable_irq(INT_ADSP);
- free_irq(INT_ADSP, 0);
+ enable_irq(adsp_info.int_adsp);
+ free_irq(adsp_info.int_adsp, 0);
fail_request_irq:
kfree(adsp_modules);
kfree(adsp_info.init_info_ptr);
@@ -1187,11 +1191,6 @@
},
};
-struct platform_device msm_adsp_device = {
- .name = "msm_adsp",
- .id = -1,
-};
-
static char msm_adsp_driver_name[] = "msm_adsp";
#ifdef CONFIG_DEBUG_FS
@@ -1218,7 +1217,6 @@
#endif /* CONFIG_DEBUG_FS */
msm_adsp_driver.driver.name = msm_adsp_driver_name;
- rc = platform_device_register(&msm_adsp_device);
rc = platform_driver_register(&msm_adsp_driver);
MM_INFO("%s -- %d\n", msm_adsp_driver_name, rc);
return rc;
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp.h b/arch/arm/mach-msm/qdsp5v2/adsp.h
index 18f4046..5aceff9 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp.h
+++ b/arch/arm/mach-msm/qdsp5v2/adsp.h
@@ -229,6 +229,9 @@
void *handle;
void *cb_handle;
+
+ /* Interrupt value */
+ int int_adsp;
};
#define ADSP_STATE_DISABLED 0
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c b/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
index 0a5acce..aaae776 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/sched.h>
+#include <linux/workqueue.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <mach/qdsp6v2/audio_dev_ctl.h>
@@ -31,6 +32,9 @@
static DEFINE_MUTEX(session_lock);
+static struct workqueue_struct *msm_reset_device_work_queue;
+static void reset_device_work(struct work_struct *work);
+static DECLARE_WORK(msm_reset_device_work, reset_device_work);
struct audio_dev_ctrl_state {
struct msm_snddev_info *devs[AUDIO_DEV_CTL_MAX_DEV];
@@ -119,6 +123,18 @@
}
EXPORT_SYMBOL(msm_reset_all_device);
+static void reset_device_work(struct work_struct *work)
+{
+ msm_reset_all_device();
+}
+
+int reset_device(void)
+{
+ queue_work(msm_reset_device_work_queue, &msm_reset_device_work);
+ return 0;
+}
+EXPORT_SYMBOL(reset_device);
+
int msm_set_copp_id(int session_id, int copp_id)
{
int rc = 0;
@@ -1686,7 +1702,9 @@
init_waitqueue_head(&audio_dev_ctrl.wait);
event.cb = NULL;
-
+ msm_reset_device_work_queue = create_workqueue("reset_device");
+ if (msm_reset_device_work_queue == NULL)
+ return -ENOMEM;
atomic_set(&audio_dev_ctrl.opened, 0);
audio_dev_ctrl.num_dev = 0;
audio_dev_ctrl.voice_tx_dev = NULL;
@@ -1704,6 +1722,7 @@
static void __exit audio_dev_ctrl_exit(void)
{
+ destroy_workqueue(msm_reset_device_work_queue);
}
module_init(audio_dev_ctrl_init);
module_exit(audio_dev_ctrl_exit);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
index 599198e..41a7387 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
@@ -28,8 +28,8 @@
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/earlysuspend.h>
+#include <linux/ion.h>
#include <linux/list.h>
-#include <linux/android_pmem.h>
#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/ioctls.h>
@@ -88,10 +88,10 @@
int event_type;
union msm_audio_event_payload payload;
};
-
-struct audlpa_pmem_region {
+struct audlpa_ion_region {
struct list_head list;
- struct file *file;
+ struct ion_handle *handle;
+ struct ion_client *client;
int fd;
void *vaddr;
unsigned long paddr;
@@ -115,12 +115,13 @@
static void audlpa_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload);
-static unsigned long audlpa_pmem_fixup(struct audio *audio, void *addr,
+
+static unsigned long audlpa_ion_fixup(struct audio *audio, void *addr,
unsigned long len, int ref_up);
+static void audlpa_unmap_ion_region(struct audio *audio);
static void audlpa_async_send_data(struct audio *audio, unsigned needed,
uint32_t token);
static int audlpa_pause(struct audio *audio);
-static void audlpa_unmap_pmem_region(struct audio *audio);
static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static int audlpa_set_pcm_params(void *data);
@@ -422,7 +423,7 @@
drv_evt->event_type == AUDIO_EVENT_READ_DONE)) {
pr_debug("%s: AUDIO_EVENT_WRITE_DONE completing\n", __func__);
mutex_lock(&audio->lock);
- audlpa_pmem_fixup(audio, drv_evt->payload.aio_buf.buf_addr,
+ audlpa_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr,
drv_evt->payload.aio_buf.buf_len, 0);
mutex_unlock(&audio->lock);
}
@@ -432,38 +433,41 @@
return rc;
}
-static int audlpa_pmem_check(struct audio *audio,
- void *vaddr, unsigned long len)
+static int audlpa_ion_check(struct audio *audio,
+ void *vaddr, unsigned long len)
{
- struct audlpa_pmem_region *region_elt;
- struct audlpa_pmem_region t = { .vaddr = vaddr, .len = len };
+ struct audlpa_ion_region *region_elt;
+ struct audlpa_ion_region t = {.vaddr = vaddr, .len = len };
- list_for_each_entry(region_elt, &audio->pmem_region_queue, list) {
+ list_for_each_entry(region_elt, &audio->ion_region_queue, list) {
if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
OVERLAPS(region_elt, &t)) {
- pr_err("%s: region (vaddr %p len %ld)"
- " clashes with registered region"
- " (vaddr %p paddr %p len %ld)\n",
- __func__, vaddr, len,
- region_elt->vaddr,
- (void *)region_elt->paddr,
- region_elt->len);
+ pr_err("%s[%p]:region (vaddr %p len %ld)"
+ " clashes with registered region"
+ " (vaddr %p paddr %p len %ld)\n",
+ __func__, audio, vaddr, len,
+ region_elt->vaddr,
+ (void *)region_elt->paddr, region_elt->len);
return -EINVAL;
}
}
return 0;
}
-
-static int audlpa_pmem_add(struct audio *audio,
- struct msm_audio_pmem_info *info)
+static int audlpa_ion_add(struct audio *audio,
+ struct msm_audio_ion_info *info)
{
- unsigned long paddr, kvaddr, len;
- struct file *file;
- struct audlpa_pmem_region *region;
+ ion_phys_addr_t paddr;
+ size_t len;
+ unsigned long kvaddr;
+ struct audlpa_ion_region *region;
int rc = -EINVAL;
+ struct ion_handle *handle;
+ struct ion_client *client;
+ unsigned long ionflag;
+ void *temp_ptr;
- pr_debug("%s:\n", __func__);
+ pr_debug("%s[%p]:\n", __func__, audio);
region = kmalloc(sizeof(*region), GFP_KERNEL);
if (!region) {
@@ -471,61 +475,105 @@
goto end;
}
- if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
- kfree(region);
- goto end;
+ client = msm_ion_client_create(UINT_MAX, "Audio_LPA_Client");
+ if (IS_ERR_OR_NULL(client)) {
+ pr_err("Unable to create ION client\n");
+ goto client_error;
}
- rc = audlpa_pmem_check(audio, info->vaddr, len);
+ handle = ion_import_fd(client, info->fd);
+ if (IS_ERR_OR_NULL(handle)) {
+ pr_err("%s: could not get handle of the given fd\n", __func__);
+ goto import_error;
+ }
+
+ rc = ion_handle_get_flags(client, handle, &ionflag);
+ if (rc) {
+ pr_err("%s: could not get flags for the handle\n", __func__);
+ goto flag_error;
+ }
+
+ temp_ptr = ion_map_kernel(client, handle, ionflag);
+ if (IS_ERR_OR_NULL(temp_ptr)) {
+ pr_err("%s: could not get virtual address\n", __func__);
+ goto map_error;
+ }
+ kvaddr = (unsigned long) temp_ptr;
+
+ rc = ion_phys(client, handle, &paddr, &len);
+ if (rc) {
+ pr_err("%s: could not get physical address\n", __func__);
+ goto ion_error;
+ }
+
+ rc = audlpa_ion_check(audio, info->vaddr, len);
if (rc < 0) {
- put_pmem_file(file);
- kfree(region);
- goto end;
+ pr_err("%s: audlpa_ion_check failed\n", __func__);
+ goto ion_error;
}
+ region->client = client;
+ region->handle = handle;
region->vaddr = info->vaddr;
region->fd = info->fd;
region->paddr = paddr;
region->kvaddr = kvaddr;
region->len = len;
- region->file = file;
region->ref_cnt = 0;
- pr_debug("%s: add region paddr %lx vaddr %p, len %lu\n", __func__,
- region->paddr, region->vaddr,
- region->len);
- list_add_tail(®ion->list, &audio->pmem_region_queue);
+ pr_debug("%s[%p]:add region paddr %lx vaddr %p, len %lu kvaddr %lx\n",
+ __func__, audio,
+ region->paddr, region->vaddr, region->len, region->kvaddr);
+ list_add_tail(®ion->list, &audio->ion_region_queue);
+
rc = q6asm_memory_map(audio->ac, (uint32_t)paddr, IN, (uint32_t)len, 1);
- if (rc < 0)
- pr_err("%s: memory map failed\n", __func__);
+ if (rc < 0) {
+ pr_err("%s[%p]: memory map failed\n", __func__, audio);
+ goto ion_error;
+ } else {
+ goto end;
+ }
+
+ion_error:
+ ion_unmap_kernel(client, handle);
+map_error:
+ ion_free(client, handle);
+flag_error:
+import_error:
+ ion_client_destroy(client);
+client_error:
+ kfree(region);
end:
return rc;
}
-static int audlpa_pmem_remove(struct audio *audio,
- struct msm_audio_pmem_info *info)
+static int audlpa_ion_remove(struct audio *audio,
+ struct msm_audio_ion_info *info)
{
- struct audlpa_pmem_region *region;
+ struct audlpa_ion_region *region;
struct list_head *ptr, *next;
int rc = -EINVAL;
- list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
- region = list_entry(ptr, struct audlpa_pmem_region, list);
+ list_for_each_safe(ptr, next, &audio->ion_region_queue) {
+ region = list_entry(ptr, struct audlpa_ion_region, list);
- if ((region != NULL) && (region->fd == info->fd) &&
- (region->vaddr == info->vaddr)) {
+ if (region != NULL && (region->fd == info->fd) &&
+ (region->vaddr == info->vaddr)) {
if (region->ref_cnt) {
- pr_debug("%s: region %p in use ref_cnt %d\n",
- __func__, region, region->ref_cnt);
+ pr_debug("%s[%p]:region %p in use ref_cnt %d\n",
+ __func__, audio, region,
+ region->ref_cnt);
break;
}
rc = q6asm_memory_unmap(audio->ac,
- (uint32_t)region->paddr,
- IN);
+ (uint32_t) region->paddr, IN);
if (rc < 0)
- pr_err("%s: memory unmap failed\n", __func__);
+ pr_err("%s[%p]: memory unmap failed\n",
+ __func__, audio);
list_del(®ion->list);
- put_pmem_file(region->file);
+ ion_unmap_kernel(region->client, region->handle);
+ ion_free(region->client, region->handle);
+ ion_client_destroy(region->client);
kfree(region);
rc = 0;
break;
@@ -535,24 +583,21 @@
return rc;
}
-static int audlpa_pmem_lookup_vaddr(struct audio *audio, void *addr,
- unsigned long len, struct audlpa_pmem_region **region)
+static int audlpa_ion_lookup_vaddr(struct audio *audio, void *addr,
+ unsigned long len, struct audlpa_ion_region **region)
{
- struct audlpa_pmem_region *region_elt;
-
+ struct audlpa_ion_region *region_elt;
int match_count = 0;
-
*region = NULL;
/* returns physical address or zero */
- list_for_each_entry(region_elt, &audio->pmem_region_queue,
- list) {
+ list_for_each_entry(region_elt, &audio->ion_region_queue, list) {
if (addr >= region_elt->vaddr &&
- addr < region_elt->vaddr + region_elt->len &&
- addr + len <= region_elt->vaddr + region_elt->len) {
+ addr < region_elt->vaddr + region_elt->len &&
+ addr + len <= region_elt->vaddr + region_elt->len) {
/* offset since we could pass vaddr inside a registerd
- * pmem buffer
- */
+ * ion buffer
+ */
match_count++;
if (!*region)
@@ -561,32 +606,33 @@
}
if (match_count > 1) {
- pr_err("%s: multiple hits for vaddr %p, len %ld\n", __func__,
- addr, len);
- list_for_each_entry(region_elt,
- &audio->pmem_region_queue, list) {
- if (addr >= region_elt->vaddr &&
- addr < region_elt->vaddr + region_elt->len &&
- addr + len <= region_elt->vaddr + region_elt->len)
- pr_err("%s: \t%p, %ld --> %p\n", __func__,
- region_elt->vaddr, region_elt->len,
- (void *)region_elt->paddr);
+ pr_err("%s[%p]:multiple hits for vaddr %p, len %ld\n",
+ __func__, audio, addr, len);
+ list_for_each_entry(region_elt, &audio->ion_region_queue,
+ list) {
+ if (addr >= region_elt->vaddr &&
+ addr < region_elt->vaddr + region_elt->len &&
+ addr + len <= region_elt->vaddr + region_elt->len)
+ pr_err("\t%s[%p]:%p, %ld --> %p\n",
+ __func__, audio,
+ region_elt->vaddr,
+ region_elt->len,
+ (void *)region_elt->paddr);
}
}
-
return *region ? 0 : -1;
}
-
-unsigned long audlpa_pmem_fixup(struct audio *audio, void *addr,
- unsigned long len, int ref_up)
+static unsigned long audlpa_ion_fixup(struct audio *audio, void *addr,
+ unsigned long len, int ref_up)
{
- struct audlpa_pmem_region *region;
+ struct audlpa_ion_region *region;
unsigned long paddr;
int ret;
- ret = audlpa_pmem_lookup_vaddr(audio, addr, len, ®ion);
+ ret = audlpa_ion_lookup_vaddr(audio, addr, len, ®ion);
if (ret) {
- pr_err("%s: lookup (%p, %ld) failed\n", __func__, addr, len);
+ pr_err("%s[%p]:lookup (%p, %ld) failed\n",
+ __func__, audio, addr, len);
return 0;
}
if (ref_up)
@@ -613,7 +659,7 @@
return -EFAULT;
}
- buf_node->paddr = audlpa_pmem_fixup(
+ buf_node->paddr = audlpa_ion_fixup(
audio, buf_node->buf.buf_addr,
buf_node->buf.buf_len, 1);
if (dir) {
@@ -669,6 +715,9 @@
break;
case ASM_SESSION_CMDRSP_GET_SESSION_TIME:
break;
+ case RESET_EVENTS:
+ reset_device();
+ break;
default:
break;
}
@@ -918,25 +967,26 @@
}
break;
- case AUDIO_REGISTER_PMEM: {
- struct msm_audio_pmem_info info;
- pr_debug("%s: AUDIO_REGISTER_PMEM\n", __func__);
- if (copy_from_user(&info, (void *) arg, sizeof(info)))
- rc = -EFAULT;
- else
- rc = audlpa_pmem_add(audio, &info);
- break;
- }
+ case AUDIO_REGISTER_ION: {
+ struct msm_audio_ion_info info;
+ pr_debug("%s: AUDIO_REGISTER_ION\n", __func__);
+ if (copy_from_user(&info, (void *)arg, sizeof(info)))
+ rc = -EFAULT;
+ else
+ rc = audlpa_ion_add(audio, &info);
+ break;
+ }
- case AUDIO_DEREGISTER_PMEM: {
- struct msm_audio_pmem_info info;
- pr_debug("%s: AUDIO_DEREGISTER_PMEM\n", __func__);
- if (copy_from_user(&info, (void *) arg, sizeof(info)))
- rc = -EFAULT;
- else
- rc = audlpa_pmem_remove(audio, &info);
- break;
- }
+ case AUDIO_DEREGISTER_ION: {
+ struct msm_audio_ion_info info;
+ pr_debug("%s: AUDIO_DEREGISTER_ION\n", __func__);
+ if (copy_from_user(&info, (void *)arg, sizeof(info)))
+ rc = -EFAULT;
+ else
+ rc = audlpa_ion_remove(audio, &info);
+ break;
+ }
+
case AUDIO_ASYNC_WRITE:
pr_debug("%s: AUDIO_ASYNC_WRITE\n", __func__);
if (audio->drv_status & ADRV_STATUS_FSYNC)
@@ -1035,34 +1085,37 @@
return audlpa_async_fsync(audio);
}
-static void audlpa_reset_pmem_region(struct audio *audio)
+void audlpa_reset_ion_region(struct audio *audio)
{
- struct audlpa_pmem_region *region;
+ struct audlpa_ion_region *region;
struct list_head *ptr, *next;
- list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
- region = list_entry(ptr, struct audlpa_pmem_region, list);
+ list_for_each_safe(ptr, next, &audio->ion_region_queue) {
+ region = list_entry(ptr, struct audlpa_ion_region, list);
list_del(®ion->list);
- put_pmem_file(region->file);
+ ion_unmap_kernel(region->client, region->handle);
+ ion_free(region->client, region->handle);
+ ion_client_destroy(region->client);
kfree(region);
}
return;
}
-static void audlpa_unmap_pmem_region(struct audio *audio)
+static void audlpa_unmap_ion_region(struct audio *audio)
{
- struct audlpa_pmem_region *region;
+ struct audlpa_ion_region *region;
struct list_head *ptr, *next;
int rc = -EINVAL;
- pr_debug("%s:\n", __func__);
- list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
- region = list_entry(ptr, struct audlpa_pmem_region, list);
- pr_debug("%s: phy_address = 0x%lx\n", __func__, region->paddr);
+ pr_debug("%s[%p]:\n", __func__, audio);
+ list_for_each_safe(ptr, next, &audio->ion_region_queue) {
+ region = list_entry(ptr, struct audlpa_ion_region, list);
+ pr_debug("%s[%p]: phy_address = 0x%lx\n",
+ __func__, audio, region->paddr);
if (region != NULL) {
rc = q6asm_memory_unmap(audio->ac,
- (uint32_t)region->paddr, IN);
+ (uint32_t)region->paddr, IN);
if (rc < 0)
pr_err("%s: memory unmap failed\n", __func__);
}
@@ -1081,12 +1134,12 @@
if (audio->out_enabled)
audlpa_async_flush(audio);
audio->wflush = 0;
- audlpa_unmap_pmem_region(audio);
+ audlpa_unmap_ion_region(audio);
audio_disable(audio);
msm_clear_session_id(audio->ac->session);
auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->ac->session);
q6asm_audio_client_free(audio->ac);
- audlpa_reset_pmem_region(audio);
+ audlpa_reset_ion_region(audio);
#ifdef CONFIG_HAS_EARLYSUSPEND
unregister_early_suspend(&audio->suspend_ctl.node);
#endif
@@ -1096,7 +1149,6 @@
audio->event_abort = 1;
wake_up(&audio->event_wait);
audlpa_reset_event_queue(audio);
- pmem_kfree(audio->phys);
if (audio->stopped == 0)
audlpa_allow_sleep(audio);
wake_lock_destroy(&audio->wakelock);
@@ -1274,7 +1326,7 @@
spin_lock_init(&audio->dsp_lock);
init_waitqueue_head(&audio->write_wait);
INIT_LIST_HEAD(&audio->out_queue);
- INIT_LIST_HEAD(&audio->pmem_region_queue);
+ INIT_LIST_HEAD(&audio->ion_region_queue);
INIT_LIST_HEAD(&audio->free_event_queue);
INIT_LIST_HEAD(&audio->event_queue);
init_waitqueue_head(&audio->wait);
@@ -1339,7 +1391,6 @@
return rc;
err:
q6asm_audio_client_free(audio->ac);
- pmem_kfree(audio->phys);
kfree(audio);
return rc;
}
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
index ffc27ad..34b53f2 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -88,7 +88,7 @@
uint32_t device_events;
- struct list_head pmem_region_queue; /* protected by lock */
+ struct list_head ion_region_queue; /* protected by lock */
int eq_enable;
int eq_needs_commit;
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_in.c b/arch/arm/mach-msm/qdsp6v2/pcm_in.c
index 1f20aa7..667628c 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_in.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2009 Google, Inc.
* Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -72,6 +72,9 @@
case ASM_DATA_EVENT_READ_DONE:
pcm_in_get_dsp_buffers(pcm, token, payload);
break;
+ case RESET_EVENTS:
+ reset_device();
+ break;
default:
break;
}
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_out.c b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
index a4a6b72..733d5e3 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_out.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -66,6 +66,9 @@
atomic_inc(&pcm->out_count);
wake_up(&pcm->write_wait);
break;
+ case RESET_EVENTS:
+ reset_device();
+ break;
default:
break;
}
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index bca1e0c..9321b40 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -72,6 +72,7 @@
MSM_SMSM_DEBUG = 1U << 1,
MSM_SMD_INFO = 1U << 2,
MSM_SMSM_INFO = 1U << 3,
+ MSM_SMx_POWER_INFO = 1U << 4,
};
struct smsm_shared_info {
@@ -117,29 +118,34 @@
};
static irqreturn_t smd_modem_irq_handler(int irq, void *data);
+static irqreturn_t smsm_modem_irq_handler(int irq, void *data);
static irqreturn_t smd_dsp_irq_handler(int irq, void *data);
+static irqreturn_t smsm_dsp_irq_handler(int irq, void *data);
static irqreturn_t smd_dsps_irq_handler(int irq, void *data);
+static irqreturn_t smsm_dsps_irq_handler(int irq, void *data);
static irqreturn_t smd_wcnss_irq_handler(int irq, void *data);
+static irqreturn_t smsm_wcnss_irq_handler(int irq, void *data);
static irqreturn_t smsm_irq_handler(int irq, void *data);
static struct interrupt_config private_intr_config[NUM_SMD_SUBSYSTEMS] = {
[SMD_MODEM] = {
.smd.irq_handler = smd_modem_irq_handler,
- .smsm.irq_handler = smsm_irq_handler,
+ .smsm.irq_handler = smsm_modem_irq_handler,
},
[SMD_Q6] = {
.smd.irq_handler = smd_dsp_irq_handler,
- .smsm.irq_handler = smsm_irq_handler,
+ .smsm.irq_handler = smsm_dsp_irq_handler,
},
[SMD_DSPS] = {
.smd.irq_handler = smd_dsps_irq_handler,
- .smsm.irq_handler = smsm_irq_handler,
+ .smsm.irq_handler = smsm_dsps_irq_handler,
},
[SMD_WCNSS] = {
.smd.irq_handler = smd_wcnss_irq_handler,
- .smsm.irq_handler = smsm_irq_handler,
+ .smsm.irq_handler = smsm_wcnss_irq_handler,
},
};
+struct interrupt_stat interrupt_stats[NUM_SMD_SUBSYSTEMS];
#define SMSM_STATE_ADDR(entry) (smsm_info.state + entry)
#define SMSM_INTR_MASK_ADDR(entry, host) (smsm_info.intr_mask + \
@@ -175,11 +181,16 @@
if (msm_smd_debug_mask & MSM_SMSM_INFO) \
printk(KERN_INFO x); \
} while (0)
+#define SMx_POWER_INFO(x...) do { \
+ if (msm_smd_debug_mask & MSM_SMx_POWER_INFO) \
+ printk(KERN_INFO x); \
+ } while (0)
#else
#define SMD_DBG(x...) do { } while (0)
#define SMSM_DBG(x...) do { } while (0)
#define SMD_INFO(x...) do { } while (0)
#define SMSM_INFO(x...) do { } while (0)
+#define SMx_POWER_INFO(x...) do { } while (0)
#endif
static unsigned last_heap_free = 0xffffffff;
@@ -214,24 +225,6 @@
#define MSM_TRIG_A2DSPS_SMSM_INT
#define MSM_TRIG_A2WCNSS_SMD_INT
#define MSM_TRIG_A2WCNSS_SMSM_INT
-#elif defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_MSM8930) || \
- defined(CONFIG_ARCH_APQ8064)
-#define MSM_TRIG_A2M_SMD_INT \
- (smd_write_intr(1 << 3, MSM_APCS_GCC_BASE + 0x8))
-#define MSM_TRIG_A2Q6_SMD_INT \
- (smd_write_intr(1 << 15, MSM_APCS_GCC_BASE + 0x8))
-#define MSM_TRIG_A2M_SMSM_INT \
- (smd_write_intr(1 << 4, MSM_APCS_GCC_BASE + 0x8))
-#define MSM_TRIG_A2Q6_SMSM_INT \
- (smd_write_intr(1 << 14, MSM_APCS_GCC_BASE + 0x8))
-#define MSM_TRIG_A2DSPS_SMD_INT \
- (smd_write_intr(1, MSM_SIC_NON_SECURE_BASE + 0x4080))
-#define MSM_TRIG_A2DSPS_SMSM_INT \
- (smd_write_intr(1, MSM_SIC_NON_SECURE_BASE + 0x4094))
-#define MSM_TRIG_A2WCNSS_SMD_INT \
- (smd_write_intr(1 << 25, MSM_APCS_GCC_BASE + 0x8))
-#define MSM_TRIG_A2WCNSS_SMSM_INT \
- (smd_write_intr(1 << 23, MSM_APCS_GCC_BASE + 0x8))
#elif defined(CONFIG_ARCH_MSM9615)
#define MSM_TRIG_A2M_SMD_INT \
(smd_write_intr(1 << 3, MSM_APCS_GCC_BASE + 0x8))
@@ -258,15 +251,33 @@
#define MSM_TRIG_A2DSPS_SMSM_INT
#define MSM_TRIG_A2WCNSS_SMD_INT
#define MSM_TRIG_A2WCNSS_SMSM_INT
-#else
+#elif defined(CONFIG_ARCH_MSM7X01A) || defined(CONFIG_ARCH_MSM7x25)
#define MSM_TRIG_A2M_SMD_INT \
(smd_write_intr(1, MSM_CSR_BASE + 0x400 + (0) * 4))
-#define MSM_TRIG_A2Q6_SMD_INT \
- (smd_write_intr(1, MSM_CSR_BASE + 0x400 + (8) * 4))
+#define MSM_TRIG_A2Q6_SMD_INT
#define MSM_TRIG_A2M_SMSM_INT \
(smd_write_intr(1, MSM_CSR_BASE + 0x400 + (5) * 4))
-#define MSM_TRIG_A2Q6_SMSM_INT \
- (smd_write_intr(1, MSM_CSR_BASE + 0x400 + (8) * 4))
+#define MSM_TRIG_A2Q6_SMSM_INT
+#define MSM_TRIG_A2DSPS_SMD_INT
+#define MSM_TRIG_A2DSPS_SMSM_INT
+#define MSM_TRIG_A2WCNSS_SMD_INT
+#define MSM_TRIG_A2WCNSS_SMSM_INT
+#elif defined(CONFIG_ARCH_MSM7X27) || defined(CONFIG_ARCH_MSM7X27A)
+#define MSM_TRIG_A2M_SMD_INT \
+ (smd_write_intr(1, MSM_CSR_BASE + 0x400 + (0) * 4))
+#define MSM_TRIG_A2Q6_SMD_INT
+#define MSM_TRIG_A2M_SMSM_INT \
+ (smd_write_intr(1, MSM_CSR_BASE + 0x400 + (5) * 4))
+#define MSM_TRIG_A2Q6_SMSM_INT
+#define MSM_TRIG_A2DSPS_SMD_INT
+#define MSM_TRIG_A2DSPS_SMSM_INT
+#define MSM_TRIG_A2WCNSS_SMD_INT
+#define MSM_TRIG_A2WCNSS_SMSM_INT
+#else /* use platform device / device tree configuration */
+#define MSM_TRIG_A2M_SMD_INT
+#define MSM_TRIG_A2Q6_SMD_INT
+#define MSM_TRIG_A2M_SMSM_INT
+#define MSM_TRIG_A2Q6_SMSM_INT
#define MSM_TRIG_A2DSPS_SMD_INT
#define MSM_TRIG_A2DSPS_SMSM_INT
#define MSM_TRIG_A2WCNSS_SMD_INT
@@ -349,33 +360,42 @@
{
static const struct interrupt_config_item *intr
= &private_intr_config[SMD_MODEM].smd;
- if (intr->out_base)
+ if (intr->out_base) {
+ ++interrupt_stats[SMD_MODEM].smd_out_config_count;
smd_write_intr(intr->out_bit_pos,
intr->out_base + intr->out_offset);
- else
+ } else {
+ ++interrupt_stats[SMD_MODEM].smd_out_hardcode_count;
MSM_TRIG_A2M_SMD_INT;
+ }
}
static inline void notify_dsp_smd(void)
{
static const struct interrupt_config_item *intr
= &private_intr_config[SMD_Q6].smd;
- if (intr->out_base)
+ if (intr->out_base) {
+ ++interrupt_stats[SMD_Q6].smd_out_config_count;
smd_write_intr(intr->out_bit_pos,
intr->out_base + intr->out_offset);
- else
+ } else {
+ ++interrupt_stats[SMD_Q6].smd_out_hardcode_count;
MSM_TRIG_A2Q6_SMD_INT;
+ }
}
static inline void notify_dsps_smd(void)
{
static const struct interrupt_config_item *intr
= &private_intr_config[SMD_DSPS].smd;
- if (intr->out_base)
+ if (intr->out_base) {
+ ++interrupt_stats[SMD_DSPS].smd_out_config_count;
smd_write_intr(intr->out_bit_pos,
intr->out_base + intr->out_offset);
- else
+ } else {
+ ++interrupt_stats[SMD_DSPS].smd_out_hardcode_count;
MSM_TRIG_A2DSPS_SMD_INT;
+ }
}
static inline void notify_wcnss_smd(void)
@@ -384,44 +404,56 @@
= &private_intr_config[SMD_WCNSS].smd;
wakeup_v1_riva();
- if (intr->out_base)
+ if (intr->out_base) {
+ ++interrupt_stats[SMD_WCNSS].smd_out_config_count;
smd_write_intr(intr->out_bit_pos,
intr->out_base + intr->out_offset);
- else
+ } else {
+ ++interrupt_stats[SMD_WCNSS].smd_out_hardcode_count;
MSM_TRIG_A2WCNSS_SMD_INT;
+ }
}
static inline void notify_modem_smsm(void)
{
static const struct interrupt_config_item *intr
= &private_intr_config[SMD_MODEM].smsm;
- if (intr->out_base)
+ if (intr->out_base) {
+ ++interrupt_stats[SMD_MODEM].smsm_out_config_count;
smd_write_intr(intr->out_bit_pos,
intr->out_base + intr->out_offset);
- else
+ } else {
+ ++interrupt_stats[SMD_MODEM].smsm_out_hardcode_count;
MSM_TRIG_A2M_SMSM_INT;
+ }
}
static inline void notify_dsp_smsm(void)
{
static const struct interrupt_config_item *intr
= &private_intr_config[SMD_Q6].smsm;
- if (intr->out_base)
+ if (intr->out_base) {
+ ++interrupt_stats[SMD_Q6].smsm_out_config_count;
smd_write_intr(intr->out_bit_pos,
intr->out_base + intr->out_offset);
- else
+ } else {
+ ++interrupt_stats[SMD_Q6].smsm_out_hardcode_count;
MSM_TRIG_A2Q6_SMSM_INT;
+ }
}
static inline void notify_dsps_smsm(void)
{
static const struct interrupt_config_item *intr
= &private_intr_config[SMD_DSPS].smsm;
- if (intr->out_base)
+ if (intr->out_base) {
+ ++interrupt_stats[SMD_DSPS].smsm_out_config_count;
smd_write_intr(intr->out_bit_pos,
intr->out_base + intr->out_offset);
- else
+ } else {
+ ++interrupt_stats[SMD_DSPS].smsm_out_hardcode_count;
MSM_TRIG_A2DSPS_SMSM_INT;
+ }
}
static inline void notify_wcnss_smsm(void)
@@ -430,11 +462,14 @@
= &private_intr_config[SMD_WCNSS].smsm;
wakeup_v1_riva();
- if (intr->out_base)
+ if (intr->out_base) {
+ ++interrupt_stats[SMD_WCNSS].smsm_out_config_count;
smd_write_intr(intr->out_bit_pos,
intr->out_base + intr->out_offset);
- else
+ } else {
+ ++interrupt_stats[SMD_WCNSS].smsm_out_hardcode_count;
MSM_TRIG_A2WCNSS_SMSM_INT;
+ }
}
static void notify_other_smsm(uint32_t smsm_entry, uint32_t notify_mask)
@@ -589,27 +624,28 @@
struct edge_to_pid {
uint32_t local_pid;
uint32_t remote_pid;
+ char subsys_name[SMD_MAX_CH_NAME_LEN];
};
/**
* Maps edge type to local and remote processor ID's.
*/
static struct edge_to_pid edge_to_pids[] = {
- [SMD_APPS_MODEM] = {SMSM_APPS, SMSM_MODEM},
- [SMD_APPS_QDSP] = {SMSM_APPS, SMSM_Q6},
- [SMD_MODEM_QDSP] = {SMSM_MODEM, SMSM_Q6},
- [SMD_APPS_DSPS] = {SMSM_APPS, SMSM_DSPS},
- [SMD_MODEM_DSPS] = {SMSM_MODEM, SMSM_DSPS},
- [SMD_QDSP_DSPS] = {SMSM_Q6, SMSM_DSPS},
- [SMD_APPS_WCNSS] = {SMSM_APPS, SMSM_WCNSS},
- [SMD_MODEM_WCNSS] = {SMSM_MODEM, SMSM_WCNSS},
- [SMD_QDSP_WCNSS] = {SMSM_Q6, SMSM_WCNSS},
- [SMD_DSPS_WCNSS] = {SMSM_DSPS, SMSM_WCNSS},
- [SMD_APPS_Q6FW] = {SMSM_APPS, SMD_MODEM_Q6_FW},
- [SMD_MODEM_Q6FW] = {SMSM_MODEM, SMD_MODEM_Q6_FW},
- [SMD_QDSP_Q6FW] = {SMSM_Q6, SMD_MODEM_Q6_FW},
- [SMD_DSPS_Q6FW] = {SMSM_DSPS, SMD_MODEM_Q6_FW},
- [SMD_WCNSS_Q6FW] = {SMSM_WCNSS, SMD_MODEM_Q6_FW},
+ [SMD_APPS_MODEM] = {SMD_APPS, SMD_MODEM, "modem"},
+ [SMD_APPS_QDSP] = {SMD_APPS, SMD_Q6, "q6"},
+ [SMD_MODEM_QDSP] = {SMD_MODEM, SMD_Q6},
+ [SMD_APPS_DSPS] = {SMD_APPS, SMD_DSPS, "dsps"},
+ [SMD_MODEM_DSPS] = {SMD_MODEM, SMD_DSPS},
+ [SMD_QDSP_DSPS] = {SMD_Q6, SMD_DSPS},
+ [SMD_APPS_WCNSS] = {SMD_APPS, SMD_WCNSS, "wcnss"},
+ [SMD_MODEM_WCNSS] = {SMD_MODEM, SMD_WCNSS},
+ [SMD_QDSP_WCNSS] = {SMD_Q6, SMD_WCNSS},
+ [SMD_DSPS_WCNSS] = {SMD_DSPS, SMD_WCNSS},
+ [SMD_APPS_Q6FW] = {SMD_APPS, SMD_MODEM_Q6_FW},
+ [SMD_MODEM_Q6FW] = {SMD_MODEM, SMD_MODEM_Q6_FW},
+ [SMD_QDSP_Q6FW] = {SMD_Q6, SMD_MODEM_Q6_FW},
+ [SMD_DSPS_Q6FW] = {SMD_DSPS, SMD_MODEM_Q6_FW},
+ [SMD_WCNSS_Q6FW] = {SMD_WCNSS, SMD_MODEM_Q6_FW},
};
struct restart_notifier_block {
@@ -721,6 +757,50 @@
return ret;
}
+/*
+ * Returns a pointer to the subsystem name or NULL if no
+ * subsystem name is available.
+ *
+ * @type - Edge definition
+ */
+const char *smd_edge_to_subsystem(uint32_t type)
+{
+ const char *subsys = NULL;
+
+ if (type < ARRAY_SIZE(edge_to_pids)) {
+ subsys = edge_to_pids[type].subsys_name;
+ if (subsys[0] == 0x0)
+ subsys = NULL;
+ }
+ return subsys;
+}
+EXPORT_SYMBOL(smd_edge_to_subsystem);
+
+/*
+ * Returns a pointer to the subsystem name given the
+ * remote processor ID.
+ *
+ * @pid Remote processor ID
+ * @returns Pointer to subsystem name or NULL if not found
+ */
+const char *smd_pid_to_subsystem(uint32_t pid)
+{
+ const char *subsys = NULL;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(edge_to_pids); ++i) {
+ if (pid == edge_to_pids[i].remote_pid &&
+ edge_to_pids[i].subsys_name[0] != 0x0
+ ) {
+ subsys = edge_to_pids[i].subsys_name;
+ break;
+ }
+ }
+
+ return subsys;
+}
+EXPORT_SYMBOL(smd_pid_to_subsystem);
+
static void smd_reset_edge(struct smd_half_channel *ch, unsigned new_state)
{
if (ch->state != SMD_SS_CLOSED) {
@@ -796,9 +876,10 @@
/* notify SMSM processors */
smsm_irq_handler(0, 0);
- MSM_TRIG_A2M_SMSM_INT;
- MSM_TRIG_A2Q6_SMSM_INT;
- MSM_TRIG_A2DSPS_SMSM_INT;
+ notify_modem_smsm();
+ notify_dsp_smsm();
+ notify_dsps_smsm();
+ notify_wcnss_smsm();
}
/* change all remote states to CLOSING */
@@ -1110,15 +1191,24 @@
}
tmp = ch->recv->state;
if (tmp != ch->last_state) {
+ SMx_POWER_INFO("SMD ch%d '%s' State change %d->%d\n",
+ ch->n, ch->name, ch->last_state, tmp);
smd_state_change(ch, ch->last_state, tmp);
state_change = 1;
}
- if (ch_flags) {
+ if (ch_flags & 0x3) {
ch->update_state(ch);
+ SMx_POWER_INFO("SMD ch%d '%s' Data event r%d/w%d\n",
+ ch->n, ch->name,
+ ch->read_avail(ch),
+ ch->fifo_size - ch->write_avail(ch));
ch->notify(ch->priv, SMD_EVENT_DATA);
}
- if (ch_flags & 0x4 && !state_change)
+ if (ch_flags & 0x4 && !state_change) {
+ SMx_POWER_INFO("SMD ch%d '%s' State update\n",
+ ch->n, ch->name);
ch->notify(ch->priv, SMD_EVENT_STATUS);
+ }
}
spin_unlock_irqrestore(&smd_lock, flags);
do_smd_probe();
@@ -1126,6 +1216,8 @@
static irqreturn_t smd_modem_irq_handler(int irq, void *data)
{
+ SMx_POWER_INFO("SMD Int Modem->Apps\n");
+ ++interrupt_stats[SMD_MODEM].smd_in_count;
handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
@@ -1133,6 +1225,8 @@
static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
{
+ SMx_POWER_INFO("SMD Int LPASS->Apps\n");
+ ++interrupt_stats[SMD_Q6].smd_in_count;
handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
@@ -1140,6 +1234,8 @@
static irqreturn_t smd_dsps_irq_handler(int irq, void *data)
{
+ SMx_POWER_INFO("SMD Int DSPS->Apps\n");
+ ++interrupt_stats[SMD_DSPS].smd_in_count;
handle_smd_irq(&smd_ch_list_dsps, notify_dsps_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
@@ -1147,6 +1243,8 @@
static irqreturn_t smd_wcnss_irq_handler(int irq, void *data)
{
+ SMx_POWER_INFO("SMD Int WCNSS->Apps\n");
+ ++interrupt_stats[SMD_WCNSS].smd_in_count;
handle_smd_irq(&smd_ch_list_wcnss, notify_wcnss_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
@@ -2286,6 +2384,34 @@
return IRQ_HANDLED;
}
+static irqreturn_t smsm_modem_irq_handler(int irq, void *data)
+{
+ SMx_POWER_INFO("SMSM Int Modem->Apps\n");
+ ++interrupt_stats[SMD_MODEM].smsm_in_count;
+ return smsm_irq_handler(irq, data);
+}
+
+static irqreturn_t smsm_dsp_irq_handler(int irq, void *data)
+{
+ SMx_POWER_INFO("SMSM Int LPASS->Apps\n");
+ ++interrupt_stats[SMD_Q6].smsm_in_count;
+ return smsm_irq_handler(irq, data);
+}
+
+static irqreturn_t smsm_dsps_irq_handler(int irq, void *data)
+{
+ SMx_POWER_INFO("SMSM Int DSPS->Apps\n");
+ ++interrupt_stats[SMD_DSPS].smsm_in_count;
+ return smsm_irq_handler(irq, data);
+}
+
+static irqreturn_t smsm_wcnss_irq_handler(int irq, void *data)
+{
+ SMx_POWER_INFO("SMSM Int WCNSS->Apps\n");
+ ++interrupt_stats[SMD_WCNSS].smsm_in_count;
+ return smsm_irq_handler(irq, data);
+}
+
int smsm_change_intr_mask(uint32_t smsm_entry,
uint32_t clear_mask, uint32_t set_mask)
{
@@ -2417,6 +2543,9 @@
state_changes = state_info->last_value ^ new_state;
if (state_changes) {
+ SMx_POWER_INFO("SMSM Change %d: %08x->%08x\n",
+ n, state_info->last_value,
+ new_state);
list_for_each_entry(cb_info,
&state_info->callbacks, cb_list) {
@@ -2567,7 +2696,7 @@
pr_err("smd_core_init: "
"enable_irq_wake failed for INT_A9_M2A_0\n");
- r = request_irq(INT_A9_M2A_5, smsm_irq_handler,
+ r = request_irq(INT_A9_M2A_5, smsm_modem_irq_handler,
flags, "smsm_dev", 0);
if (r < 0) {
free_irq(INT_A9_M2A_0, 0);
@@ -2590,8 +2719,8 @@
return r;
}
- r = request_irq(INT_ADSP_A11_SMSM, smsm_irq_handler,
- flags, "smsm_dev", smsm_irq_handler);
+ r = request_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler,
+ flags, "smsm_dev", smsm_dsp_irq_handler);
if (r < 0) {
free_irq(INT_A9_M2A_0, 0);
free_irq(INT_A9_M2A_5, 0);
@@ -2620,7 +2749,7 @@
free_irq(INT_A9_M2A_0, 0);
free_irq(INT_A9_M2A_5, 0);
free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
- free_irq(INT_ADSP_A11_SMSM, smsm_irq_handler);
+ free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
return r;
}
@@ -2637,7 +2766,7 @@
free_irq(INT_A9_M2A_0, 0);
free_irq(INT_A9_M2A_5, 0);
free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
- free_irq(INT_ADSP_A11_SMSM, smsm_irq_handler);
+ free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
free_irq(INT_DSPS_A11, smd_dsps_irq_handler);
return r;
}
@@ -2647,13 +2776,13 @@
pr_err("smd_core_init: "
"enable_irq_wake failed for INT_WCNSS_A11\n");
- r = request_irq(INT_WCNSS_A11_SMSM, smsm_irq_handler,
- flags, "smsm_dev", smsm_irq_handler);
+ r = request_irq(INT_WCNSS_A11_SMSM, smsm_wcnss_irq_handler,
+ flags, "smsm_dev", smsm_wcnss_irq_handler);
if (r < 0) {
free_irq(INT_A9_M2A_0, 0);
free_irq(INT_A9_M2A_5, 0);
free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
- free_irq(INT_ADSP_A11_SMSM, smsm_irq_handler);
+ free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
free_irq(INT_DSPS_A11, smd_dsps_irq_handler);
free_irq(INT_WCNSS_A11, smd_wcnss_irq_handler);
return r;
@@ -2666,16 +2795,16 @@
#endif
#if defined(CONFIG_DSPS_SMSM)
- r = request_irq(INT_DSPS_A11_SMSM, smsm_irq_handler,
- flags, "smsm_dev", smsm_irq_handler);
+ r = request_irq(INT_DSPS_A11_SMSM, smsm_dsps_irq_handler,
+ flags, "smsm_dev", smsm_dsps_irq_handler);
if (r < 0) {
free_irq(INT_A9_M2A_0, 0);
free_irq(INT_A9_M2A_5, 0);
free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
- free_irq(INT_ADSP_A11_SMSM, smsm_irq_handler);
+ free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
free_irq(INT_DSPS_A11, smd_dsps_irq_handler);
free_irq(INT_WCNSS_A11, smd_wcnss_irq_handler);
- free_irq(INT_WCNSS_A11_SMSM, smsm_irq_handler);
+ free_irq(INT_WCNSS_A11_SMSM, smsm_wcnss_irq_handler);
return r;
}
@@ -2770,6 +2899,9 @@
cfg->smsm_int.irq_name);
break;
}
+
+ strncpy(edge_to_pids[cfg->edge].subsys_name,
+ cfg->subsys_name, SMD_MAX_CH_NAME_LEN);
}
if (err_ret < 0) {
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
index b95a35c..764102d 100644
--- a/arch/arm/mach-msm/smd_debug.c
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -95,6 +95,61 @@
return max;
}
+static int debug_int_stats(char *buf, int max)
+{
+ int i = 0;
+ int subsys;
+ struct interrupt_stat *stats = interrupt_stats;
+ const char *subsys_name;
+
+ i += scnprintf(buf + i, max - i,
+ " Subsystem | In | Out (Hardcoded) |"
+ " Out (Configured) |\n");
+
+ for (subsys = 0; subsys < NUM_SMD_SUBSYSTEMS; ++subsys) {
+ subsys_name = smd_pid_to_subsystem(subsys);
+ if (subsys_name) {
+ i += scnprintf(buf + i, max - i,
+ "%-10s %4s | %9u | %9u | %9u |\n",
+ smd_pid_to_subsystem(subsys), "smd",
+ stats->smd_in_count,
+ stats->smd_out_hardcode_count,
+ stats->smd_out_config_count);
+
+ i += scnprintf(buf + i, max - i,
+ "%-10s %4s | %9u | %9u | %9u |\n",
+ smd_pid_to_subsystem(subsys), "smsm",
+ stats->smsm_in_count,
+ stats->smsm_out_hardcode_count,
+ stats->smsm_out_config_count);
+ }
+ ++stats;
+ }
+
+ return i;
+}
+
+static int debug_int_stats_reset(char *buf, int max)
+{
+ int i = 0;
+ int subsys;
+ struct interrupt_stat *stats = interrupt_stats;
+
+ i += scnprintf(buf + i, max - i, "Resetting interrupt stats.\n");
+
+ for (subsys = 0; subsys < NUM_SMD_SUBSYSTEMS; ++subsys) {
+ stats->smd_in_count = 0;
+ stats->smd_out_hardcode_count = 0;
+ stats->smd_out_config_count = 0;
+ stats->smsm_in_count = 0;
+ stats->smsm_out_hardcode_count = 0;
+ stats->smsm_out_config_count = 0;
+ ++stats;
+ }
+
+ return i;
+}
+
static int debug_diag(char *buf, int max)
{
int i = 0;
@@ -694,6 +749,8 @@
debug_create("modem_err_f3", 0444, dent, debug_modem_err_f3);
debug_create("print_diag", 0444, dent, debug_diag);
debug_create("print_f3", 0444, dent, debug_f3);
+ debug_create("int_stats", 0444, dent, debug_int_stats);
+ debug_create("int_stats_reset", 0444, dent, debug_int_stats_reset);
/* NNV: this is google only stuff */
debug_create("build", 0444, dent, debug_read_build_id);
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index aeffbfd..158015a 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -607,7 +607,7 @@
{
int r = 0;
struct smd_pkt_dev *smd_pkt_devp;
- char *peripheral = NULL;
+ const char *peripheral = NULL;
smd_pkt_devp = container_of(inode->i_cdev, struct smd_pkt_dev, cdev);
@@ -622,12 +622,8 @@
mutex_lock(&smd_pkt_devp->ch_lock);
if (smd_pkt_devp->ch == 0) {
-
- if (smd_ch_edge[smd_pkt_devp->i] == SMD_APPS_MODEM)
- peripheral = "modem";
- else if (smd_ch_edge[smd_pkt_devp->i] == SMD_APPS_QDSP)
- peripheral = "q6";
-
+ peripheral = smd_edge_to_subsystem(
+ smd_ch_edge[smd_pkt_devp->i]);
if (peripheral) {
smd_pkt_devp->pil = pil_get(peripheral);
if (IS_ERR(smd_pkt_devp->pil)) {
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
index a4c60e8..e39c57b 100644
--- a/arch/arm/mach-msm/smd_private.h
+++ b/arch/arm/mach-msm/smd_private.h
@@ -1,7 +1,7 @@
/* arch/arm/mach-msm/smd_private.h
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -19,6 +19,7 @@
#include <linux/types.h>
#include <linux/spinlock.h>
#include <mach/msm_smsm.h>
+#include <mach/msm_smd.h>
#define PC_APPS 0
#define PC_MODEM 1
@@ -208,4 +209,15 @@
void smd_diag(void);
+struct interrupt_stat {
+ uint32_t smd_in_count;
+ uint32_t smd_out_hardcode_count;
+ uint32_t smd_out_config_count;
+
+ uint32_t smsm_in_count;
+ uint32_t smsm_out_hardcode_count;
+ uint32_t smsm_out_config_count;
+};
+extern struct interrupt_stat interrupt_stats[NUM_SMD_SUBSYSTEMS];
+
#endif
diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
index 4248be4..d856024 100644
--- a/arch/arm/mach-msm/smd_tty.c
+++ b/arch/arm/mach-msm/smd_tty.c
@@ -235,7 +235,7 @@
int res = 0;
unsigned int n = tty->index;
struct smd_tty_info *info;
- char *peripheral = NULL;
+ const char *peripheral = NULL;
if (n >= MAX_SMD_TTYS || !smd_tty[n].smd)
@@ -247,9 +247,7 @@
tty->driver_data = info;
if (info->open_count++ == 0) {
- if (smd_tty[n].smd->edge == SMD_APPS_MODEM)
- peripheral = "modem";
-
+ peripheral = smd_edge_to_subsystem(smd_tty[n].smd->edge);
if (peripheral) {
info->pil = pil_get(peripheral);
if (IS_ERR(info->pil)) {
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index 9970c90..59abfe6 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -35,6 +35,7 @@
static void riva_fatal_fn(struct work_struct *);
static DECLARE_WORK(riva_fatal_work, riva_fatal_fn);
+static struct delayed_work cancel_vote_work;
static void *riva_ramdump_dev;
static int riva_crash;
static int ss_restart_inprogress;
@@ -97,20 +98,24 @@
smsm_change_state(SMSM_APPS_STATE, SMSM_RESET, SMSM_RESET);
}
-/* Subsystem handlers */
-static int riva_shutdown(const struct subsys_data *subsys)
+static void riva_post_bootup(struct work_struct *work)
{
struct platform_device *pdev = wcnss_get_platform_device();
struct wcnss_wlan_config *pwlanconfig = wcnss_get_wlan_config();
- int ret = -1;
+ pr_debug(MODULE_NAME ": Cancel APPS vote for Iris & Riva\n");
+
+ wcnss_wlan_power(&pdev->dev, pwlanconfig,
+ WCNSS_WLAN_SWITCH_OFF);
+}
+
+/* Subsystem handlers */
+static int riva_shutdown(const struct subsys_data *subsys)
+{
pil_force_shutdown("wcnss");
+ flush_delayed_work(&cancel_vote_work);
- /* proxy vote on behalf of Riva */
- if (pdev && pwlanconfig)
- ret = wcnss_wlan_power(&pdev->dev, pwlanconfig,
- WCNSS_WLAN_SWITCH_OFF);
- return ret;
+ return 0;
}
static int riva_powerup(const struct subsys_data *subsys)
@@ -131,6 +136,7 @@
}
ss_restart_inprogress = false;
enable_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ);
+ schedule_delayed_work(&cancel_vote_work, msecs_to_jiffies(5000));
return ret;
}
@@ -222,6 +228,8 @@
ret = -ENOMEM;
goto out;
}
+ INIT_DELAYED_WORK(&cancel_vote_work, riva_post_bootup);
+
pr_info("%s: module initialized\n", MODULE_NAME);
out:
return ret;
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 321abe8..edede47 100755
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1140,3 +1140,4 @@
mpq8064_dtv MACH_MPQ8064_DTV MPQ8064_DTV 3995
msm7627a_qrd3 MACH_MSM7627A_QRD3 MSM7627A_QRD3 4005
msm8625_surf MACH_MSM8625_SURF MSM8625_SURF 4037
+msm8625_evb MACH_MSM8625_EVB MSM8625_EVB 4042
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 371d319..a701773 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -228,6 +228,7 @@
int hsic_ch;
int hsic_device_enabled;
int hsic_device_opened;
+ int hsic_suspend;
int read_len_mdm;
int in_busy_hsic_read_on_mdm;
int in_busy_hsic_write_on_mdm;
@@ -238,6 +239,8 @@
struct workqueue_struct *diag_hsic_wq;
struct work_struct diag_read_mdm_work;
struct work_struct diag_read_hsic_work;
+ struct work_struct diag_disconnect_work;
+ struct work_struct diag_usb_read_complete_work;
struct diag_request *usb_read_mdm_ptr;
struct diag_request *write_ptr_mdm;
#endif
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index efba92b..d9f12ac 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -48,7 +48,7 @@
};
/* The following variables can be specified by module options */
/* for copy buffer */
-static unsigned int itemsize = 2048; /*Size of item in the mempool */
+static unsigned int itemsize = 4096; /*Size of item in the mempool */
static unsigned int poolsize = 10; /*Number of items in the mempool */
/* for hdlc buffer */
static unsigned int itemsize_hdlc = 8192; /*Size of item in the mempool */
@@ -768,6 +768,14 @@
return 0;
}
+ if (payload_size > itemsize) {
+ pr_err("diag: Dropping packet, packet payload size crosses"
+ "4KB limit. Current payload size %d\n",
+ payload_size);
+ driver->dropped_count++;
+ return -EBADMSG;
+ }
+
buf_copy = diagmem_alloc(driver, payload_size, POOL_TYPE_COPY);
if (!buf_copy) {
driver->dropped_count++;
diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c
index ac5722f..b2080b3 100644
--- a/drivers/char/diag/diagfwd_hsic.c
+++ b/drivers/char/diag/diagfwd_hsic.c
@@ -102,14 +102,16 @@
driver->write_ptr_mdm);
}
} else {
- pr_err("DIAG in %s: actual_size: %d\n", __func__, actual_size);
+ pr_debug("%s: actual_size: %d\n", __func__, actual_size);
}
/*
* If for some reason there was no hsic data to write to the
* mdm channel, set up another read
*/
- if (!driver->in_busy_hsic_write_on_mdm)
+ if (!driver->in_busy_hsic_write_on_mdm &&
+ driver->usb_mdm_connected &&
+ !driver->hsic_suspend)
queue_work(driver->diag_hsic_wq, &driver->diag_read_hsic_work);
}
@@ -127,13 +129,34 @@
if (actual_size < 0)
pr_err("DIAG in %s: actual_size: %d\n", __func__, actual_size);
- queue_work(driver->diag_hsic_wq, &driver->diag_read_mdm_work);
+ if (driver->usb_mdm_connected)
+ queue_work(driver->diag_hsic_wq, &driver->diag_read_mdm_work);
+}
+
+static int diag_hsic_suspend(void *ctxt)
+{
+ if (driver->in_busy_hsic_write)
+ return -EBUSY;
+
+ driver->hsic_suspend = 1;
+
+ return 0;
+}
+
+static void diag_hsic_resume(void *ctxt)
+{
+ driver->hsic_suspend = 0;
+
+ if (!driver->in_busy_hsic_write_on_mdm && driver->usb_mdm_connected)
+ queue_work(driver->diag_hsic_wq, &driver->diag_read_hsic_work);
}
static struct diag_bridge_ops hsic_diag_bridge_ops = {
.ctxt = NULL,
.read_complete_cb = diag_hsic_read_complete_callback,
.write_complete_cb = diag_hsic_write_complete_callback,
+ .suspend = diag_hsic_suspend,
+ .resume = diag_hsic_resume,
};
static int diag_hsic_close(void)
@@ -177,11 +200,11 @@
pr_err("DIAG: HSIC channel open error: %d\n",
err);
} else {
- pr_info("DIAG: opened HSIC channel\n");
+ pr_debug("DIAG: opened HSIC channel\n");
driver->hsic_device_opened = 1;
}
} else {
- pr_info("DIAG: HSIC channel already open\n");
+ pr_debug("DIAG: HSIC channel already open\n");
}
/*
@@ -220,9 +243,7 @@
driver->in_busy_hsic_read = 1;
/* Turn off communication over usb mdm and hsic */
- driver->hsic_ch = 0;
-
- return 0;
+ return diag_hsic_close();
}
/*
@@ -311,10 +332,11 @@
diagfwd_connect_hsic();
break;
case USB_DIAG_DISCONNECT:
- diagfwd_disconnect_hsic();
+ queue_work(driver->diag_hsic_wq, &driver->diag_disconnect_work);
break;
case USB_DIAG_READ_DONE:
- diagfwd_read_complete_hsic(d_req);
+ queue_work(driver->diag_hsic_wq,
+ &driver->diag_usb_read_complete_work);
break;
case USB_DIAG_WRITE_DONE:
diagfwd_write_complete_hsic();
@@ -326,6 +348,16 @@
}
}
+static void diag_usb_read_complete_fn(struct work_struct *w)
+{
+ diagfwd_read_complete_hsic(driver->usb_read_mdm_ptr);
+}
+
+static void diag_disconnect_work_fn(struct work_struct *w)
+{
+ diagfwd_disconnect_hsic();
+}
+
static void diag_read_mdm_work_fn(struct work_struct *work)
{
if (!driver->hsic_ch) {
@@ -380,7 +412,6 @@
sizeof(struct diag_request), GFP_KERNEL);
if (driver->usb_read_mdm_ptr == NULL)
goto err;
- driver->diag_hsic_wq = create_singlethread_workqueue("diag_hsic_wq");
#ifdef CONFIG_DIAG_OVER_USB
INIT_WORK(&(driver->diag_read_mdm_work), diag_read_mdm_work_fn);
#endif
@@ -413,23 +444,22 @@
}
}
- /* The hsic (diag_bridge) platform device driver is enabled */
- err = diag_bridge_open(&hsic_diag_bridge_ops);
- if (err) {
- pr_err("DIAG could not open HSIC channel, err: %d\n", err);
- driver->hsic_device_opened = 0;
- return err;
- }
-
- pr_info("DIAG opened HSIC channel\n");
- driver->hsic_device_opened = 1;
-
/*
* The probe function was called after the usb was connected
* on the legacy channel. Communication over usb mdm and hsic
* needs to be turned on.
*/
- if (driver->usb_connected) {
+ if (driver->usb_mdm_connected) {
+ /* The hsic (diag_bridge) platform device driver is enabled */
+ 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;
+ return err;
+ }
+
+ pr_debug("DIAG opened HSIC channel\n");
+ driver->hsic_device_opened = 1;
driver->hsic_ch = 1;
driver->in_busy_hsic_write_on_mdm = 0;
driver->in_busy_hsic_read_on_mdm = 0;
@@ -448,7 +478,7 @@
static int diag_hsic_remove(struct platform_device *pdev)
{
- pr_info("DIAG: %s called\n", __func__);
+ pr_debug("DIAG: %s called\n", __func__);
diag_hsic_close();
return 0;
}
@@ -487,6 +517,11 @@
pr_debug("DIAG in %s\n", __func__);
+ driver->diag_hsic_wq = create_singlethread_workqueue("diag_hsic_wq");
+ INIT_WORK(&(driver->diag_disconnect_work), diag_disconnect_work_fn);
+ INIT_WORK(&(driver->diag_usb_read_complete_work),
+ diag_usb_read_complete_fn);
+
#ifdef CONFIG_DIAG_OVER_USB
driver->mdm_ch = usb_diag_open(DIAG_MDM, driver, diagfwd_hsic_notifier);
if (IS_ERR(driver->mdm_ch)) {
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index bd48925..3d9c9d1 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -749,7 +749,8 @@
}
static int get_img(struct msmfb_data *fbd, unsigned long *start,
- unsigned long *len, struct file **p_file, struct ion_handle **p_ihdl)
+ unsigned long *len, struct file **p_file, int *p_need,
+ struct ion_handle **p_ihdl)
{
int ret = 0;
#ifdef CONFIG_FB
@@ -760,6 +761,8 @@
unsigned long vstart;
#endif
+ *p_need = 0;
+
#ifdef CONFIG_FB
if (fbd->flags & MDP_MEMORY_ID_TYPE_FB) {
file = fget_light(fbd->memory_id, &put_needed);
@@ -770,8 +773,10 @@
fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
if (get_fb_phys_info(start, len, fb_num))
ret = -1;
- else
+ else {
*p_file = file;
+ *p_need = put_needed;
+ }
} else
ret = -1;
if (ret)
@@ -822,6 +827,7 @@
struct file *srcp1_file = NULL, *dstp1_file = NULL;
struct ion_handle *srcp0_ihdl = NULL, *dstp0_ihdl = NULL;
struct ion_handle *srcp1_ihdl = NULL, *dstp1_ihdl = NULL;
+ int ps0_need, p_need;
unsigned int in_chroma_paddr = 0, out_chroma_paddr = 0;
unsigned int in_chroma2_paddr = 0;
struct msm_rotator_img_info *img_info;
@@ -872,8 +878,9 @@
goto do_rotate_unlock_mutex;
}
+
rc = get_img(&info.src, (unsigned long *)&in_paddr,
- (unsigned long *)&src_len, &srcp0_file, &srcp0_ihdl);
+ (unsigned long *)&src_len, &srcp0_file, &ps0_need, &srcp0_ihdl);
if (rc) {
pr_err("%s: in get_img() failed id=0x%08x\n",
DRIVER_NAME, info.src.memory_id);
@@ -881,7 +888,7 @@
}
rc = get_img(&info.dst, (unsigned long *)&out_paddr,
- (unsigned long *)&dst_len, &dstp0_file, &dstp0_ihdl);
+ (unsigned long *)&dst_len, &dstp0_file, &p_need, &dstp0_ihdl);
if (rc) {
pr_err("%s: out get_img() failed id=0x%08x\n",
DRIVER_NAME, info.dst.memory_id);
@@ -911,7 +918,7 @@
rc = get_img(&info.src_chroma,
(unsigned long *)&in_chroma_paddr,
- (unsigned long *)&src_len, &srcp1_file,
+ (unsigned long *)&src_len, &srcp1_file, &p_need,
&srcp1_ihdl);
if (rc) {
pr_err("%s: in chroma get_img() failed id=0x%08x\n",
@@ -921,7 +928,7 @@
rc = get_img(&info.dst_chroma,
(unsigned long *)&out_chroma_paddr,
- (unsigned long *)&dst_len, &dstp1_file,
+ (unsigned long *)&dst_len, &dstp1_file, &p_need,
&dstp1_ihdl);
if (rc) {
pr_err("%s: out chroma get_img() failed id=0x%08x\n",
@@ -1089,7 +1096,12 @@
put_img(dstp1_file, dstp1_ihdl);
put_img(srcp1_file, srcp1_ihdl);
put_img(dstp0_file, dstp0_ihdl);
- put_img(srcp0_file, srcp0_ihdl);
+
+ /* only source may use frame buffer */
+ if (info.src.flags & MDP_MEMORY_ID_TYPE_FB)
+ fput_light(srcp0_file, ps0_need);
+ else
+ put_img(srcp0_file, srcp0_ihdl);
mutex_unlock(&msm_rotator_dev->rotator_lock);
dev_dbg(msm_rotator_dev->device, "%s() returning rc = %d\n",
__func__, rc);
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index c1a65fc..fff494c 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1,6 +1,6 @@
/* Qualcomm CE device driver.
*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -172,7 +172,7 @@
#endif
}
-static int qcedev_ce_high_bw_req(struct qcedev_control *podev,
+static void qcedev_ce_high_bw_req(struct qcedev_control *podev,
bool high_bw_req)
{
int ret = 0;
@@ -180,18 +180,22 @@
mutex_lock(&sent_bw_req);
if (high_bw_req) {
if (podev->high_bw_req_count == 0)
- msm_bus_scale_client_update_request(
+ ret = msm_bus_scale_client_update_request(
podev->bus_scale_handle, 1);
+ if (ret)
+ pr_err("%s Unable to set to high bandwidth\n",
+ __func__);
podev->high_bw_req_count++;
} else {
if (podev->high_bw_req_count == 1)
- msm_bus_scale_client_update_request(
+ ret = msm_bus_scale_client_update_request(
podev->bus_scale_handle, 0);
+ if (ret)
+ pr_err("%s Unable to set to low bandwidth\n",
+ __func__);
podev->high_bw_req_count--;
}
mutex_unlock(&sent_bw_req);
-
- return ret;
}
@@ -331,7 +335,7 @@
handle->cntl = podev;
file->private_data = handle;
if (podev->platform_support.bus_scale_table != NULL)
- return qcedev_ce_high_bw_req(podev, true);
+ qcedev_ce_high_bw_req(podev, true);
return 0;
}
@@ -349,7 +353,7 @@
kzfree(handle);
file->private_data = NULL;
if (podev->platform_support.bus_scale_table != NULL)
- return qcedev_ce_high_bw_req(podev, false);
+ qcedev_ce_high_bw_req(podev, false);
return 0;
}
@@ -2218,7 +2222,7 @@
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
MODULE_DESCRIPTION("Qualcomm DEV Crypto driver");
-MODULE_VERSION("1.25");
+MODULE_VERSION("1.26");
module_init(qcedev_init);
module_exit(qcedev_exit);
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 3fff05c..21c3aff 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -1,6 +1,6 @@
/* Qualcomm Crypto driver
*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -329,7 +329,7 @@
}
}
-static int qcrypto_ce_high_bw_req(struct crypto_priv *cp, bool high_bw_req)
+static void qcrypto_ce_high_bw_req(struct crypto_priv *cp, bool high_bw_req)
{
int ret = 0;
@@ -338,16 +338,20 @@
if (cp->high_bw_req_count == 0)
ret = msm_bus_scale_client_update_request(
cp->bus_scale_handle, 1);
+ if (ret)
+ pr_err("%s Unable to set to high bandwidth\n",
+ __func__);
cp->high_bw_req_count++;
} else {
if (cp->high_bw_req_count == 1)
ret = msm_bus_scale_client_update_request(
cp->bus_scale_handle, 0);
+ if (ret)
+ pr_err("%s Unable to set to low bandwidth\n",
+ __func__);
cp->high_bw_req_count--;
}
mutex_unlock(&sent_bw_req);
-
- return ret;
}
static void _start_qcrypto_process(struct crypto_priv *cp);
@@ -403,7 +407,7 @@
/* random first IV */
get_random_bytes(ctx->iv, QCRYPTO_MAX_IV_LENGTH);
if (ctx->cp->platform_support.bus_scale_table != NULL)
- return qcrypto_ce_high_bw_req(ctx->cp, true);
+ qcrypto_ce_high_bw_req(ctx->cp, true);
return 0;
};
@@ -440,7 +444,7 @@
sha_ctx->ahash_req = NULL;
if (sha_ctx->cp->platform_support.bus_scale_table != NULL)
- return qcrypto_ce_high_bw_req(sha_ctx->cp, true);
+ qcrypto_ce_high_bw_req(sha_ctx->cp, true);
return 0;
};
@@ -3359,4 +3363,4 @@
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
MODULE_DESCRIPTION("Qualcomm Crypto driver");
-MODULE_VERSION("1.20");
+MODULE_VERSION("1.21");
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index e33155f..ea16c31 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1274,7 +1274,7 @@
default:
KGSL_DRV_INFO(dev_priv->device,
"invalid ioctl code %08x\n", cmd);
- result = -EINVAL;
+ result = -ENOIOCTLCMD;
break;
}
return result;
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index b53ca8f..68299cf 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,7 +23,8 @@
#include "a2xx_reg.h"
unsigned int kgsl_cff_dump_enable;
-int kgsl_pm_regs_enabled;
+int adreno_pm_regs_enabled;
+int adreno_pm_ib_enabled;
static struct dentry *pm_d_debugfs;
@@ -46,20 +47,37 @@
static int pm_regs_enabled_set(void *data, u64 val)
{
- kgsl_pm_regs_enabled = val ? 1 : 0;
+ adreno_pm_regs_enabled = val ? 1 : 0;
return 0;
}
static int pm_regs_enabled_get(void *data, u64 *val)
{
- *val = kgsl_pm_regs_enabled;
+ *val = adreno_pm_regs_enabled;
return 0;
}
+static int pm_ib_enabled_set(void *data, u64 val)
+{
+ adreno_pm_ib_enabled = val ? 1 : 0;
+ return 0;
+}
+
+static int pm_ib_enabled_get(void *data, u64 *val)
+{
+ *val = adreno_pm_ib_enabled;
+ return 0;
+}
+
+
DEFINE_SIMPLE_ATTRIBUTE(pm_regs_enabled_fops,
pm_regs_enabled_get,
pm_regs_enabled_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(pm_ib_enabled_fops,
+ pm_ib_enabled_get,
+ pm_ib_enabled_set, "%llu\n");
+
static int kgsl_cff_dump_enable_set(void *data, u64 val)
{
@@ -358,4 +376,6 @@
&pm_dump_fops);
debugfs_create_file("regs_enabled", 0644, pm_d_debugfs, device,
&pm_regs_enabled_fops);
+ debugfs_create_file("ib_enabled", 0644, pm_d_debugfs, device,
+ &pm_ib_enabled_fops);
}
diff --git a/drivers/gpu/msm/adreno_debugfs.h b/drivers/gpu/msm/adreno_debugfs.h
index 0356ac6..5f8d89a 100644
--- a/drivers/gpu/msm/adreno_debugfs.h
+++ b/drivers/gpu/msm/adreno_debugfs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,11 +17,17 @@
int adreno_debugfs_init(struct kgsl_device *device);
-extern int kgsl_pm_regs_enabled;
+extern int adreno_pm_regs_enabled;
+extern int adreno_pm_ib_enabled;
-static inline int kgsl_pmregs_enabled(void)
+static inline int is_adreno_pm_regs_enabled(void)
{
- return kgsl_pm_regs_enabled;
+ return adreno_pm_regs_enabled;
+}
+
+static inline int is_adreno_pm_ib_enabled(void)
+{
+ return adreno_pm_ib_enabled;
}
#else
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 7902f30..f9e498f 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -294,15 +294,6 @@
}
}
-static bool adreno_ib_dump_enabled(void)
-{
-#ifdef CONFIG_MSM_KGSL_PSTMRTMDMP_NO_IB_DUMP
- return 0;
-#else
- return 1;
-#endif
-}
-
struct log_field {
bool show;
const char *display;
@@ -817,7 +808,7 @@
cp_rb_base, cp_rb_rptr, cp_rb_wptr, read_idx);
adreno_dump_rb(device, rb_copy, num_item<<2, read_idx, rb_count);
- if (adreno_ib_dump_enabled()) {
+ if (is_adreno_pm_ib_enabled()) {
for (read_idx = NUM_DWORDS_OF_RINGBUFFER_HISTORY;
read_idx >= 0; --read_idx) {
uint32_t this_cmd = rb_copy[read_idx];
@@ -849,16 +840,17 @@
}
/* Dump the registers if the user asked for it */
-
- if (adreno_is_a20x(adreno_dev))
- adreno_dump_regs(device, a200_registers,
- a200_registers_count);
- else if (adreno_is_a22x(adreno_dev))
- adreno_dump_regs(device, a220_registers,
- a220_registers_count);
- else if (adreno_is_a3xx(adreno_dev))
- adreno_dump_regs(device, a3xx_registers,
- a3xx_registers_count);
+ if (is_adreno_pm_regs_enabled()) {
+ if (adreno_is_a20x(adreno_dev))
+ adreno_dump_regs(device, a200_registers,
+ a200_registers_count);
+ else if (adreno_is_a22x(adreno_dev))
+ adreno_dump_regs(device, a220_registers,
+ a220_registers_count);
+ else if (adreno_is_a3xx(adreno_dev))
+ adreno_dump_regs(device, a3xx_registers,
+ a3xx_registers_count);
+ }
error_vfree:
vfree(rb_copy);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 45007da..b7356ac 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1024,6 +1024,7 @@
spin_lock(&entry->priv->mem_lock);
list_del(&entry->list);
spin_unlock(&entry->priv->mem_lock);
+ trace_kgsl_mem_timestamp_free(entry, timestamp);
kgsl_mem_entry_put(entry);
}
@@ -1034,12 +1035,18 @@
int result = 0;
struct kgsl_cmdstream_freememontimestamp *param = data;
struct kgsl_mem_entry *entry = NULL;
+ struct kgsl_device *device = dev_priv->device;
+ unsigned int cur;
spin_lock(&dev_priv->process_priv->mem_lock);
entry = kgsl_sharedmem_find(dev_priv->process_priv, param->gpuaddr);
spin_unlock(&dev_priv->process_priv->mem_lock);
if (entry) {
+ cur = device->ftbl->readtimestamp(device,
+ KGSL_TIMESTAMP_RETIRED);
+
+ trace_kgsl_mem_timestamp_queue(entry, cur);
result = kgsl_add_event(dev_priv->device, param->timestamp,
kgsl_freemem_event_cb, entry, dev_priv);
} else {
@@ -1118,6 +1125,7 @@
spin_unlock(&private->mem_lock);
if (entry) {
+ trace_kgsl_mem_free(entry);
kgsl_mem_entry_put(entry);
} else {
KGSL_CORE_ERR("invalid gpuaddr %08x\n", param->gpuaddr);
@@ -1218,6 +1226,7 @@
kgsl_mem_entry_attach_process(entry, private);
+ trace_kgsl_mem_alloc(entry);
/* Process specific statistics */
kgsl_process_add_stats(private, entry->memtype, len);
@@ -1652,6 +1661,7 @@
kgsl_process_add_stats(private, entry->memtype, param->len);
kgsl_mem_entry_attach_process(entry, private);
+ trace_kgsl_mem_map(entry, param->fd);
kgsl_check_idle(dev_priv->device);
return result;
@@ -1718,6 +1728,7 @@
param->gpuaddr = entry->memdesc.gpuaddr;
kgsl_process_add_stats(private, entry->memtype, param->size);
+ trace_kgsl_mem_alloc(entry);
} else
kfree(entry);
@@ -1964,7 +1975,7 @@
if (!func) {
KGSL_DRV_INFO(dev_priv->device,
"invalid ioctl code %08x\n", cmd);
- ret = -EINVAL;
+ ret = -ENOIOCTLCMD;
goto done;
}
lock = 1;
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 389ed6d..7264c25 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -150,7 +150,7 @@
#endif
MEM_ENTRY_STAT(KGSL_MEM_ENTRY_USER, user),
#ifdef CONFIG_ION
- MEM_ENTRY_STAT(KGSL_MEM_ENTRY_USER, ion),
+ MEM_ENTRY_STAT(KGSL_MEM_ENTRY_ION, ion),
#endif
};
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index de39ee4..93fdc08 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -10,7 +10,6 @@
* GNU General Public License for more details.
*/
-#include <linux/vmalloc.h>
#include <linux/time.h>
#include <linux/sysfs.h>
#include <linux/utsname.h>
@@ -299,6 +298,10 @@
/* Freeze the snapshot on a hang until it gets read */
device->snapshot_frozen = (hang) ? 1 : 0;
+ /* log buffer info to aid in ramdump recovery */
+ KGSL_DRV_ERR(device, "snapshot created at va %p pa %lx size %d\n",
+ device->snapshot, __pa(device->snapshot),
+ device->snapshot_size);
return 0;
}
EXPORT_SYMBOL(kgsl_device_snapshot);
@@ -448,7 +451,7 @@
int ret;
if (device->snapshot == NULL)
- device->snapshot = vmalloc(KGSL_SNAPSHOT_MEMSIZE);
+ device->snapshot = kzalloc(KGSL_SNAPSHOT_MEMSIZE, GFP_KERNEL);
if (device->snapshot == NULL)
return -ENOMEM;
@@ -491,7 +494,7 @@
kobject_put(&device->snapshot_kobj);
- vfree(device->snapshot);
+ kfree(device->snapshot);
device->snapshot = NULL;
device->snapshot_maxsize = 0;
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index 86a9adc..22bc576 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -257,6 +257,122 @@
TP_ARGS(device, state)
);
+TRACE_EVENT(kgsl_mem_alloc,
+
+ TP_PROTO(struct kgsl_mem_entry *mem_entry),
+
+ TP_ARGS(mem_entry),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, gpuaddr)
+ __field(unsigned int, size)
+ ),
+
+ TP_fast_assign(
+ __entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+ __entry->size = mem_entry->memdesc.size;
+ ),
+
+ TP_printk(
+ "gpuaddr=0x%08x size=%d",
+ __entry->gpuaddr, __entry->size
+ )
+);
+
+TRACE_EVENT(kgsl_mem_map,
+
+ TP_PROTO(struct kgsl_mem_entry *mem_entry, int fd),
+
+ TP_ARGS(mem_entry, fd),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, gpuaddr)
+ __field(unsigned int, size)
+ __field(int, fd)
+ __field(int, type)
+ ),
+
+ TP_fast_assign(
+ __entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+ __entry->size = mem_entry->memdesc.size;
+ __entry->fd = fd;
+ __entry->type = mem_entry->memtype;
+ ),
+
+ TP_printk(
+ "gpuaddr=0x%08x size=%d type=%d fd=%d",
+ __entry->gpuaddr, __entry->size,
+ __entry->type, __entry->fd
+ )
+);
+
+TRACE_EVENT(kgsl_mem_free,
+
+ TP_PROTO(struct kgsl_mem_entry *mem_entry),
+
+ TP_ARGS(mem_entry),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, gpuaddr)
+ __field(unsigned int, size)
+ __field(int, type)
+ __field(int, fd)
+ ),
+
+ TP_fast_assign(
+ __entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+ __entry->size = mem_entry->memdesc.size;
+ __entry->type = mem_entry->memtype;
+ ),
+
+ TP_printk(
+ "gpuaddr=0x%08x size=%d type=%d",
+ __entry->gpuaddr, __entry->size, __entry->type
+ )
+);
+
+DECLARE_EVENT_CLASS(kgsl_mem_timestamp_template,
+
+ TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int curr_ts),
+
+ TP_ARGS(mem_entry, curr_ts),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, gpuaddr)
+ __field(unsigned int, size)
+ __field(int, type)
+ __field(unsigned int, drawctxt_id)
+ __field(unsigned int, curr_ts)
+ __field(unsigned int, free_ts)
+ ),
+
+ TP_fast_assign(
+ __entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+ __entry->size = mem_entry->memdesc.size;
+ __entry->drawctxt_id = 1337;
+ __entry->type = mem_entry->memtype;
+ __entry->curr_ts = curr_ts;
+ __entry->free_ts = mem_entry->free_timestamp;
+ ),
+
+ TP_printk(
+ "gpuaddr=0x%08x size=%d type=%d ctx=%u curr_ts=0x%08x free_ts=0x%08x",
+ __entry->gpuaddr, __entry->size, __entry->type,
+ __entry->drawctxt_id, __entry->curr_ts, __entry->free_ts
+ )
+);
+
+DEFINE_EVENT(kgsl_mem_timestamp_template, kgsl_mem_timestamp_queue,
+ TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int curr_ts),
+ TP_ARGS(mem_entry, curr_ts)
+);
+
+DEFINE_EVENT(kgsl_mem_timestamp_template, kgsl_mem_timestamp_free,
+ TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int curr_ts),
+ TP_ARGS(mem_entry, curr_ts)
+);
+
+
#endif /* _KGSL_TRACE_H */
/* This part must be outside protection */
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index cb3da90..6c43a75 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -339,13 +339,15 @@
*p++ = ADDR_VGV3_LAST << 24;
}
-static void z180_cmdstream_start(struct kgsl_device *device)
+static void z180_cmdstream_start(struct kgsl_device *device, int init_ram)
{
struct z180_device *z180_dev = Z180_DEVICE(device);
unsigned int cmd = VGV3_NEXTCMD_JUMP << VGV3_NEXTCMD_NEXTCMD_FSHIFT;
- z180_dev->timestamp = 0;
- z180_dev->current_timestamp = 0;
+ if (init_ram) {
+ z180_dev->timestamp = 0;
+ z180_dev->current_timestamp = 0;
+ }
addmarker(&z180_dev->ringbuffer, 0);
@@ -566,7 +568,7 @@
if (status)
goto error_clk_off;
- z180_cmdstream_start(device);
+ z180_cmdstream_start(device, init_ram);
mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index f18c2d0..f5bfc7b 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -514,6 +514,31 @@
}
}
+static int mxt_get_bootloader_id(struct i2c_client *client)
+{
+ u8 val;
+ u8 buf[3];
+
+ if (i2c_master_recv(client, &val, 1) != 1) {
+ dev_err(&client->dev, "%s: i2c recv failed\n", __func__);
+ return -EIO;
+ }
+
+ if (val | MXT_BOOT_EXTENDED_ID) {
+ if (i2c_master_recv(client, &buf[0], 3) != 3) {
+ dev_err(&client->dev, "%s: i2c recv failed\n",
+ __func__);
+ return -EIO;
+ }
+ return buf[1];
+ } else {
+ dev_info(&client->dev, "Bootloader ID:%d",
+ val & MXT_BOOT_ID_MASK);
+
+ return val & MXT_BOOT_ID_MASK;
+ }
+}
+
static int mxt_check_bootloader(struct i2c_client *client,
unsigned int state)
{
@@ -1449,24 +1474,69 @@
return ret;
}
+static const char *
+mxt_search_fw_name(struct mxt_data *data, u8 bootldr_id)
+{
+ const struct mxt_platform_data *pdata = data->pdata;
+ const struct mxt_config_info *cfg_info;
+ const char *fw_name = NULL;
+ int i;
+
+ for (i = 0; i < pdata->config_array_size; i++) {
+ cfg_info = &pdata->config_array[i];
+ if (bootldr_id == cfg_info->bootldr_id && cfg_info->fw_name) {
+ data->config_info = cfg_info;
+ data->info.family_id = cfg_info->family_id;
+ fw_name = cfg_info->fw_name;
+ }
+ }
+
+ return fw_name;
+}
+
static ssize_t mxt_update_fw_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct mxt_data *data = dev_get_drvdata(dev);
int error;
+ const char *fw_name;
+ u8 bootldr_id;
/* If fw_name is set, then the existing firmware has an upgrade */
if (!data->fw_name) {
- dev_err(dev, "Firmware name not specifed in platform data\n");
- return -EINVAL;
+ /*
+ * If the device boots up in the bootloader mode, check if
+ * there is a firmware to upgrade.
+ */
+ if (data->state == BOOTLOADER) {
+ bootldr_id = mxt_get_bootloader_id(data->client);
+ if (bootldr_id <= 0) {
+ dev_err(dev,
+ "Unable to retrieve bootloader id\n");
+ return -EINVAL;
+ }
+ fw_name = mxt_search_fw_name(data, bootldr_id);
+ if (fw_name == NULL) {
+ dev_err(dev,
+ "Unable to find fw from bootloader id\n");
+ return -EINVAL;
+ }
+ } else {
+ /* In APPMODE, if the f/w name does not exist, quit */
+ dev_err(dev,
+ "Firmware name not specified in platform data\n");
+ return -EINVAL;
+ }
+ } else {
+ fw_name = data->fw_name;
}
- dev_info(dev, "Upgrading the firmware file to %s\n", data->fw_name);
+ dev_info(dev, "Upgrading the firmware file to %s\n", fw_name);
disable_irq(data->irq);
- error = mxt_load_fw(dev, data->fw_name);
+ error = mxt_load_fw(dev, fw_name);
if (error) {
dev_err(dev, "The firmware update failed(%d)\n", error);
count = error;
@@ -1559,10 +1629,12 @@
struct mxt_data *data = input_get_drvdata(dev);
int error;
- error = mxt_start(data);
- if (error < 0) {
- dev_err(&data->client->dev, "mxt_start failed in input_open\n");
- return error;
+ if (data->state == APPMODE) {
+ error = mxt_start(data);
+ if (error < 0) {
+ dev_err(&data->client->dev, "mxt_start failed in input_open\n");
+ return error;
+ }
}
return 0;
@@ -1573,10 +1645,11 @@
struct mxt_data *data = input_get_drvdata(dev);
int error;
- error = mxt_stop(data);
- if (error < 0)
- dev_err(&data->client->dev, "mxt_stop failed in input_close\n");
-
+ if (data->state == APPMODE) {
+ error = mxt_stop(data);
+ if (error < 0)
+ dev_err(&data->client->dev, "mxt_stop failed in input_close\n");
+ }
}
static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA)
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 4598b31..78c474e 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -522,6 +522,7 @@
ctrlcmd.value = (void *)ctrl_data;
memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
ctrlcmd.timeout_ms = 1000;
+ ctrlcmd.vnode_id = pcam->vnode_id;
ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
/* send command to config thread in usersspace, and get return value */
@@ -547,6 +548,7 @@
ctrlcmd.value = (void *)ctrl_data;
memcpy(ctrlcmd.value, queryctrl, ctrlcmd.length);
ctrlcmd.timeout_ms = 1000;
+ ctrlcmd.vnode_id = pcam->vnode_id;
ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
/* send command to config thread in userspace, and get return value */
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index e4c3152..a8f9f35 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -199,7 +199,7 @@
};
static int __qseecom_is_svc_unique(struct qseecom_dev_handle *data,
- struct qseecom_register_listener_req svc)
+ struct qseecom_register_listener_req *svc)
{
struct qseecom_registered_listener_list *ptr;
int unique = 1;
@@ -207,7 +207,7 @@
spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags);
list_for_each_entry(ptr, &qseecom.registered_listener_list_head, list) {
- if (ptr->svc.listener_id == svc.listener_id) {
+ if (ptr->svc.listener_id == svc->listener_id) {
pr_err("Service id: %u is already registered\n",
ptr->svc.listener_id);
unique = 0;
@@ -333,16 +333,12 @@
pr_err("copy_from_user failed\n");
return ret;
}
-
- if (!__qseecom_is_svc_unique(data, rcvd_lstnr)) {
+ data->listener.id = 0;
+ data->service = true;
+ if (!__qseecom_is_svc_unique(data, &rcvd_lstnr)) {
pr_err("Service is not unique and is already registered\n");
- return ret;
- }
-
- ret = copy_to_user(argp, &rcvd_lstnr, sizeof(rcvd_lstnr));
- if (ret) {
- pr_err("copy_to_user failed\n");
- return ret;
+ data->released = true;
+ return -EBUSY;
}
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
@@ -360,13 +356,14 @@
kzfree(new_entry);
return -ENOMEM;
}
+
data->listener.id = rcvd_lstnr.listener_id;
- data->service = true;
init_waitqueue_head(&new_entry->rcv_req_wq);
spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags);
list_add_tail(&new_entry->list, &qseecom.registered_listener_list_head);
spin_unlock_irqrestore(&qseecom.registered_listener_list_lock, flags);
+
return ret;
}
@@ -743,6 +740,7 @@
break;
} else {
ptr_app->ref_cnt--;
+ data->released = true;
break;
}
}
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 0d2b11d..ad4dfe6 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -134,6 +134,7 @@
u32 c);
static inline void msmsdcc_delay(struct msmsdcc_host *host);
static void msmsdcc_dump_sdcc_state(struct msmsdcc_host *host);
+static void msmsdcc_sg_start(struct msmsdcc_host *host);
static inline unsigned short msmsdcc_get_nr_sg(struct msmsdcc_host *host)
{
@@ -1076,21 +1077,15 @@
/* Is data transfer in PIO mode required? */
if (!(datactrl & MCI_DPSM_DMAENABLE)) {
- unsigned int sg_miter_flags = SG_MITER_ATOMIC;
-
if (data->flags & MMC_DATA_READ) {
- sg_miter_flags |= SG_MITER_TO_SG;
pio_irqmask = MCI_RXFIFOHALFFULLMASK;
if (host->curr.xfer_remain < MCI_FIFOSIZE)
pio_irqmask |= MCI_RXDATAAVLBLMASK;
- } else {
- sg_miter_flags |= SG_MITER_FROM_SG;
+ } else
pio_irqmask = MCI_TXFIFOHALFEMPTYMASK |
MCI_TXFIFOEMPTYMASK;
- }
- sg_miter_start(&host->sg_miter, data->sg, data->sg_len,
- sg_miter_flags);
+ msmsdcc_sg_start(host);
}
if (data->flags & MMC_DATA_READ)
@@ -1250,6 +1245,144 @@
return ptr - buffer;
}
+/*
+ * Copy up to a word (4 bytes) between a scatterlist
+ * and a temporary bounce buffer when the word lies across
+ * two pages. The temporary buffer can then be read to/
+ * written from the FIFO once.
+ */
+static void _msmsdcc_sg_consume_word(struct msmsdcc_host *host)
+{
+ struct msmsdcc_pio_data *pio = &host->pio;
+ unsigned int bytes_avail;
+
+ if (host->curr.data->flags & MMC_DATA_READ)
+ memcpy(pio->sg_miter.addr, pio->bounce_buf,
+ pio->bounce_buf_len);
+ else
+ memcpy(pio->bounce_buf, pio->sg_miter.addr,
+ pio->bounce_buf_len);
+
+ while (pio->bounce_buf_len != 4) {
+ if (!sg_miter_next(&pio->sg_miter))
+ break;
+ bytes_avail = min_t(unsigned int, pio->sg_miter.length,
+ 4 - pio->bounce_buf_len);
+ if (host->curr.data->flags & MMC_DATA_READ)
+ memcpy(pio->sg_miter.addr,
+ &pio->bounce_buf[pio->bounce_buf_len],
+ bytes_avail);
+ else
+ memcpy(&pio->bounce_buf[pio->bounce_buf_len],
+ pio->sg_miter.addr, bytes_avail);
+
+ pio->sg_miter.consumed = bytes_avail;
+ pio->bounce_buf_len += bytes_avail;
+ }
+}
+
+/*
+ * Use sg_miter_next to return as many 4-byte aligned
+ * chunks as possible, using a temporary 4 byte buffer
+ * for alignment if necessary
+ */
+static int msmsdcc_sg_next(struct msmsdcc_host *host, char **buf, int *len)
+{
+ struct msmsdcc_pio_data *pio = &host->pio;
+ unsigned int length, rlength;
+ char *buffer;
+
+ if (!sg_miter_next(&pio->sg_miter))
+ return 0;
+
+ buffer = pio->sg_miter.addr;
+ length = pio->sg_miter.length;
+
+ if (length < host->curr.xfer_remain) {
+ rlength = round_down(length, 4);
+ if (rlength) {
+ /*
+ * We have a 4-byte aligned chunk.
+ * The rounding will be reflected by
+ * a call to msmsdcc_sg_consumed
+ */
+ length = rlength;
+ goto sg_next_end;
+ }
+ /*
+ * We have a length less than 4 bytes. Check to
+ * see if more buffer is available, and combine
+ * to make 4 bytes if possible.
+ */
+ pio->bounce_buf_len = length;
+ memset(pio->bounce_buf, 0, 4);
+
+ /*
+ * On a read, get 4 bytes from FIFO, and distribute
+ * (4-bouce_buf_len) bytes into consecutive
+ * sgl buffers when msmsdcc_sg_consumed is called
+ */
+ if (host->curr.data->flags & MMC_DATA_READ) {
+ buffer = pio->bounce_buf;
+ length = 4;
+ goto sg_next_end;
+ } else {
+ _msmsdcc_sg_consume_word(host);
+ buffer = pio->bounce_buf;
+ length = pio->bounce_buf_len;
+ }
+ }
+
+sg_next_end:
+ *buf = buffer;
+ *len = length;
+ return 1;
+}
+
+/*
+ * Update sg_miter.consumed based on how many bytes were
+ * consumed. If the bounce buffer was used to read from FIFO,
+ * redistribute into sgls.
+ */
+static void msmsdcc_sg_consumed(struct msmsdcc_host *host,
+ unsigned int length)
+{
+ struct msmsdcc_pio_data *pio = &host->pio;
+
+ if (host->curr.data->flags & MMC_DATA_READ) {
+ if (length > pio->sg_miter.consumed)
+ /*
+ * consumed 4 bytes, but sgl
+ * describes < 4 bytes
+ */
+ _msmsdcc_sg_consume_word(host);
+ else
+ pio->sg_miter.consumed = length;
+ } else
+ if (length < pio->sg_miter.consumed)
+ pio->sg_miter.consumed = length;
+}
+
+static void msmsdcc_sg_start(struct msmsdcc_host *host)
+{
+ unsigned int sg_miter_flags = SG_MITER_ATOMIC;
+
+ host->pio.bounce_buf_len = 0;
+
+ if (host->curr.data->flags & MMC_DATA_READ)
+ sg_miter_flags |= SG_MITER_TO_SG;
+ else
+ sg_miter_flags |= SG_MITER_FROM_SG;
+
+ sg_miter_start(&host->pio.sg_miter, host->curr.data->sg,
+ host->curr.data->sg_len, sg_miter_flags);
+}
+
+static void msmsdcc_sg_stop(struct msmsdcc_host *host)
+{
+ sg_miter_stop(&host->pio.sg_miter);
+}
+
static irqreturn_t
msmsdcc_pio_irq(int irq, void *dev_id)
{
@@ -1257,6 +1390,8 @@
void __iomem *base = host->base;
uint32_t status;
unsigned long flags;
+ unsigned int remain;
+ char *buffer;
spin_lock(&host->lock);
@@ -1267,45 +1402,43 @@
spin_unlock(&host->lock);
return IRQ_NONE;
}
-
#if IRQ_DEBUG
msmsdcc_print_status(host, "irq1-r", status);
#endif
local_irq_save(flags);
- while (sg_miter_next(&host->sg_miter)) {
-
- unsigned int remain, len;
- char *buffer;
+ do {
+ unsigned int len;
if (!(status & (MCI_TXFIFOHALFEMPTY | MCI_TXFIFOEMPTY
| MCI_RXDATAAVLBL)))
break;
- buffer = host->sg_miter.addr;
- remain = host->sg_miter.length;
+ if (!msmsdcc_sg_next(host, &buffer, &remain))
+ break;
len = 0;
if (status & MCI_RXACTIVE)
len = msmsdcc_pio_read(host, buffer, remain);
if (status & MCI_TXACTIVE)
len = msmsdcc_pio_write(host, buffer, remain);
+
/* len might have aligned to 32bits above */
if (len > remain)
len = remain;
- host->sg_miter.consumed = len;
host->curr.xfer_remain -= len;
host->curr.data_xfered += len;
remain -= len;
+ msmsdcc_sg_consumed(host, len);
if (remain) /* Done with this page? */
break; /* Nope */
status = readl_relaxed(base + MMCISTATUS);
- }
+ } while (1);
- sg_miter_stop(&host->sg_miter);
+ msmsdcc_sg_stop(host);
local_irq_restore(flags);
if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE) {
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 319d721..8a728f2 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -281,9 +281,10 @@
};
struct msmsdcc_pio_data {
- struct scatterlist *sg;
- unsigned int sg_len;
- unsigned int sg_off;
+ struct sg_mapping_iter sg_miter;
+ char bounce_buf[4];
+ /* valid bytes in bounce_buf */
+ int bounce_buf_len;
};
struct msmsdcc_curr_req {
@@ -361,7 +362,7 @@
struct msmsdcc_sps_data sps;
bool is_dma_mode;
bool is_sps_mode;
- struct sg_mapping_iter sg_miter;
+ struct msmsdcc_pio_data pio;
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
diff --git a/drivers/mtd/devices/msm_nand.c b/drivers/mtd/devices/msm_nand.c
index 5ced423..2479a11 100644
--- a/drivers/mtd/devices/msm_nand.c
+++ b/drivers/mtd/devices/msm_nand.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -6718,7 +6718,7 @@
supported_flash.pagesize = 1024 << (devcfg & 0x3);
supported_flash.blksize = (64 * 1024) <<
((devcfg >> 4) & 0x3);
- supported_flash.oobsize = (8 << ((devcfg >> 2) & 1)) *
+ supported_flash.oobsize = (8 << ((devcfg >> 2) & 0x3)) *
(supported_flash.pagesize >> 9);
} else {
supported_flash.flash_id = flash_id;
diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c
index dcbd761..5a016bb 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.c
+++ b/drivers/net/usb/rmnet_usb_ctrl.c
@@ -264,19 +264,10 @@
{
int retval = 0;
- retval = usb_autopm_get_interface(dev->intf);
- if (retval < 0) {
- dev_err(dev->devicep, "%s Resumption fail\n", __func__);
- goto done_nopm;
- }
-
retval = usb_submit_urb(dev->inturb, GFP_KERNEL);
if (retval < 0)
dev_err(dev->devicep, "%s Intr submit %d\n", __func__, retval);
- usb_autopm_put_interface(dev->intf);
-
-done_nopm:
return retval;
}
@@ -342,35 +333,19 @@
}
static int rmnet_usb_ctrl_write_cmd(struct rmnet_ctrl_dev *dev)
{
- int retval = 0;
struct usb_device *udev;
if (!is_dev_connected(dev))
return -ENODEV;
udev = interface_to_usbdev(dev->intf);
- retval = usb_autopm_get_interface(dev->intf);
- if (retval < 0) {
- dev_err(dev->devicep, "%s: Unable to resume interface: %d\n",
- __func__, retval);
-
- /*
- * Revisit if (retval == -EPERM)
- * rmnet_usb_suspend(dev->intf, PMSG_SUSPEND);
- */
-
- return retval;
- }
dev->set_ctrl_line_state_cnt++;
- retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
USB_CDC_REQ_SET_CONTROL_LINE_STATE,
(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE),
dev->cbits_tomdm,
dev->intf->cur_altsetting->desc.bInterfaceNumber,
NULL, 0, USB_CTRL_SET_TIMEOUT);
- usb_autopm_put_interface(dev->intf);
-
- return retval;
}
static void ctrl_write_callback(struct urb *urb)
@@ -428,7 +403,7 @@
(unsigned char *)out_ctlreq, (void *)buf, size,
ctrl_write_callback, dev);
- result = usb_autopm_get_interface_async(dev->intf);
+ result = usb_autopm_get_interface(dev->intf);
if (result < 0) {
dev_err(dev->devicep, "%s: Unable to resume interface: %d\n",
__func__, result);
@@ -450,7 +425,7 @@
dev_err(dev->devicep, "%s: Submit URB error %d\n",
__func__, result);
dev->snd_encap_cmd_cnt--;
- usb_autopm_put_interface_async(dev->intf);
+ usb_autopm_put_interface(dev->intf);
usb_unanchor_urb(sndurb);
usb_free_urb(sndurb);
kfree(out_ctlreq);
@@ -662,6 +637,8 @@
static int rmnet_ctrl_tiocmset(struct rmnet_ctrl_dev *dev, unsigned int set,
unsigned int clear)
{
+ int retval;
+
mutex_lock(&dev->dev_lock);
if (set & TIOCM_DTR)
dev->cbits_tomdm |= ACM_CTRL_DTR;
@@ -681,7 +658,17 @@
mutex_unlock(&dev->dev_lock);
- return rmnet_usb_ctrl_write_cmd(dev);
+ retval = usb_autopm_get_interface(dev->intf);
+ if (retval < 0) {
+ dev_err(dev->devicep, "%s: Unable to resume interface: %d\n",
+ __func__, retval);
+ return retval;
+ }
+
+ retval = rmnet_usb_ctrl_write_cmd(dev);
+
+ usb_autopm_put_interface(dev->intf);
+ return retval;
}
static int rmnet_ctrl_tiocmget(struct rmnet_ctrl_dev *dev)
@@ -774,6 +761,10 @@
dev->tx_ctrl_err_cnt = 0;
dev->set_ctrl_line_state_cnt = 0;
+ ret = rmnet_usb_ctrl_write_cmd(dev);
+ if (ret < 0)
+ return ret;
+
dev->inturb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->inturb) {
dev_err(dev->devicep, "Error allocating int urb\n");
@@ -799,19 +790,15 @@
dev->intf->cur_altsetting->desc.bInterfaceNumber;
dev->in_ctlreq->wLength = cpu_to_le16(DEFAULT_READ_URB_LENGTH);
- interval =
- max((int)int_in->desc.bInterval,
- (udev->speed == USB_SPEED_HIGH) ? HS_INTERVAL : FS_LS_INTERVAL);
+ interval = max((int)int_in->desc.bInterval,
+ (udev->speed == USB_SPEED_HIGH) ? HS_INTERVAL
+ : FS_LS_INTERVAL);
usb_fill_int_urb(dev->inturb, udev,
dev->int_pipe,
dev->intbuf, wMaxPacketSize,
notification_available_cb, dev, interval);
- ret = rmnet_usb_ctrl_write_cmd(dev);
- if (ret < 0)
- return ret;
-
return rmnet_usb_ctrl_start_rx(dev);
}
diff --git a/drivers/net/usb/rmnet_usb_data.c b/drivers/net/usb/rmnet_usb_data.c
index 658b393..1eb6845 100644
--- a/drivers/net/usb/rmnet_usb_data.c
+++ b/drivers/net/usb/rmnet_usb_data.c
@@ -148,7 +148,6 @@
retval = usbnet_resume(iface);
if (!retval) {
-
if (oldstate & PM_EVENT_SUSPEND)
retval = rmnet_usb_ctrl_start(dev);
}
@@ -260,6 +259,12 @@
return 1;
}
+static int rmnet_usb_manage_power(struct usbnet *dev, int on)
+{
+ dev->intf->needs_remote_wakeup = on;
+ return 0;
+}
+
static int rmnet_change_mtu(struct net_device *dev, int new_mtu)
{
if (0 > new_mtu || RMNET_DATA_LEN < new_mtu)
@@ -501,6 +506,7 @@
.bind = rmnet_usb_bind,
.tx_fixup = rmnet_usb_tx_fixup,
.rx_fixup = rmnet_usb_rx_fixup,
+ .manage_power = rmnet_usb_manage_power,
.data = PID9034_IFACE_MASK,
};
@@ -509,6 +515,7 @@
.bind = rmnet_usb_bind,
.tx_fixup = rmnet_usb_tx_fixup,
.rx_fixup = rmnet_usb_rx_fixup,
+ .manage_power = rmnet_usb_manage_power,
.data = PID9048_IFACE_MASK,
};
@@ -517,6 +524,7 @@
.bind = rmnet_usb_bind,
.tx_fixup = rmnet_usb_tx_fixup,
.rx_fixup = rmnet_usb_rx_fixup,
+ .manage_power = rmnet_usb_manage_power,
.data = PID904C_IFACE_MASK,
};
diff --git a/drivers/net/wireless/libra/libra_sdioif.c b/drivers/net/wireless/libra/libra_sdioif.c
index 3955642..3421f84 100644
--- a/drivers/net/wireless/libra/libra_sdioif.c
+++ b/drivers/net/wireless/libra/libra_sdioif.c
@@ -29,6 +29,37 @@
static suspend_handler_t *libra_suspend_hldr;
static resume_handler_t *libra_resume_hldr;
+int libra_enable_sdio_irq_in_chip(struct sdio_func *func, u8 enable)
+{
+ unsigned char reg = 0;
+ int err = 0;
+
+ sdio_claim_host(func);
+
+ /* Read the value into reg */
+ libra_sdiocmd52(func, SDIO_CCCR_IENx, ®, 0, &err);
+ if (err)
+ printk(KERN_ERR "%s: Could not read SDIO_CCCR_IENx register "
+ "err=%d\n", __func__, err);
+
+ if (libra_mmc_host) {
+ if (enable) {
+ reg |= 1 << func->num;
+ reg |= 1;
+ } else {
+ reg &= ~(1 << func->num);
+ }
+ libra_sdiocmd52(func, SDIO_CCCR_IENx, ®, 1, &err);
+ if (err)
+ printk(KERN_ERR "%s: Could not enable/disable irq "
+ "err=%d\n", __func__, err);
+ }
+ sdio_release_host(func);
+
+ return err;
+}
+EXPORT_SYMBOL(libra_enable_sdio_irq_in_chip);
+
/**
* libra_sdio_configure() - Function to configure the SDIO device param
* @libra_sdio_rxhandler Rx handler
@@ -89,6 +120,8 @@
goto cfg_error;
}
+ libra_enable_sdio_irq_in_chip(func, 0);
+
sdio_release_host(func);
return 0;
diff --git a/drivers/net/wireless/libra/qcomwlan_pwrif.c b/drivers/net/wireless/libra/qcomwlan_pwrif.c
index 6a0c78f..94ea0b3 100644
--- a/drivers/net/wireless/libra/qcomwlan_pwrif.c
+++ b/drivers/net/wireless/libra/qcomwlan_pwrif.c
@@ -154,7 +154,7 @@
/* WLAN VREG settings */
for (i = 0; i < ARRAY_SIZE(vregs_qwlan_name); i++) {
- if (vregs_qwlan[i] == NULL) {
+ if (on && !wlan_on) {
vregs_qwlan[i] = regulator_get(NULL,
vregs_qwlan_name[i]);
if (IS_ERR(vregs_qwlan[i])) {
@@ -187,8 +187,7 @@
goto vreg_fail;
}
}
- }
- if (on && !wlan_on) {
+
if (vregs_qwlan_peek_current[i]) {
rc = regulator_set_optimum_mode(vregs_qwlan[i],
vregs_qwlan_peek_current[i]);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5442297..4a37dc2 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1690,7 +1690,7 @@
#ifdef CONFIG_USB_OTG
if (udev->bus->hnp_support && udev->portnum == udev->bus->otg_port) {
- cancel_delayed_work(&udev->bus->hnp_polling);
+ cancel_delayed_work_sync(&udev->bus->hnp_polling);
udev->bus->hnp_support = 0;
}
#endif
@@ -1811,7 +1811,10 @@
* compliant to revision 2.0 or subsequent
* versions.
*/
- if (le16_to_cpu(desc->bcdOTG) >= 0x0200)
+
+ if ((le16_to_cpu(desc->bLength) ==
+ USB_DT_OTG_SIZE) &&
+ le16_to_cpu(desc->bcdOTG) >= 0x0200)
goto out;
/* Legacy B-device i.e compliant to spec
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 4c33695..4fe494b 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -858,6 +858,7 @@
u16 w_length = le16_to_cpu(ctrl->wLength);
struct usb_function *f = NULL;
u8 endp;
+ struct usb_configuration *c;
if (w_length > USB_BUFSIZ)
@@ -902,6 +903,16 @@
if (value >= 0)
value = min(w_length, (u16) value);
break;
+ case USB_DT_OTG:
+ if (!gadget_is_otg(gadget))
+ break;
+ c = list_first_entry(&cdev->configs,
+ struct usb_configuration, list);
+ if (c && c->descriptors)
+ value = usb_find_descriptor_fillbuf(req->buf,
+ USB_BUFSIZ, c->descriptors,
+ USB_DT_OTG);
+ break;
case USB_DT_STRING:
value = get_string(cdev, req->buf,
w_index, w_value & 0xff);
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index 09084fd..384332c 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -28,6 +28,40 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
+/**
+ * usb_find_descriptor_fillbuf - fill buffer with the requested descriptor
+ * @buf: Buffer to be filled
+ * @buflen: Size of buf
+ * @src: Array of descriptor pointers, terminated by null pointer.
+ * @desc_type: bDescriptorType field of the requested descriptor.
+ *
+ * Copies the requested descriptor into the buffer, returning the length
+ * or a negative error code if it is not found or can't be copied. Useful
+ * when DT_OTG descriptor is requested.
+ */
+int
+usb_find_descriptor_fillbuf(void *buf, unsigned buflen,
+ const struct usb_descriptor_header **src, u8 desc_type)
+{
+ if (!src)
+ return -EINVAL;
+
+ for (; NULL != *src; src++) {
+ unsigned len;
+
+ if ((*src)->bDescriptorType != desc_type)
+ continue;
+
+ len = (*src)->bLength;
+ if (len > buflen)
+ return -EINVAL;
+
+ memcpy(buf, *src, len);
+ return len;
+ }
+
+ return -ENOENT;
+}
/**
* usb_descriptor_fillbuf - fill buffer with descriptors
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index 5ab987e..9794918 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -82,6 +82,7 @@
urb->status, urb->actual_length);
if (urb->status == -EPROTO) {
+ dev_err(&dev->udev->dev, "%s: proto error\n", __func__);
/* save error so that subsequent read/write returns ESHUTDOWN */
dev->err = urb->status;
return;
@@ -119,27 +120,36 @@
if (dev->err)
return -ESHUTDOWN;
- urb = usb_alloc_urb(0, GFP_ATOMIC);
+ urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
dev_err(&dev->udev->dev, "unable to allocate urb\n");
return -ENOMEM;
}
+ ret = usb_autopm_get_interface(dev->ifc);
+ if (ret < 0) {
+ dev_err(&dev->udev->dev, "autopm_get failed:%d\n", ret);
+ usb_free_urb(urb);
+ return ret;
+ }
+
pipe = usb_rcvbulkpipe(dev->udev, dev->in_epAddr);
usb_fill_bulk_urb(urb, dev->udev, pipe, data, size,
diag_bridge_read_cb, dev);
usb_anchor_urb(urb, &dev->submitted);
dev->pending_reads++;
- ret = usb_submit_urb(urb, GFP_ATOMIC);
+ ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret) {
dev_err(&dev->udev->dev, "submitting urb failed err:%d\n", ret);
dev->pending_reads--;
usb_unanchor_urb(urb);
usb_free_urb(urb);
+ usb_autopm_put_interface(dev->ifc);
return ret;
}
+ usb_autopm_put_interface(dev->ifc);
usb_free_urb(urb);
return 0;
@@ -153,7 +163,10 @@
dev_dbg(&dev->udev->dev, "%s:\n", __func__);
+ usb_autopm_put_interface_async(dev->ifc);
+
if (urb->status == -EPROTO) {
+ dev_err(&dev->udev->dev, "%s: proto error\n", __func__);
/* save error so that subsequent read/write returns ESHUTDOWN */
dev->err = urb->status;
return;
@@ -191,24 +204,32 @@
if (dev->err)
return -ESHUTDOWN;
- urb = usb_alloc_urb(0, GFP_ATOMIC);
+ urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
err("unable to allocate urb");
return -ENOMEM;
}
+ ret = usb_autopm_get_interface(dev->ifc);
+ if (ret < 0) {
+ dev_err(&dev->udev->dev, "autopm_get failed:%d\n", ret);
+ usb_free_urb(urb);
+ return ret;
+ }
+
pipe = usb_sndbulkpipe(dev->udev, dev->out_epAddr);
usb_fill_bulk_urb(urb, dev->udev, pipe, data, size,
diag_bridge_write_cb, dev);
usb_anchor_urb(urb, &dev->submitted);
dev->pending_writes++;
- ret = usb_submit_urb(urb, GFP_ATOMIC);
+ ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret) {
dev_err(&dev->udev->dev, "submitting urb failed err:%d\n", ret);
dev->pending_writes--;
usb_unanchor_urb(urb);
usb_free_urb(urb);
+ usb_autopm_put_interface(dev->ifc);
return ret;
}
@@ -381,6 +402,37 @@
usb_set_intfdata(ifc, NULL);
}
+static int diag_bridge_suspend(struct usb_interface *ifc, pm_message_t message)
+{
+ struct diag_bridge *dev = usb_get_intfdata(ifc);
+ struct diag_bridge_ops *cbs = dev->ops;
+ int ret = 0;
+
+ if (cbs && cbs->suspend) {
+ ret = cbs->suspend(cbs->ctxt);
+ if (ret) {
+ dev_dbg(&dev->udev->dev,
+ "%s: diag veto'd suspend\n", __func__);
+ return ret;
+ }
+
+ usb_kill_anchored_urbs(&dev->submitted);
+ }
+
+ return ret;
+}
+
+static int diag_bridge_resume(struct usb_interface *ifc)
+{
+ struct diag_bridge *dev = usb_get_intfdata(ifc);
+ struct diag_bridge_ops *cbs = dev->ops;
+
+
+ if (cbs && cbs->resume)
+ cbs->resume(cbs->ctxt);
+
+ return 0;
+}
#define VALID_INTERFACE_NUM 0
static const struct usb_device_id diag_bridge_ids[] = {
@@ -401,7 +453,10 @@
.name = "diag_bridge",
.probe = diag_bridge_probe,
.disconnect = diag_bridge_disconnect,
+ .suspend = diag_bridge_suspend,
+ .resume = diag_bridge_resume,
.id_table = diag_bridge_ids,
+ .supports_autosuspend = 1,
};
static int __init diag_bridge_init(void)
@@ -410,8 +465,7 @@
ret = usb_register(&diag_bridge_driver);
if (ret) {
- err("%s: unable to register diag driver",
- __func__);
+ err("%s: unable to register diag driver", __func__);
return ret;
}
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index a77d98f..cce819f 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -1013,6 +1013,7 @@
#define PID9001_IFACE_MASK 0xC
#define PID9034_IFACE_MASK 0xC
#define PID9048_IFACE_MASK 0x18
+#define PID904C_IFACE_MASK 0x28
static const struct usb_device_id bridge_ids[] = {
{ USB_DEVICE(0x5c6, 0x9001),
@@ -1024,6 +1025,9 @@
{ USB_DEVICE(0x5c6, 0x9048),
.driver_info = PID9048_IFACE_MASK,
},
+ { USB_DEVICE(0x5c6, 0x904c),
+ .driver_info = PID904C_IFACE_MASK,
+ },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 6964835..dd07d4e 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -67,6 +67,7 @@
static DECLARE_COMPLETION(pmic_vbus_init);
static struct msm_otg *the_msm_otg;
static bool debug_aca_enabled;
+static bool debug_bus_voting_enabled;
/* Prevent idle power collapse(pc) while operating in peripheral mode */
static void otg_pm_qos_update_latency(struct msm_otg *dev, int vote)
@@ -1155,7 +1156,7 @@
*/
otg_pm_qos_update_latency(motg, 1);
/* Configure BUS performance parameters for MAX bandwidth */
- if (motg->bus_perf_client) {
+ if (motg->bus_perf_client && debug_bus_voting_enabled) {
ret = msm_bus_scale_client_update_request(
motg->bus_perf_client, 1);
if (ret)
@@ -2232,13 +2233,64 @@
.release = single_release,
};
+static int msm_otg_bus_show(struct seq_file *s, void *unused)
+{
+ if (debug_bus_voting_enabled)
+ seq_printf(s, "enabled\n");
+ else
+ seq_printf(s, "disabled\n");
+
+ return 0;
+}
+
+static int msm_otg_bus_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, msm_otg_bus_show, inode->i_private);
+}
+
+static ssize_t msm_otg_bus_write(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ char buf[8];
+ int ret;
+ struct seq_file *s = file->private_data;
+ struct msm_otg *motg = s->private;
+
+ memset(buf, 0x00, sizeof(buf));
+
+ if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+ return -EFAULT;
+
+ if (!strncmp(buf, "enable", 6)) {
+ /* Do not vote here. Let OTG statemachine decide when to vote */
+ debug_bus_voting_enabled = true;
+ } else {
+ debug_bus_voting_enabled = false;
+ if (motg->bus_perf_client) {
+ ret = msm_bus_scale_client_update_request(
+ motg->bus_perf_client, 0);
+ if (ret)
+ dev_err(motg->otg.dev, "%s: Failed to devote "
+ "for bus bw %d\n", __func__, ret);
+ }
+ }
+
+ return count;
+}
+
+const struct file_operations msm_otg_bus_fops = {
+ .open = msm_otg_bus_open,
+ .read = seq_read,
+ .write = msm_otg_bus_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static struct dentry *msm_otg_dbg_root;
-static struct dentry *msm_otg_dbg_mode;
-static struct dentry *msm_otg_chg_type;
-static struct dentry *msm_otg_dbg_aca;
static int msm_otg_debugfs_init(struct msm_otg *motg)
{
+ struct dentry *msm_otg_dentry;
msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL);
@@ -2248,35 +2300,43 @@
if (motg->pdata->mode == USB_OTG &&
motg->pdata->otg_control == OTG_USER_CONTROL) {
- msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO |
+ msm_otg_dentry = debugfs_create_file("mode", S_IRUGO |
S_IWUSR, msm_otg_dbg_root, motg,
&msm_otg_mode_fops);
- if (!msm_otg_dbg_mode) {
+ if (!msm_otg_dentry) {
debugfs_remove(msm_otg_dbg_root);
msm_otg_dbg_root = NULL;
return -ENODEV;
}
}
- msm_otg_chg_type = debugfs_create_file("chg_type", S_IRUGO,
+ msm_otg_dentry = debugfs_create_file("chg_type", S_IRUGO,
msm_otg_dbg_root, motg,
&msm_otg_chg_fops);
- if (!msm_otg_chg_type) {
+ if (!msm_otg_dentry) {
debugfs_remove_recursive(msm_otg_dbg_root);
return -ENODEV;
}
- msm_otg_dbg_aca = debugfs_create_file("aca", S_IRUGO | S_IWUSR,
+ msm_otg_dentry = debugfs_create_file("aca", S_IRUGO | S_IWUSR,
msm_otg_dbg_root, motg,
&msm_otg_aca_fops);
- if (!msm_otg_dbg_aca) {
+ if (!msm_otg_dentry) {
debugfs_remove_recursive(msm_otg_dbg_root);
return -ENODEV;
}
+ msm_otg_dentry = debugfs_create_file("bus_voting", S_IRUGO | S_IWUSR,
+ msm_otg_dbg_root, motg,
+ &msm_otg_bus_fops);
+
+ if (!msm_otg_dentry) {
+ debugfs_remove_recursive(msm_otg_dbg_root);
+ return -ENODEV;
+ }
return 0;
}
@@ -2642,6 +2702,8 @@
if (!motg->bus_perf_client)
dev_err(motg->otg.dev, "%s: Failed to register BUS "
"scaling client!!\n", __func__);
+ else
+ debug_bus_voting_enabled = true;
}
return 0;
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index ef357db..96d9487 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -2475,12 +2475,6 @@
goto error;
}
- /*
- * A small delay is needed here to avoid device crash observed
- * during reauthentication in MSM8960
- */
- msleep(20);
-
/* 0x0168 HDCP_RCVPORT_DATA12
[23:8] BSTATUS
[7:0] BCAPS */
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index c57ec5d..033a73c 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1887,7 +1887,7 @@
static int get_img(struct msmfb_data *img, struct fb_info *info,
unsigned long *start, unsigned long *len, struct file **srcp_file,
- struct ion_handle **srcp_ihdl)
+ int *p_need, struct ion_handle **srcp_ihdl)
{
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
@@ -1897,6 +1897,8 @@
#ifdef CONFIG_ANDROID_PMEM
unsigned long vstart;
#endif
+ *p_need = 0;
+
if (img->flags & MDP_BLIT_SRC_GEM) {
*srcp_file = NULL;
return kgsl_gem_obj_addr(img->memory_id, (int) img->priv,
@@ -1912,8 +1914,10 @@
fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
if (get_fb_phys_info(start, len, fb_num))
ret = -1;
- else
+ else {
*srcp_file = file;
+ *p_need = put_needed;
+ }
} else
ret = -1;
if (ret)
@@ -2137,6 +2141,21 @@
mfd->ov0_blt_state = mfd->use_ov0_blt;
}
+static void mdp4_overlay1_update_blt_mode(struct msm_fb_data_type *mfd)
+{
+ if (mfd->ov1_blt_state == mfd->use_ov1_blt)
+ return;
+ if (mfd->use_ov1_blt) {
+ mdp4_allocate_writeback_buf(mfd, MDP4_MIXER1);
+ mdp4_dtv_overlay_blt_start(mfd);
+ pr_debug("%s overlay1 writeback is enabled\n", __func__);
+ } else {
+ mdp4_dtv_overlay_blt_stop(mfd);
+ pr_debug("%s overlay1 writeback is disabled\n", __func__);
+ }
+ mfd->ov1_blt_state = mfd->use_ov1_blt;
+}
+
static u32 mdp4_overlay_blt_enable(struct mdp_overlay *req,
struct msm_fb_data_type *mfd, uint32 perf_level)
{
@@ -2147,7 +2166,8 @@
clk_rate = (&mfd->panel_info.mipi)->dsi_pclk_rate;
if ((mfd->panel_info.type == LCDC_PANEL) ||
- (mfd->panel_info.type == MIPI_VIDEO_PANEL))
+ (mfd->panel_info.type == MIPI_VIDEO_PANEL) ||
+ (mfd->panel_info.type == DTV_PANEL))
pull_mode = 1;
if (pull_mode && (req->src_rect.h > req->dst_rect.h ||
@@ -2166,7 +2186,8 @@
if (req->dst_rect.x != 0)
use_blt = 1;
}
- if (mfd->panel_info.xres > 1280)
+ if ((mfd->panel_info.xres > 1280) &&
+ (mfd->panel_info.type != DTV_PANEL))
use_blt = 1;
}
return use_blt;
@@ -2249,8 +2270,12 @@
}
if (ctrl->panel_mode & MDP4_PANEL_DTV &&
- pipe->mixer_num == MDP4_MIXER1)
+ pipe->mixer_num == MDP4_MIXER1) {
+ u32 use_blt = mdp4_overlay_blt_enable(req, mfd, perf_level);
mdp4_overlay_dtv_set(mfd, pipe);
+ mfd->use_ov1_blt &= ~(1 << (pipe->pipe_ndx-1));
+ mfd->use_ov1_blt |= (use_blt << (pipe->pipe_ndx-1));
+ }
if (new_perf_level != perf_level) {
u32 old_level = new_perf_level;
@@ -2358,8 +2383,14 @@
if (!mfd->use_ov0_blt)
mdp4_free_writeback_buf(mfd, MDP4_MIXER0);
} else { /* mixer1, DTV, ATV */
- if (ctrl->panel_mode & MDP4_PANEL_DTV)
+ if (ctrl->panel_mode & MDP4_PANEL_DTV) {
mdp4_overlay_dtv_unset(mfd, pipe);
+ mfd->use_ov1_blt &= ~(1 << (pipe->pipe_ndx-1));
+ mdp4_overlay1_update_blt_mode(mfd);
+ if (!mfd->use_ov1_blt)
+ mdp4_free_writeback_buf(mfd,
+ MDP4_MIXER1);
+ }
}
}
@@ -2436,6 +2467,9 @@
mdp4_mixer_stage_commit(pipe->mixer_num);
+ if (mfd->use_ov1_blt)
+ mdp4_overlay1_update_blt_mode(mfd);
+
mdp4_overlay_dtv_wait_for_ov(mfd, pipe);
mutex_unlock(&mfd->dma->ov_mutex);
@@ -2453,6 +2487,7 @@
struct file *srcp1_file = NULL, *srcp2_file = NULL;
struct ion_handle *srcp0_ihdl = NULL;
struct ion_handle *srcp1_ihdl = NULL, *srcp2_ihdl = NULL;
+ int ps0_need, p_need;
uint32_t overlay_version = 0;
int ret = 0;
@@ -2472,7 +2507,7 @@
return -EINTR;
img = &req->data;
- get_img(img, info, &start, &len, &srcp0_file, &srcp0_ihdl);
+ get_img(img, info, &start, &len, &srcp0_file, &ps0_need, &srcp0_ihdl);
if (len == 0) {
mutex_unlock(&mfd->dma->ov_mutex);
pr_err("%s: pmem Error\n", __func__);
@@ -2491,7 +2526,7 @@
if (overlay_version > 0) {
img = &req->plane1_data;
get_img(img, info, &start, &len, &srcp1_file,
- &srcp1_ihdl);
+ &p_need, &srcp1_ihdl);
if (len == 0) {
mutex_unlock(&mfd->dma->ov_mutex);
pr_err("%s: Error to get plane1\n", __func__);
@@ -2523,7 +2558,7 @@
if (overlay_version > 0) {
img = &req->plane1_data;
get_img(img, info, &start, &len, &srcp1_file,
- &srcp1_ihdl);
+ &p_need, &srcp1_ihdl);
if (len == 0) {
mutex_unlock(&mfd->dma->ov_mutex);
pr_err("%s: Error to get plane1\n", __func__);
@@ -2534,7 +2569,7 @@
img = &req->plane2_data;
get_img(img, info, &start, &len, &srcp2_file,
- &srcp2_ihdl);
+ &p_need, &srcp2_ihdl);
if (len == 0) {
mutex_unlock(&mfd->dma->ov_mutex);
pr_err("%s: Error to get plane2\n", __func__);
@@ -2577,6 +2612,9 @@
if (mfd->use_ov0_blt)
mdp4_overlay_update_blt_mode(mfd);
+ if (mfd->use_ov1_blt)
+ mdp4_overlay1_update_blt_mode(mfd);
+
if (pipe->pipe_type == OVERLAY_TYPE_VIDEO) {
mdp4_overlay_vg_setup(pipe); /* video/graphic pipe */
} else {
@@ -2602,8 +2640,11 @@
} else if (pipe->mixer_num == MDP4_MIXER1) {
ctrl->mixer1_played++;
/* enternal interface */
- if (ctrl->panel_mode & MDP4_PANEL_DTV)
+ if (ctrl->panel_mode & MDP4_PANEL_DTV) {
mdp4_overlay_dtv_ov_done_push(mfd, pipe);
+ if (!mfd->use_ov1_blt)
+ mdp4_overlay1_update_blt_mode(mfd);
+ }
} else {
/* primary interface */
@@ -2656,9 +2697,13 @@
if (srcp2_file)
put_pmem_file(srcp2_file);
#endif
+ /* only source may use frame buffer */
+ if (img->flags & MDP_MEMORY_ID_TYPE_FB)
+ fput_light(srcp0_file, ps0_need);
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- if (!IS_ERR_OR_NULL(srcp0_ihdl))
+ else if (!IS_ERR_OR_NULL(srcp0_ihdl))
ion_free(mfd->iclient, srcp0_ihdl);
+
if (!IS_ERR_OR_NULL(srcp1_ihdl))
ion_free(mfd->iclient, srcp1_ihdl);
if (!IS_ERR_OR_NULL(srcp2_ihdl))
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 635b104..d5c08e8 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -301,7 +301,7 @@
/* MSP_BORDER_COLOR */
MDP_OUTP(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x5008,
(0x0 & 0xFFF)); /* 12-bit R */
- mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
} else {
switch (mfd->ibuf.bpp) {
case 2:
@@ -596,13 +596,11 @@
void mdp4_dtv_overlay_blt_start(struct msm_fb_data_type *mfd)
{
- mdp4_allocate_writeback_buf(mfd, MDP4_MIXER1);
mdp4_dtv_do_blt(mfd, 1);
}
void mdp4_dtv_overlay_blt_stop(struct msm_fb_data_type *mfd)
{
- mdp4_free_writeback_buf(mfd, MDP4_MIXER1);
mdp4_dtv_do_blt(mfd, 0);
}
diff --git a/drivers/video/msm/msm_dss_io_8960.c b/drivers/video/msm/msm_dss_io_8960.c
index 3b000ec..0f40c77 100644
--- a/drivers/video/msm/msm_dss_io_8960.c
+++ b/drivers/video/msm/msm_dss_io_8960.c
@@ -11,6 +11,7 @@
*
*/
#include <linux/clk.h>
+#include <mach/clk.h>
#include "msm_fb.h"
#include "mdp.h"
#include "mdp4.h"
@@ -634,6 +635,10 @@
hdmi_msm_clk(0);
udelay(5);
hdmi_msm_clk(1);
+
+ clk_reset(hdmi_msm_state->hdmi_app_clk, CLK_RESET_ASSERT);
+ udelay(20);
+ clk_reset(hdmi_msm_state->hdmi_app_clk, CLK_RESET_DEASSERT);
}
void hdmi_msm_init_phy(int video_format)
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index 9837f07..a4b46ea 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -177,6 +177,7 @@
u32 mem_hid;
u32 mdp_rev;
u32 use_ov0_blt, ov0_blt_state;
+ u32 use_ov1_blt, ov1_blt_state;
u32 writeback_state;
};
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
index 3f54756..267e924 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -246,6 +246,8 @@
DDL_METADATA_ALIGNSIZE(suffix);
encoder->suffix = suffix;
encoder->output_buf_req.sz += suffix;
+ encoder->output_buf_req.sz =
+ DDL_ALIGN(encoder->output_buf_req.sz, DDL_KILO_BYTE(4));
}
u32 ddl_set_metadata_params(struct ddl_client_context *ddl,
@@ -454,6 +456,7 @@
return;
}
out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
+ DDL_MSG_LOW("processing metadata for encoder");
start_addr = (u32) ((u8 *)out_frame->virtual + out_frame->offset);
qfiller = (u32 *)((out_frame->data_len +
start_addr + 3) & ~3);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index 51a72c8..444db9f 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -915,10 +915,15 @@
}
case VCD_I_METADATA_ENABLE:
case VCD_I_METADATA_HEADER:
- DDL_MSG_ERROR("Meta Data Interface is Requested");
- vcd_status = ddl_set_metadata_params(ddl, property_hdr,
- property_value);
- vcd_status = VCD_S_SUCCESS;
+ DDL_MSG_LOW("Meta Data Interface is Requested");
+ if (!res_trk_check_for_sec_session()) {
+ vcd_status = ddl_set_metadata_params(ddl,
+ property_hdr, property_value);
+ } else {
+ DDL_MSG_ERROR("Meta Data Interface is not "
+ "supported in secure session");
+ vcd_status = VCD_ERR_ILLEGAL_OP;
+ }
break;
case VCD_I_META_BUFFER_MODE:
vcd_status = VCD_S_SUCCESS;
@@ -1836,8 +1841,16 @@
/*original_buf_req->align <= req_buf_req->align,*/
original_buf_req->sz <= req_buf_req->sz)
status = true;
- else
+ else {
DDL_MSG_ERROR("ddl_valid_buf_req:Failed");
+ DDL_MSG_ERROR("codec_buf_req: min_cnt=%d, mx_cnt=%d, "
+ "align=%d, sz=%d\n", original_buf_req->min_count,
+ original_buf_req->max_count, original_buf_req->align,
+ original_buf_req->sz);
+ DDL_MSG_ERROR("client_buffs: actual_count=%d, align=%d, "
+ "sz=%d\n", req_buf_req->actual_count,
+ req_buf_req->align, req_buf_req->sz);
+ }
return status;
}
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 6d6dcdc..3c25751 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1575,6 +1575,34 @@
}
break;
}
+ case VEN_IOCTL_SET_EXTRADATA:
+ case VEN_IOCTL_GET_EXTRADATA:
+ {
+ u32 extradata_flag;
+ DBG("VEN_IOCTL_(G)SET_EXTRADATA\n");
+ if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+ return -EFAULT;
+ if (cmd == VEN_IOCTL_SET_EXTRADATA) {
+ if (copy_from_user(&extradata_flag, venc_msg.in,
+ sizeof(u32)))
+ return -EFAULT;
+ result = vid_enc_set_get_extradata(client_ctx,
+ &extradata_flag, true);
+ } else {
+ result = vid_enc_set_get_extradata(client_ctx,
+ &extradata_flag, false);
+ if (result) {
+ if (copy_to_user(venc_msg.out, &extradata_flag,
+ sizeof(u32)))
+ return -EFAULT;
+ }
+ }
+ if (!result) {
+ ERR("setting VEN_IOCTL_(G)SET_LIVE_MODE failed\n");
+ return -EIO;
+ }
+ break;
+ }
case VEN_IOCTL_SET_AC_PREDICTION:
case VEN_IOCTL_GET_AC_PREDICTION:
case VEN_IOCTL_SET_RVLC:
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index f362f7b..cac5dc4 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -316,6 +316,42 @@
return true;
}
+u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx,
+ u32 *extradata_flag, u32 set_flag)
+{
+ struct vcd_property_hdr vcd_property_hdr;
+ struct vcd_property_meta_data_enable vcd_meta_data;
+ u32 vcd_status = VCD_ERR_FAIL;
+ if (!client_ctx || !extradata_flag)
+ return false;
+ vcd_property_hdr.prop_id = VCD_I_METADATA_ENABLE;
+ vcd_property_hdr.sz = sizeof(struct vcd_property_meta_data_enable);
+ if (set_flag) {
+ DBG("vcd_set_property: VCD_I_METADATA_ENABLE = %d\n",
+ *extradata_flag);
+ vcd_meta_data.meta_data_enable_flag = *extradata_flag;
+ vcd_status = vcd_set_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &vcd_meta_data);
+ if (vcd_status) {
+ ERR("%s(): Set VCD_I_METADATA_ENABLE Failed\n",
+ __func__);
+ return false;
+ }
+ } else {
+ vcd_status = vcd_get_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &vcd_meta_data);
+ if (vcd_status) {
+ ERR("%s(): Get VCD_I_METADATA_ENABLE Failed\n",
+ __func__);
+ return false;
+ }
+ *extradata_flag = vcd_meta_data.meta_data_enable_flag;
+ DBG("vcd_get_property: VCD_I_METADATA_ENABLE = %d\n",
+ *extradata_flag);
+ }
+ return true;
+}
+
u32 vid_enc_set_get_framerate(struct video_client_ctx *client_ctx,
struct venc_framerate *frame_rate, u32 set_flag)
{
@@ -1494,6 +1530,11 @@
venc_buf_req->alignment = buffer_req.align;
venc_buf_req->bufpoolid = buffer_req.buf_pool_id;
venc_buf_req->suffixsize = 0;
+ DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, "
+ "max_count=%d, buf_pool_id=%d\n", __func__,
+ buffer_req.actual_count, buffer_req.align,
+ buffer_req.sz, buffer_req.min_count,
+ buffer_req.max_count, buffer_req.buf_pool_id);
}
return status;
}
@@ -1521,6 +1562,11 @@
buffer_req.align = venc_buf_req->alignment;
buffer_req.buf_pool_id = 0;
+ DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, "
+ "max_count=%d, buf_pool_id=%d\n", __func__,
+ buffer_req.actual_count, buffer_req.align, buffer_req.sz,
+ buffer_req.min_count, buffer_req.max_count,
+ buffer_req.buf_pool_id);
vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle,
buffer, &buffer_req);
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.h b/drivers/video/msm/vidc/common/enc/venc_internal.h
index a07f7ab..8a07fdb 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.h
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.h
@@ -68,6 +68,9 @@
u32 vid_enc_set_get_live_mode(struct video_client_ctx *client_ctx,
struct venc_switch *encoder_switch, u32 set_flag);
+u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx,
+ u32 *extradata_flag, u32 set_flag);
+
u32 vid_enc_set_get_short_header(struct video_client_ctx *client_ctx,
struct venc_switch *encoder_switch, u32 set_flag);
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index 3ac41bc..a2391e3 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -29,6 +29,12 @@
/* MXT_TOUCH_KEYARRAY_T15 */
#define MXT_KEYARRAY_MAX_KEYS 32
+/* Bootoader IDs */
+#define MXT_BOOTLOADER_ID_224 0x0A
+#define MXT_BOOTLOADER_ID_224E 0x06
+#define MXT_BOOTLOADER_ID_1386 0x01
+#define MXT_BOOTLOADER_ID_1386E 0x10
+
/* Config data for a given maXTouch controller with a specific firmware */
struct mxt_config_info {
const u8 *config;
@@ -37,6 +43,7 @@
u8 variant_id;
u8 version;
u8 build;
+ u8 bootldr_id;
/* Points to the firmware name to be upgraded to */
const char *fw_name;
};
diff --git a/include/linux/libra_sdioif.h b/include/linux/libra_sdioif.h
index 965e2b5..08be83a 100644
--- a/include/linux/libra_sdioif.h
+++ b/include/linux/libra_sdioif.h
@@ -35,6 +35,7 @@
typedef int (suspend_handler_t)(struct sdio_func *);
typedef void (resume_handler_t)(struct sdio_func *);
+int libra_enable_sdio_irq_in_chip(struct sdio_func *func, u8 enable);
int libra_sdio_configure(sdio_irq_handler_t libra_sdio_rxhandler,
void (*func_drv_fn)(int *status),
u32 funcdrv_timeout, u32 blksize);
diff --git a/include/linux/mfd/wcd9xxx/wcd9310_registers.h b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
index d2736ea..67c2a6b 100644
--- a/include/linux/mfd/wcd9xxx/wcd9310_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
@@ -897,6 +897,38 @@
#define TABLA_A_CDC_DEBUG_B5_CTL__POR (0x00000000)
#define TABLA_A_CDC_DEBUG_B6_CTL (0x0000036D)
#define TABLA_A_CDC_DEBUG_B6_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B1_CTL (0x00000370)
+#define TABLA_A_CDC_COMP1_B1_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B2_CTL (0x00000371)
+#define TABLA_A_CDC_COMP1_B2_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B3_CTL (0x00000372)
+#define TABLA_A_CDC_COMP1_B3_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B4_CTL (0x00000373)
+#define TABLA_A_CDC_COMP1_B4_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B5_CTL (0x00000374)
+#define TABLA_A_CDC_COMP1_B5_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_B6_CTL (0x00000375)
+#define TABLA_A_CDC_COMP1_B6_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS (0x00000376)
+#define TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS__POR (0x00000000)
+#define TABLA_A_CDC_COMP1_FS_CFG (0x00000377)
+#define TABLA_A_CDC_COMP1_FS_CFG__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B1_CTL (0x00000378)
+#define TABLA_A_CDC_COMP2_B1_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B2_CTL (0x00000379)
+#define TABLA_A_CDC_COMP2_B2_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B3_CTL (0x0000037A)
+#define TABLA_A_CDC_COMP2_B3_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B4_CTL (0x0000037B)
+#define TABLA_A_CDC_COMP2_B4_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B5_CTL (0x0000037C)
+#define TABLA_A_CDC_COMP2_B5_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_B6_CTL (0x0000037D)
+#define TABLA_A_CDC_COMP2_B6_CTL__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS (0x0000037E)
+#define TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS__POR (0x00000000)
+#define TABLA_A_CDC_COMP2_FS_CFG (0x0000037F)
+#define TABLA_A_CDC_COMP2_FS_CFG__POR (0x00000000)
#define TABLA_A_CDC_CONN_RX1_B1_CTL (0x00000380)
#define TABLA_A_CDC_CONN_RX1_B1_CTL__POR (0x00000000)
#define TABLA_A_CDC_CONN_RX1_B2_CTL (0x00000381)
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index 1f264e9..bf149eb 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -52,6 +52,11 @@
#define VEN_BUFFLAG_EXTRADATA 0x00000040
#define VEN_BUFFLAG_CODECCONFIG 0x00000080
+/*Post processing flags bit masks*/
+#define VEN_EXTRADATA_NONE 0x001
+#define VEN_EXTRADATA_QCOMFILLER 0x002
+#define VEN_EXTRADATA_SLICEINFO 0x100
+
/*ENCODER CONFIGURATION CONSTANTS*/
/*Encoded video frame types*/
@@ -257,6 +262,8 @@
#define VEN_IOCTL_GET_RECON_BUFFER_SIZE \
_IOW(VEN_IOCTLBASE_NENC, 22, struct venc_ioctl_msg)
+
+
/*ENCODER PROPERTY CONFIGURATION & CAPABILITY IOCTLs*/
/*IOCTL params:SET: InputData - venc_basecfg, OutputData - NULL
@@ -439,6 +446,14 @@
#define VEN_IOCTL_SET_METABUFFER_MODE \
_IOW(VEN_IOCTLBASE_ENC, 47, struct venc_ioctl_msg)
+
+/*IOCTL params:SET: InputData - unsigned int, OutputData - NULL.*/
+#define VEN_IOCTL_SET_EXTRADATA \
+ _IOW(VEN_IOCTLBASE_ENC, 48, struct venc_ioctl_msg)
+/*IOCTL params:GET: InputData - NULL, OutputData - unsigned int.*/
+#define VEN_IOCTL_GET_EXTRADATA \
+ _IOR(VEN_IOCTLBASE_ENC, 49, struct venc_ioctl_msg)
+
struct venc_switch{
unsigned char status;
};
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index 736203b..e4ee15c 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -147,7 +147,7 @@
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
#define OTG_STATUS_SELECTOR 0xF000
-#define THOST_REQ_POLL 2000 /* msec */
+#define THOST_REQ_POLL 1500 /* msec (1000 - 2000) */
#define HOST_REQUEST_FLAG 0
/* Bit array elements as returned by the USB_REQ_GET_STATUS request. */
@@ -617,8 +617,10 @@
__u8 bDescriptorType;
__u8 bmAttributes; /* support for HNP, SRP, etc */
+ __le16 bcdOTG;
} __attribute__ ((packed));
+#define USB_DT_OTG_SIZE 5
/* from usb_otg_descriptor.bmAttributes */
#define USB_OTG_SRP (1 << 0)
#define USB_OTG_HNP (1 << 1) /* swap host/device roles */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 47e8427..a9c1b6a 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -860,6 +860,11 @@
/* utility to simplify managing config descriptors */
+/* Find and fill the requested descriptor into buffer */
+int
+usb_find_descriptor_fillbuf(void *, unsigned,
+ const struct usb_descriptor_header **, u8);
+
/* write vector of descriptors into buffer */
int usb_descriptor_fillbuf(void *, unsigned,
const struct usb_descriptor_header **);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index fec6f32..86479ab 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1106,9 +1106,25 @@
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
if (conn) {
- if (status && conn->state == BT_CONFIG) {
- hci_proto_connect_cfm(conn, status);
- hci_conn_put(conn);
+ if (status) {
+ mgmt_auth_failed(hdev->id, &conn->dst, status);
+ clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
+
+ if (conn->state == BT_CONFIG) {
+ conn->state = BT_CONNECTED;
+ hci_proto_connect_cfm(conn, status);
+ hci_conn_put(conn);
+ } else {
+ hci_auth_cfm(conn, status);
+ hci_conn_hold(conn);
+ conn->disc_timeout = HCI_DISCONN_TIMEOUT;
+ hci_conn_put(conn);
+ }
+
+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+ hci_encrypt_cfm(conn, status, 0x00);
+ }
}
conn->auth_initiator = 1;
}
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 9662795..a3d5e34 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -569,7 +569,7 @@
struct hci_chan *ampchan = l2cap_pi(sk)->ampchan;
l2cap_pi(sk)->ampchan = NULL;
if (!hci_chan_put(ampchan))
- l2cap_deaggregate(l2cap_pi(sk)->ampchan, l2cap_pi(sk));
+ l2cap_deaggregate(ampchan, l2cap_pi(sk));
}
sk->sk_state = BT_CLOSED;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 910ef77..25ad435 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2672,8 +2672,11 @@
if ((conn->auth_type & HCI_AT_DEDICATED_BONDING) &&
conn->auth_initiator && rem_cap == 0x03)
ev.auto_confirm = 1;
- else if (loc_cap == 0x01 && (rem_cap == 0x00 || rem_cap == 0x03))
+ else if (loc_cap == 0x01 && (rem_cap == 0x00 || rem_cap == 0x03)) {
+ if (!loc_mitm && !rem_mitm)
+ value = 0;
goto no_auto_confirm;
+ }
if ((!loc_mitm || rem_cap == 0x03) && (!rem_mitm || loc_cap == 0x03))
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 0d41625..11e1a67 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -8,9 +8,10 @@
use strict;
use constant BEFORE_SHORTTEXT => 0;
-use constant IN_SHORTTEXT => 1;
-use constant AFTER_SHORTTEXT => 2;
-use constant CHECK_NEXT_SHORTTEXT => 3;
+use constant IN_SHORTTEXT_BLANKLINE => 1;
+use constant IN_SHORTTEXT => 2;
+use constant AFTER_SHORTTEXT => 3;
+use constant CHECK_NEXT_SHORTTEXT => 4;
use constant SHORTTEXT_LIMIT => 75;
my $P = $0;
@@ -1233,6 +1234,7 @@
my $shorttext = BEFORE_SHORTTEXT;
my $shorttext_exspc = 0;
+ my $commit_text_present = 0;
sanitise_line_reset();
cleanup_continuation_headers();
@@ -1416,8 +1418,24 @@
my $hereprev = "$here\n$prevrawline\n$rawline\n";
if ($shorttext != AFTER_SHORTTEXT) {
+ if ($shorttext == IN_SHORTTEXT_BLANKLINE && $line=~/\S/) {
+ # the subject line was just processed,
+ # a blank line must be next
+ WARN("non-blank line after summary line\n" . $herecurr);
+ $shorttext = IN_SHORTTEXT;
+ # this non-blank line may or may not be commit text -
+ # a warning has been generated so assume it is commit
+ # text and move on
+ $commit_text_present = 1;
+ # fall through and treat this line as IN_SHORTTEXT
+ }
if ($shorttext == IN_SHORTTEXT) {
if ($line=~/^---/ || $line=~/^diff.*/) {
+ if ($commit_text_present == 0) {
+ WARN("please add commit text explaining " .
+ "*why* the change is needed\n" .
+ $herecurr);
+ }
$shorttext = AFTER_SHORTTEXT;
} elsif (length($line) > (SHORTTEXT_LIMIT +
$shorttext_exspc)
@@ -1427,7 +1445,22 @@
WARN("commit text line over " .
SHORTTEXT_LIMIT .
" characters\n" . $herecurr);
+ } elsif ($line=~/^\s*[\x21-\x39\x3b-\x7e]+:/) {
+ # this is a tag, there must be commit
+ # text by now
+ if ($commit_text_present == 0) {
+ WARN("please add commit text explaining " .
+ "*why* the change is needed\n" .
+ $herecurr);
+ # prevent duplicate warnings
+ $commit_text_present = 1;
+ }
+ } elsif ($line=~/\S/) {
+ $commit_text_present = 1;
}
+ } elsif ($shorttext == IN_SHORTTEXT_BLANKLINE) {
+ # case of non-blank line in this state handled above
+ $shorttext = IN_SHORTTEXT;
} elsif ($shorttext == CHECK_NEXT_SHORTTEXT) {
# The Subject line doesn't have to be the last header in the patch.
# Avoid moving to the IN_SHORTTEXT state until clear of all headers.
@@ -1435,16 +1468,25 @@
# text which looks like a header is definitely a header.
if ($line!~/^[\x21-\x39\x3b-\x7e]+:/) {
$shorttext = IN_SHORTTEXT;
-# Check for Subject line followed by a blank line.
+ # Check for Subject line followed by a blank line.
if (length($line) != 0) {
WARN("non-blank line after " .
"summary line\n" .
$sublinenr . $here .
"\n" . $subjectline .
"\n" . $line . "\n");
+ # this non-blank line may or may not
+ # be commit text - a warning has been
+ # generated so assume it is commit
+ # text and move on
+ $commit_text_present = 1;
}
}
+ # The next two cases are BEFORE_SHORTTEXT.
} elsif ($line=~/^Subject: \[[^\]]*\] (.*)/) {
+ # This is the subject line. Go to
+ # CHECK_NEXT_SHORTTEXT to wait for the commit
+ # text to show up.
$shorttext = CHECK_NEXT_SHORTTEXT;
$subjectline = $line;
$sublinenr = "#$linenr & ";
@@ -1455,7 +1497,10 @@
" characters\n" . $herecurr);
}
} elsif ($line=~/^ (.*)/) {
- $shorttext = IN_SHORTTEXT;
+ # Indented format, this must be the summary
+ # line (i.e. git show). There will be no more
+ # headers so we are now in the shorttext.
+ $shorttext = IN_SHORTTEXT_BLANKLINE;
$shorttext_exspc = 4;
if (length($1) > SHORTTEXT_LIMIT) {
WARN("summary line over " .
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 4d40384..2c52866 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -55,16 +55,17 @@
echo "+"
return
fi
- # If we are past a tagged commit (like
- # "v2.6.30-rc5-302-g72357d5"), we pretty print it.
- if atag="`git describe 2>/dev/null`"; then
- echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
-
- # If we don't have a tag at all we print -g{commitish}.
- else
- printf '%s%s' -g $head
- fi
fi
+ # If we are past a tagged commit (like
+ # "v2.6.30-rc5-302-g72357d5"), we pretty print it but strip
+ # off the v2.6.30-rc5 part because that's in the Makefile.
+ if atag="`git describe 2>/dev/null`"; then
+ atag="-${atag/v$KERNELVERSION-/}"
+ # If we don't have a tag at all we print -g{commitish}.
+ else
+ atag="-g$head"
+ fi
+ printf '%s' "$atag"
# Is this git on svn?
if git config --get svn-remote.svn.url >/dev/null; then
diff --git a/sound/soc/codecs/wcd9310-tables.c b/sound/soc/codecs/wcd9310-tables.c
index e0ad541..2cba59d 100644
--- a/sound/soc/codecs/wcd9310-tables.c
+++ b/sound/soc/codecs/wcd9310-tables.c
@@ -451,6 +451,22 @@
[TABLA_A_CDC_DEBUG_B4_CTL] = 1,
[TABLA_A_CDC_DEBUG_B5_CTL] = 1,
[TABLA_A_CDC_DEBUG_B6_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B1_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B2_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B3_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B4_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B5_CTL] = 1,
+ [TABLA_A_CDC_COMP1_B6_CTL] = 1,
+ [TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS] = 1,
+ [TABLA_A_CDC_COMP1_FS_CFG] = 1,
+ [TABLA_A_CDC_COMP2_B1_CTL] = 1,
+ [TABLA_A_CDC_COMP2_B2_CTL] = 1,
+ [TABLA_A_CDC_COMP2_B3_CTL] = 1,
+ [TABLA_A_CDC_COMP2_B4_CTL] = 1,
+ [TABLA_A_CDC_COMP2_B5_CTL] = 1,
+ [TABLA_A_CDC_COMP2_B6_CTL] = 1,
+ [TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS] = 1,
+ [TABLA_A_CDC_COMP2_FS_CFG] = 1,
[TABLA_A_CDC_CONN_RX1_B1_CTL] = 1,
[TABLA_A_CDC_CONN_RX1_B2_CTL] = 1,
[TABLA_A_CDC_CONN_RX1_B3_CTL] = 1,
@@ -993,6 +1009,24 @@
[TABLA_A_CDC_DEBUG_B4_CTL] = TABLA_A_CDC_DEBUG_B4_CTL__POR,
[TABLA_A_CDC_DEBUG_B5_CTL] = TABLA_A_CDC_DEBUG_B5_CTL__POR,
[TABLA_A_CDC_DEBUG_B6_CTL] = TABLA_A_CDC_DEBUG_B6_CTL__POR,
+ [TABLA_A_CDC_COMP1_B1_CTL] = TABLA_A_CDC_COMP1_B1_CTL__POR,
+ [TABLA_A_CDC_COMP1_B2_CTL] = TABLA_A_CDC_COMP1_B2_CTL__POR,
+ [TABLA_A_CDC_COMP1_B3_CTL] = TABLA_A_CDC_COMP1_B3_CTL__POR,
+ [TABLA_A_CDC_COMP1_B4_CTL] = TABLA_A_CDC_COMP1_B4_CTL__POR,
+ [TABLA_A_CDC_COMP1_B5_CTL] = TABLA_A_CDC_COMP1_B5_CTL__POR,
+ [TABLA_A_CDC_COMP1_B6_CTL] = TABLA_A_CDC_COMP1_B6_CTL__POR,
+ [TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS] =
+ TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS__POR,
+ [TABLA_A_CDC_COMP1_FS_CFG] = TABLA_A_CDC_COMP1_FS_CFG__POR,
+ [TABLA_A_CDC_COMP2_B1_CTL] = TABLA_A_CDC_COMP2_B1_CTL__POR,
+ [TABLA_A_CDC_COMP2_B2_CTL] = TABLA_A_CDC_COMP2_B2_CTL__POR,
+ [TABLA_A_CDC_COMP2_B3_CTL] = TABLA_A_CDC_COMP2_B3_CTL__POR,
+ [TABLA_A_CDC_COMP2_B4_CTL] = TABLA_A_CDC_COMP2_B4_CTL__POR,
+ [TABLA_A_CDC_COMP2_B5_CTL] = TABLA_A_CDC_COMP2_B5_CTL__POR,
+ [TABLA_A_CDC_COMP2_B6_CTL] = TABLA_A_CDC_COMP2_B6_CTL__POR,
+ [TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS] =
+ TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS__POR,
+ [TABLA_A_CDC_COMP2_FS_CFG] = TABLA_A_CDC_COMP2_FS_CFG__POR,
[TABLA_A_CDC_CONN_RX1_B1_CTL] = TABLA_A_CDC_CONN_RX1_B1_CTL__POR,
[TABLA_A_CDC_CONN_RX1_B2_CTL] = TABLA_A_CDC_CONN_RX1_B2_CTL__POR,
[TABLA_A_CDC_CONN_RX1_B3_CTL] = TABLA_A_CDC_CONN_RX1_B3_CTL__POR,
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 082b29e..0ae9680 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -53,6 +53,7 @@
#define AIF1_CAP 2
#define AIF2_PB 3
#define NUM_CODEC_DAIS 3
+#define TABLA_COMP_DIGITAL_GAIN_OFFSET 3
struct tabla_codec_dai_data {
u32 rate;
@@ -103,6 +104,20 @@
BAND_MAX,
};
+enum {
+ COMPANDER_1 = 0,
+ COMPANDER_2,
+ COMPANDER_MAX,
+};
+
+enum {
+ COMPANDER_FS_8KHZ = 0,
+ COMPANDER_FS_16KHZ,
+ COMPANDER_FS_32KHZ,
+ COMPANDER_FS_48KHZ,
+ COMPANDER_FS_MAX,
+};
+
/* Flags to track of PA and DAC state.
* PA and DAC should be tracked separately as AUXPGA loopback requires
* only PA to be turned on without DAC being on. */
@@ -113,6 +128,13 @@
TABLA_HPHR_DAC_OFF_ACK
};
+
+struct comp_sample_dependent_params {
+ u32 peak_det_timeout;
+ u32 rms_meter_div_fact;
+ u32 rms_meter_resamp_fact;
+};
+
/* Data used by MBHC */
struct mbhc_internal_cal_data {
u16 dce_z;
@@ -210,12 +232,56 @@
/* num of slim ports required */
struct tabla_codec_dai_data dai[NUM_CODEC_DAIS];
+
+ /*compander*/
+ int comp_enabled[COMPANDER_MAX];
+ u32 comp_fs[COMPANDER_MAX];
};
#ifdef CONFIG_DEBUG_FS
struct tabla_priv *debug_tabla_priv;
#endif
+static const u32 comp_shift[] = {
+ 0,
+ 2,
+};
+
+static const int comp_rx_path[] = {
+ COMPANDER_1,
+ COMPANDER_1,
+ COMPANDER_2,
+ COMPANDER_2,
+ COMPANDER_2,
+ COMPANDER_2,
+ COMPANDER_MAX,
+};
+
+static const struct comp_sample_dependent_params comp_samp_params[] = {
+ {
+ .peak_det_timeout = 0x2,
+ .rms_meter_div_fact = 0x8 << 4,
+ .rms_meter_resamp_fact = 0x21,
+ },
+ {
+ .peak_det_timeout = 0x3,
+ .rms_meter_div_fact = 0x9 << 4,
+ .rms_meter_resamp_fact = 0x28,
+ },
+
+ {
+ .peak_det_timeout = 0x5,
+ .rms_meter_div_fact = 0xB << 4,
+ .rms_meter_resamp_fact = 0x28,
+ },
+
+ {
+ .peak_det_timeout = 0x5,
+ .rms_meter_div_fact = 0xB << 4,
+ .rms_meter_resamp_fact = 0x28,
+ },
+};
+
static int tabla_codec_enable_charge_pump(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -479,6 +545,192 @@
return 0;
}
+static int tabla_compander_gain_offset(
+ struct snd_soc_codec *codec, u32 enable,
+ unsigned int reg, int mask, int event)
+{
+ int pa_mode = snd_soc_read(codec, reg) & mask;
+ int gain_offset = 0;
+ /* if PMU && enable is 1-> offset is 3
+ * if PMU && enable is 0-> offset is 0
+ * if PMD && pa_mode is PA -> offset is 0: PMU compander is off
+ * if PMD && pa_mode is comp -> offset is -3: PMU compander is on.
+ */
+
+ if (SND_SOC_DAPM_EVENT_ON(event) && (enable != 0))
+ gain_offset = TABLA_COMP_DIGITAL_GAIN_OFFSET;
+ if (SND_SOC_DAPM_EVENT_OFF(event) && (pa_mode == 0))
+ gain_offset = -TABLA_COMP_DIGITAL_GAIN_OFFSET;
+ return gain_offset;
+}
+
+
+static int tabla_config_gain_compander(
+ struct snd_soc_codec *codec,
+ u32 compander, u32 enable, int event)
+{
+ int value = 0;
+ int mask = 1 << 4;
+ int gain = 0;
+ int gain_offset;
+ if (compander >= COMPANDER_MAX) {
+ pr_err("%s: Error, invalid compander channel\n", __func__);
+ return -EINVAL;
+ }
+
+ if ((enable == 0) || SND_SOC_DAPM_EVENT_OFF(event))
+ value = 1 << 4;
+
+ if (compander == COMPANDER_1) {
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_HPH_L_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_HPH_L_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_HPH_R_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_HPH_R_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ } else if (compander == COMPANDER_2) {
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_LINE_1_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_LINE_1_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_LINE_3_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_LINE_3_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_LINE_2_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_LINE_2_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ gain_offset = tabla_compander_gain_offset(codec, enable,
+ TABLA_A_RX_LINE_4_GAIN, mask, event);
+ snd_soc_update_bits(codec, TABLA_A_RX_LINE_4_GAIN, mask, value);
+ gain = snd_soc_read(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL);
+ snd_soc_update_bits(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL,
+ 0xFF, gain - gain_offset);
+ }
+ return 0;
+}
+static int tabla_get_compander(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ int comp = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->max;
+ struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = tabla->comp_enabled[comp];
+
+ return 0;
+}
+
+static int tabla_set_compander(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+ int comp = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->max;
+ int value = ucontrol->value.integer.value[0];
+
+ if (value == tabla->comp_enabled[comp]) {
+ pr_debug("%s: compander #%d enable %d no change\n",
+ __func__, comp, value);
+ return 0;
+ }
+ tabla->comp_enabled[comp] = value;
+ return 0;
+}
+
+
+static int tabla_config_compander(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+ u32 rate = tabla->comp_fs[w->shift];
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (tabla->comp_enabled[w->shift] != 0) {
+ /* Enable both L/R compander clocks */
+ snd_soc_update_bits(codec,
+ TABLA_A_CDC_CLK_RX_B2_CTL,
+ 0x03 << comp_shift[w->shift],
+ 0x03 << comp_shift[w->shift]);
+ /* Clar the HALT for the compander*/
+ snd_soc_update_bits(codec,
+ TABLA_A_CDC_COMP1_B1_CTL +
+ w->shift * 8, 1 << 2, 0);
+ /* Toggle compander reset bits*/
+ snd_soc_update_bits(codec,
+ TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+ 0x03 << comp_shift[w->shift],
+ 0x03 << comp_shift[w->shift]);
+ snd_soc_update_bits(codec,
+ TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+ 0x03 << comp_shift[w->shift], 0);
+ tabla_config_gain_compander(codec, w->shift, 1, event);
+ /* Update the RMS meter resampling*/
+ snd_soc_update_bits(codec,
+ TABLA_A_CDC_COMP1_B3_CTL +
+ w->shift * 8, 0xFF, 0x01);
+ /* Wait for 1ms*/
+ usleep_range(1000, 1000);
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ /* Set sample rate dependent paramater*/
+ if (tabla->comp_enabled[w->shift] != 0) {
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_FS_CFG +
+ w->shift * 8, 0x03, rate);
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
+ w->shift * 8, 0x0F,
+ comp_samp_params[rate].peak_det_timeout);
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
+ w->shift * 8, 0xF0,
+ comp_samp_params[rate].rms_meter_div_fact);
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B3_CTL +
+ w->shift * 8, 0xFF,
+ comp_samp_params[rate].rms_meter_resamp_fact);
+ /* Compander enable -> 0x370/0x378*/
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+ w->shift * 8, 0x03, 0x03);
+ }
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ /* Halt the compander*/
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+ w->shift * 8, 1 << 2, 1 << 2);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* Restore the gain */
+ tabla_config_gain_compander(codec, w->shift,
+ tabla->comp_enabled[w->shift], event);
+ /* Disable the compander*/
+ snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+ w->shift * 8, 0x03, 0x00);
+ /* Turn off the clock for compander in pair*/
+ snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_B2_CTL,
+ 0x03 << comp_shift[w->shift], 0);
+ break;
+ }
+ return 0;
+}
+
static const char *tabla_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
static const struct soc_enum tabla_ear_pa_gain_enum[] = {
SOC_ENUM_SINGLE_EXT(2, tabla_ear_pa_gain_text),
@@ -696,6 +948,10 @@
tabla_get_iir_band_audio_mixer, tabla_put_iir_band_audio_mixer),
SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
tabla_get_iir_band_audio_mixer, tabla_put_iir_band_audio_mixer),
+ SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, 1, COMPANDER_1, 0,
+ tabla_get_compander, tabla_set_compander),
+ SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, 0, COMPANDER_2, 0,
+ tabla_get_compander, tabla_set_compander),
};
static const struct snd_kcontrol_new tabla_1_x_snd_controls[] = {
@@ -2075,6 +2331,12 @@
{"LINEOUT4 DAC", NULL, "RX_BIAS"},
{"LINEOUT5 DAC", NULL, "RX_BIAS"},
+ {"RX1 MIX1", NULL, "COMP1_CLK"},
+ {"RX2 MIX1", NULL, "COMP1_CLK"},
+ {"RX3 MIX1", NULL, "COMP2_CLK"},
+ {"RX5 MIX1", NULL, "COMP2_CLK"},
+
+
{"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
{"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
{"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
@@ -2748,6 +3010,7 @@
u8 path, shift;
u16 tx_fs_reg, rx_fs_reg;
u8 tx_fs_rate, rx_fs_rate, rx_state, tx_state;
+ u32 compander_fs;
pr_debug("%s: DAI-ID %x rate %d\n", __func__, dai->id,
params_rate(params));
@@ -2756,18 +3019,22 @@
case 8000:
tx_fs_rate = 0x00;
rx_fs_rate = 0x00;
+ compander_fs = COMPANDER_FS_8KHZ;
break;
case 16000:
tx_fs_rate = 0x01;
rx_fs_rate = 0x20;
+ compander_fs = COMPANDER_FS_16KHZ;
break;
case 32000:
tx_fs_rate = 0x02;
rx_fs_rate = 0x40;
+ compander_fs = COMPANDER_FS_32KHZ;
break;
case 48000:
tx_fs_rate = 0x03;
rx_fs_rate = 0x60;
+ compander_fs = COMPANDER_FS_48KHZ;
break;
default:
pr_err("%s: Invalid sampling rate %d\n", __func__,
@@ -2845,6 +3112,9 @@
+ (BITS_PER_REG*(path-1));
snd_soc_update_bits(codec, rx_fs_reg,
0xE0, rx_fs_rate);
+ if (comp_rx_path[shift] < COMPANDER_MAX)
+ tabla->comp_fs[comp_rx_path[shift]]
+ = compander_fs;
}
}
if (tabla->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
@@ -3229,6 +3499,13 @@
SND_SOC_DAPM_SUPPLY("LDO_H", TABLA_A_LDO_H_MODE_1, 7, 0,
tabla_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_SUPPLY("COMP1_CLK", SND_SOC_NOPM, 0, 0,
+ tabla_config_compander, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("COMP2_CLK", SND_SOC_NOPM, 1, 0,
+ tabla_config_compander, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
+
SND_SOC_DAPM_INPUT("AMIC1"),
SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TABLA_A_MICB_1_CTL, 7, 0,
tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
@@ -4989,6 +5266,10 @@
tabla->mbhc_fake_ins_start = 0;
tabla->no_mic_headset_override = false;
tabla->codec = codec;
+ for (i = 0; i < COMPANDER_MAX; i++) {
+ tabla->comp_enabled[i] = 0;
+ tabla->comp_fs[i] = COMPANDER_FS_48KHZ;
+ }
tabla->pdata = dev_get_platdata(codec->dev->parent);
tabla->intf_type = wcd9xxx_get_intf_type();
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 73de89e..fe31b27 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -827,6 +827,9 @@
if (data->opcode == RESET_EVENTS) {
pr_debug("q6asm_callback: Reset event is received: %d %d apr[%p]\n",
data->reset_event, data->reset_proc, ac->apr);
+ if (ac->cb)
+ ac->cb(data->opcode, data->token,
+ (uint32_t *)data->payload, ac->priv);
apr_reset(ac->apr);
return 0;
}