[PATCH 1/2] clk: change clk_ops' ->round_rate() prototype

Boris Brezillon
2015-04-17T07:29:28Z

Clock rates are stored in an unsigned long field, but ->round_rate()
(which returns a rounded rate from a requested one) returns a long
value (errors are reported using negative error codes), which can lead
to long overflow if the clock rate exceed 2Ghz.

Change ->round_rate() prototype to return 0 or an error code, and pass the
requested rate as a pointer so that it can be adjusted depending on
hardware capabilities.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
CC: Jonathan Corbet <corbet@lwn.net>
CC: Shawn Guo <shawn.guo@linaro.org>
CC: ascha Hauer <kernel@pengutronix.de>
CC: David Brown <davidb@codeaurora.org>
CC: Daniel Walker <dwalker@fifo99.com>
CC: Bryan Huntsman <bryanh@codeaurora.org>
CC: Tony Lindgren <tony@atomide.com>
CC: Paul Walmsley <paul@pwsan.com>
CC: Liviu Dudau <liviu.dudau@arm.com>
CC: Sudeep Holla <sudeep.holla@arm.com>
CC: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
CC: Ralf Baechle <ralf@linux-mips.org>
CC: Max Filippov <jcmvbkbc@gmail.com>
CC: Heiko Stuebner <heiko@sntech.de>
CC: Sylwester Nawrocki <s.nawrocki@samsung.com>
CC: Tomasz Figa <tomasz.figa@gmail.com>
CC: Barry Song <baohua@kernel.org>
CC: Viresh Kumar <viresh.linux@gmail.com>
CC: "Emilio López" <emilio@elopez.com.ar>
CC: Maxime Ripard <maxime.ripard@free-electrons.com>
CC: Peter De Schrijver <pdeschrijver@nvidia.com>
CC: Prashant Gaikwad <pgaikwad@nvidia.com>
CC: Stephen Warren <swarren@wwwdotorg.org>
CC: Thierry Reding <thierry.reding@gmail.com>
CC: Alexandre Courbot <gnurou@gmail.com>
CC: Tero Kristo <t-kristo@ti.com>
CC: Ulf Hansson <ulf.hansson@linaro.org>
CC: Michal Simek <michal.simek@xilinx.com>
CC: Philipp Zabel <p.zabel@pengutronix.de>
CC: linux-doc@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-arm-kernel@lists.infradead.org
CC: linux-arm-msm@vger.kernel.org
CC: linux-omap@vger.kernel.org
CC: linux-mips@linux-mips.org
CC: patches@opensource.wolfsonmicro.com
CC: linux-rockchip@lists.infradead.org
CC: linux-samsung-soc@vger.kernel.org
CC: spear-devel@list.st.com
CC: linux-tegra@vger.kernel.org
CC: dri-devel@lists.freedesktop.org
CC: linux-media@vger.kernel.org
CC: rtc-linux@googlegroups.com

Documentation/clk.txt | 4 +-
arch/arm/mach-imx/clk-busy.c | 2 +-
arch/arm/mach-imx/clk-cpu.c | 12 +++-
arch/arm/mach-imx/clk-fixup-div.c | 2 +-
arch/arm/mach-imx/clk-pfd.c | 11 ++--
arch/arm/mach-imx/clk-pllv2.c | 8 ++-
arch/arm/mach-imx/clk-pllv3.c | 46 +++++++------
arch/arm/mach-msm/clock-pcom.c | 4 +-
arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c | 13 ++--
arch/arm/mach-omap2/clkt_clksel.c | 6 +-
arch/arm/mach-omap2/clkt_dpll.c | 21 +++---
arch/arm/mach-omap2/clock.h | 4 +-
arch/arm/mach-omap2/dpll3xxx.c | 27 +++++---
arch/arm/mach-omap2/dpll44xx.c | 26 +++++---
arch/arm/mach-vexpress/spc.c | 11 +++-
arch/mips/alchemy/common/clock.c | 13 ++--
drivers/clk/at91/clk-h32mx.c | 24 ++++---
drivers/clk/at91/clk-peripheral.c | 31 +++++----
drivers/clk/at91/clk-pll.c | 14 ++--
drivers/clk/at91/clk-plldiv.c | 22 ++++---
drivers/clk/at91/clk-smd.c | 24 ++++---
drivers/clk/at91/clk-usb.c | 34 ++++++----
drivers/clk/clk-axi-clkgen.c | 5 +-
drivers/clk/clk-cdce706.c | 46 ++++++-------
drivers/clk/clk-composite.c | 23 ++++---
drivers/clk/clk-divider.c | 16 +++--
drivers/clk/clk-fixed-factor.c | 7 +-
drivers/clk/clk-fractional-divider.c | 16 +++--
drivers/clk/clk-highbank.c | 18 +++---
drivers/clk/clk-si5351.c | 96 ++++++++++++++--------------
drivers/clk/clk-si570.c | 14 ++--
drivers/clk/clk-u300.c | 65 ++++++++++---------
drivers/clk/clk-vt8500.c | 27 ++++----
drivers/clk/clk-wm831x.c | 11 ++--
drivers/clk/clk-xgene.c | 11 ++--
drivers/clk/clk.c | 15 +++--
drivers/clk/mmp/clk-frac.c | 14 ++--
drivers/clk/mvebu/clk-corediv.c | 7 +-
drivers/clk/mvebu/clk-cpu.c | 9 +--
drivers/clk/mxs/clk-div.c | 4 +-
drivers/clk/mxs/clk-frac.c | 11 ++--
drivers/clk/mxs/clk-ref.c | 11 ++--
drivers/clk/qcom/clk-regmap-divider.c | 4 +-
drivers/clk/rockchip/clk-pll.c | 13 ++--
drivers/clk/samsung/clk-pll.c | 13 ++--
drivers/clk/shmobile/clk-div6.c | 7 +-
drivers/clk/shmobile/clk-rcar-gen2.c | 9 +--
drivers/clk/sirf/clk-common.c | 18 +++---
drivers/clk/spear/clk-aux-synth.c | 10 ++-
drivers/clk/spear/clk-frac-synth.c | 10 ++-
drivers/clk/spear/clk-gpt-synth.c | 10 ++-
drivers/clk/spear/clk-vco-pll.c | 20 ++++--
drivers/clk/st/clk-flexgen.c | 11 ++--
drivers/clk/st/clkgen-fsyn.c | 21 +++---
drivers/clk/st/clkgen-mux.c | 2 +-
drivers/clk/sunxi/clk-factors.c | 14 ++--
drivers/clk/tegra/clk-audio-sync.c | 8 +--
drivers/clk/tegra/clk-divider.c | 19 ++++--
drivers/clk/tegra/clk-periph.c | 4 +-
drivers/clk/tegra/clk-pll.c | 39 ++++++-----
drivers/clk/ti/clk-dra7-atl.c | 9 +--
drivers/clk/ti/composite.c | 4 +-
drivers/clk/ti/divider.c | 9 +--
drivers/clk/ux500/clk-prcmu.c | 13 +++-
drivers/clk/versatile/clk-icst.c | 9 +--
drivers/clk/versatile/clk-vexpress-osc.c | 12 ++--
drivers/clk/zynq/pll.c | 7 +-
drivers/gpu/drm/imx/imx-tve.c | 15 +++--
drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c | 7 +-
drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_pll.c | 7 +-
drivers/media/platform/omap3isp/isp.c | 6 +-
drivers/rtc/rtc-hym8563.c | 14 ++--
include/linux/clk-provider.h | 6 +-
include/linux/clk/ti.h | 12 ++--
74 files changed, 672 insertions(+), 475 deletions(-)

diff --git a/Documentation/clk.txt b/Documentation/clk.txt
index 0e4f90a..fca8b7a 100644
--- a/Documentation/clk.txt
+++ b/Documentation/clk.txt
@@ -68,8 +68,8 @@ the operations defined in clk.h:
int (*is_enabled)(struct clk_hw *hw);
unsigned long (*recalc_rate)(struct clk_hw *hw,
unsigned long parent_rate);
- long (*round_rate)(struct clk_hw *hw,
- unsigned long rate,
+ int (*round_rate)(struct clk_hw *hw,
+ unsigned long *rate,
unsigned long *parent_rate);
long (*determine_rate)(struct clk_hw *hw,
unsigned long rate,
diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c
index 4bb1bc4..f8c67e9 100644
--- a/arch/arm/mach-imx/clk-busy.c
+++ b/arch/arm/mach-imx/clk-busy.c
@@ -51,7 +51,7 @@ static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw,
return busy->div_ops->recalc_rate(&busy->div.hw, parent_rate);
}

-static long clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct clk_busy_divider *busy = to_clk_busy_divider(hw);
diff --git a/arch/arm/mach-imx/clk-cpu.c b/arch/arm/mach-imx/clk-cpu.c
index aa1c345..f6af2d8 100644
--- a/arch/arm/mach-imx/clk-cpu.c
+++ b/arch/arm/mach-imx/clk-cpu.c
@@ -34,12 +34,18 @@ static unsigned long clk_cpu_recalc_rate(struct clk_hw *hw,
return clk_get_rate(cpu->div);
}

-static long clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_cpu_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
struct clk_cpu *cpu = to_clk_cpu(hw);
+ long ret;

- return clk_round_rate(cpu->pll, rate);
+ ret = clk_round_rate(cpu->pll, *rate);
+ if (ret < 0)
+ return ret;
+
+ *rate = ret;
+ return 0;
}

static int clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/arch/arm/mach-imx/clk-fixup-div.c b/arch/arm/mach-imx/clk-fixup-div.c
index 21db020..c2f4f00 100644
--- a/arch/arm/mach-imx/clk-fixup-div.c
+++ b/arch/arm/mach-imx/clk-fixup-div.c
@@ -48,7 +48,7 @@ static unsigned long clk_fixup_div_recalc_rate(struct clk_hw *hw,
return fixup_div->ops->recalc_rate(&fixup_div->divider.hw, parent_rate);
}

-static long clk_fixup_div_round_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_fixup_div_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw);
diff --git a/arch/arm/mach-imx/clk-pfd.c b/arch/arm/mach-imx/clk-pfd.c
index 0b0f6f6..449fb7a 100644
--- a/arch/arm/mach-imx/clk-pfd.c
+++ b/arch/arm/mach-imx/clk-pfd.c
@@ -68,14 +68,14 @@ static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw,
return tmp;
}

-static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_pfd_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
u64 tmp = *prate;
u8 frac;

- tmp = tmp * 18 + rate / 2;
- do_div(tmp, rate);
+ tmp = tmp * 18 + *rate / 2;
+ do_div(tmp, *rate);
frac = tmp;
if (frac < 12)
frac = 12;
@@ -85,7 +85,8 @@ static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
tmp *= 18;
do_div(tmp, frac);

- return tmp;
+ *rate = tmp;
+ return 0;
}

static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c
index 20889d5..6b48bf5 100644
--- a/arch/arm/mach-imx/clk-pllv2.c
+++ b/arch/arm/mach-imx/clk-pllv2.c
@@ -180,14 +180,16 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}

-static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_pllv2_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
u32 dp_op, dp_mfd, dp_mfn;

- __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn);
- return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN,
+ __clk_pllv2_set_rate(*rate, *prate, &dp_op, &dp_mfd, &dp_mfn);
+ *rate = __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN,
dp_op, dp_mfd, dp_mfn);
+
+ return 0;
}

static int clk_pllv2_prepare(struct clk_hw *hw)
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
index 641ebc5..4d8f4eb 100644
--- a/arch/arm/mach-imx/clk-pllv3.c
+++ b/arch/arm/mach-imx/clk-pllv3.c
@@ -104,13 +104,15 @@ static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
return (div == 1) ? parent_rate * 22 : parent_rate * 20;
}

