* [PATCH] irqchip/imx-irqsteer: Add irq_bus_lock/sync_unlock handlers
@ 2024-07-03 16:32 Shenwei Wang
2024-07-11 15:16 ` [tip: irq/core] irqchip/imx-irqsteer: Handle runtime power management correctly tip-bot2 for Shenwei Wang
2024-07-15 13:20 ` tip-bot2 for Shenwei Wang
0 siblings, 2 replies; 3+ messages in thread
From: Shenwei Wang @ 2024-07-03 16:32 UTC (permalink / raw)
To: Thomas Gleixner, Shawn Guo, Sascha Hauer
Cc: Pengutronix Kernel Team, Fabio Estevam, linux-kernel, imx,
linux-imx, Shenwei Wang
Add irq_bus_lock/sync_unlock handlers.
Without these handlers, the power domain is automatically activated during
clk_prepare. However, on certain platforms like i.MX8QM and i.MX8QXP, the
power-on phase may involve sleep function calls, which can lead to random
system dumps during driver probes at system boot.
By adding these handlers, the actual power-on actions are moved to occur
before clk_prepare, thus resolving the system dump issue.
The following is the example of system dump on i.MX8QM MEK.
[ 3.135799] BUG: scheduling while atomic: kworker/u13:1/48/0x00000002
[ 3.142270] Modules linked in:
[ 3.145349] CPU: 0 PID: 48 Comm: kworker/u13:1 Not tainted 6.6.3-lts-next-g5a913c7fc95d #1
[ 3.153616] Hardware name: Freescale i.MX8QM MEK (DT)
[ 3.158678] Workqueue: events_unbound deferred_probe_work_func
[ 3.164529] Call trace:
[ 3.166981] dump_backtrace+0x90/0xe8
[ 3.170652] show_stack+0x18/0x24
[ 3.173971] dump_stack_lvl+0x48/0x60
[ 3.177644] dump_stack+0x18/0x24
[ 3.180964] __schedule_bug+0x54/0x6c
[ 3.184628] __schedule+0x7f0/0xa94
[ 3.188121] schedule+0x5c/0xc4
[ 3.191266] schedule_preempt_disabled+0x24/0x40
[ 3.195887] __mutex_lock.constprop.0+0x2c0/0x540
[ 3.200596] __mutex_lock_slowpath+0x14/0x20
[ 3.204870] mutex_lock+0x48/0x54
[ 3.208189] clk_prepare_lock+0x44/0xa0
[ 3.212040] clk_prepare+0x20/0x44
[ 3.215452] imx_irqsteer_resume+0x28/0xe0
[ 3.219552] pm_generic_runtime_resume+0x2c/0x44
[ 3.224174] __genpd_runtime_resume+0x30/0x80
[ 3.228535] genpd_runtime_resume+0xc8/0x2c0
[ 3.232809] __rpm_callback+0x48/0x1d8
[ 3.236562] rpm_callback+0x6c/0x78
[ 3.240055] rpm_resume+0x490/0x6b4
[ 3.243549] __pm_runtime_resume+0x50/0x94
[ 3.247648] irq_chip_pm_get+0x2c/0xa0
[ 3.251401] __irq_do_set_handler+0x178/0x24c
[ 3.255762] irq_set_chained_handler_and_data+0x60/0xa4
[ 3.260992] mxc_gpio_probe+0x160/0x4b0
[ 3.264840] platform_probe+0x68/0xc8
[ 3.268506] really_probe+0x148/0x2b0
[ 3.272172] __driver_probe_device+0x78/0x12c
[ 3.276536] driver_probe_device+0xd8/0x15c
[ 3.280721] __device_attach_driver+0xb8/0x134
[ 3.285169] bus_for_each_drv+0x88/0xe8
[ 3.289009] __device_attach+0xa0/0x190
[ 3.292849] device_initial_probe+0x14/0x20
[ 3.297036] bus_probe_device+0xac/0xb0
[ 3.300876] deferred_probe_work_func+0x80/0xb8
[ 3.305411] process_one_work+0x138/0x248
[ 3.309427] worker_thread+0x320/0x438
[ 3.313177] kthread+0x110/0x114
[ 3.316409] ret_from_fork+0x10/0x20
Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
---
drivers/irqchip/irq-imx-irqsteer.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c
index 20cf7a9e9ece..f81e4ff3aec3 100644
--- a/drivers/irqchip/irq-imx-irqsteer.c
+++ b/drivers/irqchip/irq-imx-irqsteer.c
@@ -36,6 +36,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,
@@ -72,10 +73,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,
+ .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,
@@ -150,6 +167,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");
--
2.34.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [tip: irq/core] irqchip/imx-irqsteer: Handle runtime power management correctly
2024-07-03 16:32 [PATCH] irqchip/imx-irqsteer: Add irq_bus_lock/sync_unlock handlers Shenwei Wang
@ 2024-07-11 15:16 ` tip-bot2 for Shenwei Wang
2024-07-15 13:20 ` tip-bot2 for Shenwei Wang
1 sibling, 0 replies; 3+ messages in thread
From: tip-bot2 for Shenwei Wang @ 2024-07-11 15:16 UTC (permalink / raw)
To: linux-tip-commits
Cc: Shenwei Wang, Thomas Gleixner, stable, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: cd0406fab8d4a16ec4f617c0a4b405bf70543b5b
Gitweb: https://git.kernel.org/tip/cd0406fab8d4a16ec4f617c0a4b405bf70543b5b
Author: Shenwei Wang <shenwei.wang@nxp.com>
AuthorDate: Wed, 03 Jul 2024 11:32:50 -05:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 11 Jul 2024 17:06:02 +02:00
irqchip/imx-irqsteer: Handle runtime power management correctly
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@nxp.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20240703163250.47887-1-shenwei.wang@nxp.com
---
drivers/irqchip/irq-imx-irqsteer.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c
index 20cf7a9..75a0e98 100644
--- a/drivers/irqchip/irq-imx-irqsteer.c
+++ b/drivers/irqchip/irq-imx-irqsteer.c
@@ -36,6 +36,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,
@@ -72,10 +73,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,
@@ -150,6 +167,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");
^ permalink raw reply [flat|nested] 3+ messages in thread
* [tip: irq/core] irqchip/imx-irqsteer: Handle runtime power management correctly
2024-07-03 16:32 [PATCH] irqchip/imx-irqsteer: Add irq_bus_lock/sync_unlock handlers Shenwei Wang
2024-07-11 15:16 ` [tip: irq/core] irqchip/imx-irqsteer: Handle runtime power management correctly tip-bot2 for Shenwei Wang
@ 2024-07-15 13:20 ` tip-bot2 for Shenwei Wang
1 sibling, 0 replies; 3+ messages in thread
From: tip-bot2 for Shenwei Wang @ 2024-07-15 13:20 UTC (permalink / raw)
To: linux-tip-commits
Cc: Shenwei Wang, Thomas Gleixner, stable, x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 33b1c47d1fc0b5f06a393bb915db85baacba18ea
Gitweb: https://git.kernel.org/tip/33b1c47d1fc0b5f06a393bb915db85baacba18ea
Author: Shenwei Wang <shenwei.wang@nxp.com>
AuthorDate: Wed, 03 Jul 2024 11:32:50 -05:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 15 Jul 2024 15:13:56 +02:00
irqchip/imx-irqsteer: Handle runtime power management correctly
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@nxp.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20240703163250.47887-1-shenwei.wang@nxp.com
---
drivers/irqchip/irq-imx-irqsteer.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c
index 20cf7a9..75a0e98 100644
--- a/drivers/irqchip/irq-imx-irqsteer.c
+++ b/drivers/irqchip/irq-imx-irqsteer.c
@@ -36,6 +36,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,
@@ -72,10 +73,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,
@@ -150,6 +167,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");
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-07-15 13:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-07-03 16:32 [PATCH] irqchip/imx-irqsteer: Add irq_bus_lock/sync_unlock handlers Shenwei Wang
2024-07-11 15:16 ` [tip: irq/core] irqchip/imx-irqsteer: Handle runtime power management correctly tip-bot2 for Shenwei Wang
2024-07-15 13:20 ` tip-bot2 for Shenwei Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®