From: Jason Lunz <lunz@falooley.org>
To: Vojtech Pavlik <vojtech@suse.cz>
Cc: Pavel Machek <pavel@suse.cz>,
linux-ide@vger.kernel.org, linux-pm@lists.osdl.org
Subject: [patch, rft] amd74xx: implement suspend-to-ram
Date: Sun, 23 Jul 2006 20:53:41 -0400 [thread overview]
Message-ID: <20060724005340.GA4073@opus.vpn-dev.reflex> (raw)
In-Reply-To: <20060718133920.GA4106@suse.cz>
The amd74xx driver needs to reprogram each drive's PIO timings as well
as the DMA timings on resume from s2ram. Otherwise, my
nforce3-150-based laptop hangs hard when ide_start_power_step() calls
drive->hwif->ide_dma_check(drive).
Suspend/resume from ram now works with the disk and the cdrom under
load, both with and without DMA enabled.
Signed-off-by: Jason Lunz <lunz@falooley.org>
---
I'm hardcoding a maximum of 2 ide channels, but other aspects of this
driver (like the amd_80w global) are already doing that.
DMA is re-enabled on resume even if it wasn't on at suspend, but that
doesn't look unusual in drivers/ide/pci.
drivers/ide/pci/amd74xx.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
Index: linux-2.6.18-rc2-git1/drivers/ide/pci/amd74xx.c
===================================================================
--- linux-2.6.18-rc2-git1.orig/drivers/ide/pci/amd74xx.c
+++ linux-2.6.18-rc2-git1/drivers/ide/pci/amd74xx.c
@@ -83,6 +83,8 @@
static ide_pci_device_t *amd_chipset;
static unsigned int amd_80w;
static unsigned int amd_clock;
+#define AMD_MAX_CHANNELS (2)
+static ide_hwif_t *amd_hwifs[AMD_MAX_CHANNELS];
static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 };
@@ -416,6 +418,8 @@
{
int i;
+ amd_hwifs[hwif->channel] = hwif;
+
if (hwif->irq == 0) /* 0 is bogus but will do for now */
hwif->irq = pci_get_legacy_ide_irq(hwif->pci_dev, hwif->channel);
@@ -494,6 +498,53 @@
/* 19 */ DECLARE_AMD_DEV("AMD5536"),
};
+static int amd74xx_suspend(struct pci_dev *dev, pm_message_t state)
+{
+ pci_save_state(dev);
+
+ // PM_EVENT_SUSPEND means s2ram. otherwise, the disk behind this device
+ // might hold the s2disk image, and we can't disable the disk
+ // controller until we've used it to write that out.
+ if(state.event == PM_EVENT_SUSPEND) {
+ pci_disable_device(dev);
+ pci_set_power_state(dev, pci_choose_state(dev, state));
+ }
+ return 0;
+}
+
+static int amd74xx_resume(struct pci_dev *dev)
+{
+ int retval = 0;
+ int i;
+
+ pci_set_power_state(dev, PCI_D0);
+ retval = pci_enable_device(dev);
+ pci_restore_state(dev);
+
+ for (i = 0; i < AMD_MAX_CHANNELS; i++) {
+ int d;
+
+ if (!amd_hwifs[i])
+ continue;
+
+ for (d = 0; d < MAX_DRIVES; ++d) {
+ ide_drive_t *drive = &amd_hwifs[i]->drives[d];
+ if (drive->present && !__ide_dma_bad_drive(drive)) {
+ /* this is the primary reason this driver needs
+ * a suspend()/resume() implementation at all.
+ * Calling amd74xx_ide_dma_check() without also
+ * calling amd74xx_tune_drive() hangs my
+ * nforce3-150 system. ide-disk.c will do just
+ * that later if we're resuming from s2ram. */
+ amd_hwifs[i]->tuneproc(drive, 255);
+ amd_hwifs[i]->ide_dma_check(drive);
+ }
+ }
+ }
+
+ return retval;
+}
+
static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
amd_chipset = amd74xx_chipsets + id->driver_data;
@@ -539,6 +590,8 @@
.name = "AMD_IDE",
.id_table = amd74xx_pci_tbl,
.probe = amd74xx_probe,
+ .suspend = amd74xx_suspend,
+ .resume = amd74xx_resume,
};
static int amd74xx_ide_init(void)
next prev parent reply other threads:[~2006-07-24 0:53 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-15 21:05 amd74xx crashes when resuming from STR Jason Lunz
2006-07-18 4:34 ` [linux-pm] " Pavel Machek
2006-07-18 4:35 ` Pavel Machek
[not found] ` <19700101003716.GA3558@ucw.cz>
2006-07-18 13:39 ` [linux-pm] " Vojtech Pavlik
2006-07-24 0:53 ` Jason Lunz [this message]
2006-07-25 23:09 ` [patch, rft] amd74xx: implement suspend-to-ram Pavel Machek
2006-07-26 0:27 ` [linux-pm] " David Brownell
2006-07-26 2:45 ` [patch v2] amd74xx: fix hang on resume from ram Jason Lunz
2006-07-26 3:14 ` [patch v3] " Jason Lunz
2006-07-27 20:35 ` David Brownell
2006-07-26 9:02 ` [linux-pm] [patch, rft] amd74xx: implement suspend-to-ram Pavel Machek
2006-07-27 0:29 ` David Brownell
2006-07-27 20:49 ` Pavel Machek
2006-07-27 22:43 ` Jason Lunz
2006-07-27 22:51 ` Pavel Machek
2006-07-28 9:15 ` Rafael J. Wysocki
2006-07-28 13:23 ` Vojtech Pavlik
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=20060724005340.GA4073@opus.vpn-dev.reflex \
--to=lunz@falooley.org \
--cc=linux-ide@vger.kernel.org \
--cc=linux-pm@lists.osdl.org \
--cc=pavel@suse.cz \
--cc=vojtech@suse.cz \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.