Skip to content

Commit cd1a6a0

Browse files
NXP-CarlosSongalexandrebelloni
authored andcommitted
i3c: master: svc: switch to bulk clk API for flexible clock support
Use the clk_bulk API to handle clocks, so the code can support different numbers of clocks more easily. Make the code cleaner and more flexible. No change in functionality. Signed-off-by: Carlos Song <[email protected]> Reviewed-by: Frank Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent 489c773 commit cd1a6a0

File tree

1 file changed

+26
-50
lines changed

1 file changed

+26
-50
lines changed

drivers/i3c/master/svc-i3c-master.c

Lines changed: 26 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,9 @@ struct svc_i3c_drvdata {
202202
* @descs: Array of descriptors, one per attached device
203203
* @hj_work: Hot-join work
204204
* @irq: Main interrupt
205-
* @pclk: System clock
205+
* @num_clks: I3C clock number
206206
* @fclk: Fast clock (bus)
207-
* @sclk: Slow clock (other events)
207+
* @clks: I3C clock array
208208
* @xferqueue: Transfer queue structure
209209
* @xferqueue.list: List member
210210
* @xferqueue.cur: Current ongoing transfer
@@ -229,9 +229,9 @@ struct svc_i3c_master {
229229
struct i3c_dev_desc *descs[SVC_I3C_MAX_DEVS];
230230
struct work_struct hj_work;
231231
int irq;
232-
struct clk *pclk;
232+
int num_clks;
233233
struct clk *fclk;
234-
struct clk *sclk;
234+
struct clk_bulk_data *clks;
235235
struct {
236236
struct list_head list;
237237
struct svc_i3c_xfer *cur;
@@ -1871,42 +1871,11 @@ static const struct i3c_master_controller_ops svc_i3c_master_ops = {
18711871
.set_speed = svc_i3c_master_set_speed,
18721872
};
18731873

1874-
static int svc_i3c_master_prepare_clks(struct svc_i3c_master *master)
1875-
{
1876-
int ret = 0;
1877-
1878-
ret = clk_prepare_enable(master->pclk);
1879-
if (ret)
1880-
return ret;
1881-
1882-
ret = clk_prepare_enable(master->fclk);
1883-
if (ret) {
1884-
clk_disable_unprepare(master->pclk);
1885-
return ret;
1886-
}
1887-
1888-
ret = clk_prepare_enable(master->sclk);
1889-
if (ret) {
1890-
clk_disable_unprepare(master->pclk);
1891-
clk_disable_unprepare(master->fclk);
1892-
return ret;
1893-
}
1894-
1895-
return 0;
1896-
}
1897-
1898-
static void svc_i3c_master_unprepare_clks(struct svc_i3c_master *master)
1899-
{
1900-
clk_disable_unprepare(master->pclk);
1901-
clk_disable_unprepare(master->fclk);
1902-
clk_disable_unprepare(master->sclk);
1903-
}
1904-
19051874
static int svc_i3c_master_probe(struct platform_device *pdev)
19061875
{
19071876
struct device *dev = &pdev->dev;
19081877
struct svc_i3c_master *master;
1909-
int ret;
1878+
int ret, i;
19101879

19111880
master = devm_kzalloc(dev, sizeof(*master), GFP_KERNEL);
19121881
if (!master)
@@ -1920,27 +1889,31 @@ static int svc_i3c_master_probe(struct platform_device *pdev)
19201889
if (IS_ERR(master->regs))
19211890
return PTR_ERR(master->regs);
19221891

1923-
master->pclk = devm_clk_get(dev, "pclk");
1924-
if (IS_ERR(master->pclk))
1925-
return PTR_ERR(master->pclk);
1892+
master->num_clks = devm_clk_bulk_get_all(dev, &master->clks);
1893+
if (master->num_clks < 0)
1894+
return dev_err_probe(dev, -EINVAL, "can't get I3C clocks\n");
1895+
1896+
for (i = 0; i < master->num_clks; i++) {
1897+
if (!strcmp(master->clks[i].id, "fast_clk"))
1898+
break;
1899+
}
1900+
1901+
if (i == master->num_clks)
1902+
return dev_err_probe(dev, -EINVAL,
1903+
"can't get I3C peripheral clock\n");
19261904

1927-
master->fclk = devm_clk_get(dev, "fast_clk");
1905+
master->fclk = master->clks[i].clk;
19281906
if (IS_ERR(master->fclk))
19291907
return PTR_ERR(master->fclk);
19301908

1931-
master->sclk = devm_clk_get(dev, "slow_clk");
1932-
if (IS_ERR(master->sclk))
1933-
return PTR_ERR(master->sclk);
1934-
19351909
master->irq = platform_get_irq(pdev, 0);
19361910
if (master->irq < 0)
19371911
return master->irq;
19381912

19391913
master->dev = dev;
1940-
1941-
ret = svc_i3c_master_prepare_clks(master);
1914+
ret = clk_bulk_prepare_enable(master->num_clks, master->clks);
19421915
if (ret)
1943-
return ret;
1916+
return dev_err_probe(dev, ret, "can't enable I3C clocks\n");
19441917

19451918
INIT_WORK(&master->hj_work, svc_i3c_master_hj_work);
19461919
mutex_init(&master->lock);
@@ -1993,7 +1966,7 @@ static int svc_i3c_master_probe(struct platform_device *pdev)
19931966
pm_runtime_set_suspended(&pdev->dev);
19941967

19951968
err_disable_clks:
1996-
svc_i3c_master_unprepare_clks(master);
1969+
clk_bulk_disable_unprepare(master->num_clks, master->clks);
19971970

19981971
return ret;
19991972
}
@@ -2031,7 +2004,7 @@ static int __maybe_unused svc_i3c_runtime_suspend(struct device *dev)
20312004
struct svc_i3c_master *master = dev_get_drvdata(dev);
20322005

20332006
svc_i3c_save_regs(master);
2034-
svc_i3c_master_unprepare_clks(master);
2007+
clk_bulk_disable_unprepare(master->num_clks, master->clks);
20352008
pinctrl_pm_select_sleep_state(dev);
20362009

20372010
return 0;
@@ -2040,9 +2013,12 @@ static int __maybe_unused svc_i3c_runtime_suspend(struct device *dev)
20402013
static int __maybe_unused svc_i3c_runtime_resume(struct device *dev)
20412014
{
20422015
struct svc_i3c_master *master = dev_get_drvdata(dev);
2016+
int ret;
20432017

20442018
pinctrl_pm_select_default_state(dev);
2045-
svc_i3c_master_prepare_clks(master);
2019+
ret = clk_bulk_prepare_enable(master->num_clks, master->clks);
2020+
if (ret)
2021+
return ret;
20462022

20472023
svc_i3c_restore_regs(master);
20482024

0 commit comments

Comments
 (0)