forked from Minki/linux
Here's the last batch of clk driver fixes for this release. These
patches fix serious problems, for example, i.MX has an issue where changing the NAND clk frequency hangs the system. On Allwinner H6 the GPU is being overclocked which could lead to long term hardware damage. And finally on some Broadcom SoCs the serial console stopped working because the clk tree hierarchy description got broken by an inadvertant DT node name change. That's fixed by using 'clock-output-names' to generate a stable and unique name for clks so the framework can properly link things up. There's also a couple build fixes in here. One to fix CONFIG_OF=n builds and one to avoid an array out of bounds bug that happens during clk registration on microchip. I hope that KASAN would have found that OOB problem, but probably KASAN wasn't attempted. Instead LLVM/clang compilation caused an oops, while GCC didn't. -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmM3WigRHHNib3lkQGtl cm5lbC5vcmcACgkQrQKIl8bklSUagQ//WM5qcHAYbvxCXN44m+dr+Y/5h/3wUMcB RySFPR67wao2yiCe/868kt8RMBA9hvCLEtTE/qai31+67jZpYjJontKjCx+YigDa sobGDTFFg5BsBODLAvPcDbnL41CDAbyShBgSuwUyqBKiV4XasN52NFu1U13kiyuO iay+zho398oaINnjNje0mJU4TsKUavK6lxwp+siHOsRAFUa9+g+jG/aY2G0He26f jZ5fzxWeVjdhUtUhZRNwtKI+1Y25qOG/ETuz7eGVFPCkBED01AegKgpG7M22E2PD n/ZUMjr4kvepTBQpd0tBGRIQ/v3jBLKPHU1PWp0cSjvRCo8Z0d6qUc57nYwb3fcd hYKp+i1BC8M3on+jvLX6Ktwe+YGDhw1q82JxJ0lD4Kj9vfg1bO6GBE/zSeWp1e04 ZGopKA9+pZoj4nYEnifrsxJ39ib7yM+OM7XUhO+fRNvjl8u516jkt4TwbBO8G6vF lsRu8/6QqAN88eIVJAUHP4osCL5ZP/gu0zL8VuFuVfm4baBnqjswY0BkFXkktSd8 RUc5tHJB4GyFQ/B3KF8w8lv0z5rocxDMqjqRABdZpMugnX/x4JhKvik+YMQ9CzYC YF0Sp614x3GvVGFRZIzl0O502FHTLx+0uqS3dL38U5SBbKi3hNSBsiIWkFTKNdbz rcpLi41GY1c= =5AzX -----END PGP SIGNATURE----- Merge tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux Pull clk driver fixes from Stephen Boyd: "Here's the last batch of clk driver fixes for this release. These patches fix serious problems, for example, i.MX has an issue where changing the NAND clk frequency hangs the system. On Allwinner H6 the GPU is being overclocked which could lead to long term hardware damage. And finally on some Broadcom SoCs the serial console stopped working because the clk tree hierarchy description got broken by an inadvertant DT node name change. That's fixed by using 'clock-output-names' to generate a stable and unique name for clks so the framework can properly link things up. There's also a couple build fixes in here. One to fix CONFIG_OF=n builds and one to avoid an array out of bounds bug that happens during clk registration on microchip. I hope that KASAN would have found that OOB problem, but probably KASAN wasn't attempted. Instead LLVM/clang compilation caused an oops, while GCC didn't" * tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: clk: imx93: drop of_match_ptr clk: iproc: Do not rely on node name for correct PLL setup clk: sunxi-ng: h6: Fix default PLL GPU rate clk: imx: imx6sx: remove the SET_RATE_PARENT flag for QSPI clocks clk: microchip: mpfs: make the rtc's ahb clock critical clk: microchip: mpfs: fix clk_cfg array bounds violation clk: ingenic-tcu: Properly enable registers before accessing timers
This commit is contained in:
commit
e5fa173f9a
@ -726,6 +726,7 @@ void iproc_pll_clk_setup(struct device_node *node,
|
||||
const char *parent_name;
|
||||
struct iproc_clk *iclk_array;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
const char *clk_name;
|
||||
|
||||
if (WARN_ON(!pll_ctrl) || WARN_ON(!clk_ctrl))
|
||||
return;
|
||||
@ -773,7 +774,12 @@ void iproc_pll_clk_setup(struct device_node *node,
|
||||
iclk = &iclk_array[0];
|
||||
iclk->pll = pll;
|
||||
|
||||
init.name = node->name;
|
||||
ret = of_property_read_string_index(node, "clock-output-names",
|
||||
0, &clk_name);
|
||||
if (WARN_ON(ret))
|
||||
goto err_pll_register;
|
||||
|
||||
init.name = clk_name;
|
||||
init.ops = &iproc_pll_ops;
|
||||
init.flags = 0;
|
||||
parent_name = of_clk_get_parent_name(node, 0);
|
||||
@ -793,13 +799,11 @@ void iproc_pll_clk_setup(struct device_node *node,
|
||||
goto err_pll_register;
|
||||
|
||||
clk_data->hws[0] = &iclk->hw;
|
||||
parent_name = clk_name;
|
||||
|
||||
/* now initialize and register all leaf clocks */
|
||||
for (i = 1; i < num_clks; i++) {
|
||||
const char *clk_name;
|
||||
|
||||
memset(&init, 0, sizeof(init));
|
||||
parent_name = node->name;
|
||||
|
||||
ret = of_property_read_string_index(node, "clock-output-names",
|
||||
i, &clk_name);
|
||||
|
@ -280,13 +280,13 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
|
||||
hws[IMX6SX_CLK_SSI3_SEL] = imx_clk_hw_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
|
||||
hws[IMX6SX_CLK_SSI2_SEL] = imx_clk_hw_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
|
||||
hws[IMX6SX_CLK_SSI1_SEL] = imx_clk_hw_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
|
||||
hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
|
||||
hws[IMX6SX_CLK_PERCLK_SEL] = imx_clk_hw_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
|
||||
hws[IMX6SX_CLK_VID_SEL] = imx_clk_hw_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels));
|
||||
hws[IMX6SX_CLK_ESAI_SEL] = imx_clk_hw_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
|
||||
hws[IMX6SX_CLK_CAN_SEL] = imx_clk_hw_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels));
|
||||
hws[IMX6SX_CLK_UART_SEL] = imx_clk_hw_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
|
||||
hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels));
|
||||
hws[IMX6SX_CLK_SPDIF_SEL] = imx_clk_hw_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
|
||||
hws[IMX6SX_CLK_AUDIO_SEL] = imx_clk_hw_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
|
||||
hws[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_hw_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels));
|
||||
|
@ -332,7 +332,7 @@ static struct platform_driver imx93_clk_driver = {
|
||||
.driver = {
|
||||
.name = "imx93-ccm",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = of_match_ptr(imx93_clk_of_match),
|
||||
.of_match_table = imx93_clk_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(imx93_clk_driver);
|
||||
|
@ -101,15 +101,11 @@ static bool ingenic_tcu_enable_regs(struct clk_hw *hw)
|
||||
bool enabled = false;
|
||||
|
||||
/*
|
||||
* If the SoC has no global TCU clock, we must ungate the channel's
|
||||
* clock to be able to access its registers.
|
||||
* If we have a TCU clock, it will be enabled automatically as it has
|
||||
* been attached to the regmap.
|
||||
* According to the programming manual, a timer channel's registers can
|
||||
* only be accessed when the channel's stop bit is clear.
|
||||
*/
|
||||
if (!tcu->clk) {
|
||||
enabled = !!ingenic_tcu_is_enabled(hw);
|
||||
regmap_write(tcu->map, TCU_REG_TSCR, BIT(info->gate_bit));
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
@ -120,7 +116,6 @@ static void ingenic_tcu_disable_regs(struct clk_hw *hw)
|
||||
const struct ingenic_tcu_clk_info *info = tcu_clk->info;
|
||||
struct ingenic_tcu *tcu = tcu_clk->tcu;
|
||||
|
||||
if (!tcu->clk)
|
||||
regmap_write(tcu->map, TCU_REG_TSSR, BIT(info->gate_bit));
|
||||
}
|
||||
|
||||
|
@ -239,6 +239,11 @@ static const struct clk_ops mpfs_clk_cfg_ops = {
|
||||
.hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \
|
||||
}
|
||||
|
||||
#define CLK_CPU_OFFSET 0u
|
||||
#define CLK_AXI_OFFSET 1u
|
||||
#define CLK_AHB_OFFSET 2u
|
||||
#define CLK_RTCREF_OFFSET 3u
|
||||
|
||||
static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
|
||||
CLK_CFG(CLK_CPU, "clk_cpu", "clk_msspll", 0, 2, mpfs_div_cpu_axi_table, 0,
|
||||
REG_CLOCK_CONFIG_CR),
|
||||
@ -362,7 +367,7 @@ static const struct clk_ops mpfs_periph_clk_ops = {
|
||||
_flags), \
|
||||
}
|
||||
|
||||
#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].hw)
|
||||
#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].hw)
|
||||
|
||||
/*
|
||||
* Critical clocks:
|
||||
@ -370,6 +375,8 @@ static const struct clk_ops mpfs_periph_clk_ops = {
|
||||
* trap handler
|
||||
* - CLK_MMUART0: reserved by the hss
|
||||
* - CLK_DDRC: provides clock to the ddr subsystem
|
||||
* - CLK_RTC: the onboard RTC's AHB bus clock must be kept running as the rtc will stop
|
||||
* if the AHB interface clock is disabled
|
||||
* - CLK_FICx: these provide the processor side clocks to the "FIC" (Fabric InterConnect)
|
||||
* clock domain crossers which provide the interface to the FPGA fabric. Disabling them
|
||||
* causes the FPGA fabric to go into reset.
|
||||
@ -394,7 +401,7 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
|
||||
CLK_PERIPH(CLK_CAN0, "clk_periph_can0", PARENT_CLK(AHB), 14, 0),
|
||||
CLK_PERIPH(CLK_CAN1, "clk_periph_can1", PARENT_CLK(AHB), 15, 0),
|
||||
CLK_PERIPH(CLK_USB, "clk_periph_usb", PARENT_CLK(AHB), 16, 0),
|
||||
CLK_PERIPH(CLK_RTC, "clk_periph_rtc", PARENT_CLK(AHB), 18, 0),
|
||||
CLK_PERIPH(CLK_RTC, "clk_periph_rtc", PARENT_CLK(AHB), 18, CLK_IS_CRITICAL),
|
||||
CLK_PERIPH(CLK_QSPI, "clk_periph_qspi", PARENT_CLK(AHB), 19, 0),
|
||||
CLK_PERIPH(CLK_GPIO0, "clk_periph_gpio0", PARENT_CLK(AHB), 20, 0),
|
||||
CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", PARENT_CLK(AHB), 21, 0),
|
||||
|
@ -1191,9 +1191,13 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
/* Force PLL_GPU output divider bits to 0 */
|
||||
/*
|
||||
* Force PLL_GPU output divider bits to 0 and adjust
|
||||
* multiplier to sensible default value of 432 MHz.
|
||||
*/
|
||||
val = readl(reg + SUN50I_H6_PLL_GPU_REG);
|
||||
val &= ~BIT(0);
|
||||
val &= ~(GENMASK(15, 8) | BIT(0));
|
||||
val |= 17 << 8;
|
||||
writel(val, reg + SUN50I_H6_PLL_GPU_REG);
|
||||
|
||||
/* Force GPU_CLK divider bits to 0 */
|
||||
|
Loading…
Reference in New Issue
Block a user