mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-25 05:34:00 +08:00
i2c: designware: Add support for an interface clock
The Synopsys I2C Controller has an interface clock, but most SoCs hide this away. However, on some SoCs you need to explicitly enable the interface clock in order to access the registers. Therefore, add support for an optional interface clock. Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com> Signed-off-by: Gareth Williams <gareth.williams.jx@renesas.com> Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
This commit is contained in:
parent
bdfdf4b2ba
commit
c62ebb3d5f
@ -251,13 +251,27 @@ unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev)
|
|||||||
|
|
||||||
int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare)
|
int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (IS_ERR(dev->clk))
|
if (IS_ERR(dev->clk))
|
||||||
return PTR_ERR(dev->clk);
|
return PTR_ERR(dev->clk);
|
||||||
|
|
||||||
if (prepare)
|
if (prepare) {
|
||||||
return clk_prepare_enable(dev->clk);
|
/* Optional interface clock */
|
||||||
|
ret = clk_prepare_enable(dev->pclk);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = clk_prepare_enable(dev->clk);
|
||||||
|
if (ret)
|
||||||
|
clk_disable_unprepare(dev->pclk);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
clk_disable_unprepare(dev->clk);
|
clk_disable_unprepare(dev->clk);
|
||||||
|
clk_disable_unprepare(dev->pclk);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(i2c_dw_prepare_clk);
|
EXPORT_SYMBOL_GPL(i2c_dw_prepare_clk);
|
||||||
|
@ -177,6 +177,7 @@
|
|||||||
* @base: IO registers pointer
|
* @base: IO registers pointer
|
||||||
* @cmd_complete: tx completion indicator
|
* @cmd_complete: tx completion indicator
|
||||||
* @clk: input reference clock
|
* @clk: input reference clock
|
||||||
|
* @pclk: clock required to access the registers
|
||||||
* @slave: represent an I2C slave device
|
* @slave: represent an I2C slave device
|
||||||
* @cmd_err: run time hadware error code
|
* @cmd_err: run time hadware error code
|
||||||
* @msgs: points to an array of messages currently being transferred
|
* @msgs: points to an array of messages currently being transferred
|
||||||
@ -227,6 +228,7 @@ struct dw_i2c_dev {
|
|||||||
void __iomem *ext;
|
void __iomem *ext;
|
||||||
struct completion cmd_complete;
|
struct completion cmd_complete;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
struct clk *pclk;
|
||||||
struct reset_control *rst;
|
struct reset_control *rst;
|
||||||
struct i2c_client *slave;
|
struct i2c_client *slave;
|
||||||
u32 (*get_clk_rate_khz) (struct dw_i2c_dev *dev);
|
u32 (*get_clk_rate_khz) (struct dw_i2c_dev *dev);
|
||||||
|
@ -344,6 +344,11 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
|
|||||||
else
|
else
|
||||||
i2c_dw_configure_master(dev);
|
i2c_dw_configure_master(dev);
|
||||||
|
|
||||||
|
/* Optional interface clock */
|
||||||
|
dev->pclk = devm_clk_get_optional(&pdev->dev, "pclk");
|
||||||
|
if (IS_ERR(dev->pclk))
|
||||||
|
return PTR_ERR(dev->pclk);
|
||||||
|
|
||||||
dev->clk = devm_clk_get(&pdev->dev, NULL);
|
dev->clk = devm_clk_get(&pdev->dev, NULL);
|
||||||
if (!i2c_dw_prepare_clk(dev, true)) {
|
if (!i2c_dw_prepare_clk(dev, true)) {
|
||||||
u64 clk_khz;
|
u64 clk_khz;
|
||||||
|
Loading…
Reference in New Issue
Block a user