1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright 2015, Heiner Kallweit <hkallweit1@gmail.com>
6 #include <net/bluetooth/bluetooth.h>
7 #include <net/bluetooth/hci_core.h>
11 DEFINE_LED_TRIGGER(bt_power_led_trigger
);
13 struct hci_basic_led_trigger
{
14 struct led_trigger led_trigger
;
18 #define to_hci_basic_led_trigger(arg) container_of(arg, \
19 struct hci_basic_led_trigger, led_trigger)
21 void hci_leds_update_powered(struct hci_dev
*hdev
, bool enabled
)
24 led_trigger_event(hdev
->power_led
,
25 enabled
? LED_FULL
: LED_OFF
);
30 read_lock(&hci_dev_list_lock
);
32 list_for_each_entry(d
, &hci_dev_list
, list
) {
33 if (test_bit(HCI_UP
, &d
->flags
))
37 read_unlock(&hci_dev_list_lock
);
40 led_trigger_event(bt_power_led_trigger
, enabled
? LED_FULL
: LED_OFF
);
43 static int power_activate(struct led_classdev
*led_cdev
)
45 struct hci_basic_led_trigger
*htrig
;
48 htrig
= to_hci_basic_led_trigger(led_cdev
->trigger
);
49 powered
= test_bit(HCI_UP
, &htrig
->hdev
->flags
);
51 led_trigger_event(led_cdev
->trigger
, powered
? LED_FULL
: LED_OFF
);
56 static struct led_trigger
*led_allocate_basic(struct hci_dev
*hdev
,
57 int (*activate
)(struct led_classdev
*led_cdev
),
60 struct hci_basic_led_trigger
*htrig
;
62 htrig
= devm_kzalloc(&hdev
->dev
, sizeof(*htrig
), GFP_KERNEL
);
67 htrig
->led_trigger
.activate
= activate
;
68 htrig
->led_trigger
.name
= devm_kasprintf(&hdev
->dev
, GFP_KERNEL
,
71 if (!htrig
->led_trigger
.name
)
74 if (devm_led_trigger_register(&hdev
->dev
, &htrig
->led_trigger
))
77 return &htrig
->led_trigger
;
80 devm_kfree(&hdev
->dev
, (void *)htrig
->led_trigger
.name
);
82 devm_kfree(&hdev
->dev
, htrig
);
86 void hci_leds_init(struct hci_dev
*hdev
)
88 /* initialize power_led */
89 hdev
->power_led
= led_allocate_basic(hdev
, power_activate
, "power");
92 void bt_leds_init(void)
94 led_trigger_register_simple("bluetooth-power", &bt_power_led_trigger
);
97 void bt_leds_cleanup(void)
99 led_trigger_unregister_simple(bt_power_led_trigger
);