Merge "bluetooth: Reset BT stack when wcnss chip resets" into msm-3.0
diff --git a/Documentation/genlock.txt b/Documentation/genlock.txt
index d3a44e2..6f24a76 100644
--- a/Documentation/genlock.txt
+++ b/Documentation/genlock.txt
@@ -82,15 +82,13 @@
 Release a handle.
 
 * struct genlock * genlock_create_lock(struct genlock_handle *)
-Create a new lock and attach it to the handle.
+Create a new lock and attach it to the handle.  Once a lock is attached to a
+handle it stays attached until the handle is destroyed.
 
 * struct genlock * genlock_attach_lock(struct genlock_handle *handle, int fd)
 Given a valid file descriptor, get the lock associated with it and attach it to
 the handle.
 
-* void genlock_release_lock(struct genlock_handle *)
-Release a lock attached to a handle.
-
 * int genlock_lock(struct genlock_handle *, int op, int flags, u32 timeout)
 Lock or unlock the lock attached to the handle. A zero timeout value will
 be treated just like if the GENOCK_NOBLOCK flag is passed; if the lock
@@ -155,7 +153,4 @@
 -EINVAL if a zero timeout is passed, or -ETIMEDOUT if the timeout expires.
 
 * GENLOCK_IOC_RELEASE
-Use this to release an existing lock. This is useful if you wish to attach a
-different lock to the same handle. You do not need to call this under normal
-circumstances; when the handle is closed the reference to the lock is released.
-No data is passed from the user for this ioctl.
+This ioctl has been deprecated.  Do not use.
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index fc1d81a..76ff09c 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -201,6 +201,7 @@
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 3cf01a1..3ddb0c9 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -201,6 +201,7 @@
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h
index d493d0b..ec4b8b8 100644
--- a/arch/arm/include/asm/fiq.h
+++ b/arch/arm/include/asm/fiq.h
@@ -33,11 +33,22 @@
 	void *dev_id;
 };
 
+#ifdef CONFIG_FIQ
 extern int claim_fiq(struct fiq_handler *f);
 extern void release_fiq(struct fiq_handler *f);
 extern void set_fiq_handler(void *start, unsigned int length);
 extern void enable_fiq(int fiq);
 extern void disable_fiq(int fiq);
+#else
+static inline int claim_fiq(struct fiq_handler *f)
+{
+	return 0;
+}
+static inline void release_fiq(struct fiq_handler *f) { }
+static inline void set_fiq_handler(void *start, unsigned int length) { }
+static inline void enable_fiq(int fiq) { }
+static inline void disable_fiq(int fiq) { }
+#endif
 
 /* helpers defined in fiqasm.S: */
 extern void __set_fiq_regs(unsigned long const *regs);
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index fa82e34..05c5a2b 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -1795,7 +1795,7 @@
 	if (bam_tx_pipe == NULL) {
 		pr_err("%s: tx alloc endpoint failed\n", __func__);
 		ret = -ENOMEM;
-		goto register_bam_failed;
+		goto tx_alloc_endpoint_failed;
 	}
 	ret = sps_get_config(bam_tx_pipe, &tx_connection);
 	if (ret) {
@@ -1815,7 +1815,7 @@
 	if (tx_desc_mem_buf.base == NULL) {
 		pr_err("%s: tx memory alloc failed\n", __func__);
 		ret = -ENOMEM;
-		goto tx_mem_failed;
+		goto tx_get_config_failed;
 	}
 	tx_desc_mem_buf.phys_base = dma_addr;
 	memset(tx_desc_mem_buf.base, 0x0, tx_desc_mem_buf.size);
@@ -1832,7 +1832,7 @@
 	if (bam_rx_pipe == NULL) {
 		pr_err("%s: rx alloc endpoint failed\n", __func__);
 		ret = -ENOMEM;
-		goto tx_connect_failed;
+		goto rx_alloc_endpoint_failed;
 	}
 	ret = sps_get_config(bam_rx_pipe, &rx_connection);
 	if (ret) {
@@ -1901,15 +1901,16 @@
 	dma_free_coherent(NULL, rx_desc_mem_buf.size, rx_desc_mem_buf.base,
 				rx_desc_mem_buf.phys_base);
 rx_mem_failed:
-	sps_disconnect(bam_tx_pipe);
 rx_get_config_failed:
 	sps_free_endpoint(bam_rx_pipe);
+rx_alloc_endpoint_failed:
+	sps_disconnect(bam_tx_pipe);
 tx_connect_failed:
 	dma_free_coherent(NULL, tx_desc_mem_buf.size, tx_desc_mem_buf.base,
 				tx_desc_mem_buf.phys_base);
 tx_get_config_failed:
 	sps_free_endpoint(bam_tx_pipe);
-tx_mem_failed:
+tx_alloc_endpoint_failed:
 	sps_deregister_bam_device(h);
 	/*
 	 * sps_deregister_bam_device() calls iounmap.  calling iounmap on the
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index c652238..6c01764 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -70,6 +70,9 @@
 	REGULATOR_SUPPLY("iris_vddio",		"wcnss_wlan.0"),
 	REGULATOR_SUPPLY("riva_vddpx",		"wcnss_wlan.0"),
 	REGULATOR_SUPPLY("sdc_vccq",		"msm_sdcc.1"),
+	REGULATOR_SUPPLY("VDDIO_CDC",		"sitar-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_TX",		"sitar-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_RX",		"sitar-slim"),
 };
 VREG_CONSUMERS(L12) = {
 	REGULATOR_SUPPLY("8038_l12",		NULL),
@@ -97,6 +100,8 @@
 };
 VREG_CONSUMERS(L20) = {
 	REGULATOR_SUPPLY("8038_l20",		NULL),
+	REGULATOR_SUPPLY("VDDD_CDC_D",		"sitar-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_A_1P2V",	"sitar-slim"),
 };
 VREG_CONSUMERS(L21) = {
 	REGULATOR_SUPPLY("8038_l21",		NULL),
@@ -138,6 +143,7 @@
 };
 VREG_CONSUMERS(S4) = {
 	REGULATOR_SUPPLY("8038_s4",		NULL),
+	REGULATOR_SUPPLY("CDC_VDD_CP",		"sitar-slim"),
 };
 VREG_CONSUMERS(S5) = {
 	REGULATOR_SUPPLY("8038_s5",		NULL),
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index fc91337..f9601a6 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1475,8 +1475,8 @@
 	 27, 0, 5, 1, 0, 0, 8, 8, 0, 0,
 	/* T9 Object */
 	 131, 0, 0, 19, 11, 0, 16, 35, 1, 3,
-	 10, 15, 1, 11, 4, 5, 40, 10, 54, 2,
-	 43, 4, 0, 0, 0, 0, 143, 40, 143, 80,
+	 10, 15, 1, 11, 4, 5, 40, 10, 43, 4,
+	 54, 2, 0, 0, 0, 0, 143, 40, 143, 80,
 	 18, 15, 50, 50, 2,
 	/* T15 Object */
 	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1513,10 +1513,10 @@
 			struct kobj_attribute *attr, char *buf)
 {
 	return snprintf(buf, 200,
-	__stringify(EV_KEY) ":" __stringify(KEY_BACK) ":65:938:90:90"
-	":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":208:938:90:90"
-	":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":348:938:90:90"
-	":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":490:938:90:90"
+	__stringify(EV_KEY) ":" __stringify(KEY_BACK) ":57:1030:90:90"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":206:1030:90:90"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":366:1030:90:90"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":503:1030:90:90"
 	"\n");
 }
 
@@ -1568,8 +1568,10 @@
 static struct mxt_platform_data mxt_platform_data_8930 = {
 	.config_array		= mxt_config_array,
 	.config_array_size	= ARRAY_SIZE(mxt_config_array),
-	.x_size			= 1067,
-	.y_size			= 566,
+	.x_size			= 540,
+	.y_size			= 960,
+	.touch_x_size		= 566,
+	.touch_y_size		= 1067,
 	.irqflags		= IRQF_TRIGGER_FALLING,
 #ifdef MSM8930_PHASE_2
 	.digital_pwr_regulator	= true,
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 2d5ae78..1bb9c86 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -631,7 +631,8 @@
 			bank_info = &bank_masks->bank1_mask;
 
 		ns_mask = bank_info->ns_mask;
-		md_val = readl_relaxed(bank_info->md_reg);
+		md_val = bank_info->md_reg ?
+				readl_relaxed(bank_info->md_reg) : 0;
 	} else {
 		ns_mask = clk->ns_mask;
 		md_val = clk->md_reg ? readl_relaxed(clk->md_reg) : 0;
diff --git a/arch/arm/mach-msm/lpass-8960.c b/arch/arm/mach-msm/lpass-8960.c
index 11b9092..5eccf06 100644
--- a/arch/arm/mach-msm/lpass-8960.c
+++ b/arch/arm/mach-msm/lpass-8960.c
@@ -66,6 +66,28 @@
 	.notifier_call = riva_notifier_cb,
 };
 
+static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
+								void *ss_handle)
+{
+	int ret;
+	switch (code) {
+	case SUBSYS_BEFORE_SHUTDOWN:
+		pr_debug("%s: M-Notify: Shutdown started\n", __func__);
+		ret = sysmon_send_event(SYSMON_SS_LPASS, "modem",
+				SUBSYS_BEFORE_SHUTDOWN);
+		if (ret < 0)
+			pr_err("%s: sysmon_send_event error %d", __func__,
+				ret);
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+static void *ssr_modem_notif_hdle;
+static struct notifier_block mnb = {
+	.notifier_call = modem_notifier_cb,
+};
+
 static void lpass_fatal_fn(struct work_struct *work)
 {
 	pr_err("%s %s: Watchdog bite received from Q6!\n", MODULE_NAME,
@@ -213,6 +235,18 @@
 		goto out;
 	}
 
+	ssr_modem_notif_hdle = subsys_notif_register_notifier("modem",
+							&mnb);
+	if (IS_ERR(ssr_modem_notif_hdle) < 0) {
+		ret = PTR_ERR(ssr_modem_notif_hdle);
+		pr_err("%s: subsys_register_notifier for Modem: err = %d\n",
+			__func__, ret);
+		subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+		iounmap(q6_wakeup_intr);
+		free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
+		goto out;
+	}
+
 	pr_info("%s: lpass SSR driver init'ed.\n", __func__);
 out:
 	return ret;
@@ -221,6 +255,7 @@
 static void __exit lpass_fatal_exit(void)
 {
 	subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+	subsys_notif_unregister_notifier(ssr_modem_notif_hdle, &mnb);
 	iounmap(q6_wakeup_intr);
 	free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
 }
diff --git a/drivers/base/genlock.c b/drivers/base/genlock.c
index 27717e0..1507915 100644
--- a/drivers/base/genlock.c
+++ b/drivers/base/genlock.c
@@ -496,12 +496,7 @@
 	return ret;
 }
 
-/**
- * genlock_release_lock - Release a lock attached to a handle
- * @handle - Pointer to the handle holding the lock
- */
-
-void genlock_release_lock(struct genlock_handle *handle)
+static void genlock_release_lock(struct genlock_handle *handle)
 {
 	unsigned long flags;
 
@@ -522,7 +517,6 @@
 	handle->lock = NULL;
 	handle->active = 0;
 }
-EXPORT_SYMBOL(genlock_release_lock);
 
 /*
  * Release function called when all references to a handle are released
@@ -671,8 +665,13 @@
 		return genlock_wait(handle, param.timeout);
 	}
 	case GENLOCK_IOC_RELEASE: {
-		genlock_release_lock(handle);
-		return 0;
+		/*
+		 * Return error - this ioctl has been deprecated.
+		 * Locks should only be released when the handle is
+		 * destroyed
+		 */
+		GENLOCK_LOG_ERR("Deprecated RELEASE ioctl called\n");
+		return -EINVAL;
 	}
 	default:
 		GENLOCK_LOG_ERR("Invalid ioctl\n");
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 71bdcde..4e81567 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -303,6 +303,8 @@
 	struct mxt_info info;
 	struct mxt_finger finger[MXT_MAX_FINGER];
 	unsigned int irq;
+	unsigned int touch_x_size;
+	unsigned int touch_y_size;
 	struct regulator *vcc_ana;
 	struct regulator *vcc_dig;
 	struct regulator *vcc_i2c;
@@ -667,9 +669,9 @@
 
 	x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
 	y = (message->message[2] << 4) | ((message->message[3] & 0xf));
-	if (data->pdata->x_size < 1024)
+	if (data->touch_x_size < 1024)
 		x = x >> 2;
-	if (data->pdata->y_size < 1024)
+	if (data->touch_y_size < 1024)
 		y = y >> 2;
 
 	area = message->message[4];
@@ -1809,7 +1811,7 @@
 		goto err_free_mem;
 	}
 
-	input_dev->name = "Atmel maXTouch Touchscreen";
+	input_dev->name = "atmel_mxt_ts";
 	input_dev->id.bustype = BUS_I2C;
 	input_dev->dev.parent = &client->dev;
 	input_dev->open = mxt_input_open;
@@ -1842,6 +1844,16 @@
 	input_set_abs_params(input_dev, ABS_MT_PRESSURE,
 			     0, 255, 0, 0);
 
+	if (pdata->touch_x_size)
+		data->touch_x_size = pdata->touch_x_size;
+	else
+		data->touch_x_size = pdata->x_size;
+
+	if (pdata->touch_y_size)
+		data->touch_y_size = pdata->touch_y_size;
+	else
+		data->touch_y_size = pdata->y_size;
+
 	/* set key array supported keys */
 	if (pdata->key_codes) {
 		for (i = 0; i < MXT_KEYARRAY_MAX_KEYS; i++) {
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index 283f985..eb0048a 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -132,6 +132,9 @@
 #define UART_PATH_SEL_MASK			0x60
 #define UART_PATH_SEL_SHIFT			0x5
 
+#define USB_ID_PU_EN_MASK			0x10	/* PM8921 family only */
+#define USB_ID_PU_EN_SHIFT			4
+
 /* Shutdown/restart delays to allow for LDO 7/dVdd regulator load settling. */
 #define PM8901_DELAY_AFTER_REG_DISABLE_MS	4
 #define PM8901_DELAY_BEFORE_SHUTDOWN_MS		8
@@ -944,6 +947,48 @@
 }
 EXPORT_SYMBOL(pm8xxx_uart_gpio_mux_ctrl);
 
+/**
+ * pm8xxx_usb_id_pullup - Control a pullup for USB ID
+ *
+ * @enable: enable (1) or disable (0) the pullup
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_usb_id_pullup(int enable)
+{
+	struct pm8xxx_misc_chip *chip;
+	unsigned long flags;
+	int rc = -ENXIO;
+
+	spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+	/* Loop over all attached PMICs and call specific functions for them. */
+	list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+		switch (chip->version) {
+		case PM8XXX_VERSION_8921:
+		case PM8XXX_VERSION_8922:
+		case PM8XXX_VERSION_8917:
+		case PM8XXX_VERSION_8038:
+			rc = pm8xxx_misc_masked_write(chip,
+				REG_PM8XXX_GPIO_MUX_CTRL, USB_ID_PU_EN_MASK,
+				enable << USB_ID_PU_EN_SHIFT);
+
+			if (rc)
+				pr_err("Fail: reg=%x, rc=%d\n",
+				       REG_PM8XXX_GPIO_MUX_CTRL, rc);
+			break;
+		default:
+			/* Functionality not supported */
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_usb_id_pullup);
+
 static int __pm8901_preload_dVdd(struct pm8xxx_misc_chip *chip)
 {
 	int rc;
diff --git a/drivers/mfd/pm8xxx-pwm.c b/drivers/mfd/pm8xxx-pwm.c
index b5e2092..05f02c4 100644
--- a/drivers/mfd/pm8xxx-pwm.c
+++ b/drivers/mfd/pm8xxx-pwm.c
@@ -27,8 +27,14 @@
 
 #define PM8XXX_PWM_CHANNELS		3
 
-#define PM8XXX_LPG_BANKS                8
-#define PM8XXX_LPG_PWM_CHANNELS         PM8XXX_LPG_BANKS
+/*
+ * For the lack of better term to distinguish functional
+ * differences, hereby, LPG version 0 (V0, v0) denotes
+ * PM8058/8921, and version 1 (V1, v1) denotes
+ * PM8922/8038.
+ */
+#define PM8XXX_LPG_V0_PWM_CHANNELS	8
+#define PM8XXX_LPG_V1_PWM_CHANNELS	6
 #define PM8XXX_LPG_CTL_REGS		7
 
 /* PM8XXX PWM */
@@ -149,12 +155,10 @@
 #define NSEC_32768HZ	(NSEC_PER_SEC / 32768)
 #define NSEC_19P2MHZ	(NSEC_PER_SEC / 19200000)
 
-#define CLK_PERIOD_MIN	NSEC_19P2MHZ
-#define CLK_PERIOD_MAX	NSEC_1024HZ
-
 #define NUM_LPG_PRE_DIVIDE	4
 #define NUM_PWM_PRE_DIVIDE	2
 
+#define PRE_DIVIDE_1		1	/* v1 */
 #define PRE_DIVIDE_2		2
 #define PRE_DIVIDE_3		3
 #define PRE_DIVIDE_5		5
@@ -1339,11 +1343,19 @@
 
 	if (version == PM8XXX_VERSION_8921 ||
 			version == PM8XXX_VERSION_8058 ||
-			version == PM8XXX_VERSION_8922) {
+			version == PM8XXX_VERSION_8922 ||
+			version == PM8XXX_VERSION_8038) {
 		chip->is_lpg_supported = 1;
 	}
 	if (chip->is_lpg_supported) {
-		chip->pwm_channels = PM8XXX_LPG_PWM_CHANNELS;
+		if (version == PM8XXX_VERSION_8922 ||
+				version == PM8XXX_VERSION_8038) {
+			for (i = 0; i < NUM_CLOCKS; i++)
+				pt_t[0][i] /= PRE_DIVIDE_2;
+			chip->pwm_channels = PM8XXX_LPG_V1_PWM_CHANNELS;
+		} else {
+			chip->pwm_channels = PM8XXX_LPG_V0_PWM_CHANNELS;
+		}
 		chip->pwm_total_pre_divs = NUM_LPG_PRE_DIVIDE;
 	} else {
 		chip->pwm_channels = PM8XXX_PWM_CHANNELS;
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index c40f13e..51ec91c 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -263,6 +263,7 @@
 	enum pm8921_chg_hot_thr		hot_thr;
 };
 
+static int usb_max_current;
 static int charging_disabled;
 static int thermal_mitigation;
 
@@ -575,6 +576,22 @@
 	return 0;
 }
 
+struct usb_ma_limit_entry {
+	int usb_ma;
+	u8  chg_iusb_value;
+};
+
+static struct usb_ma_limit_entry usb_ma_table[] = {
+	{100, 0},
+	{500, 1},
+	{700, 2},
+	{850, 3},
+	{900, 4},
+	{1100, 5},
+	{1300, 6},
+	{1500, 7},
+};
+
 #define PM8921_CHG_IUSB_MASK 0x1C
 #define PM8921_CHG_IUSB_MAX  7
 #define PM8921_CHG_IUSB_MIN  0
@@ -591,6 +608,26 @@
 					 temp);
 }
 
