From b4b1963ffdb89d62498f6c4b8b161559ceda9026 Mon Sep 17 00:00:00 2001 From: litong20 Date: Mon, 10 May 2021 20:17:06 +0800 Subject: [PATCH] touch:sleep in atomic context disable_irq will sleep while atomic context, switch mutex_lock to fix it. <4>[ 109.768530] Call trace: <4>[ 109.768533] __schedule_bug+0x9c/0xac <4>[ 109.768537] __schedule+0x94/0x884 <4>[ 109.768540] schedule+0x80/0xb0 <4>[ 109.768544] synchronize_irq+0x7c/0xb8 <4>[ 109.768547] disable_irq+0x70/0x9c <4>[ 109.768554] fts_disableInterrupt+0x60/0xcc [stmicro_mmi] <4>[ 109.768560] fts_mmi_drv_irq+0x94/0xf8 [stmicro_mmi] <4>[ 109.768567] ts_mmi_panel_off+0x1cc/0x274 [touchscreen_mmi] <4>[ 109.768571] ts_mmi_panel_cb+0x16c/0x4e0 [touchscreen_mmi] <4>[ 109.768575] blocking_notifier_call_chain+0x70/0xe4 <4>[ 109.768579] drm_panel_notifier_call_chain+0x14/0x20 <4>[ 109.768684] _sde_kms_drm_check_dpms+0x214/0x264 [msm_drm] <4>[ 109.768780] sde_kms_prepare_commit+0x250/0x3c4 [msm_drm] <4>[ 109.768866] complete_commit+0x74/0x264 [msm_drm] <4>[ 109.768952] _msm_drm_commit_work_cb+0x128/0x22c [msm_drm] <4>[ 109.768957] kthread_worker_fn+0x110/0x1ac <4>[ 109.768960] kthread+0x160/0x170 <4>[ 109.768964] ret_from_fork+0x10/0x18 <0>[ 109.768968] Code: 9401195f 90013928 b9488d08 35000048 (d4210000) <4>[ 109.768971] ---[ end trace 94703c960d9e3dae ]--- <0>[ 109.770403] Kernel panic - not syncing: Fatal exception Change-Id: Ib4f9fa13604f255b7a5432a48b66ef7707124017 Reviewed-on: https://gerrit.mot.com/1944265 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Jianqi Yang Submit-Approved: Jira Key --- drivers/input/touchscreen/stmicro_mmi/fts.c | 4 --- .../touchscreen/stmicro_mmi/fts_lib/ftsCore.c | 29 ++++++++----------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/input/touchscreen/stmicro_mmi/fts.c b/drivers/input/touchscreen/stmicro_mmi/fts.c index 32befe070a0e..3f19910a37b4 100644 --- a/drivers/input/touchscreen/stmicro_mmi/fts.c +++ b/drivers/input/touchscreen/stmicro_mmi/fts.c @@ -123,8 +123,6 @@ static u8 key_mask = 0x00; /* /< store the last update of the key mask #endif -extern spinlock_t fts_int; - static int fts_mode_handler(struct fts_ts_info *info, int force); @@ -4248,8 +4246,6 @@ static int fts_probe(struct spi_device *client) mutex_init(&gestureMask_mutex); #endif - spin_lock_init(&fts_int); - /* register the multi-touch input device */ error = input_register_device(info->input_dev); if (error) { diff --git a/drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCore.c b/drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCore.c index b39d3fbeafc2..fd64be681e0b 100644 --- a/drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCore.c +++ b/drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCore.c @@ -18,6 +18,7 @@ * \brief Contains the implementation of the Core functions */ +#include #include #include #include @@ -52,7 +53,7 @@ static int system_reseted_down; /* /< flag checked during suspend to static int disable_irq_count = 1; /* /< count the number of call to * disable_irq, start with 1 because at * the boot IRQ are already disabled */ -spinlock_t fts_int; /* /< spinlock to controll the access to the +DEFINE_MUTEX(fts_int_mlock); /* /< mutex lock to controll the access to the * disable_irq_counter */ @@ -881,24 +882,18 @@ int writeConfig(u16 offset, u8 *data, int len) */ int fts_disableInterrupt(void) { -#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE - unsigned long flag; -#endif - if (getClient() != NULL) { -#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE - spin_lock_irqsave(&fts_int, flag); -#endif + mutex_lock(&fts_int_mlock); if (disable_irq_count == 0) { logError(0, "%s Executing Disable...\n", tag); + disable_irq(getClient()->irq); + disable_irq_count++; } /* disable_irq is re-entrant so it is required to keep track * of the number of calls of this when reenabling */ -#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE - spin_unlock_irqrestore(&fts_int, flag); -#endif + mutex_unlock(&fts_int_mlock); return OK; } else { logError(1, "%s %s: Impossible get client irq... ERROR %08X\n", @@ -915,7 +910,7 @@ int fts_disableInterrupt(void) int fts_disableInterruptNoSync(void) { if (getClient() != NULL) { - spin_lock_irq(&fts_int); + mutex_lock(&fts_int_mlock); if (disable_irq_count == 0) { logError(0, "%s Executing DisableNoSync...\n", tag); disable_irq_nosync(getClient()->irq); @@ -923,7 +918,7 @@ int fts_disableInterruptNoSync(void) } /* disable_irq is re-entrant so it is required to keep track * of the number of calls of this when reenabling */ - spin_unlock(&fts_int); + mutex_unlock(&fts_int_mlock); return OK; } else { logError(1, "%s %s: Impossible get client irq... ERROR %08X\n", @@ -954,18 +949,18 @@ int fts_is_InterruptEnabled(void) */ int fts_enableInterrupt(void) { - unsigned long flag; - if (getClient() != NULL) { - spin_lock_irqsave(&fts_int, flag); + mutex_lock(&fts_int_mlock); while (disable_irq_count > 0) { /* loop N times according on the pending number of * disable_irq to truly re-enable the int */ + logError(0, "%s Executing Enable...\n", tag); enable_irq(getClient()->irq); + disable_irq_count--; } - spin_unlock_irqrestore(&fts_int, flag); + mutex_unlock(&fts_int_mlock); return OK; } else { logError(1, "%s %s: Impossible get client irq... ERROR %08X\n",