diff --git a/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_fw_update.c index 47f519e83806..7ef8f8c10f73 100644 --- a/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_fw_update.c +++ b/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_fw_update.c @@ -4445,6 +4445,8 @@ static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data) if (!fwu) goto exit; + wakeup_source_trash(&fwu->flash_wake_src); + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { sysfs_remove_file(SYSFS_KOBJ, &attrs[attr_count].attr); } @@ -4452,7 +4454,8 @@ static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data) #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS_MMI sysfs_remove_bin_file(SYSFS_KOBJ, &dev_attr_data); #endif - kfree(fwu->read_config_buf); + if (fwu->read_config_buf_size) + kfree(fwu->read_config_buf); kfree(fwu->image_name); kfree(fwu); fwu = NULL; diff --git a/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_i2c.c b/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_i2c.c index 1fbf639ac1c9..e457f3638a39 100644 --- a/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_i2c.c +++ b/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_i2c.c @@ -6619,6 +6619,14 @@ static void synaptics_rmi4_detection_work(struct work_struct *work) if (exp_fhandler->func_init == NULL) { if (exp_fhandler->inserted == true) { exp_fhandler->func_remove(rmi4_data); + + /* need to restore status function on F34 removal */ + if (exp_fhandler->fn_type == RMI_FW_UPDATER && + exp_fhandler->func_status == rmi4_data->get_status) { + rmi4_data->get_status = synaptics_rmi4_f01_flashprog_status; + pr_info("using default status retrieval function\n"); + } + list_del(&exp_fhandler->link); kfree(exp_fhandler); } @@ -6770,10 +6778,9 @@ void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert, } else { list_for_each_entry(exp_fhandler, &exp_fn_ctrl.fn_list, link) { if (exp_fhandler->func_init == func_init) { - exp_fhandler->inserted = false; + /* leave inserted flag ON to run */ + /* remove function in detection work */ exp_fhandler->func_init = NULL; - exp_fhandler->func_attn = NULL; - exp_fhandler->func_status = NULL; goto exit; } } @@ -7261,7 +7268,6 @@ static int synaptics_rmi4_probe(struct i2c_client *client, goto err_query_device; } - init_waitqueue_head(&rmi4_data->wait); INIT_WORK(&rmi4_data->resume_work, synaptics_dsx_queued_resume); #if defined(CONFIG_MMI_PANEL_NOTIFICATIONS) @@ -7434,7 +7440,9 @@ err_mem_free: */ static int synaptics_rmi4_remove(struct i2c_client *client) { + struct pinctrl *pinctrl; int attr_count; + const struct synaptics_dsx_platform_data *platform_data; struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client); if (exp_fn_ctrl.inited) { @@ -7447,8 +7455,6 @@ static int synaptics_rmi4_remove(struct i2c_client *client) return 0; atomic_set(&rmi4_data->touch_stopped, 1); - wake_up(&rmi4_data->wait); - synaptics_rmi4_irq_enable(rmi4_data, false); for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { @@ -7489,6 +7495,19 @@ static int synaptics_rmi4_remove(struct i2c_client *client) if (rmi4_data->is_fps_registered) FPS_unregister_notifier(&rmi4_data->fps_notif, 0xBEEF); + unregister_reboot_notifier(&rmi4_data->rmi_reboot); + + platform_data = rmi4_data->board; + if (platform_data->gpio_config) + gpio_free(platform_data->irq_gpio); + if (gpio_is_valid(platform_data->reset_gpio)) + gpio_free(platform_data->reset_gpio); + + pinctrl = devm_pinctrl_get_select_default(&rmi4_data->i2c_client->dev); + if (IS_ERR(pinctrl)) + dev_err(&rmi4_data->i2c_client->dev, + "%s: pinctrl default failed\n", __func__); + kfree(rmi4_data); return 0; } diff --git a/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_i2c.h b/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_i2c.h index ec3708051d1d..e18741e1ab88 100644 --- a/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_i2c.h +++ b/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_i2c.h @@ -456,7 +456,6 @@ struct temp_buffer { * @flash_enabled: allow flashing once transition to active state is complete * @ic_on: touch ic power state * @fingers_on_2d: flag to indicate presence of fingers in 2d area - * @wait: wait queue for touch data polling in interrupt thread * @number_irq: total number of remembered interrupt times * @last_irq: last interrup time's number (index of the location of interrupt) * @irq_info: information about last few interrupt times @@ -504,7 +503,6 @@ struct synaptics_rmi4_data { bool fingers_on_2d; bool input_registered; bool in_bootloader; - wait_queue_head_t wait; int (*i2c_read)(struct synaptics_rmi4_data *pdata, unsigned short addr, unsigned char *data, unsigned short length); int (*i2c_write)(struct synaptics_rmi4_data *pdata, unsigned short addr, diff --git a/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_rmi_dev.c b/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_rmi_dev.c index 68469caa3165..632b27325abc 100644 --- a/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_rmi_dev.c +++ b/drivers/input/touchscreen/synaptics_mmi/synaptics_dsx_rmi_dev.c @@ -737,6 +737,10 @@ static void rmidev_remove_device(struct synaptics_rmi4_data *rmi4_data) if (!rmidev) return; + gpio_unexport(rmi4_data->board->irq_gpio); + + sysfs_remove_link(&rmi4_data->i2c_client->dev.kobj, "attn"); + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr);