diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-11-20 06:12:26 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-02-12 12:32:39 -0500 |
| commit | 0321cb83e1c3f3a4282bd620c6cec78c5b80b572 (patch) | |
| tree | 5a72693de37c889cb5339a1556cd4ab5967a0864 | |
| parent | a0dcf19f59d4f37150a6b7e115925d72aca15293 (diff) | |
ARM: PNX4008: move i2c clock start/stop into driver
Acked-by: Vitaly Wool <vitalywool@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
| -rw-r--r-- | arch/arm/mach-pnx4008/i2c.c | 36 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-pnx.c | 39 | ||||
| -rw-r--r-- | include/linux/i2c-pnx.h | 4 |
3 files changed, 32 insertions, 47 deletions
diff --git a/arch/arm/mach-pnx4008/i2c.c b/arch/arm/mach-pnx4008/i2c.c index 707d819f1280..14b4906bec2f 100644 --- a/arch/arm/mach-pnx4008/i2c.c +++ b/arch/arm/mach-pnx4008/i2c.c | |||
| @@ -18,36 +18,6 @@ | |||
| 18 | #include <mach/irqs.h> | 18 | #include <mach/irqs.h> |
| 19 | #include <mach/i2c.h> | 19 | #include <mach/i2c.h> |
| 20 | 20 | ||
| 21 | static int set_clock_run(struct platform_device *pdev) | ||
| 22 | { | ||
| 23 | struct clk *clk; | ||
| 24 | int retval = 0; | ||
| 25 | |||
| 26 | clk = clk_get(&pdev->dev, NULL); | ||
| 27 | if (!IS_ERR(clk)) { | ||
| 28 | clk_set_rate(clk, 1); | ||
| 29 | clk_put(clk); | ||
| 30 | } else | ||
| 31 | retval = -ENOENT; | ||
| 32 | |||
| 33 | return retval; | ||
| 34 | } | ||
| 35 | |||
| 36 | static int set_clock_stop(struct platform_device *pdev) | ||
| 37 | { | ||
| 38 | struct clk *clk; | ||
| 39 | int retval = 0; | ||
| 40 | |||
| 41 | clk = clk_get(&pdev->dev, NULL); | ||
| 42 | if (!IS_ERR(clk)) { | ||
| 43 | clk_set_rate(clk, 0); | ||
| 44 | clk_put(clk); | ||
| 45 | } else | ||
| 46 | retval = -ENOENT; | ||
| 47 | |||
| 48 | return retval; | ||
| 49 | } | ||
| 50 | |||
| 51 | static u32 calculate_input_freq(struct platform_device *pdev) | 21 | static u32 calculate_input_freq(struct platform_device *pdev) |
| 52 | { | 22 | { |
| 53 | return HCLK_MHZ; | 23 | return HCLK_MHZ; |
| @@ -85,22 +55,16 @@ static struct i2c_adapter pnx_adapter2 = { | |||
| 85 | 55 | ||
| 86 | static struct i2c_pnx_data i2c0_data = { | 56 | static struct i2c_pnx_data i2c0_data = { |
| 87 | .calculate_input_freq = calculate_input_freq, | 57 | .calculate_input_freq = calculate_input_freq, |
| 88 | .set_clock_run = set_clock_run, | ||
| 89 | .set_clock_stop = set_clock_stop, | ||
| 90 | .adapter = &pnx_adapter0, | 58 | .adapter = &pnx_adapter0, |
| 91 | }; | 59 | }; |
| 92 | 60 | ||
| 93 | static struct i2c_pnx_data i2c1_data = { | 61 | static struct i2c_pnx_data i2c1_data = { |
| 94 | .calculate_input_freq = calculate_input_freq, | 62 | .calculate_input_freq = calculate_input_freq, |
| 95 | .set_clock_run = set_clock_run, | ||
| 96 | .set_clock_stop = set_clock_stop, | ||
| 97 | .adapter = &pnx_adapter1, | 63 | .adapter = &pnx_adapter1, |
| 98 | }; | 64 | }; |
| 99 | 65 | ||
| 100 | static struct i2c_pnx_data i2c2_data = { | 66 | static struct i2c_pnx_data i2c2_data = { |
| 101 | .calculate_input_freq = calculate_input_freq, | 67 | .calculate_input_freq = calculate_input_freq, |
| 102 | .set_clock_run = set_clock_run, | ||
| 103 | .set_clock_stop = set_clock_stop, | ||
| 104 | .adapter = &pnx_adapter2, | 68 | .adapter = &pnx_adapter2, |
| 105 | }; | 69 | }; |
| 106 | 70 | ||
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index bc8075514e53..98462671cdf7 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c | |||
| @@ -20,6 +20,9 @@ | |||
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/i2c-pnx.h> | 21 | #include <linux/i2c-pnx.h> |
| 22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
| 23 | #include <linux/err.h> | ||
| 24 | #include <linux/clk.h> | ||
| 25 | |||
| 23 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
| 24 | #include <mach/i2c.h> | 27 | #include <mach/i2c.h> |
| 25 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
| @@ -550,13 +553,22 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev, | |||
| 550 | pm_message_t state) | 553 | pm_message_t state) |
| 551 | { | 554 | { |
| 552 | struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); | 555 | struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); |
| 553 | return i2c_pnx->set_clock_run(pdev); | 556 | struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; |
| 557 | |||
| 558 | /* FIXME: disable clock? */ | ||
| 559 | clk_set_rate(alg_data->clk, 1); | ||
| 560 | |||
| 561 | return 0; | ||
| 554 | } | 562 | } |
| 555 | 563 | ||
| 556 | static int i2c_pnx_controller_resume(struct platform_device *pdev) | 564 | static int i2c_pnx_controller_resume(struct platform_device *pdev) |
| 557 | { | 565 | { |
| 558 | struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); | 566 | struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); |
| 559 | return i2c_pnx->set_clock_run(pdev); | 567 | struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; |
| 568 | |||
| 569 | clk_set_rate(alg_data->clk, 1); | ||
| 570 | |||
| 571 | return 0; | ||
| 560 | } | 572 | } |
| 561 | #else | 573 | #else |
| 562 | #define i2c_pnx_controller_suspend NULL | 574 | #define i2c_pnx_controller_suspend NULL |
| @@ -580,6 +592,15 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) | |||
| 580 | 592 | ||
| 581 | platform_set_drvdata(pdev, i2c_pnx); | 593 | platform_set_drvdata(pdev, i2c_pnx); |
| 582 | 594 | ||
| 595 | i2c_pnx->adapter->algo = &pnx_algorithm; | ||
| 596 | alg_data = i2c_pnx->adapter->algo_data; | ||
| 597 | |||
| 598 | alg_data->clk = clk_get(&pdev->dev, NULL); | ||
| 599 | if (IS_ERR(alg_data->clk)) { | ||
| 600 | ret = PTR_ERR(alg_data->clk); | ||
| 601 | goto out_drvdata; | ||
| 602 | } | ||
| 603 | |||
| 583 | if (i2c_pnx->calculate_input_freq) | 604 | if (i2c_pnx->calculate_input_freq) |
| 584 | freq_mhz = i2c_pnx->calculate_input_freq(pdev); | 605 | freq_mhz = i2c_pnx->calculate_input_freq(pdev); |
| 585 | else { | 606 | else { |
| @@ -588,9 +609,6 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) | |||
| 588 | "%d MHz\n", freq_mhz); | 609 | "%d MHz\n", freq_mhz); |
| 589 | } | 610 | } |
| 590 | 611 | ||
| 591 | i2c_pnx->adapter->algo = &pnx_algorithm; | ||
| 592 | |||
| 593 | alg_data = i2c_pnx->adapter->algo_data; | ||
| 594 | init_timer(&alg_data->mif.timer); | 612 | init_timer(&alg_data->mif.timer); |
| 595 | alg_data->mif.timer.function = i2c_pnx_timeout; | 613 | alg_data->mif.timer.function = i2c_pnx_timeout; |
| 596 | alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; | 614 | alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; |
| @@ -602,7 +620,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) | |||
| 602 | "I/O region 0x%08x for I2C already in use.\n", | 620 | "I/O region 0x%08x for I2C already in use.\n", |
| 603 | alg_data->base); | 621 | alg_data->base); |
| 604 | ret = -ENODEV; | 622 | ret = -ENODEV; |
| 605 | goto out_drvdata; | 623 | goto out_clkget; |
| 606 | } | 624 | } |
| 607 | 625 | ||
| 608 | if (!(alg_data->ioaddr = | 626 | if (!(alg_data->ioaddr = |
| @@ -612,7 +630,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) | |||
| 612 | goto out_release; | 630 | goto out_release; |
| 613 | } | 631 | } |
| 614 | 632 | ||
| 615 | i2c_pnx->set_clock_run(pdev); | 633 | clk_set_rate(alg_data->clk, 1); |
| 616 | 634 | ||
| 617 | /* | 635 | /* |
| 618 | * Clock Divisor High This value is the number of system clocks | 636 | * Clock Divisor High This value is the number of system clocks |
| @@ -658,11 +676,13 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) | |||
| 658 | out_irq: | 676 | out_irq: |
| 659 | free_irq(alg_data->irq, i2c_pnx->adapter); | 677 | free_irq(alg_data->irq, i2c_pnx->adapter); |
| 660 | out_clock: | 678 | out_clock: |
| 661 | i2c_pnx->set_clock_stop(pdev); | 679 | clk_set_rate(alg_data->clk, 0); |
| 662 | out_unmap: | 680 | out_unmap: |
| 663 | iounmap((void *)alg_data->ioaddr); | 681 | iounmap((void *)alg_data->ioaddr); |
| 664 | out_release: | 682 | out_release: |
| 665 | release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); | 683 | release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); |
| 684 | out_clkget: | ||
| 685 | clk_put(alg_data->clk); | ||
| 666 | out_drvdata: | 686 | out_drvdata: |
| 667 | platform_set_drvdata(pdev, NULL); | 687 | platform_set_drvdata(pdev, NULL); |
| 668 | out: | 688 | out: |
| @@ -677,9 +697,10 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev) | |||
| 677 | 697 | ||
| 678 | free_irq(alg_data->irq, i2c_pnx->adapter); | 698 | free_irq(alg_data->irq, i2c_pnx->adapter); |
| 679 | i2c_del_adapter(adap); | 699 | i2c_del_adapter(adap); |
| 680 | i2c_pnx->set_clock_stop(pdev); | 700 | clk_set_rate(alg_data->clk, 0); |
| 681 | iounmap((void *)alg_data->ioaddr); | 701 | iounmap((void *)alg_data->ioaddr); |
| 682 | release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); | 702 | release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); |
| 703 | clk_put(alg_data->clk); | ||
| 683 | platform_set_drvdata(pdev, NULL); | 704 | platform_set_drvdata(pdev, NULL); |
| 684 | 705 | ||
| 685 | return 0; | 706 | return 0; |
diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h index 71de7f976adf..688e29262a43 100644 --- a/include/linux/i2c-pnx.h +++ b/include/linux/i2c-pnx.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #define __I2C_PNX_H__ | 13 | #define __I2C_PNX_H__ |
| 14 | 14 | ||
| 15 | struct platform_device; | 15 | struct platform_device; |
| 16 | struct clk; | ||
| 16 | 17 | ||
| 17 | struct i2c_pnx_mif { | 18 | struct i2c_pnx_mif { |
| 18 | int ret; /* Return value */ | 19 | int ret; /* Return value */ |
| @@ -29,12 +30,11 @@ struct i2c_pnx_algo_data { | |||
| 29 | int irq; | 30 | int irq; |
| 30 | struct i2c_pnx_mif mif; | 31 | struct i2c_pnx_mif mif; |
| 31 | int last; | 32 | int last; |
| 33 | struct clk *clk; | ||
| 32 | }; | 34 | }; |
| 33 | 35 | ||
| 34 | struct i2c_pnx_data { | 36 | struct i2c_pnx_data { |
| 35 | u32 (*calculate_input_freq) (struct platform_device *pdev); | 37 | u32 (*calculate_input_freq) (struct platform_device *pdev); |
| 36 | int (*set_clock_run) (struct platform_device *pdev); | ||
| 37 | int (*set_clock_stop) (struct platform_device *pdev); | ||
| 38 | struct i2c_adapter *adapter; | 38 | struct i2c_adapter *adapter; |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
