Merge "msm: platsmp-8625: refactor code for core_reset_base"
diff --git a/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt b/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt
index 21d376a..adb93b8 100644
--- a/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt
+++ b/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt
@@ -11,18 +11,24 @@
 - compatible:	Must be "qcom,qpnp-power-on"
 - reg:		Specifies the SPMI address and size for this PON (power-on) peripheral
 - interrupts:	Specifies the interrupt associated with PON.
+- interrupt-names:	Specify the interrupt names associated with interrupts. Must be
+			one of "kpdpwr", "kpdpwr-bark", "resin", "resin-bark", "cblpwr".
+			Bark interrupts are associated with system reset configuration
+			to allow default reset configuration to be activated. If system
+			reset configuration is not supported then bark interrupts are
+			nops.
 
 Optional properties:
-- qcom,pon-dbc-delay		The debouce delay for the power-key interrupt
-				specifed in us. The value ranges from 2 seconds
+- qcom,pon-dbc-delay		The debounce delay for the power-key interrupt
+				specified in us. The value ranges from 2 seconds
 				to 1/64 of a second. Possible values are -
 				- 2, 1, 1/2, 1/4, 1/8, 1/16, 1/32, 1/64
 				- Intermediate value is rounded down to the
 				nearest valid value.
 - qcom,pon_1 ...pon_n		These represent the child nodes which describe
 				the properties (reset, key) for each of the pon
-				reset source. All the child nodes are optional,
-				if none of them are specified the driver fails
+				reset source. All the child nodes are optional.
+				If none of them is specified, the driver fails
 				to register.
 - qcom,system-reset		Specifies that this PON peripheral can be used
 				to reset the system. This property can only be
@@ -32,32 +38,32 @@
 All the below properties are in the sub-node section (properties of the child
 node).
 
+Sub-node required properties:
+- qcom,pon-type			The type of PON/RESET source. The driver
+				currently supports KPDPWR(0), RESIN(1) and
+				CBLPWR(2) pon/reset sources.
+
+Sub-node optional properties:
 - qcom,pull-up			The initial state of the reset pin under
 				consideration.
 				0 = No pull-up
 				1 = pull-up enabled
-				This property is optional and is set to '0'
-				if not specified.
-- qcom,pon-type			The type of PON/RESET source. The driver
-				currently supports KPDPWR(0) and RESIN(1)
-				pon/reset sources. This property must be
-				specified.
+				This property is set to '0' if not specified.
 - qcom,support-reset		Indicates if this PON source supports
 				reset functionality.
 				0 = Not supported
 				1 = Supported
-				This property is optional and is set to '0'
-				if not specified.
-- qcom,s1-timer			The debouce timer for the BARK interrupt for
+				This property is set to '0' if not specified.
+- qcom,s1-timer			The debounce timer for the BARK interrupt for
 				that reset source. Value is specified in ms.
 				Supported values are -
 				- 0, 32, 56, 80, 128, 184, 272, 408, 608, 904
 				  1352, 2048, 3072, 4480, 6720, 10256
 				This property must be specified only if
 				'support-reset' is set to 1.
-- qcom,s2-timer			The debouce timer for the S2 reset specified
+- qcom,s2-timer			The debounce timer for the S2 reset specified
 				in ms. On the expiry of this timer, the PMIC
-				executes the reset sequence. Supoprted values -
+				executes the reset sequence. Supported values -
 				- 0, 10, 50, 100, 250, 500, 1000, 2000
 				This property is required only if
 				'support-reset' is set to 1.
@@ -68,7 +74,7 @@
 				'support-reset' is set to 1.
 - linux,code			The input key-code associated with the reset source.
 				The reset source in its default configuration can be
