Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2016-2020 NVIDIA Corporation
0004  */
0005 
0006 #include <linux/clk-provider.h>
0007 #include <linux/device.h>
0008 #include <linux/seq_buf.h>
0009 #include <linux/slab.h>
0010 
0011 #include <soc/tegra/bpmp.h>
0012 #include <soc/tegra/bpmp-abi.h>
0013 
0014 #define TEGRA_BPMP_DUMP_CLOCK_INFO  0
0015 
0016 #define TEGRA_BPMP_CLK_HAS_MUX      BIT(0)
0017 #define TEGRA_BPMP_CLK_HAS_SET_RATE BIT(1)
0018 #define TEGRA_BPMP_CLK_IS_ROOT      BIT(2)
0019 
0020 struct tegra_bpmp_clk_info {
0021     unsigned int id;
0022     char name[MRQ_CLK_NAME_MAXLEN];
0023     unsigned int parents[MRQ_CLK_MAX_PARENTS];
0024     unsigned int num_parents;
0025     unsigned long flags;
0026 };
0027 
0028 struct tegra_bpmp_clk {
0029     struct clk_hw hw;
0030 
0031     struct tegra_bpmp *bpmp;
0032     unsigned int id;
0033 
0034     unsigned int num_parents;
0035     unsigned int *parents;
0036 };
0037 
0038 static inline struct tegra_bpmp_clk *to_tegra_bpmp_clk(struct clk_hw *hw)
0039 {
0040     return container_of(hw, struct tegra_bpmp_clk, hw);
0041 }
0042 
0043 struct tegra_bpmp_clk_message {
0044     unsigned int cmd;
0045     unsigned int id;
0046 
0047     struct {
0048         const void *data;
0049         size_t size;
0050     } tx;
0051 
0052     struct {
0053         void *data;
0054         size_t size;
0055         int ret;
0056     } rx;
0057 };
0058 
0059 static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
0060                    const struct tegra_bpmp_clk_message *clk)
0061 {
0062     struct mrq_clk_request request;
0063     struct tegra_bpmp_message msg;
0064     void *req = &request;
0065     int err;
0066 
0067     memset(&request, 0, sizeof(request));
0068     request.cmd_and_id = (clk->cmd << 24) | clk->id;
0069 
0070     /*
0071      * The mrq_clk_request structure has an anonymous union at offset 4
0072      * that contains all possible sub-command structures. Copy the data
0073      * to that union. Ideally we'd be able to refer to it by name, but
0074      * doing so would require changing the ABI header and increase the
0075      * maintenance burden.
0076      */
0077     memcpy(req + 4, clk->tx.data, clk->tx.size);
0078 
0079     memset(&msg, 0, sizeof(msg));
0080     msg.mrq = MRQ_CLK;
0081     msg.tx.data = &request;
0082     msg.tx.size = sizeof(request);
0083     msg.rx.data = clk->rx.data;
0084     msg.rx.size = clk->rx.size;
0085 
0086     err = tegra_bpmp_transfer(bpmp, &msg);
0087     if (err < 0)
0088         return err;
0089     else if (msg.rx.ret < 0)
0090         return -EINVAL;
0091 
0092     return 0;
0093 }
0094 
0095 static int tegra_bpmp_clk_prepare(struct clk_hw *hw)
0096 {
0097     struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
0098     struct tegra_bpmp_clk_message msg;
0099 
0100     memset(&msg, 0, sizeof(msg));
0101     msg.cmd = CMD_CLK_ENABLE;
0102     msg.id = clk->id;
0103 
0104     return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
0105 }
0106 
0107 static void tegra_bpmp_clk_unprepare(struct clk_hw *hw)
0108 {
0109     struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
0110     struct tegra_bpmp_clk_message msg;
0111     int err;
0112 
0113     memset(&msg, 0, sizeof(msg));
0114     msg.cmd = CMD_CLK_DISABLE;
0115     msg.id = clk->id;
0116 
0117     err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
0118     if (err < 0)
0119         dev_err(clk->bpmp->dev, "failed to disable clock %s: %d\n",
0120             clk_hw_get_name(hw), err);
0121 }
0122 
0123 static int tegra_bpmp_clk_is_prepared(struct clk_hw *hw)
0124 {
0125     struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
0126     struct cmd_clk_is_enabled_response response;
0127     struct tegra_bpmp_clk_message msg;
0128     int err;
0129 
0130     memset(&msg, 0, sizeof(msg));
0131     msg.cmd = CMD_CLK_IS_ENABLED;
0132     msg.id = clk->id;
0133     msg.rx.data = &response;
0134     msg.rx.size = sizeof(response);
0135 
0136     err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
0137     if (err < 0)
0138         return err;
0139 
0140     return response.state;
0141 }
0142 
0143 static unsigned long tegra_bpmp_clk_recalc_rate(struct clk_hw *hw,
0144                         unsigned long parent_rate)
0145 {
0146     struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
0147     struct cmd_clk_get_rate_response response;
0148     struct cmd_clk_get_rate_request request;
0149     struct tegra_bpmp_clk_message msg;
0150     int err;
0151 
0152     memset(&msg, 0, sizeof(msg));
0153     msg.cmd = CMD_CLK_GET_RATE;
0154     msg.id = clk->id;
0155     msg.tx.data = &request;
0156     msg.tx.size = sizeof(request);
0157     msg.rx.data = &response;
0158     msg.rx.size = sizeof(response);
0159 
0160     err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
0161     if (err < 0)
0162         return err;
0163 
0164     return response.rate;
0165 }
0166 
0167 static int tegra_bpmp_clk_determine_rate(struct clk_hw *hw,
0168                      struct clk_rate_request *rate_req)
0169 {
0170     struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
0171     struct cmd_clk_round_rate_response response;
0172     struct cmd_clk_round_rate_request request;
0173     struct tegra_bpmp_clk_message msg;
0174     unsigned long rate;
0175     int err;
0176 
0177     rate = min(max(rate_req->rate, rate_req->min_rate), rate_req->max_rate);
0178 
0179     memset(&request, 0, sizeof(request));
0180     request.rate = min_t(u64, rate, S64_MAX);
0181 
0182     memset(&msg, 0, sizeof(msg));
0183     msg.cmd = CMD_CLK_ROUND_RATE;
0184     msg.id = clk->id;
0185     msg.tx.data = &request;
0186     msg.tx.size = sizeof(request);
0187     msg.rx.data = &response;
0188     msg.rx.size = sizeof(response);
0189 
0190     err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
0191     if (err < 0)
0192         return err;
0193 
0194     rate_req->rate = (unsigned long)response.rate;
0195 
0196     return 0;
0197 }
0198 
0199 static int tegra_bpmp_clk_set_parent(struct clk_hw *hw, u8 index)
0200 {
0201     struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
0202     struct cmd_clk_set_parent_response response;
0203     struct cmd_clk_set_parent_request request;
0204     struct tegra_bpmp_clk_message msg;
0205     int err;
0206 
0207     memset(&request, 0, sizeof(request));
0208     request.parent_id = clk->parents[index];
0209 
0210     memset(&msg, 0, sizeof(msg));
0211     msg.cmd = CMD_CLK_SET_PARENT;
0212     msg.id = clk->id;
0213     msg.tx.data = &request;
0214     msg.tx.size = sizeof(request);
0215     msg.rx.data = &response;
0216     msg.rx.size = sizeof(response);
0217 
0218     err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
0219     if (err < 0)
0220         return err;
0221 
0222     /* XXX check parent ID in response */
0223 
0224     return 0;
0225 }
0226 
0227 static u8 tegra_bpmp_clk_get_parent(struct clk_hw *hw)
0228 {
0229     struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
0230     struct cmd_clk_get_parent_response response;
0231     struct tegra_bpmp_clk_message msg;
0232     unsigned int i;
0233     int err;
0234 
0235     memset(&msg, 0, sizeof(msg));
0236     msg.cmd = CMD_CLK_GET_PARENT;
0237     msg.id = clk->id;
0238     msg.rx.data = &response;
0239     msg.rx.size = sizeof(response);
0240 
0241     err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
0242     if (err < 0) {
0243         dev_err(clk->bpmp->dev, "failed to get parent for %s: %d\n",
0244             clk_hw_get_name(hw), err);
0245         return U8_MAX;
0246     }
0247 
0248     for (i = 0; i < clk->num_parents; i++)
0249         if (clk->parents[i] == response.parent_id)
0250             return i;
0251 
0252     return U8_MAX;
0253 }
0254 
0255 static int tegra_bpmp_clk_set_rate(struct clk_hw *hw, unsigned long rate,
0256                    unsigned long parent_rate)
0257 {
0258     struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
0259     struct cmd_clk_set_rate_response response;
0260     struct cmd_clk_set_rate_request request;
0261     struct tegra_bpmp_clk_message msg;
0262 
0263     memset(&request, 0, sizeof(request));
0264     request.rate = min_t(u64, rate, S64_MAX);
0265 
0266     memset(&msg, 0, sizeof(msg));
0267     msg.cmd = CMD_CLK_SET_RATE;
0268     msg.id = clk->id;
0269     msg.tx.data = &request;
0270     msg.tx.size = sizeof(request);
0271     msg.rx.data = &response;
0272     msg.rx.size = sizeof(response);
0273 
0274     return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
0275 }
0276 
0277 static const struct clk_ops tegra_bpmp_clk_gate_ops = {
0278     .prepare = tegra_bpmp_clk_prepare,
0279     .unprepare = tegra_bpmp_clk_unprepare,
0280     .is_prepared = tegra_bpmp_clk_is_prepared,
0281     .recalc_rate = tegra_bpmp_clk_recalc_rate,
0282 };
0283 
0284 static const struct clk_ops tegra_bpmp_clk_mux_ops = {
0285     .prepare = tegra_bpmp_clk_prepare,
0286     .unprepare = tegra_bpmp_clk_unprepare,
0287     .is_prepared = tegra_bpmp_clk_is_prepared,
0288     .recalc_rate = tegra_bpmp_clk_recalc_rate,
0289     .set_parent = tegra_bpmp_clk_set_parent,
0290     .get_parent = tegra_bpmp_clk_get_parent,
0291 };
0292 
0293 static const struct clk_ops tegra_bpmp_clk_rate_ops = {
0294     .prepare = tegra_bpmp_clk_prepare,
0295     .unprepare = tegra_bpmp_clk_unprepare,
0296     .is_prepared = tegra_bpmp_clk_is_prepared,
0297     .recalc_rate = tegra_bpmp_clk_recalc_rate,
0298     .determine_rate = tegra_bpmp_clk_determine_rate,
0299     .set_rate = tegra_bpmp_clk_set_rate,
0300 };
0301 
0302 static const struct clk_ops tegra_bpmp_clk_mux_rate_ops = {
0303     .prepare = tegra_bpmp_clk_prepare,
0304     .unprepare = tegra_bpmp_clk_unprepare,
0305     .is_prepared = tegra_bpmp_clk_is_prepared,
0306     .recalc_rate = tegra_bpmp_clk_recalc_rate,
0307     .determine_rate = tegra_bpmp_clk_determine_rate,
0308     .set_parent = tegra_bpmp_clk_set_parent,
0309     .get_parent = tegra_bpmp_clk_get_parent,
0310     .set_rate = tegra_bpmp_clk_set_rate,
0311 };
0312 
0313 static int tegra_bpmp_clk_get_max_id(struct tegra_bpmp *bpmp)
0314 {
0315     struct cmd_clk_get_max_clk_id_response response;
0316     struct tegra_bpmp_clk_message msg;
0317     int err;
0318 
0319     memset(&msg, 0, sizeof(msg));
0320     msg.cmd = CMD_CLK_GET_MAX_CLK_ID;
0321     msg.rx.data = &response;
0322     msg.rx.size = sizeof(response);
0323 
0324     err = tegra_bpmp_clk_transfer(bpmp, &msg);
0325     if (err < 0)
0326         return err;
0327 
0328     if (response.max_id > INT_MAX)
0329         return -E2BIG;
0330 
0331     return response.max_id;
0332 }
0333 
0334 static int tegra_bpmp_clk_get_info(struct tegra_bpmp *bpmp, unsigned int id,
0335                    struct tegra_bpmp_clk_info *info)
0336 {
0337     struct cmd_clk_get_all_info_response response;
0338     struct tegra_bpmp_clk_message msg;
0339     unsigned int i;
0340     int err;
0341 
0342     memset(&msg, 0, sizeof(msg));
0343     msg.cmd = CMD_CLK_GET_ALL_INFO;
0344     msg.id = id;
0345     msg.rx.data = &response;
0346     msg.rx.size = sizeof(response);
0347 
0348     err = tegra_bpmp_clk_transfer(bpmp, &msg);
0349     if (err < 0)
0350         return err;
0351 
0352     strlcpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN);
0353     info->num_parents = response.num_parents;
0354 
0355     for (i = 0; i < info->num_parents; i++)
0356         info->parents[i] = response.parents[i];
0357 
0358     info->flags = response.flags;
0359 
0360     return 0;
0361 }
0362 
0363 static void tegra_bpmp_clk_info_dump(struct tegra_bpmp *bpmp,
0364                      const char *level,
0365                      const struct tegra_bpmp_clk_info *info)
0366 {
0367     const char *prefix = "";
0368     struct seq_buf buf;
0369     unsigned int i;
0370     char flags[64];
0371 
0372     seq_buf_init(&buf, flags, sizeof(flags));
0373 
0374     if (info->flags)
0375         seq_buf_printf(&buf, "(");
0376 
0377     if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) {
0378         seq_buf_printf(&buf, "%smux", prefix);
0379         prefix = ", ";
0380     }
0381 
0382     if ((info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) == 0) {
0383         seq_buf_printf(&buf, "%sfixed", prefix);
0384         prefix = ", ";
0385     }
0386 
0387     if (info->flags & TEGRA_BPMP_CLK_IS_ROOT) {
0388         seq_buf_printf(&buf, "%sroot", prefix);
0389         prefix = ", ";
0390     }
0391 
0392     if (info->flags)
0393         seq_buf_printf(&buf, ")");
0394 
0395     dev_printk(level, bpmp->dev, "%03u: %s\n", info->id, info->name);
0396     dev_printk(level, bpmp->dev, "  flags: %lx %s\n", info->flags, flags);
0397     dev_printk(level, bpmp->dev, "  parents: %u\n", info->num_parents);
0398 
0399     for (i = 0; i < info->num_parents; i++)
0400         dev_printk(level, bpmp->dev, "    %03u\n", info->parents[i]);
0401 }
0402 
0403 static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp,
0404                    struct tegra_bpmp_clk_info **clocksp)
0405 {
0406     struct tegra_bpmp_clk_info *clocks;
0407     unsigned int max_id, id, count = 0;
0408     unsigned int holes = 0;
0409     int err;
0410 
0411     err = tegra_bpmp_clk_get_max_id(bpmp);
0412     if (err < 0)
0413         return err;
0414 
0415     max_id = err;
0416 
0417     dev_dbg(bpmp->dev, "maximum clock ID: %u\n", max_id);
0418 
0419     clocks = kcalloc(max_id + 1, sizeof(*clocks), GFP_KERNEL);
0420     if (!clocks)
0421         return -ENOMEM;
0422 
0423     for (id = 0; id <= max_id; id++) {
0424         struct tegra_bpmp_clk_info *info = &clocks[count];
0425 
0426         err = tegra_bpmp_clk_get_info(bpmp, id, info);
0427         if (err < 0)
0428             continue;
0429 
0430         if (info->num_parents >= U8_MAX) {
0431             dev_err(bpmp->dev,
0432                 "clock %u has too many parents (%u, max: %u)\n",
0433                 id, info->num_parents, U8_MAX);
0434             continue;
0435         }
0436 
0437         /* clock not exposed by BPMP */
0438         if (info->name[0] == '\0') {
0439             holes++;
0440             continue;
0441         }
0442 
0443         info->id = id;
0444         count++;
0445 
0446         if (TEGRA_BPMP_DUMP_CLOCK_INFO)
0447             tegra_bpmp_clk_info_dump(bpmp, KERN_DEBUG, info);
0448     }
0449 
0450     dev_dbg(bpmp->dev, "holes: %u\n", holes);
0451     *clocksp = clocks;
0452 
0453     return count;
0454 }
0455 
0456 static unsigned int
0457 tegra_bpmp_clk_id_to_index(const struct tegra_bpmp_clk_info *clocks,
0458                unsigned int num_clocks, unsigned int id)
0459 {
0460     unsigned int i;
0461 
0462     for (i = 0; i < num_clocks; i++)
0463         if (clocks[i].id == id)
0464             return i;
0465 
0466     return UINT_MAX;
0467 }
0468 
0469 static const struct tegra_bpmp_clk_info *
0470 tegra_bpmp_clk_find(const struct tegra_bpmp_clk_info *clocks,
0471             unsigned int num_clocks, unsigned int id)
0472 {
0473     unsigned int i;
0474 
0475     i = tegra_bpmp_clk_id_to_index(clocks, num_clocks, id);
0476 
0477     if (i < num_clocks)
0478         return &clocks[i];
0479 
0480     return NULL;
0481 }
0482 
0483 static struct tegra_bpmp_clk *
0484 tegra_bpmp_clk_register(struct tegra_bpmp *bpmp,
0485             const struct tegra_bpmp_clk_info *info,
0486             const struct tegra_bpmp_clk_info *clocks,
0487             unsigned int num_clocks)
0488 {
0489     struct tegra_bpmp_clk *clk;
0490     struct clk_init_data init;
0491     const char **parents;
0492     unsigned int i;
0493     int err;
0494 
0495     clk = devm_kzalloc(bpmp->dev, sizeof(*clk), GFP_KERNEL);
0496     if (!clk)
0497         return ERR_PTR(-ENOMEM);
0498 
0499     clk->id = info->id;
0500     clk->bpmp = bpmp;
0501 
0502     clk->parents = devm_kcalloc(bpmp->dev, info->num_parents,
0503                     sizeof(*clk->parents), GFP_KERNEL);
0504     if (!clk->parents)
0505         return ERR_PTR(-ENOMEM);
0506 
0507     clk->num_parents = info->num_parents;
0508 
0509     /* hardware clock initialization */
0510     memset(&init, 0, sizeof(init));
0511     init.name = info->name;
0512     clk->hw.init = &init;
0513 
0514     if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) {
0515         if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE)
0516             init.ops = &tegra_bpmp_clk_mux_rate_ops;
0517         else
0518             init.ops = &tegra_bpmp_clk_mux_ops;
0519     } else {
0520         if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE)
0521             init.ops = &tegra_bpmp_clk_rate_ops;
0522         else
0523             init.ops = &tegra_bpmp_clk_gate_ops;
0524     }
0525 
0526     init.num_parents = info->num_parents;
0527 
0528     parents = kcalloc(info->num_parents, sizeof(*parents), GFP_KERNEL);
0529     if (!parents)
0530         return ERR_PTR(-ENOMEM);
0531 
0532     for (i = 0; i < info->num_parents; i++) {
0533         const struct tegra_bpmp_clk_info *parent;
0534 
0535         /* keep a private copy of the ID to parent index map */
0536         clk->parents[i] = info->parents[i];
0537 
0538         parent = tegra_bpmp_clk_find(clocks, num_clocks,
0539                          info->parents[i]);
0540         if (!parent) {
0541             dev_err(bpmp->dev, "no parent %u found for %u\n",
0542                 info->parents[i], info->id);
0543             continue;
0544         }
0545 
0546         parents[i] = parent->name;
0547     }
0548 
0549     init.parent_names = parents;
0550 
0551     err = devm_clk_hw_register(bpmp->dev, &clk->hw);
0552 
0553     kfree(parents);
0554 
0555     if (err < 0)
0556         return ERR_PTR(err);
0557 
0558     return clk;
0559 }
0560 
0561 static void tegra_bpmp_register_clocks_one(struct tegra_bpmp *bpmp,
0562                        struct tegra_bpmp_clk_info *infos,
0563                        unsigned int i,
0564                        unsigned int count)
0565 {
0566     unsigned int j;
0567     struct tegra_bpmp_clk_info *info;
0568     struct tegra_bpmp_clk *clk;
0569 
0570     if (bpmp->clocks[i]) {
0571         /* already registered */
0572         return;
0573     }
0574 
0575     info = &infos[i];
0576     for (j = 0; j < info->num_parents; ++j) {
0577         unsigned int p_id = info->parents[j];
0578         unsigned int p_i = tegra_bpmp_clk_id_to_index(infos, count,
0579                                   p_id);
0580         if (p_i < count)
0581             tegra_bpmp_register_clocks_one(bpmp, infos, p_i, count);
0582     }
0583 
0584     clk = tegra_bpmp_clk_register(bpmp, info, infos, count);
0585     if (IS_ERR(clk)) {
0586         dev_err(bpmp->dev,
0587             "failed to register clock %u (%s): %ld\n",
0588             info->id, info->name, PTR_ERR(clk));
0589         /* intentionally store the error pointer to
0590          * bpmp->clocks[i] to avoid re-attempting the
0591          * registration later
0592          */
0593     }
0594 
0595     bpmp->clocks[i] = clk;
0596 }
0597 
0598 static int tegra_bpmp_register_clocks(struct tegra_bpmp *bpmp,
0599                       struct tegra_bpmp_clk_info *infos,
0600                       unsigned int count)
0601 {
0602     unsigned int i;
0603 
0604     bpmp->num_clocks = count;
0605 
0606     bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(struct tegra_bpmp_clk), GFP_KERNEL);
0607     if (!bpmp->clocks)
0608         return -ENOMEM;
0609 
0610     for (i = 0; i < count; i++) {
0611         tegra_bpmp_register_clocks_one(bpmp, infos, i, count);
0612     }
0613 
0614     return 0;
0615 }
0616 
0617 static void tegra_bpmp_unregister_clocks(struct tegra_bpmp *bpmp)
0618 {
0619     unsigned int i;
0620 
0621     for (i = 0; i < bpmp->num_clocks; i++)
0622         clk_hw_unregister(&bpmp->clocks[i]->hw);
0623 }
0624 
0625 static struct clk_hw *tegra_bpmp_clk_of_xlate(struct of_phandle_args *clkspec,
0626                           void *data)
0627 {
0628     unsigned int id = clkspec->args[0], i;
0629     struct tegra_bpmp *bpmp = data;
0630 
0631     for (i = 0; i < bpmp->num_clocks; i++) {
0632         struct tegra_bpmp_clk *clk = bpmp->clocks[i];
0633 
0634         if (!clk)
0635             continue;
0636 
0637         if (clk->id == id)
0638             return &clk->hw;
0639     }
0640 
0641     return NULL;
0642 }
0643 
0644 int tegra_bpmp_init_clocks(struct tegra_bpmp *bpmp)
0645 {
0646     struct tegra_bpmp_clk_info *clocks;
0647     unsigned int count;
0648     int err;
0649 
0650     err = tegra_bpmp_probe_clocks(bpmp, &clocks);
0651     if (err < 0)
0652         return err;
0653 
0654     count = err;
0655 
0656     dev_dbg(bpmp->dev, "%u clocks probed\n", count);
0657 
0658     err = tegra_bpmp_register_clocks(bpmp, clocks, count);
0659     if (err < 0)
0660         goto free;
0661 
0662     err = of_clk_add_hw_provider(bpmp->dev->of_node,
0663                      tegra_bpmp_clk_of_xlate,
0664                      bpmp);
0665     if (err < 0) {
0666         tegra_bpmp_unregister_clocks(bpmp);
0667         goto free;
0668     }
0669 
0670 free:
0671     kfree(clocks);
0672     return err;
0673 }