diff options
Diffstat (limited to 'drivers/clk/clk-lmk04832.c')
| -rw-r--r-- | drivers/clk/clk-lmk04832.c | 100 |
1 files changed, 46 insertions, 54 deletions
diff --git a/drivers/clk/clk-lmk04832.c b/drivers/clk/clk-lmk04832.c index 99b271c1278a..b2107b31efa2 100644 --- a/drivers/clk/clk-lmk04832.c +++ b/drivers/clk/clk-lmk04832.c @@ -375,7 +375,7 @@ static unsigned long lmk04832_vco_recalc_rate(struct clk_hw *hw, unsigned long prate) { struct lmk04832 *lmk = container_of(hw, struct lmk04832, vco); - const unsigned int pll2_p[] = {8, 2, 2, 3, 4, 5, 6, 7}; + static const unsigned int pll2_p[] = {8, 2, 2, 3, 4, 5, 6, 7}; unsigned int pll2_n, p, pll2_r; unsigned int pll2_misc; unsigned long vco_rate; @@ -491,28 +491,33 @@ static long lmk04832_calc_pll2_params(unsigned long prate, unsigned long rate, return DIV_ROUND_CLOSEST(prate * 2 * pll2_p * pll2_n, pll2_r); } -static long lmk04832_vco_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int lmk04832_vco_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct lmk04832 *lmk = container_of(hw, struct lmk04832, vco); unsigned int n, p, r; long vco_rate; int ret; - ret = lmk04832_check_vco_ranges(lmk, rate); + ret = lmk04832_check_vco_ranges(lmk, req->rate); if (ret < 0) return ret; - vco_rate = lmk04832_calc_pll2_params(*prate, rate, &n, &p, &r); + vco_rate = lmk04832_calc_pll2_params(req->best_parent_rate, req->rate, + &n, &p, &r); if (vco_rate < 0) { dev_err(lmk->dev, "PLL2 parameters out of range\n"); - return vco_rate; + req->rate = vco_rate; + + return 0; } - if (rate != vco_rate) + if (req->rate != vco_rate) return -EINVAL; - return vco_rate; + req->rate = vco_rate; + + return 0; } static int lmk04832_vco_set_rate(struct clk_hw *hw, unsigned long rate, @@ -579,7 +584,7 @@ static const struct clk_ops lmk04832_vco_ops = { .prepare = lmk04832_vco_prepare, .unprepare = lmk04832_vco_unprepare, .recalc_rate = lmk04832_vco_recalc_rate, - .round_rate = lmk04832_vco_round_rate, + .determine_rate = lmk04832_vco_determine_rate, .set_rate = lmk04832_vco_set_rate, }; @@ -637,7 +642,7 @@ static int lmk04832_register_vco(struct lmk04832 *lmk) static int lmk04832_clkout_set_ddly(struct lmk04832 *lmk, int id) { - const int dclk_div_adj[] = {0, 0, -2, -2, 0, 3, -1, 0}; + static const int dclk_div_adj[] = {0, 0, -2, -2, 0, 3, -1, 0}; unsigned int sclkx_y_ddly = 10; unsigned int dclkx_y_ddly; unsigned int dclkx_y_div; @@ -888,25 +893,27 @@ static unsigned long lmk04832_sclk_recalc_rate(struct clk_hw *hw, return DIV_ROUND_CLOSEST(prate, sysref_div); } -static long lmk04832_sclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int lmk04832_sclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct lmk04832 *lmk = container_of(hw, struct lmk04832, sclk); unsigned long sclk_rate; unsigned int sysref_div; - sysref_div = DIV_ROUND_CLOSEST(*prate, rate); - sclk_rate = DIV_ROUND_CLOSEST(*prate, sysref_div); + sysref_div = DIV_ROUND_CLOSEST(req->best_parent_rate, req->rate); + sclk_rate = DIV_ROUND_CLOSEST(req->best_parent_rate, sysref_div); if (sysref_div < 0x07 || sysref_div > 0x1fff) { dev_err(lmk->dev, "SYSREF divider out of range\n"); return -EINVAL; } - if (rate != sclk_rate) + if (req->rate != sclk_rate) return -EINVAL; - return sclk_rate; + req->rate = sclk_rate; + + return 0; } static int lmk04832_sclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -945,7 +952,7 @@ static const struct clk_ops lmk04832_sclk_ops = { .prepare = lmk04832_sclk_prepare, .unprepare = lmk04832_sclk_unprepare, .recalc_rate = lmk04832_sclk_recalc_rate, - .round_rate = lmk04832_sclk_round_rate, + .determine_rate = lmk04832_sclk_determine_rate, .set_rate = lmk04832_sclk_set_rate, }; @@ -1069,26 +1076,28 @@ static unsigned long lmk04832_dclk_recalc_rate(struct clk_hw *hw, return rate; } -static long lmk04832_dclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int lmk04832_dclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw); struct lmk04832 *lmk = dclk->lmk; unsigned long dclk_rate; unsigned int dclk_div; - dclk_div = DIV_ROUND_CLOSEST(*prate, rate); - dclk_rate = DIV_ROUND_CLOSEST(*prate, dclk_div); + dclk_div = DIV_ROUND_CLOSEST(req->best_parent_rate, req->rate); + dclk_rate = DIV_ROUND_CLOSEST(req->best_parent_rate, dclk_div); if (dclk_div < 1 || dclk_div > 0x3ff) { dev_err(lmk->dev, "%s_div out of range\n", clk_hw_get_name(hw)); return -EINVAL; } - if (rate != dclk_rate) + if (req->rate != dclk_rate) return -EINVAL; - return dclk_rate; + req->rate = dclk_rate; + + return 0; } static int lmk04832_dclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -1158,7 +1167,7 @@ static const struct clk_ops lmk04832_dclk_ops = { .prepare = lmk04832_dclk_prepare, .unprepare = lmk04832_dclk_unprepare, .recalc_rate = lmk04832_dclk_recalc_rate, - .round_rate = lmk04832_dclk_round_rate, + .determine_rate = lmk04832_dclk_determine_rate, .set_rate = lmk04832_dclk_set_rate, }; @@ -1405,16 +1414,12 @@ static int lmk04832_probe(struct spi_device *spi) lmk->dev = &spi->dev; - lmk->oscin = devm_clk_get(lmk->dev, "oscin"); + lmk->oscin = devm_clk_get_enabled(lmk->dev, "oscin"); if (IS_ERR(lmk->oscin)) { dev_err(lmk->dev, "failed to get oscin clock\n"); return PTR_ERR(lmk->oscin); } - ret = clk_prepare_enable(lmk->oscin); - if (ret) - return ret; - lmk->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW); @@ -1422,14 +1427,14 @@ static int lmk04832_probe(struct spi_device *spi) sizeof(struct lmk_dclk), GFP_KERNEL); if (!lmk->dclk) { ret = -ENOMEM; - goto err_disable_oscin; + return ret; } lmk->clkout = devm_kcalloc(lmk->dev, info->num_channels, sizeof(*lmk->clkout), GFP_KERNEL); if (!lmk->clkout) { ret = -ENOMEM; - goto err_disable_oscin; + return ret; } lmk->clk_data = devm_kzalloc(lmk->dev, struct_size(lmk->clk_data, hws, @@ -1437,7 +1442,7 @@ static int lmk04832_probe(struct spi_device *spi) GFP_KERNEL); if (!lmk->clk_data) { ret = -ENOMEM; - goto err_disable_oscin; + return ret; } device_property_read_u32(lmk->dev, "ti,vco-hz", &lmk->vco_rate); @@ -1465,7 +1470,7 @@ static int lmk04832_probe(struct spi_device *spi) dev_err(lmk->dev, "missing reg property in child: %s\n", child->full_name); of_node_put(child); - goto err_disable_oscin; + return ret; } of_property_read_u32(child, "ti,clkout-fmt", @@ -1486,7 +1491,7 @@ static int lmk04832_probe(struct spi_device *spi) __func__, PTR_ERR(lmk->regmap)); ret = PTR_ERR(lmk->regmap); - goto err_disable_oscin; + return ret; } regmap_write(lmk->regmap, LMK04832_REG_RST3W, LMK04832_BIT_RESET); @@ -1496,7 +1501,7 @@ static int lmk04832_probe(struct spi_device *spi) &rdbk_pin); ret = lmk04832_set_spi_rdbk(lmk, rdbk_pin); if (ret) - goto err_disable_oscin; + return ret; } regmap_bulk_read(lmk->regmap, LMK04832_REG_ID_PROD_MSB, &tmp, 3); @@ -1504,13 +1509,13 @@ static int lmk04832_probe(struct spi_device *spi) dev_err(lmk->dev, "unsupported device type: pid 0x%04x, maskrev 0x%02x\n", tmp[0] << 8 | tmp[1], tmp[2]); ret = -EINVAL; - goto err_disable_oscin; + return ret; } ret = lmk04832_register_vco(lmk); if (ret) { dev_err(lmk->dev, "failed to init device clock path\n"); - goto err_disable_oscin; + return ret; } if (lmk->vco_rate) { @@ -1518,21 +1523,21 @@ static int lmk04832_probe(struct spi_device *spi) ret = clk_set_rate(lmk->vco.clk, lmk->vco_rate); if (ret) { dev_err(lmk->dev, "failed to set VCO rate\n"); - goto err_disable_oscin; + return ret; } } ret = lmk04832_register_sclk(lmk); if (ret) { dev_err(lmk->dev, "failed to init SYNC/SYSREF clock path\n"); - goto err_disable_oscin; + return ret; } for (i = 0; i < info->num_channels; i++) { ret = lmk04832_register_clkout(lmk, i); if (ret) { dev_err(lmk->dev, "failed to register clk %d\n", i); - goto err_disable_oscin; + return ret; } } @@ -1541,24 +1546,12 @@ static int lmk04832_probe(struct spi_device *spi) lmk->clk_data); if (ret) { dev_err(lmk->dev, "failed to add provider (%d)\n", ret); - goto err_disable_oscin; + return ret; } spi_set_drvdata(spi, lmk); return 0; - -err_disable_oscin: - clk_disable_unprepare(lmk->oscin); - - return ret; -} - -static void lmk04832_remove(struct spi_device *spi) -{ - struct lmk04832 *lmk = spi_get_drvdata(spi); - - clk_disable_unprepare(lmk->oscin); } static const struct spi_device_id lmk04832_id[] = { @@ -1579,7 +1572,6 @@ static struct spi_driver lmk04832_driver = { .of_match_table = lmk04832_of_id, }, .probe = lmk04832_probe, - .remove = lmk04832_remove, .id_table = lmk04832_id, }; module_spi_driver(lmk04832_driver); |