-				used to support standard keys. This property is optional.
+				used to support standard keys.
 
 Example:
 	qcom,power-on@800 {
diff --git a/arch/arm/boot/dts/msm-pm8019.dtsi b/arch/arm/boot/dts/msm-pm8019.dtsi
index 3b06450..e70eb36 100755
--- a/arch/arm/boot/dts/msm-pm8019.dtsi
+++ b/arch/arm/boot/dts/msm-pm8019.dtsi
@@ -22,6 +22,21 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 
+		qcom,power_on@800 {
+			compatible = "qcom,qpnp-power-on";
+			reg = <0x800 0x100>;
+			interrupts = <0x0 0x8 0x2>;
+			interrupt-names = "cblpwr";
+			qcom,pon-dbc-delay = <15625>;
+			qcom,system-reset;
+
+			qcom,pon_1 {
+				qcom,pon-type = <2>;
+				qcom,pull-up = <1>;
+				linux,code = <116>;
+			};
+		};
+
 		clkdiv@5b00 {
 			reg = <0x5b00 0x100>;
 			compatible = "qcom,qpnp-clkdiv";
diff --git a/arch/arm/boot/dts/msm8974-ion.dtsi b/arch/arm/boot/dts/msm8974-ion.dtsi
index 1893ae4..9b5aaac 100644
--- a/arch/arm/boot/dts/msm8974-ion.dtsi
+++ b/arch/arm/boot/dts/msm8974-ion.dtsi
@@ -70,7 +70,7 @@
 			reg = <28>;
 			qcom,heap-align = <0x1000>;
 			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
-			qcom,memory-reservation-size = <0x2B4000>;
+			qcom,memory-reservation-size = <0x314000>;
 		};
 	};
 };
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 364a1bf..284f5fc 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -113,6 +113,7 @@
 CONFIG_USB_BAM=y
 CONFIG_SPS_SUPPORT_BAMDMA=y
 CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_QPNP_POWER_ON=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_YAFFS_FS=y
diff --git a/arch/arm/mach-msm/rpm-regulator-smd.c b/arch/arm/mach-msm/rpm-regulator-smd.c
index 9c621c4..d1c61fe 100644
--- a/arch/arm/mach-msm/rpm-regulator-smd.c
+++ b/arch/arm/mach-msm/rpm-regulator-smd.c
@@ -112,7 +112,7 @@
 	PARAM(HEAD_ROOM,       1,  0,  0,  1, "hr",   0, 0x7FFFFFFF, "qcom,init-head-room"),
 	PARAM(QUIET_MODE,      0,  1,  0,  0, "qm",   0, 2,          "qcom,init-quiet-mode"),
 	PARAM(FREQ_REASON,     0,  1,  0,  1, "resn", 0, 8,          "qcom,init-freq-reason"),
-	PARAM(CORNER,          0,  1,  0,  0, "corn", 0, 6,          "qcom,init-voltage-corner"),
+	PARAM(CORNER,          1,  1,  0,  0, "corn", 0, 6,          "qcom,init-voltage-corner"),
 	PARAM(BYPASS,          1,  0,  0,  0, "bypa", 0, 1,          "qcom,init-disallow-bypass"),
 };
 
@@ -1037,6 +1037,19 @@
 	.enable_time		= rpm_vreg_enable_time,
 };
 
