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>
This commit is contained in:
parent
a9e94bb80e
commit
1534156e99
|
@ -25,6 +25,15 @@ default frequency is 100kHz
|
||||||
whenever you're using the "allwinner,sun6i-a31-i2c"
|
whenever you're using the "allwinner,sun6i-a31-i2c"
|
||||||
compatible.
|
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:
|
Examples:
|
||||||
|
|
||||||
i2c@11000 {
|
i2c@11000 {
|
||||||
|
@ -42,3 +51,14 @@ For the Armada XP:
|
||||||
interrupts = <29>;
|
interrupts = <29>;
|
||||||
clock-frequency = <100000>;
|
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>, <®_clock>;
|
||||||
|
};
|
||||||
|
|
|
@ -135,6 +135,7 @@ struct mv64xxx_i2c_data {
|
||||||
u32 freq_m;
|
u32 freq_m;
|
||||||
u32 freq_n;
|
u32 freq_n;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
struct clk *reg_clk;
|
||||||
wait_queue_head_t waitq;
|
wait_queue_head_t waitq;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct i2c_msg *msg;
|
struct i2c_msg *msg;
|
||||||
|
@ -894,13 +895,20 @@ mv64xxx_i2c_probe(struct platform_device *pd)
|
||||||
init_waitqueue_head(&drv_data->waitq);
|
init_waitqueue_head(&drv_data->waitq);
|
||||||
spin_lock_init(&drv_data->lock);
|
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);
|
drv_data->clk = devm_clk_get(&pd->dev, NULL);
|
||||||
if (IS_ERR(drv_data->clk) && PTR_ERR(drv_data->clk) == -EPROBE_DEFER)
|
if (IS_ERR(drv_data->clk) && PTR_ERR(drv_data->clk) == -EPROBE_DEFER)
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
if (!IS_ERR(drv_data->clk))
|
if (!IS_ERR(drv_data->clk))
|
||||||
clk_prepare_enable(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);
|
drv_data->irq = platform_get_irq(pd, 0);
|
||||||
|
|
||||||
if (pdata) {
|
if (pdata) {
|
||||||
|
@ -950,6 +958,7 @@ exit_free_irq:
|
||||||
exit_reset:
|
exit_reset:
|
||||||
reset_control_assert(drv_data->rstc);
|
reset_control_assert(drv_data->rstc);
|
||||||
exit_clk:
|
exit_clk:
|
||||||
|
clk_disable_unprepare(drv_data->reg_clk);
|
||||||
clk_disable_unprepare(drv_data->clk);
|
clk_disable_unprepare(drv_data->clk);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -963,6 +972,7 @@ mv64xxx_i2c_remove(struct platform_device *dev)
|
||||||
i2c_del_adapter(&drv_data->adapter);
|
i2c_del_adapter(&drv_data->adapter);
|
||||||
free_irq(drv_data->irq, drv_data);
|
free_irq(drv_data->irq, drv_data);
|
||||||
reset_control_assert(drv_data->rstc);
|
reset_control_assert(drv_data->rstc);
|
||||||
|
clk_disable_unprepare(drv_data->reg_clk);
|
||||||
clk_disable_unprepare(drv_data->clk);
|
clk_disable_unprepare(drv_data->clk);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue