diff -u b/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- b/drivers/char/keyboard.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/char/keyboard.c	2005-02-22 18:34:50 -08:00
@@ -929,7 +929,7 @@
 #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
     defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) ||\
     defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
-    (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC))
+    (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_RPC))
 
 #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
 			((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
diff -u b/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
--- b/drivers/input/gameport/gameport.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/gameport/gameport.c	2005-02-22 18:34:49 -08:00
@@ -39,8 +39,6 @@
 EXPORT_SYMBOL(gameport_cooked_read);
 EXPORT_SYMBOL(gameport_set_name);
 EXPORT_SYMBOL(gameport_set_phys);
-EXPORT_SYMBOL(gameport_start_polling);
-EXPORT_SYMBOL(gameport_stop_polling);
 
 /*
  * gameport_sem protects entire gameport subsystem and is taken
@@ -124,37 +122,6 @@
 #endif
 }
 
-void gameport_start_polling(struct gameport *gameport)
-{
-	spin_lock(&gameport->timer_lock);
-
-	if (!gameport->poll_cnt++) {
-		BUG_ON(!gameport->poll_handler);
-		BUG_ON(!gameport->poll_interval);
-		mod_timer(&gameport->poll_timer, jiffies + msecs_to_jiffies(gameport->poll_interval));
-	}
-
-	spin_unlock(&gameport->timer_lock);
-}
-
-void gameport_stop_polling(struct gameport *gameport)
-{
-	spin_lock(&gameport->timer_lock);
-
-	if (!--gameport->poll_cnt)
-		del_timer(&gameport->poll_timer);
-
-	spin_unlock(&gameport->timer_lock);
-}
-
-static void gameport_run_poll_handler(unsigned long d)
-{
-	struct gameport *gameport = (struct gameport *)d;
-
-	gameport->poll_handler(gameport);
-	if (gameport->poll_cnt)
-		mod_timer(&gameport->poll_timer, jiffies + msecs_to_jiffies(gameport->poll_interval));
-}
 
 /*
  * Basic gameport -> driver core mappings
@@ -498,14 +465,10 @@
 	device_initialize(&gameport->dev);
 	snprintf(gameport->dev.bus_id, sizeof(gameport->dev.bus_id),
 		 "gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1);
+	gameport->dev.bus = &gameport_bus;
 	gameport->dev.release = gameport_release_port;
 	if (gameport->parent)
 		gameport->dev.parent = &gameport->parent->dev;
-
-	spin_lock_init(&gameport->timer_lock);
-	init_timer(&gameport->poll_timer);
-	gameport->poll_timer.function = gameport_run_poll_handler;
-	gameport->poll_timer.data = (unsigned long)gameport;
 }
 
 /*
@@ -734,9 +697,6 @@
 
 void gameport_close(struct gameport *gameport)
 {
-	del_timer_sync(&gameport->poll_timer);
-	gameport->poll_handler = NULL;
-	gameport->poll_interval = 0;
 	gameport_set_drv(gameport, NULL);
 	if (gameport->close)
 		gameport->close(gameport);
diff -u b/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
--- b/drivers/input/joystick/a3d.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/joystick/a3d.c	2005-02-22 18:34:49 -08:00
@@ -45,6 +45,7 @@
 #define A3D_MAX_STROBE		60	/* 40 us */
 #define A3D_DELAY_READ		3	/* 3 ms */
 #define A3D_MAX_LENGTH		40	/* 40*3 bits */
+#define A3D_REFRESH_TIME	HZ/50	/* 20 ms */
 
 #define A3D_MODE_A3D		1	/* Assassin 3D */
 #define A3D_MODE_PAN		2	/* Panther */
@@ -58,10 +59,12 @@
 	struct gameport *gameport;
 	struct gameport *adc;
 	struct input_dev dev;
+	struct timer_list timer;
 	int axes[4];
 	int buttons;
 	int mode;
 	int length;
+	int used;
 	int reads;
 	int bads;
 	char phys[32];
@@ -175,20 +178,19 @@
 
 
 /*
- * a3d_poll() reads and analyzes A3D joystick data.
+ * a3d_timer() reads and analyzes A3D joystick data.
  */
 
-static void a3d_poll(struct gameport *gameport)
+static void a3d_timer(unsigned long private)
 {
-	struct a3d *a3d = gameport_get_drvdata(gameport);
+	struct a3d *a3d = (void *) private;
 	unsigned char data[A3D_MAX_LENGTH];
 
 	a3d->reads++;
-	if (a3d_read_packet(a3d->gameport, a3d->length, data) != a3d->length ||
-	    data[0] != a3d->mode || a3d_csum(data, a3d->length))
-	 	a3d->bads++;
-	else
-		a3d_read(a3d, data);
+	if (a3d_read_packet(a3d->gameport, a3d->length, data) != a3d->length
+		|| data[0] != a3d->mode || a3d_csum(data, a3d->length))
+	 	a3d->bads++; else a3d_read(a3d, data);
+	mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
 }
 
 /*
@@ -216,11 +218,10 @@
 static int a3d_adc_open(struct gameport *gameport, int mode)
 {
 	struct a3d *a3d = gameport->port_data;
-
 	if (mode != GAMEPORT_MODE_COOKED)
 		return -1;
-
-	gameport_start_polling(a3d->gameport);
+	if (!a3d->used++)
+		mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
 	return 0;
 }
 
@@ -232,7 +233,8 @@
 {
 	struct a3d *a3d = gameport->port_data;
 
-	gameport_stop_polling(a3d->gameport);
+	if (!--a3d->used)
+		del_timer(&a3d->timer);
 }
 
 /*
@@ -243,7 +245,8 @@
 {
 	struct a3d *a3d = dev->private;
 
-	gameport_start_polling(a3d->gameport);
+	if (!a3d->used++)
+		mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
 	return 0;
 }
 
@@ -255,7 +258,8 @@
 {
 	struct a3d *a3d = dev->private;
 
-	gameport_stop_polling(a3d->gameport);
+	if (!--a3d->used)
+		del_timer(&a3d->timer);
 }
 
 /*
@@ -274,6 +278,9 @@
 		return -ENOMEM;
 
 	a3d->gameport = gameport;
+	init_timer(&a3d->timer);
+	a3d->timer.data = (long) a3d;
+	a3d->timer.function = a3d_timer;
 
 	gameport_set_drvdata(gameport, a3d);
 
@@ -297,9 +304,6 @@
 		goto fail2;
 	}
 
-	gameport_set_poll_handler(gameport, a3d_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	sprintf(a3d->phys, "%s/input0", gameport->phys);
 
 	if (a3d->mode == A3D_MODE_PXL) {
diff -u b/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
--- b/drivers/input/joystick/adi.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/joystick/adi.c	2005-02-22 18:34:49 -08:00
@@ -49,6 +49,7 @@
 
 #define ADI_MAX_START		200	/* Trigger to packet timeout [200us] */
 #define ADI_MAX_STROBE		40	/* Single bit timeout [40us] */
+#define ADI_REFRESH_TIME	HZ/50	/* How often to poll the joystick [20 ms] */
 #define ADI_INIT_DELAY		10	/* Delay after init packet [10ms] */
 #define ADI_DATA_DELAY		4	/* Delay after data packet [4ms] */
 
@@ -128,9 +129,11 @@
 
 struct adi_port {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct adi adi[2];
 	int bad;
 	int reads;
+	int used;
 };
 
 /*
@@ -274,15 +277,15 @@
 }
 
 /*
- * adi_poll() repeatedly polls the Logitech joysticks.
+ * adi_timer() repeatedly polls the Logitech joysticks.
  */
 
-static void adi_poll(struct gameport *gameport)
+static void adi_timer(unsigned long data)
 {
-	struct adi_port *port = gameport_get_drvdata(gameport);
-
+	struct adi_port *port = (void *) data;
 	port->bad -= adi_read(port);
 	port->reads++;
+	mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME);
 }
 
 /*
@@ -292,8 +295,8 @@
 static int adi_open(struct input_dev *dev)
 {
 	struct adi_port *port = dev->private;
-
-	gameport_start_polling(port->gameport);
+	if (!port->used++)
+		mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME);
 	return 0;
 }
 
@@ -304,8 +307,8 @@
 static void adi_close(struct input_dev *dev)
 {
 	struct adi_port *port = dev->private;
-
-	gameport_stop_polling(port->gameport);
+	if (!--port->used)
+		del_timer(&port->timer);
 }
 
 /*
@@ -472,6 +475,9 @@
 		return -ENOMEM;
 
 	port->gameport = gameport;
+	init_timer(&port->timer);
+	port->timer.data = (long) port;
+	port->timer.function = adi_timer;
 
 	gameport_set_drvdata(gameport, port);
 
@@ -498,9 +504,6 @@
 		return -ENODEV;
 	}
 
-	gameport_set_poll_handler(gameport, adi_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	msleep(ADI_INIT_DELAY);
 	if (adi_read(port)) {
 		msleep(ADI_DATA_DELAY);
diff -u b/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
--- b/drivers/input/joystick/analog.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/joystick/analog.c	2005-02-22 18:34:50 -08:00
@@ -90,6 +90,7 @@
 
 #define ANALOG_MAX_TIME		3	/* 3 ms */
 #define ANALOG_LOOP_TIME	2000	/* 2 * loop */
+#define ANALOG_REFRESH_TIME	HZ/100	/* 10 ms */
 #define ANALOG_SAITEK_DELAY	200	/* 200 us */
 #define ANALOG_SAITEK_TIME	2000	/* 2000 us */
 #define ANALOG_AXIS_TIME	2	/* 2 * refresh */
@@ -120,6 +121,7 @@
 
 struct analog_port {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct analog analog[2];
 	unsigned char mask;
 	char saitek;
@@ -132,6 +134,7 @@
 	int axes[4];
 	int buttons;
 	int initial[4];
+	int used;
 	int axtime;
 };
 
@@ -304,12 +307,12 @@
 }
 
 /*
- * analog_poll() repeatedly polls the Analog joysticks.
+ * analog_timer() repeatedly polls the Analog joysticks.
  */
 
