PCMCIA / PM: Avoid noirq suspend aborts during suspend-to-idle
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 21 Feb 2018 12:24:16 +0000 (13:24 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 May 2018 05:52:39 +0000 (07:52 +0200)
commita548ba4de32eaabeba42ebd2ba918c3fc68ea101
tree4b82f94eb51a83383142b51b10153733e275a50f
parent7d5ab9bf4f3404159ba3978c81a823e49b925dd0
PCMCIA / PM: Avoid noirq suspend aborts during suspend-to-idle

[ Upstream commit dbdd0f58fd2cdde5cf945c9da67a2d52d32ba550 ]

There is a problem with PCMCIA system resume callbacks with respect
to suspend-to-idle in which the ->suspend_noirq() callback may be
invoked after the ->resume_noirq() one without resuming the system
entirely in some cases.  This doesn't work for PCMCIA because of
the lack of symmetry between its system suspend and system resume
"noirq" callbacks.

The system resume handling in PCMCIA is split between
socket_early_resume() and socket_late_resume() which are called in
different phases of system resume and both need to run for
socket_suspend() (invoked by the system suspend "noirq" callback)
to work.  Specifically, socket_suspend() returns an error when
called after socket_early_resume() without socket_late_resume(),
so if the suspend-to-idle core detects a spurious wakeup event and
attempts to put the system back to sleep, that is aborted by the
error coming from socket_suspend().

Avoid that by using a new socket state flag, SOCKET_IN_RESUME,
to indicate that socket_early_resume() has already run for the
socket in which case socket_suspend() will do minimum handling
and return 0.

This change has been tested on my venerable Toshiba Portege R500
(which is where the problem has been discovered in the first place),
but admittedly I have no PCMCIA cards to test along with the socket
itself.

Fixes: 33e4f80ee69b (ACPI / PM: Ignore spurious SCI wakeups from suspend-to-idle)
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
[linux@dominikbrodowski.net: follow same codepaths for both suspend variants; call ->suspend()]
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/pcmcia/cs.c
drivers/pcmcia/cs_internal.h