summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Belloni <alexandre.belloni@bootlin.com>2019-09-20 11:39:06 -0400
committerStephen Boyd <sboyd@kernel.org>2019-10-28 10:55:01 -0400
commit658fd65cf0b0d511de1718e48d9a28844c385ae0 (patch)
treeb4612e8239fe47aa125d7d69267eb79707096513
parentb234fe9558615098d8d62516e7041ad7f99ebcea (diff)
clk: at91: avoid sleeping early
It is not allowed to sleep to early in the boot process and this may lead to kernel issues if the bootloader didn't prepare the slow clock and main clock. This results in the following error and dump stack on the AriettaG25: bad: scheduling from the idle thread! Ensure it is possible to sleep, else simply have a delay. Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Link: https://lkml.kernel.org/r/20190920153906.20887-1-alexandre.belloni@bootlin.com Fixes: 80eded6ce8bb ("clk: at91: add slow clks driver") Tested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-rw-r--r--drivers/clk/at91/clk-main.c5
-rw-r--r--drivers/clk/at91/sckc.c20
2 files changed, 20 insertions, 5 deletions
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
index 87083b3a2769..37c22667e831 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -297,7 +297,10 @@ static int clk_main_probe_frequency(struct regmap *regmap)
297 regmap_read(regmap, AT91_CKGR_MCFR, &mcfr); 297 regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
298 if (mcfr & AT91_PMC_MAINRDY) 298 if (mcfr & AT91_PMC_MAINRDY)
299 return 0; 299 return 0;
300 usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); 300 if (system_state < SYSTEM_RUNNING)
301 udelay(MAINF_LOOP_MIN_WAIT);
302 else
303 usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
301 } while (time_before(prep_time, timeout)); 304 } while (time_before(prep_time, timeout));
302 305
303 return -ETIMEDOUT; 306 return -ETIMEDOUT;
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
index 9bfe9a28294a..fac0ca56d42d 100644
--- a/drivers/clk/at91/sckc.c
+++ b/drivers/clk/at91/sckc.c
@@ -76,7 +76,10 @@ static int clk_slow_osc_prepare(struct clk_hw *hw)
76 76
77 writel(tmp | osc->bits->cr_osc32en, sckcr); 77 writel(tmp | osc->bits->cr_osc32en, sckcr);
78 78
79 usleep_range(osc->startup_usec, osc->startup_usec + 1); 79 if (system_state < SYSTEM_RUNNING)
80 udelay(osc->startup_usec);
81 else
82 usleep_range(osc->startup_usec, osc->startup_usec + 1);
80 83
81 return 0; 84 return 0;
82} 85}
@@ -187,7 +190,10 @@ static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
187 190
188 writel(readl(sckcr) | osc->bits->cr_rcen, sckcr); 191 writel(readl(sckcr) | osc->bits->cr_rcen, sckcr);
189 192
190 usleep_range(osc->startup_usec, osc->startup_usec + 1); 193 if (system_state < SYSTEM_RUNNING)
194 udelay(osc->startup_usec);
195 else
196 usleep_range(osc->startup_usec, osc->startup_usec + 1);
191 197
192 return 0; 198 return 0;
193} 199}
@@ -288,7 +294,10 @@ static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
288 294
289 writel(tmp, sckcr); 295 writel(tmp, sckcr);
290 296
291 usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); 297 if (system_state < SYSTEM_RUNNING)
298 udelay(SLOWCK_SW_TIME_USEC);
299 else
300 usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
292 301
293 return 0; 302 return 0;
294} 303}
@@ -533,7 +542,10 @@ static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw)
533 return 0; 542 return 0;
534 } 543 }
535 544
536 usleep_range(osc->startup_usec, osc->startup_usec + 1); 545 if (system_state < SYSTEM_RUNNING)
546 udelay(osc->startup_usec);
547 else
548 usleep_range(osc->startup_usec, osc->startup_usec + 1);
537 osc->prepared = true; 549 osc->prepared = true;
538 550
539 return 0; 551 return 0;