+static int pm_chg_iusbmax_get(struct pm8921_chg_chip *chip, int *mA)
+{
+	u8 temp;
+	int i, rc;
+
+	*mA = 0;
+	rc = pm8xxx_readb(chip->dev->parent, PBL_ACCESS2, &temp);
+	if (rc) {
+		pr_err("err=%d reading PBL_ACCESS2\n", rc);
+		return rc;
+	}
+	temp &= PM8921_CHG_IUSB_MASK;
+	temp = temp >> 2;
+	for (i = ARRAY_SIZE(usb_ma_table) - 1; i >= 0; i--) {
+		if (usb_ma_table[i].chg_iusb_value == temp)
+			*mA = usb_ma_table[i].usb_ma;
+	}
+	return rc;
+}
+
 #define PM8921_CHG_WD_MASK 0x1F
 static int pm_chg_disable_wd(struct pm8921_chg_chip *chip)
 {
@@ -1209,27 +1246,17 @@
 	}
 }
 
-struct usb_ma_limit_entry {
-	int usb_ma;
-	u8  chg_iusb_value;
-};
-
-static struct usb_ma_limit_entry usb_ma_table[] = {
-	{100, 0},
-	{500, 1},
-	{700, 2},
-	{850, 3},
-	{900, 4},
-	{1100, 5},
-	{1300, 6},
-	{1500, 7},
-};
-
 /* assumes vbus_lock is held */
 static void __pm8921_charger_vbus_draw(unsigned int mA)
 {
 	int i, rc;
 
+	if (usb_max_current && mA > usb_max_current) {
+		pr_warn("restricting usb current to %d instead of %d\n",
+					usb_max_current, mA);
+		mA = usb_max_current;
+	}
+
 	if (mA > 0 && mA <= 2) {
 		usb_chg_current = 0;
 		rc = pm_chg_iusbmax_set(the_chip,
@@ -2391,6 +2418,28 @@
 					param_get_uint,
 					&thermal_mitigation, 0644);
 
+static int set_usb_max_current(const char *val, struct kernel_param *kp)
+{
+	int ret, mA;
+	struct pm8921_chg_chip *chip = the_chip;
+
+	ret = param_set_int(val, kp);
+	if (ret) {
+		pr_err("error setting value %d\n", ret);
+		return ret;
+	}
+	if (chip) {
+		pr_warn("setting current max to %d\n", usb_max_current);
+		pm_chg_iusbmax_get(chip, &mA);
+		if (mA > usb_max_current)
+			pm8921_charger_vbus_draw(usb_max_current);
+		return 0;
+	}
+	return -EINVAL;
+}
+module_param_call(usb_max_current, set_usb_max_current, param_get_uint,
+					&usb_max_current, 0644);
+
 static void free_irqs(struct pm8921_chg_chip *chip)
 {
 	int i;
@@ -3200,6 +3249,7 @@
 	enable_irq_wake(chip->pmic_chg_irq[USBIN_UV_IRQ]);
 	enable_irq_wake(chip->pmic_chg_irq[BAT_TEMP_OK_IRQ]);
 	enable_irq_wake(chip->pmic_chg_irq[VBATDET_LOW_IRQ]);
+	enable_irq_wake(chip->pmic_chg_irq[FASTCHG_IRQ]);
 	/*
 	 * if both the cool_temp_dc and warm_temp_dc are invalid device doesnt
 	 * care for jeita compliance
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index ee7a2a9..c0c6c1e 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -1493,6 +1493,7 @@
 }
 
 static struct platform_driver android_platform_driver = {
+	.probe = android_probe,
 	.driver = { .name = "android_usb"},
 };
 
@@ -1527,7 +1528,7 @@
 	composite_driver.setup = android_setup;
 	composite_driver.disconnect = android_disconnect;
 
-	ret = platform_driver_probe(&android_platform_driver, android_probe);
+	ret = platform_driver_register(&android_platform_driver);
 	if (ret) {
 		pr_err("%s(): Failed to register android"
 				 "platform driver\n", __func__);
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index 10a9256..987ae65 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -525,7 +525,6 @@
 	if (rc) {
 		ERROR(dev->cdev, "can't enable %s, result %d\n",
 						dev->in->name, rc);
-		dev->in->driver_data = NULL;
 		return rc;
 	}
 	dev->out->driver_data = dev;
@@ -534,8 +533,6 @@
 		ERROR(dev->cdev, "can't enable %s, result %d\n",
 						dev->out->name, rc);
 		usb_ep_disable(dev->in);
-		dev->in->driver_data = NULL;
-		dev->out->driver_data = NULL;
 		return rc;
 	}
 	schedule_work(&dev->config_work);
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index f59b683..2049dc0 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -116,6 +116,8 @@
 	atomic_t		online;
 	atomic_t		notify_count;
 
+	struct platform_driver		pdrv;
+	u8				is_pdrv_used;
 	struct rmnet_smd_ch_info	smd_ctl;
 	struct rmnet_smd_ch_info	smd_data;
 
@@ -134,6 +136,8 @@
 	unsigned long	cpkts_to_modem;
 };
 
+static struct rmnet_smd_dev *rmnet_smd;
+
 static struct usb_interface_descriptor rmnet_smd_interface_desc = {
 	.bLength =		USB_DT_INTERFACE_SIZE,
 	.bDescriptorType =	USB_DT_INTERFACE,
@@ -856,6 +860,10 @@
 		list_add_tail(&qmi->list, &dev->qmi_resp_pool);
 	}
 
+	if (dev->is_pdrv_used) {
+		platform_driver_unregister(&dev->pdrv);
+		dev->is_pdrv_used = 0;
+	}
 }
 
 /* SMD close may sleep
@@ -894,7 +902,18 @@
 	ret = smd_open(rmnet_ctl_ch, &dev->smd_ctl.ch,
 			&dev->smd_ctl, rmnet_smd_event_notify);
 	if (ret) {
-		ERROR(cdev, "Unable to open control smd channel\n");
+		ERROR(cdev, "Unable to open control smd channel: %d\n", ret);
+		/*
+		 * Register platform driver to be notified in case SMD channels
+		 * later becomes ready to be opened.
+		 */
+		ret = platform_driver_register(&dev->pdrv);
+		if (ret)
+			ERROR(cdev, "Platform driver %s register failed %d\n",
+					dev->pdrv.driver.name, ret);
+		else
+			dev->is_pdrv_used = 1;
+
 		return;
 	}
 	wait_event(dev->smd_ctl.wait, test_bit(CH_OPENED,
@@ -916,6 +935,15 @@
 	rmnet_smd_start_rx(dev);
 }
 
+static int rmnet_smd_ch_probe(struct platform_device *pdev)
+{
+	DBG(rmnet_smd->cdev, "Probe called for device: %s\n", pdev->name);
+
+	queue_work(rmnet_smd->wq, &rmnet_smd->connect_work);
+
+	return 0;
+}
+
 /* SMD open may sleep.
  * Schedule a work to open smd channels and enable
  * endpoints if smd channels are opened successfully.
@@ -1272,6 +1300,8 @@
 	if (!dev)
 		return -ENOMEM;
 
+	rmnet_smd = dev;
+
 	dev->wq = create_singlethread_workqueue("k_rmnet_work");
 	if (!dev->wq) {
 		ret = -ENOMEM;
@@ -1299,6 +1329,10 @@
 	init_waitqueue_head(&dev->smd_ctl.wait);
 	init_waitqueue_head(&dev->smd_data.wait);
 
+	dev->pdrv.probe = rmnet_smd_ch_probe;
+	dev->pdrv.driver.name = CONFIG_RMNET_SMD_CTL_CHANNEL;
+	dev->pdrv.driver.owner = THIS_MODULE;
+
 	INIT_LIST_HEAD(&dev->qmi_req_pool);
 	INIT_LIST_HEAD(&dev->qmi_req_q);
 	INIT_LIST_HEAD(&dev->qmi_resp_pool);
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index d9a901b..de8c8ed 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -477,7 +477,6 @@
 	if (gser->notify->driver_data) {
 		DBG(cdev, "reset generic ctl ttyGS%d\n", gser->port_num);
 		usb_ep_disable(gser->notify);
-		gser->notify->driver_data = NULL;
 	}
 	gser->notify_desc = ep_choose(cdev->gadget,
 			gser->hs.notify,
@@ -520,7 +519,6 @@
 #ifdef CONFIG_MODEM_SUPPORT
 	usb_ep_fifo_flush(gser->notify);
 	usb_ep_disable(gser->notify);
-	gser->notify->driver_data = NULL;
 #endif
 	gser->online = 0;
 }
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index ca298cd..0360f56 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -2766,17 +2766,14 @@
 	if (fsg->bulk_in_enabled) {
 		usb_ep_disable(fsg->bulk_in);
 		fsg->bulk_in_enabled = 0;
-		fsg_bulk_in->driver_data = NULL;
 	}
 	if (fsg->bulk_out_enabled) {
 		usb_ep_disable(fsg->bulk_out);
 		fsg->bulk_out_enabled = 0;
-		fsg_bulk_out->driver_data = NULL;
 	}
 	if (fsg->intr_in_enabled) {
 		usb_ep_disable(fsg->intr_in);
 		fsg->intr_in_enabled = 0;
-		fsg_intr_in->driver_data = NULL;
 	}
 
 	fsg->running = 0;
diff --git a/drivers/usb/gadget/u_rmnet_ctrl_smd.c b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
index edba510..a55fc77 100644
--- a/drivers/usb/gadget/u_rmnet_ctrl_smd.c
+++ b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -59,7 +59,7 @@
 	struct grmnet		*port_usb;
 
 	spinlock_t		port_lock;
-	struct work_struct	connect_w;
+	struct delayed_work	connect_w;
 };
 
 static struct rmnet_ctrl_ports {
@@ -320,7 +320,7 @@
 static void grmnet_ctrl_smd_connect_w(struct work_struct *w)
 {
 	struct rmnet_ctrl_port *port =
-			container_of(w, struct rmnet_ctrl_port, connect_w);
+			container_of(w, struct rmnet_ctrl_port, connect_w.work);
 	struct smd_ch_info *c = &port->ctrl_ch;
 	unsigned long flags;
 	int ret;
@@ -332,8 +332,16 @@
 
 	ret = smd_open(c->name, &c->ch, port, grmnet_ctrl_smd_notify);
 	if (ret) {
-		pr_err("%s: Unable to open smd ch:%s err:%d\n",
-				__func__, c->name, ret);
+		if (ret == -EAGAIN) {
+			/* port not ready  - retry */
+			pr_debug("%s: SMD port not ready - rescheduling:%s err:%d\n",
+					__func__, c->name, ret);
+			queue_delayed_work(grmnet_ctrl_wq, &port->connect_w,
+				msecs_to_jiffies(250));
+		} else {
+			pr_err("%s: unable to open smd port:%s err:%d\n",
+					__func__, c->name, ret);
+		}
 		return;
 	}
 
@@ -370,7 +378,7 @@
 	gr->notify_modem = gsmd_ctrl_send_cbits_tomodem;
 	spin_unlock_irqrestore(&port->port_lock, flags);
 
-	queue_work(grmnet_ctrl_wq, &port->connect_w);
+	queue_delayed_work(grmnet_ctrl_wq, &port->connect_w, 0);
 
 	return 0;
 }
