Merge "PM / devfreq: Fix incorrect argument in error message"
diff --git a/arch/arm/mach-msm/acpuclock-8226.c b/arch/arm/mach-msm/acpuclock-8226.c
index 8ba1b39..fcbd74d 100644
--- a/arch/arm/mach-msm/acpuclock-8226.c
+++ b/arch/arm/mach-msm/acpuclock-8226.c
@@ -98,13 +98,13 @@
 
 	drv_data.apcs_rcg_config = drv_data.apcs_rcg_cmd + 4;
 
-	drv_data.vdd_cpu = regulator_get(&pdev->dev, "a7_cpu");
+	drv_data.vdd_cpu = devm_regulator_get(&pdev->dev, "a7_cpu");
 	if (IS_ERR(drv_data.vdd_cpu)) {
 		dev_err(&pdev->dev, "regulator for %s get failed\n", "a7_cpu");
 		return PTR_ERR(drv_data.vdd_cpu);
 	}
 
-	drv_data.vdd_mem = regulator_get(&pdev->dev, "a7_mem");
+	drv_data.vdd_mem = devm_regulator_get(&pdev->dev, "a7_mem");
 	if (IS_ERR(drv_data.vdd_mem)) {
 		dev_err(&pdev->dev, "regulator for %s get failed\n", "a7_mem");
 		return PTR_ERR(drv_data.vdd_mem);
diff --git a/arch/arm/mach-msm/acpuclock-9625.c b/arch/arm/mach-msm/acpuclock-9625.c
index b439088..34952fb 100644
--- a/arch/arm/mach-msm/acpuclock-9625.c
+++ b/arch/arm/mach-msm/acpuclock-9625.c
@@ -105,13 +105,13 @@
 	if (!drv_data.apcs_cpu_pwr_ctl)
 		return -ENOMEM;
 
-	drv_data.vdd_cpu = regulator_get(&pdev->dev, "a5_cpu");
+	drv_data.vdd_cpu = devm_regulator_get(&pdev->dev, "a5_cpu");
 	if (IS_ERR(drv_data.vdd_cpu)) {
 		dev_err(&pdev->dev, "regulator for %s get failed\n", "a5_cpu");
 		return PTR_ERR(drv_data.vdd_cpu);
 	}
 
-	drv_data.vdd_mem = regulator_get(&pdev->dev, "a5_mem");
+	drv_data.vdd_mem = devm_regulator_get(&pdev->dev, "a5_mem");
 	if (IS_ERR(drv_data.vdd_mem)) {
 		dev_err(&pdev->dev, "regulator for %s get failed\n", "a5_mem");
 		return PTR_ERR(drv_data.vdd_mem);
diff --git a/arch/arm/mach-msm/acpuclock-cortex.c b/arch/arm/mach-msm/acpuclock-cortex.c
index ce56b6b..88bf919 100644
--- a/arch/arm/mach-msm/acpuclock-cortex.c
+++ b/arch/arm/mach-msm/acpuclock-cortex.c
@@ -40,7 +40,7 @@
 #define POLL_INTERVAL_US		1
 #define APCS_RCG_UPDATE_TIMEOUT_US	20
 
-static struct acpuclk_drv_data *acpuclk_init_data;
+static struct acpuclk_drv_data *priv;
 static uint32_t bus_perf_client;
 
 /* Update the bus bandwidth request. */
@@ -48,7 +48,7 @@
 {
 	int ret;
 
-	if (bw >= acpuclk_init_data->bus_scale->num_usecases) {
+	if (bw >= priv->bus_scale->num_usecases) {
 		pr_err("invalid bandwidth request (%d)\n", bw);
 		return;
 	}
@@ -67,15 +67,13 @@
 	int rc = 0;
 
 	/* Increase vdd_mem before vdd_cpu. vdd_mem should be >= vdd_cpu. */
-	rc = regulator_set_voltage(acpuclk_init_data->vdd_mem, vdd_mem,
-		acpuclk_init_data->vdd_max_mem);
+	rc = regulator_set_voltage(priv->vdd_mem, vdd_mem, priv->vdd_max_mem);
 	if (rc) {
 		pr_err("vdd_mem increase failed (%d)\n", rc);
 		return rc;
 	}
 
-	rc = regulator_set_voltage(acpuclk_init_data->vdd_cpu, vdd_cpu,
-		acpuclk_init_data->vdd_max_cpu);
+	rc = regulator_set_voltage(priv->vdd_cpu, vdd_cpu, priv->vdd_max_cpu);
 	if (rc)
 		pr_err("vdd_cpu increase failed (%d)\n", rc);
 
@@ -88,16 +86,14 @@
 	int ret;
 
 	/* Update CPU voltage. */
-	ret = regulator_set_voltage(acpuclk_init_data->vdd_cpu, vdd_cpu,
-		acpuclk_init_data->vdd_max_cpu);
+	ret = regulator_set_voltage(priv->vdd_cpu, vdd_cpu, priv->vdd_max_cpu);
 	if (ret) {
 		pr_err("vdd_cpu decrease failed (%d)\n", ret);
 		return;
 	}
 
 	/* Decrease vdd_mem after vdd_cpu. vdd_mem should be >= vdd_cpu. */
-	ret = regulator_set_voltage(acpuclk_init_data->vdd_mem, vdd_mem,
-		acpuclk_init_data->vdd_max_mem);
+	ret = regulator_set_voltage(priv->vdd_mem, vdd_mem, priv->vdd_max_mem);
 	if (ret)
 		pr_err("vdd_mem decrease failed (%d)\n", ret);
 }
@@ -142,14 +138,14 @@
 {
 	int rc = 0;
 	unsigned int tgt_freq_hz = tgt_s->khz * 1000;
-	struct clkctl_acpu_speed *strt_s = acpuclk_init_data->current_speed;
-	struct clkctl_acpu_speed *cxo_s = &acpuclk_init_data->freq_tbl[0];
-	struct clk *strt = acpuclk_init_data->src_clocks[strt_s->src].clk;
-	struct clk *tgt = acpuclk_init_data->src_clocks[tgt_s->src].clk;
+	struct clkctl_acpu_speed *strt_s = priv->current_speed;
+	struct clkctl_acpu_speed *cxo_s = &priv->freq_tbl[0];
+	struct clk *strt = priv->src_clocks[strt_s->src].clk;
+	struct clk *tgt = priv->src_clocks[tgt_s->src].clk;
 
 	if (strt_s->src == ACPUPLL && tgt_s->src == ACPUPLL) {
 		/* Switch to another always on src */
-		select_clk_source_div(acpuclk_init_data, cxo_s);
+		select_clk_source_div(priv, cxo_s);
 
 		/* Re-program acpu pll */
 		if (atomic)
@@ -167,7 +163,7 @@
 			BUG_ON(clk_prepare_enable(tgt));
 
 		/* Switch back to acpu pll */
-		select_clk_source_div(acpuclk_init_data, tgt_s);
+		select_clk_source_div(priv, tgt_s);
 
 	} else if (strt_s->src != ACPUPLL && tgt_s->src == ACPUPLL) {
 		rc = clk_set_rate(tgt, tgt_freq_hz);
@@ -186,7 +182,7 @@
 			return rc;
 		}
 
-		select_clk_source_div(acpuclk_init_data, tgt_s);
+		select_clk_source_div(priv, tgt_s);
 
 		if (atomic)
 			clk_disable(strt);
@@ -201,11 +197,11 @@
 
 		if (rc) {
 			pr_err("%s enable failed\n",
-				acpuclk_init_data->src_clocks[tgt_s->src].name);
+				priv->src_clocks[tgt_s->src].name);
 			return rc;
 		}
 
-		select_clk_source_div(acpuclk_init_data, tgt_s);
+		select_clk_source_div(priv, tgt_s);
 
 		if (atomic)
 			clk_disable(strt);
@@ -224,16 +220,16 @@
 	int rc = 0;
 
 	if (reason == SETRATE_CPUFREQ)
-		mutex_lock(&acpuclk_init_data->lock);
+		mutex_lock(&priv->lock);
 
-	strt_s = acpuclk_init_data->current_speed;
+	strt_s = priv->current_speed;
 
 	/* Return early if rate didn't change */
 	if (rate == strt_s->khz)
 		goto out;
 
 	/* Find target frequency */
-	for (tgt_s = acpuclk_init_data->freq_tbl; tgt_s->khz != 0; tgt_s++)
+	for (tgt_s = priv->freq_tbl; tgt_s->khz != 0; tgt_s++)
 		if (tgt_s->khz == rate)
 			break;
 	if (tgt_s->khz == 0) {
@@ -261,7 +257,7 @@
 	if (rc)
 		goto out;
 
-	acpuclk_init_data->current_speed = tgt_s;
+	priv->current_speed = tgt_s;
 	pr_debug("CPU speed change complete\n");
 
 	/* Nothing else to do for SWFI or power-collapse. */
@@ -277,13 +273,13 @@
 
 out:
 	if (reason == SETRATE_CPUFREQ)
-		mutex_unlock(&acpuclk_init_data->lock);
+		mutex_unlock(&priv->lock);
 	return rc;
 }
 
 static unsigned long acpuclk_cortex_get_rate(int cpu)
 {
-	return acpuclk_init_data->current_speed->khz;
+	return priv->current_speed->khz;
 }
 
 #ifdef CONFIG_CPU_FREQ_MSM
@@ -293,18 +289,17 @@
 {
 	int i, freq_cnt = 0;
 
-	/* Construct the freq_table tables from acpuclk_init_data->freq_tbl. */
-	for (i = 0; acpuclk_init_data->freq_tbl[i].khz != 0
+	/* Construct the freq_table tables from priv->freq_tbl. */
+	for (i = 0; priv->freq_tbl[i].khz != 0
 			&& freq_cnt < ARRAY_SIZE(freq_table); i++) {
-		if (!acpuclk_init_data->freq_tbl[i].use_for_scaling)
+		if (!priv->freq_tbl[i].use_for_scaling)
 			continue;
 		freq_table[freq_cnt].index = freq_cnt;
-		freq_table[freq_cnt].frequency =
-			acpuclk_init_data->freq_tbl[i].khz;
+		freq_table[freq_cnt].frequency = priv->freq_tbl[i].khz;
 		freq_cnt++;
 	}
 	/* freq_table not big enough to store all usable freqs. */
-	BUG_ON(acpuclk_init_data->freq_tbl[i].khz != 0);
+	BUG_ON(priv->freq_tbl[i].khz != 0);
 
 	freq_table[freq_cnt].index = freq_cnt;
 	freq_table[freq_cnt].frequency = CPUFREQ_TABLE_END;
@@ -332,43 +327,40 @@
 	unsigned long max_cpu_khz = 0;
 	int i, rc;
 
-	acpuclk_init_data = data;
-	mutex_init(&acpuclk_init_data->lock);
+	priv = data;
+	mutex_init(&priv->lock);
 
-	bus_perf_client = msm_bus_scale_register_client(
-		acpuclk_init_data->bus_scale);
+	bus_perf_client = msm_bus_scale_register_client(priv->bus_scale);
 	if (!bus_perf_client) {
 		pr_err("Unable to register bus client\n");
 		BUG();
 	}
 
 	for (i = 0; i < NUM_SRC; i++) {
-		if (!acpuclk_init_data->src_clocks[i].name)
+		if (!priv->src_clocks[i].name)
 			continue;
-		acpuclk_init_data->src_clocks[i].clk =
-			clk_get(&pdev->dev,
-				acpuclk_init_data->src_clocks[i].name);
-		BUG_ON(IS_ERR(acpuclk_init_data->src_clocks[i].clk));
+		priv->src_clocks[i].clk =
+			devm_clk_get(&pdev->dev, priv->src_clocks[i].name);
+		BUG_ON(IS_ERR(priv->src_clocks[i].clk));
 	}
 
 	/* Improve boot time by ramping up CPU immediately */
-	for (i = 0; acpuclk_init_data->freq_tbl[i].khz != 0; i++)
-		if (acpuclk_init_data->freq_tbl[i].use_for_scaling)
-			max_cpu_khz = acpuclk_init_data->freq_tbl[i].khz;
+	for (i = 0; priv->freq_tbl[i].khz != 0; i++)
+		if (priv->freq_tbl[i].use_for_scaling)
+			max_cpu_khz = priv->freq_tbl[i].khz;
 
 	/* Initialize regulators */
-	rc = increase_vdd(acpuclk_init_data->vdd_max_cpu,
-		acpuclk_init_data->vdd_max_mem);
+	rc = increase_vdd(priv->vdd_max_cpu, priv->vdd_max_mem);
 	if (rc)
 		goto err_vdd;
 
-	rc = regulator_enable(acpuclk_init_data->vdd_mem);
+	rc = regulator_enable(priv->vdd_mem);
 	if (rc) {
 		dev_err(&pdev->dev, "regulator_enable for mem failed\n");
 		goto err_vdd;
 	}
 
-	rc = regulator_enable(acpuclk_init_data->vdd_cpu);
+	rc = regulator_enable(priv->vdd_cpu);
 	if (rc) {
 		dev_err(&pdev->dev, "regulator_enable for cpu failed\n");
 		goto err_vdd_cpu;
@@ -388,15 +380,7 @@
 	return 0;
 
 err_vdd_cpu:
-	regulator_disable(acpuclk_init_data->vdd_mem);
+	regulator_disable(priv->vdd_mem);
 err_vdd:
-	regulator_put(acpuclk_init_data->vdd_mem);
-	regulator_put(acpuclk_init_data->vdd_cpu);
-
-	for (i = 0; i < NUM_SRC; i++) {
-		if (!acpuclk_init_data->src_clocks[i].name)
-			continue;
-		clk_put(acpuclk_init_data->src_clocks[i].clk);
-	}
 	return rc;
 }
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 0436a82..8e2b7c9 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -1919,6 +1919,8 @@
 };
 
 static struct clk_freq_tbl ftbl_camss_mclk0_1_clk[] = {
+	F_MMSS(  19200000,         xo,   1,    0,    0),
+	F_MMSS(  24000000,      gpll0,   5,    1,    5),
 	F_MMSS(  66670000,      gpll0,   9,    0,    0),
 	F_END
 };
@@ -3062,7 +3064,8 @@
 	CLK_LOOKUP("a7sspll", a7sspll.c, "f9011050.qcom,acpuclk"),
 
 	/* WCNSS CLOCKS */
-	CLK_LOOKUP("xo", xo.c, "fb000000.qcom,wcnss-wlan"),
+	CLK_LOOKUP("xo", xo.c,         "fb000000.qcom,wcnss-wlan"),
+	CLK_LOOKUP("rf_clk", cxo_a2.c, "fb000000.qcom,wcnss-wlan"),
 
 	/* BUS DRIVER */
 	CLK_LOOKUP("bus_clk", cnoc_msmbus_clk.c, "msm_config_noc"),
@@ -3179,6 +3182,11 @@
 	CLK_LOOKUP("bus_clk",      gcc_ce1_axi_clk.c,     "qseecom"),
 	CLK_LOOKUP("core_clk_src", ce1_clk_src.c,         "qseecom"),
 
+	CLK_LOOKUP("core_clk",     gcc_ce1_clk.c,         "scm"),
+	CLK_LOOKUP("iface_clk",    gcc_ce1_ahb_clk.c,     "scm"),
+	CLK_LOOKUP("bus_clk",      gcc_ce1_axi_clk.c,     "scm"),
+	CLK_LOOKUP("core_clk_src", ce1_clk_src.c,         "scm"),
+
 	/* SDCC */
 	CLK_LOOKUP("iface_clk", gcc_sdcc1_ahb_clk.c, "f9824000.qcom,sdcc"),
 	CLK_LOOKUP("core_clk", gcc_sdcc1_apps_clk.c, "f9824000.qcom,sdcc"),
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 0657c21..c5594e2 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -4815,6 +4815,11 @@
 	CLK_LOOKUP("bus_clk",      gcc_ce1_axi_clk.c,     "qseecom"),
 	CLK_LOOKUP("core_clk_src", ce1_clk_src.c,         "qseecom"),
 
+	CLK_LOOKUP("core_clk",     gcc_ce1_clk.c,         "scm"),
+	CLK_LOOKUP("iface_clk",    gcc_ce1_ahb_clk.c,     "scm"),
+	CLK_LOOKUP("bus_clk",      gcc_ce1_axi_clk.c,     "scm"),
+	CLK_LOOKUP("core_clk_src", ce1_clk_src.c,         "scm"),
+
 	CLK_LOOKUP("core_clk", gcc_gp1_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_gp2_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_gp3_clk.c, ""),
diff --git a/arch/arm/mach-msm/scm-pas.c b/arch/arm/mach-msm/scm-pas.c
index f73055e..b7271bb 100644
--- a/arch/arm/mach-msm/scm-pas.c
+++ b/arch/arm/mach-msm/scm-pas.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-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
@@ -29,6 +29,23 @@
 #define PAS_SHUTDOWN_CMD	6
 #define PAS_IS_SUPPORTED_CMD	7
 
+enum scm_clock_ids {
+	BUS_CLK = 0,
+	CORE_CLK,
+	IFACE_CLK,
+	CORE_CLK_SRC,
+	NUM_CLKS
+};
+
+static const char * const scm_clock_names[NUM_CLKS] = {
+	[BUS_CLK]      = "bus_clk",
+	[CORE_CLK]     = "core_clk",
+	[IFACE_CLK]    = "iface_clk",
+	[CORE_CLK_SRC] = "core_clk_src",
+};
+
+static struct clk *scm_clocks[NUM_CLKS];
+
 int pas_init_image(enum pas_id id, const u8 *metadata, size_t size)
 {
 	int ret;
@@ -108,14 +125,13 @@
 };
 
 static uint32_t scm_perf_client;
-static struct clk *scm_bus_clk;
 
 static DEFINE_MUTEX(scm_pas_bw_mutex);
 static int scm_pas_bw_count;
 
 static int scm_pas_enable_bw(void)
 {
-	int ret = 0;
+	int ret = 0, i;
 
 	if (!scm_perf_client)
 		return -EINVAL;
@@ -123,30 +139,40 @@
 	mutex_lock(&scm_pas_bw_mutex);
 	if (!scm_pas_bw_count) {
 		ret = msm_bus_scale_client_update_request(scm_perf_client, 1);
-		if (ret) {
-			pr_err("bandwidth request failed (%d)\n", ret);
-		} else if (scm_bus_clk) {
-			ret = clk_prepare_enable(scm_bus_clk);
-			if (ret)
-				pr_err("clock enable failed\n");
-		}
-	}
-	if (ret)
-		msm_bus_scale_client_update_request(scm_perf_client, 0);
-	else
+		if (ret)
+			goto err_bus;
 		scm_pas_bw_count++;
+	}
+	for (i = 0; i < NUM_CLKS; i++)
+		if (clk_prepare_enable(scm_clocks[i]))
+			goto err_clk;
+
+	mutex_unlock(&scm_pas_bw_mutex);
+	return ret;
+
+err_clk:
+	pr_err("clk prepare_enable failed (%s)\n", scm_clock_names[i]);
+	for (i--; i >= 0; i--)
+		clk_disable_unprepare(scm_clocks[i]);
+
+err_bus:
+	pr_err("bandwidth request failed (%d)\n", ret);
+	msm_bus_scale_client_update_request(scm_perf_client, 0);
+
 	mutex_unlock(&scm_pas_bw_mutex);
 	return ret;
 }
 
 static void scm_pas_disable_bw(void)
 {
+	int i;
 	mutex_lock(&scm_pas_bw_mutex);
 	if (scm_pas_bw_count-- == 1) {
 		msm_bus_scale_client_update_request(scm_perf_client, 0);
-		if (scm_bus_clk)
-			clk_disable_unprepare(scm_bus_clk);
 	}
+	for (i = NUM_CLKS - 1; i >= 0; i--)
+		clk_disable_unprepare(scm_clocks[i]);
+
 	mutex_unlock(&scm_pas_bw_mutex);
 }
 
@@ -214,17 +240,25 @@
 
 static int __init scm_pas_init(void)
 {
-	if (cpu_is_msm8974()) {
+	int i, rate;
+	for (i = 0; i < NUM_CLKS; i++) {
+		scm_clocks[i] = clk_get_sys("scm", scm_clock_names[i]);
+		if (IS_ERR(scm_clocks[i]))
+			scm_clocks[i] = NULL;
+	}
+
+	/* Fail silently if this clock is not supported */
+	rate = clk_round_rate(scm_clocks[CORE_CLK_SRC], 1);
+	clk_set_rate(scm_clocks[CORE_CLK_SRC], rate);
+
+	if (cpu_is_msm8974() || cpu_is_msm8226()) {
 		scm_pas_bw_tbl[0].vectors[0].src = MSM_BUS_MASTER_CRYPTO_CORE0;
 		scm_pas_bw_tbl[1].vectors[0].src = MSM_BUS_MASTER_CRYPTO_CORE0;
 	} else {
-		scm_bus_clk = clk_get_sys("scm", "bus_clk");
-		if (!IS_ERR(scm_bus_clk)) {
-			clk_set_rate(scm_bus_clk, 64000000);
-		} else {
-			scm_bus_clk = NULL;
+		if (!IS_ERR(scm_clocks[BUS_CLK]))
+			clk_set_rate(scm_clocks[BUS_CLK], 64000000);
+		else
 			pr_warn("unable to get bus clock\n");
-		}
 	}
 
 	scm_perf_client = msm_bus_scale_register_client(&scm_pas_bus_pdata);