예제 #1
0
파일: leds.c 프로젝트: uarka/linux-next
/*
 * 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);
}
예제 #2
0
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);
}
예제 #4
0
파일: leds.c 프로젝트: uarka/linux-next
/* 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;
}
예제 #5
0
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;
}
예제 #6
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);
}
예제 #7
0
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;
}
예제 #8
0
static void phy_led_trigger_unregister(struct phy_led_trigger *plt)
{
	led_trigger_unregister(&plt->trigger);
}
예제 #9
0
static void __exit touchwake_control_exit(void)
{
	led_trigger_unregister(&touchwake_led_trigger);
}
예제 #10
0
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");
예제 #11
0
static void __exit usbdev_trig_exit(void)
{
	led_trigger_unregister(&usbdev_led_trigger);
}
예제 #12
0
static void __exit defon_trig_exit(void)
{
	led_trigger_unregister(&defon_led_trigger);
}
예제 #13
0
static void __exit ledtrig_network_exit(void)
{
	led_trigger_unregister(&ledtrig_eth);
	led_trigger_unregister(&ledtrig_wifi);
}
예제 #14
0
static void __exit dim_trig_exit(void)
{
	led_trigger_unregister(&dim_led_trigger);
}
예제 #15
0
static void __exit netdev_trig_exit(void)
{
	led_trigger_unregister(&netdev_led_trigger);
}
예제 #16
0
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);
}
예제 #18
0
static void __exit gpio_trig_exit(void)
{
	led_trigger_unregister(&gpio_led_trigger);
}
예제 #19
0
static void __exit transient_trig_exit(void)
{
	led_trigger_unregister(&transient_trigger);
}
예제 #20
0
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);
}
예제 #22
0
void led_trigger_unregister_hwtimer(struct led_trigger *trig)
{
	led_trigger_unregister(trig);
	kfree(trig);
	return;
}
예제 #23
0
static void __exit notification_trig_exit(void)
{
	led_trigger_unregister(&notification_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);
}