diff options
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 75 |
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 @@ | |||
1 | /* | ||
2 | * xHCI host controller driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Intel Corp. | ||
5 | * | ||
6 | * Author: Sarah Sharp | ||
7 | * Some code borrowed from the Linux EHCI driver. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
15 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
16 | * for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software Foundation, | ||
20 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/usb.h> | ||
24 | |||
25 | #include "xhci.h" | ||
26 | |||
27 | void xhci_mem_cleanup(struct xhci_hcd *xhci) | ||
28 | { | ||
29 | xhci->page_size = 0; | ||
30 | xhci->page_shift = 0; | ||
31 | } | ||
32 | |||
33 | int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | ||
34 | { | ||
35 | unsigned int val, val2; | ||
36 | u32 page_size; | ||
37 | int i; | ||
38 | |||
39 | page_size = xhci_readl(xhci, &xhci->op_regs->page_size); | ||
40 | xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size); | ||
41 | for (i = 0; i < 16; i++) { | ||
42 | if ((0x1 & page_size) != 0) | ||
43 | break; | ||
44 | page_size = page_size >> 1; | ||
45 | } | ||
46 | if (i < 16) | ||
47 | xhci_dbg(xhci, "Supported page size of %iK\n", (1 << (i+12)) / 1024); | ||
48 | else | ||
49 | xhci_warn(xhci, "WARN: no supported page size\n"); | ||
50 | /* Use 4K pages, since that's common and the minimum the HC supports */ | ||
51 | xhci->page_shift = 12; | ||
52 | xhci->page_size = 1 << xhci->page_shift; | ||
53 | xhci_dbg(xhci, "HCD page size set to %iK\n", xhci->page_size / 1024); | ||
54 | |||
55 | /* | ||
56 | * Program the Number of Device Slots Enabled field in the CONFIG | ||
57 | * register with the max value of slots the HC can handle. | ||
58 | */ | ||
59 | val = HCS_MAX_SLOTS(xhci_readl(xhci, &xhci->cap_regs->hcs_params1)); | ||
60 | xhci_dbg(xhci, "// xHC can handle at most %d device slots.\n", | ||
61 | (unsigned int) val); | ||
62 | val2 = xhci_readl(xhci, &xhci->op_regs->config_reg); | ||
63 | val |= (val2 & ~HCS_SLOTS_MASK); | ||
64 | xhci_dbg(xhci, "// Setting Max device slots reg = 0x%x.\n", | ||
65 | (unsigned int) val); | ||
66 | xhci_writel(xhci, val, &xhci->op_regs->config_reg); | ||
67 | |||
68 | xhci->ir_set = &xhci->run_regs->ir_set[0]; | ||
69 | |||
70 | return 0; | ||
71 | fail: | ||
72 | xhci_warn(xhci, "Couldn't initialize memory\n"); | ||
73 | xhci_mem_cleanup(xhci); | ||
74 | return -ENOMEM; | ||
75 | } | ||