-static void analog_poll(struct gameport *gameport)
+static void analog_timer(unsigned long data)
 {
-	struct analog_port *port = gameport_get_drvdata(gameport);
+	struct analog_port *port = (void *) data;
 	int i;
 
 	char saitek = !!(port->analog[0].mask & ANALOG_SAITEK);
@@ -335,6 +338,8 @@
 	for (i = 0; i < 2; i++)
 		if (port->analog[i].mask)
 			analog_decode(port->analog + i, port->axes, port->initial, port->buttons);
+
+	mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME);
 }
 
 /*
@@ -344,8 +349,8 @@
 static int analog_open(struct input_dev *dev)
 {
 	struct analog_port *port = dev->private;
-
-	gameport_start_polling(port->gameport);
+	if (!port->used++)
+		mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME);
 	return 0;
 }
 
@@ -356,8 +361,8 @@
 static void analog_close(struct input_dev *dev)
 {
 	struct analog_port *port = dev->private;
-
-	gameport_stop_polling(port->gameport);
+	if (!--port->used)
+		del_timer(&port->timer);
 }
 
 /*
@@ -589,6 +594,9 @@
 	int i, t, u, v;
 
 	port->gameport = gameport;
+	init_timer(&port->timer);
+	port->timer.data = (long) port;
+	port->timer.function = analog_timer;
 
 	gameport_set_drvdata(gameport, port);
 
@@ -670,9 +678,6 @@
 		return err;
 	}
 
-	gameport_set_poll_handler(gameport, analog_poll);
-	gameport_set_poll_interval(gameport, 10);
-
 	for (i = 0; i < 2; i++)
 		if (port->analog[i].mask)
 			analog_init_device(port, port->analog + i, i);
diff -u b/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
--- b/drivers/input/joystick/cobra.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/joystick/cobra.c	2005-02-22 18:34:49 -08:00
@@ -42,6 +42,7 @@
 MODULE_LICENSE("GPL");
 
 #define COBRA_MAX_STROBE	45	/* 45 us max wait for first strobe */
+#define COBRA_REFRESH_TIME	HZ/50	/* 20 ms between reads */
 #define COBRA_LENGTH		36
 
 static char* cobra_name = "Creative Labs Blaster GamePad Cobra";
@@ -50,7 +51,9 @@
 
 struct cobra {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct input_dev dev[2];
+	int used;
 	int reads;
 	int bads;
 	unsigned char exists;
@@ -111,19 +114,18 @@
 	return ret;
 }
 
