[PATCH 5/9] usb: chipidea: replace interrupt accounting with tracepoints

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The driver also has interrupt counters and another ring buffer for keeping
track of the order in which they arrive. This patch converts these counters
to trace points. Userspace tools such as perf can provide information on both
order and stats of the interrupts.

Signed-off-by: Alexander Shishkin <alexander.shishkin@xxxxxxxxxxxxxxx>
---
 drivers/usb/chipidea/debug.c    |  160 +--------------------------------------
 drivers/usb/chipidea/debug.h    |    5 --
 drivers/usb/chipidea/udc.c      |   11 ++-
 include/trace/events/chipidea.h |   18 ++++-
 4 files changed, 26 insertions(+), 168 deletions(-)

diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c
index 9e9caa8..898aca5 100644
--- a/drivers/usb/chipidea/debug.c
+++ b/drivers/usb/chipidea/debug.c
@@ -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
@@ -197,118 +157,6 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
 static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL);
 
 /**
- * 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
  *
  * Check "device.h" for details
@@ -536,12 +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_inters);
-	if (retval)
-		goto rm_driver;
 	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;
@@ -559,8 +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_driver:
 	device_remove_file(dev, &dev_attr_driver);
  rm_device:
@@ -583,7 +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_driver);
 	device_remove_file(dev, &dev_attr_device);
 	return 0;
diff --git a/drivers/usb/chipidea/debug.h b/drivers/usb/chipidea/debug.h
index 3e9019f..425f1ff 100644
--- a/drivers/usb/chipidea/debug.h
+++ b/drivers/usb/chipidea/debug.h
@@ -14,14 +14,9 @@
 #define __DRIVERS_USB_CHIPIDEA_DEBUG_H
 
 #ifdef CONFIG_USB_CHIPIDEA_DEBUG
-void dbg_interrupt(u32 intmask);
 int dbg_create_files(struct device *dev);
 int dbg_remove_files(struct device *dev);
 #else
-static inline void dbg_interrupt(u32 intmask)
-{
-}
-
 static inline int dbg_create_files(struct device *dev)
 {
 	return 0;
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 5c573f5..5d2c76b 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1626,14 +1626,16 @@ 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 */
-		if (USBi_URI & intr)
+		if (USBi_URI & intr) {
+			trace_ci_int_uri(ci);
 			isr_reset_handler(ci);
+		}
 
 		if (USBi_PCI & intr) {
+			trace_ci_int_pci(ci);
 			ci->gadget.speed = hw_port_is_high_speed(ci) ?
 				USB_SPEED_HIGH : USB_SPEED_FULL;
 			if (ci->suspended && ci->driver->resume) {
@@ -1644,10 +1646,13 @@ static irqreturn_t udc_irq(struct ci13xxx *ci)
 			}
 		}
 
-		if (USBi_UI  & intr)
+		if (USBi_UI  & intr) {
+			trace_ci_int_ui(ci);
 			isr_tr_complete_handler(ci);
+		}
 
 		if (USBi_SLI & intr) {
+			trace_ci_int_sli(ci);
 			if (ci->gadget.speed != USB_SPEED_UNKNOWN &&
 			    ci->driver->suspend) {
 				ci->suspended = 1;
diff --git a/include/trace/events/chipidea.h b/include/trace/events/chipidea.h
index 5e5c2ed..ef249da 100644
--- a/include/trace/events/chipidea.h
+++ b/include/trace/events/chipidea.h
@@ -8,7 +8,7 @@
 #include <linux/usb/gadget.h>
 #include <linux/usb/ch9.h>
 
-TRACE_EVENT(ci_bus_reset,
+DECLARE_EVENT_CLASS(ci_event,
 	TP_PROTO(struct ci13xxx *ci),
 
 	TP_ARGS(ci),
@@ -24,6 +24,22 @@ TRACE_EVENT(ci_bus_reset,
 	TP_printk("ci_hdrc.%d", __entry->id)
 );
 
+DEFINE_EVENT(ci_event, ci_bus_reset,
+	TP_PROTO(struct ci13xxx *ci),
+	TP_ARGS(ci));
+DEFINE_EVENT(ci_event, ci_int_uri,
+	TP_PROTO(struct ci13xxx *ci),
+	TP_ARGS(ci));
+DEFINE_EVENT(ci_event, ci_int_ui,
+	TP_PROTO(struct ci13xxx *ci),
+	TP_ARGS(ci));
+DEFINE_EVENT(ci_event, ci_int_pci,
+	TP_PROTO(struct ci13xxx *ci),
+	TP_ARGS(ci));
+DEFINE_EVENT(ci_event, ci_int_sli,
+	TP_PROTO(struct ci13xxx *ci),
+	TP_ARGS(ci));
+
 TRACE_EVENT(ci_ep_setup,
 	TP_PROTO(struct ci13xxx_ep *cep, struct usb_ctrlrequest *creq),
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux