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
Unified · Split
| @@ -237,6 +237,18 @@ static int gemini_reset(struct reset_controller_dev *rcdev, · 236 unmodified lines | ||
| 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 | { |
| @@ -253,6 +265,8 @@ static int gemini_reset_status(struct reset_controller_dev *rcdev, · 10 unmodified lines | ||
| 253 | 265 | |
| 254 | 266 | static const struct reset_control_ops gemini_reset_ops = { |
| 255 | 267 | .reset = gemini_reset, |
| 268 | + .assert = gemini_reset_assert, | |
| 269 | + .deassert = gemini_reset_deassert, | |
| 256 | 270 | .status = gemini_reset_status, |
| 257 | 271 | }; |
| 258 | 272 | |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 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) |
| @@ -44,6 +45,7 @@ struct sci_clk_data { · 16 unmodified lines | ||
| 44 | 45 | * @dev: Device pointer for the clock provider |
| 45 | 46 | * @clk_data: Clock data |
| 46 | 47 | * @clocks: Clocks array for this device |
| 48 | + * @num_clocks: Total number of clocks for this provider | |
| 47 | 49 | */ |
| 48 | 50 | struct sci_clk_provider { |
| 49 | 51 | const struct ti_sci_handle *sci; |
| @@ -51,6 +53,7 @@ struct sci_clk_provider { · 1 unmodified line | ||
| 51 | 53 | struct device *dev; |
| 52 | 54 | const struct sci_clk_data *clk_data; |
| 53 | 55 | struct clk_hw **clocks; |
| 56 | + int num_clocks; | |
| 54 | 57 | }; |
| 55 | 58 | |
| 56 | 59 | /** |
| @@ -58,7 +61,6 @@ struct sci_clk_provider { · 1 unmodified line | ||
| 58 | 61 | * @hw: Hardware clock cookie for common clock framework |
| 59 | 62 | * @dev_id: Device index |
| 60 | 63 | * @clk_id: Clock index |
| 61 | − * @node: Clocks list link | |
| 62 | 64 | * @provider: Master clock provider |
| 63 | 65 | * @flags: Flags for the clock |
| 64 | 66 | */ |
| @@ -66,7 +68,6 @@ struct sci_clk { · 1 unmodified line | ||
| 66 | 68 | struct clk_hw hw; |
| 67 | 69 | u16 dev_id; |
| 68 | 70 | u8 clk_id; |
| 69 | − struct list_head node; | |
| 70 | 71 | struct sci_clk_provider *provider; |
| 71 | 72 | u8 flags; |
| 72 | 73 | }; |
| @@ -367,6 +368,19 @@ err: · 294 unmodified lines | ||
| 367 | 368 | return &sci_clk->hw; |
| 368 | 369 | } |
| 369 | 370 | |
| 371 | +static int _cmp_sci_clk(const void *a, const void *b) | |
| 372 | +{ | |
| 373 | + const struct sci_clk *ca = a; | |
| 374 | + const struct sci_clk *cb = *(struct sci_clk **)b; | |
| 375 | + | |
| 376 | + if (ca->dev_id == cb->dev_id && ca->clk_id == cb->clk_id) | |
| 377 | + return 0; | |
| 378 | + if (ca->dev_id > cb->dev_id || | |
| 379 | + (ca->dev_id == cb->dev_id && ca->clk_id > cb->clk_id)) | |
| 380 | + return 1; | |
| 381 | + return -1; | |
| 382 | +} | |
| 383 | + | |
| 370 | 384 | /** |
| 371 | 385 | * sci_clk_get - Xlate function for getting clock handles |
| 372 | 386 | * @clkspec: device tree clock specifier |
| @@ -380,29 +394,22 @@ err: · 7 unmodified lines | ||
| 380 | 394 | static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data) |
| 381 | 395 | { |
| 382 | 396 | struct sci_clk_provider *provider = data; |
| 383 | − u16 dev_id; | |
| 384 | − u8 clk_id; | |
| 385 | − const struct sci_clk_data *clks = provider->clk_data; | |
| 386 | − struct clk_hw **clocks = provider->clocks; | |
| 397 | + struct sci_clk **clk; | |
| 398 | + struct sci_clk key; | |
| 387 | 399 | |
| 388 | 400 | if (clkspec->args_count != 2) |
| 389 | 401 | return ERR_PTR(-EINVAL); |
| 390 | 402 | |
| 391 | − dev_id = clkspec->args[0]; | |
| 392 | − clk_id = clkspec->args[1]; | |
| 403 | + key.dev_id = clkspec->args[0]; | |
| 404 | + key.clk_id = clkspec->args[1]; | |
| 393 | 405 | |
| 394 | − while (clks->num_clks) { | |
| 395 | − if (clks->dev == dev_id) { | |
| 396 | − if (clk_id >= clks->num_clks) | |
| 397 | − return ERR_PTR(-EINVAL); | |
| 398 | − | |
| 399 | − return clocks[clk_id]; | |
| 400 | − } | |
| 406 | + clk = bsearch(&key, provider->clocks, provider->num_clocks, | |
| 407 | + sizeof(clk), _cmp_sci_clk); | |
| 401 | 408 | |
| 402 | − clks++; | |
| 403 | − } | |
| 409 | + if (!clk) | |
| 410 | + return ERR_PTR(-ENODEV); | |
| 404 | 411 | |
| 405 | − return ERR_PTR(-ENODEV); | |
| 412 | + return &(*clk)->hw; | |
| 406 | 413 | } |
| 407 | 414 | |
| 408 | 415 | static int ti_sci_init_clocks(struct sci_clk_provider *p) |
| @@ -410,18 +417,29 @@ static int ti_sci_init_clocks(struct sci_clk_provider *p) · 1 unmodified line | ||
| 410 | 417 | const struct sci_clk_data *data = p->clk_data; |
| 411 | 418 | struct clk_hw *hw; |
| 412 | 419 | int i; |
| 420 | + int num_clks = 0; | |
| 413 | 421 | |
| 414 | 422 | while (data->num_clks) { |
| 415 | − p->clocks = devm_kcalloc(p->dev, data->num_clks, | |
| 416 | − sizeof(struct sci_clk), | |
| 417 | − GFP_KERNEL); | |
| 418 | − if (!p->clocks) | |
| 419 | − return -ENOMEM; | |
| 423 | + num_clks += data->num_clks; | |
| 424 | + data++; | |
| 425 | + } | |
| 420 | 426 | |
| 427 | + p->num_clocks = num_clks; | |
| 428 | + | |
| 429 | + p->clocks = devm_kcalloc(p->dev, num_clks, sizeof(struct sci_clk), | |
| 430 | + GFP_KERNEL); | |
| 431 | + if (!p->clocks) | |
| 432 | + return -ENOMEM; | |
| 433 | + | |
| 434 | + num_clks = 0; | |
| 435 | + | |
| 436 | + data = p->clk_data; | |
| 437 | + | |
| 438 | + while (data->num_clks) { | |
| 421 | 439 | for (i = 0; i < data->num_clks; i++) { |
| 422 | 440 | hw = _sci_clk_build(p, data->dev, i); |
| 423 | 441 | if (!IS_ERR(hw)) { |
| 424 | − p->clocks[i] = hw; | |
| 442 | + p->clocks[num_clks++] = hw; | |
| 425 | 443 | continue; |
| 426 | 444 | } |
| 427 | 445 | |
| @@ -161,6 +161,13 @@ static int mpll_set_rate(struct clk_hw *hw, · 160 unmodified lines | ||
| 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); |
| @@ -118,6 +118,7 @@ struct meson_clk_mpll { · 117 unmodified lines | ||
| 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 | |
| @@ -528,6 +528,11 @@ static struct meson_clk_mpll gxbb_mpll0 = { · 527 unmodified lines | ||
| 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", |
| @@ -267,6 +267,11 @@ static struct meson_clk_mpll meson8b_mpll0 = { · 266 unmodified lines | ||
| 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", |
| @@ -1283,16 +1283,16 @@ static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __ini · 1282 unmodified lines | ||
| 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 = { |
| @@ -184,7 +184,7 @@ static struct ccu_mux cpu_clk = { · 183 unmodified lines | ||
| 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 | |
| @@ -186,6 +186,13 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id, · 185 unmodified lines | ||
| 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); |