]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
greybus: arche-platform: Reset SVC & APB only if turned off by SUSPEND_PREPARE
authorVaibhav Hiremath <hiremath_vaibhav@projectara.com>
Wed, 3 Aug 2016 11:45:38 +0000 (17:15 +0530)
committerGreg Kroah-Hartman <gregkh@google.com>
Wed, 3 Aug 2016 13:43:51 +0000 (15:43 +0200)
There is possible race condition in arche platform driver for
maintaining of ->state field, when shared with timesync driver.

Assume device booted fine, all connected modules have been enumerated
correctly. As part of suspend-resume operation we have pm_notifier
callback, where we turn off SVC & APB and coldboot on resume.
In the process of resume, all modules gets enumerated again, and
timesync driver does come into picture everytime.
So when timesync driver requests arche-platform to change the state
to TIMESYNC and in the middle of sync operation, if suspend gets
triggered, then execution lands into arche-platform->pm_notifier callback,
leading to race condition in the driver, where it checks for (state != ACTIVE)
in PM_SUSPEND_PREPARE and returns, but in PM_POST_SUSPEND it just simply
coldboots SVC & APB, which would inbalance all resources (including IRQ).

So we need a add check in PM_POST_SUSPEND, to make sure that, we only
coldboot devices if they are in to off state,
i.e. if (state != OFF) then return.

Testing Done: Done regressive suspend/resume testing on EVT2 platform.
Note that, I some time hit issue.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/arche-platform.c

index cbe8bdcabceb6d743c90e94673b5950e99a29d21..adec1fdcb5bbc58259c9a7736594bfb2d73c37bd 100644 (file)
@@ -548,6 +548,9 @@ static int arche_platform_pm_notifier(struct notifier_block *notifier,
                arche_platform_poweroff_seq(arche_pdata);
                break;
        case PM_POST_SUSPEND:
+               if (arche_pdata->state != ARCHE_PLATFORM_STATE_OFF)
+                       break;
+
                arche_platform_wd_irq_en(arche_pdata);
                arche_platform_coldboot_seq(arche_pdata);
                break;