Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

platform/chrome: cros_ec_lightbar - Avoid I2C xfer to EC during suspend

A Mutex lock in cros_ec_cmd_xfer which may be held by frozen
Userspace thread during system suspending. So should not
call this routine in suspend thread.

Signed-off-by: Jeffery Yu <jefferyy@nvidia.com>
Signed-off-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: Benson Leung <bleung@chromium.org>

authored by

Jeffery Yu and committed by
Benson Leung
995c0ec9 abbb054d

+13 -12
+4 -8
drivers/platform/chrome/cros_ec_dev.c
··· 437 437 cros_ec_sensors_register(ec); 438 438 439 439 /* Take control of the lightbar from the EC. */ 440 - if (ec_has_lightbar(ec)) 441 - lb_manual_suspend_ctrl(ec, 1); 440 + lb_manual_suspend_ctrl(ec, 1); 442 441 443 442 return 0; 444 443 ··· 451 452 struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev); 452 453 453 454 /* Let the EC take over the lightbar again. */ 454 - if (ec_has_lightbar(ec)) 455 - lb_manual_suspend_ctrl(ec, 0); 455 + lb_manual_suspend_ctrl(ec, 0); 456 456 457 457 cros_ec_debugfs_remove(ec); 458 458 ··· 470 472 { 471 473 struct cros_ec_dev *ec = dev_get_drvdata(dev); 472 474 473 - if (ec_has_lightbar(ec)) 474 - lb_suspend(ec); 475 + lb_suspend(ec); 475 476 476 477 return 0; 477 478 } ··· 479 482 { 480 483 struct cros_ec_dev *ec = dev_get_drvdata(dev); 481 484 482 - if (ec_has_lightbar(ec)) 483 - lb_resume(ec); 485 + lb_resume(ec); 484 486 485 487 return 0; 486 488 }
+9 -4
drivers/platform/chrome/cros_ec_lightbar.c
··· 43 43 * If this is true, we won't do anything during suspend/resume. 44 44 */ 45 45 static bool userspace_control; 46 + static struct cros_ec_dev *ec_with_lightbar; 46 47 47 48 static ssize_t interval_msec_show(struct device *dev, 48 49 struct device_attribute *attr, char *buf) ··· 385 384 struct cros_ec_command *msg; 386 385 int ret; 387 386 387 + if (ec != ec_with_lightbar) 388 + return 0; 389 + 388 390 msg = alloc_lightbar_cmd_msg(ec); 389 391 if (!msg) 390 392 return -ENOMEM; ··· 417 413 418 414 int lb_suspend(struct cros_ec_dev *ec) 419 415 { 420 - if (userspace_control) 416 + if (userspace_control || ec != ec_with_lightbar) 421 417 return 0; 422 418 423 419 return lb_send_empty_cmd(ec, LIGHTBAR_CMD_SUSPEND); ··· 425 421 426 422 int lb_resume(struct cros_ec_dev *ec) 427 423 { 428 - if (userspace_control) 424 + if (userspace_control || ec != ec_with_lightbar) 429 425 return 0; 430 426 431 427 return lb_send_empty_cmd(ec, LIGHTBAR_CMD_RESUME); ··· 610 606 return 0; 611 607 612 608 /* Only instantiate this stuff if the EC has a lightbar */ 613 - if (ec_has_lightbar(ec)) 609 + if (ec_has_lightbar(ec)) { 610 + ec_with_lightbar = ec; 614 611 return a->mode; 615 - 612 + } 616 613 return 0; 617 614 } 618 615