clk: qcom: Add WARN_CLK support for PLL, RCG and Branch clocks

Add support for WARN_CLK to dump the clock registers and
calltrace in case of failure in the kernel message.

Change-Id: If7452aaa02cc50deafd6f3721921f66cad9ab932
Signed-off-by: Taniya Das <tdas@codeaurora.org>
This commit is contained in:
Taniya Das 2020-10-01 23:28:15 +05:30 • committed by Jagadeesh Kona
commit 6949a466ba
5 changed files with 53 additions and 37 deletions

View file

@ -294,7 +294,6 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
int count;
int ret;
u64 time;
const char *name = clk_hw_get_name(&pll->clkr.hw);
ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
if (ret)
@ -317,7 +316,7 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
pr_err("PLL lock bit detection total wait time: %lld ns\n", time);
WARN(1, "%s failed to %s!\n", name, action);
WARN_CLK(&pll->clkr.hw, 1, "failed to %s!\n", action);
return -ETIMEDOUT;
}
@ -1261,7 +1260,8 @@ static int clk_trion_pll_set_rate(struct clk_hw *hw, unsigned long rate,
udelay(1);
regmap_read(pll->clkr.regmap, PLL_MODE(pll), &regval);
if (!(regval & ALPHA_PLL_ACK_LATCH)) {
WARN(1, "PLL latch failed. Output may be unstable!\n");
WARN_CLK(&pll->clkr.hw, 1,
"PLL latch failed. Output may be unstable!\n");
return -EINVAL;
}
@ -1338,7 +1338,7 @@ static void clk_trion_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
for (i = 0; i < size; i++) {
regmap_read(pll->clkr.regmap, pll->offset +
pll->regs[data[i].offset], &val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
regmap_read(pll->clkr.regmap, pll->offset + pll->regs[data[0].offset],
@ -1347,7 +1347,7 @@ static void clk_trion_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
if (val & PLL_FSM_ENA) {
regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
data1[0].offset, &val);
seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
@ -1762,9 +1762,9 @@ static void clk_alpha_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
size = ARRAY_SIZE(data);
for (i = 0; i < size; i++) {
regmap_read(pll->clkr.regmap,
pll->offset + pll->regs[data[i].offset], &val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
regmap_read(pll->clkr.regmap, pll->offset + data[i].offset,
&val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
regmap_read(pll->clkr.regmap, pll->offset +
@ -1773,7 +1773,7 @@ static void clk_alpha_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
if (val & PLL_FSM_ENA) {
regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
data1[0].offset, &val);
seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
@ -1819,7 +1819,7 @@ static void clk_alpha_pll_huayra_list_registers(struct seq_file *f,
for (i = 0; i < size; i++) {
regmap_read(pll->clkr.regmap, pll->offset +
pll->regs[data[i].offset], &val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
regmap_read(pll->clkr.regmap, pll->offset + pll->regs[data[0].offset],
@ -1828,7 +1828,7 @@ static void clk_alpha_pll_huayra_list_registers(struct seq_file *f,
if (val & PLL_FSM_ENA) {
regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
data1[0].offset, &val);
seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
@ -1969,7 +1969,7 @@ static void clk_alpha_pll_zonda_list_registers(struct seq_file *f,
for (i = 0; i < size; i++) {
regmap_read(pll->clkr.regmap, pll->offset +
pll->regs[data[i].offset], &val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
regmap_read(pll->clkr.regmap, pll->offset + pll->regs[data[0].offset],
@ -1978,7 +1978,7 @@ static void clk_alpha_pll_zonda_list_registers(struct seq_file *f,
if (val & PLL_FSM_ENA) {
regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
data1[0].offset, &val);
seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
@ -2383,7 +2383,7 @@ static void clk_fabia_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
for (i = 0; i < size; i++) {
regmap_read(pll->clkr.regmap, pll->offset +
pll->regs[data[i].offset], &val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
regmap_read(pll->clkr.regmap, pll->offset + pll->regs[data[0].offset],
@ -2392,7 +2392,7 @@ static void clk_fabia_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
if (val & PLL_FSM_ENA) {
regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
data1[0].offset, &val);
seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
@ -2873,7 +2873,8 @@ static int alpha_pll_lucid_set_rate(struct clk_hw *hw, unsigned long rate,
udelay(1);
regmap_read(pll->clkr.regmap, PLL_MODE(pll), &regval);
if (!(regval & ALPHA_PLL_ACK_LATCH)) {
WARN(1, "PLL latch failed. Output may be unstable!\n");
WARN_CLK(&pll->clkr.hw, 1,
"PLL latch failed. Output may be unstable!\n");
return -EINVAL;
}
@ -3152,7 +3153,8 @@ static int alpha_pll_lucid_5lpe_set_rate(struct clk_hw *hw, unsigned long rate,
udelay(1);
regmap_read(pll->clkr.regmap, PLL_MODE(pll), &regval);
if (!(regval & LUCID_5LPE_ALPHA_PLL_ACK_LATCH)) {
WARN(1, "PLL latch failed. Output may be unstable!\n");
WARN_CLK(&pll->clkr.hw, 1,
"PLL latch failed. Output may be unstable!\n");
return -EINVAL;
}
@ -3249,7 +3251,7 @@ static void lucid_pll_list_registers(struct seq_file *f,
for (i = 0; i < size; i++) {
regmap_read(pll->clkr.regmap, pll->offset +
pll->regs[data[i].offset], &val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
regmap_read(pll->clkr.regmap, pll->offset +
@ -3258,7 +3260,7 @@ static void lucid_pll_list_registers(struct seq_file *f,
if (val & PLL_FSM_ENA) {
regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
data1[0].offset, &val);
seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
@ -3669,7 +3671,8 @@ static int alpha_pll_lucid_evo_set_rate(struct clk_hw *hw, unsigned long rate,
udelay(1);
regmap_read(pll->clkr.regmap, PLL_MODE(pll), &regval);
if (!(regval & LUCID_5LPE_ALPHA_PLL_ACK_LATCH)) {
WARN(1, "PLL latch failed. Output may be unstable!\n");
WARN_CLK(&pll->clkr.hw, 1,
"PLL latch failed. Output may be unstable!\n");
return -EINVAL;
}
@ -3719,7 +3722,7 @@ static void lucid_evo_pll_list_registers(struct seq_file *f,
for (i = 0; i < size; i++) {
regmap_read(pll->clkr.regmap, pll->offset +
pll->regs[data[i].offset], &val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);
@ -3727,7 +3730,7 @@ static void lucid_evo_pll_list_registers(struct seq_file *f,
if (val & LUCID_EVO_ENABLE_VOTE_RUN) {
regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
data1[0].offset, &val);
seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
@ -4058,7 +4061,7 @@ static void clk_regera_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
for (i = 0; i < size; i++) {
regmap_read(pll->clkr.regmap, pll->offset +
pll->regs[data[i].offset], &val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
regmap_read(pll->clkr.regmap, pll->offset + pll->regs[data[0].offset],
@ -4066,7 +4069,7 @@ static void clk_regera_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
if (val & PLL_FSM_ENA) {
regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
data1[0].offset, &val);
seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
@ -4214,7 +4217,7 @@ static void clk_agera_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
for (i = 0; i < size; i++) {
regmap_read(pll->clkr.regmap, pll->offset +
pll->regs[data[i].offset], &val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
regmap_read(pll->clkr.regmap, pll->offset + pll->regs[data[0].offset],
@ -4222,7 +4225,7 @@ static void clk_agera_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
if (val & PLL_FSM_ENA) {
regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
data1[0].offset, &val);
seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data1[0].name, val);
}
}

View file

@ -72,7 +72,6 @@ static int clk_branch_wait(const struct clk_branch *br, bool enabling,
bool (check_halt)(const struct clk_branch *, bool))
{
bool voted = br->halt_check & BRANCH_VOTED;
const char *name = clk_hw_get_name(&br->clkr.hw);
/*
* Skip checking halt bit if we're explicitly ignoring the bit or the
@ -93,7 +92,7 @@ static int clk_branch_wait(const struct clk_branch *br, bool enabling,
return 0;
udelay(1);
}
WARN(1, "%s status stuck at 'o%s'", name,
WARN_CLK((struct clk_hw *)&br->clkr.hw, 1, "status stuck at 'o%s'",
enabling ? "ff" : "n");
return -EBUSY;
}
@ -191,7 +190,7 @@ static void clk_branch2_list_registers(struct seq_file *f, struct clk_hw *hw)
for (i = 0; i < size; i++) {
regmap_read(br->clkr.regmap, br->halt_reg + data[i].offset,
&val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
if ((br->halt_check & BRANCH_HALT_VOTED) &&
@ -201,7 +200,7 @@ static void clk_branch2_list_registers(struct seq_file *f, struct clk_hw *hw)
for (i = 0; i < size; i++) {
regmap_read(br->clkr.regmap, rclk->enable_reg +
data1[i].offset, &val);
seq_printf(f, "%20s: 0x%.8x\n",
clock_debug_output(f, "%20s: 0x%.8x\n",
data1[i].name, val);
}
}

View file

@ -501,7 +501,7 @@ static const struct file_operations list_rates_fops = {
.release = seq_release,
};
static void clk_debug_print_hw(struct clk_hw *hw, struct seq_file *f)
void clk_debug_print_hw(struct clk_hw *hw, struct seq_file *f)
{
struct clk_regmap *rclk;
@ -509,7 +509,7 @@ static void clk_debug_print_hw(struct clk_hw *hw, struct seq_file *f)
return;
clk_debug_print_hw(clk_hw_get_parent(hw), f);
seq_printf(f, "%s\n", clk_hw_get_name(hw));
clock_debug_output(f, "%s\n", clk_hw_get_name(hw));
if (clk_is_regmap_clk(hw)) {
rclk = to_clk_regmap(hw);

View file

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2016, 2019, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2016, 2019-2020, The Linux Foundation. All rights reserved. */
#ifndef __QCOM_CLK_DEBUG_H__
#define __QCOM_CLK_DEBUG_H__
@ -92,4 +92,19 @@ int map_debug_bases(struct platform_device *pdev, const char *base,
void clk_common_debug_init(struct clk_hw *hw, struct dentry *dentry);
extern void clk_debug_print_hw(struct clk_hw *hw, struct seq_file *f);
#define WARN_CLK(hw, cond, fmt, ...) do { \
clk_debug_print_hw(hw, NULL); \
WARN(cond, "%s: " fmt, clk_hw_get_name(hw), ##__VA_ARGS__); \
} while (0)
#define clock_debug_output(m, fmt, ...) \
do { \
if (m) \
seq_printf(m, fmt, ##__VA_ARGS__); \
else \
pr_info(fmt, ##__VA_ARGS__); \
} while (0)
#endif

View file

@ -112,7 +112,6 @@ static int update_config(struct clk_rcg2 *rcg)
int count, ret;
u32 cmd;
struct clk_hw *hw = &rcg->clkr.hw;
const char *name = clk_hw_get_name(hw);
ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
CMD_UPDATE, CMD_UPDATE);
@ -129,7 +128,7 @@ static int update_config(struct clk_rcg2 *rcg)
udelay(1);
}
WARN(1, "%s: rcg didn't update its configuration.", name);
WARN_CLK(hw, 1, "rcg didn't update its configuration.");
return -EBUSY;
}
@ -164,7 +163,7 @@ static int clk_rcg2_set_force_enable(struct clk_hw *hw)
udelay(1);
}
WARN(1, "%s: rcg didn't turn on.", clk_hw_get_name(hw));
WARN_CLK(hw, 1, "rcg didn't turn on.");
return ret;
}
@ -489,7 +488,7 @@ static void clk_rcg2_list_registers(struct seq_file *f, struct clk_hw *hw)
for (i = 0; data[i].name != NULL; i++) {
regmap_read(rcg->clkr.regmap, (rcg->cmd_rcgr +
data[i].offset), &val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
}