From: Yinghai Lu <yinghai@kernel.org>
To: Jesse Barnes <jbarnes@virtuousgeek.org>, Greg KH <greg@kroah.com>,
Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@elte.hu>,
"H. Peter Anvin" <hpa@zytor.com>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: "linux-pci@vger.kernel.org" <linux-pci@vger.kernel.org>,
linux-usb@vger.kernel.org,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: [PATCH -v3 4/4] x86: usb handoff in early_quirk
Date: Mon, 10 Jan 2011 16:55:33 -0800 [thread overview]
Message-ID: <4D2BAA85.9060902@kernel.org> (raw)
In-Reply-To: <4D2BA8FE.9090204@kernel.org>
some systems keep getting
APIC calibration not consistent with PM-Timer: 139ms instead of 100ms
APIC delta adjusted to PM-Timer: 831249 (1163736)
USB legacy SMI handler is not disabled at that time.
Try to disable USB legacy support early with this patch.
So later APIC Timer calibration don't get messed up by USB legacy support SMI handler.
After this patch, that warning never show up for 100 reboot tests.
reuse code from drivers/usb/host/pci-quirks.c
with changes
1. delay and sleep ===> io_delay
2. dev_warn etc to pr_warn(num, slot, func...)
-v2: use get_early_pci_dev() etc.
fix typo with PARAVIRT according to Sander Eikelenboom <linux@eikelenboom.it>
-v3: include .h instead of .c file
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
arch/x86/kernel/early-quirks.c | 175 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 175 insertions(+)
Index: linux-2.6/arch/x86/kernel/early-quirks.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/early-quirks.c
+++ linux-2.6/arch/x86/kernel/early-quirks.c
@@ -19,6 +19,179 @@
#include <asm/iommu.h>
#include <asm/gart.h>
+#include "../../../drivers/usb/host/pci-quirks.h"
+
+static inline void early_udelay2(void)
+{
+#ifndef CONFIG_PARAVIRT
+ native_io_delay();
+#else
+ pv_cpu_ops.io_delay();
+#endif
+}
+
+static void early_usb_handoff_udelay(unsigned long usecs)
+{
+ unsigned long count;
+
+ count = usecs >> 1;
+
+ if (!count)
+ count = 1;
+
+ while (count-- > 0)
+ early_udelay2();
+}
+
+static void early_usb_handoff_msleep(unsigned long msecs)
+{
+ while (msecs-- > 0)
+ early_usb_handoff_udelay(1000);
+}
+
+static __init u32 get_usb_io_port(int num, int slot, int func)
+{
+ int i;
+ u16 cmd;
+
+ cmd = read_pci_config_16(num, slot, func, PCI_COMMAND);
+ if (!(cmd & PCI_COMMAND_IO))
+ return 0;
+
+ for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+ u32 addr = read_pci_config(num, slot, func, 0x10 + (i<<2));
+
+ if (!addr)
+ continue;
+ if ((addr&PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO)
+ continue;
+
+ addr &= PCI_BASE_ADDRESS_IO_MASK;
+ if (addr)
+ return addr;
+ }
+
+ return 0;
+}
+
+static void __init quirk_usb_handoff_uhci(int num, int slot, int func)
+{
+ unsigned long base;
+
+ base = get_usb_io_port(num, slot, func);
+ if (!base)
+ return;
+
+ printk(KERN_DEBUG "%02x:%02x.%01x: uhci ioport = 0x%04lx\n",
+ num, slot, func, base);
+ uhci_check_and_reset_hc(get_early_pci_dev(num, slot, func), base);
+}
+
+static __init u32 get_usb_mmio_addr(int num, int slot, int func)
+{
+ u32 addr;
+ u16 cmd;
+
+ cmd = read_pci_config_16(num, slot, func, PCI_COMMAND);
+ if (!(cmd & PCI_COMMAND_MEMORY))
+ return 0;
+
+ addr = read_pci_config(num, slot, func, 0x10);
+ if (!addr)
+ return 0;
+ if ((addr & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY)
+ return 0;
+
+ addr &= PCI_BASE_ADDRESS_MEM_MASK;
+
+ return addr;
+}
+
+static __init void quirk_usb_handoff_ohci(int num, int slot, int func)
+{
+ void __iomem *base;
+ u32 addr;
+
+ addr = get_usb_mmio_addr(num, slot, func);
+ if (!addr)
+ return;
+
+ printk(KERN_DEBUG "%02x:%02x.%01x: ohci mmio = 0x%08x\n",
+ num, slot, func, addr);
+ base = early_ioremap(addr, 0x1000);
+ if (!base)
+ return;
+
+ __usb_handoff_ohci(get_early_pci_dev(num, slot, func), base);
+
+ early_iounmap(base, 0x1000);
+}
+
+static __init void quirk_usb_handoff_ehci(int num, int slot, int func)
+{
+ void __iomem *base;
+ u32 addr;
+
+ addr = get_usb_mmio_addr(num, slot, func);
+ if (!addr)
+ return;
+
+ printk(KERN_DEBUG "%02x:%02x.%01x: ehci mmio = 0x%08x\n",
+ num, slot, func, addr);
+ base = early_ioremap(addr, 0x1000);
+ if (!base)
+ return;
+
+ __usb_handoff_ehci(get_early_pci_dev(num, slot, func), base);
+
+ early_iounmap(base, 0x1000);
+}
+
+static __init void quirk_usb_handoff_xhci(int num, int slot, int func)
+{
+ void __iomem *base;
+ u32 addr;
+
+ addr = get_usb_mmio_addr(num, slot, func);
+ if (!addr)
+ return;
+
+ printk(KERN_DEBUG "%02x:%02x.%01x: xhci mmio = 0x%08x\n",
+ num, slot, func, addr);
+ base = early_ioremap(addr, 0x1000);
+ if (!base)
+ return;
+
+ __usb_handoff_xhci(get_early_pci_dev(num, slot, func), base);
+
+ early_iounmap(base, 0x1000);
+}
+
+static __init void quirk_usb_handoff(int num, int slot, int func)
+{
+ u32 class;
+ void (*old_usb_handoff_udelay)(unsigned long) = usb_handoff_udelay;
+ void (*old_usb_handoff_msleep)(unsigned long) = usb_handoff_msleep;
+
+ usb_handoff_udelay = early_usb_handoff_udelay;
+ usb_handoff_msleep = early_usb_handoff_msleep;
+
+ class = read_pci_config(num, slot, func, PCI_CLASS_REVISION);
+ class >>= 8;
+
+ if (class == PCI_CLASS_SERIAL_USB_UHCI)
+ quirk_usb_handoff_uhci(num, slot, func);
+ else if (class == PCI_CLASS_SERIAL_USB_OHCI)
+ quirk_usb_handoff_ohci(num, slot, func);
+ else if (class == PCI_CLASS_SERIAL_USB_EHCI)
+ quirk_usb_handoff_ehci(num, slot, func);
+ else if (class == PCI_CLASS_SERIAL_USB_XHCI)
+ quirk_usb_handoff_xhci(num, slot, func);
+
+ usb_handoff_udelay = old_usb_handoff_udelay;
+ usb_handoff_msleep = old_usb_handoff_msleep;
+}
+
static void __init fix_hypertransport_config(int num, int slot, int func)
{
u32 htcfg;
@@ -208,6 +381,8 @@ struct chipset {
* only matching on bus 0.
*/
static struct chipset early_qrk[] __initdata = {
+ { PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_SERIAL_USB, PCI_ANY_ID, 0, quirk_usb_handoff },
{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, nvidia_bugs },
{ PCI_VENDOR_ID_VIA, PCI_ANY_ID,
next prev parent reply other threads:[~2011-01-11 0:57 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-09 19:58 [PATCH 0/3] x86, usb, pci: Disable usb legacy support early Yinghai Lu
2011-01-10 8:43 ` [PATCH -v2 0/4] " Yinghai Lu
2011-01-11 0:49 ` [PATCH -v3 " Yinghai Lu
2011-01-11 0:55 ` [PATCH -v3 1/4] pci, usb: Make usb handoff func all take base remapping Yinghai Lu
2011-01-11 1:07 ` Greg KH
2011-01-11 1:20 ` Yinghai Lu
2011-01-11 3:37 ` Greg KH
2011-01-11 5:21 ` Benjamin Herrenschmidt
2011-01-11 6:34 ` Yinghai Lu
2011-01-11 7:37 ` Benjamin Herrenschmidt
2011-01-11 9:21 ` Yinghai Lu
2011-01-11 13:56 ` Greg KH
2011-01-11 17:39 ` Konrad Rzeszutek Wilk
2011-01-12 1:06 ` [RFC PATCH] x86: Add safe_udelay() and safe_msleep() Yinghai Lu
2011-01-12 2:32 ` Benjamin Herrenschmidt
2011-01-12 5:07 ` Greg KH
2011-01-13 22:21 ` Yinghai Lu
2011-01-13 22:44 ` Greg KH
2011-01-13 22:52 ` Thomas Gleixner
2011-01-13 23:02 ` Greg KH
2011-01-13 23:04 ` Yinghai Lu
2011-01-13 23:31 ` Thomas Gleixner
2011-01-14 22:42 ` Yinghai Lu
2011-01-13 23:48 ` Greg KH
2011-01-14 0:31 ` Yinghai Lu
2011-01-14 0:40 ` Benjamin Herrenschmidt
2011-01-14 1:00 ` Yinghai Lu
2011-01-14 14:46 ` Christoph Lameter
2011-01-14 0:44 ` Greg KH
2011-01-14 1:12 ` Yinghai Lu
2011-01-14 14:50 ` Christoph Lameter
2011-01-14 21:22 ` [PATCH] x86: set percpu cpu0 lpj to default Yinghai Lu
2011-01-14 21:28 ` Christoph Lameter
2011-01-15 13:09 ` Tejun Heo
2011-01-16 2:32 ` Yinghai Lu
2011-01-14 22:16 ` Greg KH
2011-01-14 22:29 ` Yinghai Lu
2011-01-11 5:18 ` [PATCH -v3 1/4] pci, usb: Make usb handoff func all take base remapping Benjamin Herrenschmidt
2011-01-11 0:55 ` [PATCH 2/4] x86: early_quirk check all dev/func in domain 0 Yinghai Lu
2011-01-11 1:09 ` Greg KH
2011-01-11 1:46 ` Yinghai Lu
2011-01-11 3:38 ` Greg KH
2011-01-11 3:39 ` Greg KH
2011-01-11 0:55 ` [PATCH 3/4] x86, pci: add dummy pci device for early stage Yinghai Lu
2011-01-11 0:55 ` Yinghai Lu [this message]
2011-01-11 1:08 ` [PATCH -v3 4/4] x86: usb handoff in early_quirk Greg KH
2011-01-11 1:41 ` Yinghai Lu
2011-01-11 1:07 ` [PATCH -v3 0/4] x86, usb, pci: Disable usb legacy support early Greg KH
2011-01-11 1:25 ` Yinghai Lu
2011-01-11 3:35 ` Greg KH
[not found] ` <4D2AC584.6010004@kernel.org>
2011-01-10 8:43 ` [PATCH -v2 1/4] pci, usb: Seperate usb handoff func to another file Yinghai Lu
2011-01-10 8:44 ` [PATCH 2/4] x86: early_quirk check all dev/func in domain 0 Yinghai Lu
2011-01-10 8:44 ` [PATCH 3/4] x86, pci: add dummy pci device for early stage Yinghai Lu
2011-01-10 8:44 ` [PATCH v2 4/4] x86: usb handoff in early_quirk Yinghai Lu
2011-01-10 15:57 ` [PATCH 0/3] x86, usb, pci: Disable usb legacy support early Greg KH
2011-01-10 18:27 ` Jesse Barnes
2011-01-10 20:10 ` Yinghai Lu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D2BAA85.9060902@kernel.org \
--to=yinghai@kernel.org \
--cc=benh@kernel.crashing.org \
--cc=greg@kroah.com \
--cc=hpa@zytor.com \
--cc=jbarnes@virtuousgeek.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).