]> err.no Git - linux-2.6/blobdiff - drivers/input/gameport/gameport.c
Input: make serio and gameport more swsusp friendly
[linux-2.6] / drivers / input / gameport / gameport.c
index d7dfa6f53cf6676e3ac06c42fce8476767a02427..caac6d63d46f4a7da7ffc70293aad635d7c6bb37 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/sched.h>       /* HZ */
 
 /*#include <asm/io.h>*/
 
@@ -60,12 +61,13 @@ static void gameport_disconnect_port(struct gameport *gameport);
 
 #if defined(__i386__)
 
+#include <asm/i8253.h>
+
 #define DELTA(x,y)      ((y)-(x)+((y)<(x)?1193182/HZ:0))
 #define GET_TIME(x)     do { x = get_time_pit(); } while (0)
 
 static unsigned int get_time_pit(void)
 {
-       extern spinlock_t i8253_lock;
        unsigned long flags;
        unsigned int count;
 
@@ -133,7 +135,7 @@ static int gameport_measure_speed(struct gameport *gameport)
        }
 
        gameport_close(gameport);
-       return (cpu_data[_smp_processor_id()].loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
+       return (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
 
 #else
 
@@ -337,14 +339,20 @@ static struct gameport_event *gameport_get_event(void)
        return event;
 }
 
-static void gameport_handle_events(void)
+static void gameport_handle_event(void)
 {
        struct gameport_event *event;
        struct gameport_driver *gameport_drv;
 
        down(&gameport_sem);
 
-       while ((event = gameport_get_event())) {
+       /*
+        * Note that we handle only one event here to give swsusp
+        * a chance to freeze kgameportd thread. Gameport events
+        * should be pretty rare so we are not concerned about
+        * taking performance hit.
+        */
+       if ((event = gameport_get_event())) {
 
                switch (event->type) {
                        case GAMEPORT_REGISTER_PORT:
@@ -431,10 +439,10 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent)
 static int gameport_thread(void *nothing)
 {
        do {
-               gameport_handle_events();
+               gameport_handle_event();
                wait_event_interruptible(gameport_wait,
                        kthread_should_stop() || !list_empty(&gameport_event_list));
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
        } while (!kthread_should_stop());
 
        printk(KERN_DEBUG "gameport: kgameportd exiting\n");
@@ -446,13 +454,13 @@ static int gameport_thread(void *nothing)
  * Gameport port operations
  */
 
-static ssize_t gameport_show_description(struct device *dev, char *buf)
+static ssize_t gameport_show_description(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct gameport *gameport = to_gameport_port(dev);
        return sprintf(buf, "%s\n", gameport->name);
 }
 
-static ssize_t gameport_rebind_driver(struct device *dev, const char *buf, size_t count)
+static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct gameport *gameport = to_gameport_port(dev);
        struct device_driver *drv;