[PATCH linux dev-4.13] clk: aspeed: Prevent reset and enable if clock is already enabled
Joel Stanley
joel at jms.id.au
Wed Mar 7 14:01:47 AEDT 2018
Hi Eddie,
On Wed, Mar 7, 2018 at 1:03 PM, Lei YU <mine260309 at gmail.com> wrote:
> With the patch, the hang issue in ISTEPS (openbmc/openbmc#2948) is gone, in both
> cold and warm boot.
>
> Tested-by: Lei YU <mine260309 at gmail.com>
Please send this upstream after addressing Lei's concerns. Can you
also add a Fixes tag?
Cheers,
Joel
>
> On Wed, Mar 7, 2018 at 4:24 AM, Eddie James <eajames at linux.vnet.ibm.com> wrote:
>> Systems are seeing some issues where the LPC clock gets into a bad state
>> when the ASPEED clock driver resets and enables the clock during
>> startup. The LPC clock (according to AST2500 spec) is enabled by default,
>> so resetting and re-enabling is not desired. Add a simple check before the
>> enable procedure to see if the clock is already enabled.
>>
>> Signed-off-by: Eddie James <eajames at linux.vnet.ibm.com>
>> ---
>> drivers/clk/clk-aspeed.c | 42 ++++++++++++++++++++++++------------------
>> 1 file changed, 24 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c
>> index b67ba14..3d12f7a 100644
>> --- a/drivers/clk/clk-aspeed.c
>> +++ b/drivers/clk/clk-aspeed.c
>> @@ -221,27 +221,33 @@ static int aspeed_clk_enable(struct clk_hw *hw)
>> u32 clk = BIT(gate->clock_idx);
>> u32 rst = BIT(gate->reset_idx);
>> u32 enval;
>> + u32 reg;
>>
>
> I would prefer to call aspeed_clk_is_enabled() to check if it's
> enabled and return
> before spin_lock_irqsave().
>
>> spin_lock_irqsave(gate->lock, flags);
>>
>> - if (gate->reset_idx >= 0) {
>> - /* Put IP in reset */
>> - regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, rst);
>> -
>> - /* Delay 100us */
>> - udelay(100);
>> - }
>> -
>> - /* Enable clock */
>> - enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
>> - regmap_update_bits(gate->map, ASPEED_CLK_STOP_CTRL, clk, enval);
>> -
>> - if (gate->reset_idx >= 0) {
>> - /* A delay of 10ms is specified by the ASPEED docs */
>> - mdelay(10);
>> -
>> - /* Take IP out of reset */
>> - regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, 0);
>> + /* Only reset/enable/unreset if clock isn't already enabled */
>> + regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, ®);
>> + if (reg & clk) {
>> + if (gate->reset_idx >= 0) {
>> + /* Put IP in reset */
>> + regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst,
>> + rst);
>> +
>> + /* Delay 100us */
>> + udelay(100);
>> + }
>> +
>> + /* Enable clock */
>> + enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
>> + regmap_update_bits(gate->map, ASPEED_CLK_STOP_CTRL, clk, enval);
>> +
>> + if (gate->reset_idx >= 0) {
>> + /* A delay of 10ms is specified by the ASPEED docs */
>> + mdelay(10);
>> +
>> + /* Take IP out of reset */
>> + regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, 0);
>
> Remove the extra blanks or put it in next line.
>
>> + }
>> }
>>
>> spin_unlock_irqrestore(gate->lock, flags);
>> --
>> 1.8.3.1
>>
More information about the openbmc
mailing list