Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 39814
b: refs/heads/master
c: b62df45
h: refs/heads/master
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Oct 17, 2006
1 parent 34e29c8 commit ec74911
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 96a518928e1fd00a6d0eb344f420ea82aeec8ab9
refs/heads/master: b62df4516981745d4b5de01ceec1d65a9174a524
44 changes: 39 additions & 5 deletions trunk/drivers/usb/host/uhci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <linux/dma-mapping.h>
#include <linux/usb.h>
#include <linux/bitops.h>
#include <linux/dmi.h>

#include <asm/uaccess.h>
#include <asm/io.h>
Expand Down Expand Up @@ -196,12 +197,42 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci)
return 0;
}

static int remote_wakeup_is_broken(struct uhci_hcd *uhci)
{
static struct dmi_system_id broken_wakeup_table[] = {
{
.ident = "Asus A7V8X",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK"),
DMI_MATCH(DMI_BOARD_NAME, "A7V8X"),
DMI_MATCH(DMI_BOARD_VERSION, "REV 1.xx"),
}
},
{ }
};
int port;

/* One of Asus's motherboards has a bug which causes it to
* wake up immediately from suspend-to-RAM if any of the ports
* are connected. In such cases we will not set EGSM.
*/
if (dmi_check_system(broken_wakeup_table)) {
for (port = 0; port < uhci->rh_numports; ++port) {
if (inw(uhci->io_addr + USBPORTSC1 + port * 2) &
USBPORTSC_CCS)
return 1;
}
}

return 0;
}

static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state)
__releases(uhci->lock)
__acquires(uhci->lock)
{
int auto_stop;
int int_enable;
int int_enable, egsm_enable;

auto_stop = (new_state == UHCI_RH_AUTO_STOPPED);
dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev,
Expand All @@ -217,15 +248,18 @@ __acquires(uhci->lock)
}

/* Enable resume-detect interrupts if they work.
* Then enter Global Suspend mode, still configured.
* Then enter Global Suspend mode if _it_ works, still configured.
*/
egsm_enable = USBCMD_EGSM;
uhci->working_RD = 1;
int_enable = USBINTR_RESUME;
if (resume_detect_interrupts_are_broken(uhci)) {
if (remote_wakeup_is_broken(uhci))
egsm_enable = 0;
if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable)
uhci->working_RD = int_enable = 0;
}

outw(int_enable, uhci->io_addr + USBINTR);
outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD);
outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD);
mb();
udelay(5);

Expand Down

0 comments on commit ec74911

Please sign in to comment.