Commit 9d7a375e authored by Shawn Lin's avatar Shawn Lin Committed by Khalid Elmously

clk: rockchip: Prevent calculating mmc phase if clock rate is zero

BugLink: https://bugs.launchpad.net/bugs/1775771

[ Upstream commit 4bf59902 ]

The MMC sample and drv clock for rockchip platforms are derived from
the bus clock output to the MMC/SDIO card. So it should never happens
that the clk rate is zero given it should inherits the clock rate from
its parent. If something goes wrong and makes the clock rate to be zero,
the calculation would be wrong but may still make the mmc tuning process
work luckily. However it makes people harder to debug when the following
data transfer is unstable.
Signed-off-by: default avatarShawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Signed-off-by: default avatarSasha Levin <alexander.levin@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarJuerg Haefliger <juergh@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent 6b7c6745
...@@ -60,6 +60,12 @@ static int rockchip_mmc_get_phase(struct clk_hw *hw) ...@@ -60,6 +60,12 @@ static int rockchip_mmc_get_phase(struct clk_hw *hw)
u16 degrees; u16 degrees;
u32 delay_num = 0; u32 delay_num = 0;
/* See the comment for rockchip_mmc_set_phase below */
if (!rate) {
pr_err("%s: invalid clk rate\n", __func__);
return -EINVAL;
}
raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift); raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift);
degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
...@@ -86,6 +92,23 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees) ...@@ -86,6 +92,23 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
u32 raw_value; u32 raw_value;
u32 delay; u32 delay;
/*
* The below calculation is based on the output clock from
* MMC host to the card, which expects the phase clock inherits
* the clock rate from its parent, namely the output clock
* provider of MMC host. However, things may go wrong if
* (1) It is orphan.
* (2) It is assigned to the wrong parent.
*
* This check help debug the case (1), which seems to be the
* most likely problem we often face and which makes it difficult
* for people to debug unstable mmc tuning results.
*/
if (!rate) {
pr_err("%s: invalid clk rate\n", __func__);
return -EINVAL;
}
nineties = degrees / 90; nineties = degrees / 90;
remainder = (degrees % 90); remainder = (degrees % 90);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment