Merge "arm: Turn off generic lockbreak when using ticket spinlocks" into msm-3.0
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index e4456dc..d14757b 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -191,8 +191,10 @@
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
CONFIG_IP6_NF_MANGLE=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 406992a..dafaffc 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -193,8 +193,10 @@
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
CONFIG_IP6_NF_MANGLE=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index a2c8827..1004683 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -222,6 +222,7 @@
select MSM_SPM_V2
select MSM_L2_SPM
select MSM_PM8X60 if PM
+ select CPU_HAS_L2_PMU
config ARCH_MSMCOPPER
bool "MSM Copper"
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 1f3945e..525dce4 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -54,7 +54,7 @@
msm-etm-objs := etm.o
obj-$(CONFIG_MSM_ETM) += msm-etm.o
-obj-$(CONFIG_MSM_QDSS) += qdss.o qdss-etb.o qdss-tpiu.o qdss-funnel.o qdss-ptm.o
+obj-$(CONFIG_MSM_QDSS) += qdss.o qdss-etb.o qdss-tpiu.o qdss-funnel.o qdss-etm.o
quiet_cmd_mkrpcsym = MKCAP $@
cmd_mkrpcsym = $(PERL) $(srctree)/$(src)/mkrpcsym.pl $< $@
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 604769d..62e5dda 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -66,7 +66,6 @@
}
};
-#define PANEL_NAME_MAX_LEN 30
#define LVDS_CHIMEI_PANEL_NAME "lvds_chimei_wxga"
#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
#define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME "mipi_video_chimei_wxga"
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 05002a2..f4650a9 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -141,6 +141,8 @@
/* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
PM8921_MPP_INIT(7, D_OUTPUT, PM8921_MPP_DIG_LEVEL_VPH, DOUT_CTRL_LOW),
PM8921_MPP_INIT(8, D_OUTPUT, PM8921_MPP_DIG_LEVEL_S4, DOUT_CTRL_LOW),
+ /*MPP9 is used to detect docking station connection/removal on Liquid*/
+ PM8921_MPP_INIT(9, D_INPUT, PM8921_MPP_DIG_LEVEL_S4, DIN_TO_INT),
};
void __init apq8064_pm8xxx_gpio_mpp_init(void)
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 9d4f0aa..bc866d1 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -469,12 +469,50 @@
},
};
+/* Bandwidth requests (zero) if no vote placed */
+static struct msm_bus_vectors usb_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+
+/* Bus bandwidth requests in Bytes/sec */
+static struct msm_bus_vectors usb_max_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 60000000, /* At least 480Mbps on bus. */
+ .ib = 960000000, /* MAX bursts rate */
+ },
+};
+
+static struct msm_bus_paths usb_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(usb_init_vectors),
+ usb_init_vectors,
+ },
+ {
+ ARRAY_SIZE(usb_max_vectors),
+ usb_max_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata usb_bus_scale_pdata = {
+ usb_bus_scale_usecases,
+ ARRAY_SIZE(usb_bus_scale_usecases),
+ .name = "usb",
+};
+
static struct msm_otg_platform_data msm_otg_pdata = {
.mode = USB_OTG,
.otg_control = OTG_PMIC_CONTROL,
.phy_type = SNPS_28NM_INTEGRATED_PHY,
.pmic_id_irq = PM8921_USB_ID_IN_IRQ(PM8921_IRQ_BASE),
.power_budget = 750,
+ .bus_scale_table = &usb_bus_scale_pdata,
};
static struct msm_usb_host_platform_data msm_ehci_host_pdata = {
@@ -484,6 +522,9 @@
static void __init apq8064_ehci_host_init(void)
{
if (machine_is_apq8064_liquid()) {
+ msm_ehci_host_pdata.dock_connect_irq =
+ PM8921_MPP_IRQ(PM8921_IRQ_BASE, 9);
+
apq8064_device_ehci_host3.dev.platform_data =
&msm_ehci_host_pdata;
platform_device_register(&apq8064_device_ehci_host3);
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index a840877..fe5d82f 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -68,7 +68,6 @@
#define MDP_VSYNC_GPIO 0
-#define PANEL_NAME_MAX_LEN 30
#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME "mipi_cmd_novatek_qhd"
#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME "mipi_video_novatek_qhd"
#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
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-display.c b/arch/arm/mach-msm/board-8960-display.c
index 4dba1be..80372c5 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -46,13 +46,8 @@
#define MSM_FB_EXT_BUF_SIZE 0
#endif
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-/* 4 bpp x 2 page HDMI case */
-#define MSM_FB_SIZE roundup((1920 * 1088 * 4 * 2), 4096)
-#else
/* Note: must be multiple of 4096 */
#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE, 4096)
-#endif
#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
#define MSM_FB_OVERLAY0_WRITEBACK_SIZE roundup((1920 * 1200 * 3 * 2), 4096)
@@ -68,7 +63,6 @@
#define MDP_VSYNC_GPIO 0
-#define PANEL_NAME_MAX_LEN 30
#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME "mipi_cmd_novatek_qhd"
#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME "mipi_video_novatek_qhd"
#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
@@ -80,6 +74,12 @@
#define HDMI_PANEL_NAME "hdmi_msm"
#define TVOUT_PANEL_NAME "tvout_msm"
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+unsigned char hdmi_is_primary = 1;
+#else
+unsigned char hdmi_is_primary;
+#endif
+
static struct resource msm_fb_resources[] = {
{
.flags = IORESOURCE_DMA,
@@ -624,29 +624,16 @@
#endif
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-static int mdp_core_clk_rate_table[] = {
- 200000000,
- 200000000,
- 200000000,
- 200000000,
-};
-#else
static int mdp_core_clk_rate_table[] = {
85330000,
128000000,
160000000,
200000000,
};
-#endif
static struct msm_panel_common_pdata mdp_pdata = {
.gpio = MDP_VSYNC_GPIO,
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- .mdp_core_clk_rate = 200000000,
-#else
.mdp_core_clk_rate = 85330000,
-#endif
.mdp_core_clk_table = mdp_core_clk_rate_table,
.num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
#ifdef CONFIG_MSM_BUS_SCALING
@@ -833,16 +820,6 @@
},
};
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-static struct msm_bus_vectors dtv_bus_def_vectors[] = {
- {
- .src = MSM_BUS_MASTER_MDP_PORT0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 2000000000,
- .ib = 2000000000,
- },
-};
-#else
static struct msm_bus_vectors dtv_bus_def_vectors[] = {
{
.src = MSM_BUS_MASTER_MDP_PORT0,
@@ -851,7 +828,6 @@
.ib = 707616000 * 2,
},
};
-#endif
static struct msm_bus_paths dtv_bus_scale_usecases[] = {
{
@@ -1108,3 +1084,27 @@
pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
size, addr, __pa(addr));
}
+
+void __init msm8960_set_display_params(char *prim_panel, char *ext_panel)
+{
+ if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
+ strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
+ PANEL_NAME_MAX_LEN);
+ pr_debug("msm_fb_pdata.prim_panel_name %s\n",
+ msm_fb_pdata.prim_panel_name);
+
+ if (!strncmp((char *)msm_fb_pdata.prim_panel_name,
+ HDMI_PANEL_NAME, strnlen(HDMI_PANEL_NAME,
+ PANEL_NAME_MAX_LEN))) {
+ pr_debug("HDMI is the primary display by"
+ " boot parameter\n");
+ hdmi_is_primary = 1;
+ }
+ }
+ if (strnlen(ext_panel, PANEL_NAME_MAX_LEN)) {
+ strlcpy(msm_fb_pdata.ext_panel_name, ext_panel,
+ PANEL_NAME_MAX_LEN);
+ pr_debug("msm_fb_pdata.ext_panel_name %s\n",
+ msm_fb_pdata.ext_panel_name);
+ }
+}
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 9a8b843..3b0f8be 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -131,12 +131,9 @@
#define MSM_PMEM_ADSP_SIZE 0x7800000
#define MSM_PMEM_AUDIO_SIZE 0x2B4000
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-#define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
-#else
#define MSM_PMEM_SIZE 0x2800000 /* 40 Mbytes */
-#endif
#define MSM_LIQUID_PMEM_SIZE 0x4000000 /* 64 Mbytes */
+#define MSM_HDMI_PRIM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
#define MSM_PMEM_KERNEL_EBI1_SIZE 0x280000
@@ -148,7 +145,9 @@
#define MSM_ION_AUDIO_SIZE MSM_PMEM_AUDIO_SIZE
#define MSM_ION_HEAP_NUM 8
#define MSM_LIQUID_ION_MM_SIZE (MSM_ION_MM_SIZE + 0x600000)
-static unsigned int msm_ion_cp_mm_size = MSM_ION_MM_SIZE;
+#define MSM_LIQUID_ION_SF_SIZE MSM_LIQUID_PMEM_SIZE
+#define MSM_HDMI_PRIM_ION_SF_SIZE MSM_HDMI_PRIM_PMEM_SIZE
+static unsigned msm_ion_sf_size = MSM_ION_SF_SIZE;
#else
#define MSM_PMEM_KERNEL_EBI1_SIZE 0x110C000
#define MSM_ION_HEAP_NUM 1
@@ -308,8 +307,13 @@
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
android_pmem_adsp_pdata.size = pmem_adsp_size;
- if (!pmem_param_set && machine_is_msm8960_liquid())
- pmem_size = MSM_LIQUID_PMEM_SIZE;
+ if (!pmem_param_set) {
+ if (machine_is_msm8960_liquid())
+ pmem_size = MSM_LIQUID_PMEM_SIZE;
+ if (hdmi_is_primary)
+ pmem_size = MSM_HDMI_PRIM_PMEM_SIZE;
+ }
+
android_pmem_pdata.size = pmem_size;
#endif
android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
@@ -463,14 +467,22 @@
{
unsigned int i;
- if (!pmem_param_set && machine_is_msm8960_liquid()) {
- msm_ion_cp_mm_size = MSM_LIQUID_ION_MM_SIZE;
- for (i = 0; i < ion_pdata.nr; i++) {
- if (ion_pdata.heaps[i].id == ION_CP_MM_HEAP_ID) {
- ion_pdata.heaps[i].size = msm_ion_cp_mm_size;
- pr_debug("msm_ion_cp_mm_size 0x%x\n",
- msm_ion_cp_mm_size);
- break;
+ if (!pmem_param_set) {
+ if (machine_is_msm8960_liquid())
+ msm_ion_sf_size = MSM_LIQUID_ION_SF_SIZE;
+
+ if (hdmi_is_primary)
+ msm_ion_sf_size = MSM_HDMI_PRIM_ION_SF_SIZE;
+
+ if (machine_is_msm8960_liquid() || hdmi_is_primary) {
+ for (i = 0; i < ion_pdata.nr; i++) {
+ if (ion_pdata.heaps[i].id == ION_SF_HEAP_ID) {
+ ion_pdata.heaps[i].size =
+ msm_ion_sf_size;
+ pr_debug("msm_ion_sf_size 0x%x\n",
+ msm_ion_sf_size);
+ break;
+ }
}
}
}
@@ -633,8 +645,27 @@
place_movable_zone();
}
+static char prim_panel_name[PANEL_NAME_MAX_LEN];
+static char ext_panel_name[PANEL_NAME_MAX_LEN];
+static int __init prim_display_setup(char *param)
+{
+ if (strnlen(param, PANEL_NAME_MAX_LEN))
+ strlcpy(prim_panel_name, param, PANEL_NAME_MAX_LEN);
+ return 0;
+}
+early_param("prim_display", prim_display_setup);
+
+static int __init ext_display_setup(char *param)
+{
+ if (strnlen(param, PANEL_NAME_MAX_LEN))
+ strlcpy(ext_panel_name, param, PANEL_NAME_MAX_LEN);
+ return 0;
+}
+early_param("ext_display", ext_display_setup);
+
static void __init msm8960_reserve(void)
{
+ msm8960_set_display_params(prim_panel_name, ext_panel_name);
msm_reserve();
fmem_pdata.phys = reserve_memory_for_fmem(fmem_pdata.size);
}
@@ -1884,6 +1915,7 @@
.variant_id = 0x0,
.version = 0x10,
.build = 0xAA,
+ .bootldr_id = MXT_BOOTLOADER_ID_1386,
},
{
.config = mxt1386e_config_data_v1_0,
@@ -1892,6 +1924,7 @@
.variant_id = 0x2,
.version = 0x10,
.build = 0xAA,
+ .bootldr_id = MXT_BOOTLOADER_ID_1386E,
.fw_name = "atmel_8960_liquid_v2_1_AA.hex",
},
{
@@ -1901,6 +1934,7 @@
.variant_id = 0x7,
.version = 0x21,
.build = 0xAA,
+ .bootldr_id = MXT_BOOTLOADER_ID_1386E,
},
};
diff --git a/arch/arm/mach-msm/board-8960.h b/arch/arm/mach-msm/board-8960.h
index 20af7b8..dc63fee 100644
--- a/arch/arm/mach-msm/board-8960.h
+++ b/arch/arm/mach-msm/board-8960.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 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
@@ -73,12 +73,15 @@
extern struct sx150x_platform_data msm8960_sx150x_data[];
extern struct msm_camera_board_info msm8960_camera_board_info;
+extern unsigned char hdmi_is_primary;
+
void msm8960_init_cam(void);
void msm8960_init_fb(void);
void msm8960_init_pmic(void);
void msm8960_init_mmc(void);
int msm8960_init_gpiomux(void);
void msm8960_allocate_fb_region(void);
+void msm8960_set_display_params(char *prim_panel, char *ext_panel);
void msm8960_pm8921_gpio_mpp_init(void);
void msm8960_mdp_writeback(struct memtype_reserve *reserve_table);
uint32_t msm_rpm_get_swfi_latency(void);
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index 644c0855..a8ab81a 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -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-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 45bfaed..b1fe0c7 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -208,7 +208,6 @@
}
};
-#define PANEL_NAME_MAX_LEN 30
#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 3ad4773..b44b03f 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -825,6 +825,7 @@
&msm8625_device_smd,
&msm8625_device_otg,
&msm8625_device_gadget_peripheral,
+ &msm8625_kgsl_3d0,
};
static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE;
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index e3fc97f..9b5e1e2 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -119,7 +119,6 @@
#define LCDC_AUO_SPI_DEVICE_NAME "lcdc_auo_nt35582"
#define LCDC_NT35582_PANEL_NAME "lcdc_nt35582_wvga"
-#define PANEL_NAME_MAX_LEN 30
#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME "mipi_cmd_novatek_qhd"
#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME "mipi_video_novatek_qhd"
#define MIPI_VIDEO_TOSHIBA_WVGA_PANEL_NAME "mipi_video_toshiba_wvga"
@@ -2660,19 +2659,17 @@
#define MSM_FB_EXT_BUFT_SIZE 0
#endif
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-/* 4 bpp x 2 page HDMI case */
-#define MSM_FB_SIZE roundup((1920 * 1088 * 4 * 2), 4096)
-#else
/* Note: must be multiple of 4096 */
#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE + \
MSM_FB_DSUB_PMEM_ADDER, 4096)
-#endif
+
+#define MSM_PMEM_SF_SIZE 0x4000000 /* 64 Mbytes */
+#define MSM_HDMI_PRIM_PMEM_SF_SIZE 0x4000000 /* 64 Mbytes */
#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-#define MSM_PMEM_SF_SIZE 0x8000000 /* 128 Mbytes */
+unsigned char hdmi_is_primary = 1;
#else
-#define MSM_PMEM_SF_SIZE 0x4000000 /* 64 Mbytes */
+unsigned char hdmi_is_primary;
#endif
#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
@@ -2712,6 +2709,8 @@
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
#define MSM_ION_HEAP_NUM 9
+#define MSM_HDMI_PRIM_ION_SF_SIZE MSM_HDMI_PRIM_PMEM_SF_SIZE
+static unsigned msm_ion_sf_size = MSM_ION_SF_SIZE;
#else
#define MSM_ION_HEAP_NUM 1
#endif
@@ -3159,7 +3158,11 @@
void *addr;
unsigned long size;
- size = MSM_FB_SIZE;
+ if (hdmi_is_primary)
+ size = roundup((1920 * 1088 * 4 * 2), 4096);
+ else
+ size = MSM_FB_SIZE;
+
addr = alloc_bootmem_align(size, 0x1000);
msm_fb_resources[0].start = __pa(addr);
msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
@@ -3168,6 +3171,30 @@
}
+void __init msm8x60_set_display_params(char *prim_panel, char *ext_panel)
+{
+ if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
+ strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
+ PANEL_NAME_MAX_LEN);
+ pr_debug("msm_fb_pdata.prim_panel_name %s\n",
+ msm_fb_pdata.prim_panel_name);
+
+ if (!strncmp((char *)msm_fb_pdata.prim_panel_name,
+ HDMI_PANEL_NAME, strnlen(HDMI_PANEL_NAME,
+ PANEL_NAME_MAX_LEN))) {
+ pr_debug("HDMI is the primary display by"
+ " boot parameter\n");
+ hdmi_is_primary = 1;
+ }
+ }
+ if (strnlen(ext_panel, PANEL_NAME_MAX_LEN)) {
+ strlcpy(msm_fb_pdata.ext_panel_name, ext_panel,
+ PANEL_NAME_MAX_LEN);
+ pr_debug("msm_fb_pdata.ext_panel_name %s\n",
+ msm_fb_pdata.ext_panel_name);
+ }
+}
+
#if defined(CONFIG_TOUCHSCREEN_CYTTSP_I2C) || \
defined(CONFIG_TOUCHSCREEN_CYTTSP_I2C_MODULE)
/*virtual key support */
@@ -5410,7 +5437,21 @@
static void reserve_ion_memory(void)
{
#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
- msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
+ unsigned int i;
+
+ if (hdmi_is_primary) {
+ msm_ion_sf_size = MSM_HDMI_PRIM_ION_SF_SIZE;
+ for (i = 0; i < ion_pdata.nr; i++) {
+ if (ion_pdata.heaps[i].id == ION_SF_HEAP_ID) {
+ ion_pdata.heaps[i].size = msm_ion_sf_size;
+ pr_debug("msm_ion_sf_size 0x%x\n",
+ msm_ion_sf_size);
+ break;
+ }
+ }
+ }
+
+ msm8x60_reserve_table[MEMTYPE_EBI1].size += msm_ion_sf_size;
msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MM_FW_SIZE;
msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MM_SIZE;
msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MFC_SIZE;
@@ -5426,6 +5467,9 @@
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
android_pmem_adsp_pdata.size = pmem_adsp_size;
android_pmem_smipool_pdata.size = MSM_PMEM_SMIPOOL_SIZE;
+
+ if (hdmi_is_primary)
+ pmem_sf_size = MSM_HDMI_PRIM_PMEM_SF_SIZE;
android_pmem_pdata.size = pmem_sf_size;
#endif
android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
@@ -5475,8 +5519,27 @@
.paddr_to_memtype = msm8x60_paddr_to_memtype,
};
+static char prim_panel_name[PANEL_NAME_MAX_LEN];
+static char ext_panel_name[PANEL_NAME_MAX_LEN];
+static int __init prim_display_setup(char *param)
+{
+ if (strnlen(param, PANEL_NAME_MAX_LEN))
+ strlcpy(prim_panel_name, param, PANEL_NAME_MAX_LEN);
+ return 0;
+}
+early_param("prim_display", prim_display_setup);
+
+static int __init ext_display_setup(char *param)
+{
+ if (strnlen(param, PANEL_NAME_MAX_LEN))
+ strlcpy(ext_panel_name, param, PANEL_NAME_MAX_LEN);
+ return 0;
+}
+early_param("ext_display", ext_display_setup);
+
static void __init msm8x60_reserve(void)
{
+ msm8x60_set_display_params(prim_panel_name, ext_panel_name);
reserve_info = &msm8x60_reserve_info;
msm_reserve();
}
@@ -9422,26 +9485,7 @@
.ib = 0,
},
};
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-static struct msm_bus_vectors dtv_bus_def_vectors[] = {
- /* For now, 0th array entry is reserved.
- * Please leave 0 as is and don't use it
- */
- {
- .src = MSM_BUS_MASTER_MDP_PORT0,
- .dst = MSM_BUS_SLAVE_SMI,
- .ab = 2000000000,
- .ib = 2000000000,
- },
- /* Master and slaves can be from different fabrics */
- {
- .src = MSM_BUS_MASTER_MDP_PORT0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 2000000000,
- .ib = 2000000000,
- },
-};
-#else
+
static struct msm_bus_vectors dtv_bus_def_vectors[] = {
/* For now, 0th array entry is reserved.
* Please leave 0 as is and don't use it
@@ -9460,7 +9504,26 @@
.ib = 707616000,
},
};
-#endif
+
+static struct msm_bus_vectors dtv_bus_hdmi_prim_vectors[] = {
+ /* For now, 0th array entry is reserved.
+ * Please leave 0 as is and don't use it
+ */
+ {
+ .src = MSM_BUS_MASTER_MDP_PORT0,
+ .dst = MSM_BUS_SLAVE_SMI,
+ .ab = 2000000000,
+ .ib = 2000000000,
+ },
+ /* Master and slaves can be from different fabrics */
+ {
+ .src = MSM_BUS_MASTER_MDP_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 2000000000,
+ .ib = 2000000000,
+ },
+};
+
static struct msm_bus_paths dtv_bus_scale_usecases[] = {
{
ARRAY_SIZE(dtv_bus_init_vectors),
@@ -9471,6 +9534,7 @@
dtv_bus_def_vectors,
},
};
+
static struct msm_bus_scale_pdata dtv_bus_scale_pdata = {
dtv_bus_scale_usecases,
ARRAY_SIZE(dtv_bus_scale_usecases),
@@ -9480,6 +9544,27 @@
static struct lcdc_platform_data dtv_pdata = {
.bus_scale_table = &dtv_bus_scale_pdata,
};
+
+static struct msm_bus_paths dtv_hdmi_prim_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(dtv_bus_init_vectors),
+ dtv_bus_init_vectors,
+ },
+ {
+ ARRAY_SIZE(dtv_bus_hdmi_prim_vectors),
+ dtv_bus_hdmi_prim_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata dtv_hdmi_prim_bus_scale_pdata = {
+ dtv_hdmi_prim_bus_scale_usecases,
+ ARRAY_SIZE(dtv_hdmi_prim_bus_scale_usecases),
+ .name = "dtv",
+};
+
+static struct lcdc_platform_data dtv_hdmi_prim_pdata = {
+ .bus_scale_table = &dtv_hdmi_prim_bus_scale_pdata,
+};
#endif
@@ -9601,13 +9686,6 @@
160000000,
200000000,
};
-#elif defined(CONFIG_FB_MSM_HDMI_AS_PRIMARY)
-int mdp_core_clk_rate_table[] = {
- 200000000,
- 200000000,
- 200000000,
- 200000000,
-};
#else
int mdp_core_clk_rate_table[] = {
59080000,
@@ -9619,11 +9697,7 @@
static struct msm_panel_common_pdata mdp_pdata = {
.gpio = MDP_VSYNC_GPIO,
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- .mdp_core_clk_rate = 200000000,
-#else
.mdp_core_clk_rate = 59080000,
-#endif
.mdp_core_clk_table = mdp_core_clk_rate_table,
.num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
#ifdef CONFIG_MSM_BUS_SCALING
@@ -9729,7 +9803,10 @@
msm_fb_register_device("lcdc", &lcdc_pdata);
msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
#ifdef CONFIG_MSM_BUS_SCALING
- msm_fb_register_device("dtv", &dtv_pdata);
+ if (hdmi_is_primary)
+ msm_fb_register_device("dtv", &dtv_hdmi_prim_pdata);
+ else
+ msm_fb_register_device("dtv", &dtv_pdata);
#endif
#ifdef CONFIG_FB_MSM_TVOUT
msm_fb_register_device("tvenc", &atv_pdata);
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 0a3632e..cb264a4 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4461,6 +4461,9 @@
DEFINE_CLK_RPM(sfab_clk, sfab_a_clk, SYSTEM_FABRIC, NULL);
DEFINE_CLK_RPM(sfpb_clk, sfpb_a_clk, SFPB, NULL);
+static DEFINE_CLK_VOTER(sfab_msmbus_a_clk, &sfab_a_clk.c);
+static DEFINE_CLK_VOTER(sfab_tmr_a_clk, &sfab_a_clk.c);
+
static DEFINE_CLK_VOTER(dfab_dsps_clk, &dfab_clk.c);
static DEFINE_CLK_VOTER(dfab_usb_hs_clk, &dfab_clk.c);
static DEFINE_CLK_VOTER(dfab_usb_hs3_clk, &dfab_clk.c);
@@ -4898,7 +4901,7 @@
CLK_LOOKUP("bus_clk", cfpb_clk.c, "msm_cpss_fpb"),
CLK_LOOKUP("bus_a_clk", cfpb_a_clk.c, "msm_cpss_fpb"),
CLK_LOOKUP("bus_clk", sfab_clk.c, "msm_sys_fab"),
- CLK_LOOKUP("bus_a_clk", sfab_a_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("bus_a_clk", sfab_msmbus_a_clk.c, "msm_sys_fab"),
CLK_LOOKUP("bus_clk", sfpb_clk.c, "msm_sys_fpb"),
CLK_LOOKUP("bus_a_clk", sfpb_a_clk.c, "msm_sys_fpb"),
CLK_LOOKUP("bus_clk", mmfab_clk.c, "msm_mm_fab"),
@@ -5175,7 +5178,7 @@
CLK_LOOKUP("bus_clk", cfpb_clk.c, "msm_cpss_fpb"),
CLK_LOOKUP("bus_a_clk", cfpb_a_clk.c, "msm_cpss_fpb"),
CLK_LOOKUP("bus_clk", sfab_clk.c, "msm_sys_fab"),
- CLK_LOOKUP("bus_a_clk", sfab_a_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("bus_a_clk", sfab_msmbus_a_clk.c, "msm_sys_fab"),
CLK_LOOKUP("bus_clk", sfpb_clk.c, "msm_sys_fpb"),
CLK_LOOKUP("bus_a_clk", sfpb_a_clk.c, "msm_sys_fpb"),
CLK_LOOKUP("bus_clk", mmfab_clk.c, "msm_mm_fab"),
@@ -5763,6 +5766,14 @@
rcg_clk_disable(&tssc_clk.c);
clk_enable(&usb_hsic_hsic_clk.c);
clk_disable(&usb_hsic_hsic_clk.c);
+
+ /*
+ * Keep sfab floor @ 54MHz so that Krait AHB is at least 27MHz at all
+ * times when Apps CPU is active. This ensures the timer's requirement
+ * of Krait AHB running 4 times as fast as the timer itself.
+ */
+ clk_set_rate(&sfab_tmr_a_clk.c, 54000000);
+ clk_enable(&sfab_tmr_a_clk.c);
}
static int __init msm8960_clock_late_init(void)
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 9a4696f..c19c133 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -797,7 +797,9 @@
kgsl_3d0_pdata.pwrlevel[0].bus_freq = 160000000;
kgsl_3d0_pdata.pwrlevel[1].gpu_freq = 96000000;
kgsl_3d0_pdata.pwrlevel[1].bus_freq = 0;
- }
+ } else if (cpu_is_msm8625())
+ /* msm8625 has an idle_timout of 50 hours */
+ kgsl_3d0_pdata.idle_timeout = 18000000;
}
static void __init msm_register_device(struct platform_device *pdev, void *data)
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 96b0083..105a46f 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -417,10 +417,13 @@
int *gpio;
};
+#define PANEL_NAME_MAX_LEN 50
struct msm_fb_platform_data {
int (*detect_client)(const char *name);
int mddi_prescan;
int (*allow_set_offset)(void);
+ char prim_panel_name[PANEL_NAME_MAX_LEN];
+ char ext_panel_name[PANEL_NAME_MAX_LEN];
};
struct msm_hdmi_platform_data {
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/pm2.c b/arch/arm/mach-msm/pm2.c
index 1396463..4d63b6d 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -1769,6 +1769,8 @@
pmd_t *pmd;
unsigned long pmdval;
+ if (cpu_is_msm8625())
+ return 0;
/* Page table for cores to come back up safely. */
pc_pgd = pgd_alloc(&init_mm);
if (!pc_pgd)
diff --git a/arch/arm/mach-msm/qdss-ptm.c b/arch/arm/mach-msm/qdss-etm.c
similarity index 100%
rename from arch/arm/mach-msm/qdss-ptm.c
rename to arch/arm/mach-msm/qdss-etm.c
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 158015a..542d224 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -622,13 +622,25 @@
mutex_lock(&smd_pkt_devp->ch_lock);
if (smd_pkt_devp->ch == 0) {
+ init_completion(&smd_pkt_devp->ch_allocated);
+ smd_pkt_devp->driver.probe = smd_pkt_dummy_probe;
+ smd_pkt_devp->driver.driver.name =
+ smd_ch_name[smd_pkt_devp->i];
+ smd_pkt_devp->driver.driver.owner = THIS_MODULE;
+ r = platform_driver_register(&smd_pkt_devp->driver);
+ if (r) {
+ pr_err("%s: %s Platform driver reg. failed\n",
+ __func__, smd_ch_name[smd_pkt_devp->i]);
+ goto out;
+ }
+
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)) {
r = PTR_ERR(smd_pkt_devp->pil);
- goto out;
+ goto release_pd;
}
/* Wait for the modem SMSM to be inited for the SMD
@@ -697,6 +709,10 @@
release_pil:
if (peripheral && (r < 0))
pil_put(smd_pkt_devp->pil);
+
+release_pd:
+ if (r < 0)
+ platform_driver_unregister(&smd_pkt_devp->driver);
out:
mutex_unlock(&smd_pkt_devp->ch_lock);
@@ -722,6 +738,7 @@
smd_pkt_devp->ch = 0;
smd_pkt_devp->blocking_write = 0;
smd_pkt_devp->poll_mode = 0;
+ platform_driver_unregister(&smd_pkt_devp->driver);
if (smd_pkt_devp->pil)
pil_put(smd_pkt_devp->pil);
}
@@ -798,7 +815,6 @@
mutex_init(&smd_pkt_devp[i]->ch_lock);
mutex_init(&smd_pkt_devp[i]->rx_lock);
mutex_init(&smd_pkt_devp[i]->tx_lock);
- init_completion(&smd_pkt_devp[i]->ch_allocated);
cdev_init(&smd_pkt_devp[i]->cdev, &smd_pkt_fops);
smd_pkt_devp[i]->cdev.owner = THIS_MODULE;
@@ -839,13 +855,6 @@
&dev_attr_open_timeout))
pr_err("%s: unable to create device attr on #%d\n",
__func__, i);
-
- smd_pkt_devp[i]->driver.probe = smd_pkt_dummy_probe;
- smd_pkt_devp[i]->driver.driver.name = smd_ch_name[i];
- smd_pkt_devp[i]->driver.driver.owner = THIS_MODULE;
- r = platform_driver_register(&smd_pkt_devp[i]->driver);
- if (r)
- goto error2;
}
INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker);
@@ -856,7 +865,6 @@
error2:
if (i > 0) {
while (--i >= 0) {
- platform_driver_unregister(&smd_pkt_devp[i]->driver);
cdev_del(&smd_pkt_devp[i]->cdev);
kfree(smd_pkt_devp[i]);
device_destroy(smd_pkt_classp,
@@ -876,7 +884,6 @@
int i;
for (i = 0; i < NUM_SMD_PKT_PORTS; ++i) {
- platform_driver_unregister(&smd_pkt_devp[i]->driver);
cdev_del(&smd_pkt_devp[i]->cdev);
kfree(smd_pkt_devp[i]);
device_destroy(smd_pkt_classp,
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index 59abfe6..1bdec12 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -52,6 +52,9 @@
static void smsm_state_cb_hdlr(void *data, uint32_t old_state,
uint32_t new_state)
{
+ if (!(new_state & SMSM_RESET))
+ return;
+
riva_crash = true;
pr_err("%s: smsm state changed to smsm reset\n", MODULE_NAME);
@@ -60,10 +63,8 @@
MODULE_NAME);
return;
}
- if (new_state & SMSM_RESET) {
- ss_restart_inprogress = true;
- schedule_work(&riva_smsm_cb_work);
- }
+ ss_restart_inprogress = true;
+ schedule_work(&riva_smsm_cb_work);
}
static void riva_fatal_fn(struct work_struct *work)
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index a701773..4153b7b 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -23,6 +23,7 @@
#include <asm/mach-types.h>
/* Size of the USB buffers used for read and write*/
#define USB_MAX_OUT_BUF 4096
+#define APPS_BUF_SIZE 2000
#define IN_BUF_SIZE 16384
#define MAX_IN_BUF_SIZE 32768
#define MAX_SYNC_OBJ_NAME_SIZE 32
@@ -50,6 +51,9 @@
#define USER_SPACE_DATA 8000
#define PKT_SIZE 4096
#define MAX_EQUIP_ID 12
+#define DIAG_CTRL_MSG_LOG_MASK 9
+#define DIAG_CTRL_MSG_EVENT_MASK 10
+#define DIAG_CTRL_MSG_F3_MASK 11
/* Maximum number of pkt reg supported at initialization*/
extern unsigned int diag_max_reg;
@@ -148,7 +152,10 @@
int count_hdlc_pool;
int count_write_struct_pool;
int used;
-
+ /* Buffers for masks */
+ struct diag_ctrl_event_mask *event_mask;
+ struct diag_ctrl_log_mask *log_mask;
+ struct diag_ctrl_msg_mask *msg_mask;
/* State for diag forwarding */
unsigned char *buf_in_1;
unsigned char *buf_in_2;
@@ -161,6 +168,10 @@
unsigned char *usb_buf_out;
unsigned char *apps_rsp_buf;
unsigned char *user_space_data;
+ /* buffer for updating mask to peripherals */
+ unsigned char *buf_msg_mask_update;
+ unsigned char *buf_log_mask_update;
+ unsigned char *buf_event_mask_update;
smd_channel_t *ch;
smd_channel_t *ch_cntl;
smd_channel_t *chqdsp;
@@ -190,6 +201,13 @@
struct work_struct diag_read_smd_qdsp_cntl_work;
struct work_struct diag_read_smd_wcnss_work;
struct work_struct diag_read_smd_wcnss_cntl_work;
+ struct workqueue_struct *diag_cntl_wq;
+ struct work_struct diag_msg_mask_update_work;
+ struct work_struct diag_log_mask_update_work;
+ struct work_struct diag_event_mask_update_work;
+ struct work_struct diag_modem_mask_update_work;
+ struct work_struct diag_qdsp_mask_update_work;
+ struct work_struct diag_wcnss_mask_update_work;
uint8_t *msg_masks;
uint8_t *log_masks;
int log_masks_length;
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 7f26856..cc2b6e5 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -43,8 +43,15 @@
static unsigned int buf_tbl_size = 8; /*Number of entries in table of buffers */
struct diag_master_table entry;
smd_channel_t *ch_temp, *chqdsp_temp, *ch_wcnss_temp;
+int diag_event_num_bytes;
+int diag_event_config;
struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
+struct mask_info {
+ int equip_id;
+ int num_items;
+ int index;
+};
#define ENCODE_RSP_AND_SEND(buf_length) \
do { \
@@ -54,7 +61,7 @@
send.terminate = 1; \
if (!driver->in_busy_1) { \
enc.dest = driver->buf_in_1; \
- enc.dest_last = (void *)(driver->buf_in_1 + 499); \
+ enc.dest_last = (void *)(driver->buf_in_1 + APPS_BUF_SIZE - 1);\
diag_hdlc_encode(&send, &enc); \
driver->write_ptr_1->buf = driver->buf_in_1; \
driver->write_ptr_1->length = (int)(enc.dest - \
@@ -62,7 +69,7 @@
driver->in_busy_1 = 1; \
diag_device_write(driver->buf_in_1, MODEM_DATA, \
driver->write_ptr_1); \
- memset(driver->apps_rsp_buf, '\0', 500); \
+ memset(driver->apps_rsp_buf, '\0', APPS_BUF_SIZE); \
} \
} while (0)
@@ -94,7 +101,7 @@
}
/*
- * This will return TRUE for targets which support apps only mode.
+ * This will return TRUE for targets which support apps only mode and hence SSR.
* This applies to 8960 and newer targets.
*/
int chk_apps_only(void)
@@ -400,8 +407,8 @@
uint8_t *ptr_buffer_end = &(*(driver->msg_masks)) + MSG_MASK_SIZE;
mutex_lock(&driver->diagchar_mutex);
- /* First SSID can be zero : So check that last is non-zero */
+ /* First SSID can be zero : So check that last is non-zero */
while (*(uint32_t *)(ptr + 4)) {
first = *(uint32_t *)ptr;
ptr += 4;
@@ -446,7 +453,7 @@
}
-static void diag_update_event_mask(uint8_t *buf, int toggle, int num_bits)
+static void diag_update_event_mask(uint8_t *buf, int toggle, int num_bytes)
{
uint8_t *ptr = driver->event_masks;
uint8_t *temp = buf + 2;
@@ -456,9 +463,8 @@
memset(ptr, 0 , EVENT_MASK_SIZE);
else
if (CHK_OVERFLOW(ptr, ptr,
- ptr+EVENT_MASK_SIZE,
- num_bits/8 + 1))
- memcpy(ptr, temp , num_bits/8 + 1);
+ ptr+EVENT_MASK_SIZE, num_bytes))
+ memcpy(ptr, temp , num_bytes);
else
printk(KERN_CRIT "Not enough buffer space "
"for EVENT_MASK\n");
@@ -468,10 +474,6 @@
static void diag_update_log_mask(int equip_id, uint8_t *buf, int num_items)
{
uint8_t *temp = buf;
- struct mask_info {
- int equip_id;
- int index;
- };
int i = 0;
unsigned char *ptr_data;
int offset = 8*MAX_EQUIP_ID;
@@ -485,8 +487,9 @@
break;
}
if ((ptr->equip_id == 0) && (ptr->index == 0)) {
- /*Reached a null entry */
+ /* Reached a null entry */
ptr->equip_id = equip_id;
+ ptr->num_items = num_items;
ptr->index = driver->log_masks_length;
offset = driver->log_masks_length;
driver->log_masks_length += ((num_items+7)/8);
@@ -571,6 +574,123 @@
}
}
+void diag_modem_mask_update_fn(struct work_struct *work)
+{
+ diag_send_msg_mask_update(driver->ch_cntl);
+ diag_send_log_mask_update(driver->ch_cntl);
+ diag_send_event_mask_update(driver->ch_cntl, diag_event_num_bytes);
+}
+
+void diag_qdsp_mask_update_fn(struct work_struct *work)
+{
+ diag_send_msg_mask_update(driver->chqdsp_cntl);
+ diag_send_log_mask_update(driver->chqdsp_cntl);
+ diag_send_event_mask_update(driver->chqdsp_cntl, diag_event_num_bytes);
+}
+
+void diag_wcnss_mask_update_fn(struct work_struct *work)
+{
+ diag_send_msg_mask_update(driver->ch_wcnss_cntl);
+ diag_send_log_mask_update(driver->ch_wcnss_cntl);
+ diag_send_event_mask_update(driver->ch_wcnss_cntl,
+ diag_event_num_bytes);
+}
+
+void diag_msg_mask_update_fn(struct work_struct *work)
+{
+ diag_send_msg_mask_update(driver->ch_cntl);
+ diag_send_msg_mask_update(driver->chqdsp_cntl);
+ diag_send_msg_mask_update(driver->ch_wcnss_cntl);
+}
+
+void diag_log_mask_update_fn(struct work_struct *work)
+{
+ diag_send_log_mask_update(driver->ch_cntl);
+ diag_send_log_mask_update(driver->chqdsp_cntl);
+ diag_send_log_mask_update(driver->ch_wcnss_cntl);
+}
+
+void diag_send_log_mask_update(smd_channel_t *ch)
+{
+ void *buf = driver->buf_log_mask_update;
+ int header_size = sizeof(struct diag_ctrl_log_mask);
+ struct mask_info *ptr = (struct mask_info *)driver->log_masks;
+ int i, size = (driver->log_mask->num_items+7)/8;
+
+ for (i = 0; i < MAX_EQUIP_ID; i++) {
+ /* reached null entry */
+ if ((ptr->equip_id == 0) && (ptr->index == 0))
+ break;
+ driver->log_mask->cmd_type = DIAG_CTRL_MSG_LOG_MASK;
+ driver->log_mask->num_items = ptr->num_items;
+ driver->log_mask->data_len = 11 + size;
+ driver->log_mask->stream_id = 1; /* 2, if dual stream */
+ driver->log_mask->status = 3; /* status for valid mask */
+ driver->log_mask->equip_id = ptr->equip_id;
+ driver->log_mask->log_mask_size = size;
+ memcpy(buf, driver->log_mask, header_size);
+ memcpy(buf+header_size, driver->log_masks+ptr->index, size);
+ msleep(100);
+ if (ch)
+ smd_write(ch, buf, header_size + size);
+ ptr++;
+ }
+}
+
+void diag_send_event_mask_update(smd_channel_t *ch, int num_bytes)
+{
+ void *buf = driver->buf_event_mask_update;
+ int header_size = sizeof(struct diag_ctrl_event_mask);
+
+ /* send event mask update */
+ driver->event_mask->cmd_type = DIAG_CTRL_MSG_EVENT_MASK;
+ driver->event_mask->data_len = 7 + num_bytes;
+ driver->event_mask->stream_id = 1; /* 2, if dual stream */
+ driver->event_mask->status = 3; /* status for valid mask */
+ driver->event_mask->event_config = diag_event_config; /* event config */
+ driver->event_mask->event_mask_size = num_bytes;
+ memcpy(buf, driver->event_mask, header_size);
+ memcpy(buf+header_size, driver->event_masks, num_bytes);
+ msleep(100);
+ if (ch)
+ smd_write(ch, buf, header_size + num_bytes);
+}
+
+void diag_send_msg_mask_update(smd_channel_t *ch)
+{
+ void *buf = driver->buf_msg_mask_update;
+ int first, last;
+ int header_size = sizeof(struct diag_ctrl_msg_mask);
+ uint8_t *ptr = driver->msg_masks;
+
+ while (*(uint32_t *)(ptr + 4)) {
+ first = *(uint32_t *)ptr;
+ ptr += 4;
+ last = *(uint32_t *)ptr;
+ ptr += 4;
+ /* send event mask update */
+ driver->msg_mask->cmd_type = DIAG_CTRL_MSG_F3_MASK;
+ driver->msg_mask->msg_mask_size = last - first + 1;
+ driver->msg_mask->data_len = 11 +
+ 4 * (driver->msg_mask->msg_mask_size);
+ driver->msg_mask->stream_id = 1; /* 2, if dual stream */
+ driver->msg_mask->status = 3; /* status for valid mask */
+ driver->msg_mask->msg_mode = 0; /* Legcay mode */
+ driver->msg_mask->ssid_first = first;
+ driver->msg_mask->ssid_last = last;
+ memcpy(buf, driver->msg_mask, header_size);
+ memcpy(buf+header_size, ptr,
+ 4 * (driver->msg_mask->msg_mask_size));
+ /* since mask updates are slow, so sleep needed as to
+ prevent modem running out of DSM items */
+ msleep(100);
+ if (ch)
+ smd_write(ch, buf,
+ header_size + 4*(driver->msg_mask->msg_mask_size));
+ ptr += ((last - first) + 1)*4;
+ }
+}
+
static int diag_process_apps_pkt(unsigned char *buf, int len)
{
uint16_t subsys_cmd_code;
@@ -583,6 +703,93 @@
unsigned char *ptr;
#endif
+ /* Set log masks */
+ if (*buf == 0x73 && *(int *)(buf+4) == 3) {
+ buf += 8;
+ /* Read Equip ID and pass as first param below*/
+ diag_update_log_mask(*(int *)buf, buf+8, *(int *)(buf+4));
+ diag_update_userspace_clients(LOG_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x73;
+ *(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
+ *(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
+ payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
+ for (i = 0; i < payload_length; i++)
+ *(int *)(driver->apps_rsp_buf+12+i) = *(buf+i);
+ queue_work(driver->diag_cntl_wq,
+ &(driver->diag_log_mask_update_work));
+ ENCODE_RSP_AND_SEND(12 + payload_length - 1);
+ return 0;
+ } else
+ buf = temp;
+#endif
+ } /* Check for set message mask */
+ else if ((*buf == 0x7d) && (*(buf+1) == 0x4)) {
+ ssid_first = *(uint16_t *)(buf + 2);
+ ssid_last = *(uint16_t *)(buf + 4);
+ ssid_range = 4 * (ssid_last - ssid_first + 1);
+ diag_update_msg_mask(ssid_first, ssid_last , buf + 8);
+ diag_update_userspace_clients(MSG_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ for (i = 0; i < 8 + ssid_range; i++)
+ *(driver->apps_rsp_buf + i) = *(buf+i);
+ *(driver->apps_rsp_buf + 6) = 0x1;
+ queue_work(driver->diag_cntl_wq,
+ &(driver->diag_msg_mask_update_work));
+ ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
+ return 0;
+ } else
+ buf = temp;
+#endif
+ } else if (*buf == 0x82) { /* event mask change */
+ buf += 4;
+ diag_event_num_bytes = (*(uint16_t *)buf)/8+1;
+ diag_update_event_mask(buf, 1, (*(uint16_t *)buf)/8+1);
+ diag_update_userspace_clients(EVENT_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x82;
+ driver->apps_rsp_buf[1] = 0x0;
+ *(uint16_t *)(driver->apps_rsp_buf + 2) = 0x0;
+ *(uint16_t *)(driver->apps_rsp_buf + 4) =
+ EVENT_LAST_ID + 1;
+ for (i = 0; i < EVENT_LAST_ID/8 + 1; i++)
+ *(unsigned char *)(driver->apps_rsp_buf + 6 + i)
+ = 0x0;
+ /* cannot do this on work queue, as each event update
+ needs a num_bytes variable. Each queue_work call will
+ overwrite the previous input, as its the same struct */
+ diag_send_event_mask_update(driver->ch_cntl,
+ diag_event_num_bytes);
+ diag_send_event_mask_update(driver->chqdsp_cntl,
+ diag_event_num_bytes);
+ diag_send_event_mask_update(driver->ch_wcnss_cntl,
+ diag_event_num_bytes);
+ ENCODE_RSP_AND_SEND(6 + EVENT_LAST_ID/8);
+ return 0;
+ } else
+ buf = temp;
+#endif
+ } else if (*buf == 0x60) {
+ diag_event_config = *(buf+1);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x60;
+ driver->apps_rsp_buf[1] = 0x0;
+ driver->apps_rsp_buf[2] = 0x0;
+ diag_send_event_mask_update(driver->ch_cntl,
+ diag_event_num_bytes);
+ diag_send_event_mask_update(driver->chqdsp_cntl,
+ diag_event_num_bytes);
+ diag_send_event_mask_update(driver->ch_wcnss_cntl,
+ diag_event_num_bytes);
+ ENCODE_RSP_AND_SEND(2);
+ return 0;
+ }
+#endif
+ }
/* Check for registered clients and forward packet to apropriate proc */
cmd_code = (int)(*(char *)buf);
temp++;
@@ -632,70 +839,9 @@
}
}
}
- /* set event mask */
- if (*buf == 0x82) {
- buf += 4;
- diag_update_event_mask(buf, 1, *(uint16_t *)buf);
- diag_update_userspace_clients(EVENT_MASKS_TYPE);
- }
- /* event mask change */
- else if ((*buf == 0x60) && (*(buf+1) == 0x0)) {
- diag_update_event_mask(buf+1, 0, 0);
- diag_update_userspace_clients(EVENT_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- /* Check for Apps Only */
- if (!(driver->ch) && chk_apps_only()) {
- /* echo response back for apps only DIAG */
- driver->apps_rsp_buf[0] = 0x60;
- driver->apps_rsp_buf[1] = 0x0;
- driver->apps_rsp_buf[2] = 0x0;
- ENCODE_RSP_AND_SEND(2);
- return 0;
- }
-#endif
- }
- /* Set log masks */
- else if (*buf == 0x73 && *(int *)(buf+4) == 3) {
- buf += 8;
- /* Read Equip ID and pass as first param below*/
- diag_update_log_mask(*(int *)buf, buf+8, *(int *)(buf+4));
- diag_update_userspace_clients(LOG_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- /* Check for Apps Only */
- if (!(driver->ch) && chk_apps_only()) {
- /* echo response back for Apps only DIAG */
- driver->apps_rsp_buf[0] = 0x73;
- *(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
- *(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
- payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
- for (i = 0; i < payload_length; i++)
- *(int *)(driver->apps_rsp_buf+12+i) =
- *(buf+8+i);
- ENCODE_RSP_AND_SEND(12 + payload_length - 1);
- return 0;
- }
-#endif
- }
- /* Check for set message mask */
- else if ((*buf == 0x7d) && (*(buf+1) == 0x4)) {
- ssid_first = *(uint16_t *)(buf + 2);
- ssid_last = *(uint16_t *)(buf + 4);
- ssid_range = 4 * (ssid_last - ssid_first + 1);
- diag_update_msg_mask(ssid_first, ssid_last , buf + 8);
- diag_update_userspace_clients(MSG_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- if (!(driver->ch) && chk_apps_only()) {
- /* echo response back for apps only DIAG */
- for (i = 0; i < 8 + ssid_range; i++)
- *(driver->apps_rsp_buf + i) = *(buf+i);
- ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
- return 0;
- }
-#endif
- }
#if defined(CONFIG_DIAG_OVER_USB)
/* Check for Apps Only & get event mask request */
- else if (!(driver->ch) && chk_apps_only() && *buf == 0x81) {
+ if (!(driver->ch) && chk_apps_only() && *buf == 0x81) {
driver->apps_rsp_buf[0] = 0x81;
driver->apps_rsp_buf[1] = 0x0;
*(uint16_t *)(driver->apps_rsp_buf + 2) = 0x0;
@@ -776,7 +922,15 @@
*(uint16_t *)(driver->apps_rsp_buf + 78) = MSG_SSID_17_LAST;
*(uint16_t *)(driver->apps_rsp_buf + 80) = MSG_SSID_18;
*(uint16_t *)(driver->apps_rsp_buf + 82) = MSG_SSID_18_LAST;
- ENCODE_RSP_AND_SEND(83);
+ *(uint16_t *)(driver->apps_rsp_buf + 84) = MSG_SSID_19;
+ *(uint16_t *)(driver->apps_rsp_buf + 86) = MSG_SSID_19_LAST;
+ *(uint16_t *)(driver->apps_rsp_buf + 88) = MSG_SSID_20;
+ *(uint16_t *)(driver->apps_rsp_buf + 90) = MSG_SSID_20_LAST;
+ *(uint16_t *)(driver->apps_rsp_buf + 92) = MSG_SSID_21;
+ *(uint16_t *)(driver->apps_rsp_buf + 94) = MSG_SSID_21_LAST;
+ *(uint16_t *)(driver->apps_rsp_buf + 96) = MSG_SSID_22;
+ *(uint16_t *)(driver->apps_rsp_buf + 98) = MSG_SSID_22_LAST;
+ ENCODE_RSP_AND_SEND(99);
return 0;
}
/* Check for Apps Only Respond to Get Subsys Build mask */
@@ -871,6 +1025,22 @@
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_18[i/4];
break;
+ case MSG_SSID_19:
+ for (i = 0; i < ssid_range; i += 4)
+ *(int *)(ptr + i) = msg_bld_masks_19[i/4];
+ break;
+ case MSG_SSID_20:
+ for (i = 0; i < ssid_range; i += 4)
+ *(int *)(ptr + i) = msg_bld_masks_20[i/4];
+ break;
+ case MSG_SSID_21:
+ for (i = 0; i < ssid_range; i += 4)
+ *(int *)(ptr + i) = msg_bld_masks_21[i/4];
+ break;
+ case MSG_SSID_22:
+ for (i = 0; i < ssid_range; i += 4)
+ *(int *)(ptr + i) = msg_bld_masks_22[i/4];
+ break;
}
ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
return 0;
@@ -1311,6 +1481,25 @@
{
diag_debug_buf_idx = 0;
driver->read_len_legacy = 0;
+
+ if (driver->event_mask == NULL) {
+ driver->event_mask = kzalloc(sizeof(
+ struct diag_ctrl_event_mask), GFP_KERNEL);
+ if (driver->event_mask == NULL)
+ goto err;
+ }
+ if (driver->msg_mask == NULL) {
+ driver->msg_mask = kzalloc(sizeof(
+ struct diag_ctrl_msg_mask), GFP_KERNEL);
+ if (driver->msg_mask == NULL)
+ goto err;
+ }
+ if (driver->log_mask == NULL) {
+ driver->log_mask = kzalloc(sizeof(
+ struct diag_ctrl_log_mask), GFP_KERNEL);
+ if (driver->log_mask == NULL)
+ goto err;
+ }
if (driver->buf_in_1 == NULL) {
driver->buf_in_1 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
if (driver->buf_in_1 == NULL)
@@ -1336,6 +1525,24 @@
if (driver->buf_in_wcnss == NULL)
goto err;
}
+ if (driver->buf_msg_mask_update == NULL) {
+ driver->buf_msg_mask_update = kzalloc(APPS_BUF_SIZE,
+ GFP_KERNEL);
+ if (driver->buf_msg_mask_update == NULL)
+ goto err;
+ }
+ if (driver->buf_log_mask_update == NULL) {
+ driver->buf_log_mask_update = kzalloc(APPS_BUF_SIZE,
+ GFP_KERNEL);
+ if (driver->buf_log_mask_update == NULL)
+ goto err;
+ }
+ if (driver->buf_event_mask_update == NULL) {
+ driver->buf_event_mask_update = kzalloc(APPS_BUF_SIZE,
+ GFP_KERNEL);
+ if (driver->buf_event_mask_update == NULL)
+ goto err;
+ }
if (driver->usb_buf_out == NULL &&
(driver->usb_buf_out = kzalloc(USB_MAX_OUT_BUF,
GFP_KERNEL)) == NULL)
@@ -1419,7 +1626,7 @@
GFP_KERNEL)) == NULL)
goto err;
if (driver->apps_rsp_buf == NULL) {
- driver->apps_rsp_buf = kzalloc(500, GFP_KERNEL);
+ driver->apps_rsp_buf = kzalloc(APPS_BUF_SIZE, GFP_KERNEL);
if (driver->apps_rsp_buf == NULL)
goto err;
}
@@ -1427,6 +1634,16 @@
#ifdef CONFIG_DIAG_OVER_USB
INIT_WORK(&(driver->diag_proc_hdlc_work), diag_process_hdlc_fn);
INIT_WORK(&(driver->diag_read_work), diag_read_work_fn);
+ INIT_WORK(&(driver->diag_msg_mask_update_work),
+ diag_msg_mask_update_fn);
+ INIT_WORK(&(driver->diag_log_mask_update_work),
+ diag_log_mask_update_fn);
+ INIT_WORK(&(driver->diag_modem_mask_update_work),
+ diag_modem_mask_update_fn);
+ INIT_WORK(&(driver->diag_qdsp_mask_update_work),
+ diag_qdsp_mask_update_fn);
+ INIT_WORK(&(driver->diag_wcnss_mask_update_work),
+ diag_wcnss_mask_update_fn);
driver->legacy_ch = usb_diag_open(DIAG_LEGACY, driver,
diag_usb_legacy_notifier);
if (IS_ERR(driver->legacy_ch)) {
@@ -1440,11 +1657,17 @@
return;
err:
pr_err("diag: Could not initialize diag buffers");
+ kfree(driver->event_mask);
+ kfree(driver->log_mask);
+ kfree(driver->msg_mask);
kfree(driver->buf_in_1);
kfree(driver->buf_in_2);
kfree(driver->buf_in_qdsp_1);
kfree(driver->buf_in_qdsp_2);
kfree(driver->buf_in_wcnss);
+ kfree(driver->buf_msg_mask_update);
+ kfree(driver->buf_log_mask_update);
+ kfree(driver->buf_event_mask_update);
kfree(driver->usb_buf_out);
kfree(driver->hdlc_buf);
kfree(driver->msg_masks);
@@ -1482,11 +1705,17 @@
#endif
platform_driver_unregister(&msm_smd_ch1_driver);
platform_driver_unregister(&diag_smd_lite_driver);
+ kfree(driver->event_mask);
+ kfree(driver->log_mask);
+ kfree(driver->msg_mask);
kfree(driver->buf_in_1);
kfree(driver->buf_in_2);
kfree(driver->buf_in_qdsp_1);
kfree(driver->buf_in_qdsp_2);
kfree(driver->buf_in_wcnss);
+ kfree(driver->buf_msg_mask_update);
+ kfree(driver->buf_log_mask_update);
+ kfree(driver->buf_event_mask_update);
kfree(driver->usb_buf_out);
kfree(driver->hdlc_buf);
kfree(driver->msg_masks);
diff --git a/drivers/char/diag/diagfwd.h b/drivers/char/diag/diagfwd.h
index 6dacab7..9ef0199 100644
--- a/drivers/char/diag/diagfwd.h
+++ b/drivers/char/diag/diagfwd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 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
@@ -28,6 +28,9 @@
int mask_request_validate(unsigned char mask_buf[]);
void diag_clear_reg(int);
int chk_apps_only(void);
+void diag_send_event_mask_update(smd_channel_t *, int num_bytes);
+void diag_send_msg_mask_update(smd_channel_t *);
+void diag_send_log_mask_update(smd_channel_t *);
/* State for diag forwarding */
#ifdef CONFIG_DIAG_OVER_USB
int diagfwd_connect(void);
@@ -35,5 +38,5 @@
#endif
extern int diag_debug_buf_idx;
extern unsigned char diag_debug_buf[1024];
-
+extern int diag_event_num_bytes;
#endif
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 2c3dc54..01ed28d 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -36,6 +36,10 @@
else
pr_debug("diag: incomplete pkt on Modem CNTL ch\n");
break;
+ case SMD_EVENT_OPEN:
+ queue_work(driver->diag_cntl_wq,
+ &(driver->diag_modem_mask_update_work));
+ break;
}
}
@@ -56,6 +60,10 @@
else
pr_debug("diag: incomplete pkt on LPASS CNTL ch\n");
break;
+ case SMD_EVENT_OPEN:
+ queue_work(driver->diag_cntl_wq,
+ &(driver->diag_qdsp_mask_update_work));
+ break;
}
}
@@ -76,6 +84,10 @@
else
pr_debug("diag: incomplete pkt on WCNSS CNTL ch\n");
break;
+ case SMD_EVENT_OPEN:
+ queue_work(driver->diag_cntl_wq,
+ &(driver->diag_wcnss_mask_update_work));
+ break;
}
}
@@ -259,6 +271,7 @@
void diagfwd_cntl_init(void)
{
driver->polling_reg_flag = 0;
+ driver->diag_cntl_wq = create_singlethread_workqueue("diag_cntl_wq");
if (driver->buf_in_cntl == NULL) {
driver->buf_in_cntl = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
if (driver->buf_in_cntl == NULL)
@@ -283,6 +296,8 @@
kfree(driver->buf_in_cntl);
kfree(driver->buf_in_qdsp_cntl);
kfree(driver->buf_in_wcnss_cntl);
+ if (driver->diag_cntl_wq)
+ destroy_workqueue(driver->diag_cntl_wq);
}
void diagfwd_cntl_exit(void)
@@ -293,6 +308,7 @@
driver->ch_cntl = 0;
driver->chqdsp_cntl = 0;
driver->ch_wcnss_cntl = 0;
+ destroy_workqueue(driver->diag_cntl_wq);
platform_driver_unregister(&msm_smd_ch1_cntl_driver);
platform_driver_unregister(&diag_smd_lite_cntl_driver);
diff --git a/drivers/char/diag/diagfwd_cntl.h b/drivers/char/diag/diagfwd_cntl.h
index a76d36d..ad1fec9 100644
--- a/drivers/char/diag/diagfwd_cntl.h
+++ b/drivers/char/diag/diagfwd_cntl.h
@@ -21,10 +21,6 @@
#define DIAG_CTRL_MSG_DIAGMODE 3
/* Diag data based on "light" diag mask */
#define DIAG_CTRL_MSG_DIAGDATA 4
-/* Deprecated */
-#define DIAG_CTRL_MSG_LOG_MASK 5
-#define DIAG_CTRL_MSG_EVENT_MASK 6
-#define DIAG_CTRL_MSG_F3_MASK 7
/* Send diag internal feature mask 'diag_int_feature_mask' */
#define DIAG_CTRL_MSG_FEATURE 8
/* Send Diag log mask for a particular equip id */
@@ -48,6 +44,39 @@
uint16_t port;
};
+struct diag_ctrl_event_mask {
+ uint32_t cmd_type;
+ uint32_t data_len;
+ uint8_t stream_id;
+ uint8_t status;
+ uint8_t event_config;
+ uint32_t event_mask_size;
+ /* Copy event mask here */
+} __packed;
+
+struct diag_ctrl_log_mask {
+ uint32_t cmd_type;
+ uint32_t data_len;
+ uint8_t stream_id;
+ uint8_t status;
+ uint8_t equip_id;
+ uint32_t num_items; /* Last log code for this equip_id */
+ uint32_t log_mask_size; /* Size of log mask stored in log_mask[] */
+ /* Copy log mask here */
+} __packed;
+
+struct diag_ctrl_msg_mask {
+ uint32_t cmd_type;
+ uint32_t data_len;
+ uint8_t stream_id;
+ uint8_t status;
+ uint8_t msg_mode;
+ uint16_t ssid_first; /* Start of range of supported SSIDs */
+ uint16_t ssid_last; /* Last SSID in range */
+ uint32_t msg_mask_size; /* ssid_last - ssid_first + 1 */
+ /* Copy msg mask here */
+} __packed;
+
void diagfwd_cntl_init(void);
void diagfwd_cntl_exit(void);
void diag_read_smd_cntl_work_fn(struct work_struct *);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index ff15497..36375c05 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -273,8 +273,10 @@
trace_cpu_frequency(freqs->new, freqs->cpu);
srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
CPUFREQ_POSTCHANGE, freqs);
- if (likely(policy) && likely(policy->cpu == freqs->cpu))
+ if (likely(policy) && likely(policy->cpu == freqs->cpu)) {
policy->cur = freqs->new;
+ sysfs_notify(&policy->kobj, NULL, "scaling_cur_freq");
+ }
break;
}
}
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index ea16c31..0cadc33 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -993,8 +993,7 @@
if (!kgsl_mmu_pt_equal(priv->pagetable, pt_base))
continue;
spin_lock(&priv->mem_lock);
- entry = kgsl_sharedmem_find_region(priv, gpuaddr,
- sizeof(unsigned int));
+ entry = kgsl_sharedmem_find_region(priv, gpuaddr, size);
if (entry) {
result = &entry->memdesc;
spin_unlock(&priv->mem_lock);
diff --git a/drivers/gpu/msm/adreno_pm4types.h b/drivers/gpu/msm/adreno_pm4types.h
index f99462e..75512d0 100644
--- a/drivers/gpu/msm/adreno_pm4types.h
+++ b/drivers/gpu/msm/adreno_pm4types.h
@@ -209,4 +209,14 @@
/* gmem command buffer length */
#define CP_REG(reg) ((0x4 << 16) | (SUBBLOCK_OFFSET(reg)))
+
+/* Return 1 if the command is an indirect buffer of any kind */
+static inline int adreno_cmd_is_ib(unsigned int cmd)
+{
+ return (cmd == cp_type3_packet(CP_INDIRECT_BUFFER_PFE, 2) ||
+ cmd == cp_type3_packet(CP_INDIRECT_BUFFER_PFD, 2) ||
+ cmd == cp_type3_packet(CP_COND_INDIRECT_BUFFER_PFE, 2) ||
+ cmd == cp_type3_packet(CP_COND_INDIRECT_BUFFER_PFD, 2));
+}
+
#endif /* __ADRENO_PM4TYPES_H */
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index f9e498f..e4bc470 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -201,7 +201,7 @@
for (i = 0; i+3 < ib1_size; ) {
value = ib1_addr[i++];
- if (value == cp_type3_packet(CP_INDIRECT_BUFFER_PFD, 2)) {
+ if (adreno_cmd_is_ib(value)) {
uint32_t ib2_base = ib1_addr[i++];
uint32_t ib2_size = ib1_addr[i++];
@@ -769,7 +769,7 @@
i = 0;
for (read_idx = 0; read_idx < num_item; ) {
uint32_t this_cmd = rb_copy[read_idx++];
- if (this_cmd == cp_type3_packet(CP_INDIRECT_BUFFER_PFD, 2)) {
+ if (adreno_cmd_is_ib(this_cmd)) {
uint32_t ib_addr = rb_copy[read_idx++];
uint32_t ib_size = rb_copy[read_idx++];
dump_ib1(device, cur_pt_base, (read_idx-3)<<2, ib_addr,
@@ -812,8 +812,7 @@
for (read_idx = NUM_DWORDS_OF_RINGBUFFER_HISTORY;
read_idx >= 0; --read_idx) {
uint32_t this_cmd = rb_copy[read_idx];
- if (this_cmd == cp_type3_packet(
- CP_INDIRECT_BUFFER_PFD, 2)) {
+ if (adreno_cmd_is_ib(this_cmd)) {
uint32_t ib_addr = rb_copy[read_idx+1];
uint32_t ib_size = rb_copy[read_idx+2];
if (ib_size && cp_ib1_base == ib_addr) {
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index a4899a2..9836043 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -104,15 +104,6 @@
return 0;
}
-/* Return 1 if the packet starting at ptr is an indirect buffer of any kind */
-static inline int packet_is_buffer(unsigned int *ptr)
-{
- return (*ptr == cp_type3_packet(CP_INDIRECT_BUFFER_PFE, 2) ||
- *ptr == cp_type3_packet(CP_INDIRECT_BUFFER_PFD, 2) ||
- *ptr == cp_type3_packet(CP_COND_INDIRECT_BUFFER_PFE, 2) ||
- *ptr == cp_type3_packet(CP_COND_INDIRECT_BUFFER_PFD, 2));
-}
-
/* Snapshot the istore memory */
static int snapshot_istore(struct kgsl_device *device, void *snapshot,
int remain, void *priv)
@@ -258,7 +249,7 @@
if (index == rptr)
parse_ibs = 0;
- if (parse_ibs && packet_is_buffer(&rbptr[index]))
+ if (parse_ibs && adreno_cmd_is_ib(rbptr[index]))
push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
rbptr[index + 1], rbptr[index + 2]);
@@ -312,7 +303,7 @@
*dst = *src;
/* If another IB is discovered, then push it on the list too */
- if (packet_is_buffer(src))
+ if (adreno_cmd_is_ib(*src))
push_object(device, SNAPSHOT_OBJ_TYPE_IB, obj->ptbase,
*(src + 1), *(src + 2));
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/wfd/enc-subdev.c b/drivers/media/video/msm/wfd/enc-subdev.c
index 6c52e21..31b8239 100644
--- a/drivers/media/video/msm/wfd/enc-subdev.c
+++ b/drivers/media/video/msm/wfd/enc-subdev.c
@@ -334,16 +334,26 @@
struct vcd_buffer_requirement buf_req;
struct venc_inst *inst = sd->dev_priv;
struct video_client_ctx *client_ctx = &inst->venc_client;
+ int aligned_width, aligned_height;
if (!client_ctx) {
WFD_MSG_ERR("Invalid client context");
rc = -EINVAL;
goto err;
}
+ aligned_width = ALIGN(b->width, 16);
+ aligned_height = ALIGN(b->height, 16);
+
+ if (aligned_width != b->width) {
+ WFD_MSG_ERR("Width not 16 byte aligned\n");
+ rc = -EINVAL;
+ goto err;
+ }
+
buf_req.actual_count = b->count;
buf_req.min_count = b->count;
buf_req.max_count = b->count;
- buf_req.sz = (((b->height * b->width) + 2047) & (~2047))
- + (((b->height * b->width * 1/2) + 2047) & (~2047));
+ buf_req.sz = ALIGN(aligned_height * aligned_width, SZ_2K)
+ + ALIGN(aligned_height * aligned_width * 1/2, SZ_2K);
buf_req.align = 0;
inst->width = b->width;
inst->height = b->height;
diff --git a/drivers/media/video/msm/wfd/wfd-ioctl.c b/drivers/media/video/msm/wfd/wfd-ioctl.c
index ce81746..e38bb80 100644
--- a/drivers/media/video/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm/wfd/wfd-ioctl.c
@@ -561,6 +561,11 @@
"V4L2_PIX_FMT_H264 are supported\n");
return -EINVAL;
}
+
+ if (fmt->fmt.pix.width % 16) {
+ WFD_MSG_ERR("Only 16 byte aligned widths are supported\n");
+ return -ENOTSUPP;
+ }
rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl, SET_FORMAT,
(void *)fmt);
if (rc) {
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 03be6d0..122ffb5 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -299,10 +299,11 @@
mmc_card_ddr_mode(card) ? "DDR " : "",
type);
} else {
- printk(KERN_INFO "%s: new %s%s%s card at address %04x\n",
+ pr_info("%s: new %s%s%s%s card at address %04x\n",
mmc_hostname(card->host),
mmc_sd_card_uhs(card) ? "ultra high speed " :
(mmc_card_highspeed(card) ? "high speed " : ""),
+ (mmc_card_hs200(card) ? "HS200 " : ""),
mmc_card_ddr_mode(card) ? "DDR " : "",
type, card->rca);
}
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 998797e..c1b0405 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -113,6 +113,9 @@
case MMC_TIMING_SD_HS:
str = "sd high-speed";
break;
+ case MMC_TIMING_MMC_HS200:
+ str = "mmc high-speed SDR200";
+ break;
default:
str = "invalid";
break;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 0c70d4a..b7b899e 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -283,6 +283,27 @@
}
card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
+ case EXT_CSD_CARD_TYPE_SDR_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200;
+ break;
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V;
+ break;
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V;
+ break;
case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 |
EXT_CSD_CARD_TYPE_26:
card->ext_csd.hs_max_dtr = 52000000;
@@ -645,6 +666,79 @@
}
/*
+ * Selects the desired buswidth and switch to the HS200 mode
+ * if bus width set without error
+ */
+static int mmc_select_hs200(struct mmc_card *card)
+{
+ int idx, err = 0;
+ struct mmc_host *host;
+ static unsigned ext_csd_bits[] = {
+ EXT_CSD_BUS_WIDTH_4,
+ EXT_CSD_BUS_WIDTH_8,
+ };
+ static unsigned bus_widths[] = {
+ MMC_BUS_WIDTH_4,
+ MMC_BUS_WIDTH_8,
+ };
+
+ BUG_ON(!card);
+
+ host = card->host;
+
+ if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_2V &&
+ host->caps2 & MMC_CAP2_HS200_1_2V_SDR)
+ if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0))
+ err = mmc_set_signal_voltage(host,
+ MMC_SIGNAL_VOLTAGE_180, 0);
+
+ /* If fails try again during next card power cycle */
+ if (err)
+ goto err;
+
+ idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 1 : 0;
+
+ /*
+ * Unlike SD, MMC cards dont have a configuration register to notify
+ * supported bus width. So bus test command should be run to identify
+ * the supported bus width or compare the ext csd values of current
+ * bus width and ext csd values of 1 bit mode read earlier.
+ */
+ for (; idx >= 0; idx--) {
+
+ /*
+ * Host is capable of 8bit transfer, then switch
+ * the device to work in 8bit transfer mode. If the
+ * mmc switch command returns error then switch to
+ * 4bit transfer mode. On success set the corresponding
+ * bus width on the host.
+ */
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_BUS_WIDTH,
+ ext_csd_bits[idx],
+ card->ext_csd.generic_cmd6_time);
+ if (err)
+ continue;
+
+ mmc_set_bus_width(card->host, bus_widths[idx]);
+
+ if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
+ err = mmc_compare_ext_csds(card, bus_widths[idx]);
+ else
+ err = mmc_bus_test(card, bus_widths[idx]);
+ if (!err)
+ break;
+ }
+
+ /* switch to HS200 mode if bus width set successfully */
+ if (!err)
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_HS_TIMING, 2, 0);
+err:
+ return err;
+}
+
+/*
* Handle the detection and initialisation of a card.
*
* In the case of a resume, "oldcard" will contain the card
@@ -848,11 +942,16 @@
/*
* Activate high speed (if supported)
*/
- if ((card->ext_csd.hs_max_dtr != 0) &&
- (host->caps & MMC_CAP_MMC_HIGHSPEED)) {
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_HS_TIMING, 1,
- card->ext_csd.generic_cmd6_time);
+ if (card->ext_csd.hs_max_dtr != 0) {
+ err = 0;
+ if (card->ext_csd.hs_max_dtr > 52000000 &&
+ host->caps2 & MMC_CAP2_HS200)
+ err = mmc_select_hs200(card);
+ else if (host->caps & MMC_CAP_MMC_HIGHSPEED)
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_HS_TIMING, 1,
+ card->ext_csd.generic_cmd6_time);
+
if (err && err != -EBADMSG)
goto free_card;
@@ -861,33 +960,24 @@
mmc_hostname(card->host));
err = 0;
} else {
- mmc_card_set_highspeed(card);
- mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+ if (card->ext_csd.hs_max_dtr > 52000000 &&
+ host->caps2 & MMC_CAP2_HS200) {
+ mmc_card_set_hs200(card);
+ mmc_set_timing(card->host,
+ MMC_TIMING_MMC_HS200);
+ } else {
+ mmc_card_set_highspeed(card);
+ mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+ }
}
}
/*
- * Enable HPI feature (if supported)
- */
- if (card->ext_csd.hpi) {
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_HPI_MGMT, 1, 0);
- if (err && err != -EBADMSG)
- goto free_card;
- if (err) {
- pr_warning("%s: Enabling HPI failed\n",
- mmc_hostname(card->host));
- err = 0;
- } else
- card->ext_csd.hpi_en = 1;
- }
-
- /*
* Compute bus speed.
*/
max_dtr = (unsigned int)-1;
- if (mmc_card_highspeed(card)) {
+ if (mmc_card_highspeed(card) || mmc_card_hs200(card)) {
if (max_dtr > card->ext_csd.hs_max_dtr)
max_dtr = card->ext_csd.hs_max_dtr;
} else if (max_dtr > card->csd.max_dtr) {
@@ -913,9 +1003,51 @@
}
/*
+ * Indicate HS200 SDR mode (if supported).
+ */
+ if (mmc_card_hs200(card)) {
+ u32 ext_csd_bits;
+ u32 bus_width = card->host->ios.bus_width;
+
+ /*
+ * For devices supporting HS200 mode, the bus width has
+ * to be set before executing the tuning function. If
+ * set before tuning, then device will respond with CRC
+ * errors for responses on CMD line. So for HS200 the
+ * sequence will be
+ * 1. set bus width 4bit / 8 bit (1 bit not supported)
+ * 2. switch to HS200 mode
+ * 3. set the clock to > 52Mhz <=200MHz and
+ * 4. execute tuning for HS200
+ */
+ if ((host->caps2 & MMC_CAP2_HS200) &&
+ card->host->ops->execute_tuning) {
+ mmc_host_clk_hold(card->host);
+ err = card->host->ops->execute_tuning(card->host,
+ MMC_SEND_TUNING_BLOCK_HS200);
+ mmc_host_clk_release(card->host);
+ }
+ if (err) {
+ pr_warning("%s: tuning execution failed\n",
+ mmc_hostname(card->host));
+ goto err;
+ }
+
+ ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
+ EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
+ err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
+ if (err) {
+ pr_err("%s: power class selection to bus width %d failed\n",
+ mmc_hostname(card->host), 1 << bus_width);
+ goto err;
+ }
+ }
+
+ /*
* Activate wide bus and DDR (if supported).
*/
- if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
+ if (!mmc_card_hs200(card) &&
+ (card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
static unsigned ext_csd_bits[][2] = {
{ EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 },
@@ -1014,6 +1146,23 @@
}
/*
+ * Enable HPI feature (if supported)
+ */
+ if (card->ext_csd.hpi) {
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_HPI_MGMT, 1,
+ card->ext_csd.generic_cmd6_time);
+ if (err && err != -EBADMSG)
+ goto free_card;
+ if (err) {
+ pr_warning("%s: Enabling HPI failed\n",
+ mmc_hostname(card->host));
+ err = 0;
+ } else
+ card->ext_csd.hpi_en = 1;
+ }
+
+ /*
* If cache size is higher than 0, this indicates
* the existence of cache and it can be turned on.
*/
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 6522efb..cd0eb4e 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -651,7 +651,8 @@
/* SPI mode doesn't define CMD19 */
if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) {
mmc_host_clk_hold(card->host);
- err = card->host->ops->execute_tuning(card->host);
+ err = card->host->ops->execute_tuning(card->host,
+ MMC_SEND_TUNING_BLOCK);
mmc_host_clk_release(card->host);
}
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 8ac2e59..1d6cf1d 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -14,6 +14,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index ad4dfe6..a1ad63e 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -3088,7 +3088,7 @@
return ret;
}
-static int msmsdcc_execute_tuning(struct mmc_host *mmc)
+static int msmsdcc_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
int rc = 0;
struct msmsdcc_host *host = mmc_priv(mmc);
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/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/driver.c b/drivers/usb/core/driver.c
index 97c5690..5cd6bb1 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1285,10 +1285,20 @@
struct usb_bus *bus =
container_of(work, struct usb_bus, hnp_polling.work);
struct usb_device *udev = bus->root_hub->children[bus->otg_port - 1];
- u8 *status = kmalloc(sizeof(*status), GFP_KERNEL);
+ u8 *status = NULL;
+ /*
+ * The OTG-B device must hand back the host role to OTG PET
+ * within 100 msec irrespective of host_request flag.
+ */
+ if (bus->quick_hnp) {
+ bus->quick_hnp = 0;
+ goto start_hnp;
+ }
+
+ status = kmalloc(sizeof(*status), GFP_KERNEL);
if (!status)
- return;
+ goto reschedule;
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_DEVICE,
@@ -1300,17 +1310,20 @@
goto out;
}
- /* Spec says host must suspend the bus with in 2 sec. */
- if (*status & (1 << HOST_REQUEST_FLAG)) {
- do_unbind_rebind(udev, DO_UNBIND);
- udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
- ret = usb_suspend_both(udev, PMSG_USER_SUSPEND);
- if (ret)
- dev_info(&udev->dev, "suspend failed\n");
- } else {
- schedule_delayed_work(&bus->hnp_polling,
- msecs_to_jiffies(THOST_REQ_POLL));
- }
+ if (!(*status & (1 << HOST_REQUEST_FLAG)))
+ goto reschedule;
+
+start_hnp:
+ do_unbind_rebind(udev, DO_UNBIND);
+ udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
+ ret = usb_suspend_both(udev, PMSG_USER_SUSPEND);
+ if (ret)
+ dev_info(&udev->dev, "suspend failed\n");
+ goto out;
+
+reschedule:
+ schedule_delayed_work(&bus->hnp_polling,
+ msecs_to_jiffies(THOST_REQ_POLL));
out:
kfree(status);
}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5442297..7347c3d 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
@@ -1778,6 +1778,7 @@
int err = 0;
#ifdef CONFIG_USB_OTG
+ bool old_otg = false;
/*
* OTG-aware devices on OTG-capable root hubs may be able to use SRP,
* to wake us after we've powered off VBUS; and HNP, switching roles
@@ -1811,7 +1812,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
@@ -1819,6 +1823,7 @@
* a_hnp_support or b_hnp_enable before
* selecting configuration.
*/
+ old_otg = true;
/* enable HNP before suspend, it's simpler */
err = usb_control_msg(udev,
@@ -1839,6 +1844,14 @@
}
}
out:
+ if ((udev->quirks & USB_QUIRK_OTG_PET)) {
+ if (le16_to_cpu(udev->descriptor.bcdDevice) &
+ OTG_TTST_VBUS_OFF)
+ udev->bus->otg_vbus_off = 1;
+ if (udev->bus->is_b_host || old_otg)
+ udev->bus->quick_hnp = 1;
+ }
+
if (!is_targeted(udev)) {
otg_send_event(OTG_EVENT_DEV_NOT_SUPPORTED);
@@ -1859,8 +1872,12 @@
* re-armed if device returns STALL. B-Host also perform
* HNP polling.
*/
- schedule_delayed_work(&udev->bus->hnp_polling,
- msecs_to_jiffies(THOST_REQ_POLL));
+ if (udev->bus->quick_hnp)
+ schedule_delayed_work(&udev->bus->hnp_polling,
+ msecs_to_jiffies(OTG_TTST_SUSP));
+ else
+ schedule_delayed_work(&udev->bus->hnp_polling,
+ msecs_to_jiffies(THOST_REQ_POLL));
}
#endif
return err;
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h
index cec4167..7bb6747 100644
--- a/drivers/usb/core/otg_whitelist.h
+++ b/drivers/usb/core/otg_whitelist.h
@@ -59,6 +59,11 @@
le16_to_cpu(dev->descriptor.idProduct) == 0xbadd))
return 0;
+ /* OTG PET device is always targeted (see OTG 2.0 ECN 6.4.2) */
+ if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x0200))
+ return 1;
+
/* NOTE: can't use usb_match_id() since interface caches
* aren't set up yet. this is cut/paste from that code.
*/
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 81ce6a8..d5a29b3 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -96,6 +96,9 @@
/* INTEL VALUE SSD */
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Protocol and OTG Electrical Test Device */
+ { USB_DEVICE(0x1a0a, 0x0200), .driver_info = USB_QUIRK_OTG_PET },
+
{ } /* terminating entry must be last */
};
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/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index 2829231..d491bd0 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -410,15 +410,6 @@
ep->driver_data = dev; /* claim the endpoint */
dev->ep_out = ep;
- ep = usb_ep_autoconfig(cdev->gadget, out_desc);
- if (!ep) {
- DBG(cdev, "usb_ep_autoconfig for ep_out failed\n");
- return -ENODEV;
- }
- DBG(cdev, "usb_ep_autoconfig for mtp ep_out got %s\n", ep->name);
- ep->driver_data = dev; /* claim the endpoint */
- dev->ep_out = ep;
-
ep = usb_ep_autoconfig(cdev->gadget, intr_desc);
if (!ep) {
DBG(cdev, "usb_ep_autoconfig for ep_intr failed\n");
diff --git a/drivers/usb/host/ehci-msm2.c b/drivers/usb/host/ehci-msm2.c
index 4f6fe3e..4318efb 100644
--- a/drivers/usb/host/ehci-msm2.c
+++ b/drivers/usb/host/ehci-msm2.c
@@ -48,6 +48,7 @@
struct regulator *hsusb_1p8;
struct regulator *vbus;
bool async_int;
+ bool vbus_on;
atomic_t in_lpm;
struct wake_lock wlock;
};
@@ -174,17 +175,24 @@
}
#ifdef CONFIG_PM_SLEEP
-#define HSUSB_PHY_SUSP_DIG_VOL 500000
+#define HSUSB_PHY_SUSP_DIG_VOL_P50 500000
+#define HSUSB_PHY_SUSP_DIG_VOL_P75 750000
static int msm_ehci_config_vddcx(struct msm_hcd *mhcd, int high)
{
+ struct msm_usb_host_platform_data *pdata;
int max_vol = HSUSB_PHY_VDD_DIG_VOL_MAX;
int min_vol;
int ret;
+ pdata = mhcd->dev->platform_data;
+
if (high)
min_vol = HSUSB_PHY_VDD_DIG_VOL_MIN;
+ else if (pdata && pdata->dock_connect_irq &&
+ !irq_read_line(pdata->dock_connect_irq))
+ min_vol = HSUSB_PHY_SUSP_DIG_VOL_P75;
else
- min_vol = HSUSB_PHY_SUSP_DIG_VOL;
+ min_vol = HSUSB_PHY_SUSP_DIG_VOL_P50;
ret = regulator_set_voltage(mhcd->hsusb_vddcx, min_vol, max_vol);
if (ret) {
@@ -205,29 +213,6 @@
}
#endif
-static int msm_ehci_init_vbus(struct msm_hcd *mhcd, int init)
-{
- struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
- struct msm_usb_host_platform_data *pdata;
-
- if (!init) {
- regulator_put(mhcd->vbus);
- return 0;
- }
-
- mhcd->vbus = regulator_get(mhcd->dev, "vbus");
- if (IS_ERR(mhcd->vbus)) {
- pr_err("Unable to get vbus\n");
- return -ENODEV;
- }
-
- pdata = mhcd->dev->platform_data;
- if (pdata)
- hcd->power_budget = pdata->power_budget;
-
- return 0;
-}
-
static void msm_ehci_vbus_power(struct msm_hcd *mhcd, bool on)
{
int ret;
@@ -236,21 +221,86 @@
pr_err("vbus is NULL.");
return;
}
+
+ if (mhcd->vbus_on == on)
+ return;
+
if (on) {
ret = regulator_enable(mhcd->vbus);
if (ret) {
pr_err("unable to enable vbus\n");
return;
}
+ mhcd->vbus_on = true;
} else {
ret = regulator_disable(mhcd->vbus);
if (ret) {
pr_err("unable to disable vbus\n");
return;
}
+ mhcd->vbus_on = false;
}
}
+static irqreturn_t msm_ehci_dock_connect_irq(int irq, void *data)
+{
+ const struct msm_usb_host_platform_data *pdata;
+ struct msm_hcd *mhcd = data;
+ struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
+
+ pdata = mhcd->dev->platform_data;
+
+ if (atomic_read(&mhcd->in_lpm))
+ usb_hcd_resume_root_hub(hcd);
+
+ if (irq_read_line(pdata->dock_connect_irq)) {
+ dev_dbg(mhcd->dev, "%s:Dock removed disable vbus\n", __func__);
+ msm_ehci_vbus_power(mhcd, 0);
+ } else {
+ dev_dbg(mhcd->dev, "%s:Dock connected enable vbus\n", __func__);
+ msm_ehci_vbus_power(mhcd, 1);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int msm_ehci_init_vbus(struct msm_hcd *mhcd, int init)
+{
+ int rc = 0;
+ struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
+ const struct msm_usb_host_platform_data *pdata;
+
+ pdata = mhcd->dev->platform_data;
+
+ if (!init) {
+ regulator_put(mhcd->vbus);
+ if (pdata && pdata->dock_connect_irq)
+ free_irq(pdata->dock_connect_irq, mhcd);
+ return rc;
+ }
+
+ mhcd->vbus = regulator_get(mhcd->dev, "vbus");
+ if (IS_ERR(mhcd->vbus)) {
+ pr_err("Unable to get vbus\n");
+ return -ENODEV;
+ }
+
+ if (pdata) {
+ hcd->power_budget = pdata->power_budget;
+
+ if (pdata->dock_connect_irq) {
+ rc = request_threaded_irq(pdata->dock_connect_irq, NULL,
+ msm_ehci_dock_connect_irq,
+ IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING |
+ IRQF_ONESHOT, "msm_ehci_host", mhcd);
+ if (!rc)
+ enable_irq_wake(pdata->dock_connect_irq);
+ }
+ }
+ return rc;
+}
+
static int msm_ehci_ldo_enable(struct msm_hcd *mhcd, int on)
{
int ret = 0;
@@ -772,6 +822,7 @@
struct usb_hcd *hcd;
struct resource *res;
struct msm_hcd *mhcd;
+ const struct msm_usb_host_platform_data *pdata;
int ret;
dev_dbg(&pdev->dev, "ehci_msm2 probe\n");
@@ -859,8 +910,10 @@
goto vbus_deinit;
}
- /*TBD:for now enable vbus here*/
- msm_ehci_vbus_power(mhcd, 1);
+ pdata = mhcd->dev->platform_data;
+ if (pdata && (!pdata->dock_connect_irq ||
+ !irq_read_line(pdata->dock_connect_irq)))
+ msm_ehci_vbus_power(mhcd, 1);
device_init_wakeup(&pdev->dev, 1);
wake_lock_init(&mhcd->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev));
@@ -903,6 +956,7 @@
pm_runtime_set_suspended(&pdev->dev);
usb_remove_hcd(hcd);
+
msm_ehci_vbus_power(mhcd, 0);
msm_ehci_init_vbus(mhcd, 0);
msm_ehci_ldo_enable(mhcd, 0);
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/serial/csvt.c b/drivers/usb/serial/csvt.c
index 5bfb2dc..28eba8a 100644
--- a/drivers/usb/serial/csvt.c
+++ b/drivers/usb/serial/csvt.c
@@ -46,7 +46,7 @@
};
static const struct usb_device_id id_table[] = {
- { USB_DEVICE_AND_INTERFACE_INFO(0x05c6 , 0x904c, 0xff, 0x00, 0xff)},
+ { USB_DEVICE_AND_INTERFACE_INFO(0x05c6 , 0x904c, 0xff, 0xfe, 0xff)},
{}, /* terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 44e887c..ef022c1 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -1,7 +1,7 @@
/*
* Qualcomm Serial USB driver
*
- * Copyright (c) 2008, 2012 QUALCOMM Incorporated.
+ * Copyright (c) 2008, 2012 Code Aurora Forum. All rights reserved.
* Copyright (c) 2009 Greg Kroah-Hartman <gregkh@suse.de>
* Copyright (c) 2009 Novell Inc.
*
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index 0110df9..af8c669 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -609,6 +609,7 @@
Support for EBI2 TMD QVGA (240x320) and Epson QCIF (176x220) panel
config FB_MSM_HDMI_AS_PRIMARY
+ depends on FB_MSM_HDMI_COMMON
bool "Use HDMI as primary panel"
---help---
Support for using HDMI as primary
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 0a86a50..d6f59aa 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -347,11 +347,12 @@
struct device_attribute *attr, const char *buf, size_t count)
{
ssize_t ret = strnlen(buf, PAGE_SIZE);
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- int hpd = 1;
-#else
- int hpd = atoi(buf);
-#endif
+ int hpd;
+ if (hdmi_prim_display)
+ hpd = 1;
+ else
+ hpd = atoi(buf);
+
if (external_common_state->hpd_feature) {
if (hpd == 0 && external_common_state->hpd_feature_on) {
external_common_state->hpd_feature(0);
@@ -652,6 +653,14 @@
return ret;
}
+static ssize_t hdmi_common_rda_hdmi_primary(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret = snprintf(buf, PAGE_SIZE, "%d\n",
+ hdmi_prim_display);
+ DEV_DBG("%s: '%d'\n", __func__, hdmi_prim_display);
+ return ret;
+}
static DEVICE_ATTR(video_mode, S_IRUGO | S_IWUGO,
external_common_rda_video_mode, external_common_wta_video_mode);
@@ -671,6 +680,7 @@
static DEVICE_ATTR(format_3d, S_IRUGO | S_IWUGO, hdmi_3d_rda_format_3d,
hdmi_3d_wta_format_3d);
#endif
+static DEVICE_ATTR(hdmi_primary, S_IRUGO, hdmi_common_rda_hdmi_primary, NULL);
static struct attribute *external_common_fs_attrs[] = {
&dev_attr_video_mode.attr,
@@ -693,6 +703,7 @@
&dev_attr_cec_rd_frame.attr,
&dev_attr_cec_wr_frame.attr,
#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+ &dev_attr_hdmi_primary.attr,
NULL,
};
static struct attribute_group external_common_fs_attr_group = {
@@ -1567,11 +1578,10 @@
pinfo->pdest = DISPLAY_2;
pinfo->wait_cycle = 0;
pinfo->bpp = 24;
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- pinfo->fb_num = 2;
-#else
- pinfo->fb_num = 1;
-#endif
+ if (hdmi_prim_display)
+ pinfo->fb_num = 2;
+ else
+ pinfo->fb_num = 1;
/* blk */
pinfo->lcdc.border_clr = 0;
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 96d9487..c240443 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -4518,6 +4518,10 @@
if (msm_fb_detect_client("hdmi_msm"))
return 0;
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+ hdmi_prim_display = 1;
+#endif
+
hdmi_msm_setup_video_mode_lut();
hdmi_msm_state = kzalloc(sizeof(*hdmi_msm_state), GFP_KERNEL);
if (!hdmi_msm_state) {
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index d374b4c..6dcc293 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -87,6 +87,7 @@
extern struct mdp_ccs mdp_ccs_yuv2rgb ;
extern struct mdp_ccs mdp_ccs_rgb2yuv ;
+extern unsigned char hdmi_prim_display;
/*
* MDP Image Structure
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index f7f48e4..c4f6a04 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -445,14 +445,7 @@
}
#endif
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
void mdp4_dtv_set_black_screen(void);
-#else
-static inline void mdp4_dtv_set_black_screen(void)
-{
- /* empty */
-}
-#endif
static inline int mdp4_overlay_borderfill_supported(void)
{
diff --git a/drivers/video/msm/mdp4_dtv.c b/drivers/video/msm/mdp4_dtv.c
index ba774b9..09bc9c2 100644
--- a/drivers/video/msm/mdp4_dtv.c
+++ b/drivers/video/msm/mdp4_dtv.c
@@ -225,11 +225,11 @@
* get/set panel specific fb info
*/
mfd->panel_info = pdata->panel_info;
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- mfd->fb_imgType = MSMFB_DEFAULT_TYPE;
-#else
- mfd->fb_imgType = MDP_RGB_565;
-#endif
+ if (hdmi_prim_display)
+ mfd->fb_imgType = MSMFB_DEFAULT_TYPE;
+ else
+ mfd->fb_imgType = MDP_RGB_565;
+
fbi = mfd->fbi;
fbi->var.pixclock = mfd->panel_info.clk_rate;
fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index d5c08e8..0b86028 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -102,12 +102,12 @@
var = &fbi->var;
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- if (is_mdp4_hw_reset()) {
- mdp4_hw_init();
- outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
+ if (hdmi_prim_display) {
+ if (is_mdp4_hw_reset()) {
+ mdp4_hw_init();
+ outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
+ }
}
-#endif
mdp4_overlay_dmae_cfg(mfd, 0);
/*
@@ -312,11 +312,10 @@
break;
case 4:
default:
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- pipe->src_format = MSMFB_DEFAULT_TYPE;
-#else
- pipe->src_format = MDP_ARGB_8888;
-#endif
+ if (hdmi_prim_display)
+ pipe->src_format = MSMFB_DEFAULT_TYPE;
+ else
+ pipe->src_format = MDP_ARGB_8888;
break;
}
}
@@ -355,7 +354,7 @@
if (pipe != NULL && pipe->mixer_stage == MDP4_MIXER_STAGE_BASE &&
pipe->pipe_type == OVERLAY_TYPE_RGB)
dtv_pipe = pipe; /* keep it */
- else if (mdp4_overlay_borderfill_supported())
+ else if (!hdmi_prim_display && mdp4_overlay_borderfill_supported())
mdp4_overlay_dtv_alloc_pipe(mfd, OVERLAY_TYPE_BF);
else
mdp4_overlay_dtv_alloc_pipe(mfd, OVERLAY_TYPE_RGB);
@@ -512,7 +511,6 @@
complete_all(&dtv_pipe->comp);
}
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
void mdp4_dtv_set_black_screen(void)
{
char *rgb_base;
@@ -520,8 +518,9 @@
uint32 color = 0x00000000;
uint32 temp_src_format;
- if (!dtv_pipe) {
- pr_err("dtv_pipe is not configured yet\n");
+ if (!dtv_pipe || !hdmi_prim_display) {
+ pr_err("dtv_pipe/hdmi as primary are not"
+ " configured yet\n");
return;
}
rgb_base = MDP_BASE + MDP4_RGB_BASE;
@@ -540,7 +539,6 @@
mdp4_mixer_stage_up(dtv_pipe);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
-#endif
static void mdp4_overlay_dtv_wait4dmae(struct msm_fb_data_type *mfd)
{
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 2962393..63fe1f3 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -189,13 +189,44 @@
#endif
static struct msm_fb_platform_data *msm_fb_pdata;
+unsigned char hdmi_prim_display;
int msm_fb_detect_client(const char *name)
{
int ret = 0;
+ u32 len;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
u32 id;
#endif
+ if (!msm_fb_pdata)
+ return -EPERM;
+
+ len = strnlen(name, PANEL_NAME_MAX_LEN);
+ if (strnlen(msm_fb_pdata->prim_panel_name, PANEL_NAME_MAX_LEN)) {
+ pr_err("\n name = %s, prim_display = %s",
+ name, msm_fb_pdata->prim_panel_name);
+ if (!strncmp((char *)msm_fb_pdata->prim_panel_name,
+ name, len)) {
+ if (!strncmp((char *)msm_fb_pdata->prim_panel_name,
+ "hdmi_msm", len))
+ hdmi_prim_display = 1;
+ return 0;
+ } else {
+ ret = -EPERM;
+ }
+ }
+
+ if (strnlen(msm_fb_pdata->ext_panel_name, PANEL_NAME_MAX_LEN)) {
+ pr_err("\n name = %s, ext_display = %s",
+ name, msm_fb_pdata->ext_panel_name);
+ if (!strncmp((char *)msm_fb_pdata->ext_panel_name, name, len))
+ return 0;
+ else
+ ret = -EPERM;
+ }
+
+ if (ret)
+ return ret;
ret = -EPERM;
if (msm_fb_pdata && msm_fb_pdata->detect_client) {
@@ -3349,11 +3380,10 @@
*/
if (type == HDMI_PANEL || type == DTV_PANEL ||
type == TV_PANEL || type == WRITEBACK_PANEL) {
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- pdata->panel_info.fb_num = 2;
-#else
- pdata->panel_info.fb_num = 1;
-#endif
+ if (hdmi_prim_display)
+ pdata->panel_info.fb_num = 2;
+ else
+ pdata->panel_info.fb_num = 1;
}
else
pdata->panel_info.fb_num = MSM_FB_NUM;
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/diagchar.h b/include/linux/diagchar.h
index 1cb5401..17580b4 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -114,11 +114,11 @@
/* This needs to be modified manually now, when we add
a new RANGE of SSIDs to the msg_mask_tbl */
-#define MSG_MASK_TBL_CNT 19
+#define MSG_MASK_TBL_CNT 23
#define EVENT_LAST_ID 0x083F
#define MSG_SSID_0 0
-#define MSG_SSID_0_LAST 68
+#define MSG_SSID_0_LAST 90
#define MSG_SSID_1 500
#define MSG_SSID_1_LAST 506
#define MSG_SSID_2 1000
@@ -126,19 +126,19 @@
#define MSG_SSID_3 2000
#define MSG_SSID_3_LAST 2008
#define MSG_SSID_4 3000
-#define MSG_SSID_4_LAST 3012
+#define MSG_SSID_4_LAST 3014
#define MSG_SSID_5 4000
#define MSG_SSID_5_LAST 4010
#define MSG_SSID_6 4500
#define MSG_SSID_6_LAST 4526
#define MSG_SSID_7 4600
-#define MSG_SSID_7_LAST 4611
+#define MSG_SSID_7_LAST 4612
#define MSG_SSID_8 5000
-#define MSG_SSID_8_LAST 5024
+#define MSG_SSID_8_LAST 5029
#define MSG_SSID_9 5500
-#define MSG_SSID_9_LAST 5514
+#define MSG_SSID_9_LAST 5516
#define MSG_SSID_10 6000
-#define MSG_SSID_10_LAST 6050
+#define MSG_SSID_10_LAST 6072
#define MSG_SSID_11 6500
#define MSG_SSID_11_LAST 6521
#define MSG_SSID_12 7000
@@ -155,6 +155,14 @@
#define MSG_SSID_17_LAST 9008
#define MSG_SSID_18 9500
#define MSG_SSID_18_LAST 9509
+#define MSG_SSID_19 10200
+#define MSG_SSID_19_LAST 10210
+#define MSG_SSID_20 10251
+#define MSG_SSID_20_LAST 10255
+#define MSG_SSID_21 10300
+#define MSG_SSID_21_LAST 10300
+#define MSG_SSID_22 10350
+#define MSG_SSID_22_LAST 10361
struct diagpkt_delay_params {
void *rsp_ptr;
@@ -249,6 +257,28 @@
MSG_LVL_MED,
MSG_LVL_LOW,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
+ MSG_LVL_MED,
+ MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
+ MSG_LVL_LOW,
+ MSG_LVL_MED,
+ MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_1[] = {
@@ -258,7 +288,7 @@
MSG_LVL_LOW,
MSG_LVL_HIGH,
MSG_LVL_HIGH,
- MSG_LVL_HIGH,
+ MSG_LVL_HIGH
};
static const uint32_t msg_bld_masks_2[] = {
@@ -297,7 +327,9 @@
MSG_LVL_HIGH,
MSG_LVL_HIGH,
MSG_LVL_HIGH,
- MSG_LVL_HIGH
+ MSG_LVL_HIGH,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_5[] = {
@@ -310,7 +342,8 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
- MSG_LVL_MED,
+ MSG_LVL_MED|MSG_LVL_MED|MSG_MASK_5|MSG_MASK_6|MSG_MASK_7| \
+ MSG_MASK_8|MSG_MASK_9,
MSG_LVL_MED
};
@@ -357,6 +390,7 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
+ MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_8[] = {
@@ -385,6 +419,11 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED
};
static const uint32_t msg_bld_masks_9[] = {
@@ -403,6 +442,8 @@
MSG_LVL_MED|MSG_MASK_5,
MSG_LVL_MED|MSG_MASK_5,
MSG_LVL_MED|MSG_MASK_5,
+ MSG_LVL_MED|MSG_MASK_5,
+ MSG_LVL_MED|MSG_MASK_5
};
static const uint32_t msg_bld_masks_10[] = {
@@ -462,6 +503,28 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_11[] = {
@@ -584,6 +647,47 @@
MSG_LVL_LOW
};
+static const uint32_t msg_bld_masks_19[] = {
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW
+};
+
+static const uint32_t msg_bld_masks_20[] = {
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW
+};
+
+static const uint32_t msg_bld_masks_21[] = {
+ MSG_LVL_HIGH
+};
+
+static const uint32_t msg_bld_masks_22[] = {
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH
+};
+
/* LOG CODES */
#define LOG_0 0x0
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/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/mmc/card.h b/include/linux/mmc/card.h
index ff53742..dedbe5c 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -190,6 +190,7 @@
#define MMC_STATE_ULTRAHIGHSPEED (1<<5) /* card is in ultra high speed mode */
#define MMC_CARD_SDXC (1<<6) /* card is SDXC */
#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
+#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
@@ -328,6 +329,7 @@
#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
#define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY)
#define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED)
+#define mmc_card_hs200(c) ((c)->state & MMC_STATE_HIGHSPEED_200)
#define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR)
#define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR)
#define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
@@ -337,6 +339,7 @@
#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
#define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED)
+#define mmc_card_set_hs200(c) ((c)->state |= MMC_STATE_HIGHSPEED_200)
#define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR)
#define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR)
#define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 35137d6..73a68c9 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -56,12 +56,15 @@
#define MMC_TIMING_UHS_SDR50 3
#define MMC_TIMING_UHS_SDR104 4
#define MMC_TIMING_UHS_DDR50 5
+#define MMC_TIMING_MMC_HS200 6
unsigned char ddr; /* dual data rate used */
#define MMC_SDR_MODE 0
#define MMC_1_2V_DDR_MODE 1
#define MMC_1_8V_DDR_MODE 2
+#define MMC_1_2V_SDR_MODE 3
+#define MMC_1_8V_SDR_MODE 4
unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */
@@ -147,7 +150,9 @@
void (*init_card)(struct mmc_host *host, struct mmc_card *card);
int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios);
- int (*execute_tuning)(struct mmc_host *host);
+
+ /* The tuning command opcode value is different for SD and eMMC cards */
+ int (*execute_tuning)(struct mmc_host *host, u32 opcode);
void (*enable_preset_value)(struct mmc_host *host, bool enable);
void (*hw_reset)(struct mmc_host *host);
};
@@ -239,7 +244,10 @@
#define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */
#define MMC_CAP2_POWEROFF_NOTIFY (1 << 2) /* Notify poweroff supported */
#define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */
-
+#define MMC_CAP2_HS200_1_8V_SDR (1 << 5) /* can support */
+#define MMC_CAP2_HS200_1_2V_SDR (1 << 6) /* can support */
+#define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \
+ MMC_CAP2_HS200_1_2V_SDR)
mmc_pm_flag_t pm_caps; /* supported pm features */
unsigned int power_notify_type;
#define MMC_HOST_PW_NOTIFY_NONE 0
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 0a72bf8..e124fbe 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -51,6 +51,7 @@
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
+#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
/* class 3 */
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
@@ -331,13 +332,76 @@
#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */
-#define EXT_CSD_CARD_TYPE_MASK 0xF /* Mask out reserved bits */
+#define EXT_CSD_CARD_TYPE_MASK 0x3F /* Mask out reserved bits */
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
/* DDR mode @1.8V or 3V I/O */
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
/* DDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
| EXT_CSD_CARD_TYPE_DDR_1_2V)
+#define EXT_CSD_CARD_TYPE_SDR_1_8V (1<<4) /* Card can run at 200MHz */
+#define EXT_CSD_CARD_TYPE_SDR_1_2V (1<<5) /* Card can run at 200MHz */
+ /* SDR mode @1.2V I/O */
+
+#define EXT_CSD_CARD_TYPE_SDR_200 (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_SDR_1_2V)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_ALL (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_ALL (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_DDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_DDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_DDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_DDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52 (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_DDR_52 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52 (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_DDR_52 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_DDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_DDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52 (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_DDR_52 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
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.h b/include/linux/usb.h
index 583ceb8..60decb6 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -322,6 +322,13 @@
unsigned is_b_host:1; /* true during some HNP roleswitches */
unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */
unsigned hnp_support:1; /* OTG: HNP is supported on OTG port */
+ unsigned quick_hnp:1; /* OTG: Indiacates if hnp is required
+ irrespective of host_request flag
+ */
+ unsigned otg_vbus_off:1; /* OTG: OTG test device feature bit that
+ * tells A-device to turn off VBUS after
+ * B-device is disconnected.
+ */
struct delayed_work hnp_polling;/* OTG: HNP polling work */
unsigned sg_tablesize; /* 0 or largest number of sg list entries */
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index 736203b..ea49aa1 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -133,6 +133,12 @@
#define TEST_PACKET 4
#define TEST_FORCE_EN 5
+/* OTG test mode feature bits
+ * See ECN OTG2.0 spec Table 6-8
+ */
+#define TEST_OTG_SRP_REQD 6
+#define TEST_OTG_HNP_REQD 7
+
/*
* New Feature Selectors as added by USB 3.0
* See USB 3.0 spec Table 9-6
@@ -146,9 +152,12 @@
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
-#define OTG_STATUS_SELECTOR 0xF000
-#define THOST_REQ_POLL 2000 /* msec */
-#define HOST_REQUEST_FLAG 0
+#define OTG_STATUS_SELECTOR 0xF000
+#define HOST_REQUEST_FLAG 0
+#define THOST_REQ_POLL 1500 /* msec (1000 - 2000) */
+#define OTG_TTST_SUSP 70 /* msec (0 - 100) */
+
+#define OTG_TTST_VBUS_OFF 1
/* Bit array elements as returned by the USB_REQ_GET_STATUS request. */
#define USB_DEV_STAT_U1_ENABLED 2 /* transition into U1 state */
@@ -617,8 +626,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..35c9cd1 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -453,6 +453,9 @@
* only supports HNP on a different root port.
* @b_hnp_enable: OTG device feature flag, indicating that the A-Host
* enabled HNP support.
+ * @host_request: A flag set by user when wishes to take up host role.
+ * @otg_srp_reqd: OTG test mode feature to initiate SRP after the end of
+ * current session.
* @name: Identifies the controller hardware type. Used in diagnostics
* and sometimes configuration.
* @dev: Driver model state for this abstract device.
@@ -488,6 +491,7 @@
unsigned a_hnp_support:1;
unsigned a_alt_hnp_support:1;
unsigned host_request:1;
+ unsigned otg_srp_reqd:1;
const char *name;
struct device dev;
};
@@ -860,6 +864,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/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 79fb177..f2ad7e1 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -279,6 +279,7 @@
struct msm_usb_host_platform_data {
unsigned int power_budget;
+ unsigned int dock_connect_irq;
};
struct usb_bam_pipe_connect {
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index 3e93de7..fb1ca8c 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -30,4 +30,6 @@
descriptor */
#define USB_QUIRK_DELAY_INIT 0x00000040
+#define USB_QUIRK_OTG_PET 0x00000080
+
#endif /* __LINUX_USB_QUIRKS_H */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 164d3b4..fe14055 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -570,7 +570,7 @@
struct hci_conn *hci_le_conn_add(struct hci_dev *hdev, bdaddr_t *dst,
__u8 addr_type);
int hci_conn_del(struct hci_conn *conn);
-void hci_conn_hash_flush(struct hci_dev *hdev);
+void hci_conn_hash_flush(struct hci_dev *hdev, u8 is_process);
void hci_conn_check_pending(struct hci_dev *hdev);
struct hci_chan *hci_chan_add(struct hci_dev *hdev);
@@ -751,7 +751,8 @@
int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
int (*connect_cfm) (struct hci_conn *conn, __u8 status);
int (*disconn_ind) (struct hci_conn *conn);
- int (*disconn_cfm) (struct hci_conn *conn, __u8 reason);
+ int (*disconn_cfm) (struct hci_conn *conn, __u8 reason,
+ __u8 is_process);
int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
@@ -808,17 +809,18 @@
return reason;
}
-static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
+static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason,
+ __u8 is_process)
{
register struct hci_proto *hp;
hp = hci_proto[HCI_PROTO_L2CAP];
if (hp && hp->disconn_cfm)
- hp->disconn_cfm(conn, reason);
+ hp->disconn_cfm(conn, reason, is_process);
hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->disconn_cfm)
- hp->disconn_cfm(conn, reason);
+ hp->disconn_cfm(conn, reason, is_process);
if (conn->disconn_cfm_cb)
conn->disconn_cfm_cb(conn, reason);
diff --git a/kernel/power/fbearlysuspend.c b/kernel/power/fbearlysuspend.c
index 1513765..4877372 100644
--- a/kernel/power/fbearlysuspend.c
+++ b/kernel/power/fbearlysuspend.c
@@ -19,7 +19,10 @@
#include "power.h"
+#define MAX_BUF 100
+
static wait_queue_head_t fb_state_wq;
+static int display = 1;
static DEFINE_SPINLOCK(fb_state_lock);
static enum {
FB_STATE_STOPPED_DRAWING,
@@ -71,10 +74,16 @@
ret = wait_event_interruptible(fb_state_wq,
fb_state != FB_STATE_DRAWING_OK);
- if (ret && fb_state == FB_STATE_DRAWING_OK)
+ if (ret && fb_state == FB_STATE_DRAWING_OK) {
return ret;
- else
+ } else {
s += sprintf(buf, "sleeping");
+ if (display == 1) {
+ display = 0;
+ sysfs_notify(power_kobj, NULL, "wait_for_fb_status");
+ }
+ }
+
return s - buf;
}
@@ -96,28 +105,47 @@
fb_state == FB_STATE_DRAWING_OK);
if (ret && fb_state != FB_STATE_DRAWING_OK)
return ret;
- else
+ else {
s += sprintf(buf, "awake");
-
+ if (display == 0) {
+ display = 1;
+ sysfs_notify(power_kobj, NULL, "wait_for_fb_status");
+ }
+ }
return s - buf;
}
-#define power_ro_attr(_name) \
-static struct kobj_attribute _name##_attr = { \
- .attr = { \
- .name = __stringify(_name), \
- .mode = 0444, \
- }, \
- .show = _name##_show, \
- .store = NULL, \
+static ssize_t wait_for_fb_status_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ int ret = 0;
+
+ if (display == 1)
+ ret = snprintf(buf, strnlen("on", MAX_BUF) + 1, "on");
+ else
+ ret = snprintf(buf, strnlen("off", MAX_BUF) + 1, "off");
+
+ return ret;
}
+#define power_ro_attr(_name) \
+ static struct kobj_attribute _name##_attr = { \
+ .attr = { \
+ .name = __stringify(_name), \
+ .mode = 0444, \
+ }, \
+ .show = _name##_show, \
+ .store = NULL, \
+ }
+
power_ro_attr(wait_for_fb_sleep);
power_ro_attr(wait_for_fb_wake);
+power_ro_attr(wait_for_fb_status);
static struct attribute *g[] = {
&wait_for_fb_sleep_attr.attr,
&wait_for_fb_wake_attr.attr,
+ &wait_for_fb_status_attr.attr,
NULL,
};
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 899c538..ca33664 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -728,7 +728,7 @@
{
BT_DBG("conn %p", conn);
- hci_proto_disconn_cfm(conn, reason);
+ hci_proto_disconn_cfm(conn, reason, 0);
}
EXPORT_SYMBOL(hci_disconnect);
@@ -1027,7 +1027,7 @@
EXPORT_SYMBOL(hci_chan_modify);
/* Drop all connection on the device */
-void hci_conn_hash_flush(struct hci_dev *hdev)
+void hci_conn_hash_flush(struct hci_dev *hdev, u8 is_process)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p;
@@ -1043,7 +1043,7 @@
c->state = BT_CLOSED;
- hci_proto_disconn_cfm(c, 0x16);
+ hci_proto_disconn_cfm(c, 0x16, is_process);
hci_conn_del(c);
}
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4c2bd37..c0eb50c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -626,7 +626,7 @@
return ret;
}
-static int hci_dev_do_close(struct hci_dev *hdev)
+static int hci_dev_do_close(struct hci_dev *hdev, u8 is_process)
{
unsigned long keepflags = 0;
@@ -647,7 +647,7 @@
hci_dev_lock_bh(hdev);
inquiry_cache_flush(hdev);
- hci_conn_hash_flush(hdev);
+ hci_conn_hash_flush(hdev, is_process);
hci_dev_unlock_bh(hdev);
hci_notify(hdev, HCI_DEV_DOWN);
@@ -714,7 +714,7 @@
hdev = hci_dev_get(dev);
if (!hdev)
return -ENODEV;
- err = hci_dev_do_close(hdev);
+ err = hci_dev_do_close(hdev, 1);
hci_dev_put(hdev);
return err;
}
@@ -740,7 +740,7 @@
hci_dev_lock_bh(hdev);
inquiry_cache_flush(hdev);
- hci_conn_hash_flush(hdev);
+ hci_conn_hash_flush(hdev, 0);
hci_dev_unlock_bh(hdev);
if (hdev->flush)
@@ -953,7 +953,7 @@
if (!blocked)
return 0;
- hci_dev_do_close(hdev);
+ hci_dev_do_close(hdev, 0);
return 0;
}
@@ -1563,7 +1563,7 @@
list_del(&hdev->list);
write_unlock_bh(&hci_dev_list_lock);
- hci_dev_do_close(hdev);
+ hci_dev_do_close(hdev, 0);
for (i = 0; i < NUM_REASSEMBLY; i++)
kfree_skb(hdev->reassembly[i]);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 86479ab..a1a5a72 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1764,7 +1764,7 @@
if (conn->type == LE_LINK)
del_timer(&conn->smp_timer);
- hci_proto_disconn_cfm(conn, ev->reason);
+ hci_proto_disconn_cfm(conn, ev->reason, 0);
hci_conn_del(conn);
unlock:
@@ -3305,7 +3305,7 @@
if (conn) {
conn->state = BT_CLOSED;
- hci_proto_disconn_cfm(conn, ev->reason);
+ hci_proto_disconn_cfm(conn, ev->reason, 0);
hci_conn_del(conn);
}
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a3d5e34..6a95c79 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -89,7 +89,7 @@
static int l2cap_create_cfm(struct hci_chan *chan, u8 status);
static int l2cap_deaggregate(struct hci_chan *chan, struct l2cap_pinfo *pi);
static void l2cap_chan_ready(struct sock *sk);
-static void l2cap_conn_del(struct hci_conn *hcon, int err);
+static void l2cap_conn_del(struct hci_conn *hcon, int err, u8 is_process);
static u16 l2cap_get_smallest_flushto(struct l2cap_chan_list *l);
static void l2cap_set_acl_flushto(struct hci_conn *hcon, u16 flush_to);
@@ -1160,7 +1160,7 @@
return conn;
}
-static void l2cap_conn_del(struct hci_conn *hcon, int err)
+static void l2cap_conn_del(struct hci_conn *hcon, int err, u8 is_process)
{
struct l2cap_conn *conn = hcon->l2cap_data;
struct sock *sk;
@@ -1181,9 +1181,15 @@
BT_DBG("ampcon %p", l2cap_pi(sk)->ampcon);
if ((conn->hcon == hcon) || (l2cap_pi(sk)->ampcon == hcon)) {
next = l2cap_pi(sk)->next_c;
- bh_lock_sock(sk);
+ if (is_process)
+ lock_sock(sk);
+ else
+ bh_lock_sock(sk);
l2cap_chan_del(sk, err);
- bh_unlock_sock(sk);
+ if (is_process)
+ release_sock(sk);
+ else
+ bh_unlock_sock(sk);
l2cap_sock_kill(sk);
sk = next;
} else
@@ -7332,7 +7338,7 @@
case L2CAP_CID_SMP:
if (smp_sig_channel(conn, skb))
- l2cap_conn_del(conn->hcon, EACCES);
+ l2cap_conn_del(conn->hcon, EACCES, 0);
break;
default:
@@ -7407,7 +7413,7 @@
if (conn)
l2cap_conn_ready(conn);
} else
- l2cap_conn_del(hcon, bt_err(status));
+ l2cap_conn_del(hcon, bt_err(status), 0);
return 0;
}
@@ -7424,14 +7430,14 @@
return conn->disc_reason;
}
-static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
+static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason, u8 is_process)
{
BT_DBG("hcon %p reason %d", hcon, reason);
if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
return -EINVAL;
- l2cap_conn_del(hcon, bt_err(reason));
+ l2cap_conn_del(hcon, bt_err(reason), is_process);
return 0;
}
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 99c4559..f8c3bba 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -62,7 +62,7 @@
static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
static void sco_chan_del(struct sock *sk, int err);
-static int sco_conn_del(struct hci_conn *conn, int err);
+static int sco_conn_del(struct hci_conn *conn, int err, u8 is_process);
static void sco_sock_close(struct sock *sk);
static void sco_sock_kill(struct sock *sk);
@@ -135,7 +135,7 @@
return sk;
}
-static int sco_conn_del(struct hci_conn *hcon, int err)
+static int sco_conn_del(struct hci_conn *hcon, int err, u8 is_process)
{
struct sco_conn *conn = hcon->sco_data;
struct sock *sk;
@@ -148,10 +148,16 @@
/* Kill socket */
sk = sco_chan_get(conn);
if (sk) {
- bh_lock_sock(sk);
+ if (is_process)
+ lock_sock(sk);
+ else
+ bh_lock_sock(sk);
sco_sock_clear_timer(sk);
sco_chan_del(sk, err);
- bh_unlock_sock(sk);
+ if (is_process)
+ release_sock(sk);
+ else
+ bh_unlock_sock(sk);
sco_sock_kill(sk);
}
@@ -952,19 +958,19 @@
if (conn)
sco_conn_ready(conn);
} else
- sco_conn_del(hcon, bt_err(status));
+ sco_conn_del(hcon, bt_err(status), 0);
return 0;
}
-static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
+static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason, __u8 is_process)
{
BT_DBG("hcon %p reason %d", hcon, reason);
if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
return -EINVAL;
- sco_conn_del(hcon, bt_err(reason));
+ sco_conn_del(hcon, bt_err(reason), is_process);
return 0;
}
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/apq8064.c b/sound/soc/msm/apq8064.c
index ff50ba6..ae4e403 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -1278,7 +1278,7 @@
};
struct snd_soc_card snd_soc_card_msm = {
- .name = "msm-snd-card",
+ .name = "apq8064-tabla-snd-card",
.dai_link = msm_dai,
.num_links = ARRAY_SIZE(msm_dai),
};
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d528f4b..76091e3 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1144,6 +1144,11 @@
struct snd_soc_codec *codec;
int i;
+ if (!card->instantiated) {
+ dev_dbg(card->dev, "uninsantiated card found card->name = %s\n",
+ card->name);
+ return 0;
+ }
/* If the initialization of this soc device failed, there is no codec
* associated with it. Just bail out in this case.
*/
@@ -1397,6 +1402,11 @@
struct snd_soc_card *card = dev_get_drvdata(dev);
int i, ac97_control = 0;
+ if (!card->instantiated) {
+ dev_dbg(card->dev, "uninsantiated card found card->name = %s\n",
+ card->name);
+ return 0;
+ }
/* AC97 devices might have other drivers hanging off them so
* need to resume immediately. Other drivers don't have that
* problem and may take a substantial amount of time to resume