Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d436b42 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

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: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent ff2f0787
Loading
Loading
Loading
Loading
+17 −13
Original line number Diff line number Diff line
@@ -176,6 +176,8 @@ static void check_and_reset_hc(struct uhci_hcd *uhci)
 */
static void configure_hc(struct uhci_hcd *uhci)
{
	struct pci_dev *pdev = to_pci_dev(uhci_dev(uhci));

	/* Set the frame length to the default: 1 ms exactly */
	outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF);

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

	/* Enable PIRQ */
	pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
			USBLEGSUP_DEFAULT);
	pci_write_config_word(pdev, USBLEGSUP, USBLEGSUP_DEFAULT);

	/* Disable platform-specific non-PME# wakeup */
	if (pdev->vendor == PCI_VENDOR_ID_INTEL)
		pci_write_config_byte(pdev, USBRES_INTEL, 0);
}


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

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

	/* FIXME: Enable non-PME# remote wakeup? */
	/* Enable platform-specific non-PME# wakeup */
	if (do_wakeup) {
		if (pdev->vendor == PCI_VENDOR_ID_INTEL)
			pci_write_config_byte(pdev, USBRES_INTEL,
					USBPORT1EN | USBPORT2EN);
	}

done_okay:
	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
@@ -831,7 +841,6 @@ static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
	 * even if the controller was dead.
	 */
	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
	mb();

	spin_lock_irq(&uhci->lock);

@@ -839,8 +848,6 @@ static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
	if (hibernated)
		uhci_hc_died(uhci);

	/* FIXME: Disable non-PME# remote wakeup? */

	/* The firmware or a boot kernel may have changed the controller
	 * settings during a system wakeup.  Check it and reconfigure
	 * to avoid problems.
@@ -850,12 +857,9 @@ static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
	/* If the controller was dead before, it's back alive now */
	configure_hc(uhci);

	if (uhci->rh_state == UHCI_RH_RESET) {

		/* The controller had to be reset */
	/* Tell the core if the controller had to be reset */
	if (uhci->rh_state == UHCI_RH_RESET)
		usb_root_hub_lost_power(hcd->self.root_hub);
		suspend_rh(uhci, UHCI_RH_SUSPENDED);
	}

	spin_unlock_irq(&uhci->lock);

+6 −1
Original line number Diff line number Diff line
@@ -67,12 +67,17 @@
#define   USBPORTSC_RES3	0x4000	/* reserved, write zeroes */
#define   USBPORTSC_RES4	0x8000	/* reserved, write zeroes */

/* Legacy support register */
/* PCI legacy support register */
#define USBLEGSUP		0xc0
#define   USBLEGSUP_DEFAULT	0x2000	/* only PIRQ enable set */
#define   USBLEGSUP_RWC		0x8f00	/* the R/WC bits */
#define   USBLEGSUP_RO		0x5040	/* R/O and reserved bits */

/* PCI Intel-specific resume-enable register */
#define USBRES_INTEL		0xc4
#define   USBPORT1EN		0x01
#define   USBPORT2EN		0x02

#define UHCI_PTR_BITS		cpu_to_le32(0x000F)
#define UHCI_PTR_TERM		cpu_to_le32(0x0001)
#define UHCI_PTR_QH		cpu_to_le32(0x0002)