Commit 5ef1bd1e authored by Dmitry Torokhov's avatar Dmitry Torokhov

[PATCH] serio: reconnect facility

Input: serio_reconnect added. Similar to serio_rescan but gives driver
       a chance to re-initialize keeping the same input device.
parent 7822f653
......@@ -57,6 +57,7 @@ EXPORT_SYMBOL(serio_unregister_device);
EXPORT_SYMBOL(serio_open);
EXPORT_SYMBOL(serio_close);
EXPORT_SYMBOL(serio_rescan);
EXPORT_SYMBOL(serio_reconnect);
struct serio_event {
int type;
......@@ -83,6 +84,7 @@ static void serio_find_dev(struct serio *serio)
}
#define SERIO_RESCAN 1
#define SERIO_RECONNECT 2
static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
static DECLARE_COMPLETION(serio_exited);
......@@ -109,6 +111,12 @@ void serio_handle_events(void)
goto event_done;
switch (event->type) {
case SERIO_RECONNECT :
if (event->serio->dev && event->serio->dev->reconnect)
if (event->serio->dev->reconnect(event->serio) == 0)
break;
/* reconnect failed - fall through to rescan */
case SERIO_RESCAN :
if (event->serio->dev && event->serio->dev->disconnect)
event->serio->dev->disconnect(event->serio);
......@@ -143,18 +151,27 @@ static int serio_thread(void *nothing)
complete_and_exit(&serio_exited, 0);
}
void serio_rescan(struct serio *serio)
static void serio_queue_event(struct serio *serio, int event_type)
{
struct serio_event *event;
if (!(event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC)))
return;
if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
event->type = event_type;
event->serio = serio;
event->type = SERIO_RESCAN;
event->serio = serio;
list_add_tail(&event->node, &serio_event_list);
wake_up(&serio_wait);
}
}
list_add_tail(&event->node, &serio_event_list);
wake_up(&serio_wait);
void serio_rescan(struct serio *serio)
{
serio_queue_event(serio, SERIO_RESCAN);
}
void serio_reconnect(struct serio *serio)
{
serio_queue_event(serio, SERIO_RECONNECT);
}
irqreturn_t serio_interrupt(struct serio *serio,
......
......@@ -49,6 +49,7 @@ struct serio_dev {
irqreturn_t (*interrupt)(struct serio *, unsigned char,
unsigned int, struct pt_regs *);
void (*connect)(struct serio *, struct serio_dev *dev);
int (*reconnect)(struct serio *);
void (*disconnect)(struct serio *);
void (*cleanup)(struct serio *);
......@@ -58,6 +59,7 @@ struct serio_dev {
int serio_open(struct serio *serio, struct serio_dev *dev);
void serio_close(struct serio *serio);
void serio_rescan(struct serio *serio);
void serio_reconnect(struct serio *serio);
irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs);
void serio_register_port(struct serio *serio);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment