msm: pil-modem: Migrate to clk APIs for XO voting

Use the clock APIs instead of the msm_xo APIs to vote on PXO.
This removes one more msm specific api from this driver and will
allow us to move XO control into the rpm clock driver.

Change-Id: Ie7d862131a7b8717c3ab0574f570f073c6a69dfd
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 94fafda..17f5d01 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3520,6 +3520,7 @@
 
 static struct clk_lookup msm_clocks_8x60[] = {
 	CLK_LOOKUP("cxo",		cxo_clk.c,	NULL),
+	CLK_LOOKUP("xo",		pxo_clk.c,	"pil_modem"),
 	CLK_LOOKUP("pll4",		pll4_clk.c,	"pil_qdsp6v3"),
 	CLK_LOOKUP("measure",		measure_clk.c,	"debug"),
 
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index 5aa3834..1d13508 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.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
@@ -18,9 +18,10 @@
 #include <linux/elf.h>
 #include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/workqueue.h>
+#include <linux/clk.h>
 
 #include <mach/msm_iomap.h>
-#include <mach/msm_xo.h>
 
 #include "peripheral-loader.h"
 #include "scm-pas.h"
@@ -52,8 +53,8 @@
 struct modem_data {
 	void __iomem *base;
 	unsigned long start_addr;
-	struct msm_xo_voter *pxo;
-	struct timer_list timer;
+	struct clk *xo;
+	struct delayed_work work;
 };
 
 static int nop_verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
@@ -61,28 +62,30 @@
 	return 0;
 }
 
-static void remove_proxy_votes(unsigned long data)
-{
-	struct modem_data *drv = (struct modem_data *)data;
-	msm_xo_mode_vote(drv->pxo, MSM_XO_MODE_OFF);
-}
-
-static void make_modem_proxy_votes(struct device *dev)
+static int make_modem_proxy_votes(struct device *dev)
 {
 	int ret;
 	struct modem_data *drv = dev_get_drvdata(dev);
 
-	ret = msm_xo_mode_vote(drv->pxo, MSM_XO_MODE_ON);
-	if (ret)
-		dev_err(dev, "Failed to enable PXO\n");
-	mod_timer(&drv->timer, jiffies + msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+	ret = clk_prepare_enable(drv->xo);
+	if (ret) {
+		dev_err(dev, "Failed to enable XO\n");
+		return ret;
+	}
+	schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+	return 0;
+}
+
+static void remove_modem_proxy_votes(struct work_struct *work)
+{
+	struct modem_data *drv;
+	drv = container_of(work, struct modem_data, work.work);
+	clk_disable_unprepare(drv->xo);
 }
 
 static void remove_modem_proxy_votes_now(struct modem_data *drv)
 {
-	/* If the proxy vote hasn't been removed yet, remove it immediately. */
-	if (del_timer(&drv->timer))
-		remove_proxy_votes((unsigned long)drv);
+	flush_delayed_work(&drv->work);
 }
 
 static int modem_init_image(struct pil_desc *pil, const u8 *metadata,
@@ -97,9 +100,12 @@
 static int modem_reset(struct pil_desc *pil)
 {
 	u32 reg;
+	int ret;
 	const struct modem_data *drv = dev_get_drvdata(pil->dev);
 
-	make_modem_proxy_votes(pil->dev);
+	ret = make_modem_proxy_votes(pil->dev);
+	if (ret)
+		return ret;
 
 	/* Put modem AHB0,1,2 clocks into reset */
 	writel_relaxed(BIT(0) | BIT(1), MAHB0_SFAB_PORT_RESET);
@@ -235,7 +241,9 @@
 	int ret;
 	struct modem_data *drv = dev_get_drvdata(pil->dev);
 
-	make_modem_proxy_votes(pil->dev);
+	ret = make_modem_proxy_votes(pil->dev);
+	if (ret)
+		return ret;
 
 	ret = pas_auth_and_reset(PAS_MODEM);
 	if (ret)
@@ -269,6 +277,7 @@
 	struct modem_data *drv;
 	struct resource *res;
 	struct pil_desc *desc;
+	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
@@ -283,15 +292,14 @@
 	if (!drv->base)
 		return -ENOMEM;
 
-	drv->pxo = msm_xo_get(MSM_XO_PXO, dev_name(&pdev->dev));
-	if (IS_ERR(drv->pxo))
-		return PTR_ERR(drv->pxo);
+	drv->xo = clk_get(&pdev->dev, "xo");
+	if (IS_ERR(drv->xo))
+		return PTR_ERR(drv->xo);
 
 	desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc)
 		return -ENOMEM;
 
-	setup_timer(&drv->timer, remove_proxy_votes, (unsigned long)drv);
 	desc->name = "modem";
 	desc->depends_on = "q6";
 	desc->dev = &pdev->dev;
@@ -303,19 +311,21 @@
 		desc->ops = &pil_modem_ops;
 		dev_info(&pdev->dev, "using non-secure boot\n");
 	}
+	INIT_DELAYED_WORK(&drv->work, remove_modem_proxy_votes);
 
-	if (msm_pil_register(desc)) {
-		msm_xo_put(drv->pxo);
-		return -EINVAL;
+	ret = msm_pil_register(desc);
+	if (ret) {
+		flush_delayed_work_sync(&drv->work);
+		clk_put(drv->xo);
 	}
-	return 0;
+	return ret;
 }
 
 static int __devexit pil_modem_driver_exit(struct platform_device *pdev)
 {
 	struct modem_data *drv = platform_get_drvdata(pdev);
-	del_timer_sync(&drv->timer);
-	msm_xo_put(drv->pxo);
+	flush_delayed_work_sync(&drv->work);
+	clk_put(drv->xo);
 	return 0;
 }