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

Commit e287b361 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "dwc3: Separate out debug events for each DWC instance"

parents 2b73d3b9 5d3261c4
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -449,6 +449,9 @@ enum event_buf_type {
	EVT_BUF_TYPE_GSI
};

#define DWC_CTRL_COUNT	10
#define NUM_LOG_PAGES	12

/**
 * struct dwc3_event_buffer - Software event buffer representation
 * @buf: _THE_ buffer
@@ -828,6 +831,7 @@ 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
 * @dwc_ipc_log_ctxt: dwc3 ipa log context
 */
struct dwc3 {
	struct usb_ctrlrequest	*ctrl_req;
@@ -979,6 +983,7 @@ struct dwc3 {
	unsigned                irq_dbg_index;

	wait_queue_head_t	wait_linkstate;
	void			*dwc_ipc_log_ctxt;
};

/* -------------------------------------------------------------------------- */
+37 −15
Original line number Diff line number Diff line
@@ -21,6 +21,28 @@

#include "core.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
@@ -217,28 +239,28 @@ static inline const char *dwc3_gadget_event_type_string(u8 event)
void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...);

#ifdef CONFIG_DEBUG_FS
extern void dbg_event(u8, const char*, int);
extern void dbg_print(u8, const char*, int, const char*);
extern void dbg_done(u8, const u32, int);
extern void dbg_queue(u8, const struct usb_request*, int);
extern void dbg_setup(u8, const struct usb_ctrlrequest*);
extern void dwc3_dbg_print(struct dwc3 *, u8, const char*, int, const char*);
extern void dwc3_dbg_done(struct dwc3 *, u8, const u32, int);
extern void dwc3_dbg_queue(struct dwc3 *, u8, const struct usb_request*, int);
extern void dwc3_dbg_setup(struct dwc3 *, u8, const struct usb_ctrlrequest*);
extern int dwc3_debugfs_init(struct dwc3 *);
extern void dwc3_debugfs_exit(struct dwc3 *);
extern void dbg_print_reg(const char *name, int reg);
extern void dwc3_dbg_print_reg(struct dwc3 *, const char *name, int reg);
#else
static inline void dbg_event(u8 ep_num, const char *name, int status)
{  }
static inline void dbg_print(u8 ep_num, const char *name, int status,
			     const char *extra)
static inline void dwc3_dbg_print(struct dwc3 *dwc, u8 ep_num, const char *name,
		int status, const char *extra)
{  }
static inline void dbg_done(u8 ep_num, const u32 count, int status)
static inline void dwc3_dbg_done(struct dwc3 *dwc, u8 ep_num,
		const u32 count, int status)
{  }
static inline void dbg_queue(u8 ep_num, const struct usb_request *req,
			     int status)
static inline void dwc3_dbg_queue(struct dwc3 *dwc, u8 ep_num,
		const struct usb_request *req, int status)
{  }
static inline void dbg_setup(u8 ep_num, const struct usb_ctrlrequest *req)
static inline void dwc3_dbg_setup(struct dwc3 *dwc, u8 ep_num,
		const struct usb_ctrlrequest *req)
{  }
static inline void dbg_print_reg(const char *name, int reg)
static inline void dwc3_dbg_print_reg(struct dwc3 *dwc, const char *name,
				int reg)
{  }
static inline int dwc3_debugfs_init(struct dwc3 *d)
{  return 0;  }
+57 −182
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/uaccess.h>

#include <linux/usb/ch9.h>
#include <linux/ipc_logging.h>

#include "core.h"
#include "gadget.h"
@@ -779,54 +780,7 @@ module_param(ep_addr_rxdbg_mask, uint, S_IRUGO | S_IWUSR);
static unsigned int ep_addr_txdbg_mask = 1;
module_param(ep_addr_txdbg_mask, uint, S_IRUGO | S_IWUSR);

/* Maximum debug message length */
#define DBG_DATA_MSG   64UL

/* Maximum number of messages */
#define DBG_DATA_MAX   2048UL

