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

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 couple fixes to the core framework logic that finds clk parents, a
handful of samsung clk driver fixes for audio and display clks, and a
small fix for the Stratix10 SoC driver that was checking the wrong
register for validity"

* tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux:
clk: Fix potential NULL dereference in clk_fetch_parent_index()
clk: Fix falling back to legacy parent string matching
clk: socfpga: stratix10: fix rate caclulationg for cnt_clks
clk: samsung: exynos542x: Move MSCL subsystem clocks to its sub-CMU
clk: samsung: exynos5800: Move MAU subsystem clocks to MAU sub-CMU
clk: samsung: Change signature of exynos5_subcmus_init() function

+163 -75
+36 -13
drivers/clk/clk.c
··· 324 324 return NULL; 325 325 } 326 326 327 + #ifdef CONFIG_OF 328 + static int of_parse_clkspec(const struct device_node *np, int index, 329 + const char *name, struct of_phandle_args *out_args); 330 + static struct clk_hw * 331 + of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec); 332 + #else 333 + static inline int of_parse_clkspec(const struct device_node *np, int index, 334 + const char *name, 335 + struct of_phandle_args *out_args) 336 + { 337 + return -ENOENT; 338 + } 339 + static inline struct clk_hw * 340 + of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec) 341 + { 342 + return ERR_PTR(-ENOENT); 343 + } 344 + #endif 345 + 327 346 /** 328 347 * clk_core_get - Find the clk_core parent of a clk 329 348 * @core: clk to find parent of ··· 374 355 * }; 375 356 * 376 357 * Returns: -ENOENT when the provider can't be found or the clk doesn't 377 - * exist in the provider. -EINVAL when the name can't be found. NULL when the 378 - * provider knows about the clk but it isn't provided on this system. 358 + * exist in the provider or the name can't be found in the DT node or 359 + * in a clkdev lookup. NULL when the provider knows about the clk but it 360 + * isn't provided on this system. 379 361 * A valid clk_core pointer when the clk can be found in the provider. 380 362 */ 381 363 static struct clk_core *clk_core_get(struct clk_core *core, u8 p_index) ··· 387 367 struct device *dev = core->dev; 388 368 const char *dev_id = dev ? dev_name(dev) : NULL; 389 369 struct device_node *np = core->of_node; 370 + struct of_phandle_args clkspec; 390 371 391 - if (np && (name || index >= 0)) 392 - hw = of_clk_get_hw(np, index, name); 393 - 394 - /* 395 - * If the DT search above couldn't find the provider or the provider 396 - * didn't know about this clk, fallback to looking up via clkdev based 397 - * clk_lookups 398 - */ 399 - if (PTR_ERR(hw) == -ENOENT && name) 372 + if (np && (name || index >= 0) && 373 + !of_parse_clkspec(np, index, name, &clkspec)) { 374 + hw = of_clk_get_hw_from_clkspec(&clkspec); 375 + of_node_put(clkspec.np); 376 + } else if (name) { 377 + /* 378 + * If the DT search above couldn't find the provider fallback to 379 + * looking up via clkdev based clk_lookups. 380 + */ 400 381 hw = clk_find_hw(dev_id, name); 382 + } 401 383 402 384 if (IS_ERR(hw)) 403 385 return ERR_CAST(hw); ··· 423 401 parent = ERR_PTR(-EPROBE_DEFER); 424 402 } else { 425 403 parent = clk_core_get(core, index); 426 - if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT) 404 + if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT && entry->name) 427 405 parent = clk_core_lookup(entry->name); 428 406 } 429 407 ··· 1654 1632 break; 1655 1633 1656 1634 /* Fallback to comparing globally unique names */ 1657 - if (!strcmp(parent->name, core->parents[i].name)) 1635 + if (core->parents[i].name && 1636 + !strcmp(parent->name, core->parents[i].name)) 1658 1637 break; 1659 1638 } 1660 1639
+8 -8
drivers/clk/samsung/clk-exynos5-subcmu.c
··· 14 14 #include "clk-exynos5-subcmu.h" 15 15 16 16 static struct samsung_clk_provider *ctx; 17 - static const struct exynos5_subcmu_info *cmu; 17 + static const struct exynos5_subcmu_info **cmu; 18 18 static int nr_cmus; 19 19 20 20 static void exynos5_subcmu_clk_save(void __iomem *base, ··· 56 56 * when OF-core populates all device-tree nodes. 57 57 */ 58 58 void exynos5_subcmus_init(struct samsung_clk_provider *_ctx, int _nr_cmus, 59 - const struct exynos5_subcmu_info *_cmu) 59 + const struct exynos5_subcmu_info **_cmu) 60 60 { 61 61 ctx = _ctx; 62 62 cmu = _cmu; 63 63 nr_cmus = _nr_cmus; 64 64 65 65 for (; _nr_cmus--; _cmu++) { 66 - exynos5_subcmu_defer_gate(ctx, _cmu->gate_clks, 67 - _cmu->nr_gate_clks); 68 - exynos5_subcmu_clk_save(ctx->reg_base, _cmu->suspend_regs, 69 - _cmu->nr_suspend_regs); 66 + exynos5_subcmu_defer_gate(ctx, (*_cmu)->gate_clks, 67 + (*_cmu)->nr_gate_clks); 68 + exynos5_subcmu_clk_save(ctx->reg_base, (*_cmu)->suspend_regs, 69 + (*_cmu)->nr_suspend_regs); 70 70 } 71 71 } 72 72 ··· 163 163 if (of_property_read_string(np, "label", &name) < 0) 164 164 continue; 165 165 for (i = 0; i < nr_cmus; i++) 166 - if (strcmp(cmu[i].pd_name, name) == 0) 166 + if (strcmp(cmu[i]->pd_name, name) == 0) 167 167 exynos5_clk_register_subcmu(&pdev->dev, 168 - &cmu[i], np); 168 + cmu[i], np); 169 169 } 170 170 return 0; 171 171 }
+1 -1
drivers/clk/samsung/clk-exynos5-subcmu.h
··· 21 21 }; 22 22 23 23 void exynos5_subcmus_init(struct samsung_clk_provider *ctx, int nr_cmus, 24 - const struct exynos5_subcmu_info *cmu); 24 + const struct exynos5_subcmu_info **cmu); 25 25 26 26 #endif
+6 -1
drivers/clk/samsung/clk-exynos5250.c
··· 681 681 .pd_name = "DISP1", 682 682 }; 683 683 684 + static const struct exynos5_subcmu_info *exynos5250_subcmus[] = { 685 + &exynos5250_disp_subcmu, 686 + }; 687 + 684 688 static const struct samsung_pll_rate_table vpll_24mhz_tbl[] __initconst = { 685 689 /* sorted in descending order */ 686 690 /* PLL_36XX_RATE(rate, m, p, s, k) */ ··· 847 843 848 844 samsung_clk_sleep_init(reg_base, exynos5250_clk_regs, 849 845 ARRAY_SIZE(exynos5250_clk_regs)); 850 - exynos5_subcmus_init(ctx, 1, &exynos5250_disp_subcmu); 846 + exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5250_subcmus), 847 + exynos5250_subcmus); 851 848 852 849 samsung_clk_of_add_provider(np, ctx); 853 850
+111 -51
drivers/clk/samsung/clk-exynos5420.c
··· 534 534 GATE_BUS_TOP, 24, 0, 0), 535 535 GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler", 536 536 GATE_BUS_TOP, 27, CLK_IS_CRITICAL, 0), 537 - GATE(CLK_MAU_EPLL, "mau_epll", "mout_user_mau_epll", 538 - SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0), 539 537 }; 540 538 541 539 static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = { ··· 575 577 576 578 static const struct samsung_gate_clock exynos5420_gate_clks[] __initconst = { 577 579 GATE(CLK_SECKEY, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0), 580 + /* Maudio Block */ 578 581 GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk", 579 582 SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0), 583 + GATE(CLK_SCLK_MAUDIO0, "sclk_maudio0", "dout_maudio0", 584 + GATE_TOP_SCLK_MAU, 0, CLK_SET_RATE_PARENT, 0), 585 + GATE(CLK_SCLK_MAUPCM0, "sclk_maupcm0", "dout_maupcm0", 586 + GATE_TOP_SCLK_MAU, 1, CLK_SET_RATE_PARENT, 0), 580 587 }; 581 588 582 589 static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { ··· 893 890 /* GSCL Block */ 894 891 DIV(0, "dout_gscl_blk_333", "aclk333_432_gscl", DIV2_RATIO0, 6, 2), 895 892 896 - /* MSCL Block */ 897 - DIV(0, "dout_mscl_blk", "aclk400_mscl", DIV2_RATIO0, 28, 2), 898 - 899 893 /* PSGEN */ 900 894 DIV(0, "dout_gen_blk", "mout_user_aclk266", DIV2_RATIO0, 8, 1), 901 895 DIV(0, "dout_jpg_blk", "aclk166", DIV2_RATIO0, 20, 1), ··· 1016 1016 GATE_TOP_SCLK_DISP1, 10, CLK_SET_RATE_PARENT, 0), 1017 1017 GATE(CLK_SCLK_DP1, "sclk_dp1", "dout_dp1", 1018 1018 GATE_TOP_SCLK_DISP1, 20, CLK_SET_RATE_PARENT, 0), 1019 - 1020 - /* Maudio Block */ 1021 - GATE(CLK_SCLK_MAUDIO0, "sclk_maudio0", "dout_maudio0", 1022 - GATE_TOP_SCLK_MAU, 0, CLK_SET_RATE_PARENT, 0), 1023 - GATE(CLK_SCLK_MAUPCM0, "sclk_maupcm0", "dout_maupcm0", 1024 - GATE_TOP_SCLK_MAU, 1, CLK_SET_RATE_PARENT, 0), 1025 1019 1026 1020 /* FSYS Block */ 1027 1021 GATE(CLK_TSI, "tsi", "aclk200_fsys", GATE_BUS_FSYS0, 0, 0, 0), ··· 1156 1162 GATE(CLK_FIMC_LITE3, "fimc_lite3", "aclk333_432_gscl", 1157 1163 GATE_IP_GSCL1, 17, 0, 0), 1158 1164 1159 - /* MSCL Block */ 1160 - GATE(CLK_MSCL0, "mscl0", "aclk400_mscl", GATE_IP_MSCL, 0, 0, 0), 1161 - GATE(CLK_MSCL1, "mscl1", "aclk400_mscl", GATE_IP_MSCL, 1, 0, 0), 1162 - GATE(CLK_MSCL2, "mscl2", "aclk400_mscl", GATE_IP_MSCL, 2, 0, 0), 1163 - GATE(CLK_SMMU_MSCL0, "smmu_mscl0", "dout_mscl_blk", 1164 - GATE_IP_MSCL, 8, 0, 0), 1165 - GATE(CLK_SMMU_MSCL1, "smmu_mscl1", "dout_mscl_blk", 1166 - GATE_IP_MSCL, 9, 0, 0), 1167 - GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "dout_mscl_blk", 1168 - GATE_IP_MSCL, 10, 0, 0), 1169 - 1170 1165 /* ISP */ 1171 1166 GATE(CLK_SCLK_UART_ISP, "sclk_uart_isp", "dout_uart_isp", 1172 1167 GATE_TOP_SCLK_ISP, 0, CLK_SET_RATE_PARENT, 0), ··· 1264 1281 { DIV4_RATIO, 0, 0x3 }, /* DIV dout_mfc_blk */ 1265 1282 }; 1266 1283 1267 - static const struct exynos5_subcmu_info exynos5x_subcmus[] = { 1268 - { 1269 - .div_clks = exynos5x_disp_div_clks, 1270 - .nr_div_clks = ARRAY_SIZE(exynos5x_disp_div_clks), 1271 - .gate_clks = exynos5x_disp_gate_clks, 1272 - .nr_gate_clks = ARRAY_SIZE(exynos5x_disp_gate_clks), 1273 - .suspend_regs = exynos5x_disp_suspend_regs, 1274 - .nr_suspend_regs = ARRAY_SIZE(exynos5x_disp_suspend_regs), 1275 - .pd_name = "DISP", 1276 - }, { 1277 - .div_clks = exynos5x_gsc_div_clks, 1278 - .nr_div_clks = ARRAY_SIZE(exynos5x_gsc_div_clks), 1279 - .gate_clks = exynos5x_gsc_gate_clks, 1280 - .nr_gate_clks = ARRAY_SIZE(exynos5x_gsc_gate_clks), 1281 - .suspend_regs = exynos5x_gsc_suspend_regs, 1282 - .nr_suspend_regs = ARRAY_SIZE(exynos5x_gsc_suspend_regs), 1283 - .pd_name = "GSC", 1284 - }, { 1285 - .div_clks = exynos5x_mfc_div_clks, 1286 - .nr_div_clks = ARRAY_SIZE(exynos5x_mfc_div_clks), 1287 - .gate_clks = exynos5x_mfc_gate_clks, 1288 - .nr_gate_clks = ARRAY_SIZE(exynos5x_mfc_gate_clks), 1289 - .suspend_regs = exynos5x_mfc_suspend_regs, 1290 - .nr_suspend_regs = ARRAY_SIZE(exynos5x_mfc_suspend_regs), 1291 - .pd_name = "MFC", 1292 - }, 1284 + static const struct samsung_gate_clock exynos5x_mscl_gate_clks[] __initconst = { 1285 + /* MSCL Block */ 1286 + GATE(CLK_MSCL0, "mscl0", "aclk400_mscl", GATE_IP_MSCL, 0, 0, 0), 1287 + GATE(CLK_MSCL1, "mscl1", "aclk400_mscl", GATE_IP_MSCL, 1, 0, 0), 1288 + GATE(CLK_MSCL2, "mscl2", "aclk400_mscl", GATE_IP_MSCL, 2, 0, 0), 1289 + GATE(CLK_SMMU_MSCL0, "smmu_mscl0", "dout_mscl_blk", 1290 + GATE_IP_MSCL, 8, 0, 0), 1291 + GATE(CLK_SMMU_MSCL1, "smmu_mscl1", "dout_mscl_blk", 1292 + GATE_IP_MSCL, 9, 0, 0), 1293 + GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "dout_mscl_blk", 1294 + GATE_IP_MSCL, 10, 0, 0), 1295 + }; 1296 + 1297 + static const struct samsung_div_clock exynos5x_mscl_div_clks[] __initconst = { 1298 + DIV(0, "dout_mscl_blk", "aclk400_mscl", DIV2_RATIO0, 28, 2), 1299 + }; 1300 + 1301 + static struct exynos5_subcmu_reg_dump exynos5x_mscl_suspend_regs[] = { 1302 + { GATE_IP_MSCL, 0xffffffff, 0xffffffff }, /* MSCL gates */ 1303 + { SRC_TOP3, 0, BIT(4) }, /* MUX mout_user_aclk400_mscl */ 1304 + { DIV2_RATIO0, 0, 0x30000000 }, /* DIV dout_mscl_blk */ 1305 + }; 1306 + 1307 + static const struct samsung_gate_clock exynos5800_mau_gate_clks[] __initconst = { 1308 + GATE(CLK_MAU_EPLL, "mau_epll", "mout_user_mau_epll", 1309 + SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0), 1310 + GATE(CLK_SCLK_MAUDIO0, "sclk_maudio0", "dout_maudio0", 1311 + GATE_TOP_SCLK_MAU, 0, CLK_SET_RATE_PARENT, 0), 1312 + GATE(CLK_SCLK_MAUPCM0, "sclk_maupcm0", "dout_maupcm0", 1313 + GATE_TOP_SCLK_MAU, 1, CLK_SET_RATE_PARENT, 0), 1314 + }; 1315 + 1316 + static struct exynos5_subcmu_reg_dump exynos5800_mau_suspend_regs[] = { 1317 + { SRC_TOP9, 0, BIT(8) }, /* MUX mout_user_mau_epll */ 1318 + }; 1319 + 1320 + static const struct exynos5_subcmu_info exynos5x_disp_subcmu = { 1321 + .div_clks = exynos5x_disp_div_clks, 1322 + .nr_div_clks = ARRAY_SIZE(exynos5x_disp_div_clks), 1323 + .gate_clks = exynos5x_disp_gate_clks, 1324 + .nr_gate_clks = ARRAY_SIZE(exynos5x_disp_gate_clks), 1325 + .suspend_regs = exynos5x_disp_suspend_regs, 1326 + .nr_suspend_regs = ARRAY_SIZE(exynos5x_disp_suspend_regs), 1327 + .pd_name = "DISP", 1328 + }; 1329 + 1330 + static const struct exynos5_subcmu_info exynos5x_gsc_subcmu = { 1331 + .div_clks = exynos5x_gsc_div_clks, 1332 + .nr_div_clks = ARRAY_SIZE(exynos5x_gsc_div_clks), 1333 + .gate_clks = exynos5x_gsc_gate_clks, 1334 + .nr_gate_clks = ARRAY_SIZE(exynos5x_gsc_gate_clks), 1335 + .suspend_regs = exynos5x_gsc_suspend_regs, 1336 + .nr_suspend_regs = ARRAY_SIZE(exynos5x_gsc_suspend_regs), 1337 + .pd_name = "GSC", 1338 + }; 1339 + 1340 + static const struct exynos5_subcmu_info exynos5x_mfc_subcmu = { 1341 + .div_clks = exynos5x_mfc_div_clks, 1342 + .nr_div_clks = ARRAY_SIZE(exynos5x_mfc_div_clks), 1343 + .gate_clks = exynos5x_mfc_gate_clks, 1344 + .nr_gate_clks = ARRAY_SIZE(exynos5x_mfc_gate_clks), 1345 + .suspend_regs = exynos5x_mfc_suspend_regs, 1346 + .nr_suspend_regs = ARRAY_SIZE(exynos5x_mfc_suspend_regs), 1347 + .pd_name = "MFC", 1348 + }; 1349 + 1350 + static const struct exynos5_subcmu_info exynos5x_mscl_subcmu = { 1351 + .div_clks = exynos5x_mscl_div_clks, 1352 + .nr_div_clks = ARRAY_SIZE(exynos5x_mscl_div_clks), 1353 + .gate_clks = exynos5x_mscl_gate_clks, 1354 + .nr_gate_clks = ARRAY_SIZE(exynos5x_mscl_gate_clks), 1355 + .suspend_regs = exynos5x_mscl_suspend_regs, 1356 + .nr_suspend_regs = ARRAY_SIZE(exynos5x_mscl_suspend_regs), 1357 + .pd_name = "MSC", 1358 + }; 1359 + 1360 + static const struct exynos5_subcmu_info exynos5800_mau_subcmu = { 1361 + .gate_clks = exynos5800_mau_gate_clks, 1362 + .nr_gate_clks = ARRAY_SIZE(exynos5800_mau_gate_clks), 1363 + .suspend_regs = exynos5800_mau_suspend_regs, 1364 + .nr_suspend_regs = ARRAY_SIZE(exynos5800_mau_suspend_regs), 1365 + .pd_name = "MAU", 1366 + }; 1367 + 1368 + static const struct exynos5_subcmu_info *exynos5x_subcmus[] = { 1369 + &exynos5x_disp_subcmu, 1370 + &exynos5x_gsc_subcmu, 1371 + &exynos5x_mfc_subcmu, 1372 + &exynos5x_mscl_subcmu, 1373 + }; 1374 + 1375 + static const struct exynos5_subcmu_info *exynos5800_subcmus[] = { 1376 + &exynos5x_disp_subcmu, 1377 + &exynos5x_gsc_subcmu, 1378 + &exynos5x_mfc_subcmu, 1379 + &exynos5x_mscl_subcmu, 1380 + &exynos5800_mau_subcmu, 1293 1381 }; 1294 1382 1295 1383 static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __initconst = { ··· 1593 1539 samsung_clk_extended_sleep_init(reg_base, 1594 1540 exynos5x_clk_regs, ARRAY_SIZE(exynos5x_clk_regs), 1595 1541 exynos5420_set_clksrc, ARRAY_SIZE(exynos5420_set_clksrc)); 1596 - if (soc == EXYNOS5800) 1542 + 1543 + if (soc == EXYNOS5800) { 1597 1544 samsung_clk_sleep_init(reg_base, exynos5800_clk_regs, 1598 1545 ARRAY_SIZE(exynos5800_clk_regs)); 1599 - exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5x_subcmus), 1600 - exynos5x_subcmus); 1546 + 1547 + exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5800_subcmus), 1548 + exynos5800_subcmus); 1549 + } else { 1550 + exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5x_subcmus), 1551 + exynos5x_subcmus); 1552 + } 1601 1553 1602 1554 samsung_clk_of_add_provider(np, ctx); 1603 1555 }
+1 -1
drivers/clk/socfpga/clk-periph-s10.c
··· 38 38 if (socfpgaclk->fixed_div) { 39 39 div = socfpgaclk->fixed_div; 40 40 } else { 41 - if (!socfpgaclk->bypass_reg) 41 + if (socfpgaclk->hw.reg) 42 42 div = ((readl(socfpgaclk->hw.reg) & 0x7ff) + 1); 43 43 } 44 44