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

Cédric Le Goater clg at kaod.org
Tue Nov 2 02:35:46 PDT 2021


On 11/2/21 00:37, 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>

LGTM,

Reviewed-by: Cédric Le Goater <clg at kaod.org>

Thanks,

C.

> ---
>   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;
>   }
>   
> 




More information about the linux-arm-kernel mailing list