Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mike.turquette/linux

Pull clock fixes from Mike Turquette:
"Small number of user-visible regression fixes for clock drivers.

There is a memory leak fix for an ST platform, an infinite Loop Of
Doom fix for the recent changes to the basic clock divider (hopefully
the last fix for those recent changes) and some Tegra PLL changes
which keep PCI from being hosed on that platform"

* tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mike.turquette/linux:
clk: st: Fix memory leak
clk: divider: Fix table round up function
clk: tegra: Fix enabling of PLLE
clk: tegra: Introduce divider mask and shift helpers
clk: tegra: Fix PLLE programming

+47 -23
+1 -1
drivers/clk/clk-divider.c
··· 147 147 static int _round_up_table(const struct clk_div_table *table, int div) 148 148 { 149 149 const struct clk_div_table *clkt; 150 - int up = _get_table_maxdiv(table); 150 + int up = INT_MAX; 151 151 152 152 for (clkt = table; clkt->div; clkt++) { 153 153 if (clkt->div == div)
+3 -1
drivers/clk/st/clkgen-pll.c
··· 521 521 gate->lock = odf_lock; 522 522 523 523 div = kzalloc(sizeof(*div), GFP_KERNEL); 524 - if (!div) 524 + if (!div) { 525 + kfree(gate); 525 526 return ERR_PTR(-ENOMEM); 527 + } 526 528 527 529 div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO; 528 530 div->reg = reg + pll_data->odf[odf].offset;
+43 -21
drivers/clk/tegra/clk-pll.c
··· 58 58 #define PLLDU_LFCON_SET_DIVN 600 59 59 60 60 #define PLLE_BASE_DIVCML_SHIFT 24 61 - #define PLLE_BASE_DIVCML_WIDTH 4 61 + #define PLLE_BASE_DIVCML_MASK 0xf 62 62 #define PLLE_BASE_DIVP_SHIFT 16 63 - #define PLLE_BASE_DIVP_WIDTH 7 63 + #define PLLE_BASE_DIVP_WIDTH 6 64 64 #define PLLE_BASE_DIVN_SHIFT 8 65 65 #define PLLE_BASE_DIVN_WIDTH 8 66 66 #define PLLE_BASE_DIVM_SHIFT 0 ··· 182 182 #define divn_mask(p) mask(p->params->div_nmp->divn_width) 183 183 #define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\ 184 184 mask(p->params->div_nmp->divp_width)) 185 + 186 + #define divm_shift(p) (p)->params->div_nmp->divm_shift 187 + #define divn_shift(p) (p)->params->div_nmp->divn_shift 188 + #define divp_shift(p) (p)->params->div_nmp->divp_shift 189 + 190 + #define divm_mask_shifted(p) (divm_mask(p) << divm_shift(p)) 191 + #define divn_mask_shifted(p) (divn_mask(p) << divn_shift(p)) 192 + #define divp_mask_shifted(p) (divp_mask(p) << divp_shift(p)) 185 193 186 194 #define divm_max(p) (divm_mask(p)) 187 195 #define divn_max(p) (divn_mask(p)) ··· 484 476 } else { 485 477 val = pll_readl_base(pll); 486 478 487 - val &= ~((divm_mask(pll) << div_nmp->divm_shift) | 488 - (divn_mask(pll) << div_nmp->divn_shift) | 489 - (divp_mask(pll) << div_nmp->divp_shift)); 479 + val &= ~(divm_mask_shifted(pll) | divn_mask_shifted(pll) | 480 + divp_mask_shifted(pll)); 490 481 491 - val |= ((cfg->m << div_nmp->divm_shift) | 492 - (cfg->n << div_nmp->divn_shift) | 493 - (cfg->p << div_nmp->divp_shift)); 482 + val |= (cfg->m << divm_shift(pll)) | 483 + (cfg->n << divn_shift(pll)) | 484 + (cfg->p << divp_shift(pll)); 494 485 495 486 pll_writel_base(val, pll); 496 487 } ··· 737 730 if (pll->params->flags & TEGRA_PLLE_CONFIGURE) { 738 731 /* configure dividers */ 739 732 val = pll_readl_base(pll); 740 - val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); 741 - val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); 742 - val |= sel.m << pll->params->div_nmp->divm_shift; 743 - val |= sel.n << pll->params->div_nmp->divn_shift; 744 - val |= sel.p << pll->params->div_nmp->divp_shift; 733 + val &= ~(divp_mask_shifted(pll) | divn_mask_shifted(pll) | 734 + divm_mask_shifted(pll)); 735 + val &= ~(PLLE_BASE_DIVCML_MASK << PLLE_BASE_DIVCML_SHIFT); 736 + val |= sel.m << divm_shift(pll); 737 + val |= sel.n << divn_shift(pll); 738 + val |= sel.p << divp_shift(pll); 745 739 val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; 746 740 pll_writel_base(val, pll); 747 741 } ··· 753 745 pll_writel_misc(val, pll); 754 746 755 747 val = readl(pll->clk_base + PLLE_SS_CTRL); 748 + val &= ~PLLE_SS_COEFFICIENTS_MASK; 756 749 val |= PLLE_SS_DISABLE; 757 750 writel(val, pll->clk_base + PLLE_SS_CTRL); 758 751 759 - val |= pll_readl_base(pll); 752 + val = pll_readl_base(pll); 760 753 val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE); 761 754 pll_writel_base(val, pll); 762 755 ··· 1301 1292 pll_writel(val, PLLE_SS_CTRL, pll); 1302 1293 1303 1294 val = pll_readl_base(pll); 1304 - val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); 1305 - val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); 1306 - val |= sel.m << pll->params->div_nmp->divm_shift; 1307 - val |= sel.n << pll->params->div_nmp->divn_shift; 1295 + val &= ~(divp_mask_shifted(pll) | divn_mask_shifted(pll) | 1296 + divm_mask_shifted(pll)); 1297 + val &= ~(PLLE_BASE_DIVCML_MASK << PLLE_BASE_DIVCML_SHIFT); 1298 + val |= sel.m << divm_shift(pll); 1299 + val |= sel.n << divn_shift(pll); 1308 1300 val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; 1309 1301 pll_writel_base(val, pll); 1310 1302 udelay(1); ··· 1420 1410 return clk; 1421 1411 } 1422 1412 1413 + static struct div_nmp pll_e_nmp = { 1414 + .divn_shift = PLLE_BASE_DIVN_SHIFT, 1415 + .divn_width = PLLE_BASE_DIVN_WIDTH, 1416 + .divm_shift = PLLE_BASE_DIVM_SHIFT, 1417 + .divm_width = PLLE_BASE_DIVM_WIDTH, 1418 + .divp_shift = PLLE_BASE_DIVP_SHIFT, 1419 + .divp_width = PLLE_BASE_DIVP_WIDTH, 1420 + }; 1421 + 1423 1422 struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, 1424 1423 void __iomem *clk_base, void __iomem *pmc, 1425 1424 unsigned long flags, struct tegra_clk_pll_params *pll_params, ··· 1439 1420 1440 1421 pll_params->flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; 1441 1422 pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; 1423 + 1424 + if (!pll_params->div_nmp) 1425 + pll_params->div_nmp = &pll_e_nmp; 1426 + 1442 1427 pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); 1443 1428 if (IS_ERR(pll)) 1444 1429 return ERR_CAST(pll); ··· 1580 1557 int m; 1581 1558 1582 1559 m = _pll_fixed_mdiv(pll_params, parent_rate); 1583 - val = m << PLL_BASE_DIVM_SHIFT; 1584 - val |= (pll_params->vco_min / parent_rate) 1585 - << PLL_BASE_DIVN_SHIFT; 1560 + val = m << divm_shift(pll); 1561 + val |= (pll_params->vco_min / parent_rate) << divn_shift(pll); 1586 1562 pll_writel_base(val, pll); 1587 1563 } 1588 1564