Commit 1534156e authored by Gregory CLEMENT's avatar Gregory CLEMENT Committed by Wolfram Sang

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: default avatarGregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent a9e94bb8
......@@ -25,6 +25,15 @@ default frequency is 100kHz
whenever you're using the "allwinner,sun6i-a31-i2c"
compatible.
- clocks: : pointers to the reference clocks for this device, the
first one is the one used for the clock on the i2c bus,
the second one is the clock used to acces the registers
of the controller
- clock-names : names of used clocks, mandatory if the second clock is
used, the name must be "core", and "reg" (the latter is
only for Armada 7K/8K).
Examples:
i2c@11000 {
......@@ -42,3 +51,14 @@ For the Armada XP:
interrupts = <29>;
clock-frequency = <100000>;
};
For the Armada 7040:
i2c@701000 {
compatible = "marvell,mv78230-i2c";
reg = <0x701000 0x20>;
interrupts = <29>;
clock-frequency = <100000>;
clock-names = "core", "reg";
clocks = <&core_clock>, <&reg_clock>;
};
......@@ -135,6 +135,7 @@ struct mv64xxx_i2c_data {
u32 freq_m;
u32 freq_n;
struct clk *clk;
struct clk *reg_clk;
wait_queue_head_t waitq;
spinlock_t lock;
struct i2c_msg *msg;
......@@ -894,13 +895,20 @@ mv64xxx_i2c_probe(struct platform_device *pd)
init_waitqueue_head(&drv_data->waitq);
spin_lock_init(&drv_data->lock);
/* Not all platforms have a clk */
/* Not all platforms have clocks */
drv_data->clk = devm_clk_get(&pd->dev, NULL);
if (IS_ERR(drv_data->clk) && PTR_ERR(drv_data->clk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (!IS_ERR(drv_data->clk))
clk_prepare_enable(drv_data->clk);
drv_data->reg_clk = devm_clk_get(&pd->dev, "reg");
if (IS_ERR(drv_data->reg_clk) &&
PTR_ERR(drv_data->reg_clk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (!IS_ERR(drv_data->reg_clk))
clk_prepare_enable(drv_data->reg_clk);
drv_data->irq = platform_get_irq(pd, 0);
if (pdata) {
......@@ -950,6 +958,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
exit_reset:
reset_control_assert(drv_data->rstc);
exit_clk:
clk_disable_unprepare(drv_data->reg_clk);
clk_disable_unprepare(drv_data->clk);
return rc;
......@@ -963,6 +972,7 @@ mv64xxx_i2c_remove(struct platform_device *dev)
i2c_del_adapter(&drv_data->adapter);
free_irq(drv_data->irq, drv_data);
reset_control_assert(drv_data->rstc);
clk_disable_unprepare(drv_data->reg_clk);
clk_disable_unprepare(drv_data->clk);
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment