|
|
|
Re: [linux-pm] ehci_hcd related S3 lockup on ASUS laptops, again | |
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] |
|
On Tue, Apr 17, 2012 at 12:58:03PM -0400, Alan Stern wrote: > > > 1. This change in hcd-pci.c: > > > + pci_dev->current_state = PCI_UNKNOWN; > > It locks up if this line is removed. > > Very bizarre indeed. All right, leave that line in place and try > removing the other changes, one at a time. In fact, let's add one more > thing to remove from the patch > > > > 2. This change in ehci-pci.c: > > > + ehci_silence_controller(ehci); > > > > > > 3. This change in hcd-pci.c: > > > + pci_disable_device(pci_dev); > > > > > > 4. This change in hcd-pci.c: > > > + iounmap(hcd->regs); > > > > > > 5. This change in hcd-pci.c: > > > + free_irq(hcd->irq, hcd); > > > > > > 6. This change in hcd-pci.c: > > > - pci_disable_device(pci_dev); > > > + pci_disable_enabled_device(pci_dev); > > > > > > 7. This change in ehci-pci.c: > > > - ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup); > > 8. This change in ehci-pci.c: > + ehci_reset(ehci); > > If you manage to reach the end of this list, you'll essentially be > doing a normal suspend (except for the PCI_UNKNOWN part). It works without changes #2..8. I'm attaching the resulting patch. -- WBR, wRAR
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 6b54b23..8a9edf4 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -713,6 +713,8 @@ static int pci_pm_suspend_noirq(struct device *dev)
if (!pm) {
pci_save_state(pci_dev);
+ pci_prepare_to_sleep(pci_dev);
+ pci_pm_set_unknown_state(pci_dev);
return 0;
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8156744..3111105 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1348,6 +1348,7 @@ void pci_disable_enabled_device(struct pci_dev *dev)
if (pci_is_enabled(dev))
do_pci_disable_device(dev);
}
+EXPORT_SYMBOL(pci_disable_enabled_device);
/**
* pci_disable_device - Disable PCI device after use
@@ -1710,6 +1711,7 @@ pci_power_t pci_target_state(struct pci_dev *dev)
*/
int pci_prepare_to_sleep(struct pci_dev *dev)
{
+ pci_power_t cur_state = dev->current_state;
pci_power_t target_state = pci_target_state(dev);
int error;
@@ -1723,6 +1725,8 @@ int pci_prepare_to_sleep(struct pci_dev *dev)
if (error)
pci_enable_wake(dev, target_state, false);
+ dev_info(&dev->dev, "cur %d target %d error %d\n", cur_state,
+ target_state, error);
return error;
}
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 622b4a4..d7dc939 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -381,6 +381,8 @@ static int check_root_hub_suspended(struct device *dev)
}
#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME)
+extern void pci_disable_enabled_device(struct pci_dev *);
+
static int suspend_common(struct device *dev, bool do_wakeup)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
@@ -427,12 +429,18 @@ static int suspend_common(struct device *dev, bool do_wakeup)
if (!hcd->msix_enabled)
synchronize_irq(pci_dev->irq);
+// free_irq(hcd->irq, hcd); // 5
+// iounmap(hcd->regs); // 4
+// pci_disable_device(pci_dev); // 3
+
/* Downstream ports from this root hub should already be quiesced, so
* there will be no DMA activity. Now we can shut down the upstream
* link (except maybe for PME# resume signaling). We'll enter a
* low power state during suspend_noirq, if the hardware allows.
*/
+// pci_disable_enabled_device(pci_dev); // 6
pci_disable_device(pci_dev);
+ pci_dev->current_state = PCI_UNKNOWN; // 1
return retval;
}
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 01bb7241d..5fbfc3e 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -342,7 +342,7 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
* mark HW unaccessible. The PM and USB cores make sure that
* the root hub is either suspended or stopped.
*/
- ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup);
+ ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup); // 7
spin_lock_irqsave (&ehci->lock, flags);
ehci_writel(ehci, 0, &ehci->regs->intr_enable);
(void)ehci_readl(ehci, &ehci->regs->intr_enable);
@@ -350,6 +350,9 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
spin_unlock_irqrestore (&ehci->lock, flags);
+// ehci_silence_controller(ehci); // 2
+// ehci_reset(ehci); // 8
+
// could save FLADJ in case of Vaux power loss
// ... we'd only use it to handle clock skew
Attachment:
signature.asc
Description: Digital signature

[Linux Media] [Video for Linux] [Linux Input] [Linux Audio Users] [Photo] [Yosemite News] [Yosemite Photos] [Free Online Dating] [Linux Kernel] [Linux SCSI] [Old Linux USB Devel Archive] [More Archives]
![]() |
![]() |