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

Commit 69b7e8d3 authored by Alexander Shishkin's avatar Alexander Shishkin Committed by Greg Kroah-Hartman
Browse files

usb: chipidea: remove home-grown tracing facility



As part of the legacy from the original driver design, we retain home-grown
tracing infrastructure, complete with own ring buffer and timestamps,
which among other things has a performance penalty. This patch removes it.

Signed-off-by: default avatarAlexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 571bb7ab
Loading
Loading
Loading
Loading
+1 −359
Original line number Diff line number Diff line
@@ -10,46 +10,6 @@
#include "bits.h"
#include "debug.h"

/* Interrupt statistics */
#define ISR_MASK   0x1F
static struct isr_statistics {
	u32 test;
	u32 ui;
	u32 uei;
	u32 pci;
	u32 uri;
	u32 sli;
	u32 none;
	struct {
		u32 cnt;
		u32 buf[ISR_MASK+1];
		u32 idx;
	} hndl;
} isr_statistics;

void dbg_interrupt(u32 intmask)
{
	if (!intmask) {
		isr_statistics.none++;
		return;
	}

	isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intmask;
	isr_statistics.hndl.idx &= ISR_MASK;
	isr_statistics.hndl.cnt++;

	if (USBi_URI & intmask)
		isr_statistics.uri++;
	if (USBi_PCI & intmask)
		isr_statistics.pci++;
	if (USBi_UEI & intmask)
		isr_statistics.uei++;
	if (USBi_UI  & intmask)
		isr_statistics.ui++;
	if (USBi_SLI & intmask)
		isr_statistics.sli++;
}

/**
 * hw_register_read: reads all device registers (execute without interruption)
 * @buf:  destination buffer
@@ -196,312 +156,6 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL);

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

/* Maximum event messages */
#define DBG_DATA_MAX   128UL

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

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

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

/**
 * dbg_print:  prints the common part of the event
 * @addr:   endpoint address
 * @name:   event name
 * @status: status
 * @extra:  extra information
 */
static void dbg_print(u8 addr, const char *name, int status, const char *extra)
{
	struct timeval tval;
	unsigned int stamp;
	unsigned long flags;

	write_lock_irqsave(&dbg_data.lck, flags);

	do_gettimeofday(&tval);
	stamp = tval.tv_sec & 0xFFFF;	/* 2^32 = 4294967296. Limit to 4096s */
	stamp = stamp * 1000000 + tval.tv_usec;

	scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
		  "%04X\t? %02X %-7.7s %4i ?\t%s\n",
		  stamp, addr, name, status, extra);

	dbg_inc(&dbg_data.idx);

	write_unlock_irqrestore(&dbg_data.lck, flags);

	if (dbg_data.tty != 0)
		pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n",
			  stamp, addr, name, status, extra);
}

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

	scnprintf(msg, sizeof(msg), "%d %02X",
		  (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES),
		  (int)(token & TD_STATUS)      >> ffs_nr(TD_STATUS));
	dbg_print(addr, "DONE", status, msg);
}

/**
 * dbg_event: prints a generic event
 * @addr:   endpoint address
 * @name:   event name
 * @status: status
 */
void dbg_event(u8 addr, const char *name, int status)
{
	if (name != NULL)
		dbg_print(addr, name, status, "");
}

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

	if (req != NULL) {
		scnprintf(msg, sizeof(msg),
			  "%d %d", !req->no_interrupt, req->length);
		dbg_print(addr, "QUEUE", status, msg);
	}
}

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

	if (req != NULL) {
		scnprintf(msg, sizeof(msg),
			  "%02X %02X %04X %04X %d", req->bRequestType,
			  req->bRequest, le16_to_cpu(req->wValue),
			  le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
		dbg_print(addr, "SETUP", 0, msg);
	}
}

/**
 * show_events: displays the event buffer
 *
 * Check "device.h" for details
 */
static ssize_t show_events(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	unsigned long flags;
	unsigned i, j, n = 0;

	if (attr == NULL || buf == NULL) {
		dev_err(dev->parent, "[%s] EINVAL\n", __func__);
		return 0;
	}

	read_lock_irqsave(&dbg_data.lck, flags);

	i = dbg_data.idx;
	for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) {
		n += strlen(dbg_data.buf[i]);
		if (n >= PAGE_SIZE) {
			n -= strlen(dbg_data.buf[i]);
			break;
		}
	}
	for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i))
		j += scnprintf(buf + j, PAGE_SIZE - j,
			       "%s", dbg_data.buf[i]);

	read_unlock_irqrestore(&dbg_data.lck, flags);

	return n;
}

/**
 * store_events: configure if events are going to be also printed to console
 *
 * Check "device.h" for details
 */
static ssize_t store_events(struct device *dev, struct device_attribute *attr,
			    const char *buf, size_t count)
{
	unsigned tty;

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

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

	dbg_data.tty = tty;
	dev_info(dev, "tty = %u", dbg_data.tty);

 done:
	return count;
}
static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events);

/**
 * show_inters: interrupt status, enable status and historic
 *
 * Check "device.h" for details
 */
static ssize_t show_inters(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev);
	unsigned long flags;
	u32 intr;
	unsigned i, j, n = 0;

	if (attr == NULL || buf == NULL) {
		dev_err(ci->dev, "[%s] EINVAL\n", __func__);
		return 0;
	}

	spin_lock_irqsave(&ci->lock, flags);

	/*n += scnprintf(buf + n, PAGE_SIZE - n,
		       "status = %08x\n", hw_read_intr_status(ci));
	n += scnprintf(buf + n, PAGE_SIZE - n,
	"enable = %08x\n", hw_read_intr_enable(ci));*/

	n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
		       isr_statistics.test);
	n += scnprintf(buf + n, PAGE_SIZE - n, "? ui  = %d\n",
		       isr_statistics.ui);
	n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n",
		       isr_statistics.uei);
	n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n",
		       isr_statistics.pci);
	n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n",
		       isr_statistics.uri);
	n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n",
		       isr_statistics.sli);
	n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
		       isr_statistics.none);
	n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n",
		       isr_statistics.hndl.cnt);

	for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) {
		i   &= ISR_MASK;
		intr = isr_statistics.hndl.buf[i];

		if (USBi_UI  & intr)
			n += scnprintf(buf + n, PAGE_SIZE - n, "ui  ");
		intr &= ~USBi_UI;
		if (USBi_UEI & intr)
			n += scnprintf(buf + n, PAGE_SIZE - n, "uei ");
		intr &= ~USBi_UEI;
		if (USBi_PCI & intr)
			n += scnprintf(buf + n, PAGE_SIZE - n, "pci ");
		intr &= ~USBi_PCI;
		if (USBi_URI & intr)
			n += scnprintf(buf + n, PAGE_SIZE - n, "uri ");
		intr &= ~USBi_URI;
		if (USBi_SLI & intr)
			n += scnprintf(buf + n, PAGE_SIZE - n, "sli ");
		intr &= ~USBi_SLI;
		if (intr)
			n += scnprintf(buf + n, PAGE_SIZE - n, "??? ");
		if (isr_statistics.hndl.buf[i])
			n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
	}

	spin_unlock_irqrestore(&ci->lock, flags);

	return n;
}

/**
 * store_inters: enable & force or disable an individual interrutps
 *                   (to be used for test purposes only)
 *
 * Check "device.h" for details
 */
static ssize_t store_inters(struct device *dev, struct device_attribute *attr,
			    const char *buf, size_t count)
{
	struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev);
	unsigned long flags;
	unsigned en, bit;

	if (attr == NULL || buf == NULL) {
		dev_err(ci->dev, "EINVAL\n");
		goto done;
	}

	if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) {
		dev_err(ci->dev, "<1|0> <bit>: enable|disable interrupt\n");
		goto done;
	}

	spin_lock_irqsave(&ci->lock, flags);
	if (en) {
		if (hw_intr_force(ci, bit))
			dev_err(dev, "invalid bit number\n");
		else
			isr_statistics.test++;
	} else {
		if (hw_intr_clear(ci, bit))
			dev_err(dev, "invalid bit number\n");
	}
	spin_unlock_irqrestore(&ci->lock, flags);

 done:
	return count;
}
static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters);

/**
 * show_port_test: reads port test mode
 *
@@ -730,15 +384,9 @@ int dbg_create_files(struct device *dev)
	retval = device_create_file(dev, &dev_attr_driver);
	if (retval)
		goto rm_device;
	retval = device_create_file(dev, &dev_attr_events);
	if (retval)
		goto rm_driver;
	retval = device_create_file(dev, &dev_attr_inters);
	if (retval)
		goto rm_events;
	retval = device_create_file(dev, &dev_attr_port_test);
	if (retval)
		goto rm_inters;
		goto rm_driver;
	retval = device_create_file(dev, &dev_attr_qheads);
	if (retval)
		goto rm_port_test;
@@ -756,10 +404,6 @@ int dbg_create_files(struct device *dev)
	device_remove_file(dev, &dev_attr_qheads);
 rm_port_test:
	device_remove_file(dev, &dev_attr_port_test);
 rm_inters:
	device_remove_file(dev, &dev_attr_inters);
 rm_events:
	device_remove_file(dev, &dev_attr_events);
 rm_driver:
	device_remove_file(dev, &dev_attr_driver);
 rm_device:
@@ -782,8 +426,6 @@ int dbg_remove_files(struct device *dev)
	device_remove_file(dev, &dev_attr_registers);
	device_remove_file(dev, &dev_attr_qheads);
	device_remove_file(dev, &dev_attr_port_test);
	device_remove_file(dev, &dev_attr_inters);
	device_remove_file(dev, &dev_attr_events);
	device_remove_file(dev, &dev_attr_driver);
	device_remove_file(dev, &dev_attr_device);
	return 0;
+0 −25
Original line number Diff line number Diff line
@@ -14,34 +14,9 @@
#define __DRIVERS_USB_CHIPIDEA_DEBUG_H

#ifdef CONFIG_USB_CHIPIDEA_DEBUG
void dbg_interrupt(u32 intmask);
void dbg_done(u8 addr, const u32 token, int status);
void dbg_event(u8 addr, const char *name, int status);
void dbg_queue(u8 addr, const struct usb_request *req, int status);
void dbg_setup(u8 addr, const struct usb_ctrlrequest *req);
int dbg_create_files(struct device *dev);
int dbg_remove_files(struct device *dev);
#else
static inline void dbg_interrupt(u32 intmask)
{
}

static inline void dbg_done(u8 addr, const u32 token, int status)
{
}

static inline void dbg_event(u8 addr, const char *name, int status)
{
}

static inline void dbg_queue(u8 addr, const struct usb_request *req, int status)
{
}

static inline void dbg_setup(u8 addr, const struct usb_ctrlrequest *req)
{
}

static inline int dbg_create_files(struct device *dev)
{
	return 0;
+1 −32
Original line number Diff line number Diff line
@@ -601,8 +601,6 @@ __acquires(ci->lock)
{
	int retval;

	dbg_event(0xFF, "BUS RST", 0);

	spin_unlock(&ci->lock);
	retval = _gadget_stop_activity(&ci->gadget);
	if (retval)
@@ -773,7 +771,6 @@ __acquires(mEp->lock)
		if (retval < 0)
			break;
		list_del_init(&mReq->queue);
		dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
		if (mReq->req.complete != NULL) {
			spin_unlock(mEp->lock);
			if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
@@ -786,8 +783,6 @@ __acquires(mEp->lock)

	if (retval == -EBUSY)
		retval = 0;
	if (retval < 0)
		dbg_event(_usb_addr(mEp), "DONE", retval);

	return retval;
}
@@ -819,8 +814,6 @@ __acquires(ci->lock)
				if (err > 0)   /* needs status phase */
					err = isr_setup_status_phase(ci);
				if (err < 0) {
					dbg_event(_usb_addr(mEp),
						  "ERROR", err);
					spin_unlock(&ci->lock);
					if (usb_ep_set_halt(&mEp->ep))
						dev_err(ci->dev,
@@ -856,8 +849,6 @@ __acquires(ci->lock)

		ci->ep0_dir = (type & USB_DIR_IN) ? TX : RX;

		dbg_setup(_usb_addr(mEp), &req);

		switch (req.bRequest) {
		case USB_REQ_CLEAR_FEATURE:
			if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
@@ -969,8 +960,6 @@ __acquires(ci->lock)
		}

		if (err < 0) {
			dbg_event(_usb_addr(mEp), "ERROR", err);

			spin_unlock(&ci->lock);
			if (usb_ep_set_halt(&mEp->ep))
				dev_err(ci->dev, "error: ep_set_halt\n");
@@ -1012,8 +1001,6 @@ static int ep_enable(struct usb_ep *ep,

	mEp->ep.maxpacket = usb_endpoint_maxp(desc);

	dbg_event(_usb_addr(mEp), "ENABLE", 0);

	mEp->qh.ptr->cap = 0;

	if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
@@ -1060,8 +1047,6 @@ static int ep_disable(struct usb_ep *ep)

	direction = mEp->dir;
	do {
		dbg_event(_usb_addr(mEp), "DISABLE", 0);

		retval |= _ep_nuke(mEp);
		retval |= hw_ep_disable(mEp->ci, mEp->num, mEp->dir);

@@ -1101,8 +1086,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
		}
	}

	dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);

	return (mReq == NULL) ? NULL : &mReq->req;
}

@@ -1130,8 +1113,6 @@ static void ep_free_request(struct usb_ep *ep, struct usb_request *req)
		dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma);
	kfree(mReq);

	dbg_event(_usb_addr(mEp), "FREE", 0);

	spin_unlock_irqrestore(mEp->lock, flags);
}

