From: Linus Torvalds <torvalds@linux-foundation.org>
To: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Carlos Corbacho <carlos@strangeworlds.co.uk>,
"H. Peter Anvin" <hpa@kernel.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Greg KH <gregkh@suse.de>, Ingo Molnar <mingo@elte.hu>,
Thomas Gleixner <tglx@linutronix.de>, Len Brown <lenb@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
pm list <linux-pm@lists.linux-foundation.org>
Subject: Re: x86: Increase PCIBIOS_MIN_IO to 0x1500 to fix nForce 4 suspend-to-RAM
Date: Mon, 24 Dec 2007 10:34:21 -0800 (PST) [thread overview]
Message-ID: <alpine.LFD.0.9999.0712241008150.21557@woody.linux-foundation.org> (raw)
In-Reply-To: <200712241444.24031.rjw@sisk.pl>
On Mon, 24 Dec 2007, Rafael J. Wysocki wrote:
>
> Well, having considered that for a longer while, I think the AML code is
> referring to a device that we have suspended already, and since it's in a low
> power state, it just can't handle the reference.
>
> If that is the case, we'll have to find the device (that should be possible
> using some code instrumentation) and move the suspending of it into the late
> stage.
Yes.
In general, I'm personally of the opinion that drivers should *not*
actually go into D3 at all in the regular "->suspend()" phase. It should
be done in ->suspend_late. The early suspend is for saving state and
returning errors.
Sadly, we've made it a bit too inconvenient to actually do that. Almost
all drivers only do the "->suspend" thing, and the default PCI behaviour
doesn't help us in any way either.
Anyway, I wonder if a patch like this could make it easier for driver
writers to handle things. It basically does:
- if you don't have a regular "suspend()" function, we'll just save state
at suspend time.
- if you don't have a "suspend_late()" function, we'll look at the
current state, and if it's still in PCI_D0, we'll suspend to PCI_D3hot
if it's a regular PCI device (ie not a bridge or something else odd).
- then, at resume time, by default we don't do anything in the early
resume, but in the late resume we'll undo everything, of course.
Anyway, with this, most drivers could just remove the
"pci_set_power_state()" call *entirely*, and let the default
suspend_late action power the device down. But if you want to override
that default action, you can either:
- set the power state in your own ->suspend() routine (either by using
pci_set_power_state(), or by just explicitly setting the state to
unknown with "dev->current_state = PCI_UNKNOWN"
- have a "late_suspend()" action, which obviously will override the
default action entirely.
Hmm?
In the case of the NVidia issue, one thing to try migh be to remove the
current call to "pci_set_power_state(pdev, 3);" in agp_nvidia_suspend() in
drivers/char/agp/nvidia-agp.c. That sounds like the most likely culprit
for something that ACPI might want to shut down.
NOTE! This following patch is just for discussion, and while I think it's
conceptually a good thing to try, I don't think it will help Carlos'
problem. But removing the "pci_set_power_state()" in agp_nvidia_suspend()
might.
Linus
---
drivers/pci/pci-driver.c | 32 +++++++++++++++++++++++++-------
1 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 6d1a216..6992f73 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -264,6 +264,28 @@ static int pci_device_remove(struct device * dev)
return 0;
}
+static void pci_default_suspend(struct pci_dev *dev, pm_message_t state)
+{
+ pci_save_state(dev);
+}
+
+static void pci_default_suspend_late(struct pci_dev *dev, pm_message_t state)
+{
+ /* Something has already suspended it? Never mind then.. */
+ if (dev->current_state != PCI_D0)
+ return;
+
+ /* We avoid powering down bridges by default.. */
+ if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL)
+ pci_set_power_state(dev, PCI_D3hot);
+
+ /*
+ * mark its power state as "unknown", since we don't know if
+ * e.g. the BIOS will change its device state when we suspend.
+ */
+ dev->current_state = PCI_UNKNOWN;
+}
+
static int pci_device_suspend(struct device * dev, pm_message_t state)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
@@ -274,13 +296,7 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
i = drv->suspend(pci_dev, state);
suspend_report_result(drv->suspend, i);
} else {
- pci_save_state(pci_dev);
- /*
- * mark its power state as "unknown", since we don't know if
- * e.g. the BIOS will change its device state when we suspend.
- */
- if (pci_dev->current_state == PCI_D0)
- pci_dev->current_state = PCI_UNKNOWN;
+ pci_default_suspend(pci_dev, state);
}
return i;
}
@@ -294,6 +310,8 @@ static int pci_device_suspend_late(struct device * dev, pm_message_t state)
if (drv && drv->suspend_late) {
i = drv->suspend_late(pci_dev, state);
suspend_report_result(drv->suspend_late, i);
+ } else {
+ pci_default_suspend_late(pci_dev, state);
}
return i;
}
next prev parent reply other threads:[~2007-12-24 18:35 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <200712231419.40207.carlos@strangeworlds.co.uk>
2007-12-23 16:30 ` Rafael J. Wysocki
2007-12-23 17:57 ` Ingo Molnar
2007-12-23 18:00 ` Linus Torvalds
2007-12-23 22:20 ` Rafael J. Wysocki
2007-12-23 23:12 ` H. Peter Anvin
2007-12-24 0:09 ` Carlos Corbacho
2007-12-24 0:56 ` Linus Torvalds
2007-12-24 1:14 ` Linus Torvalds
2007-12-24 3:05 ` Carlos Corbacho
2007-12-24 13:44 ` Rafael J. Wysocki
2007-12-24 18:34 ` Linus Torvalds [this message]
2007-12-24 21:53 ` Carlos Corbacho
2007-12-25 16:13 ` Suspend code ordering (again) (was: Re: x86: Increase PCIBIOS_MIN_IO to 0x1500 to fix nForce 4 suspend-to-RAM) Rafael J. Wysocki
2007-12-26 4:11 ` Linus Torvalds
2007-12-26 15:07 ` Rafael J. Wysocki
2007-12-26 15:24 ` Suspend code ordering (again) Alexey Starikovskiy
2007-12-26 17:50 ` H. Peter Anvin
2007-12-25 12:12 ` x86: Increase PCIBIOS_MIN_IO to 0x1500 to fix nForce 4 suspend-to-RAM Pavel Machek
2007-12-25 12:28 ` Carlos Corbacho
2007-12-23 17:53 ` [Bug 9528] " Linus Torvalds
2007-12-23 17:58 ` Linus Torvalds
2007-12-23 19:19 ` Ingo Molnar
2007-12-23 19:29 ` Linus Torvalds
2007-12-23 20:43 ` Yinghai Lu
[not found] <fa.Tr7qmPdet0rF2FSRX/94s2UEMSE@ifi.uio.no>
[not found] ` <fa.5MPS0t6OtOOALbc90ywKDrtik+4@ifi.uio.no>
[not found] ` <fa.zg2cR0292Evub+o7LgQUdg4A7ZM@ifi.uio.no>
[not found] ` <fa.ZBHAMdWAEaW7Flaz8/Gc8PLZUNg@ifi.uio.no>
2007-12-24 22:40 ` Robert Hancock
2007-12-25 0:03 ` Carlos Corbacho
2007-12-25 13:26 ` Rafael J. Wysocki
2007-12-25 13:12 ` Carlos Corbacho
2007-12-25 14:11 ` Rafael J. Wysocki
2007-12-25 17:17 ` Robert Hancock
2007-12-25 18:26 ` Rafael J. Wysocki
2007-12-26 4:29 ` Linus Torvalds
2007-12-26 5:13 ` Robert Hancock
2007-12-26 7:23 ` Avi Kivity
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=alpine.LFD.0.9999.0712241008150.21557@woody.linux-foundation.org \
--to=torvalds@linux-foundation.org \
--cc=akpm@linux-foundation.org \
--cc=carlos@strangeworlds.co.uk \
--cc=gregkh@suse.de \
--cc=hpa@kernel.org \
--cc=lenb@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.linux-foundation.org \
--cc=mingo@elte.hu \
--cc=rjw@sisk.pl \
--cc=tglx@linutronix.de \
/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
all inboxes | Powered by JetHome®