@@ -442,7 +450,8 @@
 			/* if usb is online, try opening smd_ch */
 			spin_lock_irqsave(&port->port_lock, flags);
 			if (port->port_usb)
-				queue_work(grmnet_ctrl_wq, &port->connect_w);
+				queue_delayed_work(grmnet_ctrl_wq,
+							&port->connect_w, 0);
 			spin_unlock_irqrestore(&port->port_lock, flags);
 
 			break;
@@ -503,7 +512,7 @@
 	port->port_num = portno;
 
 	spin_lock_init(&port->port_lock);
-	INIT_WORK(&port->connect_w, grmnet_ctrl_smd_connect_w);
+	INIT_DELAYED_WORK(&port->connect_w, grmnet_ctrl_smd_connect_w);
 
 	c = &port->ctrl_ch;
 	c->name = rmnet_ctrl_names[portno];
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 5caecfb..896f21b 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1864,7 +1864,6 @@
 					otg->state = OTG_STATE_B_PERIPHERAL;
 					break;
 				case USB_SDP_CHARGER:
-					msm_otg_notify_charger(motg, IUNIT);
 					msm_otg_start_peripheral(otg, 1);
 					otg->state = OTG_STATE_B_PERIPHERAL;
 					break;
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h
index c47b6ec..de8d490 100644
--- a/drivers/usb/serial/usb-wwan.h
+++ b/drivers/usb/serial/usb-wwan.h
@@ -31,10 +31,10 @@
 
 /* per port private data */
 