@@ -1179,18 +1160,14 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req,
		dev_warn(mEp->ci->dev, "request length truncated\n");
	}

	dbg_queue(_usb_addr(mEp), req, retval);

	/* push request */
	mReq->req.status = -EINPROGRESS;
	mReq->req.actual = 0;

	retval = _hardware_enqueue(mEp, mReq);

	if (retval == -EALREADY) {
		dbg_event(_usb_addr(mEp), "QUEUE", retval);
	if (retval == -EALREADY)
		retval = 0;
	}
	if (!retval)
		list_add_tail(&mReq->queue, &mEp->qh.queue);

@@ -1217,8 +1194,6 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)

	spin_lock_irqsave(mEp->lock, flags);

	dbg_event(_usb_addr(mEp), "DEQUEUE", 0);

	hw_ep_flush(mEp->ci, mEp->num, mEp->dir);

	/* pop request */
@@ -1265,7 +1240,6 @@ static int ep_set_halt(struct usb_ep *ep, int value)

	direction = mEp->dir;
	do {
		dbg_event(_usb_addr(mEp), "HALT", value);
		retval |= hw_ep_set_halt(mEp->ci, mEp->num, mEp->dir, value);

		if (!value)
@@ -1294,10 +1268,7 @@ static int ep_set_wedge(struct usb_ep *ep)
		return -EINVAL;

	spin_lock_irqsave(mEp->lock, flags);

	dbg_event(_usb_addr(mEp), "WEDGE", 0);
	mEp->wedge = 1;

	spin_unlock_irqrestore(mEp->lock, flags);

	return usb_ep_set_halt(ep);
@@ -1320,7 +1291,6 @@ static void ep_fifo_flush(struct usb_ep *ep)

	spin_lock_irqsave(mEp->lock, flags);

	dbg_event(_usb_addr(mEp), "FFLUSH", 0);
	hw_ep_flush(mEp->ci, mEp->num, mEp->dir);

	spin_unlock_irqrestore(mEp->lock, flags);
@@ -1611,7 +1581,6 @@ static irqreturn_t udc_irq(struct ci13xxx *ci)
		}
	}
	intr = hw_test_and_clear_intr_active(ci);
	dbg_interrupt(intr);

	if (intr) {
		/* order defines priority - do NOT change it */