aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-omap.c
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@ti.com>2010-09-28 11:32:58 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2010-11-09 12:31:10 -0500
commit27b1fec2caa668c162cd1a862c69e087df277fae (patch)
tree4e14adc83c89ece061ef2a76b6470f87e4bcc57a /drivers/i2c/busses/i2c-omap.c
parent4d17aeb1c5b2375769446d13012a98e6d265ec13 (diff)
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: Rajendra Nayak <rnayak@ti.com> Cc: Paul Walmsley <paul@pwsan.com> Cc: Jean Delvare <khali@linux-fr.org> Acked-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'drivers/i2c/busses/i2c-omap.c')
-rw-r--r--drivers/i2c/busses/i2c-omap.c69
1 files changed, 23 insertions, 46 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index b33c78586bfc..760b8be6975f 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -39,6 +39,7 @@
39#include <linux/io.h> 39#include <linux/io.h>
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/i2c-omap.h> 41#include <linux/i2c-omap.h>
42#include <linux/pm_runtime.h>
42 43
43/* I2C controller revisions */ 44/* I2C controller revisions */
44#define OMAP_I2C_REV_2 0x20 45#define OMAP_I2C_REV_2 0x20
@@ -175,8 +176,6 @@ struct omap_i2c_dev {
175 void __iomem *base; /* virtual */ 176 void __iomem *base; /* virtual */
176 int irq; 177 int irq;
177 int reg_shift; /* bit shift for I2C register addresses */ 178 int reg_shift; /* bit shift for I2C register addresses */
178 struct clk *iclk; /* Interface clock */
179 struct clk *fclk; /* Functional clock */
180 struct completion cmd_complete; 179 struct completion cmd_complete;
181 struct resource *ioarea; 180 struct resource *ioarea;
182 u32 latency; /* maximum mpu wkup latency */ 181 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 (i2c_dev->regs[reg] << i2c_dev->reg_shift)); 264 (i2c_dev->regs[reg] << i2c_dev->reg_shift));
266} 265}
267 266
268static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev) 267static void omap_i2c_unidle(struct omap_i2c_dev *dev)
269{ 268{
270 int ret; 269 struct platform_device *pdev;
270 struct omap_i2c_bus_platform_data *pdata;
271 271
272 dev->iclk = clk_get(dev->dev, "ick"); 272 WARN_ON(!dev->idle);
273 if (IS_ERR(dev->iclk)) {
274 ret = PTR_ERR(dev->iclk);
275 dev->iclk = NULL;
276 return ret;
277 }
278 273
279 dev->fclk = clk_get(dev->dev, "fck"); 274 pdev = to_platform_device(dev->dev);
280 if (IS_ERR(dev->fclk)) { 275 pdata = pdev->dev.platform_data;
281 ret = PTR_ERR(dev->fclk);
282 if (dev->iclk != NULL) {
283 clk_put(dev->iclk);
284 dev->iclk = NULL;
285 }
286 dev->fclk = NULL;
287 return ret;
288 }
289 276
290 return 0; 277 pm_runtime_get_sync(&pdev->dev);
291}
292 278
293static void omap_i2c_put_clocks(struct omap_i2c_dev *dev)
294{
295 clk_put(dev->fclk);
296 dev->fclk = NULL;
297 clk_put(dev->iclk);
298 dev->iclk = NULL;
299}
300
301static void omap_i2c_unidle(struct omap_i2c_dev *dev)
302{
303 WARN_ON(!dev->idle);
304
305 clk_enable(dev->iclk);
306 clk_enable(dev->fclk);
307 if (cpu_is_omap34xx()) { 279 if (cpu_is_omap34xx()) {
308 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); 280 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
309 omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); 281 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 298
327static void omap_i2c_idle(struct omap_i2c_dev *dev) 299static void omap_i2c_idle(struct omap_i2c_dev *dev)
328{ 300{
301 struct platform_device *pdev;
302 struct omap_i2c_bus_platform_data *pdata;
329 u16 iv; 303 u16 iv;
330 304
331 WARN_ON(dev->idle); 305 WARN_ON(dev->idle);
332 306
307 pdev = to_platform_device(dev->dev);
308 pdata = pdev->dev.platform_data;
309
333 dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); 310 dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
334 if (dev->rev >= OMAP_I2C_REV_ON_4430) 311 if (dev->rev >= OMAP_I2C_REV_ON_4430)
335 omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1); 312 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 omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); 322 omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
346 } 323 }
347 dev->idle = 1; 324 dev->idle = 1;
348 clk_disable(dev->fclk); 325
349 clk_disable(dev->iclk); 326 pm_runtime_put_sync(&pdev->dev);
350} 327}
351 328
352static int omap_i2c_init(struct omap_i2c_dev *dev) 329static int omap_i2c_init(struct omap_i2c_dev *dev)
@@ -356,6 +333,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
356 unsigned long fclk_rate = 12000000; 333 unsigned long fclk_rate = 12000000;
357 unsigned long timeout; 334 unsigned long timeout;
358 unsigned long internal_clk = 0; 335 unsigned long internal_clk = 0;
336 struct clk *fclk;
359 337
360 if (dev->rev >= OMAP_I2C_REV_2) { 338 if (dev->rev >= OMAP_I2C_REV_2) {
361 /* Disable I2C controller before soft reset */ 339 /* Disable I2C controller before soft reset */
@@ -414,7 +392,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
414 * always returns 12MHz for the functional clock, we can 392 * always returns 12MHz for the functional clock, we can
415 * do this bit unconditionally. 393 * do this bit unconditionally.
416 */ 394 */
417 fclk_rate = clk_get_rate(dev->fclk); 395 fclk = clk_get(dev->dev, "fck");
396 fclk_rate = clk_get_rate(fclk);
397 clk_put(fclk);
418 398
419 /* TRM for 5912 says the I2C clock must be prescaled to be 399 /* TRM for 5912 says the I2C clock must be prescaled to be
420 * between 7 - 12 MHz. The XOR input clock is typically 400 * 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 internal_clk = 9600; 423 internal_clk = 9600;
444 else 424 else
445 internal_clk = 4000; 425 internal_clk = 4000;
446 fclk_rate = clk_get_rate(dev->fclk) / 1000; 426 fclk = clk_get(dev->dev, "fck");
427 fclk_rate = clk_get_rate(fclk) / 1000;
428 clk_put(fclk);
447 429
448 /* Compute prescaler divisor */ 430 /* Compute prescaler divisor */
449 psc = fclk_rate / internal_clk; 431 psc = fclk_rate / internal_clk;
@@ -1048,14 +1030,12 @@ omap_i2c_probe(struct platform_device *pdev)
1048 else 1030 else
1049 dev->reg_shift = 2; 1031 dev->reg_shift = 2;
1050 1032
1051 if ((r = omap_i2c_get_clocks(dev)) != 0)
1052 goto err_iounmap;
1053
1054 if (cpu_is_omap44xx()) 1033 if (cpu_is_omap44xx())
1055 dev->regs = (u8 *) omap4_reg_map; 1034 dev->regs = (u8 *) omap4_reg_map;
1056 else 1035 else
1057 dev->regs = (u8 *) reg_map; 1036 dev->regs = (u8 *) reg_map;
1058 1037
1038 pm_runtime_enable(&pdev->dev);
1059 omap_i2c_unidle(dev); 1039 omap_i2c_unidle(dev);
1060 1040
1061 dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; 1041 dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
@@ -1127,8 +1107,6 @@ err_free_irq:
1127err_unuse_clocks: 1107err_unuse_clocks:
1128 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); 1108 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
1129 omap_i2c_idle(dev); 1109 omap_i2c_idle(dev);
1130 omap_i2c_put_clocks(dev);
1131err_iounmap:
1132 iounmap(dev->base); 1110 iounmap(dev->base);
1133err_free_mem: 1111err_free_mem:
1134 platform_set_drvdata(pdev, NULL); 1112 platform_set_drvdata(pdev, NULL);
@@ -1150,7 +1128,6 @@ omap_i2c_remove(struct platform_device *pdev)
1150 free_irq(dev->irq, dev); 1128 free_irq(dev->irq, dev);
1151 i2c_del_adapter(&dev->adapter); 1129 i2c_del_adapter(&dev->adapter);
1152 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); 1130 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
1153 omap_i2c_put_clocks(dev);
1154 iounmap(dev->base); 1131 iounmap(dev->base);
1155 kfree(dev); 1132 kfree(dev);
1156 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1133 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);