-#define N_IN_URB 4
-#define N_OUT_URB 4
-#define IN_BUFLEN 4096
-#define OUT_BUFLEN 4096
+#define N_IN_URB 5
+#define N_OUT_URB 5
+#define IN_BUFLEN 65536
+#define OUT_BUFLEN 65536
 
 struct usb_wwan_intf_private {
 	spinlock_t susp_lock;
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index fcf4b08..2a08101 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -410,6 +410,7 @@
 	tty->raw = 1;
 	tty->real_raw = 1;
 
+	set_bit(TTY_NO_WRITE_SPLIT, &tty->flags);
 	dbg("%s", __func__);
 
 	/* Start reading from the IN endpoint */
@@ -552,7 +553,7 @@
 		init_usb_anchor(&portdata->delayed);
 
 		for (j = 0; j < N_IN_URB; j++) {
-			buffer = (u8 *) __get_free_page(GFP_KERNEL);
+			buffer = kmalloc(IN_BUFLEN, GFP_KERNEL);
 			if (!buffer)
 				goto bail_out_error;
 			portdata->in_buffer[j] = buffer;
@@ -581,8 +582,7 @@
 		kfree(portdata->out_buffer[j]);
 bail_out_error:
 	for (j = 0; j < N_IN_URB; j++)
-		if (portdata->in_buffer[j])
-			free_page((unsigned long)portdata->in_buffer[j]);
+		kfree(portdata->in_buffer[j]);
 	kfree(portdata);
 	return 1;
 }
@@ -628,8 +628,7 @@
 
 		for (j = 0; j < N_IN_URB; j++) {
 			usb_free_urb(portdata->in_urbs[j]);
-			free_page((unsigned long)
-				  portdata->in_buffer[j]);
+			kfree(portdata->in_buffer[j]);
 			portdata->in_urbs[j] = NULL;
 		}
 		for (j = 0; j < N_OUT_URB; j++) {
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 1449c8e..512480c 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1326,10 +1326,9 @@
 	struct msm_fb_panel_data *pdata = NULL;
 	int rc;
 	resource_size_t  size ;
+	unsigned long flag;
 #ifdef CONFIG_FB_MSM_MDP40
 	int intf, if_no;
-#else
-	unsigned long flag;
 #endif
 #if defined(CONFIG_FB_MSM_MIPI_DSI) && defined(CONFIG_FB_MSM_MDP40)
 	struct mipi_panel_info *mipi;
@@ -1474,6 +1473,17 @@
 			mfd->vsync_gpio = -1;
 
 #ifdef CONFIG_FB_MSM_MDP40
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		mdp_intr_mask |= INTR_OVERLAY0_DONE;
+		if (mdp_hw_revision < MDP4_REVISION_V2_1) {
+			/* dmas dmap switch */
+			mdp_intr_mask |= INTR_DMA_S_DONE;
+		}
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
 		if (mfd->panel.type == EBI2_PANEL)
 			intf = EBI2_INTF;
 		else
@@ -1530,10 +1540,8 @@
 	case MIPI_CMD_PANEL:
 #ifndef CONFIG_FB_MSM_MDP303
 		mfd->dma_fnc = mdp4_dsi_cmd_overlay;
-#ifdef CONFIG_FB_MSM_MDP40
 		mipi = &mfd->panel_info.mipi;
 		configure_mdp_core_clk_table((mipi->dsi_pclk_rate) * 3 / 2);
-#endif
 		if (mfd->panel_info.pdest == DISPLAY_1) {
 			if_no = PRIMARY_INTF_SEL;
 			mfd->dma = &dma2_data;
@@ -1544,6 +1552,13 @@
 		mfd->lut_update = mdp_lut_update_nonlcdc;
 		mfd->do_histogram = mdp_do_histogram;
 		mdp4_display_intf_sel(if_no, DSI_CMD_INTF);
+
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		mdp_intr_mask |= INTR_OVERLAY0_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 #else
 		mfd->dma_fnc = mdp_dma2_update;
 		mfd->do_histogram = mdp_do_histogram;
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index db1580e..3862823 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -130,8 +130,7 @@
 #define INTR_OVERLAY2_DONE		BIT(30)
 
 #ifdef CONFIG_FB_MSM_OVERLAY
-#define MDP4_ANY_INTR_MASK	(INTR_OVERLAY0_DONE|INTR_DMA_S_DONE | \
-					INTR_DMA_P_HISTOGRAM)
+#define MDP4_ANY_INTR_MASK	(INTR_DMA_P_HISTOGRAM)
 #else
 #define MDP4_ANY_INTR_MASK	(INTR_DMA_P_DONE| \
 				INTR_DMA_P_HISTOGRAM)
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index a262cc4..3a1a9aa 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -455,7 +455,7 @@
 	if (!(data & 0x1) || (pipe == NULL))
 		return;
 	wait_for_completion_timeout(&dtv_pipe->comp,
-		msecs_to_jiffies(VSYNC_PERIOD));
+			msecs_to_jiffies(VSYNC_PERIOD*2));
 	mdp_disable_irq(MDP_OVERLAY1_TERM);
 }
 
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 d2969b6..51a72c8 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1457,6 +1457,7 @@
 			vcd_status = VCD_S_SUCCESS;
 		}
 	}