-static void cobra_poll(struct gameport *gameport)
+static void cobra_timer(unsigned long private)
 {
-	struct cobra *cobra = gameport_get_drvdata(gameport);
+	struct cobra *cobra = (void *) private;
 	struct input_dev *dev;
 	unsigned int data[2];
 	int i, j, r;
 
 	cobra->reads++;
 
-	if ((r = cobra_read_packet(gameport, data)) != cobra->exists) {
+	if ((r = cobra_read_packet(cobra->gameport, data)) != cobra->exists)
 		cobra->bads++;
-		return;
-	}
+	else
 
 	for (i = 0; i < 2; i++)
 		if (cobra->exists & r & (1 << i)) {
@@ -139,21 +141,23 @@
 			input_sync(dev);
 
 		}
+
+	mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
 }
 
 static int cobra_open(struct input_dev *dev)
 {
 	struct cobra *cobra = dev->private;
-
-	gameport_start_polling(cobra->gameport);
+	if (!cobra->used++)
+		mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
 	return 0;
 }
 
 static void cobra_close(struct input_dev *dev)
 {
 	struct cobra *cobra = dev->private;
-
-	gameport_stop_polling(cobra->gameport);
+	if (!--cobra->used)
+		del_timer(&cobra->timer);
 }
 
 static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
@@ -167,6 +171,9 @@
 		return -ENOMEM;
 
 	cobra->gameport = gameport;
+	init_timer(&cobra->timer);
+	cobra->timer.data = (long) cobra;
+	cobra->timer.function = cobra_timer;
 
 	gameport_set_drvdata(gameport, cobra);
 
@@ -189,7 +196,4 @@
 	}
 
-	gameport_set_poll_handler(gameport, cobra_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	for (i = 0; i < 2; i++)
 		if ((cobra->exists >> i) & 1) {
diff -u b/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
--- b/drivers/input/joystick/gf2k.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/joystick/gf2k.c	2005-02-22 18:34:49 -08:00
@@ -46,6 +46,7 @@
 #define GF2K_STROBE		40	/* The time we wait for the first bit [40 us] */
 #define GF2K_TIMEOUT		4	/* Wait for everything to settle [4 ms] */
 #define GF2K_LENGTH		80	/* Max number of triplets in a packet */
+#define GF2K_REFRESH		HZ/50	/* Time between joystick polls [20 ms] */
 
 /*
  * Genius joystick ids ...
@@ -81,9 +82,11 @@
 
 struct gf2k {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct input_dev dev;
 	int reads;
 	int bads;
+	int used;
 	unsigned char id;
 	unsigned char length;
 	char phys[32];
@@ -201,35 +204,36 @@
 }
 
 /*
- * gf2k_poll() reads and analyzes Genius joystick data.
+ * gf2k_timer() reads and analyzes Genius joystick data.
  */
 
-static void gf2k_poll(struct gameport *gameport)
+static void gf2k_timer(unsigned long private)
 {
-	struct gf2k *gf2k = gameport_get_drvdata(gameport);
+	struct gf2k *gf2k = (void *) private;
 	unsigned char data[GF2K_LENGTH];
 
 	gf2k->reads++;
 
-	if (gf2k_read_packet(gf2k->gameport, gf2k_length[gf2k->id], data) < gf2k_length[gf2k->id])
+	if (gf2k_read_packet(gf2k->gameport, gf2k_length[gf2k->id], data) < gf2k_length[gf2k->id]) {
 		gf2k->bads++;
-	else
-		gf2k_read(gf2k, data);
+	} else gf2k_read(gf2k, data);
+
+	mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH);
 }
 
 static int gf2k_open(struct input_dev *dev)
 {
 	struct gf2k *gf2k = dev->private;
-
-	gameport_start_polling(gf2k->gameport);
+	if (!gf2k->used++)
+		mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH);
 	return 0;
 }
 
 static void gf2k_close(struct input_dev *dev)
 {
 	struct gf2k *gf2k = dev->private;
-
-	gameport_stop_polling(gf2k->gameport);
+	if (!--gf2k->used)
+		del_timer(&gf2k->timer);
 }
 
 /*
@@ -246,6 +250,9 @@
 		return -ENOMEM;
 
 	gf2k->gameport = gameport;
+	init_timer(&gf2k->timer);
+	gf2k->timer.data = (long) gf2k;
+	gf2k->timer.function = gf2k_timer;
 
 	gameport_set_drvdata(gameport, gf2k);
 
@@ -288,9 +295,6 @@
 		goto fail2;
 	}
 
-	gameport_set_poll_handler(gameport, gf2k_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	sprintf(gf2k->phys, "%s/input0", gameport->phys);
 
 	gf2k->length = gf2k_lens[gf2k->id];
diff -u b/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
--- b/drivers/input/joystick/grip.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/joystick/grip.c	2005-02-22 18:34:49 -08:00
@@ -53,10 +53,14 @@
 #define GRIP_MAX_CHUNKS_XT	10
 #define GRIP_MAX_BITS_XT	30
 
+#define GRIP_REFRESH_TIME	HZ/50	/* 20 ms */
+
 struct grip {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct input_dev dev[2];
 	unsigned char mode[2];
+	int used;
 	int reads;
 	int bads;
 	char phys[2][32];
@@ -181,9 +185,9 @@
  * grip_timer() repeatedly polls the joysticks and generates events.
  */
 
-static void grip_poll(struct gameport *gameport)
+static void grip_timer(unsigned long private)
 {
-	struct grip *grip = gameport_get_drvdata(gameport);
+	struct grip *grip = (void*) private;
 	unsigned int data[GRIP_LENGTH_XT];
 	struct input_dev *dev;
 	int i, j;
@@ -277,21 +281,23 @@
 
 		input_sync(dev);
 	}
+
+	mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME);
 }
 
 static int grip_open(struct input_dev *dev)
 {
 	struct grip *grip = dev->private;
-
-	gameport_start_polling(grip->gameport);
+	if (!grip->used++)
+		mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME);
 	return 0;
 }
 
 static void grip_close(struct input_dev *dev)
 {
 	struct grip *grip = dev->private;
-
-	gameport_stop_polling(grip->gameport);
+	if (!--grip->used)
+		del_timer(&grip->timer);
 }
 
 static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
@@ -305,6 +311,9 @@
 		return -ENOMEM;
 
 	grip->gameport = gameport;
+	init_timer(&grip->timer);
+	grip->timer.data = (long) grip;
+	grip->timer.function = grip_timer;
 
 	gameport_set_drvdata(gameport, grip);
 
@@ -337,7 +346,4 @@
 	}
 