-static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_pllv3_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
unsigned long parent_rate = *prate;

- return (rate >= parent_rate * 22) ? parent_rate * 22 :
- parent_rate * 20;
+ *rate = (*rate >= parent_rate * 22) ? parent_rate * 22 :
+ parent_rate * 20;
+
+ return 0;
}

static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -151,21 +153,23 @@ static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw,
return parent_rate * div / 2;
}

-static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
unsigned long parent_rate = *prate;
unsigned long min_rate = parent_rate * 54 / 2;
unsigned long max_rate = parent_rate * 108 / 2;
u32 div;

- if (rate > max_rate)
- rate = max_rate;
- else if (rate < min_rate)
- rate = min_rate;
- div = rate * 2 / parent_rate;
+ if (*rate > max_rate)
+ *rate = max_rate;
+ else if (*rate < min_rate)
+ *rate = min_rate;
+ div = *rate * 2 / parent_rate;

- return parent_rate * div / 2;
+ *rate = parent_rate * div / 2;
+
+ return 0;
}

static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -207,7 +211,7 @@ static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
return (parent_rate * div) + ((parent_rate / mfd) * mfn);
}

-static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
unsigned long parent_rate = *prate;
@@ -217,18 +221,20 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
u32 mfn, mfd = 1000000;
s64 temp64;

- if (rate > max_rate)
- rate = max_rate;
- else if (rate < min_rate)
- rate = min_rate;
+ if (*rate > max_rate)
+ *rate = max_rate;
+ else if (*rate < min_rate)
+ *rate = min_rate;

- div = rate / parent_rate;
- temp64 = (u64) (rate - div * parent_rate);
+ div = *rate / parent_rate;
+ temp64 = (u64) (*rate - div * parent_rate);
temp64 *= mfd;
do_div(temp64, parent_rate);
mfn = temp64;

- return parent_rate * div + parent_rate / mfd * mfn;
+ *rate = parent_rate * div + parent_rate / mfd * mfn;
+
+ return 0;
}

static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c
index f5b69d7..118c288 100644
--- a/arch/arm/mach-msm/clock-pcom.c
+++ b/arch/arm/mach-msm/clock-pcom.c
@@ -109,11 +109,11 @@ static int pc_clk_is_enabled(struct clk_hw *hw)
return id;
}

-static long pc_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+static int pc_clk_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *p_rate)
{
/* Not really supported; pc_clk_set_rate() does rounding on it's own. */
- return rate;
+ return 0;
}

static struct clk_ops clk_ops_pcom = {
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
index 85e0b0c0..2829a6f 100644
--- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -71,8 +71,8 @@ unsigned long omap2_table_mpu_recalc(struct clk_hw *clk,
* Some might argue L3-DDR, others ARM, others IVA. This code is simple and
* just uses the ARM rates.
*/
-long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+int omap2_round_to_table_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
const struct prcm_config *ptr;
long highest_rate;
@@ -88,10 +88,15 @@ long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
highest_rate = ptr->mpu_speed;

/* Can check only after xtal frequency check */
- if (ptr->mpu_speed <= rate)
+ if (ptr->mpu_speed <= *rate)
break;
}
- return highest_rate;
+
+ if (highest_rate < 0)
+ return highest_rate;
+
+ *rate = highest_rate;
+ return 0;
}

/* Sets basic clocks based on the specified rate */
diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c
index 7ee2610..b932276 100644
--- a/arch/arm/mach-omap2/clkt_clksel.c
+++ b/arch/arm/mach-omap2/clkt_clksel.c
@@ -385,13 +385,15 @@ unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate)
*
* Returns the rounded clock rate or returns 0xffffffff on error.
*/
-long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate,
+int omap2_clksel_round_rate(struct clk_hw *hw, unsigned long *target_rate,
unsigned long *parent_rate)
{
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
u32 new_div;

- return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
+ *target_rate = omap2_clksel_round_rate_div(clk, *target_rate,
+ &new_div);
+ return 0;
}

/**
diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
index f251a14..7dac6b3 100644
--- a/arch/arm/mach-omap2/clkt_dpll.c
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -280,7 +280,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
* (expensive) function again. Returns ~0 if the target rate cannot
* be rounded, or the rounded rate upon success.
*/
-long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
+int omap2_dpll_round_rate(struct clk_hw *hw, unsigned long *target_rate,
unsigned long *parent_rate)
{
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
@@ -295,16 +295,16 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
const char *clk_name;

if (!clk || !clk->dpll_data)
- return ~0;
+ return -EINVAL;

dd = clk->dpll_data;

ref_rate = __clk_get_rate(dd->clk_ref);
clk_name = __clk_get_name(hw->clk);
pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n",
- clk_name, target_rate);
+ clk_name, *target_rate);

- scaled_rt_rp = target_rate / (ref_rate / DPLL_SCALE_FACTOR);
+ scaled_rt_rp = *target_rate / (ref_rate / DPLL_SCALE_FACTOR);
scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;

dd->last_rounded_rate = 0;
@@ -330,7 +330,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
if (m > scaled_max_m)
break;

- r = _dpll_test_mult(&m, n, &new_rate, target_rate,
+ r = _dpll_test_mult(&m, n, &new_rate, *target_rate,
ref_rate);

/* m can't be set low enough for this n - try with a larger n */
@@ -338,7 +338,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
continue;

/* skip rates above our target rate */
- delta = target_rate - new_rate;
+ delta = *target_rate - new_rate;
if (delta < 0)
continue;

@@ -357,14 +357,15 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,

if (prev_min_delta == LONG_MAX) {
pr_debug("clock: %s: cannot round to rate %lu\n",
- clk_name, target_rate);
- return ~0;
+ clk_name, *target_rate);
+ return -EINVAL;
}

dd->last_rounded_m = min_delta_m;
dd->last_rounded_n = min_delta_n;
- dd->last_rounded_rate = target_rate - prev_min_delta;
+ dd->last_rounded_rate = *target_rate - prev_min_delta;

- return dd->last_rounded_rate;
+ *target_rate = dd->last_rounded_rate;
+ return 0;
}

diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index a56742f..cfe41b7 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -194,8 +194,8 @@ u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk,
u32 *new_div);
u8 omap2_clksel_find_parent_index(struct clk_hw *hw);
unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate);
-long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate,
- unsigned long *parent_rate);
+int omap2_clksel_round_rate(struct clk_hw *hw, unsigned long *target_rate,
+ unsigned long *parent_rate);
int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate);
int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val);
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index 44e57ec..7a6fb45 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -480,6 +480,7 @@ long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate,
{
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
struct dpll_data *dd;
+ int ret;

if (!hw || !rate)
return -EINVAL;
@@ -492,7 +493,10 @@ long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate,
(dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
*best_parent_clk = __clk_get_hw(dd->clk_bypass);
} else {
- rate = omap2_dpll_round_rate(hw, rate, best_parent_rate);
+ ret = omap2_dpll_round_rate(hw, &rate, best_parent_rate);
+ if (ret)
+ return ret;
+
*best_parent_clk = __clk_get_hw(dd->clk_ref);
}

@@ -768,27 +772,33 @@ int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}

-long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate,
+int omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
const struct dpll_data *dd;
u32 v;
struct clk_hw_omap *pclk = NULL;

- if (!*prate)
+ if (!*prate) {
+ *rate = 0;
return 0;
+ }

pclk = omap3_find_clkoutx2_dpll(hw);

- if (!pclk)
+ if (!pclk) {
+ *rate = 0;
return 0;
+ }

dd = pclk->dpll_data;

/* TYPE J does not have a clkoutx2 */
if (dd->flags & DPLL_J_TYPE) {
- *prate = __clk_round_rate(__clk_get_parent(pclk->hw.clk), rate);
- return *prate;
+ *prate = __clk_round_rate(__clk_get_parent(pclk->hw.clk),
+ *rate);
+ *rate = *prate;
+ return 0;
}

WARN_ON(!dd->enable_mask);
@@ -803,12 +813,13 @@ long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate,
if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
unsigned long best_parent;

- best_parent = (rate / 2);
+ best_parent = (*rate / 2);
*prate = __clk_round_rate(__clk_get_parent(hw->clk),
best_parent);
}

- return *prate * 2;
+ *rate = *prate * 2;
+ return 0;
}

/* OMAP3/4 non-CORE DPLL clkops */
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
index f231be0..afd3284 100644
--- a/arch/arm/mach-omap2/dpll44xx.c
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -146,11 +146,12 @@ unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
* M-dividers) upon success, -EINVAL if @clk is null or not a DPLL, or
* ~0 if an error occurred in omap2_dpll_round_rate().
*/
-long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
- unsigned long target_rate,
- unsigned long *parent_rate)
+int omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
+ unsigned long *target_rate,
+ unsigned long *parent_rate)
{
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ unsigned long rate = *target_rate;
struct dpll_data *dd;
long r;

@@ -166,7 +167,7 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
* target rate without using the 4X multiplier.
*/
r = omap2_dpll_round_rate(hw, target_rate, NULL);
- if (r != ~0)
+ if (!r)
goto out;

/*
@@ -174,9 +175,9 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
* this time see if using the 4X multiplier can help. Enabling the
* 4X multiplier is equivalent to dividing the target rate by 4.
*/
- r = omap2_dpll_round_rate(hw, target_rate / OMAP4430_REGM4XEN_MULT,
- NULL);
- if (r == ~0)
+ rate = *target_rate / OMAP4430_REGM4XEN_MULT;
+ r = omap2_dpll_round_rate(hw, &rate, NULL);
+ if (r)
return r;

dd->last_rounded_rate *= OMAP4430_REGM4XEN_MULT;
@@ -184,8 +185,9 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,

out:
omap4_dpll_lpmode_recalc(dd);
+ *target_rate = dd->last_rounded_rate;

- return dd->last_rounded_rate;
+ return 0;
}