+static struct regulator_ops ldo_corner_ops = {
+	.enable			= rpm_vreg_enable,
+	.disable		= rpm_vreg_disable,
+	.is_enabled		= rpm_vreg_is_enabled,
+	.set_voltage		= rpm_vreg_set_voltage_corner,
+	.get_voltage		= rpm_vreg_get_voltage_corner,
+	.list_voltage		= rpm_vreg_list_voltage,
+	.set_mode		= rpm_vreg_set_mode,
+	.get_mode		= rpm_vreg_get_mode,
+	.get_optimum_mode	= rpm_vreg_get_optimum_mode,
+	.enable_time		= rpm_vreg_enable_time,
+};
+
 static struct regulator_ops smps_ops = {
 	.enable			= rpm_vreg_enable,
 	.disable		= rpm_vreg_disable,
@@ -1194,11 +1207,14 @@
 
 	/*
 	 * Switch to voltage corner regulator ops if qcom,use-voltage-corner
-	 * is specified in the device node (SMPS only).
+	 * is specified in the device node (SMPS and LDO only).
 	 */
-	if (of_find_property(node, "qcom,use-voltage-corner", NULL)
-	    && regulator_type == RPM_REGULATOR_SMD_TYPE_SMPS)
-		reg->rdesc.ops = &smps_corner_ops;
+	if (of_property_read_bool(node, "qcom,use-voltage-corner")) {
+		if (regulator_type == RPM_REGULATOR_SMD_TYPE_SMPS)
+			reg->rdesc.ops = &smps_corner_ops;
+		else if (regulator_type == RPM_REGULATOR_SMD_TYPE_LDO)
+			reg->rdesc.ops = &ldo_corner_ops;
+	}
 
 	if (regulator_type == RPM_REGULATOR_SMD_TYPE_VS)
 		reg->rdesc.n_voltages = 0;
diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c
index 775e95d..abd66f4 100644
--- a/drivers/input/misc/pmic8xxx-pwrkey.c
+++ b/drivers/input/misc/pmic8xxx-pwrkey.c
@@ -104,14 +104,75 @@
 static SIMPLE_DEV_PM_OPS(pm8xxx_pwr_key_pm_ops,
 		pmic8xxx_pwrkey_suspend, pmic8xxx_pwrkey_resume);
 
+static int pmic8xxx_set_pon1(struct device *dev, u32 debounce_us, bool pull_up)
+{
+	int err;
+	u32 delay;
+	u8 pon_cntl;
+
+	/* Valid range of pwr key trigger delay is 1/64 sec to 2 seconds. */
+	if (debounce_us > USEC_PER_SEC * 2 ||
+		debounce_us < USEC_PER_SEC / 64) {
+		dev_err(dev, "invalid power key trigger delay\n");
+		return -EINVAL;
+	}
+
+	delay = (debounce_us << 6) / USEC_PER_SEC;
+	delay = ilog2(delay);
+
+	err = pm8xxx_readb(dev->parent, PON_CNTL_1, &pon_cntl);
+	if (err < 0) {
+		dev_err(dev, "failed reading PON_CNTL_1 err=%d\n", err);
+		return err;
+	}
+
+	pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK;
+	pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK);
+
+	if (pull_up)
+		pon_cntl |= PON_CNTL_PULL_UP;
+	else
+		pon_cntl &= ~PON_CNTL_PULL_UP;
+
+	err = pm8xxx_writeb(dev->parent, PON_CNTL_1, pon_cntl);
+	if (err < 0) {
+		dev_err(dev, "failed writing PON_CNTL_1 err=%d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static ssize_t pmic8xxx_debounce_store(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t size)
+{
+	struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev);
+	int err;
+	unsigned long val;
+
+	if (size > 8)
+		return -EINVAL;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err < 0)
+		return err;
+
+	err = pmic8xxx_set_pon1(dev, val, pwrkey->pdata->pull_up);
+	if (err < 0)
+		return err;
+
+	return size;
+}
+
+static DEVICE_ATTR(debounce_us, 0664, NULL, pmic8xxx_debounce_store);
+
 static int __devinit pmic8xxx_pwrkey_probe(struct platform_device *pdev)
 {
 	struct input_dev *pwr;
 	int key_release_irq = platform_get_irq(pdev, 0);
 	int key_press_irq = platform_get_irq(pdev, 1);
 	int err;
-	unsigned int delay;
-	u8 pon_cntl;
 	struct pmic8xxx_pwrkey *pwrkey;
 	const struct pm8xxx_pwrkey_platform_data *pdata =
 					dev_get_platdata(&pdev->dev);
@@ -121,13 +182,6 @@
 		return -EINVAL;
 	}
 
-	/* Valid range of pwr key trigger delay is 1/64 sec to 2 seconds. */
-	if (pdata->kpd_trigger_delay_us > USEC_PER_SEC * 2 ||
-		pdata->kpd_trigger_delay_us < USEC_PER_SEC / 64) {
-		dev_err(&pdev->dev, "invalid power key trigger delay\n");
-		return -EINVAL;
-	}
-
 	pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL);
 	if (!pwrkey)
 		return -ENOMEM;
@@ -147,25 +201,10 @@
 	pwr->phys = "pmic8xxx_pwrkey/input0";
 	pwr->dev.parent = &pdev->dev;
 
