Message ID | 1465596231-21766-2-git-send-email-alexandre.belloni@free-electrons.com (mailing list archive) |
---|---|
State | Rejected, archived |
Delegated to: | Stephen Boyd |
Headers | show |
On Saturday, June 11, 2016 12:03:04 AM CEST Alexandre Belloni wrote: > From: Cyrille Pitchen <cyrille.pitchen@atmel.com> > > Fix the main and slow clock .prepare() implementations which used to call > usleep() when the scheduler wasn't ready yet. > Does this have to be called that early? It seems wasteful to always call udelay() here, when these are functions that are normally allowed to sleep. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 11/06/2016 at 00:30:36 +0200, Arnd Bergmann wrote : > On Saturday, June 11, 2016 12:03:04 AM CEST Alexandre Belloni wrote: > > From: Cyrille Pitchen <cyrille.pitchen@atmel.com> > > > > Fix the main and slow clock .prepare() implementations which used to call > > usleep() when the scheduler wasn't ready yet. > > > > Does this have to be called that early? It seems wasteful to always > call udelay() here, when these are functions that are normally > allowed to sleep. > Well, the main issue here is that we want to be able to prepare_enable the slow clock before we are allowed to sleep. Thinking about it when writing that, I realize that when I reworked my series, I removed the dependency between the clocksource TCB and the slow_clock. But I guess we still have one on the main clock. I'll check whether this is still necessary.
On Sat, 11 Jun 2016 00:03:04 +0200 Alexandre Belloni <alexandre.belloni@free-electrons.com> wrote: > From: Cyrille Pitchen <cyrille.pitchen@atmel.com> > > Fix the main and slow clock .prepare() implementations which used to call > usleep() when the scheduler wasn't ready yet. > > Cc: Stephen Boyd <sboyd@codeaurora.org> > Cc: linux-clk@vger.kernel.org > Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com> > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> > --- > drivers/clk/at91/clk-main.c | 2 +- > drivers/clk/at91/clk-slow.c | 6 +++--- > 2 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c > index 58b5baca670c..12c5062aeb92 100644 > --- a/drivers/clk/at91/clk-main.c > +++ b/drivers/clk/at91/clk-main.c > @@ -342,7 +342,7 @@ static int clk_main_probe_frequency(struct regmap *regmap) > regmap_read(regmap, AT91_CKGR_MCFR, &mcfr); > if (mcfr & AT91_PMC_MAINRDY) > return 0; > - usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); > + udelay(MAINF_LOOP_MIN_WAIT); > } while (time_before(prep_time, timeout)); > > return -ETIMEDOUT; > diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c > index 61090b1146cf..612e893ce994 100644 > --- a/drivers/clk/at91/clk-slow.c > +++ b/drivers/clk/at91/clk-slow.c > @@ -76,7 +76,7 @@ static int clk_slow_osc_prepare(struct clk_hw *hw) > > writel(tmp | AT91_SCKC_OSC32EN, sckcr); > > - usleep_range(osc->startup_usec, osc->startup_usec + 1); > + udelay(osc->startup_usec); If you're using udelay() you should probably move the code in ->prepare() into ->enable(). The same goes for the following changes. > > return 0; > } > @@ -195,7 +195,7 @@ static int clk_slow_rc_osc_prepare(struct clk_hw *hw) > > writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr); > > - usleep_range(osc->startup_usec, osc->startup_usec + 1); > + udelay(osc->startup_usec); > > return 0; > } > @@ -304,7 +304,7 @@ static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) > > writel(tmp, sckcr); > > - usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); > + udelay(SLOWCK_SW_TIME_USEC); > > return 0; > }
On 11/06/2016 at 00:30:36 +0200, Arnd Bergmann wrote : > On Saturday, June 11, 2016 12:03:04 AM CEST Alexandre Belloni wrote: > > From: Cyrille Pitchen <cyrille.pitchen@atmel.com> > > > > Fix the main and slow clock .prepare() implementations which used to call > > usleep() when the scheduler wasn't ready yet. > > > > Does this have to be called that early? It seems wasteful to always > call udelay() here, when these are functions that are normally > allowed to sleep. > So I've tested it and something like that would work: if (system_state < SYSTEM_RUNNING) udelay(osc->startup_usec); else usleep_range(osc->startup_usec, osc->startup_usec + 1); But I'm afraid it would be the first driver to actually do something like that (however, it is already the only driver trying to sleep).
On Monday, June 13, 2016 5:24:09 PM CEST Alexandre Belloni wrote: > On 11/06/2016 at 00:30:36 +0200, Arnd Bergmann wrote : > > On Saturday, June 11, 2016 12:03:04 AM CEST Alexandre Belloni wrote: > > > From: Cyrille Pitchen <cyrille.pitchen@atmel.com> > > > > > > Fix the main and slow clock .prepare() implementations which used to call > > > usleep() when the scheduler wasn't ready yet. > > > > > > > Does this have to be called that early? It seems wasteful to always > > call udelay() here, when these are functions that are normally > > allowed to sleep. > > > > So I've tested it and something like that would work: > > if (system_state < SYSTEM_RUNNING) > udelay(osc->startup_usec); > else > usleep_range(osc->startup_usec, osc->startup_usec + 1); I think that's reasonable in this case. > But I'm afraid it would be the first driver to actually do something > like that (however, it is already the only driver trying to sleep). We have a lot of drivers that call potentially sleeping function from the .prepare callback, e.g. when they go to an i2c controller. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi, On Mon, Jun 13, 2016 at 05:24:09PM +0200, Alexandre Belloni wrote: > On 11/06/2016 at 00:30:36 +0200, Arnd Bergmann wrote : > > Does this have to be called that early? It seems wasteful to always > > call udelay() here, when these are functions that are normally > > allowed to sleep. > So I've tested it and something like that would work: > > if (system_state < SYSTEM_RUNNING) > udelay(osc->startup_usec); > else > usleep_range(osc->startup_usec, osc->startup_usec + 1); > > But I'm afraid it would be the first driver to actually do something > like that (however, it is already the only driver trying to sleep). tglx has suggested to modify clock core to handle a somewhat similar kind of scenario (probably should work here too) and avoid driver changes, http://lkml.kernel.org/r/alpine.DEB.2.11.1606061448010.28031@nanos Regards afzal -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, 14 Jun 2016 21:35:17 +0530 Afzal Mohammed <afzal.mohd.ma@gmail.com> wrote: > Hi, > > On Mon, Jun 13, 2016 at 05:24:09PM +0200, Alexandre Belloni wrote: > > On 11/06/2016 at 00:30:36 +0200, Arnd Bergmann wrote : > > > > Does this have to be called that early? It seems wasteful to always > > > call udelay() here, when these are functions that are normally > > > allowed to sleep. > > > So I've tested it and something like that would work: > > > > if (system_state < SYSTEM_RUNNING) > > udelay(osc->startup_usec); > > else > > usleep_range(osc->startup_usec, osc->startup_usec + 1); > > > > But I'm afraid it would be the first driver to actually do something > > like that (however, it is already the only driver trying to sleep). > > tglx has suggested to modify clock core to handle a somewhat similar > kind of scenario (probably should work here too) and avoid driver > changes, > > http://lkml.kernel.org/r/alpine.DEB.2.11.1606061448010.28031@nanos Oh, interesting. Definitely a better solution than this custom check.
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index 58b5baca670c..12c5062aeb92 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -342,7 +342,7 @@ static int clk_main_probe_frequency(struct regmap *regmap) regmap_read(regmap, AT91_CKGR_MCFR, &mcfr); if (mcfr & AT91_PMC_MAINRDY) return 0; - usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); + udelay(MAINF_LOOP_MIN_WAIT); } while (time_before(prep_time, timeout)); return -ETIMEDOUT; diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index 61090b1146cf..612e893ce994 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c @@ -76,7 +76,7 @@ static int clk_slow_osc_prepare(struct clk_hw *hw) writel(tmp | AT91_SCKC_OSC32EN, sckcr); - usleep_range(osc->startup_usec, osc->startup_usec + 1); + udelay(osc->startup_usec); return 0; } @@ -195,7 +195,7 @@ static int clk_slow_rc_osc_prepare(struct clk_hw *hw) writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr); - usleep_range(osc->startup_usec, osc->startup_usec + 1); + udelay(osc->startup_usec); return 0; } @@ -304,7 +304,7 @@ static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) writel(tmp, sckcr); - usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); + udelay(SLOWCK_SW_TIME_USEC); return 0; }