led.c revision 996a953de02ffb852c9ac736f4e892008ed68884
1/*
2 * Copyright 2012, Fabio Baltieri <fabio.baltieri@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/device.h>
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/netdevice.h>
14#include <linux/can/dev.h>
15
16#include <linux/can/led.h>
17
18static unsigned long led_delay = 50;
19module_param(led_delay, ulong, 0644);
20MODULE_PARM_DESC(led_delay,
21		"blink delay time for activity leds (msecs, default: 50).");
22
23/* Trigger a LED event in response to a CAN device event */
24void can_led_event(struct net_device *netdev, enum can_led_event event)
25{
26	struct can_priv *priv = netdev_priv(netdev);
27
28	switch (event) {
29	case CAN_LED_EVENT_OPEN:
30		led_trigger_event(priv->tx_led_trig, LED_FULL);
31		led_trigger_event(priv->rx_led_trig, LED_FULL);
32		break;
33	case CAN_LED_EVENT_STOP:
34		led_trigger_event(priv->tx_led_trig, LED_OFF);
35		led_trigger_event(priv->rx_led_trig, LED_OFF);
36		break;
37	case CAN_LED_EVENT_TX:
38		if (led_delay)
39			led_trigger_blink_oneshot(priv->tx_led_trig,
40						  &led_delay, &led_delay, 1);
41		break;
42	case CAN_LED_EVENT_RX:
43		if (led_delay)
44			led_trigger_blink_oneshot(priv->rx_led_trig,
45						  &led_delay, &led_delay, 1);
46		break;
47	}
48}
49EXPORT_SYMBOL_GPL(can_led_event);
50
51static void can_led_release(struct device *gendev, void *res)
52{
53	struct can_priv *priv = netdev_priv(to_net_dev(gendev));
54
55	led_trigger_unregister_simple(priv->tx_led_trig);
56	led_trigger_unregister_simple(priv->rx_led_trig);
57}
58
59/* Register CAN LED triggers for a CAN device
60 *
61 * This is normally called from a driver's probe function
62 */
63void devm_can_led_init(struct net_device *netdev)
64{
65	struct can_priv *priv = netdev_priv(netdev);
66	void *res;
67
68	res = devres_alloc(can_led_release, 0, GFP_KERNEL);
69	if (!res) {
70		netdev_err(netdev, "cannot register LED triggers\n");
71		return;
72	}
73
74	snprintf(priv->tx_led_trig_name, sizeof(priv->tx_led_trig_name),
75		 "%s-tx", netdev->name);
76	snprintf(priv->rx_led_trig_name, sizeof(priv->rx_led_trig_name),
77		 "%s-rx", netdev->name);
78
79	led_trigger_register_simple(priv->tx_led_trig_name,
80				    &priv->tx_led_trig);
81	led_trigger_register_simple(priv->rx_led_trig_name,
82				    &priv->rx_led_trig);
83
84	devres_add(&netdev->dev, res);
85}
86EXPORT_SYMBOL_GPL(devm_can_led_init);
87