Move the clocks probe to a new cmdq_get_clocks() function; while at it, partially refactor the code: Drop the clk_names[] array and assign clock names to the array of clk_bulk_data with devm_kasprintf() instead, slightly reduce the indentation for the multi-gce clock probe path and add a comment describing the reason why we get clocks of other GCE instance instead of just the clock from the one that it is getting probed. Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@xxxxxxxxxxxxx> --- drivers/mailbox/mtk-cmdq-mailbox.c | 79 +++++++++++++++++++----------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index 66dbc8e846d8..a3f57151a221 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -578,16 +578,59 @@ static struct mbox_chan *cmdq_xlate(struct mbox_controller *mbox, return &mbox->chans[ind]; } +static int cmdq_get_clocks(struct device *dev, struct cmdq *cmdq) +{ + static const char * const gce_name = "gce"; + struct device_node *node, *parent = dev->of_node->parent; + struct clk_bulk_data *clks; + + if (cmdq->pdata->gce_num == 1) { + clks = &cmdq->clocks[0]; + + clks->id = gce_name; + clks->clk = devm_clk_get(dev, NULL); + if (IS_ERR(clks->clk)) + return dev_err_probe(dev, PTR_ERR(clks->clk), + "failed to get gce clock\n"); + + return 0; + } + + /* + * If there is more than one GCE, get the clocks for the others too, + * as the clock of the main GCE must be enabled for additional IPs + * to be reachable. + */ + for_each_child_of_node(parent, node) { + int alias_id = of_alias_get_id(node, gce_name); + + if (alias_id < 0 || alias_id >= cmdq->pdata->gce_num) + continue; + + clks = &cmdq->clocks[alias_id]; + + clks->id = devm_kasprintf(dev, GFP_KERNEL, "gce%d", alias_id); + if (!clks->id) { + of_node_put(node); + return -ENOMEM; + } + + clks->clk = of_clk_get(node, 0); + if (IS_ERR(clks->clk)) { + of_node_put(node); + return dev_err_probe(dev, PTR_ERR(clks->clk), + "failed to get gce%d clock\n", alias_id); + } + } + + return 0; +} + static int cmdq_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct cmdq *cmdq; int err, i; - struct device_node *phandle = dev->of_node; - struct device_node *node; - int alias_id = 0; - static const char * const clk_name = "gce"; - static const char * const clk_names[] = { "gce0", "gce1" }; cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL); if (!cmdq) @@ -612,29 +655,9 @@ static int cmdq_probe(struct platform_device *pdev) dev_dbg(dev, "cmdq device: addr:0x%p, va:0x%p, irq:%d\n", dev, cmdq->base, cmdq->irq); - if (cmdq->pdata->gce_num > 1) { - for_each_child_of_node(phandle->parent, node) { - alias_id = of_alias_get_id(node, clk_name); - if (alias_id >= 0 && alias_id < cmdq->pdata->gce_num) { - cmdq->clocks[alias_id].id = clk_names[alias_id]; - cmdq->clocks[alias_id].clk = of_clk_get(node, 0); - if (IS_ERR(cmdq->clocks[alias_id].clk)) { - of_node_put(node); - return dev_err_probe(dev, - PTR_ERR(cmdq->clocks[alias_id].clk), - "failed to get gce clk: %d\n", - alias_id); - } - } - } - } else { - cmdq->clocks[alias_id].id = clk_name; - cmdq->clocks[alias_id].clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(cmdq->clocks[alias_id].clk)) { - return dev_err_probe(dev, PTR_ERR(cmdq->clocks[alias_id].clk), - "failed to get gce clk\n"); - } - } + err = cmdq_get_clocks(dev, cmdq); + if (err) + return err; cmdq->mbox.dev = dev; cmdq->mbox.chans = devm_kcalloc(dev, cmdq->pdata->thread_nr, -- 2.45.2