From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nigel Cunningham Subject: [PATCH] Complain if driver reenables interrupts during drivers_[suspend|resume] & re-disable Date: Tue, 7 Feb 2006 19:06:48 +1000 Message-ID: <200602071906.55281.ncunningham@cyclades.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============79549902752071366==" Return-path: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-pm-bounces@lists.osdl.org Errors-To: linux-pm-bounces@lists.osdl.org To: Linux PM , linux-kernel@vger.kernel.org, Andrew Morton List-Id: linux-pm@vger.kernel.org --===============79549902752071366== Content-Type: multipart/signed; boundary="nextPart21107747.Ms9F2Pm8Tg"; protocol="application/pgp-signature"; micalg=pgp-sha1 Content-Transfer-Encoding: 7bit --nextPart21107747.Ms9F2Pm8Tg Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Hi all. This patch is designed to help with diagnosing and fixing the cause of problems in suspending/resuming, due to drivers wrongly re-enabling interrupts in their .suspend or .resume methods.=20 I nearly forgot about it in sending patches in suspend2 that might help where swsusp fails. Signed-off-by: Nigel Cunningham power/resume.c | 5 +++++ power/suspend.c | 5 +++++ sys.c | 37 +++++++++++++++++++++++++++++++++++-- 3 files changed, 45 insertions(+), 2 deletions(-) diff -ruNp 8010-driver-model-debug.patch-old/drivers/base/power/resume.c=20 8010-driver-model-debug.patch-new/drivers/base/power/resume.c =2D-- 8010-driver-model-debug.patch-old/drivers/base/power/resume.c=09 2006-01-19 21:27:39.000000000 +1000 +++ 8010-driver-model-debug.patch-new/drivers/base/power/resume.c=09 2006-01-31 19:54:52.000000000 +1000 @@ -35,6 +35,11 @@ int resume_device(struct device * dev) if (dev->bus && dev->bus->resume) { dev_dbg(dev,"resuming\n"); error =3D dev->bus->resume(dev); + if (!irqs_disabled()) { + printk(KERN_EMERG "WARNING: Interrupts reenabled while resuming device= =20 %s.\n", + kobject_name(&dev->kobj)); + local_irq_disable(); + } } up(&dev->sem); return error; diff -ruNp 8010-driver-model-debug.patch-old/drivers/base/power/suspend.c=20 8010-driver-model-debug.patch-new/drivers/base/power/suspend.c =2D-- 8010-driver-model-debug.patch-old/drivers/base/power/suspend.c=09 2006-01-19 21:27:39.000000000 +1000 +++ 8010-driver-model-debug.patch-new/drivers/base/power/suspend.c=09 2006-01-31 19:54:44.000000000 +1000 @@ -58,6 +58,11 @@ int suspend_device(struct device * dev,=20 if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { dev_dbg(dev, "suspending\n"); error =3D dev->bus->suspend(dev, state); + if (!irqs_disabled()) { + printk(KERN_EMERG "WARNING: Interrupts reenabled while suspending=20 device %s.\n", + kobject_name(&dev->kobj)); + local_irq_disable(); + } } up(&dev->sem); return error; diff -ruNp 8010-driver-model-debug.patch-old/drivers/base/sys.c=20 8010-driver-model-debug.patch-new/drivers/base/sys.c =2D-- 8010-driver-model-debug.patch-old/drivers/base/sys.c 2006-01-19=20 21:27:39.000000000 +1000 +++ 8010-driver-model-debug.patch-new/drivers/base/sys.c 2006-01-31=20 19:54:09.000000000 +1000 @@ -298,16 +298,34 @@ static void __sysdev_resume(struct sys_d if (cls->resume) cls->resume(dev); =20 + if (!irqs_disabled()) { + printk(KERN_EMERG "WARNING: Interrupts reenabled while resuming sysdev=20 class specific driver %s.\n", + kobject_name(&dev->kobj)); + local_irq_disable(); + } + /* Call auxillary drivers next. */ list_for_each_entry(drv, &cls->drivers, entry) { =2D if (drv->resume) + if (drv->resume) { drv->resume(dev); + if (!irqs_disabled()) { + printk(KERN_EMERG "WARNING: Interrupts reenabled while resuming sysdev= =20 class driver %s.\n", + kobject_name(&dev->kobj)); + local_irq_disable(); + } + } } =20 /* Call global drivers. */ list_for_each_entry(drv, &sysdev_drivers, entry) { =2D if (drv->resume) + if (drv->resume) { drv->resume(dev); + if (!irqs_disabled()) { + printk(KERN_EMERG "WARNING: Interrupts reenabled while resuming sysdev= =20 driver %s.\n", + kobject_name(&dev->kobj)); + local_irq_disable(); + } + } } } =20 @@ -346,6 +364,11 @@ int sysdev_suspend(pm_message_t state) list_for_each_entry(drv, &sysdev_drivers, entry) { if (drv->suspend) { ret =3D drv->suspend(sysdev, state); + if (!irqs_disabled()) { + printk(KERN_EMERG "WARNING: Interrupts reenabled while suspending=20 sysdev driver %s.\n", + kobject_name(&sysdev->kobj)); + local_irq_disable(); + } if (ret) goto gbl_driver; } @@ -355,6 +378,11 @@ int sysdev_suspend(pm_message_t state) list_for_each_entry(drv, &cls->drivers, entry) { if (drv->suspend) { ret =3D drv->suspend(sysdev, state); + if (!irqs_disabled()) { + printk(KERN_EMERG "WARNING: Interrupts reenabled while suspending=20 sysdev class driver %s.\n", + kobject_name(&sysdev->kobj)); + local_irq_disable(); + } if (ret) goto aux_driver; } @@ -363,6 +391,11 @@ int sysdev_suspend(pm_message_t state) /* Now call the generic one */ if (cls->suspend) { ret =3D cls->suspend(sysdev, state); + if (!irqs_disabled()) { + printk(KERN_EMERG "WARNING: Interrupts reenabled while suspending=20 class driver %s.\n", + kobject_name(&sysdev->kobj)); + local_irq_disable(); + } if (ret) goto cls_driver; } --nextPart21107747.Ms9F2Pm8Tg Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQBD6GMvN0y+n1M3mo0RAq03AJ9bc9T+eZzhQarqmT0LAOrJ/LH7HwCfVI0Y lrCvt4yT7ujBT7NywX1QLF8= =crMH -----END PGP SIGNATURE----- --nextPart21107747.Ms9F2Pm8Tg-- --===============79549902752071366== Content-Type: text/plain; charset="iso-8859-1" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline --===============79549902752071366==--