hwmon/mpu3050: move disable/enable irq in early_suspend/resume to avoid deadlock.
authorTang Guifang <guifang.tang@intel.com>
Wed, 2 May 2012 03:48:05 +0000 (11:48 +0800)
committerbuildbot <buildbot@intel.com>
Thu, 3 May 2012 11:37:05 +0000 (04:37 -0700)
BZ: 34000

When mpu_early_suspend() is called, it firstly calls mutex_lock(&mpu->lock).
then disable_irq(). If there is a mpu interrupt during this lock and
disable_irq, mpu interrupt handler mpu_isr() will be called.
In mpr_isr(), it will wait for mpu->lock, but in mpu_early_suspend(),
disable_irq() won't return untill mpr_isr end. Then a dead lock happens.

Change-Id: I83b339bf52ce74cffe9b43120a1047d1d9d6c4a5
Signed-off-by: Tang Guifang <guifang.tang@intel.com>
Reviewed-on: http://android.intel.com:8080/46669
Reviewed-by: Liu, Hong <hong.liu@intel.com>
Reviewed-by: Pan, Zhenjie <zhenjie.pan@intel.com>
Reviewed-by: Du, Alek <alek.du@intel.com>
Reviewed-by: Koskinen, Ilkka <ilkka.koskinen@intel.com>
Tested-by: Wang, Zhifeng <zhifeng.wang@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/hwmon/mpu3050.c

index 4aec054..ec97988 100644 (file)
@@ -578,9 +578,10 @@ static void mpu_early_suspend(struct early_suspend *h)
 {
        struct mpu_data *mpu = container_of(h, struct mpu_data, es);
 
+       disable_irq(mpu->client->irq);
+
        mutex_lock(&mpu->lock);
        mpu_disable(mpu);
-       disable_irq(mpu->client->irq);
        mutex_unlock(&mpu->lock);
 }
 
@@ -588,8 +589,9 @@ static void mpu_late_resume(struct early_suspend *h)
 {
        struct mpu_data *mpu = container_of(h, struct mpu_data, es);
 
-       mutex_lock(&mpu->lock);
        enable_irq(mpu->client->irq);
+
+       mutex_lock(&mpu->lock);
        if (mpu->enabled)
                mpu_enable(mpu);
        mutex_unlock(&mpu->lock);