-	delay = (pdata->kpd_trigger_delay_us << 6) / USEC_PER_SEC;
-	delay = ilog2(delay);
-
-	err = pm8xxx_readb(pdev->dev.parent, PON_CNTL_1, &pon_cntl);
-	if (err < 0) {
-		dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err);
-		goto free_input_dev;
-	}
-
-	pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK;
-	pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK);
-	if (pdata->pull_up)
-		pon_cntl |= PON_CNTL_PULL_UP;
-	else
-		pon_cntl &= ~PON_CNTL_PULL_UP;
-
-	err = pm8xxx_writeb(pdev->dev.parent, PON_CNTL_1, pon_cntl);
-	if (err < 0) {
-		dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err);
+	err = pmic8xxx_set_pon1(&pdev->dev,
+			pdata->kpd_trigger_delay_us, pdata->pull_up);
+	if (err) {
+		dev_dbg(&pdev->dev, "Can't set PON CTRL1 register: %d\n", err);
 		goto free_input_dev;
 	}
 
@@ -211,12 +250,22 @@
 		goto free_press_irq;
 	}
 
+	err = device_create_file(&pdev->dev, &dev_attr_debounce_us);
+	if (err < 0) {
+		dev_err(&pdev->dev,
+				"dev file creation for debounce failed: %d\n",
+				err);
+		goto free_rel_irq;
+	}
+
 	device_init_wakeup(&pdev->dev, pdata->wakeup);
 
 	return 0;
 
+free_rel_irq:
+	free_irq(key_release_irq, pwrkey);
 free_press_irq:
-	free_irq(key_press_irq, NULL);
+	free_irq(key_press_irq, pwrkey);
 unreg_input_dev:
 	platform_set_drvdata(pdev, NULL);
 	input_unregister_device(pwr);
@@ -236,6 +285,7 @@
 
 	device_init_wakeup(&pdev->dev, 0);
 
+	device_remove_file(&pdev->dev, &dev_attr_debounce_us);
 	free_irq(key_press_irq, pwrkey);
 	free_irq(key_release_irq, pwrkey);
 	input_unregister_device(pwrkey->pwr);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 595bc5d..357d290 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -5824,6 +5824,7 @@
 		mmc->caps |= (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 |
 				MMC_CAP_SET_XPC_180);
 
+	mmc->caps2 |= MMC_CAP2_PACKED_WR;
 	mmc->caps2 |= (MMC_CAP2_BOOTPART_NOACC | MMC_CAP2_DETECT_ON_ERR);
 	mmc->caps2 |= MMC_CAP2_SANITIZE;
 	mmc->caps2 |= MMC_CAP2_CACHE_CTRL;
diff --git a/drivers/platform/msm/qpnp-power-on.c b/drivers/platform/msm/qpnp-power-on.c
index 33b12ae..76a758b 100644
--- a/drivers/platform/msm/qpnp-power-on.c
+++ b/drivers/platform/msm/qpnp-power-on.c
@@ -39,8 +39,10 @@
 
 #define QPNP_PON_RESIN_PULL_UP		BIT(0)
 #define QPNP_PON_KPDPWR_PULL_UP		BIT(1)
+#define QPNP_PON_CBLPWR_PULL_UP		BIT(2)
 #define QPNP_PON_S2_CNTL_EN		BIT(7)
 #define QPNP_PON_S2_RESET_ENABLE	BIT(7)
+#define QPNP_PON_DELAY_BIT_SHIFT	6
 
 #define QPNP_PON_S1_TIMER_MASK		(0xF)
 #define QPNP_PON_S2_TIMER_MASK		(0x7)
@@ -49,6 +51,7 @@
 #define QPNP_PON_DBC_DELAY_MASK		(0x7)
 #define QPNP_PON_KPDPWR_N_SET		BIT(0)
 #define QPNP_PON_RESIN_N_SET		BIT(1)
+#define QPNP_PON_CBLPWR_N_SET		BIT(2)
 #define QPNP_PON_RESIN_BARK_N_SET	BIT(4)
 
 #define QPNP_PON_RESET_EN		BIT(7)