static struct {
	char     (buf[DBG_DATA_MAX])[DBG_DATA_MSG];   /* buffer */
	unsigned idx;   /* index */
	unsigned tty;   /* print to console? */
	rwlock_t lck;   /* lock */
} dbg_dwc3_data = {
	.idx = 0,
	.tty = 0,
	.lck = __RW_LOCK_UNLOCKED(lck)
};

/**
 * dbg_dec: decrements debug event index
 * @idx: buffer index
 */
static inline void __maybe_unused dbg_dec(unsigned *idx)
{
	*idx = (*idx - 1) % DBG_DATA_MAX;
}

/**
 * dbg_inc: increments debug event index
 * @idx: buffer index
 */
static inline void dbg_inc(unsigned *idx)
{
	*idx = (*idx + 1) % DBG_DATA_MAX;
}

#define TIME_BUF_LEN  20
/*get_timestamp - returns time of day in us */
static char *get_timestamp(char *tbuf)
{
	unsigned long long t;
	unsigned long nanosec_rem;

	t = cpu_clock(smp_processor_id());
	nanosec_rem = do_div(t, 1000000000)/1000;
	scnprintf(tbuf, TIME_BUF_LEN, "[%5lu.%06lu] ", (unsigned long)t,
		nanosec_rem);
	return tbuf;
}
static struct dwc3 *dbg_dwc3_data[DWC_CTRL_COUNT];

static int allow_dbg_print(u8 ep_num)
{
@@ -849,190 +803,95 @@ static int allow_dbg_print(u8 ep_num)
}

/**
 * dbg_print:  prints the common part of the event
 * 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 dbg_print(u8 ep_num, const char *name, int status, const char *extra)
void dwc3_dbg_print(struct dwc3 *dwc, u8 ep_num, const char *name,
			int status, const char *extra)
{
	unsigned long flags;
	char tbuf[TIME_BUF_LEN];

	if (!allow_dbg_print(ep_num))
		return;

	write_lock_irqsave(&dbg_dwc3_data.lck, flags);

	scnprintf(dbg_dwc3_data.buf[dbg_dwc3_data.idx], DBG_DATA_MSG,
		  "%s\t? %02X %-12.12s %4i ?\t%s\n",
		  get_timestamp(tbuf), ep_num, name, status, extra);

	dbg_inc(&dbg_dwc3_data.idx);

	write_unlock_irqrestore(&dbg_dwc3_data.lck, flags);

	if (dbg_dwc3_data.tty != 0)
		pr_notice("%s\t? %02X %-7.7s %4i ?\t%s\n",
			  get_timestamp(tbuf), ep_num, name, status, extra);
}

/**
 * dbg_done: prints a DONE event
 * @addr:   endpoint address
 * @td:     transfer descriptor
 * @status: status
 */
void dbg_done(u8 ep_num, const u32 count, int status)
{
	char msg[DBG_DATA_MSG];

	if (!allow_dbg_print(ep_num))
	if (name == NULL)
		return;

	scnprintf(msg, sizeof(msg), "%d", count);
	dbg_print(ep_num, "DONE", status, msg);
	ipc_log_string(dwc->dwc_ipc_log_ctxt, "%02X %-12.12s %4i ?\t%s",
			ep_num, name, status, extra);
}

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

	if (name != NULL)
		dbg_print(ep_num, name, status, "");
	ipc_log_string(dwc->dwc_ipc_log_ctxt, "%02X %-12.12s %4i ?\t%d",
			ep_num, "DONE", status, count);
}

/*
 * dbg_queue: prints a QUEUE event
 * dwc3_dbg_queue: prints a QUEUE event
 * @addr:   endpoint address
 * @req:    USB request
 * @status: status
 */
