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

Commit 679f332a authored by Mayank Rana's avatar Mayank Rana Committed by Hemant Kumar
Browse files

usb: 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>
[jackp@codeaurora: since debug.c is gone, added debug_ipc.c]
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent ac9b06a9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ CFLAGS_trace.o := -I$(src)

obj-$(CONFIG_USB_DWC3)			+= dwc3.o

dwc3-y					:= core.o
dwc3-y					:= core.o debug_ipc.o

ifneq ($(CONFIG_TRACING),)
	dwc3-y				+= trace.o
+18 −0
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@

#define DWC3_DEFAULT_AUTOSUSPEND_DELAY	5000 /* ms */

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

/**
 * dwc3_get_dr_mode - Validates and sets dr_mode
 * @dwc: pointer to our context structure
@@ -1382,6 +1385,16 @@ static int dwc3_probe(struct platform_device *pdev)
		goto err5;

	dwc3_debugfs_init(dwc);

	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_put(dev);

	return 0;
@@ -1433,6 +1446,11 @@ static int dwc3_remove(struct platform_device *pdev)
	dwc3_free_scratch_buffers(dwc);
	clk_bulk_put(dwc->num_clks, dwc->clks);

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

	return 0;
}

+8 −0
Original line number Diff line number Diff line
@@ -581,6 +581,9 @@
#define DWC3_OSTS_VBUSVLD		BIT(1)
#define DWC3_OSTS_CONIDSTS		BIT(0)

#define DWC_CTRL_COUNT	10
#define NUM_LOG_PAGES	12

/* Structures */

struct dwc3_trb;
@@ -988,6 +991,8 @@ struct dwc3_scratchpad_array {
 *                 increments or 0 to disable.
 * @xhci_imod_value: imod value to use with xhci
 * @core_id: usb core id to differentiate different controller
 * @index: dwc3's instance number
 * @dwc_ipc_log_ctxt: dwc3 ipc log context
 */
struct dwc3 {
	struct work_struct	drd_work;
@@ -1159,6 +1164,9 @@ struct dwc3 {
	u16			imod_interval;
	u32			xhci_imod_value;
	int			core_id;

	unsigned int		index;
	void			*dwc_ipc_log_ctxt;
};

#define work_to_dwc(w)		(container_of((w), struct dwc3, drd_work))
+34 −0
Original line number Diff line number Diff line
@@ -12,7 +12,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
@@ -622,6 +644,18 @@ static inline const char *dwc3_gadget_generic_cmd_status_string(int status)
	}
}

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 void dwc3_debugfs_init(struct dwc3 *);
+138 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 */

#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);

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);
}
Loading