/* * Disconnected input device. Clean it, and deregister now-useless VT LEDs * and triggers. */ void input_led_disconnect(struct input_dev *dev) { int i; struct led_classdev *leds = dev->leds; for (i = 0; i < LED_CNT; i++) if (leds[i].name) led_classdev_unregister(&leds[i]); input_led_delete(dev); mutex_lock(&vt_led_registered_lock); for (i = 0; i < LED_CNT; i++) { if (!vt_leds[i].name || !test_bit(i, dev->ledbit)) continue; vt_led_references[i]--; if (vt_led_references[i]) { /* Still some devices needing it */ continue; } led_classdev_unregister(&vt_leds[i]); led_trigger_unregister(&vt_led_triggers[i]); clear_bit(i, vt_led_registered); } mutex_unlock(&vt_led_registered_lock); }
void ieee80211_led_exit(struct ieee80211_local *local) { if (local->radio_led.name) led_trigger_unregister(&local->radio_led); if (local->assoc_led.name) led_trigger_unregister(&local->assoc_led); if (local->tx_led.name) led_trigger_unregister(&local->tx_led); if (local->rx_led.name) led_trigger_unregister(&local->rx_led); if (local->tpt_led_trigger) { led_trigger_unregister(&local->tpt_led); kfree(local->tpt_led_trigger); } }
static void __exit heartbeat_trig_exit(void) { unregister_reboot_notifier(&heartbeat_reboot_nb); atomic_notifier_chain_unregister(&panic_notifier_list, &heartbeat_panic_nb); led_trigger_unregister(&heartbeat_led_trigger); }
/* A new input device with potential LEDs to connect. */ int input_led_connect(struct input_dev *dev) { int i, error = 0; struct led_classdev *leds; dev->leds = leds = kcalloc(LED_CNT, sizeof(*leds), GFP_KERNEL); if (!dev->leds) return -ENOMEM; /* lazily register missing VT LEDs */ mutex_lock(&vt_led_registered_lock); for (i = 0; i < LED_CNT; i++) if (vt_leds[i].name && test_bit(i, dev->ledbit)) { if (!vt_led_references[i]) { led_trigger_register(&vt_led_triggers[i]); /* This keyboard is first to have led i, * try to register it */ if (!led_classdev_register(NULL, &vt_leds[i])) vt_led_references[i] = 1; else led_trigger_unregister(&vt_led_triggers[i]); } else vt_led_references[i]++; } mutex_unlock(&vt_led_registered_lock); /* and register this device's LEDs */ for (i = 0; i < LED_CNT; i++) if (vt_leds[i].name && test_bit(i, dev->ledbit)) { leds[i].name = kasprintf(GFP_KERNEL, "%s::%s", dev_name(&dev->dev), vt_led_names[i]); if (!leds[i].name) { error = -ENOMEM; goto err; } leds[i].max_brightness = 1; leds[i].brightness_set = perdevice_input_led_set; leds[i].default_trigger = vt_led_triggers[i].name; } /* No issue so far, we can register for real. */ for (i = 0; i < LED_CNT; i++) if (leds[i].name) { led_classdev_register(&dev->dev, &leds[i]); leds[i].dev->platform_data = dev; perdevice_input_led_set(&leds[i], vt_leds[i].brightness); } return 0; err: input_led_delete(dev); return error; }
static int rt_timer_remove(struct platform_device *pdev) { struct rt_timer *rt = platform_get_drvdata(pdev); led_trigger_unregister(&rt->led_trigger); rt_timer_disable(rt); rt_timer_free(rt); return 0; }
static void led_tg_destroy(const struct xt_tgdtor_param *par) { const struct xt_led_info *ledinfo = par->targinfo; struct xt_led_info_internal *ledinternal = ledinfo->internal_data; if (ledinfo->delay > 0) del_timer_sync(&ledinternal->timer); led_trigger_unregister(&ledinternal->netfilter_led_trigger); kfree(ledinternal); }
static int heartbeat_pm_notifier(struct notifier_block *nb, unsigned long pm_event, void *unused) { int rc; switch (pm_event) { case PM_SUSPEND_PREPARE: case PM_HIBERNATION_PREPARE: case PM_RESTORE_PREPARE: led_trigger_unregister(&heartbeat_led_trigger); break; case PM_POST_SUSPEND: case PM_POST_HIBERNATION: case PM_POST_RESTORE: rc = led_trigger_register(&heartbeat_led_trigger); if (rc) pr_err("could not re-register heartbeat trigger\n"); break; default: break; } return NOTIFY_DONE; }
static void phy_led_trigger_unregister(struct phy_led_trigger *plt) { led_trigger_unregister(&plt->trigger); }
static void __exit touchwake_control_exit(void) { led_trigger_unregister(&touchwake_led_trigger); }
static ssize_t usbdev_trig_name_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct led_classdev *led_cdev = dev_get_drvdata(dev); struct usbdev_trig_data *td = led_cdev->trigger_data; if (size < 0 || size >= DEV_BUS_ID_SIZE) return -EINVAL; write_lock(&td->lock); strcpy(td->device_name, buf); if (size > 0 && td->device_name[size - 1] == '\n') td->device_name[size - 1] = 0; if (td->device_name[0] != 0) { struct usbdev_trig_match match = { .device_name = td->device_name, }; /* check for existing device to update from */ usb_for_each_dev(&match, usbdev_trig_find_usb_dev); if (match.usb_dev) { if (td->usb_dev) usb_put_dev(td->usb_dev); td->usb_dev = match.usb_dev; td->last_urbnum = atomic_read(&match.usb_dev->urbnum); } /* updates LEDs, may start timers */ usbdev_trig_update_state(td); } write_unlock(&td->lock); return size; } static DEVICE_ATTR(device_name, 0644, usbdev_trig_name_show, usbdev_trig_name_store); static ssize_t usbdev_trig_interval_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); struct usbdev_trig_data *td = led_cdev->trigger_data; read_lock(&td->lock); sprintf(buf, "%u\n", jiffies_to_msecs(td->interval)); read_unlock(&td->lock); return strlen(buf) + 1; } static ssize_t usbdev_trig_interval_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct led_classdev *led_cdev = dev_get_drvdata(dev); struct usbdev_trig_data *td = led_cdev->trigger_data; int ret = -EINVAL; char *after; unsigned long value = simple_strtoul(buf, &after, 10); size_t count = after - buf; if (*after && isspace(*after)) count++; if (count == size && value <= 10000) { write_lock(&td->lock); td->interval = msecs_to_jiffies(value); usbdev_trig_update_state(td); /* resets timer */ write_unlock(&td->lock); ret = count; } return ret; } static DEVICE_ATTR(activity_interval, 0644, usbdev_trig_interval_show, usbdev_trig_interval_store); static int usbdev_trig_notify(struct notifier_block *nb, unsigned long evt, void *data) { struct usb_device *usb_dev; struct usbdev_trig_data *td; if (evt != USB_DEVICE_ADD && evt != USB_DEVICE_REMOVE) return NOTIFY_DONE; usb_dev = data; td = container_of(nb, struct usbdev_trig_data, notifier); write_lock(&td->lock); if (strcmp(dev_name(&usb_dev->dev), td->device_name)) goto done; if (evt == USB_DEVICE_ADD) { usb_get_dev(usb_dev); if (td->usb_dev != NULL) usb_put_dev(td->usb_dev); td->usb_dev = usb_dev; td->last_urbnum = atomic_read(&usb_dev->urbnum); } else if (evt == USB_DEVICE_REMOVE) { if (td->usb_dev != NULL) { usb_put_dev(td->usb_dev); td->usb_dev = NULL; } } usbdev_trig_update_state(td); done: write_unlock(&td->lock); return NOTIFY_DONE; } /* here's the real work! */ static void usbdev_trig_timer(unsigned long arg) { struct usbdev_trig_data *td = (struct usbdev_trig_data *)arg; int new_urbnum; write_lock(&td->lock); if (!td->usb_dev || td->interval == 0) { /* * we don't need to do timer work, just reflect device presence */ if (td->usb_dev) led_set_brightness(td->led_cdev, LED_FULL); else led_set_brightness(td->led_cdev, LED_OFF); goto no_restart; } if (td->interval) new_urbnum = atomic_read(&td->usb_dev->urbnum); else new_urbnum = 0; if (td->usb_dev) { /* * Base state is ON (device is present). If there's no device, * we don't get this far and the LED is off. * OFF -> ON always * ON -> OFF on activity */ if (td->led_cdev->brightness == LED_OFF) led_set_brightness(td->led_cdev, LED_FULL); else if (td->last_urbnum != new_urbnum) led_set_brightness(td->led_cdev, LED_OFF); } else { /* * base state is OFF * ON -> OFF always * OFF -> ON on activity */ if (td->led_cdev->brightness == LED_FULL) led_set_brightness(td->led_cdev, LED_OFF); else if (td->last_urbnum != new_urbnum) led_set_brightness(td->led_cdev, LED_FULL); } td->last_urbnum = new_urbnum; mod_timer(&td->timer, jiffies + td->interval); no_restart: write_unlock(&td->lock); } static void usbdev_trig_activate(struct led_classdev *led_cdev) { struct usbdev_trig_data *td; int rc; td = kzalloc(sizeof(struct usbdev_trig_data), GFP_KERNEL); if (!td) return; rwlock_init(&td->lock); td->notifier.notifier_call = usbdev_trig_notify; td->notifier.priority = 10; setup_timer(&td->timer, usbdev_trig_timer, (unsigned long) td); td->led_cdev = led_cdev; td->interval = msecs_to_jiffies(50); led_cdev->trigger_data = td; rc = device_create_file(led_cdev->dev, &dev_attr_device_name); if (rc) goto err_out; rc = device_create_file(led_cdev->dev, &dev_attr_activity_interval); if (rc) goto err_out_device_name; usb_register_notify(&td->notifier); return; err_out_device_name: device_remove_file(led_cdev->dev, &dev_attr_device_name); err_out: led_cdev->trigger_data = NULL; kfree(td); } static void usbdev_trig_deactivate(struct led_classdev *led_cdev) { struct usbdev_trig_data *td = led_cdev->trigger_data; if (td) { usb_unregister_notify(&td->notifier); device_remove_file(led_cdev->dev, &dev_attr_device_name); device_remove_file(led_cdev->dev, &dev_attr_activity_interval); write_lock(&td->lock); if (td->usb_dev) { usb_put_dev(td->usb_dev); td->usb_dev = NULL; } write_unlock(&td->lock); del_timer_sync(&td->timer); kfree(td); } } static struct led_trigger usbdev_led_trigger = { .name = "usbdev", .activate = usbdev_trig_activate, .deactivate = usbdev_trig_deactivate, }; static int __init usbdev_trig_init(void) { return led_trigger_register(&usbdev_led_trigger); } static void __exit usbdev_trig_exit(void) { led_trigger_unregister(&usbdev_led_trigger); } module_init(usbdev_trig_init); module_exit(usbdev_trig_exit); MODULE_AUTHOR("Gabor Juhos <*****@*****.**>"); MODULE_DESCRIPTION("USB device LED trigger"); MODULE_LICENSE("GPL v2");
static void __exit usbdev_trig_exit(void) { led_trigger_unregister(&usbdev_led_trigger); }
static void __exit defon_trig_exit(void) { led_trigger_unregister(&defon_led_trigger); }
static void __exit ledtrig_network_exit(void) { led_trigger_unregister(&ledtrig_eth); led_trigger_unregister(&ledtrig_wifi); }
static void __exit dim_trig_exit(void) { led_trigger_unregister(&dim_led_trigger); }
static void __exit netdev_trig_exit(void) { led_trigger_unregister(&netdev_led_trigger); }
static void __exit countdown_trig_exit(void) { led_trigger_unregister(&countdown_led_trigger); }
static void __exit oneshot_trig_exit(void) { led_trigger_unregister(&oneshot_led_trigger); }
static void __exit gpio_trig_exit(void) { led_trigger_unregister(&gpio_led_trigger); }
static void __exit transient_trig_exit(void) { led_trigger_unregister(&transient_trigger); }
static int heartbeat_reboot_notifier(struct notifier_block *nb, unsigned long code, void *unused) { led_trigger_unregister(&heartbeat_led_trigger); return NOTIFY_DONE; }
static void __exit heartbeat_trig_exit(void) { led_trigger_unregister(&heartbeat_led_trigger); }
void led_trigger_unregister_hwtimer(struct led_trigger *trig) { led_trigger_unregister(trig); kfree(trig); return; }
static void __exit notification_trig_exit(void) { led_trigger_unregister(¬ification_led_trigger); }
static void __exit timer_trig_exit(void) { led_trigger_unregister(&timer_led_trigger); }
static void __exit wifi_trig_exit(void) { led_trigger_unregister(&wifi_led_trigger); }