summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci-mem.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-04-27 19:52:28 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-15 21:44:48 -0700
commit66d4eadd8d067269ea8fead1a50fe87c2979a80d (patch)
treeb0324868818058161e528bd194f6888456924fd4 /drivers/usb/host/xhci-mem.c
parent74c6874199af98e602bb7c5fb1beb9cffda98729 (diff)
USB: xhci: BIOS handoff and HW initialization.
Add PCI initialization code to take control of the xHCI host controller away from the BIOS, halt, and reset the host controller. The xHCI spec says that BIOSes must give up the host controller within 5 seconds. Add some host controller glue functions to handle hardware initialization and memory allocation for the host controller. The current xHCI prototypes use PCI interrupts, but the xHCI spec requires MSI-X interrupts. Add code to support MSI-X interrupts, but use the PCI interrupts for now. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r--drivers/usb/host/xhci-mem.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
new file mode 100644
index 000000000000..0e383f9c380c
--- /dev/null
+++ b/drivers/usb/host/xhci-mem.c
@@ -0,0 +1,75 @@
+/*
+ * xHCI host controller driver
+ *
+ * Copyright (C) 2008 Intel Corp.
+ *
+ * Author: Sarah Sharp
+ * Some code borrowed from the Linux EHCI driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/usb.h>
+
+#include "xhci.h"
+
+void xhci_mem_cleanup(struct xhci_hcd *xhci)
+{
+ xhci->page_size = 0;
+ xhci->page_shift = 0;
+}
+
+int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
+{
+ unsigned int val, val2;
+ u32 page_size;
+ int i;
+
+ page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
+ xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
+ for (i = 0; i < 16; i++) {
+ if ((0x1 & page_size) != 0)
+ break;
+ page_size = page_size >> 1;
+ }
+ if (i < 16)
+ xhci_dbg(xhci, "Supported page size of %iK\n", (1 << (i+12)) / 1024);
+ else
+ xhci_warn(xhci, "WARN: no supported page size\n");
+ /* Use 4K pages, since that's common and the minimum the HC supports */
+ xhci->page_shift = 12;
+ xhci->page_size = 1 << xhci->page_shift;
+ xhci_dbg(xhci, "HCD page size set to %iK\n", xhci->page_size / 1024);
+
+ /*
+ * Program the Number of Device Slots Enabled field in the CONFIG
+ * register with the max value of slots the HC can handle.
+ */
+ val = HCS_MAX_SLOTS(xhci_readl(xhci, &xhci->cap_regs->hcs_params1));
+ xhci_dbg(xhci, "// xHC can handle at most %d device slots.\n",
+ (unsigned int) val);
+ val2 = xhci_readl(xhci, &xhci->op_regs->config_reg);
+ val |= (val2 & ~HCS_SLOTS_MASK);
+ xhci_dbg(xhci, "// Setting Max device slots reg = 0x%x.\n",
+ (unsigned int) val);
+ xhci_writel(xhci, val, &xhci->op_regs->config_reg);
+
+ xhci->ir_set = &xhci->run_regs->ir_set[0];
+
+ return 0;
+fail:
+ xhci_warn(xhci, "Couldn't initialize memory\n");
+ xhci_mem_cleanup(xhci);
+ return -ENOMEM;
+}