Merge "ARM: dts: msm: Remove BHS from modem configuration for msm8926"
diff --git a/arch/arm/configs/apq8084_defconfig b/arch/arm/configs/apq8084_defconfig
index 33e1923..9cd37d1 100644
--- a/arch/arm/configs/apq8084_defconfig
+++ b/arch/arm/configs/apq8084_defconfig
@@ -86,6 +86,7 @@
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
+CONFIG_COMPACTION=y
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_CP_ACCESS=y
 CONFIG_USE_OF=y
diff --git a/arch/arm/configs/msm8226-perf_defconfig b/arch/arm/configs/msm8226-perf_defconfig
index a9fc578..4f0872a 100644
--- a/arch/arm/configs/msm8226-perf_defconfig
+++ b/arch/arm/configs/msm8226-perf_defconfig
@@ -78,6 +78,7 @@
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
+CONFIG_COMPACTION=y
 CONFIG_USE_OF=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
index 8d06c59..3705a55 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -78,6 +78,7 @@
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
+CONFIG_COMPACTION=y
 CONFIG_USE_OF=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index 9d104fd..9869fbf 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -81,6 +81,7 @@
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
+CONFIG_COMPACTION=y
 CONFIG_USE_OF=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index 0587e50..24c5d9c 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -79,6 +79,7 @@
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
+CONFIG_COMPACTION=y
 CONFIG_USE_OF=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 4d124f0..d770e3f 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -92,6 +92,7 @@
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
+CONFIG_COMPACTION=y
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_CP_ACCESS=y
 CONFIG_USE_OF=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 1ffa7d2..8eecf79 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -98,6 +98,7 @@
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
+CONFIG_COMPACTION=y
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_CP_ACCESS=y
 CONFIG_USE_OF=y
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index b4fec0c..7f0a394 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -51,6 +51,7 @@
 
 /* Mux source select values */
 #define xo_source_val  0
+#define xo_a_clk_source_val  0
 #define gpll0_source_val 1
 #define gpll1_source_val 2
 
@@ -440,6 +441,7 @@
 #define Q6SS_AHB_LFABIF_CBCR                               (0x22000)
 #define Q6SS_AHBM_CBCR                                     (0x22004)
 #define Q6SS_XO_CBCR                                       (0x26000)
+#define KPSS_AHB_CMD_RCGR                                  (0x120C)
 
 static unsigned int soft_vote_gpll0;
 
@@ -2852,6 +2854,27 @@
 	},
 };
 
+static struct clk_freq_tbl ftbl_kpss_ahb_clk[] = {
+	F_GCC(19200000, xo_a_clk, 0, 0, 0),
+	F_GCC(37500000, gpll0, 16, 0, 0),
+	F_GCC(75000000, gpll0,  8, 0, 0),
+	F_END
+};
+
+static struct rcg_clk kpss_ahb_clk_src = {
+	.cmd_rcgr_reg = KPSS_AHB_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_kpss_ahb_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "kpss_ahb_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 37500000, NOMINAL, 75000000),
+		CLK_INIT(kpss_ahb_clk_src.c),
+	},
+};
+
 static DEFINE_CLK_VOTER(pnoc_msmbus_clk, &pnoc_clk.c, LONG_MAX);
 static DEFINE_CLK_VOTER(snoc_msmbus_clk, &snoc_clk.c, LONG_MAX);
 static DEFINE_CLK_VOTER(cnoc_msmbus_clk, &cnoc_clk.c, LONG_MAX);
@@ -3117,6 +3140,7 @@
 	CLK_LOOKUP("xo",     xo_a_clk.c, "f9011050.qcom,acpuclk"),
 	CLK_LOOKUP("gpll0",  gpll0_ao.c, "f9011050.qcom,acpuclk"),
 	CLK_LOOKUP("a7sspll", a7sspll.c, "f9011050.qcom,acpuclk"),
+	CLK_LOOKUP("kpss_ahb", kpss_ahb_clk_src.c, ""),
 
 	/* WCNSS CLOCKS */
 	CLK_LOOKUP("xo", cxo_wlan_clk.c, "fb000000.qcom,wcnss-wlan"),
@@ -3585,6 +3609,9 @@
 	clk_set_rate(&mclk1_clk_src.c, mclk1_clk_src.freq_tbl[0].freq_hz);
 	clk_set_rate(&esc0_clk_src.c, esc0_clk_src.freq_tbl[0].freq_hz);
 	clk_set_rate(&vsync_clk_src.c, vsync_clk_src.freq_tbl[0].freq_hz);
