From: Yakir Yang Date: Fri, 22 Apr 2016 02:47:39 +0000 (+0800) Subject: input: touchscreen: fix kernel crash in fb_notifier_callback function X-Git-Tag: firefly_0821_release~2761 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c1c93565ffbd707f29b77e0589109f7a60e29801;p=firefly-linux-kernel-4.4.55.git input: touchscreen: fix kernel crash in fb_notifier_callback function fb_event would only carry the data number in some special notify action, other actions wouldn't carry an valid data number, and in this case kernel would crash, logs like: [ 4.129846] Unable to handle kernel paging request at virtual address 200000000000 ...... [ 4.164618] Hardware name: Rockchip RK3399 Evaluation Board v1 (Chrome OS) (DT) [ 4.184624] PC is at fb_notifier_callback+0x28/0xac [ 4.189497] LR is at notifier_call_chain+0x74/0xb4 [ 4.194279] pc : [] lr : [] pstate: 20000045 ...... [ 5.703780] [] fb_notifier_callback+0x28/0xac [ 5.709690] [] notifier_call_chain+0x74/0xb4 [ 5.715504] [] __blocking_notifier_call_chain+0x48/0x64 [ 5.722280] [] blocking_notifier_call_chain+0x14/0x1c [ 5.728885] [] fb_notifier_call_chain+0x20/0x28 [ 5.734969] [] register_framebuffer+0x218/0x250 [ 5.741054] [] drm_fb_helper_initial_config+0x2f8/0x374 [ 5.747832] [] rockchip_drm_fbdev_init+0xa8/0xe8 [ 5.754002] [] rockchip_drm_load+0x1e4/0x25c Change-Id: I3314315a31bbab43489fca85dabc4c6511fc9dee Signed-off-by: Yakir Yang --- diff --git a/drivers/input/touchscreen/tp_suspend.h b/drivers/input/touchscreen/tp_suspend.h index bf23e868e770..b900ee530a2a 100644 --- a/drivers/input/touchscreen/tp_suspend.h +++ b/drivers/input/touchscreen/tp_suspend.h @@ -25,7 +25,7 @@ static inline int fb_notifier_callback(struct notifier_block *self, { struct tp_device *tp; struct fb_event *event = data; - int blank_mode = *((int *)event->data); + int blank_mode; int ret = 0; tp = container_of(self, struct tp_device, fb_notif); @@ -34,24 +34,23 @@ static inline int fb_notifier_callback(struct notifier_block *self, mutex_lock(&tp->ops_lock); - if (action == FB_EARLY_EVENT_BLANK) { - switch (blank_mode) { - case FB_BLANK_UNBLANK: - break; - default: + switch (action) { + case FB_EARLY_EVENT_BLANK: + blank_mode = *((int *)event->data); + if (blank_mode != FB_BLANK_UNBLANK) ret = tp->tp_suspend(tp); - break; - } - } - else if (action == FB_EVENT_BLANK) { - switch (blank_mode) { - case FB_BLANK_UNBLANK: + break; + + case FB_EVENT_BLANK: + blank_mode = *((int *)event->data); + if (blank_mode == FB_BLANK_UNBLANK) tp->tp_resume(tp); - break; - default: - break; - } + break; + + default: + break; } + mutex_unlock(&tp->ops_lock); if (ret < 0)