diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-06 17:14:01 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-06 17:14:01 -0800 |
commit | db30c70575822cc84d87b5613c19cac24734b99f (patch) | |
tree | 82945ad5813bfe6633698233981d270b5f0a310b /drivers/input/serio | |
parent | c861ea2cb2c25c1698734d9b0540a09e253690a1 (diff) | |
parent | 9334e90d5ac5ee1fa6d8b75acb7c64a8907787d1 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (29 commits)
Input: i8042 - add Dell Vostro 1510 to nomux list
Input: gtco - use USB endpoint API
Input: add support for Maple controller as a joystick
Input: atkbd - broaden the Dell DMI signatures
Input: HIL drivers - add MODULE_ALIAS()
Input: map_to_7segment.h - convert to __inline__ for userspace
Input: add support for enhanced rotary controller on pxa930 and pxa935
Input: add support for trackball on pxa930 and pxa935
Input: add da9034 touchscreen support
Input: ads7846 - strict_strtoul takes unsigned long
Input: make some variables and functions static
Input: add tsc2007 based touchscreen driver
Input: psmouse - add module parameters to control OLPC touchpad delays
Input: i8042 - add Gigabyte M912 netbook to noloop exception table
Input: atkbd - Samsung NC10 key repeat fix
Input: atkbd - add keyboard quirk for HP Pavilion ZV6100 laptop
Input: libps2 - handle 0xfc responses from devices
Input: add support for Wacom W8001 penabled serial touchscreen
Input: synaptics - report multi-taps only if supported by the device
Input: add joystick driver for Walkera WK-0701 RC transmitter
...
Diffstat (limited to 'drivers/input/serio')
-rw-r--r-- | drivers/input/serio/hil_mlc.c | 1 | ||||
-rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 15 | ||||
-rw-r--r-- | drivers/input/serio/libps2.c | 20 | ||||
-rw-r--r-- | drivers/input/serio/pcips2.c | 2 | ||||
-rw-r--r-- | drivers/input/serio/serio.c | 4 | ||||
-rw-r--r-- | drivers/input/serio/xilinx_ps2.c | 220 |
6 files changed, 148 insertions, 114 deletions
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 37586a68d345..7ba9f2b2c041 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -934,6 +934,7 @@ int hil_mlc_register(hil_mlc *mlc) snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); mlc_serio->id = hil_mlc_serio_id; + mlc_serio->id.id = i; /* HIL port no. */ mlc_serio->write = hil_mlc_serio_write; mlc_serio->open = hil_mlc_serio_open; mlc_serio->close = hil_mlc_serio_close; diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 29e686388a2c..6fa2deff7446 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -143,6 +143,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { DMI_MATCH(DMI_PRODUCT_VERSION, "M606"), }, }, + { + .ident = "Gigabyte M912", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "M912"), + DMI_MATCH(DMI_PRODUCT_VERSION, "01"), + }, + }, { } }; @@ -351,6 +359,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), }, }, + { + .ident = "Dell Vostro 1510", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), + }, + }, { } }; diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 2b304c22c200..67248c31e19a 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -262,9 +262,17 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data) break; case PS2_RET_NAK: - ps2dev->nak = 1; + ps2dev->flags |= PS2_FLAG_NAK; + ps2dev->nak = PS2_RET_NAK; break; + case PS2_RET_ERR: + if (ps2dev->flags & PS2_FLAG_NAK) { + ps2dev->flags &= ~PS2_FLAG_NAK; + ps2dev->nak = PS2_RET_ERR; + break; + } + /* * Workaround for mice which don't ACK the Get ID command. * These are valid mouse IDs that we recognize. @@ -282,8 +290,11 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data) } - if (!ps2dev->nak && ps2dev->cmdcnt) - ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1; + if (!ps2dev->nak) { + ps2dev->flags &= ~PS2_FLAG_NAK; + if (ps2dev->cmdcnt) + ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1; + } ps2dev->flags &= ~PS2_FLAG_ACK; wake_up(&ps2dev->wait); @@ -329,6 +340,7 @@ void ps2_cmd_aborted(struct ps2dev *ps2dev) if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) wake_up(&ps2dev->wait); - ps2dev->flags = 0; + /* reset all flags except last nack */ + ps2dev->flags &= PS2_FLAG_NAK; } EXPORT_SYMBOL(ps2_cmd_aborted); diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c index 1b404f9e3bff..1dacbe0d9348 100644 --- a/drivers/input/serio/pcips2.c +++ b/drivers/input/serio/pcips2.c @@ -153,7 +153,7 @@ static int __devinit pcips2_probe(struct pci_dev *dev, const struct pci_device_i serio->open = pcips2_open; serio->close = pcips2_close; strlcpy(serio->name, pci_name(dev), sizeof(serio->name)); - strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys)); + strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); serio->port_data = ps2if; serio->dev.parent = &dev->dev; ps2if->io = serio; diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 2f12d60eee3b..bc033250dfcd 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -546,8 +546,8 @@ static void serio_init_port(struct serio *serio) spin_lock_init(&serio->lock); mutex_init(&serio->drv_mutex); device_initialize(&serio->dev); - snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), - "serio%ld", (long)atomic_inc_return(&serio_no) - 1); + dev_set_name(&serio->dev, "serio%ld", + (long)atomic_inc_return(&serio_no) - 1); serio->dev.bus = &serio_bus; serio->dev.release = serio_release_port; if (serio->parent) { diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 765007899d9a..ebb22f88c842 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -58,23 +58,20 @@ /* Mask for all the Receive Interrupts */ #define XPS2_IPIXR_RX_ALL (XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR | \ - XPS2_IPIXR_RX_FULL) + XPS2_IPIXR_RX_FULL) /* Mask for all the Interrupts */ #define XPS2_IPIXR_ALL (XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL | \ - XPS2_IPIXR_WDT_TOUT) + XPS2_IPIXR_WDT_TOUT) /* Global Interrupt Enable mask */ #define XPS2_GIER_GIE_MASK 0x80000000 struct xps2data { int irq; - u32 phys_addr; - u32 remap_size; spinlock_t lock; - u8 rxb; /* Rx buffer */ void __iomem *base_address; /* virt. address of control registers */ - unsigned int dfl; + unsigned int flags; struct serio serio; /* serio */ }; @@ -82,8 +79,13 @@ struct xps2data { /* XPS PS/2 data transmission calls */ /************************************/ -/* - * xps2_recv() will attempt to receive a byte of data from the PS/2 port. +/** + * xps2_recv() - attempts to receive a byte from the PS/2 port. + * @drvdata: pointer to ps2 device private data structure + * @byte: address where the read data will be copied + * + * If there is any data available in the PS/2 receiver, this functions reads + * the data, otherwise it returns error. */ static int xps2_recv(struct xps2data *drvdata, u8 *byte) { @@ -116,33 +118,27 @@ static irqreturn_t xps2_interrupt(int irq, void *dev_id) /* Check which interrupt is active */ if (intr_sr & XPS2_IPIXR_RX_OVF) - printk(KERN_WARNING "%s: receive overrun error\n", - drvdata->serio.name); + dev_warn(drvdata->serio.dev.parent, "receive overrun error\n"); if (intr_sr & XPS2_IPIXR_RX_ERR) - drvdata->dfl |= SERIO_PARITY; + drvdata->flags |= SERIO_PARITY; if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT)) - drvdata->dfl |= SERIO_TIMEOUT; + drvdata->flags |= SERIO_TIMEOUT; if (intr_sr & XPS2_IPIXR_RX_FULL) { - status = xps2_recv(drvdata, &drvdata->rxb); + status = xps2_recv(drvdata, &c); /* Error, if a byte is not received */ if (status) { - printk(KERN_ERR - "%s: wrong rcvd byte count (%d)\n", - drvdata->serio.name, status); + dev_err(drvdata->serio.dev.parent, + "wrong rcvd byte count (%d)\n", status); } else { - c = drvdata->rxb; - serio_interrupt(&drvdata->serio, c, drvdata->dfl); - drvdata->dfl = 0; + serio_interrupt(&drvdata->serio, c, drvdata->flags); + drvdata->flags = 0; } } - if (intr_sr & XPS2_IPIXR_TX_ACK) - drvdata->dfl = 0; - return IRQ_HANDLED; } @@ -150,8 +146,15 @@ static irqreturn_t xps2_interrupt(int irq, void *dev_id) /* serio callbacks */ /*******************/ -/* - * sxps2_write() sends a byte out through the PS/2 interface. +/** + * sxps2_write() - sends a byte out through the PS/2 port. + * @pserio: pointer to the serio structure of the PS/2 port + * @c: data that needs to be written to the PS/2 port + * + * This function checks if the PS/2 transmitter is empty and sends a byte. + * Otherwise it returns error. Transmission fails only when nothing is connected + * to the PS/2 port. Thats why, we do not try to resend the data in case of a + * failure. */ static int sxps2_write(struct serio *pserio, unsigned char c) { @@ -174,33 +177,39 @@ static int sxps2_write(struct serio *pserio, unsigned char c) return status; } -/* - * sxps2_open() is called when a port is open by the higher layer. +/** + * sxps2_open() - called when a port is opened by the higher layer. + * @pserio: pointer to the serio structure of the PS/2 device + * + * This function requests irq and enables interrupts for the PS/2 device. */ static int sxps2_open(struct serio *pserio) { struct xps2data *drvdata = pserio->port_data; - int retval; + int error; + u8 c; - retval = request_irq(drvdata->irq, &xps2_interrupt, 0, + error = request_irq(drvdata->irq, &xps2_interrupt, 0, DRIVER_NAME, drvdata); - if (retval) { - printk(KERN_ERR - "%s: Couldn't allocate interrupt %d\n", - drvdata->serio.name, drvdata->irq); - return retval; + if (error) { + dev_err(drvdata->serio.dev.parent, + "Couldn't allocate interrupt %d\n", drvdata->irq); + return error; } /* start reception by enabling the interrupts */ out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK); out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL); - (void)xps2_recv(drvdata, &drvdata->rxb); + (void)xps2_recv(drvdata, &c); return 0; /* success */ } -/* - * sxps2_close() frees the interrupt. +/** + * sxps2_close() - frees the interrupt. + * @pserio: pointer to the serio structure of the PS/2 device + * + * This function frees the irq and disables interrupts for the PS/2 device. */ static void sxps2_close(struct serio *pserio) { @@ -212,24 +221,41 @@ static void sxps2_close(struct serio *pserio) free_irq(drvdata->irq, drvdata); } -/*********************/ -/* Device setup code */ -/*********************/ - -static int xps2_setup(struct device *dev, struct resource *regs_res, - struct resource *irq_res) +/** + * xps2_of_probe - probe method for the PS/2 device. + * @of_dev: pointer to OF device structure + * @match: pointer to the stucture used for matching a device + * + * This function probes the PS/2 device in the device tree. + * It initializes the driver data structure and the hardware. + * It returns 0, if the driver is bound to the PS/2 device, or a negative + * value if there is an error. + */ +static int __devinit xps2_of_probe(struct of_device *ofdev, + const struct of_device_id *match) { + struct resource r_irq; /* Interrupt resources */ + struct resource r_mem; /* IO mem resources */ struct xps2data *drvdata; struct serio *serio; - unsigned long remap_size; - int retval; + struct device *dev = &ofdev->dev; + resource_size_t remap_size, phys_addr; + int error; + + dev_info(dev, "Device Tree Probing \'%s\'\n", + ofdev->node->name); - if (!dev) - return -EINVAL; + /* Get iospace for the device */ + error = of_address_to_resource(ofdev->node, 0, &r_mem); + if (error) { + dev_err(dev, "invalid address\n"); + return error; + } - if (!regs_res || !irq_res) { - dev_err(dev, "IO resource(s) not found\n"); - return -EINVAL; + /* Get IRQ for the device */ + if (of_irq_to_resource(ofdev->node, 0, &r_irq) == NO_IRQ) { + dev_err(dev, "no IRQ found\n"); + return -ENODEV; } drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL); @@ -241,24 +267,23 @@ static int xps2_setup(struct device *dev, struct resource *regs_res, dev_set_drvdata(dev, drvdata); spin_lock_init(&drvdata->lock); - drvdata->irq = irq_res->start; - - remap_size = regs_res->end - regs_res->start + 1; - if (!request_mem_region(regs_res->start, remap_size, DRIVER_NAME)) { - dev_err(dev, "Couldn't lock memory region at 0x%08X\n", - (unsigned int)regs_res->start); - retval = -EBUSY; + drvdata->irq = r_irq.start; + + phys_addr = r_mem.start; + remap_size = r_mem.end - r_mem.start + 1; + if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) { + dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", + (unsigned long long)phys_addr); + error = -EBUSY; goto failed1; } /* Fill in configuration data and add them to the list */ - drvdata->phys_addr = regs_res->start; - drvdata->remap_size = remap_size; - drvdata->base_address = ioremap(regs_res->start, remap_size); + drvdata->base_address = ioremap(phys_addr, remap_size); if (drvdata->base_address == NULL) { - dev_err(dev, "Couldn't ioremap memory at 0x%08X\n", - (unsigned int)regs_res->start); - retval = -EFAULT; + dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n", + (unsigned long long)phys_addr); + error = -EFAULT; goto failed2; } @@ -269,8 +294,9 @@ static int xps2_setup(struct device *dev, struct resource *regs_res, * we have the PS2 in a good state */ out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET); - dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%p, irq=%d\n", - drvdata->phys_addr, drvdata->base_address, drvdata->irq); + dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n", + (unsigned long long)phys_addr, drvdata->base_address, + drvdata->irq); serio = &drvdata->serio; serio->id.type = SERIO_8042; @@ -280,71 +306,51 @@ static int xps2_setup(struct device *dev, struct resource *regs_res, serio->port_data = drvdata; serio->dev.parent = dev; snprintf(serio->name, sizeof(serio->name), - "Xilinx XPS PS/2 at %08X", drvdata->phys_addr); + "Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr); snprintf(serio->phys, sizeof(serio->phys), - "xilinxps2/serio at %08X", drvdata->phys_addr); + "xilinxps2/serio at %08llX", (unsigned long long)phys_addr); + serio_register_port(serio); return 0; /* success */ failed2: - release_mem_region(regs_res->start, remap_size); + release_mem_region(phys_addr, remap_size); failed1: kfree(drvdata); dev_set_drvdata(dev, NULL); - return retval; -} - -/***************************/ -/* OF Platform Bus Support */ -/***************************/ - -static int __devinit xps2_of_probe(struct of_device *ofdev, const struct - of_device_id * match) -{ - struct resource r_irq; /* Interrupt resources */ - struct resource r_mem; /* IO mem resources */ - int rc = 0; - - printk(KERN_INFO "Device Tree Probing \'%s\'\n", - ofdev->node->name); - - /* Get iospace for the device */ - rc = of_address_to_resource(ofdev->node, 0, &r_mem); - if (rc) { - dev_err(&ofdev->dev, "invalid address\n"); - return rc; - } - - /* Get IRQ for the device */ - rc = of_irq_to_resource(ofdev->node, 0, &r_irq); - if (rc == NO_IRQ) { - dev_err(&ofdev->dev, "no IRQ found\n"); - return rc; - } - - return xps2_setup(&ofdev->dev, &r_mem, &r_irq); + return error; } +/** + * xps2_of_remove - unbinds the driver from the PS/2 device. + * @of_dev: pointer to OF device structure + * + * This function is called if a device is physically removed from the system or + * if the driver module is being unloaded. It frees any resources allocated to + * the device. + */ static int __devexit xps2_of_remove(struct of_device *of_dev) { struct device *dev = &of_dev->dev; - struct xps2data *drvdata; - - if (!dev) - return -EINVAL; - - drvdata = dev_get_drvdata(dev); + struct xps2data *drvdata = dev_get_drvdata(dev); + struct resource r_mem; /* IO mem resources */ serio_unregister_port(&drvdata->serio); iounmap(drvdata->base_address); - release_mem_region(drvdata->phys_addr, drvdata->remap_size); + + /* Get iospace of the device */ + if (of_address_to_resource(of_dev->node, 0, &r_mem)) + dev_err(dev, "invalid address\n"); + else + release_mem_region(r_mem.start, r_mem.end - r_mem.start + 1); + kfree(drvdata); dev_set_drvdata(dev, NULL); - return 0; /* success */ + return 0; } /* Match table for of_platform binding */ |