Skip to content

Commit 0d436b4

Browse files
AlanSterngregkh
authored andcommitted
USB: UHCI: add support for Intel's wakeup flags
This patch (as1396) adds code to uhci-hcd to support the vendor-specific wakeup settings found in Intel's ICHx hardware. A couple of unnecessary memory barriers are removed. And the root hub isn't put back into the "suspended" state if power was lost during a system sleep -- there's not much point in doing so because the root hub will be resumed shortly. Signed-off-by: Alan Stern <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ff2f078 commit 0d436b4

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

drivers/usb/host/uhci-hcd.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ static void check_and_reset_hc(struct uhci_hcd *uhci)
176176
*/
177177
static void configure_hc(struct uhci_hcd *uhci)
178178
{
179+
struct pci_dev *pdev = to_pci_dev(uhci_dev(uhci));
180+
179181
/* Set the frame length to the default: 1 ms exactly */
180182
outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF);
181183

@@ -191,8 +193,11 @@ static void configure_hc(struct uhci_hcd *uhci)
191193
mb();
192194

193195
/* Enable PIRQ */
194-
pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
195-
USBLEGSUP_DEFAULT);
196+
pci_write_config_word(pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
197+
198+
/* Disable platform-specific non-PME# wakeup */
199+
if (pdev->vendor == PCI_VENDOR_ID_INTEL)
200+
pci_write_config_byte(pdev, USBRES_INTEL, 0);
196201
}
197202

198203

@@ -791,6 +796,7 @@ static int uhci_rh_resume(struct usb_hcd *hcd)
791796
static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
792797
{
793798
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
799+
struct pci_dev *pdev = to_pci_dev(uhci_dev(uhci));
794800
int rc = 0;
795801

796802
dev_dbg(uhci_dev(uhci), "%s\n", __func__);
@@ -808,11 +814,15 @@ static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
808814
/* All PCI host controllers are required to disable IRQ generation
809815
* at the source, so we must turn off PIRQ.
810816
*/
811-
pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
812-
mb();
817+
pci_write_config_word(pdev, USBLEGSUP, 0);
813818
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
814819

815-
/* FIXME: Enable non-PME# remote wakeup? */
820+
/* Enable platform-specific non-PME# wakeup */
821+
if (do_wakeup) {
822+
if (pdev->vendor == PCI_VENDOR_ID_INTEL)
823+
pci_write_config_byte(pdev, USBRES_INTEL,
824+
USBPORT1EN | USBPORT2EN);
825+
}
816826

817827
done_okay:
818828
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
@@ -831,16 +841,13 @@ static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
831841
* even if the controller was dead.
832842
*/
833843
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
834-
mb();
835844

836845
spin_lock_irq(&uhci->lock);
837846

838847
/* Make sure resume from hibernation re-enumerates everything */
839848
if (hibernated)
840849
uhci_hc_died(uhci);
841850

842-
/* FIXME: Disable non-PME# remote wakeup? */
843-
844851
/* The firmware or a boot kernel may have changed the controller
845852
* settings during a system wakeup. Check it and reconfigure
846853
* to avoid problems.
@@ -850,12 +857,9 @@ static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
850857
/* If the controller was dead before, it's back alive now */
851858
configure_hc(uhci);
852859

853-
if (uhci->rh_state == UHCI_RH_RESET) {
854-
855-
/* The controller had to be reset */
860+
/* Tell the core if the controller had to be reset */
861+
if (uhci->rh_state == UHCI_RH_RESET)
856862
usb_root_hub_lost_power(hcd->self.root_hub);
857-
suspend_rh(uhci, UHCI_RH_SUSPENDED);
858-
}
859863

860864
spin_unlock_irq(&uhci->lock);
861865

drivers/usb/host/uhci-hcd.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,17 @@
6767
#define USBPORTSC_RES3 0x4000 /* reserved, write zeroes */
6868
#define USBPORTSC_RES4 0x8000 /* reserved, write zeroes */
6969

70-
/* Legacy support register */
70+
/* PCI legacy support register */
7171
#define USBLEGSUP 0xc0
7272
#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
7373
#define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
7474
#define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
7575

76+
/* PCI Intel-specific resume-enable register */
77+
#define USBRES_INTEL 0xc4
78+
#define USBPORT1EN 0x01
79+
#define USBPORT2EN 0x02
80+
7681
#define UHCI_PTR_BITS cpu_to_le32(0x000F)
7782
#define UHCI_PTR_TERM cpu_to_le32(0x0001)
7883
#define UHCI_PTR_QH cpu_to_le32(0x0002)

0 commit comments

Comments
 (0)