usb: Add LED triggers for USB activity
With this patch, USB activity can be signaled by blinking a LED. There are two triggers, one for activity on USB host and one for USB gadget. Both triggers should work with all host/device controllers. Tested only with musb. Performace: I measured performance overheads on ARM Cortex-A8 (TI AM335x) running on 600 MHz. Duration of usb_led_activity(): - with no LED attached to the trigger: 2 ± 1 µs - with one GPIO LED attached to the trigger: 2 ± 1 µs or 8 ± 2 µs (two peaks in histogram) Duration of functions calling usb_led_activity() (with this patch applied and no LED attached to the trigger): - __usb_hcd_giveback_urb(): 10 - 25 µs - usb_gadget_giveback_request(): 2 - 6 µs Signed-off-by: Michal Sojka <sojka@merica.cz> Acked-by: Felipe Balbi <balbi@ti.com> Tested-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>wifi-calibration
parent
aa923ef1aa
commit
0cfbd328d6
|
@ -149,4 +149,14 @@ source "drivers/usb/phy/Kconfig"
|
||||||
|
|
||||||
source "drivers/usb/gadget/Kconfig"
|
source "drivers/usb/gadget/Kconfig"
|
||||||
|
|
||||||
|
config USB_LED_TRIG
|
||||||
|
bool "USB LED Triggers"
|
||||||
|
depends on LEDS_CLASS && USB_COMMON && LEDS_TRIGGERS
|
||||||
|
help
|
||||||
|
This option adds LED triggers for USB host and/or gadget activity.
|
||||||
|
|
||||||
|
Say Y here if you are working on a system with led-class supported
|
||||||
|
LEDs and you want to use them as activity indicators for USB host or
|
||||||
|
gadget.
|
||||||
|
|
||||||
endif # USB_SUPPORT
|
endif # USB_SUPPORT
|
||||||
|
|
|
@ -4,5 +4,6 @@
|
||||||
|
|
||||||
obj-$(CONFIG_USB_COMMON) += usb-common.o
|
obj-$(CONFIG_USB_COMMON) += usb-common.o
|
||||||
usb-common-y += common.o
|
usb-common-y += common.o
|
||||||
|
usb-common-$(CONFIG_USB_LED_TRIG) += led.o
|
||||||
|
|
||||||
obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o
|
obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* LED Triggers for USB Activity
|
||||||
|
*
|
||||||
|
* Copyright 2014 Michal Sojka <sojka@merica.cz>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/leds.h>
|
||||||
|
#include <linux/usb.h>
|
||||||
|
|
||||||
|
#define BLINK_DELAY 30
|
||||||
|
|
||||||
|
static unsigned long usb_blink_delay = BLINK_DELAY;
|
||||||
|
|
||||||
|
DEFINE_LED_TRIGGER(ledtrig_usb_gadget);
|
||||||
|
DEFINE_LED_TRIGGER(ledtrig_usb_host);
|
||||||
|
|
||||||
|
void usb_led_activity(enum usb_led_event ev)
|
||||||
|
{
|
||||||
|
struct led_trigger *trig = NULL;
|
||||||
|
|
||||||
|
switch (ev) {
|
||||||
|
case USB_LED_EVENT_GADGET:
|
||||||
|
trig = ledtrig_usb_gadget;
|
||||||
|
break;
|
||||||
|
case USB_LED_EVENT_HOST:
|
||||||
|
trig = ledtrig_usb_host;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* led_trigger_blink_oneshot() handles trig == NULL gracefully */
|
||||||
|
led_trigger_blink_oneshot(trig, &usb_blink_delay, &usb_blink_delay, 0);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(usb_led_activity);
|
||||||
|
|
||||||
|
|
||||||
|
static int __init ledtrig_usb_init(void)
|
||||||
|
{
|
||||||
|
led_trigger_register_simple("usb-gadget", &ledtrig_usb_gadget);
|
||||||
|
led_trigger_register_simple("usb-host", &ledtrig_usb_host);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit ledtrig_usb_exit(void)
|
||||||
|
{
|
||||||
|
led_trigger_unregister_simple(ledtrig_usb_gadget);
|
||||||
|
led_trigger_unregister_simple(ledtrig_usb_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(ledtrig_usb_init);
|
||||||
|
module_exit(ledtrig_usb_exit);
|
|
@ -1664,6 +1664,8 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
|
||||||
usbmon_urb_complete(&hcd->self, urb, status);
|
usbmon_urb_complete(&hcd->self, urb, status);
|
||||||
usb_anchor_suspend_wakeups(anchor);
|
usb_anchor_suspend_wakeups(anchor);
|
||||||
usb_unanchor_urb(urb);
|
usb_unanchor_urb(urb);
|
||||||
|
if (likely(status == 0))
|
||||||
|
usb_led_activity(USB_LED_EVENT_HOST);
|
||||||
|
|
||||||
/* pass ownership to the completion handler */
|
/* pass ownership to the completion handler */
|
||||||
urb->status = status;
|
urb->status = status;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <linux/usb/ch9.h>
|
#include <linux/usb/ch9.h>
|
||||||
#include <linux/usb/gadget.h>
|
#include <linux/usb/gadget.h>
|
||||||
|
#include <linux/usb.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct usb_udc - describes one usb device controller
|
* struct usb_udc - describes one usb device controller
|
||||||
|
@ -116,6 +117,9 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request);
|
||||||
void usb_gadget_giveback_request(struct usb_ep *ep,
|
void usb_gadget_giveback_request(struct usb_ep *ep,
|
||||||
struct usb_request *req)
|
struct usb_request *req)
|
||||||
{
|
{
|
||||||
|
if (likely(req->status == 0))
|
||||||
|
usb_led_activity(USB_LED_EVENT_GADGET);
|
||||||
|
|
||||||
req->complete(ep, req);
|
req->complete(ep, req);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(usb_gadget_giveback_request);
|
EXPORT_SYMBOL_GPL(usb_gadget_giveback_request);
|
||||||
|
|
|
@ -1862,6 +1862,18 @@ extern void usb_unregister_notify(struct notifier_block *nb);
|
||||||
/* debugfs stuff */
|
/* debugfs stuff */
|
||||||
extern struct dentry *usb_debug_root;
|
extern struct dentry *usb_debug_root;
|
||||||
|
|
||||||
|
/* LED triggers */
|
||||||
|
enum usb_led_event {
|
||||||
|
USB_LED_EVENT_HOST = 0,
|
||||||
|
USB_LED_EVENT_GADGET = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_USB_LED_TRIG
|
||||||
|
extern void usb_led_activity(enum usb_led_event ev);
|
||||||
|
#else
|
||||||
|
static inline void usb_led_activity(enum usb_led_event ev) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue