X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Finput%2Fserio%2Fgscps2.c;h=74f14e097789d193fe1bf6b8ffc52a248aba3875;hb=a2f44b27303a5353859d77a3e96a1d3f33f56ab7;hp=48a0ad5871600f30d5150f905233191e6aeffc40;hpb=39b607ac274a09883c7fe5f03a7eff28960a1190;p=linux-2.6.git diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 48a0ad587..74f14e097 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -1,12 +1,12 @@ /* * drivers/input/serio/gscps2.c * - * Copyright (c) 2004 Helge Deller + * Copyright (c) 2004-2006 Helge Deller * Copyright (c) 2002 Laurent Canet - * Copyright (c) 2002 Thibaut Varene + * Copyright (c) 2002 Thibaut Varene * * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c - * Copyright (c) 1999 Alex deVries + * Copyright (c) 1999 Alex deVries * Copyright (c) 1999-2000 Philipp Rumpf * Copyright (c) 2000 Xavier Debacker * Copyright (c) 2000-2001 Thomas Marteau @@ -22,7 +22,6 @@ * was usable/enabled ?) */ -#include #include #include #include @@ -37,8 +36,8 @@ #include #include -MODULE_AUTHOR("Laurent Canet , Thibaut Varene , Helge Deller "); -MODULE_DESCRIPTION("HP GSC PS/2 port driver"); +MODULE_AUTHOR("Laurent Canet , Thibaut Varene , Helge Deller "); +MODULE_DESCRIPTION("HP GSC PS2 port driver"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl); @@ -83,7 +82,7 @@ MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl); #define GSC_ID_MOUSE 1 -static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs); +static irqreturn_t gscps2_interrupt(int irq, void *dev); #define BUFFER_SIZE 0x0f @@ -91,7 +90,7 @@ static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs); struct gscps2port { struct list_head node; struct parisc_device *padev; - struct serio port; + struct serio *port; spinlock_t lock; char *addr; u8 act, append; /* position in buffer[] */ @@ -100,7 +99,6 @@ struct gscps2port { u8 str; } buffer[BUFFER_SIZE+1]; int id; - char name[32]; }; /* @@ -168,7 +166,7 @@ static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data) /* make sure any received data is returned as fast as possible */ /* this is important e.g. when we set the LEDs on the keyboard */ - gscps2_interrupt(0, NULL, NULL); + gscps2_interrupt(0, NULL); return 1; } @@ -212,9 +210,6 @@ static void gscps2_reset(struct gscps2port *ps2port) writeb(0xff, addr+GSC_RESET); gscps2_flush(ps2port); spin_unlock_irqrestore(&ps2port->lock, flags); - - /* enable it */ - gscps2_enable(ps2port, ENABLE); } static LIST_HEAD(ps2port_list); @@ -231,7 +226,7 @@ static LIST_HEAD(ps2port_list); * later. */ -static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs) +static irqreturn_t gscps2_interrupt(int irq, void *dev) { struct gscps2port *ps2port; @@ -272,7 +267,7 @@ static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs) rxflags = ((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) | ((status & GSC_STAT_PERR) ? SERIO_PARITY : 0 ); - serio_interrupt(&ps2port->port, data, rxflags, regs); + serio_interrupt(ps2port->port, data, rxflags); } /* while() */ @@ -288,7 +283,7 @@ static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs) static int gscps2_write(struct serio *port, unsigned char data) { - struct gscps2port *ps2port = port->driver; + struct gscps2port *ps2port = port->port_data; if (!gscps2_writeb_output(ps2port, data)) { printk(KERN_DEBUG PFX "sending byte %#x failed.\n", data); @@ -304,11 +299,14 @@ static int gscps2_write(struct serio *port, unsigned char data) static int gscps2_open(struct serio *port) { - struct gscps2port *ps2port = port->driver; + struct gscps2port *ps2port = port->port_data; gscps2_reset(ps2port); - gscps2_interrupt(0, NULL, NULL); + /* enable it */ + gscps2_enable(ps2port, ENABLE); + + gscps2_interrupt(0, NULL); return 0; } @@ -319,23 +317,10 @@ static int gscps2_open(struct serio *port) static void gscps2_close(struct serio *port) { - struct gscps2port *ps2port = port->driver; + struct gscps2port *ps2port = port->port_data; gscps2_enable(ps2port, DISABLE); } -static struct serio gscps2_serio_port = -{ - .name = "GSC PS/2", - .idbus = BUS_GSC, - .idvendor = PCI_VENDOR_ID_HP, - .idproduct = 0x0001, - .idversion = 0x0010, - .type = SERIO_8042, - .write = gscps2_write, - .open = gscps2_open, - .close = gscps2_close, -}; - /** * gscps2_probe() - Probes PS2 devices * @return: success/error report @@ -343,8 +328,9 @@ static struct serio gscps2_serio_port = static int __init gscps2_probe(struct parisc_device *dev) { - struct gscps2port *ps2port; - unsigned long hpa = dev->hpa; + struct gscps2port *ps2port; + struct serio *serio; + unsigned long hpa = dev->hpa.start; int ret; if (!dev->irq) @@ -355,34 +341,39 @@ static int __init gscps2_probe(struct parisc_device *dev) hpa += GSC_DINO_OFFSET; ps2port = kmalloc(sizeof(struct gscps2port), GFP_KERNEL); - if (!ps2port) - return -ENOMEM; + serio = kmalloc(sizeof(struct serio), GFP_KERNEL); + if (!ps2port || !serio) { + ret = -ENOMEM; + goto fail_nomem; + } dev_set_drvdata(&dev->dev, ps2port); memset(ps2port, 0, sizeof(struct gscps2port)); + memset(serio, 0, sizeof(struct serio)); + ps2port->port = serio; ps2port->padev = dev; - ps2port->addr = ioremap(hpa, GSC_STATUS + 4); + ps2port->addr = ioremap_nocache(hpa, GSC_STATUS + 4); spin_lock_init(&ps2port->lock); gscps2_reset(ps2port); - ps2port->id = readb(ps2port->addr+GSC_ID) & 0x0f; - snprintf(ps2port->name, sizeof(ps2port->name)-1, "%s %s", - gscps2_serio_port.name, - (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse" ); - - memcpy(&ps2port->port, &gscps2_serio_port, sizeof(gscps2_serio_port)); - ps2port->port.driver = ps2port; - ps2port->port.name = ps2port->name; - ps2port->port.phys = dev->dev.bus_id; - - list_add_tail(&ps2port->node, &ps2port_list); + ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f; + + snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s", + (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse"); + strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys)); + serio->id.type = SERIO_8042; + serio->write = gscps2_write; + serio->open = gscps2_open; + serio->close = gscps2_close; + serio->port_data = ps2port; + serio->dev.parent = &dev->dev; ret = -EBUSY; - if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->name, ps2port)) + if (request_irq(dev->irq, gscps2_interrupt, IRQF_SHARED, ps2port->port->name, ps2port)) goto fail_miserably; - if ( (ps2port->id != GSC_ID_KEYBOARD) && (ps2port->id != GSC_ID_MOUSE) ) { + if (ps2port->id != GSC_ID_KEYBOARD && ps2port->id != GSC_ID_MOUSE) { printk(KERN_WARNING PFX "Unsupported PS/2 port at 0x%08lx (id=%d) ignored\n", hpa, ps2port->id); ret = -ENODEV; @@ -395,12 +386,14 @@ static int __init gscps2_probe(struct parisc_device *dev) #endif printk(KERN_INFO "serio: %s port at 0x%p irq %d @ %s\n", - ps2port->name, + ps2port->port->name, ps2port->addr, ps2port->padev->irq, - ps2port->port.phys); + ps2port->port->phys); - serio_register_port(&ps2port->port); + serio_register_port(ps2port->port); + + list_add_tail(&ps2port->node, &ps2port_list); return 0; @@ -408,10 +401,12 @@ fail: free_irq(dev->irq, ps2port); fail_miserably: - list_del(&ps2port->node); iounmap(ps2port->addr); - release_mem_region(dev->hpa, GSC_STATUS + 4); + release_mem_region(dev->hpa.start, GSC_STATUS + 4); + +fail_nomem: kfree(ps2port); + kfree(serio); return ret; } @@ -424,7 +419,7 @@ static int __devexit gscps2_remove(struct parisc_device *dev) { struct gscps2port *ps2port = dev_get_drvdata(&dev->dev); - serio_unregister_port(&ps2port->port); + serio_unregister_port(ps2port->port); free_irq(dev->irq, ps2port); gscps2_flush(ps2port); list_del(&ps2port->node); @@ -447,7 +442,7 @@ static struct parisc_device_id gscps2_device_tbl[] = { }; static struct parisc_driver parisc_ps2_driver = { - .name = "GSC PS/2", + .name = "gsc_ps2", .id_table = gscps2_device_tbl, .probe = gscps2_probe, .remove = gscps2_remove,