+
+	clk_set_rate(&kpss_ahb_clk_src.c, 19200000);
+	clk_prepare_enable(&kpss_ahb_clk_src.c);
 }
 
 #define GCC_CC_PHYS		0xFC400000
diff --git a/arch/arm/mach-msm/msm_cache_dump.c b/arch/arm/mach-msm/msm_cache_dump.c
index 7f6a9b1..86e8963 100644
--- a/arch/arm/mach-msm/msm_cache_dump.c
+++ b/arch/arm/mach-msm/msm_cache_dump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -112,6 +112,8 @@
 
 	temp = ioremap(msm_cache_dump_addr, total_size);
 	memset(temp, 0xFF, total_size);
+	/* Clean caches before sending buffer to TZ */
+	clean_caches((unsigned long) temp, total_size, msm_cache_dump_addr);
 	iounmap(temp);
 
 	l1_cache_data.buf = msm_cache_dump_addr;
diff --git a/arch/arm/mach-msm/pil-pronto.c b/arch/arm/mach-msm/pil-pronto.c
index 098cbd5..1085408 100644
--- a/arch/arm/mach-msm/pil-pronto.c
+++ b/arch/arm/mach-msm/pil-pronto.c
@@ -348,7 +348,7 @@
 	struct platform_device *pdev = wcnss_get_platform_device();
 	struct wcnss_wlan_config *pwlanconfig = wcnss_get_wlan_config();
 
-	wcnss_wlan_power(&pdev->dev, pwlanconfig, WCNSS_WLAN_SWITCH_OFF);
+	wcnss_wlan_power(&pdev->dev, pwlanconfig, WCNSS_WLAN_SWITCH_OFF, NULL);
 }
 
 static int wcnss_shutdown(const struct subsys_desc *subsys)
@@ -371,7 +371,7 @@
 
 	if (pdev && pwlanconfig)
 		ret = wcnss_wlan_power(&pdev->dev, pwlanconfig,
-					WCNSS_WLAN_SWITCH_ON);
+					WCNSS_WLAN_SWITCH_ON, NULL);
 	if (!ret) {
 		msleep(1000);
 		ret = pil_boot(&drv->desc);
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 7fd76ab..bf7438b 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -362,7 +362,7 @@
 	struct platform_device *pdev = wcnss_get_platform_device();
 	struct wcnss_wlan_config *pwlanconfig = wcnss_get_wlan_config();
 
-	wcnss_wlan_power(&pdev->dev, pwlanconfig, WCNSS_WLAN_SWITCH_OFF);
+	wcnss_wlan_power(&pdev->dev, pwlanconfig, WCNSS_WLAN_SWITCH_OFF, NULL);
 }
 
 static int riva_start(const struct subsys_desc *desc)
@@ -404,7 +404,7 @@
 	drv = container_of(desc, struct riva_data, subsys_desc);
 	if (pdev && pwlanconfig) {
 		ret = wcnss_wlan_power(&pdev->dev, pwlanconfig,
-					WCNSS_WLAN_SWITCH_ON);
+					WCNSS_WLAN_SWITCH_ON, NULL);
 		if (!ret)
 			pil_boot(&drv->pil_desc);
 	}
diff --git a/drivers/net/wireless/wcnss/wcnss_vreg.c b/drivers/net/wireless/wcnss/wcnss_vreg.c
index 2251f2f..4713d29 100644
--- a/drivers/net/wireless/wcnss/wcnss_vreg.c
+++ b/drivers/net/wireless/wcnss/wcnss_vreg.c
@@ -120,12 +120,6 @@
 };
 
 enum {
-	WCNSS_XO_48MHZ = 1,
-	WCNSS_XO_19MHZ,
-	WCNSS_XO_INVALID,
-};
-
-enum {
 	IRIS_3660, /* also 3660A and 3680 */
 	IRIS_3620
 };
@@ -147,7 +141,8 @@
 	}
 }
 
-static int configure_iris_xo(struct device *dev, bool use_48mhz_xo, int on)
+static int configure_iris_xo(struct device *dev, bool use_48mhz_xo, int on,
+			int *iris_xo_set)
 {
 	u32 reg = 0;
 	u32 iris_reg = WCNSS_INVALID_IRIS_REG;
@@ -254,9 +249,13 @@
 		reg &= ~(WCNSS_PMU_CFG_IRIS_XO_MODE);
 
 		if ((use_48mhz_xo && auto_detect == WCNSS_XO_INVALID)
-				|| auto_detect ==  WCNSS_XO_48MHZ)
+				|| auto_detect ==  WCNSS_XO_48MHZ) {
 			reg |= WCNSS_PMU_CFG_IRIS_XO_MODE_48;
 
+			if (iris_xo_set)
+				*iris_xo_set = WCNSS_XO_48MHZ;
+		}
+
 		writel_relaxed(reg, pmu_conf_reg);
 
 		/* Start IRIS XO configuration */
