Skip to content

Commit 82f53f9

Browse files
andy-shevbebarino
authored andcommitted
clk: fractional-divider: Introduce POWER_OF_TWO_PS flag
The newly introduced POWER_OF_TWO_PS flag, when set, makes the flow to skip the assumption that the caller will use an additional 2^scale prescaler to get the desired clock rate. Reported-by: Liu Ying <[email protected]> Signed-off-by: Andy Shevchenko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 928f9e2 commit 82f53f9

File tree

4 files changed

+17
-7
lines changed

4 files changed

+17
-7
lines changed

drivers/acpi/acpi_lpss.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,8 @@ static int register_device_clock(struct acpi_device *adev,
434434
if (!clk_name)
435435
return -ENOMEM;
436436
clk = clk_register_fractional_divider(NULL, clk_name, parent,
437-
0, prv_base,
438-
1, 15, 16, 15, 0, NULL);
437+
CLK_FRAC_DIVIDER_POWER_OF_TWO_PS,
438+
prv_base, 1, 15, 16, 15, 0, NULL);
439439
parent = clk_name;
440440

441441
clk_name = kasprintf(GFP_KERNEL, "%s-update", devname);

drivers/clk/clk-fractional-divider.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,18 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw,
7676
unsigned long *m, unsigned long *n)
7777
{
7878
struct clk_fractional_divider *fd = to_clk_fd(hw);
79-
unsigned long scale;
8079

8180
/*
8281
* Get rate closer to *parent_rate to guarantee there is no overflow
8382
* for m and n. In the result it will be the nearest rate left shifted
8483
* by (scale - fd->nwidth) bits.
8584
*/
86-
scale = fls_long(*parent_rate / rate - 1);
87-
if (scale > fd->nwidth)
88-
rate <<= scale - fd->nwidth;
85+
if (fd->flags & CLK_FRAC_DIVIDER_POWER_OF_TWO_PS) {
86+
unsigned long scale = fls_long(*parent_rate / rate - 1);
87+
88+
if (scale > fd->nwidth)
89+
rate <<= scale - fd->nwidth;
90+
}
8991

9092
rational_best_approximation(rate, *parent_rate,
9193
GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),

drivers/mfd/intel-lpss.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,8 @@ static int intel_lpss_register_clock_divider(struct intel_lpss *lpss,
301301

302302
snprintf(name, sizeof(name), "%s-div", devname);
303303
tmp = clk_register_fractional_divider(NULL, name, __clk_get_name(tmp),
304-
0, lpss->priv, 1, 15, 16, 15, 0,
304+
CLK_FRAC_DIVIDER_POWER_OF_TWO_PS,
305+
lpss->priv, 1, 15, 16, 15, 0,
305306
NULL);
306307
if (IS_ERR(tmp))
307308
return PTR_ERR(tmp);

include/linux/clk-provider.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,12 @@ struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
10011001
* CLK_FRAC_DIVIDER_BIG_ENDIAN - By default little endian register accesses are
10021002
* used for the divider register. Setting this flag makes the register
10031003
* accesses big endian.
1004+
* CLK_FRAC_DIVIDER_POWER_OF_TWO_PS - By default the resulting fraction might
1005+
* be saturated and the caller will get quite far from the good enough
1006+
* approximation. Instead the caller may require, by setting this flag,
1007+
* to shift left by a few bits in case, when the asked one is quite small
1008+
* to satisfy the desired range of denominator. It assumes that on the
1009+
* caller's side the power-of-two capable prescaler exists.
10041010
*/
10051011
struct clk_fractional_divider {
10061012
struct clk_hw hw;
@@ -1022,6 +1028,7 @@ struct clk_fractional_divider {
10221028

10231029
#define CLK_FRAC_DIVIDER_ZERO_BASED BIT(0)
10241030
#define CLK_FRAC_DIVIDER_BIG_ENDIAN BIT(1)
1031+
#define CLK_FRAC_DIVIDER_POWER_OF_TWO_PS BIT(2)
10251032

10261033
struct clk *clk_register_fractional_divider(struct device *dev,
10271034
const char *name, const char *parent_name, unsigned long flags,

0 commit comments

Comments
 (0)