-	gameport_set_poll_handler(gameport, grip_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	for (i = 0; i < 2; i++)
 		if (grip->mode[i]) {
diff -u b/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
--- b/drivers/input/joystick/grip_mp.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/joystick/grip_mp.c	2005-02-22 18:34:50 -08:00
@@ -38,9 +38,11 @@
 
 struct grip_mp {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct input_dev dev[4];
 	int mode[4];
 	int registered[4];
+	int used;
 	int reads;
 	int bads;
 
@@ -79,6 +81,7 @@
  */
 
 #define GRIP_INIT_DELAY         2000          /*  2 ms */
+#define GRIP_REFRESH_TIME       HZ/50	      /* 20 ms */
 
 #define GRIP_MODE_NONE		0
 #define GRIP_MODE_RESET         1
@@ -523,9 +526,8 @@
  * Get the multiport state.
  */
 
-static void grip_poll(struct gameport *gameport)
+static void get_and_report_mp_state(struct grip_mp *grip)
 {
-	struct grip_mp *grip = gameport_get_drvdata(gameport);
 	int i, npkts, flags;
 
 	for (npkts = 0; npkts < 4; npkts++) {
@@ -552,7 +554,8 @@
 {
 	struct grip_mp *grip = dev->private;
 
-	gameport_start_polling(grip->gameport);
+	if (!grip->used++)
+		mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME);
 	return 0;
 }
 
@@ -564,7 +567,8 @@
 {
 	struct grip_mp *grip = dev->private;
 
-	gameport_start_polling(grip->gameport);
+	if (!--grip->used)
+		del_timer(&grip->timer);
 }
 
 /*
@@ -602,6 +606,18 @@
 	       grip_name[grip->mode[slot]], slot);
 }
 
+/*
+ * Repeatedly polls the multiport and generates events.
+ */
+
+static void grip_timer(unsigned long private)
+{
+	struct grip_mp *grip = (void*) private;
+
+	get_and_report_mp_state(grip);
+	mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME);
+}
+
 static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
 {
 	struct grip_mp *grip;
@@ -611,6 +627,9 @@
 		return -ENOMEM;
 
 	grip->gameport = gameport;
+	init_timer(&grip->timer);
+	grip->timer.data = (long) grip;
+	grip->timer.function = grip_timer;
 
 	gameport_set_drvdata(gameport, grip);
 
@@ -618,9 +637,6 @@
 	if (err)
 		goto fail1;
 
-	gameport_set_poll_handler(gameport, grip_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	if (!multiport_init(grip)) {
 		err = -ENODEV;
 		goto fail2;
diff -u b/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
--- b/drivers/input/joystick/guillemot.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/joystick/guillemot.c	2005-02-22 18:34:49 -08:00
@@ -45,6 +45,7 @@
 #define GUILLEMOT_MAX_START	600	/* 600 us */
 #define GUILLEMOT_MAX_STROBE	60	/* 60 us */
 #define GUILLEMOT_MAX_LENGTH	17	/* 17 bytes */
+#define GUILLEMOT_REFRESH_TIME	HZ/50	/* 20 ms */
 
 static short guillemot_abs_pad[] =
 	{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, -1 };
@@ -68,6 +69,8 @@
 struct guillemot {
 	struct gameport *gameport;
 	struct input_dev dev;
+	struct timer_list timer;
+	int used;
 	int bads;
 	int reads;
 	struct guillemot_type *type;
@@ -117,12 +120,12 @@
 }
 
 /*
- * guillemot_poll() reads and analyzes Guillemot joystick data.
+ * guillemot_timer() reads and analyzes Guillemot joystick data.
  */
 
-static void guillemot_poll(struct gameport *gameport)
+static void guillemot_timer(unsigned long private)
 {
-	struct guillemot *guillemot = gameport_get_drvdata(gameport);
+	struct guillemot *guillemot = (struct guillemot *) private;
 	struct input_dev *dev = &guillemot->dev;
 	u8 data[GUILLEMOT_MAX_LENGTH];
 	int i;
@@ -147,6 +150,8 @@
 	}
 
 	input_sync(dev);
+
+	mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME);
 }
 
 /*
@@ -157,7 +162,8 @@
 {
 	struct guillemot *guillemot = dev->private;
 
-	gameport_start_polling(guillemot->gameport);
+	if (!guillemot->used++)
+		mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME);
 	return 0;
 }
 
@@ -169,7 +175,8 @@
 {
 	struct guillemot *guillemot = dev->private;
 
-	gameport_stop_polling(guillemot->gameport);
+	if (!--guillemot->used)
+		del_timer(&guillemot->timer);
 }
 
 /*
@@ -187,6 +194,9 @@
 		return -ENOMEM;
 
 	guillemot->gameport = gameport;
+	init_timer(&guillemot->timer);
+	guillemot->timer.data = (long) guillemot;
+	guillemot->timer.function = guillemot_timer;
 
 	gameport_set_drvdata(gameport, guillemot);
 
@@ -212,9 +222,6 @@
 		goto fail2;
 	}
 
-	gameport_set_poll_handler(gameport, guillemot_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	sprintf(guillemot->phys, "%s/input0", gameport->phys);
 
 	guillemot->type = guillemot_type + i;
diff -u b/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
--- b/drivers/input/joystick/interact.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/joystick/interact.c	2005-02-22 18:34:49 -08:00
@@ -48,6 +48,7 @@
 #define INTERACT_MAX_START	400	/* 400 us */
 #define INTERACT_MAX_STROBE	40	/* 40 us */
 #define INTERACT_MAX_LENGTH	32	/* 32 bits */
+#define INTERACT_REFRESH_TIME	HZ/50	/* 20 ms */
 
 #define INTERACT_TYPE_HHFX	0	/* HammerHead/FX */
 #define INTERACT_TYPE_PP8D	1	/* ProPad 8 */
@@ -55,6 +56,8 @@
 struct interact {
 	struct gameport *gameport;
 	struct input_dev dev;
+	struct timer_list timer;
+	int used;
 	int bads;
 	int reads;
 	unsigned char type;
@@ -124,12 +127,12 @@
 }
 
 /*
- * interact_poll() reads and analyzes InterAct joystick data.
+ * interact_timer() reads and analyzes InterAct joystick data.
  */
 
-static void interact_poll(struct gameport *gameport)
+static void interact_timer(unsigned long private)
 {
-	struct interact *interact = gameport_get_drvdata(gameport);
+	struct interact *interact = (struct interact *) private;
 	struct input_dev *dev = &interact->dev;
 	u32 data[3];
 	int i;
@@ -176,6 +179,9 @@
 	}
 
 	input_sync(dev);
+
+	mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME);
+
 }
 
 /*
@@ -186,7 +192,8 @@
 {
 	struct interact *interact = dev->private;
 
-	gameport_start_polling(interact->gameport);
+	if (!interact->used++)
+		mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME);
 	return 0;
 }
 
@@ -198,7 +205,8 @@
 {
 	struct interact *interact = dev->private;
 
-	gameport_stop_polling(interact->gameport);
+	if (!--interact->used)
+		del_timer(&interact->timer);
 }
 
 /*
@@ -216,6 +224,9 @@
 		return -ENOMEM;
 
 	interact->gameport = gameport;
+	init_timer(&interact->timer);
+	interact->timer.data = (long) interact;
+	interact->timer.function = interact_timer;
 
 	gameport_set_drvdata(gameport, interact);
 
@@ -241,9 +252,6 @@
 		goto fail2;
 	}
 
-	gameport_set_poll_handler(gameport, interact_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	sprintf(interact->phys, "%s/input0", gameport->phys);
 
 	interact->type = i;
diff -u b/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
--- b/drivers/input/joystick/tmdc.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/joystick/tmdc.c	2005-02-22 18:34:49 -08:00
@@ -48,6 +48,7 @@
 #define TMDC_MAX_START		400	/* 400 us */
 #define TMDC_MAX_STROBE		45	/* 45 us */
 #define TMDC_MAX_LENGTH		13
+#define TMDC_REFRESH_TIME	HZ/50	/* 20 ms */
 
 #define TMDC_MODE_M3DI		1
 #define TMDC_MODE_3DRP		3
@@ -93,6 +94,7 @@
 
 struct tmdc {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct input_dev dev[2];
 	char name[2][64];
 	char phys[2][32];
@@ -102,6 +104,7 @@
 	unsigned char absc[2];
 	unsigned char btnc[2][4];
 	unsigned char btno[2][4];
+	int used;
 	int reads;
 	int bads;
 	unsigned char exists;
@@ -157,13 +160,13 @@
 }
 
 /*
- * tmdc_poll() reads and analyzes ThrustMaster joystick data.
+ * tmdc_read() reads and analyzes ThrustMaster joystick data.
  */
 
-static void tmdc_poll(struct gameport *gameport)
+static void tmdc_timer(unsigned long private)
 {
 	unsigned char data[2][TMDC_MAX_LENGTH];
-	struct tmdc *tmdc = gameport_get_drvdata(gameport);
+	struct tmdc *tmdc = (void *) private;
 	struct input_dev *dev;
 	unsigned char r, bad = 0;
 	int i, j, k, l;
@@ -218,21 +221,23 @@
 	}
 
 	tmdc->bads += bad;
+
+	mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME);
 }
 
 static int tmdc_open(struct input_dev *dev)
 {
 	struct tmdc *tmdc = dev->private;
-
-	gameport_start_polling(tmdc->gameport);
+	if (!tmdc->used++)
+		mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME);
 	return 0;
 }
 
 static void tmdc_close(struct input_dev *dev)
 {
 	struct tmdc *tmdc = dev->private;
-
-	gameport_stop_polling(tmdc->gameport);
+	if (!--tmdc->used)
+		del_timer(&tmdc->timer);
 }
 
 /*
@@ -266,6 +271,9 @@
 		return -ENOMEM;
 
 	tmdc->gameport = gameport;
+	init_timer(&tmdc->timer);
+	tmdc->timer.data = (long) tmdc;
+	tmdc->timer.function = tmdc_timer;
 
 	gameport_set_drvdata(gameport, tmdc);
 
@@ -279,7 +287,4 @@
 	}
 
-	gameport_set_poll_handler(gameport, tmdc_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	for (j = 0; j < 2; j++)
 		if (tmdc->exists & (1 << j)) {
diff -u b/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
--- b/drivers/input/mouse/alps.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/mouse/alps.c	2005-02-22 18:34:49 -08:00
@@ -212,10 +212,9 @@
 	return PSMOUSE_GOOD_DATA;
 }
 
-static int alps_get_model(struct psmouse *psmouse, int *version)
+static int alps_get_model(struct psmouse *psmouse)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
 	unsigned char param[4];
 	int i;
 
@@ -253,9 +252,6 @@
 
 	dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
 
-	for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++);
-	*version = (param[0] << 8) | (i << 4) | (param[1] & 0x0f);
-
 	for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
 		if (!memcmp(param, alps_model_data[i].signature, sizeof(alps_model_data[i].signature)))
 			return alps_model_data[i].model;
@@ -353,9 +349,8 @@
 {
 	struct alps_data *priv = psmouse->private;
 	unsigned char param[4];
-	int version;
 
-	if ((priv->model = alps_get_model(psmouse, &version)) < 0)
+	if ((priv->model = alps_get_model(psmouse)) < 0)
 		return -1;
 
 	if (priv->model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 1))
@@ -388,14 +383,13 @@
 {
 	struct alps_data *priv;
 	unsigned char param[4];
-	int version;
 
 	psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL);
 	if (!priv)
 		goto init_fail;
 	memset(priv, 0, sizeof(struct alps_data));
 
-	if ((priv->model = alps_get_model(psmouse, &version)) < 0)
+	if ((priv->model = alps_get_model(psmouse)) < 0)
 		goto init_fail;
 
 	printk(KERN_INFO "ALPS Touchpad (%s) detected\n",
@@ -453,15 +447,12 @@
 
 int alps_detect(struct psmouse *psmouse, int set_properties)
 {
-	int version;
-
-	if (alps_get_model(psmouse, &version) < 0)
+	if (alps_get_model(psmouse) < 0)
 		return -1;
 
 	if (set_properties) {
 		psmouse->vendor = "ALPS";
 		psmouse->name = "TouchPad";
-		psmouse->model = version;
 	}
 	return 0;
 }
diff -u b/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- b/drivers/input/mouse/psmouse-base.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/mouse/psmouse-base.c	2005-02-22 18:34:49 -08:00
@@ -423,7 +423,7 @@
  * upsets the thinkingmouse).
  */
 
