[PATCH -next 2/4] ipmi: bt: add clock control logic

Joel Stanley joel at jms.id.au
Mon Nov 1 16:32:25 PDT 2021


On Mon, 1 Nov 2021 at 23:18, <jae.hyun.yoo at intel.com> wrote:
>
> From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>
> If LPC BT driver is registered ahead of lpc-ctrl module, LPC BT
> hardware block will be enabled without heart beating of LCLK until
> lpc-ctrl enables the LCLK. This issue causes improper handling on
> host interrupts when the host sends interrupts in that time frame.
> Then kernel eventually forcibly disables the interrupt with
> dumping stack and printing a 'nobody cared this irq' message out.
>
> To prevent this issue, all LPC sub drivers should enable LCLK
> individually so this patch adds clock control logic into the LPC
> BT driver.
>
> Fixes: 54f9c4d0778b ("ipmi: add an Aspeed BT IPMI BMC driver")
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>

Reviewed-by: Joel Stanley <joel at jms.id.au>

> ---
>  drivers/char/ipmi/bt-bmc.c | 24 +++++++++++++++++++++++-
>  1 file changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> index 7450904e330a..a20f92cc7b18 100644
> --- a/drivers/char/ipmi/bt-bmc.c
> +++ b/drivers/char/ipmi/bt-bmc.c
> @@ -5,6 +5,7 @@
>
>  #include <linux/atomic.h>
>  #include <linux/bt-bmc.h>
> +#include <linux/clk.h>
>  #include <linux/errno.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
> @@ -62,6 +63,7 @@ struct bt_bmc {
>         wait_queue_head_t       queue;
>         struct timer_list       poll_timer;
>         struct mutex            mutex;
> +       struct clk              *clk;
>  };
>
>  static atomic_t open_count = ATOMIC_INIT(0);
> @@ -423,6 +425,19 @@ static int bt_bmc_probe(struct platform_device *pdev)
>         if (IS_ERR(bt_bmc->base))
>                 return PTR_ERR(bt_bmc->base);
>
> +       bt_bmc->clk = devm_clk_get(dev, NULL);
> +       if (IS_ERR(bt_bmc->clk)) {
> +               rc = PTR_ERR(bt_bmc->clk);
> +               if (rc != -EPROBE_DEFER)
> +                       dev_err(dev, "Unable to get clock\n");
> +               return rc;
> +       }
> +       rc = clk_prepare_enable(bt_bmc->clk);
> +       if (rc) {
> +               dev_err(dev, "Unable to enable clock\n");
> +               return rc;
> +       }
> +
>         mutex_init(&bt_bmc->mutex);
>         init_waitqueue_head(&bt_bmc->queue);
>
> @@ -433,7 +448,7 @@ static int bt_bmc_probe(struct platform_device *pdev)
>         rc = misc_register(&bt_bmc->miscdev);
>         if (rc) {
>                 dev_err(dev, "Unable to register misc device\n");
> -               return rc;
> +               goto err;
>         }
>
>         bt_bmc_config_irq(bt_bmc, pdev);
> @@ -457,6 +472,11 @@ static int bt_bmc_probe(struct platform_device *pdev)
>         clr_b_busy(bt_bmc);
>
>         return 0;
> +
> +err:
> +       clk_disable_unprepare(bt_bmc->clk);
> +
> +       return rc;
>  }
>
>  static int bt_bmc_remove(struct platform_device *pdev)
> @@ -466,6 +486,8 @@ static int bt_bmc_remove(struct platform_device *pdev)
>         misc_deregister(&bt_bmc->miscdev);
>         if (bt_bmc->irq < 0)
>                 del_timer_sync(&bt_bmc->poll_timer);
> +       clk_disable_unprepare(bt_bmc->clk);
> +
>         return 0;
>  }
>
> --
> 2.25.1
>



More information about the linux-arm-kernel mailing list