Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 861da2b5 authored by Mayank Rana's avatar Mayank Rana
Browse files

dwc3: debug: Add logging APIs using IPC logging framework



This change creates separate debug buffer with each DWC instance and
provides debug API to log different important events using IPC logging
framework.

CRs-Fixed: 1040809
Change-Id: I9aee21a99f5bcd0e82e81092c05bc2238863f5e4
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent fe5ce61d
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -50,6 +50,9 @@

#define DWC3_DEFAULT_AUTOSUSPEND_DELAY	5000 /* ms */

static int count;
static struct dwc3 *dwc3_instance[DWC_CTRL_COUNT];

void dwc3_usb3_phy_suspend(struct dwc3 *dwc, int suspend)
{
	u32			reg;
@@ -1125,6 +1128,13 @@ static int dwc3_probe(struct platform_device *pdev)
	void __iomem		*regs;
	void			*mem;

	if (count >= DWC_CTRL_COUNT) {
		dev_err(dev, "Err dwc instance %d >= %d available\n",
				count, DWC_CTRL_COUNT);
		ret = -EINVAL;
		return ret;
	}

	mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
	if (!mem)
		return -ENOMEM;
@@ -1336,6 +1346,15 @@ static int dwc3_probe(struct platform_device *pdev)
		goto err_core_init;
	}

	dwc->dwc_ipc_log_ctxt = ipc_log_context_create(NUM_LOG_PAGES,
					dev_name(dwc->dev), 0);
	if (!dwc->dwc_ipc_log_ctxt)
		dev_err(dwc->dev, "Error getting ipc_log_ctxt\n");

	dwc3_instance[count] = dwc;
	dwc->index = count;
	count++;

	pm_runtime_allow(dev);
	return 0;

@@ -1378,6 +1397,11 @@ static int dwc3_remove(struct platform_device *pdev)
	dwc3_free_event_buffers(dwc);
	dwc3_free_scratch_buffers(dwc);

	ipc_log_context_destroy(dwc->dwc_ipc_log_ctxt);
	dwc->dwc_ipc_log_ctxt = NULL;
	count--;
	dwc3_instance[dwc->index] = NULL;

	return 0;
}

+7 −0
Original line number Diff line number Diff line
@@ -484,6 +484,9 @@
#define DWC3_DEPCMD_TYPE_BULK		2
#define DWC3_DEPCMD_TYPE_INTR		3

#define DWC_CTRL_COUNT	10
#define NUM_LOG_PAGES	12

/* Structures */

struct dwc3_trb;
@@ -932,6 +935,8 @@ struct dwc3_scratchpad_array {
 * @bh_dbg_index: index for capturing bh_completion_time and bh_handled_evt_cnt
 * @wait_linkstate: waitqueue for waiting LINK to move into required state
 * @vbus_draw: current to be drawn from USB
 * @index: dwc3 instance's number
 * @dwc_ipc_log_ctxt: dwc3 ipc log context
 */
struct dwc3 {
	struct usb_ctrlrequest	*ctrl_req;
@@ -1114,6 +1119,8 @@ struct dwc3 {
	unsigned int		irq_dbg_index;

	wait_queue_head_t	wait_linkstate;
	unsigned int		index;
	void			*dwc_ipc_log_ctxt;
	struct dwc3_gadget_events	dbg_gadget_events;
};

+132 −0
Original line number Diff line number Diff line
@@ -17,6 +17,13 @@

#include "debug.h"

#include <linux/moduleparam.h>

static unsigned int ep_addr_rxdbg_mask = 1;
module_param(ep_addr_rxdbg_mask, uint, 0644);
static unsigned int ep_addr_txdbg_mask = 1;
module_param(ep_addr_txdbg_mask, uint, 0644);

void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...)
{
	struct va_format vaf;
@@ -30,3 +37,128 @@ void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...)

	va_end(args);
}

static int allow_dbg_print(u8 ep_num)
{
	int dir, num;

	/* allow bus wide events */
	if (ep_num == 0xff)
		return 1;

	dir = ep_num & 0x1;
	num = ep_num >> 1;
	num = 1 << num;

	if (dir && (num & ep_addr_txdbg_mask))
		return 1;
	if (!dir && (num & ep_addr_rxdbg_mask))
		return 1;

	return 0;
}

/**
 * dwc3_dbg_print:  prints the common part of the event
 * @addr:   endpoint address
 * @name:   event name
 * @status: status
 * @extra:  extra information
 * @dwc3: pointer to struct dwc3
 */
void dwc3_dbg_print(struct dwc3 *dwc, u8 ep_num, const char *name,
			int status, const char *extra)
{
	if (!allow_dbg_print(ep_num))
		return;

	if (name == NULL)
		return;

	ipc_log_string(dwc->dwc_ipc_log_ctxt, "%02X %-25.25s %4i ?\t%s",
			ep_num, name, status, extra);
}

/**
 * dwc3_dbg_done: prints a DONE event
 * @addr:   endpoint address
 * @td:     transfer descriptor
 * @status: status
 * @dwc3: pointer to struct dwc3
 */
void dwc3_dbg_done(struct dwc3 *dwc, u8 ep_num,
		const u32 count, int status)
{
	if (!allow_dbg_print(ep_num))
		return;

	ipc_log_string(dwc->dwc_ipc_log_ctxt, "%02X %-25.25s %4i ?\t%d",
			ep_num, "DONE", status, count);
}

/**
 * dwc3_dbg_event: prints a generic event
 * @addr:   endpoint address
 * @name:   event name
 * @status: status
 */
void dwc3_dbg_event(struct dwc3 *dwc, u8 ep_num, const char *name, int status)
{
	if (!allow_dbg_print(ep_num))
		return;

	if (name != NULL)
		dwc3_dbg_print(dwc, ep_num, name, status, "");
}

/*
 * dwc3_dbg_queue: prints a QUEUE event
 * @addr:   endpoint address
 * @req:    USB request
 * @status: status
 */
void dwc3_dbg_queue(struct dwc3 *dwc, u8 ep_num,
		const struct usb_request *req, int status)
{
	if (!allow_dbg_print(ep_num))
		return;

	if (req != NULL) {
		ipc_log_string(dwc->dwc_ipc_log_ctxt,
			"%02X %-25.25s %4i ?\t%d %d", ep_num, "QUEUE", status,
			!req->no_interrupt, req->length);
	}
}

/**
 * dwc3_dbg_setup: prints a SETUP event
 * @addr: endpoint address
 * @req:  setup request
 */
void dwc3_dbg_setup(struct dwc3 *dwc, u8 ep_num,
		const struct usb_ctrlrequest *req)
{
	if (!allow_dbg_print(ep_num))
		return;

	if (req != NULL) {
		ipc_log_string(dwc->dwc_ipc_log_ctxt,
			"%02X %-25.25s ?\t%02X %02X %04X %04X %d",
			ep_num, "SETUP", req->bRequestType,
			req->bRequest, le16_to_cpu(req->wValue),
			le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
	}
}

/**
 * dwc3_dbg_print_reg: prints a reg value
 * @name:   reg name
 * @reg: reg value to be printed
 */
void dwc3_dbg_print_reg(struct dwc3 *dwc, const char *name, int reg)
{
	if (name == NULL)
		return;

	ipc_log_string(dwc->dwc_ipc_log_ctxt, "%s = 0x%08x", name, reg);
}
+34 −0
Original line number Diff line number Diff line
@@ -20,7 +20,29 @@
#define __DWC3_DEBUG_H

#include "core.h"
#include <linux/ipc_logging.h>

/*
 * NOTE: Make sure to have dwc as local variable in function before using
 * below macros.
 */
#define dbg_event(ep_num, name, status) \
	dwc3_dbg_print(dwc, ep_num, name, status, "")

#define dbg_print(ep_num, name, status, extra) \
	dwc3_dbg_print(dwc, ep_num, name, status, extra)

#define dbg_print_reg(name, reg) \
	dwc3_dbg_print_reg(dwc, name, reg)

#define dbg_done(ep_num, count, status) \
	dwc3_dbg_done(dwc, ep_num, count, status)

#define dbg_queue(ep_num, req, status) \
	dwc3_dbg_queue(dwc, ep_num, req, status)

#define dbg_setup(ep_num, req) \
	dwc3_dbg_setup(dwc, ep_num, req)
/**
 * dwc3_gadget_ep_cmd_string - returns endpoint command string
 * @cmd: command code
@@ -311,6 +333,18 @@ static inline const char *dwc3_gadget_generic_cmd_status_string(int status)
}

void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...);
void dwc3_dbg_print(struct dwc3 *dwc, u8 ep_num,
		const char *name, int status, const char *extra);
void dwc3_dbg_done(struct dwc3 *dwc, u8 ep_num,
		const u32 count, int status);
void dwc3_dbg_event(struct dwc3 *dwc, u8 ep_num,
		const char *name, int status);
void dwc3_dbg_queue(struct dwc3 *dwc, u8 ep_num,
		const struct usb_request *req, int status);
void dwc3_dbg_setup(struct dwc3 *dwc, u8 ep_num,
		const struct usb_ctrlrequest *req);
void dwc3_dbg_print_reg(struct dwc3 *dwc,
		const char *name, int reg);

#ifdef CONFIG_DEBUG_FS
extern int dwc3_debugfs_init(struct dwc3 *);