1*aeb9dd1dSLu Baolu /** 2*aeb9dd1dSLu Baolu * xhci-dbc.c - xHCI debug capability early driver 3*aeb9dd1dSLu Baolu * 4*aeb9dd1dSLu Baolu * Copyright (C) 2016 Intel Corporation 5*aeb9dd1dSLu Baolu * 6*aeb9dd1dSLu Baolu * Author: Lu Baolu <baolu.lu@linux.intel.com> 7*aeb9dd1dSLu Baolu * 8*aeb9dd1dSLu Baolu * This program is free software; you can redistribute it and/or modify 9*aeb9dd1dSLu Baolu * it under the terms of the GNU General Public License version 2 as 10*aeb9dd1dSLu Baolu * published by the Free Software Foundation. 11*aeb9dd1dSLu Baolu */ 12*aeb9dd1dSLu Baolu 13*aeb9dd1dSLu Baolu #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ 14*aeb9dd1dSLu Baolu 15*aeb9dd1dSLu Baolu #include <linux/console.h> 16*aeb9dd1dSLu Baolu #include <linux/pci_regs.h> 17*aeb9dd1dSLu Baolu #include <linux/pci_ids.h> 18*aeb9dd1dSLu Baolu #include <linux/bootmem.h> 19*aeb9dd1dSLu Baolu #include <linux/io.h> 20*aeb9dd1dSLu Baolu #include <asm/pci-direct.h> 21*aeb9dd1dSLu Baolu #include <asm/fixmap.h> 22*aeb9dd1dSLu Baolu #include <linux/bcd.h> 23*aeb9dd1dSLu Baolu #include <linux/export.h> 24*aeb9dd1dSLu Baolu #include <linux/version.h> 25*aeb9dd1dSLu Baolu #include <linux/module.h> 26*aeb9dd1dSLu Baolu #include <linux/delay.h> 27*aeb9dd1dSLu Baolu #include <linux/kthread.h> 28*aeb9dd1dSLu Baolu 29*aeb9dd1dSLu Baolu #include "../host/xhci.h" 30*aeb9dd1dSLu Baolu #include "xhci-dbc.h" 31*aeb9dd1dSLu Baolu 32*aeb9dd1dSLu Baolu static struct xdbc_state xdbc; 33*aeb9dd1dSLu Baolu static bool early_console_keep; 34*aeb9dd1dSLu Baolu 35*aeb9dd1dSLu Baolu #define XDBC_TRACE 36*aeb9dd1dSLu Baolu #ifdef XDBC_TRACE 37*aeb9dd1dSLu Baolu #define xdbc_trace trace_printk 38*aeb9dd1dSLu Baolu #else 39*aeb9dd1dSLu Baolu static inline void xdbc_trace(const char *fmt, ...) { } 40*aeb9dd1dSLu Baolu #endif /* XDBC_TRACE */ 41*aeb9dd1dSLu Baolu 42*aeb9dd1dSLu Baolu static void __iomem * __init xdbc_map_pci_mmio(u32 bus, u32 dev, u32 func) 43*aeb9dd1dSLu Baolu { 44*aeb9dd1dSLu Baolu u64 val64, sz64, mask64; 45*aeb9dd1dSLu Baolu void __iomem *base; 46*aeb9dd1dSLu Baolu u32 val, sz; 47*aeb9dd1dSLu Baolu u8 byte; 48*aeb9dd1dSLu Baolu 49*aeb9dd1dSLu Baolu val = read_pci_config(bus, dev, func, PCI_BASE_ADDRESS_0); 50*aeb9dd1dSLu Baolu write_pci_config(bus, dev, func, PCI_BASE_ADDRESS_0, ~0); 51*aeb9dd1dSLu Baolu sz = read_pci_config(bus, dev, func, PCI_BASE_ADDRESS_0); 52*aeb9dd1dSLu Baolu write_pci_config(bus, dev, func, PCI_BASE_ADDRESS_0, val); 53*aeb9dd1dSLu Baolu 54*aeb9dd1dSLu Baolu if (val == 0xffffffff || sz == 0xffffffff) { 55*aeb9dd1dSLu Baolu pr_notice("invalid mmio bar\n"); 56*aeb9dd1dSLu Baolu return NULL; 57*aeb9dd1dSLu Baolu } 58*aeb9dd1dSLu Baolu 59*aeb9dd1dSLu Baolu val64 = val & PCI_BASE_ADDRESS_MEM_MASK; 60*aeb9dd1dSLu Baolu sz64 = sz & PCI_BASE_ADDRESS_MEM_MASK; 61*aeb9dd1dSLu Baolu mask64 = PCI_BASE_ADDRESS_MEM_MASK; 62*aeb9dd1dSLu Baolu 63*aeb9dd1dSLu Baolu if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) { 64*aeb9dd1dSLu Baolu val = read_pci_config(bus, dev, func, PCI_BASE_ADDRESS_0 + 4); 65*aeb9dd1dSLu Baolu write_pci_config(bus, dev, func, PCI_BASE_ADDRESS_0 + 4, ~0); 66*aeb9dd1dSLu Baolu sz = read_pci_config(bus, dev, func, PCI_BASE_ADDRESS_0 + 4); 67*aeb9dd1dSLu Baolu write_pci_config(bus, dev, func, PCI_BASE_ADDRESS_0 + 4, val); 68*aeb9dd1dSLu Baolu 69*aeb9dd1dSLu Baolu val64 |= (u64)val << 32; 70*aeb9dd1dSLu Baolu sz64 |= (u64)sz << 32; 71*aeb9dd1dSLu Baolu mask64 |= ~0ULL << 32; 72*aeb9dd1dSLu Baolu } 73*aeb9dd1dSLu Baolu 74*aeb9dd1dSLu Baolu sz64 &= mask64; 75*aeb9dd1dSLu Baolu 76*aeb9dd1dSLu Baolu if (!sz64) { 77*aeb9dd1dSLu Baolu pr_notice("invalid mmio address\n"); 78*aeb9dd1dSLu Baolu return NULL; 79*aeb9dd1dSLu Baolu } 80*aeb9dd1dSLu Baolu 81*aeb9dd1dSLu Baolu sz64 = 1ULL << __ffs64(sz64); 82*aeb9dd1dSLu Baolu 83*aeb9dd1dSLu Baolu /* Check if the mem space is enabled: */ 84*aeb9dd1dSLu Baolu byte = read_pci_config_byte(bus, dev, func, PCI_COMMAND); 85*aeb9dd1dSLu Baolu if (!(byte & PCI_COMMAND_MEMORY)) { 86*aeb9dd1dSLu Baolu byte |= PCI_COMMAND_MEMORY; 87*aeb9dd1dSLu Baolu write_pci_config_byte(bus, dev, func, PCI_COMMAND, byte); 88*aeb9dd1dSLu Baolu } 89*aeb9dd1dSLu Baolu 90*aeb9dd1dSLu Baolu xdbc.xhci_start = val64; 91*aeb9dd1dSLu Baolu xdbc.xhci_length = sz64; 92*aeb9dd1dSLu Baolu base = early_ioremap(val64, sz64); 93*aeb9dd1dSLu Baolu 94*aeb9dd1dSLu Baolu return base; 95*aeb9dd1dSLu Baolu } 96*aeb9dd1dSLu Baolu 97*aeb9dd1dSLu Baolu static void * __init xdbc_get_page(dma_addr_t *dma_addr) 98*aeb9dd1dSLu Baolu { 99*aeb9dd1dSLu Baolu void *virt; 100*aeb9dd1dSLu Baolu 101*aeb9dd1dSLu Baolu virt = alloc_bootmem_pages_nopanic(PAGE_SIZE); 102*aeb9dd1dSLu Baolu if (!virt) 103*aeb9dd1dSLu Baolu return NULL; 104*aeb9dd1dSLu Baolu 105*aeb9dd1dSLu Baolu if (dma_addr) 106*aeb9dd1dSLu Baolu *dma_addr = (dma_addr_t)__pa(virt); 107*aeb9dd1dSLu Baolu 108*aeb9dd1dSLu Baolu return virt; 109*aeb9dd1dSLu Baolu } 110*aeb9dd1dSLu Baolu 111*aeb9dd1dSLu Baolu static u32 __init xdbc_find_dbgp(int xdbc_num, u32 *b, u32 *d, u32 *f) 112*aeb9dd1dSLu Baolu { 113*aeb9dd1dSLu Baolu u32 bus, dev, func, class; 114*aeb9dd1dSLu Baolu 115*aeb9dd1dSLu Baolu for (bus = 0; bus < XDBC_PCI_MAX_BUSES; bus++) { 116*aeb9dd1dSLu Baolu for (dev = 0; dev < XDBC_PCI_MAX_DEVICES; dev++) { 117*aeb9dd1dSLu Baolu for (func = 0; func < XDBC_PCI_MAX_FUNCTION; func++) { 118*aeb9dd1dSLu Baolu 119*aeb9dd1dSLu Baolu class = read_pci_config(bus, dev, func, PCI_CLASS_REVISION); 120*aeb9dd1dSLu Baolu if ((class >> 8) != PCI_CLASS_SERIAL_USB_XHCI) 121*aeb9dd1dSLu Baolu continue; 122*aeb9dd1dSLu Baolu 123*aeb9dd1dSLu Baolu if (xdbc_num-- != 0) 124*aeb9dd1dSLu Baolu continue; 125*aeb9dd1dSLu Baolu 126*aeb9dd1dSLu Baolu *b = bus; 127*aeb9dd1dSLu Baolu *d = dev; 128*aeb9dd1dSLu Baolu *f = func; 129*aeb9dd1dSLu Baolu 130*aeb9dd1dSLu Baolu return 0; 131*aeb9dd1dSLu Baolu } 132*aeb9dd1dSLu Baolu } 133*aeb9dd1dSLu Baolu } 134*aeb9dd1dSLu Baolu 135*aeb9dd1dSLu Baolu return -1; 136*aeb9dd1dSLu Baolu } 137*aeb9dd1dSLu Baolu 138*aeb9dd1dSLu Baolu static int handshake(void __iomem *ptr, u32 mask, u32 done, int wait, int delay) 139*aeb9dd1dSLu Baolu { 140*aeb9dd1dSLu Baolu u32 result; 141*aeb9dd1dSLu Baolu 142*aeb9dd1dSLu Baolu do { 143*aeb9dd1dSLu Baolu result = readl(ptr); 144*aeb9dd1dSLu Baolu result &= mask; 145*aeb9dd1dSLu Baolu if (result == done) 146*aeb9dd1dSLu Baolu return 0; 147*aeb9dd1dSLu Baolu udelay(delay); 148*aeb9dd1dSLu Baolu wait -= delay; 149*aeb9dd1dSLu Baolu } while (wait > 0); 150*aeb9dd1dSLu Baolu 151*aeb9dd1dSLu Baolu return -ETIMEDOUT; 152*aeb9dd1dSLu Baolu } 153*aeb9dd1dSLu Baolu 154*aeb9dd1dSLu Baolu static void __init xdbc_bios_handoff(void) 155*aeb9dd1dSLu Baolu { 156*aeb9dd1dSLu Baolu int offset, timeout; 157*aeb9dd1dSLu Baolu u32 val; 158*aeb9dd1dSLu Baolu 159*aeb9dd1dSLu Baolu offset = xhci_find_next_ext_cap(xdbc.xhci_base, 0, XHCI_EXT_CAPS_LEGACY); 160*aeb9dd1dSLu Baolu val = readl(xdbc.xhci_base + offset); 161*aeb9dd1dSLu Baolu 162*aeb9dd1dSLu Baolu if (val & XHCI_HC_BIOS_OWNED) { 163*aeb9dd1dSLu Baolu writel(val | XHCI_HC_OS_OWNED, xdbc.xhci_base + offset); 164*aeb9dd1dSLu Baolu timeout = handshake(xdbc.xhci_base + offset, XHCI_HC_BIOS_OWNED, 0, 5000, 10); 165*aeb9dd1dSLu Baolu 166*aeb9dd1dSLu Baolu if (timeout) { 167*aeb9dd1dSLu Baolu pr_notice("failed to hand over xHCI control from BIOS\n"); 168*aeb9dd1dSLu Baolu writel(val & ~XHCI_HC_BIOS_OWNED, xdbc.xhci_base + offset); 169*aeb9dd1dSLu Baolu } 170*aeb9dd1dSLu Baolu } 171*aeb9dd1dSLu Baolu 172*aeb9dd1dSLu Baolu /* Disable BIOS SMIs and clear all SMI events: */ 173*aeb9dd1dSLu Baolu val = readl(xdbc.xhci_base + offset + XHCI_LEGACY_CONTROL_OFFSET); 174*aeb9dd1dSLu Baolu val &= XHCI_LEGACY_DISABLE_SMI; 175*aeb9dd1dSLu Baolu val |= XHCI_LEGACY_SMI_EVENTS; 176*aeb9dd1dSLu Baolu writel(val, xdbc.xhci_base + offset + XHCI_LEGACY_CONTROL_OFFSET); 177*aeb9dd1dSLu Baolu } 178*aeb9dd1dSLu Baolu 179*aeb9dd1dSLu Baolu static int __init 180*aeb9dd1dSLu Baolu xdbc_alloc_ring(struct xdbc_segment *seg, struct xdbc_ring *ring) 181*aeb9dd1dSLu Baolu { 182*aeb9dd1dSLu Baolu seg->trbs = xdbc_get_page(&seg->dma); 183*aeb9dd1dSLu Baolu if (!seg->trbs) 184*aeb9dd1dSLu Baolu return -ENOMEM; 185*aeb9dd1dSLu Baolu 186*aeb9dd1dSLu Baolu ring->segment = seg; 187*aeb9dd1dSLu Baolu 188*aeb9dd1dSLu Baolu return 0; 189*aeb9dd1dSLu Baolu } 190*aeb9dd1dSLu Baolu 191*aeb9dd1dSLu Baolu static void __init xdbc_free_ring(struct xdbc_ring *ring) 192*aeb9dd1dSLu Baolu { 193*aeb9dd1dSLu Baolu struct xdbc_segment *seg = ring->segment; 194*aeb9dd1dSLu Baolu 195*aeb9dd1dSLu Baolu if (!seg) 196*aeb9dd1dSLu Baolu return; 197*aeb9dd1dSLu Baolu 198*aeb9dd1dSLu Baolu free_bootmem(seg->dma, PAGE_SIZE); 199*aeb9dd1dSLu Baolu ring->segment = NULL; 200*aeb9dd1dSLu Baolu } 201*aeb9dd1dSLu Baolu 202*aeb9dd1dSLu Baolu static void xdbc_reset_ring(struct xdbc_ring *ring) 203*aeb9dd1dSLu Baolu { 204*aeb9dd1dSLu Baolu struct xdbc_segment *seg = ring->segment; 205*aeb9dd1dSLu Baolu struct xdbc_trb *link_trb; 206*aeb9dd1dSLu Baolu 207*aeb9dd1dSLu Baolu memset(seg->trbs, 0, PAGE_SIZE); 208*aeb9dd1dSLu Baolu 209*aeb9dd1dSLu Baolu ring->enqueue = seg->trbs; 210*aeb9dd1dSLu Baolu ring->dequeue = seg->trbs; 211*aeb9dd1dSLu Baolu ring->cycle_state = 1; 212*aeb9dd1dSLu Baolu 213*aeb9dd1dSLu Baolu if (ring != &xdbc.evt_ring) { 214*aeb9dd1dSLu Baolu link_trb = &seg->trbs[XDBC_TRBS_PER_SEGMENT - 1]; 215*aeb9dd1dSLu Baolu link_trb->field[0] = cpu_to_le32(lower_32_bits(seg->dma)); 216*aeb9dd1dSLu Baolu link_trb->field[1] = cpu_to_le32(upper_32_bits(seg->dma)); 217*aeb9dd1dSLu Baolu link_trb->field[3] = cpu_to_le32(TRB_TYPE(TRB_LINK)) | cpu_to_le32(LINK_TOGGLE); 218*aeb9dd1dSLu Baolu } 219*aeb9dd1dSLu Baolu } 220*aeb9dd1dSLu Baolu 221*aeb9dd1dSLu Baolu static inline void xdbc_put_utf16(u16 *s, const char *c, size_t size) 222*aeb9dd1dSLu Baolu { 223*aeb9dd1dSLu Baolu int i; 224*aeb9dd1dSLu Baolu 225*aeb9dd1dSLu Baolu for (i = 0; i < size; i++) 226*aeb9dd1dSLu Baolu s[i] = cpu_to_le16(c[i]); 227*aeb9dd1dSLu Baolu } 228*aeb9dd1dSLu Baolu 229*aeb9dd1dSLu Baolu static void xdbc_mem_init(void) 230*aeb9dd1dSLu Baolu { 231*aeb9dd1dSLu Baolu struct xdbc_ep_context *ep_in, *ep_out; 232*aeb9dd1dSLu Baolu struct usb_string_descriptor *s_desc; 233*aeb9dd1dSLu Baolu struct xdbc_erst_entry *entry; 234*aeb9dd1dSLu Baolu struct xdbc_strings *strings; 235*aeb9dd1dSLu Baolu struct xdbc_context *ctx; 236*aeb9dd1dSLu Baolu unsigned int max_burst; 237*aeb9dd1dSLu Baolu u32 string_length; 238*aeb9dd1dSLu Baolu int index = 0; 239*aeb9dd1dSLu Baolu u32 dev_info; 240*aeb9dd1dSLu Baolu 241*aeb9dd1dSLu Baolu xdbc_reset_ring(&xdbc.evt_ring); 242*aeb9dd1dSLu Baolu xdbc_reset_ring(&xdbc.in_ring); 243*aeb9dd1dSLu Baolu xdbc_reset_ring(&xdbc.out_ring); 244*aeb9dd1dSLu Baolu memset(xdbc.table_base, 0, PAGE_SIZE); 245*aeb9dd1dSLu Baolu memset(xdbc.out_buf, 0, PAGE_SIZE); 246*aeb9dd1dSLu Baolu 247*aeb9dd1dSLu Baolu /* Initialize event ring segment table: */ 248*aeb9dd1dSLu Baolu xdbc.erst_size = 16; 249*aeb9dd1dSLu Baolu xdbc.erst_base = xdbc.table_base + index * XDBC_TABLE_ENTRY_SIZE; 250*aeb9dd1dSLu Baolu xdbc.erst_dma = xdbc.table_dma + index * XDBC_TABLE_ENTRY_SIZE; 251*aeb9dd1dSLu Baolu 252*aeb9dd1dSLu Baolu index += XDBC_ERST_ENTRY_NUM; 253*aeb9dd1dSLu Baolu entry = (struct xdbc_erst_entry *)xdbc.erst_base; 254*aeb9dd1dSLu Baolu 255*aeb9dd1dSLu Baolu entry->seg_addr = cpu_to_le64(xdbc.evt_seg.dma); 256*aeb9dd1dSLu Baolu entry->seg_size = cpu_to_le32(XDBC_TRBS_PER_SEGMENT); 257*aeb9dd1dSLu Baolu entry->__reserved_0 = 0; 258*aeb9dd1dSLu Baolu 259*aeb9dd1dSLu Baolu /* Initialize ERST registers: */ 260*aeb9dd1dSLu Baolu writel(1, &xdbc.xdbc_reg->ersts); 261*aeb9dd1dSLu Baolu xdbc_write64(xdbc.erst_dma, &xdbc.xdbc_reg->erstba); 262*aeb9dd1dSLu Baolu xdbc_write64(xdbc.evt_seg.dma, &xdbc.xdbc_reg->erdp); 263*aeb9dd1dSLu Baolu 264*aeb9dd1dSLu Baolu /* Debug capability contexts: */ 265*aeb9dd1dSLu Baolu xdbc.dbcc_size = 64 * 3; 266*aeb9dd1dSLu Baolu xdbc.dbcc_base = xdbc.table_base + index * XDBC_TABLE_ENTRY_SIZE; 267*aeb9dd1dSLu Baolu xdbc.dbcc_dma = xdbc.table_dma + index * XDBC_TABLE_ENTRY_SIZE; 268*aeb9dd1dSLu Baolu 269*aeb9dd1dSLu Baolu index += XDBC_DBCC_ENTRY_NUM; 270*aeb9dd1dSLu Baolu 271*aeb9dd1dSLu Baolu /* Popluate the strings: */ 272*aeb9dd1dSLu Baolu xdbc.string_size = sizeof(struct xdbc_strings); 273*aeb9dd1dSLu Baolu xdbc.string_base = xdbc.table_base + index * XDBC_TABLE_ENTRY_SIZE; 274*aeb9dd1dSLu Baolu xdbc.string_dma = xdbc.table_dma + index * XDBC_TABLE_ENTRY_SIZE; 275*aeb9dd1dSLu Baolu strings = (struct xdbc_strings *)xdbc.string_base; 276*aeb9dd1dSLu Baolu 277*aeb9dd1dSLu Baolu index += XDBC_STRING_ENTRY_NUM; 278*aeb9dd1dSLu Baolu 279*aeb9dd1dSLu Baolu /* Serial string: */ 280*aeb9dd1dSLu Baolu s_desc = (struct usb_string_descriptor *)strings->serial; 281*aeb9dd1dSLu Baolu s_desc->bLength = (strlen(XDBC_STRING_SERIAL) + 1) * 2; 282*aeb9dd1dSLu Baolu s_desc->bDescriptorType = USB_DT_STRING; 283*aeb9dd1dSLu Baolu 284*aeb9dd1dSLu Baolu xdbc_put_utf16(s_desc->wData, XDBC_STRING_SERIAL, strlen(XDBC_STRING_SERIAL)); 285*aeb9dd1dSLu Baolu string_length = s_desc->bLength; 286*aeb9dd1dSLu Baolu string_length <<= 8; 287*aeb9dd1dSLu Baolu 288*aeb9dd1dSLu Baolu /* Product string: */ 289*aeb9dd1dSLu Baolu s_desc = (struct usb_string_descriptor *)strings->product; 290*aeb9dd1dSLu Baolu s_desc->bLength = (strlen(XDBC_STRING_PRODUCT) + 1) * 2; 291*aeb9dd1dSLu Baolu s_desc->bDescriptorType = USB_DT_STRING; 292*aeb9dd1dSLu Baolu 293*aeb9dd1dSLu Baolu xdbc_put_utf16(s_desc->wData, XDBC_STRING_PRODUCT, strlen(XDBC_STRING_PRODUCT)); 294*aeb9dd1dSLu Baolu string_length += s_desc->bLength; 295*aeb9dd1dSLu Baolu string_length <<= 8; 296*aeb9dd1dSLu Baolu 297*aeb9dd1dSLu Baolu /* Manufacture string: */ 298*aeb9dd1dSLu Baolu s_desc = (struct usb_string_descriptor *)strings->manufacturer; 299*aeb9dd1dSLu Baolu s_desc->bLength = (strlen(XDBC_STRING_MANUFACTURER) + 1) * 2; 300*aeb9dd1dSLu Baolu s_desc->bDescriptorType = USB_DT_STRING; 301*aeb9dd1dSLu Baolu 302*aeb9dd1dSLu Baolu xdbc_put_utf16(s_desc->wData, XDBC_STRING_MANUFACTURER, strlen(XDBC_STRING_MANUFACTURER)); 303*aeb9dd1dSLu Baolu string_length += s_desc->bLength; 304*aeb9dd1dSLu Baolu string_length <<= 8; 305*aeb9dd1dSLu Baolu 306*aeb9dd1dSLu Baolu /* String0: */ 307*aeb9dd1dSLu Baolu strings->string0[0] = 4; 308*aeb9dd1dSLu Baolu strings->string0[1] = USB_DT_STRING; 309*aeb9dd1dSLu Baolu strings->string0[2] = 0x09; 310*aeb9dd1dSLu Baolu strings->string0[3] = 0x04; 311*aeb9dd1dSLu Baolu 312*aeb9dd1dSLu Baolu string_length += 4; 313*aeb9dd1dSLu Baolu 314*aeb9dd1dSLu Baolu /* Populate info Context: */ 315*aeb9dd1dSLu Baolu ctx = (struct xdbc_context *)xdbc.dbcc_base; 316*aeb9dd1dSLu Baolu 317*aeb9dd1dSLu Baolu ctx->info.string0 = cpu_to_le64(xdbc.string_dma); 318*aeb9dd1dSLu Baolu ctx->info.manufacturer = cpu_to_le64(xdbc.string_dma + XDBC_MAX_STRING_LENGTH); 319*aeb9dd1dSLu Baolu ctx->info.product = cpu_to_le64(xdbc.string_dma + XDBC_MAX_STRING_LENGTH * 2); 320*aeb9dd1dSLu Baolu ctx->info.serial = cpu_to_le64(xdbc.string_dma + XDBC_MAX_STRING_LENGTH * 3); 321*aeb9dd1dSLu Baolu ctx->info.length = cpu_to_le32(string_length); 322*aeb9dd1dSLu Baolu 323*aeb9dd1dSLu Baolu /* Populate bulk out endpoint context: */ 324*aeb9dd1dSLu Baolu max_burst = DEBUG_MAX_BURST(readl(&xdbc.xdbc_reg->control)); 325*aeb9dd1dSLu Baolu ep_out = (struct xdbc_ep_context *)&ctx->out; 326*aeb9dd1dSLu Baolu 327*aeb9dd1dSLu Baolu ep_out->ep_info1 = 0; 328*aeb9dd1dSLu Baolu ep_out->ep_info2 = cpu_to_le32(EP_TYPE(BULK_OUT_EP) | MAX_PACKET(1024) | MAX_BURST(max_burst)); 329*aeb9dd1dSLu Baolu ep_out->deq = cpu_to_le64(xdbc.out_seg.dma | xdbc.out_ring.cycle_state); 330*aeb9dd1dSLu Baolu 331*aeb9dd1dSLu Baolu /* Populate bulk in endpoint context: */ 332*aeb9dd1dSLu Baolu ep_in = (struct xdbc_ep_context *)&ctx->in; 333*aeb9dd1dSLu Baolu 334*aeb9dd1dSLu Baolu ep_in->ep_info1 = 0; 335*aeb9dd1dSLu Baolu ep_in->ep_info2 = cpu_to_le32(EP_TYPE(BULK_OUT_EP) | MAX_PACKET(1024) | MAX_BURST(max_burst)); 336*aeb9dd1dSLu Baolu ep_in->deq = cpu_to_le64(xdbc.in_seg.dma | xdbc.in_ring.cycle_state); 337*aeb9dd1dSLu Baolu 338*aeb9dd1dSLu Baolu /* Set DbC context and info registers: */ 339*aeb9dd1dSLu Baolu xdbc_write64(xdbc.dbcc_dma, &xdbc.xdbc_reg->dccp); 340*aeb9dd1dSLu Baolu 341*aeb9dd1dSLu Baolu dev_info = cpu_to_le32((XDBC_VENDOR_ID << 16) | XDBC_PROTOCOL); 342*aeb9dd1dSLu Baolu writel(dev_info, &xdbc.xdbc_reg->devinfo1); 343*aeb9dd1dSLu Baolu 344*aeb9dd1dSLu Baolu dev_info = cpu_to_le32((XDBC_DEVICE_REV << 16) | XDBC_PRODUCT_ID); 345*aeb9dd1dSLu Baolu writel(dev_info, &xdbc.xdbc_reg->devinfo2); 346*aeb9dd1dSLu Baolu 347*aeb9dd1dSLu Baolu xdbc.in_buf = xdbc.out_buf + XDBC_MAX_PACKET; 348*aeb9dd1dSLu Baolu xdbc.in_dma = xdbc.out_dma + XDBC_MAX_PACKET; 349*aeb9dd1dSLu Baolu } 350*aeb9dd1dSLu Baolu 351*aeb9dd1dSLu Baolu static void xdbc_do_reset_debug_port(u32 id, u32 count) 352*aeb9dd1dSLu Baolu { 353*aeb9dd1dSLu Baolu void __iomem *ops_reg; 354*aeb9dd1dSLu Baolu void __iomem *portsc; 355*aeb9dd1dSLu Baolu u32 val, cap_length; 356*aeb9dd1dSLu Baolu int i; 357*aeb9dd1dSLu Baolu 358*aeb9dd1dSLu Baolu cap_length = readl(xdbc.xhci_base) & 0xff; 359*aeb9dd1dSLu Baolu ops_reg = xdbc.xhci_base + cap_length; 360*aeb9dd1dSLu Baolu 361*aeb9dd1dSLu Baolu id--; 362*aeb9dd1dSLu Baolu for (i = id; i < (id + count); i++) { 363*aeb9dd1dSLu Baolu portsc = ops_reg + 0x400 + i * 0x10; 364*aeb9dd1dSLu Baolu val = readl(portsc); 365*aeb9dd1dSLu Baolu if (!(val & PORT_CONNECT)) 366*aeb9dd1dSLu Baolu writel(val | PORT_RESET, portsc); 367*aeb9dd1dSLu Baolu } 368*aeb9dd1dSLu Baolu } 369*aeb9dd1dSLu Baolu 370*aeb9dd1dSLu Baolu static void xdbc_reset_debug_port(void) 371*aeb9dd1dSLu Baolu { 372*aeb9dd1dSLu Baolu u32 val, port_offset, port_count; 373*aeb9dd1dSLu Baolu int offset = 0; 374*aeb9dd1dSLu Baolu 375*aeb9dd1dSLu Baolu do { 376*aeb9dd1dSLu Baolu offset = xhci_find_next_ext_cap(xdbc.xhci_base, offset, XHCI_EXT_CAPS_PROTOCOL); 377*aeb9dd1dSLu Baolu if (!offset) 378*aeb9dd1dSLu Baolu break; 379*aeb9dd1dSLu Baolu 380*aeb9dd1dSLu Baolu val = readl(xdbc.xhci_base + offset); 381*aeb9dd1dSLu Baolu if (XHCI_EXT_PORT_MAJOR(val) != 0x3) 382*aeb9dd1dSLu Baolu continue; 383*aeb9dd1dSLu Baolu 384*aeb9dd1dSLu Baolu val = readl(xdbc.xhci_base + offset + 8); 385*aeb9dd1dSLu Baolu port_offset = XHCI_EXT_PORT_OFF(val); 386*aeb9dd1dSLu Baolu port_count = XHCI_EXT_PORT_COUNT(val); 387*aeb9dd1dSLu Baolu 388*aeb9dd1dSLu Baolu xdbc_do_reset_debug_port(port_offset, port_count); 389*aeb9dd1dSLu Baolu } while (1); 390*aeb9dd1dSLu Baolu } 391*aeb9dd1dSLu Baolu 392*aeb9dd1dSLu Baolu static void 393*aeb9dd1dSLu Baolu xdbc_queue_trb(struct xdbc_ring *ring, u32 field1, u32 field2, u32 field3, u32 field4) 394*aeb9dd1dSLu Baolu { 395*aeb9dd1dSLu Baolu struct xdbc_trb *trb, *link_trb; 396*aeb9dd1dSLu Baolu 397*aeb9dd1dSLu Baolu trb = ring->enqueue; 398*aeb9dd1dSLu Baolu trb->field[0] = cpu_to_le32(field1); 399*aeb9dd1dSLu Baolu trb->field[1] = cpu_to_le32(field2); 400*aeb9dd1dSLu Baolu trb->field[2] = cpu_to_le32(field3); 401*aeb9dd1dSLu Baolu trb->field[3] = cpu_to_le32(field4); 402*aeb9dd1dSLu Baolu 403*aeb9dd1dSLu Baolu ++(ring->enqueue); 404*aeb9dd1dSLu Baolu if (ring->enqueue >= &ring->segment->trbs[TRBS_PER_SEGMENT - 1]) { 405*aeb9dd1dSLu Baolu link_trb = ring->enqueue; 406*aeb9dd1dSLu Baolu if (ring->cycle_state) 407*aeb9dd1dSLu Baolu link_trb->field[3] |= cpu_to_le32(TRB_CYCLE); 408*aeb9dd1dSLu Baolu else 409*aeb9dd1dSLu Baolu link_trb->field[3] &= cpu_to_le32(~TRB_CYCLE); 410*aeb9dd1dSLu Baolu 411*aeb9dd1dSLu Baolu ring->enqueue = ring->segment->trbs; 412*aeb9dd1dSLu Baolu ring->cycle_state ^= 1; 413*aeb9dd1dSLu Baolu } 414*aeb9dd1dSLu Baolu } 415*aeb9dd1dSLu Baolu 416*aeb9dd1dSLu Baolu static void xdbc_ring_doorbell(int target) 417*aeb9dd1dSLu Baolu { 418*aeb9dd1dSLu Baolu writel(DOOR_BELL_TARGET(target), &xdbc.xdbc_reg->doorbell); 419*aeb9dd1dSLu Baolu } 420*aeb9dd1dSLu Baolu 421*aeb9dd1dSLu Baolu static int xdbc_start(void) 422*aeb9dd1dSLu Baolu { 423*aeb9dd1dSLu Baolu u32 ctrl, status; 424*aeb9dd1dSLu Baolu int ret; 425*aeb9dd1dSLu Baolu 426*aeb9dd1dSLu Baolu ctrl = readl(&xdbc.xdbc_reg->control); 427*aeb9dd1dSLu Baolu writel(ctrl | CTRL_DBC_ENABLE | CTRL_PORT_ENABLE, &xdbc.xdbc_reg->control); 428*aeb9dd1dSLu Baolu ret = handshake(&xdbc.xdbc_reg->control, CTRL_DBC_ENABLE, CTRL_DBC_ENABLE, 100000, 100); 429*aeb9dd1dSLu Baolu if (ret) { 430*aeb9dd1dSLu Baolu xdbc_trace("failed to initialize hardware\n"); 431*aeb9dd1dSLu Baolu return ret; 432*aeb9dd1dSLu Baolu } 433*aeb9dd1dSLu Baolu 434*aeb9dd1dSLu Baolu /* Reset port to avoid bus hang: */ 435*aeb9dd1dSLu Baolu if (xdbc.vendor == PCI_VENDOR_ID_INTEL) 436*aeb9dd1dSLu Baolu xdbc_reset_debug_port(); 437*aeb9dd1dSLu Baolu 438*aeb9dd1dSLu Baolu /* Wait for port connection: */ 439*aeb9dd1dSLu Baolu ret = handshake(&xdbc.xdbc_reg->portsc, PORTSC_CONN_STATUS, PORTSC_CONN_STATUS, 5000000, 100); 440*aeb9dd1dSLu Baolu if (ret) { 441*aeb9dd1dSLu Baolu xdbc_trace("waiting for connection timed out\n"); 442*aeb9dd1dSLu Baolu return ret; 443*aeb9dd1dSLu Baolu } 444*aeb9dd1dSLu Baolu 445*aeb9dd1dSLu Baolu /* Wait for debug device to be configured: */ 446*aeb9dd1dSLu Baolu ret = handshake(&xdbc.xdbc_reg->control, CTRL_DBC_RUN, CTRL_DBC_RUN, 5000000, 100); 447*aeb9dd1dSLu Baolu if (ret) { 448*aeb9dd1dSLu Baolu xdbc_trace("waiting for device configuration timed out\n"); 449*aeb9dd1dSLu Baolu return ret; 450*aeb9dd1dSLu Baolu } 451*aeb9dd1dSLu Baolu 452*aeb9dd1dSLu Baolu /* Check port number: */ 453*aeb9dd1dSLu Baolu status = readl(&xdbc.xdbc_reg->status); 454*aeb9dd1dSLu Baolu if (!DCST_DEBUG_PORT(status)) { 455*aeb9dd1dSLu Baolu xdbc_trace("invalid root hub port number\n"); 456*aeb9dd1dSLu Baolu return -ENODEV; 457*aeb9dd1dSLu Baolu } 458*aeb9dd1dSLu Baolu 459*aeb9dd1dSLu Baolu xdbc.port_number = DCST_DEBUG_PORT(status); 460*aeb9dd1dSLu Baolu 461*aeb9dd1dSLu Baolu xdbc_trace("DbC is running now, control 0x%08x port ID %d\n", 462*aeb9dd1dSLu Baolu readl(&xdbc.xdbc_reg->control), xdbc.port_number); 463*aeb9dd1dSLu Baolu 464*aeb9dd1dSLu Baolu return 0; 465*aeb9dd1dSLu Baolu } 466*aeb9dd1dSLu Baolu 467*aeb9dd1dSLu Baolu static int xdbc_bulk_transfer(void *data, int size, bool read) 468*aeb9dd1dSLu Baolu { 469*aeb9dd1dSLu Baolu struct xdbc_ring *ring; 470*aeb9dd1dSLu Baolu struct xdbc_trb *trb; 471*aeb9dd1dSLu Baolu u32 length, control; 472*aeb9dd1dSLu Baolu u32 cycle; 473*aeb9dd1dSLu Baolu u64 addr; 474*aeb9dd1dSLu Baolu 475*aeb9dd1dSLu Baolu if (size > XDBC_MAX_PACKET) { 476*aeb9dd1dSLu Baolu xdbc_trace("bad parameter, size %d\n", size); 477*aeb9dd1dSLu Baolu return -EINVAL; 478*aeb9dd1dSLu Baolu } 479*aeb9dd1dSLu Baolu 480*aeb9dd1dSLu Baolu if (!(xdbc.flags & XDBC_FLAGS_INITIALIZED) || 481*aeb9dd1dSLu Baolu !(xdbc.flags & XDBC_FLAGS_CONFIGURED) || 482*aeb9dd1dSLu Baolu (!read && (xdbc.flags & XDBC_FLAGS_OUT_STALL)) || 483*aeb9dd1dSLu Baolu (read && (xdbc.flags & XDBC_FLAGS_IN_STALL))) { 484*aeb9dd1dSLu Baolu 485*aeb9dd1dSLu Baolu xdbc_trace("connection not ready, flags %08x\n", xdbc.flags); 486*aeb9dd1dSLu Baolu return -EIO; 487*aeb9dd1dSLu Baolu } 488*aeb9dd1dSLu Baolu 489*aeb9dd1dSLu Baolu ring = (read ? &xdbc.in_ring : &xdbc.out_ring); 490*aeb9dd1dSLu Baolu trb = ring->enqueue; 491*aeb9dd1dSLu Baolu cycle = ring->cycle_state; 492*aeb9dd1dSLu Baolu length = TRB_LEN(size); 493*aeb9dd1dSLu Baolu control = TRB_TYPE(TRB_NORMAL) | TRB_IOC; 494*aeb9dd1dSLu Baolu 495*aeb9dd1dSLu Baolu if (cycle) 496*aeb9dd1dSLu Baolu control &= cpu_to_le32(~TRB_CYCLE); 497*aeb9dd1dSLu Baolu else 498*aeb9dd1dSLu Baolu control |= cpu_to_le32(TRB_CYCLE); 499*aeb9dd1dSLu Baolu 500*aeb9dd1dSLu Baolu if (read) { 501*aeb9dd1dSLu Baolu memset(xdbc.in_buf, 0, XDBC_MAX_PACKET); 502*aeb9dd1dSLu Baolu addr = xdbc.in_dma; 503*aeb9dd1dSLu Baolu xdbc.flags |= XDBC_FLAGS_IN_PROCESS; 504*aeb9dd1dSLu Baolu } else { 505*aeb9dd1dSLu Baolu memset(xdbc.out_buf, 0, XDBC_MAX_PACKET); 506*aeb9dd1dSLu Baolu memcpy(xdbc.out_buf, data, size); 507*aeb9dd1dSLu Baolu addr = xdbc.out_dma; 508*aeb9dd1dSLu Baolu xdbc.flags |= XDBC_FLAGS_OUT_PROCESS; 509*aeb9dd1dSLu Baolu } 510*aeb9dd1dSLu Baolu 511*aeb9dd1dSLu Baolu xdbc_queue_trb(ring, lower_32_bits(addr), upper_32_bits(addr), length, control); 512*aeb9dd1dSLu Baolu 513*aeb9dd1dSLu Baolu /* 514*aeb9dd1dSLu Baolu * Add a barrier between writes of trb fields and flipping 515*aeb9dd1dSLu Baolu * the cycle bit: 516*aeb9dd1dSLu Baolu */ 517*aeb9dd1dSLu Baolu wmb(); 518*aeb9dd1dSLu Baolu if (cycle) 519*aeb9dd1dSLu Baolu trb->field[3] |= cpu_to_le32(cycle); 520*aeb9dd1dSLu Baolu else 521*aeb9dd1dSLu Baolu trb->field[3] &= cpu_to_le32(~TRB_CYCLE); 522*aeb9dd1dSLu Baolu 523*aeb9dd1dSLu Baolu xdbc_ring_doorbell(read ? IN_EP_DOORBELL : OUT_EP_DOORBELL); 524*aeb9dd1dSLu Baolu 525*aeb9dd1dSLu Baolu return size; 526*aeb9dd1dSLu Baolu } 527*aeb9dd1dSLu Baolu 528*aeb9dd1dSLu Baolu static int xdbc_handle_external_reset(void) 529*aeb9dd1dSLu Baolu { 530*aeb9dd1dSLu Baolu int ret = 0; 531*aeb9dd1dSLu Baolu 532*aeb9dd1dSLu Baolu xdbc.flags = 0; 533*aeb9dd1dSLu Baolu writel(0, &xdbc.xdbc_reg->control); 534*aeb9dd1dSLu Baolu ret = handshake(&xdbc.xdbc_reg->control, CTRL_DBC_ENABLE, 0, 100000, 10); 535*aeb9dd1dSLu Baolu if (ret) 536*aeb9dd1dSLu Baolu goto reset_out; 537*aeb9dd1dSLu Baolu 538*aeb9dd1dSLu Baolu xdbc_mem_init(); 539*aeb9dd1dSLu Baolu 540*aeb9dd1dSLu Baolu mmiowb(); 541*aeb9dd1dSLu Baolu 542*aeb9dd1dSLu Baolu ret = xdbc_start(); 543*aeb9dd1dSLu Baolu if (ret < 0) 544*aeb9dd1dSLu Baolu goto reset_out; 545*aeb9dd1dSLu Baolu 546*aeb9dd1dSLu Baolu xdbc_trace("dbc recovered\n"); 547*aeb9dd1dSLu Baolu 548*aeb9dd1dSLu Baolu xdbc.flags |= XDBC_FLAGS_INITIALIZED | XDBC_FLAGS_CONFIGURED; 549*aeb9dd1dSLu Baolu 550*aeb9dd1dSLu Baolu xdbc_bulk_transfer(NULL, XDBC_MAX_PACKET, true); 551*aeb9dd1dSLu Baolu 552*aeb9dd1dSLu Baolu return 0; 553*aeb9dd1dSLu Baolu 554*aeb9dd1dSLu Baolu reset_out: 555*aeb9dd1dSLu Baolu xdbc_trace("failed to recover from external reset\n"); 556*aeb9dd1dSLu Baolu return ret; 557*aeb9dd1dSLu Baolu } 558*aeb9dd1dSLu Baolu 559*aeb9dd1dSLu Baolu static int __init xdbc_early_setup(void) 560*aeb9dd1dSLu Baolu { 561*aeb9dd1dSLu Baolu int ret; 562*aeb9dd1dSLu Baolu 563*aeb9dd1dSLu Baolu writel(0, &xdbc.xdbc_reg->control); 564*aeb9dd1dSLu Baolu ret = handshake(&xdbc.xdbc_reg->control, CTRL_DBC_ENABLE, 0, 100000, 100); 565*aeb9dd1dSLu Baolu if (ret) 566*aeb9dd1dSLu Baolu return ret; 567*aeb9dd1dSLu Baolu 568*aeb9dd1dSLu Baolu /* Allocate the table page: */ 569*aeb9dd1dSLu Baolu xdbc.table_base = xdbc_get_page(&xdbc.table_dma); 570*aeb9dd1dSLu Baolu if (!xdbc.table_base) 571*aeb9dd1dSLu Baolu return -ENOMEM; 572*aeb9dd1dSLu Baolu 573*aeb9dd1dSLu Baolu /* Get and store the transfer buffer: */ 574*aeb9dd1dSLu Baolu xdbc.out_buf = xdbc_get_page(&xdbc.out_dma); 575*aeb9dd1dSLu Baolu if (!xdbc.out_buf) 576*aeb9dd1dSLu Baolu return -ENOMEM; 577*aeb9dd1dSLu Baolu 578*aeb9dd1dSLu Baolu /* Allocate the event ring: */ 579*aeb9dd1dSLu Baolu ret = xdbc_alloc_ring(&xdbc.evt_seg, &xdbc.evt_ring); 580*aeb9dd1dSLu Baolu if (ret < 0) 581*aeb9dd1dSLu Baolu return ret; 582*aeb9dd1dSLu Baolu 583*aeb9dd1dSLu Baolu /* Allocate IN/OUT endpoint transfer rings: */ 584*aeb9dd1dSLu Baolu ret = xdbc_alloc_ring(&xdbc.in_seg, &xdbc.in_ring); 585*aeb9dd1dSLu Baolu if (ret < 0) 586*aeb9dd1dSLu Baolu return ret; 587*aeb9dd1dSLu Baolu 588*aeb9dd1dSLu Baolu ret = xdbc_alloc_ring(&xdbc.out_seg, &xdbc.out_ring); 589*aeb9dd1dSLu Baolu if (ret < 0) 590*aeb9dd1dSLu Baolu return ret; 591*aeb9dd1dSLu Baolu 592*aeb9dd1dSLu Baolu xdbc_mem_init(); 593*aeb9dd1dSLu Baolu 594*aeb9dd1dSLu Baolu mmiowb(); 595*aeb9dd1dSLu Baolu 596*aeb9dd1dSLu Baolu ret = xdbc_start(); 597*aeb9dd1dSLu Baolu if (ret < 0) { 598*aeb9dd1dSLu Baolu writel(0, &xdbc.xdbc_reg->control); 599*aeb9dd1dSLu Baolu return ret; 600*aeb9dd1dSLu Baolu } 601*aeb9dd1dSLu Baolu 602*aeb9dd1dSLu Baolu xdbc.flags |= XDBC_FLAGS_INITIALIZED | XDBC_FLAGS_CONFIGURED; 603*aeb9dd1dSLu Baolu 604*aeb9dd1dSLu Baolu xdbc_bulk_transfer(NULL, XDBC_MAX_PACKET, true); 605*aeb9dd1dSLu Baolu 606*aeb9dd1dSLu Baolu return 0; 607*aeb9dd1dSLu Baolu } 608*aeb9dd1dSLu Baolu 609*aeb9dd1dSLu Baolu int __init early_xdbc_parse_parameter(char *s) 610*aeb9dd1dSLu Baolu { 611*aeb9dd1dSLu Baolu unsigned long dbgp_num = 0; 612*aeb9dd1dSLu Baolu u32 bus, dev, func, offset; 613*aeb9dd1dSLu Baolu int ret; 614*aeb9dd1dSLu Baolu 615*aeb9dd1dSLu Baolu if (!early_pci_allowed()) 616*aeb9dd1dSLu Baolu return -EPERM; 617*aeb9dd1dSLu Baolu 618*aeb9dd1dSLu Baolu if (strstr(s, "keep")) 619*aeb9dd1dSLu Baolu early_console_keep = true; 620*aeb9dd1dSLu Baolu 621*aeb9dd1dSLu Baolu if (xdbc.xdbc_reg) 622*aeb9dd1dSLu Baolu return 0; 623*aeb9dd1dSLu Baolu 624*aeb9dd1dSLu Baolu if (*s && kstrtoul(s, 0, &dbgp_num)) 625*aeb9dd1dSLu Baolu dbgp_num = 0; 626*aeb9dd1dSLu Baolu 627*aeb9dd1dSLu Baolu pr_notice("dbgp_num: %lu\n", dbgp_num); 628*aeb9dd1dSLu Baolu 629*aeb9dd1dSLu Baolu /* Locate the host controller: */ 630*aeb9dd1dSLu Baolu ret = xdbc_find_dbgp(dbgp_num, &bus, &dev, &func); 631*aeb9dd1dSLu Baolu if (ret) { 632*aeb9dd1dSLu Baolu pr_notice("failed to locate xhci host\n"); 633*aeb9dd1dSLu Baolu return -ENODEV; 634*aeb9dd1dSLu Baolu } 635*aeb9dd1dSLu Baolu 636*aeb9dd1dSLu Baolu xdbc.vendor = read_pci_config_16(bus, dev, func, PCI_VENDOR_ID); 637*aeb9dd1dSLu Baolu xdbc.device = read_pci_config_16(bus, dev, func, PCI_DEVICE_ID); 638*aeb9dd1dSLu Baolu xdbc.bus = bus; 639*aeb9dd1dSLu Baolu xdbc.dev = dev; 640*aeb9dd1dSLu Baolu xdbc.func = func; 641*aeb9dd1dSLu Baolu 642*aeb9dd1dSLu Baolu /* Map the IO memory: */ 643*aeb9dd1dSLu Baolu xdbc.xhci_base = xdbc_map_pci_mmio(bus, dev, func); 644*aeb9dd1dSLu Baolu if (!xdbc.xhci_base) 645*aeb9dd1dSLu Baolu return -EINVAL; 646*aeb9dd1dSLu Baolu 647*aeb9dd1dSLu Baolu /* Locate DbC registers: */ 648*aeb9dd1dSLu Baolu offset = xhci_find_next_ext_cap(xdbc.xhci_base, 0, XHCI_EXT_CAPS_DEBUG); 649*aeb9dd1dSLu Baolu if (!offset) { 650*aeb9dd1dSLu Baolu pr_notice("xhci host doesn't support debug capability\n"); 651*aeb9dd1dSLu Baolu early_iounmap(xdbc.xhci_base, xdbc.xhci_length); 652*aeb9dd1dSLu Baolu xdbc.xhci_base = NULL; 653*aeb9dd1dSLu Baolu xdbc.xhci_length = 0; 654*aeb9dd1dSLu Baolu 655*aeb9dd1dSLu Baolu return -ENODEV; 656*aeb9dd1dSLu Baolu } 657*aeb9dd1dSLu Baolu xdbc.xdbc_reg = (struct xdbc_regs __iomem *)(xdbc.xhci_base + offset); 658*aeb9dd1dSLu Baolu 659*aeb9dd1dSLu Baolu return 0; 660*aeb9dd1dSLu Baolu } 661*aeb9dd1dSLu Baolu 662*aeb9dd1dSLu Baolu int __init early_xdbc_setup_hardware(void) 663*aeb9dd1dSLu Baolu { 664*aeb9dd1dSLu Baolu int ret; 665*aeb9dd1dSLu Baolu 666*aeb9dd1dSLu Baolu if (!xdbc.xdbc_reg) 667*aeb9dd1dSLu Baolu return -ENODEV; 668*aeb9dd1dSLu Baolu 669*aeb9dd1dSLu Baolu xdbc_bios_handoff(); 670*aeb9dd1dSLu Baolu 671*aeb9dd1dSLu Baolu raw_spin_lock_init(&xdbc.lock); 672*aeb9dd1dSLu Baolu 673*aeb9dd1dSLu Baolu ret = xdbc_early_setup(); 674*aeb9dd1dSLu Baolu if (ret) { 675*aeb9dd1dSLu Baolu pr_notice("failed to setup the connection to host\n"); 676*aeb9dd1dSLu Baolu 677*aeb9dd1dSLu Baolu xdbc_free_ring(&xdbc.evt_ring); 678*aeb9dd1dSLu Baolu xdbc_free_ring(&xdbc.out_ring); 679*aeb9dd1dSLu Baolu xdbc_free_ring(&xdbc.in_ring); 680*aeb9dd1dSLu Baolu 681*aeb9dd1dSLu Baolu if (xdbc.table_dma) 682*aeb9dd1dSLu Baolu free_bootmem(xdbc.table_dma, PAGE_SIZE); 683*aeb9dd1dSLu Baolu 684*aeb9dd1dSLu Baolu if (xdbc.out_dma) 685*aeb9dd1dSLu Baolu free_bootmem(xdbc.out_dma, PAGE_SIZE); 686*aeb9dd1dSLu Baolu 687*aeb9dd1dSLu Baolu xdbc.table_base = NULL; 688*aeb9dd1dSLu Baolu xdbc.out_buf = NULL; 689*aeb9dd1dSLu Baolu } 690*aeb9dd1dSLu Baolu 691*aeb9dd1dSLu Baolu return ret; 692*aeb9dd1dSLu Baolu } 693*aeb9dd1dSLu Baolu 694*aeb9dd1dSLu Baolu static void xdbc_handle_port_status(struct xdbc_trb *evt_trb) 695*aeb9dd1dSLu Baolu { 696*aeb9dd1dSLu Baolu u32 port_reg; 697*aeb9dd1dSLu Baolu 698*aeb9dd1dSLu Baolu port_reg = readl(&xdbc.xdbc_reg->portsc); 699*aeb9dd1dSLu Baolu if (port_reg & PORTSC_CONN_CHANGE) { 700*aeb9dd1dSLu Baolu xdbc_trace("connect status change event\n"); 701*aeb9dd1dSLu Baolu 702*aeb9dd1dSLu Baolu /* Check whether cable unplugged: */ 703*aeb9dd1dSLu Baolu if (!(port_reg & PORTSC_CONN_STATUS)) { 704*aeb9dd1dSLu Baolu xdbc.flags = 0; 705*aeb9dd1dSLu Baolu xdbc_trace("cable unplugged\n"); 706*aeb9dd1dSLu Baolu } 707*aeb9dd1dSLu Baolu } 708*aeb9dd1dSLu Baolu 709*aeb9dd1dSLu Baolu if (port_reg & PORTSC_RESET_CHANGE) 710*aeb9dd1dSLu Baolu xdbc_trace("port reset change event\n"); 711*aeb9dd1dSLu Baolu 712*aeb9dd1dSLu Baolu if (port_reg & PORTSC_LINK_CHANGE) 713*aeb9dd1dSLu Baolu xdbc_trace("port link status change event\n"); 714*aeb9dd1dSLu Baolu 715*aeb9dd1dSLu Baolu if (port_reg & PORTSC_CONFIG_CHANGE) 716*aeb9dd1dSLu Baolu xdbc_trace("config error change\n"); 717*aeb9dd1dSLu Baolu 718*aeb9dd1dSLu Baolu /* Write back the value to clear RW1C bits: */ 719*aeb9dd1dSLu Baolu writel(port_reg, &xdbc.xdbc_reg->portsc); 720*aeb9dd1dSLu Baolu } 721*aeb9dd1dSLu Baolu 722*aeb9dd1dSLu Baolu static void xdbc_handle_tx_event(struct xdbc_trb *evt_trb) 723*aeb9dd1dSLu Baolu { 724*aeb9dd1dSLu Baolu size_t remain_length; 725*aeb9dd1dSLu Baolu u32 comp_code; 726*aeb9dd1dSLu Baolu int ep_id; 727*aeb9dd1dSLu Baolu 728*aeb9dd1dSLu Baolu comp_code = GET_COMP_CODE(le32_to_cpu(evt_trb->field[2])); 729*aeb9dd1dSLu Baolu remain_length = EVENT_TRB_LEN(le32_to_cpu(evt_trb->field[2])); 730*aeb9dd1dSLu Baolu ep_id = TRB_TO_EP_ID(le32_to_cpu(evt_trb->field[3])); 731*aeb9dd1dSLu Baolu 732*aeb9dd1dSLu Baolu switch (comp_code) { 733*aeb9dd1dSLu Baolu case COMP_SUCCESS: 734*aeb9dd1dSLu Baolu remain_length = 0; 735*aeb9dd1dSLu Baolu case COMP_SHORT_PACKET: 736*aeb9dd1dSLu Baolu break; 737*aeb9dd1dSLu Baolu case COMP_TRB_ERROR: 738*aeb9dd1dSLu Baolu case COMP_BABBLE_DETECTED_ERROR: 739*aeb9dd1dSLu Baolu case COMP_USB_TRANSACTION_ERROR: 740*aeb9dd1dSLu Baolu case COMP_STALL_ERROR: 741*aeb9dd1dSLu Baolu default: 742*aeb9dd1dSLu Baolu if (ep_id == XDBC_EPID_OUT) 743*aeb9dd1dSLu Baolu xdbc.flags |= XDBC_FLAGS_OUT_STALL; 744*aeb9dd1dSLu Baolu if (ep_id == XDBC_EPID_IN) 745*aeb9dd1dSLu Baolu xdbc.flags |= XDBC_FLAGS_IN_STALL; 746*aeb9dd1dSLu Baolu 747*aeb9dd1dSLu Baolu xdbc_trace("endpoint %d stalled\n", ep_id); 748*aeb9dd1dSLu Baolu break; 749*aeb9dd1dSLu Baolu } 750*aeb9dd1dSLu Baolu 751*aeb9dd1dSLu Baolu if (ep_id == XDBC_EPID_IN) { 752*aeb9dd1dSLu Baolu xdbc.flags &= ~XDBC_FLAGS_IN_PROCESS; 753*aeb9dd1dSLu Baolu xdbc_bulk_transfer(NULL, XDBC_MAX_PACKET, true); 754*aeb9dd1dSLu Baolu } else if (ep_id == XDBC_EPID_OUT) { 755*aeb9dd1dSLu Baolu xdbc.flags &= ~XDBC_FLAGS_OUT_PROCESS; 756*aeb9dd1dSLu Baolu } else { 757*aeb9dd1dSLu Baolu xdbc_trace("invalid endpoint id %d\n", ep_id); 758*aeb9dd1dSLu Baolu } 759*aeb9dd1dSLu Baolu } 760*aeb9dd1dSLu Baolu 761*aeb9dd1dSLu Baolu static void xdbc_handle_events(void) 762*aeb9dd1dSLu Baolu { 763*aeb9dd1dSLu Baolu struct xdbc_trb *evt_trb; 764*aeb9dd1dSLu Baolu bool update_erdp = false; 765*aeb9dd1dSLu Baolu u32 reg; 766*aeb9dd1dSLu Baolu u8 cmd; 767*aeb9dd1dSLu Baolu 768*aeb9dd1dSLu Baolu cmd = read_pci_config_byte(xdbc.bus, xdbc.dev, xdbc.func, PCI_COMMAND); 769*aeb9dd1dSLu Baolu if (!(cmd & PCI_COMMAND_MASTER)) { 770*aeb9dd1dSLu Baolu cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; 771*aeb9dd1dSLu Baolu write_pci_config_byte(xdbc.bus, xdbc.dev, xdbc.func, PCI_COMMAND, cmd); 772*aeb9dd1dSLu Baolu } 773*aeb9dd1dSLu Baolu 774*aeb9dd1dSLu Baolu if (!(xdbc.flags & XDBC_FLAGS_INITIALIZED)) 775*aeb9dd1dSLu Baolu return; 776*aeb9dd1dSLu Baolu 777*aeb9dd1dSLu Baolu /* Handle external reset events: */ 778*aeb9dd1dSLu Baolu reg = readl(&xdbc.xdbc_reg->control); 779*aeb9dd1dSLu Baolu if (!(reg & CTRL_DBC_ENABLE)) { 780*aeb9dd1dSLu Baolu if (xdbc_handle_external_reset()) { 781*aeb9dd1dSLu Baolu xdbc_trace("failed to recover connection\n"); 782*aeb9dd1dSLu Baolu return; 783*aeb9dd1dSLu Baolu } 784*aeb9dd1dSLu Baolu } 785*aeb9dd1dSLu Baolu 786*aeb9dd1dSLu Baolu /* Handle configure-exit event: */ 787*aeb9dd1dSLu Baolu reg = readl(&xdbc.xdbc_reg->control); 788*aeb9dd1dSLu Baolu if (reg & CTRL_DBC_RUN_CHANGE) { 789*aeb9dd1dSLu Baolu writel(reg, &xdbc.xdbc_reg->control); 790*aeb9dd1dSLu Baolu if (reg & CTRL_DBC_RUN) 791*aeb9dd1dSLu Baolu xdbc.flags |= XDBC_FLAGS_CONFIGURED; 792*aeb9dd1dSLu Baolu else 793*aeb9dd1dSLu Baolu xdbc.flags &= ~XDBC_FLAGS_CONFIGURED; 794*aeb9dd1dSLu Baolu } 795*aeb9dd1dSLu Baolu 796*aeb9dd1dSLu Baolu /* Handle endpoint stall event: */ 797*aeb9dd1dSLu Baolu reg = readl(&xdbc.xdbc_reg->control); 798*aeb9dd1dSLu Baolu if (reg & CTRL_HALT_IN_TR) { 799*aeb9dd1dSLu Baolu xdbc.flags |= XDBC_FLAGS_IN_STALL; 800*aeb9dd1dSLu Baolu } else { 801*aeb9dd1dSLu Baolu xdbc.flags &= ~XDBC_FLAGS_IN_STALL; 802*aeb9dd1dSLu Baolu if (!(xdbc.flags & XDBC_FLAGS_IN_PROCESS)) 803*aeb9dd1dSLu Baolu xdbc_bulk_transfer(NULL, XDBC_MAX_PACKET, true); 804*aeb9dd1dSLu Baolu } 805*aeb9dd1dSLu Baolu 806*aeb9dd1dSLu Baolu if (reg & CTRL_HALT_OUT_TR) 807*aeb9dd1dSLu Baolu xdbc.flags |= XDBC_FLAGS_OUT_STALL; 808*aeb9dd1dSLu Baolu else 809*aeb9dd1dSLu Baolu xdbc.flags &= ~XDBC_FLAGS_OUT_STALL; 810*aeb9dd1dSLu Baolu 811*aeb9dd1dSLu Baolu /* Handle the events in the event ring: */ 812*aeb9dd1dSLu Baolu evt_trb = xdbc.evt_ring.dequeue; 813*aeb9dd1dSLu Baolu while ((le32_to_cpu(evt_trb->field[3]) & TRB_CYCLE) == xdbc.evt_ring.cycle_state) { 814*aeb9dd1dSLu Baolu /* 815*aeb9dd1dSLu Baolu * Add a barrier between reading the cycle flag and any 816*aeb9dd1dSLu Baolu * reads of the event's flags/data below: 817*aeb9dd1dSLu Baolu */ 818*aeb9dd1dSLu Baolu rmb(); 819*aeb9dd1dSLu Baolu 820*aeb9dd1dSLu Baolu switch ((le32_to_cpu(evt_trb->field[3]) & TRB_TYPE_BITMASK)) { 821*aeb9dd1dSLu Baolu case TRB_TYPE(TRB_PORT_STATUS): 822*aeb9dd1dSLu Baolu xdbc_handle_port_status(evt_trb); 823*aeb9dd1dSLu Baolu break; 824*aeb9dd1dSLu Baolu case TRB_TYPE(TRB_TRANSFER): 825*aeb9dd1dSLu Baolu xdbc_handle_tx_event(evt_trb); 826*aeb9dd1dSLu Baolu break; 827*aeb9dd1dSLu Baolu default: 828*aeb9dd1dSLu Baolu break; 829*aeb9dd1dSLu Baolu } 830*aeb9dd1dSLu Baolu 831*aeb9dd1dSLu Baolu ++(xdbc.evt_ring.dequeue); 832*aeb9dd1dSLu Baolu if (xdbc.evt_ring.dequeue == &xdbc.evt_seg.trbs[TRBS_PER_SEGMENT]) { 833*aeb9dd1dSLu Baolu xdbc.evt_ring.dequeue = xdbc.evt_seg.trbs; 834*aeb9dd1dSLu Baolu xdbc.evt_ring.cycle_state ^= 1; 835*aeb9dd1dSLu Baolu } 836*aeb9dd1dSLu Baolu 837*aeb9dd1dSLu Baolu evt_trb = xdbc.evt_ring.dequeue; 838*aeb9dd1dSLu Baolu update_erdp = true; 839*aeb9dd1dSLu Baolu } 840*aeb9dd1dSLu Baolu 841*aeb9dd1dSLu Baolu /* Update event ring dequeue pointer: */ 842*aeb9dd1dSLu Baolu if (update_erdp) 843*aeb9dd1dSLu Baolu xdbc_write64(__pa(xdbc.evt_ring.dequeue), &xdbc.xdbc_reg->erdp); 844*aeb9dd1dSLu Baolu } 845*aeb9dd1dSLu Baolu 846*aeb9dd1dSLu Baolu static int xdbc_bulk_write(const char *bytes, int size) 847*aeb9dd1dSLu Baolu { 848*aeb9dd1dSLu Baolu int ret, timeout = 0; 849*aeb9dd1dSLu Baolu unsigned long flags; 850*aeb9dd1dSLu Baolu 851*aeb9dd1dSLu Baolu retry: 852*aeb9dd1dSLu Baolu if (in_nmi()) { 853*aeb9dd1dSLu Baolu if (!raw_spin_trylock_irqsave(&xdbc.lock, flags)) 854*aeb9dd1dSLu Baolu return -EAGAIN; 855*aeb9dd1dSLu Baolu } else { 856*aeb9dd1dSLu Baolu raw_spin_lock_irqsave(&xdbc.lock, flags); 857*aeb9dd1dSLu Baolu } 858*aeb9dd1dSLu Baolu 859*aeb9dd1dSLu Baolu xdbc_handle_events(); 860*aeb9dd1dSLu Baolu 861*aeb9dd1dSLu Baolu /* Check completion of the previous request: */ 862*aeb9dd1dSLu Baolu if ((xdbc.flags & XDBC_FLAGS_OUT_PROCESS) && (timeout < 2000000)) { 863*aeb9dd1dSLu Baolu raw_spin_unlock_irqrestore(&xdbc.lock, flags); 864*aeb9dd1dSLu Baolu udelay(100); 865*aeb9dd1dSLu Baolu timeout += 100; 866*aeb9dd1dSLu Baolu goto retry; 867*aeb9dd1dSLu Baolu } 868*aeb9dd1dSLu Baolu 869*aeb9dd1dSLu Baolu if (xdbc.flags & XDBC_FLAGS_OUT_PROCESS) { 870*aeb9dd1dSLu Baolu raw_spin_unlock_irqrestore(&xdbc.lock, flags); 871*aeb9dd1dSLu Baolu xdbc_trace("previous transfer not completed yet\n"); 872*aeb9dd1dSLu Baolu 873*aeb9dd1dSLu Baolu return -ETIMEDOUT; 874*aeb9dd1dSLu Baolu } 875*aeb9dd1dSLu Baolu 876*aeb9dd1dSLu Baolu ret = xdbc_bulk_transfer((void *)bytes, size, false); 877*aeb9dd1dSLu Baolu raw_spin_unlock_irqrestore(&xdbc.lock, flags); 878*aeb9dd1dSLu Baolu 879*aeb9dd1dSLu Baolu return ret; 880*aeb9dd1dSLu Baolu } 881*aeb9dd1dSLu Baolu 882*aeb9dd1dSLu Baolu static void early_xdbc_write(struct console *con, const char *str, u32 n) 883*aeb9dd1dSLu Baolu { 884*aeb9dd1dSLu Baolu static char buf[XDBC_MAX_PACKET]; 885*aeb9dd1dSLu Baolu int chunk, ret; 886*aeb9dd1dSLu Baolu int use_cr = 0; 887*aeb9dd1dSLu Baolu 888*aeb9dd1dSLu Baolu if (!xdbc.xdbc_reg) 889*aeb9dd1dSLu Baolu return; 890*aeb9dd1dSLu Baolu memset(buf, 0, XDBC_MAX_PACKET); 891*aeb9dd1dSLu Baolu while (n > 0) { 892*aeb9dd1dSLu Baolu for (chunk = 0; chunk < XDBC_MAX_PACKET && n > 0; str++, chunk++, n--) { 893*aeb9dd1dSLu Baolu 894*aeb9dd1dSLu Baolu if (!use_cr && *str == '\n') { 895*aeb9dd1dSLu Baolu use_cr = 1; 896*aeb9dd1dSLu Baolu buf[chunk] = '\r'; 897*aeb9dd1dSLu Baolu str--; 898*aeb9dd1dSLu Baolu n++; 899*aeb9dd1dSLu Baolu continue; 900*aeb9dd1dSLu Baolu } 901*aeb9dd1dSLu Baolu 902*aeb9dd1dSLu Baolu if (use_cr) 903*aeb9dd1dSLu Baolu use_cr = 0; 904*aeb9dd1dSLu Baolu buf[chunk] = *str; 905*aeb9dd1dSLu Baolu } 906*aeb9dd1dSLu Baolu 907*aeb9dd1dSLu Baolu if (chunk > 0) { 908*aeb9dd1dSLu Baolu ret = xdbc_bulk_write(buf, chunk); 909*aeb9dd1dSLu Baolu if (ret < 0) 910*aeb9dd1dSLu Baolu xdbc_trace("missed message {%s}\n", buf); 911*aeb9dd1dSLu Baolu } 912*aeb9dd1dSLu Baolu } 913*aeb9dd1dSLu Baolu } 914*aeb9dd1dSLu Baolu 915*aeb9dd1dSLu Baolu static struct console early_xdbc_console = { 916*aeb9dd1dSLu Baolu .name = "earlyxdbc", 917*aeb9dd1dSLu Baolu .write = early_xdbc_write, 918*aeb9dd1dSLu Baolu .flags = CON_PRINTBUFFER, 919*aeb9dd1dSLu Baolu .index = -1, 920*aeb9dd1dSLu Baolu }; 921*aeb9dd1dSLu Baolu 922*aeb9dd1dSLu Baolu void __init early_xdbc_register_console(void) 923*aeb9dd1dSLu Baolu { 924*aeb9dd1dSLu Baolu if (early_console) 925*aeb9dd1dSLu Baolu return; 926*aeb9dd1dSLu Baolu 927*aeb9dd1dSLu Baolu early_console = &early_xdbc_console; 928*aeb9dd1dSLu Baolu if (early_console_keep) 929*aeb9dd1dSLu Baolu early_console->flags &= ~CON_BOOT; 930*aeb9dd1dSLu Baolu else 931*aeb9dd1dSLu Baolu early_console->flags |= CON_BOOT; 932*aeb9dd1dSLu Baolu register_console(early_console); 933*aeb9dd1dSLu Baolu } 934*aeb9dd1dSLu Baolu 935*aeb9dd1dSLu Baolu static void xdbc_unregister_console(void) 936*aeb9dd1dSLu Baolu { 937*aeb9dd1dSLu Baolu if (early_xdbc_console.flags & CON_ENABLED) 938*aeb9dd1dSLu Baolu unregister_console(&early_xdbc_console); 939*aeb9dd1dSLu Baolu } 940*aeb9dd1dSLu Baolu 941*aeb9dd1dSLu Baolu static int xdbc_scrub_function(void *ptr) 942*aeb9dd1dSLu Baolu { 943*aeb9dd1dSLu Baolu unsigned long flags; 944*aeb9dd1dSLu Baolu 945*aeb9dd1dSLu Baolu while (true) { 946*aeb9dd1dSLu Baolu raw_spin_lock_irqsave(&xdbc.lock, flags); 947*aeb9dd1dSLu Baolu xdbc_handle_events(); 948*aeb9dd1dSLu Baolu 949*aeb9dd1dSLu Baolu if (!(xdbc.flags & XDBC_FLAGS_INITIALIZED)) { 950*aeb9dd1dSLu Baolu raw_spin_unlock_irqrestore(&xdbc.lock, flags); 951*aeb9dd1dSLu Baolu break; 952*aeb9dd1dSLu Baolu } 953*aeb9dd1dSLu Baolu 954*aeb9dd1dSLu Baolu raw_spin_unlock_irqrestore(&xdbc.lock, flags); 955*aeb9dd1dSLu Baolu schedule_timeout_interruptible(1); 956*aeb9dd1dSLu Baolu } 957*aeb9dd1dSLu Baolu 958*aeb9dd1dSLu Baolu xdbc_unregister_console(); 959*aeb9dd1dSLu Baolu writel(0, &xdbc.xdbc_reg->control); 960*aeb9dd1dSLu Baolu xdbc_trace("dbc scrub function exits\n"); 961*aeb9dd1dSLu Baolu 962*aeb9dd1dSLu Baolu return 0; 963*aeb9dd1dSLu Baolu } 964*aeb9dd1dSLu Baolu 965*aeb9dd1dSLu Baolu static int __init xdbc_init(void) 966*aeb9dd1dSLu Baolu { 967*aeb9dd1dSLu Baolu unsigned long flags; 968*aeb9dd1dSLu Baolu void __iomem *base; 969*aeb9dd1dSLu Baolu int ret = 0; 970*aeb9dd1dSLu Baolu u32 offset; 971*aeb9dd1dSLu Baolu 972*aeb9dd1dSLu Baolu if (!(xdbc.flags & XDBC_FLAGS_INITIALIZED)) 973*aeb9dd1dSLu Baolu return 0; 974*aeb9dd1dSLu Baolu 975*aeb9dd1dSLu Baolu /* 976*aeb9dd1dSLu Baolu * It's time to shut down the DbC, so that the debug 977*aeb9dd1dSLu Baolu * port can be reused by the host controller: 978*aeb9dd1dSLu Baolu */ 979*aeb9dd1dSLu Baolu if (early_xdbc_console.index == -1 || 980*aeb9dd1dSLu Baolu (early_xdbc_console.flags & CON_BOOT)) { 981*aeb9dd1dSLu Baolu xdbc_trace("hardware not used anymore\n"); 982*aeb9dd1dSLu Baolu goto free_and_quit; 983*aeb9dd1dSLu Baolu } 984*aeb9dd1dSLu Baolu 985*aeb9dd1dSLu Baolu base = ioremap_nocache(xdbc.xhci_start, xdbc.xhci_length); 986*aeb9dd1dSLu Baolu if (!base) { 987*aeb9dd1dSLu Baolu xdbc_trace("failed to remap the io address\n"); 988*aeb9dd1dSLu Baolu ret = -ENOMEM; 989*aeb9dd1dSLu Baolu goto free_and_quit; 990*aeb9dd1dSLu Baolu } 991*aeb9dd1dSLu Baolu 992*aeb9dd1dSLu Baolu raw_spin_lock_irqsave(&xdbc.lock, flags); 993*aeb9dd1dSLu Baolu early_iounmap(xdbc.xhci_base, xdbc.xhci_length); 994*aeb9dd1dSLu Baolu xdbc.xhci_base = base; 995*aeb9dd1dSLu Baolu offset = xhci_find_next_ext_cap(xdbc.xhci_base, 0, XHCI_EXT_CAPS_DEBUG); 996*aeb9dd1dSLu Baolu xdbc.xdbc_reg = (struct xdbc_regs __iomem *)(xdbc.xhci_base + offset); 997*aeb9dd1dSLu Baolu raw_spin_unlock_irqrestore(&xdbc.lock, flags); 998*aeb9dd1dSLu Baolu 999*aeb9dd1dSLu Baolu kthread_run(xdbc_scrub_function, NULL, "%s", "xdbc"); 1000*aeb9dd1dSLu Baolu 1001*aeb9dd1dSLu Baolu return 0; 1002*aeb9dd1dSLu Baolu 1003*aeb9dd1dSLu Baolu free_and_quit: 1004*aeb9dd1dSLu Baolu xdbc_free_ring(&xdbc.evt_ring); 1005*aeb9dd1dSLu Baolu xdbc_free_ring(&xdbc.out_ring); 1006*aeb9dd1dSLu Baolu xdbc_free_ring(&xdbc.in_ring); 1007*aeb9dd1dSLu Baolu free_bootmem(xdbc.table_dma, PAGE_SIZE); 1008*aeb9dd1dSLu Baolu free_bootmem(xdbc.out_dma, PAGE_SIZE); 1009*aeb9dd1dSLu Baolu writel(0, &xdbc.xdbc_reg->control); 1010*aeb9dd1dSLu Baolu early_iounmap(xdbc.xhci_base, xdbc.xhci_length); 1011*aeb9dd1dSLu Baolu 1012*aeb9dd1dSLu Baolu return ret; 1013*aeb9dd1dSLu Baolu } 1014*aeb9dd1dSLu Baolu subsys_initcall(xdbc_init); 1015