diff options
author | Gregory CLEMENT <gregory.clement@free-electrons.com> | 2018-01-16 11:35:39 -0500 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2018-01-26 12:51:03 -0500 |
commit | 1534156e999735fe0befad958e1447600c0c20e7 (patch) | |
tree | d846509f8e3b074a5af5e47e3b690f8c3fa7969c | |
parent | a9e94bb80ea6d53745eb5ca86597696735565fb3 (diff) |
i2c: mv64xxx: Fix clock resource by adding an optional bus clock
On Armada 7K/8K we need to explicitly enable the bus clock. The bus clock
is optional because not all the SoCs need them but at least for Armada
7K/8K it is actually mandatory.
The binding documentation is updating accordingly.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r-- | Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt | 20 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-mv64xxx.c | 12 |
2 files changed, 31 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt index 5c30026921ae..0ffe65a316ae 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt | |||
@@ -25,6 +25,15 @@ default frequency is 100kHz | |||
25 | whenever you're using the "allwinner,sun6i-a31-i2c" | 25 | whenever you're using the "allwinner,sun6i-a31-i2c" |
26 | compatible. | 26 | compatible. |
27 | 27 | ||
28 | - clocks: : pointers to the reference clocks for this device, the | ||
29 | first one is the one used for the clock on the i2c bus, | ||
30 | the second one is the clock used to acces the registers | ||
31 | of the controller | ||
32 | |||
33 | - clock-names : names of used clocks, mandatory if the second clock is | ||
34 | used, the name must be "core", and "reg" (the latter is | ||
35 | only for Armada 7K/8K). | ||
36 | |||
28 | Examples: | 37 | Examples: |
29 | 38 | ||
30 | i2c@11000 { | 39 | i2c@11000 { |
@@ -42,3 +51,14 @@ For the Armada XP: | |||
42 | interrupts = <29>; | 51 | interrupts = <29>; |
43 | clock-frequency = <100000>; | 52 | clock-frequency = <100000>; |
44 | }; | 53 | }; |
54 | |||
55 | For the Armada 7040: | ||
56 | |||
57 | i2c@701000 { | ||
58 | compatible = "marvell,mv78230-i2c"; | ||
59 | reg = <0x701000 0x20>; | ||
60 | interrupts = <29>; | ||
61 | clock-frequency = <100000>; | ||
62 | clock-names = "core", "reg"; | ||
63 | clocks = <&core_clock>, <®_clock>; | ||
64 | }; | ||
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index f69066266faa..440fe4a96e68 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
@@ -135,6 +135,7 @@ struct mv64xxx_i2c_data { | |||
135 | u32 freq_m; | 135 | u32 freq_m; |
136 | u32 freq_n; | 136 | u32 freq_n; |
137 | struct clk *clk; | 137 | struct clk *clk; |
138 | struct clk *reg_clk; | ||
138 | wait_queue_head_t waitq; | 139 | wait_queue_head_t waitq; |
139 | spinlock_t lock; | 140 | spinlock_t lock; |
140 | struct i2c_msg *msg; | 141 | struct i2c_msg *msg; |
@@ -894,13 +895,20 @@ mv64xxx_i2c_probe(struct platform_device *pd) | |||
894 | init_waitqueue_head(&drv_data->waitq); | 895 | init_waitqueue_head(&drv_data->waitq); |
895 | spin_lock_init(&drv_data->lock); | 896 | spin_lock_init(&drv_data->lock); |
896 | 897 | ||
897 | /* Not all platforms have a clk */ | 898 | /* Not all platforms have clocks */ |
898 | drv_data->clk = devm_clk_get(&pd->dev, NULL); | 899 | drv_data->clk = devm_clk_get(&pd->dev, NULL); |
899 | if (IS_ERR(drv_data->clk) && PTR_ERR(drv_data->clk) == -EPROBE_DEFER) | 900 | if (IS_ERR(drv_data->clk) && PTR_ERR(drv_data->clk) == -EPROBE_DEFER) |
900 | return -EPROBE_DEFER; | 901 | return -EPROBE_DEFER; |
901 | if (!IS_ERR(drv_data->clk)) | 902 | if (!IS_ERR(drv_data->clk)) |
902 | clk_prepare_enable(drv_data->clk); | 903 | clk_prepare_enable(drv_data->clk); |
903 | 904 | ||
905 | drv_data->reg_clk = devm_clk_get(&pd->dev, "reg"); | ||
906 | if (IS_ERR(drv_data->reg_clk) && | ||
907 | PTR_ERR(drv_data->reg_clk) == -EPROBE_DEFER) | ||
908 | return -EPROBE_DEFER; | ||
909 | if (!IS_ERR(drv_data->reg_clk)) | ||
910 | clk_prepare_enable(drv_data->reg_clk); | ||
911 | |||
904 | drv_data->irq = platform_get_irq(pd, 0); | 912 | drv_data->irq = platform_get_irq(pd, 0); |
905 | 913 | ||
906 | if (pdata) { | 914 | if (pdata) { |
@@ -950,6 +958,7 @@ exit_free_irq: | |||
950 | exit_reset: | 958 | exit_reset: |
951 | reset_control_assert(drv_data->rstc); | 959 | reset_control_assert(drv_data->rstc); |
952 | exit_clk: | 960 | exit_clk: |
961 | clk_disable_unprepare(drv_data->reg_clk); | ||
953 | clk_disable_unprepare(drv_data->clk); | 962 | clk_disable_unprepare(drv_data->clk); |
954 | 963 | ||
955 | return rc; | 964 | return rc; |
@@ -963,6 +972,7 @@ mv64xxx_i2c_remove(struct platform_device *dev) | |||
963 | i2c_del_adapter(&drv_data->adapter); | 972 | i2c_del_adapter(&drv_data->adapter); |
964 | free_irq(drv_data->irq, drv_data); | 973 | free_irq(drv_data->irq, drv_data); |
965 | reset_control_assert(drv_data->rstc); | 974 | reset_control_assert(drv_data->rstc); |
975 | clk_disable_unprepare(drv_data->reg_clk); | ||
966 | clk_disable_unprepare(drv_data->clk); | 976 | clk_disable_unprepare(drv_data->clk); |
967 | 977 | ||
968 | return 0; | 978 | return 0; |