-	if (max_proto > PSMOUSE_IMEX && thinking_detect(psmouse, set_properties) == 0)
+	if (max_proto > PSMOUSE_PS2 && thinking_detect(psmouse, set_properties) == 0)
 		return PSMOUSE_THINKPS;
 
 /*
reverted:
--- b/drivers/input/mouse/psmouse.h	2005-02-22 18:43:15 -08:00
+++ a/drivers/input/mouse/psmouse.h	2005-02-22 18:43:15 -08:00
@@ -44,7 +44,7 @@
 	unsigned char pktcnt;
 	unsigned char pktsize;
 	unsigned char type;
+	unsigned char model;
-	unsigned int model;
 	unsigned long last;
 	unsigned long out_of_sync;
 	enum psmouse_state state;
diff -u b/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
--- b/drivers/input/serio/parkbd.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/serio/parkbd.c	2005-02-22 18:34:49 -08:00
@@ -16,23 +16,23 @@
  * 
  *  Parallel port            Keyboard port
  *
- *     +5V --------------------- +5V (4)
+ *     +5V --------------------- +5V
  *  
  *                 ______
  *     +5V -------|______|--.
  *                          |
- *     ACK (10) ------------|
- *                          |--- KBD CLOCK (5)
- *     STROBE (1) ---|<|----'
+ *     ACK -----------------|
+ *                          |--- KBD CLOCK
+ *     STROBE -------|<|----'
  *     
  *                 ______
  *     +5V -------|______|--.
  *                          |
- *     BUSY (11) -----------|
- *                          |--- KBD DATA (1)
- *     AUTOFD (14) --|<|----'
+ *     BUSY ----------------|
+ *                          |--- KBD DATA
+ *     AUTOFD -------|<|----'
  *
- *     GND (18-25) ------------- GND (3)
+ *     GND --------------------- GND
  *     
  * The diodes can be fairly any type, and the resistors should be somewhere
  * around 5 kOhm, but the adapter will likely work without the resistors,
diff -u b/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
--- b/drivers/input/touchscreen/elo.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/touchscreen/elo.c	2005-02-22 18:34:50 -08:00
@@ -80,7 +80,7 @@
 				input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
 				input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
 				input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]);
-				input_report_key(dev, BTN_TOUCH, elo->data[2] & 3);
+				input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]);
 				input_sync(dev);
 			}
 			elo->idx = 0;
@@ -129,7 +129,7 @@
 		case 5:
 			if ((data & 0xf0) == 0) {
 				input_report_abs(dev, ABS_PRESSURE, elo->data[5]);
-				input_report_key(dev, BTN_TOUCH, elo->data[5]);
+				input_report_key(dev, BTN_TOUCH, !!elo->data[5]);
 			}
 			input_sync(dev);
 			elo->idx = 0;
diff -u b/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c
--- b/drivers/input/touchscreen/mk712.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/input/touchscreen/mk712.c	2005-02-22 18:34:50 -08:00
@@ -161,7 +161,7 @@
 
 static struct input_dev mk712_dev = {
 	.evbit   = { BIT(EV_KEY) | BIT(EV_ABS) },
-	.keybit  = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
+	.keybit  = { [LONG(BTN_LEFT)] = BIT(BTN_TOUCH) },
 	.absbit  = { BIT(ABS_X) | BIT(ABS_Y) },
 	.open    = mk712_open,
 	.close   = mk712_close,
reverted:
--- b/drivers/usb/input/ati_remote.c	2005-02-22 18:43:15 -08:00
+++ a/drivers/usb/input/ati_remote.c	2005-02-22 18:43:15 -08:00
@@ -174,6 +174,7 @@
 	dma_addr_t outbuf_dma;
 
 	int open;                   /* open counter */
