@@ -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");
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(+)