mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 06:57:57 +00:00
235 lines
7.0 KiB
Diff
235 lines
7.0 KiB
Diff
|
From cc6faa5e0772296d815fd298c231277d47308a6a Mon Sep 17 00:00:00 2001
|
||
|
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||
|
Date: Thu, 3 Mar 2022 10:15:47 +0100
|
||
|
Subject: [PATCH 06/16] i2c: mt65xx: Simplify with clk-bulk
|
||
|
|
||
|
Since depending on the SoC or specific bus functionality some clocks
|
||
|
may be optional, we cannot get the benefit of using devm_clk_bulk_get()
|
||
|
but, by migrating to clk-bulk, we are able to remove the custom functions
|
||
|
mtk_i2c_clock_enable() and mtk_i2c_clock_disable(), increasing common
|
||
|
APIs usage, hence (lightly) decreasing kernel footprint.
|
||
|
|
||
|
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||
|
Reviewed-by: Qii Wang <qii.wang@mediatek.com>
|
||
|
Signed-off-by: Wolfram Sang <wsa@kernel.org>
|
||
|
---
|
||
|
drivers/i2c/busses/i2c-mt65xx.c | 124 +++++++++++++-------------------
|
||
|
1 file changed, 51 insertions(+), 73 deletions(-)
|
||
|
|
||
|
--- a/drivers/i2c/busses/i2c-mt65xx.c
|
||
|
+++ b/drivers/i2c/busses/i2c-mt65xx.c
|
||
|
@@ -86,6 +86,27 @@
|
||
|
|
||
|
#define I2C_DRV_NAME "i2c-mt65xx"
|
||
|
|
||
|
+/**
|
||
|
+ * enum i2c_mt65xx_clks - Clocks enumeration for MT65XX I2C
|
||
|
+ *
|
||
|
+ * @I2C_MT65XX_CLK_MAIN: main clock for i2c bus
|
||
|
+ * @I2C_MT65XX_CLK_DMA: DMA clock for i2c via DMA
|
||
|
+ * @I2C_MT65XX_CLK_PMIC: PMIC clock for i2c from PMIC
|
||
|
+ * @I2C_MT65XX_CLK_ARB: Arbitrator clock for i2c
|
||
|
+ * @I2C_MT65XX_CLK_MAX: Number of supported clocks
|
||
|
+ */
|
||
|
+enum i2c_mt65xx_clks {
|
||
|
+ I2C_MT65XX_CLK_MAIN = 0,
|
||
|
+ I2C_MT65XX_CLK_DMA,
|
||
|
+ I2C_MT65XX_CLK_PMIC,
|
||
|
+ I2C_MT65XX_CLK_ARB,
|
||
|
+ I2C_MT65XX_CLK_MAX
|
||
|
+};
|
||
|
+
|
||
|
+static const char * const i2c_mt65xx_clk_ids[I2C_MT65XX_CLK_MAX] = {
|
||
|
+ "main", "dma", "pmic", "arb"
|
||
|
+};
|
||
|
+
|
||
|
enum DMA_REGS_OFFSET {
|
||
|
OFFSET_INT_FLAG = 0x0,
|
||
|
OFFSET_INT_EN = 0x04,
|
||
|
@@ -244,10 +265,7 @@ struct mtk_i2c {
|
||
|
/* set in i2c probe */
|
||
|
void __iomem *base; /* i2c base addr */
|
||
|
void __iomem *pdmabase; /* dma base address*/
|
||
|
- struct clk *clk_main; /* main clock for i2c bus */
|
||
|
- struct clk *clk_dma; /* DMA clock for i2c via DMA */
|
||
|
- struct clk *clk_pmic; /* PMIC clock for i2c from PMIC */
|
||
|
- struct clk *clk_arb; /* Arbitrator clock for i2c */
|
||
|
+ struct clk_bulk_data clocks[I2C_MT65XX_CLK_MAX]; /* clocks for i2c */
|
||
|
bool have_pmic; /* can use i2c pins from PMIC */
|
||
|
bool use_push_pull; /* IO config push-pull mode */
|
||
|
|
||
|
@@ -449,52 +467,6 @@ static void mtk_i2c_writew(struct mtk_i2
|
||
|
writew(val, i2c->base + i2c->dev_comp->regs[reg]);
|
||
|
}
|
||
|
|
||
|
-static int mtk_i2c_clock_enable(struct mtk_i2c *i2c)
|
||
|
-{
|
||
|
- int ret;
|
||
|
-
|
||
|
- ret = clk_prepare_enable(i2c->clk_dma);
|
||
|
- if (ret)
|
||
|
- return ret;
|
||
|
-
|
||
|
- ret = clk_prepare_enable(i2c->clk_main);
|
||
|
- if (ret)
|
||
|
- goto err_main;
|
||
|
-
|
||
|
- if (i2c->have_pmic) {
|
||
|
- ret = clk_prepare_enable(i2c->clk_pmic);
|
||
|
- if (ret)
|
||
|
- goto err_pmic;
|
||
|
- }
|
||
|
-
|
||
|
- if (i2c->clk_arb) {
|
||
|
- ret = clk_prepare_enable(i2c->clk_arb);
|
||
|
- if (ret)
|
||
|
- goto err_arb;
|
||
|
- }
|
||
|
-
|
||
|
- return 0;
|
||
|
-
|
||
|
-err_arb:
|
||
|
- clk_disable_unprepare(i2c->clk_pmic);
|
||
|
-err_pmic:
|
||
|
- clk_disable_unprepare(i2c->clk_main);
|
||
|
-err_main:
|
||
|
- clk_disable_unprepare(i2c->clk_dma);
|
||
|
-
|
||
|
- return ret;
|
||
|
-}
|
||
|
-
|
||
|
-static void mtk_i2c_clock_disable(struct mtk_i2c *i2c)
|
||
|
-{
|
||
|
- clk_disable_unprepare(i2c->clk_arb);
|
||
|
-
|
||
|
- clk_disable_unprepare(i2c->clk_pmic);
|
||
|
-
|
||
|
- clk_disable_unprepare(i2c->clk_main);
|
||
|
- clk_disable_unprepare(i2c->clk_dma);
|
||
|
-}
|
||
|
-
|
||
|
static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
|
||
|
{
|
||
|
u16 control_reg;
|
||
|
@@ -1191,7 +1163,7 @@ static int mtk_i2c_transfer(struct i2c_a
|
||
|
int left_num = num;
|
||
|
struct mtk_i2c *i2c = i2c_get_adapdata(adap);
|
||
|
|
||
|
- ret = mtk_i2c_clock_enable(i2c);
|
||
|
+ ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
|
||
|
if (ret)
|
||
|
return ret;
|
||
|
|
||
|
@@ -1245,7 +1217,7 @@ static int mtk_i2c_transfer(struct i2c_a
|
||
|
ret = num;
|
||
|
|
||
|
err_exit:
|
||
|
- mtk_i2c_clock_disable(i2c);
|
||
|
+ clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
@@ -1323,9 +1295,8 @@ static int mtk_i2c_probe(struct platform
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct mtk_i2c *i2c;
|
||
|
- struct clk *clk;
|
||
|
struct resource *res;
|
||
|
- int irq;
|
||
|
+ int i, irq, speed_clk;
|
||
|
|
||
|
i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
|
||
|
if (!i2c)
|
||
|
@@ -1371,35 +1342,42 @@ static int mtk_i2c_probe(struct platform
|
||
|
if (i2c->have_pmic && !i2c->dev_comp->pmic_i2c)
|
||
|
return -EINVAL;
|
||
|
|
||
|
- i2c->clk_main = devm_clk_get(&pdev->dev, "main");
|
||
|
- if (IS_ERR(i2c->clk_main)) {
|
||
|
+ /* Fill in clk-bulk IDs */
|
||
|
+ for (i = 0; i < I2C_MT65XX_CLK_MAX; i++)
|
||
|
+ i2c->clocks[i].id = i2c_mt65xx_clk_ids[i];
|
||
|
+
|
||
|
+ /* Get clocks one by one, some may be optional */
|
||
|
+ i2c->clocks[I2C_MT65XX_CLK_MAIN].clk = devm_clk_get(&pdev->dev, "main");
|
||
|
+ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk)) {
|
||
|
dev_err(&pdev->dev, "cannot get main clock\n");
|
||
|
- return PTR_ERR(i2c->clk_main);
|
||
|
+ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk);
|
||
|
}
|
||
|
|
||
|
- i2c->clk_dma = devm_clk_get(&pdev->dev, "dma");
|
||
|
- if (IS_ERR(i2c->clk_dma)) {
|
||
|
+ i2c->clocks[I2C_MT65XX_CLK_DMA].clk = devm_clk_get(&pdev->dev, "dma");
|
||
|
+ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk)) {
|
||
|
dev_err(&pdev->dev, "cannot get dma clock\n");
|
||
|
- return PTR_ERR(i2c->clk_dma);
|
||
|
+ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk);
|
||
|
}
|
||
|
|
||
|
- i2c->clk_arb = devm_clk_get(&pdev->dev, "arb");
|
||
|
- if (IS_ERR(i2c->clk_arb))
|
||
|
- i2c->clk_arb = NULL;
|
||
|
+ i2c->clocks[I2C_MT65XX_CLK_ARB].clk = devm_clk_get_optional(&pdev->dev, "arb");
|
||
|
+ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk))
|
||
|
+ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk);
|
||
|
|
||
|
- clk = i2c->clk_main;
|
||
|
if (i2c->have_pmic) {
|
||
|
- i2c->clk_pmic = devm_clk_get(&pdev->dev, "pmic");
|
||
|
- if (IS_ERR(i2c->clk_pmic)) {
|
||
|
+ i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get(&pdev->dev, "pmic");
|
||
|
+ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
|
||
|
dev_err(&pdev->dev, "cannot get pmic clock\n");
|
||
|
- return PTR_ERR(i2c->clk_pmic);
|
||
|
+ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
|
||
|
}
|
||
|
- clk = i2c->clk_pmic;
|
||
|
+ speed_clk = I2C_MT65XX_CLK_PMIC;
|
||
|
+ } else {
|
||
|
+ i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = NULL;
|
||
|
+ speed_clk = I2C_MT65XX_CLK_MAIN;
|
||
|
}
|
||
|
|
||
|
strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
|
||
|
|
||
|
- ret = mtk_i2c_set_speed(i2c, clk_get_rate(clk));
|
||
|
+ ret = mtk_i2c_set_speed(i2c, clk_get_rate(i2c->clocks[speed_clk].clk));
|
||
|
if (ret) {
|
||
|
dev_err(&pdev->dev, "Failed to set the speed.\n");
|
||
|
return -EINVAL;
|
||
|
@@ -1414,13 +1392,13 @@ static int mtk_i2c_probe(struct platform
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- ret = mtk_i2c_clock_enable(i2c);
|
||
|
+ ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
|
||
|
if (ret) {
|
||
|
dev_err(&pdev->dev, "clock enable failed!\n");
|
||
|
return ret;
|
||
|
}
|
||
|
mtk_i2c_init_hw(i2c);
|
||
|
- mtk_i2c_clock_disable(i2c);
|
||
|
+ clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
|
||
|
|
||
|
ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq,
|
||
|
IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE,
|
||
|
@@ -1465,7 +1443,7 @@ static int mtk_i2c_resume_noirq(struct d
|
||
|
int ret;
|
||
|
struct mtk_i2c *i2c = dev_get_drvdata(dev);
|
||
|
|
||
|
- ret = mtk_i2c_clock_enable(i2c);
|
||
|
+ ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
|
||
|
if (ret) {
|
||
|
dev_err(dev, "clock enable failed!\n");
|
||
|
return ret;
|
||
|
@@ -1473,7 +1451,7 @@ static int mtk_i2c_resume_noirq(struct d
|
||
|
|
||
|
mtk_i2c_init_hw(i2c);
|
||
|
|
||
|
- mtk_i2c_clock_disable(i2c);
|
||
|
+ clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
|
||
|
|
||
|
i2c_mark_adapter_resumed(&i2c->adap);
|
||
|
|