/**
@@ -209,6 +211,7 @@ long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate,
{
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
struct dpll_data *dd;
+ int ret;

if (!hw || !rate)
return -EINVAL;
@@ -221,8 +224,11 @@ long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate,
(dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
*best_parent_clk = __clk_get_hw(dd->clk_bypass);
} else {
- rate = omap4_dpll_regm4xen_round_rate(hw, rate,
- best_parent_rate);
+ ret = omap4_dpll_regm4xen_round_rate(hw, &rate,
+ best_parent_rate);
+ if (ret)
+ return ret;
+
*best_parent_clk = __clk_get_hw(dd->clk_ref);
}

diff --git a/arch/arm/mach-vexpress/spc.c b/arch/arm/mach-vexpress/spc.c
index f61158c..774ac3b 100644
--- a/arch/arm/mach-vexpress/spc.c
+++ b/arch/arm/mach-vexpress/spc.c
@@ -507,12 +507,19 @@ static unsigned long spc_recalc_rate(struct clk_hw *hw,
return freq * 1000;
}

-static long spc_round_rate(struct clk_hw *hw, unsigned long drate,
+static int spc_round_rate(struct clk_hw *hw, unsigned long *drate,
unsigned long *parent_rate)
{
struct clk_spc *spc = to_clk_spc(hw);
+ long ret;

- return ve_spc_round_performance(spc->cluster, drate);
+ ret = ve_spc_round_performance(spc->cluster, *drate);
+ if (ret < 0)
+ return ret;
+
+ *drate = ret;
+
+ return 0;
}

static int spc_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c
index 6a98d2c..d697d8f 100644
--- a/arch/mips/alchemy/common/clock.c
+++ b/arch/mips/alchemy/common/clock.c
@@ -202,24 +202,27 @@ static int alchemy_clk_aux_setr(struct clk_hw *hw,
return 0;
}

-static long alchemy_clk_aux_roundr(struct clk_hw *hw,
- unsigned long rate,
+static int alchemy_clk_aux_roundr(struct clk_hw *hw,
+ unsigned long *rate,
unsigned long *parent_rate)
{
struct alchemy_auxpll_clk *a = to_auxpll_clk(hw);
unsigned long mult;

- if (!rate || !*parent_rate)
+ if (!*rate || !*parent_rate) {
+ *rate = 0;
return 0;
+ }

- mult = rate / (*parent_rate);
+ mult = *rate / (*parent_rate);

if (mult && (mult < 7))
mult = 7;
if (mult > a->maxmult)
mult = a->maxmult;

- return (*parent_rate) * mult;
+ *rate = (*parent_rate) * mult;
+ return 0;
}

static struct clk_ops alchemy_clkops_aux = {
diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c
index 152dcb3..e48f31e 100644
--- a/drivers/clk/at91/clk-h32mx.c
+++ b/drivers/clk/at91/clk-h32mx.c
@@ -49,21 +49,25 @@ static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk_hw *hw,
return parent_rate;
}

-static long clk_sama5d4_h32mx_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int clk_sama5d4_h32mx_round_rate(struct clk_hw *hw,
+ unsigned long *rate,
+ unsigned long *parent_rate)
{
unsigned long div;

- if (rate > *parent_rate)
- return *parent_rate;
- div = *parent_rate / 2;
- if (rate < div)
- return div;
+ if (*rate > *parent_rate) {
+ *rate = *parent_rate;
+ return 0;
+ }

- if (rate - div < *parent_rate - rate)
- return div;
+ div = *parent_rate / 2;
+ if (*rate < div || (*rate - div) < (*parent_rate - *rate)) {
+ *rate = div;
+ return 0;
+ }

- return *parent_rate;
+ *rate = *parent_rate;
+ return 0;
}

static int clk_sama5d4_h32mx_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index 597fed4..d990ae0 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -227,9 +227,9 @@ clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw,
return parent_rate >> periph->div;
}

-static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw,
- unsigned long rate,
- unsigned long *parent_rate)
+static int clk_sam9x5_peripheral_round_rate(struct clk_hw *hw,
+ unsigned long *rate,
+ unsigned long *parent_rate)
{
int shift = 0;
unsigned long best_rate;
@@ -238,8 +238,10 @@ static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw,
unsigned long cur_diff;
struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);

- if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max)
- return *parent_rate;
+ if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) {
+ *rate = *parent_rate;
+ return 0;
+ }

if (periph->range.max) {
for (; shift < PERIPHERAL_MAX_SHIFT; shift++) {
@@ -249,28 +251,31 @@ static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw,
}
}

- if (rate >= cur_rate)
- return cur_rate;
+ if (*rate >= cur_rate) {
+ *rate = cur_rate;
+ return 0;
+ }

- best_diff = cur_rate - rate;
+ best_diff = cur_rate - *rate;
best_rate = cur_rate;
for (; shift < PERIPHERAL_MAX_SHIFT; shift++) {
cur_rate = *parent_rate >> shift;
- if (cur_rate < rate)
- cur_diff = rate - cur_rate;
+ if (cur_rate < *rate)
+ cur_diff = *rate - cur_rate;
else
- cur_diff = cur_rate - rate;
+ cur_diff = cur_rate - *rate;

if (cur_diff < best_diff) {
best_diff = cur_diff;
best_rate = cur_rate;
}

- if (!best_diff || cur_rate < rate)
+ if (!best_diff || cur_rate < *rate)
break;
}

- return best_rate;
+ *rate = best_rate;
+ return 0;
}

static int clk_sam9x5_peripheral_set_rate(struct clk_hw *hw,
diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c
index 6ec79db..e7754eb 100644
--- a/drivers/clk/at91/clk-pll.c
+++ b/drivers/clk/at91/clk-pll.c
@@ -260,13 +260,19 @@ static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate,
return bestrate;
}

-static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int clk_pll_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
struct clk_pll *pll = to_clk_pll(hw);
+ long ret;

- return clk_pll_get_best_div_mul(pll, rate, *parent_rate,
- NULL, NULL, NULL);
+ ret = clk_pll_get_best_div_mul(pll, *rate, *parent_rate,
+ NULL, NULL, NULL);
+ if (ret < 0)
+ return ret;
+
+ *rate = ret;
+ return 0;
}

static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c
index ea22656..c267214 100644
--- a/drivers/clk/at91/clk-plldiv.c
+++ b/drivers/clk/at91/clk-plldiv.c
@@ -36,21 +36,23 @@ static unsigned long clk_plldiv_recalc_rate(struct clk_hw *hw,
return parent_rate;
}

-static long clk_plldiv_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int clk_plldiv_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
unsigned long div;

- if (rate > *parent_rate)
- return *parent_rate;
- div = *parent_rate / 2;
- if (rate < div)
- return div;
+ if (*rate > *parent_rate) {
+ *rate = *parent_rate;
+ return 0;
+ }

- if (rate - div < *parent_rate - rate)
- return div;
+ div = *parent_rate / 2;
+ if (*rate < div || (*rate - div) < (*parent_rate - *rate))
+ *rate = div;
+ else
+ *rate = *parent_rate;

- return *parent_rate;
+ return 0;
}

static int clk_plldiv_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c
index 144d47e..cd0f6d2 100644
--- a/drivers/clk/at91/clk-smd.c
+++ b/drivers/clk/at91/clk-smd.c
@@ -43,26 +43,32 @@ static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw,
return parent_rate / (smddiv + 1);
}

-static long at91sam9x5_clk_smd_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int at91sam9x5_clk_smd_round_rate(struct clk_hw *hw,
+ unsigned long *rate,
+ unsigned long *parent_rate)
{
unsigned long div;
unsigned long bestrate;
unsigned long tmp;

- if (rate >= *parent_rate)
- return *parent_rate;
+ if (*rate >= *parent_rate) {
+ *rate = *parent_rate;
+ return 0;
+ }

- div = *parent_rate / rate;
- if (div > SMD_MAX_DIV)
- return *parent_rate / (SMD_MAX_DIV + 1);
+ div = *parent_rate / *rate;
+ if (div > SMD_MAX_DIV) {
+ *rate = *parent_rate / (SMD_MAX_DIV + 1);
+ return 0;
+ }

bestrate = *parent_rate / div;
tmp = *parent_rate / (div + 1);
- if (bestrate - rate > rate - tmp)
+ if (bestrate - *rate > *rate - tmp)
bestrate = tmp;

- return bestrate;
+ *rate = bestrate;
+ return 0;
}

static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index)
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c
index a23ac0c..02599e6 100644
--- a/drivers/clk/at91/clk-usb.c
+++ b/drivers/clk/at91/clk-usb.c
@@ -56,22 +56,26 @@ static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw,
return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1));
}

-static long at91sam9x5_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int at91sam9x5_clk_usb_round_rate(struct clk_hw *hw,
+ unsigned long *rate,
+ unsigned long *parent_rate)
{
unsigned long div;

- if (!rate)
+ if (!*rate)
return -EINVAL;

- if (rate >= *parent_rate)
- return *parent_rate;
+ if (*rate >= *parent_rate) {
+ *rate = *parent_rate;
+ return 0;
+ }

- div = DIV_ROUND_CLOSEST(*parent_rate, rate);
+ div = DIV_ROUND_CLOSEST(*parent_rate, *rate);
if (div > SAM9X5_USB_MAX_DIV + 1)
div = SAM9X5_USB_MAX_DIV + 1;

- return DIV_ROUND_CLOSEST(*parent_rate, div);
+ *rate = DIV_ROUND_CLOSEST(*parent_rate, div);
+ return 0;
}

static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
@@ -235,8 +239,9 @@ static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw,
return 0;
}

-static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int at91rm9200_clk_usb_round_rate(struct clk_hw *hw,
+ unsigned long *rate,
+ unsigned long *parent_rate)
{
struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
struct clk *parent = __clk_get_parent(hw->clk);
@@ -252,13 +257,13 @@ static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
if (!usb->divisors[i])
continue;

- tmp_parent_rate = rate * usb->divisors[i];
+ tmp_parent_rate = *rate * usb->divisors[i];
tmp_parent_rate = __clk_round_rate(parent, tmp_parent_rate);
tmprate = DIV_ROUND_CLOSEST(tmp_parent_rate, usb->divisors[i]);
- if (tmprate < rate)
- tmpdiff = rate - tmprate;
+ if (tmprate < *rate)
+ tmpdiff = *rate - tmprate;
else
- tmpdiff = tmprate - rate;
+ tmpdiff = tmprate - *rate;

if (bestdiff < 0 || bestdiff > tmpdiff) {
bestrate = tmprate;
@@ -270,7 +275,8 @@ static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
break;
}

- return bestrate;
+ *rate = bestrate;
+ return 0;
}

static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
index e619285..3509d50 100644
--- a/drivers/clk/clk-axi-clkgen.c
+++ b/drivers/clk/clk-axi-clkgen.c
@@ -405,7 +405,7 @@ static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
return 0;
}

-static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate,
+static int axi_clkgen_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *parent_rate)
{
unsigned int d, m, dout;
@@ -415,7 +415,8 @@ static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate,
if (d == 0 || dout == 0 || m == 0)
return -EINVAL;

- return *parent_rate / d * m / dout;
+ *rate = *parent_rate / d * m / dout;
+ return 0;
}

static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c
index c386ad2..f110959 100644
--- a/drivers/clk/clk-cdce706.c
+++ b/drivers/clk/clk-cdce706.c
@@ -187,8 +187,8 @@ static unsigned long cdce706_pll_recalc_rate(struct clk_hw *hw,
return 0;
}

-static long cdce706_pll_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int cdce706_pll_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
struct cdce706_hw_data *hwd = to_hw_data(hw);
unsigned long mul, div;
@@ -196,9 +196,9 @@ static long cdce706_pll_round_rate(struct clk_hw *hw, unsigned long rate,

dev_dbg(&hwd->dev_data->client->dev,
"%s, rate: %lu, parent_rate: %lu\n",
- __func__, rate, *parent_rate);
+ __func__, *rate, *parent_rate);

- rational_best_approximation(rate, *parent_rate,
+ rational_best_approximation(*rate, *parent_rate,
CDCE706_PLL_N_MAX, CDCE706_PLL_M_MAX,
&mul, &div);
hwd->mul = mul;
@@ -210,7 +210,8 @@ static long cdce706_pll_round_rate(struct clk_hw *hw, unsigned long rate,

res = (u64)*parent_rate * hwd->mul;
do_div(res, hwd->div);
- return res;
+ *rate = res;
+ return 0;
}

static int cdce706_pll_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -292,8 +293,8 @@ static unsigned long cdce706_divider_recalc_rate(struct clk_hw *hw,
return 0;
}

-static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int cdce706_divider_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
struct cdce706_hw_data *hwd = to_hw_data(hw);
struct cdce706_dev_data *cdce = hwd->dev_data;
@@ -301,31 +302,31 @@ static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate,

dev_dbg(&hwd->dev_data->client->dev,
"%s, rate: %lu, parent_rate: %lu\n",
- __func__, rate, *parent_rate);
+ __func__, *rate, *parent_rate);

- rational_best_approximation(rate, *parent_rate,
+ rational_best_approximation(*rate, *parent_rate,
1, CDCE706_DIVIDER_DIVIDER_MAX,
&mul, &div);
if (!mul)
div = CDCE706_DIVIDER_DIVIDER_MAX;

if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
- unsigned long best_diff = rate;
+ unsigned long best_diff = *rate;
unsigned long best_div = 0;
struct clk *gp_clk = cdce->clkin_clk[cdce->clkin[0].parent];
unsigned long gp_rate = gp_clk ? clk_get_rate(gp_clk) : 0;

- for (div = CDCE706_PLL_FREQ_MIN / rate; best_diff &&
- div <= CDCE706_PLL_FREQ_MAX / rate; ++div) {
+ for (div = CDCE706_PLL_FREQ_MIN / *rate; best_diff &&
+ div <= CDCE706_PLL_FREQ_MAX / *rate; ++div) {
unsigned long n, m;
unsigned long diff;
unsigned long div_rate;
u64 div_rate64;

- if (rate * div < CDCE706_PLL_FREQ_MIN)
+ if (*rate * div < CDCE706_PLL_FREQ_MIN)
continue;

- rational_best_approximation(rate * div, gp_rate,
+ rational_best_approximation(*rate * div, gp_rate,
CDCE706_PLL_N_MAX,
CDCE706_PLL_M_MAX,
&n, &m);
@@ -333,7 +334,7 @@ static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate,
do_div(div_rate64, m);
do_div(div_rate64, div);
div_rate = div_rate64;
- diff = max(div_rate, rate) - min(div_rate, rate);
+ diff = max(div_rate, *rate) - min(div_rate, *rate);

if (diff < best_diff) {
best_diff = diff;
@@ -348,8 +349,8 @@ static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate,

dev_dbg(&hwd->dev_data->client->dev,
"%s, altering parent rate: %lu -> %lu\n",
- __func__, *parent_rate, rate * div);
- *parent_rate = rate * div;
+ __func__, *parent_rate, *rate * div);
+ *parent_rate = *rate * div;
}
hwd->div = div;

@@ -357,7 +358,8 @@ static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate,
"%s, divider: %d, div: %lu\n",
__func__, hwd->idx, div);

- return *parent_rate / div;
+ *rate = *parent_rate / div;
+ return 0;
}

static int cdce706_divider_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -425,11 +427,11 @@ static unsigned long cdce706_clkout_recalc_rate(struct clk_hw *hw,
return parent_rate;
}

-static long cdce706_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int cdce706_clkout_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
- *parent_rate = rate;
- return rate;
+ *parent_rate = *rate;
+ return 0;
}

static int cdce706_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 956b7e5..f56a71d 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -68,10 +68,10 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
struct clk_hw *mux_hw = composite->mux_hw;
struct clk *parent;
unsigned long parent_rate;
- long tmp_rate, best_rate = 0;
+ unsigned long tmp_rate, best_rate = 0;
unsigned long rate_diff;
unsigned long best_rate_diff = ULONG_MAX;
- int i;
+ int ret, i;

if (rate_hw && rate_ops && rate_ops->determine_rate) {
__clk_hw_set_clk(rate_hw, hw);
@@ -88,8 +88,12 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
*best_parent_p = __clk_get_hw(parent);
*best_parent_rate = __clk_get_rate(parent);

- return rate_ops->round_rate(rate_hw, rate,
- best_parent_rate);
+ ret = rate_ops->round_rate(rate_hw, &rate,
+ best_parent_rate);
+ if (ret)
+ return ret;
+
+ return rate;
}

for (i = 0; i < __clk_get_num_parents(mux_hw->clk); i++) {
@@ -99,9 +103,10 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,

parent_rate = __clk_get_rate(parent);

- tmp_rate = rate_ops->round_rate(rate_hw, rate,
- &parent_rate);
- if (tmp_rate < 0)
+ tmp_rate = rate;
+ ret = rate_ops->round_rate(rate_hw, &tmp_rate,
+ &parent_rate);
+ if (ret < 0)
continue;

rate_diff = abs(rate - tmp_rate);
@@ -130,8 +135,8 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
}
}

-static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_composite_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
struct clk_composite *composite = to_clk_composite(hw);
const struct clk_ops *rate_ops = composite->rate_ops;
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 25006a8..f646a0c 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -329,19 +329,20 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
return bestdiv;
}

-long divider_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate, const struct clk_div_table *table,
- u8 width, unsigned long flags)
+int divider_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate, const struct clk_div_table *table,
+ u8 width, unsigned long flags)
{
int div;

- div = clk_divider_bestdiv(hw, rate, prate, table, width, flags);
+ div = clk_divider_bestdiv(hw, *rate, prate, table, width, flags);

- return DIV_ROUND_UP(*prate, div);
+ *rate = DIV_ROUND_UP(*prate, div);
+ return 0;
}
EXPORT_SYMBOL_GPL(divider_round_rate);

-static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_divider_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct clk_divider *divider = to_clk_divider(hw);
@@ -352,7 +353,8 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
bestdiv = readl(divider->reg) >> divider->shift;
bestdiv &= div_mask(divider->width);
bestdiv = _get_div(divider->table, bestdiv, divider->flags);
- return DIV_ROUND_UP(*prate, bestdiv);
+ *rate = DIV_ROUND_UP(*prate, bestdiv);
+ return 0;
}

return divider_round_rate(hw, rate, prate, divider->table,
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index d9e3f67..ff936d0 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -36,7 +36,7 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
return (unsigned long)rate;
}

-static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_factor_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
@@ -44,12 +44,13 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
unsigned long best_parent;

- best_parent = (rate / fix->mult) * fix->div;
+ best_parent = (*rate / fix->mult) * fix->div;
*prate = __clk_round_rate(__clk_get_parent(hw->clk),
best_parent);
}

- return (*prate / fix->div) * fix->mult;
+ *rate = (*prate / fix->div) * fix->mult;
+ return 0;
}

static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 6aa72d9..1f1ba3e 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -45,24 +45,26 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
return ret;
}

-static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_fd_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
struct clk_fractional_divider *fd = to_clk_fd(hw);
unsigned maxn = (fd->nmask >> fd->nshift) + 1;
unsigned div;

- if (!rate || rate >= *prate)
- return *prate;
+ if (!*rate || *rate >= *prate) {
+ *rate = *prate;
+ return 0;
+ }

- div = gcd(*prate, rate);
+ div = gcd(*prate, *rate);

while ((*prate / div) > maxn) {
div <<= 1;
- rate <<= 1;
+ *rate <<= 1;
}

- return rate;
+ return 0;
}

static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c
index 2e7e9d9..f26d1b0 100644
--- a/drivers/clk/clk-highbank.c
+++ b/drivers/clk/clk-highbank.c
@@ -142,15 +142,16 @@ static void clk_pll_calc(unsigned long rate, unsigned long ref_freq,
*pdivf = divf;
}

-static long clk_pll_round_rate(struct clk_hw *hwclk, unsigned long rate,
- unsigned long *parent_rate)
+static int clk_pll_round_rate(struct clk_hw *hwclk, unsigned long *rate,
+ unsigned long *parent_rate)
{
u32 divq, divf;
unsigned long ref_freq = *parent_rate;

- clk_pll_calc(rate, ref_freq, &divq, &divf);
+ clk_pll_calc(*rate, ref_freq, &divq, &divf);

- return (ref_freq * (divf + 1)) / (1 << divq);
+ *rate = (ref_freq * (divf + 1)) / (1 << divq);
+ return 0;
}

static int clk_pll_set_rate(struct clk_hw *hwclk, unsigned long rate,
@@ -239,16 +240,17 @@ static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk,
return parent_rate / div;
}

-static long clk_periclk_round_rate(struct clk_hw *hwclk, unsigned long rate,
- unsigned long *parent_rate)
+static int clk_periclk_round_rate(struct clk_hw *hwclk, unsigned long *rate,
+ unsigned long *parent_rate)
{
u32 div;

- div = *parent_rate / rate;
+ div = *parent_rate / *rate;
div++;
div &= ~0x1;

- return *parent_rate / div;
+ *rate = *parent_rate / div;
+ return 0;
}

static int clk_periclk_set_rate(struct clk_hw *hwclk, unsigned long rate,
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 3b2a66f..8fad555 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -446,30 +446,30 @@ static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw,
return (unsigned long)rate;
}

-static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int si5351_pll_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned long rfrac, denom, a, b, c;
unsigned long long lltmp;

- if (rate < SI5351_PLL_VCO_MIN)
- rate = SI5351_PLL_VCO_MIN;
- if (rate > SI5351_PLL_VCO_MAX)
- rate = SI5351_PLL_VCO_MAX;
+ if (*rate < SI5351_PLL_VCO_MIN)
+ *rate = SI5351_PLL_VCO_MIN;
+ if (*rate > SI5351_PLL_VCO_MAX)
+ *rate = SI5351_PLL_VCO_MAX;

/* determine integer part of feedback equation */
- a = rate / *parent_rate;
+ a = *rate / *parent_rate;

