forked from luck/tmp_suning_uos_patched
The fixes for the clock framework are all regressions in drivers, plus a
single fix in one of the basic clock templates. No fixes to the core this time around. As with most clock driver fixes these run the gamut from fixing a build warning to fixing wrecked memory timings, with a little USB tossed in for fun. Please consider pulling. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJUcrkwAAoJEDqPOy9afJhJzq4P/jT9K+g0ljQrY93t97Wm6s4x Xi+RrVO/MOUhpIGzqrhPflGALl5Yj96iBUiC2QSVpVjDUdoQL5tc8c3FtQDGA7fA Q/9e2yUmjQ+nNxizdeIzaNUHO+fIe8FEn3NwyondfaDlI1sqVv/0WAf6MNkuLCwM /DJ1MmJbwgK255gI3FwUhbNylCCPeUENKRs3xGW3p4+fFIZGyROhBsJClE1nUiT1 EFzWM6Bq29qOLxZ4Dqkfzz1BWLiqcTlRcf8ZaHjME77k09ybwNS9cmXrB9gHhmlL sMfDa0uwsv/mFWRohP5jK3AUqqtR7EgcPL5euO+d9Q+nBVofgTwxyvA0nlGqX8XQ hm1OZeolnWHPPHasRkgzSnd/0b/A8s+tr96XSvHjIlrx1ioWQD2K7GU82/3bObTL isqzW34+Y0dX2GpgwJu2eWrSwHk705wBA0t8/pP+r7aWdUsyX4J1ElGHLElzTLI0 VkQZPwKvjVNd0kQRplZ/KPQoboDuFh8b09+MvG8Kz8t3Ilt0MS7rFrxEQ6xIBfe9 M49vUJw2egmOCgcWp3GeyICIQJCfet2acyZy+vJivpu0//ssD7BT/woR7qmgHic1 kmiVdj1iBSoUK4NIr+DvsNmMMDEW58CSK/j11chitT8WCRGYKW849iUk7LiGhXU0 IgTphTfMdFF1a2gzqaQo =4O2k -----END PGP SIGNATURE----- Merge tag 'clk-fixes-for-linus' of https://git.linaro.org/people/mike.turquette/linux Pull clock fixes from Mike Turquette: "The fixes for the clock framework are all regressions in drivers, plus a single fix in one of the basic clock templates. No fixes to the core this time around. As with most clock driver fixes these run the gamut from fixing a build warning to fixing wrecked memory timings, with a little USB tossed in for fun" * tag 'clk-fixes-for-linus' of https://git.linaro.org/people/mike.turquette/linux: clk: pxa: fix pxa27x CCCR bit usage clk-divider: Fix READ_ONLY when divider > 1 clk: qcom: Fix duplicate rbcpr clock name clk: at91: usb: fix at91sam9x5 recalc, round and set rate clk: at91: usb: fix at91rm9200 round and set rate
This commit is contained in:
commit
a7e90924e1
|
@ -52,29 +52,26 @@ static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw,
|
|||
|
||||
tmp = pmc_read(pmc, AT91_PMC_USB);
|
||||
usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT;
|
||||
return parent_rate / (usbdiv + 1);
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned long div;
|
||||
unsigned long bestrate;
|
||||
unsigned long tmp;
|
||||
|
||||
if (!rate)
|
||||
return -EINVAL;
|
||||
|
||||
if (rate >= *parent_rate)
|
||||
return *parent_rate;
|
||||
|
||||
div = *parent_rate / rate;
|
||||
if (div >= SAM9X5_USB_MAX_DIV)
|
||||
return *parent_rate / (SAM9X5_USB_MAX_DIV + 1);
|
||||
div = DIV_ROUND_CLOSEST(*parent_rate, rate);
|
||||
if (div > SAM9X5_USB_MAX_DIV + 1)
|
||||
div = SAM9X5_USB_MAX_DIV + 1;
|
||||
|
||||
bestrate = *parent_rate / div;
|
||||
tmp = *parent_rate / (div + 1);
|
||||
if (bestrate - rate > rate - tmp)
|
||||
bestrate = tmp;
|
||||
|
||||
return bestrate;
|
||||
return DIV_ROUND_CLOSEST(*parent_rate, div);
|
||||
}
|
||||
|
||||
static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
|
||||
|
@ -106,9 +103,13 @@ static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
u32 tmp;
|
||||
struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
|
||||
struct at91_pmc *pmc = usb->pmc;
|
||||
unsigned long div = parent_rate / rate;
|
||||
unsigned long div;
|
||||
|
||||
if (parent_rate % rate || div < 1 || div >= SAM9X5_USB_MAX_DIV)
|
||||
if (!rate)
|
||||
return -EINVAL;
|
||||
|
||||
div = DIV_ROUND_CLOSEST(parent_rate, rate);
|
||||
if (div > SAM9X5_USB_MAX_DIV + 1 || !div)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV;
|
||||
|
@ -253,7 +254,7 @@ static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
|
|||
|
||||
tmp_parent_rate = rate * usb->divisors[i];
|
||||
tmp_parent_rate = __clk_round_rate(parent, tmp_parent_rate);
|
||||
tmprate = tmp_parent_rate / usb->divisors[i];
|
||||
tmprate = DIV_ROUND_CLOSEST(tmp_parent_rate, usb->divisors[i]);
|
||||
if (tmprate < rate)
|
||||
tmpdiff = rate - tmprate;
|
||||
else
|
||||
|
@ -281,10 +282,10 @@ static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
struct at91_pmc *pmc = usb->pmc;
|
||||
unsigned long div;
|
||||
|
||||
if (!rate || parent_rate % rate)
|
||||
if (!rate)
|
||||
return -EINVAL;
|
||||
|
||||
div = parent_rate / rate;
|
||||
div = DIV_ROUND_CLOSEST(parent_rate, rate);
|
||||
|
||||
for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) {
|
||||
if (usb->divisors[i] == div) {
|
||||
|
|
|
@ -263,6 +263,14 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
|
|||
if (!rate)
|
||||
rate = 1;
|
||||
|
||||
/* if read only, just return current value */
|
||||
if (divider->flags & CLK_DIVIDER_READ_ONLY) {
|
||||
bestdiv = readl(divider->reg) >> divider->shift;
|
||||
bestdiv &= div_mask(divider);
|
||||
bestdiv = _get_div(divider, bestdiv);
|
||||
return bestdiv;
|
||||
}
|
||||
|
||||
maxdiv = _get_maxdiv(divider);
|
||||
|
||||
if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) {
|
||||
|
@ -361,11 +369,6 @@ const struct clk_ops clk_divider_ops = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(clk_divider_ops);
|
||||
|
||||
const struct clk_ops clk_divider_ro_ops = {
|
||||
.recalc_rate = clk_divider_recalc_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
|
||||
|
||||
static struct clk *_register_divider(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
|
@ -391,10 +394,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
|
|||
}
|
||||
|
||||
init.name = name;
|
||||
if (clk_divider_flags & CLK_DIVIDER_READ_ONLY)
|
||||
init.ops = &clk_divider_ro_ops;
|
||||
else
|
||||
init.ops = &clk_divider_ops;
|
||||
init.ops = &clk_divider_ops;
|
||||
init.flags = flags | CLK_IS_BASIC;
|
||||
init.parent_names = (parent_name ? &parent_name: NULL);
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
|
|
|
@ -322,7 +322,7 @@ static unsigned long clk_pxa27x_memory_get_rate(struct clk_hw *hw,
|
|||
unsigned long ccsr = CCSR;
|
||||
|
||||
osc_forced = ccsr & (1 << CCCR_CPDIS_BIT);
|
||||
a = cccr & CCCR_A_BIT;
|
||||
a = cccr & (1 << CCCR_A_BIT);
|
||||
l = ccsr & CCSR_L_MASK;
|
||||
|
||||
if (osc_forced || a)
|
||||
|
@ -341,7 +341,7 @@ static u8 clk_pxa27x_memory_get_parent(struct clk_hw *hw)
|
|||
unsigned long ccsr = CCSR;
|
||||
|
||||
osc_forced = ccsr & (1 << CCCR_CPDIS_BIT);
|
||||
a = cccr & CCCR_A_BIT;
|
||||
a = cccr & (1 << CCCR_A_BIT);
|
||||
if (osc_forced)
|
||||
return PXA_MEM_13Mhz;
|
||||
if (a)
|
||||
|
|
|
@ -3122,7 +3122,7 @@ static struct clk_regmap *mmcc_apq8084_clocks[] = {
|
|||
[ESC1_CLK_SRC] = &esc1_clk_src.clkr,
|
||||
[HDMI_CLK_SRC] = &hdmi_clk_src.clkr,
|
||||
[VSYNC_CLK_SRC] = &vsync_clk_src.clkr,
|
||||
[RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr,
|
||||
[MMSS_RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr,
|
||||
[RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr,
|
||||
[MAPLE_CLK_SRC] = &maple_clk_src.clkr,
|
||||
[VDP_CLK_SRC] = &vdp_clk_src.clkr,
|
||||
|
|
|
@ -90,9 +90,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
|
|||
div->width = div_width;
|
||||
div->lock = lock;
|
||||
div->table = div_table;
|
||||
div_ops = (div_flags & CLK_DIVIDER_READ_ONLY)
|
||||
? &clk_divider_ro_ops
|
||||
: &clk_divider_ops;
|
||||
div_ops = &clk_divider_ops;
|
||||
}
|
||||
|
||||
clk = clk_register_composite(NULL, name, parent_names, num_parents,
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
#define ESC1_CLK_SRC 43
|
||||
#define HDMI_CLK_SRC 44
|
||||
#define VSYNC_CLK_SRC 45
|
||||
#define RBCPR_CLK_SRC 46
|
||||
#define MMSS_RBCPR_CLK_SRC 46
|
||||
#define RBBMTIMER_CLK_SRC 47
|
||||
#define MAPLE_CLK_SRC 48
|
||||
#define VDP_CLK_SRC 49
|
||||
|
|
|
@ -352,7 +352,6 @@ struct clk_divider {
|
|||
#define CLK_DIVIDER_READ_ONLY BIT(5)
|
||||
|
||||
extern const struct clk_ops clk_divider_ops;
|
||||
extern const struct clk_ops clk_divider_ro_ops;
|
||||
struct clk *clk_register_divider(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
|
|
Loading…
Reference in New Issue
Block a user