[PATCH linux dev-4.13] clk: aspeed: Update to upstream to avoid schedule()ing from atomic context
Joel Stanley
joel at jms.id.au
Tue Feb 20 16:34:04 AEDT 2018
On Tue, Feb 20, 2018 at 2:33 PM, Andrew Jeffery <andrew at aj.id.au> wrote:
> The patch is generated against v4.16-rc2. Critically, it fixes a bug where
> we schedule() from an atomic context:
Thanks for pointing this out. I chose to backport the fixes that were
upstream and make the s/msleep/mdelay/ fix in it's own patch.
Cheers,
Joel
>
> [ 1.570455] BUG: scheduling while atomic: swapper/1/0x00000003
> [ 1.576541] 4 locks held by swapper/1:
> [ 1.580326] #0: (&dev->mutex){......}, at: [<802b7ac0>] __driver_attach+0x64/0x10c
> [ 1.588177] #1: (&dev->mutex){......}, at: [<802b7ad0>] __driver_attach+0x74/0x10c
> [ 1.596002] #2: (enable_lock){......}, at: [<80286f68>] clk_enable_lock+0x28/0x130
> [ 1.603839] #3: (aspeed_clk_lock){......}, at: [<8028ff30>] aspeed_clk_enable+0x38/0xf4
> [ 1.612096] irq event stamp: 157268
> [ 1.615630] hardirqs last enabled at (157267): [<804c10a0>] _raw_spin_unlock_irqrestore+0x40/0x6c
> [ 1.624621] hardirqs last disabled at (157268): [<80286f60>] clk_enable_lock+0x20/0x130
> [ 1.632670] softirqs last enabled at (156064): [<80116160>] bdi_register_va+0xf4/0x240
> [ 1.640713] softirqs last disabled at (156062): [<80116144>] bdi_register_va+0xd8/0x240
> [ 1.648744] CPU: 0 PID: 1 Comm: swapper Not tainted 4.13.16-00190-g78a200cb21ab #2393
> [ 1.656583] Hardware name: Generic DT based system
> [ 1.661438] [<8001141c>] (unwind_backtrace) from [<8000e87c>] (show_stack+0x20/0x24)
> [ 1.669235] [<8000e87c>] (show_stack) from [<804a65ec>] (dump_stack+0x20/0x28)
> [ 1.676527] [<804a65ec>] (dump_stack) from [<80047680>] (__schedule_bug+0x70/0xa4)
> [ 1.684150] [<80047680>] (__schedule_bug) from [<804bb8e0>] (__schedule+0x648/0x8a4)
> [ 1.691933] [<804bb8e0>] (__schedule) from [<804bbbec>] (schedule+0x5c/0xcc)
> [ 1.699025] [<804bbbec>] (schedule) from [<804bffec>] (schedule_timeout+0x220/0x498)
> [ 1.706819] [<804bffec>] (schedule_timeout) from [<80073af0>] (msleep+0x48/0x58)
> [ 1.714264] [<80073af0>] (msleep) from [<8028ffac>] (aspeed_clk_enable+0xb4/0xf4)
> [ 1.721796] [<8028ffac>] (aspeed_clk_enable) from [<80288654>] (clk_core_enable+0xac/0x248)
> [ 1.730189] [<80288654>] (clk_core_enable) from [<80288818>] (clk_core_enable_lock+0x28/0x3c)
> [ 1.738760] [<80288818>] (clk_core_enable_lock) from [<8028aab4>] (clk_enable+0x24/0x28)
> [ 1.746907] [<8028aab4>] (clk_enable) from [<802df144>] (aspeed_lpc_ctrl_probe+0x148/0x25c)
> [ 1.755315] [<802df144>] (aspeed_lpc_ctrl_probe) from [<802b97c8>] (platform_drv_probe+0x60/0xbc)
> [ 1.764230] [<802b97c8>] (platform_drv_probe) from [<802b78f0>] (driver_probe_device+0x2e4/0x450)
> [ 1.773135] [<802b78f0>] (driver_probe_device) from [<802b7b28>] (__driver_attach+0xcc/0x10c)
> [ 1.781699] [<802b7b28>] (__driver_attach) from [<802b58a4>] (bus_for_each_dev+0x5c/0xac)
> [ 1.789915] [<802b58a4>] (bus_for_each_dev) from [<802b7d04>] (driver_attach+0x28/0x30)
> [ 1.797958] [<802b7d04>] (driver_attach) from [<802b62dc>] (bus_add_driver+0x194/0x254)
> [ 1.806001] [<802b62dc>] (bus_add_driver) from [<802b8b54>] (driver_register+0x88/0x104)
> [ 1.814133] [<802b8b54>] (driver_register) from [<802ba42c>] (__platform_driver_register+0x3c/0x50)
> [ 1.823234] [<802ba42c>] (__platform_driver_register) from [<8068a814>] (aspeed_lpc_ctrl_driver_init+0x20/0x28)
> [ 1.833381] [<8068a814>] (aspeed_lpc_ctrl_driver_init) from [<80669f1c>] (do_one_initcall+0xb0/0x170)
> [ 1.842651] [<80669f1c>] (do_one_initcall) from [<8066a0f4>] (kernel_init_freeable+0x118/0x1d0)
> [ 1.851406] [<8066a0f4>] (kernel_init_freeable) from [<804b9b94>] (kernel_init+0x18/0x104)
> [ 1.859717] [<804b9b94>] (kernel_init) from [<8000a868>] (ret_from_fork+0x14/0x2c)
>
> Signed-off-by: Andrew Jeffery <andrew at aj.id.au>
> ---
> drivers/clk/clk-aspeed.c | 33 ++++++++++++++++-----------------
> 1 file changed, 16 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c
> index 4a0d2649d907..9f7f931d6b2f 100644
> --- a/drivers/clk/clk-aspeed.c
> +++ b/drivers/clk/clk-aspeed.c
> @@ -1,13 +1,4 @@
> -/*
> - * Copyright 2017 IBM Corporation
> - *
> - * Joel Stanley <joel at jms.id.au>
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License
> - * as published by the Free Software Foundation; either version
> - * 2 of the License, or (at your option) any later version.
> - */
> +// SPDX-License-Identifier: GPL-2.0+
>
> #define pr_fmt(fmt) "clk-aspeed: " fmt
>
> @@ -220,6 +211,7 @@ static int aspeed_clk_enable(struct clk_hw *hw)
> unsigned long flags;
> u32 clk = BIT(gate->clock_idx);
> u32 rst = BIT(gate->reset_idx);
> + u32 enval;
>
> spin_lock_irqsave(gate->lock, flags);
>
> @@ -232,12 +224,12 @@ static int aspeed_clk_enable(struct clk_hw *hw)
> }
>
> /* Enable clock */
> - regmap_update_bits(gate->map, ASPEED_CLK_STOP_CTRL, clk, 0);
> + 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) {
> - /* Delay 10ms */
> - /* TODO: can we sleep here? */
> - msleep(10);
> + /* 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);
> @@ -253,10 +245,12 @@ static void aspeed_clk_disable(struct clk_hw *hw)
> struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
> unsigned long flags;
> u32 clk = BIT(gate->clock_idx);
> + u32 enval;
>
> spin_lock_irqsave(gate->lock, flags);
>
> - regmap_update_bits(gate->map, ASPEED_CLK_STOP_CTRL, clk, clk);
> + enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? clk : 0;
> + regmap_update_bits(gate->map, ASPEED_CLK_STOP_CTRL, clk, enval);
>
> spin_unlock_irqrestore(gate->lock, flags);
> }
> @@ -488,7 +482,12 @@ static int aspeed_clk_probe(struct platform_device *pdev)
>
> for (i = 0; i < ARRAY_SIZE(aspeed_gates); i++) {
> const struct aspeed_gate_data *gd = &aspeed_gates[i];
> + u32 gate_flags;
>
> + /* Special case: the USB port 1 clock (bit 14) is always
> + * working the opposite way from the other ones.
> + */
> + gate_flags = (gd->clock_idx == 14) ? 0 : CLK_GATE_SET_TO_DISABLE;
> hw = aspeed_clk_hw_register_gate(dev,
> gd->name,
> gd->parent_name,
> @@ -496,7 +495,7 @@ static int aspeed_clk_probe(struct platform_device *pdev)
> map,
> gd->clock_idx,
> gd->reset_idx,
> - CLK_GATE_SET_TO_DISABLE,
> + gate_flags,
> &aspeed_clk_lock);
> if (IS_ERR(hw))
> return PTR_ERR(hw);
> @@ -619,7 +618,7 @@ static void __init aspeed_cc_init(struct device_node *np)
> int i;
>
> scu_base = of_iomap(np, 0);
> - if (IS_ERR(scu_base))
> + if (!scu_base)
> return;
>
> aspeed_clk_data = kzalloc(sizeof(*aspeed_clk_data) +
> --
> 2.14.1
>
More information about the openbmc
mailing list