if (a < SI5351_PLL_A_MIN)
- rate = *parent_rate * SI5351_PLL_A_MIN;
+ *rate = *parent_rate * SI5351_PLL_A_MIN;
if (a > SI5351_PLL_A_MAX)
- rate = *parent_rate * SI5351_PLL_A_MAX;
+ *rate = *parent_rate * SI5351_PLL_A_MAX;

/* find best approximation for b/c = fVCO mod fIN */
denom = 1000 * 1000;
- lltmp = rate % (*parent_rate);
+ lltmp = *rate % (*parent_rate);
lltmp *= denom;
do_div(lltmp, *parent_rate);
rfrac = (unsigned long)lltmp;
@@ -492,15 +492,15 @@ static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate,
lltmp *= b;
do_div(lltmp, c);

- rate = (unsigned long)lltmp;
- rate += *parent_rate * a;
+ *rate = (unsigned long)lltmp;
+ *rate += *parent_rate * a;

dev_dbg(&hwdata->drvdata->client->dev,
"%s - %s: a = %lu, b = %lu, c = %lu, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), a, b, c,
- *parent_rate, rate);
+ *parent_rate, *rate);

- return rate;
+ return 0;
}

static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -639,8 +639,8 @@ static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw,
return (unsigned long)rate;
}

-static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int si5351_msynth_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
@@ -649,17 +649,17 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
int divby4;

/* multisync6-7 can only handle freqencies < 150MHz */
- if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ)
- rate = SI5351_MULTISYNTH67_MAX_FREQ;
+ if (hwdata->num >= 6 && *rate > SI5351_MULTISYNTH67_MAX_FREQ)
+ *rate = SI5351_MULTISYNTH67_MAX_FREQ;

/* multisync frequency is 1MHz .. 160MHz */
- if (rate > SI5351_MULTISYNTH_MAX_FREQ)
- rate = SI5351_MULTISYNTH_MAX_FREQ;
- if (rate < SI5351_MULTISYNTH_MIN_FREQ)
- rate = SI5351_MULTISYNTH_MIN_FREQ;
+ if (*rate > SI5351_MULTISYNTH_MAX_FREQ)
+ *rate = SI5351_MULTISYNTH_MAX_FREQ;
+ if (*rate < SI5351_MULTISYNTH_MIN_FREQ)
+ *rate = SI5351_MULTISYNTH_MIN_FREQ;