@@ -66,6 +69,7 @@
 enum pon_type {
 	PON_KPDPWR,
 	PON_RESIN,
+	PON_CBLPWR,
 };
 
 struct qpnp_pon_config {
@@ -214,6 +218,9 @@
 	case PON_RESIN:
 		pon_rt_bit = QPNP_PON_RESIN_N_SET;
 		break;
+	case PON_CBLPWR:
+		pon_rt_bit = QPNP_PON_CBLPWR_N_SET;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -253,6 +260,18 @@
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t qpnp_cblpwr_irq(int irq, void *_pon)
+{
+	int rc;
+	struct qpnp_pon *pon = _pon;
+
+	rc = qpnp_pon_input_dispatch(pon, PON_CBLPWR);
+	if (rc)
+		dev_err(&pon->spmi->dev, "Unable to send input event\n");
+
+	return IRQ_HANDLED;
+}
+
 static void bark_work_func(struct work_struct *work)
 {
 	int rc;
@@ -351,6 +370,9 @@
 	case PON_RESIN:
 		pull_bit = QPNP_PON_RESIN_PULL_UP;
 		break;
+	case PON_CBLPWR:
+		pull_bit = QPNP_PON_CBLPWR_PULL_UP;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -489,6 +511,17 @@
 			}
 		}
 		break;
+	case PON_CBLPWR:
+		rc = devm_request_irq(&pon->spmi->dev, cfg->state_irq,
+							qpnp_cblpwr_irq,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+					"qpnp_cblpwr_status", pon);
+		if (rc < 0) {
+			dev_err(&pon->spmi->dev, "Can't request %d IRQ\n",
+							cfg->state_irq);
+			return rc;
+		}
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -595,6 +628,15 @@
 				}
 			}
 			break;
+		case PON_CBLPWR:
+			cfg->state_irq = spmi_get_irq_byname(pon->spmi,
+							NULL, "cblpwr");
+			if (cfg->state_irq < 0) {
+				dev_err(&pon->spmi->dev,
+						"Unable to get cblpwr irq\n");
+				return rc;
+			}
+			break;
 		default:
 			dev_err(&pon->spmi->dev, "PON RESET %d not supported",
 								cfg->pon_type);
@@ -763,11 +805,13 @@
 
 	rc = of_property_read_u32(pon->spmi->dev.of_node,
 				"qcom,pon-dbc-delay", &delay);
