提交 27b1fec2 编写于 作者: R Rajendra Nayak 提交者: Kevin Hilman

OMAP: I2C: Convert i2c driver to use PM runtime api's

This patch converts the i2c driver to use PM runtime apis
Signed-off-by: NRajendra Nayak <rnayak@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Jean Delvare <khali@linux-fr.org>
Acked-by: NBen Dooks <ben-linux@fluff.org>
Signed-off-by: NKevin Hilman <khilman@deeprootsystems.com>
上级 4d17aeb1
......@@ -39,6 +39,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/i2c-omap.h>
#include <linux/pm_runtime.h>
/* I2C controller revisions */
#define OMAP_I2C_REV_2 0x20
......@@ -175,8 +176,6 @@ struct omap_i2c_dev {
void __iomem *base; /* virtual */
int irq;
int reg_shift; /* bit shift for I2C register addresses */
struct clk *iclk; /* Interface clock */
struct clk *fclk; /* Functional clock */
struct completion cmd_complete;
struct resource *ioarea;
u32 latency; /* maximum mpu wkup latency */
......@@ -265,45 +264,18 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
(i2c_dev->regs[reg] << i2c_dev->reg_shift));
}
static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
static void omap_i2c_unidle(struct omap_i2c_dev *dev)
{
int ret;
struct platform_device *pdev;
struct omap_i2c_bus_platform_data *pdata;
dev->iclk = clk_get(dev->dev, "ick");
if (IS_ERR(dev->iclk)) {
ret = PTR_ERR(dev->iclk);
dev->iclk = NULL;
return ret;
}
WARN_ON(!dev->idle);
dev->fclk = clk_get(dev->dev, "fck");
if (IS_ERR(dev->fclk)) {
ret = PTR_ERR(dev->fclk);
if (dev->iclk != NULL) {
clk_put(dev->iclk);
dev->iclk = NULL;
}
dev->fclk = NULL;
return ret;
}
pdev = to_platform_device(dev->dev);
pdata = pdev->dev.platform_data;
return 0;
}
pm_runtime_get_sync(&pdev->dev);
static void omap_i2c_put_clocks(struct omap_i2c_dev *dev)
{
clk_put(dev->fclk);
dev->fclk = NULL;
clk_put(dev->iclk);
dev->iclk = NULL;
}
static void omap_i2c_unidle(struct omap_i2c_dev *dev)
{
WARN_ON(!dev->idle);
clk_enable(dev->iclk);
clk_enable(dev->fclk);
if (cpu_is_omap34xx()) {
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
......@@ -326,10 +298,15 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
static void omap_i2c_idle(struct omap_i2c_dev *dev)
{
struct platform_device *pdev;
struct omap_i2c_bus_platform_data *pdata;
u16 iv;
WARN_ON(dev->idle);
pdev = to_platform_device(dev->dev);
pdata = pdev->dev.platform_data;
dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
if (dev->rev >= OMAP_I2C_REV_ON_4430)
omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1);
......@@ -345,8 +322,8 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
}
dev->idle = 1;
clk_disable(dev->fclk);
clk_disable(dev->iclk);
pm_runtime_put_sync(&pdev->dev);
}
static int omap_i2c_init(struct omap_i2c_dev *dev)
......@@ -356,6 +333,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
unsigned long fclk_rate = 12000000;
unsigned long timeout;
unsigned long internal_clk = 0;
struct clk *fclk;
if (dev->rev >= OMAP_I2C_REV_2) {
/* Disable I2C controller before soft reset */
......@@ -414,7 +392,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
* always returns 12MHz for the functional clock, we can
* do this bit unconditionally.
*/
fclk_rate = clk_get_rate(dev->fclk);
fclk = clk_get(dev->dev, "fck");
fclk_rate = clk_get_rate(fclk);
clk_put(fclk);
/* TRM for 5912 says the I2C clock must be prescaled to be
* between 7 - 12 MHz. The XOR input clock is typically
......@@ -443,7 +423,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
internal_clk = 9600;
else
internal_clk = 4000;
fclk_rate = clk_get_rate(dev->fclk) / 1000;
fclk = clk_get(dev->dev, "fck");
fclk_rate = clk_get_rate(fclk) / 1000;
clk_put(fclk);
/* Compute prescaler divisor */
psc = fclk_rate / internal_clk;
......@@ -1048,14 +1030,12 @@ omap_i2c_probe(struct platform_device *pdev)
else
dev->reg_shift = 2;
if ((r = omap_i2c_get_clocks(dev)) != 0)
goto err_iounmap;
if (cpu_is_omap44xx())
dev->regs = (u8 *) omap4_reg_map;
else
dev->regs = (u8 *) reg_map;
pm_runtime_enable(&pdev->dev);
omap_i2c_unidle(dev);
dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
......@@ -1127,8 +1107,6 @@ omap_i2c_probe(struct platform_device *pdev)
err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
omap_i2c_idle(dev);
omap_i2c_put_clocks(dev);
err_iounmap:
iounmap(dev->base);
err_free_mem:
platform_set_drvdata(pdev, NULL);
......@@ -1150,7 +1128,6 @@ omap_i2c_remove(struct platform_device *pdev)
free_irq(dev->irq, dev);
i2c_del_adapter(&dev->adapter);
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
omap_i2c_put_clocks(dev);
iounmap(dev->base);
kfree(dev);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册