0001
0002
0003
0004
0005
0006 #include <net/bluetooth/bluetooth.h>
0007 #include <net/bluetooth/hci_core.h>
0008
0009 #include "leds.h"
0010
0011 DEFINE_LED_TRIGGER(bt_power_led_trigger);
0012
0013 struct hci_basic_led_trigger {
0014 struct led_trigger led_trigger;
0015 struct hci_dev *hdev;
0016 };
0017
0018 #define to_hci_basic_led_trigger(arg) container_of(arg, \
0019 struct hci_basic_led_trigger, led_trigger)
0020
0021 void hci_leds_update_powered(struct hci_dev *hdev, bool enabled)
0022 {
0023 if (hdev->power_led)
0024 led_trigger_event(hdev->power_led,
0025 enabled ? LED_FULL : LED_OFF);
0026
0027 if (!enabled) {
0028 struct hci_dev *d;
0029
0030 read_lock(&hci_dev_list_lock);
0031
0032 list_for_each_entry(d, &hci_dev_list, list) {
0033 if (test_bit(HCI_UP, &d->flags))
0034 enabled = true;
0035 }
0036
0037 read_unlock(&hci_dev_list_lock);
0038 }
0039
0040 led_trigger_event(bt_power_led_trigger, enabled ? LED_FULL : LED_OFF);
0041 }
0042
0043 static int power_activate(struct led_classdev *led_cdev)
0044 {
0045 struct hci_basic_led_trigger *htrig;
0046 bool powered;
0047
0048 htrig = to_hci_basic_led_trigger(led_cdev->trigger);
0049 powered = test_bit(HCI_UP, &htrig->hdev->flags);
0050
0051 led_trigger_event(led_cdev->trigger, powered ? LED_FULL : LED_OFF);
0052
0053 return 0;
0054 }
0055
0056 static struct led_trigger *led_allocate_basic(struct hci_dev *hdev,
0057 int (*activate)(struct led_classdev *led_cdev),
0058 const char *name)
0059 {
0060 struct hci_basic_led_trigger *htrig;
0061
0062 htrig = devm_kzalloc(&hdev->dev, sizeof(*htrig), GFP_KERNEL);
0063 if (!htrig)
0064 return NULL;
0065
0066 htrig->hdev = hdev;
0067 htrig->led_trigger.activate = activate;
0068 htrig->led_trigger.name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
0069 "%s-%s", hdev->name,
0070 name);
0071 if (!htrig->led_trigger.name)
0072 goto err_alloc;
0073
0074 if (devm_led_trigger_register(&hdev->dev, &htrig->led_trigger))
0075 goto err_register;
0076
0077 return &htrig->led_trigger;
0078
0079 err_register:
0080 devm_kfree(&hdev->dev, (void *)htrig->led_trigger.name);
0081 err_alloc:
0082 devm_kfree(&hdev->dev, htrig);
0083 return NULL;
0084 }
0085
0086 void hci_leds_init(struct hci_dev *hdev)
0087 {
0088
0089 hdev->power_led = led_allocate_basic(hdev, power_activate, "power");
0090 }
0091
0092 void bt_leds_init(void)
0093 {
0094 led_trigger_register_simple("bluetooth-power", &bt_power_led_trigger);
0095 }
0096
0097 void bt_leds_cleanup(void)
0098 {
0099 led_trigger_unregister_simple(bt_power_led_trigger);
0100 }