divby4 = 0;
- if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
+ if (*rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
divby4 = 1;

/* multisync can set pll */
@@ -670,7 +670,7 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
*/
if (divby4 == 0) {
lltmp = SI5351_PLL_VCO_MAX;
- do_div(lltmp, rate);
+ do_div(lltmp, *rate);
a = (unsigned long)lltmp;
} else
a = 4;
@@ -678,18 +678,18 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
b = 0;
c = 1;

- *parent_rate = a * rate;
+ *parent_rate = a * *rate;
} else {
unsigned long rfrac, denom;

/* disable divby4 */
if (divby4) {
- rate = SI5351_MULTISYNTH_DIVBY4_FREQ;
+ *rate = SI5351_MULTISYNTH_DIVBY4_FREQ;
divby4 = 0;
}

/* determine integer part of divider equation */
- a = *parent_rate / rate;
+ a = *parent_rate / *rate;
if (a < SI5351_MULTISYNTH_A_MIN)
a = SI5351_MULTISYNTH_A_MIN;
if (hwdata->num >= 6 && a > SI5351_MULTISYNTH67_A_MAX)
@@ -699,9 +699,9 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,

/* find best approximation for b/c = fVCO mod fOUT */
denom = 1000 * 1000;
- lltmp = (*parent_rate) % rate;
+ lltmp = (*parent_rate) % *rate;
lltmp *= denom;
- do_div(lltmp, rate);
+ do_div(lltmp, *rate);
rfrac = (unsigned long)lltmp;

b = 0;
@@ -716,7 +716,7 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
lltmp = *parent_rate;
lltmp *= c;
do_div(lltmp, a * c + b);
- rate = (unsigned long)lltmp;
+ *rate = (unsigned long)lltmp;

/* calculate parameters */
if (divby4) {
@@ -734,9 +734,9 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
dev_dbg(&hwdata->drvdata->client->dev,
"%s - %s: a = %lu, b = %lu, c = %lu, divby4 = %d, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), a, b, c, divby4,
- *parent_rate, rate);
+ *parent_rate, *rate);

- return rate;
+ return 0;
}

static int si5351_msynth_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -983,57 +983,57 @@ static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw,
return parent_rate >> rdiv;
}

-static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int si5351_clkout_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned char rdiv;

/* clkout6/7 can only handle output freqencies < 150MHz */
- if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ)
- rate = SI5351_CLKOUT67_MAX_FREQ;
+ if (hwdata->num >= 6 && *rate > SI5351_CLKOUT67_MAX_FREQ)
+ *rate = SI5351_CLKOUT67_MAX_FREQ;

/* clkout freqency is 8kHz - 160MHz */
- if (rate > SI5351_CLKOUT_MAX_FREQ)
- rate = SI5351_CLKOUT_MAX_FREQ;
- if (rate < SI5351_CLKOUT_MIN_FREQ)
- rate = SI5351_CLKOUT_MIN_FREQ;
+ if (*rate > SI5351_CLKOUT_MAX_FREQ)
+ *rate = SI5351_CLKOUT_MAX_FREQ;
+ if (*rate < SI5351_CLKOUT_MIN_FREQ)
+ *rate = SI5351_CLKOUT_MIN_FREQ;

/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
/* use r divider for frequencies below 1MHz */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
- while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
+ while (*rate < SI5351_MULTISYNTH_MIN_FREQ &&
rdiv < SI5351_OUTPUT_CLK_DIV_128) {
rdiv += 1;
- rate *= 2;
+ *rate *= 2;
}
- *parent_rate = rate;
+ *parent_rate = *rate;
} else {
unsigned long new_rate, new_err, err;

/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
- err = abs(new_rate - rate);
+ err = abs(new_rate - *rate);
do {
new_rate >>= 1;
- new_err = abs(new_rate - rate);
+ new_err = abs(new_rate - *rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
break;
rdiv++;
err = new_err;
} while (1);
}
- rate = *parent_rate >> rdiv;
+ *rate = *parent_rate >> rdiv;

dev_dbg(&hwdata->drvdata->client->dev,
"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
- *parent_rate, rate);
+ *parent_rate, *rate);

- return rate;
+ return 0;
}

static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/clk-si570.c b/drivers/clk/clk-si570.c
index fc167b3..0680863 100644
--- a/drivers/clk/clk-si570.c
+++ b/drivers/clk/clk-si570.c
@@ -245,7 +245,7 @@ static unsigned long si570_recalc_rate(struct clk_hw *hw,
return rate;
}

-static long si570_round_rate(struct clk_hw *hw, unsigned long rate,
+static int si570_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *parent_rate)
{
int err;
@@ -253,26 +253,26 @@ static long si570_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned int n1, hs_div;
struct clk_si570 *data = to_clk_si570(hw);

- if (!rate)
+ if (!*rate)
return 0;

- if (div64_u64(abs(rate - data->frequency) * 10000LL,
+ if (div64_u64(abs(*rate - data->frequency) * 10000LL,
data->frequency) < 35) {
- rfreq = div64_u64((data->rfreq * rate) +
+ rfreq = div64_u64((data->rfreq * *rate) +
div64_u64(data->frequency, 2), data->frequency);
n1 = data->n1;
hs_div = data->hs_div;

} else {
- err = si570_calc_divs(rate, data, &rfreq, &n1, &hs_div);
+ err = si570_calc_divs(*rate, data, &rfreq, &n1, &hs_div);
if (err) {
dev_err(&data->i2c_client->dev,
"unable to round rate\n");
- return 0;
+ *rate = 0;
}
}

- return rate;
+ return 0;
}

/**
diff --git a/drivers/clk/clk-u300.c b/drivers/clk/clk-u300.c
index 406bfc1..5e3163b 100644
--- a/drivers/clk/clk-u300.c
+++ b/drivers/clk/clk-u300.c
@@ -628,22 +628,27 @@ syscon_clk_recalc_rate(struct clk_hw *hw,
}
}

-static long
-syscon_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+static int
+syscon_clk_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct clk_syscon *sclk = to_syscon(hw);

- if (sclk->clk_val != U300_SYSCON_SBCER_CPU_CLK_EN)
- return *prate;
+ if (sclk->clk_val != U300_SYSCON_SBCER_CPU_CLK_EN) {
+ *rate = *prate;
+ return 0;
+ }
/* We really only support setting the rate of the CPU clock */
- if (rate <= 13000000)
- return 13000000;
- if (rate <= 52000000)
- return 52000000;
- if (rate <= 104000000)
- return 104000000;
- return 208000000;
+ if (*rate <= 13000000)
+ *rate = 13000000;
+ else if (*rate <= 52000000)
+ *rate = 52000000;
+ else if (*rate <= 104000000)
+ *rate = 104000000;
+ else
+ *rate = 208000000;
+
+ return 0;
}

static int syscon_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -1037,26 +1042,28 @@ mclk_clk_recalc_rate(struct clk_hw *hw,
return parent_rate;
}

-static long
-mclk_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+static int
+mclk_clk_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
- if (rate <= 18900000)
- return 18900000;
- if (rate <= 20800000)
- return 20800000;
- if (rate <= 23100000)
- return 23100000;
- if (rate <= 26000000)
- return 26000000;
- if (rate <= 29700000)
- return 29700000;
- if (rate <= 34700000)
- return 34700000;
- if (rate <= 41600000)
- return 41600000;
- /* Highest rate */
- return 52000000;
+ if (*rate <= 18900000)
+ *rate = 18900000;
+ else if (*rate <= 20800000)
+ *rate = 20800000;
+ else if (*rate <= 23100000)
+ *rate = 23100000;
+ else if (*rate <= 26000000)
+ *rate = 26000000;
+ else if (*rate <= 29700000)
+ *rate = 29700000;
+ else if (*rate <= 34700000)
+ *rate = 34700000;
+ else if (*rate <= 41600000)
+ *rate = 41600000;
+ else
+ *rate = 52000000;
+
+ return 0;
}

static int mclk_clk_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c
index 37e9288..221eec3 100644
--- a/drivers/clk/clk-vt8500.c
+++ b/drivers/clk/clk-vt8500.c
@@ -137,19 +137,19 @@ static unsigned long vt8500_dclk_recalc_rate(struct clk_hw *hw,
return parent_rate / div;
}

-static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
+static int vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct clk_device *cdev = to_clk_device(hw);
u32 divisor;

- if (rate == 0)
+ if (*rate == 0)
return 0;

- divisor = *prate / rate;
+ divisor = *prate / *rate;

/* If prate / rate would be decimal, incr the divisor */
- if (rate * divisor < *prate)
+ if (*rate * divisor < *prate)
divisor++;

/*
@@ -160,7 +160,8 @@ static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
divisor = 64 * ((divisor / 64) + 1);
}

- return *prate / divisor;
+ *rate = *prate / divisor;
+ return 0;
}

static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -579,8 +580,8 @@ static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}

-static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int vtwm_pll_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
struct clk_pll *pll = to_clk_pll(hw);
u32 filter, mul, div1, div2;
@@ -588,26 +589,28 @@ static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate,

switch (pll->type) {
case PLL_TYPE_VT8500:
- vt8500_find_pll_bits(rate, *prate, &mul, &div1);
+ vt8500_find_pll_bits(*rate, *prate, &mul, &div1);
round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1);
break;
case PLL_TYPE_WM8650:
- wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2);
+ wm8650_find_pll_bits(*rate, *prate, &mul, &div1, &div2);
round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2);
break;
case PLL_TYPE_WM8750:
- wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2);
+ wm8750_find_pll_bits(*rate, *prate, &filter, &mul, &div1,
+ &div2);
round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2);
break;
case PLL_TYPE_WM8850:
- wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2);
+ wm8850_find_pll_bits(*rate, *prate, &mul, &div1, &div2);
round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2);
break;
default:
round_rate = 0;
}

- return round_rate;
+ *rate = round_rate;
+ return 0;
}

static unsigned long vtwm_pll_recalc_rate(struct clk_hw *hw,
diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c
index ef67719..23db1b5 100644
--- a/drivers/clk/clk-wm831x.c
+++ b/drivers/clk/clk-wm831x.c
@@ -142,18 +142,19 @@ static unsigned long wm831x_fll_recalc_rate(struct clk_hw *hw,
return 0;
}

-static long wm831x_fll_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *unused)
+static int wm831x_fll_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *unused)
{
int best = 0;
int i;

for (i = 0; i < ARRAY_SIZE(wm831x_fll_auto_rates); i++)
- if (abs(wm831x_fll_auto_rates[i] - rate) <
- abs(wm831x_fll_auto_rates[best] - rate))
+ if (abs(wm831x_fll_auto_rates[i] - *rate) <
+ abs(wm831x_fll_auto_rates[best] - *rate))
best = i;

- return wm831x_fll_auto_rates[best];
+ *rate = wm831x_fll_auto_rates[best];
+ return 0;
}

static int wm831x_fll_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index dd8a62d..27460e3 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -367,7 +367,7 @@ static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate,
return parent_rate / divider_save;
}

-static long xgene_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+static int xgene_clk_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct xgene_clk *pclk = to_xgene_clk(hw);
@@ -376,14 +376,15 @@ static long xgene_clk_round_rate(struct clk_hw *hw, unsigned long rate,

if (pclk->param.divider_reg) {
/* Let's compute the divider */
- if (rate > parent_rate)
- rate = parent_rate;
- divider = parent_rate / rate; /* Rounded down */
+ if (*rate > parent_rate)
+ *rate = parent_rate;
+ divider = parent_rate / *rate; /* Rounded down */
} else {
divider = 1;
}

- return parent_rate / divider;
+ *rate = parent_rate / divider;
+ return 0;
}

