Re: [PATCH] [115/275] OHCI: work around for nVidia shutdown problem
From: Pali RohÃr
Date: Thu Mar 31 2011 - 01:55:19 EST
Hello,
please see comment 33 in LP bug tracker:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/42149
Maybe there are problem with this patch on new nvidia HW.
2011/3/30 Andi Kleen <andi@xxxxxxxxxxxxxx>:
> 2.6.35-longterm review patch. ÂIf anyone has any objections, please let me know.
>
> ------------------
> From: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
>
> commit 3df7169e73fc1d71a39cffeacc969f6840cdf52b upstream.
>
> This patch (as1417) fixes a problem affecting some (or all) nVidia
> chipsets. ÂWhen the computer is shut down, the OHCI controllers
> continue to power the USB buses and evidently they drive a Reset
> signal out all their ports. ÂThis prevents attached devices from going
> to low power. ÂMouse LEDs stay on, for example, which is disconcerting
> for users and a drain on laptop batteries.
>
> The fix involves leaving each OHCI controller in the OPERATIONAL state
> during system shutdown rather than putting it in the RESET state.
> Although this nominally means the controller is running, in fact it's
> not doing very much since all the schedules are all disabled. ÂHowever
> there is ongoing DMA to the Host Controller Communications Area, so
> the patch also disables the bus-master capability of all PCI USB
> controllers after the shutdown routine runs.
>
> The fix is applied only to nVidia-based PCI OHCI controllers, so it
> shouldn't cause problems on systems using other hardware. ÂAs an added
> safety measure, in case the kernel encounters one of these running
> controllers during boot, the patch changes quirk_usb_handoff_ohci()
> (which runs early on during PCI discovery) to reset the controller
> before anything bad can happen.
>
> Reported-by: Pali RohÃr <pali.rohar@xxxxxxxxx>
> Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
> Signed-off-by: Andi Kleen <ak@xxxxxxxxxxxxxxx>
> CC: David Brownell <david-b@xxxxxxxxxxx>
> Tested-by: Pali RohÃr <pali.rohar@xxxxxxxxx>
> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
>
> ---
> Âdrivers/usb/core/hcd-pci.c  Â|  Â4 +++-
> Âdrivers/usb/host/ohci-hcd.c  |  Â9 ++++++++-
> Âdrivers/usb/host/ohci-pci.c  |  18 ++++++++++++++++++
> Âdrivers/usb/host/ohci.h    |  Â1 +
> Âdrivers/usb/host/pci-quirks.c | Â 18 +++++++++++-------
> Â5 files changed, 41 insertions(+), 9 deletions(-)
>
> Index: linux-2.6.35.y/drivers/usb/core/hcd-pci.c
> ===================================================================
> --- linux-2.6.35.y.orig/drivers/usb/core/hcd-pci.c   Â2011-03-29 22:51:22.609144656 -0700
> +++ linux-2.6.35.y/drivers/usb/core/hcd-pci.c  2011-03-29 23:03:00.575285450 -0700
> @@ -317,8 +317,10 @@
> Â Â Â Âif (!hcd)
> Â Â Â Â Â Â Â Âreturn;
>
> - Â Â Â if (hcd->driver->shutdown)
> + Â Â Â if (hcd->driver->shutdown) {
> Â Â Â Â Â Â Â Âhcd->driver->shutdown(hcd);
> + Â Â Â Â Â Â Â pci_disable_device(dev);
> + Â Â Â }
> Â}
> ÂEXPORT_SYMBOL_GPL(usb_hcd_pci_shutdown);
>
> Index: linux-2.6.35.y/drivers/usb/host/ohci-hcd.c
> ===================================================================
> --- linux-2.6.35.y.orig/drivers/usb/host/ohci-hcd.c   2011-03-29 22:51:22.609144656 -0700
> +++ linux-2.6.35.y/drivers/usb/host/ohci-hcd.c Â2011-03-29 23:03:00.576285425 -0700
> @@ -398,7 +398,14 @@
>
> Â Â Â Âohci = hcd_to_ohci (hcd);
> Â Â Â Âohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
> - Â Â Â ohci_usb_reset (ohci);
> + Â Â Â ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
> +
> + Â Â Â /* If the SHUTDOWN quirk is set, don't put the controller in RESET */
> + Â Â Â ohci->hc_control &= (ohci->flags & OHCI_QUIRK_SHUTDOWN ?
> + Â Â Â Â Â Â Â Â Â Â Â OHCI_CTRL_RWC | OHCI_CTRL_HCFS :
> + Â Â Â Â Â Â Â Â Â Â Â OHCI_CTRL_RWC);
> + Â Â Â ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
> +
> Â Â Â Â/* flush the writes */
> Â Â Â Â(void) ohci_readl (ohci, &ohci->regs->control);
> Â}
> Index: linux-2.6.35.y/drivers/usb/host/ohci-pci.c
> ===================================================================
> --- linux-2.6.35.y.orig/drivers/usb/host/ohci-pci.c   2011-03-29 22:51:22.609144656 -0700
> +++ linux-2.6.35.y/drivers/usb/host/ohci-pci.c Â2011-03-29 23:03:00.577285400 -0700
> @@ -201,6 +201,20 @@
> Â Â Â Âreturn 0;
> Â}
>
> +/* nVidia controllers continue to drive Reset signalling on the bus
> + * even after system shutdown, wasting power. ÂThis flag tells the
> + * shutdown routine to leave the controller OPERATIONAL instead of RESET.
> + */
> +static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd)
> +{
> + Â Â Â struct ohci_hcd *ohci = hcd_to_ohci(hcd);
> +
> + Â Â Â ohci->flags |= OHCI_QUIRK_SHUTDOWN;
> + Â Â Â ohci_dbg(ohci, "enabled nVidia shutdown quirk\n");
> +
> + Â Â Â return 0;
> +}
> +
> Â/*
> Â* The hardware normally enables the A-link power management feature, which
> Â* lets the system lower the power consumption in idle states.
> @@ -332,6 +346,10 @@
> Â Â Â Â Â Â Â ÂPCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
> Â Â Â Â Â Â Â Â.driver_data = (unsigned long)ohci_quirk_amd700,
> Â Â Â Â},
> + Â Â Â {
> + Â Â Â Â Â Â Â PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
> + Â Â Â Â Â Â Â .driver_data = (unsigned long) ohci_quirk_nvidia_shutdown,
> + Â Â Â },
>
> Â Â Â Â/* FIXME for some of the early AMD 760 southbridges, OHCI
> Â Â Â Â * won't work at all. Âblacklist them.
> Index: linux-2.6.35.y/drivers/usb/host/ohci.h
> ===================================================================
> --- linux-2.6.35.y.orig/drivers/usb/host/ohci.h 2011-03-29 22:51:22.610144631 -0700
> +++ linux-2.6.35.y/drivers/usb/host/ohci.h   Â2011-03-29 23:03:00.578285374 -0700
> @@ -403,6 +403,7 @@
> Â#define    ÂOHCI_QUIRK_HUB_POWER  Â0x100          /* distrust firmware power/oc setup */
> Â#define    ÂOHCI_QUIRK_AMD_ISO   Â0x200          /* ISO transfers*/
> Â#define    ÂOHCI_QUIRK_AMD_PREFETCH 0x400          /* pre-fetch for ISO transfer */
> +#define    ÂOHCI_QUIRK_SHUTDOWN   0x800          /* nVidia power bug */
> Â Â Â Â// there are also chip quirks/bugs in init logic
>
>    Âstruct work_struct   Ânec_work;    /* Worker for NEC quirk */
> Index: linux-2.6.35.y/drivers/usb/host/pci-quirks.c
> ===================================================================
> --- linux-2.6.35.y.orig/drivers/usb/host/pci-quirks.c  2011-03-29 22:51:22.610144631 -0700
> +++ linux-2.6.35.y/drivers/usb/host/pci-quirks.c    Â2011-03-29 23:03:00.579285348 -0700
> @@ -169,6 +169,7 @@
> Âstatic void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
> Â{
> Â Â Â Âvoid __iomem *base;
> + Â Â Â u32 control;
>
> Â Â Â Âif (!mmio_resource_enabled(pdev, 0))
> Â Â Â Â Â Â Â Âreturn;
> @@ -177,10 +178,14 @@
> Â Â Â Âif (base == NULL)
> Â Â Â Â Â Â Â Âreturn;
>
> + Â Â Â control = readl(base + OHCI_CONTROL);
> +
> Â/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
> -#ifndef __hppa__
> -{
> - Â Â Â u32 control = readl(base + OHCI_CONTROL);
> +#ifdef __hppa__
> +#define    ÂOHCI_CTRL_MASK     Â(OHCI_CTRL_RWC | OHCI_CTRL_IR)
> +#else
> +#define    ÂOHCI_CTRL_MASK     ÂOHCI_CTRL_RWC
> +
> Â Â Â Âif (control & OHCI_CTRL_IR) {
> Â Â Â Â Â Â Â Âint wait_time = 500; /* arbitrary; 5 seconds */
> Â Â Â Â Â Â Â Âwritel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
> @@ -194,13 +199,12 @@
> Â Â Â Â Â Â Â Â Â Â Â Âdev_warn(&pdev->dev, "OHCI: BIOS handoff failed"
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â" (BIOS bug?) %08x\n",
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âreadl(base + OHCI_CONTROL));
> -
> - Â Â Â Â Â Â Â /* reset controller, preserving RWC */
> - Â Â Â Â Â Â Â writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL);
> Â Â Â Â}
> -}
> Â#endif
>
> + Â Â Â /* reset controller, preserving RWC (and possibly IR) */
> + Â Â Â writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
> +
> Â Â Â Â/*
> Â Â Â Â * disable interrupts
> Â Â Â Â */
>
--
Pali RohÃr
pali.rohar@xxxxxxxxx
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/