-	if (rc && rc != -EINVAL) {
-		dev_err(&spmi->dev, "Unable to read debounce delay\n");
-		return rc;
+	if (rc) {
+		if (rc != -EINVAL) {
+			dev_err(&spmi->dev, "Unable to read debounce delay\n");
+			return rc;
+		}
 	} else {
-		delay = (delay << 6) / USEC_PER_SEC;
+		delay = (delay << QPNP_PON_DELAY_BIT_SHIFT) / USEC_PER_SEC;
 		delay = ilog2(delay);
 		rc = qpnp_pon_masked_write(pon, QPNP_PON_DBC_CTL(pon->base),
 						QPNP_PON_DBC_DELAY_MASK, delay);
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 45dfb87..f092329 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -50,7 +50,7 @@
 
 #define BAM_MUX_RX_Q_SIZE			16
 #define BAM_MUX_TX_Q_SIZE			200
-#define BAM_MUX_RX_REQ_SIZE			(2048 - BAM_MUX_HDR)
+#define BAM_MUX_RX_REQ_SIZE			2048   /* Must be 1KB aligned */
 
 #define DL_INTR_THRESHOLD			20
 
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index c7e811f..8499e3e 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1959,7 +1959,7 @@
 	struct mdp4_overlay_pipe *d_pipe;
 	struct mdp4_overlay_pipe *s_pipe;
 	struct blend_cfg *blend;
-	int i, off, ptype, alpha_drop = 0;
+	int i, off, alpha_drop = 0;
 	int d_alpha, s_alpha;
 	unsigned char *overlay_base;
 	uint32 c0, c1, c2, base_premulti;
@@ -2026,25 +2026,17 @@
 			} else
 				blend->op = MDP4_BLEND_BG_ALPHA_FG_CONST;
 		} else if (d_alpha) {
-			ptype = mdp4_overlay_format2type(s_pipe->src_format);
-			if (ptype == OVERLAY_TYPE_VIDEO) {
-				blend->op = (MDP4_BLEND_FG_ALPHA_BG_PIXEL |
-					MDP4_BLEND_FG_INV_ALPHA);
-				if ((!(s_pipe->flags & MDP_BLEND_FG_PREMULT)) &&
-						((i != MDP4_MIXER_STAGE0) ||
-							(!base_premulti)))
-					blend->op |=
-						MDP4_BLEND_BG_ALPHA_BG_PIXEL;
-				else
-					blend->fg_alpha = 0xff;
+			blend->op = (MDP4_BLEND_FG_ALPHA_BG_PIXEL |
+				MDP4_BLEND_FG_INV_ALPHA);
+			if ((!(d_pipe->flags & MDP_BLEND_FG_PREMULT)) &&
+					((i != MDP4_MIXER_STAGE0) ||
+						(!base_premulti)))
+				blend->op |=
+					MDP4_BLEND_BG_ALPHA_BG_PIXEL;
+			else
+				blend->fg_alpha = 0xff;
 
-				blend->co3_sel = 0; /* use bg alpha */
-			} else {
-				/* s_pipe is rgb without alpha */
-				blend->op = (MDP4_BLEND_FG_ALPHA_FG_CONST |
-					    MDP4_BLEND_BG_ALPHA_BG_CONST);
-				blend->bg_alpha = 0;
-			}
+			blend->co3_sel = 0; /* use bg alpha */
 		}
 
 		if (s_pipe->transp != MDP_TRANSP_NOP) {
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index d0c5baf..4eec66e 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -295,7 +295,9 @@
 static int
 cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp)
 {
-	return *rdp->nxttail[RCU_DONE_TAIL] && !rcu_gp_in_progress(rsp);
+	return *rdp->nxttail[RCU_DONE_TAIL +
+			     ACCESS_ONCE(rsp->completed) != rdp->completed] &&
+	       !rcu_gp_in_progress(rsp);
 }
 
 /*
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index b921df1..7894368 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -1353,6 +1353,8 @@
 	pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
 			channels->min, channels->max);
 
+	if (channels->max < 2)
+		channels->min = channels->max = 2;
 	rate->min = rate->max = 48000;
 
 	return 0;
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index 3cb7c58..011b798 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -1374,20 +1374,6 @@
 		.codec_dai_name = "snd-soc-dummy-dai",
 		.codec_name = "snd-soc-dummy",
 	},
-	{
-		.name = "AUXPCM Hostless",
-		.stream_name = "AUXPCM Hostless",
-		.cpu_dai_name	= "AUXPCM_HOSTLESS",
-		.platform_name	= "msm-pcm-hostless",
-		.dynamic = 1,
-		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
-				SND_SOC_DPCM_TRIGGER_POST},
-		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
-		.ignore_suspend = 1,
-		.ignore_pmdown_time = 1, /* dainlink has playback support */
-		.codec_dai_name = "snd-soc-dummy-dai",
-		.codec_name = "snd-soc-dummy",
-	},
 	/* Secondary I2S RX Hostless */
 	{
 		.name = "SEC_I2S_RX Hostless",
@@ -1459,6 +1445,20 @@
 		.ignore_pmdown_time = 1, /* this dailink has playback support */
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
 	},
+	{
+		.name = "AUXPCM Hostless",
+		.stream_name = "AUXPCM Hostless",
+		.cpu_dai_name	= "AUXPCM_HOSTLESS",
+		.platform_name	= "msm-pcm-hostless",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+				SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1, /* dainlink has playback support */
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
 	/* Backend DAI Links */
 	{
 		.name = LPASS_BE_SLIMBUS_0_RX,
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 59d118e..6ec44bf 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -1018,6 +1018,8 @@
 	pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
 			channels->min, channels->max);
 
+	if (channels->max < 2)
+		channels->min = channels->max = 2;
 	rate->min = rate->max = 48000;
 
 	return 0;