| .. | .. |
|---|
| 43 | 43 | #include <linux/module.h> |
|---|
| 44 | 44 | #include <linux/of.h> |
|---|
| 45 | 45 | #include <linux/platform_device.h> |
|---|
| 46 | +#include <linux/pm_runtime.h> |
|---|
| 46 | 47 | |
|---|
| 47 | 48 | #define RIIC_ICCR1 0x00 |
|---|
| 48 | 49 | #define RIIC_ICCR2 0x04 |
|---|
| .. | .. |
|---|
| 112 | 113 | { |
|---|
| 113 | 114 | struct riic_dev *riic = i2c_get_adapdata(adap); |
|---|
| 114 | 115 | unsigned long time_left; |
|---|
| 115 | | - int i, ret; |
|---|
| 116 | + int i; |
|---|
| 116 | 117 | u8 start_bit; |
|---|
| 117 | 118 | |
|---|
| 118 | | - ret = clk_prepare_enable(riic->clk); |
|---|
| 119 | | - if (ret) |
|---|
| 120 | | - return ret; |
|---|
| 119 | + pm_runtime_get_sync(adap->dev.parent); |
|---|
| 121 | 120 | |
|---|
| 122 | 121 | if (readb(riic->base + RIIC_ICCR2) & ICCR2_BBSY) { |
|---|
| 123 | 122 | riic->err = -EBUSY; |
|---|
| .. | .. |
|---|
| 150 | 149 | } |
|---|
| 151 | 150 | |
|---|
| 152 | 151 | out: |
|---|
| 153 | | - clk_disable_unprepare(riic->clk); |
|---|
| 152 | + pm_runtime_put(adap->dev.parent); |
|---|
| 154 | 153 | |
|---|
| 155 | 154 | return riic->err ?: num; |
|---|
| 156 | 155 | } |
|---|
| .. | .. |
|---|
| 282 | 281 | |
|---|
| 283 | 282 | static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t) |
|---|
| 284 | 283 | { |
|---|
| 285 | | - int ret; |
|---|
| 284 | + int ret = 0; |
|---|
| 286 | 285 | unsigned long rate; |
|---|
| 287 | 286 | int total_ticks, cks, brl, brh; |
|---|
| 288 | 287 | |
|---|
| 289 | | - ret = clk_prepare_enable(riic->clk); |
|---|
| 290 | | - if (ret) |
|---|
| 291 | | - return ret; |
|---|
| 288 | + pm_runtime_get_sync(riic->adapter.dev.parent); |
|---|
| 292 | 289 | |
|---|
| 293 | | - if (t->bus_freq_hz > 400000) { |
|---|
| 290 | + if (t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ) { |
|---|
| 294 | 291 | dev_err(&riic->adapter.dev, |
|---|
| 295 | | - "unsupported bus speed (%dHz). 400000 max\n", |
|---|
| 296 | | - t->bus_freq_hz); |
|---|
| 297 | | - clk_disable_unprepare(riic->clk); |
|---|
| 298 | | - return -EINVAL; |
|---|
| 292 | + "unsupported bus speed (%dHz). %d max\n", |
|---|
| 293 | + t->bus_freq_hz, I2C_MAX_FAST_MODE_FREQ); |
|---|
| 294 | + ret = -EINVAL; |
|---|
| 295 | + goto out; |
|---|
| 299 | 296 | } |
|---|
| 300 | 297 | |
|---|
| 301 | 298 | rate = clk_get_rate(riic->clk); |
|---|
| .. | .. |
|---|
| 333 | 330 | if (brl > (0x1F + 3)) { |
|---|
| 334 | 331 | dev_err(&riic->adapter.dev, "invalid speed (%lu). Too slow.\n", |
|---|
| 335 | 332 | (unsigned long)t->bus_freq_hz); |
|---|
| 336 | | - clk_disable_unprepare(riic->clk); |
|---|
| 337 | | - return -EINVAL; |
|---|
| 333 | + ret = -EINVAL; |
|---|
| 334 | + goto out; |
|---|
| 338 | 335 | } |
|---|
| 339 | 336 | |
|---|
| 340 | 337 | brh = total_ticks - brl; |
|---|
| .. | .. |
|---|
| 379 | 376 | |
|---|
| 380 | 377 | riic_clear_set_bit(riic, ICCR1_IICRST, 0, RIIC_ICCR1); |
|---|
| 381 | 378 | |
|---|
| 382 | | - clk_disable_unprepare(riic->clk); |
|---|
| 383 | | - |
|---|
| 384 | | - return 0; |
|---|
| 379 | +out: |
|---|
| 380 | + pm_runtime_put(riic->adapter.dev.parent); |
|---|
| 381 | + return ret; |
|---|
| 385 | 382 | } |
|---|
| 386 | 383 | |
|---|
| 387 | 384 | static struct riic_irq_desc riic_irqs[] = { |
|---|
| .. | .. |
|---|
| 440 | 437 | |
|---|
| 441 | 438 | i2c_parse_fw_timings(&pdev->dev, &i2c_t, true); |
|---|
| 442 | 439 | |
|---|
| 440 | + pm_runtime_enable(&pdev->dev); |
|---|
| 441 | + |
|---|
| 443 | 442 | ret = riic_init_hw(riic, &i2c_t); |
|---|
| 444 | 443 | if (ret) |
|---|
| 445 | | - return ret; |
|---|
| 446 | | - |
|---|
| 444 | + goto out; |
|---|
| 447 | 445 | |
|---|
| 448 | 446 | ret = i2c_add_adapter(adap); |
|---|
| 449 | 447 | if (ret) |
|---|
| 450 | | - return ret; |
|---|
| 448 | + goto out; |
|---|
| 451 | 449 | |
|---|
| 452 | 450 | platform_set_drvdata(pdev, riic); |
|---|
| 453 | 451 | |
|---|
| 454 | 452 | dev_info(&pdev->dev, "registered with %dHz bus speed\n", |
|---|
| 455 | 453 | i2c_t.bus_freq_hz); |
|---|
| 456 | 454 | return 0; |
|---|
| 455 | + |
|---|
| 456 | +out: |
|---|
| 457 | + pm_runtime_disable(&pdev->dev); |
|---|
| 458 | + return ret; |
|---|
| 457 | 459 | } |
|---|
| 458 | 460 | |
|---|
| 459 | 461 | static int riic_i2c_remove(struct platform_device *pdev) |
|---|
| 460 | 462 | { |
|---|
| 461 | 463 | struct riic_dev *riic = platform_get_drvdata(pdev); |
|---|
| 462 | 464 | |
|---|
| 465 | + pm_runtime_get_sync(&pdev->dev); |
|---|
| 463 | 466 | writeb(0, riic->base + RIIC_ICIER); |
|---|
| 467 | + pm_runtime_put(&pdev->dev); |
|---|
| 464 | 468 | i2c_del_adapter(&riic->adapter); |
|---|
| 469 | + pm_runtime_disable(&pdev->dev); |
|---|
| 465 | 470 | |
|---|
| 466 | 471 | return 0; |
|---|
| 467 | 472 | } |
|---|