+	break;
 	case VCD_I_INTRA_REFRESH:
 	{
 		struct vcd_property_intra_refresh_mb_number
diff --git a/include/linux/genlock.h b/include/linux/genlock.h
index 2e9f9d6..9351a15 100644
--- a/include/linux/genlock.h
+++ b/include/linux/genlock.h
@@ -12,7 +12,7 @@
 struct genlock *genlock_create_lock(struct genlock_handle *);
 struct genlock *genlock_attach_lock(struct genlock_handle *, int fd);
 int genlock_wait(struct genlock_handle *handle, u32 timeout);
-void genlock_release_lock(struct genlock_handle *);
+/* genlock_release_lock was deprecated */
 int genlock_lock(struct genlock_handle *handle, int op, int flags,
 	u32 timeout);
 #endif
@@ -39,6 +39,8 @@
 	struct genlock_lock)
 #define GENLOCK_IOC_LOCK _IOW(GENLOCK_IOC_MAGIC, 3, \
 	struct genlock_lock)
+
+/* Deprecated */
 #define GENLOCK_IOC_RELEASE _IO(GENLOCK_IOC_MAGIC, 4)
 #define GENLOCK_IOC_WAIT _IOW(GENLOCK_IOC_MAGIC, 5, \
 	struct genlock_lock)
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index 7ae8342..500ee6b 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -46,6 +46,8 @@
 
 	unsigned int x_size;
 	unsigned int y_size;
+	unsigned int touch_x_size;
+	unsigned int touch_y_size;
 	unsigned long irqflags;
 	bool	i2c_pull_up;
 	bool	digital_pwr_regulator;
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index f9fc498..c4f601b 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -172,6 +172,15 @@
  */
 int pm8xxx_preload_dVdd(void);
 
+/**
+ * pm8xxx_usb_id_pullup - Control a pullup for USB ID
+ *
+ * @enable: enable (1) or disable (0) the pullup
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_usb_id_pullup(int enable);
+
 #else
 
 static inline int pm8xxx_reset_pwr_off(int reset)
@@ -212,6 +221,10 @@
 {
 	return -ENODEV;
 }
+static inline int pm8xxx_usb_id_pullup(int enable)
+{
+	return -ENODEV;
+}
 #endif
 
 #endif
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 4918caa..0a3b91d 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -1158,6 +1158,7 @@
 		if (skb->len < sizeof(*grsp))
 			goto cpl_finished;
 		grsp = (struct a2mp_getinfo_rsp *) skb_pull(skb, sizeof(*hdr));
+		skb_pull(skb, sizeof(*grsp));
 		if (grsp->status)
 			goto cpl_finished;
 		if (grsp->id != ctx->d.cpl.remote_id)
@@ -1171,7 +1172,6 @@
 		ctrl->min_latency = le32_to_cpu(grsp->min_latency);
 		ctrl->pal_cap = le16_to_cpu(grsp->pal_cap);
 		ctrl->max_assoc_size = le16_to_cpu(grsp->assoc_size);
-		skb_pull(skb, sizeof(*grsp));
 
 		ctx->d.cpl.max_len = ctrl->max_assoc_size;
 
@@ -1191,8 +1191,6 @@
 			goto cpl_finished;
 		hdr = (void *) skb->data;
 		arsp = (void *) skb_pull(skb, sizeof(*hdr));
-		if (arsp->id != ctx->d.cpl.remote_id)
-			goto cpl_finished;
 		if (arsp->status != 0)
 			goto cpl_finished;
 
@@ -1200,12 +1198,12 @@
 		assoc = (u8 *) skb_pull(skb, sizeof(*arsp));
 		ctx->d.cpl.len_so_far = 0;
 		ctx->d.cpl.rem_len = hdr->len - sizeof(*arsp);
+		skb_pull(skb, ctx->d.cpl.rem_len);
 		rassoc = kmalloc(ctx->d.cpl.rem_len, GFP_ATOMIC);
 		if (!rassoc)
 			goto cpl_finished;
 		memcpy(rassoc, assoc, ctx->d.cpl.rem_len);
 		ctx->d.cpl.remote_assoc = rassoc;
-		skb_pull(skb, ctx->d.cpl.rem_len);
 
 		/* set up CPL command */
 		ctx->d.cpl.phy_handle = physlink_handle(ctx->hdev);
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 92d72b7..0719874 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -523,6 +523,7 @@
 	struct sock *sk = sock->sk;
 	struct hci_dev *hdev;
 	struct sk_buff *skb;
