mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 21:59:12 -04:00
synaptics_mmi: load module with regard to power state
When FW upgrade happens, regmap might change. This makes access to test reporting invalid and thus DLKM needs to reload. However, if touch IC's power state does not allow successful I2C communications, DLKM will never properly initialize. This change introdices 2 things: * waiting for valid power state to load DLKM * new state "loading" that allows to hold on power state change during DLKM load Note: It has been evaluated for test reporting DLKM only at this time. Long term it would need to apply to all DLKMs. Change-Id: I86f1ab6b815053e499b01a655fccf517d1e9addc Signed-off-by: Konstantin Makariev <hcv867@motorola.com> Reviewed-on: https://gerrit.mot.com/1346820 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Konstantin Makariev <kmakariev@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
02b0f7c724
commit
db27ede695
5 changed files with 135 additions and 102 deletions
|
|
@ -419,7 +419,7 @@ static int __init synaptics_control_access_block_module_init(void)
|
|||
synaptics_rmi4_new_function(RMI_CTRL_ACCESS_BLK, true,
|
||||
synaptics_control_access_block_init,
|
||||
synaptics_control_access_block_remove,
|
||||
NULL, NULL, IC_MODE_ANY);
|
||||
NULL, NULL, IC_MODE_UI);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -429,7 +429,7 @@ static void __exit synaptics_control_access_block_module_exit(void)
|
|||
synaptics_rmi4_new_function(RMI_CTRL_ACCESS_BLK, false,
|
||||
synaptics_control_access_block_init,
|
||||
synaptics_control_access_block_remove,
|
||||
NULL, NULL, IC_MODE_ANY);
|
||||
NULL, NULL, IC_MODE_UI);
|
||||
wait_for_completion(&remove_complete);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2653,7 +2653,7 @@ static void synaptics_dsx_enable_wakeup_source(
|
|||
|
||||
static const char * const synaptics_state_names[] = {"UNKNOWN",
|
||||
"ACTIVE", "SUSPEND", "UNUSED", "STANDBY", "BL", "INIT",
|
||||
"FLASH", "QUERY", "INVALID" };
|
||||
"FLASH", "QUERY", "LOADING", "INVALID" };
|
||||
|
||||
static const char *synaptics_dsx_state_name(int state)
|
||||
{
|
||||
|
|
@ -2766,6 +2766,7 @@ static int synaptics_dsx_wait_for_idle(struct synaptics_rmi4_data *rmi4_data)
|
|||
current_state = synaptics_dsx_get_state_safe(rmi4_data);
|
||||
if (!(current_state == STATE_INIT ||
|
||||
current_state == STATE_FLASH ||
|
||||
current_state == STATE_LOADING ||
|
||||
current_state == STATE_UNKNOWN))
|
||||
break;
|
||||
|
||||
|
|
@ -2884,6 +2885,7 @@ static void synaptics_dsx_sensor_state(struct synaptics_rmi4_data *rmi4_data,
|
|||
case STATE_UNKNOWN:
|
||||
rmi4_data->in_bootloader = false;
|
||||
case STATE_FLASH:
|
||||
case STATE_LOADING:
|
||||
/* no special handling for these states */
|
||||
break;
|
||||
|
||||
|
|
@ -6745,10 +6747,20 @@ static void synaptics_rmi4_detection_work(struct work_struct *work)
|
|||
|
||||
if (exp_fhandler->mode == IC_MODE_UI) {
|
||||
if (rmi4_data->in_bootloader) {
|
||||
dev_err(dev, "%s: handler %d requires UI mode\n",
|
||||
dev_warn(dev, "%s: handler %d requires UI mode\n",
|
||||
__func__, exp_fhandler->fn_type);
|
||||
continue;
|
||||
}
|
||||
/* UI mode requires IC powered on */
|
||||
if (state == STATE_SUSPEND) {
|
||||
dev_warn(dev, "%s: handler %d cannot operate while suspended\n",
|
||||
__func__, exp_fhandler->fn_type);
|
||||
scheduled_delay = 500;
|
||||
continue;
|
||||
}
|
||||
/* postpone suspend for loading RMI_F54 and */
|
||||
if (exp_fhandler->fn_type == RMI_F54)
|
||||
synaptics_dsx_sensor_state(rmi4_data, STATE_LOADING);
|
||||
}
|
||||
|
||||
exp_fhandler->func_init(rmi4_data);
|
||||
|
|
@ -6762,7 +6774,7 @@ static void synaptics_rmi4_detection_work(struct work_struct *work)
|
|||
|
||||
regs = find_function(rmi4_data, SYNAPTICS_RMI4_F54);
|
||||
if (!regs)
|
||||
continue;
|
||||
goto restore_state;
|
||||
error = rmi4_data->scan_f54_ctrl_regs(rmi4_data, regs);
|
||||
if (error) {
|
||||
regs->nr_regs = 0;
|
||||
|
|
@ -6771,7 +6783,7 @@ static void synaptics_rmi4_detection_work(struct work_struct *work)
|
|||
|
||||
regs = find_function(rmi4_data, SYNAPTICS_RMI4_F54 | COMMAND_TYPE);
|
||||
if (!regs)
|
||||
continue;
|
||||
goto restore_state;
|
||||
error = rmi4_data->scan_f54_cmd_regs(rmi4_data, regs);
|
||||
if (error) {
|
||||
regs->nr_regs = 0;
|
||||
|
|
@ -6780,7 +6792,7 @@ static void synaptics_rmi4_detection_work(struct work_struct *work)
|
|||
|
||||
regs = find_function(rmi4_data, SYNAPTICS_RMI4_F54 | DATA_TYPE);
|
||||
if (!regs)
|
||||
continue;
|
||||
goto restore_state;
|
||||
error = rmi4_data->scan_f54_data_regs(rmi4_data, regs);
|
||||
if (error) {
|
||||
regs->nr_regs = 0;
|
||||
|
|
@ -6790,7 +6802,7 @@ static void synaptics_rmi4_detection_work(struct work_struct *work)
|
|||
|
||||
regs = find_function(rmi4_data, SYNAPTICS_RMI4_F54 | QUERY_TYPE);
|
||||
if (!regs)
|
||||
continue;
|
||||
goto restore_state;
|
||||
error = rmi4_data->scan_f54_query_regs(rmi4_data, regs);
|
||||
if (error) {
|
||||
regs->nr_regs = 0;
|
||||
|
|
@ -6813,11 +6825,9 @@ static void synaptics_rmi4_detection_work(struct work_struct *work)
|
|||
control_access_block_update_dynamic(rmi4_data);
|
||||
}
|
||||
|
||||
if (exp_fhandler->fn_type == RMI_FW_UPDATER) {
|
||||
if (exp_fhandler->fn_type == RMI_FW_UPDATER && exp_fhandler->func_status) {
|
||||
int status;
|
||||
|
||||
if (!exp_fhandler->func_status)
|
||||
continue;
|
||||
status = exp_fhandler->func_status(rmi4_data);
|
||||
/* consider changing to */
|
||||
/* if (status == 1) */
|
||||
|
|
@ -6827,7 +6837,7 @@ static void synaptics_rmi4_detection_work(struct work_struct *work)
|
|||
|
||||
rmi = &(rmi4_data->rmi4_mod_info);
|
||||
rmi4_data->in_bootloader = true;
|
||||
synaptics_dsx_set_state_safe(rmi4_data, STATE_BL);
|
||||
synaptics_dsx_sensor_state(rmi4_data, STATE_BL);
|
||||
|
||||
state = synaptics_dsx_get_state_safe(rmi4_data);
|
||||
dev_dbg(dev, "%s: current state %s\n",
|
||||
|
|
@ -6855,11 +6865,17 @@ static void synaptics_rmi4_detection_work(struct work_struct *work)
|
|||
/* allowing sufficient time for F34 to complete */
|
||||
scheduled_delay = 3000;
|
||||
}
|
||||
|
||||
restore_state:
|
||||
if (STATE_LOADING == synaptics_dsx_get_state_safe(rmi4_data))
|
||||
synaptics_dsx_sensor_state(rmi4_data, state);
|
||||
}
|
||||
|
||||
if (scheduled_delay)
|
||||
if (scheduled_delay) {
|
||||
queue_delayed_work(det_workqueue, &exp_fn_ctrl->det_work,
|
||||
msecs_to_jiffies(scheduled_delay));
|
||||
dev_dbg(dev, "%s: re-scheduled %d\n", __func__, scheduled_delay);
|
||||
}
|
||||
|
||||
release_mutex:
|
||||
mutex_unlock(&exp_fn_ctrl->list_mutex);
|
||||
|
|
@ -6936,12 +6952,18 @@ void synaptics_rmi4_new_function(
|
|||
list_add_tail(&exp_fhandler->link, &rmi4_data->exp_fn_ctrl.fn_list);
|
||||
} else {
|
||||
list_for_each_entry(exp_fhandler, &rmi4_data->exp_fn_ctrl.fn_list, link) {
|
||||
if (exp_fhandler->func_init == func_init) {
|
||||
/* leave inserted flag ON to run */
|
||||
/* remove function in detection work */
|
||||
exp_fhandler->func_init = NULL;
|
||||
goto exit;
|
||||
if (exp_fhandler->func_init != func_init)
|
||||
continue;
|
||||
/* insert flag needed to run remove function in detection */
|
||||
/* work even though function was never properly inserted */
|
||||
if (!exp_fhandler->inserted) {
|
||||
exp_fhandler->inserted = true;
|
||||
dev_info(&rmi4_data->i2c_client->dev,
|
||||
"removing not inserted handler %d\n",
|
||||
exp_fhandler->fn_type);
|
||||
}
|
||||
exp_fhandler->func_init = NULL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -335,6 +335,7 @@ enum {
|
|||
STATE_INIT,
|
||||
STATE_FLASH,
|
||||
STATE_QUERY,
|
||||
STATE_LOADING,
|
||||
STATE_INVALID
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -850,7 +850,7 @@ static int __init rmidev_module_init(void)
|
|||
synaptics_rmi4_new_function(next, RMI_DEV, true,
|
||||
rmidev_init_device,
|
||||
rmidev_remove_device,
|
||||
NULL, NULL, IC_MODE_ANY);
|
||||
NULL, NULL, IC_MODE_UI);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -869,7 +869,7 @@ static void __exit rmidev_module_exit(void)
|
|||
synaptics_rmi4_new_function(next, RMI_DEV, false,
|
||||
rmidev_init_device,
|
||||
rmidev_remove_device,
|
||||
NULL, NULL, IC_MODE_ANY);
|
||||
NULL, NULL, IC_MODE_UI);
|
||||
wait_for_completion(&rmidev->remove_complete);
|
||||
kfree(rmidev);
|
||||
next->rmidev_data = NULL;
|
||||
|
|
|
|||
|
|
@ -2304,6 +2304,7 @@ struct f54_kobj_data {
|
|||
#define to_f54_attr(x) container_of(x, struct f54_attribute, attr)
|
||||
|
||||
struct synaptics_rmi4_f54_handle {
|
||||
bool init_done;
|
||||
bool no_auto_cal;
|
||||
int status;
|
||||
unsigned char intr_mask;
|
||||
|
|
@ -3453,92 +3454,92 @@ static void print_image_report(struct synaptics_rmi4_f54_handle *f54)
|
|||
|
||||
static void free_control_mem(struct synaptics_rmi4_f54_handle *f54)
|
||||
{
|
||||
struct f54_control control = f54->control;
|
||||
struct f54_control *control = &f54->control;
|
||||
|
||||
kfree(control.reg_0);
|
||||
kfree(control.reg_1);
|
||||
kfree(control.reg_2);
|
||||
kfree(control.reg_3);
|
||||
kfree(control.reg_4__6);
|
||||
kfree(control.reg_7);
|
||||
kfree(control.reg_8__9);
|
||||
kfree(control.reg_10);
|
||||
kfree(control.reg_11);
|
||||
kfree(control.reg_12__13);
|
||||
kfree(control.reg_14);
|
||||
if (control.reg_15)
|
||||
kfree(control.reg_15->data);
|
||||
kfree(control.reg_15);
|
||||
if (control.reg_16)
|
||||
kfree(control.reg_16->data);
|
||||
kfree(control.reg_16);
|
||||
if (control.reg_17)
|
||||
kfree(control.reg_17->data);
|
||||
kfree(control.reg_17);
|
||||
if (control.reg_18)
|
||||
kfree(control.reg_18->data);
|
||||
kfree(control.reg_18);
|
||||
if (control.reg_19)
|
||||
kfree(control.reg_19->data);
|
||||
kfree(control.reg_19);
|
||||
kfree(control.reg_20);
|
||||
kfree(control.reg_21);
|
||||
kfree(control.reg_22__26);
|
||||
kfree(control.reg_27);
|
||||
kfree(control.reg_28);
|
||||
kfree(control.reg_29);
|
||||
kfree(control.reg_30);
|
||||
kfree(control.reg_31);
|
||||
kfree(control.reg_32__35);
|
||||
if (control.reg_36)
|
||||
kfree(control.reg_36->data);
|
||||
kfree(control.reg_36);
|
||||
if (control.reg_37)
|
||||
kfree(control.reg_37->data);
|
||||
kfree(control.reg_37);
|
||||
if (control.reg_38)
|
||||
kfree(control.reg_38->data);
|
||||
kfree(control.reg_38);
|
||||
if (control.reg_39)
|
||||
kfree(control.reg_39->data);
|
||||
kfree(control.reg_39);
|
||||
if (control.reg_40)
|
||||
kfree(control.reg_40->data);
|
||||
kfree(control.reg_40);
|
||||
if (control.reg_89)
|
||||
kfree(control.reg_89->data);
|
||||
kfree(control.reg_89);
|
||||
kfree(control.reg_93);
|
||||
if (control.reg_95)
|
||||
kfree(control.reg_95->data);
|
||||
kfree(control.reg_95);
|
||||
kfree(control.reg_99);
|
||||
kfree(control.reg_107);
|
||||
kfree(control.reg_113);
|
||||
kfree(control.reg_116);
|
||||
kfree(control.reg_137);
|
||||
kfree(control.reg_145);
|
||||
kfree(control.reg_146);
|
||||
kfree(control.reg_242);
|
||||
kfree(control.reg_269);
|
||||
kfree(control->reg_0);
|
||||
kfree(control->reg_1);
|
||||
kfree(control->reg_2);
|
||||
kfree(control->reg_3);
|
||||
kfree(control->reg_4__6);
|
||||
kfree(control->reg_7);
|
||||
kfree(control->reg_8__9);
|
||||
kfree(control->reg_10);
|
||||
kfree(control->reg_11);
|
||||
kfree(control->reg_12__13);
|
||||
kfree(control->reg_14);
|
||||
if (control->reg_15)
|
||||
kfree(control->reg_15->data);
|
||||
kfree(control->reg_15);
|
||||
if (control->reg_16)
|
||||
kfree(control->reg_16->data);
|
||||
kfree(control->reg_16);
|
||||
if (control->reg_17)
|
||||
kfree(control->reg_17->data);
|
||||
kfree(control->reg_17);
|
||||
if (control->reg_18)
|
||||
kfree(control->reg_18->data);
|
||||
kfree(control->reg_18);
|
||||
if (control->reg_19)
|
||||
kfree(control->reg_19->data);
|
||||
kfree(control->reg_19);
|
||||
kfree(control->reg_20);
|
||||
kfree(control->reg_21);
|
||||
kfree(control->reg_22__26);
|
||||
kfree(control->reg_27);
|
||||
kfree(control->reg_28);
|
||||
kfree(control->reg_29);
|
||||
kfree(control->reg_30);
|
||||
kfree(control->reg_31);
|
||||
kfree(control->reg_32__35);
|
||||
if (control->reg_36)
|
||||
kfree(control->reg_36->data);
|
||||
kfree(control->reg_36);
|
||||
if (control->reg_37)
|
||||
kfree(control->reg_37->data);
|
||||
kfree(control->reg_37);
|
||||
if (control->reg_38)
|
||||
kfree(control->reg_38->data);
|
||||
kfree(control->reg_38);
|
||||
if (control->reg_39)
|
||||
kfree(control->reg_39->data);
|
||||
kfree(control->reg_39);
|
||||
if (control->reg_40)
|
||||
kfree(control->reg_40->data);
|
||||
kfree(control->reg_40);
|
||||
if (control->reg_89)
|
||||
kfree(control->reg_89->data);
|
||||
kfree(control->reg_89);
|
||||
kfree(control->reg_93);
|
||||
if (control->reg_95)
|
||||
kfree(control->reg_95->data);
|
||||
kfree(control->reg_95);
|
||||
kfree(control->reg_99);
|
||||
kfree(control->reg_107);
|
||||
kfree(control->reg_113);
|
||||
kfree(control->reg_116);
|
||||
kfree(control->reg_137);
|
||||
kfree(control->reg_145);
|
||||
kfree(control->reg_146);
|
||||
kfree(control->reg_242);
|
||||
kfree(control->reg_269);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void free_data_mem(struct synaptics_rmi4_f54_handle *f54)
|
||||
{
|
||||
struct f54_data data = f54->data;
|
||||
struct f54_data *data = &f54->data;
|
||||
|
||||
kfree(data.reg_4);
|
||||
kfree(data.reg_6);
|
||||
kfree(data.reg_7_0);
|
||||
kfree(data.reg_7_1);
|
||||
kfree(data.reg_8);
|
||||
kfree(data.reg_9);
|
||||
kfree(data.reg_10);
|
||||
kfree(data.reg_14);
|
||||
kfree(data.reg_16);
|
||||
kfree(data.reg_17);
|
||||
kfree(data->reg_4);
|
||||
kfree(data->reg_6);
|
||||
kfree(data->reg_7_0);
|
||||
kfree(data->reg_7_1);
|
||||
kfree(data->reg_8);
|
||||
kfree(data->reg_9);
|
||||
kfree(data->reg_10);
|
||||
kfree(data->reg_14);
|
||||
kfree(data->reg_16);
|
||||
kfree(data->reg_17);
|
||||
}
|
||||
|
||||
static void remove_sysfs(struct synaptics_rmi4_f54_handle *f54)
|
||||
|
|
@ -5868,6 +5869,8 @@ found:
|
|||
INIT_WORK(&f54->timeout_work, timeout_set_status);
|
||||
#endif
|
||||
|
||||
f54->init_done = true;
|
||||
|
||||
return 0;
|
||||
|
||||
exit_sysfs:
|
||||
|
|
@ -5891,6 +5894,12 @@ static void synaptics_rmi4_f54_remove(struct synaptics_rmi4_data *rmi4_data)
|
|||
{
|
||||
struct synaptics_rmi4_f54_handle *f54 =
|
||||
(struct synaptics_rmi4_f54_handle *)rmi4_data->f54_data;
|
||||
|
||||
if (!f54->init_done) {
|
||||
dev_dbg(&rmi4_data->i2c_client->dev, "%s: no cleanup necessary!!!\n", __func__);
|
||||
goto exit_and_complete;
|
||||
}
|
||||
|
||||
#ifdef WATCHDOG_HRTIMER
|
||||
hrtimer_cancel(&f54->watchdog);
|
||||
#endif
|
||||
|
|
@ -5902,11 +5911,12 @@ static void synaptics_rmi4_f54_remove(struct synaptics_rmi4_data *rmi4_data)
|
|||
|
||||
kfree(f54->report_data);
|
||||
kfree(f54->fn55);
|
||||
/* cancel delayed work first then free fn_ptr!!! */
|
||||
cancel_delayed_work_sync(&f54->status_work);
|
||||
kfree(f54->fn_ptr);
|
||||
|
||||
cancel_delayed_work(&f54->status_work);
|
||||
wakeup_source_trash(&f54->test_wake_lock);
|
||||
|
||||
exit_and_complete:
|
||||
complete(&f54->remove_complete);
|
||||
|
||||
return;
|
||||
|
|
|
|||
Loading…
Reference in a new issue