void dbg_queue(u8 ep_num, const struct usb_request *req, int status)
void dwc3_dbg_queue(struct dwc3 *dwc, u8 ep_num,
		const struct usb_request *req, int status)
{
	char msg[DBG_DATA_MSG];

	if (!allow_dbg_print(ep_num))
		return;

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

/**
 * dbg_setup: prints a SETUP event
 * dwc3_dbg_setup: prints a SETUP event
 * @addr: endpoint address
 * @req:  setup request
 */
void dbg_setup(u8 ep_num, const struct usb_ctrlrequest *req)
void dwc3_dbg_setup(struct dwc3 *dwc, u8 ep_num,
		const struct usb_ctrlrequest *req)
{
	char msg[DBG_DATA_MSG];

	if (!allow_dbg_print(ep_num))
		return;

	if (req != NULL) {
		scnprintf(msg, sizeof(msg),
			  "%02X %02X %04X %04X %d", req->bRequestType,
		ipc_log_string(dwc->dwc_ipc_log_ctxt,
			"%02X %-12.12s ?\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));
		dbg_print(ep_num, "SETUP", 0, msg);
	}
}

/**
 * dbg_print_reg: prints a reg value
 * dwc3_dbg_print_reg: prints a reg value
 * @name:   reg name
 * @reg: reg value to be printed
 */
void dbg_print_reg(const char *name, int reg)
void dwc3_dbg_print_reg(struct dwc3 *dwc, const char *name, int reg)
{
	unsigned long flags;

	write_lock_irqsave(&dbg_dwc3_data.lck, flags);

	scnprintf(dbg_dwc3_data.buf[dbg_dwc3_data.idx], DBG_DATA_MSG,
		  "%s = 0x%08x\n", name, reg);

	dbg_inc(&dbg_dwc3_data.idx);

	write_unlock_irqrestore(&dbg_dwc3_data.lck, flags);

	if (dbg_dwc3_data.tty != 0)
		pr_notice("%s = 0x%08x\n", name, reg);
}

/**
 * store_events: configure if events are going to be also printed to console
 *
 */
static ssize_t dwc3_store_events(struct file *file,
			    const char __user *buf, size_t count, loff_t *ppos)
{
	unsigned tty;

	if (buf == NULL) {
		pr_err("[%s] EINVAL\n", __func__);
		goto done;
	}

	if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
		pr_err("<1|0>: enable|disable console log\n");
		goto done;
	}

	dbg_dwc3_data.tty = tty;
	pr_info("tty = %u", dbg_dwc3_data.tty);

 done:
	return count;
}

static int dwc3_gadget_data_events_show(struct seq_file *s, void *unused)
{
	unsigned long	flags;
	unsigned	i;

	read_lock_irqsave(&dbg_dwc3_data.lck, flags);

	i = dbg_dwc3_data.idx;
	if (strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
		seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
	for (dbg_inc(&i); i != dbg_dwc3_data.idx; dbg_inc(&i)) {
		if (!strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
			continue;
		seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
	}

	read_unlock_irqrestore(&dbg_dwc3_data.lck, flags);
	if (name == NULL)
		return;

	return 0;
	ipc_log_string(dwc->dwc_ipc_log_ctxt, "%s = 0x%08x", name, reg);
}

static int dwc3_gadget_data_events_open(struct inode *inode, struct file *f)
{
	return single_open(f, dwc3_gadget_data_events_show, inode->i_private);
}

const struct file_operations dwc3_gadget_dbg_data_fops = {
	.open			= dwc3_gadget_data_events_open,
	.read			= seq_read,
	.write			= dwc3_store_events,
	.llseek			= seq_lseek,
	.release		= single_release,
};

static ssize_t dwc3_store_int_events(struct file *file,
			const char __user *ubuf, size_t count, loff_t *ppos)
{
@@ -1202,12 +1061,20 @@ const struct file_operations dwc3_gadget_dbg_events_fops = {
	.release	= single_release,
};

static int count;
int dwc3_debugfs_init(struct dwc3 *dwc)
{
	struct dentry		*root;
	struct dentry		*file;
	int			ret;

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

	root = debugfs_create_dir(dev_name(dwc->dev), NULL);
	if (!root) {
		ret = -ENOMEM;
@@ -1279,23 +1146,27 @@ int dwc3_debugfs_init(struct dwc3 *dwc)
		goto err1;
	}

	file = debugfs_create_file("events", S_IRUGO | S_IWUSR, root,
			dwc, &dwc3_gadget_dbg_data_fops);
	file = debugfs_create_file("int_events", S_IRUGO | S_IWUSR, root,
			dwc, &dwc3_gadget_dbg_events_fops);
	if (!file) {
		ret = -ENOMEM;
		goto err1;
	}

	file = debugfs_create_file("int_events", S_IRUGO | S_IWUSR, root,
			dwc, &dwc3_gadget_dbg_events_fops);
	if (!file) {
		ret = -ENOMEM;
	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");
		goto err1;
	}

	dbg_dwc3_data[count] = dwc;
	count++;
	return 0;

err1:
	kfree(dwc->regset);
	dwc->regset = NULL;
	debugfs_remove_recursive(root);

err0:
@@ -1306,4 +1177,8 @@ void dwc3_debugfs_exit(struct dwc3 *dwc)
{
	debugfs_remove_recursive(dwc->root);
	dwc->root = NULL;
	kfree(dwc->regset);
	dwc->regset = NULL;
	ipc_log_context_destroy(dwc->dwc_ipc_log_ctxt);
	dwc->dwc_ipc_log_ctxt = NULL;
}
+10 −1
Original line number Diff line number Diff line
@@ -3060,6 +3060,7 @@ static int dwc3_msm_remove_children(struct device *dev, void *data)
static int dwc3_msm_remove(struct platform_device *pdev)
{
	struct dwc3_msm	*mdwc = platform_get_drvdata(pdev);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
	int ret_pm;

	if (cpu_to_affin)
@@ -3089,10 +3090,11 @@ static int dwc3_msm_remove(struct platform_device *pdev)
		power_supply_unregister(&mdwc->usb_psy);
	if (mdwc->hs_phy)
		mdwc->hs_phy->flags &= ~PHY_HOST_MODE;

	dbg_event(0xFF, "Remov put", 0);
	platform_device_put(mdwc->dwc3);
	device_for_each_child(&pdev->dev, NULL, dwc3_msm_remove_children);

	dbg_event(0xFF, "Remov put", 0);
	pm_runtime_disable(mdwc->dev);
	pm_runtime_barrier(mdwc->dev);
	pm_runtime_put_sync(mdwc->dev);
@@ -3384,6 +3386,7 @@ psy_error:
static void dwc3_check_float_lines(struct dwc3_msm *mdwc)
{
	int dpdm;
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	dev_dbg(mdwc->dev, "%s: Check linestate\n", __func__);
	dwc3_msm_gadget_vbus_draw(mdwc, 0);
@@ -3740,6 +3743,7 @@ static int dwc3_msm_pm_suspend(struct device *dev)
static int dwc3_msm_pm_resume(struct device *dev)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	dev_dbg(dev, "dwc3-msm PM resume\n");

@@ -3759,6 +3763,9 @@ static int dwc3_msm_pm_resume(struct device *dev)
#ifdef CONFIG_PM_RUNTIME
static int dwc3_msm_runtime_idle(struct device *dev)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	dev_dbg(dev, "DWC3-msm runtime idle\n");
	dbg_event(0xFF, "RT Idle", 0);

@@ -3768,6 +3775,7 @@ static int dwc3_msm_runtime_idle(struct device *dev)
static int dwc3_msm_runtime_suspend(struct device *dev)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	dev_dbg(dev, "DWC3-msm runtime suspend\n");
	dbg_event(0xFF, "RT Sus", 0);
@@ -3778,6 +3786,7 @@ static int dwc3_msm_runtime_suspend(struct device *dev)
static int dwc3_msm_runtime_resume(struct device *dev)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	dev_dbg(dev, "DWC3-msm runtime resume\n");
	dbg_event(0xFF, "RT Res", 0);
+1 −0
Original line number Diff line number Diff line
@@ -927,6 +927,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
	unsigned int		last_one = 0;
	int			maxpkt_size;
	bool			isoc;
	struct dwc3		*dwc = dep->dwc;

	maxpkt_size = usb_endpoint_maxp(dep->endpoint.desc);
	isoc = usb_endpoint_xfer_isoc(dep->endpoint.desc);