[PATCH -next 2/4] ipmi: bt: add clock control logic
Joel Stanley
joel at jms.id.au
Tue Nov 2 10:32:25 AEDT 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-aspeed
mailing list