vserver 1.9.5.x5
[linux-2.6.git] / drivers / input / serio / parkbd.c
index 1df2dd1..d0510ec 100644 (file)
 /*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or 
+ * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * 
+ *
  * Should you need to contact me, the author, you can do so either by
  * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -37,15 +37,17 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Parallel port to Keyboard port adapter driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(parkbd, "1i");
-MODULE_PARM(parkbd_mode, "1i");
+static unsigned int parkbd_pp_no;
+module_param_named(port, parkbd_pp_no, int, 0);
+MODULE_PARM_DESC(port, "Parallel port the adapter is connected to (default is 0)");
+
+static unsigned int parkbd_mode = SERIO_8042;
+module_param_named(mode, parkbd_mode, uint, 0);
+MODULE_PARM_DESC(mode, "Mode of operation: XT = 0/AT = 1 (default)");
 
 #define PARKBD_CLOCK   0x01    /* Strobe & Ack */
 #define PARKBD_DATA    0x02    /* AutoFd & Busy */
 
-static int parkbd;
-static int parkbd_mode = SERIO_8042;
-
 static int parkbd_buffer;
 static int parkbd_counter;
 static unsigned long parkbd_last;
@@ -53,9 +55,7 @@ static int parkbd_writing;
 static unsigned long parkbd_start;
 
 static struct pardevice *parkbd_dev;
-
-static char parkbd_name[] = "PARKBD AT/XT keyboard adapter";
-static char parkbd_phys[32];
+static struct serio *parkbd_port;
 
 static int parkbd_readlines(void)
 {
@@ -86,24 +86,6 @@ static int parkbd_write(struct serio *port, unsigned char c)
        return 0;
 }
 
-static int parkbd_open(struct serio *port)
-{
-       return 0;
-}
-
-static void parkbd_close(struct serio *port)
-{
-}
-
-static struct serio parkbd_port =
-{
-       .write  = parkbd_write,
-       .open   = parkbd_open,
-       .close  = parkbd_close,
-       .name   = parkbd_name,
-       .phys   = parkbd_phys,
-};
-
 static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 
@@ -115,7 +97,7 @@ static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        parkbd_writing = 0;
                        parkbd_writelines(3);
                        return;
-               }       
+               }
 
                parkbd_writelines(((parkbd_buffer >> parkbd_counter++) & 1) | 2);
 
@@ -131,12 +113,12 @@ static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                if ((parkbd_counter == parkbd_mode + 10) || time_after(jiffies, parkbd_last + HZ/100)) {
                        parkbd_counter = 0;
                        parkbd_buffer = 0;
-               }       
+               }
 
                parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++;
 
                if (parkbd_counter == parkbd_mode + 10)
-                       serio_interrupt(&parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs);
+                       serio_interrupt(parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs);
        }
 
        parkbd_last = jiffies;
@@ -146,12 +128,7 @@ static int parkbd_getport(void)
 {
        struct parport *pp;
 
-       if (parkbd < 0) {
-               printk(KERN_ERR "parkbd: no port specified\n");
-               return -ENODEV;
-       }
-
-       pp = parport_find_number(parkbd);
+       pp = parport_find_number(parkbd_pp_no);
 
        if (pp == NULL) {
                printk(KERN_ERR "parkbd: no such parport\n");
@@ -174,16 +151,39 @@ static int parkbd_getport(void)
        return 0;
 }
 
+static struct serio * __init parkbd_allocate_serio(void)
+{
+       struct serio *serio;
+
+       serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+       if (serio) {
+               memset(serio, 0, sizeof(struct serio));
+               serio->type = parkbd_mode;
+               serio->write = parkbd_write,
+               strlcpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name));
+               snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", parkbd_dev->port->name);
+       }
+
+       return serio;
+}
 
 int __init parkbd_init(void)
 {
-       if (parkbd_getport()) return -1;
-       parkbd_writelines(3);
-       parkbd_port.type = parkbd_mode;
+       int err;
+
+       err = parkbd_getport();
+       if (err)
+               return err;
 
-       sprintf(parkbd_phys, "%s/serio0", parkbd_dev->port->name);
+       parkbd_port = parkbd_allocate_serio();
+       if (!parkbd_port) {
+               parport_release(parkbd_dev);
+               return -ENOMEM;
+       }
+
+       parkbd_writelines(3);
 
-       serio_register_port(&parkbd_port);
+       serio_register_port(parkbd_port);
 
        printk(KERN_INFO "serio: PARKBD %s adapter on %s\n",
                         parkbd_mode ? "AT" : "XT", parkbd_dev->port->name);
@@ -194,7 +194,7 @@ int __init parkbd_init(void)
 void __exit parkbd_exit(void)
 {
        parport_release(parkbd_dev);
-       serio_unregister_port(&parkbd_port);
+       serio_unregister_port(parkbd_port);
        parport_unregister_device(parkbd_dev);
 }