From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Kernel Testers List <kernel-testers@vger.kernel.org>,
Greg Kroah-Hartman <gregkh@suse.de>,
Jose Marino <braket@hotmail.com>,
ACPI Devel Maling List <linux-acpi@vger.kernel.org>,
Linux PCI <linux-pci@vger.kernel.org>,
Dominik Brodowski <linux@dominikbrodowski.net>
Subject: Re: Help needed, Re: [Bug #14334] pcmcia suspend regression from 2.6.31.1 to 2.6.31.2 - Dell Inspiron 600m
Date: Sat, 31 Oct 2009 22:27:15 +0100 [thread overview]
Message-ID: <200910312227.15493.rjw@sisk.pl> (raw)
In-Reply-To: <1257022890.7907.14.camel@pasglop>
On Saturday 31 October 2009, Benjamin Herrenschmidt wrote:
> On Sat, 2009-10-31 at 10:31 +0100, Rafael J. Wysocki wrote:
>
> > > To me the proper approach would be to split it so that
> >
> > Well, agreed, but ...
> >
> > > - early_resume() restores power & config space etc... so that existing
> > > devices can move on (might check for removal). There's no other hotplug
> > > activity
> >
> > ... that's exactly what doesn't work at the moment.
>
> BTW. This is a PCMCIA problem, a Cardbus or both ?
I _think_ it's a CardBus problem. Evidently, it only happens if the second
CardBus bridge is resumed right after the first one (which resumes entirely
correctly) and only if that happens in the early resume phase (ie. before
resume_device_irqs()).
> I'll see if I can dig something on monday ?
In the meantime I invented a patch that works, ie. apparently fixes the problem
and if there was a card in the socket during the suspend, it's standard config
space is restored correctly. I tested it on one of my boxes with two different
CardBus adapters and Jose says it fixes the problem for him.
The patch is appended, please have a look.
> >From the little email history I caught, it smells like pcmcia old style.
>
> I don't see a problem per-se with the mutex usage with the new interrupt
> masking style as Linus says. socket_resume() also looks reasonably sane,
> it's the whole handling of removal that should be deferred.
In the failing case we don't even get there. There are two CardBus bridges in
the system, but both sockets are empty, so we take the socket_insert() code
path.
> Maybe instead of doing socket_remove_drivers()...send_event() etc.. in there,
> we could simply just shut the socket down (PCMCIA drivers should cope
> with sockets returning ffff's for a short amount of time), flag it dead
> in skt->state and have the "late" resume actually fire off the driver
> removal and sending of the event.
>
> BTW. Have we ever documented whether it's kosher to ->remove() a driver
> before ->resume()'ing it ? (In which case obviously we wouldn't resume
> it).
The PM core doesn't have a problem with that. Whether or not it's sane from
the driver design point of view is a separate question, though.
Thanks,
Rafael
---
From: Rafael J. Wysocki <rjw@sisk.pl>
Subject: PM / yenta: Split resume into early and late parts
Commit 0c570cdeb8fdfcb354a3e9cd81bfc6a09c19de0c
(PM / yenta: Fix cardbus suspend/resume regression) caused resume to
fail on systems with two CardBus bridges. While the exact nature
of the failure is not known at the moment, it can be worked around by
splitting the yenta resume into an early part, executed during the
early phase of resume, that will only resume the socket and power it
up if there was a card in it during suspend, and a late part,
executed during "regular" resume, that will carry out all of the
remaining yenta resume operations.
Fixes http://bugzilla.kernel.org/show_bug.cgi?id=14334, which is a
listed regression from 2.6.31.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/pcmcia/cs.c | 79 +++++++++++++++++++++++++++++-------------
drivers/pcmcia/yenta_socket.c | 12 +++++-
include/pcmcia/ss.h | 2 +
3 files changed, 68 insertions(+), 25 deletions(-)
Index: linux-2.6/drivers/pcmcia/yenta_socket.c
===================================================================
--- linux-2.6.orig/drivers/pcmcia/yenta_socket.c
+++ linux-2.6/drivers/pcmcia/yenta_socket.c
@@ -1275,16 +1275,26 @@ static int yenta_dev_resume_noirq(struct
if (socket->type && socket->type->restore_state)
socket->type->restore_state(socket);
- return pcmcia_socket_dev_resume(dev);
+ pcmcia_socket_dev_early_resume(dev);
+ return 0;
+}
+
+static int yenta_dev_resume(struct device *dev)
+{
+ pcmcia_socket_dev_late_resume(dev);
+ return 0;
}
static struct dev_pm_ops yenta_pm_ops = {
.suspend_noirq = yenta_dev_suspend_noirq,
.resume_noirq = yenta_dev_resume_noirq,
+ .resume = yenta_dev_resume,
.freeze_noirq = yenta_dev_suspend_noirq,
.thaw_noirq = yenta_dev_resume_noirq,
+ .thaw = yenta_dev_resume,
.poweroff_noirq = yenta_dev_suspend_noirq,
.restore_noirq = yenta_dev_resume_noirq,
+ .restore = yenta_dev_resume,
};
#define YENTA_PM_OPS (¥ta_pm_ops)
Index: linux-2.6/drivers/pcmcia/cs.c
===================================================================
--- linux-2.6.orig/drivers/pcmcia/cs.c
+++ linux-2.6/drivers/pcmcia/cs.c
@@ -98,10 +98,13 @@ EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
* These functions check for the appropriate struct pcmcia_soket arrays,
* and pass them to the low-level functions pcmcia_{suspend,resume}_socket
*/
+static int socket_early_resume(struct pcmcia_socket *skt);
+static int socket_late_resume(struct pcmcia_socket *skt);
static int socket_resume(struct pcmcia_socket *skt);
static int socket_suspend(struct pcmcia_socket *skt);
-int pcmcia_socket_dev_suspend(struct device *dev)
+static void pcmcia_socket_dev_run(struct device *dev,
+ int (*cb)(struct pcmcia_socket *))
{
struct pcmcia_socket *socket;
@@ -110,29 +113,34 @@ int pcmcia_socket_dev_suspend(struct dev
if (socket->dev.parent != dev)
continue;
mutex_lock(&socket->skt_mutex);
- socket_suspend(socket);
+ cb(socket);
mutex_unlock(&socket->skt_mutex);
}
up_read(&pcmcia_socket_list_rwsem);
+}
+int pcmcia_socket_dev_suspend(struct device *dev)
+{
+ pcmcia_socket_dev_run(dev, socket_suspend);
return 0;
}
EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
-int pcmcia_socket_dev_resume(struct device *dev)
+void pcmcia_socket_dev_early_resume(struct device *dev)
{
- struct pcmcia_socket *socket;
+ pcmcia_socket_dev_run(dev, socket_early_resume);
+}
+EXPORT_SYMBOL(pcmcia_socket_dev_early_resume);
- down_read(&pcmcia_socket_list_rwsem);
- list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
- if (socket->dev.parent != dev)
- continue;
- mutex_lock(&socket->skt_mutex);
- socket_resume(socket);
- mutex_unlock(&socket->skt_mutex);
- }
- up_read(&pcmcia_socket_list_rwsem);
+void pcmcia_socket_dev_late_resume(struct device *dev)
+{
+ pcmcia_socket_dev_run(dev, socket_late_resume);
+}
+EXPORT_SYMBOL(pcmcia_socket_dev_late_resume);
+int pcmcia_socket_dev_resume(struct device *dev)
+{
+ pcmcia_socket_dev_run(dev, socket_resume);
return 0;
}
EXPORT_SYMBOL(pcmcia_socket_dev_resume);
@@ -546,23 +554,30 @@ static int socket_suspend(struct pcmcia_
return 0;
}
-/*
- * Resume a socket. If a card is present, verify its CIS against
- * our cached copy. If they are different, the card has been
- * replaced, and we need to tell the drivers.
- */
-static int socket_resume(struct pcmcia_socket *skt)
+static void socket_start_resume(struct pcmcia_socket *skt)
{
- int ret;
-
- if (!(skt->state & SOCKET_SUSPEND))
- return -EBUSY;
-
skt->socket = dead_socket;
skt->ops->init(skt);
skt->ops->set_socket(skt, &skt->socket);
+}
+
+static int socket_early_resume(struct pcmcia_socket *skt)
+{
+ if ((skt->state & SOCKET_SUSPEND) && (skt->state & SOCKET_PRESENT))
+ socket_start_resume(skt);
+
+ return 0;
+}
+
+static int socket_late_resume(struct pcmcia_socket *skt)
+{
+ int ret;
+
+ if (!(skt->state & SOCKET_SUSPEND))
+ return 0;
if (!(skt->state & SOCKET_PRESENT)) {
+ socket_start_resume(skt);
skt->state &= ~SOCKET_SUSPEND;
return socket_insert(skt);
}
@@ -596,6 +611,22 @@ static int socket_resume(struct pcmcia_s
return 0;
}
+/*
+ * Resume a socket. If a card is present, verify its CIS against
+ * our cached copy. If they are different, the card has been
+ * replaced, and we need to tell the drivers.
+ */
+static int socket_resume(struct pcmcia_socket *skt)
+{
+ if (!(skt->state & SOCKET_SUSPEND))
+ return -EBUSY;
+
+ if (skt->state & SOCKET_PRESENT)
+ socket_start_resume(skt);
+
+ return socket_late_resume(skt);
+}
+
static void socket_remove(struct pcmcia_socket *skt)
{
dev_printk(KERN_NOTICE, &skt->dev,
Index: linux-2.6/include/pcmcia/ss.h
===================================================================
--- linux-2.6.orig/include/pcmcia/ss.h
+++ linux-2.6/include/pcmcia/ss.h
@@ -280,6 +280,8 @@ extern struct pccard_resource_ops pccard
/* socket drivers are expected to use these callbacks in their .drv struct */
extern int pcmcia_socket_dev_suspend(struct device *dev);
+extern void pcmcia_socket_dev_early_resume(struct device *dev);
+extern void pcmcia_socket_dev_late_resume(struct device *dev);
extern int pcmcia_socket_dev_resume(struct device *dev);
/* socket drivers use this callback in their IRQ handler */
next prev parent reply other threads:[~2009-10-31 21:27 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-26 18:45 2.6.32-rc5-git3: Reported regressions from 2.6.31 Rafael J. Wysocki
[not found] ` <6dRYo8ss7vL.A.Z4G.kre5KB@chimera>
[not found] ` <4AE5F563.5020803@gmail.com>
2009-10-26 19:30 ` [Bug #14379] ACPI Warning for _SB_.BAT0._BIF: Converted Buffer to expected String Rafael J. Wysocki
[not found] ` <6dRYo8ss7vL.A.hyE.2qe5KB@chimera>
[not found] ` <4AE601B1.7050000@gmail.com>
[not found] ` <4AE601B1.7050000-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-10-26 21:01 ` [Bug #14483] WARNING: at drivers/base/sys.c:353 __sysdev_resume+0x54/0xca() Rafael J. Wysocki
[not found] ` <6dRYo8ss7vL.A.EqH.Nse5KB@chimera>
2009-10-30 18:48 ` Help needed, Re: [Bug #14334] pcmcia suspend regression from 2.6.31.1 to 2.6.31.2 - Dell Inspiron 600m Rafael J. Wysocki
2009-10-30 19:47 ` Linus Torvalds
2009-10-30 20:32 ` Rafael J. Wysocki
2009-10-30 20:40 ` Linus Torvalds
2009-10-30 21:17 ` Linus Torvalds
[not found] ` <alpine.LFD.2.01.0910301412500.31845-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-10-30 22:17 ` Rafael J. Wysocki
2009-10-30 23:54 ` Benjamin Herrenschmidt
2009-10-30 23:57 ` Benjamin Herrenschmidt
2009-10-31 9:31 ` Rafael J. Wysocki
2009-10-31 21:01 ` Benjamin Herrenschmidt
2009-10-31 21:27 ` Rafael J. Wysocki [this message]
2009-10-31 21:44 ` Linus Torvalds
2009-10-31 21:52 ` Rafael J. Wysocki
[not found] ` <200910312252.39446.rjw-KKrjLPT3xs0@public.gmane.org>
2009-10-31 21:57 ` Linus Torvalds
[not found] ` <alpine.LFD.2.01.0910311455520.31845-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-10-31 22:10 ` Rafael J. Wysocki
[not found] ` <200910312227.15493.rjw-KKrjLPT3xs0@public.gmane.org>
2009-10-31 22:56 ` Benjamin Herrenschmidt
2009-10-31 23:10 ` Rafael J. Wysocki
2009-10-31 23:24 ` Rafael J. Wysocki
2009-11-01 8:36 ` Rafael J. Wysocki
2009-11-01 16:47 ` Dominik Brodowski
[not found] ` <20091101164736.GA5666-S7uyTPAaJ/sb6pqDj42GsMgv3T4z79SOrE5yTffgRl4@public.gmane.org>
2009-11-02 13:35 ` Rafael J. Wysocki
[not found] ` <200911010936.10409.rjw-KKrjLPT3xs0@public.gmane.org>
2009-11-01 17:18 ` Linus Torvalds
2009-11-02 13:39 ` Rafael J. Wysocki
2009-11-02 17:38 ` Dominik Brodowski
[not found] ` <20091102173843.GA662-S7uyTPAaJ/sb6pqDj42GsMgv3T4z79SOrE5yTffgRl4@public.gmane.org>
2009-11-02 18:40 ` Rafael J. Wysocki
[not found] ` <200911021439.28266.rjw-KKrjLPT3xs0@public.gmane.org>
2009-11-02 17:50 ` Linus Torvalds
2009-11-02 22:22 ` Benjamin Herrenschmidt
2009-11-12 12:14 ` Pavel Machek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200910312227.15493.rjw@sisk.pl \
--to=rjw@sisk.pl \
--cc=benh@kernel.crashing.org \
--cc=braket@hotmail.com \
--cc=gregkh@suse.de \
--cc=kernel-testers@vger.kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux@dominikbrodowski.net \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox