Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 226448
b: refs/heads/master
c: 27b1fec
h: refs/heads/master
v: v3
  • Loading branch information
Rajendra Nayak authored and Kevin Hilman committed Nov 9, 2010
1 parent 8d55bd4 commit 32357b0
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 47 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4d17aeb1c5b2375769446d13012a98e6d265ec13
refs/heads/master: 27b1fec2caa668c162cd1a862c69e087df277fae
69 changes: 23 additions & 46 deletions trunk/drivers/i2c/busses/i2c-omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -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 */
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit 32357b0

Please sign in to comment.