+	int present;                /* device plugged in? */
 	
 	unsigned char old_data[2];  /* Detect duplicate events */
 	unsigned long old_jiffies;
@@ -251,8 +252,8 @@
 	{KIND_FILTERED, 0xdd, 0x18, EV_KEY, KEY_KPENTER, 1},    /* "check" */
 	{KIND_FILTERED, 0xdb, 0x16, EV_KEY, KEY_MENU, 1},       /* "menu" */
 	{KIND_FILTERED, 0xc7, 0x02, EV_KEY, KEY_POWER, 1},      /* Power */
+	{KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_PROG1, 1},      /* TV */
+	{KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_PROG2, 1},      /* DVD */
-	{KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_TV, 1},         /* TV */
-	{KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_DVD, 1},        /* DVD */
 	{KIND_FILTERED, 0xca, 0x05, EV_KEY, KEY_WWW, 1},        /* WEB */
 	{KIND_FILTERED, 0xcb, 0x06, EV_KEY, KEY_BOOKMARKS, 1},  /* "book" */
 	{KIND_FILTERED, 0xcc, 0x07, EV_KEY, KEY_EDIT, 1},       /* "hand" */
@@ -262,14 +263,14 @@
 	{KIND_FILTERED, 0xe4, 0x1f, EV_KEY, KEY_RIGHT, 1},      /* right */
 	{KIND_FILTERED, 0xe7, 0x22, EV_KEY, KEY_DOWN, 1},       /* down */
 	{KIND_FILTERED, 0xdf, 0x1a, EV_KEY, KEY_UP, 1},         /* up */
+	{KIND_FILTERED, 0xe3, 0x1e, EV_KEY, KEY_ENTER, 1},      /* "OK" */
-	{KIND_FILTERED, 0xe3, 0x1e, EV_KEY, KEY_OK, 1},         /* "OK" */
 	{KIND_FILTERED, 0xce, 0x09, EV_KEY, KEY_VOLUMEDOWN, 1}, /* VOL + */
 	{KIND_FILTERED, 0xcd, 0x08, EV_KEY, KEY_VOLUMEUP, 1},   /* VOL - */
 	{KIND_FILTERED, 0xcf, 0x0a, EV_KEY, KEY_MUTE, 1},       /* MUTE  */
+	{KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_CHANNELUP, 1},  /* CH + */
+	{KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_CHANNELDOWN, 1},/* CH - */
-	{KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_CHANNELUP, 1},  /* CH + */
-	{KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_CHANNELDOWN, 1},/* CH - */
 	{KIND_FILTERED, 0xec, 0x27, EV_KEY, KEY_RECORD, 1},     /* ( o) red */
+	{KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAYCD, 1},     /* ( >) */
-	{KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAY, 1},       /* ( >) */
 	{KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_REWIND, 1},     /* (<<) */
 	{KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1},    /* (>>) */
 	{KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1},       /* ([]) */ 
@@ -355,8 +356,19 @@
 {
 	struct ati_remote *ati_remote = inputdev->private;
 	
+	if (ati_remote == NULL) {
+		err("ati_remote: %s: object is NULL!\n", __FUNCTION__);
+		return;
+	}
+	
+	if (ati_remote->open <= 0)
+		dev_dbg(&ati_remote->interface->dev, "%s: Not open.\n", __FUNCTION__);
+	else
+		--ati_remote->open;
+	
+	/* If still present, disconnect will call delete. */
+	if (!ati_remote->present && !ati_remote->open)
+		ati_remote_delete(ati_remote);
-	if (!--ati_remote->open)
-		usb_kill_urb(ati_remote->irq_urb);
 }
 
 /*
@@ -800,6 +812,7 @@
 		 ati_remote->name, path);
 
 	usb_set_intfdata(interface, ati_remote);
+	ati_remote->present = 1;	
 	
 error:
 	if (buf)
@@ -827,7 +840,12 @@
 		return;
 	}
 	
+	/* Mark device as unplugged */
+	ati_remote->present = 0;
+
+	/* If device is still open, ati_remote_close will call delete. */
+	if (!ati_remote->open)
+		ati_remote_delete(ati_remote);
-	ati_remote_delete(ati_remote);
 
 	up(&disconnect_sem);
 }
