diff options
| author | Shaohua Li <shaohua.li@intel.com> | 2008-07-03 10:45:38 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2008-07-23 14:02:04 -0400 |
| commit | 6aabcdffd1a5f8f5b906696e58069c4f8fced542 (patch) | |
| tree | 43dfbbfc928d37fe20433f34a9e583d164ee1f80 /drivers/input | |
| parent | a822bea7962b500b0bcab41bf3500f7c40ae56b5 (diff) | |
Input: serio - offload resume to kseriod
When resuming AUX ports psmouse driver calls psmouse_extensions()
to determine if the attached mouse is still the same, which may take
a while to complete for generic mice. Offload the resume process to
kseriod so the rest of the system may continue resuming without
waiting for the mouse.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
| -rw-r--r-- | drivers/input/serio/serio.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 78f2abb5c11b..2f12d60eee3b 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
| @@ -63,8 +63,9 @@ static LIST_HEAD(serio_list); | |||
| 63 | static struct bus_type serio_bus; | 63 | static struct bus_type serio_bus; |
| 64 | 64 | ||
| 65 | static void serio_add_port(struct serio *serio); | 65 | static void serio_add_port(struct serio *serio); |
| 66 | static void serio_reconnect_port(struct serio *serio); | 66 | static int serio_reconnect_port(struct serio *serio); |
| 67 | static void serio_disconnect_port(struct serio *serio); | 67 | static void serio_disconnect_port(struct serio *serio); |
| 68 | static void serio_reconnect_chain(struct serio *serio); | ||
| 68 | static void serio_attach_driver(struct serio_driver *drv); | 69 | static void serio_attach_driver(struct serio_driver *drv); |
| 69 | 70 | ||
| 70 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) | 71 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) |
| @@ -161,6 +162,7 @@ static void serio_find_driver(struct serio *serio) | |||
| 161 | enum serio_event_type { | 162 | enum serio_event_type { |
| 162 | SERIO_RESCAN_PORT, | 163 | SERIO_RESCAN_PORT, |
| 163 | SERIO_RECONNECT_PORT, | 164 | SERIO_RECONNECT_PORT, |
| 165 | SERIO_RECONNECT_CHAIN, | ||
| 164 | SERIO_REGISTER_PORT, | 166 | SERIO_REGISTER_PORT, |
| 165 | SERIO_ATTACH_DRIVER, | 167 | SERIO_ATTACH_DRIVER, |
| 166 | }; | 168 | }; |
| @@ -315,6 +317,10 @@ static void serio_handle_event(void) | |||
| 315 | serio_find_driver(event->object); | 317 | serio_find_driver(event->object); |
| 316 | break; | 318 | break; |
| 317 | 319 | ||
| 320 | case SERIO_RECONNECT_CHAIN: | ||
| 321 | serio_reconnect_chain(event->object); | ||
| 322 | break; | ||
| 323 | |||
| 318 | case SERIO_ATTACH_DRIVER: | 324 | case SERIO_ATTACH_DRIVER: |
| 319 | serio_attach_driver(event->object); | 325 | serio_attach_driver(event->object); |
| 320 | break; | 326 | break; |
| @@ -470,7 +476,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * | |||
| 470 | if (!strncmp(buf, "none", count)) { | 476 | if (!strncmp(buf, "none", count)) { |
| 471 | serio_disconnect_port(serio); | 477 | serio_disconnect_port(serio); |
| 472 | } else if (!strncmp(buf, "reconnect", count)) { | 478 | } else if (!strncmp(buf, "reconnect", count)) { |
| 473 | serio_reconnect_port(serio); | 479 | serio_reconnect_chain(serio); |
| 474 | } else if (!strncmp(buf, "rescan", count)) { | 480 | } else if (!strncmp(buf, "rescan", count)) { |
| 475 | serio_disconnect_port(serio); | 481 | serio_disconnect_port(serio); |
| 476 | serio_find_driver(serio); | 482 | serio_find_driver(serio); |
| @@ -620,14 +626,30 @@ static void serio_destroy_port(struct serio *serio) | |||
| 620 | } | 626 | } |
| 621 | 627 | ||
| 622 | /* | 628 | /* |
| 629 | * Reconnect serio port (re-initialize attached device). | ||
| 630 | * If reconnect fails (old device is no longer attached or | ||
| 631 | * there was no device to begin with) we do full rescan in | ||
| 632 | * hope of finding a driver for the port. | ||
| 633 | */ | ||
| 634 | static int serio_reconnect_port(struct serio *serio) | ||
| 635 | { | ||
| 636 | int error = serio_reconnect_driver(serio); | ||
| 637 | |||
| 638 | if (error) { | ||
| 639 | serio_disconnect_port(serio); | ||
| 640 | serio_find_driver(serio); | ||
| 641 | } | ||
| 642 | |||
| 643 | return error; | ||
| 644 | } | ||
| 645 | |||
| 646 | /* | ||
| 623 | * Reconnect serio port and all its children (re-initialize attached devices) | 647 | * Reconnect serio port and all its children (re-initialize attached devices) |
| 624 | */ | 648 | */ |
| 625 | static void serio_reconnect_port(struct serio *serio) | 649 | static void serio_reconnect_chain(struct serio *serio) |
| 626 | { | 650 | { |
| 627 | do { | 651 | do { |
| 628 | if (serio_reconnect_driver(serio)) { | 652 | if (serio_reconnect_port(serio)) { |
| 629 | serio_disconnect_port(serio); | ||
| 630 | serio_find_driver(serio); | ||
| 631 | /* Ok, old children are now gone, we are done */ | 653 | /* Ok, old children are now gone, we are done */ |
| 632 | break; | 654 | break; |
| 633 | } | 655 | } |
| @@ -673,7 +695,7 @@ void serio_rescan(struct serio *serio) | |||
| 673 | 695 | ||
| 674 | void serio_reconnect(struct serio *serio) | 696 | void serio_reconnect(struct serio *serio) |
| 675 | { | 697 | { |
| 676 | serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); | 698 | serio_queue_event(serio, NULL, SERIO_RECONNECT_CHAIN); |
| 677 | } | 699 | } |
| 678 | 700 | ||
| 679 | /* | 701 | /* |
| @@ -927,19 +949,16 @@ static int serio_suspend(struct device *dev, pm_message_t state) | |||
| 927 | 949 | ||
| 928 | static int serio_resume(struct device *dev) | 950 | static int serio_resume(struct device *dev) |
| 929 | { | 951 | { |
| 930 | struct serio *serio = to_serio_port(dev); | 952 | /* |
| 931 | 953 | * Driver reconnect can take a while, so better let kseriod | |
| 932 | if (dev->power.power_state.event != PM_EVENT_ON && | 954 | * deal with it. |
| 933 | serio_reconnect_driver(serio)) { | 955 | */ |
| 934 | /* | 956 | if (dev->power.power_state.event != PM_EVENT_ON) { |
| 935 | * Driver re-probing can take a while, so better let kseriod | 957 | dev->power.power_state = PMSG_ON; |
| 936 | * deal with it. | 958 | serio_queue_event(to_serio_port(dev), NULL, |
| 937 | */ | 959 | SERIO_RECONNECT_PORT); |
| 938 | serio_rescan(serio); | ||
| 939 | } | 960 | } |
| 940 | 961 | ||
| 941 | dev->power.power_state = PMSG_ON; | ||
| 942 | |||
| 943 | return 0; | 962 | return 0; |
| 944 | } | 963 | } |
| 945 | #endif /* CONFIG_PM */ | 964 | #endif /* CONFIG_PM */ |
