
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I9UDJX -------------------------------- Use readl_poll_timeout_atomic to wait reg op finish rather than do..while in order to avoid lockup if something is wrong during reg updating. Signed-off-by: Wupeng Ma <mawupeng1@huawei.com> --- drivers/soc/hisilicon/l3t.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/soc/hisilicon/l3t.c b/drivers/soc/hisilicon/l3t.c index eacbb8fa3212..35106e091098 100644 --- a/drivers/soc/hisilicon/l3t.c +++ b/drivers/soc/hisilicon/l3t.c @@ -15,6 +15,7 @@ #include <linux/smp.h> #include <linux/xarray.h> #include <linux/irqchip.h> +#include <linux/iopoll.h> #include "hisi_l3t.h" @@ -23,6 +24,10 @@ #define UNLOCK_EN BIT(2) #define UNLOCK_DONE BIT(3) +#define HISI_L3C_LOCK_CTRL_POLL_GAP_US 10 + +#define l3c_lock_ctrl_mask(lock_ctrl, mask) ((lock_ctrl) & (mask)) + DEFINE_MUTEX(l3t_mutex); static DEFINE_XARRAY(l3t_mapping); @@ -121,13 +126,17 @@ static int hisi_l3t_init_mapping(struct device *dev, struct hisi_l3t *l3t) /* write bit b_update and wait bit b_wait to be zero */ static void __l3t_update_and_wait(void __iomem *addr, u32 b_update, u32 b_wait) { + int timeout; u32 val; writel(b_update, addr); - do { - val = readl(addr); - } while ((val & b_wait) == 0); + timeout = readl_poll_timeout_atomic(addr, val, + l3c_lock_ctrl_mask(val, b_wait), + HISI_L3C_LOCK_CTRL_POLL_GAP_US, + jiffies_to_usecs(HZ)); + if (timeout) + pr_warn_ratelimited("read reg timeout\n"); } static void __l3t_maintain_do_lock(void __iomem *addr, int slot_idx, -- 2.43.0