const struct clk_ops xgene_clk_ops = {
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index fa5a00e..1462ddc 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1146,9 +1146,12 @@ static unsigned long clk_core_round_rate_nolock(struct clk_core *clk,
return clk->ops->determine_rate(clk->hw, rate,
min_rate, max_rate,
&parent_rate, &parent_hw);
- } else if (clk->ops->round_rate)
- return clk->ops->round_rate(clk->hw, rate, &parent_rate);
- else if (clk->flags & CLK_SET_RATE_PARENT)
+ } else if (clk->ops->round_rate) {
+ if (clk->ops->round_rate(clk->hw, &rate, &parent_rate))
+ return 0;
+
+ return rate;
+ } else if (clk->flags & CLK_SET_RATE_PARENT)
return clk_core_round_rate_nolock(clk->parent, rate, min_rate,
max_rate);
else
@@ -1640,8 +1643,10 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *clk,
&parent_hw);
parent = parent_hw ? parent_hw->core : NULL;
} else if (clk->ops->round_rate) {
- new_rate = clk->ops->round_rate(clk->hw, rate,
- &best_parent_rate);
+ if (clk->ops->round_rate(clk->hw, &new_rate,
+ &best_parent_rate))
+ return NULL;
+
if (new_rate < min_rate || new_rate > max_rate)
return NULL;
} else if (!parent || !(clk->flags & CLK_SET_RATE_PARENT)) {
diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 584a992..6652983 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -24,7 +24,7 @@

#define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)

-static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
+static int clk_factor_round_rate(struct clk_hw *hw, unsigned long *drate,
unsigned long *prate)
{
struct mmp_clk_factor *factor = to_clk_factor(hw);
@@ -35,17 +35,19 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
prev_rate = rate;
rate = (((*prate / 10000) * factor->ftbl[i].den) /
(factor->ftbl[i].num * factor->masks->factor)) * 10000;
- if (rate > drate)
+ if (rate > *drate)
break;
}
if ((i == 0) || (i == factor->ftbl_cnt)) {
- return rate;
+ *drate = rate;
} else {
- if ((drate - prev_rate) > (rate - drate))
- return rate;
+ if ((*drate - prev_rate) > (rate - *drate))
+ *drate = rate;
else
- return prev_rate;
+ *drate = prev_rate;
}
+
+ return 0;
}

static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
diff --git a/drivers/clk/mvebu/clk-corediv.c b/drivers/clk/mvebu/clk-corediv.c
index d1e5863..c5aee2f 100644
--- a/drivers/clk/mvebu/clk-corediv.c
+++ b/drivers/clk/mvebu/clk-corediv.c
@@ -132,19 +132,20 @@ static unsigned long clk_corediv_recalc_rate(struct clk_hw *hwclk,
return parent_rate / div;
}

-static long clk_corediv_round_rate(struct clk_hw *hwclk, unsigned long rate,
+static int clk_corediv_round_rate(struct clk_hw *hwclk, unsigned long *rate,
unsigned long *parent_rate)
{
/* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */
u32 div;

- div = *parent_rate / rate;
+ div = *parent_rate / *rate;
if (div < 4)
div = 4;
else if (div > 6)
div = 8;

- return *parent_rate / div;
+ *rate = *parent_rate / div;
+ return 0;
}

static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,
diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c
index 3821a88..0279b50 100644
--- a/drivers/clk/mvebu/clk-cpu.c
+++ b/drivers/clk/mvebu/clk-cpu.c
@@ -57,19 +57,20 @@ static unsigned long clk_cpu_recalc_rate(struct clk_hw *hwclk,
return parent_rate / div;
}

-static long clk_cpu_round_rate(struct clk_hw *hwclk, unsigned long rate,
- unsigned long *parent_rate)
+static int clk_cpu_round_rate(struct clk_hw *hwclk, unsigned long *rate,
+ unsigned long *parent_rate)
{
/* Valid ratio are 1:1, 1:2 and 1:3 */
u32 div;

- div = *parent_rate / rate;
+ div = *parent_rate / *rate;
if (div == 0)
div = 1;
else if (div > 3)
div = 3;

- return *parent_rate / div;
+ *rate = *parent_rate / div;
+ return 0;
}

static int clk_cpu_off_set_rate(struct clk_hw *hwclk, unsigned long rate,
diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c
index 90e1da9..3677e51 100644
--- a/drivers/clk/mxs/clk-div.c
+++ b/drivers/clk/mxs/clk-div.c
@@ -47,8 +47,8 @@ static unsigned long clk_div_recalc_rate(struct clk_hw *hw,
return div->ops->recalc_rate(&div->divider.hw, parent_rate);
}

-static long clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_div_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
struct clk_div *div = to_clk_div(hw);

diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c
index e6aa6b5..86fc3bb 100644
--- a/drivers/clk/mxs/clk-frac.c
+++ b/drivers/clk/mxs/clk-frac.c
@@ -49,18 +49,18 @@ static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
return (parent_rate >> frac->width) * div;
}

-static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_frac_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
struct clk_frac *frac = to_clk_frac(hw);
unsigned long parent_rate = *prate;
u32 div;
u64 tmp;

- if (rate > parent_rate)
+ if (*rate > parent_rate)
return -EINVAL;

- tmp = rate;
+ tmp = *rate;
tmp <<= frac->width;
do_div(tmp, parent_rate);
div = tmp;
@@ -68,7 +68,8 @@ static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
if (!div)
return -EINVAL;

- return (parent_rate >> frac->width) * div;
+ *rate = (parent_rate >> frac->width) * div;
+ return 0;
}

static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/mxs/clk-ref.c b/drivers/clk/mxs/clk-ref.c
index 4adeed6..e0d6529 100644
--- a/drivers/clk/mxs/clk-ref.c
+++ b/drivers/clk/mxs/clk-ref.c
@@ -64,15 +64,15 @@ static unsigned long clk_ref_recalc_rate(struct clk_hw *hw,
return tmp;
}

-static long clk_ref_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_ref_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
unsigned long parent_rate = *prate;
u64 tmp = parent_rate;
u8 frac;

- tmp = tmp * 18 + rate / 2;
- do_div(tmp, rate);
+ tmp = tmp * 18 + *rate / 2;
+ do_div(tmp, *rate);
frac = tmp;

if (frac < 18)
@@ -83,8 +83,9 @@ static long clk_ref_round_rate(struct clk_hw *hw, unsigned long rate,
tmp = parent_rate;
tmp *= 18;
do_div(tmp, frac);
+ *rate = tmp;

- return tmp;
+ return 0;
}

static int clk_ref_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/qcom/clk-regmap-divider.c b/drivers/clk/qcom/clk-regmap-divider.c
index 5348491..1720da4 100644
--- a/drivers/clk/qcom/clk-regmap-divider.c
+++ b/drivers/clk/qcom/clk-regmap-divider.c
@@ -23,8 +23,8 @@ static inline struct clk_regmap_div *to_clk_regmap_div(struct clk_hw *hw)
return container_of(to_clk_regmap(hw), struct clk_regmap_div, clkr);
}

-static long div_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int div_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
struct clk_regmap_div *divider = to_clk_regmap_div(hw);

diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index f8d3baf..bd408ef 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -63,8 +63,8 @@ static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
return NULL;
}

-static long rockchip_pll_round_rate(struct clk_hw *hw,
- unsigned long drate, unsigned long *prate)
+static int rockchip_pll_round_rate(struct clk_hw *hw,
+ unsigned long *drate, unsigned long *prate)
{
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
@@ -72,12 +72,15 @@ static long rockchip_pll_round_rate(struct clk_hw *hw,

/* Assumming rate_table is in descending order */
for (i = 0; i < pll->rate_count; i++) {
- if (drate >= rate_table[i].rate)
- return rate_table[i].rate;
+ if (*drate >= rate_table[i].rate) {
+ *drate = rate_table[i].rate;
+ return 0;
+ }
}

/* return minimum supported value */
- return rate_table[i - 1].rate;
+ *drate = rate_table[i - 1].rate;
+ return 0;
}

/*
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 9d70e5c..0128de2 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -42,8 +42,8 @@ static const struct samsung_pll_rate_table *samsung_get_pll_settings(
return NULL;
}

-static long samsung_pll_round_rate(struct clk_hw *hw,
- unsigned long drate, unsigned long *prate)
+static int samsung_pll_round_rate(struct clk_hw *hw,
+ unsigned long *drate, unsigned long *prate)
{
struct samsung_clk_pll *pll = to_clk_pll(hw);
const struct samsung_pll_rate_table *rate_table = pll->rate_table;
@@ -51,12 +51,15 @@ static long samsung_pll_round_rate(struct clk_hw *hw,

/* Assumming rate_table is in descending order */
for (i = 0; i < pll->rate_count; i++) {
- if (drate >= rate_table[i].rate)
- return rate_table[i].rate;
+ if (*drate >= rate_table[i].rate) {
+ *drate = rate_table[i].rate;
+ return 0;
+ }
}

/* return minimum supported value */
- return rate_table[i - 1].rate;
+ *drate = rate_table[i - 1].rate;
+ return 0;
}

/*
diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c
index 036a692..d31ae3d 100644
--- a/drivers/clk/shmobile/clk-div6.c
+++ b/drivers/clk/shmobile/clk-div6.c
@@ -97,12 +97,13 @@ static unsigned int cpg_div6_clock_calc_div(unsigned long rate,
return clamp_t(unsigned int, div, 1, 64);
}

-static long cpg_div6_clock_round_rate(struct clk_hw *hw, unsigned long rate,
+static int cpg_div6_clock_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *parent_rate)
{
- unsigned int div = cpg_div6_clock_calc_div(rate, *parent_rate);
+ unsigned int div = cpg_div6_clock_calc_div(*rate, *parent_rate);

- return *parent_rate / div;
+ *rate = *parent_rate / div;
+ return 0;
}

static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c
index acfb6d7..57581a9 100644
--- a/drivers/clk/shmobile/clk-rcar-gen2.c
+++ b/drivers/clk/shmobile/clk-rcar-gen2.c
@@ -68,8 +68,8 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
return div_u64((u64)parent_rate * mult, 32);
}

-static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
unsigned long prate = *parent_rate;
unsigned int mult;
@@ -77,10 +77,11 @@ static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate,
if (!prate)
prate = 1;

- mult = div_u64((u64)rate * 32, prate);
+ mult = div_u64((u64)*rate * 32, prate);
mult = clamp(mult, 1U, 32U);

- return *parent_rate / 32 * mult;
+ *rate = *parent_rate / 32 * mult;
+ return 0;
}

static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/sirf/clk-common.c b/drivers/clk/sirf/clk-common.c
index 37af51c..68a7889 100644
--- a/drivers/clk/sirf/clk-common.c
+++ b/drivers/clk/sirf/clk-common.c
@@ -91,7 +91,7 @@ static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
}
}

-static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+static int pll_clk_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *parent_rate)
{
unsigned long fin, nf, nr, od;
@@ -101,9 +101,9 @@ static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
* fout = fin * nf / (nr * od);
* set od = 1, nr = fin/MHz, so fout = nf * MHz
*/
- rate = rate - rate % MHZ;
+ *rate = *rate - *rate % MHZ;

- nf = rate / MHZ;
+ nf = *rate / MHZ;
if (nf > BIT(13))
nf = BIT(13);
if (nf < 1)
@@ -119,7 +119,8 @@ static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
dividend = (u64)fin * nf;
do_div(dividend, nr * od);

- return (long)dividend;
+ *rate = dividend;
+ return 0;
}

static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -158,7 +159,7 @@ static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}

