usb: xhci: Add debugfs interface for xHCI driver

This adds debugfs consumer for xHCI driver. The debugfs entries
read all host registers, device/endpoint contexts, command ring,
event ring and various endpoint rings. With these entries, users
can check the registers and memory spaces used by a host during
run time, or save all the information with a simple 'cp -r' for
post-mortem programs.

The file hierarchy looks like this.

[root of debugfs]
|__usb
|____[e,u,o]hci                 <---------[root for other HCIs]
|____xhci                       <---------------[root for xHCI]
|______0000:00:14.0             <--------------[xHCI host name]
|________reg-cap                <--------[capability registers]
|________reg-op                 <-------[operational registers]
|________reg-runtime            <-----------[runtime registers]
|________reg-ext-#cap_name      <----[extended capability regs]
|________command-ring           <-------[root for command ring]
|__________cycle                <------------------[ring cycle]
|__________dequeue              <--------[ring dequeue pointer]
|__________enqueue              <--------[ring enqueue pointer]
|__________trbs                 <-------------------[ring trbs]
|________event-ring             <---------[root for event ring]
|__________cycle                <------------------[ring cycle]
|__________dequeue              <--------[ring dequeue pointer]
|__________enqueue              <--------[ring enqueue pointer]
|__________trbs                 <-------------------[ring trbs]
|________devices                <------------[root for devices]
|__________#slot_id             <-----------[root for a device]
|____________name               <-----------------[device name]
|____________slot-context       <----------------[slot context]
|____________ep-context         <-----------[endpoint contexts]
|____________ep#ep_index        <--------[root for an endpoint]
|______________cycle            <------------------[ring cycle]
|______________dequeue          <--------[ring dequeue pointer]
|______________enqueue          <--------[ring enqueue pointer]
|______________trbs             <-------------------[ring trbs]

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 3a8e75f..e20b2c2 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -32,6 +32,7 @@
 #include "xhci.h"
 #include "xhci-trace.h"
 #include "xhci-mtk.h"
+#include "xhci-debugfs.h"
 
 #define DRIVER_AUTHOR "Sarah Sharp"
 #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
@@ -632,6 +633,9 @@ int xhci_run(struct usb_hcd *hcd)
 	}
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
 			"Finished xhci_run for USB2 roothub");
+
+	xhci_debugfs_init(xhci);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(xhci_run);
@@ -660,6 +664,8 @@ static void xhci_stop(struct usb_hcd *hcd)
 		return;
 	}
 
+	xhci_debugfs_exit(xhci);
+
 	spin_lock_irq(&xhci->lock);
 	xhci->xhc_state |= XHCI_STATE_HALTED;
 	xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
@@ -1600,6 +1606,8 @@ static int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
 	ctrl_ctx->add_flags &= cpu_to_le32(~drop_flag);
 	new_add_flags = le32_to_cpu(ctrl_ctx->add_flags);
 
+	xhci_debugfs_remove_endpoint(xhci, xhci->devs[udev->slot_id], ep_index);
+
 	xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
 
 	if (xhci->quirks & XHCI_MTK_HOST)
@@ -1722,6 +1730,8 @@ static int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
 	/* Store the usb_device pointer for later use */
 	ep->hcpriv = udev;
 
+	xhci_debugfs_create_endpoint(xhci, virt_dev, ep_index);
+
 	xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n",
 			(unsigned int) ep->desc.bEndpointAddress,
 			udev->slot_id,
@@ -2772,6 +2782,7 @@ static void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 	/* Free any rings allocated for added endpoints */
 	for (i = 0; i < 31; i++) {
 		if (virt_dev->eps[i].new_ring) {
+			xhci_debugfs_remove_endpoint(xhci, virt_dev, i);
 			xhci_ring_free(xhci, virt_dev->eps[i].new_ring);
 			virt_dev->eps[i].new_ring = NULL;
 		}
@@ -3487,6 +3498,7 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd,
 		}
 
 		if (ep->ring) {
+			xhci_debugfs_remove_endpoint(xhci, virt_dev, i);
 			xhci_free_endpoint_ring(xhci, virt_dev, i);
 			last_freed_endpoint = i;
 		}
@@ -3521,6 +3533,8 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
 	int i, ret;
 	struct xhci_command *command;
 
+	xhci_debugfs_remove_slot(xhci, udev->slot_id);
+
 	command = xhci_alloc_command(xhci, false, false, GFP_KERNEL);
 	if (!command)
 		return;
@@ -3693,6 +3707,8 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
 
 	udev->slot_id = slot_id;
 
+	xhci_debugfs_create_slot(xhci, slot_id);
+
 #ifndef CONFIG_USB_DEFAULT_PERSIST
 	/*
 	 * If resetting upon resume, we can't put the controller into runtime
@@ -5003,6 +5019,8 @@ static int __init xhci_hcd_init(void)
 	if (usb_disabled())
 		return -ENODEV;
 
+	xhci_debugfs_create_root();
+
 	return 0;
 }
 
@@ -5010,7 +5028,10 @@ static int __init xhci_hcd_init(void)
  * If an init function is provided, an exit function must also be provided
  * to allow module unload.
  */
-static void __exit xhci_hcd_fini(void) { }
+static void __exit xhci_hcd_fini(void)
+{
+	xhci_debugfs_remove_root();
+}
 
 module_init(xhci_hcd_init);
 module_exit(xhci_hcd_fini);