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 <yangj@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
litong20 2021-05-10 20:17:06 +08:00 • committed by Jichao Zou
commit b4b1963ffd
2 changed files with 12 additions and 21 deletions

View file

@ -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) {

View file

@ -18,6 +18,7 @@
* \brief Contains the implementation of the Core functions
*/
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/slab.h>
@ -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",