diff options
Diffstat (limited to 'drivers/clk/qcom/clk-spmi-pmic-div.c')
| -rw-r--r-- | drivers/clk/qcom/clk-spmi-pmic-div.c | 37 |
1 files changed, 15 insertions, 22 deletions
diff --git a/drivers/clk/qcom/clk-spmi-pmic-div.c b/drivers/clk/qcom/clk-spmi-pmic-div.c index f2cf55cee2fd..3e2ac6745325 100644 --- a/drivers/clk/qcom/clk-spmi-pmic-div.c +++ b/drivers/clk/qcom/clk-spmi-pmic-div.c @@ -3,6 +3,7 @@ */ #include <linux/bitops.h> +#include <linux/cleanup.h> #include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/delay.h> @@ -111,16 +112,18 @@ static void clk_spmi_pmic_div_disable(struct clk_hw *hw) spin_unlock_irqrestore(&clkdiv->lock, flags); } -static long clk_spmi_pmic_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_spmi_pmic_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned int div, div_factor; - div = DIV_ROUND_UP(*parent_rate, rate); + div = DIV_ROUND_UP(req->best_parent_rate, req->rate); div_factor = div_to_div_factor(div); div = div_factor_to_div(div_factor); - return *parent_rate / div; + req->rate = req->best_parent_rate / div; + + return 0; } static unsigned long @@ -140,30 +143,26 @@ static int clk_spmi_pmic_div_set_rate(struct clk_hw *hw, unsigned long rate, { struct clkdiv *clkdiv = to_clkdiv(hw); unsigned int div_factor = div_to_div_factor(parent_rate / rate); - unsigned long flags; bool enabled; int ret; - spin_lock_irqsave(&clkdiv->lock, flags); + guard(spinlock_irqsave)(&clkdiv->lock); + enabled = is_spmi_pmic_clkdiv_enabled(clkdiv); if (enabled) { ret = spmi_pmic_clkdiv_set_enable_state(clkdiv, false); if (ret) - goto unlock; + return ret; } ret = regmap_update_bits(clkdiv->regmap, clkdiv->base + REG_DIV_CTL1, DIV_CTL1_DIV_FACTOR_MASK, div_factor); if (ret) - goto unlock; + return ret; if (enabled) ret = __spmi_pmic_clkdiv_set_enable_state(clkdiv, true, div_factor); - -unlock: - spin_unlock_irqrestore(&clkdiv->lock, flags); - return ret; } @@ -172,12 +171,12 @@ static const struct clk_ops clk_spmi_pmic_div_ops = { .disable = clk_spmi_pmic_div_disable, .set_rate = clk_spmi_pmic_div_set_rate, .recalc_rate = clk_spmi_pmic_div_recalc_rate, - .round_rate = clk_spmi_pmic_div_round_rate, + .determine_rate = clk_spmi_pmic_div_determine_rate, }; struct spmi_pmic_div_clk_cc { int nclks; - struct clkdiv clks[]; + struct clkdiv clks[] __counted_by(nclks); }; static struct clk_hw * @@ -204,7 +203,7 @@ static int spmi_pmic_clkdiv_probe(struct platform_device *pdev) struct regmap *regmap; struct device *dev = &pdev->dev; struct device_node *of_node = dev->of_node; - const char *parent_name; + struct clk_parent_data parent_data = { .index = 0, }; int nclks, i, ret, cxo_hz; char name[20]; u32 start; @@ -246,14 +245,8 @@ static int spmi_pmic_clkdiv_probe(struct platform_device *pdev) cxo_hz = clk_get_rate(cxo); clk_put(cxo); - parent_name = of_clk_get_parent_name(of_node, 0); - if (!parent_name) { - dev_err(dev, "missing parent clock\n"); - return -ENODEV; - } - init.name = name; - init.parent_names = &parent_name; + init.parent_data = &parent_data; init.num_parents = 1; init.ops = &clk_spmi_pmic_div_ops; |