diff -u b/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- b/drivers/usb/input/hid-core.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/usb/input/hid-core.c	2005-02-22 18:34:49 -08:00
@@ -1007,21 +1007,63 @@
 	return 0;
 }
 
+int hid_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
+{
+	struct hid_report_enum *report_enum = hid->report_enum + HID_OUTPUT_REPORT;
+	struct list_head *list = report_enum->report_list.next;
+	int i, j;
+
+	while (list != &report_enum->report_list) {
+		struct hid_report *report = (struct hid_report *) list;
+		list = list->next;
+		for (i = 0; i < report->maxfield; i++) {
+			*field = report->field[i];
+			for (j = 0; j < (*field)->maxusage; j++)
+				if ((*field)->usage[j].type == type && (*field)->usage[j].code == code)
+					return j;
+		}
+	}
+	return -1;
+}
+
 /*
  * Find a report with a specified HID usage.
  */
 
-struct hid_report *hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, int type)
+int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type)
 {
-	struct hid_report *report;
-	int i;
+	struct hid_report_enum *report_enum = hid->report_enum + type;
+	struct list_head *list = report_enum->report_list.next;
+	int i, j;
+
+	while (list != &report_enum->report_list) {
+		*report = (struct hid_report *) list;
+		list = list->next;
+		for (i = 0; i < (*report)->maxfield; i++) {
+			struct hid_field *field = (*report)->field[i];
+			for (j = 0; j < field->maxusage; j++)
+				if (field->logical == wanted_usage)
+					return j;
+		}
+	}
+	return -1;
+}
+
+#if 0
+static int hid_find_field_in_report(struct hid_report *report, __u32 wanted_usage, struct hid_field **field)
+{
+	int i, j;
 
-	list_for_each_entry(report, &hid->report_enum[type].report_list, list)
-		for (i = 0; i < report->maxfield; i++)
-			if (report->field[i]->logical == wanted_usage)
-				return report;
-	return NULL;
+	for (i = 0; i < report->maxfield; i++) {
+		*field = report->field[i];
+		for (j = 0; j < (*field)->maxusage; j++)
+			if ((*field)->usage[j].hid == wanted_usage)
+				return j;
+	}
+
+	return -1;
 }