-static long cpu_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+static int cpu_clk_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *parent_rate)
{
/*
@@ -347,7 +348,7 @@ static unsigned long dmn_clk_recalc_rate(struct clk_hw *hw,
}
}

-static long dmn_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+static int dmn_clk_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *parent_rate)
{
unsigned long fin;
@@ -355,7 +356,7 @@ static long dmn_clk_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;

fin = *parent_rate;
- ratio = fin / rate;
+ ratio = fin / *rate;

if (ratio < 2)
ratio = 2;
@@ -365,7 +366,8 @@ static long dmn_clk_round_rate(struct clk_hw *hw, unsigned long rate,
wait = (ratio >> 1) - 1;
hold = ratio - wait - 2;

- return fin / (wait + hold + 2);
+ *rate = fin / (wait + hold + 2);
+ return 0;
}

static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c
index bdfb442..1a93f6a 100644
--- a/drivers/clk/spear/clk-aux-synth.c
+++ b/drivers/clk/spear/clk-aux-synth.c
@@ -52,14 +52,20 @@ static unsigned long aux_calc_rate(struct clk_hw *hw, unsigned long prate,
(rtbl[index].yscale * eq)) * 10000;
}

-static long clk_aux_round_rate(struct clk_hw *hw, unsigned long drate,
+static int clk_aux_round_rate(struct clk_hw *hw, unsigned long *drate,
unsigned long *prate)
{
struct clk_aux *aux = to_clk_aux(hw);
int unused;
+ long ret;

- return clk_round_rate_index(hw, drate, *prate, aux_calc_rate,
+ ret = clk_round_rate_index(hw, *drate, *prate, aux_calc_rate,
aux->rtbl_cnt, &unused);
+ if (ret < 0)
+ return ret;
+
+ *drate = ret;
+ return 0;
}

static unsigned long clk_aux_recalc_rate(struct clk_hw *hw,
diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c
index dffd4ce..d4098c8 100644
--- a/drivers/clk/spear/clk-frac-synth.c
+++ b/drivers/clk/spear/clk-frac-synth.c
@@ -55,14 +55,20 @@ static unsigned long frac_calc_rate(struct clk_hw *hw, unsigned long prate,
return prate;
}

-static long clk_frac_round_rate(struct clk_hw *hw, unsigned long drate,
+static int clk_frac_round_rate(struct clk_hw *hw, unsigned long *drate,
unsigned long *prate)
{
struct clk_frac *frac = to_clk_frac(hw);
int unused;
+ long ret;

- return clk_round_rate_index(hw, drate, *prate, frac_calc_rate,
+ ret = clk_round_rate_index(hw, *drate, *prate, frac_calc_rate,
frac->rtbl_cnt, &unused);
+ if (ret < 0)
+ return ret;
+
+ *drate = ret;
+ return 0;
}

static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c
index 1afc18c..ea3328b 100644
--- a/drivers/clk/spear/clk-gpt-synth.c
+++ b/drivers/clk/spear/clk-gpt-synth.c
@@ -42,14 +42,20 @@ static unsigned long gpt_calc_rate(struct clk_hw *hw, unsigned long prate,
return prate;
}

-static long clk_gpt_round_rate(struct clk_hw *hw, unsigned long drate,
+static int clk_gpt_round_rate(struct clk_hw *hw, unsigned long *drate,
unsigned long *prate)
{
struct clk_gpt *gpt = to_clk_gpt(hw);
int unused;
+ long ret;

- return clk_round_rate_index(hw, drate, *prate, gpt_calc_rate,
+ ret = clk_round_rate_index(hw, *drate, *prate, gpt_calc_rate,
gpt->rtbl_cnt, &unused);
+ if (ret < 0)
+ return ret;
+
+ *drate = ret;
+ return 0;
}

static unsigned long clk_gpt_recalc_rate(struct clk_hw *hw,
diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c
index 1b9b65b..08b1411 100644
--- a/drivers/clk/spear/clk-vco-pll.c
+++ b/drivers/clk/spear/clk-vco-pll.c
@@ -113,12 +113,18 @@ static long clk_pll_round_rate_index(struct clk_hw *hw, unsigned long drate,
return rate;
}

-static long clk_pll_round_rate(struct clk_hw *hw, unsigned long drate,
+static int clk_pll_round_rate(struct clk_hw *hw, unsigned long *drate,
unsigned long *prate)
{
int unused;
+ long ret;

- return clk_pll_round_rate_index(hw, drate, prate, &unused);
+ ret = clk_pll_round_rate_index(hw, *drate, prate, &unused);
+ if (ret < 0)
+ return ret;
+
+ *drate = ret;
+ return 0;
}

static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, unsigned long
@@ -179,14 +185,20 @@ static inline unsigned long vco_calc_rate(struct clk_hw *hw,
return pll_calc_rate(vco->rtbl, prate, index, NULL);
}

-static long clk_vco_round_rate(struct clk_hw *hw, unsigned long drate,
+static int clk_vco_round_rate(struct clk_hw *hw, unsigned long *drate,
unsigned long *prate)
{
struct clk_vco *vco = to_clk_vco(hw);
int unused;
+ long ret;

- return clk_round_rate_index(hw, drate, *prate, vco_calc_rate,
+ ret = clk_round_rate_index(hw, *drate, *prate, vco_calc_rate,
vco->rtbl_cnt, &unused);
+ if (ret < 0)
+ return ret;
+
+ *drate = ret;
+ return 0;
}

static unsigned long clk_vco_recalc_rate(struct clk_hw *hw,
diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c
index bf12a25..d04278b 100644
--- a/drivers/clk/st/clk-flexgen.c
+++ b/drivers/clk/st/clk-flexgen.c
@@ -100,20 +100,21 @@ clk_best_div(unsigned long parent_rate, unsigned long rate)
return parent_rate / rate + ((rate > (2*(parent_rate % rate))) ? 0 : 1);
}

-static long flexgen_round_rate(struct clk_hw *hw, unsigned long rate,
+static int flexgen_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
unsigned long div;

/* Round div according to exact prate and wished rate */
- div = clk_best_div(*prate, rate);
+ div = clk_best_div(*prate, *rate);

if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
- *prate = rate * div;
- return rate;
+ *prate = *rate * div;
+ return 0;
}

- return *prate / div;
+ *rate = *prate / div;
+ return 0;
}

unsigned long flexgen_recalc_rate(struct clk_hw *hw,
diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
index af94ed8..7c70049 100644
--- a/drivers/clk/st/clkgen-fsyn.c
+++ b/drivers/clk/st/clkgen-fsyn.c
@@ -548,21 +548,22 @@ int clk_fs660c32_vco_get_params(unsigned long input,
return 0;
}

-static long quadfs_pll_fs660c32_round_rate(struct clk_hw *hw, unsigned long rate
- , unsigned long *prate)
+static int quadfs_pll_fs660c32_round_rate(struct clk_hw *hw,
+ unsigned long *rate,
+ unsigned long *prate)
{
struct stm_fs params;

- if (!clk_fs660c32_vco_get_params(*prate, rate, &params))
- clk_fs660c32_vco_get_rate(*prate, &params, &rate);
+ if (!clk_fs660c32_vco_get_params(*prate, *rate, &params))
+ clk_fs660c32_vco_get_rate(*prate, &params, rate);

pr_debug("%s: %s new rate %ld [sdiv=0x%x,md=0x%x,pe=0x%x,nsdiv3=%u]\n",
__func__, __clk_get_name(hw->clk),
- rate, (unsigned int)params.sdiv,
+ *rate, (unsigned int)params.sdiv,
(unsigned int)params.mdiv,
(unsigned int)params.pe, (unsigned int)params.nsdiv);

- return rate;
+ return 0;
}

static int quadfs_pll_fs660c32_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -953,19 +954,19 @@ static unsigned long quadfs_recalc_rate(struct clk_hw *hw,
return rate;
}

-static long quadfs_round_rate(struct clk_hw *hw, unsigned long rate,
+static int quadfs_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct stm_fs params;

- rate = quadfs_find_best_rate(hw, rate, *prate, &params);
+ *rate = quadfs_find_best_rate(hw, *rate, *prate, &params);

pr_debug("%s: %s new rate %ld [sdiv=0x%x,md=0x%x,pe=0x%x,nsdiv3=%u]\n",
__func__, __clk_get_name(hw->clk),
- rate, (unsigned int)params.sdiv, (unsigned int)params.mdiv,
+ *rate, (unsigned int)params.sdiv, (unsigned int)params.mdiv,
(unsigned int)params.pe, (unsigned int)params.nsdiv);

- return rate;
+ return 0;
}

diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c
index 9a15ec3..2bbcb7b 100644
--- a/drivers/clk/st/clkgen-mux.c
+++ b/drivers/clk/st/clkgen-mux.c
@@ -190,7 +190,7 @@ static int clkgena_divmux_set_rate(struct clk_hw *hw, unsigned long rate,
return clk_divider_ops.set_rate(div_hw, rate, parent_rate);
}

-static long clkgena_divmux_round_rate(struct clk_hw *hw, unsigned long rate,
+static int clkgena_divmux_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index 8c20190..5865300 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -69,14 +69,17 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
return rate;
}

-static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int clk_factors_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
struct clk_factors *factors = to_clk_factors(hw);
- factors->get_factors((u32 *)&rate, (u32)*parent_rate,
+ u32 tmp_rate = *rate;
+
+ factors->get_factors(&tmp_rate, (u32)*parent_rate,
NULL, NULL, NULL, NULL);

- return rate;
+ *rate = tmp_rate;
+ return 0;
}

static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate,
@@ -100,7 +103,8 @@ static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate,
else
parent_rate = __clk_get_rate(parent);

- child_rate = clk_factors_round_rate(hw, rate, &parent_rate);
+ child_rate = rate;
+ clk_factors_round_rate(hw, &child_rate, &parent_rate);

if (child_rate <= rate && child_rate > best_child_rate) {
best_parent = parent;
diff --git a/drivers/clk/tegra/clk-audio-sync.c b/drivers/clk/tegra/clk-audio-sync.c
index c0f7843..0224256 100644
--- a/drivers/clk/tegra/clk-audio-sync.c
+++ b/drivers/clk/tegra/clk-audio-sync.c
@@ -28,15 +28,15 @@ static unsigned long clk_sync_source_recalc_rate(struct clk_hw *hw,
return sync->rate;
}

-static long clk_sync_source_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_sync_source_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);

- if (rate > sync->max_rate)
+ if (*rate > sync->max_rate)
return -EINVAL;
else
- return rate;
+ return 0;
}

static int clk_sync_source_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c
index 59a5714..9e5ca82 100644
--- a/drivers/clk/tegra/clk-divider.c
+++ b/drivers/clk/tegra/clk-divider.c
@@ -85,23 +85,28 @@ static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw,
return rate;
}

-static long clk_frac_div_round_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_frac_div_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct tegra_clk_frac_div *divider = to_clk_frac_div(hw);
int div, mul;
unsigned long output_rate = *prate;

- if (!rate)
- return output_rate;
+ if (!*rate) {
+ *rate = output_rate;
+ return 0;
+ }

- div = get_div(divider, rate, output_rate);
- if (div < 0)
- return *prate;
+ div = get_div(divider, *rate, output_rate);
+ if (div < 0) {
+ *rate = *prate;
+ return 0;
+ }

mul = get_mul(divider);

- return DIV_ROUND_UP(output_rate * mul, div + mul);
+ *rate = DIV_ROUND_UP(output_rate * mul, div + mul);
+ return 0;
}

static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index d84ae49..5a262f5 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -56,8 +56,8 @@ static unsigned long clk_periph_recalc_rate(struct clk_hw *hw,
return div_ops->recalc_rate(div_hw, parent_rate);
}

-static long clk_periph_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_periph_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
struct tegra_clk_periph *periph = to_clk_periph(hw);
const struct clk_ops *div_ops = periph->div_ops;
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index bfef9ab..a73bdb3 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -623,24 +623,29 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
return ret;
}

-static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_pll_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct tegra_clk_pll *pll = to_clk_pll(hw);
struct tegra_clk_pll_freq_table cfg;

- if (pll->params->flags & TEGRA_PLL_FIXED)
- return pll->params->fixed_rate;
+ if (pll->params->flags & TEGRA_PLL_FIXED) {
+ *rate = pll->params->fixed_rate;
+ return 0;
+ }