+	int reserve = 0;
 	int err;
 
 	BT_DBG("sock %p sk %p", sock, sk);
@@ -560,10 +561,18 @@
 		goto done;
 	}
 
-	skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
+	/* Allocate extra headroom for Qualcomm PAL */
+	if (hdev->dev_type == HCI_AMP && hdev->manufacturer == 0x001d)
+		reserve = BT_SKB_RESERVE_80211;
+
+	skb = bt_skb_send_alloc(sk, len + reserve,
+					msg->msg_flags & MSG_DONTWAIT, &err);
 	if (!skb)
 		goto done;
 
+	if (reserve)
+		skb_reserve(skb, reserve);
+
 	if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
 		err = -EFAULT;
 		goto drop;
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 96260ab..27a27ec 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -420,6 +420,7 @@
 	switch (dai->id) {
 	case PRIMARY_I2S_TX:
 	case PRIMARY_I2S_RX:
+	case SECONDARY_I2S_RX:
 		rc = msm_dai_q6_cdc_hw_params(params, dai, substream->stream);
 		break;
 	case MI2S_RX:
@@ -820,6 +821,7 @@
 	case PRIMARY_I2S_TX:
 	case PRIMARY_I2S_RX:
 	case MI2S_RX:
+	case SECONDARY_I2S_RX:
 		rc = msm_dai_q6_cdc_set_fmt(dai, fmt);
 		break;
 	default:
@@ -1086,6 +1088,7 @@
 
 	switch (pdev->id) {
 	case PRIMARY_I2S_RX:
+	case SECONDARY_I2S_RX:
 		rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_i2s_rx_dai);
 		break;
 	case PRIMARY_I2S_TX:
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 1331ebf..94ed504 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -118,6 +118,7 @@
 	{ VOICE_RECORD_RX, 0, NULL, 0, 0},
 	{ VOICE_RECORD_TX, 0, NULL, 0, 0},
 	{ MI2S_RX, 0, NULL, 0, 0},
+	{ SECONDARY_I2S_RX, 0, NULL, 0, 0},
 };
 
 
@@ -668,6 +669,21 @@
 	msm_routing_put_audio_mixer),
 };
 
+static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = {
+	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_I2S_RX ,
+	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+};
+
 static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
 	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
 	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -824,6 +840,15 @@
 	msm_routing_put_voice_mixer),
 };
 
+static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = {
+	SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
+};
+
 static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
 	SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
 	MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
@@ -1134,6 +1159,8 @@
 	/* Stream name equals to backend dai link stream name
 	 */
 	SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback",
+				0, 0, 0 , 0),
 	SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
 	SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0),
@@ -1166,6 +1193,8 @@
 	/* Mixer definitions */
 	SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 	pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
+	SND_SOC_DAPM_MIXER("SEC_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+	sec_i2s_rx_mixer_controls, ARRAY_SIZE(sec_i2s_rx_mixer_controls)),
 	SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 	slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
 	SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
@@ -1186,6 +1215,10 @@
 	SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer",
 				SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls,
 				ARRAY_SIZE(pri_rx_voice_mixer_controls)),
+	SND_SOC_DAPM_MIXER("SEC_RX_Voice Mixer",
+				SND_SOC_NOPM, 0, 0,
+				sec_i2s_rx_voice_mixer_controls,
+				ARRAY_SIZE(sec_i2s_rx_voice_mixer_controls)),
 	SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer",
 				SND_SOC_NOPM, 0, 0,
 				slimbus_rx_voice_mixer_controls,
@@ -1230,6 +1263,12 @@
 	{"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
 	{"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
 
+	{"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+	{"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+	{"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"},
+
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -1295,6 +1334,10 @@
 	{"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
 
+	{"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+	{"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"},
+
 	{"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index a8d2d91..25efb58 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,7 @@
 #define LPASS_BE_VOICE_PLAYBACK_TX "(Backend) VOICE_PLAYBACK_TX"
 #define LPASS_BE_INCALL_RECORD_RX "(Backend) INCALL_RECORD_TX"
 #define LPASS_BE_INCALL_RECORD_TX "(Backend) INCALL_RECORD_RX"
+#define LPASS_BE_SEC_I2S_RX "(Backend) SECONDARY_I2S_RX"
 
 #define LPASS_BE_MI2S_RX "(Backend) MI2S_RX"
 
@@ -71,6 +72,7 @@
 	MSM_BACKEND_DAI_INCALL_RECORD_RX,
 	MSM_BACKEND_DAI_INCALL_RECORD_TX,
 	MSM_BACKEND_DAI_MI2S_RX,
+	MSM_BACKEND_DAI_SEC_I2S_RX,
 	MSM_BACKEND_DAI_MAX,
 };