misc: cec: defer suspend if init is in progress
Deepak Nibade [Tue, 24 Sep 2013 10:13:11 +0000 (15:13 +0530)]
- there is below race condition in cec driver :
  -tegra_cec_init() is in progress which is setting many registers
  -suspend is called at the same time
  -tegra_cec_suspend() disables clock before tegra_cec_init() completes
- above race condition hangs the system with trying to write cec
  register while clock is off
- fix this race condition by deferring suspend if init is still in
  progress

Bug 1360341

Change-Id: I0450db565e864f289d1ce5af13b43ee8ad4f0ee6
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/278381
(cherry picked from commit 58effacbdd01c2b6e71023cae828b2eaddbbb4bf)
Reviewed-on: http://git-master/r/278324
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>

drivers/misc/tegra-cec/tegra_cec.c

index 3ec1267..e125aa1 100644 (file)
@@ -378,6 +378,13 @@ static int tegra_cec_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct tegra_cec *cec = platform_get_drvdata(pdev);
 
+       /* defer suspend if init is still in progress */
+       if (cec->init_done == 0) {
+               dev_err(&pdev->dev,
+                               "Init still in progress. Aborting suspend\n");
+               return -EBUSY;
+       }
+
        clk_disable(cec->clk);
 
        dev_notice(&pdev->dev, "suspended\n");