mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-02 00:24:12 +08:00
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>
This commit is contained in:
parent
aa923ef1aa
commit
0cfbd328d6
@ -149,4 +149,14 @@ source "drivers/usb/phy/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
|
||||
|
@ -4,5 +4,6 @@
|
||||
|
||||
obj-$(CONFIG_USB_COMMON) += usb-common.o
|
||||
usb-common-y += common.o
|
||||
usb-common-$(CONFIG_USB_LED_TRIG) += led.o
|
||||
|
||||
obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o
|
||||
|
57
drivers/usb/common/led.c
Normal file
57
drivers/usb/common/led.c
Normal file
@ -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);
|
||||
usb_anchor_suspend_wakeups(anchor);
|
||||
usb_unanchor_urb(urb);
|
||||
if (likely(status == 0))
|
||||
usb_led_activity(USB_LED_EVENT_HOST);
|
||||
|
||||
/* pass ownership to the completion handler */
|
||||
urb->status = status;
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
/**
|
||||
* 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,
|
||||
struct usb_request *req)
|
||||
{
|
||||
if (likely(req->status == 0))
|
||||
usb_led_activity(USB_LED_EVENT_GADGET);
|
||||
|
||||
req->complete(ep, req);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_gadget_giveback_request);
|
||||
|
@ -1862,6 +1862,18 @@ extern void usb_unregister_notify(struct notifier_block *nb);
|
||||
/* debugfs stuff */
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user