Patch "irqchip/imx-irqsteer: Handle runtime power management correctly" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    irqchip/imx-irqsteer: Handle runtime power management correctly

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     irqchip-imx-irqsteer-handle-runtime-power-management.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit c4dd509c3ae6d48d4cceda130d567c9424531e72
Author: Shenwei Wang <shenwei.wang@xxxxxxx>
Date:   Wed Jul 3 11:32:50 2024 -0500

    irqchip/imx-irqsteer: Handle runtime power management correctly
    
    [ Upstream commit 33b1c47d1fc0b5f06a393bb915db85baacba18ea ]
    
    The power domain is automatically activated from clk_prepare(). However, on
    certain platforms like i.MX8QM and i.MX8QXP, the power-on handling invokes
    sleeping functions, which triggers the 'scheduling while atomic' bug in the
    context switch path during device probing:
    
     BUG: scheduling while atomic: kworker/u13:1/48/0x00000002
     Call trace:
      __schedule_bug+0x54/0x6c
      __schedule+0x7f0/0xa94
      schedule+0x5c/0xc4
      schedule_preempt_disabled+0x24/0x40
      __mutex_lock.constprop.0+0x2c0/0x540
      __mutex_lock_slowpath+0x14/0x20
      mutex_lock+0x48/0x54
      clk_prepare_lock+0x44/0xa0
      clk_prepare+0x20/0x44
      imx_irqsteer_resume+0x28/0xe0
      pm_generic_runtime_resume+0x2c/0x44
      __genpd_runtime_resume+0x30/0x80
      genpd_runtime_resume+0xc8/0x2c0
      __rpm_callback+0x48/0x1d8
      rpm_callback+0x6c/0x78
      rpm_resume+0x490/0x6b4
      __pm_runtime_resume+0x50/0x94
      irq_chip_pm_get+0x2c/0xa0
      __irq_do_set_handler+0x178/0x24c
      irq_set_chained_handler_and_data+0x60/0xa4
      mxc_gpio_probe+0x160/0x4b0
    
    Cure this by implementing the irq_bus_lock/sync_unlock() interrupt chip
    callbacks and handle power management in them as they are invoked from
    non-atomic context.
    
    [ tglx: Rewrote change log, added Fixes tag ]
    
    Fixes: 0136afa08967 ("irqchip: Add driver for imx-irqsteer controller")
    Signed-off-by: Shenwei Wang <shenwei.wang@xxxxxxx>
    Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
    Cc: stable@xxxxxxxxxxxxxxx
    Link: https://lore.kernel.org/r/20240703163250.47887-1-shenwei.wang@xxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c
index 96230a04ec238..44ce85c27f57a 100644
--- a/drivers/irqchip/irq-imx-irqsteer.c
+++ b/drivers/irqchip/irq-imx-irqsteer.c
@@ -35,6 +35,7 @@ struct irqsteer_data {
 	int			channel;
 	struct irq_domain	*domain;
 	u32			*saved_reg;
+	struct device		*dev;
 };
 
 static int imx_irqsteer_get_reg_index(struct irqsteer_data *data,
@@ -71,10 +72,26 @@ static void imx_irqsteer_irq_mask(struct irq_data *d)
 	raw_spin_unlock_irqrestore(&data->lock, flags);
 }
 
+static void imx_irqsteer_irq_bus_lock(struct irq_data *d)
+{
+	struct irqsteer_data *data = d->chip_data;
+
+	pm_runtime_get_sync(data->dev);
+}
+
+static void imx_irqsteer_irq_bus_sync_unlock(struct irq_data *d)
+{
+	struct irqsteer_data *data = d->chip_data;
+
+	pm_runtime_put_autosuspend(data->dev);
+}
+
 static const struct irq_chip imx_irqsteer_irq_chip = {
-	.name		= "irqsteer",
-	.irq_mask	= imx_irqsteer_irq_mask,
-	.irq_unmask	= imx_irqsteer_irq_unmask,
+	.name			= "irqsteer",
+	.irq_mask		= imx_irqsteer_irq_mask,
+	.irq_unmask		= imx_irqsteer_irq_unmask,
+	.irq_bus_lock		= imx_irqsteer_irq_bus_lock,
+	.irq_bus_sync_unlock	= imx_irqsteer_irq_bus_sync_unlock,
 };
 
 static int imx_irqsteer_irq_map(struct irq_domain *h, unsigned int irq,
@@ -149,6 +166,7 @@ static int imx_irqsteer_probe(struct platform_device *pdev)
 	if (!data)
 		return -ENOMEM;
 
+	data->dev = &pdev->dev;
 	data->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->regs)) {
 		dev_err(&pdev->dev, "failed to initialize reg\n");




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux