Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 33179
b: refs/heads/master
c: c7e8dc6
h: refs/heads/master
i:
  33177: 7f9c76b
  33175: e9417af
v: v3
  • Loading branch information
Dmitry Torokhov committed Jul 6, 2006
1 parent 601ebf8 commit f3793df
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 22 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e9c8862f19958846dd0c7b39d0f6216aad6c7bee
refs/heads/master: c7e8dc6ee6d59bf72f5478fa6355a27750e6c7d2
39 changes: 20 additions & 19 deletions trunk/drivers/char/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,7 @@ static inline unsigned char getleds(void)
* interrupt routines for this thing allows us to easily mask
* this when we don't want any of the above to happen.
* This allows for easy and efficient race-condition prevention
* for kbd_refresh_leds => input_event(dev, EV_LED, ...) => ...
* for kbd_start => input_event(dev, EV_LED, ...) => ...
*/

static void kbd_bh(unsigned long dummy)
Expand All @@ -1011,23 +1011,6 @@ static void kbd_bh(unsigned long dummy)

DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);

/*
* This allows a newly plugged keyboard to pick the LED state.
*/
static void kbd_refresh_leds(struct input_handle *handle)
{
unsigned char leds = ledstate;

tasklet_disable(&keyboard_tasklet);
if (leds != 0xff) {
input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02));
input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04));
input_sync(handle->dev);
}
tasklet_enable(&keyboard_tasklet);
}

#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
Expand Down Expand Up @@ -1307,7 +1290,6 @@ static struct input_handle *kbd_connect(struct input_handler *handler,
handle->name = "kbd";

input_open_device(handle);
kbd_refresh_leds(handle);

return handle;
}
Expand All @@ -1318,6 +1300,24 @@ static void kbd_disconnect(struct input_handle *handle)
kfree(handle);
}

/*
* Start keyboard handler on the new keyboard by refreshing LED state to
* match the rest of the system.
*/
static void kbd_start(struct input_handle *handle)
{
unsigned char leds = ledstate;

tasklet_disable(&keyboard_tasklet);
if (leds != 0xff) {
input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02));
input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04));
input_sync(handle->dev);
}
tasklet_enable(&keyboard_tasklet);
}

static struct input_device_id kbd_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
Expand All @@ -1338,6 +1338,7 @@ static struct input_handler kbd_handler = {
.event = kbd_event,
.connect = kbd_connect,
.disconnect = kbd_disconnect,
.start = kbd_start,
.name = "kbd",
.id_table = kbd_ids,
};
Expand Down
12 changes: 10 additions & 2 deletions trunk/drivers/input/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,13 @@ EXPORT_SYMBOL(input_grab_device);

void input_release_device(struct input_handle *handle)
{
if (handle->dev->grab == handle)
if (handle->dev->grab == handle) {
handle->dev->grab = NULL;

list_for_each_entry(handle, &handle->dev->h_list, d_node)
if (handle->handler->start)
handle->handler->start(handle);
}
}
EXPORT_SYMBOL(input_release_device);

Expand Down Expand Up @@ -954,8 +959,11 @@ int input_register_device(struct input_dev *dev)
list_for_each_entry(handler, &input_handler_list, node)
if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
if ((id = input_match_device(handler->id_table, dev)))
if ((handle = handler->connect(handler, dev, id)))
if ((handle = handler->connect(handler, dev, id))) {
input_link_handle(handle);
if (handler->start)
handler->start(handle);
}

input_wakeup_procfs_readers();

Expand Down
21 changes: 21 additions & 0 deletions trunk/include/linux/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -960,13 +960,34 @@ struct input_dev {

struct input_handle;

/**
* struct input_handler - implements one of interfaces for input devices
* @private: driver-specific data
* @event: event handler
* @connect: called when attaching a handler to an input device
* @disconnect: disconnects a handler from input device
* @start: starts handler for given handle. This function is called by
* input core right after connect() method and also when a process
* that "grabbed" a device releases it
* @fops: file operations this driver implements
* @minor: beginning of range of 32 minors for devices this driver
* can provide
* @name: name of the handler, to be shown in /proc/bus/input/handlers
* @id_table: pointer to a table of input_device_ids this driver can
* handle
* @blacklist: prointer to a table of input_device_ids this driver should
* ignore even if they match @id_table
* @h_list: list of input handles associated with the handler
* @node: for placing the driver onto input_handler_list
*/
struct input_handler {

void *private;

void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id);
void (*disconnect)(struct input_handle *handle);
void (*start)(struct input_handle *handle);

const struct file_operations *fops;
int minor;
Expand Down

0 comments on commit f3793df

Please sign in to comment.