mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
Cypfg: dlkm: Improve gcore_mmi driver
- Request irq change to thread. - Resume will use thread instead of queue. - Fixed irq panic issue. Change-Id: I9e54944fc276d8554db2b5c23042693923f2e5cc Signed-off-by: wengjun1 <wengjun1@motorola.com> Reviewed-on: https://gerrit.mot.com/1990930 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Huosheng Liao <liaohs@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
908e2bdb8b
commit
d4b40823fe
7 changed files with 239 additions and 63 deletions
10
drivers/input/touchscreen/gcore_mmi/gcore_drv_common.h
Normal file → Executable file
10
drivers/input/touchscreen/gcore_mmi/gcore_drv_common.h
Normal file → Executable file
|
|
@ -250,7 +250,6 @@ static const struct of_device_id tpd_of_match[] = {
|
|||
#define GESTURE_KEY KEY_POWER
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_ENABLE_FW_RAWDATA
|
||||
enum FW_MODE {
|
||||
DEMO,
|
||||
|
|
@ -277,7 +276,7 @@ struct gcore_dev {
|
|||
struct spi_device *bus_device;
|
||||
#endif
|
||||
|
||||
unsigned int touch_irq;
|
||||
int touch_irq;
|
||||
spinlock_t irq_flag_lock;
|
||||
int irq_flag;
|
||||
int tpd_flag;
|
||||
|
|
@ -396,5 +395,12 @@ extern int gcore_ts_drm_notifier_callback(struct notifier_block *self,
|
|||
unsigned long event, void *data);
|
||||
#endif
|
||||
|
||||
extern int gcore_start_mp_test(void);
|
||||
|
||||
#define RESUME_USES_WORKQ 1
|
||||
#if RESUME_USES_WORKQ
|
||||
extern void gcore_resume_wq_init(void);
|
||||
#endif
|
||||
|
||||
#endif /* GCORE_TPD_COMMON_H_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -1905,6 +1905,13 @@ static int fwu_event_handler(void *p)
|
|||
wait_event_interruptible(gdev->wait, fw_update_fn.event_flag == true);
|
||||
fw_update_fn.event_flag = false;
|
||||
|
||||
if (mutex_is_locked(&gdev->transfer_lock)) {
|
||||
GTP_DEBUG("fw event is locked, ignore");
|
||||
continue;
|
||||
}
|
||||
|
||||
mutex_lock(&gdev->transfer_lock);
|
||||
|
||||
switch (gdev->fw_event) {
|
||||
case FW_UPDATE:
|
||||
#ifdef CONFIG_GCORE_AUTO_UPDATE_FW_HOSTDOWNLOAD
|
||||
|
|
@ -1922,7 +1929,7 @@ static int fwu_event_handler(void *p)
|
|||
break;
|
||||
}
|
||||
|
||||
gdev_fwu->irq_enable(gdev_fwu);
|
||||
mutex_unlock(&gdev->transfer_lock);
|
||||
|
||||
} while (!kthread_should_stop());
|
||||
|
||||
|
|
|
|||
|
|
@ -254,6 +254,17 @@ long gcore_app_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
|
||||
break;
|
||||
|
||||
case IOC_APP_START_MP_TEST:
|
||||
|
||||
GTP_DEBUG("App ioctl start mp test");
|
||||
|
||||
if (gcore_start_mp_test()) {
|
||||
GTP_ERROR("App ioctl mp test fail!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
GTP_ERROR("ioctl unknow cmd!");
|
||||
return -ENOTTY;
|
||||
|
|
|
|||
80
drivers/input/touchscreen/gcore_mmi/gcore_drv_main.c
Normal file → Executable file
80
drivers/input/touchscreen/gcore_mmi/gcore_drv_main.c
Normal file → Executable file
|
|
@ -629,41 +629,30 @@ s32 gcore_touch_event_handler(struct gcore_dev *gdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tpd_event_handler(void *p)
|
||||
static irqreturn_t tpd_event_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct gcore_dev *gdev = (struct gcore_dev *)p;
|
||||
struct sched_param param = {.sched_priority = 4};
|
||||
struct gcore_dev *gdev = (struct gcore_dev *)dev_id;
|
||||
|
||||
sched_setscheduler(current, SCHED_RR, ¶m);
|
||||
do {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (mutex_is_locked(&gdev->transfer_lock)) {
|
||||
GTP_DEBUG("touch is locked, ignore");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
wait_event_interruptible(gdev->wait, gdev->tpd_flag != 0);
|
||||
gdev->tpd_flag = 0;
|
||||
mutex_lock(&gdev->transfer_lock);
|
||||
/* don't reset before "if (tpd_halt..." */
|
||||
|
||||
set_current_state(TASK_RUNNING);
|
||||
if (gcore_touch_event_handler(gdev)) {
|
||||
GTP_ERROR("touch event handler error.");
|
||||
}
|
||||
|
||||
mutex_lock(&gdev->transfer_lock);
|
||||
/* don't reset before "if (tpd_halt..." */
|
||||
mutex_unlock(&gdev->transfer_lock);
|
||||
|
||||
if (gcore_touch_event_handler(gdev)) {
|
||||
GTP_ERROR("touch event handler error.");
|
||||
}
|
||||
|
||||
gcore_irq_enable(gdev);
|
||||
|
||||
mutex_unlock(&gdev->transfer_lock);
|
||||
|
||||
} while (!kthread_should_stop());
|
||||
|
||||
return 0;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t tpd_eint_interrupt_handler(unsigned irq, void *p)
|
||||
static irqreturn_t tpd_eint_interrupt_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct gcore_dev *gdev = (struct gcore_dev *)p;
|
||||
unsigned long flags;
|
||||
struct gcore_dev *gdev = (struct gcore_dev *)dev_id;
|
||||
struct gcore_exp_fn *exp_fn = NULL;
|
||||
struct gcore_exp_fn *exp_fn_temp = NULL;
|
||||
u8 found = 0;
|
||||
|
|
@ -680,22 +669,12 @@ static irqreturn_t tpd_eint_interrupt_handler(unsigned irq, void *p)
|
|||
|
||||
if (!found) {
|
||||
gdev->tpd_flag = 1;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&gdev->irq_flag_lock, flags);
|
||||
if (gdev->irq_flag == 0) {
|
||||
spin_unlock_irqrestore(&gdev->irq_flag_lock, flags);
|
||||
return IRQ_WAKE_THREAD;
|
||||
} else {
|
||||
wake_up_interruptible(&gdev->wait);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
/* enter EINT handler disable INT, make sure INT is disable when handle touch event including top/bottom half */
|
||||
/* use _nosync to avoid deadlock */
|
||||
gdev->irq_flag = 0;
|
||||
spin_unlock_irqrestore(&gdev->irq_flag_lock, flags);
|
||||
disable_irq_nosync(gdev->touch_irq);
|
||||
|
||||
/*GTP_DEBUG("disable irq_flag=%d",g_touch.irq_flag);*/
|
||||
wake_up_interruptible(&gdev->wait);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int tpd_irq_registration(struct gcore_dev *gdev)
|
||||
|
|
@ -741,8 +720,10 @@ static int tpd_irq_registration(struct gcore_dev *gdev)
|
|||
|
||||
#endif
|
||||
|
||||
ret = request_irq(gdev->touch_irq, (irq_handler_t) tpd_eint_interrupt_handler,
|
||||
IRQF_TRIGGER_RISING, "TOUCH_PANEL-eint", gdev);
|
||||
ret = devm_request_threaded_irq(&gdev->bus_device->dev, gdev->touch_irq,
|
||||
tpd_eint_interrupt_handler,
|
||||
tpd_event_handler,
|
||||
IRQF_TRIGGER_RISING | IRQF_ONESHOT, "TOUCH_PANEL-eint", gdev);
|
||||
if (ret > 0) {
|
||||
ret = -1;
|
||||
GTP_ERROR("tpd request_irq IRQ LINE NOT AVAILABLE!.");
|
||||
|
|
@ -873,12 +854,6 @@ void gcore_deinit(struct gcore_dev *gdev)
|
|||
}
|
||||
}
|
||||
|
||||
if (gdev->touch_irq) {
|
||||
free_irq(gdev->touch_irq, gdev);
|
||||
}
|
||||
|
||||
kthread_stop(gdev->thread);
|
||||
|
||||
destroy_workqueue(gdev->fwu_workqueue);
|
||||
|
||||
if (gdev->touch_data) {
|
||||
|
|
@ -898,7 +873,6 @@ void gcore_deinit(struct gcore_dev *gdev)
|
|||
|
||||
int gcore_touch_probe(struct gcore_dev *gdev)
|
||||
{
|
||||
s32 err = 0;
|
||||
#if 0
|
||||
struct gcore_exp_fn *exp_fn = NULL;
|
||||
struct gcore_exp_fn *exp_fn_temp = NULL;
|
||||
|
|
@ -914,11 +888,6 @@ int gcore_touch_probe(struct gcore_dev *gdev)
|
|||
GTP_ERROR("gcore init fail!");
|
||||
}
|
||||
|
||||
gdev->thread = kthread_run(tpd_event_handler, gdev, GTP_DRIVER_NAME);
|
||||
if (IS_ERR(gdev->thread)) {
|
||||
err = PTR_ERR(gdev->thread);
|
||||
GTP_DEBUG(GTP_DRIVER_NAME " failed to create kernel thread: %d\n", err);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
|
||||
tpd_gpio_as_int(GTP_INT_PORT);
|
||||
|
|
@ -970,6 +939,11 @@ int gcore_touch_probe(struct gcore_dev *gdev)
|
|||
GTP_ERROR("register notifier failed!");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RESUME_USES_WORKQ
|
||||
gcore_resume_wq_init();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -193,6 +193,92 @@ int gcore_parse_mp_test_dt(struct gcore_mp_data *mp_data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define MP_TEST_INI "/sdcard/gcore_mp_test.ini"
|
||||
|
||||
static u8 *read_line(u8 *buf, int buf_len, struct file *fp)
|
||||
{
|
||||
int ret;
|
||||
int i = 0;
|
||||
mm_segment_t fs;
|
||||
|
||||
|
||||
fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
ret = fp->f_op->read(fp, buf, buf_len, &(fp->f_pos));
|
||||
set_fs(fs);
|
||||
|
||||
if (ret <= 0)
|
||||
return NULL;
|
||||
|
||||
while (buf[i] != '\n' && i < ret) {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i < ret) {
|
||||
fp->f_pos += i-ret;
|
||||
}
|
||||
|
||||
if (i < buf_len) {
|
||||
buf[i] = 0;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
int gcore_parse_mp_test_ini(struct gcore_mp_data *mp_data)
|
||||
{
|
||||
struct file *f = NULL;
|
||||
u8 *buff = NULL;
|
||||
int buff_len = 20;
|
||||
|
||||
buff = kzalloc(buff_len, GFP_KERNEL);
|
||||
if (!buff) {
|
||||
GTP_ERROR("file mem alloc fail!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
f = filp_open(MP_TEST_INI, O_RDONLY, 644);
|
||||
if (!f) {
|
||||
GTP_ERROR("open mp test ini file fail!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buff = read_line(buff, buff_len, f);
|
||||
GTP_DEBUG("ini read line %s", buff);
|
||||
|
||||
buff = read_line(buff, buff_len, f);
|
||||
GTP_DEBUG("ini read line %s", buff);
|
||||
sscanf(buff, "open_cb=%d", &mp_data->open_cb);
|
||||
GTP_DEBUG("read open cb:%d", mp_data->open_cb);
|
||||
|
||||
buff = read_line(buff, buff_len, f);
|
||||
GTP_DEBUG("ini read line %s", buff);
|
||||
sscanf(buff, "open_min=%d", &mp_data->open_min);
|
||||
GTP_DEBUG("read open min:%d", mp_data->open_min);
|
||||
|
||||
buff = read_line(buff, buff_len, f);
|
||||
GTP_DEBUG("ini read line %s", buff);
|
||||
sscanf(buff, "short_cb=%d", &mp_data->short_cb);
|
||||
GTP_DEBUG("read short cb:%d", mp_data->short_cb);
|
||||
|
||||
buff = read_line(buff, buff_len, f);
|
||||
GTP_DEBUG("ini read line %s", buff);
|
||||
sscanf(buff, "short_min=%d", &mp_data->short_min);
|
||||
GTP_DEBUG("read short min:%d", mp_data->short_min);
|
||||
|
||||
if (f != NULL) {
|
||||
filp_close(f, NULL);
|
||||
}
|
||||
|
||||
kfree(buff);
|
||||
|
||||
mp_data->test_chip_id = true;
|
||||
mp_data->test_int_pin = true;
|
||||
mp_data->test_open = true;
|
||||
mp_data->test_short = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcore_mp_test_int_pin(struct gcore_mp_data *mp_data)
|
||||
{
|
||||
u8 read_buf[4] = { 0 };
|
||||
|
|
@ -442,6 +528,13 @@ static int mp_test_event_handler(void *p)
|
|||
wait_event_interruptible(gdev->wait, mp_test_fn.event_flag == true);
|
||||
mp_test_fn.event_flag = false;
|
||||
|
||||
if (mutex_is_locked(&gdev->transfer_lock)) {
|
||||
GTP_DEBUG("fw event is locked, ignore");
|
||||
continue;
|
||||
}
|
||||
|
||||
mutex_lock(&gdev->transfer_lock);
|
||||
|
||||
switch (gdev->fw_event) {
|
||||
case FW_READ_OPEN:
|
||||
gcore_mp_test_item_open_reply(gdev->firmware, gdev->fw_xfer);
|
||||
|
|
@ -455,7 +548,7 @@ static int mp_test_event_handler(void *p)
|
|||
break;
|
||||
}
|
||||
|
||||
gdev->irq_enable(gdev);
|
||||
mutex_unlock(&gdev->transfer_lock);
|
||||
|
||||
} while (!kthread_should_stop());
|
||||
|
||||
|
|
@ -666,6 +759,65 @@ int gcore_save_mp_data_to_file(struct gcore_mp_data *mp_data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int gcore_start_mp_test(void)
|
||||
{
|
||||
struct gcore_mp_data *mp_data = g_mp_data;
|
||||
int test_result = 0;
|
||||
|
||||
GTP_DEBUG("gcore start mp test.");
|
||||
|
||||
gcore_parse_mp_test_ini(mp_data);
|
||||
|
||||
gcore_alloc_mp_test_mem(mp_data);
|
||||
|
||||
if (mp_data->test_int_pin) {
|
||||
mp_data->int_pin_test_result = gcore_mp_test_int_pin(mp_data);
|
||||
}
|
||||
|
||||
msleep(1);
|
||||
|
||||
if (mp_data->test_chip_id) {
|
||||
mp_data->chip_id_test_result = gcore_mp_test_chip_id(mp_data);
|
||||
}
|
||||
|
||||
msleep(1);
|
||||
|
||||
if (mp_data->test_open || mp_data->test_short) {
|
||||
GTP_DEBUG("mp test begin to updata mp bin");
|
||||
|
||||
#ifdef CONFIG_GCORE_AUTO_UPDATE_FW_HOSTDOWNLOAD
|
||||
if (gcore_auto_update_hostdownload_proc(gcore_mp_FW)) {
|
||||
GTP_ERROR("mp bin update hostdownload proc fail");
|
||||
}
|
||||
// gcore_request_firmware_update_work(NULL);
|
||||
#endif
|
||||
else {
|
||||
msleep(1);
|
||||
|
||||
if (mp_data->test_open) {
|
||||
mp_data->open_test_result = gcore_mp_test_item_open(mp_data);
|
||||
}
|
||||
|
||||
msleep(1);
|
||||
|
||||
if (mp_data->test_short) {
|
||||
mp_data->short_test_result = gcore_mp_test_item_short(mp_data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gcore_save_mp_data_to_file(mp_data);
|
||||
|
||||
test_result = (mp_data->int_pin_test_result || mp_data->chip_id_test_result \
|
||||
|| mp_data->open_test_result || mp_data->short_test_result) ? -1 : 0;
|
||||
|
||||
GTP_DEBUG("start mp test result:%d", test_result);
|
||||
|
||||
return test_result;
|
||||
|
||||
}
|
||||
|
||||
static int32_t gcore_mp_test_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct gcore_mp_data *mp_data = PDE_DATA(inode);
|
||||
|
|
|
|||
27
drivers/input/touchscreen/gcore_mmi/gcore_drv_qcom.c
Normal file → Executable file
27
drivers/input/touchscreen/gcore_mmi/gcore_drv_qcom.c
Normal file → Executable file
|
|
@ -23,6 +23,27 @@
|
|||
#include <drm/drm_panel.h>
|
||||
#endif
|
||||
|
||||
#if RESUME_USES_WORKQ
|
||||
static struct workqueue_struct *resume_by_ddi_wq;
|
||||
static struct work_struct resume_by_ddi_work;
|
||||
|
||||
void gcore_resume_by_ddi_work(struct work_struct *work)
|
||||
{
|
||||
gcore_request_firmware_update_work(NULL);
|
||||
|
||||
gcore_touch_release_all_point(fn_data.gdev->input_device);
|
||||
|
||||
fn_data.gdev->tp_suspend = false;
|
||||
}
|
||||
|
||||
void gcore_resume_wq_init(void)
|
||||
{
|
||||
resume_by_ddi_wq = create_singlethread_workqueue("resume_by_ddi_wq");
|
||||
WARN_ON(!resume_by_ddi_wq);
|
||||
INIT_WORK(&resume_by_ddi_work, gcore_resume_by_ddi_work);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ENABLE_GESTURE_WAKEUP) && defined(CONFIG_GESTURE_SPECIAL_INT)
|
||||
|
||||
int gcore_enable_irq_wake(struct gcore_dev *gdev)
|
||||
|
|
@ -115,6 +136,7 @@ void gcore_resume(void)
|
|||
|
||||
GTP_DEBUG("enter gcore resume");
|
||||
|
||||
#if !RESUME_USES_WORKQ
|
||||
#if defined(CONFIG_ENABLE_GESTURE_WAKEUP) && defined(CONFIG_GESTURE_SPECIAL_INT)
|
||||
struct gcore_dev *gdev = fn_data.gdev;
|
||||
if (gdev->gesture_wakeup_en) {
|
||||
|
|
@ -137,10 +159,13 @@ void gcore_resume(void)
|
|||
gcore_touch_release_all_point(fn_data.gdev->input_device);
|
||||
|
||||
fn_data.gdev->tp_suspend = false;
|
||||
#else
|
||||
queue_work(resume_by_ddi_wq, &(resume_by_ddi_work));
|
||||
GTP_DEBUG("TP resume work queued.");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_DRM
|
||||
int gcore_ts_drm_notifier_callback(struct notifier_block *self,
|
||||
unsigned long event, void *data)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ struct reg_msg {
|
|||
};
|
||||
|
||||
#define GALAXYCORE_MAGIC_NUMBER 'G'
|
||||
#define GALAXYCORE_MAX_NR 11
|
||||
#define GALAXYCORE_MAX_NR 12
|
||||
#define IOC_APP_READ_FW_VERSION _IOR(GALAXYCORE_MAGIC_NUMBER, 0, char)
|
||||
#define IOC_APP_UPDATE_FW _IOW(GALAXYCORE_MAGIC_NUMBER, 1, char)
|
||||
#define IOC_APP_DEMO _IO(GALAXYCORE_MAGIC_NUMBER, 2)
|
||||
|
|
@ -35,12 +35,13 @@ struct reg_msg {
|
|||
#define IOC_APP_READ_REG _IOR(GALAXYCORE_MAGIC_NUMBER, 4, struct reg_msg)
|
||||
#define IOC_APP_WRITE_REG _IOW(GALAXYCORE_MAGIC_NUMBER, 5, struct reg_msg)
|
||||
#define IOC_APP_GET_RAWDATA_RES _IOR(GALAXYCORE_MAGIC_NUMBER, 6, char)
|
||||
#define IOC_APP_START_MP_TEST _IO(GALAXYCORE_MAGIC_NUMBER, 7)
|
||||
|
||||
/* Tool */
|
||||
#define IOC_DEBUG_TIME_RST0 _IO(GALAXYCORE_MAGIC_NUMBER, 7)
|
||||
#define IOC_DEBUG_TIME_RST1 _IO(GALAXYCORE_MAGIC_NUMBER, 8)
|
||||
#define IOC_TOOL_MODE _IOW(GALAXYCORE_MAGIC_NUMBER, 9, int)
|
||||
#define IOC_TOOL_IDM_OPERATION _IOW(GALAXYCORE_MAGIC_NUMBER, 10, int)
|
||||
#define IOC_DEBUG_TIME_RST0 _IO(GALAXYCORE_MAGIC_NUMBER, 8)
|
||||
#define IOC_DEBUG_TIME_RST1 _IO(GALAXYCORE_MAGIC_NUMBER, 9)
|
||||
#define IOC_TOOL_MODE _IOW(GALAXYCORE_MAGIC_NUMBER, 10, int)
|
||||
#define IOC_TOOL_IDM_OPERATION _IOW(GALAXYCORE_MAGIC_NUMBER, 11, int)
|
||||
|
||||
|
||||
#endif /* _GCORE_IOCTL_H_ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue