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.kernel.org/pub/scm/linux/kernel/git/clk/linux

Pull clk fixes from Stephen Boyd:
"A handful of critical fixes for changes introduce this merge window.

- The TI sci_clk_get() API was pretty broken and nobody noticed.

- There were some CPUfreq crashes on C.H.I.P devices because we
failed to propagate rates up the clk tree.

- Also, the Intel Atom PMC clk driver needs to mark a clk critical if
the firmware has it enabled already so that audio doesn't get
killed on Baytrail.

- Gemini devices have a dead serial console because the reset control
usage in the serial driver assume one method of reset that gemini
doesn't support (this will be fixed in the next version in the
reset framework so this is the small fix for -rc series).

- Finally we have two rate calculation fixes, one for Exynos and one
for Meson SoCs, that fix rate inconsistencies"

* tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux:
clk: keystone: sci-clk: Fix sci_clk_get
clk: meson: mpll: fix mpll0 fractional part ignored
clk: samsung: exynos5420: The EPLL rate table corrections
clk: sunxi-ng: sun5i: Add clk_set_rate_parent to the CPU clock
clk: x86: Do not gate clocks enabled by the firmware
clk: gemini: Fix reset regression

+90 -33
+14
drivers/clk/clk-gemini.c
··· 237 237 BIT(GEMINI_RESET_CPU1) | BIT(id)); 238 238 } 239 239 240 + static int gemini_reset_assert(struct reset_controller_dev *rcdev, 241 + unsigned long id) 242 + { 243 + return 0; 244 + } 245 + 246 + static int gemini_reset_deassert(struct reset_controller_dev *rcdev, 247 + unsigned long id) 248 + { 249 + return 0; 250 + } 251 + 240 252 static int gemini_reset_status(struct reset_controller_dev *rcdev, 241 253 unsigned long id) 242 254 { ··· 265 253 266 254 static const struct reset_control_ops gemini_reset_ops = { 267 255 .reset = gemini_reset, 256 + .assert = gemini_reset_assert, 257 + .deassert = gemini_reset_deassert, 268 258 .status = gemini_reset_status, 269 259 }; 270 260
+42 -24
drivers/clk/keystone/sci-clk.c
··· 22 22 #include <linux/platform_device.h> 23 23 #include <linux/slab.h> 24 24 #include <linux/soc/ti/ti_sci_protocol.h> 25 + #include <linux/bsearch.h> 25 26 26 27 #define SCI_CLK_SSC_ENABLE BIT(0) 27 28 #define SCI_CLK_ALLOW_FREQ_CHANGE BIT(1) ··· 45 44 * @dev: Device pointer for the clock provider 46 45 * @clk_data: Clock data 47 46 * @clocks: Clocks array for this device 47 + * @num_clocks: Total number of clocks for this provider 48 48 */ 49 49 struct sci_clk_provider { 50 50 const struct ti_sci_handle *sci; ··· 53 51 struct device *dev; 54 52 const struct sci_clk_data *clk_data; 55 53 struct clk_hw **clocks; 54 + int num_clocks; 56 55 }; 57 56 58 57 /** ··· 61 58 * @hw: Hardware clock cookie for common clock framework 62 59 * @dev_id: Device index 63 60 * @clk_id: Clock index 64 - * @node: Clocks list link 65 61 * @provider: Master clock provider 66 62 * @flags: Flags for the clock 67 63 */ ··· 68 66 struct clk_hw hw; 69 67 u16 dev_id; 70 68 u8 clk_id; 71 - struct list_head node; 72 69 struct sci_clk_provider *provider; 73 70 u8 flags; 74 71 }; ··· 368 367 return &sci_clk->hw; 369 368 } 370 369 370 + static int _cmp_sci_clk(const void *a, const void *b) 371 + { 372 + const struct sci_clk *ca = a; 373 + const struct sci_clk *cb = *(struct sci_clk **)b; 374 + 375 + if (ca->dev_id == cb->dev_id && ca->clk_id == cb->clk_id) 376 + return 0; 377 + if (ca->dev_id > cb->dev_id || 378 + (ca->dev_id == cb->dev_id && ca->clk_id > cb->clk_id)) 379 + return 1; 380 + return -1; 381 + } 382 + 371 383 /** 372 384 * sci_clk_get - Xlate function for getting clock handles 373 385 * @clkspec: device tree clock specifier ··· 394 380 static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data) 395 381 { 396 382 struct sci_clk_provider *provider = data; 397 - u16 dev_id; 398 - u8 clk_id; 399 - const struct sci_clk_data *clks = provider->clk_data; 400 - struct clk_hw **clocks = provider->clocks; 383 + struct sci_clk **clk; 384 + struct sci_clk key; 401 385 402 386 if (clkspec->args_count != 2) 403 387 return ERR_PTR(-EINVAL); 404 388 405 - dev_id = clkspec->args[0]; 406 - clk_id = clkspec->args[1]; 389 + key.dev_id = clkspec->args[0]; 390 + key.clk_id = clkspec->args[1]; 407 391 408 - while (clks->num_clks) { 409 - if (clks->dev == dev_id) { 410 - if (clk_id >= clks->num_clks) 411 - return ERR_PTR(-EINVAL); 392 + clk = bsearch(&key, provider->clocks, provider->num_clocks, 393 + sizeof(clk), _cmp_sci_clk); 412 394 413 - return clocks[clk_id]; 414 - } 395 + if (!clk) 396 + return ERR_PTR(-ENODEV); 415 397 416 - clks++; 417 - } 418 - 419 - return ERR_PTR(-ENODEV); 398 + return &(*clk)->hw; 420 399 } 421 400 422 401 static int ti_sci_init_clocks(struct sci_clk_provider *p) ··· 417 410 const struct sci_clk_data *data = p->clk_data; 418 411 struct clk_hw *hw; 419 412 int i; 413 + int num_clks = 0; 420 414 421 415 while (data->num_clks) { 422 - p->clocks = devm_kcalloc(p->dev, data->num_clks, 423 - sizeof(struct sci_clk), 424 - GFP_KERNEL); 425 - if (!p->clocks) 426 - return -ENOMEM; 416 + num_clks += data->num_clks; 417 + data++; 418 + } 427 419 420 + p->num_clocks = num_clks; 421 + 422 + p->clocks = devm_kcalloc(p->dev, num_clks, sizeof(struct sci_clk), 423 + GFP_KERNEL); 424 + if (!p->clocks) 425 + return -ENOMEM; 426 + 427 + num_clks = 0; 428 + 429 + data = p->clk_data; 430 + 431 + while (data->num_clks) { 428 432 for (i = 0; i < data->num_clks; i++) { 429 433 hw = _sci_clk_build(p, data->dev, i); 430 434 if (!IS_ERR(hw)) { 431 - p->clocks[i] = hw; 435 + p->clocks[num_clks++] = hw; 432 436 continue; 433 437 } 434 438
+7
drivers/clk/meson/clk-mpll.c
··· 161 161 reg = PARM_SET(p->width, p->shift, reg, 1); 162 162 writel(reg, mpll->base + p->reg_off); 163 163 164 + p = &mpll->ssen; 165 + if (p->width != 0) { 166 + reg = readl(mpll->base + p->reg_off); 167 + reg = PARM_SET(p->width, p->shift, reg, 1); 168 + writel(reg, mpll->base + p->reg_off); 169 + } 170 + 164 171 p = &mpll->n2; 165 172 reg = readl(mpll->base + p->reg_off); 166 173 reg = PARM_SET(p->width, p->shift, reg, n2);
+1
drivers/clk/meson/clkc.h
··· 118 118 struct parm sdm_en; 119 119 struct parm n2; 120 120 struct parm en; 121 + struct parm ssen; 121 122 spinlock_t *lock; 122 123 }; 123 124
+5
drivers/clk/meson/gxbb.c
··· 528 528 .shift = 14, 529 529 .width = 1, 530 530 }, 531 + .ssen = { 532 + .reg_off = HHI_MPLL_CNTL, 533 + .shift = 25, 534 + .width = 1, 535 + }, 531 536 .lock = &clk_lock, 532 537 .hw.init = &(struct clk_init_data){ 533 538 .name = "mpll0",
+5
drivers/clk/meson/meson8b.c
··· 267 267 .shift = 14, 268 268 .width = 1, 269 269 }, 270 + .ssen = { 271 + .reg_off = HHI_MPLL_CNTL, 272 + .shift = 25, 273 + .width = 1, 274 + }, 270 275 .lock = &clk_lock, 271 276 .hw.init = &(struct clk_init_data){ 272 277 .name = "mpll0",
+8 -8
drivers/clk/samsung/clk-exynos5420.c
··· 1283 1283 static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = { 1284 1284 PLL_36XX_RATE(600000000U, 100, 2, 1, 0), 1285 1285 PLL_36XX_RATE(400000000U, 200, 3, 2, 0), 1286 - PLL_36XX_RATE(393216000U, 197, 3, 2, 25690), 1287 - PLL_36XX_RATE(361267200U, 301, 5, 2, 3671), 1286 + PLL_36XX_RATE(393216003U, 197, 3, 2, -25690), 1287 + PLL_36XX_RATE(361267218U, 301, 5, 2, 3671), 1288 1288 PLL_36XX_RATE(200000000U, 200, 3, 3, 0), 1289 - PLL_36XX_RATE(196608000U, 197, 3, 3, -25690), 1290 - PLL_36XX_RATE(180633600U, 301, 5, 3, 3671), 1291 - PLL_36XX_RATE(131072000U, 131, 3, 3, 4719), 1289 + PLL_36XX_RATE(196608001U, 197, 3, 3, -25690), 1290 + PLL_36XX_RATE(180633609U, 301, 5, 3, 3671), 1291 + PLL_36XX_RATE(131072006U, 131, 3, 3, 4719), 1292 1292 PLL_36XX_RATE(100000000U, 200, 3, 4, 0), 1293 - PLL_36XX_RATE(65536000U, 131, 3, 4, 4719), 1294 - PLL_36XX_RATE(49152000U, 197, 3, 5, 25690), 1295 - PLL_36XX_RATE(32768000U, 131, 3, 5, 4719), 1293 + PLL_36XX_RATE( 65536003U, 131, 3, 4, 4719), 1294 + PLL_36XX_RATE( 49152000U, 197, 3, 5, -25690), 1295 + PLL_36XX_RATE( 32768001U, 131, 3, 5, 4719), 1296 1296 }; 1297 1297 1298 1298 static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
+1 -1
drivers/clk/sunxi-ng/ccu-sun5i.c
··· 184 184 .hw.init = CLK_HW_INIT_PARENTS("cpu", 185 185 cpu_parents, 186 186 &ccu_mux_ops, 187 - CLK_IS_CRITICAL), 187 + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), 188 188 } 189 189 }; 190 190
+7
drivers/clk/x86/clk-pmc-atom.c
··· 186 186 pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE; 187 187 spin_lock_init(&pclk->lock); 188 188 189 + /* 190 + * If the clock was already enabled by the firmware mark it as critical 191 + * to avoid it being gated by the clock framework if no driver owns it. 192 + */ 193 + if (plt_clk_is_enabled(&pclk->hw)) 194 + init.flags |= CLK_IS_CRITICAL; 195 + 189 196 ret = devm_clk_hw_register(&pdev->dev, &pclk->hw); 190 197 if (ret) { 191 198 pclk = ERR_PTR(ret);