+#endif
 
 static int hid_submit_out(struct hid_device *hid)
 {
@@ -1294,19 +1336,47 @@
 
 void hid_init_reports(struct hid_device *hid)
 {
+	struct hid_report_enum *report_enum;
 	struct hid_report *report;
-	int err, ret;
+	struct list_head *list;
+	int err, ret, size;
+
+	/*
+	 * The Set_Idle request is supposed to affect only the
+	 * "Interrupt In" pipe. Unfortunately, buggy devices such as
+	 * the BTC keyboard (ID 046e:5303) the request also affects
+	 * Get_Report requests on the control pipe.  In the worst
+	 * case, if the device was put on idle for an indefinite
+	 * amount of time (as we do below) and there are no input
+	 * events to report, the Get_Report requests will just hang
+	 * until we get a USB timeout.  To avoid this, we temporarily
+	 * establish a minimal idle time of 1ms.  This shouldn't hurt
+	 * bugfree devices and will cause a worst-case extra delay of
+	 * 1ms for buggy ones.
+	 */
+	usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
+			HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (1 << 8),
+			hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
 
-	list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) {
-		int size = ((report->size - 1) >> 3) + 1 + hid->report_enum[HID_INPUT_REPORT].numbered;
+	report_enum = hid->report_enum + HID_INPUT_REPORT;
+	list = report_enum->report_list.next;
+	while (list != &report_enum->report_list) {
+		report = (struct hid_report *) list;
+		size = ((report->size - 1) >> 3) + 1 + report_enum->numbered;
 		if (size > HID_BUFFER_SIZE) size = HID_BUFFER_SIZE;
 		if (size > hid->urbin->transfer_buffer_length)
 			hid->urbin->transfer_buffer_length = size;
 		hid_submit_report(hid, report, USB_DIR_IN);
+		list = list->next;
 	}
 
-	list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
+	report_enum = hid->report_enum + HID_FEATURE_REPORT;
+	list = report_enum->report_list.next;
+	while (list != &report_enum->report_list) {
+		report = (struct hid_report *) list;
 		hid_submit_report(hid, report, USB_DIR_IN);
+		list = list->next;
+	}
 
 	err = 0;
 	ret = hid_wait_io(hid);
@@ -1322,9 +1392,15 @@
 	if (err)
 		warn("timeout initializing reports\n");
 
-	usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
-		HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
-		hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+	report_enum = hid->report_enum + HID_INPUT_REPORT;
+	list = report_enum->report_list.next;
+	while (list != &report_enum->report_list) {
+		report = (struct hid_report *) list;
+		usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
+			HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id,
+			hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+		list = list->next;
+	}
 }
 
 #define USB_VENDOR_ID_WACOM		0x056a
@@ -1429,9 +1505,6 @@
 #define USB_VENDOR_ID_CHICONY		0x04f2
 #define USB_DEVICE_ID_CHICONY_USBHUB_KB	0x0100
 
-#define USB_VENDOR_ID_BTC		0x046e
-#define USB_DEVICE_ID_BTC_KEYBOARD	0x5303
-
 
 /*
  * Alphabetically sorted blacklist by quirk type.
@@ -1509,7 +1582,6 @@
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
-	{ USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET},
 	{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET},
 	{ USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
 
@@ -1753,7 +1825,7 @@
 	hid_free_device(hid);
 }
 
-static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct hid_device *hid;
 	char path[64];
reverted:
--- b/drivers/usb/input/hid-input.c	2005-02-22 18:43:15 -08:00
+++ a/drivers/usb/input/hid-input.c	2005-02-22 18:43:15 -08:00
@@ -483,26 +483,10 @@
 	}
 }
 
-static int hid_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
-{
-	struct hid_report *report;
-	int i, j;
-
-	list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) {
-		for (i = 0; i < report->maxfield; i++) {
-			*field = report->field[i];
-			for (j = 0; j < (*field)->maxusage; j++)
-				if ((*field)->usage[j].type == type && (*field)->usage[j].code == code)
-					return j;
-		}
-	}
-	return -1;
-}
-
 static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
 	struct hid_device *hid = dev->private;
+	struct hid_field *field = NULL;
-	struct hid_field *field;
 	int offset;
 
 	if (type == EV_FF)
@@ -543,7 +527,9 @@
 int hidinput_connect(struct hid_device *hid)
 {
 	struct usb_device *dev = hid->dev;
+	struct hid_report_enum *report_enum;
 	struct hid_report *report;
+	struct list_head *list;
 	struct hid_input *hidinput = NULL;
 	int i, j, k;
 
@@ -558,11 +544,16 @@
 	if (i == hid->maxcollection)
 		return -1;
 
+	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
+		report_enum = hid->report_enum + k;
+		list = report_enum->report_list.next;
+		while (list != &report_enum->report_list) {
+			report = (struct hid_report *) list;
-	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++)
-		list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
 
+			if (!report->maxfield) {
+				list = list->next;
-			if (!report->maxfield)
 				continue;
+			}
 
 			if (!hidinput) {
 				hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL);
@@ -607,7 +598,10 @@
 				input_register_device(&hidinput->input);
 				hidinput = NULL;
 			}
+
+			list = list->next;
 		}
+	}
 
 	/* This only gets called when we are a single-input (most of the
 	 * time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is
@@ -625,7 +619,7 @@
 	struct list_head *lh, *next;
 	struct hid_input *hidinput;
 
+	list_for_each_safe (lh, next, &hid->inputs) {
-	list_for_each_safe(lh, next, &hid->inputs) {
 		hidinput = list_entry(lh, struct hid_input, list);
 		input_unregister_device(&hidinput->input);
 		list_del(&hidinput->list);
reverted:
--- b/drivers/usb/input/hid.h	2005-02-22 18:43:15 -08:00
+++ a/drivers/usb/input/hid.h	2005-02-22 18:43:15 -08:00
@@ -484,10 +484,11 @@
 
 int hid_open(struct hid_device *);
 void hid_close(struct hid_device *);
+int hid_find_field(struct hid_device *, unsigned int, unsigned int, struct hid_field **);
 int hid_set_field(struct hid_field *, unsigned, __s32);
 void hid_submit_report(struct hid_device *, struct hid_report *, unsigned char dir);
 void hid_init_reports(struct hid_device *hid);
+int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type);
-struct hid_report *hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, int type);
 int hid_wait_io(struct hid_device* hid);
 
 
diff -u b/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- b/drivers/usb/input/hiddev.c	2005-02-22 18:43:15 -08:00
+++ b/drivers/usb/input/hiddev.c	2005-02-22 18:34:49 -08:00
@@ -124,6 +124,7 @@
 	int i, j;
 	struct hid_report *report;
 	struct hid_report_enum *report_enum;
+	struct list_head *list;
 	struct hid_field *field;
 
 	if (uref->report_type < HID_REPORT_TYPE_MIN ||
@@ -131,8 +132,9 @@
 
 	report_enum = hid->report_enum +
 		(uref->report_type - HID_REPORT_TYPE_MIN);
-
-	list_for_each_entry(report, &report_enum->report_list, list)
+	list = report_enum->report_list.next;
+	while (list != &report_enum->report_list) {
+		report = (struct hid_report *) list;
 		for (i = 0; i < report->maxfield; i++) {
 			field = report->field[i];
 			for (j = 0; j < field->maxusage; j++) {
@@ -144,6 +146,8 @@
 				}
 			}
 		}
+		list = list->next;
+	}
 
 	return NULL;
 }
reverted:
--- b/drivers/usb/input/pid.c	2005-02-22 18:43:15 -08:00
+++ a/drivers/usb/input/pid.c	2005-02-22 18:43:15 -08:00
@@ -114,28 +114,28 @@
 	struct hid_report* report;
 	struct hid_ff_pid *pid = hid->ff_private;
 	unsigned long flags;
+	unsigned wanted_report = HID_UP_PID | FF_PID_USAGE_BLOCK_FREE;  /*  PID Block Free Report */
 	int ret;
 
 	if (!CHECK_OWNERSHIP(id, pid))
 		return -EACCES;
 
 	/* Find report */
+	ret =  hid_find_report_by_usage(hid, wanted_report, &report, HID_OUTPUT_REPORT);
+	if(!ret) {
-	report = hid_find_report_by_usage(hid,
-		HID_UP_PID | FF_PID_USAGE_BLOCK_FREE, HID_OUTPUT_REPORT);
-	if (!report) {
 		dev_err(&hid->dev->dev, "couldn't find report\n");
 		return ret;
 	}
 
 	/* Find field */
 	field = (struct hid_field *) kmalloc(sizeof(struct hid_field), GFP_KERNEL);
+	if(!field) {
-	if (!field) {
 		dev_err(&hid->dev->dev, "couldn't allocate field\n");
 		return -ENOMEM;
 	}
 
 	ret = hid_set_field(field, ret, pid->effects[id].device_id);
+	if(!ret) {
-	if (ret) {
 		dev_err(&hid->dev->dev, "couldn't set field\n");
 		return ret;
 	}
diff -u b/include/linux/gameport.h b/include/linux/gameport.h
--- b/include/linux/gameport.h	2005-02-22 18:43:15 -08:00
+++ b/include/linux/gameport.h	2005-02-22 18:34:50 -08:00
@@ -30,12 +30,6 @@
 	int (*open)(struct gameport *, int);
 	void (*close)(struct gameport *);
 
-	struct timer_list poll_timer;
-	unsigned int poll_interval;	/* in msecs */
-	spinlock_t timer_lock;
-	unsigned int poll_cnt;
-	void (*poll_handler)(struct gameport *);
-
 	struct gameport *parent, *child;
 
 	struct gameport_driver *drv;
@@ -184,15 +178,2 @@
 
-static inline void gameport_set_poll_handler(struct gameport *gameport, void (*handler)(struct gameport *))
-{
-	gameport->poll_handler = handler;
-}
-
-static inline void gameport_set_poll_interval(struct gameport *gameport, unsigned int msecs)
-{
-	gameport->poll_interval = msecs;
-}
-
-void gameport_start_polling(struct gameport *gameport);
-void gameport_stop_polling(struct gameport *gameport);
-
 #endif
reverted:
--- b/include/linux/hiddev.h	2005-02-22 18:43:15 -08:00
+++ a/include/linux/hiddev.h	2005-02-22 18:43:15 -08:00
@@ -201,8 +201,8 @@
  *		ioctl(fd, HIDIOCGUSAGE, &uref);
  *          }
  *	}
+ *	uref.report_id |= HID_REPORT_ID_NEXT;
+ *	ret = ioctl(fd, HIDIOCGREPORTINFO, &uref);
- *	rinfo.report_id |= HID_REPORT_ID_NEXT;
- *	ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo);
  *  }
  */