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;
}