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 | ||