提交 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 @@ ...@@ -39,6 +39,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c-omap.h> #include <linux/i2c-omap.h>
#include <linux/pm_runtime.h>
/* I2C controller revisions */ /* I2C controller revisions */
#define OMAP_I2C_REV_2 0x20 #define OMAP_I2C_REV_2 0x20
...@@ -175,8 +176,6 @@ struct omap_i2c_dev { ...@@ -175,8 +176,6 @@ struct omap_i2c_dev {
void __iomem *base; /* virtual */ void __iomem *base; /* virtual */
int irq; int irq;
int reg_shift; /* bit shift for I2C register addresses */ int reg_shift; /* bit shift for I2C register addresses */
struct clk *iclk; /* Interface clock */
struct clk *fclk; /* Functional clock */
struct completion cmd_complete; struct completion cmd_complete;
struct resource *ioarea; struct resource *ioarea;
u32 latency; /* maximum mpu wkup latency */ 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) ...@@ -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)); (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"); WARN_ON(!dev->idle);
if (IS_ERR(dev->iclk)) {
ret = PTR_ERR(dev->iclk);
dev->iclk = NULL;
return ret;
}
dev->fclk = clk_get(dev->dev, "fck"); pdev = to_platform_device(dev->dev);
if (IS_ERR(dev->fclk)) { pdata = pdev->dev.platform_data;
ret = PTR_ERR(dev->fclk);
if (dev->iclk != NULL) {
clk_put(dev->iclk);
dev->iclk = NULL;
}
dev->fclk = NULL;
return ret;
}
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()) { if (cpu_is_omap34xx()) {
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); 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) ...@@ -326,10 +298,15 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
static void omap_i2c_idle(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; u16 iv;
WARN_ON(dev->idle); 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); dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
if (dev->rev >= OMAP_I2C_REV_ON_4430) if (dev->rev >= OMAP_I2C_REV_ON_4430)
omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1); omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1);
...@@ -345,8 +322,8 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) ...@@ -345,8 +322,8 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
} }
dev->idle = 1; 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) static int omap_i2c_init(struct omap_i2c_dev *dev)
...@@ -356,6 +333,7 @@ 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 fclk_rate = 12000000;
unsigned long timeout; unsigned long timeout;
unsigned long internal_clk = 0; unsigned long internal_clk = 0;
struct clk *fclk;
if (dev->rev >= OMAP_I2C_REV_2) { if (dev->rev >= OMAP_I2C_REV_2) {
/* Disable I2C controller before soft reset */ /* Disable I2C controller before soft reset */
...@@ -414,7 +392,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) ...@@ -414,7 +392,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
* always returns 12MHz for the functional clock, we can * always returns 12MHz for the functional clock, we can
* do this bit unconditionally. * 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 /* TRM for 5912 says the I2C clock must be prescaled to be
* between 7 - 12 MHz. The XOR input clock is typically * between 7 - 12 MHz. The XOR input clock is typically
...@@ -443,7 +423,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) ...@@ -443,7 +423,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
internal_clk = 9600; internal_clk = 9600;
else else
internal_clk = 4000; 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 */ /* Compute prescaler divisor */
psc = fclk_rate / internal_clk; psc = fclk_rate / internal_clk;
...@@ -1048,14 +1030,12 @@ omap_i2c_probe(struct platform_device *pdev) ...@@ -1048,14 +1030,12 @@ omap_i2c_probe(struct platform_device *pdev)
else else
dev->reg_shift = 2; dev->reg_shift = 2;
if ((r = omap_i2c_get_clocks(dev)) != 0)
goto err_iounmap;
if (cpu_is_omap44xx()) if (cpu_is_omap44xx())
dev->regs = (u8 *) omap4_reg_map; dev->regs = (u8 *) omap4_reg_map;
else else
dev->regs = (u8 *) reg_map; dev->regs = (u8 *) reg_map;
pm_runtime_enable(&pdev->dev);
omap_i2c_unidle(dev); omap_i2c_unidle(dev);
dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
...@@ -1127,8 +1107,6 @@ omap_i2c_probe(struct platform_device *pdev) ...@@ -1127,8 +1107,6 @@ omap_i2c_probe(struct platform_device *pdev)
err_unuse_clocks: err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
omap_i2c_idle(dev); omap_i2c_idle(dev);
omap_i2c_put_clocks(dev);
err_iounmap:
iounmap(dev->base); iounmap(dev->base);
err_free_mem: err_free_mem:
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
...@@ -1150,7 +1128,6 @@ omap_i2c_remove(struct platform_device *pdev) ...@@ -1150,7 +1128,6 @@ omap_i2c_remove(struct platform_device *pdev)
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
i2c_del_adapter(&dev->adapter); i2c_del_adapter(&dev->adapter);
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
omap_i2c_put_clocks(dev);
iounmap(dev->base); iounmap(dev->base);
kfree(dev); kfree(dev);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 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.
先完成此消息的编辑!
想要评论请 注册