@@ -288,6 +287,8 @@
 				pr_err("clk_rf enable failed\n");
 				goto fail;
 			}
+			if (iris_xo_set)
+				*iris_xo_set = WCNSS_XO_19MHZ;
 		}
 
 	}  else if ((!use_48mhz_xo && auto_detect == WCNSS_XO_INVALID)
@@ -491,7 +492,7 @@
 
 int wcnss_wlan_power(struct device *dev,
 		struct wcnss_wlan_config *cfg,
-		enum wcnss_opcode on)
+		enum wcnss_opcode on, int *iris_xo_set)
 {
 	int rc = 0;
 	enum wcnss_hw_type hw_type = wcnss_hardware_type();
@@ -510,14 +511,14 @@
 
 		/* Configure IRIS XO */
 		rc = configure_iris_xo(dev, cfg->use_48mhz_xo,
-				WCNSS_WLAN_SWITCH_ON);
+				WCNSS_WLAN_SWITCH_ON, iris_xo_set);
 		if (rc)
 			goto fail_iris_xo;
 		up(&wcnss_power_on_lock);
 
 	} else {
 		configure_iris_xo(dev, cfg->use_48mhz_xo,
-				WCNSS_WLAN_SWITCH_OFF);
+				WCNSS_WLAN_SWITCH_OFF, NULL);
 		wcnss_iris_vregs_off(hw_type);
 		wcnss_core_vregs_off(hw_type);
 	}
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 0b4f0fe..a3d7f12 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -301,6 +301,7 @@
 	int	user_cal_rcvd;
 	int	user_cal_exp_size;
 	int	device_opened;
+	int	iris_xo_mode_set;
 	struct mutex dev_lock;
 	wait_queue_head_t read_wait;
 } *penv = NULL;
@@ -644,7 +645,7 @@
 
 	/* Since WCNSS is up, cancel any APPS vote for Iris & WCNSS VREGs  */
 	wcnss_wlan_power(&penv->pdev->dev, &penv->wlan_config,
-		WCNSS_WLAN_SWITCH_OFF);
+		WCNSS_WLAN_SWITCH_OFF, NULL);
 
 }
 
@@ -916,6 +917,14 @@
 	return (has_autodetect_xo == 1 ? 1 : 0);
 }
 
+int wcnss_wlan_iris_xo_mode(void)
+{
+	if (penv && penv->pdev && penv->smd_channel_ready)
+		return penv->iris_xo_mode_set;
+	return -ENODEV;
+}
+EXPORT_SYMBOL(wcnss_wlan_iris_xo_mode);
+
 
 void wcnss_suspend_notify(void)
 {
@@ -1598,7 +1607,8 @@
 
 	/* power up the WCNSS */
 	ret = wcnss_wlan_power(&pdev->dev, &penv->wlan_config,
-					WCNSS_WLAN_SWITCH_ON);
+					WCNSS_WLAN_SWITCH_ON,
+					&penv->iris_xo_mode_set);
 	if (ret) {
 		dev_err(&pdev->dev, "WCNSS Power-up failed.\n");
 		goto fail_power;
@@ -1704,7 +1714,7 @@
 	wake_lock_destroy(&penv->wcnss_wake_lock);
 fail_res:
 	wcnss_wlan_power(&pdev->dev, &penv->wlan_config,
-				WCNSS_WLAN_SWITCH_OFF);
+				WCNSS_WLAN_SWITCH_OFF, NULL);
 fail_power:
 	if (has_pronto_hw)
 		wcnss_pronto_gpios_config(&pdev->dev, false);
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 439a8ae..85bdd67 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -940,6 +940,20 @@
 }
 
 static int
