Re: blink driver power saving

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 7/2/07, Andi Kleen <[email protected]> wrote:

> > Perhaps one of you geniuses who all hate it can find a better way to
> > solve the "video output dead after kexec; but need visual feedback to the user
> > while crash dumping" problem. I'm waiting for your patches.
> >
>
> I don't don't like it ;) Unfortunately too many people end up enabling

Yes that's pretty weird. I admit I hadn't expected
that problem. blink is equivalent to "annoy me" and it
is a mystery why so many people should willingly ask their computer to
annoy them.

Or perhaps they update their configs with yes | make oldconfig?

User psychology can be mysterious.

I wonder if the kernel offered a CONFIG_FORMAT_FILESYSTEMS_AT_BOOT
how many people would enable that @) Might be an interesting experiment
for next April.


Heh ;) That could be interesting.

> it and having issues with their keyboards.

Forcing a suitable slow rate should fix that shouldn't it? We need
that anyways to stop the "setleds DOS".


I already have a patch that throttles AT keyboard when switching LED
state. However there is another problem - i8042's interrupt hanler is
racing with panic_blink polling the keyboar controller and they both
don;t quite like that.

> Can we have it depend on
> DEBUG_KERNEL?

Yes that would be probably a good idea; even though it is technically
not correct: the debug kernel doesn't try to debug itself. But anyways,
it's probably the best place.

> And probably KEXEC as well?

The kcrash kernel doesn't necessarily need to have kexec enabled by
itself.


OK.

> Another option would be for it not use panic_blink. Do your kexec
> kernels have atkbd support enabled? You could write an new "blink"
> input handler that would latch to keyboards supporting leds and blink
> by sending EV_LED events.

Yes that would be probably a better implementation. Also hook something
for USB keyboards. iirc Bernhard Walle (cc'ed) was looking at that.


I was thinking about something like the atached (untested and sorry
for using attachment). It shoudl blink just one led (numLock) on any
keyboard that has such LED (and allows to control it).

--
Dmitry
/*
 * Debug driver that continuosly blink LEDs on keyboards
 *
 * Copyright (c) 2007 Dmitry Torokhov
 */

/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/init.h>

MODULE_AUTHOR("Dmitry Torokhov <[email protected]>");
MODULE_DESCRIPTION("Blink driver");
MODULE_LICENSE("GPL");

struct blinker {
	struct delayed_work work;
	struct input_handle handle;
	int state;
};

static void blink_task_handler(struct work_struct *work)
{
	struct blinker *blinker = container_of(work, struct blinker, work.work);

	blinker->state = !blinker->state;
	input_inject_event(&blinker->handle, EV_LED, LED_NUML, blinker->state);
	schedule_delayed_work(&blinker->work, msecs_to_jiffies(250));
}

static void blink_event(struct input_handle *handle, unsigned int type,
		        unsigned int code, int down)
{
	/*
	 * This is a very rare handler that does not process any input
	 * events; just injects them.
	 */
}

static int blink_connect(struct input_handler *handler, struct input_dev *dev,
			  const struct input_device_id *id)
{
	struct blinker *blinker;
	struct input_handle *handle;
	int error;

	blinker = kzalloc(sizeof(struct blinker), GFP_KERNEL);
	if (!blinker)
		return -ENOMEM;

	INIT_DELAYED_WORK(&blinker->work, blink_task_handler);

	handle = &blinker->handle;
	handle->dev = dev;
	handle->handler = handler;
	handle->name = "blink";
	handle->private = blinker;

	error = input_register_handle(handle);
	if (error)
		goto err_free_handle;

	error = input_open_device(handle);
	if (error)
		goto err_unregister_handle;

	schedule_delayed_work(&blinker->work, 0);

	return 0;

 err_unregister_handle:
	input_unregister_handle(handle);
 err_free_handle:
	kfree(handle);
	return error;
}

static void blink_disconnect(struct input_handle *handle)
{
	struct blinker *blinker = handle->private;

	cancel_rearming_delayed_work(&blinker->work);
	input_close_device(handle);
	input_unregister_handle(handle);
	kfree(blinker);
}

static const struct input_device_id blink_ids[] = {
	{
		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_LEDBIT,
		.evbit = { BIT(EV_LED) },
		.keybit = { [LONG(LED_NUML)] = BIT(LED_NUML) },
	},
	{ }
};

static struct input_handler blink_handler = {
	.event		= blink_event;
	.connect	= blink_connect,
	.disconnect	= blink_disconnect,
	.name		= "blink",
	.id_table	= blink_ids,
};

static int __init blink_handler_init(void)
{
	return input_register_handler(&blink_handler);
}

static void __exit blink_handler_exit(void)
{
	input_unregister_handler(&blink_handler);
	flush_scheduled_work();
}

module_init(blink_handler_init);
module_exit(blink_handler_exit);

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux