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 1/4] pci, usb: Make usb handoff func all take base remapping
Date: Mon, 10 Jan 2011 16:55:17 -0800 [thread overview]
Message-ID: <4D2BAA75.60001@kernel.org> (raw)
In-Reply-To: <4D2BA8FE.9090204@kernel.org>
So later could reuse them to do usb handoff much early for x86.
will make arch early code get MMIO BAR and do remapping itself.
-v2: still keep pci_device *pdev as parameter according to BenH.
-v3: expose three functions that take *base instead of including .c file.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/usb/host/pci-quirks.c | 195 ++++++++++++++++++++++++------------------
drivers/usb/host/pci-quirks.h | 6 +
2 files changed, 120 insertions(+), 81 deletions(-)
Index: linux-2.6/drivers/usb/host/pci-quirks.c
===================================================================
--- linux-2.6.orig/drivers/usb/host/pci-quirks.c
+++ linux-2.6/drivers/usb/host/pci-quirks.c
@@ -17,6 +17,19 @@
#include "pci-quirks.h"
#include "xhci-ext-caps.h"
+static void default_usb_handoff_udelay(unsigned long usecs)
+{
+ udelay(usecs);
+}
+
+static void __devinit default_usb_handoff_msleep(unsigned long msecs)
+{
+ msleep(msecs);
+}
+
+void (*usb_handoff_udelay)(unsigned long) = default_usb_handoff_udelay;
+void (*usb_handoff_msleep)(unsigned long) __devinitdata =
+ default_usb_handoff_msleep;
#define UHCI_USBLEGSUP 0xc0 /* legacy support */
#define UHCI_USBCMD 0 /* command register */
@@ -71,7 +84,7 @@ void uhci_reset_hc(struct pci_dev *pdev,
*/
outw(UHCI_USBCMD_HCRESET, base + UHCI_USBCMD);
mb();
- udelay(5);
+ (*usb_handoff_udelay)(5);
if (inw(base + UHCI_USBCMD) & UHCI_USBCMD_HCRESET)
dev_warn(&pdev->dev, "HCRESET not completed yet!\n");
@@ -106,78 +119,38 @@ int uhci_check_and_reset_hc(struct pci_d
*/
pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup);
if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) {
- dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n",
- __func__, legsup);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "legsup = 0x%04x\n", legsup);
goto reset_needed;
}
cmd = inw(base + UHCI_USBCMD);
if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) ||
!(cmd & UHCI_USBCMD_EGSM)) {
- dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n",
- __func__, cmd);
+ dev_printk(KERN_DEBUG, &pdev->dev, "cmd = 0x%04x\n", cmd);
goto reset_needed;
}
intr = inw(base + UHCI_USBINTR);
if (intr & (~UHCI_USBINTR_RESUME)) {
- dev_dbg(&pdev->dev, "%s: intr = 0x%04x\n",
- __func__, intr);
+ dev_printk(KERN_DEBUG, &pdev->dev, "intr = 0x%04x\n", intr);
goto reset_needed;
}
return 0;
reset_needed:
- dev_dbg(&pdev->dev, "Performing full reset\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "Performing full reset\n");
+
uhci_reset_hc(pdev, base);
+
return 1;
}
EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
-static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
-{
- u16 cmd;
- return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
-}
-
-#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
-#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
-
-static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
-{
- unsigned long base = 0;
- int i;
-
- if (!pio_enabled(pdev))
- return;
-
- for (i = 0; i < PCI_ROM_RESOURCE; i++)
- if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
- base = pci_resource_start(pdev, i);
- break;
- }
-
- if (base)
- uhci_check_and_reset_hc(pdev, base);
-}
-
-static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
+void __devinit __usb_handoff_ohci(struct pci_dev *pdev, void __iomem *base)
{
- return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
-}
-
-static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
-{
- void __iomem *base;
u32 control;
- if (!mmio_resource_enabled(pdev, 0))
- return;
-
- base = pci_ioremap_bar(pdev, 0);
- if (base == NULL)
- return;
-
control = readl(base + OHCI_CONTROL);
/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
@@ -193,7 +166,7 @@ static void __devinit quirk_usb_handoff_
while (wait_time > 0 &&
readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
wait_time -= 10;
- msleep(10);
+ (*usb_handoff_msleep)(10);
}
if (wait_time <= 0)
dev_warn(&pdev->dev, "OHCI: BIOS handoff failed"
@@ -210,26 +183,17 @@ static void __devinit quirk_usb_handoff_
*/
writel(~(u32)0, base + OHCI_INTRDISABLE);
writel(~(u32)0, base + OHCI_INTRSTATUS);
-
- iounmap(base);
}
-static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
+void __devinit __usb_handoff_ehci(struct pci_dev *pdev, void __iomem *base)
{
int wait_time, delta;
- void __iomem *base, *op_reg_base;
+ void *op_reg_base;
u32 hcc_params, val;
u8 offset, cap_length;
int count = 256/4;
int tried_handoff = 0;
- if (!mmio_resource_enabled(pdev, 0))
- return;
-
- base = pci_ioremap_bar(pdev, 0);
- if (base == NULL)
- return;
-
cap_length = readb(base);
op_reg_base = base + cap_length;
@@ -247,7 +211,8 @@ static void __devinit quirk_usb_disable_
switch (cap & 0xff) {
case 1: /* BIOS/SMM/... handoff support */
if ((cap & EHCI_USBLEGSUP_BIOS)) {
- dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n");
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "EHCI: BIOS handoff\n");
#if 0
/* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on,
@@ -279,7 +244,7 @@ static void __devinit quirk_usb_disable_
msec = 1000;
while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
tried_handoff = 1;
- msleep(10);
+ (*usb_handoff_msleep)(10);
msec -= 10;
pci_read_config_dword(pdev, offset, &cap);
}
@@ -330,18 +295,15 @@ static void __devinit quirk_usb_disable_
delta = 100;
do {
writel(0x3f, op_reg_base + EHCI_USBSTS);
- udelay(delta);
+ (*usb_handoff_udelay)(delta);
wait_time -= delta;
val = readl(op_reg_base + EHCI_USBSTS);
- if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
+ if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED))
break;
- }
} while (wait_time > 0);
}
writel(0, op_reg_base + EHCI_USBINTR);
writel(0x3f, op_reg_base + EHCI_USBSTS);
-
- iounmap(base);
}
/*
@@ -357,7 +319,7 @@ static void __devinit quirk_usb_disable_
* Returns -ETIMEDOUT if this condition is not true after
* wait_usec microseconds have passed.
*/
-static int handshake(void __iomem *ptr, u32 mask, u32 done,
+static int __devinit handshake(void __iomem *ptr, u32 mask, u32 done,
int wait_usec, int delay_usec)
{
u32 result;
@@ -367,7 +329,7 @@ static int handshake(void __iomem *ptr,
result &= mask;
if (result == done)
return 0;
- udelay(delay_usec);
+ (*usb_handoff_udelay)(delay_usec);
wait_usec -= delay_usec;
} while (wait_usec > 0);
return -ETIMEDOUT;
@@ -381,22 +343,13 @@ static int handshake(void __iomem *ptr,
* and then waits 5 seconds for the BIOS to hand over control.
* If we timeout, assume the BIOS is broken and take control anyway.
*/
-static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
+void __usb_handoff_xhci(struct pci_dev *pdev, void __iomem *base)
{
- void __iomem *base;
int ext_cap_offset;
void __iomem *op_reg_base;
u32 val;
int timeout;
- if (!mmio_resource_enabled(pdev, 0))
- return;
-
- base = ioremap_nocache(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- if (base == NULL)
- return;
-
/*
* Find the Legacy Support Capability register -
* this is optional for xHCI host controllers.
@@ -462,6 +415,86 @@ hc_init:
"xHCI HW did not halt within %d usec "
"status = 0x%x\n", XHCI_MAX_HALT_USEC, val);
}
+}
+
+static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
+{
+ u16 cmd;
+ return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
+}
+
+#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
+#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
+
+static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
+{
+ unsigned long base = 0;
+ int i;
+
+ if (!pio_enabled(pdev))
+ return;
+
+ for (i = 0; i < PCI_ROM_RESOURCE; i++)
+ if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
+ base = pci_resource_start(pdev, i);
+ break;
+ }
+
+ if (!base)
+ return;
+
+ uhci_check_and_reset_hc(pdev, base);
+}
+
+static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
+{
+ return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
+}
+
+static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
+{
+ void __iomem *base;
+
+ if (!mmio_resource_enabled(pdev, 0))
+ return;
+
+ base = pci_ioremap_bar(pdev, 0);
+ if (base == NULL)
+ return;
+
+ __usb_handoff_ohci(pdev, base);
+
+ iounmap(base);
+}
+
+static void __devinit quirk_usb_handoff_ehci(struct pci_dev *pdev)
+{
+ void __iomem *base;
+
+ if (!mmio_resource_enabled(pdev, 0))
+ return;
+
+ base = pci_ioremap_bar(pdev, 0);
+ if (base == NULL)
+ return;
+
+ __usb_handoff_ehci(pdev, base);
+
+ iounmap(base);
+}
+
+static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
+{
+ void __iomem *base;
+
+ if (!mmio_resource_enabled(pdev, 0))
+ return;
+
+ base = pci_ioremap_bar(pdev, 0);
+ if (base == NULL)
+ return;
+
+ __usb_handoff_xhci(pdev, base);
iounmap(base);
}
@@ -473,7 +506,7 @@ static void __devinit quirk_usb_early_ha
else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI)
quirk_usb_handoff_ohci(pdev);
else if (pdev->class == PCI_CLASS_SERIAL_USB_EHCI)
- quirk_usb_disable_ehci(pdev);
+ quirk_usb_handoff_ehci(pdev);
else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI)
quirk_usb_handoff_xhci(pdev);
}
Index: linux-2.6/drivers/usb/host/pci-quirks.h
===================================================================
--- linux-2.6.orig/drivers/usb/host/pci-quirks.h
+++ linux-2.6/drivers/usb/host/pci-quirks.h
@@ -3,5 +3,11 @@
void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
+void __usb_handoff_ohci(struct pci_dev *pdev, void __iomem *base);
+void __usb_handoff_ehci(struct pci_dev *pdev, void __iomem *base);
+void __usb_handoff_xhci(struct pci_dev *pdev, void __iomem *base);
+
+extern void (*usb_handoff_udelay)(unsigned long);
+extern void (*usb_handoff_msleep)(unsigned long);
#endif /* __LINUX_USB_PCI_QUIRKS_H */
next prev parent reply other threads:[~2011-01-11 0:56 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 ` Yinghai Lu [this message]
2011-01-11 1:07 ` [PATCH -v3 1/4] pci, usb: Make usb handoff func all take base remapping 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 ` [PATCH -v3 4/4] x86: usb handoff in early_quirk Yinghai Lu
2011-01-11 1:08 ` 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=4D2BAA75.60001@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.