+qpnp_dc_property_is_writeable(struct power_supply *psy,
+						enum power_supply_property psp)
+{
+	switch (psp) {
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		return 1;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int
 qpnp_batt_property_is_writeable(struct power_supply *psy,
 						enum power_supply_property psp)
 {
@@ -1036,6 +1050,7 @@
 static enum power_supply_property pm_power_props_mains[] = {
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_CURRENT_MAX,
 };
 
 static enum power_supply_property msm_batt_power_props[] = {
@@ -1082,6 +1097,9 @@
 
 		val->intval = qpnp_chg_is_dc_chg_plugged_in(chip);
 		break;
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		val->intval = chip->maxinput_dc_ma;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -1265,22 +1283,15 @@
 	if (chip->use_default_batt_values || !get_prop_batt_present(chip))
 		return DEFAULT_TEMP;
 
-	if (chip->revision > 0) {
-		rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &results);
-		if (rc) {
-			pr_debug("Unable to read batt temperature rc=%d\n", rc);
-			return 0;
-		}
-		pr_debug("get_bat_temp %d %lld\n",
-			results.adc_code, results.physical);
-		return (int)results.physical;
-	} else {
-		pr_debug("batt temp not supported for PMIC 1.0 rc=%d\n", rc);
+	rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &results);
+	if (rc) {
+		pr_debug("Unable to read batt temperature rc=%d\n", rc);
+		return 0;
 	}
+	pr_debug("get_bat_temp %d %lld\n",
+		results.adc_code, results.physical);
 
-	/* return default temperature to avoid userspace
-	 * from shutting down unecessarily */
-	return DEFAULT_TEMP;
+	return (int)results.physical;
 }
 
 static int get_prop_cycle_count(struct qpnp_chg_chip *chip)
@@ -2056,6 +2067,36 @@
 }
 
 static int
+qpnp_dc_power_set_property(struct power_supply *psy,
+				  enum power_supply_property psp,
+				  const union power_supply_propval *val)
+{
+	struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
+								dc_psy);
+	int rc = 0;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		if (!val->intval)
+			break;
+
+		rc = qpnp_chg_idcmax_set(chip, val->intval / 1000);
+		if (rc) {
+			pr_err("Error setting idcmax property %d\n", rc);
+			return rc;
+		}
+		chip->maxinput_dc_ma = (val->intval / 1000);
+
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	power_supply_changed(&chip->dc_psy);
+	return rc;
+}
+
+static int
 qpnp_batt_power_set_property(struct power_supply *psy,
 				  enum power_supply_property psp,
 				  const union power_supply_propval *val)
@@ -2890,6 +2931,9 @@
 		chip->dc_psy.properties = pm_power_props_mains;
 		chip->dc_psy.num_properties = ARRAY_SIZE(pm_power_props_mains);
 		chip->dc_psy.get_property = qpnp_power_get_property_mains;
+		chip->dc_psy.set_property = qpnp_dc_power_set_property;
+		chip->dc_psy.property_is_writeable =
+				qpnp_dc_property_is_writeable;
 
 		rc = power_supply_register(chip->dev, &chip->dc_psy);
 		if (rc < 0) {
@@ -2909,7 +2953,8 @@
 		}
 	}
 
-	if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
+	if (chip->cool_bat_decidegc && chip->warm_bat_decidegc
+							&& chip->bat_if_base) {
 		chip->adc_param.low_temp = chip->cool_bat_decidegc;
 		chip->adc_param.high_temp = chip->warm_bat_decidegc;
 		chip->adc_param.timer_interval = ADC_MEAS2_INTERVAL_1S;
@@ -2939,6 +2984,7 @@
 	}
 
 	qpnp_chg_usb_usbin_valid_irq_handler(USBIN_VALID_IRQ, chip);
+	qpnp_chg_dc_dcin_valid_irq_handler(DCIN_VALID_IRQ, chip);
 	power_supply_set_present(chip->usb_psy,
 			qpnp_chg_is_usb_chg_plugged_in(chip));
 
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 2ba585e..717bd73 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -30,6 +30,12 @@
 	int		use_48mhz_xo;
 };
 
+enum {
+	WCNSS_XO_48MHZ = 1,
+	WCNSS_XO_19MHZ,
+	WCNSS_XO_INVALID,
+};
+
 #define WCNSS_WLAN_IRQ_INVALID -1
 #define HAVE_WCNSS_SUSPEND_RESUME_NOTIFY 1
 #define HAVE_WCNSS_RESET_INTR 1
@@ -52,7 +58,8 @@
 struct wcnss_wlan_config *wcnss_get_wlan_config(void);
 int wcnss_wlan_power(struct device *dev,
 				struct wcnss_wlan_config *cfg,
-				enum wcnss_opcode opcode);
+				enum wcnss_opcode opcode,
+				int *iris_xo_mode_set);
 int wcnss_req_power_on_lock(char *driver_name);
 int wcnss_free_power_on_lock(char *driver_name);
 unsigned int wcnss_get_serial_number(void);
@@ -71,6 +78,7 @@
 void wcnss_riva_dump_pmic_regs(void);
 int wcnss_xo_auto_detect_enabled(void);
 u32 wcnss_get_wlan_rx_buff_count(void);
+int wcnss_wlan_iris_xo_mode(void);
 
 #define wcnss_wlan_get_drvdata(dev) dev_get_drvdata(dev)
 #define wcnss_wlan_set_drvdata(dev, data) dev_set_drvdata((dev), (data))