aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDudley Du <dudl@cypress.com>2016-03-04 14:23:09 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2016-03-04 14:32:13 -0500
commit3cd47869431d7402d0613cf0f7fbb392f2b97565 (patch)
tree295eebb05b77b62f3b64ee8112b83b4e11980198
parent5186b8c41a89fd071f8d036b41ec4b68fbcf2e4d (diff)
Input: cyapa - fix for losing events during device power transitions
When changing the scan rate as part of runtime-resume process we may lose some of the events, because: 1) for gen3 trackpads, the driver must msleep() some time to ensure that the device is ready to accept next command; 2) for gen5 and later trackpads, the queue dumping function will simply ignore the events when waiting for the set power mode command response. The solution is to keep polling and report those valid events when the set power mode command is in progress. Signed-off-by: Dudley Du <dudl@cypress.com> Tested-by: Jeremiah Mahler <jmmahler@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/mouse/cyapa.c22
-rw-r--r--drivers/input/mouse/cyapa.h14
-rw-r--r--drivers/input/mouse/cyapa_gen3.c108
-rw-r--r--drivers/input/mouse/cyapa_gen5.c99
-rw-r--r--drivers/input/mouse/cyapa_gen6.c4
5 files changed, 188 insertions, 59 deletions
diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
index eb76b61418f3..dc2394292088 100644
--- a/drivers/input/mouse/cyapa.c
+++ b/drivers/input/mouse/cyapa.c
@@ -383,7 +383,7 @@ static int cyapa_open(struct input_dev *input)
383 * when in operational mode. 383 * when in operational mode.
384 */ 384 */
385 error = cyapa->ops->set_power_mode(cyapa, 385 error = cyapa->ops->set_power_mode(cyapa,
386 PWR_MODE_FULL_ACTIVE, 0, false); 386 PWR_MODE_FULL_ACTIVE, 0, CYAPA_PM_ACTIVE);
387 if (error) { 387 if (error) {
388 dev_warn(dev, "set active power failed: %d\n", error); 388 dev_warn(dev, "set active power failed: %d\n", error);
389 goto out; 389 goto out;
@@ -424,7 +424,8 @@ static void cyapa_close(struct input_dev *input)
424 pm_runtime_set_suspended(dev); 424 pm_runtime_set_suspended(dev);
425 425
426 if (cyapa->operational) 426 if (cyapa->operational)
427 cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0, false); 427 cyapa->ops->set_power_mode(cyapa,
428 PWR_MODE_OFF, 0, CYAPA_PM_DEACTIVE);
428 429
429 mutex_unlock(&cyapa->state_sync_lock); 430 mutex_unlock(&cyapa->state_sync_lock);
430} 431}
@@ -534,7 +535,7 @@ static void cyapa_enable_irq_for_cmd(struct cyapa *cyapa)
534 */ 535 */
535 if (!input || cyapa->operational) 536 if (!input || cyapa->operational)
536 cyapa->ops->set_power_mode(cyapa, 537 cyapa->ops->set_power_mode(cyapa,
537 PWR_MODE_FULL_ACTIVE, 0, false); 538 PWR_MODE_FULL_ACTIVE, 0, CYAPA_PM_ACTIVE);
538 /* Gen3 always using polling mode for command. */ 539 /* Gen3 always using polling mode for command. */
539 if (cyapa->gen >= CYAPA_GEN5) 540 if (cyapa->gen >= CYAPA_GEN5)
540 enable_irq(cyapa->client->irq); 541 enable_irq(cyapa->client->irq);
@@ -550,7 +551,7 @@ static void cyapa_disable_irq_for_cmd(struct cyapa *cyapa)
550 disable_irq(cyapa->client->irq); 551 disable_irq(cyapa->client->irq);
551 if (!input || cyapa->operational) 552 if (!input || cyapa->operational)
552 cyapa->ops->set_power_mode(cyapa, 553 cyapa->ops->set_power_mode(cyapa,
553 PWR_MODE_OFF, 0, false); 554 PWR_MODE_OFF, 0, CYAPA_PM_ACTIVE);
554 } 555 }
555} 556}
556 557
@@ -617,7 +618,8 @@ static int cyapa_initialize(struct cyapa *cyapa)
617 618
618 /* Power down the device until we need it. */ 619 /* Power down the device until we need it. */
619 if (cyapa->operational) 620 if (cyapa->operational)
620 cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0, false); 621 cyapa->ops->set_power_mode(cyapa,
622 PWR_MODE_OFF, 0, CYAPA_PM_ACTIVE);
621 623
622 return 0; 624 return 0;
623} 625}
@@ -634,7 +636,7 @@ static int cyapa_reinitialize(struct cyapa *cyapa)
634 /* Avoid command failures when TP was in OFF state. */ 636 /* Avoid command failures when TP was in OFF state. */
635 if (cyapa->operational) 637 if (cyapa->operational)
636 cyapa->ops->set_power_mode(cyapa, 638 cyapa->ops->set_power_mode(cyapa,
637 PWR_MODE_FULL_ACTIVE, 0, false); 639 PWR_MODE_FULL_ACTIVE, 0, CYAPA_PM_ACTIVE);
638 640
639 error = cyapa_detect(cyapa); 641 error = cyapa_detect(cyapa);
640 if (error) 642 if (error)
@@ -654,7 +656,7 @@ out:
654 /* Reset to power OFF state to save power when no user open. */ 656 /* Reset to power OFF state to save power when no user open. */
655 if (cyapa->operational) 657 if (cyapa->operational)
656 cyapa->ops->set_power_mode(cyapa, 658 cyapa->ops->set_power_mode(cyapa,
657 PWR_MODE_OFF, 0, false); 659 PWR_MODE_OFF, 0, CYAPA_PM_DEACTIVE);
658 } else if (!error && cyapa->operational) { 660 } else if (!error && cyapa->operational) {
659 /* 661 /*
660 * Make sure only enable runtime PM when device is 662 * Make sure only enable runtime PM when device is
@@ -1392,7 +1394,7 @@ static int __maybe_unused cyapa_suspend(struct device *dev)
1392 power_mode = device_may_wakeup(dev) ? cyapa->suspend_power_mode 1394 power_mode = device_may_wakeup(dev) ? cyapa->suspend_power_mode
1393 : PWR_MODE_OFF; 1395 : PWR_MODE_OFF;
1394 error = cyapa->ops->set_power_mode(cyapa, power_mode, 1396 error = cyapa->ops->set_power_mode(cyapa, power_mode,
1395 cyapa->suspend_sleep_time, true); 1397 cyapa->suspend_sleep_time, CYAPA_PM_SUSPEND);
1396 if (error) 1398 if (error)
1397 dev_err(dev, "suspend set power mode failed: %d\n", 1399 dev_err(dev, "suspend set power mode failed: %d\n",
1398 error); 1400 error);
@@ -1447,7 +1449,7 @@ static int __maybe_unused cyapa_runtime_suspend(struct device *dev)
1447 error = cyapa->ops->set_power_mode(cyapa, 1449 error = cyapa->ops->set_power_mode(cyapa,
1448 cyapa->runtime_suspend_power_mode, 1450 cyapa->runtime_suspend_power_mode,
1449 cyapa->runtime_suspend_sleep_time, 1451 cyapa->runtime_suspend_sleep_time,
1450 false); 1452 CYAPA_PM_RUNTIME_SUSPEND);
1451 if (error) 1453 if (error)
1452 dev_warn(dev, "runtime suspend failed: %d\n", error); 1454 dev_warn(dev, "runtime suspend failed: %d\n", error);
1453 1455
@@ -1460,7 +1462,7 @@ static int __maybe_unused cyapa_runtime_resume(struct device *dev)
1460 int error; 1462 int error;
1461 1463
1462 error = cyapa->ops->set_power_mode(cyapa, 1464 error = cyapa->ops->set_power_mode(cyapa,
1463 PWR_MODE_FULL_ACTIVE, 0, false); 1465 PWR_MODE_FULL_ACTIVE, 0, CYAPA_PM_RUNTIME_RESUME);
1464 if (error) 1466 if (error)
1465 dev_warn(dev, "runtime resume failed: %d\n", error); 1467 dev_warn(dev, "runtime resume failed: %d\n", error);
1466 1468
diff --git a/drivers/input/mouse/cyapa.h b/drivers/input/mouse/cyapa.h
index b812bba8cdd7..ce951fe4516a 100644
--- a/drivers/input/mouse/cyapa.h
+++ b/drivers/input/mouse/cyapa.h
@@ -250,6 +250,15 @@ struct cyapa;
250 250
251typedef bool (*cb_sort)(struct cyapa *, u8 *, int); 251typedef bool (*cb_sort)(struct cyapa *, u8 *, int);
252 252
253enum cyapa_pm_stage {
254 CYAPA_PM_DEACTIVE,
255 CYAPA_PM_ACTIVE,
256 CYAPA_PM_SUSPEND,
257 CYAPA_PM_RESUME,
258 CYAPA_PM_RUNTIME_SUSPEND,
259 CYAPA_PM_RUNTIME_RESUME,
260};
261
253struct cyapa_dev_ops { 262struct cyapa_dev_ops {
254 int (*check_fw)(struct cyapa *, const struct firmware *); 263 int (*check_fw)(struct cyapa *, const struct firmware *);
255 int (*bl_enter)(struct cyapa *); 264 int (*bl_enter)(struct cyapa *);
@@ -273,7 +282,7 @@ struct cyapa_dev_ops {
273 int (*sort_empty_output_data)(struct cyapa *, 282 int (*sort_empty_output_data)(struct cyapa *,
274 u8 *, int *, cb_sort); 283 u8 *, int *, cb_sort);
275 284
276 int (*set_power_mode)(struct cyapa *, u8, u16, bool); 285 int (*set_power_mode)(struct cyapa *, u8, u16, enum cyapa_pm_stage);
277 286
278 int (*set_proximity)(struct cyapa *, bool); 287 int (*set_proximity)(struct cyapa *, bool);
279}; 288};
@@ -289,6 +298,9 @@ struct cyapa_pip_cmd_states {
289 u8 *resp_data; 298 u8 *resp_data;
290 int *resp_len; 299 int *resp_len;
291 300
301 enum cyapa_pm_stage pm_stage;
302 struct mutex pm_stage_lock;
303
292 u8 irq_cmd_buf[CYAPA_REG_MAP_SIZE]; 304 u8 irq_cmd_buf[CYAPA_REG_MAP_SIZE];
293 u8 empty_buf[CYAPA_REG_MAP_SIZE]; 305 u8 empty_buf[CYAPA_REG_MAP_SIZE];
294}; 306};
diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c
index 1a9d12ae7538..f9600753eca5 100644
--- a/drivers/input/mouse/cyapa_gen3.c
+++ b/drivers/input/mouse/cyapa_gen3.c
@@ -269,6 +269,7 @@ static const struct cyapa_cmd_len cyapa_smbus_cmds[] = {
269 { CYAPA_SMBUS_MIN_BASELINE, 1 }, /* CYAPA_CMD_MIN_BASELINE */ 269 { CYAPA_SMBUS_MIN_BASELINE, 1 }, /* CYAPA_CMD_MIN_BASELINE */
270}; 270};
271 271
272static int cyapa_gen3_try_poll_handler(struct cyapa *cyapa);
272 273
273/* 274/*
274 * cyapa_smbus_read_block - perform smbus block read command 275 * cyapa_smbus_read_block - perform smbus block read command
@@ -950,12 +951,14 @@ static u16 cyapa_get_wait_time_for_pwr_cmd(u8 pwr_mode)
950 * Device power mode can only be set when device is in operational mode. 951 * Device power mode can only be set when device is in operational mode.
951 */ 952 */
952static int cyapa_gen3_set_power_mode(struct cyapa *cyapa, u8 power_mode, 953static int cyapa_gen3_set_power_mode(struct cyapa *cyapa, u8 power_mode,
953 u16 always_unused, bool is_suspend_unused) 954 u16 always_unused, enum cyapa_pm_stage pm_stage)
954{ 955{
955 int ret; 956 struct input_dev *input = cyapa->input;
956 u8 power; 957 u8 power;
957 int tries; 958 int tries;
958 u16 sleep_time; 959 int sleep_time;
960 int interval;
961 int ret;
959 962
960 if (cyapa->state != CYAPA_STATE_OP) 963 if (cyapa->state != CYAPA_STATE_OP)
961 return 0; 964 return 0;
@@ -977,7 +980,7 @@ static int cyapa_gen3_set_power_mode(struct cyapa *cyapa, u8 power_mode,
977 if ((ret & PWR_MODE_MASK) == power_mode) 980 if ((ret & PWR_MODE_MASK) == power_mode)
978 return 0; 981 return 0;
979 982
980 sleep_time = cyapa_get_wait_time_for_pwr_cmd(ret & PWR_MODE_MASK); 983 sleep_time = (int)cyapa_get_wait_time_for_pwr_cmd(ret & PWR_MODE_MASK);
981 power = ret; 984 power = ret;
982 power &= ~PWR_MODE_MASK; 985 power &= ~PWR_MODE_MASK;
983 power |= power_mode & PWR_MODE_MASK; 986 power |= power_mode & PWR_MODE_MASK;
@@ -995,7 +998,23 @@ static int cyapa_gen3_set_power_mode(struct cyapa *cyapa, u8 power_mode,
995 * doing so before issuing the next command may result in errors 998 * doing so before issuing the next command may result in errors
996 * depending on the command's content. 999 * depending on the command's content.
997 */ 1000 */
998 msleep(sleep_time); 1001 if (cyapa->operational && input && input->users &&
1002 (pm_stage == CYAPA_PM_RUNTIME_SUSPEND ||
1003 pm_stage == CYAPA_PM_RUNTIME_RESUME)) {
1004 /* Try to polling in 120Hz, read may fail, just ignore it. */
1005 interval = 1000 / 120;
1006 while (sleep_time > 0) {
1007 if (sleep_time > interval)
1008 msleep(interval);
1009 else
1010 msleep(sleep_time);
1011 sleep_time -= interval;
1012 cyapa_gen3_try_poll_handler(cyapa);
1013 }
1014 } else {
1015 msleep(sleep_time);
1016 }
1017
999 return ret; 1018 return ret;
1000} 1019}
1001 1020
@@ -1112,7 +1131,7 @@ static int cyapa_gen3_do_operational_check(struct cyapa *cyapa)
1112 * may cause problems, so we set the power mode first here. 1131 * may cause problems, so we set the power mode first here.
1113 */ 1132 */
1114 error = cyapa_gen3_set_power_mode(cyapa, 1133 error = cyapa_gen3_set_power_mode(cyapa,
1115 PWR_MODE_FULL_ACTIVE, 0, false); 1134 PWR_MODE_FULL_ACTIVE, 0, CYAPA_PM_ACTIVE);
1116 if (error) 1135 if (error)
1117 dev_err(dev, "%s: set full power mode failed: %d\n", 1136 dev_err(dev, "%s: set full power mode failed: %d\n",
1118 __func__, error); 1137 __func__, error);
@@ -1168,32 +1187,16 @@ static bool cyapa_gen3_irq_cmd_handler(struct cyapa *cyapa)
1168 return false; 1187 return false;
1169} 1188}
1170 1189
1171static int cyapa_gen3_irq_handler(struct cyapa *cyapa) 1190static int cyapa_gen3_event_process(struct cyapa *cyapa,
1191 struct cyapa_reg_data *data)
1172{ 1192{
1173 struct input_dev *input = cyapa->input; 1193 struct input_dev *input = cyapa->input;
1174 struct device *dev = &cyapa->client->dev;
1175 struct cyapa_reg_data data;
1176 int num_fingers; 1194 int num_fingers;
1177 int ret;
1178 int i; 1195 int i;
1179 1196
1180 ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_DATA, (u8 *)&data); 1197 num_fingers = (data->finger_btn >> 4) & 0x0f;
1181 if (ret != sizeof(data)) {
1182 dev_err(dev, "failed to read report data, (%d)\n", ret);
1183 return -EINVAL;
1184 }
1185
1186 if ((data.device_status & OP_STATUS_SRC) != OP_STATUS_SRC ||
1187 (data.device_status & OP_STATUS_DEV) != CYAPA_DEV_NORMAL ||
1188 (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID) {
1189 dev_err(dev, "invalid device state bytes, %02x %02x\n",
1190 data.device_status, data.finger_btn);
1191 return -EINVAL;
1192 }
1193
1194 num_fingers = (data.finger_btn >> 4) & 0x0f;
1195 for (i = 0; i < num_fingers; i++) { 1198 for (i = 0; i < num_fingers; i++) {
1196 const struct cyapa_touch *touch = &data.touches[i]; 1199 const struct cyapa_touch *touch = &data->touches[i];
1197 /* Note: touch->id range is 1 to 15; slots are 0 to 14. */ 1200 /* Note: touch->id range is 1 to 15; slots are 0 to 14. */
1198 int slot = touch->id - 1; 1201 int slot = touch->id - 1;
1199 1202
@@ -1210,18 +1213,65 @@ static int cyapa_gen3_irq_handler(struct cyapa *cyapa)
1210 1213
1211 if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK) 1214 if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK)
1212 input_report_key(input, BTN_LEFT, 1215 input_report_key(input, BTN_LEFT,
1213 !!(data.finger_btn & OP_DATA_LEFT_BTN)); 1216 !!(data->finger_btn & OP_DATA_LEFT_BTN));
1214 if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK) 1217 if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK)
1215 input_report_key(input, BTN_MIDDLE, 1218 input_report_key(input, BTN_MIDDLE,
1216 !!(data.finger_btn & OP_DATA_MIDDLE_BTN)); 1219 !!(data->finger_btn & OP_DATA_MIDDLE_BTN));
1217 if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK) 1220 if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK)
1218 input_report_key(input, BTN_RIGHT, 1221 input_report_key(input, BTN_RIGHT,
1219 !!(data.finger_btn & OP_DATA_RIGHT_BTN)); 1222 !!(data->finger_btn & OP_DATA_RIGHT_BTN));
1220 input_sync(input); 1223 input_sync(input);
1221 1224
1222 return 0; 1225 return 0;
1223} 1226}
1224 1227
1228static int cyapa_gen3_irq_handler(struct cyapa *cyapa)
1229{
1230 struct device *dev = &cyapa->client->dev;
1231 struct cyapa_reg_data data;
1232 int ret;
1233
1234 ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_DATA, (u8 *)&data);
1235 if (ret != sizeof(data)) {
1236 dev_err(dev, "failed to read report data, (%d)\n", ret);
1237 return -EINVAL;
1238 }
1239
1240 if ((data.device_status & OP_STATUS_SRC) != OP_STATUS_SRC ||
1241 (data.device_status & OP_STATUS_DEV) != CYAPA_DEV_NORMAL ||
1242 (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID) {
1243 dev_err(dev, "invalid device state bytes: %02x %02x\n",
1244 data.device_status, data.finger_btn);
1245 return -EINVAL;
1246 }
1247
1248 return cyapa_gen3_event_process(cyapa, &data);
1249}
1250
1251/*
1252 * This function will be called in the cyapa_gen3_set_power_mode function,
1253 * and it's known that it may failed in some situation after the set power
1254 * mode command was sent. So this function is aimed to avoid the knwon
1255 * and unwanted output I2C and data parse error messages.
1256 */
1257static int cyapa_gen3_try_poll_handler(struct cyapa *cyapa)
1258{
1259 struct cyapa_reg_data data;
1260 int ret;
1261
1262 ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_DATA, (u8 *)&data);
1263 if (ret != sizeof(data))
1264 return -EINVAL;
1265
1266 if ((data.device_status & OP_STATUS_SRC) != OP_STATUS_SRC ||
1267 (data.device_status & OP_STATUS_DEV) != CYAPA_DEV_NORMAL ||
1268 (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID)
1269 return -EINVAL;
1270
1271 return cyapa_gen3_event_process(cyapa, &data);
1272
1273}
1274
1225static int cyapa_gen3_initialize(struct cyapa *cyapa) { return 0; } 1275static int cyapa_gen3_initialize(struct cyapa *cyapa) { return 0; }
1226static int cyapa_gen3_bl_initiate(struct cyapa *cyapa, 1276static int cyapa_gen3_bl_initiate(struct cyapa *cyapa,
1227 const struct firmware *fw) { return 0; } 1277 const struct firmware *fw) { return 0; }
diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c
index 118ba977181e..5775d40b3d53 100644
--- a/drivers/input/mouse/cyapa_gen5.c
+++ b/drivers/input/mouse/cyapa_gen5.c
@@ -342,6 +342,9 @@ u8 pip_bl_read_app_info[] = { 0x04, 0x00, 0x0b, 0x00, 0x40, 0x00,
342static u8 cyapa_pip_bl_cmd_key[] = { 0xa5, 0x01, 0x02, 0x03, 342static u8 cyapa_pip_bl_cmd_key[] = { 0xa5, 0x01, 0x02, 0x03,
343 0xff, 0xfe, 0xfd, 0x5a }; 343 0xff, 0xfe, 0xfd, 0x5a };
344 344
345static int cyapa_pip_event_process(struct cyapa *cyapa,
346 struct cyapa_pip_report_data *report_data);
347
345int cyapa_pip_cmd_state_initialize(struct cyapa *cyapa) 348int cyapa_pip_cmd_state_initialize(struct cyapa *cyapa)
346{ 349{
347 struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip; 350 struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
@@ -350,6 +353,9 @@ int cyapa_pip_cmd_state_initialize(struct cyapa *cyapa)
350 atomic_set(&pip->cmd_issued, 0); 353 atomic_set(&pip->cmd_issued, 0);
351 mutex_init(&pip->cmd_lock); 354 mutex_init(&pip->cmd_lock);
352 355
356 mutex_init(&pip->pm_stage_lock);
357 pip->pm_stage = CYAPA_PM_DEACTIVE;
358
353 pip->resp_sort_func = NULL; 359 pip->resp_sort_func = NULL;
354 pip->in_progress_cmd = PIP_INVALID_CMD; 360 pip->in_progress_cmd = PIP_INVALID_CMD;
355 pip->resp_data = NULL; 361 pip->resp_data = NULL;
@@ -397,6 +403,38 @@ ssize_t cyapa_i2c_pip_write(struct cyapa *cyapa, u8 *buf, size_t size)
397 return 0; 403 return 0;
398} 404}
399 405
406static void cyapa_set_pip_pm_state(struct cyapa *cyapa,
407 enum cyapa_pm_stage pm_stage)
408{
409 struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
410
411 mutex_lock(&pip->pm_stage_lock);
412 pip->pm_stage = pm_stage;
413 mutex_unlock(&pip->pm_stage_lock);
414}
415
416static void cyapa_reset_pip_pm_state(struct cyapa *cyapa)
417{
418 struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
419
420 /* Indicates the pip->pm_stage is not valid. */
421 mutex_lock(&pip->pm_stage_lock);
422 pip->pm_stage = CYAPA_PM_DEACTIVE;
423 mutex_unlock(&pip->pm_stage_lock);
424}
425
426static enum cyapa_pm_stage cyapa_get_pip_pm_state(struct cyapa *cyapa)
427{
428 struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
429 enum cyapa_pm_stage pm_stage;
430
431 mutex_lock(&pip->pm_stage_lock);
432 pm_stage = pip->pm_stage;
433 mutex_unlock(&pip->pm_stage_lock);
434
435 return pm_stage;
436}
437
400/** 438/**
401 * This function is aimed to dump all not read data in Gen5 trackpad 439 * This function is aimed to dump all not read data in Gen5 trackpad
402 * before send any command, otherwise, the interrupt line will be blocked. 440 * before send any command, otherwise, the interrupt line will be blocked.
@@ -404,7 +442,9 @@ ssize_t cyapa_i2c_pip_write(struct cyapa *cyapa, u8 *buf, size_t size)
404int cyapa_empty_pip_output_data(struct cyapa *cyapa, 442int cyapa_empty_pip_output_data(struct cyapa *cyapa,
405 u8 *buf, int *len, cb_sort func) 443 u8 *buf, int *len, cb_sort func)
406{ 444{
445 struct input_dev *input = cyapa->input;
407 struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip; 446 struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
447 enum cyapa_pm_stage pm_stage = cyapa_get_pip_pm_state(cyapa);
408 int length; 448 int length;
409 int report_count; 449 int report_count;
410 int empty_count; 450 int empty_count;
@@ -478,6 +518,12 @@ int cyapa_empty_pip_output_data(struct cyapa *cyapa,
478 *len = length; 518 *len = length;
479 /* Response found, success. */ 519 /* Response found, success. */
480 return 0; 520 return 0;
521 } else if (cyapa->operational && input && input->users &&
522 (pm_stage == CYAPA_PM_RUNTIME_RESUME ||
523 pm_stage == CYAPA_PM_RUNTIME_SUSPEND)) {
524 /* Parse the data and report it if it's valid. */
525 cyapa_pip_event_process(cyapa,
526 (struct cyapa_pip_report_data *)pip->empty_buf);
481 } 527 }
482 528
483 error = -EINVAL; 529 error = -EINVAL;
@@ -1566,15 +1612,17 @@ int cyapa_pip_deep_sleep(struct cyapa *cyapa, u8 state)
1566} 1612}
1567 1613
1568static int cyapa_gen5_set_power_mode(struct cyapa *cyapa, 1614static int cyapa_gen5_set_power_mode(struct cyapa *cyapa,
1569 u8 power_mode, u16 sleep_time, bool is_suspend) 1615 u8 power_mode, u16 sleep_time, enum cyapa_pm_stage pm_stage)
1570{ 1616{
1571 struct device *dev = &cyapa->client->dev; 1617 struct device *dev = &cyapa->client->dev;
1572 u8 power_state; 1618 u8 power_state;
1573 int error; 1619 int error = 0;
1574 1620
1575 if (cyapa->state != CYAPA_STATE_GEN5_APP) 1621 if (cyapa->state != CYAPA_STATE_GEN5_APP)
1576 return 0; 1622 return 0;
1577 1623
1624 cyapa_set_pip_pm_state(cyapa, pm_stage);
1625
1578 if (PIP_DEV_GET_PWR_STATE(cyapa) == UNINIT_PWR_MODE) { 1626 if (PIP_DEV_GET_PWR_STATE(cyapa) == UNINIT_PWR_MODE) {
1579 /* 1627 /*
1580 * Assume TP in deep sleep mode when driver is loaded, 1628 * Assume TP in deep sleep mode when driver is loaded,
@@ -1597,7 +1645,7 @@ static int cyapa_gen5_set_power_mode(struct cyapa *cyapa,
1597 power_mode == PWR_MODE_BTN_ONLY || 1645 power_mode == PWR_MODE_BTN_ONLY ||
1598 PIP_DEV_GET_SLEEP_TIME(cyapa) == sleep_time) { 1646 PIP_DEV_GET_SLEEP_TIME(cyapa) == sleep_time) {
1599 /* Has in correct power mode state, early return. */ 1647 /* Has in correct power mode state, early return. */
1600 return 0; 1648 goto out;
1601 } 1649 }
1602 } 1650 }
1603 1651
@@ -1605,11 +1653,11 @@ static int cyapa_gen5_set_power_mode(struct cyapa *cyapa,
1605 error = cyapa_pip_deep_sleep(cyapa, PIP_DEEP_SLEEP_STATE_OFF); 1653 error = cyapa_pip_deep_sleep(cyapa, PIP_DEEP_SLEEP_STATE_OFF);
1606 if (error) { 1654 if (error) {
1607 dev_err(dev, "enter deep sleep fail: %d\n", error); 1655 dev_err(dev, "enter deep sleep fail: %d\n", error);
1608 return error; 1656 goto out;
1609 } 1657 }
1610 1658
1611 PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_OFF); 1659 PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_OFF);
1612 return 0; 1660 goto out;
1613 } 1661 }
1614 1662
1615 /* 1663 /*
@@ -1621,7 +1669,7 @@ static int cyapa_gen5_set_power_mode(struct cyapa *cyapa,
1621 error = cyapa_pip_deep_sleep(cyapa, PIP_DEEP_SLEEP_STATE_ON); 1669 error = cyapa_pip_deep_sleep(cyapa, PIP_DEEP_SLEEP_STATE_ON);
1622 if (error) { 1670 if (error) {
1623 dev_err(dev, "deep sleep wake fail: %d\n", error); 1671 dev_err(dev, "deep sleep wake fail: %d\n", error);
1624 return error; 1672 goto out;
1625 } 1673 }
1626 } 1674 }
1627 1675
@@ -1630,7 +1678,7 @@ static int cyapa_gen5_set_power_mode(struct cyapa *cyapa,
1630 GEN5_POWER_STATE_ACTIVE); 1678 GEN5_POWER_STATE_ACTIVE);
1631 if (error) { 1679 if (error) {
1632 dev_err(dev, "change to active fail: %d\n", error); 1680 dev_err(dev, "change to active fail: %d\n", error);
1633 return error; 1681 goto out;
1634 } 1682 }
1635 1683
1636 PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_FULL_ACTIVE); 1684 PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_FULL_ACTIVE);
@@ -1639,7 +1687,7 @@ static int cyapa_gen5_set_power_mode(struct cyapa *cyapa,
1639 GEN5_POWER_STATE_BTN_ONLY); 1687 GEN5_POWER_STATE_BTN_ONLY);
1640 if (error) { 1688 if (error) {
1641 dev_err(dev, "fail to button only mode: %d\n", error); 1689 dev_err(dev, "fail to button only mode: %d\n", error);
1642 return error; 1690 goto out;
1643 } 1691 }
1644 1692
1645 PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_BTN_ONLY); 1693 PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_BTN_ONLY);
@@ -1664,7 +1712,7 @@ static int cyapa_gen5_set_power_mode(struct cyapa *cyapa,
1664 if (error) { 1712 if (error) {
1665 dev_err(dev, "set power state to 0x%02x failed: %d\n", 1713 dev_err(dev, "set power state to 0x%02x failed: %d\n",
1666 power_state, error); 1714 power_state, error);
1667 return error; 1715 goto out;
1668 } 1716 }
1669 1717
1670 /* 1718 /*
@@ -1677,14 +1725,16 @@ static int cyapa_gen5_set_power_mode(struct cyapa *cyapa,
1677 * is suspending which may cause interrupt line unable to be 1725 * is suspending which may cause interrupt line unable to be
1678 * asserted again. 1726 * asserted again.
1679 */ 1727 */
1680 if (is_suspend) 1728 if (pm_stage == CYAPA_PM_SUSPEND)
1681 cyapa_gen5_disable_pip_report(cyapa); 1729 cyapa_gen5_disable_pip_report(cyapa);
1682 1730
1683 PIP_DEV_SET_PWR_STATE(cyapa, 1731 PIP_DEV_SET_PWR_STATE(cyapa,
1684 cyapa_sleep_time_to_pwr_cmd(sleep_time)); 1732 cyapa_sleep_time_to_pwr_cmd(sleep_time));
1685 } 1733 }
1686 1734
1687 return 0; 1735out:
1736 cyapa_reset_pip_pm_state(cyapa);
1737 return error;
1688} 1738}
1689 1739
1690int cyapa_pip_resume_scanning(struct cyapa *cyapa) 1740int cyapa_pip_resume_scanning(struct cyapa *cyapa)
@@ -2513,7 +2563,7 @@ static int cyapa_gen5_do_operational_check(struct cyapa *cyapa)
2513 * the device state is required. 2563 * the device state is required.
2514 */ 2564 */
2515 error = cyapa_gen5_set_power_mode(cyapa, 2565 error = cyapa_gen5_set_power_mode(cyapa,
2516 PWR_MODE_FULL_ACTIVE, 0, false); 2566 PWR_MODE_FULL_ACTIVE, 0, CYAPA_PM_ACTIVE);
2517 if (error) 2567 if (error)
2518 dev_warn(dev, "%s: failed to set power active mode.\n", 2568 dev_warn(dev, "%s: failed to set power active mode.\n",
2519 __func__); 2569 __func__);
@@ -2715,7 +2765,6 @@ int cyapa_pip_irq_handler(struct cyapa *cyapa)
2715 struct device *dev = &cyapa->client->dev; 2765 struct device *dev = &cyapa->client->dev;
2716 struct cyapa_pip_report_data report_data; 2766 struct cyapa_pip_report_data report_data;
2717 unsigned int report_len; 2767 unsigned int report_len;
2718 u8 report_id;
2719 int ret; 2768 int ret;
2720 2769
2721 if (!cyapa_is_pip_app_mode(cyapa)) { 2770 if (!cyapa_is_pip_app_mode(cyapa)) {
@@ -2752,7 +2801,23 @@ int cyapa_pip_irq_handler(struct cyapa *cyapa)
2752 return -EINVAL; 2801 return -EINVAL;
2753 } 2802 }
2754 2803
2755 report_id = report_data.report_head[PIP_RESP_REPORT_ID_OFFSET]; 2804 return cyapa_pip_event_process(cyapa, &report_data);
2805}
2806
2807static int cyapa_pip_event_process(struct cyapa *cyapa,
2808 struct cyapa_pip_report_data *report_data)
2809{
2810 struct device *dev = &cyapa->client->dev;
2811 unsigned int report_len;
2812 u8 report_id;
2813
2814 report_len = get_unaligned_le16(
2815 &report_data->report_head[PIP_RESP_LENGTH_OFFSET]);
2816 /* Idle, no data for report. */
2817 if (report_len == PIP_RESP_LENGTH_SIZE)
2818 return 0;
2819
2820 report_id = report_data->report_head[PIP_RESP_REPORT_ID_OFFSET];
2756 if (report_id == PIP_WAKEUP_EVENT_REPORT_ID && 2821 if (report_id == PIP_WAKEUP_EVENT_REPORT_ID &&
2757 report_len == PIP_WAKEUP_EVENT_SIZE) { 2822 report_len == PIP_WAKEUP_EVENT_SIZE) {
2758 /* 2823 /*
@@ -2805,11 +2870,11 @@ int cyapa_pip_irq_handler(struct cyapa *cyapa)
2805 } 2870 }
2806 2871
2807 if (report_id == PIP_TOUCH_REPORT_ID) 2872 if (report_id == PIP_TOUCH_REPORT_ID)
2808 cyapa_pip_report_touches(cyapa, &report_data); 2873 cyapa_pip_report_touches(cyapa, report_data);
2809 else if (report_id == PIP_PROXIMITY_REPORT_ID) 2874 else if (report_id == PIP_PROXIMITY_REPORT_ID)
2810 cyapa_pip_report_proximity(cyapa, &report_data); 2875 cyapa_pip_report_proximity(cyapa, report_data);
2811 else 2876 else
2812 cyapa_pip_report_buttons(cyapa, &report_data); 2877 cyapa_pip_report_buttons(cyapa, report_data);
2813 2878
2814 return 0; 2879 return 0;
2815} 2880}
diff --git a/drivers/input/mouse/cyapa_gen6.c b/drivers/input/mouse/cyapa_gen6.c
index e4eb048d1bf6..016397850b1b 100644
--- a/drivers/input/mouse/cyapa_gen6.c
+++ b/drivers/input/mouse/cyapa_gen6.c
@@ -425,7 +425,7 @@ static int cyapa_gen6_deep_sleep(struct cyapa *cyapa, u8 state)
425} 425}
426 426
427static int cyapa_gen6_set_power_mode(struct cyapa *cyapa, 427static int cyapa_gen6_set_power_mode(struct cyapa *cyapa,
428 u8 power_mode, u16 sleep_time, bool is_suspend) 428 u8 power_mode, u16 sleep_time, enum cyapa_pm_stage pm_stage)
429{ 429{
430 struct device *dev = &cyapa->client->dev; 430 struct device *dev = &cyapa->client->dev;
431 struct gen6_interval_setting *interval_setting = 431 struct gen6_interval_setting *interval_setting =
@@ -689,7 +689,7 @@ static int cyapa_gen6_operational_check(struct cyapa *cyapa)
689 * the device state is required. 689 * the device state is required.
690 */ 690 */
691 error = cyapa_gen6_set_power_mode(cyapa, 691 error = cyapa_gen6_set_power_mode(cyapa,
692 PWR_MODE_FULL_ACTIVE, 0, false); 692 PWR_MODE_FULL_ACTIVE, 0, CYAPA_PM_ACTIVE);
693 if (error) 693 if (error)
694 dev_warn(dev, "%s: failed to set power active mode.\n", 694 dev_warn(dev, "%s: failed to set power active mode.\n",
695 __func__); 695 __func__);