/* PLLM is used for memory; we do not change rate */
- if (pll->params->flags & TEGRA_PLLM)
- return __clk_get_rate(hw->clk);
+ if (pll->params->flags & TEGRA_PLLM) {
+ *rate = __clk_get_rate(hw->clk);
+ return 0;
+ }

- if (_get_table_rate(hw, &cfg, rate, *prate) &&
- _calc_rate(hw, &cfg, rate, *prate))
+ if (_get_table_rate(hw, &cfg, *rate, *prate) &&
+ _calc_rate(hw, &cfg, *rate, *prate))
return -EINVAL;

- return cfg.output_rate;
+ *rate = cfg.output_rate;
+ return 0;
}

static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
@@ -1001,25 +1006,28 @@ static int clk_pllxc_set_rate(struct clk_hw *hw, unsigned long rate,
return ret;
}

-static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct tegra_clk_pll_freq_table cfg;
int ret = 0, p_div;
u64 output_rate = *prate;

- ret = _pll_ramp_calc_pll(hw, &cfg, rate, *prate);
+ ret = _pll_ramp_calc_pll(hw, &cfg, *rate, *prate);
if (ret < 0)
return ret;

p_div = _hw_to_p_div(hw, cfg.p);
- if (p_div < 0)
- return p_div;
+ if (p_div < 0) {
+ *rate = p_div;
+ return 0;
+ }

output_rate *= cfg.n;
do_div(output_rate, cfg.m * p_div);

- return output_rate;
+ *rate = output_rate;
+ return 0;
}

static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -1272,12 +1280,13 @@ static unsigned long clk_pllre_recalc_rate(struct clk_hw *hw,
return rate;
}

-static long clk_pllre_round_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_pllre_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
struct tegra_clk_pll *pll = to_clk_pll(hw);

- return _pllre_calc_rate(pll, NULL, rate, *prate);
+ *rate = _pllre_calc_rate(pll, NULL, *rate, *prate);
+ return 0;
}

static int clk_plle_tegra114_enable(struct clk_hw *hw)
diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
index 59bb4b3..cdf1d17 100644
--- a/drivers/clk/ti/clk-dra7-atl.c
+++ b/drivers/clk/ti/clk-dra7-atl.c
@@ -124,16 +124,17 @@ static unsigned long atl_clk_recalc_rate(struct clk_hw *hw,
return parent_rate / cdesc->divider;
}

-static long atl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int atl_clk_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
unsigned divider;

- divider = (*parent_rate + rate / 2) / rate;
+ divider = (*parent_rate + *rate / 2) / *rate;
if (divider > DRA7_ATL_DIVIDER_MASK + 1)
divider = DRA7_ATL_DIVIDER_MASK + 1;

- return *parent_rate / divider;
+ *rate = *parent_rate / divider;
+ return 0;
}

static int atl_clk_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 3654f61..eddad41 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -36,8 +36,8 @@ static unsigned long ti_composite_recalc_rate(struct clk_hw *hw,
return ti_clk_divider_ops.recalc_rate(hw, parent_rate);
}

-static long ti_composite_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int ti_composite_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
return -EINVAL;
}
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index ff5f117..6044251 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -200,13 +200,14 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
return bestdiv;
}

-static long ti_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int ti_clk_divider_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
int div;
- div = ti_clk_divider_bestdiv(hw, rate, prate);
+ div = ti_clk_divider_bestdiv(hw, *rate, prate);

- return DIV_ROUND_UP(*prate, div);
+ *rate = DIV_ROUND_UP(*prate, div);
+ return 0;
}

static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c
index bf63c96..1e1aa2d 100644
--- a/drivers/clk/ux500/clk-prcmu.c
+++ b/drivers/clk/ux500/clk-prcmu.c
@@ -80,11 +80,18 @@ static unsigned long clk_prcmu_recalc_rate(struct clk_hw *hw,
return prcmu_clock_rate(clk->cg_sel);
}

-static long clk_prcmu_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static int clk_prcmu_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate)
{
struct clk_prcmu *clk = to_clk_prcmu(hw);
- return prcmu_round_clock_rate(clk->cg_sel, rate);
+ long ret;
+
+ ret = prcmu_round_clock_rate(clk->cg_sel, *rate);
+ if (ret < 0)
+ return ret;
+
+ *rate = ret;
+ return 0;
}

static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index bc96f10..6404e61 100644
--- a/drivers/clk/versatile/clk-icst.c
+++ b/drivers/clk/versatile/clk-icst.c
@@ -91,14 +91,15 @@ static unsigned long icst_recalc_rate(struct clk_hw *hw,
return icst->rate;
}

-static long icst_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int icst_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
struct clk_icst *icst = to_icst(hw);
struct icst_vco vco;

- vco = icst_hz_to_vco(icst->params, rate);
- return icst_hz(icst->params, vco);
+ vco = icst_hz_to_vco(icst->params, *rate);
+ *rate = icst_hz(icst->params, vco);
+ return 0;
}

static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c
index 765f1e0..b507758 100644
--- a/drivers/clk/versatile/clk-vexpress-osc.c
+++ b/drivers/clk/versatile/clk-vexpress-osc.c
@@ -39,18 +39,18 @@ static unsigned long vexpress_osc_recalc_rate(struct clk_hw *hw,
return rate;
}

-static long vexpress_osc_round_rate(struct clk_hw *hw, unsigned long rate,
+static int vexpress_osc_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *parent_rate)
{
struct vexpress_osc *osc = to_vexpress_osc(hw);

- if (WARN_ON(osc->rate_min && rate < osc->rate_min))
- rate = osc->rate_min;
+ if (WARN_ON(osc->rate_min && *rate < osc->rate_min))
+ *rate = osc->rate_min;

- if (WARN_ON(osc->rate_max && rate > osc->rate_max))
- rate = osc->rate_max;
+ if (WARN_ON(osc->rate_max && *rate > osc->rate_max))
+ *rate = osc->rate_max;

- return rate;
+ return 0;
}

static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c
index 00d72fb..b62d298 100644
--- a/drivers/clk/zynq/pll.c
+++ b/drivers/clk/zynq/pll.c
@@ -60,18 +60,19 @@ struct zynq_pll {
* @prate: Clock frequency of parent clock
* Returns frequency closest to @rate the hardware can generate.
*/
-static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+static int zynq_pll_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate)
{
u32 fbdiv;

- fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
+ fbdiv = DIV_ROUND_CLOSEST(*rate, *prate);
if (fbdiv < PLL_FBDIV_MIN)
fbdiv = PLL_FBDIV_MIN;
else if (fbdiv > PLL_FBDIV_MAX)
fbdiv = PLL_FBDIV_MAX;

- return *prate * fbdiv;
+ *rate = *prate * fbdiv;
+ return 0;
}

/**
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index 4216e47..0695428 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -423,17 +423,20 @@ static unsigned long clk_tve_di_recalc_rate(struct clk_hw *hw,
return 0;
}

-static long clk_tve_di_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_tve_di_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
unsigned long div;

- div = *prate / rate;
+ div = *prate / *rate;
if (div >= 4)
- return *prate / 4;
+ *rate = *prate / 4;
else if (div >= 2)
- return *prate / 2;
- return *prate;
+ *rate = *prate / 2;
+ else
+ *rate = *prate;
+
+ return 0;
}

static int clk_tve_di_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c
index eeed006..97cdcb4 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c
@@ -336,11 +336,12 @@ static unsigned long hdmi_pll_recalc_rate(struct clk_hw *hw,
return phy_8960->pixclk;
}

-static long hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+static int hdmi_pll_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *parent_rate)
{
- const struct pll_rate *pll_rate = find_rate(rate);
- return pll_rate->rate;
+ const struct pll_rate *pll_rate = find_rate(*rate);
+ *rate = pll_rate->rate;
+ return 0;
}

static int hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_pll.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_pll.c
index ce42459..c89b109 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_pll.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_pll.c
@@ -109,11 +109,12 @@ static unsigned long mpd4_lvds_pll_recalc_rate(struct clk_hw *hw,
return lvds_pll->pixclk;
}

-static long mpd4_lvds_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+static int mpd4_lvds_pll_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *parent_rate)
{
- const struct pll_rate *pll_rate = find_rate(rate);
- return pll_rate->rate;
+ const struct pll_rate *pll_rate = find_rate(*rate);
+ *rate = pll_rate->rate;
+ return 0;
}

static int mpd4_lvds_pll_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index deca809..4d5ba85 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -231,11 +231,11 @@ static u32 isp_xclk_calc_divider(unsigned long *rate, unsigned long parent_rate)
return divider;
}

-static long isp_xclk_round_rate(struct clk_hw *hw, unsigned long rate,
+static int isp_xclk_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *parent_rate)
{
- isp_xclk_calc_divider(&rate, *parent_rate);
- return rate;
+ isp_xclk_calc_divider(rate, *parent_rate);
+ return 0;
}

static int isp_xclk_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c
index b936bb4..5e6f5a5 100644
--- a/drivers/rtc/rtc-hym8563.c
+++ b/drivers/rtc/rtc-hym8563.c
@@ -316,15 +316,19 @@ static unsigned long hym8563_clkout_recalc_rate(struct clk_hw *hw,
return clkout_rates[ret];
}

-static long hym8563_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int hym8563_clkout_round_rate(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *prate)
{
int i;

- for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
- if (clkout_rates[i] <= rate)
- return clkout_rates[i];
+ for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) {
+ if (clkout_rates[i] <= *rate) {
+ *rate = clkout_rates[i];
+ return 0;
+ }
+ }

+ *rate = 0;
return 0;
}

diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 5591ea7..1213b0b 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -173,8 +173,8 @@ struct clk_ops {
void (*disable_unused)(struct clk_hw *hw);
unsigned long (*recalc_rate)(struct clk_hw *hw,
unsigned long parent_rate);
- long (*round_rate)(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate);
+ int (*round_rate)(struct clk_hw *hw, unsigned long *rate,
+ unsigned long *parent_rate);
long (*determine_rate)(struct clk_hw *hw,
unsigned long rate,
unsigned long min_rate,
@@ -365,7 +365,7 @@ extern const struct clk_ops clk_divider_ops;
unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
unsigned int val, const struct clk_div_table *table,
unsigned long flags);
-long divider_round_rate(struct clk_hw *hw, unsigned long rate,
+int divider_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate, const struct clk_div_table *table,
u8 width, unsigned long flags);
int divider_get_val(unsigned long rate, unsigned long parent_rate,
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 6784400..3b2406c 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -277,9 +277,9 @@ long omap3_noncore_dpll_determine_rate(struct clk_hw *hw,
struct clk_hw **best_parent_clk);
unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
unsigned long parent_rate);
-long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
- unsigned long target_rate,
- unsigned long *parent_rate);
+int omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
+ unsigned long *target_rate,
+ unsigned long *parent_rate);
long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long min_rate,
@@ -288,14 +288,14 @@ long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw,
struct clk_hw **best_parent_clk);
u8 omap2_init_dpll_parent(struct clk_hw *hw);
unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate);
-long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
- unsigned long *parent_rate);
+int omap2_dpll_round_rate(struct clk_hw *hw, unsigned long *target_rate,
+ unsigned long *parent_rate);
void omap2_init_clk_clkdm(struct clk_hw *clk);
unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
unsigned long parent_rate);
int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate);
-long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate,
+int omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long *rate,
unsigned long *prate);
int omap2_clkops_enable_clkdm(struct clk_hw *hw);
void omap2_clkops_disable_clkdm(struct clk_hw *hw);
--
1.9.1