Skip to content

Commit 0016a32

Browse files
AngeloGioacchino Del Regnowsakernel
authored andcommitted
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 <[email protected]> Reviewed-by: Qii Wang <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent 52c74d1 commit 0016a32

File tree

1 file changed

+51
-73
lines changed

1 file changed

+51
-73
lines changed

drivers/i2c/busses/i2c-mt65xx.c

Lines changed: 51 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,27 @@
8686

8787
#define I2C_DRV_NAME "i2c-mt65xx"
8888

89+
/**
90+
* enum i2c_mt65xx_clks - Clocks enumeration for MT65XX I2C
91+
*
92+
* @I2C_MT65XX_CLK_MAIN: main clock for i2c bus
93+
* @I2C_MT65XX_CLK_DMA: DMA clock for i2c via DMA
94+
* @I2C_MT65XX_CLK_PMIC: PMIC clock for i2c from PMIC
95+
* @I2C_MT65XX_CLK_ARB: Arbitrator clock for i2c
96+
* @I2C_MT65XX_CLK_MAX: Number of supported clocks
97+
*/
98+
enum i2c_mt65xx_clks {
99+
I2C_MT65XX_CLK_MAIN = 0,
100+
I2C_MT65XX_CLK_DMA,
101+
I2C_MT65XX_CLK_PMIC,
102+
I2C_MT65XX_CLK_ARB,
103+
I2C_MT65XX_CLK_MAX
104+
};
105+
106+
static const char * const i2c_mt65xx_clk_ids[I2C_MT65XX_CLK_MAX] = {
107+
"main", "dma", "pmic", "arb"
108+
};
109+
89110
enum DMA_REGS_OFFSET {
90111
OFFSET_INT_FLAG = 0x0,
91112
OFFSET_INT_EN = 0x04,
@@ -244,10 +265,7 @@ struct mtk_i2c {
244265
/* set in i2c probe */
245266
void __iomem *base; /* i2c base addr */
246267
void __iomem *pdmabase; /* dma base address*/
247-
struct clk *clk_main; /* main clock for i2c bus */
248-
struct clk *clk_dma; /* DMA clock for i2c via DMA */
249-
struct clk *clk_pmic; /* PMIC clock for i2c from PMIC */
250-
struct clk *clk_arb; /* Arbitrator clock for i2c */
268+
struct clk_bulk_data clocks[I2C_MT65XX_CLK_MAX]; /* clocks for i2c */
251269
bool have_pmic; /* can use i2c pins from PMIC */
252270
bool use_push_pull; /* IO config push-pull mode */
253271

@@ -449,52 +467,6 @@ static void mtk_i2c_writew(struct mtk_i2c *i2c, u16 val,
449467
writew(val, i2c->base + i2c->dev_comp->regs[reg]);
450468
}
451469

452-
static int mtk_i2c_clock_enable(struct mtk_i2c *i2c)
453-
{
454-
int ret;
455-
456-
ret = clk_prepare_enable(i2c->clk_dma);
457-
if (ret)
458-
return ret;
459-
460-
ret = clk_prepare_enable(i2c->clk_main);
461-
if (ret)
462-
goto err_main;
463-
464-
if (i2c->have_pmic) {
465-
ret = clk_prepare_enable(i2c->clk_pmic);
466-
if (ret)
467-
goto err_pmic;
468-
}
469-
470-
if (i2c->clk_arb) {
471-
ret = clk_prepare_enable(i2c->clk_arb);
472-
if (ret)
473-
goto err_arb;
474-
}
475-
476-
return 0;
477-
478-
err_arb:
479-
clk_disable_unprepare(i2c->clk_pmic);
480-
err_pmic:
481-
clk_disable_unprepare(i2c->clk_main);
482-
err_main:
483-
clk_disable_unprepare(i2c->clk_dma);
484-
485-
return ret;
486-
}
487-
488-
static void mtk_i2c_clock_disable(struct mtk_i2c *i2c)
489-
{
490-
clk_disable_unprepare(i2c->clk_arb);
491-
492-
clk_disable_unprepare(i2c->clk_pmic);
493-
494-
clk_disable_unprepare(i2c->clk_main);
495-
clk_disable_unprepare(i2c->clk_dma);
496-
}
497-
498470
static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
499471
{
500472
u16 control_reg;
@@ -1191,7 +1163,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
11911163
int left_num = num;
11921164
struct mtk_i2c *i2c = i2c_get_adapdata(adap);
11931165

1194-
ret = mtk_i2c_clock_enable(i2c);
1166+
ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
11951167
if (ret)
11961168
return ret;
11971169

@@ -1245,7 +1217,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
12451217
ret = num;
12461218

12471219
err_exit:
1248-
mtk_i2c_clock_disable(i2c);
1220+
clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
12491221
return ret;
12501222
}
12511223

@@ -1323,9 +1295,8 @@ static int mtk_i2c_probe(struct platform_device *pdev)
13231295
{
13241296
int ret = 0;
13251297
struct mtk_i2c *i2c;
1326-
struct clk *clk;
13271298
struct resource *res;
1328-
int irq;
1299+
int i, irq, speed_clk;
13291300

13301301
i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
13311302
if (!i2c)
@@ -1371,35 +1342,42 @@ static int mtk_i2c_probe(struct platform_device *pdev)
13711342
if (i2c->have_pmic && !i2c->dev_comp->pmic_i2c)
13721343
return -EINVAL;
13731344

1374-
i2c->clk_main = devm_clk_get(&pdev->dev, "main");
1375-
if (IS_ERR(i2c->clk_main)) {
1345+
/* Fill in clk-bulk IDs */
1346+
for (i = 0; i < I2C_MT65XX_CLK_MAX; i++)
1347+
i2c->clocks[i].id = i2c_mt65xx_clk_ids[i];
1348+
1349+
/* Get clocks one by one, some may be optional */
1350+
i2c->clocks[I2C_MT65XX_CLK_MAIN].clk = devm_clk_get(&pdev->dev, "main");
1351+
if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk)) {
13761352
dev_err(&pdev->dev, "cannot get main clock\n");
1377-
return PTR_ERR(i2c->clk_main);
1353+
return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk);
13781354
}
13791355

1380-
i2c->clk_dma = devm_clk_get(&pdev->dev, "dma");
1381-
if (IS_ERR(i2c->clk_dma)) {
1356+
i2c->clocks[I2C_MT65XX_CLK_DMA].clk = devm_clk_get(&pdev->dev, "dma");
1357+
if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk)) {
13821358
dev_err(&pdev->dev, "cannot get dma clock\n");
1383-
return PTR_ERR(i2c->clk_dma);
1359+
return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk);
13841360
}
13851361

1386-
i2c->clk_arb = devm_clk_get(&pdev->dev, "arb");
1387-
if (IS_ERR(i2c->clk_arb))
1388-
i2c->clk_arb = NULL;
1362+
i2c->clocks[I2C_MT65XX_CLK_ARB].clk = devm_clk_get_optional(&pdev->dev, "arb");
1363+
if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk))
1364+
return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk);
13891365

1390-
clk = i2c->clk_main;
13911366
if (i2c->have_pmic) {
1392-
i2c->clk_pmic = devm_clk_get(&pdev->dev, "pmic");
1393-
if (IS_ERR(i2c->clk_pmic)) {
1367+
i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get(&pdev->dev, "pmic");
1368+
if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
13941369
dev_err(&pdev->dev, "cannot get pmic clock\n");
1395-
return PTR_ERR(i2c->clk_pmic);
1370+
return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
13961371
}
1397-
clk = i2c->clk_pmic;
1372+
speed_clk = I2C_MT65XX_CLK_PMIC;
1373+
} else {
1374+
i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = NULL;
1375+
speed_clk = I2C_MT65XX_CLK_MAIN;
13981376
}
13991377

14001378
strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
14011379

1402-
ret = mtk_i2c_set_speed(i2c, clk_get_rate(clk));
1380+
ret = mtk_i2c_set_speed(i2c, clk_get_rate(i2c->clocks[speed_clk].clk));
14031381
if (ret) {
14041382
dev_err(&pdev->dev, "Failed to set the speed.\n");
14051383
return -EINVAL;
@@ -1414,13 +1392,13 @@ static int mtk_i2c_probe(struct platform_device *pdev)
14141392
}
14151393
}
14161394

1417-
ret = mtk_i2c_clock_enable(i2c);
1395+
ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
14181396
if (ret) {
14191397
dev_err(&pdev->dev, "clock enable failed!\n");
14201398
return ret;
14211399
}
14221400
mtk_i2c_init_hw(i2c);
1423-
mtk_i2c_clock_disable(i2c);
1401+
clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
14241402

14251403
ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq,
14261404
IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE,
@@ -1465,15 +1443,15 @@ static int mtk_i2c_resume_noirq(struct device *dev)
14651443
int ret;
14661444
struct mtk_i2c *i2c = dev_get_drvdata(dev);
14671445

1468-
ret = mtk_i2c_clock_enable(i2c);
1446+
ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
14691447
if (ret) {
14701448
dev_err(dev, "clock enable failed!\n");
14711449
return ret;
14721450
}
14731451

14741452
mtk_i2c_init_hw(i2c);
14751453

1476-
mtk_i2c_clock_disable(i2c);
1454+
clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
14771455

14781456
i2c_mark_adapter_resumed(&i2c->adap);
14791457

0 commit comments

Comments
 (0)