aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2014-04-30 18:45:10 -0400
committerFelipe Balbi <balbi@ti.com>2014-09-05 10:55:51 -0400
commit2c4cbe6e5a9c71408b496e00a78ea9284e98af16 (patch)
treec90423ae169751bf43925c9a37734762199ec803
parent3ece0ec474bf3cea9eefa7f92e3d4b6c3f9f71fd (diff)
usb: dwc3: add tracepoints to aid debugging
When we're debugging hard-to-reproduce and time-sensitive use cases, printk() poses too much overhead. That's when the kernel's tracing infrastructure comes into play. This patch implements a few initial tracepoints for the dwc3 driver. More traces can be added as necessary in order to ease the task of debugging dwc3. Reviewed-by: Paul Zimmerman <paulz@synopsys.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/dwc3/Makefile5
-rw-r--r--drivers/usb/dwc3/core.h2
-rw-r--r--drivers/usb/dwc3/debug.c32
-rw-r--r--drivers/usb/dwc3/debug.h2
-rw-r--r--drivers/usb/dwc3/ep0.c64
-rw-r--r--drivers/usb/dwc3/gadget.c36
-rw-r--r--drivers/usb/dwc3/io.h30
-rw-r--r--drivers/usb/dwc3/trace.c19
-rw-r--r--drivers/usb/dwc3/trace.h220
9 files changed, 357 insertions, 53 deletions
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 10ac3e72482e..7793e6c99f27 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -1,9 +1,12 @@
1# define_trace.h needs to know how to find our header
2CFLAGS_trace.o := -I$(src)
3
1ccflags-$(CONFIG_USB_DWC3_DEBUG) := -DDEBUG 4ccflags-$(CONFIG_USB_DWC3_DEBUG) := -DDEBUG
2ccflags-$(CONFIG_USB_DWC3_VERBOSE) += -DVERBOSE_DEBUG 5ccflags-$(CONFIG_USB_DWC3_VERBOSE) += -DVERBOSE_DEBUG
3 6
4obj-$(CONFIG_USB_DWC3) += dwc3.o 7obj-$(CONFIG_USB_DWC3) += dwc3.o
5 8
6dwc3-y := core.o 9dwc3-y := core.o debug.o trace.o
7 10
8ifneq ($(filter y,$(CONFIG_USB_DWC3_HOST) $(CONFIG_USB_DWC3_DUAL_ROLE)),) 11ifneq ($(filter y,$(CONFIG_USB_DWC3_HOST) $(CONFIG_USB_DWC3_DUAL_ROLE)),)
9 dwc3-y += host.o 12 dwc3-y += host.o
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index c1237453465e..66f62563bcf9 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -33,6 +33,8 @@
33 33
34#include <linux/phy/phy.h> 34#include <linux/phy/phy.h>
35 35
36#define DWC3_MSG_MAX 500
37
36/* Global constants */ 38/* Global constants */
37#define DWC3_EP0_BOUNCE_SIZE 512 39#define DWC3_EP0_BOUNCE_SIZE 512
38#define DWC3_ENDPOINTS_NUM 32 40#define DWC3_ENDPOINTS_NUM 32
diff --git a/drivers/usb/dwc3/debug.c b/drivers/usb/dwc3/debug.c
new file mode 100644
index 000000000000..0be6885bc370
--- /dev/null
+++ b/drivers/usb/dwc3/debug.c
@@ -0,0 +1,32 @@
1/**
2 * debug.c - DesignWare USB3 DRD Controller Debug/Trace Support
3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
5 *
6 * Author: Felipe Balbi <balbi@ti.com>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 of
10 * the License as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include "debug.h"
19
20void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...)
21{
22 struct va_format vaf;
23 va_list args;
24
25 va_start(args, fmt);
26 vaf.fmt = fmt;
27 vaf.va = &args;
28
29 trace(&vaf);
30
31 va_end(args);
32}
diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h
index 12ff4c9479c0..07fbc2d94fd4 100644
--- a/drivers/usb/dwc3/debug.h
+++ b/drivers/usb/dwc3/debug.h
@@ -214,6 +214,8 @@ static inline const char *dwc3_gadget_event_type_string(u8 event)
214 } 214 }
215} 215}
216 216
217void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...);
218
217#ifdef CONFIG_DEBUG_FS 219#ifdef CONFIG_DEBUG_FS
218extern int dwc3_debugfs_init(struct dwc3 *); 220extern int dwc3_debugfs_init(struct dwc3 *);
219extern void dwc3_debugfs_exit(struct dwc3 *); 221extern void dwc3_debugfs_exit(struct dwc3 *);
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 994e1d864679..b35938777dde 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -66,7 +66,7 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
66 66
67 dep = dwc->eps[epnum]; 67 dep = dwc->eps[epnum];
68 if (dep->flags & DWC3_EP_BUSY) { 68 if (dep->flags & DWC3_EP_BUSY) {
69 dev_vdbg(dwc->dev, "%s: still busy\n", dep->name); 69 dwc3_trace(trace_dwc3_ep0, "%s still busy", dep->name);
70 return 0; 70 return 0;
71 } 71 }
72 72
@@ -89,7 +89,8 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
89 ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, 89 ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
90 DWC3_DEPCMD_STARTTRANSFER, &params); 90 DWC3_DEPCMD_STARTTRANSFER, &params);
91 if (ret < 0) { 91 if (ret < 0) {
92 dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n"); 92 dwc3_trace(trace_dwc3_ep0, "%s STARTTRANSFER failed",
93 dep->name);
93 return ret; 94 return ret;
94 } 95 }
95 96
@@ -154,7 +155,8 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
154 if (dwc->ep0state == EP0_STATUS_PHASE) 155 if (dwc->ep0state == EP0_STATUS_PHASE)
155 __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]); 156 __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]);
156 else 157 else
157 dev_dbg(dwc->dev, "too early for delayed status\n"); 158 dwc3_trace(trace_dwc3_ep0,
159 "too early for delayed status");
158 160
159 return 0; 161 return 0;
160 } 162 }
@@ -218,7 +220,8 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
218 220
219 spin_lock_irqsave(&dwc->lock, flags); 221 spin_lock_irqsave(&dwc->lock, flags);
220 if (!dep->endpoint.desc) { 222 if (!dep->endpoint.desc) {
221 dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", 223 dwc3_trace(trace_dwc3_ep0,
224 "trying to queue request %p to disabled %s",
222 request, dep->name); 225 request, dep->name);
223 ret = -ESHUTDOWN; 226 ret = -ESHUTDOWN;
224 goto out; 227 goto out;
@@ -230,7 +233,8 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
230 goto out; 233 goto out;
231 } 234 }
232 235
233 dev_vdbg(dwc->dev, "queueing request %p to %s length %d, state '%s'\n", 236 dwc3_trace(trace_dwc3_ep0,
237 "queueing request %p to %s length %d state '%s'",
234 request, dep->name, request->length, 238 request, dep->name, request->length,
235 dwc3_ep0_state_string(dwc->ep0state)); 239 dwc3_ep0_state_string(dwc->ep0state));
236 240
@@ -486,12 +490,13 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
486 490
487 addr = le16_to_cpu(ctrl->wValue); 491 addr = le16_to_cpu(ctrl->wValue);
488 if (addr > 127) { 492 if (addr > 127) {
489 dev_dbg(dwc->dev, "invalid device address %d\n", addr); 493 dwc3_trace(trace_dwc3_ep0, "invalid device address %d", addr);
490 return -EINVAL; 494 return -EINVAL;
491 } 495 }
492 496
493 if (state == USB_STATE_CONFIGURED) { 497 if (state == USB_STATE_CONFIGURED) {
494 dev_dbg(dwc->dev, "trying to set address when configured\n"); 498 dwc3_trace(trace_dwc3_ep0,
499 "trying to set address when configured");
495 return -EINVAL; 500 return -EINVAL;
496 } 501 }
497 502
@@ -557,7 +562,7 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
557 dwc3_writel(dwc->regs, DWC3_DCTL, reg); 562 dwc3_writel(dwc->regs, DWC3_DCTL, reg);
558 563
559 dwc->resize_fifos = true; 564 dwc->resize_fifos = true;
560 dev_dbg(dwc->dev, "resize fifos flag SET\n"); 565 dwc3_trace(trace_dwc3_ep0, "resize FIFOs flag SET");
561 } 566 }
562 break; 567 break;
563 568
@@ -681,35 +686,35 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
681 686
682 switch (ctrl->bRequest) { 687 switch (ctrl->bRequest) {
683 case USB_REQ_GET_STATUS: 688 case USB_REQ_GET_STATUS:
684 dev_vdbg(dwc->dev, "USB_REQ_GET_STATUS\n"); 689 dwc3_trace(trace_dwc3_ep0, "USB_REQ_GET_STATUS\n");
685 ret = dwc3_ep0_handle_status(dwc, ctrl); 690 ret = dwc3_ep0_handle_status(dwc, ctrl);
686 break; 691 break;
687 case USB_REQ_CLEAR_FEATURE: 692 case USB_REQ_CLEAR_FEATURE:
688 dev_vdbg(dwc->dev, "USB_REQ_CLEAR_FEATURE\n"); 693 dwc3_trace(trace_dwc3_ep0, "USB_REQ_CLEAR_FEATURE\n");
689 ret = dwc3_ep0_handle_feature(dwc, ctrl, 0); 694 ret = dwc3_ep0_handle_feature(dwc, ctrl, 0);
690 break; 695 break;
691 case USB_REQ_SET_FEATURE: 696 case USB_REQ_SET_FEATURE:
692 dev_vdbg(dwc->dev, "USB_REQ_SET_FEATURE\n"); 697 dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_FEATURE\n");
693 ret = dwc3_ep0_handle_feature(dwc, ctrl, 1); 698 ret = dwc3_ep0_handle_feature(dwc, ctrl, 1);
694 break; 699 break;
695 case USB_REQ_SET_ADDRESS: 700 case USB_REQ_SET_ADDRESS:
696 dev_vdbg(dwc->dev, "USB_REQ_SET_ADDRESS\n"); 701 dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ADDRESS\n");
697 ret = dwc3_ep0_set_address(dwc, ctrl); 702 ret = dwc3_ep0_set_address(dwc, ctrl);
698 break; 703 break;
699 case USB_REQ_SET_CONFIGURATION: 704 case USB_REQ_SET_CONFIGURATION:
700 dev_vdbg(dwc->dev, "USB_REQ_SET_CONFIGURATION\n"); 705 dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_CONFIGURATION\n");
701 ret = dwc3_ep0_set_config(dwc, ctrl); 706 ret = dwc3_ep0_set_config(dwc, ctrl);
702 break; 707 break;
703 case USB_REQ_SET_SEL: 708 case USB_REQ_SET_SEL:
704 dev_vdbg(dwc->dev, "USB_REQ_SET_SEL\n"); 709 dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_SEL\n");
705 ret = dwc3_ep0_set_sel(dwc, ctrl); 710 ret = dwc3_ep0_set_sel(dwc, ctrl);
706 break; 711 break;
707 case USB_REQ_SET_ISOCH_DELAY: 712 case USB_REQ_SET_ISOCH_DELAY:
708 dev_vdbg(dwc->dev, "USB_REQ_SET_ISOCH_DELAY\n"); 713 dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ISOCH_DELAY\n");
709 ret = dwc3_ep0_set_isoch_delay(dwc, ctrl); 714 ret = dwc3_ep0_set_isoch_delay(dwc, ctrl);
710 break; 715 break;
711 default: 716 default:
712 dev_vdbg(dwc->dev, "Forwarding to gadget driver\n"); 717 dwc3_trace(trace_dwc3_ep0, "Forwarding to gadget driver\n");
713 ret = dwc3_ep0_delegate_req(dwc, ctrl); 718 ret = dwc3_ep0_delegate_req(dwc, ctrl);
714 break; 719 break;
715 } 720 }
@@ -727,6 +732,8 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
727 if (!dwc->gadget_driver) 732 if (!dwc->gadget_driver)
728 goto out; 733 goto out;
729 734
735 trace_dwc3_ctrl_req(ctrl);
736
730 len = le16_to_cpu(ctrl->wLength); 737 len = le16_to_cpu(ctrl->wLength);
731 if (!len) { 738 if (!len) {
732 dwc->three_stage_setup = false; 739 dwc->three_stage_setup = false;
@@ -775,7 +782,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
775 782
776 status = DWC3_TRB_SIZE_TRBSTS(trb->size); 783 status = DWC3_TRB_SIZE_TRBSTS(trb->size);
777 if (status == DWC3_TRBSTS_SETUP_PENDING) { 784 if (status == DWC3_TRBSTS_SETUP_PENDING) {
778 dev_dbg(dwc->dev, "Setup Pending received\n"); 785 dwc3_trace(trace_dwc3_ep0, "Setup Pending received");
779 786
780 if (r) 787 if (r)
781 dwc3_gadget_giveback(ep0, r, -ECONNRESET); 788 dwc3_gadget_giveback(ep0, r, -ECONNRESET);
@@ -835,7 +842,7 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
835 842
836 ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr); 843 ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr);
837 if (ret < 0) { 844 if (ret < 0) {
838 dev_dbg(dwc->dev, "Invalid Test #%d\n", 845 dwc3_trace(trace_dwc3_ep0, "Invalid Test #%d",
839 dwc->test_mode_nr); 846 dwc->test_mode_nr);
840 dwc3_ep0_stall_and_restart(dwc); 847 dwc3_ep0_stall_and_restart(dwc);
841 return; 848 return;
@@ -844,7 +851,7 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
844 851
845 status = DWC3_TRB_SIZE_TRBSTS(trb->size); 852 status = DWC3_TRB_SIZE_TRBSTS(trb->size);
846 if (status == DWC3_TRBSTS_SETUP_PENDING) 853 if (status == DWC3_TRBSTS_SETUP_PENDING)
847 dev_dbg(dwc->dev, "Setup Pending received\n"); 854 dwc3_trace(trace_dwc3_ep0, "Setup Pending received\n");
848 855
849 dwc->ep0state = EP0_SETUP_PHASE; 856 dwc->ep0state = EP0_SETUP_PHASE;
850 dwc3_ep0_out_start(dwc); 857 dwc3_ep0_out_start(dwc);
@@ -861,17 +868,17 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc,
861 868
862 switch (dwc->ep0state) { 869 switch (dwc->ep0state) {
863 case EP0_SETUP_PHASE: 870 case EP0_SETUP_PHASE:
864 dev_vdbg(dwc->dev, "Inspecting Setup Bytes\n"); 871 dwc3_trace(trace_dwc3_ep0, "Setup Phase");
865 dwc3_ep0_inspect_setup(dwc, event); 872 dwc3_ep0_inspect_setup(dwc, event);
866 break; 873 break;
867 874
868 case EP0_DATA_PHASE: 875 case EP0_DATA_PHASE:
869 dev_vdbg(dwc->dev, "Data Phase\n"); 876 dwc3_trace(trace_dwc3_ep0, "Data Phase");
870 dwc3_ep0_complete_data(dwc, event); 877 dwc3_ep0_complete_data(dwc, event);
871 break; 878 break;
872 879
873 case EP0_STATUS_PHASE: 880 case EP0_STATUS_PHASE:
874 dev_vdbg(dwc->dev, "Status Phase\n"); 881 dwc3_trace(trace_dwc3_ep0, "Status Phase");
875 dwc3_ep0_complete_status(dwc, event); 882 dwc3_ep0_complete_status(dwc, event);
876 break; 883 break;
877 default: 884 default:
@@ -947,7 +954,7 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep)
947static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) 954static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
948{ 955{
949 if (dwc->resize_fifos) { 956 if (dwc->resize_fifos) {
950 dev_dbg(dwc->dev, "starting to resize fifos\n"); 957 dwc3_trace(trace_dwc3_ep0, "Resizing FIFOs");
951 dwc3_gadget_resize_tx_fifos(dwc); 958 dwc3_gadget_resize_tx_fifos(dwc);
952 dwc->resize_fifos = 0; 959 dwc->resize_fifos = 0;
953 } 960 }
@@ -988,7 +995,7 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
988 995
989 switch (event->status) { 996 switch (event->status) {
990 case DEPEVT_STATUS_CONTROL_DATA: 997 case DEPEVT_STATUS_CONTROL_DATA:
991 dev_vdbg(dwc->dev, "Control Data\n"); 998 dwc3_trace(trace_dwc3_ep0, "Control Data");
992 999
993 /* 1000 /*
994 * We already have a DATA transfer in the controller's cache, 1001 * We already have a DATA transfer in the controller's cache,
@@ -1002,7 +1009,8 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
1002 if (dwc->ep0_expect_in != event->endpoint_number) { 1009 if (dwc->ep0_expect_in != event->endpoint_number) {
1003 struct dwc3_ep *dep = dwc->eps[dwc->ep0_expect_in]; 1010 struct dwc3_ep *dep = dwc->eps[dwc->ep0_expect_in];
1004 1011
1005 dev_vdbg(dwc->dev, "Wrong direction for Data phase\n"); 1012 dwc3_trace(trace_dwc3_ep0,
1013 "Wrong direction for Data phase");
1006 dwc3_ep0_end_control_data(dwc, dep); 1014 dwc3_ep0_end_control_data(dwc, dep);
1007 dwc3_ep0_stall_and_restart(dwc); 1015 dwc3_ep0_stall_and_restart(dwc);
1008 return; 1016 return;
@@ -1014,13 +1022,13 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
1014 if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) 1022 if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS)
1015 return; 1023 return;
1016 1024
1017 dev_vdbg(dwc->dev, "Control Status\n"); 1025 dwc3_trace(trace_dwc3_ep0, "Control Status");
1018 1026
1019 dwc->ep0state = EP0_STATUS_PHASE; 1027 dwc->ep0state = EP0_STATUS_PHASE;
1020 1028
1021 if (dwc->delayed_status) { 1029 if (dwc->delayed_status) {
1022 WARN_ON_ONCE(event->endpoint_number != 1); 1030 WARN_ON_ONCE(event->endpoint_number != 1);
1023 dev_vdbg(dwc->dev, "Mass Storage delayed status\n"); 1031 dwc3_trace(trace_dwc3_ep0, "Delayed Status");
1024 return; 1032 return;
1025 } 1033 }
1026 1034
@@ -1033,7 +1041,7 @@ void dwc3_ep0_interrupt(struct dwc3 *dwc,
1033{ 1041{
1034 u8 epnum = event->endpoint_number; 1042 u8 epnum = event->endpoint_number;
1035 1043
1036 dev_dbg(dwc->dev, "%s while ep%d%s in state '%s'\n", 1044 dwc3_trace(trace_dwc3_ep0, "%s while ep%d%s in state '%s'",
1037 dwc3_ep_event_string(event->endpoint_event), 1045 dwc3_ep_event_string(event->endpoint_event),
1038 epnum >> 1, (epnum & 1) ? "in" : "out", 1046 epnum >> 1, (epnum & 1) ? "in" : "out",
1039 dwc3_ep0_state_string(dwc->ep0state)); 1047 dwc3_ep0_state_string(dwc->ep0state));
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 096b63838dc0..f2dbaca5df2c 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -267,6 +267,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
267 dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", 267 dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",
268 req, dep->name, req->request.actual, 268 req, dep->name, req->request.actual,
269 req->request.length, status); 269 req->request.length, status);
270 trace_dwc3_gadget_giveback(req);
270 271
271 spin_unlock(&dwc->lock); 272 spin_unlock(&dwc->lock);
272 req->request.complete(&dep->endpoint, &req->request); 273 req->request.complete(&dep->endpoint, &req->request);
@@ -278,8 +279,7 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param)
278 u32 timeout = 500; 279 u32 timeout = 500;
279 u32 reg; 280 u32 reg;
280 281
281 dev_vdbg(dwc->dev, "generic cmd '%s' [%d] param %08x\n", 282 trace_dwc3_gadget_generic_cmd(cmd, param);
282 dwc3_gadget_generic_cmd_string(cmd), cmd, param);
283 283
284 dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param); 284 dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param);
285 dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT); 285 dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
@@ -310,10 +310,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
310 u32 timeout = 500; 310 u32 timeout = 500;
311 u32 reg; 311 u32 reg;
312 312
313 dev_vdbg(dwc->dev, "%s: cmd '%s' [%d] params %08x %08x %08x\n", 313 trace_dwc3_gadget_ep_cmd(dep, cmd, params);
314 dep->name,
315 dwc3_gadget_ep_cmd_string(cmd), cmd, params->param0,
316 params->param1, params->param2);
317 314
318 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0); 315 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
319 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1); 316 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1);
@@ -710,6 +707,8 @@ static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep,
710 req->epnum = dep->number; 707 req->epnum = dep->number;
711 req->dep = dep; 708 req->dep = dep;
712 709
710 trace_dwc3_alloc_request(req);
711
713 return &req->request; 712 return &req->request;
714} 713}
715 714
@@ -718,6 +717,7 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
718{ 717{
719 struct dwc3_request *req = to_dwc3_request(request); 718 struct dwc3_request *req = to_dwc3_request(request);
720 719
720 trace_dwc3_free_request(req);
721 kfree(req); 721 kfree(req);
722} 722}
723 723
@@ -799,6 +799,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
799 trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id); 799 trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id);
800 800
801 trb->ctrl |= DWC3_TRB_CTRL_HWO; 801 trb->ctrl |= DWC3_TRB_CTRL_HWO;
802
803 trace_dwc3_prepare_trb(dep, trb);
802} 804}
803 805
804/* 806/*
@@ -1143,6 +1145,7 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
1143 1145
1144 dev_vdbg(dwc->dev, "queing request %p to %s length %d\n", 1146 dev_vdbg(dwc->dev, "queing request %p to %s length %d\n",
1145 request, ep->name, request->length); 1147 request, ep->name, request->length);
1148 trace_dwc3_ep_queue(req);
1146 1149
1147 spin_lock_irqsave(&dwc->lock, flags); 1150 spin_lock_irqsave(&dwc->lock, flags);
1148 ret = __dwc3_gadget_ep_queue(dep, req); 1151 ret = __dwc3_gadget_ep_queue(dep, req);
@@ -1163,6 +1166,8 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
1163 unsigned long flags; 1166 unsigned long flags;
1164 int ret = 0; 1167 int ret = 0;
1165 1168
1169 trace_dwc3_ep_dequeue(req);
1170
1166 spin_lock_irqsave(&dwc->lock, flags); 1171 spin_lock_irqsave(&dwc->lock, flags);
1167 1172
1168 list_for_each_entry(r, &dep->request_list, list) { 1173 list_for_each_entry(r, &dep->request_list, list) {
@@ -1753,6 +1758,8 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep,
1753 unsigned int s_pkt = 0; 1758 unsigned int s_pkt = 0;
1754 unsigned int trb_status; 1759 unsigned int trb_status;
1755 1760
1761 trace_dwc3_complete_trb(dep, trb);
1762
1756 if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN) 1763 if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN)
1757 /* 1764 /*
1758 * We continue despite the error. There is not much we 1765 * We continue despite the error. There is not much we
@@ -1927,9 +1934,6 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
1927 if (!(dep->flags & DWC3_EP_ENABLED)) 1934 if (!(dep->flags & DWC3_EP_ENABLED))
1928 return; 1935 return;
1929 1936
1930 dev_vdbg(dwc->dev, "%s: %s\n", dep->name,
1931 dwc3_ep_event_string(event->endpoint_event));
1932
1933 if (epnum == 0 || epnum == 1) { 1937 if (epnum == 0 || epnum == 1) {
1934 dwc3_ep0_interrupt(dwc, event); 1938 dwc3_ep0_interrupt(dwc, event);
1935 return; 1939 return;
@@ -2122,8 +2126,6 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
2122{ 2126{
2123 int reg; 2127 int reg;
2124 2128
2125 dev_vdbg(dwc->dev, "%s\n", __func__);
2126
2127 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 2129 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
2128 reg &= ~DWC3_DCTL_INITU1ENA; 2130 reg &= ~DWC3_DCTL_INITU1ENA;
2129 dwc3_writel(dwc->regs, DWC3_DCTL, reg); 2131 dwc3_writel(dwc->regs, DWC3_DCTL, reg);
@@ -2142,8 +2144,6 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
2142{ 2144{
2143 u32 reg; 2145 u32 reg;
2144 2146
2145 dev_vdbg(dwc->dev, "%s\n", __func__);
2146
2147 /* 2147 /*
2148 * WORKAROUND: DWC3 revisions <1.88a have an issue which 2148 * WORKAROUND: DWC3 revisions <1.88a have an issue which
2149 * would cause a missing Disconnect Event if there's a 2149 * would cause a missing Disconnect Event if there's a
@@ -2228,8 +2228,6 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
2228 u32 reg; 2228 u32 reg;
2229 u8 speed; 2229 u8 speed;
2230 2230
2231 dev_vdbg(dwc->dev, "%s\n", __func__);
2232
2233 reg = dwc3_readl(dwc->regs, DWC3_DSTS); 2231 reg = dwc3_readl(dwc->regs, DWC3_DSTS);
2234 speed = reg & DWC3_DSTS_CONNECTSPD; 2232 speed = reg & DWC3_DSTS_CONNECTSPD;
2235 dwc->speed = speed; 2233 dwc->speed = speed;
@@ -2327,8 +2325,6 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
2327 2325
2328static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc) 2326static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc)
2329{ 2327{
2330 dev_vdbg(dwc->dev, "%s\n", __func__);
2331
2332 /* 2328 /*
2333 * TODO take core out of low power mode when that's 2329 * TODO take core out of low power mode when that's
2334 * implemented. 2330 * implemented.
@@ -2433,10 +2429,6 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
2433 break; 2429 break;
2434 } 2430 }
2435 2431
2436 dev_vdbg(dwc->dev, "link change: %s [%d] -> %s [%d]\n",
2437 dwc3_gadget_link_string(dwc->link_state),
2438 dwc->link_state, dwc3_gadget_link_string(next), next);
2439
2440 dwc->link_state = next; 2432 dwc->link_state = next;
2441} 2433}
2442 2434
@@ -2513,6 +2505,8 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
2513static void dwc3_process_event_entry(struct dwc3 *dwc, 2505static void dwc3_process_event_entry(struct dwc3 *dwc,
2514 const union dwc3_event *event) 2506 const union dwc3_event *event)
2515{ 2507{
2508 trace_dwc3_event(event->raw);
2509
2516 /* Endpoint IRQ, handle it and return early */ 2510 /* Endpoint IRQ, handle it and return early */
2517 if (event->type.is_devspec == 0) { 2511 if (event->type.is_devspec == 0) {
2518 /* depevt */ 2512 /* depevt */
diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
index d94441c14d8c..6a79c8e66bbc 100644
--- a/drivers/usb/dwc3/io.h
+++ b/drivers/usb/dwc3/io.h
@@ -20,27 +20,51 @@
20#define __DRIVERS_USB_DWC3_IO_H 20#define __DRIVERS_USB_DWC3_IO_H
21 21
22#include <linux/io.h> 22#include <linux/io.h>
23 23#include "trace.h"
24#include "debug.h"
24#include "core.h" 25#include "core.h"
25 26
26static inline u32 dwc3_readl(void __iomem *base, u32 offset) 27static inline u32 dwc3_readl(void __iomem *base, u32 offset)
27{ 28{
29 u32 offs = offset - DWC3_GLOBALS_REGS_START;
30 u32 value;
31
28 /* 32 /*
29 * We requested the mem region starting from the Globals address 33 * We requested the mem region starting from the Globals address
30 * space, see dwc3_probe in core.c. 34 * space, see dwc3_probe in core.c.
31 * However, the offsets are given starting from xHCI address space. 35 * However, the offsets are given starting from xHCI address space.
32 */ 36 */
33 return readl(base + (offset - DWC3_GLOBALS_REGS_START)); 37 value = readl(base + offs);
38
39 /*
40 * When tracing we want to make it easy to find the correct address on
41 * documentation, so we revert it back to the proper addresses, the
42 * same way they are described on SNPS documentation
43 */
44 dwc3_trace(trace_dwc3_readl, "addr %p value %08x",
45 base - DWC3_GLOBALS_REGS_START + offset, value);
46
47 return value;
34} 48}
35 49
36static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value) 50static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
37{ 51{
52 u32 offs = offset - DWC3_GLOBALS_REGS_START;
53
38 /* 54 /*
39 * We requested the mem region starting from the Globals address 55 * We requested the mem region starting from the Globals address
40 * space, see dwc3_probe in core.c. 56 * space, see dwc3_probe in core.c.
41 * However, the offsets are given starting from xHCI address space. 57 * However, the offsets are given starting from xHCI address space.
42 */ 58 */
43 writel(value, base + (offset - DWC3_GLOBALS_REGS_START)); 59 writel(value, base + offs);
60
61 /*
62 * When tracing we want to make it easy to find the correct address on
63 * documentation, so we revert it back to the proper addresses, the
64 * same way they are described on SNPS documentation
65 */
66 dwc3_trace(trace_dwc3_writel, "addr %p value %08x",
67 base - DWC3_GLOBALS_REGS_START + offset, value);
44} 68}
45 69
46#endif /* __DRIVERS_USB_DWC3_IO_H */ 70#endif /* __DRIVERS_USB_DWC3_IO_H */
diff --git a/drivers/usb/dwc3/trace.c b/drivers/usb/dwc3/trace.c
new file mode 100644
index 000000000000..6cd166412ad0
--- /dev/null
+++ b/drivers/usb/dwc3/trace.c
@@ -0,0 +1,19 @@
1/**
2 * trace.c - DesignWare USB3 DRD Controller Trace Support
3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
5 *
6 * Author: Felipe Balbi <balbi@ti.com>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 of
10 * the License as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#define CREATE_TRACE_POINTS
19#include "trace.h"
diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h
new file mode 100644
index 000000000000..78aff1da089a
--- /dev/null
+++ b/drivers/usb/dwc3/trace.h
@@ -0,0 +1,220 @@
1/**
2 * trace.h - DesignWare USB3 DRD Controller Trace Support
3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
5 *
6 * Author: Felipe Balbi <balbi@ti.com>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 of
10 * the License as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#undef TRACE_SYSTEM
19#define TRACE_SYSTEM dwc3
20
21#if !defined(__DWC3_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
22#define __DWC3_TRACE_H
23
24#include <linux/types.h>
25#include <linux/tracepoint.h>
26#include <asm/byteorder.h>
27#include "core.h"
28#include "debug.h"
29
30DECLARE_EVENT_CLASS(dwc3_log_msg,
31 TP_PROTO(struct va_format *vaf),
32 TP_ARGS(vaf),
33 TP_STRUCT__entry(__dynamic_array(char, msg, DWC3_MSG_MAX)),
34 TP_fast_assign(
35 vsnprintf(__get_str(msg), DWC3_MSG_MAX, vaf->fmt, *vaf->va);
36 ),
37 TP_printk("%s", __get_str(msg))
38);
39
40DEFINE_EVENT(dwc3_log_msg, dwc3_readl,
41 TP_PROTO(struct va_format *vaf),
42 TP_ARGS(vaf)
43);
44
45DEFINE_EVENT(dwc3_log_msg, dwc3_writel,
46 TP_PROTO(struct va_format *vaf),
47 TP_ARGS(vaf)
48);
49
50DEFINE_EVENT(dwc3_log_msg, dwc3_ep0,
51 TP_PROTO(struct va_format *vaf),
52 TP_ARGS(vaf)
53);
54
55DECLARE_EVENT_CLASS(dwc3_log_event,
56 TP_PROTO(u32 event),
57 TP_ARGS(event),
58 TP_STRUCT__entry(
59 __field(u32, event)
60 ),
61 TP_fast_assign(
62 __entry->event = event;
63 ),
64 TP_printk("event %08x\n", __entry->event)
65);
66
67DEFINE_EVENT(dwc3_log_event, dwc3_event,
68 TP_PROTO(u32 event),
69 TP_ARGS(event)
70);
71
72DECLARE_EVENT_CLASS(dwc3_log_ctrl,
73 TP_PROTO(struct usb_ctrlrequest *ctrl),
74 TP_ARGS(ctrl),
75 TP_STRUCT__entry(
76 __field(struct usb_ctrlrequest *, ctrl)
77 ),
78 TP_fast_assign(
79 __entry->ctrl = ctrl;
80 ),
81 TP_printk("bRequestType %02x bRequest %02x wValue %04x wIndex %04x wLength %d",
82 __entry->ctrl->bRequestType, __entry->ctrl->bRequest,
83 le16_to_cpu(__entry->ctrl->wValue), le16_to_cpu(__entry->ctrl->wIndex),
84 le16_to_cpu(__entry->ctrl->wLength)
85 )
86);
87
88DEFINE_EVENT(dwc3_log_ctrl, dwc3_ctrl_req,
89 TP_PROTO(struct usb_ctrlrequest *ctrl),
90 TP_ARGS(ctrl)
91);
92
93DECLARE_EVENT_CLASS(dwc3_log_request,
94 TP_PROTO(struct dwc3_request *req),
95 TP_ARGS(req),
96 TP_STRUCT__entry(
97 __field(struct dwc3_request *, req)
98 ),
99 TP_fast_assign(
100 __entry->req = req;
101 ),
102 TP_printk("%s: req %p length %u/%u ==> %d",
103 __entry->req->dep->name, __entry->req,
104 __entry->req->request.actual, __entry->req->request.length,
105 __entry->req->request.status
106 )
107);
108
109DEFINE_EVENT(dwc3_log_request, dwc3_alloc_request,
110 TP_PROTO(struct dwc3_request *req),
111 TP_ARGS(req)
112);
113
114DEFINE_EVENT(dwc3_log_request, dwc3_free_request,
115 TP_PROTO(struct dwc3_request *req),
116 TP_ARGS(req)
117);
118
119DEFINE_EVENT(dwc3_log_request, dwc3_ep_queue,
120 TP_PROTO(struct dwc3_request *req),
121 TP_ARGS(req)
122);
123
124DEFINE_EVENT(dwc3_log_request, dwc3_ep_dequeue,
125 TP_PROTO(struct dwc3_request *req),
126 TP_ARGS(req)
127);
128
129DEFINE_EVENT(dwc3_log_request, dwc3_gadget_giveback,
130 TP_PROTO(struct dwc3_request *req),
131 TP_ARGS(req)
132);
133
134DECLARE_EVENT_CLASS(dwc3_log_generic_cmd,
135 TP_PROTO(unsigned int cmd, u32 param),
136 TP_ARGS(cmd, param),
137 TP_STRUCT__entry(
138 __field(unsigned int, cmd)
139 __field(u32, param)
140 ),
141 TP_fast_assign(
142 __entry->cmd = cmd;
143 __entry->param = param;
144 ),
145 TP_printk("cmd '%s' [%d] param %08x\n",
146 dwc3_gadget_generic_cmd_string(__entry->cmd),
147 __entry->cmd, __entry->param
148 )
149);
150
151DEFINE_EVENT(dwc3_log_generic_cmd, dwc3_gadget_generic_cmd,
152 TP_PROTO(unsigned int cmd, u32 param),
153 TP_ARGS(cmd, param)
154);
155
156DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd,
157 TP_PROTO(struct dwc3_ep *dep, unsigned int cmd,
158 struct dwc3_gadget_ep_cmd_params *params),
159 TP_ARGS(dep, cmd, params),
160 TP_STRUCT__entry(
161 __field(struct dwc3_ep *, dep)
162 __field(unsigned int, cmd)
163 __field(struct dwc3_gadget_ep_cmd_params *, params)
164 ),
165 TP_fast_assign(
166 __entry->dep = dep;
167 __entry->cmd = cmd;
168 __entry->params = params;
169 ),
170 TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x\n",
171 __entry->dep->name, dwc3_gadget_ep_cmd_string(__entry->cmd),
172 __entry->cmd, __entry->params->param0,
173 __entry->params->param1, __entry->params->param2
174 )
175);
176
177DEFINE_EVENT(dwc3_log_gadget_ep_cmd, dwc3_gadget_ep_cmd,
178 TP_PROTO(struct dwc3_ep *dep, unsigned int cmd,
179 struct dwc3_gadget_ep_cmd_params *params),
180 TP_ARGS(dep, cmd, params)
181);
182
183DECLARE_EVENT_CLASS(dwc3_log_trb,
184 TP_PROTO(struct dwc3_ep *dep, struct dwc3_trb *trb),
185 TP_ARGS(dep, trb),
186 TP_STRUCT__entry(
187 __field(struct dwc3_ep *, dep)
188 __field(struct dwc3_trb *, trb)
189 ),
190 TP_fast_assign(
191 __entry->dep = dep;
192 __entry->trb = trb;
193 ),
194 TP_printk("%s: trb %p bph %08x bpl %08x size %08x ctrl %08x\n",
195 __entry->dep->name, __entry->trb, __entry->trb->bph,
196 __entry->trb->bpl, __entry->trb->size, __entry->trb->ctrl
197 )
198);
199
200DEFINE_EVENT(dwc3_log_trb, dwc3_prepare_trb,
201 TP_PROTO(struct dwc3_ep *dep, struct dwc3_trb *trb),
202 TP_ARGS(dep, trb)
203);
204
205DEFINE_EVENT(dwc3_log_trb, dwc3_complete_trb,
206 TP_PROTO(struct dwc3_ep *dep, struct dwc3_trb *trb),
207 TP_ARGS(dep, trb)
208);
209
210#endif /* __DWC3_TRACE_H */
211
212/* this part has to be here */
213
214#undef TRACE_INCLUDE_PATH
215#define TRACE_INCLUDE_PATH .
216
217#undef TRACE_INCLUDE_FILE
218#define TRACE_INCLUDE_FILE trace
219
220#include <trace/define_trace.h>